diff --git a/Common/FeatureFlags.swift b/Common/FeatureFlags.swift index e9652b4404..3ed4b4a4eb 100644 --- a/Common/FeatureFlags.swift +++ b/Common/FeatureFlags.swift @@ -30,12 +30,15 @@ struct FeatureFlagConfiguration: Decodable { let predictedGlucoseChartClampEnabled: Bool let scenariosEnabled: Bool let sensitivityOverridesEnabled: Bool + let showEventualBloodGlucoseOnWatchEnabled: Bool let simulatedCoreDataEnabled: Bool let siriEnabled: Bool let simpleBolusCalculatorEnabled: Bool let usePositiveMomentumAndRCForManualBoluses: Bool let dynamicCarbAbsorptionEnabled: Bool let adultChildInsulinModelSelectionEnabled: Bool + let profileExpirationSettingsViewEnabled: Bool + let missedMealNotifications: Bool fileprivate init() { @@ -159,7 +162,7 @@ struct FeatureFlagConfiguration: Decodable { #endif // Swift compiler config is inverse, since the default state is enabled. - #if REMOTE_COMMANDS_DISABLED + #if REMOTE_COMMANDS_DISABLED || REMOTE_OVERRIDES_DISABLED //REMOTE_OVERRIDES_DISABLED: backwards compatibility of Loop 3 & prior self.remoteCommandsEnabled = false #else self.remoteCommandsEnabled = true @@ -171,6 +174,13 @@ struct FeatureFlagConfiguration: Decodable { self.scenariosEnabled = false #endif + // Swift compiler config is inverse, since the default state is enabled. + #if SHOW_EVENTUAL_BLOOD_GLUCOSE_ON_WATCH_DISABLED + self.showEventualBloodGlucoseOnWatchEnabled = false + #else + self.showEventualBloodGlucoseOnWatchEnabled = true + #endif + #if SIMULATED_CORE_DATA_ENABLED self.simulatedCoreDataEnabled = true #else @@ -204,6 +214,21 @@ struct FeatureFlagConfiguration: Decodable { #endif self.dynamicCarbAbsorptionEnabled = true + + // ProfileExpirationSettingsView is inverse, since the default state is enabled. + #if PROFILE_EXPIRATION_SETTINGS_VIEW_DISABLED + self.profileExpirationSettingsViewEnabled = false + #else + self.profileExpirationSettingsViewEnabled = true + #endif + + // Missed meal notifications compiler flag is inverse, since the default state is enabled. + #if MISSED_MEAL_NOTIFICATIONS_DISABLED + self.missedMealNotifications = false + #else + self.missedMealNotifications = true + #endif + } } @@ -227,6 +252,7 @@ extension FeatureFlagConfiguration : CustomDebugStringConvertible { "* remoteCommandsEnabled: \(remoteCommandsEnabled)", "* scenariosEnabled: \(scenariosEnabled)", "* sensitivityOverridesEnabled: \(sensitivityOverridesEnabled)", + "* showEventualBloodGlucoseOnWatchEnabled: \(showEventualBloodGlucoseOnWatchEnabled)", "* simulatedCoreDataEnabled: \(simulatedCoreDataEnabled)", "* siriEnabled: \(siriEnabled)", "* automaticBolusEnabled: \(automaticBolusEnabled)", @@ -235,7 +261,9 @@ extension FeatureFlagConfiguration : CustomDebugStringConvertible { "* simpleBolusCalculatorEnabled: \(simpleBolusCalculatorEnabled)", "* usePositiveMomentumAndRCForManualBoluses: \(usePositiveMomentumAndRCForManualBoluses)", "* dynamicCarbAbsorptionEnabled: \(dynamicCarbAbsorptionEnabled)", - "* adultChildInsulinModelSelectionEnabled: \(adultChildInsulinModelSelectionEnabled)" + "* adultChildInsulinModelSelectionEnabled: \(adultChildInsulinModelSelectionEnabled)", + "* profileExpirationSettingsViewEnabled: \(profileExpirationSettingsViewEnabled)", + "* missedMealNotifications: \(missedMealNotifications)" ].joined(separator: "\n") } } diff --git a/Common/ar.lproj/Intents.strings b/Common/ar.lproj/Intents.strings new file mode 100644 index 0000000000..69202aa99c --- /dev/null +++ b/Common/ar.lproj/Intents.strings @@ -0,0 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "I've set the preset"; + +/* (No Comment) */ +"80eo5o" = "Add Carb Entry"; + +/* (No Comment) */ +"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ +"I4OZy8" = "Enable Override Preset"; + +/* (No Comment) */ +"lYMuWV" = "Override Name"; + +/* (No Comment) */ +"nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Add Carb Entry"; + +/* (No Comment) */ +"oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ +"yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Add a carb entry to Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/ar.lproj/Localizable.strings b/Common/ar.lproj/Localizable.strings new file mode 100644 index 0000000000..e0fb9dff1b --- /dev/null +++ b/Common/ar.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Add Carb Entry"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Common/cs.lproj/Intents.strings b/Common/cs.lproj/Intents.strings new file mode 100644 index 0000000000..69202aa99c --- /dev/null +++ b/Common/cs.lproj/Intents.strings @@ -0,0 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "I've set the preset"; + +/* (No Comment) */ +"80eo5o" = "Add Carb Entry"; + +/* (No Comment) */ +"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ +"I4OZy8" = "Enable Override Preset"; + +/* (No Comment) */ +"lYMuWV" = "Override Name"; + +/* (No Comment) */ +"nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Add Carb Entry"; + +/* (No Comment) */ +"oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ +"yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Add a carb entry to Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/da.lproj/Intents.strings b/Common/da.lproj/Intents.strings index a901bd953b..7fdba3c551 100644 --- a/Common/da.lproj/Intents.strings +++ b/Common/da.lproj/Intents.strings @@ -1,18 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "Jeg har indstillet forudindstillingen"; + /* (No Comment) */ "80eo5o" = "Tilføj kulhydrater"; +/* (No Comment) */ +"b085BW" = "Jeg var ikke i stand til at indstille forudindstillingen."; + +/* (No Comment) */ +"I4OZy8" = "Aktiver forudindstilling for Override"; + +/* (No Comment) */ +"lYMuWV" = "Override navn"; + +/* (No Comment) */ +"nDKAmn" = "Hvad er navnet på den Override, du vil angive?"; + /* (No Comment) */ "OcNxIj" = "Tilføj kulhydrater"; /* (No Comment) */ -"yc02Yq" = "Tilføj kulhydrater til Loop."; +"oLQSsJ" = "Aktiver \"${overrideName}\" Override forudindstilling"; + +/* (No Comment) */ +"XNNmtH" = "Aktiver forudindstilling i Loop"; + +/* (No Comment) */ +"yBzwCL" = "Override valg"; + +/* (No Comment) */ +"yc02Yq" = "Tilføj kulhydrater til Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Aktivere en forudindstilling for Override i Loop"; -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; diff --git a/Common/da.lproj/Localizable.strings b/Common/da.lproj/Localizable.strings index d19cbd7249..05492ad924 100644 --- a/Common/da.lproj/Localizable.strings +++ b/Common/da.lproj/Localizable.strings @@ -4,6 +4,9 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Tilføj kulhydrater"; +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Beregner procentdelen af ​​blodsukkermålinger inden for et specificeret interval"; + /* Title of the button to begin lesson execution */ "Continue" = "Fortsæt"; @@ -14,7 +17,7 @@ "g" = "g"; /* Placeholder for upper range entry */ -"Maximum" = "Maximum"; +"Maximum" = "Maksimum"; /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; @@ -26,7 +29,7 @@ "mmol/L" = "mmol/L"; /* Lesson title */ -"Modal Day" = "Modal Dag"; +"Modal Day" = "Modal-dag"; /* Lesson result text for no data */ "No data available" = "Ingen data tilgængelige"; @@ -38,16 +41,16 @@ "Range" = "Interval"; /* Title of config entry */ -"Start Date" = "Start Dato"; +"Start Date" = "Startdato"; /* Lesson title */ -"Time in Range" = "Tme in Range"; +"Time in Range" = "Tid inden for korrektionsområde"; /* The short unit display string for international units of insulin */ "U" = "E"; /* Lesson subtitle */ -"Visualizes the most frequent glucose values by time of day" = "Visualiserer de hyppigste blodsukker værdier fordelt på dagen"; +"Visualizes the most frequent glucose values by time of day" = "Visualiserer de hyppigste blodsukkerværdier fordelt på dagen"; /* Unit string for a count of calendar weeks */ "Weeks" = "Uger"; diff --git a/Common/de.lproj/Intents.strings b/Common/de.lproj/Intents.strings index cb4bd9c6fb..53e85eca4e 100644 --- a/Common/de.lproj/Intents.strings +++ b/Common/de.lproj/Intents.strings @@ -2,7 +2,7 @@ "9KhaIS" = "Voreinstellung gesetzt"; /* (No Comment) */ -"80eo5o" = "KH-Eintrag hinzufügen"; +"80eo5o" = "Kohlenhydrate hinzufügen"; /* (No Comment) */ "b085BW" = "Voreinstellung konnte nicht gesetzt werden."; @@ -14,10 +14,10 @@ "lYMuWV" = "Voreinstellungs-Name"; /* (No Comment) */ -"nDKAmn" = "Welche Voreinstellung möchtest Du aktivieren?"; +"nDKAmn" = "Welche Voreinstellung möchten Sie aktivieren?"; /* (No Comment) */ -"OcNxIj" = "KH-Eintrag hinzufügen"; +"OcNxIj" = "Kohlenhydrate hinzufügen"; /* (No Comment) */ "oLQSsJ" = "Aktiviere '${overrideName}' Voreinstellung"; diff --git a/Common/es.lproj/Intents.strings b/Common/es.lproj/Intents.strings index d7f678f91c..fe46670365 100644 --- a/Common/es.lproj/Intents.strings +++ b/Common/es.lproj/Intents.strings @@ -1,18 +1,36 @@ -/* INIntentTitle */ -"80eo5o" = "Agregar Registro de Carbs"; +/* (No Comment) */ +"9KhaIS" = "He establecido el ajuste"; -/* INIntentParameterCombinationTitle */ -"OcNxIj" = "Agregar Registro de Carbs"; +/* (No Comment) */ +"80eo5o" = "Agregar Entrada de Carb"; -/* INIntentDescription */ -"yc02Yq" = "Agregar registro de carbs a Loop"; +/* (No Comment) */ +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Agregar Entrada de Carb"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Agregar registro de carbs a Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/es.lproj/Localizable.strings b/Common/es.lproj/Localizable.strings index edde7c378c..2517bb2aa1 100644 --- a/Common/es.lproj/Localizable.strings +++ b/Common/es.lproj/Localizable.strings @@ -7,18 +7,33 @@ /* Lesson subtitle */ "Computes the percentage of glucose measurements within a specified range" = "Calcula el porcentaje de medidas de glucosa entre una gama especificada"; +/* Title of the button to begin lesson execution */ +"Continue" = "Continuar"; + /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ "g" = "g"; +/* Placeholder for upper range entry */ +"Maximum" = "Máximo"; + /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; +/* Placeholder for lower range entry */ +"Minimum" = "Mínimo"; + /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "mmol/L"; +/* Lesson title */ +"Modal Day" = "Día modal"; + +/* Lesson result text for no data */ +"No data available" = "Datos no disponibles"; + /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; @@ -28,6 +43,15 @@ /* Title of config entry */ "Start Date" = "Fecha de Inicio"; +/* Lesson title */ +"Time in Range" = "Tiempo en Rango"; + /* The short unit display string for international units of insulin */ "U" = "U"; +/* Lesson subtitle */ +"Visualizes the most frequent glucose values by time of day" = "Visualiza los valores de glucosa más frecuentes por hora del día"; + +/* Unit string for a count of calendar weeks */ +"Weeks" = "Semanas"; + diff --git a/Common/fi.lproj/Intents.strings b/Common/fi.lproj/Intents.strings index cd3e0d1c9f..e4c15dd161 100644 --- a/Common/fi.lproj/Intents.strings +++ b/Common/fi.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Lisää hiilihydraatteja"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "Lisää hiilihydraatteja"; +"80eo5o" = "Lisää hiilihydraatteja"; /* (No Comment) */ -"yc02Yq" = "Lisää hiilihydraatteja Loopiin"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Lisää hiilihydraatteja"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Lisää hiilihydraatteja Loopiin"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/fr.lproj/Intents.strings b/Common/fr.lproj/Intents.strings index 6adcf0a383..56bed88c3f 100644 --- a/Common/fr.lproj/Intents.strings +++ b/Common/fr.lproj/Intents.strings @@ -1,18 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "J'ai défini le préréglage"; + /* (No Comment) */ "80eo5o" = "Ajouter des glucides"; +/* (No Comment) */ +"b085BW" = "Je n'ai pas pu définir le préréglage."; + +/* (No Comment) */ +"I4OZy8" = "Activer l'ajustement préréglé"; + +/* (No Comment) */ +"lYMuWV" = "Nom Ajustement"; + +/* (No Comment) */ +"nDKAmn" = "Quel est le nom de l'ajustement que vous voulez définir ?"; + /* (No Comment) */ "OcNxIj" = "Ajouter des glucides"; +/* (No Comment) */ +"oLQSsJ" = "Activer l'ajustement '${overrideName}' "; + +/* (No Comment) */ +"XNNmtH" = "Activer le préréglage dans Loop"; + +/* (No Comment) */ +"yBzwCL" = "Selection Ajustement"; + /* (No Comment) */ "yc02Yq" = "Ajouter des glucides à Loop"; -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; +/* (No Comment) */ +"ZZ3mtM" = "Activer un ajustement préréglé dans Loop"; + diff --git a/Common/fr.lproj/Localizable.strings b/Common/fr.lproj/Localizable.strings index 694e77a7d1..e58151d89a 100644 --- a/Common/fr.lproj/Localizable.strings +++ b/Common/fr.lproj/Localizable.strings @@ -7,18 +7,33 @@ /* Lesson subtitle */ "Computes the percentage of glucose measurements within a specified range" = "Ceci calcule le pourcentage des mesures de glycémie dans une plage spécifique"; +/* Title of the button to begin lesson execution */ +"Continue" = "Continuer"; + /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ "g" = "g"; +/* Placeholder for upper range entry */ +"Maximum" = "Maximum"; + /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; +/* Placeholder for lower range entry */ +"Minimum" = "Minimum"; + /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "mmol/L"; +/* Lesson title */ +"Modal Day" = "Journée type"; + +/* Lesson result text for no data */ +"No data available" = "Données indisponibles"; + /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; @@ -26,8 +41,17 @@ "Range" = "Plage"; /* Title of config entry */ -"Start Date" = "Date de commencement"; +"Start Date" = "Date de démarrage"; + +/* Lesson title */ +"Time in Range" = "Durée dans la cible"; /* The short unit display string for international units of insulin */ "U" = "U"; +/* Lesson subtitle */ +"Visualizes the most frequent glucose values by time of day" = "Visualise les glycémies les plus fréquentes par heure de la journée"; + +/* Unit string for a count of calendar weeks */ +"Weeks" = "Semaines"; + diff --git a/Common/he.lproj/Intents.strings b/Common/he.lproj/Intents.strings index 853af215c0..69202aa99c 100644 --- a/Common/he.lproj/Intents.strings +++ b/Common/he.lproj/Intents.strings @@ -1,24 +1,36 @@ -"80eo5o" = "Add Carb Entry"; - +/* (No Comment) */ "9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; - -"OcNxIj" = "Add Carb Entry"; - -"XNNmtH" = "Enable preset in Loop"; - -"ZZ3mtM" = "Enable an override preset in Loop"; +/* (No Comment) */ +"80eo5o" = "Add Carb Entry"; +/* (No Comment) */ "b085BW" = "I wasn't able to set the preset."; +/* (No Comment) */ +"I4OZy8" = "Enable Override Preset"; + +/* (No Comment) */ "lYMuWV" = "Override Name"; +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; +/* (No Comment) */ +"OcNxIj" = "Add Carb Entry"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; +/* (No Comment) */ "yc02Yq" = "Add a carb entry to Loop"; +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/it.lproj/Intents.strings b/Common/it.lproj/Intents.strings index d3a0e94880..847d80d4eb 100644 --- a/Common/it.lproj/Intents.strings +++ b/Common/it.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Aggiungi carboidrati assunti"; +"9KhaIS" = "Ho impostato la preimpostazione"; /* (No Comment) */ -"OcNxIj" = "Aggiungi carboidrati assunti"; +"80eo5o" = "Agg. Carb. Assunti"; /* (No Comment) */ -"yc02Yq" = "Aggiungi carboidrati assunti a Loop"; +"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ +"I4OZy8" = "Abilita Programma Alternativo"; + +/* (No Comment) */ +"lYMuWV" = "Nome Programma Alternativo"; + +/* (No Comment) */ +"nDKAmn" = "Qual'è il nome del programma alternativo che vuoi impostare?"; + +/* (No Comment) */ +"OcNxIj" = "Agg. Carb. Assunti"; + +/* (No Comment) */ +"oLQSsJ" = "Abilita '${overrideName}' Programma Alternativo"; -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; +/* (No Comment) */ "XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yBzwCL" = "Selezione Programma Alternativo"; + +/* (No Comment) */ +"yc02Yq" = "Aggiungi carboidrati a Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Attiva Programma Alternativo in Loop"; + diff --git a/Common/it.lproj/Localizable.strings b/Common/it.lproj/Localizable.strings index 6da1a77ad0..55e7848e7b 100644 --- a/Common/it.lproj/Localizable.strings +++ b/Common/it.lproj/Localizable.strings @@ -2,7 +2,10 @@ "%1$@ v%2$@" = "%1$@ v%2$@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Aggiungi carboidrati assunti"; +"Add Carb Entry" = "Agg. Carb. Assunti"; + +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Calcola la percentuale di misurazioni della glicemia entro un intervallo specifico"; /* Title of the button to begin lesson execution */ "Continue" = "Continua"; diff --git a/Common/ja.lproj/Intents.strings b/Common/ja.lproj/Intents.strings index ca2038ce0d..f59cfa9e62 100644 --- a/Common/ja.lproj/Intents.strings +++ b/Common/ja.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "カーボを追加"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "カーボを追加"; +"80eo5o" = "糖質の記入を追加"; /* (No Comment) */ -"yc02Yq" = "ループにカーボを追加"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "糖質の記入を追加"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "ループにカーボを追加"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/nb.lproj/Intents.strings b/Common/nb.lproj/Intents.strings index d7a0b641a9..0fe45121af 100644 --- a/Common/nb.lproj/Intents.strings +++ b/Common/nb.lproj/Intents.strings @@ -1,18 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "Jeg har angitt forhåndsinnstillingen"; + /* (No Comment) */ "80eo5o" = "Legg til karbohydrater"; +/* (No Comment) */ +"b085BW" = "Jeg kunne ikke angi forhåndsinnstillingen."; + +/* (No Comment) */ +"I4OZy8" = "Aktiver forhåndsinnstillt overstyring"; + +/* (No Comment) */ +"lYMuWV" = "Navn på overstyring"; + +/* (No Comment) */ +"nDKAmn" = "Hva heter overstyringen du vil angi?"; + /* (No Comment) */ "OcNxIj" = "Legg til karbohydrater"; +/* (No Comment) */ +"oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Aktiver forhåndsinnstilling i Loop"; + +/* (No Comment) */ +"yBzwCL" = "Overstyr valg"; + /* (No Comment) */ "yc02Yq" = "Legg til karbohydrater i Loop"; -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; +/* (No Comment) */ +"ZZ3mtM" = "Aktiver en forhåndsinnstilling for overstyring i Loop"; + diff --git a/Common/nb.lproj/Localizable.strings b/Common/nb.lproj/Localizable.strings index 32bdd8539c..056b65c455 100644 --- a/Common/nb.lproj/Localizable.strings +++ b/Common/nb.lproj/Localizable.strings @@ -4,6 +4,9 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Legg til karbohydrater"; +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Beregner prosentandelen av blodsukkermålinger innenfor et spesifisert område"; + /* Title of the button to begin lesson execution */ "Continue" = "Fortsett"; diff --git a/Common/nl.lproj/Intents.strings b/Common/nl.lproj/Intents.strings index 1533363380..e72963d83a 100644 --- a/Common/nl.lproj/Intents.strings +++ b/Common/nl.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Voeg koolhydraten toe"; +"9KhaIS" = "Ik heb het programma ingesteld"; /* (No Comment) */ -"OcNxIj" = "Voeg koolhydraten toe"; +"80eo5o" = "Kh. Inv. Toevoegen"; /* (No Comment) */ -"yc02Yq" = "Voeg koolhydraten toe aan Loop"; +"b085BW" = "Ik kon het programma niet instellen."; + +/* (No Comment) */ +"I4OZy8" = "Override Programma Inschakelen"; + +/* (No Comment) */ +"lYMuWV" = "Override Naam"; + +/* (No Comment) */ +"nDKAmn" = "Wat is de naam van de override die je zou willen instellen?"; + +/* (No Comment) */ +"OcNxIj" = "Kh. Inv. Toevoegen"; + +/* (No Comment) */ +"oLQSsJ" = "Override '${overrideName}' Inschakelen"; + +/* (No Comment) */ +"XNNmtH" = "Programma in Loop inschakelen"; + +/* (No Comment) */ +"yBzwCL" = "Overrideselectie"; + +/* (No Comment) */ +"yc02Yq" = "Voeg koolhydrateninvoer toe aan Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Een override programma in Loop inschakelen"; -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; diff --git a/Common/nl.lproj/Localizable.strings b/Common/nl.lproj/Localizable.strings index e98674e351..a272262f20 100644 --- a/Common/nl.lproj/Localizable.strings +++ b/Common/nl.lproj/Localizable.strings @@ -2,13 +2,13 @@ "%1$@ v%2$@" = "%1$@ v%2$@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Voeg koolhydraten toe"; +"Add Carb Entry" = "Koolhydraatinvoer Toevoegen"; /* Lesson subtitle */ "Computes the percentage of glucose measurements within a specified range" = "Berekent het percentage glucosemetingen in een specifiek bereik"; /* Title of the button to begin lesson execution */ -"Continue" = "Ga verder"; +"Continue" = "Ga Verder"; /* The short unit display string for decibles */ "dB" = "dB"; @@ -29,10 +29,10 @@ "mmol/L" = "mmol/L"; /* Lesson title */ -"Modal Day" = "Modale dag"; +"Modal Day" = "Modale Dag"; /* Lesson result text for no data */ -"No data available" = "Geen data beschikbaar"; +"No data available" = "Geen gegevens beschikbaar"; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; @@ -41,16 +41,16 @@ "Range" = "Bereik"; /* Title of config entry */ -"Start Date" = "Start datum"; +"Start Date" = "Startdatum"; /* Lesson title */ -"Time in Range" = "Tijd binnen bereik"; +"Time in Range" = "Tijd binnen Bereik"; /* The short unit display string for international units of insulin */ "U" = "E"; /* Lesson subtitle */ -"Visualizes the most frequent glucose values by time of day" = "Geeft de meest voorkomende glucose waardes weer per moment van de dag "; +"Visualizes the most frequent glucose values by time of day" = "Geeft de meest voorkomende glucosewaarden weer per moment van de dag"; /* Unit string for a count of calendar weeks */ "Weeks" = "Weken"; diff --git a/Common/pl.lproj/Intents.strings b/Common/pl.lproj/Intents.strings index 9cec9c4b65..86f8cd9c3f 100644 --- a/Common/pl.lproj/Intents.strings +++ b/Common/pl.lproj/Intents.strings @@ -1,18 +1,36 @@ -/* INIntentTitle */ -"80eo5o" = "Add Carb Entry"; - -/* INIntentParameterCombinationTitle */ -"OcNxIj" = "Add Carb Entry"; - -/* INIntentDescription */ -"yc02Yq" = "Add a carb entry to Loop"; - -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; +/* (No Comment) */ +"9KhaIS" = "Ustawiłem Cel Tymczas."; + +/* (No Comment) */ +"80eo5o" = "Wprowadź węglowodany"; + +/* (No Comment) */ +"b085BW" = "Nie mogłem ustawić celu."; + +/* (No Comment) */ +"I4OZy8" = "Włącz Cel Tymczasowy"; + +/* (No Comment) */ +"lYMuWV" = "Nazwa Celu Tymczas."; + +/* (No Comment) */ +"nDKAmn" = "Jak nazywa się Cel Tymczasowy, który chcesz włączyć?"; + +/* (No Comment) */ +"OcNxIj" = "Wprowadź węglowodany"; + +/* (No Comment) */ +"oLQSsJ" = "Włącz '${overrideName}' Cel Tymczasowy"; + +/* (No Comment) */ +"XNNmtH" = "Włącz Cel Tymczasowy w pętli"; + +/* (No Comment) */ +"yBzwCL" = "Wybierz Cel Tymczasowy"; + +/* (No Comment) */ +"yc02Yq" = "Dodaj węglowodany do pętli"; + +/* (No Comment) */ +"ZZ3mtM" = "Włącz Cel Tymczasowy w pętli"; + diff --git a/Common/pl.lproj/Localizable.strings b/Common/pl.lproj/Localizable.strings index f630a70c5d..904ee7d8a8 100644 --- a/Common/pl.lproj/Localizable.strings +++ b/Common/pl.lproj/Localizable.strings @@ -4,20 +4,54 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Dodaj pozycję dla węglowodanów"; +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Oblicza procent pomiarów glukozy w określonym zakresie"; + +/* Title of the button to begin lesson execution */ +"Continue" = "Kontynuuj"; + /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ "g" = "g"; +/* Placeholder for upper range entry */ +"Maximum" = "Maksymalnie"; + /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; +/* Placeholder for lower range entry */ +"Minimum" = "Minimalnie"; + /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "mmol/L"; +/* Lesson title */ +"Modal Day" = "Dzień modalny"; + +/* Lesson result text for no data */ +"No data available" = "Brak danych"; + /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; +/* Section title for glucose range */ +"Range" = "Zasięg"; + +/* Title of config entry */ +"Start Date" = "Data rozpoczęcia"; + +/* Lesson title */ +"Time in Range" = "Czas w zakresie (TIR)"; + /* The short unit display string for international units of insulin */ "U" = "J"; + +/* Lesson subtitle */ +"Visualizes the most frequent glucose values by time of day" = "Wizualizuje najczęstsze wartości glukozy według pory dnia"; + +/* Unit string for a count of calendar weeks */ +"Weeks" = "Tygodnie"; + diff --git a/Common/pt-BR.lproj/Intents.strings b/Common/pt-BR.lproj/Intents.strings index 694faa1fe9..130b82cbb5 100644 --- a/Common/pt-BR.lproj/Intents.strings +++ b/Common/pt-BR.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Adicionar Carboidratos"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "Adicionar Carboidratos"; +"80eo5o" = "Adicionar Carb"; /* (No Comment) */ -"yc02Yq" = "Adicionar Carboidratos ao Loop"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Adicionar Carb"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Adicionar Carboidratos ao Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/ro.lproj/Intents.strings b/Common/ro.lproj/Intents.strings index ce36e2214c..2f029b1cd6 100644 --- a/Common/ro.lproj/Intents.strings +++ b/Common/ro.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Adăugare carbohidrați"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "Adăugare carbohidrați"; +"80eo5o" = "Adaugă carbohidrați"; /* (No Comment) */ -"yc02Yq" = "Adaugă carbohidrați în Loop"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Adaugă carbohidrați"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Adaugă carbohidrați în Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/ru.lproj/Intents.strings b/Common/ru.lproj/Intents.strings index 2f55bd8c16..43f070d0c0 100644 --- a/Common/ru.lproj/Intents.strings +++ b/Common/ru.lproj/Intents.strings @@ -1,18 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "Я установил пресет"; + /* (No Comment) */ "80eo5o" = "Добавить запись углеводов"; +/* (No Comment) */ +"b085BW" = "Я не смог установить пресет."; + +/* (No Comment) */ +"I4OZy8" = "Включить пресет временной цели"; + +/* (No Comment) */ +"lYMuWV" = "Имя пресета"; + +/* (No Comment) */ +"nDKAmn" = "Как называется пресет, которое вы хотите установить?"; + /* (No Comment) */ "OcNxIj" = "Добавить запись углеводов"; +/* (No Comment) */ +"oLQSsJ" = "Включить '${overrideName}' пресет"; + +/* (No Comment) */ +"XNNmtH" = "Включить пресет в Loop"; + +/* (No Comment) */ +"yBzwCL" = "Выбор временных целей"; + /* (No Comment) */ "yc02Yq" = "Добавьте запись углеводов в алгоритм цикла"; -"9KhaIS" = "I've set the preset"; -"I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; -"lYMuWV" = "Override Name"; -"nDKAmn" = "What's the name of the override you'd like to set?"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; -"yBzwCL" = "Override Selection"; +/* (No Comment) */ +"ZZ3mtM" = "Включение пресета ВЦ в Loop"; + diff --git a/Common/ru.lproj/Localizable.strings b/Common/ru.lproj/Localizable.strings index bdee38ba11..29b8b0e0e1 100644 --- a/Common/ru.lproj/Localizable.strings +++ b/Common/ru.lproj/Localizable.strings @@ -4,21 +4,51 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Введите углеводы"; +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Вычисляет процент измерений глюкозы в заданном диапазоне"; + +/* Title of the button to begin lesson execution */ +"Continue" = "Продолжить"; + /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ "g" = "г"; +/* Placeholder for upper range entry */ +"Maximum" = "Максимум"; + /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "мг/дл"; +/* Placeholder for lower range entry */ +"Minimum" = "Минимум"; + /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "ммоль/л"; +/* Lesson result text for no data */ +"No data available" = "Данные недоступны"; + /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; +/* Section title for glucose range */ +"Range" = "Диапазон"; + +/* Title of config entry */ +"Start Date" = "Дата начала"; + +/* Lesson title */ +"Time in Range" = "Время в диапазоне"; + /* The short unit display string for international units of insulin */ "U" = "ед"; +/* Lesson subtitle */ +"Visualizes the most frequent glucose values by time of day" = "Визуализация наиболее частых значений глюкозы по времени суток"; + +/* Unit string for a count of calendar weeks */ +"Weeks" = "Недели"; + diff --git a/Common/sk.lproj/Intents.strings b/Common/sk.lproj/Intents.strings new file mode 100644 index 0000000000..ef6d2d0920 --- /dev/null +++ b/Common/sk.lproj/Intents.strings @@ -0,0 +1,36 @@ +/* (No Comment) */ +"9KhaIS" = "Nastavil som predvoľbu"; + +/* (No Comment) */ +"80eo5o" = "Zadať sacharidy"; + +/* (No Comment) */ +"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ +"I4OZy8" = "Enable Override Preset"; + +/* (No Comment) */ +"lYMuWV" = "Override Name"; + +/* (No Comment) */ +"nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Zadať sacharidy"; + +/* (No Comment) */ +"oLQSsJ" = "Enable '$%1$@' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ +"yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Zadať sacharidy do Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/sk.lproj/Localizable.strings b/Common/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..4e49851fe2 --- /dev/null +++ b/Common/sk.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Zadať sacharidy"; + +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Vypočíta percento meraní glykémie v rámci špecifikovaného rozsahu"; + +/* Title of the button to begin lesson execution */ +"Continue" = "Pokračovať"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Placeholder for upper range entry */ +"Maximum" = "Maximum"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* Placeholder for lower range entry */ +"Minimum" = "Minimum"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Lesson result text for no data */ +"No data available" = "Údaje nie sú k dispozícii"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Section title for glucose range */ +"Range" = "Rozsah"; + +/* Title of config entry */ +"Start Date" = "Dátum začiatku"; + +/* Lesson title */ +"Time in Range" = "Čas v rozsahu"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + +/* Lesson subtitle */ +"Visualizes the most frequent glucose values by time of day" = "Zobrazuje najčastejšie hodnoty glykémie podľa hodín dňa"; + +/* Unit string for a count of calendar weeks */ +"Weeks" = "Týždne"; + diff --git a/Common/sv.lproj/Intents.strings b/Common/sv.lproj/Intents.strings index 20bf063944..25e1a6e213 100644 --- a/Common/sv.lproj/Intents.strings +++ b/Common/sv.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Lägg till kolhydrater"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "Lägg till kolhydrater"; +"80eo5o" = "Lägg till kolhydrater"; /* (No Comment) */ -"yc02Yq" = "Lägg till kolhydrater för att kunna loopa"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Lägg till kolhydrater"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Lägg till kolhydrater för att kunna loopa"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/tr.lproj/Intents.strings b/Common/tr.lproj/Intents.strings index 853af215c0..416c11d092 100644 --- a/Common/tr.lproj/Intents.strings +++ b/Common/tr.lproj/Intents.strings @@ -1,24 +1,36 @@ -"80eo5o" = "Add Carb Entry"; +/* (No Comment) */ +"9KhaIS" = "Ön ayarı yaptım"; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ +"80eo5o" = "Karb Girişi Ekle"; -"I4OZy8" = "Enable Override Preset"; +/* (No Comment) */ +"b085BW" = "Ön ayarı yapamadım."; -"OcNxIj" = "Add Carb Entry"; +/* (No Comment) */ +"I4OZy8" = "Ön Ayarı Geçersiz Kıl"; -"XNNmtH" = "Enable preset in Loop"; +/* (No Comment) */ +"lYMuWV" = "Geçersiz Kılma Adı"; -"ZZ3mtM" = "Enable an override preset in Loop"; +/* (No Comment) */ +"nDKAmn" = "Ayarlamak istediğiniz geçersiz kılmanın adı nedir?"; -"b085BW" = "I wasn't able to set the preset."; +/* (No Comment) */ +"OcNxIj" = "Karb Girişi Ekle"; -"lYMuWV" = "Override Name"; +/* (No Comment) */ +"oLQSsJ" = "'${overrideName}' Ön Ayarını Geçersiz Kılmayı Etkinleştir"; -"nDKAmn" = "What's the name of the override you'd like to set?"; +/* (No Comment) */ +"XNNmtH" = "Döngüde ön ayarı etkinleştir"; -"oLQSsJ" = "Enable '${overrideName}' Override Preset"; +/* (No Comment) */ +"yBzwCL" = "Geçersiz Kılma Seçimi"; -"yBzwCL" = "Override Selection"; +/* (No Comment) */ +"yc02Yq" = "Döngüye bir karbonhidrat girişi ekleyin"; -"yc02Yq" = "Add a carb entry to Loop"; +/* (No Comment) */ +"ZZ3mtM" = "Döngüde ön ayarı geçersiz kıl"; diff --git a/Common/tr.lproj/Localizable.strings b/Common/tr.lproj/Localizable.strings index e0fb9dff1b..f924e32220 100644 --- a/Common/tr.lproj/Localizable.strings +++ b/Common/tr.lproj/Localizable.strings @@ -2,23 +2,56 @@ "%1$@ v%2$@" = "%1$@ v%2$@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Add Carb Entry"; +"Add Carb Entry" = "Karbonhidrat Girişi Ekle"; + +/* Lesson subtitle */ +"Computes the percentage of glucose measurements within a specified range" = "Belirli bir aralıktaki glikoz ölçümlerinin yüzdesini hesaplar"; + +/* Title of the button to begin lesson execution */ +"Continue" = "Devam et"; /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ -"g" = "g"; +"g" = "gr"; + +/* Placeholder for upper range entry */ +"Maximum" = "Maksimum"; /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; +/* Placeholder for lower range entry */ +"Minimum" = "Minimum"; + /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "mmol/L"; +/* Lesson title */ +"Modal Day" = "Modal Gün"; + +/* Lesson result text for no data */ +"No data available" = "Kullanılabilir veri yok"; + /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; +/* Section title for glucose range */ +"Range" = "Aralık"; + +/* Title of config entry */ +"Start Date" = "Başlangıç tarihi"; + +/* Lesson title */ +"Time in Range" = "Aralıktaki Süre"; + /* The short unit display string for international units of insulin */ -"U" = "U"; +"U" = "Ü"; + +/* Lesson subtitle */ +"Visualizes the most frequent glucose values by time of day" = "En sık görülen glikoz değerlerini günün saatine göre görselleştirir"; + +/* Unit string for a count of calendar weeks */ +"Weeks" = "Hafta"; diff --git a/Common/vi.lproj/Intents.strings b/Common/vi.lproj/Intents.strings index e078394091..26f9af1fd2 100644 --- a/Common/vi.lproj/Intents.strings +++ b/Common/vi.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "Khai báo khối lượng Carb"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "Khai báo khối lượng Carb"; +"80eo5o" = "Khai báo Carb"; /* (No Comment) */ -"yc02Yq" = "Khai báo khối lượng Carb cho Loop"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "Khai báo Carb"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "Khai báo khối lượng Carb cho Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/zh-Hans.lproj/Intents.strings b/Common/zh-Hans.lproj/Intents.strings index cff018b0c0..3c86a8a391 100644 --- a/Common/zh-Hans.lproj/Intents.strings +++ b/Common/zh-Hans.lproj/Intents.strings @@ -1,18 +1,36 @@ /* (No Comment) */ -"80eo5o" = "添加碳水化合物"; +"9KhaIS" = "I've set the preset"; /* (No Comment) */ -"OcNxIj" = "添加碳水化合物"; +"80eo5o" = "添加碳水化合物"; /* (No Comment) */ -"yc02Yq" = "将碳水化合物添加到Loop"; +"b085BW" = "I wasn't able to set the preset."; -"9KhaIS" = "I've set the preset"; +/* (No Comment) */ "I4OZy8" = "Enable Override Preset"; -"XNNmtH" = "Enable preset in Loop"; -"ZZ3mtM" = "Enable an override preset in Loop"; -"b085BW" = "I wasn't able to set the preset."; + +/* (No Comment) */ "lYMuWV" = "Override Name"; + +/* (No Comment) */ "nDKAmn" = "What's the name of the override you'd like to set?"; + +/* (No Comment) */ +"OcNxIj" = "添加碳水化合物"; + +/* (No Comment) */ "oLQSsJ" = "Enable '${overrideName}' Override Preset"; + +/* (No Comment) */ +"XNNmtH" = "Enable preset in Loop"; + +/* (No Comment) */ "yBzwCL" = "Override Selection"; + +/* (No Comment) */ +"yc02Yq" = "将碳水化合物添加到Loop"; + +/* (No Comment) */ +"ZZ3mtM" = "Enable an override preset in Loop"; + diff --git a/Common/zh-Hans.lproj/Localizable.strings b/Common/zh-Hans.lproj/Localizable.strings index be5965c657..62b18b0ecd 100644 --- a/Common/zh-Hans.lproj/Localizable.strings +++ b/Common/zh-Hans.lproj/Localizable.strings @@ -1,6 +1,3 @@ -/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ -"%1$@ v%2$@" = "%1$@ v%2$@"; - /* Title of the user activity for adding carbs */ "Add Carb Entry" = "添加碳水化合物"; @@ -10,9 +7,6 @@ /* Title of the button to begin lesson execution */ "Continue" = "继续"; -/* The short unit display string for decibles */ -"dB" = "dB"; - /* The short unit display string for grams */ "g" = "克"; @@ -31,9 +25,6 @@ /* Lesson result text for no data */ "No data available" = "无数据"; -/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ -"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; - /* Section title for glucose range */ "Range" = "范围"; diff --git a/DoseMathTests/DoseMathTests.swift b/DoseMathTests/DoseMathTests.swift index ce9e1767bf..5205955465 100644 --- a/DoseMathTests/DoseMathTests.swift +++ b/DoseMathTests/DoseMathTests.swift @@ -751,7 +751,7 @@ class RecommendTempBasalTests: XCTestCase { func testHighAndFalling() { let glucose = loadGlucoseValueFixture("recommend_temp_basal_high_and_falling") - + let insulinModel = WalshInsulinModel(actionDuration: insulinActionDuration, delay: 0) let dose = glucose.recommendedTempBasal( diff --git a/DoseMathTests/ar.lproj/Localizable.strings b/DoseMathTests/ar.lproj/Localizable.strings index a3607f260e..97a7523522 100644 --- a/DoseMathTests/ar.lproj/Localizable.strings +++ b/DoseMathTests/ar.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "سكر الدم الحالي %1$@ أقل من نطاق التصحيح."; +"Current glucose of %1$@ is below correction range." = "قراءة سكر الدم %1$@ أقل من نطاق التصحيح."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,10 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "متوقع سكر الدم خلال %1$@ هو %2$@."; +"Predicted glucose at %1$@ is %2$@." = "قراءاة سكر الدم بعد %1$@ هي %2$@."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "متوقع سكر الدم %1$@ أقل من إعدادات التعليق المؤقت."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "قراءة سكر الدم المتوقعة %1$@ أقل من قيمة تعليق الضخ في الإعدادات."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/da.lproj/Localizable.strings b/DoseMathTests/da.lproj/Localizable.strings index 13db793a4f..8161cac496 100644 --- a/DoseMathTests/da.lproj/Localizable.strings +++ b/DoseMathTests/da.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = "Den aktuelle glukose for %1$@ er under korrektionsområdet."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,16 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Forventet glukose ved %1$@ er %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Den forventede glukose er inden for intervallet."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Det forventede glukoseindhold på %1$@ er under din indstilling af glukose-sikkerhedsgrænsen."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet glukose på %1$@ er under din indstilling for suspenderingstærskel."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/de.lproj/Localizable.strings b/DoseMathTests/de.lproj/Localizable.strings index ffa45f1be7..b4b56621fc 100644 --- a/DoseMathTests/de.lproj/Localizable.strings +++ b/DoseMathTests/de.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Der aktuelle Blutzucker von %1$@ liegt unterhalb des Korrekturbereiches."; +"Current glucose of %1$@ is below correction range." = "Der aktuelle Blutzucker von %1$@ liegt unter dem Korrekturbereich."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -8,22 +8,22 @@ "g" = "g"; /* The short unit display string for milligrams of glucose per decilter */ -"mg/dL" = "mg/dl"; +"mg/dL" = "mg/dL"; /* The short unit display string for millimoles of glucose per liter */ -"mmol/L" = "mmol/l"; +"mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Der vorhergesagte Blutzucker um %1$@ ist %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Vorhergesagte Glukose um %1$@ ist %2$@."; /* Notice when predicted glucose for bolus recommendation is in range */ -"Predicted glucose is in range." = "Der vorhergesagte Glukosewert liegt im Bereich."; +"Predicted glucose is in range." = "Der vorhergesagte Blutzucker liegt im Zielbereich."; /* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ -"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Der vorhergesagte Glukosewert von %1$@ liegt unter Ihrer Glukose-Sicherheitsgrenzwerteinstellung."; +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Der vorhergesagte Blutzucker von %1$@ liegt unter der Sicherheitsgrenze."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Der vorhergesagte Blutzucker von %1$@ liegt unterhalb des eingestellten Schwellwertes zur Unterbrechung der Basalrate. "; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Der vorhergesagte Blutzucker von %1$@ liegt unter dem Grenzwert für die Hypo-Abschaltung."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/es.lproj/Localizable.strings b/DoseMathTests/es.lproj/Localizable.strings index ea86cdbd48..8550028f10 100644 --- a/DoseMathTests/es.lproj/Localizable.strings +++ b/DoseMathTests/es.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Glucosa actual de %1$@ está debajo del rango correctivo."; +"Current glucose of %1$@ is below correction range." = "Glucosa actual de %1$@ está por debajo del rango de corrección."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,16 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Glucosa proyectada en %1$@ es %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Glucosa proyectada a las %1$@ es %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "La glucosa proyectada está en rango"; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Glucosa proyectada de %1$@ se encuentra por debajo de tu nivel de suspensión."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Glucosa proyectada de %1$@ se encuentra debajo de tu nivel de suspensión."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Glucosa proyectada de %1$@ se encuentra por debajo de su nivel de suspensión."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/fi.lproj/Localizable.strings b/DoseMathTests/fi.lproj/Localizable.strings index 95e33d98bb..715f2b62be 100644 --- a/DoseMathTests/fi.lproj/Localizable.strings +++ b/DoseMathTests/fi.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = "Nykyinen glukoosi %1$@ on korjausalueen alapuolella."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,13 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Ennustettu glukoosi klo %1$@ on %2$@."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Ennustettu glukoosi %1$@ on turvarajan alapuolella."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Ennustettu glukoosi %1$@ on pysäytysrajan alapuolella."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/fr.lproj/Localizable.strings b/DoseMathTests/fr.lproj/Localizable.strings index a148669627..5b6ca784e3 100644 --- a/DoseMathTests/fr.lproj/Localizable.strings +++ b/DoseMathTests/fr.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Glycémie actuelle %1$@ sous la plage de correction."; +"Current glucose of %1$@ is below correction range." = "Glycémie actuelle de %1$@ est en dessous de la plage de correction."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,7 +14,13 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Glycémie de %2$@ prédite pour %1$@."; +"Predicted glucose at %1$@ is %2$@." = "Glycémie prévue à %1$@ est %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "La glycémie prévue est dans la plage."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "La glycémie estimée à %1$@ est sous le seuil de suspension."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Prédiction de la glycémie à %1$@ sous le seuil de suspension défini."; diff --git a/DoseMathTests/he.lproj/Localizable.strings b/DoseMathTests/he.lproj/Localizable.strings index cb195752e8..95e33d98bb 100644 --- a/DoseMathTests/he.lproj/Localizable.strings +++ b/DoseMathTests/he.lproj/Localizable.strings @@ -24,3 +24,4 @@ /* The short unit display string for international units of insulin */ "U" = "U"; + diff --git a/DoseMathTests/it.lproj/Localizable.strings b/DoseMathTests/it.lproj/Localizable.strings index ac7b220625..2b1f0b3c81 100644 --- a/DoseMathTests/it.lproj/Localizable.strings +++ b/DoseMathTests/it.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "La glicemia corrente %1$@ é al di sotto dell'intervallo glicemico selezionato."; +"Current glucose of %1$@ is below correction range." = "La glicemia attuale di %1$@ è al di sotto dell'intervallo glicemico selezionato."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,16 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "La glicemia prevista a %1$@ è %2$@."; +"Predicted glucose at %1$@ is %2$@." = "La glicemia prevista tra %1$@ e' di %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "La glicemia prevista è nell'intervallo"; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "La glicemia prevista da %1$@ è al di sotto del tuo limite glicemico di sicurezza"; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "La glicemia prevista %1$@ è inferiore al valore glicemico previsto per la sospensione dell'erogazione."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "La glicemia prevista %1$@ e' inferiore al valore soglia per la sospensione dell'erogazione."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/ja.lproj/Localizable.strings b/DoseMathTests/ja.lproj/Localizable.strings index 95e33d98bb..fc23adb8cb 100644 --- a/DoseMathTests/ja.lproj/Localizable.strings +++ b/DoseMathTests/ja.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = "現在の血糖値は %1$@ で補正範囲を下回っています。"; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,10 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "%1$@の予想グルコースは %2$@です。"; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "予想グルコースは %1$@ で一時停止値を下回ります。"; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/nb.lproj/Localizable.strings b/DoseMathTests/nb.lproj/Localizable.strings index f76a4f8154..656e726c6f 100644 --- a/DoseMathTests/nb.lproj/Localizable.strings +++ b/DoseMathTests/nb.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Nåværende blodsukker på %1$@ er under målområde."; +"Current glucose of %1$@ is below correction range." = "Gjeldende glukose på %1$@ er under korreksjonsområdet."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,16 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Forventet blodsukker om %1$@ er %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Forventet blodsukker kl %1$@ er %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Forventet blodsukker er innenfor målområdet."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Forventet blodsukker på %1$@ er lavere enn innstillingen for blodsukkersikkerhet."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet blodsukker %1$@ er under innstillingen for insulinstopp."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet blodsukker %1$@ er lavere enn innstilling for insulinstopp"; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/nl.lproj/Localizable.strings b/DoseMathTests/nl.lproj/Localizable.strings index f104ed4a4d..fc884f7931 100644 --- a/DoseMathTests/nl.lproj/Localizable.strings +++ b/DoseMathTests/nl.lproj/Localizable.strings @@ -1,11 +1,11 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Huidige glucose van %1$@ is onder het correctie bereik."; +"Current glucose of %1$@ is below correction range." = "Huidige glucose %1$@ is lager dan het correctiebereik."; /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ -"g" = "gr"; +"g" = "g"; /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; @@ -14,10 +14,16 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Voorspelde glucose van %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Voorspelde glucose om %1$@ is %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Voorspelde glucose is binnen bereik."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Voorspelde glucose van %1$@ ligt onder je ingestelde glucoseveiligheidslimiet."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Voorspelde glucose van %1$@ is onder het onderbreken van basaal instelling."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Verwachte glucose van %1$@ is lager dan je ingestelde insulineonderbrekingsdrempel."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/pl.lproj/Localizable.strings b/DoseMathTests/pl.lproj/Localizable.strings index de8ed4e1d2..37275a855b 100644 --- a/DoseMathTests/pl.lproj/Localizable.strings +++ b/DoseMathTests/pl.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Obecny cukier jest %1$@ poniżej poziomu korekcji."; +"Current glucose of %1$@ is below correction range." = "Poziom glukozy %1$@ jest poniżej wartości korekcji."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -8,19 +8,26 @@ "g" = "g"; /* The short unit display string for milligrams of glucose per decilter */ -"mg/dL" = "mg/dL"; +"mg/dL" = "mg/dl"; /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Przewidywany cukier o %1$@ wyniesie %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Przewidywany poziom cukru o %1$@ wyniesie %2$@"; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Przewidywane stężenie glukozy jest w zakresie."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Przewidywana glukoza %1$@ jest poniżej ustawionego bezpiecznego limitu glukozy."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Przewidywany poziom cukru %1$@ jest poniżej progu wstrzymania."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Przewidywany poziom cukru %1$@ jest poniżej progu zawieszenia."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The short unit display string for international units of insulin */ "U" = "J"; + diff --git a/DoseMathTests/pt-BR.lproj/Localizable.strings b/DoseMathTests/pt-BR.lproj/Localizable.strings index 95e33d98bb..e2b2c21af8 100644 --- a/DoseMathTests/pt-BR.lproj/Localizable.strings +++ b/DoseMathTests/pt-BR.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = " Glicemia atual %1$@ está abaixo da zona de correção."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,10 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Glicemia prevista em %1$@ é %2$@."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Glicemia prevista de %1$@ está abaixo do limite de suspensão."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/ro.lproj/Localizable.strings b/DoseMathTests/ro.lproj/Localizable.strings index 95e33d98bb..e40c294d20 100644 --- a/DoseMathTests/ro.lproj/Localizable.strings +++ b/DoseMathTests/ro.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = " Glicemia curentă de %1$@ se situează sub intervalul țintă de corecție."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,13 +14,19 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Glicemia prognozată pentru %1$@ este %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Glicemia prognozată este în interval."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Glicemia prognozată de %1$@ se situează sub limita de siguranță configurată."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Glicemia prognozată de %1$@ se situează sub limita de suspendare configurată"; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ -"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; +"QUANTITY_VALUE_AND_UNIT" = "%1$@%2$@"; /* The short unit display string for international units of insulin */ "U" = "U"; diff --git a/DoseMathTests/ru.lproj/Localizable.strings b/DoseMathTests/ru.lproj/Localizable.strings index c15e8d72e7..ee719e1110 100644 --- a/DoseMathTests/ru.lproj/Localizable.strings +++ b/DoseMathTests/ru.lproj/Localizable.strings @@ -1,8 +1,8 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = " Текущая гликемия %1$@ ниже диапазона коррекции"; +"Current glucose of %1$@ is below correction range." = "Гликемия %1$@ ниже диапазона коррекции"; /* The short unit display string for decibles */ -"dB" = "dB"; +"dB" = "дБ"; /* The short unit display string for grams */ "g" = "г"; @@ -11,13 +11,19 @@ "mg/dL" = "мг/дл"; /* The short unit display string for millimoles of glucose per liter */ -"mmol/L" = "ммоль/л"; +"mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Предсказываемая гликемия в %1$@ - %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Прогнозируемый уровень глюкозы на %1$@ составляет %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Прогнозируемый уровень глюкозы находится в диапазоне."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Прогнозируемое значение глюкозы %1$@ ниже установленного вами предела безопасности глюкозы."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Предсказываемая гликемия %1$@ ниже установленного вами порога приостановки помпы"; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Предсказываемая гликемия %1$@ ниже ваших настроек порога приостановки помпы"; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/sk.lproj/Localizable.strings b/DoseMathTests/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..a8f518bed3 --- /dev/null +++ b/DoseMathTests/sk.lproj/Localizable.strings @@ -0,0 +1,27 @@ +/* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ +"Current glucose of %1$@ is below correction range." = "Aktuálna glykémie %1$@ je pod cieľovým rozsahom."; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ +"Predicted glucose at %1$@ is %2$@." = "Predpokladaná glykémia o %1$@ je %2$@ ."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Predpokladaná glykémia je v cieľovom rozsahu."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + diff --git a/DoseMathTests/sv.lproj/Localizable.strings b/DoseMathTests/sv.lproj/Localizable.strings index b992061cd5..a464fa7a93 100644 --- a/DoseMathTests/sv.lproj/Localizable.strings +++ b/DoseMathTests/sv.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Nuvarande glukosvärde %1$@ är under målvärdet."; +"Current glucose of %1$@ is below correction range." = "Nuvarande glukosvärde %1$@ är under målvärde."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -11,13 +11,16 @@ "mg/dL" = "mg/dl"; /* The short unit display string for millimoles of glucose per liter */ -"mmol/L" = "mmol/l"; +"mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "Förväntat glukosvärde vid %1$@ är %2$@."; +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Förväntat blodsocker på %1$@ är under ditt tröskelvärde."; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Det förväntade slutglukosvärdet %1$@ är under ditt angivna tröskelvärde."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Förväntat glukosvärde %1$@ är under ditt tröskelvärde."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/DoseMathTests/tr.lproj/Localizable.strings b/DoseMathTests/tr.lproj/Localizable.strings index cb195752e8..16eb8735b9 100644 --- a/DoseMathTests/tr.lproj/Localizable.strings +++ b/DoseMathTests/tr.lproj/Localizable.strings @@ -1,11 +1,11 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = "%1$@ Mevcut KŞ düzeltme aralığının altında."; /* The short unit display string for decibles */ "dB" = "dB"; /* The short unit display string for grams */ -"g" = "g"; +"g" = "gr"; /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; @@ -14,13 +14,20 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Tahmini KŞ %1$@ %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Tahmini KŞ aralık içinde."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "%1$@ tahmini KŞ, KŞ güvenlik limiti ayarınızın altında."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Tahmini KŞ %1$@ askıya alma eşiği ayarınızın altında."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The short unit display string for international units of insulin */ -"U" = "U"; +"U" = "Ü"; + diff --git a/DoseMathTests/vi.lproj/Localizable.strings b/DoseMathTests/vi.lproj/Localizable.strings index 95e33d98bb..1787817048 100644 --- a/DoseMathTests/vi.lproj/Localizable.strings +++ b/DoseMathTests/vi.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = " Chỉ số glucose hiện tại %1$@ nằm dưới Phạm vi Điều chỉnh."; /* The short unit display string for decibles */ "dB" = "dB"; @@ -14,10 +14,10 @@ "mmol/L" = "mmol/L"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Dự đoán đường huyết vào lúc %1$@ là %2$@."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Dự đoán đường huyết %1$@ là dưới ngưỡng tạm ngưng trong cài đặt của bạn."; /* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ "QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; diff --git a/Learn/Base.lproj/LaunchScreen.storyboard b/Learn/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index bfa3612941..0000000000 --- a/Learn/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Learn/ar.lproj/Main.strings b/Learn/ar.lproj/Main.strings index bb24a4e11e..6359029045 100644 --- a/Learn/ar.lproj/Main.strings +++ b/Learn/ar.lproj/Main.strings @@ -1,3 +1,3 @@ - /* Class = "UINavigationItem"; title = "Learn"; ObjectID = "8hF-Ij-B7m"; */ "8hF-Ij-B7m.title" = "تعلم"; + diff --git a/Learn/da.lproj/InfoPlist.strings b/Learn/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..bf67d54ddb --- /dev/null +++ b/Learn/da.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Lær"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Mad-data fra Health-databasen bruges til at bestemme blodsukkereffekten. Blodsukkerdata fra Health-databasen bruges til graftegning og momentumberegning. Søvndata fra sundhedsdatabasen bruges til at optimere leveringen af opdateringer om komplikationer af Apple Watch i den tid, du er vågen."; + diff --git a/Learn/da.lproj/Main.strings b/Learn/da.lproj/Main.strings index 50fa41e306..d8d90ac21a 100644 --- a/Learn/da.lproj/Main.strings +++ b/Learn/da.lproj/Main.strings @@ -1,3 +1,3 @@ /* Class = "UINavigationItem"; title = "Learn"; ObjectID = "8hF-Ij-B7m"; */ -"8hF-Ij-B7m.title" = "Learn"; +"8hF-Ij-B7m.title" = "Lær"; diff --git a/Learn/de.lproj/InfoPlist.strings b/Learn/de.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7b3a9db485 --- /dev/null +++ b/Learn/de.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Lerne"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Mahlzeitendaten aus der Health Datenbank werden verwendet, um die Glukoseeffekte zu bestimmen. Glukosedaten aus der Health Datenbank werden zur grafischen Darstellung und Impulsberechnung verwendet. Schlafdaten aus der Health-Datenbank werden verwendet, um die Bereitstellung von Apple Watch-Komplikationsupdates während Ihrer Wachzeit zu optimieren."; + diff --git a/Learn/es.lproj/InfoPlist.strings b/Learn/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9ca3ae0719 --- /dev/null +++ b/Learn/es.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Aprender"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Los datos de alimentos de la base de datos de Salud se utilizan para determinar los efectos en el nivel de glucosa. Los datos de glucosa de la base de datos de Salud se utilizan para graficar y determinar cálculos de momento. Los datos de Sueño de la base de datos de Salud se utilizan para optimizar la entrega de actualizaciones de las complicaciones del Apple Watch durante el tiempo que está despierto."; + diff --git a/Learn/fi.lproj/InfoPlist.strings b/Learn/fi.lproj/InfoPlist.strings index fbbd5eaa64..72a3c2f38b 100644 --- a/Learn/fi.lproj/InfoPlist.strings +++ b/Learn/fi.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Opettele"; + /* Privacy - Health Share Usage Description */ "NSHealthShareUsageDescription" = "Terveys-sovelluksen ateriatietoja käytetään glukoosivaikutusten määrittämiseen. Terveys-sovelluksen glukoositietoja käytetään graafeissa ja laskelmissa. Unitietoja käytetään Apple Watch -komplikaation toiminnan optimointiin hereillä olon aikana."; diff --git a/Learn/fr.lproj/InfoPlist.strings b/Learn/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..904ee70a5b --- /dev/null +++ b/Learn/fr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Apprendre"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Les données sur les repas provenant de la base de données Santé sont utilisées pour déterminer les effets du glucose. Les données relatives au glucose provenant de la base de données Santé sont utilisées pour la création de graphiques et le calcul de l'élan. Les données relatives au sommeil provenant de la base de données Santé sont utilisées pour optimiser l'envoi des mises à jour des complications de l'Apple Watch pendant la période où vous êtes éveillé(e)."; + diff --git a/Learn/he.lproj/LaunchScreen.strings b/Learn/he.lproj/LaunchScreen.strings deleted file mode 100644 index 8b13789179..0000000000 --- a/Learn/he.lproj/LaunchScreen.strings +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Learn/he.lproj/Main.strings b/Learn/he.lproj/Main.strings index 6b8f04c045..50fa41e306 100644 --- a/Learn/he.lproj/Main.strings +++ b/Learn/he.lproj/Main.strings @@ -1,3 +1,3 @@ - /* Class = "UINavigationItem"; title = "Learn"; ObjectID = "8hF-Ij-B7m"; */ "8hF-Ij-B7m.title" = "Learn"; + diff --git a/Learn/it.lproj/InfoPlist.strings b/Learn/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..3cf2b9683c --- /dev/null +++ b/Learn/it.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Impara"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "I dati sui pasti del database Salute vengono utilizzati per determinare gli effetti del glucosio. I dati sul glucosio del database Salute vengono utilizzati per la rappresentazione grafica e il calcolo del momento. I dati sul sonno del database Salute vengono utilizzati per ottimizzare la consegna degli aggiornamenti delle complicazioni di Apple Watch durante il periodo di veglia."; + diff --git a/Learn/nb.lproj/InfoPlist.strings b/Learn/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..874720150f --- /dev/null +++ b/Learn/nb.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Lære"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Måltidsdata fra helsedatabasen brukes til å bestemme glukoseeffekter. Glukosedata fra helsedatabasen brukes til grafer og momentumberegning. Søvndata fra helsedatabasen brukes til å optimalisere leveringen av Apple Watch-komplikasjonsoppdateringer når du er våken."; + diff --git a/Learn/nl.lproj/InfoPlist.strings b/Learn/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..2d6020792e --- /dev/null +++ b/Learn/nl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Leer"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Maaltijdgegevens uit de database Gezondheid worden gebruikt om glucose-effecenten te bepalen. Glucosegegevens uit de database Gezondheid worden gebruikt voor grafieken en het berekenen van trendlijnen. Slaapgegevens uit de database Gezondheid worden gebruikt om de Apple Watch complicatie bij te werken wanneer je wakker bent."; + diff --git a/Learn/pl.lproj/InfoPlist.strings b/Learn/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..afba6db611 --- /dev/null +++ b/Learn/pl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Learn"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Dane posiłków z bazy danych aplikacji Zdrowie służą do określania wpływu glukozy. Dane dotyczące glukozy z bazy danych aplikacji Zdrowie są wykorzystywane do tworzenia wykresów i wyznaczania trendu. Dane dotyczące snu z bazy danych aplikacji Zdrowie służą do optymalizacji dostarczania aktualizacji komplikacji Apple Watch w czasie, gdy nie śpisz."; + diff --git a/Learn/pl.lproj/Main.strings b/Learn/pl.lproj/Main.strings index 6b8f04c045..50fa41e306 100644 --- a/Learn/pl.lproj/Main.strings +++ b/Learn/pl.lproj/Main.strings @@ -1,3 +1,3 @@ - /* Class = "UINavigationItem"; title = "Learn"; ObjectID = "8hF-Ij-B7m"; */ "8hF-Ij-B7m.title" = "Learn"; + diff --git a/Learn/ro.lproj/InfoPlist.strings b/Learn/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7b3f99c93d --- /dev/null +++ b/Learn/ro.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Learn"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Datele mesei din baza de date din aplicația Sănătate sunt folosite pentru a determina efectele glicemice. Datele despre glicemie din baza de date Sănătate sunt folosite pentru construirea graficelor și calcularea influențelor glicemice. Datele de somn din baza de date Sănătate sunt folosite pentru a optimiza livrarea de actualizări de datele ale ceasului Apple pe perioada când sunteți treaz."; + diff --git a/Learn/ru.lproj/InfoPlist.strings b/Learn/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..c0198b35f9 --- /dev/null +++ b/Learn/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "Узнать"; + diff --git a/Learn/sk.lproj/InfoPlist.strings b/Learn/sk.lproj/InfoPlist.strings new file mode 100644 index 0000000000..da8422aedb --- /dev/null +++ b/Learn/sk.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Údaje o jedle z databázy Health sa používajú na určenie účinkov glukózy. Údaje o glukóze z databázy Health sa používajú na vytváranie grafov a výpočet hybnosti. Údaje o spánku z databázy Health sa používajú na optimalizáciu doručovania aktualizácií komplikácií Apple Watch v čase, keď ste hore."; + diff --git a/Learn/sv.lproj/InfoPlist.strings b/Learn/sv.lproj/InfoPlist.strings new file mode 100644 index 0000000000..55302cd95c --- /dev/null +++ b/Learn/sv.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Learn"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Kolhydratdata från Apple Health-databasen används för att avgöra blodsockereffekt. Blodsockervärden från Apple Health-databasen används i diagram och för beräkning av förändring."; + diff --git a/Learn/tr.lproj/InfoPlist.strings b/Learn/tr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7ff69b11e8 --- /dev/null +++ b/Learn/tr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle name */ +"CFBundleName" = "Öğren"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Sağlık veri tabanından alınan yemek verileri, glikoz etkilerini belirlemek için kullanılır. Sağlık veri tabanından alınan glikoz verileri, grafik ve momentum hesaplaması için kullanılır. Sağlık veritabanındaki uyku verileri, uyanık olduğunuz süre boyunca Apple Watch komplikasyon güncellemelerinin teslimini optimize etmek için kullanılır."; + diff --git a/Learn/tr.lproj/LaunchScreen.strings b/Learn/tr.lproj/LaunchScreen.strings deleted file mode 100644 index 8b13789179..0000000000 --- a/Learn/tr.lproj/LaunchScreen.strings +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Learn/tr.lproj/Main.strings b/Learn/tr.lproj/Main.strings index 6b8f04c045..92d1c6c547 100644 --- a/Learn/tr.lproj/Main.strings +++ b/Learn/tr.lproj/Main.strings @@ -1,3 +1,3 @@ - /* Class = "UINavigationItem"; title = "Learn"; ObjectID = "8hF-Ij-B7m"; */ -"8hF-Ij-B7m.title" = "Learn"; +"8hF-Ij-B7m.title" = "Öğren"; + diff --git a/Loop Intent Extension/ar.lproj/Localizable.strings b/Loop Intent Extension/ar.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/ar.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/da.lproj/InfoPlist.strings b/Loop Intent Extension/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..e1fa874bc4 --- /dev/null +++ b/Loop Intent Extension/da.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent-udvidelse"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent-udvidelse"; + diff --git a/Loop Intent Extension/da.lproj/Localizable.strings b/Loop Intent Extension/da.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/da.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/de.lproj/InfoPlist.strings b/Loop Intent Extension/de.lproj/InfoPlist.strings new file mode 100644 index 0000000000..b26b270e4a --- /dev/null +++ b/Loop Intent Extension/de.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Absichts Erweiterung"; + +/* Bundle name */ +"CFBundleName" = "Loop Absichts Erweiterung"; + diff --git a/Loop Intent Extension/de.lproj/Localizable.strings b/Loop Intent Extension/de.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/de.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/es.lproj/InfoPlist.strings b/Loop Intent Extension/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..0ddf6e188b --- /dev/null +++ b/Loop Intent Extension/es.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Extensión de Intención de Loop"; + +/* Bundle name */ +"CFBundleName" = "Extensión de Intención de Loop"; + diff --git a/Loop Intent Extension/es.lproj/Localizable.strings b/Loop Intent Extension/es.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/es.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/fi.lproj/InfoPlist.strings b/Loop Intent Extension/fi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7dba838e53 --- /dev/null +++ b/Loop Intent Extension/fi.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent Extension"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent Extension"; + diff --git a/Loop Intent Extension/fi.lproj/Localizable.strings b/Loop Intent Extension/fi.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/fi.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/fr.lproj/InfoPlist.strings b/Loop Intent Extension/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7dba838e53 --- /dev/null +++ b/Loop Intent Extension/fr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent Extension"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent Extension"; + diff --git a/Loop Intent Extension/fr.lproj/Localizable.strings b/Loop Intent Extension/fr.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/fr.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/he.lproj/Localizable.strings b/Loop Intent Extension/he.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/he.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/it.lproj/InfoPlist.strings b/Loop Intent Extension/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..d7b1b818ad --- /dev/null +++ b/Loop Intent Extension/it.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Estensione dell'intento di Loop"; + +/* Bundle name */ +"CFBundleName" = "Estensione dell'intento di Loop"; + diff --git a/Loop Intent Extension/it.lproj/Localizable.strings b/Loop Intent Extension/it.lproj/Localizable.strings new file mode 100644 index 0000000000..dcd56fd902 --- /dev/null +++ b/Loop Intent Extension/it.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ contro %2$@"; + diff --git a/Loop Intent Extension/ja.lproj/Localizable.strings b/Loop Intent Extension/ja.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/ja.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/nb.lproj/InfoPlist.strings b/Loop Intent Extension/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..359db83e9d --- /dev/null +++ b/Loop Intent Extension/nb.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Utvidelse av Loop intensjon"; + +/* Bundle name */ +"CFBundleName" = "Utvidelse av Loop intensjon"; + diff --git a/Loop Intent Extension/nb.lproj/Localizable.strings b/Loop Intent Extension/nb.lproj/Localizable.strings new file mode 100644 index 0000000000..0039fc241d --- /dev/null +++ b/Loop Intent Extension/nb.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + diff --git a/Loop Intent Extension/nl.lproj/InfoPlist.strings b/Loop Intent Extension/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7e45d4d58b --- /dev/null +++ b/Loop Intent Extension/nl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent Extensie"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent Extensie"; + diff --git a/Loop Intent Extension/nl.lproj/Localizable.strings b/Loop Intent Extension/nl.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/nl.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/pl.lproj/InfoPlist.strings b/Loop Intent Extension/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7dba838e53 --- /dev/null +++ b/Loop Intent Extension/pl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent Extension"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent Extension"; + diff --git a/Loop Intent Extension/pl.lproj/Localizable.strings b/Loop Intent Extension/pl.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/pl.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/pt-BR.lproj/Localizable.strings b/Loop Intent Extension/pt-BR.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/pt-BR.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/ro.lproj/InfoPlist.strings b/Loop Intent Extension/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..a9ddd00908 --- /dev/null +++ b/Loop Intent Extension/ro.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Extensie Intent Loop"; + +/* Bundle name */ +"CFBundleName" = "Extensie Intent Loop"; + diff --git a/Loop Intent Extension/ro.lproj/Localizable.strings b/Loop Intent Extension/ro.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/ro.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/ru.lproj/InfoPlist.strings b/Loop Intent Extension/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7dba838e53 --- /dev/null +++ b/Loop Intent Extension/ru.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent Extension"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent Extension"; + diff --git a/Loop Intent Extension/ru.lproj/Localizable.strings b/Loop Intent Extension/ru.lproj/Localizable.strings new file mode 100644 index 0000000000..d468c09692 --- /dev/null +++ b/Loop Intent Extension/ru.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ против %2$@"; + diff --git a/Loop Intent Extension/sk.lproj/Localizable.strings b/Loop Intent Extension/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..0039fc241d --- /dev/null +++ b/Loop Intent Extension/sk.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + diff --git a/Loop Intent Extension/sv.lproj/InfoPlist.strings b/Loop Intent Extension/sv.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7dba838e53 --- /dev/null +++ b/Loop Intent Extension/sv.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop Intent Extension"; + +/* Bundle name */ +"CFBundleName" = "Loop Intent Extension"; + diff --git a/Loop Intent Extension/sv.lproj/Localizable.strings b/Loop Intent Extension/sv.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/sv.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/tr.lproj/InfoPlist.strings b/Loop Intent Extension/tr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..64bff70e71 --- /dev/null +++ b/Loop Intent Extension/tr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Döngü Amaç Uzantısı"; + +/* Bundle name */ +"CFBundleName" = "Döngü Amaç Uzantısı"; + diff --git a/Loop Intent Extension/tr.lproj/Localizable.strings b/Loop Intent Extension/tr.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/tr.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Intent Extension/vi.lproj/Localizable.strings b/Loop Intent Extension/vi.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/Loop Intent Extension/vi.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/Loop Status Extension/ar.lproj/InfoPlist.strings b/Loop Status Extension/ar.lproj/InfoPlist.strings new file mode 100644 index 0000000000..034a1e1f6a --- /dev/null +++ b/Loop Status Extension/ar.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + diff --git a/Loop Status Extension/ar.lproj/Localizable.strings b/Loop Status Extension/ar.lproj/Localizable.strings index 5b7fa9b26d..5935bf3282 100644 --- a/Loop Status Extension/ar.lproj/Localizable.strings +++ b/Loop Status Extension/ar.lproj/Localizable.strings @@ -1,5 +1,33 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "كارب النشط"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "أنسولين نشط"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "متوقع %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "أنسولين نشط %1$@ وحدة"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "وحدة"; + diff --git a/Loop Status Extension/ar.lproj/MainInterface.strings b/Loop Status Extension/ar.lproj/MainInterface.strings index f5f9da2c9a..23ec628122 100644 --- a/Loop Status Extension/ar.lproj/MainInterface.strings +++ b/Loop Status Extension/ar.lproj/MainInterface.strings @@ -1,6 +1,6 @@ +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "كارب النشط"; -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "متوقع 92 mg/dL"; +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "أنسولين نشط"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "أنسولين نشط 1.0 وحدة"; diff --git a/Loop Status Extension/da.lproj/InfoPlist.strings b/Loop Status Extension/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..ffe563a634 --- /dev/null +++ b/Loop Status Extension/da.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop-statusudvidelse"; + diff --git a/Loop Status Extension/da.lproj/Localizable.strings b/Loop Status Extension/da.lproj/Localizable.strings index fdea45f6b6..4388492489 100644 --- a/Loop Status Extension/da.lproj/Localizable.strings +++ b/Loop Status Extension/da.lproj/Localizable.strings @@ -1,9 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? E"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Aktive kulhydrater"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Aktivt insulin"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %1$@" = "Til sidst %1$@"; +"Eventually %1$@" = "Med tiden %1$@"; + +/* The short unit display string for grams */ +"g" = "g"; /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ E"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The short unit display string for international units of insulin */ "U" = "E"; diff --git a/Loop Status Extension/da.lproj/MainInterface.strings b/Loop Status Extension/da.lproj/MainInterface.strings index 00e818d7d5..ca088fa3ce 100644 --- a/Loop Status Extension/da.lproj/MainInterface.strings +++ b/Loop Status Extension/da.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Til sidst 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Aktive kulhydrater"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 E"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Aktivt insulin"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 E"; diff --git a/Loop Status Extension/de.lproj/InfoPlist.strings b/Loop Status Extension/de.lproj/InfoPlist.strings new file mode 100644 index 0000000000..8a7abf7ee4 --- /dev/null +++ b/Loop Status Extension/de.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status-Erweiterung"; + diff --git a/Loop Status Extension/de.lproj/Localizable.strings b/Loop Status Extension/de.lproj/Localizable.strings index 51c1679402..8dac8187e8 100644 --- a/Loop Status Extension/de.lproj/Localizable.strings +++ b/Loop Status Extension/de.lproj/Localizable.strings @@ -1,9 +1,18 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + /* Displayed in the widget when the amount of active insulin cannot be determined. */ "? U" = "? IE"; +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "%1$@ U" = "%1$@ IE"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Widget label title describing the active carbs */ "Active Carbs" = "Aktive KH"; @@ -16,9 +25,21 @@ /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Irgendwann %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ IE"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The short unit display string for international units of insulin */ "U" = "IE"; diff --git a/Loop Status Extension/de.lproj/MainInterface.strings b/Loop Status Extension/de.lproj/MainInterface.strings index e525eeb307..fb0ae387e6 100644 --- a/Loop Status Extension/de.lproj/MainInterface.strings +++ b/Loop Status Extension/de.lproj/MainInterface.strings @@ -1,6 +1,9 @@ /* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ "9iF-xY-Bh4.text" = "Aktive KH"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + /* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ "UPi-dG-yYD.text" = "Aktives Insulin"; diff --git a/Loop Status Extension/en.lproj/MainInterface.strings b/Loop Status Extension/en.lproj/MainInterface.strings index 0f89462fa3..3a52b2e5e2 100644 --- a/Loop Status Extension/en.lproj/MainInterface.strings +++ b/Loop Status Extension/en.lproj/MainInterface.strings @@ -1,6 +1,6 @@ - -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ "9iF-xY-Bh4.text" = "Eventually 92 mg/dL"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ "UPi-dG-yYD.text" = "IOB 1.0 U"; + diff --git a/Loop Status Extension/es.lproj/InfoPlist.strings b/Loop Status Extension/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..029eaa2d2a --- /dev/null +++ b/Loop Status Extension/es.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Extensión de Estado de Loop"; + diff --git a/Loop Status Extension/es.lproj/Localizable.strings b/Loop Status Extension/es.lproj/Localizable.strings index 7d3b493829..a893db7399 100644 --- a/Loop Status Extension/es.lproj/Localizable.strings +++ b/Loop Status Extension/es.lproj/Localizable.strings @@ -1,6 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? gr"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? U"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Carbohidratos Activos"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Insulina activa"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Eventualmente %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/es.lproj/MainInterface.strings b/Loop Status Extension/es.lproj/MainInterface.strings index 8d4fcfa1e0..5354b0e9c3 100644 --- a/Loop Status Extension/es.lproj/MainInterface.strings +++ b/Loop Status Extension/es.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Eventualmente 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Carbohidratos Activos"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 gr"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Insulina activa"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 U"; diff --git a/Loop Status Extension/fi.lproj/InfoPlist.strings b/Loop Status Extension/fi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1565e025fa --- /dev/null +++ b/Loop Status Extension/fi.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status Extension"; + diff --git a/Loop Status Extension/fi.lproj/Localizable.strings b/Loop Status Extension/fi.lproj/Localizable.strings index 1dbfbd5cf3..af5d51baf2 100644 --- a/Loop Status Extension/fi.lproj/Localizable.strings +++ b/Loop Status Extension/fi.lproj/Localizable.strings @@ -1,6 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? U"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Akt. hiilari"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Akt. insuliini"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Ennuste %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/fi.lproj/MainInterface.strings b/Loop Status Extension/fi.lproj/MainInterface.strings index 9bb1d27d3d..a1e847d468 100644 --- a/Loop Status Extension/fi.lproj/MainInterface.strings +++ b/Loop Status Extension/fi.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Ennuste 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Akt. hiilari"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Akt. insuliini"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 U"; diff --git a/Loop Status Extension/fr.lproj/InfoPlist.strings b/Loop Status Extension/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1565e025fa --- /dev/null +++ b/Loop Status Extension/fr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status Extension"; + diff --git a/Loop Status Extension/fr.lproj/Localizable.strings b/Loop Status Extension/fr.lproj/Localizable.strings index 78372a5724..1c6e8dfb18 100644 --- a/Loop Status Extension/fr.lproj/Localizable.strings +++ b/Loop Status Extension/fr.lproj/Localizable.strings @@ -1,6 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? U"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Glucides actifs"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Insuline active"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %1$@" = "Éventuellement %1$@"; +"Eventually %1$@" = "Finalement %1$@"; + +/* The short unit display string for grams */ +"g" = "g"; /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/fr.lproj/MainInterface.strings b/Loop Status Extension/fr.lproj/MainInterface.strings index 718222e748..4d13ebda2d 100644 --- a/Loop Status Extension/fr.lproj/MainInterface.strings +++ b/Loop Status Extension/fr.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Éventuellement 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Glucides actifs"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Insuline active"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 U"; diff --git a/Loop Status Extension/he.lproj/InfoPlist.strings b/Loop Status Extension/he.lproj/InfoPlist.strings new file mode 100644 index 0000000000..034a1e1f6a --- /dev/null +++ b/Loop Status Extension/he.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + diff --git a/Loop Status Extension/he.lproj/Localizable.strings b/Loop Status Extension/he.lproj/Localizable.strings index d21551845d..e8c025e6a6 100644 --- a/Loop Status Extension/he.lproj/Localizable.strings +++ b/Loop Status Extension/he.lproj/Localizable.strings @@ -1,5 +1,33 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Active Carbs"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Active Insulin"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Eventually %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/he.lproj/MainInterface.strings b/Loop Status Extension/he.lproj/MainInterface.strings index 25ea93a823..1adc815b18 100644 --- a/Loop Status Extension/he.lproj/MainInterface.strings +++ b/Loop Status Extension/he.lproj/MainInterface.strings @@ -1,12 +1,12 @@ - /* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ "9iF-xY-Bh4.text" = "Active Carbs"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + /* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ "UPi-dG-yYD.text" = "Active Insulin"; /* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ "Vgf-p1-2QP.text" = "0 U"; -/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ -"dPp-lJ-5sh.text" = "0 g"; diff --git a/Loop Status Extension/it.lproj/InfoPlist.strings b/Loop Status Extension/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..da11eb5a77 --- /dev/null +++ b/Loop Status Extension/it.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Estensione dello stato di funzionamento di Loop"; + diff --git a/Loop Status Extension/it.lproj/Localizable.strings b/Loop Status Extension/it.lproj/Localizable.strings index 8d36fd4bed..871ef62d8c 100644 --- a/Loop Status Extension/it.lproj/Localizable.strings +++ b/Loop Status Extension/it.lproj/Localizable.strings @@ -1,6 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? U"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ contro %2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Carb Attivi"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Insulina attiva"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Probabile Glic. %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/it.lproj/MainInterface.strings b/Loop Status Extension/it.lproj/MainInterface.strings index 660125a4df..ab9c005998 100644 --- a/Loop Status Extension/it.lproj/MainInterface.strings +++ b/Loop Status Extension/it.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "probabile glic. 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Carb Attivi"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Insulina attiva"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 U"; diff --git a/Loop Status Extension/ja.lproj/InfoPlist.strings b/Loop Status Extension/ja.lproj/InfoPlist.strings new file mode 100644 index 0000000000..bb232bb4cc --- /dev/null +++ b/Loop Status Extension/ja.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "ループ"; + diff --git a/Loop Status Extension/ja.lproj/Localizable.strings b/Loop Status Extension/ja.lproj/Localizable.strings index 0f9b31a8ea..d328a81f35 100644 --- a/Loop Status Extension/ja.lproj/Localizable.strings +++ b/Loop Status Extension/ja.lproj/Localizable.strings @@ -1,6 +1,33 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "残存糖質"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "残存インスリン"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "予想 %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/ja.lproj/MainInterface.strings b/Loop Status Extension/ja.lproj/MainInterface.strings index 3e7844c42b..2407f97e64 100644 --- a/Loop Status Extension/ja.lproj/MainInterface.strings +++ b/Loop Status Extension/ja.lproj/MainInterface.strings @@ -1,6 +1,6 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "予想 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "残存糖質"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "残存インスリン"; diff --git a/Loop Status Extension/nb.lproj/InfoPlist.strings b/Loop Status Extension/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..24d50f5390 --- /dev/null +++ b/Loop Status Extension/nb.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Utvidelse av Loop status"; + diff --git a/Loop Status Extension/nb.lproj/Localizable.strings b/Loop Status Extension/nb.lproj/Localizable.strings index af0e1fc932..2e4a88ce5f 100644 --- a/Loop Status Extension/nb.lproj/Localizable.strings +++ b/Loop Status Extension/nb.lproj/Localizable.strings @@ -1,9 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? E"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Aktive karbohydrater"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Aktivt insulin"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Omsider %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ E"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The short unit display string for international units of insulin */ "U" = "E"; diff --git a/Loop Status Extension/nb.lproj/MainInterface.strings b/Loop Status Extension/nb.lproj/MainInterface.strings index c464634590..7942de07be 100644 --- a/Loop Status Extension/nb.lproj/MainInterface.strings +++ b/Loop Status Extension/nb.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Omsider 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Aktive karbohydrater"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 E"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Aktivt insulin"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 E"; diff --git a/Loop Status Extension/nl.lproj/InfoPlist.strings b/Loop Status Extension/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..62e5156f17 --- /dev/null +++ b/Loop Status Extension/nl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status Extensie"; + diff --git a/Loop Status Extension/nl.lproj/Localizable.strings b/Loop Status Extension/nl.lproj/Localizable.strings index 20a25693db..b5f9439380 100644 --- a/Loop Status Extension/nl.lproj/Localizable.strings +++ b/Loop Status Extension/nl.lproj/Localizable.strings @@ -1,9 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? E"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Actieve Koolhydraten"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Actieve Insuline"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Uiteindelijk %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ E"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The short unit display string for international units of insulin */ "U" = "E"; diff --git a/Loop Status Extension/nl.lproj/MainInterface.strings b/Loop Status Extension/nl.lproj/MainInterface.strings index c652dfaa76..3300ee0aec 100644 --- a/Loop Status Extension/nl.lproj/MainInterface.strings +++ b/Loop Status Extension/nl.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Uiteindelijk 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Actieve Koolhydraten"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 E"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Actieve Insuline"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 E"; diff --git a/Loop Status Extension/pl.lproj/InfoPlist.strings b/Loop Status Extension/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1565e025fa --- /dev/null +++ b/Loop Status Extension/pl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status Extension"; + diff --git a/Loop Status Extension/pl.lproj/Localizable.strings b/Loop Status Extension/pl.lproj/Localizable.strings index 6522679f83..9f9cab187f 100644 --- a/Loop Status Extension/pl.lproj/Localizable.strings +++ b/Loop Status Extension/pl.lproj/Localizable.strings @@ -1,5 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? J"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ J"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Aktywne węglowodany"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Aktywna insulina"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Docelowo %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ J"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "J"; + diff --git a/Loop Status Extension/pl.lproj/MainInterface.strings b/Loop Status Extension/pl.lproj/MainInterface.strings index 7421b4922b..137aac2c3c 100644 --- a/Loop Status Extension/pl.lproj/MainInterface.strings +++ b/Loop Status Extension/pl.lproj/MainInterface.strings @@ -1,6 +1,12 @@ +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Aktywne węglowodany"; -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "docelowo 92 mg/dL"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Aktywna insulina"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 J"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 J"; diff --git a/Loop Status Extension/pt-BR.lproj/InfoPlist.strings b/Loop Status Extension/pt-BR.lproj/InfoPlist.strings new file mode 100644 index 0000000000..034a1e1f6a --- /dev/null +++ b/Loop Status Extension/pt-BR.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + diff --git a/Loop Status Extension/pt-BR.lproj/Localizable.strings b/Loop Status Extension/pt-BR.lproj/Localizable.strings index 7d3b493829..ed1ddc8056 100644 --- a/Loop Status Extension/pt-BR.lproj/Localizable.strings +++ b/Loop Status Extension/pt-BR.lproj/Localizable.strings @@ -1,6 +1,33 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Carboidratos Ativos"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Insulina Ativa"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Eventualmente %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/pt-BR.lproj/MainInterface.strings b/Loop Status Extension/pt-BR.lproj/MainInterface.strings index 8d4fcfa1e0..09c2331507 100644 --- a/Loop Status Extension/pt-BR.lproj/MainInterface.strings +++ b/Loop Status Extension/pt-BR.lproj/MainInterface.strings @@ -1,6 +1,6 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Eventualmente 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Carboidratos Ativos"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Insulina Ativa"; diff --git a/Loop Status Extension/ro.lproj/InfoPlist.strings b/Loop Status Extension/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..811f60ffd2 --- /dev/null +++ b/Loop Status Extension/ro.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Extensie stare Loop"; + diff --git a/Loop Status Extension/ro.lproj/Localizable.strings b/Loop Status Extension/ro.lproj/Localizable.strings index 177cf6e0c5..e749a36e8e 100644 --- a/Loop Status Extension/ro.lproj/Localizable.strings +++ b/Loop Status Extension/ro.lproj/Localizable.strings @@ -1,6 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? U"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Carbohidrați activi"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Insulină activă"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Eventually %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@%2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/ro.lproj/MainInterface.strings b/Loop Status Extension/ro.lproj/MainInterface.strings index 3eb5d43c9e..52df0e4c8c 100644 --- a/Loop Status Extension/ro.lproj/MainInterface.strings +++ b/Loop Status Extension/ro.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Eventually 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Carbohidrați activi"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Insulină activă"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 U"; diff --git a/Loop Status Extension/ru.lproj/InfoPlist.strings b/Loop Status Extension/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1565e025fa --- /dev/null +++ b/Loop Status Extension/ru.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status Extension"; + diff --git a/Loop Status Extension/ru.lproj/Localizable.strings b/Loop Status Extension/ru.lproj/Localizable.strings index 1049e0663e..319107dd52 100644 --- a/Loop Status Extension/ru.lproj/Localizable.strings +++ b/Loop Status Extension/ru.lproj/Localizable.strings @@ -1,6 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? г"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? ед."; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ Ед."; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ против %2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Активные углеводы"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Активный инсулин"; + +/* The short unit display string for decibles */ +"dB" = "дБ"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "В конечном итоге %1$@"; +/* The short unit display string for grams */ +"g" = "г"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ ед"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "мг/дл"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "ед"; + diff --git a/Loop Status Extension/ru.lproj/MainInterface.strings b/Loop Status Extension/ru.lproj/MainInterface.strings index ac17fcfd98..7a44069cbe 100644 --- a/Loop Status Extension/ru.lproj/MainInterface.strings +++ b/Loop Status Extension/ru.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "в конечном итоге 92 мг/дл"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Активные углеводы"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 ед"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 г"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Активный инсулин"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 ед."; diff --git a/Loop Status Extension/sk.lproj/InfoPlist.strings b/Loop Status Extension/sk.lproj/InfoPlist.strings new file mode 100644 index 0000000000..034a1e1f6a --- /dev/null +++ b/Loop Status Extension/sk.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + diff --git a/Loop Status Extension/sk.lproj/Localizable.strings b/Loop Status Extension/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..f7fe0850f1 --- /dev/null +++ b/Loop Status Extension/sk.lproj/Localizable.strings @@ -0,0 +1,42 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? j"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%@ j"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Aktívne sacharidy"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Aktívny inzulín"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"IOB %1$@ U" = "IOB %1$@ j"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + diff --git a/Loop Status Extension/sk.lproj/MainInterface.strings b/Loop Status Extension/sk.lproj/MainInterface.strings new file mode 100644 index 0000000000..e249f99412 --- /dev/null +++ b/Loop Status Extension/sk.lproj/MainInterface.strings @@ -0,0 +1,12 @@ +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Aktívne sacharidy"; + +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Aktívny inzulín"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 j"; + diff --git a/Loop Status Extension/sv.lproj/InfoPlist.strings b/Loop Status Extension/sv.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1565e025fa --- /dev/null +++ b/Loop Status Extension/sv.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Status Extension"; + diff --git a/Loop Status Extension/sv.lproj/Localizable.strings b/Loop Status Extension/sv.lproj/Localizable.strings index ec07cf13d5..fb3f8b00e7 100644 --- a/Loop Status Extension/sv.lproj/Localizable.strings +++ b/Loop Status Extension/sv.lproj/Localizable.strings @@ -1,9 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? g"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? E"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Aktiva kolhydrater"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Aktivt insulin"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Förväntat %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ E"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The short unit display string for international units of insulin */ "U" = "E"; diff --git a/Loop Status Extension/sv.lproj/MainInterface.strings b/Loop Status Extension/sv.lproj/MainInterface.strings index d826dbc61a..afc966ed37 100644 --- a/Loop Status Extension/sv.lproj/MainInterface.strings +++ b/Loop Status Extension/sv.lproj/MainInterface.strings @@ -1,6 +1,12 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Förväntat 5,1 mmol/l"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Aktiva kolhydrater"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 E"; +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 g"; + +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Aktivt insulin"; + +/* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ +"Vgf-p1-2QP.text" = "0 E"; diff --git a/Loop Status Extension/tr.lproj/InfoPlist.strings b/Loop Status Extension/tr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..a67e46ff7e --- /dev/null +++ b/Loop Status Extension/tr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Bundle name */ +"CFBundleName" = "Loop Durum Uzantısı"; + diff --git a/Loop Status Extension/tr.lproj/Localizable.strings b/Loop Status Extension/tr.lproj/Localizable.strings index d21551845d..0f5ebe9125 100644 --- a/Loop Status Extension/tr.lproj/Localizable.strings +++ b/Loop Status Extension/tr.lproj/Localizable.strings @@ -1,5 +1,45 @@ +/* Displayed in the widget when the amount of active carbs cannot be determined. */ +"? g" = "? gr"; + +/* Displayed in the widget when the amount of active insulin cannot be determined. */ +"? U" = "? Ü"; + +/* The subtitle format describing the grams of active carbs. (1: localized carb value description) */ +"%1$@" = "%1$@"; + +/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ +"%1$@ U" = "%1$@ Ü"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Aktif Karb."; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Aktif İnsülin"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %1$@" = "Eventually %1$@"; +"Eventually %1$@" = "Nihai KŞ %1$@"; + +/* The short unit display string for grams */ +"g" = "gr"; /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ -"IOB %1$@ U" = "IOB %1$@ U"; +"IOB %1$@ U" = "AİNS %1$@ Ü"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "Ü"; + diff --git a/Loop Status Extension/tr.lproj/MainInterface.strings b/Loop Status Extension/tr.lproj/MainInterface.strings index 25ea93a823..de7b3fc545 100644 --- a/Loop Status Extension/tr.lproj/MainInterface.strings +++ b/Loop Status Extension/tr.lproj/MainInterface.strings @@ -1,12 +1,12 @@ - /* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Active Carbs"; +"9iF-xY-Bh4.text" = "Aktif Karb."; + +/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ +"dPp-lJ-5sh.text" = "0 gr"; /* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "Active Insulin"; +"UPi-dG-yYD.text" = "Aktif İnsülin"; /* Class = "UILabel"; text = "0 U"; ObjectID = "Vgf-p1-2QP"; */ -"Vgf-p1-2QP.text" = "0 U"; +"Vgf-p1-2QP.text" = "0 Ü"; -/* Class = "UILabel"; text = "0 g"; ObjectID = "dPp-lJ-5sh"; */ -"dPp-lJ-5sh.text" = "0 g"; diff --git a/Loop Status Extension/vi.lproj/InfoPlist.strings b/Loop Status Extension/vi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..034a1e1f6a --- /dev/null +++ b/Loop Status Extension/vi.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + diff --git a/Loop Status Extension/vi.lproj/Localizable.strings b/Loop Status Extension/vi.lproj/Localizable.strings index 471ea04c90..a0b94d6a7f 100644 --- a/Loop Status Extension/vi.lproj/Localizable.strings +++ b/Loop Status Extension/vi.lproj/Localizable.strings @@ -1,6 +1,33 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Widget label title describing the active carbs */ +"Active Carbs" = "Lượng Carbs còn hoạt động"; + +/* Widget label title describing the active insulin */ +"Active Insulin" = "Lượng Insulin còn hoạt động"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %1$@" = "Kết quả là %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The subtitle format describing units of active insulin. (1: localized insulin value description) */ "IOB %1$@ U" = "IOB %1$@ U"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Loop Status Extension/vi.lproj/MainInterface.strings b/Loop Status Extension/vi.lproj/MainInterface.strings index 66ec8fb074..c766b97e1b 100644 --- a/Loop Status Extension/vi.lproj/MainInterface.strings +++ b/Loop Status Extension/vi.lproj/MainInterface.strings @@ -1,6 +1,6 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ -"9iF-xY-Bh4.text" = "Kết quả là 92 mg/dL"; +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ +"9iF-xY-Bh4.text" = "Lượng Carbs còn hoạt động"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ -"UPi-dG-yYD.text" = "IOB 1.0 U"; +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ +"UPi-dG-yYD.text" = "Lượng Insulin còn hoạt động"; diff --git a/Loop Status Extension/zh-Hans.lproj/MainInterface.strings b/Loop Status Extension/zh-Hans.lproj/MainInterface.strings index c315a458c2..2a063e6084 100644 --- a/Loop Status Extension/zh-Hans.lproj/MainInterface.strings +++ b/Loop Status Extension/zh-Hans.lproj/MainInterface.strings @@ -1,6 +1,6 @@ -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "9iF-xY-Bh4"; */ +/* Class = "UILabel"; text = "Active Carbs"; ObjectID = "9iF-xY-Bh4"; */ "9iF-xY-Bh4.text" = "最终血糖为92 毫克/分升"; -/* Class = "UILabel"; text = "IOB 1.0 U"; ObjectID = "UPi-dG-yYD"; */ +/* Class = "UILabel"; text = "Active Insulin"; ObjectID = "UPi-dG-yYD"; */ "UPi-dG-yYD.text" = "IOB 1.0 单位"; diff --git a/Loop.xcconfig b/Loop.xcconfig index af9e83470a..9e1bb856ae 100644 --- a/Loop.xcconfig +++ b/Loop.xcconfig @@ -43,7 +43,10 @@ LOOP_PROVISIONING_PROFILE_SPECIFIER_WATCHAPP_RELEASE = LOOP_PROVISIONING_PROFILE_SPECIFIER_WATCHAPP_EXTENSION_RELEASE = // Min iOS Version [DEFAULT] -IPHONEOS_DEPLOYMENT_TARGET = 14.1 +IPHONEOS_DEPLOYMENT_TARGET = 15.1 + +// Base string for opening app via URL [DEFAULT] +URL_SCHEME_NAME = $(MAIN_APP_DISPLAY_NAME) // Version [DEFAULT] #include? "Version.xcconfig" diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index f220c9c11d..52137df99d 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -85,11 +85,8 @@ 4344629820A8B2D700C4BE6F /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4374B5EE209D84BE00D17AA8 /* OSLog.swift */; }; 4345E3F421F036FC009E00E5 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D848AF1E7DCBE100DADCBC /* Result.swift */; }; 4345E3F521F036FC009E00E5 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D848AF1E7DCBE100DADCBC /* Result.swift */; }; - 4345E3F821F03D2A009E00E5 /* DatesAndNumberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345E3F721F03D2A009E00E5 /* DatesAndNumberCell.swift */; }; - 4345E3FA21F0473B009E00E5 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345E3F921F0473B009E00E5 /* TextCell.swift */; }; 4345E3FB21F04911009E00E5 /* UIColor+HIG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BFF0C31E4659E700FF19A9 /* UIColor+HIG.swift */; }; 4345E3FC21F04911009E00E5 /* UIColor+HIG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BFF0C31E4659E700FF19A9 /* UIColor+HIG.swift */; }; - 4345E3FE21F04A50009E00E5 /* DateIntervalFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345E3FD21F04A50009E00E5 /* DateIntervalFormatter.swift */; }; 4345E3FF21F051C6009E00E5 /* LoopCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; }; 4345E40021F051DD009E00E5 /* LoopCore.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4345E40121F67300009E00E5 /* PotentialCarbEntryUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DE92581C5479E4001FFDE1 /* PotentialCarbEntryUserInfo.swift */; }; @@ -157,29 +154,15 @@ 43C05CAC21EB2B8B006FB252 /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58D1D4AEC230097D1CA /* NSBundle.swift */; }; 43C05CAD21EB2BBF006FB252 /* NSUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430B29892041F54A00BA9F93 /* NSUserDefaults.swift */; }; 43C05CAF21EB2C24006FB252 /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58D1D4AEC230097D1CA /* NSBundle.swift */; }; - 43C05CB121EBBDB9006FB252 /* TimeInRangeLesson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CB021EBBDB9006FB252 /* TimeInRangeLesson.swift */; }; 43C05CB221EBD88A006FB252 /* LoopCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9002A21EB209400AF44BF /* LoopCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 43C05CB521EBE274006FB252 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CB421EBE274006FB252 /* Date.swift */; }; - 43C05CB621EBE321006FB252 /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; }; 43C05CB821EBEA54006FB252 /* HKUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CB721EBEA54006FB252 /* HKUnit.swift */; }; 43C05CB921EBEA54006FB252 /* HKUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CB721EBEA54006FB252 /* HKUnit.swift */; }; - 43C05CBD21EBF77D006FB252 /* LessonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CBC21EBF77D006FB252 /* LessonsViewController.swift */; }; - 43C05CC021EBFFA4006FB252 /* Lesson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CBF21EBFFA4006FB252 /* Lesson.swift */; }; - 43C05CC221EC06E4006FB252 /* LessonConfigurationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CC121EC06E4006FB252 /* LessonConfigurationViewController.swift */; }; 43C05CC521EC29E3006FB252 /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4374B5F3209D89A900D17AA8 /* TextFieldTableViewCell.swift */; }; - 43C05CC621EC29E7006FB252 /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4374B5F3209D89A900D17AA8 /* TextFieldTableViewCell.swift */; }; 43C05CC721EC2ABC006FB252 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1E91CF26C29000DB779 /* IdentifiableClass.swift */; }; 43C05CC821EC2ABC006FB252 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1E91CF26C29000DB779 /* IdentifiableClass.swift */; }; - 43C05CCA21EC382B006FB252 /* NumberEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C05CC921EC382B006FB252 /* NumberEntry.swift */; }; 43C0944A1CACCC73001F6403 /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C094491CACCC73001F6403 /* NotificationManager.swift */; }; 43C2FAE11EB656A500364AFF /* GlucoseEffectVelocity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C2FAE01EB656A500364AFF /* GlucoseEffectVelocity.swift */; }; 43C513191E864C4E001547C7 /* GlucoseRangeSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C513181E864C4E001547C7 /* GlucoseRangeSchedule.swift */; }; - 43C5F257222C7B7200905D10 /* TimeComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C5F256222C7B7200905D10 /* TimeComponents.swift */; }; - 43C5F258222C7BD400905D10 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9FFA421EA9A0C00AF44BF /* AppDelegate.swift */; }; - 43C5F25A222C921B00905D10 /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C5F259222C921B00905D10 /* OSLog.swift */; }; - 43C728F5222266F000C62969 /* ModalDayLesson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C728F4222266F000C62969 /* ModalDayLesson.swift */; }; - 43C728F72222700000C62969 /* DateIntervalEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C728F62222700000C62969 /* DateIntervalEntry.swift */; }; - 43C728F9222A448700C62969 /* DayCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C728F8222A448700C62969 /* DayCalculator.swift */; }; 43CB2B2B1D924D450079823D /* WCSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CB2B2A1D924D450079823D /* WCSession.swift */; }; 43CE7CDE1CA8B63E003CC1B0 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CE7CDD1CA8B63E003CC1B0 /* Data.swift */; }; 43D381621EBD9759007F8C8F /* HeaderValuesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D381611EBD9759007F8C8F /* HeaderValuesTableViewCell.swift */; }; @@ -187,29 +170,11 @@ 43D9002021EB209400AF44BF /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; }; 43D9002D21EB225D00AF44BF /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9002C21EB225D00AF44BF /* HealthKit.framework */; }; 43D9002F21EB234400AF44BF /* LoopCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9002A21EB209400AF44BF /* LoopCore.framework */; }; - 43D9F81821EC51CC000578CD /* DateEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9F81721EC51CC000578CD /* DateEntry.swift */; }; - 43D9F81A21EC593C000578CD /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9F81921EC593C000578CD /* UITableViewCell.swift */; }; - 43D9F81E21EF0609000578CD /* NumberRangeEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9F81D21EF0609000578CD /* NumberRangeEntry.swift */; }; - 43D9F82021EF0906000578CD /* NSNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9F81F21EF0906000578CD /* NSNumber.swift */; }; - 43D9F82221EF0A7A000578CD /* QuantityRangeEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9F82121EF0A7A000578CD /* QuantityRangeEntry.swift */; }; - 43D9F82421EFF1AB000578CD /* LessonResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9F82321EFF1AB000578CD /* LessonResultsViewController.swift */; }; - 43D9FFAA21EA9A0C00AF44BF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43D9FFA821EA9A0C00AF44BF /* Main.storyboard */; }; - 43D9FFAC21EA9A0F00AF44BF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43D9FFAB21EA9A0F00AF44BF /* Assets.xcassets */; }; - 43D9FFAF21EA9A0F00AF44BF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43D9FFAD21EA9A0F00AF44BF /* LaunchScreen.storyboard */; }; - 43D9FFB421EA9AD800AF44BF /* LoopUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F75288B1DFE1DC600C322D6 /* LoopUI.framework */; }; - 43D9FFB621EA9B2F00AF44BF /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F5C2C81B929C09003EB13D /* HealthKit.framework */; }; - 43D9FFBB21EA9CC900AF44BF /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F78D4B1C914197002152D1 /* LoopKit.framework */; }; - 43D9FFBC21EA9CCD00AF44BF /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 437AFEE6203688CF008C4892 /* LoopKitUI.framework */; }; - 43D9FFC021EAB22E00AF44BF /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D9FFBF21EAB22E00AF44BF /* DataManager.swift */; }; 43D9FFD321EAE05D00AF44BF /* LoopCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 43D9FFD121EAE05D00AF44BF /* LoopCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43D9FFD621EAE05D00AF44BF /* LoopCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; }; 43D9FFD721EAE05D00AF44BF /* LoopCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 43D9FFDE21EAE3AE00AF44BF /* LoopCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; }; - 43D9FFE021EAE3E500AF44BF /* LoopUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4F75288B1DFE1DC600C322D6 /* LoopUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 43D9FFE121EAE3E500AF44BF /* LoopCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 43D9FFFB21EAF3D300AF44BF /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; }; 43DBF0531C93EC8200B3C386 /* DeviceDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DBF0521C93EC8200B3C386 /* DeviceDataManager.swift */; }; - 43DBF0591C93F73800B3C386 /* CarbEntryTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DBF0581C93F73800B3C386 /* CarbEntryTableViewController.swift */; }; 43DFB62320D4CAE7008A7BAE /* PumpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C3B6F620BBCAA30026CAFA /* PumpManager.swift */; }; 43E2D8D41D20BF42004DA55F /* DoseMathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E2D8D31D20BF42004DA55F /* DoseMathTests.swift */; }; 43E2D8DB1D20C03B004DA55F /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; }; @@ -296,6 +261,7 @@ 4FF4D0F81E1725B000846527 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434F54561D287FDB002A9274 /* NibLoadable.swift */; }; 4FF4D1001E18374700846527 /* WatchContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF4D0FF1E18374700846527 /* WatchContext.swift */; }; 4FF4D1011E18375000846527 /* WatchContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF4D0FF1E18374700846527 /* WatchContext.swift */; }; + 63F5E17C297DDF3900A62D4B /* ckcomplication.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63F5E17A297DDF3900A62D4B /* ckcomplication.strings */; }; 7D23667D21250C7E0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D23667C21250C7E0028B67D /* LocalizedString.swift */; }; 7D7076351FE06EDE004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076371FE06EDE004AC8EA /* Localizable.strings */; }; 7D7076451FE06EE0004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076471FE06EE0004AC8EA /* InfoPlist.strings */; }; @@ -304,8 +270,6 @@ 7D7076591FE06EE2004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70765B1FE06EE2004AC8EA /* Localizable.strings */; }; 7D70765E1FE06EE3004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076601FE06EE3004AC8EA /* Localizable.strings */; }; 7D7076631FE06EE4004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076651FE06EE4004AC8EA /* Localizable.strings */; }; - 7D9BEEF32335CF8D005DCFD6 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D9BEEF52335CF8D005DCFD6 /* Localizable.strings */; }; - 80F864E62433BF5D0026EC26 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 80F864E42433BF5D0026EC26 /* InfoPlist.strings */; }; 891B508524342BE1005DA578 /* CarbAndBolusFlowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891B508424342BE1005DA578 /* CarbAndBolusFlowViewModel.swift */; }; 892A5D59222F0A27008961AB /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A5D58222F0A27008961AB /* Debug.swift */; }; 892A5D692230C41D008961AB /* RangeReplaceableCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A5D682230C41D008961AB /* RangeReplaceableCollection.swift */; }; @@ -390,6 +354,12 @@ A98556852493F901000FD662 /* AlertStore+SimulatedCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98556842493F901000FD662 /* AlertStore+SimulatedCoreData.swift */; }; A987CD4924A58A0100439ADC /* ZipArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = A987CD4824A58A0100439ADC /* ZipArchive.swift */; }; A999D40624663D18004C89D4 /* PumpManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A999D40524663D18004C89D4 /* PumpManagerError.swift */; }; + A99A114229A581F4007919CE /* BolusAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114129A581F4007919CE /* BolusAction.swift */; }; + A99A114429A5829A007919CE /* CarbAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114329A5829A007919CE /* CarbAction.swift */; }; + A99A114629A582A2007919CE /* OverrideAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114529A582A2007919CE /* OverrideAction.swift */; }; + A99A114E29A5879D007919CE /* BolusActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114B29A5879C007919CE /* BolusActionTests.swift */; }; + A99A114F29A5879D007919CE /* CarbActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114C29A5879C007919CE /* CarbActionTests.swift */; }; + A99A115029A5879D007919CE /* OverrideActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A99A114D29A5879C007919CE /* OverrideActionTests.swift */; }; A9A056B324B93C62007CF06D /* CriticalEventLogExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A056B224B93C62007CF06D /* CriticalEventLogExportView.swift */; }; A9A056B524B94123007CF06D /* CriticalEventLogExportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A056B424B94123007CF06D /* CriticalEventLogExportViewModel.swift */; }; A9A63F8E246B271600588D5B /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; }; @@ -413,7 +383,6 @@ A9DF02CB24F72B9E00B7C988 /* CriticalEventLogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DF02CA24F72B9E00B7C988 /* CriticalEventLogTests.swift */; }; A9DFAFB324F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DFAFB224F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift */; }; A9DFAFB524F048A000950D1E /* WatchHistoricalCarbsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DFAFB424F048A000950D1E /* WatchHistoricalCarbsTests.swift */; }; - A9E8A80528A7CAC000C0A8A4 /* RemoteCommandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E8A80428A7CAC000C0A8A4 /* RemoteCommandTests.swift */; }; A9F5F1F5251050EC00E7C8A4 /* ZipArchiveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F5F1F4251050EC00E7C8A4 /* ZipArchiveTests.swift */; }; A9F66FC3247F451500096EA7 /* UIDevice+Loop.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F66FC2247F451500096EA7 /* UIDevice+Loop.swift */; }; A9F703732489BC8500C98AD8 /* CarbStore+SimulatedCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F703722489BC8500C98AD8 /* CarbStore+SimulatedCoreData.swift */; }; @@ -456,7 +425,12 @@ B4E96D5D248A82A2002DABAD /* StatusBarHUDView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B4E96D5C248A82A2002DABAD /* StatusBarHUDView.xib */; }; B4F3D25124AF890C0095CE44 /* BluetoothStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4F3D25024AF890C0095CE44 /* BluetoothStateManager.swift */; }; B4FEEF7D24B8A71F00A8DF9B /* DeviceDataManager+DeviceStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FEEF7C24B8A71F00A8DF9B /* DeviceDataManager+DeviceStatus.swift */; }; + C1004DF22981F5B700B8CF94 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1004DF02981F5B700B8CF94 /* InfoPlist.strings */; }; + C1004DF52981F5B700B8CF94 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1004DF32981F5B700B8CF94 /* Localizable.strings */; }; + C1004DF82981F5B700B8CF94 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1004DF62981F5B700B8CF94 /* InfoPlist.strings */; }; C10B28461EA9BA5E006EA1FC /* far_future_high_bg_forecast.json in Resources */ = {isa = PBXBuildFile; fileRef = C10B28451EA9BA5E006EA1FC /* far_future_high_bg_forecast.json */; }; + C11613492983096D00777E7C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C11613472983096D00777E7C /* InfoPlist.strings */; }; + C116134C2983096D00777E7C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C116134A2983096D00777E7C /* Localizable.strings */; }; C11B9D5B286778A800500CF8 /* SwiftCharts in Frameworks */ = {isa = PBXBuildFile; productRef = C11B9D5A286778A800500CF8 /* SwiftCharts */; }; C11B9D5E286778D000500CF8 /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C11B9D5D286778D000500CF8 /* LoopKitUI.framework */; }; C11B9D62286779C000500CF8 /* MockKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C11B9D60286779C000500CF8 /* MockKit.framework */; }; @@ -483,7 +457,6 @@ C16575752539FD60004AE16E /* LoopCoreConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16575742539FD60004AE16E /* LoopCoreConstants.swift */; }; C16575762539FEF3004AE16E /* LoopCoreConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16575742539FD60004AE16E /* LoopCoreConstants.swift */; }; C1657578253A0021004AE16E /* ChartConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1657577253A0021004AE16E /* ChartConstants.swift */; }; - C165B8CE23302C5D0004112E /* RemoteCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C165B8CD23302C5D0004112E /* RemoteCommand.swift */; }; C16B983E26B4893300256B05 /* DoseEnactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16B983D26B4893300256B05 /* DoseEnactor.swift */; }; C16B984026B4898800256B05 /* DoseEnactorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16B983F26B4898800256B05 /* DoseEnactorTests.swift */; }; C16DA84222E8E112008624C2 /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16DA84122E8E112008624C2 /* PluginManager.swift */; }; @@ -497,7 +470,6 @@ C17824A61E1AF91F00D9D25C /* ManualBolusRecommendation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17824A41E1AD4D100D9D25C /* ManualBolusRecommendation.swift */; }; C17DDC9C28AC339E005FBF4C /* PersistedProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DA986B2843B6F9001D04CC /* PersistedProperty.swift */; }; C17DDC9D28AC33A1005FBF4C /* PersistedProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DA986B2843B6F9001D04CC /* PersistedProperty.swift */; }; - C1814B86225E507C008D2D8E /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1814B85225E507C008D2D8E /* Sequence.swift */; }; C18913B52524F24C007B0683 /* DeviceDataManager+SimpleBolusViewModelDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18913B42524F24C007B0683 /* DeviceDataManager+SimpleBolusViewModelDelegate.swift */; }; C19008FE25225D3900721625 /* SimpleBolusCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19008FD25225D3900721625 /* SimpleBolusCalculator.swift */; }; C1900900252271BB00721625 /* SimpleBolusCalculatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19008FF252271BB00721625 /* SimpleBolusCalculatorTests.swift */; }; @@ -521,11 +493,14 @@ C19E96E023D275FA003F79B0 /* LoopCompletionFreshness.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19E96DD23D2733F003F79B0 /* LoopCompletionFreshness.swift */; }; C19F48742560ABFB003632D7 /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58D1D4AEC230097D1CA /* NSBundle.swift */; }; C1AD4200256D61E500164DDD /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1AD41FF256D61E500164DDD /* Comparable.swift */; }; + C1AF062329426300002C1B19 /* ManualGlucoseEntryRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1AF062229426300002C1B19 /* ManualGlucoseEntryRow.swift */; }; C1C6591C1E1B1FDA0025CC58 /* recommend_temp_basal_dropping_then_rising.json in Resources */ = {isa = PBXBuildFile; fileRef = C1C6591B1E1B1FDA0025CC58 /* recommend_temp_basal_dropping_then_rising.json */; }; C1C660D1252E4DD5009B5C32 /* LoopConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C660D0252E4DD5009B5C32 /* LoopConstants.swift */; }; C1C73F0D1DE3D0270022FC89 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1C73F0F1DE3D0270022FC89 /* InfoPlist.strings */; }; C1CCF1122858FA900035389C /* LoopCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */; }; C1CCF1172858FBAD0035389C /* SwiftCharts in Frameworks */ = {isa = PBXBuildFile; productRef = C1CCF1162858FBAD0035389C /* SwiftCharts */; }; + C1D0B6302986D4D90098D215 /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D0B62F2986D4D90098D215 /* LocalizedString.swift */; }; + C1D0B6312986D4D90098D215 /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D0B62F2986D4D90098D215 /* LocalizedString.swift */; }; C1D289B522F90A52003FFBD9 /* BasalDeliveryState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D289B422F90A52003FFBD9 /* BasalDeliveryState.swift */; }; C1DE5D23251BFC4D00439E49 /* SimpleBolusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DE5D22251BFC4D00439E49 /* SimpleBolusView.swift */; }; C1E2773E224177C000354103 /* ClockKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1E2773D224177C000354103 /* ClockKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; @@ -582,6 +557,7 @@ E942DE96253BE68F00AC532D /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58D1D4AEC230097D1CA /* NSBundle.swift */; }; E942DE9F253BE6A900AC532D /* NSTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897341CD2F7DE00223065 /* NSTimeInterval.swift */; }; E942DF34253BF87F00AC532D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 43785E9B2120E7060057DED1 /* Intents.intentdefinition */; }; + E950CA9129002D9000B5B692 /* LoopDataManagerDosingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E950CA9029002D9000B5B692 /* LoopDataManagerDosingTests.swift */; }; E95D380124EADE7C005E2F50 /* DoseStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95D380024EADE7C005E2F50 /* DoseStoreProtocol.swift */; }; E95D380324EADF36005E2F50 /* CarbStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95D380224EADF36005E2F50 /* CarbStoreProtocol.swift */; }; E95D380524EADF78005E2F50 /* GlucoseStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E95D380424EADF78005E2F50 /* GlucoseStoreProtocol.swift */; }; @@ -599,6 +575,18 @@ E9B08021253BBDE900BAD8F8 /* IntentExtensionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B08020253BBDE900BAD8F8 /* IntentExtensionInfo.swift */; }; E9B0802B253BBDFF00BAD8F8 /* IntentExtensionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B08020253BBDE900BAD8F8 /* IntentExtensionInfo.swift */; }; E9B080B1253BDA6300BAD8F8 /* UserDefaults+LoopIntents.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B08015253BBD7300BAD8F8 /* UserDefaults+LoopIntents.swift */; }; + E9B3552229358C440076AB04 /* MealDetectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B3552129358C440076AB04 /* MealDetectionManager.swift */; }; + E9B355292935919E0076AB04 /* MissedMealSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B35525293590980076AB04 /* MissedMealSettings.swift */; }; + E9B3552A293591E70076AB04 /* MissedMealNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B3551B292844010076AB04 /* MissedMealNotification.swift */; }; + E9B3552B293591E70076AB04 /* MissedMealNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B3551B292844010076AB04 /* MissedMealNotification.swift */; }; + E9B3552D293592B40076AB04 /* MealDetectionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B3552C293592B40076AB04 /* MealDetectionManagerTests.swift */; }; + E9B3552F2935968E0076AB04 /* HKHealthStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B3552E2935968E0076AB04 /* HKHealthStoreMock.swift */; }; + E9B35538293706CB0076AB04 /* needs_clamping_counteraction_effect.json in Resources */ = {isa = PBXBuildFile; fileRef = E9B35532293706CA0076AB04 /* needs_clamping_counteraction_effect.json */; }; + E9B35539293706CB0076AB04 /* dynamic_autofill_counteraction_effect.json in Resources */ = {isa = PBXBuildFile; fileRef = E9B35533293706CA0076AB04 /* dynamic_autofill_counteraction_effect.json */; }; + E9B3553A293706CB0076AB04 /* missed_meal_counteraction_effect.json in Resources */ = {isa = PBXBuildFile; fileRef = E9B35534293706CB0076AB04 /* missed_meal_counteraction_effect.json */; }; + E9B3553B293706CB0076AB04 /* noisy_cgm_counteraction_effect.json in Resources */ = {isa = PBXBuildFile; fileRef = E9B35535293706CB0076AB04 /* noisy_cgm_counteraction_effect.json */; }; + E9B3553C293706CB0076AB04 /* realistic_report_counteraction_effect.json in Resources */ = {isa = PBXBuildFile; fileRef = E9B35536293706CB0076AB04 /* realistic_report_counteraction_effect.json */; }; + E9B3553D293706CB0076AB04 /* long_interval_counteraction_effect.json in Resources */ = {isa = PBXBuildFile; fileRef = E9B35537293706CB0076AB04 /* long_interval_counteraction_effect.json */; }; E9BB27AB23B85C3500FB4987 /* SleepStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9BB27AA23B85C3500FB4987 /* SleepStore.swift */; }; E9C00EF224C6221B00628F35 /* LoopSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C00EEF24C620EF00628F35 /* LoopSettings.swift */; }; E9C00EF324C6222400628F35 /* LoopSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C00EEF24C620EF00628F35 /* LoopSettings.swift */; }; @@ -641,13 +629,6 @@ remoteGlobalIDString = 43A943711B926B7B0051FA24; remoteInfo = WatchApp; }; - 43D9FFB921EA9CA400AF44BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 43776F841B8022E90074EA36 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4F75288A1DFE1DC600C322D6; - remoteInfo = LoopUI; - }; 43D9FFD421EAE05D00AF44BF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 43776F841B8022E90074EA36 /* Project object */; @@ -683,13 +664,6 @@ remoteGlobalIDString = 43D9FFCE21EAE05D00AF44BF; remoteInfo = LoopCore; }; - A942E446225FD9A300DD4980 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 43776F841B8022E90074EA36 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 43D9FFCE21EAE05D00AF44BF; - remoteInfo = LoopCore; - }; C117ED70232EDB3200DA57CD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 43776F841B8022E90074EA36 /* Project object */; @@ -776,18 +750,6 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - 43D9FFDF21EAE3C600AF44BF /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 43D9FFE021EAE3E500AF44BF /* LoopUI.framework in Embed Frameworks */, - 43D9FFE121EAE3E500AF44BF /* LoopCore.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; 43E2D8DD1D20C072004DA55F /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -990,11 +952,9 @@ 43D9F81F21EF0906000578CD /* NSNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSNumber.swift; sourceTree = ""; }; 43D9F82121EF0A7A000578CD /* QuantityRangeEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuantityRangeEntry.swift; sourceTree = ""; }; 43D9F82321EFF1AB000578CD /* LessonResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonResultsViewController.swift; sourceTree = ""; }; - 43D9FFA221EA9A0C00AF44BF /* Learn.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Learn.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43D9FFA421EA9A0C00AF44BF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 43D9FFA921EA9A0C00AF44BF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 43D9FFAB21EA9A0F00AF44BF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 43D9FFAE21EA9A0F00AF44BF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 43D9FFB021EA9A0F00AF44BF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43D9FFB521EA9B0100AF44BF /* Learn.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Learn.entitlements; sourceTree = ""; }; 43D9FFBF21EAB22E00AF44BF /* DataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManager.swift; sourceTree = ""; }; @@ -1002,7 +962,6 @@ 43D9FFD121EAE05D00AF44BF /* LoopCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoopCore.h; sourceTree = ""; }; 43D9FFD221EAE05D00AF44BF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43DBF0521C93EC8200B3C386 /* DeviceDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DeviceDataManager.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - 43DBF0581C93F73800B3C386 /* CarbEntryTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarbEntryTableViewController.swift; sourceTree = ""; }; 43DE92581C5479E4001FFDE1 /* PotentialCarbEntryUserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PotentialCarbEntryUserInfo.swift; sourceTree = ""; }; 43E2D8D11D20BF42004DA55F /* DoseMathTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DoseMathTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 43E2D8D31D20BF42004DA55F /* DoseMathTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoseMathTests.swift; sourceTree = ""; }; @@ -1075,6 +1034,7 @@ 4FDDD23620DC51DF00D04B16 /* LoopDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopDataManager.swift; sourceTree = ""; }; 4FF4D0FF1E18374700846527 /* WatchContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatchContext.swift; sourceTree = ""; }; 4FFEDFBE20E5CF22000BFC58 /* ChartHUDController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartHUDController.swift; sourceTree = ""; }; + 63F5E17B297DDF3900A62D4B /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/ckcomplication.strings; sourceTree = ""; }; 7D199D93212A067600241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Main.strings; sourceTree = ""; }; 7D199D94212A067600241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/MainInterface.strings; sourceTree = ""; }; 7D199D95212A067600241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Interface.strings; sourceTree = ""; }; @@ -1381,6 +1341,12 @@ A98556842493F901000FD662 /* AlertStore+SimulatedCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AlertStore+SimulatedCoreData.swift"; sourceTree = ""; }; A987CD4824A58A0100439ADC /* ZipArchive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = ""; }; A999D40524663D18004C89D4 /* PumpManagerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpManagerError.swift; sourceTree = ""; }; + A99A114129A581F4007919CE /* BolusAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusAction.swift; sourceTree = ""; }; + A99A114329A5829A007919CE /* CarbAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbAction.swift; sourceTree = ""; }; + A99A114529A582A2007919CE /* OverrideAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideAction.swift; sourceTree = ""; }; + A99A114B29A5879C007919CE /* BolusActionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusActionTests.swift; sourceTree = ""; }; + A99A114C29A5879C007919CE /* CarbActionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarbActionTests.swift; sourceTree = ""; }; + A99A114D29A5879C007919CE /* OverrideActionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverrideActionTests.swift; sourceTree = ""; }; A9A056B224B93C62007CF06D /* CriticalEventLogExportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogExportView.swift; sourceTree = ""; }; A9A056B424B94123007CF06D /* CriticalEventLogExportViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogExportViewModel.swift; sourceTree = ""; }; A9B607AF247F000F00792BE4 /* UserNotifications+Loop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserNotifications+Loop.swift"; sourceTree = ""; }; @@ -1402,7 +1368,6 @@ A9DF02CA24F72B9E00B7C988 /* CriticalEventLogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogTests.swift; sourceTree = ""; }; A9DFAFB224F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbBackfillRequestUserInfoTests.swift; sourceTree = ""; }; A9DFAFB424F048A000950D1E /* WatchHistoricalCarbsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchHistoricalCarbsTests.swift; sourceTree = ""; }; - A9E8A80428A7CAC000C0A8A4 /* RemoteCommandTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteCommandTests.swift; sourceTree = ""; }; A9F5F1F4251050EC00E7C8A4 /* ZipArchiveTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipArchiveTests.swift; sourceTree = ""; }; A9F66FC2247F451500096EA7 /* UIDevice+Loop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Loop.swift"; sourceTree = ""; }; A9F703722489BC8500C98AD8 /* CarbStore+SimulatedCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarbStore+SimulatedCoreData.swift"; sourceTree = ""; }; @@ -1439,14 +1404,99 @@ B4E96D5C248A82A2002DABAD /* StatusBarHUDView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusBarHUDView.xib; sourceTree = ""; }; B4F3D25024AF890C0095CE44 /* BluetoothStateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothStateManager.swift; sourceTree = ""; }; B4FEEF7C24B8A71F00A8DF9B /* DeviceDataManager+DeviceStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DeviceDataManager+DeviceStatus.swift"; sourceTree = ""; }; + C1004DEF2981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DF12981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DF42981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; + C1004DF72981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DF92981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; + C1004DFA2981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DFB2981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DFC2981F5B700B8CF94 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DFD2981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DFE2981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004DFF2981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; + C1004E002981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E012981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; + C1004E022981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E032981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E042981F67A00B8CF94 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E052981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E062981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E072981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; + C1004E082981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E092981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; + C1004E0A2981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E0B2981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E0C2981F6A100B8CF94 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E0D2981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E0E2981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E0F2981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + C1004E102981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E112981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + C1004E122981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E132981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E142981F6E200B8CF94 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E152981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E162981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E172981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + C1004E182981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E192981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + C1004E1A2981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E1B2981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E1C2981F6F500B8CF94 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E1D2981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E1E2981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E1F2981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + C1004E202981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E212981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + C1004E222981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E232981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E242981F72D00B8CF94 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E252981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E262981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = ""; }; + C1004E272981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E282981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = ""; }; + C1004E292981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E2A2981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E2B2981F74300B8CF94 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E2C2981F75B00B8CF94 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E2D2981F75B00B8CF94 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E2E2981F75B00B8CF94 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E2F2981F75B00B8CF94 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E302981F77B00B8CF94 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E312981F77B00B8CF94 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E322981F77B00B8CF94 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + C1004E332981F77B00B8CF94 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E342981F77B00B8CF94 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + C1004E352981F77B00B8CF94 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; C101947127DD473C004E7EB8 /* MockKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MockKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C1092BFD29F8116700AE3D1C /* apply-info-customizations.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "apply-info-customizations.sh"; sourceTree = ""; }; C10B28451EA9BA5E006EA1FC /* far_future_high_bg_forecast.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = far_future_high_bg_forecast.json; sourceTree = ""; }; + C11613482983096D00777E7C /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C116134B2983096D00777E7C /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + C116134D2983096D00777E7C /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/ckcomplication.strings; sourceTree = ""; }; + C11A2BCE29830A3100AC5135 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + C11A2BCF29830A3100AC5135 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ckcomplication.strings; sourceTree = ""; }; C11AA5C7258736CF00BDE12F /* DerivedAssetsBase.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = DerivedAssetsBase.xcassets; sourceTree = ""; }; C11B9D5D286778D000500CF8 /* LoopKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C11B9D60286779C000500CF8 /* MockKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MockKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C11B9D61286779C000500CF8 /* MockKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MockKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C11BD0542523CFED00236B08 /* SimpleBolusViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleBolusViewModel.swift; sourceTree = ""; }; C1201E2B23ECDBD0002DA84A /* WatchContextRequestUserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchContextRequestUserInfo.swift; sourceTree = ""; }; + C121D8CF29C7866D00DA0520 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Main.strings; sourceTree = ""; }; + C121D8D029C7866D00DA0520 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; + C121D8D129C7866D00DA0520 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; + C121D8D229C7866D00DA0520 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Interface.strings; sourceTree = ""; }; + C122DEF829BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C122DEF929BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + C122DEFA29BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + C122DEFB29BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C122DEFC29BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C122DEFD29BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + C122DEFE29BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ckcomplication.strings; sourceTree = ""; }; + C122DEFF29BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C122DF0029BBFAAE00321F8D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C12BCCF929BBFA480066A158 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; C12CB9AC23106A3C00F84978 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intents.strings; sourceTree = ""; }; C12CB9AE23106A5C00F84978 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Intents.strings; sourceTree = ""; }; C12CB9B023106A5F00F84978 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intents.strings; sourceTree = ""; }; @@ -1457,20 +1507,33 @@ C12F21A61DFA79CB00748193 /* recommend_temp_basal_very_low_end_in_range.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_very_low_end_in_range.json; sourceTree = ""; }; C13DA2AF24F6C7690098BB29 /* UIViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; }; C148CEE624FD91BD00711B3B /* DeliveryUncertaintyAlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeliveryUncertaintyAlertManager.swift; sourceTree = ""; }; + C14952142995822A0095AA84 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C14952152995822A0095AA84 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C155A8F32986396E009BD257 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + C155A8F42986396E009BD257 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + C155A8F52986396E009BD257 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/ckcomplication.strings; sourceTree = ""; }; C159C8192867857000A86EC0 /* LoopKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C159C8212867859800A86EC0 /* MockKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MockKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C159C82E286787EF00A86EC0 /* LoopKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C15A581F29C7866600D3A5A1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C15A582029C7866600D3A5A1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; + C15A582129C7866600D3A5A1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C15A582229C7866600D3A5A1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C15A582329C7866600D3A5A1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; C165756E2534C468004AE16E /* SimpleBolusViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleBolusViewModelTests.swift; sourceTree = ""; }; C16575702538A36B004AE16E /* CGMStalenessMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMStalenessMonitor.swift; sourceTree = ""; }; C16575722538AFF6004AE16E /* CGMStalenessMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMStalenessMonitorTests.swift; sourceTree = ""; }; C16575742539FD60004AE16E /* LoopCoreConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopCoreConstants.swift; sourceTree = ""; }; C1657577253A0021004AE16E /* ChartConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartConstants.swift; sourceTree = ""; }; - C165B8CD23302C5D0004112E /* RemoteCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteCommand.swift; sourceTree = ""; }; C16B983D26B4893300256B05 /* DoseEnactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoseEnactor.swift; sourceTree = ""; }; C16B983F26B4898800256B05 /* DoseEnactorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoseEnactorTests.swift; sourceTree = ""; }; C16DA84122E8E112008624C2 /* PluginManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginManager.swift; sourceTree = ""; }; C1742331259BEADC00399C9D /* ManualEntryDoseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualEntryDoseView.swift; sourceTree = ""; }; C174233B259BEB0F00399C9D /* ManualEntryDoseViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualEntryDoseViewModel.swift; sourceTree = ""; }; + C174571229830930009EFCF2 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C174571329830930009EFCF2 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C174571429830930009EFCF2 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; + C174571529830930009EFCF2 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; C1750AEB255B013300B8011C /* Minizip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Minizip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C1777A6525A125F100595963 /* ManualEntryDoseViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualEntryDoseViewModelTests.swift; sourceTree = ""; }; C17824991E1999FA00D9D25C /* CaseCountable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaseCountable.swift; sourceTree = ""; }; @@ -1478,22 +1541,92 @@ C17824A21E19EAB600D9D25C /* recommend_temp_basal_start_very_low_end_high.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_start_very_low_end_high.json; sourceTree = ""; }; C17824A41E1AD4D100D9D25C /* ManualBolusRecommendation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManualBolusRecommendation.swift; sourceTree = ""; }; C1814B85225E507C008D2D8E /* Sequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = ""; }; + C186B73F298309A700F83024 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + C18886E629830A5E004C982D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C18886E729830A5E004C982D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + C18886E829830A5E004C982D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/ckcomplication.strings; sourceTree = ""; }; C18913B42524F24C007B0683 /* DeviceDataManager+SimpleBolusViewModelDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DeviceDataManager+SimpleBolusViewModelDelegate.swift"; sourceTree = ""; }; C18A491222FCC22800FDA733 /* build-derived-assets.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "build-derived-assets.sh"; sourceTree = ""; }; C18A491322FCC22900FDA733 /* make_scenario.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = make_scenario.py; sourceTree = ""; }; C18A491522FCC22900FDA733 /* copy-plugins.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "copy-plugins.sh"; sourceTree = ""; }; + C18B725E299581C600F138D3 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = ""; }; + C18B725F299581C600F138D3 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; + C18B7260299581C600F138D3 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/ckcomplication.strings; sourceTree = ""; }; C19008FD25225D3900721625 /* SimpleBolusCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleBolusCalculator.swift; sourceTree = ""; }; C19008FF252271BB00721625 /* SimpleBolusCalculatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleBolusCalculatorTests.swift; sourceTree = ""; }; C191D2A025B3ACAA00C26C0B /* DosingStrategySelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DosingStrategySelectionView.swift; sourceTree = ""; }; + C192C5FE29C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = ""; }; + C192C5FF29C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/InfoPlist.strings; sourceTree = ""; }; + C192C60029C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = ""; }; + C192C60129C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/InfoPlist.strings; sourceTree = ""; }; + C192C60229C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = ""; }; + C192C60329C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/InfoPlist.strings; sourceTree = ""; }; + C192C60429C78711001EFEA6 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/InfoPlist.strings; sourceTree = ""; }; + C19A2247298951AC000E4E71 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; C19C8BB928651DFB0056D5E4 /* TrueTime.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TrueTime.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C19C8BC228651EAE0056D5E4 /* LoopTestingKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopTestingKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C19C8BC728651F0A0056D5E4 /* MockKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MockKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C19C8C20286776C20056D5E4 /* LoopKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = LoopKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C19E387B298638CE00851444 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; + C19E387C298638CE00851444 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; + C19E387D298638CE00851444 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; + C19E387E298638CE00851444 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; C19E96DD23D2733F003F79B0 /* LoopCompletionFreshness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopCompletionFreshness.swift; sourceTree = ""; }; C19F496225630504003632D7 /* Minizip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Minizip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C1AD41FF256D61E500164DDD /* Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comparable.swift; sourceTree = ""; }; + C1AD48CE298639890013B994 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1AD62FE29BBFAA80002685D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = ""; }; + C1AD62FF29BBFAA80002685D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; + C1AD630029BBFAA80002685D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/ckcomplication.strings; sourceTree = ""; }; + C1AF062229426300002C1B19 /* ManualGlucoseEntryRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualGlucoseEntryRow.swift; sourceTree = ""; }; + C1B0CFD429C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; + C1B0CFD529C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; + C1B0CFD629C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; + C1B0CFD729C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; + C1B0CFD829C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; + C1B0CFD929C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; + C1B0CFDA29C786BF0045B04D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; + C1B267992995824000BCB7C1 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; + C1B2679A2995824000BCB7C1 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1B2679B2995824000BCB7C1 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; + C1B2679C2995824000BCB7C1 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/ckcomplication.strings; sourceTree = ""; }; + C1B2679D2995824000BCB7C1 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5AF298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5B0298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5B1298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + C1BCB5B2298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5B3298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + C1BCB5B4298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5B5298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5B6298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + C1BCB5B7298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/ckcomplication.strings; sourceTree = ""; }; + C1BCB5B8298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1BCB5B9298309C4001C50FF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1C247882995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Intents.strings; sourceTree = ""; }; + C1C247892995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1C2478A2995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1C2478B2995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/InfoPlist.strings; sourceTree = ""; }; + C1C2478C2995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1C2478D2995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1C2478E2995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/MainInterface.strings; sourceTree = ""; }; + C1C2478F2995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/InfoPlist.strings; sourceTree = ""; }; + C1C247902995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/InfoPlist.strings; sourceTree = ""; }; + C1C247912995823200371B88 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1C31277297E4BFE00296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main.strings; sourceTree = ""; }; + C1C31278297E4BFE00296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/MainInterface.strings; sourceTree = ""; }; + C1C31279297E4BFE00296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Interface.strings; sourceTree = ""; }; + C1C3127A297E4BFE00296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main.strings; sourceTree = ""; }; + C1C3127C297E4BFE00296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C1C3127D297E4C0100296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; + C1C3127E297E4C0100296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ckcomplication.strings; sourceTree = ""; }; + C1C3127F297E4C0400296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Intents.strings; sourceTree = ""; }; + C1C31280297E4C0400296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C1C31281297E4C0400296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; + C1C31282297E4F6E00296DA4 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + C1C5357529C6346A00E32DF9 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Intents.strings; sourceTree = ""; }; C1C6591B1E1B1FDA0025CC58 /* recommend_temp_basal_dropping_then_rising.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_dropping_then_rising.json; sourceTree = ""; }; C1C660D0252E4DD5009B5C32 /* LoopConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopConstants.swift; sourceTree = ""; }; + C1D0B62F2986D4D90098D215 /* LocalizedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedString.swift; sourceTree = ""; }; C1D197FE232CF92D0096D646 /* capture-build-details.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "capture-build-details.sh"; sourceTree = ""; }; C1D289B422F90A52003FFBD9 /* BasalDeliveryState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasalDeliveryState.swift; sourceTree = ""; }; C1DA986B2843B6F9001D04CC /* PersistedProperty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistedProperty.swift; sourceTree = ""; }; @@ -1501,15 +1634,59 @@ C1E2773D224177C000354103 /* ClockKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ClockKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/System/Library/Frameworks/ClockKit.framework; sourceTree = DEVELOPER_DIR; }; C1E2774722433D7A00354103 /* MKRingProgressView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MKRingProgressView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C1E3862428247B7100F561A4 /* StoredLoopNotRunningNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoredLoopNotRunningNotification.swift; sourceTree = ""; }; + C1E5A6DE29C7870100703C90 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; }; + C1E693CA29C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; }; + C1E693CB29C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; + C1E693CC29C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; }; + C1E693CD29C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; + C1E693CE29C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; }; + C1E693CF29C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; + C1E693D029C786E200410918 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = ""; }; C1E71721292E90CC00DA646F /* SmallStatusWidgetEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallStatusWidgetEntryView.swift; sourceTree = ""; }; C1E9CB5A295101570022387B /* install-scenarios.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "install-scenarios.sh"; sourceTree = ""; }; + C1EB0D1D299581D900628475 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1EB0D1E299581D900628475 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + C1EB0D1F299581D900628475 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1EB0D20299581D900628475 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1EB0D21299581D900628475 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + C1EB0D22299581D900628475 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/ckcomplication.strings; sourceTree = ""; }; C1EF747128D6A44A00C8C083 /* CrashRecoveryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashRecoveryManager.swift; sourceTree = ""; }; C1F2075B26D6F9B0007AB7EB /* ProfileExpirationAlerter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileExpirationAlerter.swift; sourceTree = ""; }; + C1F48FF62995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F48FF72995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F48FF82995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + C1F48FF92995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F48FFA2995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + C1F48FFB2995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F48FFC2995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F48FFD2995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + C1F48FFE2995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/ckcomplication.strings; sourceTree = ""; }; + C1F48FFF2995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F490002995821600C8BD69 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1F4FD5929C7869800D7ACBC /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = ""; }; C1F7822527CC056900C0919A /* SettingsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsManager.swift; sourceTree = ""; }; C1F8B1D122375E4200DD66CF /* BolusProgressTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BolusProgressTableViewCell.swift; sourceTree = ""; }; C1F8B1DB223862D500DD66CF /* BolusProgressTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BolusProgressTableViewCell.xib; sourceTree = ""; }; + C1FAB5BE29C786B000D25073 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = ""; }; + C1FAB5BF29C786B000D25073 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Main.strings; sourceTree = ""; }; + C1FAB5C029C786B000D25073 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = ""; }; + C1FAB5C129C786B000D25073 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = ""; }; + C1FAB5C229C786B000D25073 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Interface.strings; sourceTree = ""; }; C1FB428B217806A300FAB378 /* StateColorPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateColorPalette.swift; sourceTree = ""; }; C1FB428E217921D600FAB378 /* PumpManagerUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpManagerUI.swift; sourceTree = ""; }; + C1FDCBFC29C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Main.strings; sourceTree = ""; }; + C1FDCBFD29C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1FDCBFE29C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1FDCBFF29C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1FDCC0029C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Localizable.strings; sourceTree = ""; }; + C1FDCC0129C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FDCC0229C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FDCC0329C786F90056E652 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Interface.strings; sourceTree = ""; }; + C1FF3D4929C786A900BDC1EC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = ""; }; + C1FF3D4A29C786A900BDC1EC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FF3D4B29C786A900BDC1EC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = ""; }; + C1FF3D4C29C786A900BDC1EC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = ""; }; + C1FF3D4D29C786A900BDC1EC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/InfoPlist.strings; sourceTree = ""; }; E90909CC24E34AC500F963D2 /* high_and_rising_with_cob_momentum_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = high_and_rising_with_cob_momentum_effect.json; sourceTree = ""; }; E90909CD24E34AC500F963D2 /* high_and_rising_with_cob_insulin_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = high_and_rising_with_cob_insulin_effect.json; sourceTree = ""; }; E90909CE24E34AC500F963D2 /* high_and_rising_with_cob_predicted_glucose.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = high_and_rising_with_cob_predicted_glucose.json; sourceTree = ""; }; @@ -1547,6 +1724,7 @@ E93E86C824E2E02200FF40C8 /* high_and_stable_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = high_and_stable_counteraction_effect.json; sourceTree = ""; }; E93E86C924E2E02200FF40C8 /* high_and_stable_momentum_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = high_and_stable_momentum_effect.json; sourceTree = ""; }; E942DE6D253BE5E100AC532D /* Loop Intent Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Loop Intent Extension.entitlements"; sourceTree = ""; }; + E950CA9029002D9000B5B692 /* LoopDataManagerDosingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopDataManagerDosingTests.swift; sourceTree = ""; }; E95D380024EADE7C005E2F50 /* DoseStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoseStoreProtocol.swift; sourceTree = ""; }; E95D380224EADF36005E2F50 /* CarbStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbStoreProtocol.swift; sourceTree = ""; }; E95D380424EADF78005E2F50 /* GlucoseStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseStoreProtocol.swift; sourceTree = ""; }; @@ -1564,6 +1742,17 @@ E9B07FED253BBC7100BAD8F8 /* OverrideIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideIntentHandler.swift; sourceTree = ""; }; E9B08015253BBD7300BAD8F8 /* UserDefaults+LoopIntents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+LoopIntents.swift"; sourceTree = ""; }; E9B08020253BBDE900BAD8F8 /* IntentExtensionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentExtensionInfo.swift; sourceTree = ""; }; + E9B3551B292844010076AB04 /* MissedMealNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MissedMealNotification.swift; sourceTree = ""; }; + E9B3552129358C440076AB04 /* MealDetectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealDetectionManager.swift; sourceTree = ""; }; + E9B35525293590980076AB04 /* MissedMealSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MissedMealSettings.swift; sourceTree = ""; }; + E9B3552C293592B40076AB04 /* MealDetectionManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealDetectionManagerTests.swift; sourceTree = ""; }; + E9B3552E2935968E0076AB04 /* HKHealthStoreMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HKHealthStoreMock.swift; sourceTree = ""; }; + E9B35532293706CA0076AB04 /* needs_clamping_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = needs_clamping_counteraction_effect.json; sourceTree = ""; }; + E9B35533293706CA0076AB04 /* dynamic_autofill_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = dynamic_autofill_counteraction_effect.json; sourceTree = ""; }; + E9B35534293706CB0076AB04 /* missed_meal_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = missed_meal_counteraction_effect.json; sourceTree = ""; }; + E9B35535293706CB0076AB04 /* noisy_cgm_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = noisy_cgm_counteraction_effect.json; sourceTree = ""; }; + E9B35536293706CB0076AB04 /* realistic_report_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = realistic_report_counteraction_effect.json; sourceTree = ""; }; + E9B35537293706CB0076AB04 /* long_interval_counteraction_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = long_interval_counteraction_effect.json; sourceTree = ""; }; E9BB27AA23B85C3500FB4987 /* SleepStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepStore.swift; sourceTree = ""; }; E9C00EEF24C620EF00628F35 /* LoopSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopSettings.swift; sourceTree = ""; }; E9C00EF424C623EF00628F35 /* LoopSettings+Loop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LoopSettings+Loop.swift"; sourceTree = ""; }; @@ -1575,12 +1764,10 @@ E9C58A7B24DB529A00487A17 /* insulin_effect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = insulin_effect.json; sourceTree = ""; }; E9E5E55F24D3519700B5DFFE /* far_future_high_bg_forecast_after_6_hours.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = far_future_high_bg_forecast_after_6_hours.json; sourceTree = ""; }; F5D9C01727DABBE0002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Intents.strings; sourceTree = ""; }; - F5D9C01827DABBE0002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/LaunchScreen.strings; sourceTree = ""; }; F5D9C01927DABBE0002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Main.strings; sourceTree = ""; }; F5D9C01A27DABBE1002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/MainInterface.strings; sourceTree = ""; }; F5D9C01B27DABBE1002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Interface.strings; sourceTree = ""; }; F5D9C01C27DABBE1002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Main.strings; sourceTree = ""; }; - F5D9C01D27DABBE1002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/LaunchScreen.strings; sourceTree = ""; }; F5D9C01E27DABBE2002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; F5D9C01F27DABBE2002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; F5D9C02027DABBE2002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1592,12 +1779,10 @@ F5D9C02627DABBE4002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; F5D9C02727DABBE4002E48F6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; F5E0BDD327E1D71C0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Intents.strings; sourceTree = ""; }; - F5E0BDD427E1D71C0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/LaunchScreen.strings; sourceTree = ""; }; F5E0BDD527E1D71D0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Main.strings; sourceTree = ""; }; F5E0BDD627E1D71D0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/MainInterface.strings; sourceTree = ""; }; F5E0BDD727E1D71E0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Interface.strings; sourceTree = ""; }; F5E0BDD827E1D71E0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Main.strings; sourceTree = ""; }; - F5E0BDD927E1D71F0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/LaunchScreen.strings; sourceTree = ""; }; F5E0BDDA27E1D71F0033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = ""; }; F5E0BDDB27E1D7200033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = ""; }; F5E0BDDC27E1D7200033557E /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1671,18 +1856,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 43D9FF9F21EA9A0C00AF44BF /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 43D9FFDE21EAE3AE00AF44BF /* LoopCore.framework in Frameworks */, - 43D9FFB421EA9AD800AF44BF /* LoopUI.framework in Frameworks */, - 43D9FFBB21EA9CC900AF44BF /* LoopKit.framework in Frameworks */, - 43D9FFB621EA9B2F00AF44BF /* HealthKit.framework in Frameworks */, - 43D9FFBC21EA9CCD00AF44BF /* LoopKitUI.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 43D9FFCC21EAE05D00AF44BF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1747,6 +1920,8 @@ 14B1736E28AEDBF6006CCD7C /* BasalView.swift */, 14B1737028AEDBF6006CCD7C /* GlucoseView.swift */, 14B1736628AED9EE006CCD7C /* Info.plist */, + C116134A2983096D00777E7C /* Localizable.strings */, + C11613472983096D00777E7C /* InfoPlist.strings */, 14B1737128AEDBF6006CCD7C /* LoopCircleView.swift */, C1E71721292E90CC00DA646F /* SmallStatusWidgetEntryView.swift */, 14B1736F28AEDBF6006CCD7C /* StatusWidget.swift */, @@ -1774,10 +1949,13 @@ isa = PBXGroup; children = ( 1DA7A84024476E98008257F0 /* Alerts */, + E950CA9429002E4B00B5B692 /* LoopDataManager */, C16575722538AFF6004AE16E /* CGMStalenessMonitorTests.swift */, A91E4C2224F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift */, C16B983F26B4898800256B05 /* DoseEnactorTests.swift */, E9C58A7124DB489100487A17 /* LoopDataManagerTests.swift */, + E950CA9029002D9000B5B692 /* LoopDataManagerDosingTests.swift */, + E9B3552C293592B40076AB04 /* MealDetectionManagerTests.swift */, 1D70C40026EC0F9D00C62570 /* SupportManagerTests.swift */, A9F5F1F4251050EC00E7C8A4 /* ZipArchiveTests.swift */, ); @@ -1859,6 +2037,7 @@ 43757D131C06F26C00910CB9 /* Models */ = { isa = PBXGroup; children = ( + A99A114029A581D6007919CE /* Remote */, 43511CDD21FD80AD00566C63 /* RetrospectiveCorrection */, A9FB75F0252BE320004C7D3F /* BolusDosingDecision.swift */, C17824A41E1AD4D100D9D25C /* ManualBolusRecommendation.swift */, @@ -1869,7 +2048,6 @@ A9B996EF27235191002DC09C /* LoopWarning.swift */, 4F526D601DF8D9A900A04910 /* NetBasal.swift */, 438D42F81D7C88BC003244B0 /* PredictionInputEffect.swift */, - C165B8CD23302C5D0004112E /* RemoteCommand.swift */, 4328E0311CFC068900E199AA /* WatchContext+LoopKit.swift */, E9C00EF424C623EF00628F35 /* LoopSettings+Loop.swift */, A987CD4824A58A0100439ADC /* ZipArchive.swift */, @@ -1915,7 +2093,6 @@ 43E2D90B1D20C581004DA55F /* LoopTests.xctest */, 4F70C1DC1DE8DCA7006380B7 /* Loop Status Extension.appex */, 4F75288B1DFE1DC600C322D6 /* LoopUI.framework */, - 43D9FFA221EA9A0C00AF44BF /* Learn.app */, 43D9FFCF21EAE05D00AF44BF /* LoopCore.framework */, 43D9002A21EB209400AF44BF /* LoopCore.framework */, E9B07F7C253BBA6500BAD8F8 /* Loop Intent Extension.appex */, @@ -1964,6 +2141,7 @@ 43A943821B926B7B0051FA24 /* WatchApp Extension */ = { isa = PBXGroup; children = ( + 63F5E17A297DDF3900A62D4B /* ckcomplication.strings */, 7D7076601FE06EE3004AC8EA /* Localizable.strings */, 43D533BB1CFD1DD7009E3085 /* WatchApp Extension.entitlements */, 43A943911B926B7B0051FA24 /* Info.plist */, @@ -2058,7 +2236,6 @@ 43D9FFB521EA9B0100AF44BF /* Learn.entitlements */, 43D9FFA821EA9A0C00AF44BF /* Main.storyboard */, 43D9FFAB21EA9A0F00AF44BF /* Assets.xcassets */, - 43D9FFAD21EA9A0F00AF44BF /* LaunchScreen.storyboard */, 43D9FFB021EA9A0F00AF44BF /* Info.plist */, 80F864E42433BF5D0026EC26 /* InfoPlist.strings */, 7D9BEEE72335A6B3005DCFD6 /* Localizable.strings */, @@ -2091,6 +2268,8 @@ 4B60626A287E286000BF8BBB /* Localizable.strings */, E9C00EEF24C620EF00628F35 /* LoopSettings.swift */, C16575742539FD60004AE16E /* LoopCoreConstants.swift */, + E9B3551B292844010076AB04 /* MissedMealNotification.swift */, + C1D0B62F2986D4D90098D215 /* LocalizedString.swift */, ); path = LoopCore; sourceTree = ""; @@ -2179,7 +2358,6 @@ isa = PBXGroup; children = ( 43A51E1E1EB6D62A000736CC /* CarbAbsorptionViewController.swift */, - 43DBF0581C93F73800B3C386 /* CarbEntryTableViewController.swift */, 892D7C5023B54A14008A9656 /* CarbEntryViewController.swift */, 43A51E201EB6DBDD000736CC /* LoopChartsTableViewController.swift */, 433EA4C31D9F71C800CD78FB /* CommandResponseViewController.swift */, @@ -2221,6 +2399,7 @@ 1DD0B76624EC77AC008A2DC3 /* SupportScreenView.swift */, 43F64DD81D9C92C900D24DC6 /* TitleSubtitleTableViewCell.swift */, 4311FB9A1F37FE1B00D4C0A7 /* TitleSubtitleTextFieldTableViewCell.swift */, + C1AF062229426300002C1B19 /* ManualGlucoseEntryRow.swift */, ); path = Views; sourceTree = ""; @@ -2258,6 +2437,7 @@ 4328E0341CFC0AE100E199AA /* WatchDataManager.swift */, 1DA6499D2441266400F61E75 /* Alerts */, E95D37FF24EADE68005E2F50 /* Store Protocols */, + E9B355232935906B0076AB04 /* Missed Meal Detection */, C1F2075B26D6F9B0007AB7EB /* ProfileExpirationAlerter.swift */, A96DAC2B2838F31200D94E38 /* SharedLogging.swift */, ); @@ -2290,6 +2470,7 @@ 7D7076371FE06EDE004AC8EA /* Localizable.strings */, 4F70C1FD1DE8E662006380B7 /* Loop Status Extension.entitlements */, 4F70C1E51DE8DCA7006380B7 /* Info.plist */, + C1004DF62981F5B700B8CF94 /* InfoPlist.strings */, 43BFF0CC1E466C8400FF19A9 /* StateColorPalette.swift */, 43FCEEB0221A863E0013DD30 /* StatusChartsManager.swift */, 4F70C1E01DE8DCA7006380B7 /* StatusViewController.swift */, @@ -2624,6 +2805,26 @@ path = Shortcuts; sourceTree = ""; }; + A99A114029A581D6007919CE /* Remote */ = { + isa = PBXGroup; + children = ( + A99A114129A581F4007919CE /* BolusAction.swift */, + A99A114329A5829A007919CE /* CarbAction.swift */, + A99A114529A582A2007919CE /* OverrideAction.swift */, + ); + path = Remote; + sourceTree = ""; + }; + A99A114A29A58789007919CE /* Remote */ = { + isa = PBXGroup; + children = ( + A99A114B29A5879C007919CE /* BolusActionTests.swift */, + A99A114C29A5879C007919CE /* CarbActionTests.swift */, + A99A114D29A5879C007919CE /* OverrideActionTests.swift */, + ); + path = Remote; + sourceTree = ""; + }; A9E6DFE4246A0418005B1A1C /* Extensions */ = { isa = PBXGroup; children = ( @@ -2635,13 +2836,13 @@ A9E6DFED246A0460005B1A1C /* Models */ = { isa = PBXGroup; children = ( + A99A114A29A58789007919CE /* Remote */, A9DFAFB224F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift */, A963B279252CEBAE0062AA12 /* SetBolusUserInfoTests.swift */, A9DFAFB424F048A000950D1E /* WatchHistoricalCarbsTests.swift */, C19008FF252271BB00721625 /* SimpleBolusCalculatorTests.swift */, A9C1719625366F780053BCBD /* WatchHistoricalGlucoseTest.swift */, A9BD28E6272226B40071DF15 /* TestLocalizedError.swift */, - A9E8A80428A7CAC000C0A8A4 /* RemoteCommandTests.swift */, ); path = Models; sourceTree = ""; @@ -2697,6 +2898,7 @@ C18A491522FCC22900FDA733 /* copy-plugins.sh */, C18A491322FCC22900FDA733 /* make_scenario.py */, C1E9CB5A295101570022387B /* install-scenarios.sh */, + C1092BFD29F8116700AE3D1C /* apply-info-customizations.sh */, ); path = Scripts; sourceTree = ""; @@ -2757,6 +2959,7 @@ E93E86B124DDE21D00FF40C8 /* MockCarbStore.swift */, E98A55F024EDD85E0008715D /* MockDosingDecisionStore.swift */, E98A55F224EDD9530008715D /* MockSettingsStore.swift */, + E9B3552E2935968E0076AB04 /* HKHealthStoreMock.swift */, ); path = "Mock Stores"; sourceTree = ""; @@ -2785,6 +2988,13 @@ path = high_and_stable; sourceTree = ""; }; + E950CA9429002E4B00B5B692 /* LoopDataManager */ = { + isa = PBXGroup; + children = ( + ); + path = LoopDataManager; + sourceTree = ""; + }; E95D37FF24EADE68005E2F50 /* Store Protocols */ = { isa = PBXGroup; children = ( @@ -2803,14 +3013,39 @@ E942DE6D253BE5E100AC532D /* Loop Intent Extension.entitlements */, E9B07F7E253BBA6500BAD8F8 /* IntentHandler.swift */, E9B07F80253BBA6500BAD8F8 /* Info.plist */, + C1004DF32981F5B700B8CF94 /* Localizable.strings */, + C1004DF02981F5B700B8CF94 /* InfoPlist.strings */, E9B07FED253BBC7100BAD8F8 /* OverrideIntentHandler.swift */, ); path = "Loop Intent Extension"; sourceTree = ""; }; + E9B355232935906B0076AB04 /* Missed Meal Detection */ = { + isa = PBXGroup; + children = ( + E9B3552129358C440076AB04 /* MealDetectionManager.swift */, + E9B35525293590980076AB04 /* MissedMealSettings.swift */, + ); + path = "Missed Meal Detection"; + sourceTree = ""; + }; + E9B355312937068A0076AB04 /* meal_detection */ = { + isa = PBXGroup; + children = ( + E9B35533293706CA0076AB04 /* dynamic_autofill_counteraction_effect.json */, + E9B35532293706CA0076AB04 /* needs_clamping_counteraction_effect.json */, + E9B35534293706CB0076AB04 /* missed_meal_counteraction_effect.json */, + E9B35535293706CB0076AB04 /* noisy_cgm_counteraction_effect.json */, + E9B35537293706CB0076AB04 /* long_interval_counteraction_effect.json */, + E9B35536293706CB0076AB04 /* realistic_report_counteraction_effect.json */, + ); + path = meal_detection; + sourceTree = ""; + }; E9C58A7624DB510500487A17 /* Fixtures */ = { isa = PBXGroup; children = ( + E9B355312937068A0076AB04 /* meal_detection */, E90909EC24E35B3400F963D2 /* high_and_falling */, E90909E124E352C300F963D2 /* low_with_low_treatment */, E90909D624E34EC200F963D2 /* low_and_falling */, @@ -2890,6 +3125,7 @@ C113F4472951352C00758735 /* Install Scenarios */, C16DA84322E8E5FF008624C2 /* Install Plugins */, C1D19800232CFA2A0096D646 /* Capture Build Details */, + C1092BFE29F88F0600AE3D1C /* Apply Info Customizations */, 4F70C1EC1DE8DCA8006380B7 /* Embed App Extensions */, ); buildRules = ( @@ -2914,7 +3150,6 @@ isa = PBXNativeTarget; buildConfigurationList = 43A943991B926B7B0051FA24 /* Build configuration list for PBXNativeTarget "WatchApp" */; buildPhases = ( - C1D1406222FB7ED200DA6242 /* Build Derived Assets */, 43A943701B926B7B0051FA24 /* Resources */, 43A943981B926B7B0051FA24 /* Embed App Extensions */, 43105EF81BADC8F9009CD81E /* Frameworks */, @@ -2933,6 +3168,7 @@ isa = PBXNativeTarget; buildConfigurationList = 43A943951B926B7B0051FA24 /* Build configuration list for PBXNativeTarget "WatchApp Extension" */; buildPhases = ( + C1E9CB59294E67060022387B /* Build Derived Assets */, 43A9437A1B926B7B0051FA24 /* Sources */, 43A9437B1B926B7B0051FA24 /* Frameworks */, 43A9437C1B926B7B0051FA24 /* Resources */, @@ -2966,26 +3202,6 @@ productReference = 43D9002A21EB209400AF44BF /* LoopCore.framework */; productType = "com.apple.product-type.framework"; }; - 43D9FFA121EA9A0C00AF44BF /* Learn */ = { - isa = PBXNativeTarget; - buildConfigurationList = 43D9FFB321EA9A0F00AF44BF /* Build configuration list for PBXNativeTarget "Learn" */; - buildPhases = ( - 43D9FF9E21EA9A0C00AF44BF /* Sources */, - 43D9FF9F21EA9A0C00AF44BF /* Frameworks */, - 43D9FFA021EA9A0C00AF44BF /* Resources */, - 43D9FFDF21EAE3C600AF44BF /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 43D9FFBA21EA9CA400AF44BF /* PBXTargetDependency */, - A942E447225FD9A300DD4980 /* PBXTargetDependency */, - ); - name = Learn; - productName = Learn; - productReference = 43D9FFA221EA9A0C00AF44BF /* Learn.app */; - productType = "com.apple.product-type.application"; - }; 43D9FFCE21EAE05D00AF44BF /* LoopCore */ = { isa = PBXNativeTarget; buildConfigurationList = 43D9FFD821EAE05D00AF44BF /* Build configuration list for PBXNativeTarget "LoopCore" */; @@ -3179,19 +3395,6 @@ LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; - 43D9FFA121EA9A0C00AF44BF = { - CreatedOnToolsVersion = 10.1; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.ApplicationGroups.iOS = { - enabled = 1; - }; - com.apple.HealthKit = { - enabled = 1; - }; - }; - }; 43D9FFCE21EAE05D00AF44BF = { CreatedOnToolsVersion = 10.1; LastSwiftMigration = 1020; @@ -3253,6 +3456,10 @@ ro, tr, he, + ar, + sk, + cs, + hi, ); mainGroup = 43776F831B8022E90074EA36; packageReferences = ( @@ -3264,11 +3471,10 @@ targets = ( 43776F8B1B8022E90074EA36 /* Loop */, 4F70C1DB1DE8DCA7006380B7 /* Loop Status Extension */, - 14B1735B28AED9EC006CCD7C /* SmallStatusWidgetExtension */, 43A943711B926B7B0051FA24 /* WatchApp */, 43A9437D1B926B7B0051FA24 /* WatchApp Extension */, + 14B1735B28AED9EC006CCD7C /* SmallStatusWidgetExtension */, E9B07F7B253BBA6500BAD8F8 /* Loop Intent Extension */, - 43D9FFA121EA9A0C00AF44BF /* Learn */, 43D9FFCE21EAE05D00AF44BF /* LoopCore */, 43D9001A21EB209400AF44BF /* LoopCore-watchOS */, 4F75288A1DFE1DC600C322D6 /* LoopUI */, @@ -3284,6 +3490,8 @@ buildActionMask = 2147483647; files = ( 14B1736528AED9EE006CCD7C /* Assets.xcassets in Resources */, + C116134C2983096D00777E7C /* Localizable.strings in Resources */, + C11613492983096D00777E7C /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3320,6 +3528,7 @@ 7D70765E1FE06EE3004AC8EA /* Localizable.strings in Resources */, 4B67E2C8289B4EDB002D92AF /* InfoPlist.strings in Resources */, 43A943901B926B7B0051FA24 /* Assets.xcassets in Resources */, + 63F5E17C297DDF3900A62D4B /* ckcomplication.strings in Resources */, B405E35924D2A75B00DD058D /* DerivedAssets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3332,18 +3541,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 43D9FFA021EA9A0C00AF44BF /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7D9BEEF32335CF8D005DCFD6 /* Localizable.strings in Resources */, - 43D9FFAF21EA9A0F00AF44BF /* LaunchScreen.storyboard in Resources */, - 43D9FFAC21EA9A0F00AF44BF /* Assets.xcassets in Resources */, - 43D9FFAA21EA9A0C00AF44BF /* Main.storyboard in Resources */, - 80F864E62433BF5D0026EC26 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 43D9FFCD21EAE05D00AF44BF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -3385,6 +3582,9 @@ E93E865424DB6CBA00FF40C8 /* retrospective_output.json in Resources */, E9C58A7F24DB529A00487A17 /* counteraction_effect_falling_glucose.json in Resources */, E93E865624DB731900FF40C8 /* predicted_glucose_without_retrospective.json in Resources */, + E9B3553D293706CB0076AB04 /* long_interval_counteraction_effect.json in Resources */, + E9B3553A293706CB0076AB04 /* missed_meal_counteraction_effect.json in Resources */, + E9B35538293706CB0076AB04 /* needs_clamping_counteraction_effect.json in Resources */, E90909D424E34AC500F963D2 /* high_and_rising_with_cob_carb_effect.json in Resources */, E93E86CC24E2E02200FF40C8 /* high_and_stable_predicted_glucose.json in Resources */, E90909DC24E34F1600F963D2 /* low_and_falling_predicted_glucose.json in Resources */, @@ -3399,10 +3599,13 @@ E90909DF24E34F1600F963D2 /* low_and_falling_insulin_effect.json in Resources */, E93E86BE24E1FDC400FF40C8 /* flat_and_stable_carb_effect.json in Resources */, E90909E824E3530200F963D2 /* low_with_low_treatment_insulin_effect.json in Resources */, + E9B3553B293706CB0076AB04 /* noisy_cgm_counteraction_effect.json in Resources */, + E9B3553C293706CB0076AB04 /* realistic_report_counteraction_effect.json in Resources */, E93E865824DB75BE00FF40C8 /* predicted_glucose_very_negative.json in Resources */, E93E86BC24E1FDC400FF40C8 /* flat_and_stable_predicted_glucose.json in Resources */, E90909EB24E3530200F963D2 /* low_with_low_treatment_counteraction_effect.json in Resources */, E90909F424E35B4D00F963D2 /* high_and_falling_insulin_effect.json in Resources */, + E9B35539293706CB0076AB04 /* dynamic_autofill_counteraction_effect.json in Resources */, E90909F624E35B7C00F963D2 /* high_and_falling_momentum_effect.json in Resources */, E93E86BA24E1FDC400FF40C8 /* flat_and_stable_insulin_effect.json in Resources */, E90909E724E3530200F963D2 /* low_with_low_treatment_carb_effect.json in Resources */, @@ -3430,6 +3633,7 @@ 4F70C1E41DE8DCA7006380B7 /* MainInterface.storyboard in Resources */, B405E35B24D2E05600DD058D /* HUDAssets.xcassets in Resources */, 7D7076351FE06EDE004AC8EA /* Localizable.strings in Resources */, + C1004DF82981F5B700B8CF94 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3450,12 +3654,34 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + C1004DF22981F5B700B8CF94 /* InfoPlist.strings in Resources */, + C1004DF52981F5B700B8CF94 /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + C1092BFE29F88F0600AE3D1C /* Apply Info Customizations */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "$(SRCROOT)/../InfoCustomizations", + ); + name = "Apply Info Customizations"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Scripts/apply-info-customizations.sh\"\n"; + }; C113F4472951352C00758735 /* Install Scenarios */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -3510,25 +3736,27 @@ shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Scripts/build-derived-assets.sh\" \"${SRCROOT}/Loop\"\n"; }; - C1D1406222FB7ED200DA6242 /* Build Derived Assets */ = { + C1D19800232CFA2A0096D646 /* Capture Build Details */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( + "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", ); - name = "Build Derived Assets"; + name = "Capture Build Details"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Scripts/build-derived-assets.sh\" \"${SRCROOT}/WatchApp\"\n"; + shellScript = "\"${SRCROOT}/Scripts/capture-build-details.sh\"\n"; }; - C1D19800232CFA2A0096D646 /* Capture Build Details */ = { + C1E9CB59294E67060022387B /* Build Derived Assets */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -3536,16 +3764,15 @@ inputFileListPaths = ( ); inputPaths = ( - "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}", ); - name = "Capture Build Details"; + name = "Build Derived Assets"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Scripts/capture-build-details.sh\"\n"; + shellScript = "\"${SRCROOT}/Scripts/build-derived-assets.sh\" \"${SRCROOT}/WatchApp\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -3594,6 +3821,7 @@ C1FB428F217921D600FAB378 /* PumpManagerUI.swift in Sources */, A9B996F227238705002DC09C /* DosingDecisionStore.swift in Sources */, 43C513191E864C4E001547C7 /* GlucoseRangeSchedule.swift in Sources */, + E9B355292935919E0076AB04 /* MissedMealSettings.swift in Sources */, 43A51E1F1EB6D62A000736CC /* CarbAbsorptionViewController.swift in Sources */, 43776F901B8022E90074EA36 /* AppDelegate.swift in Sources */, 4372E48B213CB5F00068E043 /* Double.swift in Sources */, @@ -3634,13 +3862,13 @@ C17824A01E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift in Sources */, 4372E487213C86240068E043 /* SampleValue.swift in Sources */, 437CEEE41CDE5C0A003C8C80 /* UIImage.swift in Sources */, + A99A114229A581F4007919CE /* BolusAction.swift in Sources */, C1201E2C23ECDBD0002DA84A /* WatchContextRequestUserInfo.swift in Sources */, 1D49795824E7289700948F05 /* ServicesViewModel.swift in Sources */, 1D4A3E2D2478628500FD601B /* StoredAlert+CoreDataClass.swift in Sources */, 892D7C5123B54A15008A9656 /* CarbEntryViewController.swift in Sources */, B4E202302661063E009421B5 /* AutomaticDosingStatus.swift in Sources */, C191D2A125B3ACAA00C26C0B /* DosingStrategySelectionView.swift in Sources */, - 43DBF0591C93F73800B3C386 /* CarbEntryTableViewController.swift in Sources */, A977A2F424ACFECF0059C207 /* CriticalEventLogExportManager.swift in Sources */, 89CA2B32226C18B8004D9350 /* TestingScenariosTableViewController.swift in Sources */, 43E93FB71E469A5100EAB8DB /* HKUnit.swift in Sources */, @@ -3656,7 +3884,6 @@ 439BED2A1E76093C00B0AED5 /* CGMManager.swift in Sources */, C16B983E26B4893300256B05 /* DoseEnactor.swift in Sources */, E98A55EF24EDD6E60008715D /* DosingDecisionStoreProtocol.swift in Sources */, - C165B8CE23302C5D0004112E /* RemoteCommand.swift in Sources */, B4001CEE28CBBC82002FB414 /* AlertManagementView.swift in Sources */, E9C00EF524C623EF00628F35 /* LoopSettings+Loop.swift in Sources */, 4389916B1E91B689000EEF90 /* ChartSettings+Loop.swift in Sources */, @@ -3695,7 +3922,9 @@ 1D6B1B6726866D89009AC446 /* AlertPermissionsChecker.swift in Sources */, 4F08DE8F1E7BB871006741EA /* CollectionType+Loop.swift in Sources */, A9F703772489D8AA00C98AD8 /* PersistentDeviceLog+SimulatedCoreData.swift in Sources */, + A99A114629A582A2007919CE /* OverrideAction.swift in Sources */, E9B080B1253BDA6300BAD8F8 /* UserDefaults+LoopIntents.swift in Sources */, + C1AF062329426300002C1B19 /* ManualGlucoseEntryRow.swift in Sources */, C148CEE724FD91BD00711B3B /* DeliveryUncertaintyAlertManager.swift in Sources */, 1D12D3B92548EFDD00B53E8B /* main.swift in Sources */, 435400341C9F878D00D5819C /* SetBolusUserInfo.swift in Sources */, @@ -3709,6 +3938,7 @@ 43F41C371D3BF32400C11ED6 /* UIAlertController.swift in Sources */, A9CBE45C248ACC03008E7BA2 /* SettingsStore+SimulatedCoreData.swift in Sources */, 433EA4C41D9F71C800CD78FB /* CommandResponseViewController.swift in Sources */, + E9B3552229358C440076AB04 /* MealDetectionManager.swift in Sources */, C16DA84222E8E112008624C2 /* PluginManager.swift in Sources */, 43785E932120A01B0057DED1 /* NewCarbEntryIntent+Loop.swift in Sources */, 439A7944211FE22F0041B75F /* NSUserActivity.swift in Sources */, @@ -3741,6 +3971,7 @@ A9C62D842331700E00535612 /* DiagnosticLog+Subsystem.swift in Sources */, 895FE0952201234000FCF18A /* OverrideSelectionViewController.swift in Sources */, C1EF747228D6A44A00C8C083 /* CrashRecoveryManager.swift in Sources */, + A99A114429A5829A007919CE /* CarbAction.swift in Sources */, A9F66FC3247F451500096EA7 /* UIDevice+Loop.swift in Sources */, 439706E622D2E84900C81566 /* PredictionSettingTableViewCell.swift in Sources */, 430D85891F44037000AF2D4F /* HUDViewTableViewCell.swift in Sources */, @@ -3855,6 +4086,7 @@ buildActionMask = 2147483647; files = ( E9C00EF324C6222400628F35 /* LoopSettings.swift in Sources */, + C1D0B6312986D4D90098D215 /* LocalizedString.swift in Sources */, 43C05CB821EBEA54006FB252 /* HKUnit.swift in Sources */, 4345E3F421F036FC009E00E5 /* Result.swift in Sources */, C19E96E023D275FA003F79B0 /* LoopCompletionFreshness.swift in Sources */, @@ -3865,47 +4097,17 @@ A9CE912224CA032E00302A40 /* NSUserDefaults.swift in Sources */, 43C05CAB21EB2B4A006FB252 /* NSBundle.swift in Sources */, 43C05CC721EC2ABC006FB252 /* IdentifiableClass.swift in Sources */, + E9B3552B293591E70076AB04 /* MissedMealNotification.swift in Sources */, 4345E40221F67300009E00E5 /* PotentialCarbEntryUserInfo.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 43D9FF9E21EA9A0C00AF44BF /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 43C05CBD21EBF77D006FB252 /* LessonsViewController.swift in Sources */, - 43C05CB621EBE321006FB252 /* NSTimeInterval.swift in Sources */, - 43C5F25A222C921B00905D10 /* OSLog.swift in Sources */, - 43C05CB521EBE274006FB252 /* Date.swift in Sources */, - 43D9F82421EFF1AB000578CD /* LessonResultsViewController.swift in Sources */, - 43C728F9222A448700C62969 /* DayCalculator.swift in Sources */, - 4345E3FA21F0473B009E00E5 /* TextCell.swift in Sources */, - 43C728F5222266F000C62969 /* ModalDayLesson.swift in Sources */, - 43D9F81821EC51CC000578CD /* DateEntry.swift in Sources */, - 43D9FFC021EAB22E00AF44BF /* DataManager.swift in Sources */, - 43C05CB121EBBDB9006FB252 /* TimeInRangeLesson.swift in Sources */, - 43C728F72222700000C62969 /* DateIntervalEntry.swift in Sources */, - 43D9F81E21EF0609000578CD /* NumberRangeEntry.swift in Sources */, - 43C05CCA21EC382B006FB252 /* NumberEntry.swift in Sources */, - 4345E3FE21F04A50009E00E5 /* DateIntervalFormatter.swift in Sources */, - 43C5F257222C7B7200905D10 /* TimeComponents.swift in Sources */, - 4345E3F821F03D2A009E00E5 /* DatesAndNumberCell.swift in Sources */, - 43D9F82221EF0A7A000578CD /* QuantityRangeEntry.swift in Sources */, - 43D9F81A21EC593C000578CD /* UITableViewCell.swift in Sources */, - 43D9F82021EF0906000578CD /* NSNumber.swift in Sources */, - 43C05CC221EC06E4006FB252 /* LessonConfigurationViewController.swift in Sources */, - 43C05CC621EC29E7006FB252 /* TextFieldTableViewCell.swift in Sources */, - 43C05CC021EBFFA4006FB252 /* Lesson.swift in Sources */, - C1814B86225E507C008D2D8E /* Sequence.swift in Sources */, - 43C5F258222C7BD400905D10 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 43D9FFCB21EAE05D00AF44BF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E9C00EF224C6221B00628F35 /* LoopSettings.swift in Sources */, + C1D0B6302986D4D90098D215 /* LocalizedString.swift in Sources */, 43C05CB921EBEA54006FB252 /* HKUnit.swift in Sources */, 4345E3F521F036FC009E00E5 /* Result.swift in Sources */, C19E96DF23D275F8003F79B0 /* LoopCompletionFreshness.swift in Sources */, @@ -3916,6 +4118,7 @@ 43C05CAA21EB2B49006FB252 /* NSBundle.swift in Sources */, 43C05CC821EC2ABC006FB252 /* IdentifiableClass.swift in Sources */, 43C05CAD21EB2BBF006FB252 /* NSUserDefaults.swift in Sources */, + E9B3552A293591E70076AB04 /* MissedMealNotification.swift in Sources */, 4345E40121F67300009E00E5 /* PotentialCarbEntryUserInfo.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3939,10 +4142,12 @@ buildActionMask = 2147483647; files = ( A9DF02CB24F72B9E00B7C988 /* CriticalEventLogTests.swift in Sources */, + A99A114F29A5879D007919CE /* CarbActionTests.swift in Sources */, B44251B3252350CE00605937 /* ChartAxisValuesStaticGeneratorTests.swift in Sources */, 1D80313D24746274002810DF /* AlertStoreTests.swift in Sources */, C1777A6625A125F100595963 /* ManualEntryDoseViewModelTests.swift in Sources */, C16B984026B4898800256B05 /* DoseEnactorTests.swift in Sources */, + A99A115029A5879D007919CE /* OverrideActionTests.swift in Sources */, A9A63F8E246B271600588D5B /* NSTimeInterval.swift in Sources */, A9DFAFB324F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift in Sources */, A963B27A252CEBAE0062AA12 /* SetBolusUserInfoTests.swift in Sources */, @@ -3957,9 +4162,12 @@ 8968B114240C55F10074BB48 /* LoopSettingsTests.swift in Sources */, A9BD28E7272226B40071DF15 /* TestLocalizedError.swift in Sources */, A9F5F1F5251050EC00E7C8A4 /* ZipArchiveTests.swift in Sources */, + E9B3552D293592B40076AB04 /* MealDetectionManagerTests.swift in Sources */, + E950CA9129002D9000B5B692 /* LoopDataManagerDosingTests.swift in Sources */, B4CAD8792549D2540057946B /* LoopCompletionFreshnessTests.swift in Sources */, 1D8D55BC252274650044DBB6 /* BolusEntryViewModelTests.swift in Sources */, A91E4C2124F867A700BE9213 /* StoredAlertTests.swift in Sources */, + A99A114E29A5879D007919CE /* BolusActionTests.swift in Sources */, 1DA7A84224476EAD008257F0 /* AlertManagerTests.swift in Sources */, A91E4C2324F86F1000BE9213 /* CriticalEventLogExportManagerTests.swift in Sources */, E9C58A7324DB4A2700487A17 /* LoopDataManagerTests.swift in Sources */, @@ -3968,8 +4176,8 @@ A96DAC2A2838EF8A00D94E38 /* DiagnosticLogTests.swift in Sources */, A9DAE7D02332D77F006AE942 /* LoopTests.swift in Sources */, E93E86B024DDE1BD00FF40C8 /* MockGlucoseStore.swift in Sources */, - A9E8A80528A7CAC000C0A8A4 /* RemoteCommandTests.swift in Sources */, 1DFE9E172447B6270082C280 /* UserNotificationAlertSchedulerTests.swift in Sources */, + E9B3552F2935968E0076AB04 /* HKHealthStoreMock.swift in Sources */, B4BC56382518DEA900373647 /* CGMStatusHUDViewModelTests.swift in Sources */, C1900900252271BB00721625 /* SimpleBolusCalculatorTests.swift in Sources */, A9C1719725366F780053BCBD /* WatchHistoricalGlucoseTest.swift in Sources */, @@ -4096,11 +4304,6 @@ target = 43A943711B926B7B0051FA24 /* WatchApp */; targetProxy = 43A943921B926B7B0051FA24 /* PBXContainerItemProxy */; }; - 43D9FFBA21EA9CA400AF44BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4F75288A1DFE1DC600C322D6 /* LoopUI */; - targetProxy = 43D9FFB921EA9CA400AF44BF /* PBXContainerItemProxy */; - }; 43D9FFD521EAE05D00AF44BF /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 43D9FFCE21EAE05D00AF44BF /* LoopCore */; @@ -4126,11 +4329,6 @@ target = 43D9FFCE21EAE05D00AF44BF /* LoopCore */; targetProxy = A942E444225FD97F00DD4980 /* PBXContainerItemProxy */; }; - A942E447225FD9A300DD4980 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 43D9FFCE21EAE05D00AF44BF /* LoopCore */; - targetProxy = A942E446225FD9A300DD4980 /* PBXContainerItemProxy */; - }; C117ED71232EDB3200DA57CD /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 43D9001A21EB209400AF44BF /* LoopCore-watchOS */; @@ -4177,6 +4375,10 @@ 7D9BF13B23370E8B005DCFD6 /* ro */, F5D9C01927DABBE0002E48F6 /* tr */, F5E0BDD527E1D71D0033557E /* he */, + C1C31277297E4BFE00296DA4 /* ar */, + C121D8CF29C7866D00DA0520 /* cs */, + C1FAB5BF29C786B000D25073 /* hi */, + C1FDCBFC29C786F90056E652 /* sk */, ); name = Main.storyboard; sourceTree = ""; @@ -4185,8 +4387,6 @@ isa = PBXVariantGroup; children = ( 43776F9B1B8022E90074EA36 /* Base */, - F5D9C01827DABBE0002E48F6 /* tr */, - F5E0BDD427E1D71C0033557E /* he */, ); name = LaunchScreen.storyboard; sourceTree = ""; @@ -4214,6 +4414,9 @@ 7D9BF13A23370E8B005DCFD6 /* ro */, F5D9C01727DABBE0002E48F6 /* tr */, F5E0BDD327E1D71C0033557E /* he */, + C1C3127F297E4C0400296DA4 /* ar */, + C1C247882995823200371B88 /* sk */, + C1C5357529C6346A00E32DF9 /* cs */, ); name = Intents.intentdefinition; sourceTree = ""; @@ -4241,6 +4444,10 @@ 7D9BF13D23370E8B005DCFD6 /* ro */, F5D9C01B27DABBE1002E48F6 /* tr */, F5E0BDD727E1D71E0033557E /* he */, + C1C31279297E4BFE00296DA4 /* ar */, + C121D8D229C7866D00DA0520 /* cs */, + C1FAB5C229C786B000D25073 /* hi */, + C1FDCC0329C786F90056E652 /* sk */, ); name = Interface.storyboard; sourceTree = ""; @@ -4268,24 +4475,34 @@ 7D9BF13E23370E8C005DCFD6 /* ro */, F5D9C01C27DABBE1002E48F6 /* tr */, F5E0BDD827E1D71E0033557E /* he */, + C1C3127A297E4BFE00296DA4 /* ar */, ); name = Main.storyboard; sourceTree = ""; }; - 43D9FFAD21EA9A0F00AF44BF /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 43D9FFAE21EA9A0F00AF44BF /* Base */, - F5D9C01D27DABBE1002E48F6 /* tr */, - F5E0BDD927E1D71F0033557E /* he */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; 4B60626A287E286000BF8BBB /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( 4B60626B287E286000BF8BBB /* de */, + C1004DF92981F5B700B8CF94 /* da */, + C1004E012981F67A00B8CF94 /* sv */, + C1004E092981F6A100B8CF94 /* ro */, + C1004E112981F6E200B8CF94 /* nl */, + C1004E192981F6F500B8CF94 /* nb */, + C1004E212981F72D00B8CF94 /* fr */, + C1004E282981F74300B8CF94 /* fi */, + C1BCB5B3298309C4001C50FF /* it */, + C19A2247298951AC000E4E71 /* en */, + C1EB0D1E299581D900628475 /* es */, + C1F48FFA2995821600C8BD69 /* pl */, + C1B267992995824000BCB7C1 /* tr */, + C122DEFA29BBFAAE00321F8D /* ru */, + C15A582129C7866600D3A5A1 /* ar */, + C1FF3D4B29C786A900BDC1EC /* he */, + C1B0CFD629C786BF0045B04D /* ja */, + C1E693CC29C786E200410918 /* pt-BR */, + C1FDCBFD29C786F90056E652 /* sk */, + C192C60029C78711001EFEA6 /* vi */, ); name = Localizable.strings; sourceTree = ""; @@ -4294,6 +4511,24 @@ isa = PBXVariantGroup; children = ( 4B67E2C7289B4EDB002D92AF /* de */, + C1004DFB2981F5B700B8CF94 /* da */, + C1004E032981F67A00B8CF94 /* sv */, + C1004E0B2981F6A100B8CF94 /* ro */, + C1004E132981F6E200B8CF94 /* nl */, + C1004E1B2981F6F500B8CF94 /* nb */, + C1004E232981F72D00B8CF94 /* fr */, + C1004E2A2981F74300B8CF94 /* fi */, + C1004E2E2981F75B00B8CF94 /* es */, + C1BCB5B8298309C4001C50FF /* it */, + C1F48FFF2995821600C8BD69 /* pl */, + C1B2679D2995824000BCB7C1 /* tr */, + C122DEFF29BBFAAE00321F8D /* ru */, + C15A582329C7866600D3A5A1 /* ar */, + C1FF3D4D29C786A900BDC1EC /* he */, + C1B0CFD929C786BF0045B04D /* ja */, + C1E693CF29C786E200410918 /* pt-BR */, + C1FDCC0129C786F90056E652 /* sk */, + C192C60329C78711001EFEA6 /* vi */, ); name = InfoPlist.strings; sourceTree = ""; @@ -4321,10 +4556,32 @@ 7D9BF13C23370E8B005DCFD6 /* ro */, F5D9C01A27DABBE1002E48F6 /* tr */, F5E0BDD627E1D71D0033557E /* he */, + C1C31278297E4BFE00296DA4 /* ar */, + C1C2478E2995823200371B88 /* sk */, ); name = MainInterface.storyboard; sourceTree = ""; }; + 63F5E17A297DDF3900A62D4B /* ckcomplication.strings */ = { + isa = PBXVariantGroup; + children = ( + 63F5E17B297DDF3900A62D4B /* Base */, + C1C3127E297E4C0100296DA4 /* ar */, + C116134D2983096D00777E7C /* nb */, + C1BCB5B7298309C4001C50FF /* it */, + C11A2BCF29830A3100AC5135 /* fr */, + C18886E829830A5E004C982D /* nl */, + C155A8F52986396E009BD257 /* de */, + C18B7260299581C600F138D3 /* da */, + C1EB0D22299581D900628475 /* es */, + C1F48FFE2995821600C8BD69 /* pl */, + C1B2679C2995824000BCB7C1 /* tr */, + C1AD630029BBFAA80002685D /* ro */, + C122DEFE29BBFAAE00321F8D /* ru */, + ); + name = ckcomplication.strings; + sourceTree = ""; + }; 7D7076371FE06EDE004AC8EA /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( @@ -4348,6 +4605,8 @@ 7D9BF14223370E8C005DCFD6 /* ro */, F5D9C02127DABBE3002E48F6 /* tr */, F5E0BDDD27E1D7210033557E /* he */, + C174571329830930009EFCF2 /* ar */, + C1C2478D2995823200371B88 /* sk */, ); name = Localizable.strings; sourceTree = ""; @@ -4358,6 +4617,22 @@ 7D23667A21250C480028B67D /* Base */, F5D9C02327DABBE3002E48F6 /* tr */, F5E0BDDF27E1D7210033557E /* he */, + C1C31281297E4C0400296DA4 /* ar */, + C1004DFA2981F5B700B8CF94 /* da */, + C1004E022981F67A00B8CF94 /* sv */, + C1004E0A2981F6A100B8CF94 /* ro */, + C1004E122981F6E200B8CF94 /* nl */, + C1004E1A2981F6F500B8CF94 /* nb */, + C1004E222981F72D00B8CF94 /* fr */, + C1004E292981F74300B8CF94 /* fi */, + C1004E342981F77B00B8CF94 /* de */, + C1BCB5B4298309C4001C50FF /* it */, + C1EB0D1F299581D900628475 /* es */, + C1F48FFB2995821600C8BD69 /* pl */, + C122DEFB29BBFAAE00321F8D /* ru */, + C1B0CFD729C786BF0045B04D /* ja */, + C1E693CD29C786E200410918 /* pt-BR */, + C192C60129C78711001EFEA6 /* vi */, ); name = InfoPlist.strings; sourceTree = ""; @@ -4385,6 +4660,10 @@ 7D9BF14323370E8C005DCFD6 /* ro */, F5D9C02227DABBE3002E48F6 /* tr */, F5E0BDDE27E1D7210033557E /* he */, + C1C31280297E4C0400296DA4 /* ar */, + C121D8D029C7866D00DA0520 /* cs */, + C1FAB5C029C786B000D25073 /* hi */, + C1FDCBFE29C786F90056E652 /* sk */, ); name = Localizable.strings; sourceTree = ""; @@ -4412,6 +4691,8 @@ 7D9BF14123370E8C005DCFD6 /* ro */, F5D9C02027DABBE2002E48F6 /* tr */, F5E0BDDC27E1D7200033557E /* he */, + C174571429830930009EFCF2 /* ar */, + C1C247902995823200371B88 /* sk */, ); name = InfoPlist.strings; sourceTree = ""; @@ -4438,6 +4719,8 @@ 7D9BF14523370E8D005DCFD6 /* ro */, F5D9C02627DABBE4002E48F6 /* tr */, F5E0BDE227E1D7230033557E /* he */, + C174571229830930009EFCF2 /* ar */, + C1C2478A2995823200371B88 /* sk */, ); name = Localizable.strings; sourceTree = ""; @@ -4465,6 +4748,10 @@ 7D9BF14423370E8D005DCFD6 /* ro */, F5D9C02527DABBE4002E48F6 /* tr */, F5E0BDE127E1D7230033557E /* he */, + C174571529830930009EFCF2 /* ar */, + C121D8D129C7866D00DA0520 /* cs */, + C1FAB5C129C786B000D25073 /* hi */, + C1FDCC0029C786F90056E652 /* sk */, ); name = Localizable.strings; sourceTree = ""; @@ -4492,6 +4779,10 @@ 7D9BF14023370E8C005DCFD6 /* ro */, F5D9C01F27DABBE2002E48F6 /* tr */, F5E0BDDB27E1D7200033557E /* he */, + C1C31282297E4F6E00296DA4 /* ar */, + C1C247912995823200371B88 /* sk */, + C12BCCF929BBFA480066A158 /* cs */, + C1FAB5BE29C786B000D25073 /* hi */, ); name = Localizable.strings; sourceTree = ""; @@ -4544,6 +4835,8 @@ 7D9BF13F23370E8C005DCFD6 /* ro */, F5D9C01E27DABBE2002E48F6 /* tr */, F5E0BDDA27E1D71F0033557E /* he */, + C1C3127C297E4BFE00296DA4 /* ar */, + C1C247892995823200371B88 /* sk */, ); name = Localizable.strings; sourceTree = ""; @@ -4552,16 +4845,162 @@ isa = PBXVariantGroup; children = ( 80F864E52433BF5D0026EC26 /* fi */, + C1004DEF2981F5B700B8CF94 /* da */, + C1004DFD2981F67A00B8CF94 /* sv */, + C1004E052981F6A100B8CF94 /* ro */, + C1004E0D2981F6E200B8CF94 /* nl */, + C1004E152981F6F500B8CF94 /* nb */, + C1004E1D2981F72D00B8CF94 /* fr */, + C1004E2C2981F75B00B8CF94 /* es */, + C1004E302981F77B00B8CF94 /* de */, + C1BCB5AF298309C4001C50FF /* it */, + C19E387B298638CE00851444 /* tr */, + C1F48FF62995821600C8BD69 /* pl */, + C14952142995822A0095AA84 /* ru */, + C1C2478B2995823200371B88 /* sk */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + C1004DF02981F5B700B8CF94 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + C1004DF12981F5B700B8CF94 /* da */, + C1004DFE2981F67A00B8CF94 /* sv */, + C1004E062981F6A100B8CF94 /* ro */, + C1004E0E2981F6E200B8CF94 /* nl */, + C1004E162981F6F500B8CF94 /* nb */, + C1004E1E2981F72D00B8CF94 /* fr */, + C1004E252981F74300B8CF94 /* fi */, + C1004E312981F77B00B8CF94 /* de */, + C1BCB5B0298309C4001C50FF /* it */, + C19E387C298638CE00851444 /* tr */, + C1EB0D1D299581D900628475 /* es */, + C1F48FF72995821600C8BD69 /* pl */, + C122DEF829BBFAAE00321F8D /* ru */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + C1004DF32981F5B700B8CF94 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + C1004DF42981F5B700B8CF94 /* da */, + C1004DFF2981F67A00B8CF94 /* sv */, + C1004E072981F6A100B8CF94 /* ro */, + C1004E0F2981F6E200B8CF94 /* nl */, + C1004E172981F6F500B8CF94 /* nb */, + C1004E1F2981F72D00B8CF94 /* fr */, + C1004E262981F74300B8CF94 /* fi */, + C1004E322981F77B00B8CF94 /* de */, + C186B73F298309A700F83024 /* es */, + C1BCB5B1298309C4001C50FF /* it */, + C19E387D298638CE00851444 /* tr */, + C1F48FF82995821600C8BD69 /* pl */, + C1C2478C2995823200371B88 /* sk */, + C122DEF929BBFAAE00321F8D /* ru */, + C15A581F29C7866600D3A5A1 /* ar */, + C1FF3D4929C786A900BDC1EC /* he */, + C1B0CFD429C786BF0045B04D /* ja */, + C1E693CA29C786E200410918 /* pt-BR */, + C192C5FE29C78711001EFEA6 /* vi */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + C1004DF62981F5B700B8CF94 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + C1004DF72981F5B700B8CF94 /* da */, + C1004E002981F67A00B8CF94 /* sv */, + C1004E082981F6A100B8CF94 /* ro */, + C1004E102981F6E200B8CF94 /* nl */, + C1004E182981F6F500B8CF94 /* nb */, + C1004E202981F72D00B8CF94 /* fr */, + C1004E272981F74300B8CF94 /* fi */, + C1004E2D2981F75B00B8CF94 /* es */, + C1004E332981F77B00B8CF94 /* de */, + C1BCB5B2298309C4001C50FF /* it */, + C19E387E298638CE00851444 /* tr */, + C1F48FF92995821600C8BD69 /* pl */, + C14952152995822A0095AA84 /* ru */, + C1C2478F2995823200371B88 /* sk */, + C15A582029C7866600D3A5A1 /* ar */, + C1FF3D4A29C786A900BDC1EC /* he */, + C1B0CFD529C786BF0045B04D /* ja */, + C1E693CB29C786E200410918 /* pt-BR */, + C192C5FF29C78711001EFEA6 /* vi */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + C11613472983096D00777E7C /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + C11613482983096D00777E7C /* nb */, + C1BCB5B5298309C4001C50FF /* it */, + C18886E629830A5E004C982D /* nl */, + C155A8F32986396E009BD257 /* de */, + C1AD48CE298639890013B994 /* fr */, + C18B725E299581C600F138D3 /* da */, + C1EB0D20299581D900628475 /* es */, + C1F48FFC2995821600C8BD69 /* pl */, + C1B2679A2995824000BCB7C1 /* tr */, + C1AD62FE29BBFAA80002685D /* ro */, + C122DEFC29BBFAAE00321F8D /* ru */, ); name = InfoPlist.strings; sourceTree = ""; }; + C116134A2983096D00777E7C /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + C116134B2983096D00777E7C /* nb */, + C1BCB5B6298309C4001C50FF /* it */, + C11A2BCE29830A3100AC5135 /* fr */, + C18886E729830A5E004C982D /* nl */, + C155A8F42986396E009BD257 /* de */, + C18B725F299581C600F138D3 /* da */, + C1EB0D21299581D900628475 /* es */, + C1F48FFD2995821600C8BD69 /* pl */, + C1B2679B2995824000BCB7C1 /* tr */, + C1AD62FF29BBFAA80002685D /* ro */, + C122DEFD29BBFAAE00321F8D /* ru */, + C15A582229C7866600D3A5A1 /* ar */, + C1F4FD5929C7869800D7ACBC /* fi */, + C1FF3D4C29C786A900BDC1EC /* he */, + C1B0CFD829C786BF0045B04D /* ja */, + C1E693CE29C786E200410918 /* pt-BR */, + C1FDCBFF29C786F90056E652 /* sk */, + C1E5A6DE29C7870100703C90 /* sv */, + C192C60229C78711001EFEA6 /* vi */, + ); + name = Localizable.strings; + sourceTree = ""; + }; C1C73F0F1DE3D0270022FC89 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 7D23667E21250CAC0028B67D /* Base */, F5D9C02427DABBE3002E48F6 /* tr */, F5E0BDE027E1D7220033557E /* he */, + C1C3127D297E4C0100296DA4 /* ar */, + C1004DFC2981F5B700B8CF94 /* da */, + C1004E042981F67A00B8CF94 /* sv */, + C1004E0C2981F6A100B8CF94 /* ro */, + C1004E142981F6E200B8CF94 /* nl */, + C1004E1C2981F6F500B8CF94 /* nb */, + C1004E242981F72D00B8CF94 /* fr */, + C1004E2B2981F74300B8CF94 /* fi */, + C1004E2F2981F75B00B8CF94 /* es */, + C1004E352981F77B00B8CF94 /* de */, + C1BCB5B9298309C4001C50FF /* it */, + C1F490002995821600C8BD69 /* pl */, + C122DF0029BBFAAE00321F8D /* ru */, + C1B0CFDA29C786BF0045B04D /* ja */, + C1E693D029C786E200410918 /* pt-BR */, + C1FDCC0229C786F90056E652 /* sk */, + C192C60429C78711001EFEA6 /* vi */, ); name = InfoPlist.strings; sourceTree = ""; @@ -4751,6 +5190,7 @@ GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.1; LOCALIZED_STRING_MACRO_NAMES = ( NSLocalizedString, CFLocalizedString, @@ -4860,6 +5300,7 @@ GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.1; LOCALIZED_STRING_MACRO_NAMES = ( NSLocalizedString, CFLocalizedString, @@ -4904,6 +5345,9 @@ PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "$(LOOP_PROVISIONING_PROFILE_SPECIFIER_DEBUG)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; @@ -4927,6 +5371,9 @@ PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "$(LOOP_PROVISIONING_PROFILE_SPECIFIER_RELEASE)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; TARGETED_DEVICE_FAMILY = 1; }; name = Release; @@ -5083,44 +5530,6 @@ }; name = Release; }; - 43D9FFB121EA9A0F00AF44BF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = YES; - CODE_SIGN_ENTITLEMENTS = Learn/Learn.entitlements; - DEVELOPMENT_TEAM = "$(LOOP_DEVELOPMENT_TEAM)"; - INFOPLIST_FILE = Learn/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER)Learn"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 43D9FFB221EA9A0F00AF44BF /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = YES; - CODE_SIGN_ENTITLEMENTS = Learn/Learn.entitlements; - DEVELOPMENT_TEAM = "$(LOOP_DEVELOPMENT_TEAM)"; - INFOPLIST_FILE = Learn/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER)Learn"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; 43D9FFD921EAE05D00AF44BF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5417,15 +5826,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 43D9FFB321EA9A0F00AF44BF /* Build configuration list for PBXNativeTarget "Learn" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 43D9FFB121EA9A0F00AF44BF /* Debug */, - 43D9FFB221EA9A0F00AF44BF /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 43D9FFD821EAE05D00AF44BF /* Build configuration list for PBXNativeTarget "LoopCore" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Loop.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Loop.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1bd3f8ef6f..919434a625 100644 --- a/Loop.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Loop.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/Loop.xcodeproj/xcshareddata/xcschemes/DoseMathTests.xcscheme b/Loop.xcodeproj/xcshareddata/xcschemes/DoseMathTests.xcscheme index acaf4976e1..f225f4098a 100644 --- a/Loop.xcodeproj/xcshareddata/xcschemes/DoseMathTests.xcscheme +++ b/Loop.xcodeproj/xcshareddata/xcschemes/DoseMathTests.xcscheme @@ -1,6 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Loop.xcodeproj/xcshareddata/xcschemes/Loop Intent Extension.xcscheme b/Loop.xcodeproj/xcshareddata/xcschemes/Loop Intent Extension.xcscheme index 949bee0edf..b19776bb0a 100644 --- a/Loop.xcodeproj/xcshareddata/xcschemes/Loop Intent Extension.xcscheme +++ b/Loop.xcodeproj/xcshareddata/xcschemes/Loop Intent Extension.xcscheme @@ -1,6 +1,6 @@ Bool { log.default("%{public}@ with launchOptions: %{public}@", #function, String(describing: launchOptions)) + setenv("CFNETWORK_DIAGNOSTICS", "3", 1) + loopAppManager.initialize(windowProvider: self, launchOptions: launchOptions) loopAppManager.launch() return loopAppManager.isLaunchComplete diff --git a/Loop/Base.lproj/Localizable.strings b/Loop/Base.lproj/Localizable.strings index 7020b95773..fd9d1fe652 100644 --- a/Loop/Base.lproj/Localizable.strings +++ b/Loop/Base.lproj/Localizable.strings @@ -90,9 +90,6 @@ /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Algorithm Settings"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "An adjustment to the adult model based on empirical effects in children."; - /* The title of the amplitude API key credential */ "API Key" = "API Key"; @@ -184,9 +181,6 @@ /* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "Custom Override"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; - /* Button title to delete CGM */ "Delete CGM" = "Delete CGM"; diff --git a/Loop/Extensions/DeviceDataManager+BolusEntryViewModelDelegate.swift b/Loop/Extensions/DeviceDataManager+BolusEntryViewModelDelegate.swift index b4559bb0b5..46a29e075a 100644 --- a/Loop/Extensions/DeviceDataManager+BolusEntryViewModelDelegate.swift +++ b/Loop/Extensions/DeviceDataManager+BolusEntryViewModelDelegate.swift @@ -19,11 +19,20 @@ extension DeviceDataManager: BolusEntryViewModelDelegate, ManualDoseViewModelDel func withLoopState(do block: @escaping (LoopState) -> Void) { loopManager.getLoopState { block($1) } } - - func addGlucoseSamples(_ samples: [NewGlucoseSample], completion: ((Swift.Result<[StoredGlucoseSample], Error>) -> Void)?) { - loopManager.addGlucoseSamples(samples, completion: completion) + + func saveGlucose(sample: NewGlucoseSample) async -> StoredGlucoseSample? { + return await withCheckedContinuation { continuation in + loopManager.addGlucoseSamples([sample]) { result in + switch result { + case .success(let samples): + continuation.resume(returning: samples.first) + case .failure: + continuation.resume(returning: nil) + } + } + } } - + func addCarbEntry(_ carbEntry: NewCarbEntry, replacing replacingEntry: StoredCarbEntry?, completion: @escaping (Result) -> Void) { loopManager.addCarbEntry(carbEntry, replacing: replacingEntry, completion: completion) } @@ -76,4 +85,7 @@ extension DeviceDataManager: BolusEntryViewModelDelegate, ManualDoseViewModelDel return loopManager.settings } + func updateRemoteRecommendation() { + loopManager.updateRemoteRecommendation() + } } diff --git a/Loop/Extensions/UIAlertController.swift b/Loop/Extensions/UIAlertController.swift index d5625776fa..3b83aa11d8 100644 --- a/Loop/Extensions/UIAlertController.swift +++ b/Loop/Extensions/UIAlertController.swift @@ -103,7 +103,7 @@ extension UIAlertController { preferredStyle: .actionSheet ) - for availableCGMManager in availableCGMManagers { + for availableCGMManager in availableCGMManagers.sorted(by: {$0.localizedTitle < $1.localizedTitle}) { addAction(UIAlertAction( title: availableCGMManager.localizedTitle, style: .default, diff --git a/Loop/Info.plist b/Loop/Info.plist index f881313453..75e59c58bc 100644 --- a/Loop/Info.plist +++ b/Loop/Info.plist @@ -31,9 +31,13 @@ CFBundleURLTypes + CFBundleTypeRole + Editor + CFBundleURLName + $(MAIN_APP_BUNDLE_IDENTIFIER) CFBundleURLSchemes - $(MAIN_APP_BUNDLE_IDENTIFIER) + $(URL_SCHEME_NAME) diff --git a/Loop/Managers/Alerts/AlertManager.swift b/Loop/Managers/Alerts/AlertManager.swift index 52031269a1..f60af78016 100644 --- a/Loop/Managers/Alerts/AlertManager.swift +++ b/Loop/Managers/Alerts/AlertManager.swift @@ -50,21 +50,25 @@ public final class AlertManager { private let bluetoothPoweredOffIdentifier = Alert.Identifier(managerIdentifier: managerIdentifier, alertIdentifier: "bluetoothPoweredOff") + var analyticsServicesManager: AnalyticsServicesManager + lazy private var cancellables = Set() // For testing var getCurrentDate = { return Date() } - public init(alertPresenter: AlertPresenter, + init(alertPresenter: AlertPresenter, modalAlertScheduler: InAppModalAlertScheduler? = nil, userNotificationAlertScheduler: UserNotificationAlertScheduler, fileManager: FileManager = FileManager.default, alertStore: AlertStore? = nil, expireAfter: TimeInterval = 24 /* hours */ * 60 /* minutes */ * 60 /* seconds */, bluetoothProvider: BluetoothProvider, + analyticsServicesManager: AnalyticsServicesManager, preventIssuanceBeforePlayback: Bool = true ) { self.fileManager = fileManager + self.analyticsServicesManager = analyticsServicesManager playbackFinished = !preventIssuanceBeforePlayback let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first let alertStoreDirectory = documentsDirectory?.appendingPathComponent("AlertStore") @@ -85,8 +89,10 @@ public final class AlertManager { bluetoothProvider.addBluetoothObserver(self, queue: .main) NotificationCenter.default.publisher(for: .LoopCompleted) - .sink { [weak self] _ in - self?.loopDidComplete(self?.getLastLoopDate()) + .sink { [weak self] publisher in + if let loopDataManager = publisher.object as? LoopDataManager { + self?.loopDidComplete(loopDataManager.lastLoopCompleted) + } } .store(in: &cancellables) @@ -174,8 +180,9 @@ public final class AlertManager { var scheduledNotifications: [StoredLoopNotRunningNotification] = [] for (minutes, isCritical) in [(20.0, false), (40.0, false), (60.0, true), (120.0, true)] { - let failureInterval = lastLoopDate.addingTimeInterval(.minutes(minutes)).timeIntervalSinceNow - guard failureInterval >= 0 else { break } + let warningInterval = TimeInterval(minutes: minutes) + let timeUntilNotification = lastLoopDate.addingTimeInterval(warningInterval).timeIntervalSinceNow + guard timeUntilNotification >= 0 else { break } let formatter = DateComponentsFormatter() formatter.maximumUnitCount = 1 @@ -183,12 +190,12 @@ public final class AlertManager { formatter.unitsStyle = .full let notificationContent = UNMutableNotificationContent() - if let failureIntervalString = formatter.string(from: failureInterval)?.localizedLowercase { + if let failureIntervalString = formatter.string(from: warningInterval)?.localizedLowercase { notificationContent.body = String(format: NSLocalizedString("Loop has not completed successfully in %@", comment: "The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop"), failureIntervalString) } notificationContent.title = NSLocalizedString("Loop Failure", comment: "The notification title for a loop failure") - let shouldMuteAlert = alertMuter.shouldMuteAlert(scheduledAt: failureInterval) + let shouldMuteAlert = alertMuter.shouldMuteAlert(scheduledAt: timeUntilNotification) if isCritical, FeatureFlags.criticalAlertsEnabled { if #available(iOS 15.0, *) { notificationContent.interruptionLevel = .critical @@ -204,14 +211,13 @@ public final class AlertManager { notificationContent.threadIdentifier = LoopNotificationCategory.loopNotRunning.rawValue let trigger = UNTimeIntervalNotificationTrigger( - timeInterval: failureInterval + gracePeriod, + timeInterval: timeUntilNotification + gracePeriod, repeats: false ) - let intervalIdentifierValue = TimeInterval(minutes: minutes) let request = UNNotificationRequest( - identifier: "\(LoopNotificationCategory.loopNotRunning.rawValue)\(intervalIdentifierValue)", + identifier: "\(LoopNotificationCategory.loopNotRunning.rawValue)\(warningInterval)", content: notificationContent, trigger: trigger ) @@ -221,7 +227,6 @@ public final class AlertManager { alertAt: nextTriggerDate, title: notificationContent.title, body: notificationContent.body, - timeInterval: failureInterval, isCritical: isCritical) scheduledNotifications.append(scheduledNotification) } @@ -356,6 +361,7 @@ extension AlertManager: AlertIssuer { deferredAlerts.append(alert) return } + analyticsServicesManager.didIssueAlert(identifier: alert.identifier.value, interruptionLevel: alert.interruptionLevel) scheduleAlertWithSchedulers(alert) alertStore.recordIssued(alert: alert) } diff --git a/Loop/Managers/AnalyticsServicesManager.swift b/Loop/Managers/AnalyticsServicesManager.swift index 4845f0bff0..682407ac43 100644 --- a/Loop/Managers/AnalyticsServicesManager.swift +++ b/Loop/Managers/AnalyticsServicesManager.swift @@ -9,6 +9,7 @@ import Foundation import LoopKit import LoopCore +import HealthKit final class AnalyticsServicesManager { @@ -35,18 +36,44 @@ final class AnalyticsServicesManager { analyticsServices.forEach { $0.recordAnalyticsEvent(name, withProperties: properties, outOfSession: outOfSession) } } + private func identify(_ property: String, value: String) { + log.debug("Identify %{public}@: %{public}@", property, value) + analyticsServices.forEach { $0.recordIdentify(property, value: value) } + } + // MARK: - UIApplicationDelegate func application(didFinishLaunchingWithOptions launchOptions: [AnyHashable: Any]?) { logEvent("App Launch") } + func identifyAppName(_ appName: String) { + identify("App Name", value: appName) + } + + func identifyWorkspaceGitRevision(_ revision: String) { + identify("Workspace Revision", value: revision) + } + + // MARK: - Device Type + func identifyPumpType(_ pumpType: String) { + identify("Pump Type", value: pumpType) + } + + func identifyCGMType(_ cgmType: String) { + identify("CGM Type", value: cgmType) + } + // MARK: - Screens func didDisplayBolusScreen() { logEvent("Bolus Screen") } + func didDisplayCarbEntryScreen() { + logEvent("Carb Entry Screen") + } + func didDisplaySettingsScreen() { logEvent("Settings Screen") } @@ -121,16 +148,32 @@ final class AnalyticsServicesManager { // MARK: - Loop Events - func didAddCarbsFromWatch() { - logEvent("Carb entry created", withProperties: ["source" : "Watch"], outOfSession: true) + func pumpWasRemoved() { + logEvent("Pump Removed") + } + + func pumpWasAdded(identifier: String) { + logEvent("Pump Added", withProperties: ["identifier" : identifier]) + } + + func cgmWasRemoved() { + logEvent("CGM Removed") + } + + func cgmWasAdded(identifier: String) { + logEvent("CGM Added", withProperties: ["identifier" : identifier]) + } + + func didAddCarbs(source: String, amount: Double, inSession: Bool = false) { + logEvent("Carb entry created", withProperties: ["source" : source, "amount": "\(amount)"], outOfSession: inSession) } func didRetryBolus() { - logEvent("Bolus Retry", outOfSession: true) + logEvent("Bolus Retry") } - func didSetBolusFromWatch(_ units: Double) { - logEvent("Bolus set", withProperties: ["source" : "Watch"], outOfSession: true) + func didBolus(source: String, units: Double, inSession: Bool = false) { + logEvent("Bolus set", withProperties: ["source" : source, "units": "\(units)"], outOfSession: true) } func didFetchNewCGMData() { @@ -141,8 +184,72 @@ final class AnalyticsServicesManager { logEvent("Loop success", withProperties: ["duration": duration], outOfSession: true) } - func loopDidError(error: Error) { - logEvent("Loop error", withProperties: ["description": error.localizedDescription], outOfSession: true) + func loopDidError(error: LoopError) { + var props = [AnyHashable: Any]() + + props["issueId"] = error.issueId + + for (detailKey, detail) in error.issueDetails { + props[detailKey] = detail + } + + logEvent("Loop error", withProperties: props, outOfSession: true) + } + + func didIssueAlert(identifier: String, interruptionLevel: Alert.InterruptionLevel) { + logEvent("Alert Issued", withProperties: ["identifier": identifier, "interruptionLevel": interruptionLevel.rawValue]) + } + + func didEnactOverride(name: String, symbol: String, duration: TemporaryScheduleOverride.Duration, insulinSensitivityMultiplier: Double = 1.0, targetRange: ClosedRange? = nil) + { + let combinedName = "\(symbol) - \(name)" + + var properties: [String: Any] = [ + "name": name, + "symbol": symbol, + "sensitivityMultiplier": insulinSensitivityMultiplier, + "nameWithEmoji": combinedName + ] + + if let targetUpperBound = targetRange?.upperBound.doubleValue(for: HKUnit.milligramsPerDeciliter) { + properties["targetUpperBound"] = targetUpperBound + } + if let targetLowerBound = targetRange?.lowerBound.doubleValue(for: HKUnit.milligramsPerDeciliter) { + properties["targetLowerBound"] = targetLowerBound + } + + + logEvent("Override Enacted", withProperties: properties) + } + + func didCancelOverride(name: String) { + logEvent("Override Canceled", withProperties: ["name": name]) } +} + +// MARK: - PresetActivationObserver +extension AnalyticsServicesManager: PresetActivationObserver { + func presetActivated(context: TemporaryScheduleOverride.Context, duration: TemporaryScheduleOverride.Duration) { + switch context { + case .legacyWorkout: + didEnactOverride(name: "workout", symbol: "", duration: duration) + case .preMeal: + didEnactOverride(name: "preMeal", symbol: "", duration: duration) + case .custom: + didEnactOverride(name: "custom", symbol: "", duration: duration) + case .preset(let preset): + didEnactOverride(name: preset.name, symbol: preset.symbol, duration: duration, insulinSensitivityMultiplier: preset.settings.effectiveInsulinNeedsScaleFactor, targetRange: preset.settings.targetRange) + } + } + + func presetDeactivated(context: TemporaryScheduleOverride.Context) { + switch context { + case .legacyWorkout: + break + default: + break + } + } } + diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 05edfdd587..fda9e3677d 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -94,6 +94,15 @@ final class DeviceDataManager { didSet { dispatchPrecondition(condition: .onQueue(.main)) setupCGM() + + if cgmManager?.managerIdentifier != oldValue?.managerIdentifier { + if let cgmManager = cgmManager { + analyticsServicesManager.cgmWasAdded(identifier: cgmManager.managerIdentifier) + } else { + analyticsServicesManager.cgmWasRemoved() + } + } + NotificationCenter.default.post(name: .CGMManagerChanged, object: self, userInfo: nil) rawCGMManager = cgmManager?.rawValue UserDefaults.appGroup?.clearLegacyCGMManagerRawValue() @@ -114,6 +123,14 @@ final class DeviceDataManager { cgmManager = nil } + if pumpManager?.managerIdentifier != oldValue?.managerIdentifier { + if let pumpManager = pumpManager { + analyticsServicesManager.pumpWasAdded(identifier: pumpManager.managerIdentifier) + } else { + analyticsServicesManager.pumpWasRemoved() + } + } + setupPump() NotificationCenter.default.post(name: .PumpManagerChanged, object: self, userInfo: nil) @@ -201,8 +218,6 @@ final class DeviceDataManager { var analyticsServicesManager: AnalyticsServicesManager - var loggingServicesManager: LoggingServicesManager - var settingsManager: SettingsManager var remoteDataServicesManager: RemoteDataServicesManager { return servicesManager.remoteDataServicesManager } @@ -230,6 +245,8 @@ final class DeviceDataManager { init(pluginManager: PluginManager, alertManager: AlertManager, settingsManager: SettingsManager, + loggingServicesManager: LoggingServicesManager, + analyticsServicesManager: AnalyticsServicesManager, bluetoothProvider: BluetoothProvider, alertPresenter: AlertPresenter, automaticDosingStatus: AutomaticDosingStatus, @@ -251,9 +268,6 @@ final class DeviceDataManager { } deviceLog = PersistentDeviceLog(storageFile: deviceLogDirectory.appendingPathComponent("Storage.sqlite"), maxEntryAge: localCacheDuration) - loggingServicesManager = LoggingServicesManager() - analyticsServicesManager = AnalyticsServicesManager() - self.pluginManager = pluginManager self.alertManager = alertManager self.bluetoothProvider = bluetoothProvider @@ -286,6 +300,8 @@ final class DeviceDataManager { } else { insulinModelProvider = PresetInsulinModelProvider(defaultRapidActingModel: nil) } + + self.analyticsServicesManager = analyticsServicesManager self.doseStore = DoseStore( healthStore: healthStore, @@ -369,7 +385,8 @@ final class DeviceDataManager { trustedTimeOffset: { trustedTimeChecker.detectedSystemTimeOffset } ) cacheStore.delegate = loopManager - loopManager.presetActivationObserver = alertManager + loopManager.presetActivationObservers.append(alertManager) + loopManager.presetActivationObservers.append(analyticsServicesManager) watchManager = WatchDataManager(deviceManager: self, healthStore: healthStore) @@ -389,6 +406,7 @@ final class DeviceDataManager { servicesManager = ServicesManager( pluginManager: pluginManager, + alertManager: alertManager, analyticsServicesManager: analyticsServicesManager, loggingServicesManager: loggingServicesManager, remoteDataServicesManager: remoteDataServicesManager @@ -717,6 +735,8 @@ private extension DeviceDataManager { alertManager?.addAlertSoundVendor(managerIdentifier: cgmManager.managerIdentifier, soundVendor: cgmManager) cgmHasValidSensorSession = cgmManager.cgmManagerStatus.hasValidSensorSession + + analyticsServicesManager.identifyCGMType(cgmManager.managerIdentifier) } if let cgmManagerUI = cgmManager as? CGMManagerUI { @@ -744,6 +764,8 @@ private extension DeviceDataManager { soundVendor: pumpManager) deliveryUncertaintyAlertManager = DeliveryUncertaintyAlertManager(pumpManager: pumpManager, alertPresenter: alertPresenter) + + analyticsServicesManager.identifyPumpType(pumpManager.managerIdentifier) } } @@ -762,28 +784,43 @@ extension DeviceDataManager { return } - self.loopManager.addRequestedBolus(DoseEntry(type: .bolus, startDate: Date(), value: units, unit: .units, isMutable: true), completion: nil) - pumpManager.enactBolus(units: units, activationType: activationType) { (error) in - if let error = error { - self.log.error("%{public}@", String(describing: error)) - switch error { - case .uncertainDelivery: - // Do not generate notification on uncertain delivery error - break - default: - // Do not generate notifications for automatic boluses that fail. - if !activationType.isAutomatic { - NotificationManager.sendBolusFailureNotification(for: error, units: units, at: Date(), activationType: activationType) + self.loopManager.addRequestedBolus(DoseEntry(type: .bolus, startDate: Date(), value: units, unit: .units, isMutable: true)) { + pumpManager.enactBolus(units: units, activationType: activationType) { (error) in + if let error = error { + self.log.error("%{public}@", String(describing: error)) + switch error { + case .uncertainDelivery: + // Do not generate notification on uncertain delivery error + break + default: + // Do not generate notifications for automatic boluses that fail. + if !activationType.isAutomatic { + NotificationManager.sendBolusFailureNotification(for: error, units: units, at: Date(), activationType: activationType) + } + } + + self.loopManager.bolusRequestFailed(error) { + completion(error) + } + } else { + self.loopManager.bolusConfirmed() { + completion(nil) } } - - self.loopManager.bolusRequestFailed(error) { - completion(error) - } - } else { - self.loopManager.bolusConfirmed() { - completion(nil) + } + // Trigger forecast/recommendation update for remote clients + self.loopManager.updateRemoteRecommendation() + } + } + + func enactBolus(units: Double, activationType: BolusActivationType) async throws { + return try await withCheckedThrowingContinuation { continuation in + enactBolus(units: units, activationType: activationType) { error in + if let error = error { + continuation.resume(throwing: error) + return } + continuation.resume() } } } @@ -1284,6 +1321,10 @@ extension DeviceDataManager: LoopDataManagerDelegate { return rounded } + + func loopDataManager(_ manager: LoopDataManager, estimateBolusDuration units: Double) -> TimeInterval? { + pumpManager?.estimatedDuration(toBolus: units) + } func loopDataManager( _ manager: LoopDataManager, @@ -1318,112 +1359,149 @@ extension Notification.Name { // MARK: - Remote Notification Handling extension DeviceDataManager { + func handleRemoteNotification(_ notification: [String: AnyObject]) { - + Task { + let backgroundTask = await beginBackgroundTask(name: "Remote Data Upload") + await handleRemoteNotification(notification) + await endBackgroundTask(backgroundTask) + } + } + + func handleRemoteNotification(_ notification: [String: AnyObject]) async { + defer { - log.info("Finished handling remote notification") + log.default("Remote Notification: Finished handling") } guard FeatureFlags.remoteCommandsEnabled else { + log.error("Remote Notification: Remote Commands not enabled.") return } - - if let expirationStr = notification["expiration"] as? String { - let formatter = ISO8601DateFormatter() - formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] - if let expiration = formatter.date(from: expirationStr) { - guard expiration > Date() else { - log.error("Expired notification: %{public}@", String(describing: notification)) - return - } - } else { - log.error("Invalid expiration: %{public}@", expirationStr) - return - } - } let command: RemoteCommand - do { - command = try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: loopManager.settings.overridePresets, defaultAbsorptionTime: carbStore.defaultAbsorptionTimes.medium).get() + command = try await remoteDataServicesManager.commandFromPushNotification(notification) } catch { - log.error("Remote Notification Error: %{public}@", String(describing: error)) + log.error("Remote Notification: Parse Error: %{public}@", String(describing: error)) return } - - switch command { - - case .temporaryScheduleOverride(let override): - log.default("Enacting remote temporary override: %{public}@", String(describing: override)) - loopManager.mutateSettings { settings in settings.scheduleOverride = override } - case .cancelTemporaryOverride: - log.default("Canceling temporary override from remote command") - loopManager.mutateSettings { settings in settings.scheduleOverride = nil } - case .bolusEntry(let bolusAmount): - log.default("Enacting remote bolus entry: %{public}@", String(describing: bolusAmount)) - - //Remote bolus requires validation from its remote source - guard remoteDataServicesManager.validatePushNotificationSource(notification) else { - NotificationManager.sendRemoteBolusFailureNotification(for: RemoteCommandError.invalidOTP, amount: bolusAmount) - log.info("Could not validate notification: %{public}@", String(describing: notification)) - return - } - - guard let maxBolusAmount = loopManager.settings.maximumBolus else { - NotificationManager.sendRemoteBolusFailureNotification(for: RemoteCommandError.missingMaxBolus, amount: bolusAmount) - log.default("No max bolus detected. Aborting...") - return - } - - guard bolusAmount.isLessThanOrEqualTo(maxBolusAmount) else { - NotificationManager.sendRemoteBolusFailureNotification(for: RemoteCommandError.exceedsMaxBolus, amount: bolusAmount) - log.default("Remote bolus higher than maximum. Aborting...") - return - } - - // For remote boluses, assume manual no recommendation. - self.enactBolus(units: bolusAmount, activationType: .manualNoRecommendation) { error in - if let error = error { - NotificationManager.sendRemoteBolusFailureNotification(for: error, amount: bolusAmount) - } else { - NotificationManager.sendRemoteBolusNotification(amount: bolusAmount) - } + + await handleRemoteCommand(command) + } + + func handleRemoteCommand(_ command: RemoteCommand) async { + + log.default("Remote Notification: Handling command %{public}@", String(describing: command)) + + switch command.action { + case .temporaryScheduleOverride(let overrideAction): + do { + try command.validate() + try await handleOverrideAction(overrideAction) + } catch { + log.error("Remote Notification: Override Action Error: %{public}@", String(describing: error)) } - case .carbsEntry(let candidateCarbEntry): - log.default("Adding carbs entry.") - - let candidateCarbsInGrams = candidateCarbEntry.quantity.doubleValue(for: .gram()) - - //Remote carb entry requires validation from its remote source - guard remoteDataServicesManager.validatePushNotificationSource(notification) else { - NotificationManager.sendRemoteCarbEntryFailureNotification(for: RemoteCommandError.invalidOTP, amountInGrams: candidateCarbsInGrams) - log.info("Could not validate notification: %{public}@", String(describing: notification)) - return + case .cancelTemporaryOverride(let overrideCancelAction): + do { + try command.validate() + try await handleOverrideCancelAction(overrideCancelAction) + } catch { + log.error("Remote Notification: Override Action Cancel Error: %{public}@", String(describing: error)) } - - guard candidateCarbsInGrams > 0.0 else { - NotificationManager.sendRemoteCarbEntryFailureNotification(for: RemoteCommandError.invalidCarbs, amountInGrams: candidateCarbsInGrams) - log.default("Invalid carb entry amount. Aborting...") - return + case .bolusEntry(let bolusAction): + do { + try command.validate() + try await handleBolusAction(bolusAction) + } catch { + await NotificationManager.sendRemoteBolusFailureNotification(for: error, amount: bolusAction.amountInUnits) + log.error("Remote Notification: Bolus Action Error: %{public}@", String(describing: error)) } - - guard candidateCarbsInGrams <= LoopConstants.maxCarbEntryQuantity.doubleValue(for: .gram()) else { - NotificationManager.sendRemoteCarbEntryFailureNotification(for: RemoteCommandError.exceedsMaxCarbs, amountInGrams: candidateCarbsInGrams) - log.default("Carbs higher than maximum. Aborting...") - return + case .carbsEntry(let carbAction): + do { + try command.validate() + try await handleCarbAction(carbAction) + } catch { + await NotificationManager.sendRemoteCarbEntryFailureNotification(for: error, amountInGrams: carbAction.amountInGrams) + log.error("Remote Notification: Carb Action Error: %{public}@", String(describing: error)) } - - carbStore.addCarbEntry(candidateCarbEntry) { carbEntryAddResult in - switch carbEntryAddResult { - case .success(let completedCarbEntry): - NotificationManager.sendRemoteCarbEntryNotification(amountInGrams: completedCarbEntry.quantity.doubleValue(for: .gram())) + } + } + + //Remote Overrides + + func handleOverrideAction(_ action: OverrideAction) async throws { + let remoteOverride = try action.toValidOverride(allowedPresets: loopManager.settings.overridePresets) + await activateRemoteOverride(remoteOverride) + } + + func handleOverrideCancelAction(_ action: OverrideCancelAction) async throws { + await activateRemoteOverride(nil) + } + + func activateRemoteOverride(_ remoteOverride: TemporaryScheduleOverride?) async { + loopManager.mutateSettings { settings in settings.scheduleOverride = remoteOverride } + await remoteDataServicesManager.triggerUpload(for: .overrides) + } + + //Remote Bolus + + func handleBolusAction(_ action: BolusAction) async throws { + let validBolusAmount = try action.toValidBolusAmount(maximumBolus: loopManager.settings.maximumBolus) + try await self.enactBolus(units: validBolusAmount, activationType: .manualNoRecommendation) + await remoteDataServicesManager.triggerUpload(for: .dose) + self.analyticsServicesManager.didBolus(source: "Remote", units: validBolusAmount) + } + + //Remote Carb Entry + + func handleCarbAction(_ action: CarbAction) async throws { + let candidateCarbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: carbStore.defaultAbsorptionTimes.medium, + minAbsorptionTime: LoopConstants.minCarbAbsorptionTime, + maxAbsorptionTime: LoopConstants.maxCarbAbsorptionTime, + maxCarbEntryQuantity: LoopConstants.maxCarbEntryQuantity.doubleValue(for: .gram()), + maxCarbEntryPastTime: LoopConstants.maxCarbEntryPastTime, + maxCarbEntryFutureTime: LoopConstants.maxCarbEntryFutureTime + ) + + let _ = try await addRemoteCarbEntry(candidateCarbEntry) + await remoteDataServicesManager.triggerUpload(for: .carb) + } + + //Can't add this concurrency wrapper method to LoopKit due to the minimum iOS version + func addRemoteCarbEntry(_ carbEntry: NewCarbEntry) async throws -> StoredCarbEntry { + return try await withCheckedThrowingContinuation { continuation in + carbStore.addCarbEntry(carbEntry) { result in + switch result { + case .success(let storedCarbEntry): + self.analyticsServicesManager.didAddCarbs(source: "Remote", amount: carbEntry.quantity.doubleValue(for: .gram())) + continuation.resume(returning: storedCarbEntry) case .failure(let error): - NotificationManager.sendRemoteCarbEntryFailureNotification(for: error, amountInGrams: candidateCarbsInGrams) + continuation.resume(throwing: error) } } } - // Wait up to 25 seconds for uploads triggered by these commands to finish - let _ = remoteDataServicesManager.waitForUploadsToFinish(timeout: .now() + TimeInterval(25)) + } + + //Background Uploads + + func beginBackgroundTask(name: String) async -> UIBackgroundTaskIdentifier? { + var backgroundTask: UIBackgroundTaskIdentifier? + backgroundTask = await UIApplication.shared.beginBackgroundTask(withName: name) { + guard let backgroundTask = backgroundTask else {return} + Task { + await UIApplication.shared.endBackgroundTask(backgroundTask) + } + + self.log.error("Background Task Expired: %{public}@", name) + } + + return backgroundTask + } + + func endBackgroundTask(_ backgroundTask: UIBackgroundTaskIdentifier?) async { + guard let backgroundTask else {return} + await UIApplication.shared.endBackgroundTask(backgroundTask) } } diff --git a/Loop/Managers/DoseMath.swift b/Loop/Managers/DoseMath.swift index 01c9bedfe5..e13a36139a 100644 --- a/Loop/Managers/DoseMath.swift +++ b/Loop/Managers/DoseMath.swift @@ -122,7 +122,7 @@ extension InsulinCorrection { let partialDose = units * partialApplicationFactor - return Swift.min(Swift.max(0, volumeRounder?(partialDose) ?? partialDose),maxBolusUnits) + return Swift.min(Swift.max(0, volumeRounder?(partialDose) ?? partialDose),volumeRounder?(maxBolusUnits) ?? maxBolusUnits) } } @@ -298,24 +298,24 @@ extension Collection where Element: GlucoseValue { minCorrectionUnits = correctionUnits } - guard let eventual = eventualGlucose, let min = minGlucose else { + guard let eventualGlucose, let minGlucose else { return nil } // Choose either the minimum glucose or eventual glucose as the correction delta - let minGlucoseTargets = correctionRange.quantityRange(at: min.startDate) - let eventualGlucoseTargets = correctionRange.quantityRange(at: eventual.startDate) + let minGlucoseTargets = correctionRange.quantityRange(at: minGlucose.startDate) + let eventualGlucoseTargets = correctionRange.quantityRange(at: eventualGlucose.startDate) // Treat the mininum glucose when both are below range - if min.quantity < minGlucoseTargets.lowerBound && - eventual.quantity < eventualGlucoseTargets.lowerBound + if minGlucose.quantity < minGlucoseTargets.lowerBound && + eventualGlucose.quantity < eventualGlucoseTargets.lowerBound { - let time = min.startDate.timeIntervalSince(date) + let time = minGlucose.startDate.timeIntervalSince(date) // For 0 <= time <= effectDelay, assume a small amount effected. This will result in large (negative) unit recommendation rather than no recommendation at all. let percentEffected = Swift.max(.ulpOfOne, 1 - model.percentEffectRemaining(at: time)) guard let units = insulinCorrectionUnits( - fromValue: min.quantity.doubleValue(for: unit), + fromValue: minGlucose.quantity.doubleValue(for: unit), toValue: minGlucoseTargets.averageValue(for: unit), effectedSensitivity: sensitivityValue * percentEffected ) else { @@ -323,15 +323,15 @@ extension Collection where Element: GlucoseValue { } return .entirelyBelowRange( - min: min, + min: minGlucose, minTarget: minGlucoseTargets.lowerBound, units: units ) - } else if eventual.quantity > eventualGlucoseTargets.upperBound, + } else if eventualGlucose.quantity > eventualGlucoseTargets.upperBound, let minCorrectionUnits = minCorrectionUnits, let correctingGlucose = correctingGlucose { return .aboveRange( - min: min, + min: minGlucose, correcting: correctingGlucose, minTarget: eventualGlucoseTargets.lowerBound, units: minCorrectionUnits @@ -352,6 +352,7 @@ extension Collection where Element: GlucoseValue { /// - sensitivity: The schedule of insulin sensitivities /// - model: The insulin absorption model /// - basalRates: The schedule of basal rates + /// - additionalActiveInsulinClamp: Max amount of additional insulin above scheduled basal rate allowed to be scheduled /// - maxBasalRate: The maximum allowed basal rate /// - lastTempBasal: The previously set temp basal /// - rateRounder: Closure that rounds recommendation to nearest supported rate. If nil, no rounding is performed @@ -367,6 +368,7 @@ extension Collection where Element: GlucoseValue { model: InsulinModel, basalRates: BasalRateSchedule, maxBasalRate: Double, + additionalActiveInsulinClamp: Double? = nil, lastTempBasal: DoseEntry?, rateRounder: ((Double) -> Double)? = nil, isBasalRateScheduleOverrideActive: Bool = false, @@ -391,6 +393,11 @@ extension Collection where Element: GlucoseValue { maxBasalRate = scheduledBasalRate } + if let additionalActiveInsulinClamp { + let maxThirtyMinuteRateToKeepIOBBelowLimit = additionalActiveInsulinClamp * 2.0 + scheduledBasalRate // 30 minutes of a U/hr rate + maxBasalRate = Swift.min(maxThirtyMinuteRateToKeepIOBBelowLimit, maxBasalRate) + } + let temp = correction?.asTempBasal( scheduledBasalRate: scheduledBasalRate, maxBasalRate: maxBasalRate, diff --git a/Loop/Managers/LoopAppManager.swift b/Loop/Managers/LoopAppManager.swift index 9398eb6a8e..76829cb4e8 100644 --- a/Loop/Managers/LoopAppManager.swift +++ b/Loop/Managers/LoopAppManager.swift @@ -11,11 +11,16 @@ import Intents import Combine import LoopKit import LoopKitUI -import TidepoolKit import MockKit import HealthKit import WidgetKit +#if targetEnvironment(simulator) +enum SimulatorError: Error { + case remoteNotificationsNotAvailable +} +#endif + public protocol AlertPresenter: AnyObject { /// Present the alert view controller, with or without animation. /// - Parameters: @@ -74,6 +79,9 @@ class LoopAppManager: NSObject { private var alertPermissionsChecker: AlertPermissionsChecker! private var supportManager: SupportManager! private var settingsManager: SettingsManager! + private var loggingServicesManager = LoggingServicesManager() + private var analyticsServicesManager = AnalyticsServicesManager() + private var overrideHistory = UserDefaults.appGroup?.overrideHistory ?? TemporaryScheduleOverrideHistory.init() private var state: State = .initialize @@ -100,10 +108,13 @@ class LoopAppManager: NSObject { if FeatureFlags.remoteCommandsEnabled { DispatchQueue.main.async { +#if targetEnvironment(simulator) + self.remoteNotificationRegistrationDidFinish(.failure(SimulatorError.remoteNotificationsNotAvailable)) +#else UIApplication.shared.registerForRemoteNotifications() +#endif } } - self.state = state.next } @@ -156,32 +167,42 @@ class LoopAppManager: NSObject { let localCacheDuration = Bundle.main.localCacheDuration let cacheStore = PersistenceController.controllerInAppGroupDirectory() - self.pluginManager = PluginManager() - self.bluetoothStateManager = BluetoothStateManager() - self.alertManager = AlertManager(alertPresenter: self, - userNotificationAlertScheduler: UserNotificationAlertScheduler(userNotificationCenter: UNUserNotificationCenter.current()), - expireAfter: Bundle.main.localCacheDuration, - bluetoothProvider: bluetoothStateManager) + pluginManager = PluginManager() - self.alertPermissionsChecker = AlertPermissionsChecker() - self.alertPermissionsChecker.delegate = alertManager + for support in pluginManager.availableSupports { + if let analyticsService = support as? AnalyticsService { + analyticsServicesManager.addService(analyticsService) + } + } + + bluetoothStateManager = BluetoothStateManager() + alertManager = AlertManager(alertPresenter: self, + userNotificationAlertScheduler: UserNotificationAlertScheduler(userNotificationCenter: UNUserNotificationCenter.current()), + expireAfter: Bundle.main.localCacheDuration, + bluetoothProvider: bluetoothStateManager, + analyticsServicesManager: analyticsServicesManager) + + alertPermissionsChecker = AlertPermissionsChecker() + alertPermissionsChecker.delegate = alertManager - self.trustedTimeChecker = TrustedTimeChecker(alertManager: alertManager) + trustedTimeChecker = TrustedTimeChecker(alertManager: alertManager) - self.settingsManager = SettingsManager(cacheStore: cacheStore, + settingsManager = SettingsManager(cacheStore: cacheStore, expireAfter: localCacheDuration, alertMuter: alertManager.alertMuter) - self.deviceDataManager = DeviceDataManager(pluginManager: pluginManager, - alertManager: alertManager, - settingsManager: settingsManager, - bluetoothProvider: bluetoothStateManager, - alertPresenter: self, - automaticDosingStatus: automaticDosingStatus, - cacheStore: cacheStore, - localCacheDuration: localCacheDuration, - overrideHistory: overrideHistory, - trustedTimeChecker: trustedTimeChecker + deviceDataManager = DeviceDataManager(pluginManager: pluginManager, + alertManager: alertManager, + settingsManager: settingsManager, + loggingServicesManager: loggingServicesManager, + analyticsServicesManager: analyticsServicesManager, + bluetoothProvider: bluetoothStateManager, + alertPresenter: self, + automaticDosingStatus: automaticDosingStatus, + cacheStore: cacheStore, + localCacheDuration: localCacheDuration, + overrideHistory: overrideHistory, + trustedTimeChecker: trustedTimeChecker ) settingsManager.deviceStatusProvider = deviceDataManager settingsManager.displayGlucoseUnitObservable = deviceDataManager.displayGlucoseUnitObservable @@ -189,20 +210,27 @@ class LoopAppManager: NSObject { overrideHistory.delegate = self - SharedLogging.instance = deviceDataManager.loggingServicesManager + SharedLogging.instance = loggingServicesManager scheduleBackgroundTasks() - self.onboardingManager = OnboardingManager(pluginManager: pluginManager, - bluetoothProvider: bluetoothStateManager, - deviceDataManager: deviceDataManager, - servicesManager: deviceDataManager.servicesManager, - loopDataManager: deviceDataManager.loopManager, - windowProvider: windowProvider, - userDefaults: UserDefaults.appGroup!) + onboardingManager = OnboardingManager(pluginManager: pluginManager, + bluetoothProvider: bluetoothStateManager, + deviceDataManager: deviceDataManager, + servicesManager: deviceDataManager.servicesManager, + loopDataManager: deviceDataManager.loopManager, + windowProvider: windowProvider, + userDefaults: UserDefaults.appGroup!) deviceDataManager.onboardingManager = onboardingManager - deviceDataManager.analyticsServicesManager.application(didFinishLaunchingWithOptions: launchOptions) + + analyticsServicesManager.identifyAppName(Bundle.main.bundleDisplayName) + + if let workspaceGitRevision = Bundle.main.workspaceGitRevision { + analyticsServicesManager.identifyWorkspaceGitRevision(workspaceGitRevision) + } + + analyticsServicesManager.application(didFinishLaunchingWithOptions: launchOptions) supportManager = SupportManager(pluginManager: pluginManager, deviceDataManager: deviceDataManager, @@ -215,7 +243,7 @@ class LoopAppManager: NSObject { .assign(to: \.automaticDosingStatus.automaticDosingEnabled, on: self) .store(in: &cancellables) - self.state = state.next + state = state.next } private func launchOnboarding() { @@ -468,7 +496,8 @@ extension LoopAppManager: UNUserNotificationCenterDelegate { LoopNotificationCategory.remoteBolus.rawValue, LoopNotificationCategory.remoteBolusFailure.rawValue, LoopNotificationCategory.remoteCarbs.rawValue, - LoopNotificationCategory.remoteCarbsFailure.rawValue: + LoopNotificationCategory.remoteCarbsFailure.rawValue, + LoopNotificationCategory.missedMeal.rawValue: completionHandler([.badge, .sound, .list, .banner]) default: // For all others, banners are not to be displayed while in the foreground @@ -500,6 +529,28 @@ extension LoopAppManager: UNUserNotificationCenterDelegate { let managerIdentifier = userInfo[LoopNotificationUserInfoKey.managerIDForAlert.rawValue] as? String { alertManager?.acknowledgeAlert(identifier: Alert.Identifier(managerIdentifier: managerIdentifier, alertIdentifier: alertIdentifier)) } + case UNNotificationDefaultActionIdentifier: + guard response.notification.request.identifier == LoopNotificationCategory.missedMeal.rawValue else { + break + } + + let carbActivity = NSUserActivity.forNewCarbEntry() + let userInfo = response.notification.request.content.userInfo + + if + let mealTime = userInfo[LoopNotificationUserInfoKey.missedMealTime.rawValue] as? Date, + let carbAmount = userInfo[LoopNotificationUserInfoKey.missedMealCarbAmount.rawValue] as? Double + { + let missedEntry = NewCarbEntry(quantity: HKQuantity(unit: .gram(), + doubleValue: carbAmount), + startDate: mealTime, + foodType: nil, + absorptionTime: nil) + carbActivity.update(from: missedEntry, isMissedMeal: true) + } + + rootViewController?.restoreUserActivityState(carbActivity) + default: break } diff --git a/Loop/Managers/LoopDataManager.swift b/Loop/Managers/LoopDataManager.swift index bfef3bbec6..ffc66ee314 100644 --- a/Loop/Managers/LoopDataManager.swift +++ b/Loop/Managers/LoopDataManager.swift @@ -30,6 +30,8 @@ final class LoopDataManager { static let LoopUpdateContextKey = "com.loudnate.Loop.LoopDataManager.LoopUpdateContext" private let carbStore: CarbStoreProtocol + + private let mealDetectionManager: MealDetectionManager private let doseStore: DoseStoreProtocol @@ -59,10 +61,12 @@ final class LoopDataManager { private var overrideIntentObserver: NSKeyValueObservation? = nil - weak var presetActivationObserver: PresetActivationObserver? + var presetActivationObservers: [PresetActivationObserver] = [] private var timeBasedDoseApplicationFactor: Double = 1.0 + private var insulinOnBoard: InsulinValue? + deinit { for observer in notificationObservers { NotificationCenter.default.removeObserver(observer) @@ -107,6 +111,11 @@ final class LoopDataManager { self.now = now self.latestStoredSettingsProvider = latestStoredSettingsProvider + self.mealDetectionManager = MealDetectionManager( + carbRatioScheduleApplyingOverrideHistory: carbStore.carbRatioScheduleApplyingOverrideHistory, + insulinSensitivityScheduleApplyingOverrideHistory: carbStore.insulinSensitivityScheduleApplyingOverrideHistory, + maximumBolus: settings.maximumBolus + ) self.lockedPumpInsulinType = Locked(pumpInsulinType) @@ -129,10 +138,18 @@ final class LoopDataManager { self?.logger.default("Override Intent: setting override named '%s'", String(describing: name)) self?.mutateSettings { settings in if let oldPreset = settings.scheduleOverride { - self?.presetActivationObserver?.presetDeactivated(context: oldPreset.context) + if let observers = self?.presetActivationObservers { + for observer in observers { + observer.presetDeactivated(context: oldPreset.context) + } + } } settings.scheduleOverride = preset.createOverride(enactTrigger: .remote("Siri")) - self?.presetActivationObserver?.presetActivated(context: .preset(preset), duration: preset.duration) + if let observers = self?.presetActivationObservers { + for observer in observers { + observer.presetActivated(context: .preset(preset), duration: preset.duration) + } + } } // Remove the override from UserDefaults so we don't set it multiple times appGroup.intentExtensionOverrideToSet = nil @@ -154,6 +171,7 @@ final class LoopDataManager { self.carbEffect = nil self.carbsOnBoard = nil self.recentCarbEntries = nil + self.remoteRecommendationNeedsUpdating = true self.notify(forChange: .carbs) } }, @@ -166,6 +184,7 @@ final class LoopDataManager { self.logger.default("Received notification of glucose samples changing") self.glucoseMomentumEffect = nil + self.remoteRecommendationNeedsUpdating = true self.notify(forChange: .glucose) } @@ -179,6 +198,7 @@ final class LoopDataManager { self.logger.default("Received notification of dosing changing") self.insulinEffect = nil + self.remoteRecommendationNeedsUpdating = true self.notify(forChange: .insulin) } @@ -233,19 +253,29 @@ final class LoopDataManager { overrideHistory.recordOverride(settings.scheduleOverride) if let oldPreset = oldValue.scheduleOverride { - self.presetActivationObserver?.presetDeactivated(context: oldPreset.context) + for observer in self.presetActivationObservers { + observer.presetDeactivated(context: oldPreset.context) + } + } if let newPreset = newValue.scheduleOverride { - self.presetActivationObserver?.presetActivated(context: newPreset.context, duration: newPreset.duration) + for observer in self.presetActivationObservers { + observer.presetActivated(context: newPreset.context, duration: newPreset.duration) + } } // Invalidate cached effects affected by the override invalidateCachedEffects = true + + // Update the affected schedules + mealDetectionManager.carbRatioScheduleApplyingOverrideHistory = carbRatioScheduleApplyingOverrideHistory + mealDetectionManager.insulinSensitivityScheduleApplyingOverrideHistory = insulinSensitivityScheduleApplyingOverrideHistory } if newValue.insulinSensitivitySchedule != oldValue.insulinSensitivitySchedule { carbStore.insulinSensitivitySchedule = newValue.insulinSensitivitySchedule doseStore.insulinSensitivitySchedule = newValue.insulinSensitivitySchedule + mealDetectionManager.insulinSensitivityScheduleApplyingOverrideHistory = insulinSensitivityScheduleApplyingOverrideHistory invalidateCachedEffects = true analyticsServicesManager.didChangeInsulinSensitivitySchedule() } @@ -260,6 +290,7 @@ final class LoopDataManager { if newValue.carbRatioSchedule != oldValue.carbRatioSchedule { carbStore.carbRatioSchedule = newValue.carbRatioSchedule + mealDetectionManager.carbRatioScheduleApplyingOverrideHistory = carbRatioScheduleApplyingOverrideHistory invalidateCachedEffects = true analyticsServicesManager.didChangeCarbRatioSchedule() } @@ -274,6 +305,10 @@ final class LoopDataManager { analyticsServicesManager.didChangeInsulinModel() } + if newValue.maximumBolus != oldValue.maximumBolus { + mealDetectionManager.maximumBolus = newValue.maximumBolus + } + if invalidateCachedEffects { dataAccessQueue.async { // Invalidate cached effects based on this schedule @@ -437,6 +472,37 @@ final class LoopDataManager { dosingDecisionWithError.appendError(error) dosingDecisionStore.storeDosingDecision(dosingDecisionWithError) {} } + + // This is primarily for remote clients displaying a bolus recommendation and forecast + // Should be called after any significant change to forecast input data. + + + var remoteRecommendationNeedsUpdating: Bool = false + + func updateRemoteRecommendation() { + dataAccessQueue.async { + if self.remoteRecommendationNeedsUpdating { + var (dosingDecision, updateError) = self.update(for: .updateRemoteRecommendation) + + if let error = updateError { + self.logger.error("Error updating manual bolus recommendation: %{public}@", String(describing: error)) + } else { + do { + if let predictedGlucoseIncludingPendingInsulin = self.predictedGlucoseIncludingPendingInsulin, + let manualBolusRecommendation = try self.recommendManualBolus(forPrediction: predictedGlucoseIncludingPendingInsulin, consideringPotentialCarbEntry: nil) + { + dosingDecision.manualBolusRecommendation = ManualBolusRecommendationWithDate(recommendation: manualBolusRecommendation, date: Date()) + self.logger.debug("Manual bolus rec = %{public}@", String(describing: dosingDecision.manualBolusRecommendation)) + self.dosingDecisionStore.storeDosingDecision(dosingDecision) {} + } + } catch { + self.logger.error("Error updating manual bolus recommendation: %{public}@", String(describing: error)) + } + } + self.remoteRecommendationNeedsUpdating = false + } + } + } } // MARK: Background task management @@ -605,7 +671,6 @@ extension LoopDataManager { func deleteCarbEntry(_ oldEntry: StoredCarbEntry, completion: @escaping (_ result: CarbStoreResult) -> Void) { carbStore.deleteCarbEntry(oldEntry) { result in completion(result) - self.updateRecommendedManualBolus() } } @@ -809,43 +874,43 @@ extension LoopDataManager { logger.default("Loop ended") notify(forChange: .loopFinished) + if FeatureFlags.missedMealNotifications { + let carbEffectStart = now().addingTimeInterval(-MissedMealSettings.maxRecency) + carbStore.getGlucoseEffects(start: carbEffectStart, end: now(), effectVelocities: insulinCounteractionEffects) {[weak self] result in + guard + let self = self, + case .success((_, let carbEffects)) = result + else { + if case .failure(let error) = result { + self?.logger.error("Failed to fetch glucose effects to check for missed meal: %{public}@", String(describing: error)) + } + return + } + + self.mealDetectionManager.generateMissedMealNotificationIfNeeded( + insulinCounteractionEffects: self.insulinCounteractionEffects, + carbEffects: carbEffects, + pendingAutobolusUnits: self.recommendedAutomaticDose?.recommendation.bolusUnits, + bolusDurationEstimator: { [unowned self] bolusAmount in + return self.delegate?.loopDataManager(self, estimateBolusDuration: bolusAmount) + } + ) + } + } + // 5 second delay to allow stores to cache data before it is read by widget DispatchQueue.main.asyncAfter(deadline: .now() + 5) { self.widgetLog.default("Refreshing widget. Reason: Loop completed") WidgetCenter.shared.reloadAllTimelines() } - updateRecommendedManualBolus() - } - - // This is primarily for external clients displaying a bolus recommendation and forecast - // Should be called after any significant change to forecast input data. - private func updateRecommendedManualBolus() { - dataAccessQueue.async { - var (dosingDecision, updateError) = self.update(for: .updateRecommendedManualBolus) - - if let error = updateError { - self.logger.error("Error updating manual bolus recommendation: %{public}@", String(describing: error)) - } else { - do { - if let predictedGlucoseIncludingPendingInsulin = self.predictedGlucoseIncludingPendingInsulin, - let manualBolusRecommendation = try self.recommendManualBolus(forPrediction: predictedGlucoseIncludingPendingInsulin, consideringPotentialCarbEntry: nil) - { - dosingDecision.manualBolusRecommendation = ManualBolusRecommendationWithDate(recommendation: manualBolusRecommendation, date: Date()) - self.logger.debug("Manual bolus rec = %{public}@", String(describing: dosingDecision.manualBolusRecommendation)) - self.dosingDecisionStore.storeDosingDecision(dosingDecision) {} - } - } catch { - self.logger.error("Error updating manual bolus recommendation: %{public}@", String(describing: error)) - } - } - } + updateRemoteRecommendation() } fileprivate enum UpdateReason: String { case loop case getLoopState - case updateRecommendedManualBolus + case updateRemoteRecommendation } fileprivate func update(for reason: UpdateReason) -> (StoredDosingDecision, LoopError?) { @@ -1012,16 +1077,13 @@ extension LoopDataManager { updateGroup.leave() } } - - var insulinOnBoard: InsulinValue? - updateGroup.enter() doseStore.insulinOnBoard(at: now()) { result in switch result { case .failure(let error): warnings.append(.fetchDataWarning(.insulinOnBoard(error: error))) case .success(let insulinValue): - insulinOnBoard = insulinValue + self.insulinOnBoard = insulinValue } updateGroup.leave() } @@ -1042,7 +1104,7 @@ extension LoopDataManager { dosingDecision.date = now() dosingDecision.historicalGlucose = historicalGlucose dosingDecision.carbsOnBoard = carbsOnBoard - dosingDecision.insulinOnBoard = insulinOnBoard + dosingDecision.insulinOnBoard = self.insulinOnBoard dosingDecision.glucoseTargetRangeSchedule = settings.effectiveGlucoseTargetRangeSchedule() // These will be updated by updatePredictedGlucoseAndRecommendedDose, if possible @@ -1108,6 +1170,7 @@ extension LoopDataManager { /// - LoopError.missingDataError /// - LoopError.configurationError /// - LoopError.glucoseTooOld + /// - LoopError.invalidFutureGlucose /// - LoopError.pumpDataTooOld fileprivate func predictGlucose( startingAt startingGlucoseOverride: GlucoseValue? = nil, @@ -1134,6 +1197,10 @@ extension LoopDataManager { throw LoopError.glucoseTooOld(date: glucose.startDate) } + guard lastGlucoseDate.timeIntervalSince(now()) <= LoopCoreConstants.futureGlucoseDataInterval else { + throw LoopError.invalidFutureGlucose(date: lastGlucoseDate) + } + guard now().timeIntervalSince(pumpStatusDate) <= LoopCoreConstants.inputDataRecencyInterval else { throw LoopError.pumpDataTooOld(date: pumpStatusDate) } @@ -1368,6 +1435,7 @@ extension LoopDataManager { /// - Throws: /// - LoopError.missingDataError /// - LoopError.glucoseTooOld + /// - LoopError.invalidFutureGlucose /// - LoopError.pumpDataTooOld /// - LoopError.configurationError fileprivate func recommendBolusValidatingDataRecency(forPrediction predictedGlucose: [Sample], @@ -1383,6 +1451,10 @@ extension LoopDataManager { throw LoopError.glucoseTooOld(date: glucose.startDate) } + guard lastGlucoseDate.timeIntervalSince(now()) <= LoopCoreConstants.inputDataRecencyInterval else { + throw LoopError.invalidFutureGlucose(date: lastGlucoseDate) + } + guard now().timeIntervalSince(pumpStatusDate) <= LoopCoreConstants.inputDataRecencyInterval else { throw LoopError.pumpDataTooOld(date: pumpStatusDate) } @@ -1494,6 +1566,7 @@ extension LoopDataManager { /// - Throws: /// - LoopError.configurationError /// - LoopError.glucoseTooOld + /// - LoopError.invalidFutureGlucose /// - LoopError.missingDataError /// - LoopError.pumpDataTooOld private func updatePredictedGlucoseAndRecommendedDose(with dosingDecision: StoredDosingDecision) -> (StoredDosingDecision, LoopError?) { @@ -1517,6 +1590,10 @@ extension LoopDataManager { errors.append(.glucoseTooOld(date: glucose.startDate)) } + if glucose.startDate.timeIntervalSince(startDate) > LoopCoreConstants.inputDataRecencyInterval { + errors.append(.invalidFutureGlucose(date: glucose.startDate)) + } + let pumpStatusDate = doseStore.lastAddedPumpData if startDate.timeIntervalSince(pumpStatusDate) > LoopCoreConstants.inputDataRecencyInterval { @@ -1528,8 +1605,8 @@ extension LoopDataManager { errors.append(.configurationError(.glucoseTargetRangeSchedule)) } - let basalRates = basalRateScheduleApplyingOverrideHistory - if basalRates == nil { + let basalRateSchedule = basalRateScheduleApplyingOverrideHistory + if basalRateSchedule == nil { errors.append(.configurationError(.basalRateSchedule)) } @@ -1568,6 +1645,10 @@ extension LoopDataManager { errors.append(.missingDataError(.insulinEffectIncludingPendingInsulin)) } + if self.insulinOnBoard == nil { + errors.append(.missingDataError(.activeInsulin)) + } + dosingDecision.appendErrors(errors) if let error = errors.first { logger.error("%{public}@", String(describing: error)) @@ -1607,20 +1688,26 @@ extension LoopDataManager { let dosingRecommendation: AutomaticDoseRecommendation? + // automaticDosingIOBLimit calculated from the user entered maxBolus + let automaticDosingIOBLimit = maxBolus! * 2.0 + let iobHeadroom = automaticDosingIOBLimit - self.insulinOnBoard!.value + switch settings.automaticDosingStrategy { case .automaticBolus: let volumeRounder = { (_ units: Double) in return self.delegate?.roundBolusVolume(units: units) ?? units } + let maxAutomaticBolus = min(iobHeadroom, maxBolus! * LoopConstants.bolusPartialApplicationFactor) + dosingRecommendation = predictedGlucose.recommendedAutomaticDose( to: glucoseTargetRange!, at: predictedGlucose[0].startDate, suspendThreshold: settings.suspendThreshold?.quantity, sensitivity: insulinSensitivity!, model: doseStore.insulinModelProvider.model(for: pumpInsulinType), - basalRates: basalRates!, - maxAutomaticBolus: maxBolus! * LoopConstants.bolusPartialApplicationFactor, + basalRates: basalRateSchedule!, + maxAutomaticBolus: maxAutomaticBolus, partialApplicationFactor: LoopConstants.bolusPartialApplicationFactor * self.timeBasedDoseApplicationFactor, lastTempBasal: lastTempBasal, volumeRounder: volumeRounder, @@ -1628,14 +1715,16 @@ extension LoopDataManager { isBasalRateScheduleOverrideActive: settings.scheduleOverride?.isBasalRateScheduleOverriden(at: startDate) == true ) case .tempBasalOnly: + let temp = predictedGlucose.recommendedTempBasal( to: glucoseTargetRange!, at: predictedGlucose[0].startDate, suspendThreshold: settings.suspendThreshold?.quantity, sensitivity: insulinSensitivity!, model: doseStore.insulinModelProvider.model(for: pumpInsulinType), - basalRates: basalRates!, + basalRates: basalRateSchedule!, maxBasalRate: maxBasal!, + additionalActiveInsulinClamp: iobHeadroom, lastTempBasal: lastTempBasal, rateRounder: rateRounder, isBasalRateScheduleOverrideActive: settings.scheduleOverride?.isBasalRateScheduleOverriden(at: startDate) == true @@ -1716,13 +1805,15 @@ extension LoopDataManager { } } } - } /// Describes a view into the loop state protocol LoopState { /// The last-calculated carbs on board var carbsOnBoard: CarbValue? { get } + + /// The last-calculated insulin on board + var insulinOnBoard: InsulinValue? { get } /// An error in the current state of the loop, or one that happened during the last attempt to loop. var error: LoopError? { get } @@ -1825,6 +1916,11 @@ extension LoopDataManager { dispatchPrecondition(condition: .onQueue(loopDataManager.dataAccessQueue)) return loopDataManager.carbsOnBoard } + + var insulinOnBoard: InsulinValue? { + dispatchPrecondition(condition: .onQueue(loopDataManager.dataAccessQueue)) + return loopDataManager.insulinOnBoard + } var error: LoopError? { dispatchPrecondition(condition: .onQueue(loopDataManager.dataAccessQueue)) @@ -2029,6 +2125,7 @@ extension LoopDataManager { "lastLoopCompleted: \(String(describing: manager.lastLoopCompleted))", "basalDeliveryState: \(String(describing: manager.basalDeliveryState))", "carbsOnBoard: \(String(describing: state.carbsOnBoard))", + "insulinOnBoard: \(String(describing: manager.insulinOnBoard))", "error: \(String(describing: state.error))", "overrideInUserDefaults: \(String(describing: UserDefaults.appGroup?.intentExtensionOverrideToSet))", "", @@ -2047,16 +2144,21 @@ extension LoopDataManager { self.doseStore.generateDiagnosticReport { (report) in entries.append(report) entries.append("") - - UNUserNotificationCenter.current().generateDiagnosticReport { (report) in + + self.mealDetectionManager.generateDiagnosticReport { report in entries.append(report) entries.append("") - - UIDevice.current.generateDiagnosticReport { (report) in + + UNUserNotificationCenter.current().generateDiagnosticReport { (report) in entries.append(report) entries.append("") - completion(entries.joined(separator: "\n")) + UIDevice.current.generateDiagnosticReport { (report) in + entries.append(report) + entries.append("") + + completion(entries.joined(separator: "\n")) + } } } } @@ -2090,7 +2192,14 @@ protocol LoopDataManagerDelegate: AnyObject { /// - rate: The recommended rate in U/hr /// - Returns: a supported rate of delivery in Units/hr. The rate returned should not be larger than the passed in rate. func roundBasalRate(unitsPerHour: Double) -> Double - + + /// Asks the delegate to estimate the duration to deliver the bolus. + /// + /// - Parameters: + /// - bolusUnits: size of the bolus in U + /// - Returns: the estimated time it will take to deliver bolus + func loopDataManager(_ manager: LoopDataManager, estimateBolusDuration bolusUnits: Double) -> TimeInterval? + /// Asks the delegate to round a recommended bolus volume to a supported volume /// /// - Parameters: diff --git a/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift b/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift new file mode 100644 index 0000000000..5de7972225 --- /dev/null +++ b/Loop/Managers/Missed Meal Detection/MealDetectionManager.swift @@ -0,0 +1,296 @@ +// +// MealDetectionManager.swift +// Loop +// +// Created by Anna Quinlan on 11/28/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import Foundation +import HealthKit +import OSLog +import LoopCore +import LoopKit + +enum MissedMealStatus: Equatable { + case hasMissedMeal(startTime: Date, carbAmount: Double) + case noMissedMeal +} + +class MealDetectionManager { + private let log = OSLog(category: "MealDetectionManager") + + public var carbRatioScheduleApplyingOverrideHistory: CarbRatioSchedule? + public var insulinSensitivityScheduleApplyingOverrideHistory: InsulinSensitivitySchedule? + public var maximumBolus: Double? + + /// The last missed meal notification that was sent + /// Internal for unit testing + var lastMissedMealNotification: MissedMealNotification? = UserDefaults.standard.lastMissedMealNotification { + didSet { + UserDefaults.standard.lastMissedMealNotification = lastMissedMealNotification + } + } + + /// Debug info for missed meal detection + /// Timeline from the most recent check for missed meals + private var lastEvaluatedMissedMealTimeline: [(date: Date, unexpectedDeviation: Double?, mealThreshold: Double?, rateOfChangeThreshold: Double?)] = [] + + /// Timeline from the most recent detection of an missed meal + private var lastDetectedMissedMealTimeline: [(date: Date, unexpectedDeviation: Double?, mealThreshold: Double?, rateOfChangeThreshold: Double?)] = [] + + /// Allows for controlling uses of the system date in unit testing + internal var test_currentDate: Date? + + /// Current date. Will return the unit-test configured date if set, or the current date otherwise. + internal var currentDate: Date { + test_currentDate ?? Date() + } + + internal func currentDate(timeIntervalSinceNow: TimeInterval = 0) -> Date { + return currentDate.addingTimeInterval(timeIntervalSinceNow) + } + + public init( + carbRatioScheduleApplyingOverrideHistory: CarbRatioSchedule?, + insulinSensitivityScheduleApplyingOverrideHistory: InsulinSensitivitySchedule?, + maximumBolus: Double?, + test_currentDate: Date? = nil + ) { + self.carbRatioScheduleApplyingOverrideHistory = carbRatioScheduleApplyingOverrideHistory + self.insulinSensitivityScheduleApplyingOverrideHistory = insulinSensitivityScheduleApplyingOverrideHistory + self.maximumBolus = maximumBolus + self.test_currentDate = test_currentDate + } + + // MARK: Meal Detection + func hasMissedMeal(insulinCounteractionEffects: [GlucoseEffectVelocity], carbEffects: [GlucoseEffect], completion: @escaping (MissedMealStatus) -> Void) { + let delta = TimeInterval(minutes: 5) + + let intervalStart = currentDate(timeIntervalSinceNow: -MissedMealSettings.maxRecency) + let intervalEnd = currentDate(timeIntervalSinceNow: -MissedMealSettings.minRecency) + let now = self.currentDate + + let filteredCarbEffects = carbEffects.filterDateRange(intervalStart, now) + + /// Compute how much of the ICE effect we can't explain via our entered carbs + /// Effect caching inspired by `LoopMath.predictGlucose` + var effectValueCache: [Date: Double] = [:] + let unit = HKUnit.milligramsPerDeciliter + + /// Carb effects are cumulative, so we have to subtract the previous effect value + var previousEffectValue: Double = filteredCarbEffects.first?.quantity.doubleValue(for: unit) ?? 0 + + /// Counteraction effects only take insulin into account, so we need to account for the carb effects when computing the unexpected deviations + for effect in filteredCarbEffects { + let value = effect.quantity.doubleValue(for: unit) + /// We do `-1 * (value - previousEffectValue)` because this will compute the carb _counteraction_ effect + effectValueCache[effect.startDate] = (effectValueCache[effect.startDate] ?? 0) + -1 * (value - previousEffectValue) + previousEffectValue = value + } + + let processedICE = insulinCounteractionEffects + .filterDateRange(intervalStart, now) + .compactMap { + /// Clamp starts & ends to `intervalStart...now` since our algorithm assumes all effects occur within that interval + let start = max($0.startDate, intervalStart) + let end = min($0.endDate, now) + + guard let effect = $0.effect(from: start, to: end) else { + let item: GlucoseEffect? = nil // FIXME: we get a compiler error if we try to return `nil` directly + return item + } + + return GlucoseEffect(startDate: effect.endDate.dateCeiledToTimeInterval(delta), + quantity: effect.quantity) + } + + for effect in processedICE { + let value = effect.quantity.doubleValue(for: unit) + effectValueCache[effect.startDate] = (effectValueCache[effect.startDate] ?? 0) + value + } + + var unexpectedDeviation: Double = 0 + var mealTime = now + + /// Dates the algorithm uses when computing effects + /// Have the range go from newest -> oldest time + let summationRange = LoopMath.simulationDateRange(from: intervalStart, + to: now, + delta: delta) + .reversed() + + /// Dates the algorithm is allowed to check for the presence of a missed meal + let dateSearchRange = Set(LoopMath.simulationDateRange(from: intervalStart, + to: intervalEnd, + delta: delta)) + + /// Timeline used for debug purposes + var missedMealTimeline: [(date: Date, unexpectedDeviation: Double?, mealThreshold: Double?, rateOfChangeThreshold: Double?)] = [] + + for pastTime in summationRange { + guard let unexpectedEffect = effectValueCache[pastTime] else { + missedMealTimeline.append((pastTime, nil, nil, nil)) + continue + } + + unexpectedDeviation += unexpectedEffect + + guard dateSearchRange.contains(pastTime) else { + /// This time is too recent to check for a missed meal + missedMealTimeline.append((pastTime, unexpectedDeviation, nil, nil)) + continue + } + + /// Find the threshold based on a minimum of `missedMealGlucoseRiseThreshold` of change per minute + let minutesAgo = now.timeIntervalSince(pastTime).minutes + let rateThreshold = MissedMealSettings.glucoseRiseThreshold * minutesAgo + + /// Find the total effect we'd expect to see for a meal with `carbThreshold`-worth of carbs that started at `pastTime` + guard let mealThreshold = self.effectThreshold(mealStart: pastTime, carbsInGrams: MissedMealSettings.minCarbThreshold) else { + continue + } + + missedMealTimeline.append((pastTime, unexpectedDeviation, mealThreshold, rateThreshold)) + + /// Use the higher of the 2 thresholds to ensure noisy CGM data doesn't cause false-positives for more recent times + let effectThreshold = max(rateThreshold, mealThreshold) + + if unexpectedDeviation >= effectThreshold { + mealTime = pastTime + } + } + + self.lastEvaluatedMissedMealTimeline = missedMealTimeline.reversed() + + let mealTimeTooRecent = now.timeIntervalSince(mealTime) < MissedMealSettings.minRecency + guard !mealTimeTooRecent else { + completion(.noMissedMeal) + return + } + + self.lastDetectedMissedMealTimeline = missedMealTimeline.reversed() + + let carbAmount = self.determineCarbs(mealtime: mealTime, unexpectedDeviation: unexpectedDeviation) + completion(.hasMissedMeal(startTime: mealTime, carbAmount: carbAmount ?? MissedMealSettings.minCarbThreshold)) + } + + private func determineCarbs(mealtime: Date, unexpectedDeviation: Double) -> Double? { + var mealCarbs: Double? = nil + + /// Search `carbAmount`s from `minCarbThreshold` to `maxCarbThreshold` in 5-gram increments, + /// seeing if the deviation is at least `carbAmount` of carbs + for carbAmount in stride(from: MissedMealSettings.minCarbThreshold, through: MissedMealSettings.maxCarbThreshold, by: 5) { + if + let modeledCarbEffect = effectThreshold(mealStart: mealtime, carbsInGrams: carbAmount), + unexpectedDeviation >= modeledCarbEffect + { + mealCarbs = carbAmount + } + } + + return mealCarbs + } + + private func effectThreshold(mealStart: Date, carbsInGrams: Double) -> Double? { + guard + let carbRatio = carbRatioScheduleApplyingOverrideHistory?.value(at: mealStart), + let insulinSensitivity = insulinSensitivityScheduleApplyingOverrideHistory?.value(at: mealStart) + else { + return nil + } + + return carbsInGrams / carbRatio * insulinSensitivity + } + + // MARK: Notification Generation + /// Searches for any potential missed meals and sends a notification. + /// A missed meal notification can be delivered a maximum of every `MissedMealSettings.maxRecency - MissedMealSettings.minRecency` minutes. + /// + /// - Parameters: + /// - insulinCounteractionEffects: the current insulin counteraction effects that have been observed + /// - carbEffects: the effects of any active carb entries. Must include effects from `currentDate() - MissedMealSettings.maxRecency` until `currentDate()`. + /// - pendingAutobolusUnits: any autobolus units that are still being delivered. Used to delay the missed meal notification to avoid notifying during an autobolus. + /// - bolusDurationEstimator: estimator of bolus duration that takes the units of the bolus as an input. Used to delay the missed meal notification to avoid notifying during an autobolus. + func generateMissedMealNotificationIfNeeded( + insulinCounteractionEffects: [GlucoseEffectVelocity], + carbEffects: [GlucoseEffect], + pendingAutobolusUnits: Double? = nil, + bolusDurationEstimator: @escaping (Double) -> TimeInterval? + ) { + hasMissedMeal(insulinCounteractionEffects: insulinCounteractionEffects, carbEffects: carbEffects) {[weak self] status in + self?.manageMealNotifications(for: status, pendingAutobolusUnits: pendingAutobolusUnits, bolusDurationEstimator: bolusDurationEstimator) + } + } + + + // Internal for unit testing + func manageMealNotifications(for status: MissedMealStatus, pendingAutobolusUnits: Double? = nil, bolusDurationEstimator getBolusDuration: (Double) -> TimeInterval?) { + // We should remove expired notifications regardless of whether or not there was a meal + NotificationManager.removeExpiredMealNotifications() + + // Figure out if we should deliver a notification + let now = self.currentDate + let notificationTimeTooRecent = now.timeIntervalSince(lastMissedMealNotification?.deliveryTime ?? .distantPast) < (MissedMealSettings.maxRecency - MissedMealSettings.minRecency) + + guard + case .hasMissedMeal(let startTime, let carbAmount) = status, + !notificationTimeTooRecent, + UserDefaults.standard.missedMealNotificationsEnabled + else { + // No notification needed! + return + } + + var clampedCarbAmount = carbAmount + if + let maxBolus = maximumBolus, + let currentCarbRatio = carbRatioScheduleApplyingOverrideHistory?.quantity(at: now).doubleValue(for: .gram()) + { + let maxAllowedCarbAutofill = maxBolus * currentCarbRatio + clampedCarbAmount = min(clampedCarbAmount, maxAllowedCarbAutofill) + } + + log.debug("Delivering a missed meal notification") + + /// Coordinate the missed meal notification time with any pending autoboluses that `update` may have started + /// so that the user doesn't have to cancel the current autobolus to bolus in response to the missed meal notification + if + let pendingAutobolusUnits, + pendingAutobolusUnits > 0, + let estimatedBolusDuration = getBolusDuration(pendingAutobolusUnits), + estimatedBolusDuration < MissedMealSettings.maxNotificationDelay + { + NotificationManager.sendMissedMealNotification(mealStart: startTime, amountInGrams: clampedCarbAmount, delay: estimatedBolusDuration) + lastMissedMealNotification = MissedMealNotification(deliveryTime: now.advanced(by: estimatedBolusDuration), + carbAmount: clampedCarbAmount) + } else { + NotificationManager.sendMissedMealNotification(mealStart: startTime, amountInGrams: clampedCarbAmount) + lastMissedMealNotification = MissedMealNotification(deliveryTime: now, carbAmount: clampedCarbAmount) + } + } + + // MARK: Logging + + /// Generates a diagnostic report about the current state + /// + /// - parameter completionHandler: A closure called once the report has been generated. The closure takes a single argument of the report string. + func generateDiagnosticReport(_ completionHandler: @escaping (_ report: String) -> Void) { + let report = [ + "## MealDetectionManager", + "", + "* lastMissedMealNotificationTime: \(String(describing: lastMissedMealNotification?.deliveryTime))", + "* lastMissedMealCarbEstimate: \(String(describing: lastMissedMealNotification?.carbAmount))", + "* lastEvaluatedMissedMealTimeline:", + lastEvaluatedMissedMealTimeline.reduce(into: "", { (entries, entry) in + entries.append(" * date: \(entry.date), unexpectedDeviation: \(entry.unexpectedDeviation ?? -1), meal-based threshold: \(entry.mealThreshold ?? -1), change-based threshold: \(entry.rateOfChangeThreshold ?? -1) \n") + }), + "* lastDetectedMissedMealTimeline:", + lastDetectedMissedMealTimeline.reduce(into: "", { (entries, entry) in + entries.append(" * date: \(entry.date), unexpectedDeviation: \(entry.unexpectedDeviation ?? -1), meal-based threshold: \(entry.mealThreshold ?? -1), change-based threshold: \(entry.rateOfChangeThreshold ?? -1) \n") + }) + ] + + completionHandler(report.joined(separator: "\n")) + } +} diff --git a/Loop/Managers/Missed Meal Detection/MissedMealSettings.swift b/Loop/Managers/Missed Meal Detection/MissedMealSettings.swift new file mode 100644 index 0000000000..24ff03a9a8 --- /dev/null +++ b/Loop/Managers/Missed Meal Detection/MissedMealSettings.swift @@ -0,0 +1,25 @@ +// +// MissedMealSettings.swift +// Loop +// +// Created by Anna Quinlan on 11/28/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import Foundation + +public struct MissedMealSettings { + /// Minimum grams of unannounced carbs that must be detected for a notification to be delivered + public static let minCarbThreshold: Double = 15 // grams + /// Maximum grams of unannounced carbs that the algorithm will search for + public static let maxCarbThreshold: Double = 80 // grams + /// Minimum threshold for glucose rise over the detection window + static let glucoseRiseThreshold = 2.0 // mg/dL/m + /// Minimum time from now that must have passed for the meal to be detected + public static let minRecency = TimeInterval(minutes: 15) + /// Maximum time from now that a meal can be detected + public static let maxRecency = TimeInterval(hours: 2) + /// Maximum delay allowed in missed meal notification time to avoid + /// notifying the user during an autobolus + public static let maxNotificationDelay = TimeInterval(minutes: 4) +} diff --git a/Loop/Managers/NotificationManager.swift b/Loop/Managers/NotificationManager.swift index 7ad18d308e..22540cdfa9 100644 --- a/Loop/Managers/NotificationManager.swift +++ b/Loop/Managers/NotificationManager.swift @@ -9,6 +9,7 @@ import UIKit import UserNotifications import LoopKit +import LoopCore enum NotificationManager { @@ -77,6 +78,27 @@ extension NotificationManager { // MARK: - Notifications + + @MainActor + static func sendRemoteCommandExpiredNotification(timeExpired: TimeInterval) { + let notification = UNMutableNotificationContent() + + notification.title = NSLocalizedString("Remote Command Expired", comment: "The notification title for the remote command expiration error") + + notification.body = String(format: NSLocalizedString("The remote command expired %.0f minutes ago.", comment: "The notification body for a remote command expiration. (1: Expiration in minutes)"), fabs(timeExpired / 60.0)) + notification.sound = .default + + notification.categoryIdentifier = LoopNotificationCategory.remoteCommandExpired.rawValue + + let request = UNNotificationRequest( + // Only support 1 expiration notification at once + identifier: LoopNotificationCategory.remoteCommandExpired.rawValue, + content: notification, + trigger: nil + ) + + UNUserNotificationCenter.current().add(request) + } static func sendBolusFailureNotification(for error: PumpManagerError, units: Double, at startDate: Date, activationType: BolusActivationType) { let notification = UNMutableNotificationContent() @@ -93,9 +115,6 @@ extension NotificationManager { notification.body = body notification.sound = .default - if #available(iOS 15.0, *) { - notification.interruptionLevel = .timeSensitive - } if startDate.timeIntervalSinceNow >= TimeInterval(minutes: -5) { notification.categoryIdentifier = LoopNotificationCategory.bolusFailure.rawValue @@ -117,6 +136,7 @@ extension NotificationManager { UNUserNotificationCenter.current().add(request) } + @MainActor static func sendRemoteBolusNotification(amount: Double) { let notification = UNMutableNotificationContent() let quantityFormatter = QuantityFormatter() @@ -140,6 +160,7 @@ extension NotificationManager { UNUserNotificationCenter.current().add(request) } + @MainActor static func sendRemoteBolusFailureNotification(for error: Error, amount: Double) { let notification = UNMutableNotificationContent() let quantityFormatter = QuantityFormatter() @@ -161,6 +182,7 @@ extension NotificationManager { UNUserNotificationCenter.current().add(request) } + @MainActor static func sendRemoteCarbEntryNotification(amountInGrams: Double) { let notification = UNMutableNotificationContent() @@ -181,6 +203,7 @@ extension NotificationManager { UNUserNotificationCenter.current().add(request) } + @MainActor static func sendRemoteCarbEntryFailureNotification(for error: Error, amountInGrams: Double) { let notification = UNMutableNotificationContent() @@ -201,6 +224,68 @@ extension NotificationManager { UNUserNotificationCenter.current().add(request) } + static func sendMissedMealNotification(mealStart: Date, amountInGrams: Double, delay: TimeInterval? = nil) { + let notification = UNMutableNotificationContent() + /// Notifications should expire after the missed meal is no longer relevant + let expirationDate = mealStart.addingTimeInterval(LoopCoreConstants.defaultCarbAbsorptionTimes.slow) + + notification.title = String(format: NSLocalizedString("Possible Missed Meal", comment: "The notification title for a meal that was possibly not logged in Loop.")) + notification.body = String(format: NSLocalizedString("It looks like you may not have logged a meal you ate. Tap to log it now.", comment: "The notification description for a meal that was possibly not logged in Loop.")) + notification.sound = .default + + notification.userInfo = [ + LoopNotificationUserInfoKey.missedMealTime.rawValue: mealStart, + LoopNotificationUserInfoKey.missedMealCarbAmount.rawValue: amountInGrams, + LoopNotificationUserInfoKey.expirationDate.rawValue: expirationDate + ] + + + var notificationTrigger: UNTimeIntervalNotificationTrigger? = nil + if let delay { + notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: delay, repeats: false) + } + + let request = UNNotificationRequest( + /// We use the same `identifier` for all requests so a newer missed meal notification will replace a current one (if it exists) + identifier: LoopNotificationCategory.missedMeal.rawValue, + content: notification, + trigger: notificationTrigger + ) + + UNUserNotificationCenter.current().add(request) + } + + static func removeExpiredMealNotifications(now: Date = Date()) { + let notificationCenter = UNUserNotificationCenter.current() + var identifiersToRemove: [String] = [] + + notificationCenter.getDeliveredNotifications { notifications in + for notification in notifications { + let request = notification.request + + guard + request.identifier == LoopNotificationCategory.missedMeal.rawValue, + let expirationDate = request.content.userInfo[LoopNotificationUserInfoKey.expirationDate.rawValue] as? Date, + expirationDate < now + else { + continue + } + + /// The notification is expired: mark it for removal + identifiersToRemove.append(request.identifier) + /// We can break early because all missed meal notifications have the same `identifier`, + /// so there will only ever be 1 outstanding missed meal notification + break + } + + guard identifiersToRemove.count > 0 else { + return + } + + notificationCenter.removeDeliveredNotifications(withIdentifiers: identifiersToRemove) + } + } + private static func remoteCarbEntryNotificationBody(amountInGrams: Double) -> String { return String(format: NSLocalizedString("Remote Carbs Entry: %d grams", comment: "The carb amount message for a remote carbs entry notification. (1: Carb amount in grams)"), Int(amountInGrams)) } diff --git a/Loop/Managers/ProfileExpirationAlerter.swift b/Loop/Managers/ProfileExpirationAlerter.swift index f262a7d82b..a28d452783 100644 --- a/Loop/Managers/ProfileExpirationAlerter.swift +++ b/Loop/Managers/ProfileExpirationAlerter.swift @@ -14,6 +14,7 @@ import LoopCore class ProfileExpirationAlerter { static let expirationAlertWindow: TimeInterval = .days(20) + static let settingsPageExpirationWarningModeWindow: TimeInterval = .days(3) static func alertIfNeeded(viewControllerToPresentFrom: UIViewController) { @@ -40,9 +41,11 @@ class ProfileExpirationAlerter { formatter.maximumUnitCount = 1 let timeUntilExpirationStr = formatter.string(from: timeUntilExpiration) + let alertMessage = createVerboseAlertMessage(timeUntilExpirationStr: timeUntilExpirationStr!) + let dialog = UIAlertController( title: NSLocalizedString("Profile Expires Soon", comment: "The title for notification of upcoming profile expiration"), - message: String(format: NSLocalizedString("%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile.", comment: "Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration"), Bundle.main.bundleDisplayName, timeUntilExpirationStr!), + message: alertMessage, preferredStyle: .alert) dialog.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Text for ok action on notification of upcoming profile expiration"), style: .default, handler: nil)) dialog.addAction(UIAlertAction(title: NSLocalizedString("More Info", comment: "Text for more info action on notification of upcoming profile expiration"), style: .default, handler: { (_) in @@ -52,4 +55,32 @@ class ProfileExpirationAlerter { UserDefaults.appGroup?.lastProfileExpirationAlertDate = now } + + static func createVerboseAlertMessage(timeUntilExpirationStr:String) -> String { + return String(format: NSLocalizedString("%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile.", comment: "Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration"), Bundle.main.bundleDisplayName, timeUntilExpirationStr) + } + + static func isNearProfileExpiration(profileExpiration:Date) -> Bool { + return profileExpiration.timeIntervalSinceNow < settingsPageExpirationWarningModeWindow + } + + static func createProfileExpirationSettingsMessage(profileExpiration:Date) -> String { + let nearExpiration = isNearProfileExpiration(profileExpiration: profileExpiration) + let maxUnitCount = nearExpiration ? 2 : 1 // only include hours in the msg if near expiration + let readableRelativeTime: String? = relativeTimeFormatter(maxUnitCount: maxUnitCount).string(from: profileExpiration.timeIntervalSinceNow) + let relativeTimeRemaining: String = readableRelativeTime ?? NSLocalizedString("Unknown time", comment: "Unknown amount of time in settings' profile expiration section") + let verboseMessage = createVerboseAlertMessage(timeUntilExpirationStr: relativeTimeRemaining) + let conciseMessage = relativeTimeRemaining + NSLocalizedString(" remaining", comment: "remaining time in setting's profile expiration section") + return nearExpiration ? verboseMessage : conciseMessage + } + + private static func relativeTimeFormatter(maxUnitCount:Int) -> DateComponentsFormatter { + let formatter = DateComponentsFormatter() + let includeHours = maxUnitCount == 2 + formatter.allowedUnits = includeHours ? [.day, .hour] : [.day] + formatter.unitsStyle = .full + formatter.zeroFormattingBehavior = .dropLeading + formatter.maximumUnitCount = maxUnitCount + return formatter; + } } diff --git a/Loop/Managers/RemoteDataServicesManager.swift b/Loop/Managers/RemoteDataServicesManager.swift index ef7da45e61..e8a8ea0868 100644 --- a/Loop/Managers/RemoteDataServicesManager.swift +++ b/Loop/Managers/RemoteDataServicesManager.swift @@ -176,10 +176,6 @@ final class RemoteDataServicesManager { clearSettingsQueryAnchor(for: remoteDataService) } - public func waitForUploadsToFinish(timeout: DispatchTime = .now() + TimeInterval(10)) -> DispatchTimeoutResult { - return uploadGroup.wait(timeout: timeout) - } - func triggerUpload(for triggeringType: RemoteDataType) { let uploadTypes = [triggeringType] + failedUploads.map { $0.remoteDataType } @@ -206,6 +202,21 @@ final class RemoteDataServicesManager { } } } + + func triggerUpload(for triggeringType: RemoteDataType, completion: @escaping () -> Void) { + triggerUpload(for: triggeringType) + self.uploadGroup.notify(queue: DispatchQueue.main) { + completion() + } + } + + func triggerUpload(for triggeringType: RemoteDataType) async { + return await withCheckedContinuation { continuation in + triggerUpload(for: triggeringType) { + continuation.resume(returning: ()) + } + } + } } extension RemoteDataServicesManager { @@ -586,15 +597,24 @@ extension RemoteDataServicesManager { extension RemoteDataServicesManager { - func validatePushNotificationSource(_ notification: [String: AnyObject]) -> Bool { - for service in remoteDataServices { - let validated = service.validatePushNotificationSource(notification) - if validated { - return validated - } + func serviceForPushNotification(_ notification: [String: AnyObject]) -> RemoteDataService? { + + let defaultServiceIdentifier = "NightscoutService" + let serviceIdentifier = notification["serviceIdentifier"] as? String ?? defaultServiceIdentifier + return remoteDataServices.first(where: {$0.serviceIdentifier == serviceIdentifier}) + } + + func commandFromPushNotification(_ notification: [String : AnyObject]) async throws -> RemoteCommand { + + enum RemoteDataServicesManagerCommandError: LocalizedError { + case missingNotificationService } - return false + guard let service = serviceForPushNotification(notification) else { + throw RemoteDataServicesManagerCommandError.missingNotificationService + } + + return try await service.commandFromPushNotification(notification) } public func temporaryScheduleOverrideHistoryDidUpdate() { @@ -635,10 +655,8 @@ extension RemoteDataServicesManager { UserDefaults.appGroup?.deleteQueryAnchor(for: remoteDataService, withRemoteDataType: .overrides) } } - } - protocol RemoteDataServicesManagerDelegate: AnyObject { var shouldSyncToRemoteService: Bool {get} } diff --git a/Loop/Managers/ServicesManager.swift b/Loop/Managers/ServicesManager.swift index 602ea75301..3140029e08 100644 --- a/Loop/Managers/ServicesManager.swift +++ b/Loop/Managers/ServicesManager.swift @@ -15,6 +15,8 @@ class ServicesManager { private let pluginManager: PluginManager + private let alertManager: AlertManager + let analyticsServicesManager: AnalyticsServicesManager let loggingServicesManager: LoggingServicesManager @@ -32,11 +34,13 @@ class ServicesManager { init( pluginManager: PluginManager, + alertManager: AlertManager, analyticsServicesManager: AnalyticsServicesManager, loggingServicesManager: LoggingServicesManager, remoteDataServicesManager: RemoteDataServicesManager ) { self.pluginManager = pluginManager + self.alertManager = alertManager self.analyticsServicesManager = analyticsServicesManager self.loggingServicesManager = loggingServicesManager self.remoteDataServicesManager = remoteDataServicesManager @@ -68,7 +72,7 @@ class ServicesManager { return .failure(UnknownServiceIdentifierError()) } - let result = serviceUIType.setupViewController(colorPalette: .default) + let result = serviceUIType.setupViewController(colorPalette: .default, pluginHost: self) if case .createdAndOnboarded(let serviceUI) = result { serviceOnboarding(didCreateService: serviceUI) serviceOnboarding(didOnboardService: serviceUI) @@ -173,6 +177,22 @@ class ServicesManager { // MARK: - ServiceDelegate extension ServicesManager: ServiceDelegate { + var hostIdentifier: String { + return "com.loopkit.Loop" + } + + var hostVersion: String { + var semanticVersion = Bundle.main.shortVersionString + + while semanticVersion.split(separator: ".").count < 3 { + semanticVersion += ".0" + } + + semanticVersion += "+\(Bundle.main.version)" + + return semanticVersion + } + func serviceDidUpdateState(_ service: Service) { saveState() } @@ -183,6 +203,16 @@ extension ServicesManager: ServiceDelegate { } } +extension ServicesManager: AlertIssuer { + func issueAlert(_ alert: Alert) { + alertManager.issueAlert(alert) + } + + func retractAlert(identifier: Alert.Identifier) { + alertManager.retractAlert(identifier: identifier) + } +} + // MARK: - ServiceOnboardingDelegate extension ServicesManager: ServiceOnboardingDelegate { diff --git a/Loop/Managers/SupportManager.swift b/Loop/Managers/SupportManager.swift index 356f008890..37250a24ad 100644 --- a/Loop/Managers/SupportManager.swift +++ b/Loop/Managers/SupportManager.swift @@ -103,8 +103,9 @@ extension SupportManager { // MARK: Version checking extension SupportManager { func performCheck() { - checkVersion { [weak self] versionUpdate in - self?.notify(versionUpdate) + Task { @MainActor in + let versionUpdate = await checkVersion() + self.notify(versionUpdate) } } @@ -114,37 +115,41 @@ extension SupportManager { } } - func checkVersion(completion: @escaping (VersionUpdate) -> Void) { - let group = DispatchGroup() - var results = [String: Result]() - supports.value.values.forEach { support in - group.enter() - support.checkVersion(bundleIdentifier: Bundle.main.bundleIdentifier!, currentVersion: Bundle.main.shortVersionString) { result in - results[support.identifier] = result - group.leave() + func checkVersion() async -> VersionUpdate { + + let results = await withTaskGroup(of: (VersionUpdate?,String).self) { group in + var updatesFromServices = [(VersionUpdate?,String)]() + + supports.value.values.forEach { support in + group.addTask { + return (await support.checkVersion(bundleIdentifier: Bundle.main.bundleIdentifier!, currentVersion: Bundle.main.shortVersionString), support.identifier) + } } + + for await update in group { + updatesFromServices.append(update) + } + + return updatesFromServices } - group.notify(queue: DispatchQueue.main) { [weak self] in - guard let self = self else { return } - self.saveState() - let (identifierWithHighestVersionUpdate, aggregatedVersionUpdate) = self.aggregate(results: results) - self.identifierWithHighestVersionUpdate = identifierWithHighestVersionUpdate - completion(aggregatedVersionUpdate) - } + + self.saveState() + let (identifierWithHighestVersionUpdate, aggregatedVersionUpdate) = self.aggregate(results: results) + self.identifierWithHighestVersionUpdate = identifierWithHighestVersionUpdate + return aggregatedVersionUpdate } - private func aggregate(results: [String : Result]) -> (String?, VersionUpdate) { + private func aggregate(results: [(VersionUpdate?,String)]) -> (String?, VersionUpdate) { var aggregatedVersionUpdate = VersionUpdate.default var identifierWithHighestVersionUpdate: String? - results.forEach { key, value in - switch value { - case .failure(let error): - self.log.error("Error from version check %{public}@: %{public}@", key, error.localizedDescription) - case .success(let versionUpdate): - if let versionUpdate = versionUpdate, versionUpdate > aggregatedVersionUpdate { + results.forEach { versionUpdate, identifier in + if let versionUpdate { + if versionUpdate > aggregatedVersionUpdate { aggregatedVersionUpdate = versionUpdate - identifierWithHighestVersionUpdate = key + identifierWithHighestVersionUpdate = identifier } + } else { + self.log.error("Version check failed for %{public}@", identifier) } } return (identifierWithHighestVersionUpdate, aggregatedVersionUpdate) @@ -225,8 +230,8 @@ extension SupportManager { fileprivate extension Result where Success == VersionUpdate? { var value: VersionUpdate { switch self { - case .failure: return .none - case .success(let val): return val ?? .none + case .failure: return .noUpdateNeeded + case .success(let val): return val ?? .noUpdateNeeded } } } diff --git a/Loop/Managers/WatchDataManager.swift b/Loop/Managers/WatchDataManager.swift index 8598f39c6e..94a0c218e1 100644 --- a/Loop/Managers/WatchDataManager.swift +++ b/Loop/Managers/WatchDataManager.swift @@ -386,11 +386,13 @@ final class WatchDataManager: NSObject { deviceManager.enactBolus(units: bolus.value, activationType: bolus.activationType) { (error) in if error == nil { - self.deviceManager.analyticsServicesManager.didSetBolusFromWatch(bolus.value) + self.deviceManager.analyticsServicesManager.didBolus(source: "Watch", units: bolus.value) } // When we've successfully started the bolus, send a new context with our new prediction self.sendWatchContextIfNeeded() + + self.deviceManager.loopManager.updateRemoteRecommendation() } } @@ -399,7 +401,7 @@ final class WatchDataManager: NSObject { switch result { case .success(let storedCarbEntry): dosingDecision.carbEntry = storedCarbEntry - self.deviceManager.analyticsServicesManager.didAddCarbsFromWatch() + self.deviceManager.analyticsServicesManager.didAddCarbs(source: "Watch", amount: storedCarbEntry.quantity.doubleValue(for: .gram())) enactBolus() case .failure(let error): self.log.error("%{public}@", String(describing: error)) diff --git a/Loop/Models/LoopConstants.swift b/Loop/Models/LoopConstants.swift index 67f43e38c0..a62fc13849 100644 --- a/Loop/Models/LoopConstants.swift +++ b/Loop/Models/LoopConstants.swift @@ -15,12 +15,19 @@ enum LoopConstants { // Input field bounds - static let maxCarbEntryQuantity = HKQuantity(unit: .gram(), doubleValue: 250) + static let maxCarbEntryQuantity = HKQuantity(unit: .gram(), doubleValue: 250) // cannot exceed this value + + static let warningCarbEntryQuantity = HKQuantity(unit: .gram(), doubleValue: 99) // user is warned above this value static let validManualGlucoseEntryRange = HKQuantity(unit: .milligramsPerDeciliter, doubleValue: 10)...HKQuantity(unit: .milligramsPerDeciliter, doubleValue: 600) + static let minCarbAbsorptionTime = TimeInterval(minutes: 30) static let maxCarbAbsorptionTime = TimeInterval(hours: 8) + + static let maxCarbEntryPastTime = TimeInterval(hours: (-12)) + static let maxCarbEntryFutureTime = TimeInterval(hours: 1) + static let maxOverrideDurationTime = TimeInterval(hours: 24) // MARK - Display settings diff --git a/Loop/Models/LoopError.swift b/Loop/Models/LoopError.swift index d8c9bc2fa5..015d5cc05c 100644 --- a/Loop/Models/LoopError.swift +++ b/Loop/Models/LoopError.swift @@ -43,6 +43,7 @@ enum MissingDataErrorDetail: String, Codable { case momentumEffect case carbEffect case insulinEffect + case activeInsulin case insulinEffectIncludingPendingInsulin var localizedDetail: String { @@ -55,6 +56,8 @@ enum MissingDataErrorDetail: String, Codable { return NSLocalizedString("Carb effects", comment: "Details for missing data error when carb effects are missing") case .insulinEffect: return NSLocalizedString("Insulin effects", comment: "Details for missing data error when insulin effects are missing") + case .activeInsulin: + return NSLocalizedString("Active Insulin", comment: "Details for missing data error when active insulin amount is missing") case .insulinEffectIncludingPendingInsulin: return NSLocalizedString("Insulin effects", comment: "Details for missing data error when insulin effects including pending insulin are missing") } @@ -68,9 +71,7 @@ enum MissingDataErrorDetail: String, Codable { return nil case .carbEffect: return nil - case .insulinEffect: - return nil - case .insulinEffectIncludingPendingInsulin: + case .insulinEffect, .activeInsulin, .insulinEffectIncludingPendingInsulin: return nil } } @@ -89,6 +90,9 @@ enum LoopError: Error { // Glucose data is too old to perform action case glucoseTooOld(date: Date) + // Glucose data is in the future + case invalidFutureGlucose(date: Date) + // Pump data is too old to perform action case pumpDataTooOld(date: Date) @@ -120,6 +124,8 @@ extension LoopError { return "missingDataError" case .glucoseTooOld: return "glucoseTooOld" + case .invalidFutureGlucose: + return "invalidFutureGlucose" case .pumpDataTooOld: return "pumpDataTooOld" case .recommendationExpired: @@ -142,6 +148,8 @@ extension LoopError { details["detail"] = detail.rawValue case .glucoseTooOld(let date): details["date"] = StoredDosingDecisionIssue.description(for: date) + case .invalidFutureGlucose(let date): + details["date"] = StoredDosingDecisionIssue.description(for: date) case .pumpDataTooOld(let date): details["date"] = StoredDosingDecisionIssue.description(for: date) case .recommendationExpired(let date): @@ -183,6 +191,9 @@ extension LoopError: LocalizedError { case .glucoseTooOld(let date): let minutes = formatter.string(from: -date.timeIntervalSinceNow) ?? "" return String(format: NSLocalizedString("Glucose data is %1$@ old", comment: "The error message when glucose data is too old to be used. (1: glucose data age in minutes)"), minutes) + case .invalidFutureGlucose(let date): + let minutes = formatter.string(from: -date.timeIntervalSinceNow) ?? "" + return String(format: NSLocalizedString("Invalid glucose reading with a timestamp that is %1$@ in the future", comment: "The error message when glucose data is in the future. (1: glucose data time in future in minutes)"), minutes) case .pumpDataTooOld(let date): let minutes = formatter.string(from: -date.timeIntervalSinceNow) ?? "" return String(format: NSLocalizedString("Pump data is %1$@ old", comment: "The error message when pump data is too old to be used. (1: pump data age in minutes)"), minutes) diff --git a/Loop/Models/Remote/BolusAction.swift b/Loop/Models/Remote/BolusAction.swift new file mode 100644 index 0000000000..054b618089 --- /dev/null +++ b/Loop/Models/Remote/BolusAction.swift @@ -0,0 +1,46 @@ +// +// BolusAction.swift +// Loop +// +// Created by Bill Gestrich on 2/21/23. +// Copyright © 2023 LoopKit Authors. All rights reserved. +// + +import LoopKit + +extension BolusAction { + func toValidBolusAmount(maximumBolus: Double?) throws -> Double { + + guard amountInUnits > 0 else { + throw BolusActionError.invalidBolus + } + + guard let maxBolusAmount = maximumBolus else { + throw BolusActionError.missingMaxBolus + } + + guard amountInUnits <= maxBolusAmount else { + throw BolusActionError.exceedsMaxBolus + } + + return amountInUnits + } +} + +enum BolusActionError: LocalizedError { + + case invalidBolus + case missingMaxBolus + case exceedsMaxBolus + + var errorDescription: String? { + switch self { + case .invalidBolus: + return NSLocalizedString("Invalid Bolus Amount", comment: "Remote command error description: invalid bolus amount.") + case .missingMaxBolus: + return NSLocalizedString("Missing maximum allowed bolus in settings", comment: "Remote command error description: missing maximum bolus in settings.") + case .exceedsMaxBolus: + return NSLocalizedString("Exceeds maximum allowed bolus in settings", comment: "Remote command error description: bolus exceeds maximum bolus in settings.") + } + } +} diff --git a/Loop/Models/Remote/CarbAction.swift b/Loop/Models/Remote/CarbAction.swift new file mode 100644 index 0000000000..fd00ed9d6a --- /dev/null +++ b/Loop/Models/Remote/CarbAction.swift @@ -0,0 +1,73 @@ +// +// CarbAction.swift +// Loop +// +// Created by Bill Gestrich on 2/21/23. +// Copyright © 2023 LoopKit Authors. All rights reserved. +// + +import LoopKit +import HealthKit + +extension CarbAction { + + func toValidCarbEntry(defaultAbsorptionTime: TimeInterval, + minAbsorptionTime: TimeInterval, + maxAbsorptionTime: TimeInterval, + maxCarbEntryQuantity: Double, + maxCarbEntryPastTime: TimeInterval, + maxCarbEntryFutureTime: TimeInterval, + nowDate: Date = Date()) throws -> NewCarbEntry { + + let absorptionTime = absorptionTime ?? defaultAbsorptionTime + if absorptionTime < minAbsorptionTime || absorptionTime > maxAbsorptionTime { + throw CarbActionError.invalidAbsorptionTime(absorptionTime) + } + + guard amountInGrams > 0.0 else { + throw CarbActionError.invalidCarbs + } + + guard amountInGrams <= maxCarbEntryQuantity else { + throw CarbActionError.exceedsMaxCarbs + } + + if let startDate = startDate { + let maxStartDate = nowDate.addingTimeInterval(maxCarbEntryFutureTime) + let minStartDate = nowDate.addingTimeInterval(maxCarbEntryPastTime) + guard startDate <= maxStartDate && startDate >= minStartDate else { + throw CarbActionError.invalidStartDate(startDate) + } + } + + let quantity = HKQuantity(unit: .gram(), doubleValue: amountInGrams) + return NewCarbEntry(quantity: quantity, startDate: startDate ?? nowDate, foodType: foodType, absorptionTime: absorptionTime) + } +} + +enum CarbActionError: LocalizedError { + + case invalidAbsorptionTime(TimeInterval) + case invalidStartDate(Date) + case exceedsMaxCarbs + case invalidCarbs + + var errorDescription: String? { + switch self { + case .exceedsMaxCarbs: + return NSLocalizedString("Exceeds maximum allowed carbs", comment: "Remote command error description: carbs exceed maximum amount.") + case .invalidCarbs: + return NSLocalizedString("Invalid carb amount", comment: "Remote command error description: invalid carb amount.") + case .invalidAbsorptionTime(let absorptionTime): + return String(format: NSLocalizedString("Invalid absorption time: %d hours", comment: "Remote command error description: invalid absorption time."), absorptionTime.hours) + case .invalidStartDate(let startDate): + return String(format: NSLocalizedString("Start time is out of range: %@", comment: "Remote command error description: invalid start time is out of range."), Self.dateFormatter.string(from: startDate)) + } + } + + static var dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.timeStyle = .medium + return formatter + }() +} diff --git a/Loop/Models/Remote/OverrideAction.swift b/Loop/Models/Remote/OverrideAction.swift new file mode 100644 index 0000000000..28ea26e383 --- /dev/null +++ b/Loop/Models/Remote/OverrideAction.swift @@ -0,0 +1,57 @@ +// +// OverrideAction.swift +// Loop +// +// Created by Bill Gestrich on 2/21/23. +// Copyright © 2023 LoopKit Authors. All rights reserved. +// + +import LoopKit + +extension OverrideAction { + + func toValidOverride(allowedPresets: [TemporaryScheduleOverridePreset]) throws -> TemporaryScheduleOverride { + guard let preset = allowedPresets.first(where: { $0.name == name }) else { + throw OverrideActionError.unknownPreset(name) + } + + var remoteOverride = preset.createOverride(enactTrigger: .remote(remoteAddress)) + + if let durationTime = durationTime { + + guard durationTime <= LoopConstants.maxOverrideDurationTime else { + throw OverrideActionError.durationExceedsMax(LoopConstants.maxOverrideDurationTime) + } + + guard durationTime >= 0 else { + throw OverrideActionError.negativeDuration + } + + if durationTime == 0 { + remoteOverride.duration = .indefinite + } else { + remoteOverride.duration = .finite(durationTime) + } + } + + return remoteOverride + } +} + +enum OverrideActionError: LocalizedError { + + case unknownPreset(String) + case durationExceedsMax(TimeInterval) + case negativeDuration + + var errorDescription: String? { + switch self { + case .unknownPreset(let presetName): + return String(format: NSLocalizedString("Unknown preset: %1$@", comment: "Remote command error description: unknown preset (1: preset name)."), presetName) + case .durationExceedsMax(let maxDurationTime): + return String(format: NSLocalizedString("Duration exceeds: %1$.1f hours", comment: "Remote command error description: duration exceed max (1: max duration in hours)."), maxDurationTime.hours) + case .negativeDuration: + return String(format: NSLocalizedString("Negative duration not allowed", comment: "Remote command error description: negative duration error.")) + } + } +} diff --git a/Loop/Models/RemoteCommand.swift b/Loop/Models/RemoteCommand.swift deleted file mode 100644 index 52196b5a82..0000000000 --- a/Loop/Models/RemoteCommand.swift +++ /dev/null @@ -1,105 +0,0 @@ -// -// RemoteCommand.swift -// Loop -// -// Created by Pete Schwamb on 9/16/19. -// Copyright © 2019 LoopKit Authors. All rights reserved. -// - -import Foundation -import LoopKit -import HealthKit - -public enum RemoteCommandError: LocalizedError { - case expired - case invalidOTP - case missingMaxBolus - case exceedsMaxBolus - case exceedsMaxCarbs - case invalidCarbs - - public var errorDescription: String? { - get { - switch self { - case .expired: - return NSLocalizedString("Expired", comment: "Remote command error description: expired.") - case .invalidOTP: - return NSLocalizedString("Invalid OTP", comment: "Remote command error description: invalid OTP.") - case .missingMaxBolus: - return NSLocalizedString("Missing maximum allowed bolus in settings", comment: "Remote command error description: missing maximum bolus in settings.") - case .exceedsMaxBolus: - return NSLocalizedString("Exceeds maximum allowed bolus in settings", comment: "Remote command error description: bolus exceeds maximum bolus in settings.") - case .exceedsMaxCarbs: - return NSLocalizedString("Exceeds maximum allowed carbs", comment: "Remote command error description: carbs exceed maximum amount.") - case .invalidCarbs: - return NSLocalizedString("Invalid carb amount", comment: "Remote command error description: invalid carb amount.") - } - } - } -} - - -enum RemoteCommand { - case temporaryScheduleOverride(TemporaryScheduleOverride) - case cancelTemporaryOverride - case bolusEntry(Double) - case carbsEntry(NewCarbEntry) -} - - -// Push Notifications -extension RemoteCommand { - static func createRemoteCommand(notification: [String: Any], allowedPresets: [TemporaryScheduleOverridePreset], defaultAbsorptionTime: TimeInterval, nowDate: Date = Date()) -> Result { - if let overrideName = notification["override-name"] as? String, - let preset = allowedPresets.first(where: { $0.name == overrideName }), - let remoteAddress = notification["remote-address"] as? String - { - var override = preset.createOverride(enactTrigger: .remote(remoteAddress)) - if let overrideDurationMinutes = notification["override-duration-minutes"] as? Double { - override.duration = .finite(TimeInterval(minutes: overrideDurationMinutes)) - } - return .success(.temporaryScheduleOverride(override)) - } else if let _ = notification["cancel-temporary-override"] as? String { - return .success(.cancelTemporaryOverride) - } else if let bolusValue = notification["bolus-entry"] as? Double { - return .success(.bolusEntry(bolusValue)) - } else if let carbsValue = notification["carbs-entry"] as? Double { - - let minAbsorptionTime = TimeInterval(hours: 0.5) - let maxAbsorptionTime = LoopConstants.maxCarbAbsorptionTime - - var absorptionTime = defaultAbsorptionTime - if let absorptionOverrideInHours = notification["absorption-time"] as? Double { - absorptionTime = TimeInterval(hours: absorptionOverrideInHours) - } - - if absorptionTime < minAbsorptionTime || absorptionTime > maxAbsorptionTime { - return .failure(RemoteCommandParseError.invalidAbsorptionSeconds(absorptionTime)) - } - - let quantity = HKQuantity(unit: .gram(), doubleValue: carbsValue) - - var startDate = nowDate - if let notificationStartTimeString = notification["start-time"] as? String { - let formatter = ISO8601DateFormatter() - formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] - if let notificationStartDate = formatter.date(from: notificationStartTimeString) { - startDate = notificationStartDate - } else { - return .failure(RemoteCommandParseError.invalidStartTime(notificationStartTimeString)) - } - } - - let newEntry = NewCarbEntry(quantity: quantity, startDate: startDate, foodType: "", absorptionTime: absorptionTime) - return .success(.carbsEntry(newEntry)) - } else { - return .failure(RemoteCommandParseError.unhandledNotication("\(notification)")) - } - } - - enum RemoteCommandParseError: LocalizedError { - case invalidStartTime(String) - case invalidAbsorptionSeconds(Double) - case unhandledNotication(String) - } -} diff --git a/Loop/Models/StoredLoopNotRunningNotification.swift b/Loop/Models/StoredLoopNotRunningNotification.swift index 82a6457ac0..0b66f8eeb2 100644 --- a/Loop/Models/StoredLoopNotRunningNotification.swift +++ b/Loop/Models/StoredLoopNotRunningNotification.swift @@ -12,7 +12,6 @@ struct StoredLoopNotRunningNotification: Codable { var alertAt: Date var title: String var body: String - var timeInterval: TimeInterval var isCritical: Bool } diff --git a/Loop/View Controllers/CarbEntryTableViewController.swift b/Loop/View Controllers/CarbEntryTableViewController.swift deleted file mode 100644 index 1c66be5fb3..0000000000 --- a/Loop/View Controllers/CarbEntryTableViewController.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// CarbEntryTableViewController.swift -// Naterade -// -// Created by Nathan Racklyeft on 3/11/16. -// Copyright © 2016 Nathan Racklyeft. All rights reserved. -// - -import LoopKitUI -import LoopCore - - -extension CarbEntryTableViewController: IdentifiableClass { -} diff --git a/Loop/View Controllers/CarbEntryViewController.swift b/Loop/View Controllers/CarbEntryViewController.swift index 3ca4397e9a..31f65e0067 100644 --- a/Loop/View Controllers/CarbEntryViewController.swift +++ b/Loop/View Controllers/CarbEntryViewController.swift @@ -15,8 +15,6 @@ import LoopUI final class CarbEntryViewController: LoopChartsTableViewController, IdentifiableClass { - var navigationDelegate = CarbEntryNavigationDelegate() - var defaultAbsorptionTimes: CarbStore.DefaultAbsorptionTimes? { didSet { if let times = defaultAbsorptionTimes { @@ -33,7 +31,9 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable return deviceManager.displayGlucoseUnitObservable.displayGlucoseUnit } - var maxQuantity = HKQuantity(unit: .gram(), doubleValue: 250) + var maxCarbEntryQuantity = LoopConstants.maxCarbEntryQuantity + + var warningCarbEntryQuantity = LoopConstants.warningCarbEntryQuantity /// Entry configuration values. Must be set before presenting. var absorptionTimePickerInterval = TimeInterval(minutes: 30) @@ -108,10 +108,34 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable private var shouldBeginEditingFoodType = false - private var shouldDisplayAccurateCarbEntryWarning = false { + private var shouldDisplayMissedMealWarning = false { + didSet { + if shouldDisplayMissedMealWarning != oldValue { + if shouldDisplayOverrideEnabledWarning { + self.displayWarningRow(rowType: WarningRow.missedMeal, isAddingRow: shouldDisplayMissedMealWarning) + } else { + self.shouldDisplayWarning = shouldDisplayMissedMealWarning || shouldDisplayOverrideEnabledWarning + } + } + } + } + + private var shouldDisplayOverrideEnabledWarning = false { didSet { - if shouldDisplayAccurateCarbEntryWarning != oldValue { - self.displayAccuracyWarning() + if shouldDisplayOverrideEnabledWarning != oldValue { + if shouldDisplayMissedMealWarning { + self.displayWarningRow(rowType: WarningRow.override, isAddingRow: shouldDisplayOverrideEnabledWarning) + } else { + self.shouldDisplayWarning = shouldDisplayOverrideEnabledWarning || shouldDisplayMissedMealWarning + } + } + } + } + + private var shouldDisplayWarning = false { + didSet { + if shouldDisplayWarning != oldValue { + self.displayWarning() } } } @@ -183,18 +207,18 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - if shouldBeginEditingQuantity, let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.value.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayAccurateCarbEntryWarning))) as? DecimalTextFieldTableViewCell { + if shouldBeginEditingQuantity, let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.value.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayWarning))) as? DecimalTextFieldTableViewCell { shouldBeginEditingQuantity = false cell.textField.becomeFirstResponder() } - // check if the warning should be displayed - updateDisplayAccurateCarbEntryWarning() + // check if warning should be displayed + updateDisplayOverrideEnabledWarning() // monitor loop updates notificationObservers += [ NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: deviceManager.loopManager, queue: nil) { [weak self] _ in - self?.updateDisplayAccurateCarbEntryWarning() + self?.updateDisplayOverrideEnabledWarning() } ] } @@ -215,38 +239,22 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable private var foodKeyboard: EmojiInputController! - private func updateDisplayAccurateCarbEntryWarning() { - let now = Date() - let startDate = now.addingTimeInterval(-LoopConstants.missedMealWarningGlucoseRecencyWindow) - - deviceManager.glucoseStore.getGlucoseSamples(start: startDate, end: nil) { [weak self] (result) -> Void in - DispatchQueue.main.async { - switch result { - case .failure: - self?.shouldDisplayAccurateCarbEntryWarning = false - case .success(let samples): - let filteredSamples = samples.filterDateRange(startDate, now) - guard let startSample = filteredSamples.first, let endSample = filteredSamples.last else { - self?.shouldDisplayAccurateCarbEntryWarning = false - return - } - let duration = endSample.startDate.timeIntervalSince(startSample.startDate) - guard duration >= LoopConstants.missedMealWarningVelocitySampleMinDuration else { - self?.shouldDisplayAccurateCarbEntryWarning = false - return - } - let delta = endSample.quantity.doubleValue(for: .milligramsPerDeciliter) - startSample.quantity.doubleValue(for: .milligramsPerDeciliter) - let velocity = delta / duration.minutes // Unit = mg/dL/m - self?.shouldDisplayAccurateCarbEntryWarning = velocity > LoopConstants.missedMealWarningGlucoseRiseThreshold + private func updateDisplayOverrideEnabledWarning() { + DispatchQueue.main.async { + if let managerSettings = self.deviceManager?.settings { + if !managerSettings.scheduleOverrideEnabled(at: Date()) { + self.shouldDisplayOverrideEnabledWarning = false + } else if let overrideSettings = managerSettings.scheduleOverride?.settings { + self.shouldDisplayOverrideEnabledWarning = overrideSettings.effectiveInsulinNeedsScaleFactor != 1.0 } } } } - private func displayAccuracyWarning() { + private func displayWarning() { tableView.beginUpdates() - if shouldDisplayAccurateCarbEntryWarning { + if shouldDisplayWarning { tableView.insertSections([Sections.warning.rawValue], with: .top) } else { tableView.deleteSections([Sections.warning.rawValue], with: .top) @@ -254,6 +262,23 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable tableView.endUpdates() } + + private func displayWarningRow(rowType: WarningRow, isAddingRow: Bool = true ) { + if shouldDisplayWarning { + tableView.beginUpdates() + + // If the missed meal warning is shown, use the positional index of the given row type. + let rowIndex = shouldDisplayMissedMealWarning ? rowType.rawValue : 0 + + if isAddingRow { + tableView.insertRows(at: [IndexPath(row: rowIndex, section: Sections.warning.rawValue)], with: UITableView.RowAnimation.top) + } else { + tableView.deleteRows(at: [IndexPath(row: rowIndex, section: Sections.warning.rawValue)], with: UITableView.RowAnimation.top) + } + + tableView.endUpdates() + } + } // MARK: - Table view data source fileprivate enum Sections: Int, CaseIterable { @@ -272,9 +297,9 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable return displayWarningSection ? indexPath.section : indexPath.section + 1 } - static func numberOfRows(for section: Int, displayWarningSection: Bool) -> Int { - if section == Sections.warning.rawValue && displayWarningSection { - return 1 + static func numberOfRows(for section: Int, displayMissedMealWarning: Bool, displayOverrideWarning: Bool) -> Int { + if section == Sections.warning.rawValue && (displayMissedMealWarning || displayOverrideWarning) { + return displayMissedMealWarning && displayOverrideWarning ? WarningRow.allCases.count : WarningRow.allCases.count - 1 } return DetailsRow.allCases.count @@ -307,32 +332,54 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable case foodType case absorptionTime } + + fileprivate enum WarningRow: Int, CaseIterable { + case missedMeal + case override + } override func numberOfSections(in tableView: UITableView) -> Int { - return Sections.numberOfSections(displayWarningSection: shouldDisplayAccurateCarbEntryWarning) + return Sections.numberOfSections(displayWarningSection: shouldDisplayWarning) } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return Sections.numberOfRows(for: section, displayWarningSection: shouldDisplayAccurateCarbEntryWarning) + return Sections.numberOfRows(for: section, displayMissedMealWarning: shouldDisplayMissedMealWarning, displayOverrideWarning: shouldDisplayOverrideEnabledWarning) } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch Sections(rawValue: Sections.section(for: indexPath, displayWarningSection: shouldDisplayAccurateCarbEntryWarning))! { + switch Sections(rawValue: Sections.section(for: indexPath, displayWarningSection: shouldDisplayWarning))! { case .warning: let cell: UITableViewCell - if let existingCell = tableView.dequeueReusableCell(withIdentifier: "CarbEntryAccuracyWarningCell") { - cell = existingCell + // if no missed meal warning should be shown OR if the given indexPath is for the override warning row, return the override warning cell. + if !shouldDisplayMissedMealWarning || WarningRow(rawValue: indexPath.row)! == .override { + if let existingCell = tableView.dequeueReusableCell(withIdentifier: "CarbEntryOverrideEnabledWarningCell") { + cell = existingCell + } else { + cell = UITableViewCell(style: .default, reuseIdentifier: "CarbEntryOverrideEnabledWarningCell") + } + + cell.imageView?.image = UIImage(systemName: "exclamationmark.triangle.fill") + cell.imageView?.tintColor = .warning + cell.textLabel?.numberOfLines = 0 + cell.textLabel?.text = NSLocalizedString("An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override.", comment: "Warning to ensure the carb entry is accurate during an override") + cell.textLabel?.font = UIFont.preferredFont(forTextStyle: .caption1) + cell.textLabel?.textColor = .secondaryLabel + cell.isUserInteractionEnabled = false } else { - cell = UITableViewCell(style: .default, reuseIdentifier: "CarbEntryAccuracyWarningCell") + if let existingCell = tableView.dequeueReusableCell(withIdentifier: "CarbEntryAccuracyWarningCell") { + cell = existingCell + } else { + cell = UITableViewCell(style: .default, reuseIdentifier: "CarbEntryAccuracyWarningCell") + } + + cell.imageView?.image = UIImage(systemName: "exclamationmark.triangle.fill") + cell.imageView?.tintColor = .destructive + cell.textLabel?.numberOfLines = 0 + cell.textLabel?.text = NSLocalizedString("Loop has detected an missed meal and estimated its size. Edit the carb amount to match the amount of any carbs you may have eaten.", comment: "Warning displayed when user is adding a meal from an missed meal notification") + cell.textLabel?.font = UIFont.preferredFont(forTextStyle: .caption1) + cell.textLabel?.textColor = .secondaryLabel + cell.isUserInteractionEnabled = false } - - cell.imageView?.image = UIImage(systemName: "exclamationmark.triangle.fill") - cell.imageView?.tintColor = .destructive - cell.textLabel?.numberOfLines = 0 - cell.textLabel?.text = NSLocalizedString("Your glucose is rapidly rising. Check that any carbs you've eaten were logged. If you logged carbs, check that the time you entered lines up with when you started eating.", comment: "Warning to ensure the carb entry is accurate") - cell.textLabel?.font = UIFont.preferredFont(forTextStyle: .caption1) - cell.textLabel?.textColor = .secondaryLabel - cell.isUserInteractionEnabled = false return cell case .details: switch DetailsRow(rawValue: indexPath.row)! { @@ -415,7 +462,7 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable } override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { - switch Sections(rawValue: Sections.section(for: indexPath, displayWarningSection: shouldDisplayAccurateCarbEntryWarning)) { + switch Sections(rawValue: Sections.section(for: indexPath, displayWarningSection: shouldDisplayWarning)) { case .details: switch DetailsRow(rawValue: indexPath.row)! { case .value, .date: @@ -434,15 +481,15 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable } override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { - return Sections.footer(for: section, displayWarningSection: shouldDisplayAccurateCarbEntryWarning) + return Sections.footer(for: section, displayWarningSection: shouldDisplayWarning) } override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - return Sections.headerHeight(for: section, displayWarningSection: shouldDisplayAccurateCarbEntryWarning) + return Sections.headerHeight(for: section, displayWarningSection: shouldDisplayWarning) } override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { - return Sections.footerHeight(for: section, displayWarningSection: shouldDisplayAccurateCarbEntryWarning) + return Sections.footerHeight(for: section, displayWarningSection: shouldDisplayWarning) } // MARK: - UITableViewDelegate @@ -459,7 +506,7 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable case is FoodTypeShortcutCell: usesCustomFoodType = true shouldBeginEditingFoodType = true - tableView.reloadRows(at: [IndexPath(row: DetailsRow.foodType.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayAccurateCarbEntryWarning))], with: .none) + tableView.reloadRows(at: [IndexPath(row: DetailsRow.foodType.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayWarning))], with: .none) default: break } @@ -485,22 +532,39 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable self.absorptionTime = absorptionTime absorptionTimeWasEdited = true } + + if activity.entryisMissedMeal { + shouldDisplayMissedMealWarning = true + } } } @objc private func continueButtonPressed() { tableView.endEditing(true) - guard validateInput(), let updatedEntry = updatedCarbEntry else { + guard validateInput() else { + return + } + continueToBolus() + } + + private func continueToBolus() { + + guard let updatedEntry = updatedCarbEntry else { return } let viewModel = BolusEntryViewModel( delegate: deviceManager, + screenWidth: UIScreen.main.bounds.width, originalCarbEntry: originalCarbEntry, potentialCarbEntry: updatedEntry, selectedCarbAbsorptionTimeEmoji: selectedDefaultAbsorptionTimeEmoji ) - viewModel.generateRecommendationAndStartObserving() + Task { + await viewModel.generateRecommendationAndStartObserving() + } + + viewModel.analyticsServicesManager = deviceManager.analyticsServicesManager let bolusEntryView = BolusEntryView(viewModel: viewModel).environmentObject(deviceManager.displayGlucoseUnitObservable) @@ -511,6 +575,7 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable dismissalMode: originalCarbEntry == nil ? .modalDismiss : .pop(to: predecessorViewControllerType) ) show(hostingController, sender: footerView.primaryButton) + deviceManager.analyticsServicesManager.didDisplayBolusScreen() } private func validateInput() -> Bool { @@ -518,17 +583,25 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable return false } guard absorptionTime <= maxAbsorptionTime else { - navigationDelegate.showAbsorptionTimeValidationWarning(for: self, maxAbsorptionTime: maxAbsorptionTime) + showAbsorptionTimeValidationWarning(for: self, maxAbsorptionTime: maxAbsorptionTime) return false } guard let quantity = quantity, quantity.doubleValue(for: preferredCarbUnit) > 0 else { return false } - guard quantity.compare(maxQuantity) != .orderedDescending else { - navigationDelegate.showMaxQuantityValidationWarning(for: self, maxQuantityGrams: maxQuantity.doubleValue(for: .gram())) + guard quantity.compare(maxCarbEntryQuantity) != .orderedDescending else { + showMaxQuantityValidationWarning(for: self, maxQuantityGrams: maxCarbEntryQuantity.doubleValue(for: .gram())) return false } - return true + let enteredGrams = quantity.doubleValue(for: .gram()) + + if (enteredGrams > warningCarbEntryQuantity.doubleValue(for: .gram())) { + showWarningQuantityValidationWarning(for: self, enteredGrams: enteredGrams) { + self.continueToBolus() + } + return false + } + return true } private func updateContinueButtonEnabled() { @@ -540,6 +613,65 @@ final class CarbEntryViewController: LoopChartsTableViewController, Identifiable footerView.primaryButton.isEnabled = readyToContinue navigationItem.rightBarButtonItem?.isEnabled = readyToContinue } + + // Alerts + private lazy var dismissActionTitle = NSLocalizedString("com.loudnate.LoopKit.errorAlertActionTitle", value: "OK", comment: "The title of the action used to dismiss an error alert") + + public func showAbsorptionTimeValidationWarning(for viewController: UIViewController, maxAbsorptionTime: TimeInterval) { + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.minute] + formatter.unitsStyle = .full + + let message = String( + format: NSLocalizedString("The maximum absorption time is %@", comment: "Alert body displayed absorption time greater than max (1: maximum absorption time)"), + formatter.string(from: maxAbsorptionTime) ?? String(describing: maxAbsorptionTime)) + let validationTitle = NSLocalizedString("Maximum Duration Exceeded", comment: "Alert title when maximum duration exceeded.") + let alert = UIAlertController(title: validationTitle, message: message, preferredStyle: .alert) + + let action = UIAlertAction(title: dismissActionTitle, style: .default) + alert.addAction(action) + alert.preferredAction = action + + viewController.present(alert, animated: true) + } + + public func showWarningQuantityValidationWarning(for viewController: UIViewController, enteredGrams: Double, didConfirm: @escaping () -> Void) { + let warningTitle = NSLocalizedString("Large Meal Entered", comment: "Title of the warning shown when a large meal was entered") + + let message = String( + format: NSLocalizedString("Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?", comment: "Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams)"), + NumberFormatter.localizedString(from: NSNumber(value: enteredGrams), number: .none) + ) + let alert = UIAlertController(title: warningTitle, message: message, preferredStyle: .alert) + + let editButtonText = NSLocalizedString("No, edit amount", comment: "The title of the action used when rejecting the the amount of carbohydrates entered.") + let editAction = UIAlertAction(title: editButtonText, style: .default) + alert.addAction(editAction) + + let confirmButtonText = NSLocalizedString("Yes", comment: "The title of the action used when confirming entered amount of carbohydrates.") + let confirm = UIAlertAction(title: confirmButtonText, style: .default) {_ in + didConfirm(); + } + alert.addAction(confirm) + alert.preferredAction = confirm + + viewController.present(alert, animated: true) + } + + public func showMaxQuantityValidationWarning(for viewController: UIViewController, maxQuantityGrams: Double) { + let errorTitle = NSLocalizedString("Input Maximum Exceeded", comment: "Title of the alert when carb input maximum was exceeded.") + let message = String( + format: NSLocalizedString("The maximum allowed amount is %@ grams.", comment: "Alert body displayed for quantity greater than max (1: maximum quantity in grams)"), + NumberFormatter.localizedString(from: NSNumber(value: maxQuantityGrams), number: .none) + ) + let alert = UIAlertController(title: errorTitle, message: message, preferredStyle: .alert) + + let action = UIAlertAction(title: dismissActionTitle, style: .default) + alert.addAction(action) + alert.preferredAction = action + + viewController.present(alert, animated: true) + } } @@ -605,14 +737,14 @@ extension CarbEntryViewController: FoodTypeShortcutCellDelegate { tableView.beginUpdates() usesCustomFoodType = true shouldBeginEditingFoodType = true - tableView.reloadRows(at: [IndexPath(row: DetailsRow.foodType.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayAccurateCarbEntryWarning))], with: .fade) + tableView.reloadRows(at: [IndexPath(row: DetailsRow.foodType.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayWarning))], with: .fade) tableView.endUpdates() } if let absorptionTime = absorptionTime { self.absorptionTime = absorptionTime - if let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.absorptionTime.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayAccurateCarbEntryWarning))) as? DateAndDurationTableViewCell { + if let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.absorptionTime.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayWarning))) as? DateAndDurationTableViewCell { cell.duration = absorptionTime } } @@ -624,7 +756,7 @@ extension CarbEntryViewController: FoodTypeShortcutCellDelegate { extension CarbEntryViewController: EmojiInputControllerDelegate { func emojiInputControllerDidAdvanceToStandardInputMode(_ controller: EmojiInputController) { - if let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.foodType.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayAccurateCarbEntryWarning))) as? TextFieldTableViewCell, let textField = cell.textField as? CustomInputTextField, textField.customInput != nil { + if let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.foodType.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayWarning))) as? TextFieldTableViewCell, let textField = cell.textField as? CustomInputTextField, textField.customInput != nil { let customInput = textField.customInput textField.customInput = nil textField.resignFirstResponder() @@ -642,7 +774,7 @@ extension CarbEntryViewController: EmojiInputControllerDelegate { // only adjust the absorption time if it wasn't already set. absorptionTime = orderedAbsorptionTimes[section] - if let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.absorptionTime.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayAccurateCarbEntryWarning))) as? DateAndDurationTableViewCell { + if let cell = tableView.cellForRow(at: IndexPath(row: DetailsRow.absorptionTime.rawValue, section: Sections.indexForDetailsSection(displayWarningSection: shouldDisplayWarning))) as? DateAndDurationTableViewCell { cell.duration = orderedAbsorptionTimes[section] } } diff --git a/Loop/View Controllers/CommandResponseViewController.swift b/Loop/View Controllers/CommandResponseViewController.swift index d000dfe99d..e14c41c8a4 100644 --- a/Loop/View Controllers/CommandResponseViewController.swift +++ b/Loop/View Controllers/CommandResponseViewController.swift @@ -19,7 +19,7 @@ extension CommandResponseViewController { deviceManager.generateDiagnosticReport { (report) in DispatchQueue.main.async { completionHandler([ - "Use the Share button above save this diagnostic report to aid investigating your problem. Issues can be filed at https://github.com/LoopKit/Loop/issues.", + "Use the Share button above to save this diagnostic report to aid investigating your problem. Issues can be filed at https://github.com/LoopKit/Loop/issues.", "Generated: \(date)", "", report, diff --git a/Loop/View Controllers/StatusTableViewController.swift b/Loop/View Controllers/StatusTableViewController.swift index d3ab7cc3e4..0af4bcea5a 100644 --- a/Loop/View Controllers/StatusTableViewController.swift +++ b/Loop/View Controllers/StatusTableViewController.swift @@ -885,7 +885,7 @@ final class StatusTableViewController: LoopChartsTableViewController { contentConfig.textProperties.color = .white contentConfig.textProperties.font = .systemFont(ofSize: adjustViewForNarrowDisplay ? 16 : 18, weight: .bold) contentConfig.textProperties.adjustsFontSizeToFitWidth = true - contentConfig.secondaryText = NSLocalizedString("Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON.", comment: "instructions on how to fix alert permission warning") + contentConfig.secondaryText = NSLocalizedString("Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON.", comment: "Secondary text for alerts disabled warning, which appears on the main status screen.") contentConfig.secondaryTextProperties.color = .white contentConfig.secondaryTextProperties.font = .systemFont(ofSize: adjustViewForNarrowDisplay ? 13 : 15) contentConfiguration = contentConfig @@ -1360,6 +1360,7 @@ final class StatusTableViewController: LoopChartsTableViewController { navigationWrapper = UINavigationController(rootViewController: carbEntryViewController) } present(navigationWrapper, animated: true) + deviceManager.analyticsServicesManager.didDisplayCarbEntryScreen() } @IBAction func presentBolusScreen() { @@ -1373,14 +1374,18 @@ final class StatusTableViewController: LoopChartsTableViewController { let bolusEntryView = SimpleBolusView(viewModel: viewModel).environmentObject(deviceManager.displayGlucoseUnitObservable) hostingController = DismissibleHostingController(rootView: bolusEntryView, isModalInPresentation: false) } else { - let viewModel = BolusEntryViewModel(delegate: deviceManager, isManualGlucoseEntryEnabled: enableManualGlucoseEntry) - viewModel.generateRecommendationAndStartObserving() + let viewModel = BolusEntryViewModel(delegate: deviceManager, screenWidth: UIScreen.main.bounds.width, isManualGlucoseEntryEnabled: enableManualGlucoseEntry) + Task { @MainActor in + await viewModel.generateRecommendationAndStartObserving() + } + viewModel.analyticsServicesManager = deviceManager.analyticsServicesManager let bolusEntryView = BolusEntryView(viewModel: viewModel).environmentObject(deviceManager.displayGlucoseUnitObservable) hostingController = DismissibleHostingController(rootView: bolusEntryView, isModalInPresentation: false) } let navigationWrapper = UINavigationController(rootViewController: hostingController) hostingController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: navigationWrapper, action: #selector(dismissWithAnimation)) present(navigationWrapper, animated: true) + deviceManager.analyticsServicesManager.didDisplayBolusScreen() } private func createPreMealButtonItem(selected: Bool, isEnabled: Bool) -> UIBarButtonItem { diff --git a/Loop/View Models/BolusEntryViewModel.swift b/Loop/View Models/BolusEntryViewModel.swift index be17d4c400..525eb6ad2c 100644 --- a/Loop/View Models/BolusEntryViewModel.swift +++ b/Loop/View Models/BolusEntryViewModel.swift @@ -22,8 +22,8 @@ protocol BolusEntryViewModelDelegate: AnyObject { func withLoopState(do block: @escaping (LoopState) -> Void) - func addGlucoseSamples(_ samples: [NewGlucoseSample], completion: ((_ result: Swift.Result<[StoredGlucoseSample], Error>) -> Void)?) - + func saveGlucose(sample: NewGlucoseSample) async -> StoredGlucoseSample? + func addCarbEntry(_ carbEntry: NewCarbEntry, replacing replacingEntry: StoredCarbEntry? , completion: @escaping (_ result: Result) -> Void) @@ -52,8 +52,11 @@ protocol BolusEntryViewModelDelegate: AnyObject { var displayGlucoseUnitObservable: DisplayGlucoseUnitObservable { get } func roundBolusVolume(units: Double) -> Double + + func updateRemoteRecommendation() } +@MainActor final class BolusEntryViewModel: ObservableObject { enum Alert: Int { case recommendationChanged @@ -73,10 +76,22 @@ final class BolusEntryViewModel: ObservableObject { case predictedGlucoseBelowSuspendThreshold(suspendThreshold: HKQuantity) case glucoseBelowTarget case staleGlucoseData + case futureGlucoseData case stalePumpData } - var authenticate: AuthenticationChallenge = LocalAuthentication.deviceOwnerCheck + var authenticationHandler: (String) async -> Bool = { message in + return await withCheckedContinuation { continuation in + LocalAuthentication.deviceOwnerCheck(message) { result in + switch result { + case .success: + continuation.resume(returning: true) + case .failure: + continuation.resume(returning: false) + } + } + } + } // MARK: - State @@ -98,10 +113,6 @@ final class BolusEntryViewModel: ObservableObject { let potentialCarbEntry: NewCarbEntry? let selectedCarbAbsorptionTimeEmoji: String? - @Published var isManualGlucoseEntryEnabled = false - @Published var manualGlucoseQuantity: HKQuantity? - private var manualGlucoseSample: NewGlucoseSample? // derived from `enteredManualGlucose`, but stored to ensure timestamp consistency - @Published var recommendedBolus: HKQuantity? var recommendedBolusAmount: Double? { recommendedBolus?.doubleValue(for: .internationalUnit()) @@ -112,6 +123,7 @@ final class BolusEntryViewModel: ObservableObject { } private var userChangedBolusAmount = false @Published var isInitiatingSaveOrBolus = false + @Published var enacting = false private var dosingDecision = BolusDosingDecision(for: .normalBolus) @@ -132,52 +144,12 @@ final class BolusEntryViewModel: ObservableObject { traitCollection: UITraitCollection.current) }() - // needed to detect change in display glucose unit when returning to the app - private var cachedDisplayGlucoseUnit: HKUnit - - private var displayGlucoseUnit: HKUnit? { - delegate?.displayGlucoseUnitObservable.displayGlucoseUnit - } - - private let glucoseQuantityFormatter = QuantityFormatter() + let glucoseQuantityFormatter = QuantityFormatter() - private var _manualGlucoseString = "" { - didSet { - guard let manualGlucoseValue = glucoseQuantityFormatter.numberFormatter.number(from: _manualGlucoseString)?.doubleValue - else { - manualGlucoseQuantity = nil - return - } + @Published var isManualGlucoseEntryEnabled = false + @Published var manualGlucoseQuantity: HKQuantity? - // only update manualGlucoseQuantity if needed - if manualGlucoseQuantity == nil || - _manualGlucoseString != glucoseQuantityFormatter.string(from: manualGlucoseQuantity!, for: cachedDisplayGlucoseUnit, includeUnit: false) - { - manualGlucoseQuantity = HKQuantity(unit: cachedDisplayGlucoseUnit, doubleValue: manualGlucoseValue) - } - } - } - - var manualGlucoseString: String { - get { - guard let displayGlucoseUnit = displayGlucoseUnit else { return "" } - if cachedDisplayGlucoseUnit != displayGlucoseUnit { - cachedDisplayGlucoseUnit = displayGlucoseUnit - glucoseQuantityFormatter.setPreferredNumberFormatter(for: displayGlucoseUnit) - guard let manualGlucoseQuantity = manualGlucoseQuantity, - let manualGlucoseString = glucoseQuantityFormatter.string(from: manualGlucoseQuantity, for: displayGlucoseUnit, includeUnit: false) - else { - _manualGlucoseString = "" - return _manualGlucoseString - } - self._manualGlucoseString = manualGlucoseString - } - return _manualGlucoseString - } - set { - _manualGlucoseString = newValue - } - } + var manualGlucoseSample: NewGlucoseSample? // MARK: - Seams private weak var delegate: BolusEntryViewModelDelegate? @@ -186,13 +158,15 @@ final class BolusEntryViewModel: ObservableObject { private let debounceIntervalMilliseconds: Int private let uuidProvider: () -> String private let carbEntryDateFormatter: DateFormatter + + var analyticsServicesManager: AnalyticsServicesManager? // MARK: - Initialization init( delegate: BolusEntryViewModelDelegate, now: @escaping () -> Date = { Date() }, - screenWidth: CGFloat = UIScreen.main.bounds.width, + screenWidth: CGFloat, debounceIntervalMilliseconds: Int = 400, uuidProvider: @escaping () -> String = { UUID().uuidString }, timeZone: TimeZone? = nil, @@ -223,20 +197,18 @@ final class BolusEntryViewModel: ObservableObject { self.dosingDecision.originalCarbEntry = originalCarbEntry - self.cachedDisplayGlucoseUnit = delegate.displayGlucoseUnitObservable.displayGlucoseUnit - self.updateSettings() } - public func generateRecommendationAndStartObserving(_ completion: (() -> Void)? = nil) { - update() { - // Only start observing after first update is complete - self.observeLoopUpdates() - self.observeEnteredManualGlucoseChanges() - self.observeElapsedTime() - self.observeEnteredBolusChanges() - completion?() - } + public func generateRecommendationAndStartObserving() async { + await update() + + // Only start observing after first update is complete + self.observeLoopUpdates() + self.observeElapsedTime() + self.observeEnteredManualGlucoseChanges() + self.observeEnteredBolusChanges() + } private func observeLoopUpdates() { @@ -244,13 +216,15 @@ final class BolusEntryViewModel: ObservableObject { .publisher(for: .LoopDataUpdated) .receive(on: DispatchQueue.main) .sink { [weak self] note in - if let rawContext = note.userInfo?[LoopDataManager.LoopUpdateContextKey] as? LoopDataManager.LoopUpdateContext.RawValue, - let context = LoopDataManager.LoopUpdateContext(rawValue: rawContext), - context == .preferences - { - self?.updateSettings() + Task { + if let rawContext = note.userInfo?[LoopDataManager.LoopUpdateContextKey] as? LoopDataManager.LoopUpdateContext.RawValue, + let context = LoopDataManager.LoopUpdateContext(rawValue: rawContext), + context == .preferences + { + self?.updateSettings() + } + await self?.update() } - self?.update() } .store(in: &cancellables) } @@ -270,13 +244,9 @@ final class BolusEntryViewModel: ObservableObject { private func observeEnteredManualGlucoseChanges() { $manualGlucoseQuantity - .dropFirst() - .debounce(for: .milliseconds(debounceIntervalMilliseconds), scheduler: RunLoop.main) - .sink { [weak self] enteredManualGlucose in + .sink { [weak self] manualGlucoseQuantity in guard let self = self else { return } - self.updateManualGlucoseSample(enteredAt: self.now()) - // Clear out any entered bolus whenever the glucose entry changes self.enteredBolus = HKQuantity(unit: .internationalUnit(), doubleValue: 0) @@ -288,10 +258,24 @@ final class BolusEntryViewModel: ObservableObject { self?.updateRecommendedBolusAndNotice(from: state, isUpdatingFromUserInput: true) } + + if let manualGlucoseQuantity = manualGlucoseQuantity { + self.manualGlucoseSample = NewGlucoseSample( + date: self.now(), + quantity: manualGlucoseQuantity, + condition: nil, // All manual glucose entries are assumed to have no condition. + trend: nil, // All manual glucose entries are assumed to have no trend. + trendRate: nil, // All manual glucose entries are assumed to have no trend rate. + isDisplayOnly: false, + wasUserEntered: true, + syncIdentifier: self.uuidProvider() + ) + } } .store(in: &cancellables) } + private func observeElapsedTime() { // If glucose data is stale, loop status updates cannot be expected to keep presented data fresh. // Periodically update the UI to ensure recommendations do not go stale. @@ -300,12 +284,10 @@ final class BolusEntryViewModel: ObservableObject { .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } - self.log.default("5 minutes elapsed on bolus screen; refreshing UI") - - // Update the manual glucose sample's timestamp, which should always be "now" - self.updateManualGlucoseSample(enteredAt: self.now()) - self.update() + Task { + await self.update() + } } .store(in: &cancellables) } @@ -320,142 +302,132 @@ final class BolusEntryViewModel: ObservableObject { return recommendedBolusAmount > 0 } - func saveAndDeliver(onSuccess completion: @escaping () -> Void) { + func saveCarbEntry(_ entry: NewCarbEntry, replacingEntry: StoredCarbEntry?) async -> StoredCarbEntry? { + guard let delegate = delegate else { + return nil + } + + return await withCheckedContinuation { continuation in + delegate.addCarbEntry(entry, replacing: replacingEntry) { result in + switch result { + case .success(let storedCarbEntry): + continuation.resume(returning: storedCarbEntry) + case .failure(let error): + self.log.error("Failed to add carb entry: %{public}@", String(describing: error)) + continuation.resume(returning: nil) + } + } + } + } + + // returns true if action succeeded + func didPressActionButton() async -> Bool { + enacting = true + if await saveAndDeliver() { + return true + } else { + enacting = false + return false + } + } + + // returns true if no errors + func saveAndDeliver() async -> Bool { guard delegate?.isPumpConfigured ?? false else { presentAlert(.noPumpManagerConfigured) - return + return false } guard let delegate = delegate else { assertionFailure("Missing BolusEntryViewModelDelegate") - return + return false } let amountToDeliver = delegate.roundBolusVolume(units: enteredBolusAmount) guard enteredBolusAmount == 0 || amountToDeliver > 0 else { presentAlert(.bolusTooSmall) - return + return false } let amountToDeliverString = formatBolusAmount(amountToDeliver) - // Capture state as is during initial action, to prevent race conditions - // caused by later updates to member variables while async operations are - // in progress let manualGlucoseSample = manualGlucoseSample let potentialCarbEntry = potentialCarbEntry guard let maximumBolus = maximumBolus else { presentAlert(.noMaxBolusConfigured) - return + return false } guard amountToDeliver <= maximumBolus.doubleValue(for: .internationalUnit()) else { presentAlert(.maxBolusExceeded) - return + return false } if let manualGlucoseSample = manualGlucoseSample { guard LoopConstants.validManualGlucoseEntryRange.contains(manualGlucoseSample.quantity) else { presentAlert(.manualGlucoseEntryOutOfAcceptableRange) - return + return false } } // Authenticate the bolus before saving anything if amountToDeliver > 0 { - isInitiatingSaveOrBolus = true let message = String(format: NSLocalizedString("Authenticate to Bolus %@ Units", comment: "The message displayed during a device authentication prompt for bolus specification"), amountToDeliverString) - authenticate(message) { [weak self] in - switch $0 { - case .success: - self?.continueSaving(amountToDeliver: amountToDeliver, manualGlucoseSample: manualGlucoseSample, potentialCarbEntry: potentialCarbEntry, onSuccess: completion) - case .failure: - self?.isInitiatingSaveOrBolus = false - break - } + + if !(await authenticationHandler(message)) { + return false } - } else if potentialCarbEntry != nil { // Allow user to save carbs without bolusing - continueSaving(amountToDeliver: amountToDeliver, manualGlucoseSample: manualGlucoseSample, potentialCarbEntry: potentialCarbEntry, onSuccess: completion) - } else if manualGlucoseSample != nil { // Allow user to save the manual glucose sample without bolusing - continueSaving(amountToDeliver: amountToDeliver, manualGlucoseSample: manualGlucoseSample, potentialCarbEntry: potentialCarbEntry, onSuccess: completion) - } else { - completion() } - } - - private func continueSaving(amountToDeliver: Double, manualGlucoseSample: NewGlucoseSample?, potentialCarbEntry: NewCarbEntry?, onSuccess completion: @escaping () -> Void) { + + defer { + delegate.updateRemoteRecommendation() + } + if let manualGlucoseSample = manualGlucoseSample { - isInitiatingSaveOrBolus = true - delegate?.addGlucoseSamples([manualGlucoseSample]) { result in - DispatchQueue.main.async { - switch result { - case .success(let glucoseValues): - self.dosingDecision.manualGlucoseSample = glucoseValues.first - self.saveCarbsAndDeliverBolus(amountToDeliver: amountToDeliver, potentialCarbEntry: potentialCarbEntry, onSuccess: completion) - case .failure(let error): - self.isInitiatingSaveOrBolus = false - self.presentAlert(.manualGlucoseEntryPersistenceFailure) - self.log.error("Failed to add manual glucose entry: %{public}@", String(describing: error)) - } - } + if let glucoseValue = await delegate.saveGlucose(sample: manualGlucoseSample) { + dosingDecision.manualGlucoseSample = glucoseValue + } else { + presentAlert(.manualGlucoseEntryPersistenceFailure) + return false } } else { self.dosingDecision.manualGlucoseSample = nil - saveCarbsAndDeliverBolus(amountToDeliver: amountToDeliver, potentialCarbEntry: potentialCarbEntry, onSuccess: completion) } - } - private func saveCarbsAndDeliverBolus(amountToDeliver: Double, potentialCarbEntry: NewCarbEntry?, onSuccess completion: @escaping () -> Void) { - let activationType = BolusActivationType.activationTypeFor(recommendedAmount: recommendedBolusAmount, bolusAmount: amountToDeliver) + let activationType = BolusActivationType.activationTypeFor(recommendedAmount: recommendedBolus?.doubleValue(for: .internationalUnit()), bolusAmount: amountToDeliver) - guard let carbEntry = potentialCarbEntry else { - dosingDecision.carbEntry = nil - deliverBolus(amountToDeliver, activationType: activationType, onSuccess: completion) - return - } + if let carbEntry = potentialCarbEntry { + if originalCarbEntry == nil { + let interaction = INInteraction(intent: NewCarbEntryIntent(), response: nil) - if originalCarbEntry == nil { - let interaction = INInteraction(intent: NewCarbEntryIntent(), response: nil) - interaction.donate { [weak self] (error) in - if let error = error { - self?.log.error("Failed to donate intent: %{public}@", String(describing: error)) + do { + try await interaction.donate() + } catch { + log.error("Failed to donate intent: %{public}@", String(describing: error)) } } - } - - isInitiatingSaveOrBolus = true - delegate?.addCarbEntry(carbEntry, replacing: originalCarbEntry) { result in - DispatchQueue.main.async { - switch result { - case .success(let storedCarbEntry): - self.dosingDecision.carbEntry = storedCarbEntry - self.deliverBolus(amountToDeliver, activationType: activationType, onSuccess: completion) - case .failure(let error): - self.isInitiatingSaveOrBolus = false - self.presentAlert(.carbEntryPersistenceFailure) - self.log.error("Failed to add carb entry: %{public}@", String(describing: error)) - } + if let storedCarbEntry = await saveCarbEntry(carbEntry, replacingEntry: originalCarbEntry) { + self.dosingDecision.carbEntry = storedCarbEntry + self.analyticsServicesManager?.didAddCarbs(source: "Phone", amount: storedCarbEntry.quantity.doubleValue(for: .gram())) + } else { + self.presentAlert(.carbEntryPersistenceFailure) + return false } } - } - private func deliverBolus(_ amount: Double, activationType: BolusActivationType, onSuccess completion: @escaping () -> Void) { - let now = self.now() + dosingDecision.manualBolusRequested = amountToDeliver - dosingDecision.manualBolusRequested = amount - delegate?.storeManualBolusDosingDecision(dosingDecision, withDate: now) + let now = self.now() + delegate.storeManualBolusDosingDecision(dosingDecision, withDate: now) - guard amount > 0 else { - completion() - return + if amountToDeliver > 0 { + savedPreMealOverride = nil + delegate.enactBolus(units: amountToDeliver, activationType: activationType, completion: { _ in + self.analyticsServicesManager?.didBolus(source: "Phone", units: amountToDeliver) + }) } - - isInitiatingSaveOrBolus = true - savedPreMealOverride = nil - - delegate?.enactBolus(units: amount, activationType: activationType, completion: { _ in }) - completion() + return true } private func presentAlert(_ alert: Alert) { @@ -527,39 +499,25 @@ final class BolusEntryViewModel: ObservableObject { } // MARK: - Data upkeep - - private func updateManualGlucoseSample(enteredAt entryDate: Date) { - dispatchPrecondition(condition: .onQueue(.main)) - - manualGlucoseSample = manualGlucoseQuantity.map { quantity in - NewGlucoseSample( - date: entryDate, - quantity: quantity, - condition: nil, // All manual glucose entries are assumed to have no condition. - trend: nil, // All manual glucose entries are assumed to have no trend. - trendRate: nil, // All manual glucose entries are assumed to have no trend rate. - isDisplayOnly: false, - wasUserEntered: true, - syncIdentifier: uuidProvider() - ) - } - } - - private func update(_ completion: (() -> Void)? = nil) { + func update() async { dispatchPrecondition(condition: .onQueue(.main)) // Prevent any UI updates after a bolus has been initiated. - guard !isInitiatingSaveOrBolus else { - completion?() + guard !enacting else { return } disableManualGlucoseEntryIfNecessary() updateChartDateInterval() updateStoredGlucoseValues() - updatePredictionAndRecommendation() { - self.updateActiveInsulin() - completion?() + await updatePredictionAndRecommendation() + + if let iob = await getInsulinOnBoard() { + self.activeInsulin = HKQuantity(unit: .internationalUnit(), doubleValue: iob.value) + self.dosingDecision.insulinOnBoard = iob + } else { + self.activeInsulin = nil + self.dosingDecision.insulinOnBoard = nil } } @@ -568,7 +526,6 @@ final class BolusEntryViewModel: ObservableObject { if isManualGlucoseEntryEnabled, !isGlucoseDataStale { isManualGlucoseEntryEnabled = false - manualGlucoseString = "" manualGlucoseQuantity = nil manualGlucoseSample = nil presentAlert(.glucoseNoLongerStale) @@ -646,34 +603,33 @@ final class BolusEntryViewModel: ObservableObject { } } - private func updateActiveInsulin() { - delegate?.insulinOnBoard(at: Date()) { [weak self] result in - guard let self = self else { return } + private func getInsulinOnBoard() async -> InsulinValue? { + guard let delegate = delegate else { + return nil + } - DispatchQueue.main.async { + return await withCheckedContinuation { continuation in + delegate.insulinOnBoard(at: Date()) { result in switch result { case .success(let iob): - self.activeInsulin = HKQuantity(unit: .internationalUnit(), doubleValue: iob.value) - self.dosingDecision.insulinOnBoard = iob + continuation.resume(returning: iob) case .failure: - self.activeInsulin = nil - self.dosingDecision.insulinOnBoard = nil + continuation.resume(returning: nil) } } } } - private func updatePredictionAndRecommendation(_ completion: @escaping () -> Void) { + private func updatePredictionAndRecommendation() async { guard let delegate = delegate else { - completion() return } - delegate.withLoopState { [weak self] state in - self?.updateCarbsOnBoard(from: state) - self?.updateRecommendedBolusAndNotice(from: state, isUpdatingFromUserInput: false) - self?.updatePredictedGlucoseValues(from: state) - DispatchQueue.main.async { - completion() + return await withCheckedContinuation { continuation in + delegate.withLoopState { [weak self] state in + self?.updateCarbsOnBoard(from: state) + self?.updateRecommendedBolusAndNotice(from: state, isUpdatingFromUserInput: false) + self?.updatePredictedGlucoseValues(from: state) + continuation.resume() } } } @@ -736,6 +692,8 @@ final class BolusEntryViewModel: ObservableObject { switch error { case LoopError.missingDataError(.glucose), LoopError.glucoseTooOld: notice = .staleGlucoseData + case LoopError.invalidFutureGlucose: + notice = .futureGlucoseData case LoopError.pumpDataTooOld: notice = .stalePumpData default: @@ -751,7 +709,7 @@ final class BolusEntryViewModel: ObservableObject { if priorRecommendedBolus != nil, priorRecommendedBolus != recommendedBolus, - !self.isInitiatingSaveOrBolus, + !self.enacting, !isUpdatingFromUserInput { self.presentAlert(.recommendationChanged) @@ -779,7 +737,7 @@ final class BolusEntryViewModel: ObservableObject { } } - private func updateSettings() { + func updateSettings() { dispatchPrecondition(condition: .onQueue(.main)) guard let delegate = delegate else { diff --git a/Loop/View Models/VersionUpdateViewModel.swift b/Loop/View Models/VersionUpdateViewModel.swift index 2114786b98..fa2b87e6c5 100644 --- a/Loop/View Models/VersionUpdateViewModel.swift +++ b/Loop/View Models/VersionUpdateViewModel.swift @@ -74,11 +74,8 @@ public class VersionUpdateViewModel: ObservableObject { } public func update() { - supportManager?.checkVersion { [weak self] versionUpdate in - DispatchQueue.main.async { - self?.versionUpdate = versionUpdate - } + Task { @MainActor in + versionUpdate = await supportManager?.checkVersion() } } - } diff --git a/Loop/Views/AlertManagementView.swift b/Loop/Views/AlertManagementView.swift index 4388601a2e..856db6da11 100644 --- a/Loop/Views/AlertManagementView.swift +++ b/Loop/Views/AlertManagementView.swift @@ -45,6 +45,15 @@ struct AlertManagementView: View { private var formatterDurations: [String] { AlertMuter.allowedDurations.compactMap { formatter.string(from: $0) } } + + private var missedMealNotificationsEnabled: Binding { + Binding( + get: { UserDefaults.standard.missedMealNotificationsEnabled }, + set: { enabled in + UserDefaults.standard.missedMealNotificationsEnabled = enabled + } + ) + } public init(checker: AlertPermissionsChecker, alertMuter: AlertMuter = AlertMuter()) { self.checker = checker @@ -57,6 +66,9 @@ struct AlertManagementView: View { if FeatureFlags.criticalAlertsEnabled { muteAlertsSection } + if FeatureFlags.missedMealNotifications { + missedMealAlertSection + } } .navigationTitle(NSLocalizedString("Alert Management", comment: "Title of alert management screen")) } @@ -155,6 +167,27 @@ struct AlertManagementView: View { message: Text(NSLocalizedString("No alerts or alarms will sound while muted. Select how long you would you like to mute for.", comment: "Message for mute alert duration selection action sheet")), buttons: muteAlertDurationOptions) } + + private var missedMealAlertSection: some View { + Section(footer: DescriptiveText(label: NSLocalizedString("When enabled, Loop can notify you when it detects a meal that wasn't logged.", comment: "Description of missed meal notifications."))) { + Toggle(NSLocalizedString("Missed Meal Notifications", comment: "Title for missed meal notifications toggle"), isOn: missedMealNotificationsEnabled) + } + } +} + +extension UserDefaults { + private enum Key: String { + case missedMealNotificationsEnabled = "com.loopkit.Loop.MissedMealNotificationsEnabled" + } + + var missedMealNotificationsEnabled: Bool { + get { + return object(forKey: Key.missedMealNotificationsEnabled.rawValue) as? Bool ?? false + } + set { + set(newValue, forKey: Key.missedMealNotificationsEnabled.rawValue) + } + } } struct AlertManagementView_Previews: PreviewProvider { diff --git a/Loop/Views/BolusEntryView.swift b/Loop/Views/BolusEntryView.swift index b556f452af..60fee77696 100644 --- a/Loop/Views/BolusEntryView.swift +++ b/Loop/Views/BolusEntryView.swift @@ -24,8 +24,6 @@ struct BolusEntryView: View { @State private var enteredBolusString = "" @State private var shouldBolusEntryBecomeFirstResponder = false - @State private var isManualGlucoseEntryRowVisible = false - @State private var isInteractingWithChart = false @State private var isKeyboardVisible = false @State private var pickerShouldExpand = false @@ -60,25 +58,21 @@ struct BolusEntryView: View { .keyboardAware() .edgesIgnoringSafeArea(self.isKeyboardVisible ? [] : .bottom) .navigationBarTitle(self.title) - .supportedInterfaceOrientations(.portrait) - .alert(item: self.$viewModel.activeAlert, content: self.alert(for:)) - .onReceive(self.viewModel.$recommendedBolus) { recommendation in - // If the user has not edited the bolus amount and there are recommendation changes, then update the bolus amount - guard !editedBolusAmount else { return } - - guard let amount = recommendation?.doubleValue(for: .internationalUnit()), - amount != 0 - else { - enteredBolusStringBinding.wrappedValue = "" - return + .supportedInterfaceOrientations(.portrait) + .alert(item: self.$viewModel.activeAlert, content: self.alert(for:)) + .onReceive(self.viewModel.$recommendedBolus) { recommendation in + // If the recommendation changes, and the user has not edited the bolus amount, update the bolus amount + let amount = recommendation?.doubleValue(for: .internationalUnit()) ?? 0 + if !editedBolusAmount { + var newEnteredBolusString: String + if amount == 0 { + newEnteredBolusString = "" + } else { + newEnteredBolusString = viewModel.formatBolusAmount(amount) } - - enteredBolusStringBinding.wrappedValue = viewModel.formatBolusAmount(amount) - } - .onReceive(self.viewModel.$isManualGlucoseEntryEnabled) { isManualGlucoseEntryEnabled in - // The view model can disable manual glucose entry if CGM data returns. - self.isManualGlucoseEntryRowVisible = isManualGlucoseEntryEnabled + enteredBolusStringBinding.wrappedValue = newEnteredBolusString } + } } } @@ -92,7 +86,7 @@ struct BolusEntryView: View { private func shouldAutoScroll(basedOn geometry: GeometryProxy) -> Bool { // Taking a guess of 640 to cover iPhone SE, iPod Touch, and other smaller devices. // Devices such as the iPhone 11 Pro Max do not need to auto-scroll. - shouldBolusEntryBecomeFirstResponder && geometry.size.height < 640 + return shouldBolusEntryBecomeFirstResponder && geometry.size.height > 640 } private var chartSection: some View { @@ -185,7 +179,7 @@ struct BolusEntryView: View { .frame(maxWidth: .infinity, alignment: .leading) if viewModel.isManualGlucoseEntryEnabled { - manualGlucoseEntryRow + ManualGlucoseEntryRow(quantity: $viewModel.manualGlucoseQuantity) } else if viewModel.potentialCarbEntry != nil { potentialCarbEntryRow } else { @@ -214,43 +208,6 @@ struct BolusEntryView: View { QuantityFormatter(for: displayGlucoseUnitObservable.displayGlucoseUnit).numberFormatter } - @ViewBuilder - private var manualGlucoseEntryRow: some View { - if viewModel.isManualGlucoseEntryEnabled { - HStack { - Text("Fingerstick Glucose", comment: "Label for manual glucose entry row on bolus screen") - Spacer() - HStack(alignment: .firstTextBaseline) { - DismissibleKeyboardTextField( - text: enteredManualGlucose, - placeholder: NSLocalizedString("– – –", comment: "No glucose value representation (3 dashes for mg/dL)"), - font: .heavy(.title1), - textAlignment: .right, - keyboardType: .decimalPad, - shouldBecomeFirstResponder: isManualGlucoseEntryRowVisible, - maxLength: 4, - doneButtonColor: .loopAccent - ) - Text(QuantityFormatter().string(from: displayGlucoseUnitObservable.displayGlucoseUnit)) - .foregroundColor(Color(.secondaryLabel)) - } - } - .onKeyboardStateChange { state in - if state.animationDuration > 0 { - DispatchQueue.main.asyncAfter(deadline: .now() + state.animationDuration) { - self.isManualGlucoseEntryRowVisible = true - } - } - } - } - } - - private var enteredManualGlucose: Binding { - Binding( - get: { viewModel.manualGlucoseString }, - set: { newValue in viewModel.manualGlucoseString = newValue } - ) - } @ViewBuilder private var potentialCarbEntryRow: some View { @@ -361,6 +318,11 @@ struct BolusEntryView: View { title: Text("No Recent Glucose Data", comment: "Title for bolus screen notice when glucose data is missing or stale"), caption: Text("Enter a blood glucose from a meter for a recommended bolus amount.", comment: "Caption for bolus screen notice when glucose data is missing or stale") ) + case .futureGlucoseData: + return WarningView( + title: Text("Invalid Future Glucose", comment: "Title for bolus screen notice when glucose data is in the future"), + caption: Text("Check your device time and/or remove any invalid data from Apple Health.", comment: "Caption for bolus screen notice when glucose data is in the future") + ) case .stalePumpData: return WarningView( title: Text("No Recent Pump Data", comment: "Title for bolus screen notice when pump data is missing or stale"), @@ -394,7 +356,11 @@ struct BolusEntryView: View { if self.viewModel.actionButtonAction == .enterBolus { self.shouldBolusEntryBecomeFirstResponder = true } else { - self.viewModel.saveAndDeliver(onSuccess: self.dismiss) + Task { + if await self.viewModel.didPressActionButton() { + dismiss() + } + } } }, label: { @@ -411,7 +377,7 @@ struct BolusEntryView: View { } ) .buttonStyle(ActionButtonStyle(viewModel.primaryButton == .actionButton ? .primary : .secondary)) - .disabled(viewModel.isInitiatingSaveOrBolus) + .disabled(viewModel.enacting) .padding() } diff --git a/Loop/Views/ManualGlucoseEntryRow.swift b/Loop/Views/ManualGlucoseEntryRow.swift new file mode 100644 index 0000000000..ddfc5ae378 --- /dev/null +++ b/Loop/Views/ManualGlucoseEntryRow.swift @@ -0,0 +1,75 @@ +// +// ManualGlucoseEntryRow.swift +// Loop +// +// Created by Pete Schwamb on 12/8/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import Foundation +import SwiftUI +import LoopKit +import LoopKitUI +import Combine +import HealthKit + +struct ManualGlucoseEntryRow: View { + @EnvironmentObject private var displayGlucoseUnitObservable: DisplayGlucoseUnitObservable + + @State private var valueText = "" + + @Binding var quantity: HKQuantity? + + let glucoseQuantityFormatter = QuantityFormatter() + + @State private var isManualGlucoseEntryRowVisible = false + + @FocusState private var fieldIsFocused: Bool + + var body: some View { + HStack { + Text("Fingerstick Glucose", comment: "Label for manual glucose entry row on bolus screen") + Spacer() + + HStack(alignment: .firstTextBaseline) { + DismissibleKeyboardTextField( + text: $valueText, + placeholder: NSLocalizedString("– – –", comment: "No glucose value representation (3 dashes for mg/dL)"), + font: .heavy(.title1), + textAlignment: .right, + keyboardType: .decimalPad, + shouldBecomeFirstResponder: isManualGlucoseEntryRowVisible, + maxLength: 4, + doneButtonColor: .loopAccent + ) + .onChange(of: valueText, perform: { value in + if let manualGlucoseValue = glucoseQuantityFormatter.numberFormatter.number(from: valueText)?.doubleValue { + quantity = HKQuantity(unit: displayGlucoseUnitObservable.displayGlucoseUnit, doubleValue: manualGlucoseValue) + } else { + quantity = nil + } + }) + .onChange(of: displayGlucoseUnitObservable.displayGlucoseUnit, perform: { value in + unitsChanged() + }) + + Text(QuantityFormatter().string(from: displayGlucoseUnitObservable.displayGlucoseUnit)) + .foregroundColor(Color(.secondaryLabel)) + } + } + .onKeyboardStateChange { state in + if state.animationDuration > 0 { + DispatchQueue.main.asyncAfter(deadline: .now() + state.animationDuration) { + self.isManualGlucoseEntryRowVisible = true + } + } + } + } + + func unitsChanged() { + glucoseQuantityFormatter.setPreferredNumberFormatter(for: displayGlucoseUnitObservable.displayGlucoseUnit) + if let quantity = quantity { + valueText = glucoseQuantityFormatter.string(from: quantity, for: displayGlucoseUnitObservable.displayGlucoseUnit, includeUnit: false) ?? "" + } + } +} diff --git a/Loop/Views/NotificationsCriticalAlertPermissionsView.swift b/Loop/Views/NotificationsCriticalAlertPermissionsView.swift index 79eb9bd4e8..e69084a46a 100644 --- a/Loop/Views/NotificationsCriticalAlertPermissionsView.swift +++ b/Loop/Views/NotificationsCriticalAlertPermissionsView.swift @@ -143,9 +143,9 @@ extension NotificationsCriticalAlertPermissionsView { } } } - } + struct NotificationsCriticalAlertPermissionsView_Previews: PreviewProvider { static var previews: some View { return Group { diff --git a/Loop/Views/SettingsView.swift b/Loop/Views/SettingsView.swift index 52e797fe4b..22c10d48dd 100644 --- a/Loop/Views/SettingsView.swift +++ b/Loop/Views/SettingsView.swift @@ -48,7 +48,7 @@ public struct SettingsView: View { } alertManagementSection if viewModel.pumpManagerSettingsViewModel.isSetUp() { - therapySettingsSection + configurationSection } deviceSettingsSection if viewModel.pumpManagerSettingsViewModel.isTestingDevice || viewModel.cgmManagerSettingsViewModel.isTestingDevice { @@ -58,6 +58,9 @@ public struct SettingsView: View { servicesSection } supportSection + if let profileExpiration = Bundle.main.profileExpiration, FeatureFlags.profileExpirationSettingsViewEnabled { + profileExpirationSection(profileExpiration: profileExpiration) + } } .insetGroupedListStyle() .navigationBarTitle(Text(NSLocalizedString("Settings", comment: "Settings screen title"))) @@ -73,6 +76,16 @@ public struct SettingsView: View { } } +struct ConfigurationMenuItem: Identifiable { + var id: String { + return pluginIdentifier + String(describing: offset) + } + + let view: AnyView + let pluginIdentifier: String + let offset: Int +} + extension SettingsView { private var dismissButton: some View { @@ -145,7 +158,7 @@ extension SettingsView { } } - private var therapySettingsSection: some View { + private var configurationSection: some View { Section(header: SectionHeader(label: NSLocalizedString("Configuration", comment: "The title of the Configuration section in settings"))) { LargeButton(action: { self.therapySettingsIsPresented = true }, includeArrow: true, @@ -167,9 +180,21 @@ extension SettingsView { .environment(\.guidanceColors, self.guidanceColors) .environment(\.insulinTintColor, self.insulinTintColor) } + + ForEach(configurationMenuItemsForSupportPlugins) { item in + item.view + } } } - + + private var configurationMenuItemsForSupportPlugins: [ConfigurationMenuItem] { + self.viewModel.availableSupports.flatMap { plugin in + plugin.configurationMenuItems().enumerated().map { index, view in + ConfigurationMenuItem(view: view, pluginIdentifier: plugin.identifier, offset: index) + } + } + } + private var deviceSettingsSection: some View { Section { pumpSection @@ -320,6 +345,40 @@ extension SettingsView { } } } + + /* + DIY loop specific component to show users the amount of time remaining on their build before a rebuild is necessary. + */ + private func profileExpirationSection(profileExpiration:Date) -> some View { + let nearExpiration : Bool = ProfileExpirationAlerter.isNearProfileExpiration(profileExpiration: profileExpiration) + let profileExpirationMsg = ProfileExpirationAlerter.createProfileExpirationSettingsMessage(profileExpiration: profileExpiration) + let readableExpirationTime = Self.dateFormatter.string(from: profileExpiration) + + return Section(header: SectionHeader(label: NSLocalizedString("App Profile", comment: "Settings app profile section")), + footer: Text(NSLocalizedString("Profile expires ", comment: "Time that profile expires") + readableExpirationTime)) { + if(nearExpiration) { + Text(profileExpirationMsg).foregroundColor(.red) + } else { + HStack { + Text("Profile Expiration", comment: "Settings App Profile expiration view") + Spacer() + Text(profileExpirationMsg).foregroundColor(Color.secondary) + } + } + Button(action: { + UIApplication.shared.open(URL(string: "https://loopkit.github.io/loopdocs/build/updating/")!) + }) { + Text(NSLocalizedString("How to update (LoopDocs)", comment: "The title text for how to update")) + } + } + } + + private static var dateFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .long + dateFormatter.timeStyle = .short + return dateFormatter // formats date like "February 4, 2023 at 2:35 PM" + }() private var plusImage: some View { Image(systemName: "plus.circle") diff --git a/Loop/ar.lproj/InfoPlist.strings b/Loop/ar.lproj/InfoPlist.strings index c13bf054d4..be734bf6e0 100644 --- a/Loop/ar.lproj/InfoPlist.strings +++ b/Loop/ar.lproj/InfoPlist.strings @@ -1,3 +1,5 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; @@ -16,3 +18,4 @@ /* Privacy - Health Update Usage Description */ "NSHealthUpdateUsageDescription" = "بيانات كربوهيدرات الوجبة المدخلة للتطبيق و الساعة محفوظة في قواعد بيانات تطبيق صحتي. يتم تخزين بيانات سكر الدم المستردة من نظام متابعة سكر الدم المستمرة بشكل آمن في تطبيق صحتي."; + diff --git a/Loop/ar.lproj/Localizable.strings b/Loop/ar.lproj/Localizable.strings index 0404117d5b..e91468b9b2 100644 --- a/Loop/ar.lproj/Localizable.strings +++ b/Loop/ar.lproj/Localizable.strings @@ -1,6 +1,30 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (قيد الانتظار: %@)"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "—"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* The format for an active override preset. (1: preset symbol)(2: preset name) */ +"%@ %@" = "%1$@ %2$@"; + +/* Formats absorbed carb value */ +"%@ absorbed" = "%@ استغرق"; + +/* The subtitle format describing total insulin. (1: localized insulin total) */ +"%@ U Total" = "%@ وحدة بشكل كامل"; + +/* Appends a full-stop to a statement */ +"%@." = "%@."; + +/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/وحدة"; @@ -19,24 +43,9 @@ /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; -/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; - /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; -/* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%1$@ %2$@"; - -/* Formats absorbed carb value */ -"%@ absorbed" = "%@ استغرق"; - -/* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ وحدة بشكل كامل"; - -/* Appends a full-stop to a statement */ -"%@." = "%@."; - /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 دقيقة معامل انحدار قراءات سكر الدم (b₁), ويستمر بالاضمحلال خلال 30 دقيقة"; @@ -58,12 +67,18 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "الكربوهيدرات النشطة: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "كارب النشط"; + /* The title of the Insulin On-Board graph */ -"Active Insulin" = "الأنسولين النشط"; +"Active Insulin" = "أنسولين نشط"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "الأنسولين النشط: %@"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Add Carb Entry"; + /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "إضافة CGM"; @@ -78,9 +93,6 @@ /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "تعديل على نموذج الكبار على أساس التأثيرات التجريبية عند الأطفال."; - /* The title of the amplitude API key credential */ "API Key" = "API Key"; @@ -105,7 +117,7 @@ /* The label of the bolus entry button The notification title for a bolus failure */ -"Bolus" = "الجرعة"; +"Bolus" = "Bolus"; /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "تم ضخ %1$@ من %2$@"; @@ -126,6 +138,9 @@ The title text for the carb ratio schedule */ "Carb Ratios" = "معاملات الكارب"; +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Add Carb Entry"; + /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "الكربوهيدرات"; @@ -172,8 +187,8 @@ /* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "تجاوز مخصص"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "رمز العميل"; +/* The short unit display string for decibles */ +"dB" = "dB"; /* Button title to delete CGM */ "Delete CGM" = "حذف CGM"; @@ -184,6 +199,10 @@ /* The action hint of the workout mode toggle button when enabled */ "Disables" = "تعطيل"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "تجاهل"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "تفعيل"; @@ -208,6 +227,9 @@ /* The format string used to describe a finite workout targets duration */ "For %1$@" = "لمدة %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "قراءات السكر"; @@ -220,9 +242,6 @@ /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "مقاومة سكر الدم"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://mysite.herokuapp.com"; - /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "إلى أجل غير مسمى"; @@ -258,18 +277,21 @@ /* The loading message for the diagnostic report screen */ "Loading..." = "تحميل..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; - /* The notification title for a loop failure */ "Loop Failure" = "فشل في الحلقة المغلقة"; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "لم تتم الحلقة المغلقة بنجاح منذ %@"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "بيانات مفقودة: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "تأثيرات النشاط"; @@ -279,6 +301,17 @@ /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "لا يوجد أجهزة متصلة, أو يوجد خطأ أثناء الاتصال"; +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "موافق"; + +/* Notification Setting Status is On */ +"On" = "On"; + /* The title text for the override presets */ "Override Presets" = "تخطي الإعدادات المسبقة"; @@ -315,6 +348,9 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "تم إيقاف الضخ مؤقتا"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "التأثيرالسريع - كبار"; @@ -325,7 +361,7 @@ "Recommendation expired: %1$@ old" = "انتهت صلاحية التوصية منذ: %1$@ "; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "الضخ المستمر الموصى به"; +"Recommended Basal" = "الضخ المستمر المقترح"; /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "الجرعة الموصى بها: %@ وحدات"; @@ -375,6 +411,10 @@ /* The short unit display string for international units of insulin */ "U" = "وحدة"; +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Unknown"; + /* The format for the description of a temporary override end date */ "until %@" = "حتى %@"; diff --git a/Loop/ar.lproj/Main.strings b/Loop/ar.lproj/Main.strings index a2074e1b8a..9b859aca71 100644 --- a/Loop/ar.lproj/Main.strings +++ b/Loop/ar.lproj/Main.strings @@ -1,36 +1,32 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "الحالة"; -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "رقم هوية المضخة"; - /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 وحدة/ساعة @ 12:12 مساء"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "الضخ"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "كمية الضخ"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "تنبأ"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "وحدات"; +/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ +"aCb-Qs-bpu.text" = "تفاصيل"; + +/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ +"bIL-Ub-qYp.text" = "Label"; + +/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ +"bq4-98-cQU.text" = "تغير قراءات السكر"; -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "وحدة"; +/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ +"d3X-AN-tA5.text" = "g المجموع"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ "D4C-I2-dhA.text" = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "أجهزة"; +/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ +"d6m-qV-wWi.text" = "Label"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "في النهاية 92 mg/dL"; @@ -38,107 +34,54 @@ /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "مُلاحظ"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 وحدة/ساعة @ 12:12 مساء"; + +/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ +"hZZ-2S-lrd.title" = "تأثيرات الكربوهيدرات"; + /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ "IxU-As-glo.text" = "التغيرات الملاحظة على سكر الدم وتغيرات الخصم المشكل من توصيل الأنسولين بالإمكان استخدامها لتقدير امتصاص الكربوهيدرات."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "تفاصيل"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ +"k3F-Na-7mn.text" = "الضخ المستمر المقترح"; + /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "علامة"; +"Krd-Aa-ret.text" = "Label"; /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "علامة"; +"OFA-qT-ZAg.text" = "Label"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "سكر الدم المتوقع"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "يتم استخدام نموذج نشاط الأنسولين لتقدير آثار الأنسولين على مستويات قراءات سكر الدم. يمكن أن يساعد النموذج الدقيق في منع تكديس الأنسولين والتوصية بعلاجات تصحيحية آمنة."; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "في النهاية 92 mg/dL"; -/* Class = "UILabel"; text = "g COB"; ObjectID = "SQx-au-ZcM"; */ +/* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ "SQx-au-ZcM.text" = "g كارب نشط"; -/* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ -"Vpi-5b-bY5.title" = "الكربوهيدرات"; - -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 ساعات"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "ضخ"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "تفاصيل"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "الجرعة"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "علامة"; - -/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "تغير قراءات السكر"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "علامة"; - -/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g المجموع"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "علامة"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "الإعدادات"; - -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "الكربوهيدرات النشطة: 40g"; - -/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "تأثيرات الكربوهيدرات"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ التنبأ بسكر الدم دون النطاق"; - -/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "الضخ المستمر المقترح"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "علامة"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "انقر للتعيين"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "وحدات"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "وحدة"; - -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "نوع الأنسولين"; - /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ "tuw-av-A3x.text" = "قراءات السكر"; /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "علامة"; +"ufi-Kj-33k.text" = "Label"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "الأنسولين النشط: 1.5وحدة"; +/* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ +"Vpi-5b-bY5.title" = "الكربوهيدرات"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "الضخ المستمر المقترح"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "مقترح"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "عنوان"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; + diff --git a/Loop/cs.lproj/Localizable.strings b/Loop/cs.lproj/Localizable.strings new file mode 100644 index 0000000000..f27d65665b --- /dev/null +++ b/Loop/cs.lproj/Localizable.strings @@ -0,0 +1,90 @@ +/* remaining time in setting's profile expiration section */ +" remaining" = "zbývající"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* Settings app profile section */ +"App Profile" = "Profil"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Opravdu chcete tuto službu smazat?"; + +/* The title of the basal rate profile screen + The title text for the basal rate schedule */ +"Basal Rates" = "Úrovně bazálu"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Zrušit"; + +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfigurace"; + +/* Default alert dismissal */ +"Continue" = "Pokračovat"; + +/* Critical Alerts Status text */ +"Critical Alerts" = "Kritická upozornění"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Smazat účet"; + +/* Button title to delete a service */ +"Delete Service" = "Smazat službu"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Limity podávání"; + +/* No comment provided by engineer. */ +"Done" = "Hotovo"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Opravit nyní zapnutím Oznámení, Kritických upozornění a Časově citlivých oznámení."; + +/* The title of the glucose and prediction graph */ +"Glucose" = "Glukóza"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Jak aktualizovat (LoopDocs)"; + +/* Insulin type label */ +"Insulin Type" = "Typ inzulínu"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Notification Setting Status is Off */ +"Off" = "Vypnuto"; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Zapnuto"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Vypršení platnosti profilu"; + +/* Time that profile expires */ +"Profile expires " = "Platnost profilu vyprší"; + +/* The title of the notification action to retry a bolus command */ +"Retry" = "Zkusit znovu"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "URL adresa webu"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Neznámý čas"; + diff --git a/Loop/cs.lproj/Main.strings b/Loop/cs.lproj/Main.strings new file mode 100644 index 0000000000..8b1faf67aa --- /dev/null +++ b/Loop/cs.lproj/Main.strings @@ -0,0 +1,6 @@ +/* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ +"3kU-n2-fha.title" = "Status"; + +/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ +"tuw-av-A3x.text" = "Glukóza"; + diff --git a/Loop/da.lproj/InfoPlist.strings b/Loop/da.lproj/InfoPlist.strings index 7ecc4483b1..3c10346dc8 100644 --- a/Loop/da.lproj/InfoPlist.strings +++ b/Loop/da.lproj/InfoPlist.strings @@ -1,18 +1,27 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth bliver brugt til at kommunikere med din insulin pumpe og din glukose monitor."; +"NSBluetoothAlwaysUsageDescription" = "Bluetooth bliver brugt til at kommunikere med din insulinpumpe og din glukosemonitor."; /* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Bluetooth bliver brugt til at kommunikere med din insulin pumpe og din glukose monitor."; +"NSBluetoothPeripheralUsageDescription" = "Bluetooth bliver brugt til at kommunikere med din insulinpumpe og din glukosemonitor."; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Kamera bruges til at scanne stregkoder på enheder."; /* Privacy - Face ID Usage Description */ -"NSFaceIDUsageDescription" = "Face ID bliver brugt til at godkende en insulin bolus."; +"NSFaceIDUsageDescription" = "Face ID bliver brugt til at godkende en insulinbolus."; /* Privacy - Health Share Usage Description */ -"NSHealthShareUsageDescription" = "Måltidsdata fra Apple Sundhed bliver brugt til at glukosens effekt på dit blodsukker. Glukose data fra Apple Sundhed bliver brugt til at danne grafer og udregninger."; +"NSHealthShareUsageDescription" = "Måltidsdata fra Apple Health bliver brugt til at glukosens effekt på dit blodsukker. Glukose data fra Apple Health bliver brugt til at danne grafer og udregninger."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Kulhydrater indtastet i appen og på uret gemmes i Apple Sundhedsdatabasen. Glukosedata hentet fra CGM gemmes sikkert i SundhedsKit."; +"NSHealthUpdateUsageDescription" = "Data om kulhydratmåltider, der indtastes i appen og på uret, gemmes i Apples Health-database. Glukosedata, der hentes fra CGM'en, gemmes sikkert i HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop bruger Siri til at give dig mulighed for at udføre forudindstillinger med din stemme."; diff --git a/Loop/da.lproj/Localizable.strings b/Loop/da.lproj/Localizable.strings index 01fe077f3a..33c567280d 100644 --- a/Loop/da.lproj/Localizable.strings +++ b/Loop/da.lproj/Localizable.strings @@ -1,27 +1,78 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (afventer: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = "Før-måltid forudindstillinger"; + +/* remaining time in setting's profile expiration section */ +" remaining" = " tilbage"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = " Sikkerhedsmeddelelser er SLÅET FRA"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = "Motion forudindstilling"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ "%@ absorbed" = "%@ optaget"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ tilbage"; + /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ E Total"; /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@%2$@ kunne ikke annullere din nuværende midlertidige basalrate, som er højere end den nye Max basalgrænse, du har indstillet. Dette kan resultere i en højere insulintilførsel end ønsket.\n\nOvervej at suspendere insulintilførslen manuelt og derefter straks genoptage den for at iværksætte basaltilførslen med den nye grænse på plads."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/E"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ kører med Lukket Loop i positionen OFF. Din pumpe og CGM fortsætter med at fungere, men appen justerer ikke doseringen automatisk."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ kan ikke slette advarslen fra din enhed"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ kan ikke kommunikere med insulinpumpen. Loop vil fortsætte med at forsøge at kommunikere med din pumpe, men insulinafgivelsesoplysninger kan ikke opdateres og ingen automatisering kan fortsætte.\nDu kan vente et par minutter for at se, om problemet bliver løst, eller tryk på knappen nedenfor for at få mere at vide om andre muligheder."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Tidsindstillinger kræver opmærksomhed"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ E"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ E tilbage"; @@ -34,21 +85,49 @@ /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ holder op med at fungere i %2$@. Du skal opdatere inden da med en ny provisioneringsprofil."; + /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 min. glukoseregressionskoefficient (b₁), fortsætter med henfald over 30 minutter."; /* Description of the prediction input effect for retrospective correction */ "30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min. sammenligning af glukose-forudsigelse kontra faktisk målt glukose, med henfald over 60 minutter."; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Et par sekunder tilbage"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "En manuel blodsukkerindtastning skal være mellem %1$@ og %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "En manuel glukoseindtastning skal være mellem %1$@ og %2$@"; + /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "En model baseret på publiceret data om absorption af Fiasp insulin."; /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "En model baseret på publiceret data om absorption Humalog, Novolog, og Apidra insulin hos voksne."; +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "En ny version af %@ er tilgængelig og anbefales for at fortsætte med at bruge appen."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "En ny version af %@ er tilgængelig."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "En pumpe skal være konfigureret, før en bolus kan leveres."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Absorptionstid"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AccepterAnbefaletBolus"; @@ -58,8 +137,11 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Aktive kulhydrater: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Aktive kulhydrater"; + /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Aktiv insulin"; +"Active Insulin" = "Aktivt insulin"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "Aktiv insulin: %@"; @@ -71,18 +153,47 @@ Title text for button to set up a CGM */ "Add CGM" = "Tilføj CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Tilføj måltid"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ "Add Pump" = "Tilføj pumpe"; +/* Title text for button to set up a service */ +"Add Service" = "Tilføj tjeneste"; + +/* No comment provided by engineer. */ +"Adjusted for" = "Justeret for"; + +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Administration af advarsler"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Alarmtilladelser"; + +/* The title of the section containing algorithm settings */ +"Algorithm Settings" = "Indstillinger for algoritme"; + /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "En tilpasning til voksenmodellen baseret på empiriske data hos børn."; +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "En aktiv Override ændrer dit kulhydratforhold og din insulinfølsomhed. Hvis du ikke ønsker, at dette skal påvirke din bolusberegning og dit forventede glukose, kan du overveje at slå Override fra."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Der opstod en fejl under forsøget på at gemme kulhydratindtastning."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Der opstod en fejl under forsøget på at gemme en manuel blodsukkerindtastning."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Der er opstået en uventet fejltilstand i forbindelse med onboarding."; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "En opdateret bolusanbefaling er tilgængelig."; /* The title of the amplitude API key credential */ "API Key" = "API nøgle"; @@ -90,8 +201,26 @@ /* The title of the nightscout API secret credential */ "API Secret" = "API kodeord"; +/* Settings app profile section */ +"App Profile" = "App-profil"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Er du sikker på at du vil slette alle gamle indtastninger?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Er du sikker på, at du vil slette alle logget dosis?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Er du sikker på at du vil slette alle reservoirværdier?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Er du sikker på, at du vil slette alle dine %@ data?\n(Denne handling kan ikke fortrydes)"; + /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Er du sikker på at du vil slette denne CGM?"; +"Are you sure you want to delete this CGM?" = "Er du sikker på, at du vil slette denne CGM?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Er du sikker på, du vil slette denne service?"; /* Format fragment for a specific time */ "at %@" = "at %@"; @@ -99,17 +228,47 @@ /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Godkend bolus af %@ Enheder"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Godkend for at logge %@ enheder"; + /* Details for configuration error when basal rate schedule is missing */ -"Basal Rate Schedule" = "Basal rater skema"; +"Basal Rate Schedule" = "Basalrateskema"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Basal rater"; +"Basal Rates" = "Basalrater"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Baseret på din forventede glukose anbefales ingen bolus."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth slået fra"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth ikke tilgængelig"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Advarsel om Bluetooth slået fra"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Bluetooth er ikke tilgængelig"; /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Bolus"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Bolusproblem"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Bolusanbefaling opdateret"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Bolus-resumé"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus for lille"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Bolus %1$@ af %2$@"; @@ -123,23 +282,39 @@ "Canceling Bolus" = "Annullerer bolus"; /* Details for missing data error when carb effects are missing */ -"Carb effects" = "Kulhydrat effekt"; +"Carb effects" = "Kulhydrateffekter"; + +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Indtast kulhydrater"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Tidsplan for kulhydratforhold"; /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Kulhydrat ratios"; +"Carb Ratios" = "Kulhydratforhold"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Tilføj kulhydrater"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Rediger kulhydrater"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Kulhydratindtastning for stor"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Kulhydrater"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Kulhydrater absorberet (g) ÷ Kulhydrat ratio (g/E) × Insulin følsomhed (%1$@/E)"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Kulhydrater absorberet (g) ÷ Kulhydratratio (g/E) × Insulinfølsomhed (%1$@/E)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Udskift pumpe batteri omgående"; +"Change the pump battery immediately" = "Udskift pumpebatteri omgående"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Skift pumpe reservoir nu"; +"Change the pump reservoir now" = "Skift pumpereservoir nu"; /* Details for configuration error when one or more loop settings are missing */ "Check settings" = "Kontroller indstillinger"; @@ -148,248 +323,796 @@ "Check that your pump is in range" = "Kontroller, at din pumpe er indenfor rækkevidde"; /* Recovery suggestion when glucose data is missing */ -"Check your CGM data source" = "Kontroller din CGM data kilde"; +"Check your CGM data source" = "Kontroller din CGM-datakilde"; + +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Tjek din enheds tid og/eller fjern ugyldige data fra Apple Health."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Vælg en længere absorptionstid ved større måltider, eller dem med fedt og proteiner. Det er blot hjælp til algoritmen og behøver ikke være nøjagtig."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Luk"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Lukket Loop"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Lukket loop FRA"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Lukket Loop kræver en aktiv CGM sensor-session"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Lukket Loop kræver, at opsætningen er fuldført"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "d %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "siden %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +/* Title text for button to complete setup */ +"Complete Setup" = "Fuldfør opsætning"; + /* The title of the configuration section in settings */ "Configuration" = "Konfiguration"; /* The error message displayed for configuration errors. (1: configuration error details) */ -"Configuration Error: %1$@" = "Konfigurations fejl: %1$@"; +"Configuration Error: %1$@" = "Konfigurationsfejl: %1$@"; + +/* Default alert dismissal */ +"Continue" = "Fortsæt"; /* The title of the continuous glucose monitor section in settings */ -"Continuous Glucose Monitor" = "Kontinuerlig Blodsukker Måler"; +"Continuous Glucose Monitor" = "Kontinuerlig Blodsukker Måler (CGM)"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ "Correction Range" = "Korrektionsområde"; +/* Critical Alerts Status text */ +"Critical Alerts" = "Kritiske advarsler"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Kritisk begivenhedslog klar"; + +/* Critical event log export title */ +"Critical Event Logs" = "Kritisk begivenhedslog"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Kritisk begivenhedslogs kunne ikke eksporteres."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Nuværende blodsukker"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = " Nuværende blodsukker på %1$@ er under dit korrektionsområde."; +"Current glucose of %1$@ is below correction range." = "Den aktuelle glukose for %1$@ er under korrektionsområdet."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Overstyr"; +"Custom Override" = "Brugerdefineret Override"; + +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Brugerdefineret forudindstilling"; + +/* Date picker label */ +"Date" = "Dato"; + +/* The short unit display string for decibles */ +"dB" = "dB"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Kunde Token"; +/* No comment provided by engineer. */ +"Delete" = "Slet"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Slet konto"; + +/* Button title to delete all objects */ +"Delete All" = "Slet alle"; /* Button title to delete CGM */ "Delete CGM" = "Slet CGM"; +/* Button title to delete a service */ +"Delete Service" = "Slet service"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Slet CGM testdata"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Slet testdata"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Slet testdata for pumpe"; + +/* Button text to deliver a bolus */ +"Deliver" = "Afgiv"; + /* Title text for delivery limits */ -"Delivery Limits" = "Indgivningsgrænser"; +"Delivery Limits" = "Insulingrænser"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Diabetesbehandling"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Havde du til hensigt at angive %1$@ gram som mængden af kulhydrater for dette måltid?"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Deaktiverer"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Afvis"; + +/* No comment provided by engineer. */ +"Done" = "Udført"; + +/* Title for card to log dose */ +"Dose Summary" = "Resumé af dosis"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Dosingstrategi"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Aktiver \nbluetooth"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Aktiverer"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Indtast blodsukker fra en fingerprikmåling for at få anbefalet en bolusmængde."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Indtast bolus"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Indtast fingerprikmåling"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Indtast glucosesikkerhedsgrænse"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Indtast grænse for suspendering"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Fejl ved annullering af bolus"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Der opstod en fejl under eksport af log"; + /* The alert title for a resume error */ -"Error Resuming" = "Fejl ved forsøg på genoptagelse"; +"Error Resuming" = "Fejl ved genoptagelse"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Hændelseshistorik"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Med tiden %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Overskrider den maksimalt tilladte bolus i indstillingerne"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Overskrider det maksimalt tilladte antal kulhydrater"; + /* The title of the alert describing a maximum bolus validation error */ -"Exceeds Maximum Bolus" = "Overstiger maximum bolus"; +"Exceeds Maximum Bolus" = "Overskrider maksimal bolus"; + +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Eksportér kritisk begivenhedslog"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Eksport-%1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Kunne ikke genoptage insulintilførsel"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Fingerprik blodsukker"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Løs nu ved at slå meddelelser, kritiske advarsler og tidsfølsomme meddelelser TIL."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "I %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Forventet blodsukker kan stadig være højere end målområdet."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Forventet blodsukker"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Få hjælp til advarselstilladelser"; + /* The title of the glucose and prediction graph */ -"Glucose" = "Blodsukker"; +"Glucose" = "Glukose"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Blodsukker data er %1$@ gamle"; +"Glucose data is %1$@ old" = "Blodsukkerdata er %1$@ gamle"; /* Description of error when glucose data is missing */ -"Glucose data not available" = "Blodsukker data ikke tilgængelige"; +"Glucose data not available" = "Blodsukkerdata ikke tilgængelige"; + +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Blodsukkerdata er nu tilgængelige"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Blodsukkerværdi er uden for intervallet"; /* Title of the prediction input effect for glucose momentum */ -"Glucose Momentum" = "Blodsukker momentum"; +"Glucose Momentum" = "Blodsukkermomentum"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://minside.herokuapp.com"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Tidsplan for glukosemålområde"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Sådan opdaterer du (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Akut"; /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Uendelig"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Input maksimum overskredet"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Insulin"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulin absorberet (E) × Insulin følsomhed (%1$@/E)"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulin absorberet (E) × Insulinfølsomhed (%1$@/E)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Insulinjusteringer er blevet deaktiveret!"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insulin Indgivelse"; +"Insulin Delivery" = "Insulintilførsel"; /* Details for missing data error when insulin effects are missing */ -"Insulin effects" = "Insulin effekter"; +"Insulin effects" = "Insulineffekter"; /* Details for configuration error when insulin model is missing The title text for the insulin model setting row */ -"Insulin Model" = "Insulin Model"; +"Insulin Model" = "Insulinmodel"; + +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Insulinpumpe"; /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Insulin Følsomheder"; +"Insulin Sensitivities" = "Insulinfølsomheder"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Insulinfølsomhed tidsplan"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insulin suspenderet"; + +/* Insulin type label */ +"Insulin Type" = "Insulintype"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Afbrudt %1$@: %2$@ af %3$@ %4$@"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Ugyldig kulhydratmængde"; /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Fejlagtige data: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Ugyldig fremtidig glukose"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Ugyldig glukoseaflæsning med et tidsstempel, der er %1$@ i fremtiden"; + /* The title text for the issue report cell */ -"Issue Report" = "Fejl Rapport"; +"Issue Report" = "Fejlrapport"; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Stort måltid indtastet"; /* Glucose HUD accessibility hint */ "Launches CGM app" = "Åbner CGM app’en"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Lær mere"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Mindre end 1 minut tilbage"; + /* The loading message for the diagnostic report screen */ -"Loading..." = "Danner..."; +"Loading..." = "Indlæser..."; + +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Log dosis"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Logget insulindosis"; -/* The title of the loggly service */ -"Loggly" = "Loggly"; +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop er crashet"; /* The notification title for a loop failure */ -"Loop Failure" = "Loop Fejl"; +"Loop Failure" = "Loop-fejl"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop har opdaget et problem med dine Bluetooth-indstillinger, og fungerer ikke korrekt, før Bluetooth er aktiveret. Du vil ikke få blodsukkeraflæsninger eller være i stand til at give bolus."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop har ikke kørt korrekt i %@"; +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop vil automatisk give bolus når insulinbehov er over planlagt basal, og vil bruge midlertidige basalrater, når det er nødvendigt for at reducere insulinlevering under planlagt basal."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop vil ikke fungere, før Bluetooth er aktiveret. Du vil ikke modtage glukoseaflæsninger eller være i stand til at give bolus."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop vil fastsætte midlertidige basalrater for at øge og reducere insulinafgivelse."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Lav glukose"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Administrer tilladelser i Indstillinger"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Manuel dosis: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Maksimal basalrate pr. time"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maksimal bolus"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Maksimal bolus overskredet"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Maksimal varighed overskredet"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Måltidsbolus"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Manglende data: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Manglende maksimalt tilladt bolus i indstillingerne"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ -"Momentum effects" = "Momentum effekter"; +"Momentum effects" = "Momentumeffekter"; + +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Mere Info"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Slå alle alarmer fra"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Handling påkrævet"; /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Der lyder ingen advarsler, mens de er slået fra. Når denne periode slutter, genoptages dine advarsler og alarmer som normalt."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Ingen bolus anbefalet"; + /* The error message displayed for device connection errors. */ -"No connected devices, or failure during device connection" = "Ingen tilsluttede enheder, eller fejl under forbindelse til enhed"; +"No connected devices, or failure during device connection" = "Ingen tilsluttede enheder eller fejl under forbindelse til enhed"; + +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Ingen maksimal bolus konfigureret"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Ingen pumpe konfigureret"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Ingen nyere glukose"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Ingen nylige glukosedata"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Ingen nyere pumpedata"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Nej, indstil mængde"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Notifikationsindstillinger"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Notifikationer er indstillet til et Planlagt resumé i telefonens indstillinger.\n\nFor at undgå forsinkelser ved modtagelse af notifikarioner fra %1$@ anbefaler vi, at notifikationslevering er indstillet til øjeblikkelig levering."; + +/* Notifications Status text */ +"Notifications" = "Notifikationer"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Notifikationer forsinkede"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Meddelelser giver dig vigtige oplysninger om %1$@-appen uden at du behøver at åbne appen."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Meddelelser giver dig vigtige oplysninger om %1$@-appen uden at du behøver at åbne appen.\n\nLad dem være aktiveret i telefonens indstillinger for at sikre, at du modtager %1$@-meddelelser, kritiske advarsler og tidsfølsomme meddelelser."; + +/* Notification Setting Status is Off */ +"Off" = "Slukket"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Åh nej! Loop gik ned under dosering, og insulinjusteringer er blevet sat på pause, indtil denne dialogboks er lukket. Doseringshistorikken er muligvis ikke nøjagtig. Gennemgå venligst insulintilførsindstillinger og overvåg dit blodsukker omhyggeligt."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Tændt"; /* The title text for the override presets */ -"Override Presets" = "Overstyring Forudinstillinger"; +"Override Presets" = "Override forudindstillinger"; /* The label of the pre-meal mode toggle button */ -"Pre-Meal Targets" = "Før-Måltid Mål"; +"Pre-Meal Targets" = "Før-måltid Mål"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Forventet blodsukker ved %1$@ er %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Forventet glukose ved %1$@ er %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Den forventede glukose er inden for intervallet."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Det forventede glukoseindhold på %1$@ er under din indstilling af glukose-sikkerhedsgrænsen."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet blodsukker på %1$@ er under den indstillede suspenderingsgrænse."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet glukose på %1$@ er under din indstilling for suspenderingstærskel."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ -"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Forventet: %1$@\nActual: %2$@ (%3$@)"; +"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Forventet: %1$@\nFaktisk: %2$@ (%3$@)"; + +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Forbereder kritiske begivenhedslogs"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Profiludløb"; + +/* Time that profile expires */ +"Profile expires " = "Profil udløber "; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Profilen udløber snart"; /* The title of the pump section in settings */ "Pump" = "Pumpe"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Pumpe Batteri Lav"; +"Pump Battery Low" = "Pumpebatteri lav"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ -"Pump data is %1$@ old" = "Pumpe data er %1$@ gamle"; +"Pump data is %1$@ old" = "Pumpedata er %1$@ gammel"; + +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pumpe-hændelse"; /* Details for configuration error when pump manager is missing */ -"Pump Manager" = "Pumpe Manager"; +"Pump Manager" = "Pumpemanager"; + +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Fejl i pumpemanager: %1$@"; /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Pumpe Reservoir Tomt"; +"Pump Reservoir Empty" = "Pumpereservoir tomt"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Pumpe Reservoir Lavt"; +"Pump Reservoir Low" = "Pumpereservoir lavt"; /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pumpe Pauset"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pumpen er suspenderet. Automatisk dosering er deaktiveret."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Hurtigt-Virkende – Voksne"; +"Rapid-Acting – Adults" = "Hurtigt-virkende (Rapid) – Voksne"; /* Title of insulin model preset */ -"Rapid-Acting – Children" = "Hurtigt-Virkende – Børn"; +"Rapid-Acting – Children" = "Hurtigt-virkende (Rapid) – Børn"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ "Recommendation expired: %1$@ old" = "Forslag udløbet: %1$@ gamle"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Foreslået Basal"; +"Recommended Basal" = "Anbefalet basal"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Anbefalet bolus"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Anbefalet bolus overstiger maksimal bolus"; /* Accessibility hint describing recommended bolus units */ -"Recommended Bolus: %@ Units" = "Foreslået: %@ E"; +"Recommended Bolus: %@ Units" = "Foreslået bolus: %@ Enheder"; + +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Fjernindtastning af bolus: %@ E"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Fjernindtastning af kulhydrater: %d gram"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Fjernkommando er udløbet"; /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Reservoir"; /* Title of the prediction input effect for retrospective correction */ -"Retrospective Correction" = "Tilbagevirkende Korrektion"; +"Retrospective Correction" = "Tilbagevirkende korrektion"; /* The title of the notification action to retry a bolus command */ "Retry" = "Forsøg igen"; +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Gem og afgiv"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Gem uden at give bolus"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Planlagt"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Indstil Mute-periode"; + /* The title of the services section in settings */ "Services" = "Services"; /* The label of the settings button */ "Settings" = "Indstillinger"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Opsætning ufuldstændig"; + /* Loop Completion HUD accessibility hint */ -"Shows last loop error" = "Viser sidste Loop fejl"; +"Shows last loop error" = "Viser sidste Loop-fejl"; + +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Simpel bolusberegner"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Simpel måltidsberegner"; /* Format fragment for a start time */ "since %@" = "siden %@"; /* The title of the nightscout site URL credential */ -"Site URL" = "Side URL"; +"Site URL" = "Side-URL"; + +/* Software update button link text */ +"Software Update" = "Software-opdatering"; /* The format for the description of a temporary override start date */ "starting at %@" = "starter ved %@"; /* The title of the cell indicating a bolus is being sent */ -"Starting Bolus" = "Starter Bolus"; +"Starting Bolus" = "Starter bolus"; + +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Support"; /* The title text in settings */ -"Suspend Threshold" = "Pause Grænseværdi"; +"Suspend Threshold" = "Pause grænseværdi"; + +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Tryk her for at konfigurere en CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Tryk her for at oprette en pumpe"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Tryk her for at konfigurere en tjeneste"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Tryk for at tilføje"; /* The subtitle of the cell displaying an action to resume insulin delivery */ "Tap to Resume" = "Tryk for at Fortsætte"; +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Tryk for at stoppe"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Temp Mute-advarsler"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Den indtastede bolusmængde er mindre end den mindste leverbare mængde."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Bolusdoseringsalgoritmen bruger et mere konservativt skøn over det forventede blodsukker end det, der bruges til at justere din basalhastighed.\n\nSom følge heraf kan dit forventede blodglukose efter en bolus stadig være højere end dit målområde."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "Bolusanbefalingen er opdateret. Bekræft venligst bolus."; + /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Den model, der bruges af Loop, tillader tilpasning af handlingens varighed."; +"The legacy model used by Loop, allowing customization of action duration." = "Ældre model, der bruges af Loop, og som gør det muligt at tilpasse insulinens varighed."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Den maksimale absorptionstid er %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "Den maksimalt tilladte mængde er %@ gram."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "Den maksimale tilladte mængde er %1$@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Den maksimale bolus er %@ enheder."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ -"The maximum bolus amount is %@ Units" = "Den maksimale bolus mængde er %@ Enheder"; +"The maximum bolus amount is %@ Units" = "Den maksimale bolusmængde er %@ enheder"; + +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Maksimal bolus skal konfigureres, før en bolus kan leveres."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Fjernkommandoen udløb for %.0f minutter siden."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Behandlingsindstillinger"; + +/* Title of the carb entry date picker cell */ +"Time" = "Tid"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Tidsfølsomme meddelelser"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Prøv igen"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Slå bluetooth til for at modtage advarsler, alarmer eller blodsukkermålinger."; /* The short unit display string for international units of insulin */ "U" = "E"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Kan ikke rydde en advarsel"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Kan ikke få kontakt til pumpen"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Kan ikke gemme kulhydrat indtastningen"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Det manuelt indtastet blodsukker kan ikke gemmes"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Kan ikke stoppe igangværende bolus. Flyt din iPhone tættere på pumpen og prøv igen. Tjek din historik for insulinafgivelse for detaljer og overvåg nøje dit blodsukkerniveau."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Ukendt"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Ukendt fejl: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Ukendt tidspunkt"; + /* The format for the description of a temporary override end date */ "until %@" = "indtil %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Indtil jeg indtaster kulhydrater"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Indtil jeg slukker"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Brug Før-måltid"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Glucose Targets" = "Anvend blodsukkermål for motion"; + /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Anvend Motion Blodsukker Mål"; +"Use Workout Preset" = "Brug forudindstillinger for motion"; /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Advarsel! Sikkerhedsmeddelelser er slået FRA"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Når den nuværende eller forventede blodsukker ligger under blodsukkersikkerhedsgrænsen, vil Loop ikke anbefale en bolus og vil altid anbefale en midlertidig basalrate på 0 enheder i timen."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Når nuværende og forventet glukose er under suspenderingsgrænsen, vil Loop ikke anbefale en bolus, og vil altid anbefale en midlertidig basal rate på 0 enheder i timen."; +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Når der ikke køres lukket Loop, bruger appen en forenklet bolusberegner som en typisk pumpe."; + /* The label of the workout mode toggle button */ "Workout Targets" = "Motion Mål"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Træning Temp Adjust har været tændt i mere end 24 timer. Sørg for, at du stadig vil have den aktiveret, eller slå den fra i appen."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Træning Temp Justere stadig på"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Ja"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Du får muligvis ikke lyd-, visuelle eller vibrationsadvarsler om vigtige sikkerhedsoplysninger.\n\nFor at løse problemet skal du trykke på \"Indstillinger\" og sikre dig, at Meddelelser, Kritiske advarsler og Tidsfølsomme meddelelser er slået til."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Din %1$@'s tid er blevet ændret. %2$@ har brug for nøjagtige tidsregistreringer for at kunne forudsige din glukose og justere din insulin i overensstemmelse hermed.\n\nTjek i dine %1$@-indstillinger (Generelt / Dato og tid), og kontrollér, at \"Indstilles automatisk\" er slået til. Hvis dette ikke løses, kan det føre til alvorlig under- eller overlevering af insulin."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Dit glukose er under %1$@. Er du sikker på, at du ønsker at give bolus?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Dit blodsukker er under eller forventes at ligge under din blodsukkersikkerhedsgrænse, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Dit blodsukker ligger under din blodsukkersikkerhedsgrænse, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Dit glukose er lavt. Spis kulhydrater, og overvej at vente med at give bolus, indtil dit glukoseniveau er i et sikkert område."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Din glukose er lav. Spis kulhydrater og overvåg nøje."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Din maksimale bolusmængde er %1$@."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Dine pumpedata er forældede. %1$@ kan ikke anbefale en bolusmængde."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Din pumpe leverer en manuel midlertidig basalrate."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Din anbefalede bolus overstiger din maksimale bolusmængde på %1$@."; + diff --git a/Loop/da.lproj/Main.strings b/Loop/da.lproj/Main.strings index 1c28260695..b6d4bab2d1 100644 --- a/Loop/da.lproj/Main.strings +++ b/Loop/da.lproj/Main.strings @@ -1,20 +1,11 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Status"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3.5 E/time @ 12:12 PM"; - -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Pumpe ID"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Bolus Mængde"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; +"5gz-kZ-iF1.text" = "3.5 E/time @ 12:12"; /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Forventet"; @@ -22,23 +13,14 @@ /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ "aCb-Qs-bpu.text" = "Detalje"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Madtype"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Label"; +"bIL-Ub-qYp.text" = "Etiket"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Blodsukker Ændring"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Enheder"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "E"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Label"; +"bq4-98-cQU.text" = "Blodsukkerændring"; /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g Total"; @@ -47,95 +29,83 @@ "D4C-I2-dhA.text" = "Fremtidige blodsukre er beregnet ved at kombinere effekterne af mange inputs. Brug dette værktøj til at vælge mellem forskellige inputs, for at se hvordan de passer med den endelige forudsigelse."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Label"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Indstillinger"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "ENHEDER"; +"d6m-qV-wWi.text" = "Etiket"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "eventually 92 mg/dL"; +"E41-FN-nkk.text" = "Med tiden 5 mmol/L"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ -"EAn-Ja-S1d.text" = "Observed"; +"EAn-Ja-S1d.text" = "Observeret"; + +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Aktive Kulhydrater: 40g"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 E/time @ 12:12"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Kulhydrate Effekt"; +"hZZ-2S-lrd.title" = "Kulhydrateffekter"; /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; +"IxU-As-glo.text" = "De observerede ændringer i glukose, fratrukket de ændringer, der er modelleret ud fra insulintilførslen, kan bruges til at estimere kulhydratabsorptionen."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detail"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Blodsukker forventes under interval"; +"J7x-W5-gwo.text" = "Detalje"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Foreslået Basal"; +"k3F-Na-7mn.text" = "Anbefalet basal"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "Label"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Label"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Tryk for at gemme"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Enheder"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "E"; +"Krd-Aa-ret.text" = "Etiket"; /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "Label"; +"OFA-qT-ZAg.text" = "Etiket"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Predicted Glucose"; +"PA3-sP-cWY.title" = "Forventet blodsukker"; + +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insulin Model"; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Madtype"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ -"Rse-x8-amW.text" = "Til sidst 92 mg/dL"; +"Rse-x8-amW.text" = "Med tiden 5 mmol/L"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g Active Carbs"; +"SQx-au-ZcM.text" = "g aktive kulhydrater"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Blodsukker"; +"tuw-av-A3x.text" = "Glukose"; -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Label"; +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Tilføj/rediger kulhydrater"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Aktiv Insulin: 1.5E"; +/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ +"ufi-Kj-33k.text" = "Etiket"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Kulhydrater"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 timer"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Forbrugt mængde kulhydrater"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Anbefalet basal"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Indgiv"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Foreslået"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "Titel"; diff --git a/Loop/de.lproj/InfoPlist.strings b/Loop/de.lproj/InfoPlist.strings index b8c460f3bf..112edb1240 100644 --- a/Loop/de.lproj/InfoPlist.strings +++ b/Loop/de.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; @@ -17,8 +20,8 @@ "NSHealthShareUsageDescription" = "Mahlzeit-Daten aus der HealthKit-Datenbank werden verwendet, um Blutzuckereffekte zu bestimmen. Blutzuckerdaten aus der HealthKit-Datenbank werden für die Grafik- und Momentumberechnung verwendet."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Die in der App und auf der Uhr eingegebenen Kohlenhydratmengen werden in der Health-Datenbank gespeichert. Blutzuckerdaten, die vom CGM abgerufen werden, werden sicher in HealthKit gespeichert."; +"NSHealthUpdateUsageDescription" = "In der App und auf der Uhr eingegebene Daten zu Kohlenhydratmahlzeiten werden in der HealthKit-Datenbank gespeichert. Vom CGM abgerufene Glukosedaten werden sicher in HealthKit-Datenbank gespeichert."; /* Privacy - Siri Usage Description */ -"NSSiriUsageDescription" = "Loop verwendet Siri, damit Du Voreinstellungen mit Deiner Sprache ausführen kannst."; +"NSSiriUsageDescription" = "Loop verwendet Siri, damit Sie Voreinstellungen mit Ihrer Sprache ausführen können."; diff --git a/Loop/de.lproj/Localizable.strings b/Loop/de.lproj/Localizable.strings index 12f3181834..e50ff87f1a 100755 --- a/Loop/de.lproj/Localizable.strings +++ b/Loop/de.lproj/Localizable.strings @@ -4,30 +4,54 @@ /* Status row title for premeal override enabled (leading space is to separate from symbol) */ " Pre-meal Preset" = " Voreinstellung zum Essen"; +/* remaining time in setting's profile expiration section */ +" remaining" = " verbleiben"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = "Sicherheitsbenachrichtigungen sind ausgeschaltet"; + /* Status row title for workout override enabled (leading space is to separate from symbol) */ " Workout Preset" = " Zielbereichsänderung"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ -"%@ absorbed" = "%@ absorbiert"; +"%@ absorbed" = "%@ resorbiert"; /* Estimated remaining duration with more than a minute */ "%@ remaining" = "%@ verbleiben"; /* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ Gesamt-IE"; +"%@ U Total" = "%@ IE gesamt"; /* Appends a full-stop to a statement */ "%@." = "%@."; /* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ -"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@%2$@ konnte Deine aktuelle temporäre Basalrate nicht abbrechen, da diese höher ist als die neue maximale Basalrate, die Du festgelegt hast. Dies kann zu einer höheren Insulinabgabe als erwünscht führen.\n\nErwäge, die Insulinabgabe manuell zu unterbrechen und dann sofort wieder aufzunehmen, um die Basalabgabe mit dem neuen Grenzwert zu initiieren."; +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@%2$@ konnte Ihre aktuelle temporäre Basalrate nicht abbrechen, da diese höher ist als die neue maximale Basalrate, die Sie festgelegt haben. Dies kann zu einer höheren Insulinabgabe, als erwünscht führen.\n\nErwägen Sie, die Insulinabgabe manuell zu unterbrechen und dann sofort wieder aufzunehmen, um die Basalabgabe mit dem neuen Grenzwert zu initiieren."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/IE"; @@ -41,7 +65,10 @@ "%1$@ is unable to clear the alert from your device" = "%1$@ kann die Benachrichtigung nicht von Ihrem Gerät löschen"; /* Message for alert shown when delivery status is uncertain. (1: app name) */ -"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ kann nicht mit Deiner Insulinpumpe kommunizieren. Die App versucht weiterhin, Deine Pumpe zu erreichen, aber die Informationen zur Insulinabgabe können nicht aktualisiert werden und die Automatisierung kann nicht fortgesetzt werden.\nDu kannst einige Minuten warten, um zu sehen, ob das Problem behoben ist, oder auf die Schaltfläche unten tippen, um mehr über andere Optionen zu erfahren."; +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ kann nicht mit Ihrer Insulinpumpe kommunizieren. Die App versucht weiterhin, Ihre Pumpe zu erreichen, aber die Informationen zur Insulinabgabe können nicht aktualisiert werden und die Automatisierung kann nicht fortgesetzt werden.\nSie können einige Minuten warten, um zu sehen, ob das Problem behoben ist, oder auf die Schaltfläche unten tippen, um mehr über andere Optionen zu erfahren."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Zeiteinstellungen erfordern Aufmerksamkeit"; /* Reservoir entry (1: volume value) */ "%1$@ U" = "%1$@ IE"; @@ -64,6 +91,10 @@ /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 Minuten Blutzucker-Regressionskoeffizient (b₁), fortgesetzt mit Abfall über 30 min"; @@ -80,10 +111,10 @@ "A manual glucose entry must be between %1$@ and %2$@." = "Der manuelle Blutzucker muss zwischen %1$@ und %2$@ liegen."; /* Subtitle of Fiasp preset */ -"A model based on the published absorption of Fiasp insulin." = "Ein Modell basierend auf der veröffentlichten Absorption von Fiasp-Insulin."; +"A model based on the published absorption of Fiasp insulin." = "Ein Modell basierend auf der veröffentlichten Resorption von Fiasp-Insulin."; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Ein Modell auf der Grundlage der veröffentlichten Absorption von Humalog, Novolog und Apidra Insulin bei Erwachsenen."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Ein Modell auf der Grundlage der veröffentlichten Resorption von Humalog, Novolog und Apidra Insulin bei Erwachsenen."; /* Software update available section footer (1: app name) */ "A new version of %@ is available and is recommended to continue using the app." = "Eine neue Version von %@ ist verfügbar und es wird empfohlen, die App weiterhin zu verwenden."; @@ -95,7 +126,7 @@ "A pump must be configured before a bolus can be delivered." = "Eine Pumpe muss konfiguriert werden, bevor ein Bolus abgegeben werden kann."; /* Title of the carb entry absorption time cell */ -"Absorption Time" = "Absorptionsdauer"; +"Absorption Time" = "Resorptionsdauer"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "Akzeptiere empfohlenen Bolus"; @@ -116,7 +147,7 @@ "Active Insulin: %@" = "Aktives Insulin: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "KH-Eintrag hinzufügen"; +"Add Carb Entry" = "Kohlenhydrate hinzufügen"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ @@ -135,27 +166,28 @@ /* No comment provided by engineer. */ "Adjusted for" = "Angepasst für"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Alarm-Einstellungen"; + /* Alert Permissions button text Notification & Critical Alert Permissions screen title */ "Alert Permissions" = "Benachrichtigungsberechtigungen"; -/* Alert Permissions Need Attention alert title */ -"Alert Permissions Need Attention" = "Mitteilungseinstellungen brauchen Deine Aufmerksamkeit"; - /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Algorithmus-Einstellungen"; /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Eine Anpassung an das Erwachsenenmodell basierend auf empirischen Effekten bei Kindern."; +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Eine aktive Voreinstellung verändert Ihr Kohlenhydratverhältnis und Ihre Insulinempfindlichkeit. Wenn Sie nicht möchten, dass sich dies auf Ihre Bolusberechnung und Ihren prognostizierten Blutzucker auswirkt, sollten Sie die Voreinstellung deaktivieren."; /* Alert message for a carb entry persistence error */ -"An error occurred while trying to save your carb entry." = "Beim Speichern Deiner Kohlenhydrateingabe ist ein Fehler aufgetreten."; +"An error occurred while trying to save your carb entry." = "Beim Speichern Ihrer Eingabe der Kohlenhydrate ist ein Fehler aufgetreten."; /* Alert message for a manual glucose entry persistence error */ -"An error occurred while trying to save your manual glucose entry." = "Beim Speichern Deines manuellen Blutzuckers ist ein Fehler aufgetreten."; +"An error occurred while trying to save your manual glucose entry." = "Beim Speichern Ihres manuell eingegebenen Blutzuckers ist ein Fehler aufgetreten."; /* Invalid onboarding state */ "An unexpected onboarding error state occurred." = "Ein unerwarteter Fehlerstatus beim Onboarding ist aufgetreten."; @@ -164,28 +196,31 @@ "An updated bolus recommendation is available." = "Eine aktualisierte Bolusempfehlung ist verfügbar."; /* The title of the amplitude API key credential */ -"API Key" = "API Schlüssel"; +"API Key" = "API Key"; /* The title of the nightscout API secret credential */ -"API Secret" = "API Geheimnis"; +"API Secret" = "API Secret"; + +/* Settings app profile section */ +"App Profile" = "App-Profil"; /* Action sheet confirmation message for pump history deletion */ "Are you sure you want to delete all history entries?" = "Möchtest Du wirklich alle Verlaufseinträge löschen?"; /* Action sheet confirmation message for logged dose deletion */ -"Are you sure you want to delete all logged dose entries?" = "Möchtest Du wirklich alle protokollierten Dosiseinträge löschen?"; +"Are you sure you want to delete all logged dose entries?" = "Möchten Sie wirklich alle protokollierten Dosiseinträge löschen?"; /* Action sheet confirmation message for reservoir deletion */ "Are you sure you want to delete all reservoir values?" = "Möchtest Du wirklich alle Reservoirwerte löschen?"; /* No comment provided by engineer. */ -"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Möchtest Du wirklich alle Deine %@-Daten löschen?\n(Diese Aktion kann nicht rückgängig gemacht werden)"; +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Möchten Sie wirklich alle %@-Daten löschen?\n(Diese Aktion kann nicht rückgängig gemacht werden)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Möchtest Du dieses CGM wirklich löschen?"; +"Are you sure you want to delete this CGM?" = "Sind Sie sicher, dass Sie dieses CGM löschen wollen?"; /* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Möchtest Du diesen Dienst wirklich löschen?"; +"Are you sure you want to delete this service?" = "Bist Du sicher, dass Du diesen Dienst löschen möchtest?"; /* Format fragment for a specific time */ "at %@" = "um %@"; @@ -194,17 +229,17 @@ "Authenticate to Bolus %@ Units" = "Bolusabgabe von %@ IE bestätigen"; /* The message displayed during a device authentication prompt to log an insulin dose */ -"Authenticate to log %@ Units" = "Authentifiziere Dich, um %@ Einheiten zu protokollieren"; +"Authenticate to log %@ Units" = "Authentifizieren Sie sich, um %@ Einheiten zu protokollieren"; /* Details for configuration error when basal rate schedule is missing */ -"Basal Rate Schedule" = "Basalraten-Zeitplan"; +"Basal Rate Schedule" = "Basalratenplan"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Basalraten"; +"Basal Rates" = "Basalrate"; /* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ -"Based on your predicted glucose, no bolus is recommended." = "Basierend auf Deinem vorhergesagten Blutzucker wird kein Bolus empfohlen."; +"Based on your predicted glucose, no bolus is recommended." = "Basierend auf Ihrem vorhergesagten Blutzucker wird kein Bolus empfohlen."; /* Message to the user to that the bluetooth is off */ "Bluetooth\nOff" = "Bluetooth aus"; @@ -226,16 +261,19 @@ "Bolus Issue" = "Bolus Problem"; /* Alert title for an updated bolus recommendation */ -"Bolus Recommendation Updated" = "Bolusempfehlung aktualisiert"; +"Bolus Recommendation Updated" = "Aktualisierte Bolusempfehlung"; /* Title for card displaying carb entry and bolus recommendation */ "Bolus Summary" = "Bolus Zusammenfassung"; +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus zu gering"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ -"Bolused %1$@ of %2$@" = "%1$@ abgegeben von %2$@"; +"Bolused %1$@ of %2$@" = "%1$@ von %2$@ als Bolus verabreicht"; /* The format string for bolus in progress showing total volume. (1: total volume) */ -"Bolusing %1$@" = "Abgabe %1$@"; +"Bolusing %1$@" = "Bolusabgabe %1$@"; /* The title of the cancel action in an action sheet */ "Cancel" = "Abbrechen"; @@ -255,10 +293,10 @@ /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Kohlenhydratfaktoren"; +"Carb Ratios" = "KH-Verhältnis"; /* The title of the view controller to create a new carb entry */ -"carb-entry-title-add" = "KH-Eintrag hinzufügen"; +"carb-entry-title-add" = "Kohlenhydrate hinzufügen"; /* The title of the view controller to edit an existing carb entry */ "carb-entry-title-edit" = "KH-Eintrag bearbeiten"; @@ -270,25 +308,31 @@ "Carbohydrates" = "Kohlenhydrate"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Absorbierte Kohlenhydrate (g) ÷ Kohlenhydratfaktor (g/IE) × Insulinempfindlichkeit (%1$@/IE)"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Resorbierte Kohlenhydrate (g) ÷ Kohlenhydratfaktor (g/IE) × Insulinempfindlichkeit (%1$@/IE)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Wechsel sofort die Pumpenbatterie."; +"Change the pump battery immediately" = "Wechseln Sie sofort die Pumpenbatterie"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Wechsel jetzt das Pumpenreservoir."; +"Change the pump reservoir now" = "Wechseln Sie jetzt das Pumpenreservoir"; /* Details for configuration error when one or more loop settings are missing */ "Check settings" = "Überprüfe die Einstellungen."; /* Recovery suggestion when reservoir data is missing */ -"Check that your pump is in range" = "Stelle sicher, dass sich Deine Pumpe in Reichweite befindet."; +"Check that your pump is in range" = "Stellen Sie sicher, dass sich Ihre Pumpe in Reichweite befindet."; /* Recovery suggestion when glucose data is missing */ -"Check your CGM data source" = "Überprüfe Deine CGM-Datenquelle."; +"Check your CGM data source" = "Überprüfen Sie Ihre CGM-Datenquelle."; + +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Überprüfen Sie die Uhrzeit Ihres Geräts und/oder entfernen Sie alle ungültigen Daten aus Apple Health."; /* Carb entry section footer text explaining absorption time */ -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Wähle eine längere Absorptionsdauer für größere Mahlzeiten oder solche, die Fette und Proteine enthalten. Dies ist nur eine Anleitung für den Algorithmus und muss nicht genau sein."; +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Wähle eine längere Resorptionsdauer für größere Mahlzeiten, oder welche die viel Fett und Proteine beinhalten. Dies ist eine Unterstützung für den Algorithmus und muss nicht genau sein."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Schliessen"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Closed Loop"; @@ -320,15 +364,18 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Konfigurationsfehler: %1$@"; +/* Default alert dismissal */ +"Continue" = "Weiter"; + /* The title of the continuous glucose monitor section in settings */ -"Continuous Glucose Monitor" = "Kontinuierliche Glukosemessung"; +"Continuous Glucose Monitor" = "Kontinuierliche Blutzuckermessung"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ "Correction Range" = "Korrekturbereich"; /* Critical Alerts Status text */ -"Critical Alerts" = "Dringende Warnungen"; +"Critical Alerts" = "Kritische Warnungen"; /* Critical event log ready text */ "Critical Event Log Ready" = "Kritisches Ereignisprotokoll bereit"; @@ -346,13 +393,10 @@ "Current glucose of %1$@ is below correction range." = "Der aktuelle Blutzucker von %1$@ liegt unter dem Korrekturbereich."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Eigene Voreinstellung"; +"Custom Override" = "Benutzerdefinierter Override"; /* The title of the cell indicating a generic custom preset is enabled */ -"Custom Preset" = "Zielbereichänderung"; - -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; +"Custom Preset" = "Voreinstellung"; /* Date picker label */ "Date" = "Datum"; @@ -385,14 +429,17 @@ "Delete Testing Pump Data" = "Pumpen-Test-Daten löschen"; /* Button text to deliver a bolus */ -"Deliver" = "Bolen"; +"Deliver" = "Abgeben"; /* Title text for delivery limits */ -"Delivery Limits" = "Verabreichungslimits"; +"Delivery Limits" = "Abgabelimits"; /* Descriptive text for Therapy Settings */ "Diabetes Treatment" = "Diabetes-Behandlung"; +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Wollten Sie %1$@ Gramm an Kohlenhydraten für diese Mahlzeit eingeben?"; + /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Deaktivieren"; @@ -409,6 +456,9 @@ /* The title of the Dosing Strategy section in settings */ "Dosing Strategy" = "Dosierungsstrategie"; +/* Remote command error description: duration exceed max (1: max duration in hours). */ +"Duration exceeds: %1$.1f hours" = "Dauer überschritten: %1$.1f Stunden"; + /* Message to the user to enable bluetooth */ "Enable\nBluetooth" = "Bluetooth einschalten"; @@ -440,7 +490,7 @@ "Error Resuming" = "Fehler beim Fortfahren"; /* Segmented button title for insulin delivery log event history */ -"Event History" = "Ereignishistorie"; +"Event History" = "Ereignisverlauf"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Voraussichtlich %@"; @@ -454,14 +504,14 @@ /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Überschreitet den maximalen Bolus"; -/* Remote command error description: expired. */ -"Expired" = "Abgelaufen"; - /* The title of the export critical event logs in support */ "Export Critical Event Logs" = "Protokolle kritischer Ereignisse exportieren"; +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Export-%1$@"; + /* The alert title for a resume error */ -"Failed to Resume Insulin Delivery" = "Insulinabgabe konnte nicht fortgesetzt werden"; +"Failed to Resume Insulin Delivery" = "Wiederaufnahme der Insulinabgabe fehlgeschlagen"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; @@ -469,6 +519,9 @@ /* Label for manual glucose entry row on bolus screen */ "Fingerstick Glucose" = "blutiger Blutzucker"; +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Behebe dies jetzt, indem Du Benachrichtigungen, kritische Alarme und zeitkritische Benachrichtigungen einschaltest."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Für %1$@"; @@ -488,10 +541,10 @@ "Glucose" = "Blutzucker"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Blutzucker ist %1$@ alt"; +"Glucose data is %1$@ old" = "Blutzuckerdaten sind %1$@ alt"; /* Description of error when glucose data is missing */ -"Glucose data not available" = "Blutzucker ist nicht verfügbar"; +"Glucose data not available" = "Blutzuckerdaten nicht verfügbar"; /* Alert title when glucose data returns while on bolus screen */ "Glucose Data Now Available" = "Blutzucker jetzt verfügbar"; @@ -506,20 +559,29 @@ /* Details for configuration error when glucose target range schedule is missing */ "Glucose Target Range Schedule" = "Zeitplan für den Blutzucker-Zielbereich"; +/* The title text for how to update */ +"How to update (LoopDocs)" = "Wie man aktualisiert (LoopDocs)"; + /* Immediate Delivery status text */ "Immediate" = "Sofort"; /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Unbegrenzt"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Eingangsmaximum Überschritten"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Insulin"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Absorbiertes Insulin (IE) × Insulinempfindlichkeit (%1$@/IE)"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Resorbiertes Insulin (IE) × Insulinempfindlichkeit (%1$@/IE)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Die Insulinanpassung wurde deaktiviert!"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insulinabgabe"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Insulinwirkungen"; @@ -539,40 +601,49 @@ "Insulin Sensitivity Schedule" = "Insulinsensitivitätsplan"; /* The title of the cell indicating the pump is suspended */ -"Insulin Suspended" = "Insulin unterbrochen"; +"Insulin Suspended" = "Insulinabgabe unterbrochen"; /* Insulin type label */ -"Insulin Type" = "Insulinart"; +"Insulin Type" = "Insulintyp"; /* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ "Interrupted %1$@: %2$@ of %3$@ %4$@" = "%1$@ unterbrochen: %2$@ von %3$@ %4$@"; +/* Remote command error description: invalid bolus amount. */ +"Invalid Bolus Amount" = "Ungültige Bolusmenge"; + /* Remote command error description: invalid carb amount. */ "Invalid carb amount" = "Ungültige Kohlenhydratmenge"; /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Ungültige Daten: %1$@"; -/* Remote command error description: invalid OTP. */ -"Invalid OTP" = "Ungültiges OTP"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Ungültige zukünftige Blutzuckerwerte"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Ungültiger Blutzuckermesswert mit einem Zeitstempel, der %1$@ in der Zukunft liegt"; /* The title text for the issue report cell */ "Issue Report" = "Problembericht"; -/* Format for Notifications permissions disabled alert body. (1: app name) */ -"It is important that you always keep %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications turned ON in your phone’s settings to ensure that you get notified by the app." = "Es ist wichtig, dass Du %1$@ Benachrichtigungen, kritische Warnungen und zeitkritische Benachrichtigungen in den Einstellungen Deines Telefons immer aktiviert lässt, um sicherzustellen, dass Du von der App benachrichtigt wirst."; +/* The notification description for a meal that was possibly not logged in Loop. */ +"It looks like you may not have logged a meal you ate. Tap to log it now." = "Es sieht so aus als ob du vergessen hast eine Mahlzeit einzugeben. Tippe um sie nun einzutragen."; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Große Mahlzeit eingegeben"; /* Glucose HUD accessibility hint */ -"Launches CGM app" = "Startet die CGM-App"; +"Launches CGM app" = "Öffnet die CGM-App"; /* OK button title for alert shown when delivery status is uncertain */ -"Learn More" = "Lernmodus"; +"Learn More" = "Mehr erfahren"; /* Estimated remaining duration with less than a minute */ "Less than a minute remaining" = "Weniger als eine Minute verbleiben"; /* The loading message for the diagnostic report screen */ -"Loading..." = "laden ..."; +"Loading..." = "Wird geladen..."; /* Button text to log a dose Title for dose logging screen */ @@ -581,11 +652,14 @@ /* The title of the screen displaying a manually entered insulin dose */ "Logged Insulin Dose" = "Gespeicherte Insulindosis"; +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop ist abgestürzt"; + /* The notification title for a loop failure */ -"Loop Failure" = "Loopfehler"; +"Loop Failure" = "Loop fehlgeschlagen"; /* Bluetooth unavailable alert body. */ -"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop hat ein Problem mit Deinen Bluetooth-Einstellungen festgestellt und funktioniert nicht, bis Bluetooth aktiviert ist. Du erhältst keinen Blutzucker und es kann kein Bolus abgeben werden."; +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop hat ein Problem mit Ihren Bluetooth-Einstellungen festgestellt und funktioniert nicht, bis Bluetooth aktiviert ist. Sie erhalten keine Blutzucker-Werte und es kann kein Bolus abgeben werden."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop wurde nicht erfolgreich abgeschlossen seit %@"; @@ -594,7 +668,7 @@ "Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop gibt automatisch einen Bolus ab, wenn der Insulinbedarf über der geplanten Basalrate liegt, und verwendet temporäre Basalraten, wenn dies erforderlich ist, um die Insulinabgabe unter die geplante Basalrate zu reduzieren."; /* Bluetooth off background alert body. */ -"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop funktioniert nicht, bis Bluetooth aktiviert ist. Du erhältst keine Glukosewerte und kannst keinen Bolus abgeben."; +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop funktioniert nicht, bis Bluetooth aktiviert ist. Sie erhalten keine Blutzuckerwerte und können keinen Bolus abgeben."; /* Description string for temp basal only dosing strategy */ "Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop stellt temporäre Basalraten ein, um die Insulinabgabe zu erhöhen oder zu verringern."; @@ -618,27 +692,45 @@ /* Title for bolus screen warning when max bolus is exceeded */ "Maximum Bolus Exceeded" = "Maximaler Bolus überschritten"; +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Maximale Dauer überschritten"; + /* Title for bolus entry screen when also entering carbs */ "Meal Bolus" = "Mahzeiten Bolus"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Fehlende Daten: %1$@"; /* Remote command error description: missing maximum bolus in settings. */ "Missing maximum allowed bolus in settings" = "Maximal erlaubter Bolus in den Einstellungen fehlt"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Momentum-Effekte"; /* Text for more info action on notification of upcoming profile expiration */ -"More Info" = "Mehr Infos"; +"More Info" = "Weitere Info"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Alle Alarme stummschalten"; /* Sensor state description for the non-valid state */ -"Needs Attention" = "Benötigt Aufmerksamkeit"; +"Needs Attention" = "Erfordert Aufmerksamkeit"; + +/* Remote command error description: negative duration error. */ +"Negative duration not allowed" = "Eine negative Dauer ist nicht erlaubt"; /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Während der Stummschaltung ertönen keine Alarme. Nach Ablauf dieser Zeitspanne werden Ihre Alarme wieder wie gewohnt fortgesetzt."; + /* Title for bolus screen notice when no bolus is recommended Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended Title for bolus screen warning when no bolus is recommended */ @@ -662,11 +754,14 @@ /* Title for bolus screen notice when pump data is missing or stale */ "No Recent Pump Data" = "Keine Pumpendaten"; +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Nein, Menge bearbeiten"; + /* Notification Delivery Status text */ "Notification Delivery" = "Benachrichtigungszustellung"; /* Format for Critical Alerts permissions disabled alert body. (1: app name) */ -"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Die Benachrichtigungszustellung ist in den Einstellungen Deines Telefons auf Geplante Zusammenfassung eingestellt.\n\nUm Verzögerungen beim Erhalt von Benachrichtigungen von %1$@ zu vermeiden, empfehlen wir, die Benachrichtigungszustellung auf Sofortige Zustellung einzustellen."; +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Die Benachrichtigungszustellung ist in den Einstellungen Ihres Telefons auf geplante Zusammenfassung eingestellt.\n\nUm Verzögerungen beim Erhalt von Benachrichtigungen von %1$@ zu vermeiden, empfehlen wir, die Benachrichtigungszustellung auf sofortige Zustellung einzustellen."; /* Notifications Status text */ "Notifications" = "Benachrichtigungen"; @@ -675,11 +770,17 @@ "Notifications Delayed" = "Benachrichtigungsverzögerung"; /* Alert Permissions descriptive text (1: app name) */ -"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Benachrichtigungen geben Dir wichtige %1$@ App-Informationen, ohne dass Du die App öffnen musst.\n\nLass diese in den Einstellungen Deines Telefons aktiviert, um sicherzustellen, dass Du %1$@ Benachrichtigungen, kritische Warnungen und zeitkritische Benachrichtigungen erhältst."; +"Notifications give you important %1$@ app information without requiring you to open the app." = "Benachrichtigungen geben Ihnen wichtige %1$@-App-Informationen, ohne dass Sie die App öffnen müssen."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Benachrichtigungen geben Ihnen wichtige %1$@ App-Informationen, ohne dass Sie die App öffnen müssen.\n\nLassen Sie diese in den Einstellungen Ihres Telefons aktiviert, um sicherzustellen, dass Sie %1$@ Benachrichtigungen, kritische Warnungen und zeitkritische Benachrichtigungen erhalten."; /* Notification Setting Status is Off */ "Off" = "Aus"; +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Oh nein! Loop ist während des Bolus abgestürzt und die Insulinanpassungen wurden angehalten, bis dieser Dialog geschlossen wird. Der Dosierungsverlauf ist möglicherweise nicht korrekt. Bitte prüfen Sie die Tabellen zur Insulinabgabe und überwachen Sie Ihren Blutzucker sorgfältig."; + /* Alert acknowledgment OK button Critical Alert permissions disabled alert button Default action for alert when alert acknowledgment fails @@ -694,6 +795,9 @@ /* The title text for the override presets */ "Override Presets" = "Voreinstellungen"; +/* The notification title for a meal that was possibly not logged in Loop. */ +"Possible Missed Meal" = "Wahrscheinlich eine Mahlzeit vergessen"; + /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Ziel vor dem Essen"; @@ -710,11 +814,17 @@ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Der vorhergesagte Blutzucker von %1$@ liegt unter dem Grenzwert für die Hypo-Abschaltung."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ -"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Vorausgesagt: %1$@\nAktuell: %2$@ (%3$@)"; +"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Vorhergesagt: %1$@\nAktuell: %2$@ (%3$@)"; /* Preparing critical event log text */ "Preparing Critical Event Logs" = "Vorbereiten der kritischer Ereigniss-Protokollen"; +/* Settings App Profile expiration view */ +"Profile Expiration" = "Ablauf des Profils"; + +/* Time that profile expires */ +"Profile expires " = "Profil läuft ab "; + /* The title for notification of upcoming profile expiration */ "Profile Expires Soon" = "Profil läuft in Kürze ab"; @@ -728,7 +838,7 @@ "Pump data is %1$@ old" = "Pumpendaten sind %1$@ alt"; /* The title of the screen displaying a pump event */ -"Pump Event" = "Pumpenereignis"; +"Pump Event" = "Pumpen-Ereignis"; /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Pumpenmanager"; @@ -748,6 +858,9 @@ /* The error message displayed for pumpSuspended errors. */ "Pump Suspended. Automatic dosing is disabled." = "Pumpe unterbrochen. Die automatische Dosierung ist deaktiviert."; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Schnellwirkend - Erwachsene"; @@ -777,6 +890,9 @@ /* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ "Remote Carbs Entry: %d grams" = "Ferneingabe von Kohlenhydraten: %d g"; +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Fernsteuerungsbefehl Abgelaufen"; + /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Reservoir"; @@ -786,18 +902,18 @@ /* The title of the notification action to retry a bolus command */ "Retry" = "Wiederholen"; -/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ -"Review Alert Permissions" = "Überprüfe die Berechtigungen für Warnungen"; - /* Button text to save carbs and/or manual glucose entry and deliver a bolus */ -"Save and Deliver" = "Speichern und Bolen"; +"Save and Deliver" = "Speichern und Bolus abgeben"; /* Button text to save carbs and/or manual glucose entry without a bolus */ -"Save without Bolusing" = "Speichern ohne zu Bolen"; +"Save without Bolusing" = "Speichern ohne Bolusgabe"; /* Scheduled Delivery status text */ "Scheduled" = "Geplant"; +/* List header for mute all alerts period */ +"Select Mute Period" = "Stummschaltungsdauer auswählen"; + /* The title of the services section in settings */ "Services" = "Dienste"; @@ -808,7 +924,7 @@ "Setup Incomplete" = "Einrichtung unvollständig"; /* Loop Completion HUD accessibility hint */ -"Shows last loop error" = "Zeigt den letzten Loopfehler an"; +"Shows last loop error" = "Zeigt den letzten Loop-Fehler an"; /* Title of simple bolus view when not displaying meal entry */ "Simple Bolus Calculator" = "Einfacher Bolusrechner"; @@ -820,7 +936,13 @@ "since %@" = "seit %@"; /* The title of the nightscout site URL credential */ -"Site URL" = "Seiten URL"; +"Site URL" = "Website URL"; + +/* Software update button link text */ +"Software Update" = "Software-Aktualisierung"; + +/* Remote command error description: invalid start time is out of range. */ +"Start time is out of range: %@" = "Startzeit liegt außerhalb des Bereichs: %@"; /* The format for the description of a temporary override start date */ "starting at %@" = "Beginnt um %@"; @@ -828,8 +950,14 @@ /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Starte Bolus"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Unterstützung"; + /* The title text in settings */ -"Suspend Threshold" = "Wert für die Hypo-Abschaltung"; +"Suspend Threshold" = "Grenzwert für Hypo-Abschaltung"; /* Descriptive text for button to add CGM device */ "Tap here to set up a CGM" = "Tippe hier, um ein CGM einzurichten"; @@ -849,6 +977,12 @@ /* Message presented in the status row instructing the user to tap this row to stop a bolus */ "Tap to Stop" = "Stoppen"; +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Alarme temporär stummschalten"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Die eingegebene Bolusmenge ist kleiner als die Mindestabgabemenge."; + /* Forecast explanation modal on bolus view */ "The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Der Bolusdosierungsalgorithmus verwendet eine konservativere Schätzung des prognostizierten Blutzuckers als die zur Anpassung Ihrer Basalrate verwendete.\n\nDaher kann Ihr prognostizierter Blutzucker nach einem Bolus immer noch über Ihrem Zielbereich liegen."; @@ -856,7 +990,13 @@ "The bolus recommendation has updated. Please reconfirm the bolus amount." = "Die Bolusempfehlung wurde aktualisiert. Bitte bestätigen Sie die Bolusmenge erneut."; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Das herkömmliche von Loop verwendete Modell, welches die Anpassung der Wirkungsdauer ermöglicht."; +"The legacy model used by Loop, allowing customization of action duration." = "Das von Loop verwendete Legacy-Modell, das die Anpassung der Aktionsdauer ermöglicht."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Die maximale Resorptionszeit beträgt %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "Die maximal zulässige Menge beträgt %@ Gramm."; /* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ "The maximum amount allowed is %1$@." = "Der maximal zulässige Wert ist %1$@."; @@ -870,15 +1010,15 @@ /* Alert message for a missing maximum bolus setting error */ "The maximum bolus setting must be configured before a bolus can be delivered." = "Die maximale Boluseinstellung muss konfiguriert werden, bevor ein Bolus abgegeben werden kann."; +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Der Fernbefehl ist vor %.0f Minuten abgelaufen."; + /* Title text for button to Therapy Settings */ -"Therapy Settings" = "Behandlungseinstellungen"; +"Therapy Settings" = "Therapieeinstellungen"; /* Title of the carb entry date picker cell */ "Time" = "Zeit"; -/* Time change alert title */ -"Time Change Detected" = "Zeitänderung erkannt"; - /* Time Sensitive Status text */ "Time Sensitive Notifications" = "Zeitkritische Benachrichtigungen"; @@ -904,7 +1044,7 @@ "Unable to Save Manual Glucose Entry" = "Manuelle Glukoseeingabe kann nicht gespeichert werden"; /* The alert body for an error while canceling a bolus */ -"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Der laufende Bolus kann nicht gestoppt werden. Bewege Dein iPhone näher an die Pumpe und versuche es erneut. Überprüfeden Verlauf der Insulinabgabe auf Einzelheiten und überwache Deinen Blutzucker genau."; +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Der laufende Bolus kann nicht gestoppt werden. Bewegen Sie Ihr iPhone näher an die Pumpe und versuchen Sie es erneut. Überprüfen Sie den Verlauf der Insulinabgabe auf Einzelheiten und überwachen Sie Ihren Blutzucker genau."; /* Event title displayed when StoredPumpEvent.title is not set The default description to use when an entry has no dose description */ @@ -913,6 +1053,12 @@ /* The error message displayed for unknown errors. (1: unknown error) */ "Unknown Error: %1$@" = "Unbekannter Fehler: %1$@"; +/* Remote command error description: unknown preset (1: preset name). */ +"Unknown preset: %1$@" = "Unbekannte Voreinstellung: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Unbekannte Zeit"; + /* The format for the description of a temporary override end date */ "until %@" = "Endet um %@"; @@ -934,11 +1080,17 @@ /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Warnung! Sicherheitsbenachrichtigungen sind AUSGESCHALTET"; + /* Explanation of glucose safety limit */ "When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Wenn der aktuelle oder prognostizierte Glukosewert unter dem Glukosesicherheitsgrenzwert liegt, empfiehlt Loop keinen Bolus und immer eine temporäre Basalrate von 0 Einheiten pro Stunde."; /* Explanation of suspend threshold */ -"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Wenn die aktuelle oder prognostizierte Glukose unter dem Wert für die Hypo-Abschaltung liegt, empfiehlt Loop immer eine temporäre Basalrate von 0 Einheiten pro Stunde und - wenn kein gesonderter Bolusgrenzwert definiert ist - auch keinen Bolus."; +"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Wenn der aktuelle oder prognostizierte Blutzucker unter dem Schwellenwert für die Unterbrechung liegt, empfiehlt Loop keinen Bolus, sondern immer eine temporäre Basalrate von 0 Einheiten pro Stunde."; + +/* Description of missed meal notifications. */ +"When enabled, Loop can notify you when it detects a meal that wasn't logged." = "Wenn aktiviert, kann Loop Dich benachrichtigen, wenn es eine Mahlzeit erkennt, die nicht protokolliert wurde."; /* No comment provided by engineer. */ "When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Ist der Loop-Modus ausgeschaltet, dann verwendet die App einen vereinfachten Bolusrechner wie eine typische Pumpe."; @@ -952,32 +1104,35 @@ /* Workout override still on reminder alert title */ "Workout Temp Adjust Still On" = "Zielbereichsänderung ist noch an"; +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Ja"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Möglicherweise erhalten Sie keine akustischen, optischen oder Vibrationswarnungen zu wichtigen Sicherheitsinformationen.\n\nUm das Problem zu beheben, tippen Sie auf \"Einstellungen\" und vergewissern Sie sich, dass \"Benachrichtigungen\", \"Dringende Warnungen\" und \"Zeitkritische Benachrichtigungen\" aktiviert sind."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Ihre Zeit %1$@ wurde geändert. %2$@ benötigt genaue Zeitaufzeichnungen, um Vorhersagen über Ihren Blutzuckerwert zu treffen und Ihr Insulin entsprechend anzupassen.\n\nÜberprüfen Sie Ihre %1$@ Einstellungen (Allgemein / Datum & Uhrzeit) und vergewissern Sie sich, dass „Automatisch einstellen“ aktiviert ist. Wird dies nicht behoben, kann dies zu einer schwerwiegenden Unter- oder Über-Abgabe von Insulin führen."; + /* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ -"Your glucose is below %1$@. Are you sure you want to bolus?" = "Dein Blutzucker liegt unter %1$@. Bist Du sicher, dass Du einen Bolus abgeben möchtest?"; +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Ihr Blutzucker liegt unter %1$@. Sind Sie sicher, dass Sie einen Bolus abgeben möchten?"; /* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ -"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Dein Blutzucker liegt unter Deiner Sicherheitsgrenze %@ oder wird voraussichtlich unter diesen fallen."; +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Ihr Blutzucker liegt unter Ihrer Sicherheitsgrenze %@ oder wird voraussichtlich unter diese fallen."; /* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ -"Your glucose is below your glucose safety limit, %1$@." = "Dein Blutzucker liegt unter Deiner Sicherheitsgrenze von %1$@."; +"Your glucose is below your glucose safety limit, %1$@." = "Ihr Blutzucker liegt unter Ihrer Sicherheitsgrenze von %1$@."; /* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ -"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Dein Blutzucker ist niedrig. Iß Kohlenhydrate und erwäge, mit dem Bolus zu warten, bis Dein Blutzcker in einem sicheren Bereich liegt."; +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Ihr Blutzucker ist niedrig. Essen Sie Kohlenhydrate und erwägen Sie, mit dem Bolus zu warten, bis Ihr Blutzucker in einem sicheren Bereich liegt."; /* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ -"Your glucose is low. Eat carbs and monitor closely." = "Dein Blutzucker ist niedrig. Kohlenhydrate essen und genau beobachten."; - -/* Warning to ensure the carb entry is accurate */ -"Your glucose is rapidly rising. Check that any carbs you've eaten were logged. If you logged carbs, check that the time you entered lines up with when you started eating." = "Dein Blutzucker steigt schnell an. Überprüfe, ob alle Kohlenhydrate, die Du gegessen hast, protokolliert wurden. Wenn Du die Kohlenhydrate protokolliert hast, überprüfe, ob die von Dir eingegebene Zeit mit dem Zeitpunkt übereinstimmt, an dem Du mit dem Essen begonnen hast."; +"Your glucose is low. Eat carbs and monitor closely." = "Ihr Blutzucker ist niedrig. Kohlenhydrate essen und genau beobachten."; /* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ -"Your maximum bolus amount is %1$@." = "Deine maximale Bolusmenge beträgt %1$@."; - -/* Time change alert body. (1: app name) */ -"Your phone’s time has been changed. %1$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your iPhone Settings (General / Date & Time) and verify that Set Automatically is enabled. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Die Uhrzeit Deines Telefons wurde geändert. %1$@ benötigt genaue Zeitaufzeichnungen, um Vorhersagen über Deinen Blutzucker zu treffen und Dein Insulin entsprechend anzupassen.\n\nÜberprüfe Deine iPhone-Einstellungen (Allgemein / Datum & Uhrzeit) und vergewissere Dich, dass Automatisch einstellen aktiviert ist. Wird dies nicht behoben, kann dies zu einer schwerwiegenden Unter- oder Überversorgung von Insulin führen."; +"Your maximum bolus amount is %1$@." = "Ihre maximale Bolusmenge beträgt %1$@."; /* Caption for bolus screen notice when pump data is missing or stale */ -"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Deine Pumpendaten sind veraltet. %1$@ kann keine Bolusmenge empfehlen."; +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Ihre Pumpendaten sind veraltet. %1$@ kann keine Bolusmenge empfehlen."; /* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ "Your pump is delivering a manual temporary basal rate." = "Ihre Pumpe liefert eine manuelle temporäre Basalrate."; diff --git a/Loop/de.lproj/Main.strings b/Loop/de.lproj/Main.strings index 5360bac9c6..3d0ec8f99e 100644 --- a/Loop/de.lproj/Main.strings +++ b/Loop/de.lproj/Main.strings @@ -1,8 +1,11 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Status"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3,5 IE/h @ 12:12"; +"5gz-kZ-iF1.text" = "3.5 IE/h @ 12:12"; /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Vorhergesagt"; @@ -11,7 +14,7 @@ "aCb-Qs-bpu.text" = "Detail"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ -"ap1-M6-naG.text" = "Essensart"; +"ap1-M6-naG.text" = "Essenstyp"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "Beschriftung"; @@ -34,6 +37,9 @@ /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Beobachtet"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ "fWV-jg-ICt.text" = "3.5 IE/h @ 12:12"; @@ -41,7 +47,7 @@ "hZZ-2S-lrd.title" = "Kohlenhydrat-Effekte"; /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Die beobachtete Blutzuckerveränderung abzüglich der modellbasierten Veränderung kann verwendet werden, um die Kohlenhydratabsorption abzuschätzen."; +"IxU-As-glo.text" = "Die beobachtete Blutzuckerveränderung abzüglich der modellbasierten Veränderung kann verwendet werden, um die Kohlenhydratresorption abzuschätzen."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Detail"; @@ -58,6 +64,12 @@ /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Vorhergesagter Blutzucker"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; + +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; + /* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ "qPH-vU-xlu.text" = "Essenstyp"; @@ -65,7 +77,7 @@ "Rse-x8-amW.text" = "voraussichtlich 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g COB"; +"SQx-au-ZcM.text" = "g aktive Kohlenhydrate"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ "tuw-av-A3x.text" = "Blutzucker"; @@ -80,10 +92,13 @@ "Vpi-5b-bY5.title" = "Kohlenhydrate"; /* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ -"Wx8-Tf-FnG.text" = "Menge gegessen"; +"Wx8-Tf-FnG.text" = "KH Menge gegessen"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ -"xhx-PI-bBI.text" = "Empfohlener Basalwert"; +"xhx-PI-bBI.text" = "Empfohlene Basalrate"; + +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; /* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ "Yf6-fw-Gex.placeholder" = "0"; diff --git a/Loop/en.lproj/InfoPlist.strings b/Loop/en.lproj/InfoPlist.strings index 3b377afb02..4fb6012aee 100644 --- a/Loop/en.lproj/InfoPlist.strings +++ b/Loop/en.lproj/InfoPlist.strings @@ -1,18 +1,6 @@ - -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - -/* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices."; - -/* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices."; - /* Privacy - Face ID Usage Description */ "NSFaceIDUsageDescription" = "Face ID is used to authenticate insulin bolus."; /* Privacy - Health Share Usage Description */ "NSHealthShareUsageDescription" = "Meal data from the Health database is used to determine glucose effects. Glucose data from the Health database is used for graphing and momentum calculation. Sleep data from the Health database is used to optimize delivery of Apple Watch complication updates during the time you are awake."; -/* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Carbohydrate meal data entered in the app and on the watch is stored in the Health database. Glucose data retrieved from the CGM is stored securely in HealthKit."; diff --git a/Loop/en.lproj/Localizable.strings b/Loop/en.lproj/Localizable.strings index bc11213827..78907ea3de 100644 --- a/Loop/en.lproj/Localizable.strings +++ b/Loop/en.lproj/Localizable.strings @@ -78,9 +78,6 @@ /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "An adjustment to the adult model based on empirical effects in children."; - /* The title of the amplitude API key credential */ "API Key" = "API Key"; @@ -172,9 +169,6 @@ /* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "Custom Override"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; - /* Button title to delete CGM */ "Delete CGM" = "Delete CGM"; diff --git a/Loop/en.lproj/Main.strings b/Loop/en.lproj/Main.strings index 66f3b9f3ba..032954b583 100644 --- a/Loop/en.lproj/Main.strings +++ b/Loop/en.lproj/Main.strings @@ -1,144 +1,3 @@ - -/* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ -"3kU-n2-fha.title" = "Status"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Pump ID"; - -/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3.5 U/hour @ 12:12 PM"; - -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Bolus Amount"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - -/* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ -"87H-N1-0vJ.text" = "Predicted"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Units"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "DEVICES"; - -/* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "eventually 92 mg/dL"; - -/* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ -"EAn-Ja-S1d.text" = "Observed"; - -/* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detail"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "Label"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "Label"; - -/* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Predicted Glucose"; - -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; - -/* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ -"Rse-x8-amW.text" = "eventually 92 mg/dL"; - /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g Active Carbs"; - -/* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ -"Vpi-5b-bY5.title" = "Carbohydrates"; - -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 hour"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Deliver"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detail"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Label"; - -/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Glucose Change"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Label"; - -/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g Total"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Label"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Settings"; - -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Active Carbohydrates: 40g"; - -/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Carbohydrate Effects"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Glucose Predicted Below Range"; - -/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Recommended Basal"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Label"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Tap to set"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Units"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insulin Model"; - -/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glucose"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Label"; - -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Active Insulin: 1.5U"; - -/* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ -"yn7-2M-jZz.text" = "0"; - -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Recommended"; - -/* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Title"; +"SQx-au-ZcM.text" = "g COB"; -/* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ -"zvZ-uf-zMX.text" = "0"; diff --git a/Loop/es.lproj/InfoPlist.strings b/Loop/es.lproj/InfoPlist.strings index 334e8e97fe..ae97a23392 100644 --- a/Loop/es.lproj/InfoPlist.strings +++ b/Loop/es.lproj/InfoPlist.strings @@ -1,11 +1,17 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth se utiliza para las comunicaciones con la microinfusora y los dispositivos de monitoreo continuo de glucosa."; +"NSBluetoothAlwaysUsageDescription" = "El bluetooth se utiliza para las comunicaciones con la bomba de insulina y los dispositivos de monitoreo continuo de glucosa."; /* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Bluetooth se utiliza para las comunicaciones con la microinfusora y los dispositivos de monitoreo continuo de glucosa."; +"NSBluetoothPeripheralUsageDescription" = "El bluetooth se utiliza para las comunicaciones con la bomba de insulina y los dispositivos de monitoreo continuo de glucosa."; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "La cámara se utiliza para escanear los códigos de barras de los dispositivos."; /* Privacy - Face ID Usage Description */ "NSFaceIDUsageDescription" = "Se utiliza reconocimiento facial para autenticar el bolo de insulina."; @@ -14,5 +20,8 @@ "NSHealthShareUsageDescription" = "Datos de alimentos de la base de datos de Salud se utiliza para determinar los efectos en el nivel de glucosa. Datos de glucosa de la bsase de datos de Salud se utilizan para graficar y determinar cálculos de momento."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Datos de alimentos ingresados en la aplicación y en el reloj son almacenados en la base de datos de Salud. Los datos de glucosa extraídos del monitor continuo de glucosa se almacenan de manera segura en Kit de Salud."; +"NSHealthUpdateUsageDescription" = "Datos de alimentos ingresados en la aplicación y en el reloj son almacenados en la base de datos de Salud. Los datos de glucosa extraídos del monitor continuo de glucosa se almacenan de manera segura en HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop utiliza Siri para permitirte activar ajustes preestablecidos con tu voz."; diff --git a/Loop/es.lproj/Localizable.strings b/Loop/es.lproj/Localizable.strings index 579687277e..567cfb4649 100644 --- a/Loop/es.lproj/Localizable.strings +++ b/Loop/es.lproj/Localizable.strings @@ -1,27 +1,78 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (pendiente: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Pre-Comida Preestablecida"; + +/* remaining time in setting's profile expiration section */ +" remaining" = "restantes"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = " Notificaciones de seguridad desactivadas"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Ejercicio Preestablecido"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ "%@ absorbed" = "%@ absorbido"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ restante"; + /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ U Totales"; /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ no pudo cancelar su basal temporal actual, que es más alta que el nuevo límite basal máximo que ha establecido. Esto puede resultar en una administración de insulina superior a la deseada. \n\n Considere suspender la administración de insulina manualmente y luego reanudarla de inmediato para activar la administración basal con el nuevo límite establecido."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@ %2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ está funcionando con Circuito Cerrado en la posición APAGADO. Su bomba y CGM seguirán funcionando, pero la aplicación no ajustará la dosis automáticamente."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ no puede borrar la alerta de su dispositivo"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ no puede comunicarse con tu bomba de insulina. La aplicación continuará intentando llegar a tu bomba, pero la información de entrega de insulina no se puede actualizar y ninguna automatización puede continuar.\nPuedes esperar varios minutos para ver si el problema resuelve o pulsa el botón de abajo para saber más sobre otras opciones."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ La configuración de la hora necesita atención"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ U"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ U restantes"; @@ -31,14 +82,33 @@ /* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ "%1$@ U/hour @ %2$@" = "%1$@ U/hora @ %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ dejará de funcionar en %2$@ . Deberá actualizar antes de eso, con un nuevo perfil de aprovisionamiento."; + /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ -"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "Coeficiente de regresión de glucosa de 15 minutos (b₁), continuado con decadencia sobre 30 minutos."; +"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "Coeficiente de regresión de glucosa de 15 minutos (b₁), continuado con decaimiento durante 30 minutos"; /* Description of the prediction input effect for retrospective correction */ -"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "Comparación de glucosa actual contra la predicha en 30 minutos, continuada con decaimiento sobre 60 minutos."; +"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "Comparación de glucosa actual contra la proyectada en 30 minutos, continuada con decaimiento durante 60 minutos."; + +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Quedan unos segundos"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Una entrada de glucosa manual debe estar entre %1$@ y %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Una entrada de glucosa manual debe estar entre %1$@ y %2$@ ."; /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "Un modelo basado en la publicación de la absorción de insulina Fiasp."; @@ -46,6 +116,15 @@ /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Un modelo basado en la publicación de la absorción de insulina Humalog, Novolog y Apidra en adultos."; +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "Hay una nueva versión de %@ disponible y se recomienda continuar usando la aplicación."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Hay una nueva versión de %@ disponible."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Una microinfusadora debe ser configurada antes de que un bolo pueda ser entregado."; + /* Title of the carb entry absorption time cell */ "Absorption Time" = "Tiempo de Absorción"; @@ -58,20 +137,23 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Carbohidratos Activos: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Carbohidratos Activos"; + /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Insulina Activa"; +"Active Insulin" = "Insulina activa"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "Insulina Activa: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Agregar Carbohidratos"; +"Add Carb Entry" = "Agregar Entrada de Carb"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ -"Add CGM" = "Agregar CGM"; +"Add CGM" = "Agregar MCG"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Agregar Alimento"; /* Action sheet title selecting Pump @@ -81,42 +163,112 @@ /* Title text for button to set up a service */ "Add Service" = "Add Service"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* No comment provided by engineer. */ +"Adjusted for" = "Ajustado para"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Gestión de Alertas"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Permisos de Alertas"; /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Ajustes de Algoritmo"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Un ajuste al modelo adulto basado en los efectos empíricos en niños."; +/* The title of the Amplitude service */ +"Amplitude" = "Amplitude"; + +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Un Ajuste Temporal activo modifica la proporción de carbohidratos y la sensibilidad a la insulina. Si no deseas que esto afecte el cálculo del bolo y la glucosa proyectada, considera desactivar el Ajuste Temporal."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Se produjo un error al intentar guardar la entrada de carbohidratos."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Se produjo un error al intentar guardar la entrada manual de glucosa."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Se ha producido un error inesperado"; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Hay una recomendación actualizada de bolo."; + +/* The title of the amplitude API key credential */ +"API Key" = "API Key"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "Clave secreta API"; + +/* Settings app profile section */ +"App Profile" = "Perfil de la aplicación"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "¿Estás seguro de querer eliminar todos las entradas históricas?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "¿Estás seguro de que quieres borrar todas las entradas de dosis registradas?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "¿Estás seguro de querer eliminar todos los datos del reservorio?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "¿Estás seguro de que quieres eliminar todos tus datos de %@ ?\n (Esta acción no es reversible)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "¿Está usted seguro de querer eliminar este CGM?"; +"Are you sure you want to delete this CGM?" = "¿Está seguro de que quiere eliminar este MCG?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "¿Está seguro de que desea eliminar este servicio?"; /* Format fragment for a specific time */ -"at %@" = "a %@"; +"at %@" = "en %@"; /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Autenticar para Bolo %@ Unidades"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Autenticarse para registrar %@ Unidades"; + /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Perfil Basal"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Perfil Basal"; +"Basal Rates" = "Tasas basales"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Basándose en su glucosa proyectada, no se recomienda ningún bolo."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth\nApagado"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth \nNo Disponible"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Alerta de Bluetooth apagado"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Alerta de Bluetooth no disponible"; /* The label of the bolus entry button - The notification title for a bolus failure - Title text for bolus screen (manual correction) */ + The notification title for a bolus failure */ "Bolus" = "Bolo"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Problema con el bolo"; + /* Alert title for an updated bolus recommendation */ "Bolus Recommendation Updated" = "Recomendación de bolo fue actualicada"; +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Resumen del bolo"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolo demasiado pequeño"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Administró bolo %1$@ de %2$@"; @@ -132,18 +284,25 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "Efectos de carbohidratos"; -/* Back button text for bolus screen to return to carb entry screen */ +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ "Carb Entry" = "Entrada de Carbohidratos"; +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Calendario de ratio de carbohidratos"; + /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Relacíon de carbohidratos"; +"Carb Ratios" = "Ratios de carbohidratos"; /* The title of the view controller to create a new carb entry */ -"carb-entry-title-add" = "Agregar Carbohidratos"; +"carb-entry-title-add" = "Agregar Entrada de Carb"; /* The title of the view controller to edit an existing carb entry */ -"carb-entry-title-edit" = "Editar Entrada de Carbohidratos"; +"carb-entry-title-edit" = "Editar Entrada de Carb"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Entrada de carbohidratos demasiado grande"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Carbohidratos"; @@ -152,10 +311,10 @@ "Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Carbohidratos absorbidos (gr) ÷ Relación de Carbohidratos (gr/U) x Sensibilidad a Insulina (%1$@/U)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Cambie la batería de la microinfusora de inmediato"; +"Change the pump battery immediately" = "Cambie la batería de la bomba de inmediato"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Cambie el reservorio de la microinfusora ya"; +"Change the pump reservoir now" = "Cambie el depósito de la bomba ahora"; /* Details for configuration error when one or more loop settings are missing */ "Check settings" = "Verificar ajustes"; @@ -166,109 +325,260 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Verifique su fuente de datos CGM"; +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Compruebe la hora de su dispositivo y/o elimine cualquier dato no válido de Apple Health."; + /* Carb entry section footer text explaining absorption time */ -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Escoja un tiempo más largo de absorción para comidas más grandes, o las cuales que contienen más grasa o proteína. Éste es consejo al algoritmo y no es necesario de que sea exacto. "; +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Elija un tiempo de absorción más largo para comidas más grandes, o aquellas que contienen grasas y proteínas. Esta es solo una guía para el algoritmo y no necesita ser exacta."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Cerrar"; /* The title text for the looping enabled switch cell */ -"Closed Loop" = "Asa cerrada"; +"Closed Loop" = "Circuito Cerrado"; + +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Asa cerrada APAGADA"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "La asa cerrada requiere una sesión de sensor CGM activa"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "El Circuito Cerrado requiere que la configuración esté completa"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "en %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "desde %1$@"; /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +/* Title text for button to complete setup */ +"Complete Setup" = "Completa la Configuración"; + /* The title of the configuration section in settings */ "Configuration" = "Configuración"; /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Error de Configuración: %1$@"; +/* Default alert dismissal */ +"Continue" = "Continuar"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Monitor de glucosa continuo"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "Rango de Correción"; +"Correction Range" = "Rango de Corrección"; + +/* Critical Alerts Status text */ +"Critical Alerts" = "Alertas críticas"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Registro de eventos críticos listo"; + +/* Critical event log export title */ +"Critical Event Logs" = "Registros de eventos críticos"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "No se han podido exportar los registros de eventos críticos."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Glucosa actual"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Glucosa actual de %1$@ está por debajo del rango correctivo."; +"Current glucose of %1$@ is below correction range." = "Glucosa actual de %1$@ está por debajo del rango de corrección."; -/* Name of custom override - The title of the cell indicating a generic temporary override is enabled */ +/* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "Sobreescritura personalizada"; -/* Button title to delete CGM */ -"Delete CGM" = "Eliminar CGM"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Ajuste Preestablecido personalizado"; + +/* Date picker label */ +"Date" = "Fecha"; /* The short unit display string for decibles */ "dB" = "dB"; +/* No comment provided by engineer. */ +"Delete" = "Eliminar"; + /* The title of the button to remove the credentials for a service */ "Delete Account" = "Eliminar Cuenta"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Token de Usuario"; - -/* Title of the carb entry date picker cell */ -"Date" = "Fecha"; +/* Button title to delete all objects */ +"Delete All" = "Eliminar Todos"; /* Button title to delete CGM */ -"Delete CGM" = "Eliminar CGM"; +"Delete CGM" = "Eliminar MCG"; + +/* Button title to delete a service */ +"Delete Service" = "Eliminar servicio"; -/* The button text to initiate a bolus */ +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Eliminar prueba de datos CGM"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Eliminar datos de prueba"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Borrar los datos de prueba de la bomba"; + +/* Button text to deliver a bolus */ "Deliver" = "Entregar"; /* Title text for delivery limits */ -"Delivery Limits" = "Límites de Dosificación"; +"Delivery Limits" = "Límites de Administración de Insulina"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Tratamiento de la diabetes"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "¿Quería introducir %1$@ gramos como cantidad de hidratos de carbono para esta comida?"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Desactivar"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Ignorar"; + +/* No comment provided by engineer. */ +"Done" = "Completado"; + +/* Title for card to log dose */ +"Dose Summary" = "Resumen de dosis"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Estrategia de dosificación"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Activar \nBluetooth"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Permitir"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Ingrese una glucosa en sangre de un medidor por una cantidad recomendada de bolo."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Introducir bolo"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Ingrese la glucosa de punción en el dedo"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Introduzca el límite de seguridad de glucosa"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Ingrese nivel de suspensión"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Error de cancelación de bolo"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Error al exportar registros"; + /* The alert title for a resume error */ -"Error Resuming" = "Error de reanudación"; +"Error Resuming" = "Error Reanudando"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Historial de Eventos"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Eventualmente %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Excede el bolo máximo permitido en la configuración"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Supera el máximo permitido de carbohidratos definido en la configuración"; + /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Excede bolo máximo"; +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Exportar registros de eventos críticos"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Exportar- %1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "No se pudo reanudar la administración de insulina"; + /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Glucosa de punción en el dedo"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Soluciónalo ahora activando Notificaciones, Alertas Críticas y Notificaciones Sensibles al Tiempo."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Por %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "La glucosa en sangre pronosticada aún puede estar por encima del rango objetivo."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Glucosa pronosticada"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Ayuda con los Permisos de Alerta"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glucosa"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Los datos de glucosa son %1$@ antiguos"; +"Glucose data is %1$@ old" = "Los datos de glucosa son de hace %1$@ "; /* Description of error when glucose data is missing */ "Glucose data not available" = "Los datos de glucosa no están disponibles"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Datos de glucosa ahora disponibles"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Entrada de glucosa fuera de rango"; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Momento de Glucosa"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Horario para el objetivo de glucosa"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Cómo actualizar (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Inmediato"; + /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Indefinidamente"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Máximo de entrada excedido"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Insulina"; /* Description of the prediction input effect for insulin */ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulina Absorbida (U) x Sensibilidad a Insulina (%1$@/U)"; +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "¡Se han deshabilitado los ajustes de insulina!"; + /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Administración de Insulina"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Efectos de la insulina"; @@ -277,57 +587,213 @@ The title text for the insulin model setting row */ "Insulin Model" = "Modelo de Insulina"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Microinfusadora de insulina"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Sensibilidades a Insulina"; +"Insulin Sensitivities" = "Sensibilidad a la insulina"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Horario de la sensibilidad a la insulina"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insulina Suspendida"; + +/* Insulin type label */ +"Insulin Type" = "Tipo de Insulina"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "%1$@ interrumpido: %2$@ de %3$@ %4$@"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Cantidad de carbohidratos no válida"; /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Datos no válidos: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Glucosa futura no válida"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Lectura de glucosa no válida de %1$@ en el futuro"; + /* The title text for the issue report cell */ "Issue Report" = "Informe de Errores"; +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Comida grande ingresada"; + /* Glucose HUD accessibility hint */ "Launches CGM app" = "Lanza app MCG"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Más información"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Queda menos de un minuto"; + /* The loading message for the diagnostic report screen */ "Loading..." = "Cargando..."; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Registrar dosis"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Dosis de insulina registrada"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Falla del Loop"; + /* The notification title for a loop failure */ "Loop Failure" = "Falla del Loop"; +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop ha detectado un problema con la configuración de Bluetooth, y no funcionará correctamente hasta que el Bluetooth esté activado. No recibirás lecturas de glucosa, ni podrás dar los bolos."; + /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop no ha terminado correctamente en %@"; -/* Title text for bolus screen following a carb entry */ +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop administrará bolos automáticamente cuando las necesidades de insulina estén por encima del basal programado y utilizará ajustes temporales de basal cuando sea necesario para reducir la administración de insulina por debajo del basal programado."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop no funcionará correctamente hasta que el Bluetooth esté habilitado. No recibirá lecturas de glucosa ni podrá administrar bolus."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop establecerá basal temporales para aumentar y disminuir la administración de insulina."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Glucosa baja"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Administrar permisos en Configuración"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Dosis manual: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Tasa basal máxima por hora"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Bolo Máximo"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Bolo máximo excedido"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Duración máxima excedida"; + +/* Title for bolus entry screen when also entering carbs */ "Meal Bolus" = "Bolo de Comida"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Faltan Datos: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Falta el bolo máximo permitido en la configuración"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Efectos de Momento"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Más Info"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Silenciar todas las alertas"; + /* Sensor state description for the non-valid state */ "Needs Attention" = "Necesita Atención"; +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "No sonarán alertas mientras esté silenciado. Una vez que termine este período, sus alertas y alarmas se reanudarán con normalidad."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "No hay bolo recomendado"; + /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "No hay dispositivos conectados o falla durante conexión de dispositivo"; -/* The title text for the override presets */ -"Override Presets" = "Sobreescritura de objetivos preestablecidos"; +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "No hay bolo máximo configurado"; -/* Alert message for attempting to change basal rates before pump was configured. */ -"Please configure a pump to view or edit scheduled basal rates." = "Configure microinfusora para mirar o cambiar el perfil basal."; +/* Alert title for a missing pump error */ +"No Pump Configured" = "No hay microinfusadora configurada"; -/* Name of pre-meal workout override */ -"Pre-Meal" = "Pre-Comida"; +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Sin glucosa reciente"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Sin datos de glucosa recientes"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Sin datos de microinfusora recientes"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "No, editar cantidad"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Entrega de notificaciones"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "El envío de notificaciones está configurado como Resumen Programado en los ajustes del teléfono.\n\nPara evitar retrasos en la recepción de notificaciones de %1$@, le recomendamos que configure el envío de notificaciones como Entrega inmediata."; + +/* Notifications Status text */ +"Notifications" = "Notificaciones"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Retraso en las notificaciones"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Las notificaciones te proporcionan información importante sobre la aplicación %1$@ sin que tengas que abrirla."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Las notificaciones te proporcionan información importante sobre la aplicación %1$@ sin que tengas que abrirla.\n\nManten estas activadas en los ajustes del teléfono para recibir notificaciones %1$@, alertas críticas y notificaciones sensibles al tiempo cuando se entregan."; + +/* Notification Setting Status is Off */ +"Off" = "Apagado"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "¡Oh, no! Loop falló durante la dosificación y los ajustes de insulina se pausaron hasta que se cierre este cuadro de diálogo. El historial de dosificación puede no ser exacto. Revise los gráficos de administración de insulina y controle cuidadosamente su nivel de glucosa en sangre."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Encendido"; + +/* The title text for the override presets */ +"Override Presets" = "Sobreescrituras preestablecidas"; /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Objetivos Pre-Comida"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Glucosa proyectada en %1$@ es %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Glucosa proyectada a las %1$@ es %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "La glucosa proyectada está en rango"; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Glucosa proyectada de %1$@ se encuentra por debajo de tu nivel de suspensión."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Glucosa proyectada de %1$@ se encuentra por debajo de su nivel de suspensión."; @@ -335,27 +801,51 @@ /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Predicción: %1$@\nActual: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Preparando registros de eventos críticos"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Caducidad del perfil"; + +/* Time that profile expires */ +"Profile expires " = "El perfil caduca"; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "El perfil caduca pronto"; + /* The title of the pump section in settings */ -"Pump" = "Microinfusora"; +"Pump" = "Microinfusadora"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Batería de Microinfusora Baja"; +"Pump Battery Low" = "Batería de la bomba baja"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Los datos de la microinfusora son %1$@ viejos"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Evento de microinfusadora"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Administratión de Microinfusora"; +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Error del administrador de bomba: %1$@"; + /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Reservorio de Microinfusora Vacío"; +"Pump Reservoir Empty" = "Reserva de bomba vacía"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Reservorio de Microinfusora Bajo"; +"Pump Reservoir Low" = "Reserva de bomba baja"; /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Microinfusora Suspendida"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Microinfusora suspendida. La dosificación automática está desactivada."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Acción Rápida — Adultos"; @@ -363,81 +853,266 @@ "Rapid-Acting – Children" = "Acción Rápida — Niños"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ -"Recommendation expired: %1$@ old" = "Recomendación expiró: %1$@ vieja"; +"Recommendation expired: %1$@ old" = "Recomendación expiró hace: %1$@"; /* The title of the cell displaying a recommended temp basal value */ "Recommended Basal" = "Basal Recomendada"; +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Bolo recomendado"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "El bolo recomendado supera al bolo máximo"; + /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Bolo Recomendado: %@ Unidades"; +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Entrada remota de bolo: %@ U"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Entrada remota de carbohidratos: %d gr"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Comando remoto caducado"; + /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Reservorio"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Corrección Retrospectiva"; -/* The button text for attempting a manual loop - The title of the notification action to retry a bolus command */ +/* The title of the notification action to retry a bolus command */ "Retry" = "Reintentar"; -/* The button text to save a carb entry without bolusing */ +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Guardar y entregar"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ "Save without Bolusing" = "Guardar sin Entregar Bolo"; +/* Scheduled Delivery status text */ +"Scheduled" = "Programado"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Seleccionar período de silenciamiento"; + /* The title of the services section in settings */ "Services" = "Servicios"; /* The label of the settings button */ "Settings" = "Ajustes"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Configuración incompleta"; + /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Muestra último error de Loop"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Calculadora simple de bolo"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Calculadora simple de comida"; + /* Format fragment for a start time */ "since %@" = "desde %@"; +/* The title of the nightscout site URL credential */ +"Site URL" = "URL de Sitio"; + +/* Software update button link text */ +"Software Update" = "Actualización de software"; + /* The format for the description of a temporary override start date */ -"starting at %@" = "comenzando a la %@"; +"starting at %@" = "comenzando a las %@"; /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Comenzando Bolo"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Ayuda"; + /* The title text in settings */ "Suspend Threshold" = "Nivel de Suspensión"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Pulsa aquí para configurar un CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Pulsa aquí para configurar una microinfusadora"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Pulsa aquí para configurar un Servicio"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Pulsa para añadir"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ "Tap to Resume" = "Toque para reanudar"; +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Pulsa para detener"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Alertas de silencio temporal"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "La cantidad de bolo ingresada es menor que el mínimo que se puede administrar."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "El algoritmo de dosificación de bolo utiliza una estimación más conservadora de la glucosa en sangre pronosticada que la que se usa para ajustar su basal. \n\n Como resultado, su glucosa en sangre pronosticada después de un bolo aún puede ser más alta que su rango objetivo."; + /* Alert message for an updated bolus recommendation */ "The bolus recommendation has updated. Please reconfirm the bolus amount." = "La recomendación de bolo ha sido updatada. Reconfirme el bolo."; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "El model utilizado por ediciones iniciales de Loop, permite ajustar duración de acción."; +"The legacy model used by Loop, allowing customization of action duration." = "El modelo heredado utilizado por Loop, que permite personalizar la duración de la acción de la insulina."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "El tiempo máximo de absorción es %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "La cantidad máxima permitida es %@ gr."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "La cantidad máxima permitida es %1$@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Bolo máximo es %@ Unidades."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Bolo máximo es %@ Unidades"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "El ajuste de bolo máximo debe configurarse antes de que se pueda administrar un bolo."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "El comando remoto expiró hace %.0f minutos."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Ajustes de la Terapia"; + +/* Title of the carb entry date picker cell */ +"Time" = "Hora"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Notificaciones sensibles al tiempo"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Inténtalo de nuevo"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Activa Bluetooth para recibir alertas, alarmas o medidas de glucosa del sensor."; + /* The short unit display string for international units of insulin */ "U" = "U"; -/* Alert title for unconfigured pump */ -"Unconfigured Pump" = "La microinfusora no está configurada"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "No se puede borrar la alerta"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "No se puede contactar con la bomba"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "No se puede guardar la entrada de carbohidratos"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "No se puede guardar la entrada manual de glucosa"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "No se puede detener el bolo en progreso. Mueve tu iPhone más cerca de la microinfusora e inténtalo de nuevo. Revisa tu historial de entrega de insulina para más detalles y supervisa tu glucosa."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Desconocido"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Error desconocido: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Tiempo desconocido"; /* The format for the description of a temporary override end date */ -"until %@" = "hasta la %@"; +"until %@" = "hasta las %@"; + +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Hasta que registre carbohidratos"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Hasta que lo desactive"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Usar Pre-Comida"; /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Utilice Objetivos de Glucosa de Ejercicio"; +"Use Workout Glucose Targets" = "Usar Objetivos de Glucosa de Ejercicio"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Usar Ejercicio"; /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Atención Las notificaciones de seguridad están desactivadas"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Cuando la glucosa actual o proyectada se encuentre debajo del nivel de suspensión, Loop no recomendará un bolo y siempre recomendará un basal temporal de 0 unidades por hora."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Cuando la glucosa actual o proyectada se encuentre debajo del nivel de suspensión, Loop no recomendará un bolo y siempre recomendará un basal temporal de 0 unidades por hora."; -/* Name of legacy workout override */ -"Workout" = "Entrenamiento"; +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Cuando está fuera del modo Closed Loop, la aplicación utiliza una calculadora de bolo simplificada como una microinfusadora típica."; /* The label of the workout mode toggle button */ "Workout Targets" = "Objetivos de Ejercicio"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "El Ajuste Temporal por Ejercicio se ha activado durante más de 24 horas. Asegúrate de que todavía quieres que esté habilitado o desactívalo en la aplicación."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Ajuste Temporal por Ejercicio todavía encendido"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Sí"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Es posible que no reciba alertas sonoras, visuales o por vibración relativas a información de seguridad crítica.\n\nPara solucionar el problema, toque \"Ajustes\" y asegúrese de que las notificaciones, las alertas críticas y las notificaciones sensibles al tiempo están activadas."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Se ha cambiado la hora de su %1$@. %2$@ necesita registros horarios precisos para hacer predicciones sobre su glucosa y ajustar su insulina.\n\nCompruebe en su %1$@ Ajustes (General / Fecha y Hora) y verifique que 'Ajustar automáticamente' está activado. Si no se resuelve, podría producirse un grave suministro insuficiente o excesivo de insulina."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Tu glucosa está por debajo de %1$@. ¿Estás seguro de que deseas administrar un bolo?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Tu nivel de glucosa está por debajo o se prevé que vaya a estar por debajo de tu límite de seguridad de glucosa, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Tu glucosa está por debajo del límite de seguridad de glucosa, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Tu glucosa está baja. Come carbohidratos y considera esperar para administrar el bolo hasta que tu glucosa esté en un rango seguro."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Tienes la glucosa baja. Come carbohidratos y vigílalo de cerca."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Su cantidad máxima de bolo es %1$@ ."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Los datos de su bomba están obsoletos. %1$@ no puede recomendar una cantidad de bolo."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Su bomba está suministrando una tasa basal temporal manual."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Su bolo recomendado excede su cantidad máxima de bolo de %1$@."; + diff --git a/Loop/es.lproj/Main.strings b/Loop/es.lproj/Main.strings index 8677f43e78..e1b9077072 100644 --- a/Loop/es.lproj/Main.strings +++ b/Loop/es.lproj/Main.strings @@ -1,30 +1,18 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ -"3kU-n2-fha.title" = "Estatus"; +"3kU-n2-fha.title" = "Estado"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/hora @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolo"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "ID de Microinfusora"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Cantidad de Bolo"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Proyectada"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ "aCb-Qs-bpu.text" = "Detalle"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolo"; - /* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ "ap1-M6-naG.text" = "Típo de Comida"; @@ -34,83 +22,53 @@ /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Cambio de Glucosa"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Unidades"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Etiqueta"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "gr Totales"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "La glucosa futura se predice combinando los efectos de diversas entradada de datos. Utiliza esta herramienta para cambiar datos de entrada y ver como varía la predicción final."; +"D4C-I2-dhA.text" = "La glucosa futura se predice combinando los efectos de diversos datos de entrada. Utiliza esta herramienta para cambiar datos de entrada y ver como varía la predicción final."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Etiqueta"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Ajustes"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "DISPOSITIVOS"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "eventualmente 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Observado"; -/* Class = "UILabel"; text = "Eventually 92 mg/dL"; ObjectID = "G51-pt-pmi"; */ -"G51-pt-pmi.text" = "Eventualmente 92 mg/dL"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/hora @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Efecto de Carbohidratos"; -/* Class = "UILabel"; text = "Label"; ObjectID = "IRb-Yj-AQH"; */ -"IRb-Yj-AQH.text" = "Etiqueta"; - /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ "IxU-As-glo.text" = "Los cambios observados en glucosa sustrayendo los cambios modelados para la entrega de insulina pueden ser utilizados para estimar la absorción de carbohidratos."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Detalle"; -/* Class = "UILabel"; text = "Detail"; ObjectID = "jQv-xb-gwu"; */ -"jQv-xb-gwu.text" = "Detaille"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Glucosa Proyectada Por Debajo Del Rango."; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Basal Recomendada"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Etiqueta"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Etiqueta"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Toca para definir"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Unidades"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Etiqueta"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Glucosa Proyectada"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Modelo de Insulina"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; + +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ "qPH-vU-xlu.text" = "Típo de Comida"; @@ -119,7 +77,7 @@ "Rse-x8-amW.text" = "eventualmente 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "gr CAB"; +"SQx-au-ZcM.text" = "gr Carbohidratos Activos"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ "tuw-av-A3x.text" = "Glucosa"; @@ -133,18 +91,21 @@ /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Carbohidratos"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 horas"; - /* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ "Wx8-Tf-FnG.text" = "Cantidad Consumida"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Basal Recomendada"; + +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; + /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Recomendado"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "Título"; diff --git a/Loop/fi.lproj/InfoPlist.strings b/Loop/fi.lproj/InfoPlist.strings index 39aa3a73da..153e9f4d6f 100644 --- a/Loop/fi.lproj/InfoPlist.strings +++ b/Loop/fi.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Loop/fi.lproj/Localizable.strings b/Loop/fi.lproj/Localizable.strings index 57565860b6..81a97d0480 100644 --- a/Loop/fi.lproj/Localizable.strings +++ b/Loop/fi.lproj/Localizable.strings @@ -1,12 +1,30 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = "(odot.: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Ennen ateriaa -esiasetus"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Liikuntatila"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ "%@ absorbed" = "%@ imeytynyt"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ jäljellä"; + /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ U yhteensä"; @@ -16,12 +34,21 @@ /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ ei pysty kommunikoimaan insuliinipumpun kanssa. Sovellus yrittää edelleen yhdistää pumppuun, mutta insuliininannostelun tiedot eivät päivity, eikä automatiikka ole päällä.\nVoit odottaa muutaman minuutin nähdäksesi ratkeaako ongelma, tai voit napauttaa alla olevaa painiketta saadaksesi lisätietoja muista vaihtoehdoista."; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ U"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ U jäljellä"; @@ -37,18 +64,31 @@ /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 min glukoosin regressiokerroin (b₁), hiipuen 30 min kuluessa"; /* Description of the prediction input effect for retrospective correction */ "30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min vertailu ennustetun ja todellisen glukoosin välillä, hiipuen 60 min kuluessa"; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Muutama sekunti jäljellä"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Syötetyn glukoosiarvon on oltava välillä %1$@ – %2$@"; + /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "Perustuu Fiasp-insuliinin julkaistuun imeytymismalliin."; /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Perustuu Humalog-, Novorapid- ja Apidra-insuliinien julkaistuun imeytymismalliin aikuisilla."; +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Pumppu on määritettävä, ennen kuin bolus voidaan annostella."; + /* Title of the carb entry absorption time cell */ "Absorption Time" = "Imeytymisaika"; @@ -61,8 +101,11 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Aktiivinen hiilihydraatti: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Akt. hiilari"; + /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Aktiivinen insuliini"; +"Active Insulin" = "Akt. insuliini"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "Aktiivinen insuliini: %@"; @@ -74,18 +117,37 @@ Title text for button to set up a CGM */ "Add CGM" = "Lisää CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Lisää ateria"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ "Add Pump" = "Lisää pumppu"; +/* Title text for button to set up a service */ +"Add Service" = "Lisää palvelu"; + +/* No comment provided by engineer. */ +"Adjusted for" = "Mukautettu"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Hälytysten käyttöoikeudet"; + +/* The title of the section containing algorithm settings */ +"Algorithm Settings" = "Algoritmin asetukset"; + /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Aikuisten mallista lapsille mukautettu empiirisiin vaikutuksiin perustuva malli."; +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Virhe hiilihydraattien tallennuksessa."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Virhe glukoosiarvon tallennuksessa."; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Päivitetty bolussuositus on saatavilla."; /* The title of the amplitude API key credential */ "API Key" = "API-avain"; @@ -93,15 +155,33 @@ /* The title of the nightscout API secret credential */ "API Secret" = "API-salasana"; +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Haluatko varmasti poistaa kaikki historiatiedot?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Haluatko varmasti poistaa kaikki kirjatut annostelutiedot?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Haluatko varmasti poistaa kaikki säiliön arvot?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Haluatko varmasti poistaa kaikki %@ tietosi?\n(Tämä toiminto ei ole palautettavissa)"; + /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Haluatko varmasti poistaa CGM:n?"; +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Haluatko varmasti poistaa tämän palvelun?"; + /* Format fragment for a specific time */ "at %@" = "klo %@"; /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Vahvista bolus %@ yksikköä"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Vahvista kirjaus %@ yksikköä"; + /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Basaaliohjelma"; @@ -109,14 +189,28 @@ The title text for the basal rate schedule */ "Basal Rates" = "Basaalitasot"; +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth ei ole käytössä"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth ei ole käytettävissä"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Bluetooth ei ole käytössä -hälytys"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Bluetooth ei ole käytettävissä -hälytys"; + /* The label of the bolus entry button - The notification title for a bolus failure - Title text for bolus screen (manual correction) */ + The notification title for a bolus failure */ "Bolus" = "Bolus"; /* Alert title for an updated bolus recommendation */ "Bolus Recommendation Updated" = "Bolussuositus päivitetty"; +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Bolusyhteenveto"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Bolus %1$@ / %2$@"; @@ -132,7 +226,8 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "Hiilihydraattivaikutus"; -/* Back button text for bolus screen to return to carb entry screen */ +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ "Carb Entry" = "Hiilihydraatit"; /* The title of the carb ratios schedule screen @@ -167,11 +262,26 @@ "Check your CGM data source" = "Tarkista CGM-tietolähde"; /* Carb entry section footer text explaining absorption time */ -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Valitse pidempi imeytymisaika isoille tai paljon rasvaa ja proteiineja sisältäville aterioille. Tämä on suuntaa antava tieto, eikä sen tarvitse olla tarkka."; +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Valitse pidempi imeytymisaika isoille tai paljon rasvaa ja proteiineja sisältäville aterioille. Tämä on suuntaa antava ohje, eikä sen tarvitse olla tarkka."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Sulje"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Suljettu säätö"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Suljettu säätö pois päältä"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Suljettu säätö vaatii aktiivisen glukoosisensorin"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "klo %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "%1$@ jälkeen"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; @@ -181,6 +291,9 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Määritysvirhe: %1$@"; +/* Default alert dismissal */ +"Continue" = "Jatka"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Glukoosinseuranta (CGM)"; @@ -188,55 +301,142 @@ The title text for the glucose target range schedule */ "Correction Range" = "Korjausalue"; +/* Critical event log ready text */ +"Critical Event Log Ready" = "Tärkeiden tapahtumien loki valmis"; + +/* Critical event log export title */ +"Critical Event Logs" = "Tärkeiden tapahtumien loki"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Tärkeiden tapahtumien lokia ei voitu viedä."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Nykyinen glukoosi"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = "Nykyinen glukoosi %1$@ on korjausalueen alapuolella."; -/* Name of custom override - The title of the cell indicating a generic temporary override is enabled */ +/* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "Mukautettu tilapäisasetus"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Asiakastunniste"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Mukautettu esiasetus"; -/* Title of the carb entry date picker cell */ +/* Date picker label */ "Date" = "Aika"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Delete" = "Poista"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Poista tili"; + +/* Button title to delete all objects */ +"Delete All" = "Poista kaikki"; + /* Button title to delete CGM */ "Delete CGM" = "Poista CGM"; -/* The button text to initiate a bolus */ +/* Button title to delete a service */ +"Delete Service" = "Poista palvelu"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Poista testi-CGM:n tiedot"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Poista testitiedot"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Poista testipumpun tiedot"; + +/* Button text to deliver a bolus */ "Deliver" = "Annostele"; /* Title text for delivery limits */ "Delivery Limits" = "Annostelurajat"; +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Diabeteshoito"; + /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Poistaa käytöstä"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Ohita"; + +/* No comment provided by engineer. */ +"Done" = "Valmis"; + +/* Title for card to log dose */ +"Dose Summary" = "Annoksen yhteenveto"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Annostelutapa"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Ota Bluetooth käyttöön"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Ottaa käyttöön"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Syötä sormenpäästä mitattu glukoosiarvo saadaksesi suositellun bolusmäärän."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Syötä bolus"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Syötä mitattu glukoosiarvo"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Aseta glukoosin turvaraja"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Aseta pysäytysraja"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Virhe boluksen kumoamisessa"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Virhe lokin viennissä"; + /* The alert title for a resume error */ "Error Resuming" = "Virhe jatkamisessa"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Tapahtumahistoria"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Ennuste %@"; /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Ylittää maksimiboluksen"; +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Vie tärkeiden tapahtumien loki"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Vienti-%1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Annostelun jatkaminen epäonnistui"; + /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Mitattu glukoosi"; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "%1$@ ajaksi"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glukoosi"; @@ -246,12 +446,16 @@ /* Description of error when glucose data is missing */ "Glucose data not available" = "Glukoositietoja ei saatavilla"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Glukoositiedot nyt saatavilla"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Glukoosiarvo alueen ulkopuolella"; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Glukoosin liike"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://omaosoite.herokuapp.com"; - /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Toistaiseksi"; @@ -262,7 +466,7 @@ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Imeytynyt insuliini (U) × Insuliiniherkkyys (%1$@/U)"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insuliinin annostelu"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Insuliinivaikutus"; @@ -271,10 +475,22 @@ The title text for the insulin model setting row */ "Insulin Model" = "Insuliinimalli"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Insuliinipumppu"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ "Insulin Sensitivities" = "Insuliiniherkkyydet"; +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insuliini pysäytetty"; + +/* Insulin type label */ +"Insulin Type" = "Insuliinityyppi"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Keskeytetty %1$@: %2$@ / %3$@ %4$@"; + /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Virheellinen tieto: %1$@"; @@ -284,54 +500,122 @@ /* Glucose HUD accessibility hint */ "Launches CGM app" = "Avaa CGM-sovelluksen"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Lue lisää"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Alle minuutti jäljellä"; + /* The loading message for the diagnostic report screen */ "Loading..." = "Ladataan..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Kirjaa annos"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Kirjattu insuliiniannos"; /* The notification title for a loop failure */ "Loop Failure" = "Loopin häiriö"; +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop on havainnut Bluetooth-asetuksissa ongelman, eikä se toimi oikein ennen kuin Bluetooth on otettu käyttöön. Et saa glukoosilukemia, etkä voi antaa bolusta."; + /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Häiriö Loopin toiminnassa %@"; -/* Title text for bolus screen following a carb entry */ +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop annostelee automaattisen boluksen kun insuliinitarve ylittää ohjelmoidun basaalin, ja käyttää tilapäisiä alhaisempia basaalitasoja kun tarvitaan vähemmän insuliinia."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop käyttää tilapäisiä basaalitasoja lisätäkseen tai vähentääkseen insuliinin annostelua."; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Suurin sallittu bolus"; + +/* Title for bolus entry screen when also entering carbs */ "Meal Bolus" = "Ateriabolus"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Tiedot puuttuvat: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Liikevaikutukset (momentum)"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Lisätietoa"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Tarvitsee huomiota"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Bolusta ei suositella"; + /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Ei yhdistettyjä laitteita tai häiriö laiteyhteydessä"; -/* Button text to acknowledge an updated bolus recommendation alert */ +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Maksimibolusta ei ole määritetty"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Pumppua ei ole määritetty"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Ei viimeaikaisia glukoositietoja"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Ei viimeaikaisia glukoositietoja"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Ei viimeaikaisia pumpun tietoja"; + +/* Notification Setting Status is Off */ +"Off" = "Pois päältä"; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ "OK" = "OK"; +/* Notification Setting Status is On */ +"On" = "Päällä"; + /* The title text for the override presets */ "Override Presets" = "Tilapäisasetukset"; -/* Name of pre-meal workout override */ -"Pre-Meal" = "Ennen ateriaa"; - /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Ennen ateriaa -tavoite"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "Ennustettu glukoosi klo %1$@ on %2$@."; +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Ennustettu glukoosi %1$@ on turvarajan alapuolella."; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Ennustettu glukoosi %1$@ on pysäytysrajan alapuolella."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Ennustettu: %1$@\nTodellinen: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Valmistellaan tärkeiden tapahtumien lokia"; + /* The title of the pump section in settings */ "Pump" = "Pumppu"; @@ -341,6 +625,9 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Pumpputieto on %1$@ vanha"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pumpputapahtuma"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Pumpun hallinta"; @@ -353,6 +640,12 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pumppu pysäytetty"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pumppu pysäytetty. Automaattinen annostelu ei ole käytössä."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Nopeavaikutteinen – aikuiset"; @@ -365,6 +658,10 @@ /* The title of the cell displaying a recommended temp basal value */ "Recommended Basal" = "Suositeltu basaali"; +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Suositeltu bolus"; + /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Suositeltu bolus: %@ yksikköä"; @@ -374,11 +671,13 @@ /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Retrospektiivinen korjaus"; -/* The button text for attempting a manual loop - The title of the notification action to retry a bolus command */ -"Retry" = "Uudelleen"; +/* The title of the notification action to retry a bolus command */ +"Retry" = "Yritä uudelleen"; + +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Tallenna ja annostele"; -/* The button text to save a carb entry without bolusing */ +/* Button text to save carbs and/or manual glucose entry without a bolus */ "Save without Bolusing" = "Tallenna ilman bolusta"; /* The title of the services section in settings */ @@ -390,6 +689,12 @@ /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Näyttää Loopin viimeisimmän virheen"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Yksinkertainen boluslaskuri"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Yksinkertainen aterialaskuri"; + /* Format fragment for a start time */ "since %@" = "%@ jälkeen"; @@ -402,39 +707,124 @@ /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Aloitetaan bolus"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Tuki"; + /* The title text in settings */ "Suspend Threshold" = "Pysäytysraja"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Määritä CGM napauttamalla tästä"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Määritä pumppu napauttamalla tästä"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Määritä palvelu napauttamalla tästä"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Lisää napauttamalla"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ "Tap to Resume" = "Jatka annostelua"; +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Pysäytä"; + /* Alert message for an updated bolus recommendation */ "The bolus recommendation has updated. Please reconfirm the bolus amount." = "Bolussuositus on päivittynyt. Vahvista bolus uudelleen."; /* Subtitle description of Walsh insulin model setting */ "The legacy model used by Loop, allowing customization of action duration." = "Loopin vanha insuliinimalli, jossa voi muokata insuliinin vaikutusaikaa."; +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Pisin sallittu imeytymisaika on %@"; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Suurin sallittu bolus on %@ U."; + /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Suurin sallittu bolus on %@ yksikköä"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Suurin sallittu bolus -asetus täytyy määrittää ennen kuin bolus voidaan annostella."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Hoitoasetukset"; + +/* Title of the carb entry date picker cell */ +"Time" = "Aika"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Yritä uudelleen"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Ota Bluetooth käyttöön saadaksesi hälytyksiä tai sensorin glukoosilukemia."; + /* The short unit display string for international units of insulin */ "U" = "U"; +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Pumppuun ei voitu yhdistää"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Hiilihydraatteja ei voitu tallentaa"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Glukoosiarvoa ei voitu tallentaa"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Käynnissä olevaa bolusta ei voitu pysäyttää. Siirrä iPhone lähemmäksi pumppua ja yritä uudelleen. Tarkista tiedot insuliinin annosteluhistoriasta ja seuraa glukoosia tarkasti."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Tuntematon"; + /* The format for the description of a temporary override end date */ "until %@" = "%@ asti"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Kunnes syötän hiilihydraatteja"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Kunnes laitan pois päältä"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Käytä Ennen ateriaa -esiasetusta"; + /* The title of the alert controller used to select a duration for workout targets */ "Use Workout Glucose Targets" = "Käytä liikuntatilan glukoositavoitetteita"; +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Käytä liikuntatilaa"; + /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Kun nykyinen tai ennustettu glukoosi on glukoosin turvarajan alapuolella, Loop ei suosittele bolusta ja suosittelee aina tilapäiseksi basaaliksi 0 yksikköä tunnissa."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Kun nykyinen tai ennustettu glukoosi on pysäytysrajan alapuolella, Loop ei suosittele bolusta ja suosittelee aina tilapäiseksi basaaliksi 0 yksikköä tunnissa."; -/* Name of legacy workout override */ -"Workout" = "Liikunta"; +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Kun suljettu säätö ei ole päällä, sovellus käyttää yksinkertaista boluslaskuria, kuten tavallisessa pumpussa."; /* The label of the workout mode toggle button */ "Workout Targets" = "Liikuntatavoitteet"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Liikuntatila on ollut käytössä yli 24 tuntia. Varmista, että haluat sen olevan edelleen käytössä, tai poista se käytöstä sovelluksessa."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Liikuntatila on yhä päällä"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Glukoosi on alle tai sen ennustetaan alittavan glukoosin turvarajan %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Glukoosi on alle glukoosin turvarajan %1$@."; + diff --git a/Loop/fi.lproj/Main.strings b/Loop/fi.lproj/Main.strings index 5cb57b548c..2b5bb08c6b 100644 --- a/Loop/fi.lproj/Main.strings +++ b/Loop/fi.lproj/Main.strings @@ -1,29 +1,17 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Tila"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/h @ 12:12"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Pumpun tunniste"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Bolusmäärä"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Ennustettu"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Yksityiskohta"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +"aCb-Qs-bpu.text" = "Detail"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ "ap1-M6-naG.text" = "Ruokatyyppi"; @@ -34,15 +22,6 @@ /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Glukoosin muutos"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Yksikköä"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Nimiö"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g yhteensä"; @@ -52,18 +31,18 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Nimiö"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Asetukset"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "LAITTEET"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "ennuste 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Havaittu"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/h @ 12:12"; + /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Hiilihydraattivaikutus"; @@ -71,13 +50,7 @@ "IxU-As-glo.text" = "Havaittua glukoosin muutosta, josta on vähennetty insuliinin mallinnettu vaikutus, voidaan käyttää hiilihydraattien imeytymisen arviointiin."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Yksityiskohta"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "jQv-xb-gwu"; */ -"jQv-xb-gwu.text" = "Yksityiskohta"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Ennustettu glukoosi alueen alapuolella"; +"J7x-W5-gwo.text" = "Detail"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Suositeltu basaali"; @@ -85,29 +58,17 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Nimiö"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Nimiö"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Napauta asettaaksesi"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Yksikköä"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Nimiö"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Ennustettu glukoosi"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insuliinimalli"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Insuliiniaktiivisuusmallia käytetään arvioimaan insuliinin vaikutuksia glukoositasoon. Tarkka malli voi auttaa estämään liian suuren insuliinimäärän kertymistä kehoon ja suosittelemaan turvallisia glukoosia korjaavia hoitotoimenpiteitä."; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ "qPH-vU-xlu.text" = "Ruokatyyppi"; @@ -130,20 +91,23 @@ /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Hiilihydraatit"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 tuntia"; - /* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ "Wx8-Tf-FnG.text" = "Määrä"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Suositeltu basaali"; + +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; + /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Suositus"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Otsikko"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; diff --git a/Loop/fr.lproj/InfoPlist.strings b/Loop/fr.lproj/InfoPlist.strings index de9a1ce22a..159de0fb7a 100644 --- a/Loop/fr.lproj/InfoPlist.strings +++ b/Loop/fr.lproj/InfoPlist.strings @@ -1,18 +1,27 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices."; +"NSBluetoothAlwaysUsageDescription" = "Bluetooth est utilisé pour communiquer avec la pompe à insuline et les dispositifs de surveillance continue du glucose."; /* Privacy - Bluetooth Peripheral Usage Description */ "NSBluetoothPeripheralUsageDescription" = "Bluetooth est utilisé pour communiquer avec la pompe à insuline et les dispositifs de surveillance continue du glucose."; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "La caméra est utilisée pour scanner les codes-barres des appareils."; + /* Privacy - Face ID Usage Description */ -"NSFaceIDUsageDescription" = "ID de visage est utilisé pour authentifier le bolus d'insuline."; +"NSFaceIDUsageDescription" = "Face ID est utilisé pour authentifier le bolus d'insuline et sauvegarder les changements dans les réglages de thérapie."; /* Privacy - Health Share Usage Description */ -"NSHealthShareUsageDescription" = "Les données sur les repas provenant de la base de données Health sont utilisées pour déterminer les effets du glucose. Les données sur la glycémie de la base de données Health sont utilisées pour le calcul graphique et le calcul du momentum."; +"NSHealthShareUsageDescription" = "Les données sur les repas provenant de la base de données Health sont utilisées pour déterminer les effets du glucose. Les données sur la glycémie de la base de données Health sont utilisées pour le calcul graphique et le calcul du momentum. Les données de sommeil provenant de la base de données Health sont utilisées pour améliorer les cadrans Apple Watch."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Les données sur les repas glucidiques saisies dans l'application et sur la montre sont stockées dans la base de données Health. Les données de glucose extraites du CGM sont stockées de manière sécurisée dans HealthKit."; +"NSHealthUpdateUsageDescription" = "Les données de glucides des repas entrées dans l'application ou la montre sont enregistrées dans la base de donnée Santé. Les données de taux de glucose provenant du CGM sont enregistrées de manière sécurisée dans HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop utilise Siri pour vous permettre d’activer des préréglages avec votre voix."; diff --git a/Loop/fr.lproj/Localizable.strings b/Loop/fr.lproj/Localizable.strings index 1eebe38eab..6daeadb988 100644 --- a/Loop/fr.lproj/Localizable.strings +++ b/Loop/fr.lproj/Localizable.strings @@ -1,27 +1,75 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ -" (pending: %@)" = " (en suspens: %@)"; +" (pending: %@)" = " (en attente : %@)"; + +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Préréglage Pré-repas"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = "Notifications de sécurité sont DÉSACTIVÉES"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Préréglage exercice"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "-"; /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ -"%@ absorbed" = "%@ absorbé"; +"%@ absorbed" = "%@ absorbé(s)"; + +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ restant"; /* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ U Totaux"; +"%@ U Total" = "%@ U total"; /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ n'a pas pu annuler votre débit basal temporaire actuel, qui est supérieur à la nouvelle limite basale max que vous avez définie. Cela peut entraîner une administration d'insuline plus élevée que souhaitée. \n\nEnvisagez de suspendre l'administration d'insuline manuellement, puis de reprendre immédiatement l'administration basale avec la nouvelle limite en place."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ fonctionne avec la boucle fermée en position ARRÊT. Votre pompe et votre CGM continueront de fonctionner, mais l'application n'ajustera pas automatiquement le dosage."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ ne parvient pas à supprimer l'alerte de votre dispositif."; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ ne parvient pas à communiquer avec votre pompe à insuline. L’application continuera d’essayer d’atteindre votre pompe, mais les informations sur l’administration d’insuline ne peuvent pas être mises à jour et aucune automatisation ne peut continuer.\nVous pouvez attendre quelques minutes pour voir si le problème est résolu ou appuyer sur le bouton ci-dessous pour en savoir plus sur les autres options."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Paramètres d'heure requierent une attention"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ U"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ U restantes"; @@ -31,23 +79,51 @@ /* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ "%1$@ U/hour @ %2$@" = "%1$@ U/heure @ %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ cessera de fonctionner dans %2$@ . Vous devrez mettre à jour avant cela, avec un nouveau profil de provisioning."; + /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ -"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "Coefficient de régression du glucose de 15 minutes (b1), désintégration poursuivi au delà de 30 min."; +"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "Coefficient de régression du glucose de 15 minutes (b1), décroissance poursuivie au-delà de 30 min."; /* Description of the prediction input effect for retrospective correction */ -"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "Comparaison sur 30 min de la glycémie Prédiction vs Actuelle, suivie d'une décroissance (decay) sur 60 min."; +"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "Comparaison sur 30 min de la glycémie prévue par rapport à celle réelle, suivie d'une décroissance (decay) sur 60 min."; + +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Quelques secondes restantes"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Une saisie manuelle de la glycémie doit être comprise entre %1$@ et %2$@."; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Une saisie manuelle de la glycémie doit être comprise entre %1$@ et %2$@."; /* Subtitle of Fiasp preset */ -"A model based on the published absorption of Fiasp insulin." = "Un modèle basé sur l’absorption publiée de l’insuline FIASP."; +"A model based on the published absorption of Fiasp insulin." = "Un modèle basé sur l’absorption de l’insuline FIASP (telle que publiée)."; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Un modèle basé sur l’absorption publiée de l’Hunalog, Novolog, et Apidra chez l’adulte."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Un modèle basé sur les absorptions de l’Humalog, Novolog (Novorapid), et Apidra chez l’adulte (telles que publiées)."; + +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "Une nouvelle version de %@ est disponible et est recommandée pour continuer à utiliser l'application."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Une nouvelle version de %@ est disponible."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Une pompe doit être configurée avant qu'un bolus puisse être administré."; /* Title of the carb entry absorption time cell */ -"Absorption Time" = "Durée d'absorption"; +"Absorption Time" = "Durée d’absorption"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AcceptRecommendedBolus"; @@ -58,6 +134,9 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Glucides actifs: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Glucides actifs"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "Insuline active"; @@ -69,9 +148,9 @@ /* Action sheet title selecting CGM Title text for button to set up a CGM */ -"Add CGM" = "Ajouter CGM"; +"Add CGM" = "Ajouter un CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Entrer un repas"; /* Action sheet title selecting Pump @@ -79,43 +158,111 @@ "Add Pump" = "Ajouter une pompe"; /* Title text for button to set up a service */ -"Add Service" = "Add Service"; +"Add Service" = "Ajouter un service"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* No comment provided by engineer. */ +"Adjusted for" = "Ajusté(e) pour"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Gestion des alertes"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Autorisations d'alerte"; /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Paramètres de l'algorithme"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Un ajustement au modèle adulte basé sur des effets empiriques chez les enfants."; +/* The title of the Amplitude service */ +"Amplitude" = "Amplitude"; + +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Un ajustement actif modifie votre ratio de glucides et votre sensibilité à l'insuline. Si vous ne voulez pas que cela affecte le calcul du bolus et votre glycémie projetée, envisagez de désactiver l'ajustement."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Une erreur est survenue lors de l'enregistrement de votre saisie manuelle de glucides."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Une erreur est survenue lors de l'enregistrement de votre saisie manuelle de glycémie."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Un état d'erreur innatendu a eu lieu durant le processus d'intégration"; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Une recommandation de bolus mise à jour est disponible."; + +/* The title of the amplitude API key credential */ +"API Key" = "Clé API"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "Secret API"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Voulez-vous vraiment supprimer toutes les entrées de l’historique?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Voulez-vous vraiment supprimer toutes les entrées de dose enregistrées ?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Voulez-vous vraiment supprimer toutes les valeurs de réservoir?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Voulez-vous vraiment effacer toutes vos valeurs de %@?\n(Cette action n'est pas réversible)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Voulez-vous vraiment supprimer ce CGM ?"; +"Are you sure you want to delete this CGM?" = "Voulez-vous vraiment supprimer ce CGM?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Voulez-vous vraiment supprimer ce service?"; /* Format fragment for a specific time */ -"at %@" = "at %@"; +"at %@" = "à %@"; /* The message displayed during a device authentication prompt for bolus specification */ -"Authenticate to Bolus %@ Units" = "Authentifier pour effectuer un Bolus %@ Unités"; +"Authenticate to Bolus %@ Units" = "Authentifiez-vous pour administrer %@ Unités"; + +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Authentifier pour enregistrer %@ unités"; /* Details for configuration error when basal rate schedule is missing */ -"Basal Rate Schedule" = "Horaire de taux basal"; +"Basal Rate Schedule" = "Programme débit basal"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Taux de basale"; +"Basal Rates" = "Débits basaux"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Sur la base de votre glycémie prévue, aucun bolus n’est recommandé."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth désactivé"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth\nIndisponible"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Bluetooth désactivé"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Bluetooth indisponible"; /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Bolus"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Problème avec le bolus"; + /* Alert title for an updated bolus recommendation */ "Bolus Recommendation Updated" = "Recommandation de Bolus modifiée"; +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Résumé du bolus"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus trop petit"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Bolus délivré %1$@ sur %2$@"; @@ -131,18 +278,25 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "Effets des glucides"; -/* Back button text for bolus screen to return to carb entry screen */ +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ "Carb Entry" = "Entrée de glucides"; +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Programme des ratios Insuline-Glucides"; + /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Ratios Glucides"; +"Carb Ratios" = "Ratios Insuline-Glucides"; /* The title of the view controller to create a new carb entry */ "carb-entry-title-add" = "Ajouter des glucides"; /* The title of the view controller to edit an existing carb entry */ -"carb-entry-title-edit" = "Editer les glucides"; +"carb-entry-title-edit" = "Modifier l’entrée des glucides"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Les glucides saisis sont trop important"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Glucides"; @@ -163,16 +317,40 @@ "Check that your pump is in range" = "Vérifier que votre pompe est à portée"; /* Recovery suggestion when glucose data is missing */ -"Check your CGM data source" = "Vérifier votre source de données de SGC"; +"Check your CGM data source" = "Vérifier votre source de données CGM"; + +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Vérifiez l'heure de votre appareil et/ou supprimez toute donnée invalide d'Apple Health."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Choisissez un temps d’absorption plus long pour les gros repas ou ceux contenant des graisses et des protéines. Ceci est seulement un guide pour l'algorithme et n'a pas besoin d'être exact."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Fermer"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Loop Fermé"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Boucle Ouverte"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Loop en boucle fermée requiert une session de capteur CGM active."; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Loop en boucle fermée nécessite une configuration complète"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "à %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "depuis %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; -/* Carb entry section footer text explaining absorption time */ -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Choisissez un temps d'absorption plus long pour les repas plus gros ou ceux contenant des graisses et des protéines. Ceci n'est qu'un guide pour l'algorithme et n'a pas besoin d'être exact."; +/* Title text for button to complete setup */ +"Complete Setup" = "Terminer la configuration"; /* The title of the configuration section in settings */ "Configuration" = "Configuration"; @@ -180,6 +358,9 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Erreur de Configuration: %1$@"; +/* Default alert dismissal */ +"Continue" = "Continuer"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Lecteur de glycémie en continu"; @@ -187,83 +368,202 @@ The title text for the glucose target range schedule */ "Correction Range" = "Plage de correction"; +/* Critical Alerts Status text */ +"Critical Alerts" = "Alertes critiques"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Journal des événements critiques prêt"; + +/* Critical event log export title */ +"Critical Event Logs" = "Journaux des événements critiques"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Les journaux d'événements critiques n'ont pas pu être exportés."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Glycémie actuelle"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Glycémie actuelle de %1$@ est en dessous de la plage."; +"Current glucose of %1$@ is below correction range." = "Glycémie actuelle de %1$@ est en dessous de la plage de correction."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Surcharge personnalisée"; +"Custom Override" = "Ajustement personnalisé"; -/* Button title to delete CGM */ -"Delete CGM" = "Supprimer CGM"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Préréglage personnalisé"; + +/* Date picker label */ +"Date" = "Date"; /* The short unit display string for decibles */ "dB" = "dB"; +/* No comment provided by engineer. */ +"Delete" = "Supprimer"; + /* The title of the button to remove the credentials for a service */ "Delete Account" = "Supprimer le compte"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Token client"; - -/* Title of the carb entry date picker cell */ -"Date" = "Date"; +/* Button title to delete all objects */ +"Delete All" = "Supprimer tout"; /* Button title to delete CGM */ -"Delete CGM" = "Supprimer CGM"; +"Delete CGM" = "Effacer le CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Supprimer le service"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Effacer les données de test du CGM"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Supprimer les données de Test"; -/* The button text to initiate a bolus */ +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Supprimer les données de la Pompe de test"; + +/* Button text to deliver a bolus */ "Deliver" = "Administrer"; /* Title text for delivery limits */ -"Delivery Limits" = "Limites de Administration"; +"Delivery Limits" = "Limites d'Administration"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Traitement du diabète"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Aviez-vous l'intention d'entrer %1$@ grammes comme quantité de glucides pour ce repas ?"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Désactive"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Fermer"; + +/* No comment provided by engineer. */ +"Done" = "Terminé"; + +/* Title for card to log dose */ +"Dose Summary" = "Résumé de la dose"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Stratégie de Dosage"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Activer \nbluetooth"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Active"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Entrez la glycémie à partir d'un mesure manuelle pour le calcul du bolus."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Entrer un Bolus"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Entrez la Glycémie capillaire"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Entrez la limite de sécurité du taux de glucose"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Entrez le seuil de suspension"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Erreur lors de l’annulation du Bolus"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Erreur lors de l'exportation des journaux"; + /* The alert title for a resume error */ "Error Resuming" = "Erreur lors de la reprise"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Historique des événements"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %@" = "Éventuellement %@"; +"Eventually %@" = "Finalement %@"; + +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Dépasse le bolus maximal défini dans les paramètres"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Dépasse le nombre de glucides maximal accepté"; /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Dépasse le bolus maximal"; +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Exporter les journaux d'événements critiques"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Export-%1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Échec de la reprise de l’administration d’insuline"; + /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Glucose capilaire"; + /* The format string used to describe a finite workout targets duration */ -"For %1$@" = "Pour %1$@"; +"For %1$@" = "Pendant %1$@"; + +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Le taux de glucose sanguin prévu pourrait quand-même être plus élevé que la plage cible."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Glycémie prévue"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Obtenir de l'aide avec les autorisations d'alerte"; /* The title of the glucose and prediction graph */ "Glucose" = "Glycémie"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Données de glucose sont vielles de %1$@"; +"Glucose data is %1$@ old" = "Les dernières données de glucose remontent à %1$@"; /* Description of error when glucose data is missing */ "Glucose data not available" = "Les données de glucose ne sont pas disponibles"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Les données de glycémie sont maintenant disponibles"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "La glycémie saisie est hors de la plage."; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Momentum de glucose"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Horaire de la plage cible de glycémie"; + +/* Immediate Delivery status text */ +"Immediate" = "Immédiat"; + /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Indéfiniment"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Dépassement du maximum de la saisie"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Insuline"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insuline absorbée x Facteur de sensibilité à l'insuline (%1$@/U)"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insuline Absorbée (U) × Sensibilité à l'Insuline ( %1$@ /U)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Les ajustements d’insuline ont été désactivés!"; /* The title of the insulin delivery graph */ "Insulin Delivery" = "Administration de l'insuline"; @@ -275,51 +575,201 @@ The title text for the insulin model setting row */ "Insulin Model" = "Modèle d'insuline"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Pompe à insuline"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ "Insulin Sensitivities" = "Facteurs de sensibilité à l'insuline"; +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Horaire de facteur de sensibilité à l'insuline"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insuline suspendue"; + +/* Insulin type label */ +"Insulin Type" = "Type d'insuline"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Interrompu %1$@: %2$@ de %3$@ %4$@"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Quantité de glucides invalide"; + /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Données Incorrectes: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Glycémie future invalide"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Lecture de glucose non valide avec un horodatage situé à %1$@ dans le futur"; + /* The title text for the issue report cell */ -"Issue Report" = "Editer rapport"; +"Issue Report" = "Créer un rapport"; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Grand repas entré"; /* Glucose HUD accessibility hint */ -"Launches CGM app" = "Lance Application CGM"; +"Launches CGM app" = "Lance l'application CGM"; + +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "En savoir plus"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Moins d'une minute restante"; /* The loading message for the diagnostic report screen */ "Loading..." = "Chargement..."; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Enregistrer la dose"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Dose d'insuline enregistrée"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Panne de Loop"; + /* The notification title for a loop failure */ -"Loop Failure" = "Echec Loop"; +"Loop Failure" = "Echec de Loop"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop a détecté un problème avec vos paramètres Bluetooth, et ne fonctionnera pas correctement tant que le Bluetooth ne sera pas activé. Vous ne pourrez pas recevoir de lectures de glucose, ni être en mesure de faire un bolus."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ -"Loop has not completed successfully in %@" = "Loop ne s'est pas complété avec succès depuis %@"; +"Loop has not completed successfully in %@" = "Loop n'a pas bouclé avec succès depuis %@"; + +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop effectue automatiquement des bolus lorsque les besoins en insuline sont supérieurs au débit de base programmé, et utilise des débits de basal temporaires si nécessaire pour réduire l'administration d'insuline en dessous du débit de basal programmé."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop ne fonctionnera pas correctement tant que le Bluetooth ne sera pas activé. Vous ne pourrez pas recevoir de lectures de glucose, ni être en mesure de faire un bolus."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop définira des débits basaux temporaires pour augmenter et diminuer l'administration d'insuline."; -/* Title text for bolus screen following a carb entry */ +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Glycémie basse"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Gérer les permissions dans les paramètres"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Dosage manuel : %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Débit Basal Maximum par heure"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Bolus Maximum"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Bolus Maximum atteint"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Durée maximale dépassée"; + +/* Title for bolus entry screen when also entering carbs */ "Meal Bolus" = "Bolus de repas"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Données manquantes: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Bolus maximal autorisé manquant dans les paramètres"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Effets de momentum"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Plus d'informations"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Enlever le son de toutes les alertes"; + /* Sensor state description for the non-valid state */ -"Needs Attention" = "Attention Requise"; +"Needs Attention" = "Demande votre attention"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Aucune alerte ne retentira pendant la mise en sourdine. Une fois cette période terminée, vos alertes et alarmes reprendront normalement."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Aucun Bolus Recommandé"; /* The error message displayed for device connection errors. */ -"No connected devices, or failure during device connection" = "Pas d'appareil connecté, ou échec durant la connectionà l'appareil"; +"No connected devices, or failure during device connection" = "Pas d'appareil connecté, ou échec durant la connexion à l'appareil"; -/* The title text for the override presets */ -"Override Presets" = "Préréglages de surcharges"; +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Aucun Bolus Maximum configuré"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Pas de pompe configurée"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Pas de Glycémie récente"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Pas de Glycémie récente"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Aucune donnée de pompe récente"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Non, modifier la quantité"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Notification de l'administration"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "L'envoi des notifications est réglé sur \"Résumé programmé\" dans les paramètres de votre téléphone.\n\nPour éviter tout retard dans la réception des notifications de %1$@, nous vous recommandons de régler l'envoi des notifications sur \"Envoi immédiat\"."; + +/* Notifications Status text */ +"Notifications" = "Notifications"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Notifications retardées"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Les notifications vous donnent des informations importantes sur l'application %1$@ sans avoir à l'ouvrir."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Les notifications vous donnent des informations importantes sur l’application %1$@ sans que vous ayez à ouvrir l’application.\n\nGardez-les activées dans les paramètres de votre téléphone pour vous assurer de recevoir Notifications, Alertes critiques et Notifications urgentes de %1$@."; + +/* Notification Setting Status is Off */ +"Off" = "Désactivé"; -/* Alert message for attempting to change basal rates before pump was configured. */ -"Please configure a pump to view or edit scheduled basal rates." = "Veuillez configurer une pompe pour afficher ou modifier les différents débits Basale."; +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Oh non ! La boucle s'est arrêtée pendant le dosage, et les ajustements d'insuline ont été mis en pause jusqu'à ce que ce dialogue soit fermé. L'historique des dosages peut ne pas être exact. Veuillez revoir les tableaux d'administration d'insuline et surveiller attentivement votre glycémie."; -/* Name of pre-meal workout override */ -"Pre-Meal" = "Pré-Repas"; +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Activé"; + +/* The title text for the override presets */ +"Override Presets" = "Préréglages ajustement"; /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Objectif de Pré-Repas"; @@ -327,11 +777,23 @@ /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "Glycémie prévue à %1$@ est %2$@."; +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "La glycémie prévue est dans la plage."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "La glycémie estimée à %1$@ est sous le seuil de suspension."; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Prédiction de la glycémie à %1$@ sous le seuil de suspension défini."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ -"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Prédit: %1$@\nActuel: %2$@ (%3$@)"; +"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Prédit : %1$@\nRéel : %2$@ (%3$@)"; + +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Préparation des journaux d’événements critiques"; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Le profil expire bientôt"; /* The title of the pump section in settings */ "Pump" = "Pompe"; @@ -340,20 +802,32 @@ "Pump Battery Low" = "Batterie de la pompe faible"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ -"Pump data is %1$@ old" = "Données de pompe sont vielles de %1$@"; +"Pump data is %1$@ old" = "Les données de la pompe remontent à %1$@"; + +/* The title of the screen displaying a pump event */ +"Pump Event" = "Événement pompe"; /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Gestionnaire de pompe"; +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Erreur du gestionnaire de pompe : %1$@"; + /* The notification title for an empty pump reservoir */ "Pump Reservoir Empty" = "Réservoir de la pompe vide"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Niveau du réservoir de la pompe bas"; +"Pump Reservoir Low" = "Réservoir de la pompe bas"; /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pompe suspendue"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pompe suspendue. Le dosage automatique est désactivé."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Action rapide - Adulte"; @@ -361,81 +835,263 @@ "Rapid-Acting – Children" = "Action rapide - Enfant"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ -"Recommendation expired: %1$@ old" = "Recommandation expirée: veille de %1$@"; +"Recommendation expired: %1$@ old" = "Recommandation expirée, remonte à %1$@"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Basale Recommendée"; +"Recommended Basal" = "Recommandation basal"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Basal Recommandé"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Le bolus recommandé dépasse le bolus maximal"; /* Accessibility hint describing recommended bolus units */ -"Recommended Bolus: %@ Units" = "Bolus Recommendé: %@ Unités"; +"Recommended Bolus: %@ Units" = "Bolus recommandé: %@ Unités"; + +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Entrée du bolus à distance : %@ U"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Entrée de glucides à distance : %d grammes"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "La commande à distance a expiré."; /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Réservoir"; /* Title of the prediction input effect for retrospective correction */ -"Retrospective Correction" = "Correction Rétrospective"; +"Retrospective Correction" = "Correction rétrospective"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Nouvel essai"; +"Retry" = "Réessayer"; -/* The button text to save a carb entry without bolusing */ +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Enregistrer et Administrer"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ "Save without Bolusing" = "Enregister sans Bolus"; +/* Scheduled Delivery status text */ +"Scheduled" = "Programmé"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Sélectionnez la période de silence"; + /* The title of the services section in settings */ "Services" = "Services"; /* The label of the settings button */ -"Settings" = "Options"; +"Settings" = "Paramètres"; + +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Configuration incomplète"; /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Affiche la dernière erreur de Loop"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Calculateur Simplifié de Bolus"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Calculateur Simplifié de Repas"; + /* Format fragment for a start time */ "since %@" = "depuis %@"; +/* The title of the nightscout site URL credential */ +"Site URL" = "URL du site"; + +/* Software update button link text */ +"Software Update" = "Mise à jour logicielle"; + /* The format for the description of a temporary override start date */ "starting at %@" = "commence à %@"; /* The title of the cell indicating a bolus is being sent */ -"Starting Bolus" = "Commencer un bolus"; +"Starting Bolus" = "Début du bolus"; + +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Support"; /* The title text in settings */ "Suspend Threshold" = "Seuil de suspension"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Appuyez ici pour configurer un CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Appuyez ici pour paramétrer une pompe"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Appuyez ici pour configurer un service"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Ajout"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ -"Tap to Resume" = "Taper pour reprendre"; +"Tap to Resume" = "Appuyez pour reprendre"; + +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Stop"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Enlever le son des alertes temporairement"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "La quantité de bolus saisie est inférieure au minimum délivrable."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "L'algorithme de dosage bolus utilise une estimation plus prudente de la glycémie prévue que celle utilisée pour ajuster votre débit basal. \n\nPar conséquent, votre glycémie prévue après un bolus peut rester supérieure à votre plage cible."; /* Alert message for an updated bolus recommendation */ "The bolus recommendation has updated. Please reconfirm the bolus amount." = "La recommandation du bolus a changé. Veuillez reconfirmer la quantité du bolus"; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Le modèle hérité utilisé par Loop, permettant de personnaliser la durée de l’action."; +"The legacy model used by Loop, allowing customization of action duration." = "Le modèle original utilisé par Loop, permettant de gérer la durée d'action de l'insuline."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Le temps d'absorption maximum est de %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "La quantité maximale autorisée est de %@ grammes"; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "La quantité maximum autorisée est de %@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "La quantité maximum du bolus est de %@ U."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Le bolus maximal est de %@ unités"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Le réglage de bolus maximum doit être configuré avant qu’un bolus puisse être effectué."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "La commande à distance a expiré il y a %.0f minutes."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Réglages Thérapeutique"; + +/* Title of the carb entry date picker cell */ +"Time" = "Heure"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Notifications urgentes"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Réessayer"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Activez le Bluetooth pour recevoir des alertes, alarmes ou les données de capteurs de glycémie."; + /* The short unit display string for international units of insulin */ "U" = "U"; -/* Alert title for unconfigured pump */ -"Unconfigured Pump" = "Pompe non configurée"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Impossible d'effacer l'alerte"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Impossible de contacter la pompe"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Impossible d'enregistrer la saisie des Glucides"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Impossible d’enregistrer la glycémie saisie"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Impossible d'arrêter le bolus en cours. Déplacez votre iPhone plus près de la pompe et réessayez. Vérifiez votre historique de distribution d'insuline pour plus de détails et surveillez votre glycémie de près."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Inconnu"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Erreur inconnue : %1$03d"; /* The format for the description of a temporary override end date */ "until %@" = "jusqu’à %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Jusqu'à l'apport de glucides"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Jusqu'à ce que je désactive"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Utiliser le préréglage Pré-repas"; + /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Utiliser les objectifs d'entraînement"; +"Use Workout Glucose Targets" = "Utiliser les objectifs exercice"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Utiliser le préréglage exercice"; /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Attention! Les notifications de sécurité sont DÉSACTIVÉES"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Lorsque la glycémie actuelle ou prévue est inférieure au seuil de suspension, Loop ne recommandera pas de bolus et recommandera toujours un débit basal temporaire de 0 unité par heure."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Lorsque le glucose actuel ou prévu est inférieur au seuil de suspension, Loop ne recommandera pas de bolus et recommandera toujours un débit basal temporaire de 0 unité par heure."; -/* Name of legacy workout override */ -"Workout" = "Entraînement"; +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "En dehors du mode Boucle fermée, l'application utilise un calcul de bolus simplifié comme pour une pompe classique."; /* The label of the workout mode toggle button */ -"Workout Targets" = "Objectifs d'entraînement"; +"Workout Targets" = "Objectifs exercice"; + +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Le réglage de la température d'entraînement est activé depuis plus de 24 heures. Vérifiez que vous souhaitez toujours l'activer ou désactivez-le dans l'application. Vérifiez que vous souhaitez toujours le garder actif ou désactivez-le dans l'application."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Le préréglage exercice temporaire est encore actif"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Oui"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Il se peut que vous ne receviez pas d'alertes sonores, visuelles ou vibratoires concernant des informations de sécurité critiques. \n\n Pour résoudre le problème, appuyez sur \"Paramètres\" et assurez-vous que les notifications, les alertes critiques et les notifications exigeant une intervention rapide sont activées."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "L'heure de votre %1$@ a été modifiée. %2$@ a besoin d'enregistrements de temps précis pour établir des prédictions sur votre glycémie et ajuster votre insuline en conséquence. \n\nEnregistrez vos paramètres %1$@ (Général / Date et heure) et vérifiez que \"Régler automatiquement\" est activé. L'absence de résolution pourrait entraîner une sous-administration ou une sur-administration grave d'insuline."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Votre glycémie est inférieure à %1$@. Êtes-vous sûr de vouloir administrer un bolus ?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Votre glycémie est en-dessous ou prévue pour aller en dessous de votre limite de sécurité de glycémie, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Votre glycémie est inférieure au seuil de suspension, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Votre glycémie est basse. Mangez des glucides et envisagez d'attendre pour le bolus jusqu'à ce que votre glycémie se situe dans une plage sûre."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Votre glycémie est basse. Mangez des glucides et surveillez de près."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "La quantité maximum de votre bolus est de %1$@ U."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Les données de votre pompe ne pas sont à jour. %1$@ ne peut pas faire de recommandation de bolus."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Votre pompe délivre un débit basal temporaire manuel."; +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Votre bolus recommandé dépasse votre bolus maximum de %1$@."; diff --git a/Loop/fr.lproj/Main.strings b/Loop/fr.lproj/Main.strings index 9b8e5fb2c0..7174e77a0d 100644 --- a/Loop/fr.lproj/Main.strings +++ b/Loop/fr.lproj/Main.strings @@ -1,20 +1,11 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Statut"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3.5 U/h @ 12:12 PM"; - -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "ID de la pompe"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Quantité de bolus"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; +"5gz-kZ-iF1.text" = "3.5 U/heure @ 12:12"; /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Prédit"; @@ -22,107 +13,71 @@ /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ "aCb-Qs-bpu.text" = "Détail"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Étiquette"; - /* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ "ap1-M6-naG.text" = "Type d'aliment"; +/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ +"bIL-Ub-qYp.text" = "Label"; + /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Variation de la glycémie"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Unités"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Étiquette"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g Totaux"; +"d3X-AN-tA5.text" = "g total"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "La glycémie future est prédite en combinant les effets de plusieurs facteurs. Utilisez cet outils pour changer différents facteurs afin d'observer leur impact sur la prédiction finale."; +"D4C-I2-dhA.text" = "Le glucose futur est prédit en combinant les effets de plusieurs entrées. Utilisez cet outil pour basculer entre différentes entrées afin de voir comment elles se comparent à la prédiction finale. Utilisez cet outil pour aller et venir entre les différentes entrées et voir comment elles se comparent à la prédiction finale."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Étiquette"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Paramètres"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "Dispositifs"; +"d6m-qV-wWi.text" = "Label"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "Éventuellement 92 mg/dL"; +"E41-FN-nkk.text" = "finalement 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Observé"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Glucides actifs: 40g"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/heure @ 12:12"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Effets des glucides"; -/* Class = "UILabel"; text = "Label"; ObjectID = "IRb-Yj-AQH"; */ -"IRb-Yj-AQH.text" = "Étiquette"; - /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Les variations observées dans la glycémie, soustrayant les variations modélisées d'administration d'insuline peuvent être utilisées pour estimer l'absoption des glucides."; +"IxU-As-glo.text" = "Les variations observées dans la glycémie, soustrayant les variations modélisées d'administration d'insuline peuvent être utilisées pour estimer l'absorption des glucides."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Détail"; -/* Class = "UILabel"; text = "Detail"; ObjectID = "jQv-xb-gwu"; */ -"jQv-xb-gwu.text" = "Détail"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Glycémie prédite sous plage objectif"; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Basale Recommendée"; +"k3F-Na-7mn.text" = "Recommandation basal"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "Étiquette"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Étiquette"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Appuyez pour définir"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Unités"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; +"Krd-Aa-ret.text" = "Label"; /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "Étiquette"; +"OFA-qT-ZAg.text" = "Label"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Glycémie prédite"; +"PA3-sP-cWY.title" = "Prédiction de glycémie"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Modèle d'insuline"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Un modèle de l'activité de l'insuline est utilisé pour estimer les effets de l'insuline sur le niveau de la glycémie. Un modèle fiable peut aider à empêcher un empillement d'insuline et recommender des traitements correctifs en toute sécurité."; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ "qPH-vU-xlu.text" = "Type d'aliment"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ -"Rse-x8-amW.text" = "Éventuellement 92 mg/dL"; +"Rse-x8-amW.text" = "finalement 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g Active Carbs"; +"SQx-au-ZcM.text" = "g glucides actifs"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ "tuw-av-A3x.text" = "Glycémie"; @@ -131,33 +86,29 @@ "Tz7-80-bJ7.title" = "Ajouter/Modifier Glucides Consommés"; /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Étiquette"; - -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Insuline active: 1.5U"; +"ufi-Kj-33k.text" = "Label"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Glucides"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 heure"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Quantité consommée"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Recommandation basal"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Administrer"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Recommandé"; - -/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ -"Wx8-Tf-FnG.text" = "Quantité consommée"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Titre"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; - diff --git a/Loop/he.lproj/InfoPlist.strings b/Loop/he.lproj/InfoPlist.strings index b422a039c4..a0bb09dadc 100644 --- a/Loop/he.lproj/InfoPlist.strings +++ b/Loop/he.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Loop/he.lproj/LaunchScreen.strings b/Loop/he.lproj/LaunchScreen.strings deleted file mode 100644 index 8b13789179..0000000000 --- a/Loop/he.lproj/LaunchScreen.strings +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Loop/he.lproj/Localizable.strings b/Loop/he.lproj/Localizable.strings index 7020b95773..cb169e9ec8 100644 --- a/Loop/he.lproj/Localizable.strings +++ b/Loop/he.lproj/Localizable.strings @@ -1,6 +1,33 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (pending: %@)"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "-"; + +/* No comment provided by engineer. */ +"– –" = "--"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* The format for an active override preset. (1: preset symbol)(2: preset name) */ +"%@ %@" = "%1$@ %2$@"; + +/* Formats absorbed carb value */ +"%@ absorbed" = "%@ absorbed"; + +/* The subtitle format describing total insulin. (1: localized insulin total) */ +"%@ U Total" = "%@ U Total"; + +/* Appends a full-stop to a statement */ +"%@." = "%@."; + +/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; @@ -19,24 +46,9 @@ /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; -/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; - /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; -/* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%1$@ %2$@"; - -/* Formats absorbed carb value */ -"%@ absorbed" = "%@ absorbed"; - -/* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ U Total"; - -/* Appends a full-stop to a statement */ -"%@." = "%@."; - /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 min glucose regression coefficient (b₁), continued with decay over 30 min"; @@ -49,6 +61,9 @@ /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults."; +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Absorption Time"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AcceptRecommendedBolus"; @@ -58,12 +73,18 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Active Carbohydrates: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Active Carbs"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "Active Insulin"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "Active Insulin: %@"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Add Carb Entry"; + /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "Add CGM"; @@ -75,23 +96,14 @@ Title text for button to set up a new pump */ "Add Pump" = "Add Pump"; -/* The title of the Amplitude service */ -"Amplitude" = "Amplitude"; - /* Title text for button to set up a service */ "Add Service" = "Add Service"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; - -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; - /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Algorithm Settings"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "An adjustment to the adult model based on empirical effects in children."; +/* The title of the Amplitude service */ +"Amplitude" = "Amplitude"; /* The title of the amplitude API key credential */ "API Key" = "API Key"; @@ -99,9 +111,18 @@ /* The title of the nightscout API secret credential */ "API Secret" = "API Secret"; +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Are you sure you want to delete all history entries?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Are you sure you want to delete all reservoir values?"; + /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Are you sure you want to delete this CGM?"; +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; + /* Format fragment for a specific time */ "at %@" = "at %@"; @@ -138,6 +159,12 @@ The title text for the carb ratio schedule */ "Carb Ratios" = "Carb Ratios"; +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Add Carb Entry"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Edit Carb Entry"; + /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Carbohydrates"; @@ -159,9 +186,18 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Check your CGM data source"; +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact."; + /* The title text for the looping enabled switch cell */ "Closed Loop" = "Closed Loop"; +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "at %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "since %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; @@ -171,6 +207,9 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Configuration Error: %1$@"; +/* Default alert dismissal */ +"Continue" = "Continue"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Continuous Glucose Monitor"; @@ -184,11 +223,8 @@ /* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "Custom Override"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; - -/* Button title to delete CGM */ -"Delete CGM" = "Delete CGM"; +/* Date picker label */ +"Date" = "Date"; /* The short unit display string for decibles */ "dB" = "dB"; @@ -196,12 +232,25 @@ /* The title of the button to remove the credentials for a service */ "Delete Account" = "Delete Account"; +/* Button title to delete all objects */ +"Delete All" = "Delete All"; + +/* Button title to delete CGM */ +"Delete CGM" = "Delete CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Delete Service"; + /* Title text for delivery limits */ "Delivery Limits" = "Delivery Limits"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Disables"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Dismiss"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Enables"; @@ -214,6 +263,9 @@ /* The alert title for a resume error */ "Error Resuming" = "Error Resuming"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Event History"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Eventually %@"; @@ -226,6 +278,9 @@ /* The format string used to describe a finite workout targets duration */ "For %1$@" = "For %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glucose"; @@ -279,21 +334,47 @@ /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop has not completed successfully in %@"; +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maximum Bolus"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Missing data: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Momentum effects"; -/* The title of the Nightscout service */ -"Nightscout" = "Nightscout"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "More Info"; /* Sensor state description for the non-valid state */ "Needs Attention" = "Needs Attention"; +/* The title of the Nightscout service */ +"Nightscout" = "נייטסקאוט"; + /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "No connected devices, or failure during device connection"; +/* Notification Setting Status is Off */ +"Off" = "כבוי"; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "דולק"; + /* The title text for the override presets */ "Override Presets" = "Override Presets"; @@ -318,6 +399,9 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Pump data is %1$@ old"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pump Event"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Pump Manager"; @@ -330,6 +414,9 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pump Suspended"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Rapid-Acting – Adults"; @@ -367,7 +454,7 @@ "since %@" = "since %@"; /* The title of the nightscout site URL credential */ -"Site URL" = "Site URL"; +"Site URL" = "כתובת האתר"; /* The format for the description of a temporary override start date */ "starting at %@" = "starting at %@"; @@ -384,12 +471,22 @@ /* Subtitle description of Walsh insulin model setting */ "The legacy model used by Loop, allowing customization of action duration." = "The legacy model used by Loop, allowing customization of action duration."; +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "The maximum absorption time is %@"; + /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "The maximum bolus amount is %@ Units"; +/* Title of the carb entry date picker cell */ +"Time" = "שעה"; + /* The short unit display string for international units of insulin */ "U" = "U"; +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Unknown"; + /* The format for the description of a temporary override end date */ "until %@" = "until %@"; @@ -405,3 +502,6 @@ /* The label of the workout mode toggle button */ "Workout Targets" = "Workout Targets"; +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "כן"; + diff --git a/Loop/he.lproj/Main.strings b/Loop/he.lproj/Main.strings index 4070b6d595..0edbc953a5 100644 --- a/Loop/he.lproj/Main.strings +++ b/Loop/he.lproj/Main.strings @@ -1,4 +1,3 @@ - /* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ "0RV-d5-muE.text" = "g"; @@ -11,9 +10,27 @@ /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Predicted"; +/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ +"aCb-Qs-bpu.text" = "Detail"; + +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Food Type"; + +/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ +"bIL-Ub-qYp.text" = "Label"; + +/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ +"bq4-98-cQU.text" = "Glucose Change"; + +/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ +"d3X-AN-tA5.text" = "g Total"; + /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ "D4C-I2-dhA.text" = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; +/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ +"d6m-qV-wWi.text" = "Label"; + /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "eventually 92 mg/dL"; @@ -23,12 +40,21 @@ /* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ "Fal-Vf-lfh.normalTitle" = "🍭"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/hour @ 12:12 PM"; + +/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ +"hZZ-2S-lrd.title" = "Carbohydrate Effects"; + /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ "IxU-As-glo.text" = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Detail"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ +"k3F-Na-7mn.text" = "Recommended Basal"; + /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Label"; @@ -44,66 +70,39 @@ /* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ "QhO-Yi-AqQ.normalTitle" = "🌮"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Food Type"; + /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "eventually 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ "SQx-au-ZcM.text" = "g Active Carbs"; +/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ +"tuw-av-A3x.text" = "Glucose"; + /* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ "Tz7-80-bJ7.title" = "Add/Edit Carb Entry"; +/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ +"ufi-Kj-33k.text" = "Label"; + /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Carbohydrates"; /* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ "Wx8-Tf-FnG.text" = "Amount Consumed"; -/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ -"Yf6-fw-Gex.placeholder" = "0"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detail"; - -/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ -"ap1-M6-naG.text" = "Food Type"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Label"; - -/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Glucose Change"; - -/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g Total"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Label"; - -/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ -"fWV-jg-ICt.text" = "3.5 U/hour @ 12:12 PM"; - -/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Carbohydrate Effects"; - -/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Recommended Basal"; - -/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ -"qPH-vU-xlu.text" = "Food Type"; - -/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glucose"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Label"; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ "xhx-PI-bBI.text" = "Recommended Basal"; /* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ "xl9-Wc-Pdu.normalTitle" = "🍕"; +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; + /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; @@ -112,3 +111,4 @@ /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; + diff --git a/Loop/hi.lproj/Localizable.strings b/Loop/hi.lproj/Localizable.strings new file mode 100644 index 0000000000..e503ab1e05 --- /dev/null +++ b/Loop/hi.lproj/Localizable.strings @@ -0,0 +1,18 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "एपीआई पास्वर्ड"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "निरस्त"; + +/* Default alert dismissal */ +"Continue" = "जारी"; + +/* The title of the glucose and prediction graph */ +"Glucose" = "शुगर"; + +/* Title of the carb entry date picker cell */ +"Time" = "समय"; + diff --git a/Loop/hi.lproj/Main.strings b/Loop/hi.lproj/Main.strings new file mode 100644 index 0000000000..82a5ef7956 --- /dev/null +++ b/Loop/hi.lproj/Main.strings @@ -0,0 +1,3 @@ +/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ +"tuw-av-A3x.text" = "शुगर"; + diff --git a/Loop/it.lproj/InfoPlist.strings b/Loop/it.lproj/InfoPlist.strings index 632467a645..9e861d4c3a 100644 --- a/Loop/it.lproj/InfoPlist.strings +++ b/Loop/it.lproj/InfoPlist.strings @@ -1,11 +1,17 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Il Bluetooth viene utilizzato per comunicare con il microinfusore e i dispositivi CGM."; +"NSBluetoothAlwaysUsageDescription" = "Il Bluetooth è utilizzato per comunicare con il microinfusore ed il sensore glicemico"; /* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Il Bluetooth viene utilizzato per comunicare con il microinfusore e i dispositivi CGM."; +"NSBluetoothPeripheralUsageDescription" = "Il Bluetooth è utilizzato per comunicare con il microinfusore ed il sensore glicemico"; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "La fotocamera è utilizzata per scansionare i codici a barre dei tuoi dispositivi."; /* Privacy - Face ID Usage Description */ "NSFaceIDUsageDescription" = "Face ID viene utilizzato per autenticare il bolo."; @@ -14,5 +20,8 @@ "NSHealthShareUsageDescription" = "I dati sui pasti dal database Salute vengono utilizzati per determinare gli effetti del glucosio. I dati del glucosio del database Salute vengono utilizzati per il calcolo del grafico della glicemia."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "I dati sui carboidrati inseriti nell'app e sull'orologio sono memorizzati nel database Salute. I dati relativi al glucosio recuperati dal CGM vengono memorizzati in modo sicuro in Salute."; +"NSHealthUpdateUsageDescription" = "I dati sui carboidrati dei pasti inseriti nell'app e sull'orologio sono trasferiti nel database di Salute. I dati recuperati dal sensore CGM sono storati nel database di HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop utilizza Siri per permettere l'attivazione delle preimpostazioni con la tua voce"; diff --git a/Loop/it.lproj/Localizable.strings b/Loop/it.lproj/Localizable.strings index ba89538ca9..633dfbfa13 100644 --- a/Loop/it.lproj/Localizable.strings +++ b/Loop/it.lproj/Localizable.strings @@ -1,11 +1,35 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (prevista l'erogazione di: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = "Preimpostazioni del Pre-Pasto"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = "Le notifiche di sicurezza risultano spente"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = "Preimpostazione modalità allenamento"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ -"%@ absorbed" = "%@ assorbiti"; +"%@ absorbed" = "%@ assorbito"; + +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ rimanente"; /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ U Totali"; @@ -13,221 +37,524 @@ /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@%2$@ non sono stati in grado di cancellare la tua attuale basale temporanea, che è più elevata di quella impostata come nuovo limite massimo di basale. Questo potrebbe comportare una maggiore infusione d'insulina di quanto desiderato. \n\nConsidera di sospendere manualmente l'erogazione d'insulina e quindi di riattivarla immediatamente per attivare l'erogazione d'insulina basale con il corretto limite impostato."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ -"%1$@ %2$@/U" = "%1$@ %2$@/U"; +"%1$@ %2$@/U" = "%1$@ %2$@ /U"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ sta funzionando in modalità Loop chiuso spento. Il tuo microinfusore e il tuo sensore continueranno a funzionare, ma l'applicazione non regolerà la somministrazione d'insulina automaticamente."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ non può cancellare l'allarme dal tuo dispositivo"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ è impossibilitato a comunicare con il tuo microinfusore. L'applicazione continuerà a cercare di contattare il microinfusore, ma le informazioni sulla somministrazione di insulina non potranno essere aggiornate e nessuna automazione può essere continuata. Puoi aspettare alcuni minuti per vedere se il problema si risolve oppure premere il bottone qui sotto per conoscere le varie opzioni."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ le impostazioni dell'orario necessitano una revisione"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ U"; + /* Low reservoir alert format string. (1: Number of units remaining) */ -"%1$@ U left" = "%1$@ U residue"; +"%1$@ U left" = "%1$@ U sinistra"; /* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ -"%1$@ U left: %2$@" = "%1$@ U residue: %2$@"; +"%1$@ U left: %2$@" = "%1$@ U sinistra: %2$@"; /* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ "%1$@ U/hour @ %2$@" = "%1$@ U/ora @ %2$@"; /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ -"%1$@ v%2$@" = "%1$@ v%2$@"; +"%1$@ v%2$@" = "%1$@ contro %2$@"; + +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ smetterà di funzionare in %2$@. Dovrai aggiornare prima di tale data con un nuovo provisioning profile."; /* Formats (1: carb value) and (2: food type) */ -"%1$@: %2$@" = "%1$@: %2$@"; +"%1$@: %2$@" = "%1$@ : %2$@"; + +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@ : %2$@ %3$@"; /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "Coefficiente di regressione del glucosio a 15 min (b₁), interpolato con il decadimento a 30 min."; /* Description of the prediction input effect for retrospective correction */ -"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "Confronto della previsione della glicemia a 30 min vs reale, interpolato con il decadimento sino a 60 min."; +"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min di confronto tra la previsione glicemica e quella attuale, proseguita con il degrado sino a 60 minuti"; + +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Pochi secondi rimanenti"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Una glicemia manuale deve essere inserita tra %1$@ e %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Una glicemia manuale deve essere inserita tra %1$@ e %2$@"; /* Subtitle of Fiasp preset */ -"A model based on the published absorption of Fiasp insulin." = "Modello basato sull'assorbimento dell'insulina Fiasp."; +"A model based on the published absorption of Fiasp insulin." = "Modello basato sull'assorbimento dichiarato dell'insulina Fiasp"; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Modello basato sull'assorbimento negli adulti dell'insulina Humalog, Novolog ed Apidra."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Modello basato sull'assorbimento dichiarato dell'insulina Humalog, Novolog e Apidra negli adulti"; + +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "Una nuova versione di %@ è disponibile ed è raccomandato di continuare a utilizzare l'app."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "È disponibile una nuova versione di %@ ."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Prima di poter erogare un bolo, è necessario configurare un microinfusore."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Tempo di assorbimento"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ -"AcceptRecommendedBolus" = "AccettaBoloConsigliato"; +"AcceptRecommendedBolus" = "AcceptRecommendedBolus"; /* The title of the Carbs On-Board graph */ -"Active Carbohydrates" = "Carboidrati Attivi"; +"Active Carbohydrates" = "Carboidrati attivi"; /* The string format describing active carbohydrates. (1: localized glucose value description) */ -"Active Carbohydrates: %@" = "Carboidrati Attivi: %@"; +"Active Carbohydrates: %@" = "Carboidrati attivi: %@"; + +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Carb Attivi"; /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Insulina Attiva"; +"Active Insulin" = "Insulina attiva"; /* The string format describing active insulin. (1: localized insulin value description) */ -"Active Insulin: %@" = "Insulina Attiva: %@"; +"Active Insulin: %@" = "Insulina attiva: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Aggiungi carboidrati assunti"; +"Add Carb Entry" = "Agg. Carb. Assunti"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "Aggiungi CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Aggiungi Pasto"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ -"Add Pump" = "Aggiungi Microinfusore"; +"Add Pump" = "Aggiungi MICRO"; /* Title text for button to set up a service */ -"Add Service" = "Add Service"; +"Add Service" = "Aggiungi Servizio"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* No comment provided by engineer. */ +"Adjusted for" = "Corretto per"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Gestione Avvisi"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Avvisi"; /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Impostazioni Algoritmo"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Un adattamento al modello adulto basato su effetti empirici nei bambini."; +/* The title of the Amplitude service */ +"Amplitude" = "Amplitude"; + +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Un programma alternativo sta modificando il tuo rapporto insulina carboidrato e la tua sensibilità all'insulina. Se non vuoi che questo influisca sul calcolo del tuo bolo e sulla glicemia predetta, considera di cancellare il programma alternativo."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Si è verificato un errore durante il tentativo di salvare l'inserimento dei carboidrati."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Si è verificato un errore durante il tentativo di salvare l'inserimento manuale della Glicemia."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Si è verificato un errore nell'inserimento"; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "È disponibile una raccomandazione aggiornata sul bolo."; + +/* The title of the amplitude API key credential */ +"API Key" = "Chiave API"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "Chiave personale API"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Sei sicuro di voler eliminare tutte le voci della cronologia?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Sei sicuro di voler eliminare tutte le dosi inserite?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Sei sicuro di voler eliminare tutti i valori del serbatoio?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Sei sicuro di voler eliminare tutti i tuoi dati %@ ?\n (Questa azione non è reversibile)"; /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Sei sicuro di voler eliminare questo CGM?"; +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Sei sicuro di voler eliminare questo servizio?"; + /* Format fragment for a specific time */ "at %@" = "a %@"; /* The message displayed during a device authentication prompt for bolus specification */ -"Authenticate to Bolus %@ Units" = "Autenticati per eseguire il bolo di %@ Unità"; +"Authenticate to Bolus %@ Units" = "Eseguire l'autenticazione per il bolo di %@ Unità"; + +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Eseguire l'autenticazione per registrare %@ Unità"; /* Details for configuration error when basal rate schedule is missing */ -"Basal Rate Schedule" = "Impostazione valori della basale"; +"Basal Rate Schedule" = "Impostazione Velocità Basale"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Impostazione Basale"; +"Basal Rates" = "Velocità basali"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "In base alla glicemia prevista, non è consigliato alcun bolo."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth\n Spento"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth\n Non disponibile"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Avviso Bluetooth disattivato"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Avviso Bluetooth non disponibile"; /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Bolo"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Problema con il bolo"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Raccomandazioni sul bolo aggiornate"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Riepilogo Boli"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolo troppo piccolo"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ -"Bolused %1$@ of %2$@" = "%1$@ somministrato in bolo su %2$@"; +"Bolused %1$@ of %2$@" = "Bolo %1$@ di %2$@"; /* The format string for bolus in progress showing total volume. (1: total volume) */ -"Bolusing %1$@" = "Somministrazione in bolo di %1$@ in corso"; +"Bolusing %1$@" = "Bolo in corso %1$@"; /* The title of the cancel action in an action sheet */ -"Cancel" = "Cancella"; +"Cancel" = "Annulla"; /* The title of the cell indicating a bolus is being canceled */ -"Canceling Bolus" = "Annullamento bolo in corso"; +"Canceling Bolus" = "Annullamento bolo"; /* Details for missing data error when carb effects are missing */ -"Carb effects" = "Effetto dei carboidrati"; +"Carb effects" = "Effetto carboidrati"; + +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Carboidrati Assunti"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Programma Rapporto Carboidrati"; /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Rapp. Carb:Insulina"; +"Carb Ratios" = "Rapporti carboidrati"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Agg. Carb. Assunti"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Mod. Carb Assunti"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Le voci dei Carboidrati inseriti sono troppo grandi"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Carboidrati"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Carboidrati Assorbiti (g) ÷ Rapporto carboidrati/insulina (g/U) × Sensibilità Insulinica (%1$@/U)"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Carboidrati Assorbiti ÷ Rapporto Carboidrati (gr/U) × Sensibilità Insulinica (%1$@/U)"; /* The notification alert describing a low pump battery */ "Change the pump battery immediately" = "Cambiare immediatamente la batteria del microinfusore"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Cambiare il serbatoio del microinfusore"; +"Change the pump reservoir now" = "Cambiare subito il serbatoio del microinfusore"; /* Details for configuration error when one or more loop settings are missing */ -"Check settings" = "Controlla le impostazioni"; +"Check settings" = "Controllare le impostazioni"; /* Recovery suggestion when reservoir data is missing */ -"Check that your pump is in range" = "Controlla che il tuo microinfusore sia nei paraggi"; +"Check that your pump is in range" = "Controlllare che il microinfusore si trovi vicino"; /* Recovery suggestion when glucose data is missing */ -"Check your CGM data source" = "Controlla la sorgente CGM"; +"Check your CGM data source" = "Controllare la sorgente dati del sensore"; + +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Controlla l'ora del tuo dispositivo e/o rimuovi eventuali dati non validi da Apple Salute."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Scegli un tempo di assorbimento piu lungo per i pasti piu grandi o quelli contenenti grassi e proteine. Questa e solo una guida all’algoritmo e non e necessario che sia esatta."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Chiudi"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Loop Chiuso"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Circuito chiuso OFF"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Loop chiuso richiede almeno una sessione attiva del sensore CGM"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Loop Chiuso richiede che la sua configurazione sia completa"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "a %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "in %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +/* Title text for button to complete setup */ +"Complete Setup" = "Configurazione completata"; + /* The title of the configuration section in settings */ "Configuration" = "Configurazione"; /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Errore di configurazione: %1$@"; +/* Default alert dismissal */ +"Continue" = "Continua"; + /* The title of the continuous glucose monitor section in settings */ -"Continuous Glucose Monitor" = "CGM: Monitoraggio Continuo Glicemia"; +"Continuous Glucose Monitor" = "CGM:\nMonitoraggio Continuo Glicemia"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ "Correction Range" = "Intervallo Glicemico"; +/* Critical Alerts Status text */ +"Critical Alerts" = "Avvisi critici"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Registro eventi Critici pronto"; + +/* Critical event log export title */ +"Critical Event Logs" = "Registro eventi Critici"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Non è stato possibile esportare i registri degli eventi critici."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Glicemia Attuale"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "L'attuale valore glicemico di %1$@ e' inferiore al valore inferiore del target glicemico."; +"Current glucose of %1$@ is below correction range." = "La glicemia attuale di %1$@ è al di sotto dell'intervallo glicemico selezionato."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Regolazione manuale personalizzata"; +"Custom Override" = "Progr. Alternativo"; -/* Button title to delete CGM */ -"Delete CGM" = "Elimina CGM"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Programmazione"; + +/* Date picker label */ +"Date" = "Data"; /* The short unit display string for decibles */ "dB" = "dB"; +/* No comment provided by engineer. */ +"Delete" = "Cancella"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Cancella Account"; + +/* Button title to delete all objects */ +"Delete All" = "Cancella tutto"; + +/* Button title to delete CGM */ +"Delete CGM" = "Elimina CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Elimina Servizio"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Elimina dati test CGM"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Cancella i dati test"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Cancella i dati test del microinfusore"; + +/* Button text to deliver a bolus */ +"Deliver" = "Somministra"; + /* Title text for delivery limits */ "Delivery Limits" = "Limiti Erogazione"; +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Trattamento del diabete"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Intendevi inserire %1$@ grammi come quantità di carboidrati per questo pasto?"; + /* The action hint of the workout mode toggle button when enabled */ -"Disables" = "Disabilitato"; +"Disables" = "Disabilita"; + +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "OK"; + +/* No comment provided by engineer. */ +"Done" = "Fine"; + +/* Title for card to log dose */ +"Dose Summary" = "Riassunto della dose"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Strategia di dosaggio"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Abilita\n Bluetooth"; /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Abilita"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Inserisci una glicemia da glucometro per una quantità di bolo consigliata."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Invio Bolo"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Glicemia da dito"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Inserisci limite di sicurezza"; + /* The placeholder text instructing users to enter a suspend treshold */ -"Enter suspend threshold" = "Inserisci il valore minimo sotto al quale l'erogazione e' sospesa"; +"Enter suspend threshold" = "Inserisci soglia di sospensione"; /* The alert title for an error while canceling a bolus */ -"Error Canceling Bolus" = "Errore durante l’annullamento del bolo"; +"Error Canceling Bolus" = "Errore durante l'Annullamento del Bolo"; + +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Errore durante l'esportazione dei registri"; /* The alert title for a resume error */ -"Error Resuming" = "Errore durante la ripresa"; +"Error Resuming" = "Errore durante la Ripresa"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Storia degli Eventi"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Probabile Glic. %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Supera il bolo massimo consentito nelle impostazioni"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Supera i carboidrati massimi consentiti"; + /* The title of the alert describing a maximum bolus validation error */ -"Exceeds Maximum Bolus" = "Valore superiore al Bolo Massimo"; +"Exceeds Maximum Bolus" = "Supera Bolo Massimo"; + +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Esporta registri eventi critici"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Esporta- %1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Impossibile riprendere l'erogazione dell'insulina"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Glicemia da dito"; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Per %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "La glicemia prevista potrebbe essere più elevata di quella impostata come obiettivo."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Glicemia prevista"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Ottieni assistenza per le autorizzazioni"; + /* The title of the glucose and prediction graph */ -"Glucose" = "Glicemie"; +"Glucose" = "Glicemia"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "L'ultimo valore glicemico e' di %1$@ fa"; +"Glucose data is %1$@ old" = "I dati sulla glicemia sono %1$@ vecchi"; /* Description of error when glucose data is missing */ -"Glucose data not available" = "I dati sulla glicemia non sono disponibili"; +"Glucose data not available" = "I dati sulla glicemia non disponibili"; + +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Dati Glicemie ora disponibili"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Glicemia inserita fuori dall'intervallo"; /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Effetto Glicemico"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Programma degli intervalli degli obiettivi glicemici"; + +/* Immediate Delivery status text */ +"Immediate" = "Immediato"; + /* The title of a target alert action specifying an indefinitely long workout targets duration */ -"Indefinitely" = "Per sempre"; +"Indefinitely" = "A tempo indeterminato"; + +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Superato il numero massimo di input"; /* Title of the prediction input effect for insulin */ "Insulin" = "Insulina"; @@ -235,6 +562,9 @@ /* Description of the prediction input effect for insulin */ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Assorbimento Insulinico (U) × Sensibilità Insulinica (%1$@/U)"; +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Le regolazioni dell'insulina sono state disabilitate!"; + /* The title of the insulin delivery graph */ "Insulin Delivery" = "Insulina Somministrata"; @@ -245,67 +575,244 @@ The title text for the insulin model setting row */ "Insulin Model" = "Modello di azione dell'Insulina"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Microinfusore"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ "Insulin Sensitivities" = "Sensibilità Insulinica"; +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Programma di sensibilità all'insulina"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Erogazione Insulina sospesa"; + +/* Insulin type label */ +"Insulin Type" = "Tipo d'insulina"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Interrotto %1$@ : %2$@ di %3$@ %4$@"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Quantità di carboidrati non valida"; + /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Dati non validi: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Glucosio futuro non valido"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Lettura del glucosio non valida con data e ora %1$@ nel futuro"; + /* The title text for the issue report cell */ -"Issue Report" = "Segnalazione"; +"Issue Report" = "Report dei problemi"; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Pasto abbondante inserito"; /* Glucose HUD accessibility hint */ -"Launches CGM app" = "Avvia CGM app"; +"Launches CGM app" = "Avvia l'app CGM"; + +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Ulteriori informazioni"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Manca meno di un minuto"; /* The loading message for the diagnostic report screen */ -"Loading..." = "Carica..."; +"Loading..." = "Caricamento..."; + +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Registra la dose"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Dose d'insulina registrata"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop si è bloccato"; /* The notification title for a loop failure */ -"Loop Failure" = "Loop Fallito"; +"Loop Failure" = "Malfunzionamento di Loop"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop ha rilevato un problema con le tue impostazioni Bluetooth e non funzionerà correttamente finché il Bluetooth non sarà abilitato. Non riceverai letture glicemiche né potrai eseguire il bolo."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ -"Loop has not completed successfully in %@" = "Loop non completato con successo da %@"; +"Loop has not completed successfully in %@" = "Loop non ha funzionato correttamente per %@"; + +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop eseguirà automaticamente il bolo quando il fabbisogno d'insulina è superiore alla basale programmata e utilizzerà velocità basali temporanee quando necessario per ridurre l'erogazione d'insulina al di sotto della basale programmata."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop non funzionerà correttamente fino a quando il Bluetooth non sarà abilitato. Non riceverai letture glicemiche né potrai eseguire il bolo."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop imposterà velocità basali temporanee per aumentare e diminuire l'erogazione d'insulina."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Glucosio basso"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Gestisci le autorizzazioni in Impostazioni"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Dose manuale: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Velocità Basale Massima all'ora"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Bolo Massimo"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Bolo Massimo Superato"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Durata massima superata"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Bolo pasto"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Dati mancanti: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Manca il bolo massimo consentito nelle impostazioni"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Effetto glicemico attuale"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Piu info"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Disattiva tutti gli avvisi"; + /* Sensor state description for the non-valid state */ -"Needs Attention" = "Fai Attenzione"; +"Needs Attention" = "Esige Attenzione"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Nessun avviso suonerà mentre è disattivato. Al termine di questo periodo, gli avvisi e gli allarmi riprenderanno normalmente."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Nessun bolo consigliato"; /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Nessun dispositivo connesso o mancanza di segnale durante la connessione del dispositivo"; +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Nessun bolo massimo configurato"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Nessun Microinfusore configurato"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "No Glicemia Recente"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Nessun Dato Recente Glicemia"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Nessun dato recente sul Microinfusore"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "No, modifica l'importo"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Notifiche erogazione"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "L'invio delle notifiche è impostato su Riepilogo pianificato nelle impostazioni del telefono. \n\n Per evitare ritardi nella ricezione delle notifiche da %1$@ , ti consigliamo di impostare la consegna delle notifiche su Consegna immediata."; + +/* Notifications Status text */ +"Notifications" = "Notifiche"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Notifiche ritardate"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Le notifiche ti forniscono informazioni importanti sull'app %1$@ senza che tu debba aprire l'app."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Le notifiche ti forniscono informazioni importanti sull'app %1$@ senza che tu debba aprire l'app. \n\n Tienili attivati nelle impostazioni del tuo telefono per assicurarti di ricevere %1$@ Notifiche, Avvisi critici e Notifiche urgenti."; + +/* Notification Setting Status is Off */ +"Off" = "Spento"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Oh No! Loop si è chiuso mentre stava eseguendo un bolo e il dosaggio di insulina è stato messo in pausa, finchè la finestra sarà chiusa. L'elenco dell'infusione d'insulina potrebbe non essere accurato. Per favore rivedi con attenzione la tabella di infusione dell'insulina e sorveglia strettamente la tua glicemia"; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Acceso"; + /* The title text for the override presets */ -"Override Presets" = "Impostazioni predefinite regolazione manuale"; +"Override Presets" = "Programma Alternativo"; /* The label of the pre-meal mode toggle button */ -"Pre-Meal Targets" = "Obiettivo pre-pasto"; +"Pre-Meal Targets" = "Obiettivo Pre-Pasto"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "La glicemia prevista tra %1$@ e' di %2$@."; +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "La glicemia prevista è nell'intervallo"; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "La glicemia prevista da %1$@ è al di sotto del tuo limite glicemico di sicurezza"; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "La glicemia prevista %1$@ e' inferiore al valore soglia per la sospensione dell'erogazione."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Previsto: %1$@\nEffettivo: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Lista degli eventi critici in preparazione"; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Il profilo scadra' presto"; + /* The title of the pump section in settings */ "Pump" = "Microinfusore"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Batteria Microinfusore e' quasi esaurita"; +"Pump Battery Low" = "Batteria Microinfusore bassa"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "I dati forniti dal microinfusore sono di %1$@ fa"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Evento Microinfusore"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Gestione Microinfusore"; +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Errore gestione microinfusore:%1$@"; + /* The notification title for an empty pump reservoir */ "Pump Reservoir Empty" = "Serbatoio microinfusore Vuoto"; @@ -313,7 +820,13 @@ "Pump Reservoir Low" = "Serbatoio microinfusore Basso"; /* The title of the cell indicating the pump is suspended */ -"Pump Suspended" = "Microinfusore sospesa"; +"Pump Suspended" = "Microinfusore sospeso"; + +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Microinfusore Sospeso. Il dosagio autoamtico e' disattivato"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Insulina ultrarapida – Adulti"; @@ -322,22 +835,51 @@ "Rapid-Acting – Children" = "Insulina ultrarapida – Bambini"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ -"Recommendation expired: %1$@ old" = "La dose raccomandata e' scaduta da %1$@"; +"Recommendation expired: %1$@ old" = "La raccomandazione è scaduta: %1$@ fa"; /* The title of the cell displaying a recommended temp basal value */ "Recommended Basal" = "Basale Raccomandata"; +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Bolo Raccomandato"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Il Bolo Raccomandato supera la quantità del Bolo Massimo."; + /* Accessibility hint describing recommended bolus units */ -"Recommended Bolus: %@ Units" = "Bolo Consigliato: %@ Unità"; +"Recommended Bolus: %@ Units" = "Bolo Raccomandato: %@ Unità"; + +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Inserimento di Bolo Remoto:%@ Unita'"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Inserimento remoto di carboidrati: %d grammi"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Il comando remoto è scaduto."; /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Serbatoio"; /* Title of the prediction input effect for retrospective correction */ -"Retrospective Correction" = "Correzione Retrospettiva"; +"Retrospective Correction" = "Correzione retrospettiva"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Riprovare"; +"Retry" = "Riprova"; + +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Salva e Invia"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Salva senza bolo"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Programmato"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Scegliere il periodo muto"; /* The title of the services section in settings */ "Services" = "Servizi"; @@ -345,45 +887,211 @@ /* The label of the settings button */ "Settings" = "Impostazioni"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Impostazione Incompleta"; + /* Loop Completion HUD accessibility hint */ -"Shows last loop error" = "Mostra ultimo errore di Loop"; +"Shows last loop error" = "Mostra l'ultimo errore di Loop"; + +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Calcolatore bolo semplice"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Calcolatore pasto semplice"; /* Format fragment for a start time */ "since %@" = "da %@"; +/* The title of the nightscout site URL credential */ +"Site URL" = "Sito URL"; + +/* Software update button link text */ +"Software Update" = "Aggiornamento software"; + /* The format for the description of a temporary override start date */ -"starting at %@" = "a partire da %@"; +"starting at %@" = "inizia a %@"; /* The title of the cell indicating a bolus is being sent */ -"Starting Bolus" = "Invio Bolo"; +"Starting Bolus" = "Avvio Bolo"; + +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Supporto"; /* The title text in settings */ -"Suspend Threshold" = "Blocco Erogazione"; +"Suspend Threshold" = "Sospendi Soglia"; + +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Premi per impostare un CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Premi per impostare un Microinfusore "; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Premi per configurare un servizio"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Aggiungi"; /* The subtitle of the cell displaying an action to resume insulin delivery */ -"Tap to Resume" = "Premi per riprendere"; +"Tap to Resume" = "Riprendi"; + +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Interrompi"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Disattiva gli avvisi"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "La quantità di bolo immessa è inferiore alla quantità minima erogabile."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "L'algoritmo di dosaggio del bolo utilizza una stima più conservativa della glicemia prevista rispetto a quella utilizzata per regolare la velocità basale.\n\nDi conseguenza, la glicemia prevista dopo un bolo potrebbe essere superiore all'intervallo obiettivo."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "La raccomandazione del bolo è stata aggiornata. Si prega di riconfermare la quantità di bolo."; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "ll modello legacy utilizzato da Loop, che consente la personalizzazione della durata dell'azione."; +"The legacy model used by Loop, allowing customization of action duration." = "ll modello antecedente usato da Loop, che consente la personalizzazione della durata dell'azione."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Il tempo di assorbimento massimo e %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "La quantità massima consentita è %@ grammi."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "L'importo massimo consentito è %1$@ ."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "L'importo massimo del bolo è %@ U."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ -"The maximum bolus amount is %@ Units" = "Il massimo bolo eseguibile e' pari a %@ Unità"; +"The maximum bolus amount is %@ Units" = "Il Bolo Massimo è %@ Unità"; + +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "L'impostazione del bolo massimo deve essere configurata prima di poter erogare un bolo."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Il comando remoto è scaduto %.0f minuti fa."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Impostazioni Terapia"; + +/* Title of the carb entry date picker cell */ +"Time" = "Tempo"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Notifiche a tempo"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Riprova"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Attiva il Bluetooth per ricevere avvisi, allarmi o letture glicemiche del sensore."; /* The short unit display string for international units of insulin */ "U" = "U"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Impossibile cancellare l'avviso"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Impossibile raggiungere il microinfusore"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Impossibile salvare l'inserimento di carboidrati"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Impossibile salvare l'inserimento manuale delle glicemie"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Impossibile interrompere il bolo in corso. Avvicinare l'iPhone al microinfusore e riprovare. Controllare nella cronologia delle somministrazioni l'insulina e monitorare attentamente la glicemia."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Sconosciuto"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Errore sconosciuto: %1$@"; + /* The format for the description of a temporary override end date */ "until %@" = "fino a %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Fino a quando non inserisco carboidrati"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Finché non spengo"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Usa preimpostazione Pre-Pasto"; + /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Utilizza i target glicemici personalizzati per l'attivita' sportiva"; +"Use Workout Glucose Targets" = "Utilizza i target glicemi per l'allenamento"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Usa l'allenamento preimpostato"; /* Title of insulin model setting */ -"Walsh" = "Walsh"; +"Walsh" = "modello mimetico modificabile di insulina "; + +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Attenzione! Le notifiche di sicurezza sono disattivate"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Quando la glicemia attuale o prevista è inferiore al limite di sicurezza, Loop non consiglia un bolo e raccomanda sempre una velocità basale temporanea di 0 unità all'ora."; /* Explanation of suspend threshold */ -"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Quando l'attuale valore glicemico o un valore previsto nel futuro e' al di sotto del valore minimo previsto per la sospensione dell'erogazione, Loop non consigliera' un bolo e blocchera' l'erogazione delle basali."; +"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Quando la glicemia attuale o prevista è sotto la soglia di sospensione, Loop non consiglia un bolo, e raccomanda una velocità basale temporanea di 0 unità per ora."; + +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Quando non è in modalità ciclo chiuso, l'applicazione utilizza un calcolatore di bolo semplificato come un tipico microinfusore."; /* The label of the workout mode toggle button */ -"Workout Targets" = "Target per l'attivita' sportiva"; +"Workout Targets" = "Obiettivi di allenamento"; + +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "La regolazione della temperatura di allenamento è stata attivata per più di 24 ore. Assicurarsi di volerla ancora attivare o disattivarla nell'app."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "La regolazione della temperatura dell'allenamento è ancora attiva"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "sì"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Potresti non ricevere avvisi sonori, visivi o con vibrazione relativi a informazioni critiche sulla sicurezza. \n\n Per risolvere il problema, tocca \"Impostazioni\" e assicurati che Notifiche, Avvisi critici e Notifiche siano attivate."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "L'orario di %1$@ è stato modificato. La %2$@ ha bisogno di registrazioni accurate dell'orario per fare previsioni sulle glicemie e regolare l'insulina di conseguenza.\n\nControllare nelle Impostazioni di %1$@ (Generale / Data e ora) e verificare che l'opzione \"Imposta automaticamente\" sia attivata. In caso contrario, l'insulina potrebbe essere somministrata in quantità insufficiente o eccessiva."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "La glicemia è inferiore a %1$@. Sei sicuro di voler fare il bolo?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "La glicemia è inferiore o si prevede che scenda al di sotto del limite di sicurezza, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "La tua glicemia è al di sotto del limite di sicurezza, %1$@ ."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "La tua Glicemia è Bassa! Mangia dei carboidrati semplici e valuta la possibilità di aspettare a fare il Bolo fino a quando la tua Glicemia raggiunge un intervallo di sicurezza."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "La tua Glicemia è Bassa! Mangia dei Carboidrati Semplici e monitora la tua glicemia attivamente."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "La quantità del tuo Bolo Massimo è %1$@"; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "I dati del microinfusore sono obsoleti. %1$@ non può consigliare una quantità di bolo."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Il microinfusore sta erogando una velocità basale temporanea manuale."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Il Bolo Raccomandato supera la quantità' del Bolo Massimo di %1$@"; diff --git a/Loop/it.lproj/Main.strings b/Loop/it.lproj/Main.strings index 1124d93ad5..db668d2b13 100644 --- a/Loop/it.lproj/Main.strings +++ b/Loop/it.lproj/Main.strings @@ -1,71 +1,50 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Stato"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/ora @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolo"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "ID Microinfusore"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Quantità di bolo"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ -"87H-N1-0vJ.text" = "Predittivo"; +"87H-N1-0vJ.text" = "Predetto"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ "aCb-Qs-bpu.text" = "Dettaglio"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolo"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Tipo di cibo"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "Etichetta"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Modifica del Glucosio"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Unità"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Etichetta"; +"bq4-98-cQU.text" = "Modifica Carboidrati"; /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g Totali"; +"d3X-AN-tA5.text" = "Totale gr"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "La glicemia futura é predetta adottando una combinazione di multiple funzioni. Utilizzare questo strumento per attivare o meno le varie funzioni per valutare come esse influiscono sul valore glicemico predetto."; +"D4C-I2-dhA.text" = "La glicemia futura è predetta combinando gli effetti di più dati inseriti. L'utilizzo di questo applicativo permette di valutare come i singoli dati inseriti influiscano sul valore finale predetto."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Etichetta"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Impostazioni"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "DISPOSITIVI"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "probabile glic. 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Osservato"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Carboidrati Attivi: 40g"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/ora @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Effetti dei Carboidrati"; +"hZZ-2S-lrd.title" = "Effetti dei carboidrati"; /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ "IxU-As-glo.text" = "Per valutare l'assorbimento dei carboidrati, è possibile utilizzare i cambiamenti osservati nel glucosio, sottraendo i cambiamenti modellati dall'erogazione di insulina."; @@ -73,69 +52,60 @@ /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Dettaglio"; -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Glicemie previste sotto il Range"; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Basale Raccomandata"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Etichetta"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Etichetta"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Imposta"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Unità"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Etichetta"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Glicemia Predetta"; +"PA3-sP-cWY.title" = "Glicemia Prevista"; + +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Modello Insulina"; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Un modello di attività insulinica viene utilizzato per stimare gli effetti dell'insulina sui livelli di glucosio. Un modello accurato può aiutare a prevenire l'accumulo di insulina e consigliare in modo sicuro trattamenti correttivi."; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Tipo di cibo"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "probabile glic. 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g Active Carbs"; +"SQx-au-ZcM.text" = "g Carboidrati attivi"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glicemie"; +"tuw-av-A3x.text" = "Glicemia"; + +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Aggiungi/Modifica carboidrati Assunti"; /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ "ufi-Kj-33k.text" = "Etichetta"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Insulina Attiva: 1.5U"; - /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Carboidrati"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 ore"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Quantità consumata"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Basale Raccomandata"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Invia"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Consigliato"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "Titolo"; diff --git a/Loop/ja.lproj/InfoPlist.strings b/Loop/ja.lproj/InfoPlist.strings index 2797fd72f0..b3e1c6d3b4 100644 --- a/Loop/ja.lproj/InfoPlist.strings +++ b/Loop/ja.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "ループ"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Loop/ja.lproj/Localizable.strings b/Loop/ja.lproj/Localizable.strings index 5b711bdd49..1dff961aac 100644 --- a/Loop/ja.lproj/Localizable.strings +++ b/Loop/ja.lproj/Localizable.strings @@ -1,6 +1,12 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (保留中: %@)"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "—"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; @@ -16,6 +22,9 @@ /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; @@ -49,6 +58,9 @@ /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "大人使用時の Humalog、Novolog、Apidraインスリンの公表吸収率に基づいたモデル。"; +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "吸収時間"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "推奨ボーラス値を使う"; @@ -58,6 +70,9 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "残存糖質: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "残存糖質"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "残存インスリン"; @@ -65,13 +80,13 @@ "Active Insulin: %@" = "残存インスリン: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "カーボを追加"; +"Add Carb Entry" = "糖質の記入を追加"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "CGMを追加"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "食事を追加"; /* Action sheet title selecting Pump @@ -81,14 +96,17 @@ /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "大人モデルに経験効果を加算し調整したモデル。"; - /* The title of the amplitude API key credential */ "API Key" = "API キー"; /* The title of the nightscout API secret credential */ -"API Secret" = "API シークレット"; +"API Secret" = "APIシークレット"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "入力履歴をすべて削除しますか?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "リザーバの値をすべて削除しますか?"; /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "このCGMを削除しますか?"; @@ -117,7 +135,7 @@ "Bolusing %1$@" = "%1$@ ボーラス中"; /* The title of the cancel action in an action sheet */ -"Cancel" = "取消"; +"Cancel" = "キャンセル"; /* The title of the cell indicating a bolus is being canceled */ "Canceling Bolus" = "ボーラスをキャンセルします"; @@ -127,10 +145,16 @@ /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "糖質比"; +"Carb Ratios" = "Carb Ratios"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "糖質の記入を追加"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "糖質の記入を編集"; /* Title of the prediction input effect for carbohydrates */ -"Carbohydrates" = "糖質"; +"Carbohydrates" = "残存糖質"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ "Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "吸収済糖質(g) ÷ 糖質比 (g/U) × インスリン効果値(%1$@/U)"; @@ -150,9 +174,18 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "CGM データソースを確認してください"; +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "量の多い食事や脂質やたんぱく質を含んだ食事には長い吸収時間を選んでください。これはアルゴリズムのための参考で、厳密である必要はありません。"; + /* The title text for the looping enabled switch cell */ "Closed Loop" = "クローズドループ"; +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "%1$@ 時点"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "%1$@ より"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; @@ -162,12 +195,15 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "設定エラー: %1$@"; +/* Default alert dismissal */ +"Continue" = "次へ"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "CGM"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "補正範囲"; +"Correction Range" = "ターゲット範囲"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = "現在の血糖値は %1$@ で補正範囲を下回っています。"; @@ -175,18 +211,34 @@ /* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "カスタムオーバーライド"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "カスタマートークン"; +/* Date picker label */ +"Date" = "日付"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "アカウントを削除"; + +/* Button title to delete all objects */ +"Delete All" = "すべて削除"; /* Button title to delete CGM */ "Delete CGM" = "CGMを削除"; +/* Button title to delete a service */ +"Delete Service" = "Delete Service"; + /* Title text for delivery limits */ "Delivery Limits" = "注入限度"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "無効にする"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "閉じる"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "有効にする"; @@ -199,6 +251,9 @@ /* The alert title for a resume error */ "Error Resuming" = "再開エラー"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Event History"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "予想 %@"; @@ -211,6 +266,9 @@ /* The format string used to describe a finite workout targets duration */ "For %1$@" = "%1$@につき"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "血糖値"; @@ -233,7 +291,7 @@ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "吸収済インスリン(U) × インスリン効果値(%1$@/U)"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "インスリン放出"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "インスリン効果"; @@ -258,27 +316,53 @@ /* The loading message for the diagnostic report screen */ "Loading..." = "ロード中..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; - /* The notification title for a loop failure */ "Loop Failure" = "ループの不良"; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "ループが %@ の間クローズされていません"; +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "最大ボーラス"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "データがありません: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "モメンタム効果"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "詳細"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "注意してください"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "機器が未接続、または接続に問題"; +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "オン"; + +/* The title text for the override presets */ +"Override Presets" = "オーバーライドプリセット"; + /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "食前ターゲット"; @@ -300,6 +384,9 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "ポンプデータが %1$@前のものです"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "ポンプイベント"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "ポンプ設定"; @@ -312,6 +399,9 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "ポンプ一時停止中"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "超速攻型 - 大人"; @@ -328,7 +418,7 @@ "Recommended Bolus: %@ Units" = "推奨ボーラス: %@ 単位"; /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "リザーバ"; +"Reservoir" = "Reservoir"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "レトロ補正"; @@ -349,7 +439,7 @@ "since %@" = "%@ から"; /* The title of the nightscout site URL credential */ -"Site URL" = "アドレス"; +"Site URL" = "URL"; /* The format for the description of a temporary override start date */ "starting at %@" = "%@から開始"; @@ -366,12 +456,19 @@ /* Subtitle description of Walsh insulin model setting */ "The legacy model used by Loop, allowing customization of action duration." = "ループのレガシーモデルで、作用期間をカスタマイズできます。"; +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "最大吸収時間: %@"; + /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "最大ボーラス量は %@単位です"; /* The short unit display string for international units of insulin */ "U" = "U"; +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "不明"; + /* The format for the description of a temporary override end date */ "until %@" = "%@まで"; diff --git a/Loop/ja.lproj/Main.strings b/Loop/ja.lproj/Main.strings index 5bbdc79252..efa46d8f08 100644 --- a/Loop/ja.lproj/Main.strings +++ b/Loop/ja.lproj/Main.strings @@ -1,29 +1,17 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "ステータス"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/時 @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "ボーラス"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "ポンプID"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "ボーラス量"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "予想"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "詳細"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "ボーラス"; +"aCb-Qs-bpu.text" = "Detail"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "ラベル"; @@ -31,15 +19,6 @@ /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "グルコース変動"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "単位"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "ラベル"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g 合計"; @@ -49,20 +28,14 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "ラベル"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "設定"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "機器"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "予想 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "観察"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "残存糖質: 40g"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/時 @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "糖質効果"; @@ -71,10 +44,7 @@ "IxU-As-glo.text" = "観察されたグルコース値の変動から、インスリン注入のモデルによる変動を引くことにより、糖質の吸収を推定することができます。"; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "詳細"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ 予想グルコースが補正範囲を下回ります"; +"J7x-W5-gwo.text" = "Detail"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "推奨基礎分泌量"; @@ -82,30 +52,12 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "ラベル"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "ラベル"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "タップして確定"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "単位"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "ラベル"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "予想グルコース"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "インスリンモデル"; - -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "インスリン作用モデルはグルコース値へのインスリンの効果を概算するために使われます。正確なモデルにより、インスリンの蓄積を防ぎ、補正治療を安全に推奨することができます。"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "予想 92 mg/dL"; @@ -118,26 +70,17 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ "ufi-Kj-33k.text" = "ラベル"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "残存インスリン: 1.5U"; - /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "残存糖質"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4時間"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "注入"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "推奨基礎分泌量"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "推奨"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "タイトル"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; diff --git a/Loop/nb.lproj/InfoPlist.strings b/Loop/nb.lproj/InfoPlist.strings index 4168f9e7ed..4e6970dff3 100644 --- a/Loop/nb.lproj/InfoPlist.strings +++ b/Loop/nb.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; @@ -7,6 +10,9 @@ /* Privacy - Bluetooth Peripheral Usage Description */ "NSBluetoothPeripheralUsageDescription" = "Bluetooth brukes til å kommunisere med insulinpumpe og kontinuerlige glukosemonitorer."; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Kamera brukes til å skanne strekkoder på enheter."; + /* Privacy - Face ID Usage Description */ "NSFaceIDUsageDescription" = "Face ID brukes til å autentisere insulin bolus."; @@ -14,5 +20,8 @@ "NSHealthShareUsageDescription" = "Matdata fra Health-databasen brukes til å bestemme blodsukkereffekt. Blodsukkerdata hentes fra HealthKit for opptegning og analyse."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Angitte karbohydrater i matdataene som tastes inn i appen blir lagret i Health-databasen."; +"NSHealthUpdateUsageDescription" = "Karbohydratmåltidsdata som legges inn i appen og på klokken lagres i Helsedatabasen. Glukosedata hentet fra CGM lagres sikkert i HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop bruker Siri slik at du kan bruke forhåndsinnstillinger med stemmen din."; diff --git a/Loop/nb.lproj/Localizable.strings b/Loop/nb.lproj/Localizable.strings index db85de9f3d..d941f0e451 100644 --- a/Loop/nb.lproj/Localizable.strings +++ b/Loop/nb.lproj/Localizable.strings @@ -1,137 +1,132 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ -" (pending: %@)" = " (Gjenstår: %@)"; +" (pending: %@)" = "(venter: %@ )"; -/* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%1$@ %2$@"; - -/* Formats absorbed carb value */ -"%@ absorbed" = "%@ absorbert"; - -/* Appends a full-stop to a statement */ -"%@." = "%@."; - -/* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ E totalt"; - -/* Lesson subtitle */ -"Computes the percentage of glucose measurements within a specified range" = "Beregner prosentandelen av glukosemålinger innenfor et bestemt område"; - -/* Title of the button to begin lesson execution */ -"Continue" = "Fortsett"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Forhåndsinnstilling før måltid"; -/* Placeholder for upper range entry */ -"Maximum" = "Maksimum"; +/* remaining time in setting's profile expiration section */ +" remaining" = "gjenstående"; -/* Placeholder for lower range entry */ -"Minimum" = "Minimum"; +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = "Sikkerhetsvarsler er AV"; -/* Lesson title */ -"Modal Day" = "Modal dag"; +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = "Forhåndsinnstilling for trening"; -/* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ -"%1$@ U/hour @ %2$@" = "%1$@ E/timen @ %2$@"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; -/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* No comment provided by engineer. */ +"– –" = "– –"; -/* Lesson result text for no data */ -"No data available" = "Ingen data tilgjengelig"; +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; -/* Section title for glucose range */ -"Range" = "Målområde"; +/* Full stop character */ +"." = "."; -/* Title of config entry */ -"Start Date" = "Startdato"; +/* The format for an active override preset. (1: preset symbol)(2: preset name) */ +"%@ %@" = "%1$@ %2$@"; -/* Lesson title */ -"Time in Range" = "Tid i målområdet"; +/* Formats absorbed carb value */ +"%@ absorbed" = "%@ absorbert"; -/* Lesson subtitle */ -"Visualizes the most frequent glucose values by time of day" = "Visualiser de nyeste blodsukkerverdier etter tid på døgnet"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ gjenstår"; -/* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ -"%1$@ U/hour @ %2$@" = "%1$@ E/timen @ %2$@"; - -/* The string format describing active carbohydrates. (1: localized glucose value description) */ -"Active Carbohydrates: %@" = "Aktive karbohydrater: %@"; +/* The subtitle format describing total insulin. (1: localized insulin total) */ +"%@ U Total" = "%@ E Totalt"; -/* The title of the Insulin On-Board graph */ -"Active Insulin" = "Aktivt insulin"; +/* Appends a full-stop to a statement */ +"%@." = "%@ ."; -/* The string format describing active insulin. (1: localized insulin value description) */ -"Active Insulin: %@" = "Aktivt insulin: %@"; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ kunne ikke avbryte den nåværende midlertidige basaldosen, som er høyere enn den nye maksimale basalgrensen du har angitt. Dette kan føre til høyere insulintilførsel enn ønsket. \n\n Vurder å avbryte insulintilførselen manuelt og deretter umiddelbart gjenoppta for å innføre basaltilførsel med den nye grensen på plass."; -/* Unit string for a count of calendar weeks */ -"Weeks" = "Uker"; +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@ %2$@"; -/* The format for dose recommendation time. (1: localized time) */ -" @ %1$@" = " @ %1$@"; +/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; -/* The format for recommended bolus string. (1: localized bolus volume) */ -"%1$@ " = "%1$@ "; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; /* Format string for carb ratio average. (1: value)(2: carb unit) */ -"%1$@ %2$@/U" = "%1$@ %2$@/E"; +"%1$@ %2$@/U" = "%1$@ %2$@ /E"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; -/* Low reservoir alert format string. (1: Number of units remaining) */ -"%1$@ U left" = "%1$@ E gjenstår"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ opererer med Closed Loop i OFF posisjon. Pumpen og CGM vil fortsette å fungere, men appen vil ikke justere doseringen automatisk."; -/* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ -"%1$@ U left: %2$@" = "%1$@ E gjenstår: %2$@"; +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ kan ikke fjerne varselet fra enheten din"; -/* The format for recommended temp basal rate and time. (1: localized rate number) */ -"%1$@ U/hour" = "%1$@ E/timen"; +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ kan ikke kommunisere med insulinpumpen. Appen vil fortsette å prøve å nå pumpen din, men insulintilførselsinformasjon kan ikke oppdateres og ingen automatisering kan fortsette.\n Du kan vente flere minutter for å se om problemet løser seg eller trykke på knappen nedenfor for å lære mer om andre alternativer."; -/* The title of the button to remove the credentials for a service */ -"Delete Account" = "Slett konto"; +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Tidsinnstillinger trenger oppmerksomhet"; -/* Title text for button to set up a service */ -"Add Service" = "Legg til tjeneste"; +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ E"; -/* Button title to delete a service */ -"Delete Service" = "Slett tjeneste"; +/* Low reservoir alert format string. (1: Number of units remaining) */ +"%1$@ U left" = "%1$@ E igjen"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Er du sikker på at du vil slette denne tjenesten?"; +/* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ +"%1$@ U left: %2$@" = "%1$@ E gjenstår: %2$@"; -/* The title of the section containing algorithm settings */ -"Algorithm Settings" = "Algoritmeinnstillinger"; +/* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ +"%1$@ U/hour @ %2$@" = "%1$@ E/timen @ %2$@"; /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ -"%1$@ v%2$@" = "%1$@ v%2$@"; +"%1$@ v%2$@" = "%1$@ v %2$@"; -/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; - -/* Format string describing glucose units per minute (1: glucose unit string) */ -"%1$@/min" = "%1$@/min"; +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ slutter å fungere om %2$@ . Du må oppdatere før det, med en ny klargjøringsprofil."; /* Formats (1: carb value) and (2: food type) */ -"%1$@: %2$@" = "%1$@: %2$@"; - -/* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%@ %@"; +"%1$@: %2$@" = "%1$@ : %2$@"; -/* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ E Totalt"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@ : %2$@ %3$@"; /* Description of the prediction input effect for glucose momentum */ -"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 minutters glukose-regresjonskoeffisient (b1), fortsatt med henfall over 30 minutter."; +"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 minutters glukose-regresjonskoeffisient (b1), fortsatt med nedbrytning over 30 minutter."; /* Description of the prediction input effect for retrospective correction */ -"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min sammenligning av glukose-prediksjon vs faktisk, fortsatt med forfall over 60 min."; +"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min sammenligning av glukose-prediksjon vs faktisk, fortsatt med nedbrytning over 60 min."; + +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Noen sekunder gjenstår"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "En manuell BS-registrering må være mellom %1$@ og %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "En manuell BS-registrering må være mellom %1$@ og %2$@ ."; /* Subtitle of Fiasp preset */ -"A model based on the published absorption of Fiasp insulin." = "En modell basert på publiserte data for absorpsjon av Fiasp insulin."; +"A model based on the published absorption of Fiasp insulin." = "En modell basert på publisert absorpsjon av Fiasp-insulin."; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "En modell basert på publiserte data for absorpsjon av Humalog, Novolog og Apidra insulin hos voksne."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "En modell basert på publisert absorpsjon av Humalog, Novolog og Apidra insulin hos voksne."; + +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "En ny versjon av %@ er tilgjengelig og anbefales for å fortsette å bruke appen."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "En ny versjon av %@ er tilgjengelig."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "En pumpe må konfigureres før en bolus kan tilføres."; /* Title of the carb entry absorption time cell */ -"Absorption Time" = "Absorpsjonstid"; +"Absorption Time" = "Absorbsjonstid"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AksepterAnbefaltBolus"; @@ -139,13 +134,18 @@ /* The title of the Carbs On-Board graph */ "Active Carbohydrates" = "Aktive karbohydrater"; -/* HUD row title for COB */ -"Active Carbs" = "Aktive karbs"; +/* The string format describing active carbohydrates. (1: localized glucose value description) */ +"Active Carbohydrates: %@" = "Aktive karbohydrater: %@"; + +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Aktive karbohydrater"; -/* HUD row title for IOB - The title of the Insulin On-Board graph */ +/* The title of the Insulin On-Board graph */ "Active Insulin" = "Aktivt insulin"; +/* The string format describing active insulin. (1: localized insulin value description) */ +"Active Insulin: %@" = "Aktivt insulin: %@"; + /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Legg til karbohydrater"; @@ -153,60 +153,124 @@ Title text for button to set up a CGM */ "Add CGM" = "Legg til CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Legg til måltid"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ "Add Pump" = "Legg til pumpe"; +/* Title text for button to set up a service */ +"Add Service" = "Legg til tjeneste"; + +/* No comment provided by engineer. */ +"Adjusted for" = "Justert for"; + +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Administrasjon av varsler"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Varslingsinnstillinger"; + +/* The title of the section containing algorithm settings */ +"Algorithm Settings" = "Algoritmeinnstillinger"; + /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "En justering til modellen tilpasset voksne, basert på empiriske effekter hos barn."; +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "En aktiv overstyring modifiserer ditt karbohydratforhold og insulinfølsomhet. Hvis du ikke vil at dette skal påvirke bolusberegningen og projisert blodsukker, bør du vurdere å slå av overstyringen."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Det oppstod en feil under forsøk på å lagre karbohydratregistreringen."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Det oppstod en feil under forsøk på å lagre den manuelle BS-registreringen."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "En uventet onboarding-feiltilstand oppstod."; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "En oppdatert bolusanbefaling er tilgjengelig."; /* The title of the amplitude API key credential */ -"API Key" = "API nøkkel"; +"API Key" = "API Nøkkel"; /* The title of the nightscout API secret credential */ -"API Secret" = "API hemmelighet"; +"API Secret" = "API Hemmelighet"; + +/* Settings app profile section */ +"App Profile" = "App-profil"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Er du sikker på at du vil slette alle historiske innslag?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Er du sikker på at du vil slette alle loggførte doseoppføringer?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Er du sikker på at du vil slette alle reservoarverdier?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Er du sikker på at du vil slette alle dine %@ Data?\n(Denne handlingen kan ikke angres)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Er du sikker på at du vil slette denne CGM?"; +"Are you sure you want to delete this CGM?" = "Er du sikker på at du vil slette CGM?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Er du sikker på at du vil slette denne tjenesten?"; /* Format fragment for a specific time */ -"at %@" = "kl. %@"; +"at %@" = "kl %@"; /* The message displayed during a device authentication prompt for bolus specification */ -"Authenticate to Bolus %@ Units" = "Autentiser for å gi bolus %@ E"; - -/* Title string for automatic bolus dosing strategy */ -"Automatic Bolus" = "Automatisk bolus"; +"Authenticate to Bolus %@ Units" = "Autentiserer for å gi %@ Enheter i Bolus"; -/* Title string for automatic bolus dosing strategy */ -"Automatic Bolus (Experimental)" = "Automatisk bolus (eksperimentell)"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Autentiser for å logge %@ Enheter"; /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Tidsplan for basaldoser"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Basaldoser"; +"Basal Rates" = "Basal-satser"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Basert på ditt forventede blodsukker, anbefales ingen bolus."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Blåtann\nAv"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Blåtann\nUtilgjengelig"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Bluetooth Avslått-varsel"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Varsel om at Bluetooth er utilgjengelig"; /* The label of the bolus entry button - The notification title for a bolus failure - Title text for bolus screen (manual correction) */ + The notification title for a bolus failure */ "Bolus" = "Bolus"; -/* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Bolus feilet"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Bolus feil"; /* Alert title for an updated bolus recommendation */ -"Bolus Recommendation Updated" = "Bolus-anbefaling oppdatert"; +"Bolus Recommendation Updated" = "Bolus anbefaling er oppdatert"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Bolus oppsummering"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus er for liten"; /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ -"Bolused %1$@ of %2$@" = "Ga bolus %1$@ av %2$@"; +"Bolused %1$@ of %2$@" = "Bolus %1$@ av %2$@"; /* The format string for bolus in progress showing total volume. (1: total volume) */ "Bolusing %1$@" = "Gir bolus %1$@"; @@ -218,53 +282,81 @@ "Canceling Bolus" = "Avbryter bolus"; /* Details for missing data error when carb effects are missing */ -"Carb effects" = "Karbohydrateffekter"; +"Carb effects" = "Karb effekter"; -/* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Tilpassede overstyringer"; +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Legg til karbohydrater"; -/* Back button text for bolus screen to return to carb entry screen */ -"Carb Entry" = "Karb oppføring"; +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Tidsplan for karbohydratforhold"; /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Karbohydratforhold"; +"Carb Ratios" = "Karb forhold"; /* The title of the view controller to create a new carb entry */ -"carb-entry-title-add" = "carb-entry-title-add"; +"carb-entry-title-add" = "Legg til karbohydrater"; /* The title of the view controller to edit an existing carb entry */ -"carb-entry-title-edit" = "carb-entry-title-edit"; +"carb-entry-title-edit" = "Rediger karbohydrater"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Karbohydratinntaket er for stort"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Karbohydrater"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Karbohydrater absorbert (g) ÷ Karbohydratforhold (g/E) × Insulinfølsomhet (%1$@/E)"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Karbohydrater absorbert (g) ÷ karbohydratforhold (g / E) × insulinfølsomhet (%1$@ / E)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Bytt batteri på pumpe snarest"; +"Change the pump battery immediately" = "Skift pumpebatteri umiddelbart"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Bytt reservoar på pumpe nå"; +"Change the pump reservoir now" = "Bytt pumpereservoar nå"; /* Details for configuration error when one or more loop settings are missing */ "Check settings" = "Sjekk innstillinger"; /* Recovery suggestion when reservoir data is missing */ -"Check that your pump is in range" = "Sjekk at pumpen er innen rekkevidde"; +"Check that your pump is in range" = "Sjekk at pumpen din er innenfor rekkevidde"; /* Recovery suggestion when glucose data is missing */ -"Check your CGM data source" = "Sjekk blodsukkerkilde"; +"Check your CGM data source" = "Sjekk CGM"; + +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Sjekk enhetens klokke og/ eller fjern eventuelle ugyldige data fra Apple Helse."; /* Carb entry section footer text explaining absorption time */ -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Velg en lengre absorpsjonstid for større måltider, eller de som inneholder fett og proteiner. Dette er bare veiledning til algoritmen og trenger ikke være nøyaktig."; +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Velg en lengre absorpsjonstid for større måltider, eller de som inneholder fett og proteiner. Dette er bare veiledning til algoritmen og trenger ikke å være nøyaktig."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Lukk"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Lukket Loop"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Lukket Loop AV"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Lukket Loop krever en aktiv CGM sensorøkt"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Lukket Loop krever at installasjonen er fullført"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "kl. %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "siden %1$@"; + /* The title of the action used to dismiss an error alert */ -"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +"com.loudnate.LoopKit.errorAlertActionTitle" = "Ok"; + +/* Title text for button to complete setup */ +"Complete Setup" = "Fullfør oppsett"; /* The title of the configuration section in settings */ "Configuration" = "Konfigurasjon"; @@ -272,6 +364,9 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Konfigurasjonsfeil: %1$@"; +/* Default alert dismissal */ +"Continue" = "Fortsett"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Kontinuerlig glukosemonitor"; @@ -279,204 +374,459 @@ The title text for the glucose target range schedule */ "Correction Range" = "Korreksjonsområde"; +/* Critical Alerts Status text */ +"Critical Alerts" = "Kritiske varsler"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Kritisk hendelseslogg er klar"; + +/* Critical event log export title */ +"Critical Event Logs" = "Kritiske hendelseslogger"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Kritiske hendelseslogger kunne ikke eksporteres."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Nåværende blodsukker"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Nåværende blodsukker på %1$@ er under korreksjonssområde."; +"Current glucose of %1$@ is below correction range." = "Gjeldende glukose på %1$@ er under korreksjonsområdet."; -/* Name of custom override - The title of the cell indicating a generic temporary override is enabled */ +/* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "Tilpasset overstyring"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Kundetoken"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Egendefinert forhåndsinnstilling"; -/* Title of the carb entry date picker cell */ +/* Date picker label */ "Date" = "Dato"; /* The short unit display string for decibles */ "dB" = "dB"; -/* Sensor state description for the non-valid state */ -"Needs Attention" = "Trenger tilsyn"; +/* No comment provided by engineer. */ +"Delete" = "Slett"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Slett Konto"; + +/* Button title to delete all objects */ +"Delete All" = "Slett alle"; /* Button title to delete CGM */ "Delete CGM" = "Slett CGM"; -/* The title text for the override presets */ -"Override Presets" = "Forhåndslagrede overstyringer"; +/* Button title to delete a service */ +"Delete Service" = "Slett tjeneste"; -/* The button text to initiate a bolus */ -"Deliver" = "Lever"; +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Slett testdata for blodsukkermåler"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Slett testdata"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Slett data for testpumpe"; + +/* Button text to deliver a bolus */ +"Deliver" = "Gi bolus"; /* Title text for delivery limits */ -"Delivery Limits" = "Leveringsgrense"; +"Delivery Limits" = "Leveringsgrenser"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Diabetesbehandling"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Hadde du tenkt å angi %1$@ gram som mengde karbohydrater for dette måltidet?"; /* The action hint of the workout mode toggle button when enabled */ -"Disables" = "Deaktiver"; +"Disables" = "Deaktiverer"; + +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Avvis"; + +/* No comment provided by engineer. */ +"Done" = "Ferdig"; -/* The action button title to dismiss an error message */ -"Dismiss" = "Ignorer"; +/* Title for card to log dose */ +"Dose Summary" = "Dose sammendrag"; -/* The title text for the dosing strategy setting row */ +/* The title of the Dosing Strategy section in settings */ "Dosing Strategy" = "Doseringsstrategi"; +/* Remote command error description: duration exceed max (1: max duration in hours). */ +"Duration exceeds: %1$.1f hours" = "Varigheten overskrider: %1$.1f timer"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Aktiver blåtann"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Aktiverer"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Legg inn blodsukkerverdi fra en måler for anbefalt bolusmengde."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Skriv inn bolus"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Legg inn blodsukkerverdi fra fingerstikk"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Angi sikkerhetsgrensen for blodsukker"; + /* The placeholder text instructing users to enter a suspend treshold */ -"Enter suspend threshold" = "Legg til grense for insulinstopp"; +"Enter suspend threshold" = "Angi suspenderingsgrense"; /* The alert title for an error while canceling a bolus */ -"Error Canceling Bolus" = "Kunne ikke kansellere bolus"; +"Error Canceling Bolus" = "Kunne ikke avbryte bolus"; + +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Feil ved eksport av logger"; /* The alert title for a resume error */ -"Error Resuming" = "Kunne ikke gjenoppta"; +"Error Resuming" = "Feil ved gjenopptagelse"; -/* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %1$@" = "Omsider %1$@"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Hendelseshistorie"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %@" = "Omsider %@"; +"Eventually %@" = "Til slutt %@"; + +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Overskrider maksimalt tillatt bolus i innstillingene"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Overskrider maksimalt tillatte karbohydrater"; /* The title of the alert describing a maximum bolus validation error */ -"Exceeds Maximum Bolus" = "Overskrider maks bolus"; +"Exceeds Maximum Bolus" = "Overskrider maksimal bolus"; + +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Eksporter kritiske hendelseslogger"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Eksporter- %1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Kunne ikke gjenoppta insulinlevering"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Blodsukkerverdi fra fingerstikk"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Fiks nå ved å slå PÅ varsler, kritiske varsler og tidssensitive varsler."; + /* The format string used to describe a finite workout targets duration */ -"For %1$@" = "Til %1$@"; +"For %1$@" = "I %1$@"; + +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Forventet blodsukker kan fortsatt være høyere enn målområdet."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Forventet blodsukker"; /* The short unit display string for grams */ "g" = "g"; +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Få hjelp med varslingsinnstillinger"; + /* The title of the glucose and prediction graph */ -"Glucose" = "Glukose"; +"Glucose" = "Blodsukker"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Glukosedata er %1$@ gammel"; +"Glucose data is %1$@ old" = "Blodsukkerdata er %1$@ gammel"; /* Description of error when glucose data is missing */ -"Glucose data not available" = "Glukosedata er utilgjengelig"; +"Glucose data not available" = "Blodsukkerdata er utilgjengelig"; + +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Blodsukkerdata er utilgjengelig"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Blodsukkerdata er utenfor intervallet"; /* Title of the prediction input effect for glucose momentum */ -"Glucose Momentum" = "Glukosemomentum"; +"Glucose Momentum" = "Glukose Momentum"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://mysite.herokuapp.com"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Tidsplan for blodsukker målområde"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Hvordan oppdatere (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Umiddelbar"; /* The title of a target alert action specifying an indefinitely long workout targets duration */ -"Indefinitely" = "Uendelig"; +"Indefinitely" = "På ubestemt tid"; + +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Maksimalt antall er overskredet"; /* Title of the prediction input effect for insulin */ "Insulin" = "Insulin"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulin absorbert (E) × Insulinfølsomhet (%1$@/E)"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulin absorbert (E) × insulinfølsomhet ( %1$@ /E)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Insulinjusteringer er deaktivert!"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insulinlevering"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ -"Insulin effects" = "Insulineffekter"; +"Insulin effects" = "Insulin effekt"; /* Details for configuration error when insulin model is missing The title text for the insulin model setting row */ -"Insulin Model" = "Insulinmodell"; +"Insulin Model" = "Insulin modell"; + +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Insulinpumpe"; /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Insulinfølsomhet"; +"Insulin Sensitivities" = "Insulinsensitivitet"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Insulin følsomhet tidsplan"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insulintilførsel utsatt"; + +/* Insulin type label */ +"Insulin Type" = "Insulintype"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Avbrutt %1$@: %2$@ av %3$@ %4$@"; + +/* Remote command error description: invalid bolus amount. */ +"Invalid Bolus Amount" = "Ugyldig bolusmengde"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Ugyldig karbohydratmengde"; /* The error message when invalid data was encountered. (1: details of invalid data) */ -"Invalid data: %1$@" = "Ugyldig data: %1$@"; +"Invalid data: %1$@" = "Ugyldige data: %1$@"; + +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Ugyldig fremtidig blodsukker"; -/* The subtitle format describing units of active insulin. (1: localized insulin value description) */ -"IOB %1$@ U" = "IOB %1$@ E"; +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Ugyldig blodsukkermåling med et tidsstempel som er %1$@ i fremtiden"; /* The title text for the issue report cell */ -"Issue Report" = "Hendelsesrapport"; +"Issue Report" = "Problem Rapport"; + +/* The notification description for a meal that was possibly not logged in Loop. */ +"It looks like you may not have logged a meal you ate. Tap to log it now." = "Det ser ut til at du kanskje ikke har logget et måltid du har spist. Trykk for å logge den nå."; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Angitt Stort Måltid"; /* Glucose HUD accessibility hint */ -"Launches CGM app" = "Starter CGM app"; +"Launches CGM app" = "Laster inn CGM-appen"; + +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Lære mer"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Mindre enn et minutt gjenstår"; /* The loading message for the diagnostic report screen */ -"Loading..." = "Laster..."; +"Loading..." = "Laster inn..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Logg Dose"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Logget insulindose"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop krasjet"; /* The notification title for a loop failure */ -"Loop Failure" = "Loop feilet"; +"Loop Failure" = "Loop-feil"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop har oppdaget et problem med Bluetooth-innstillingene dine, og vil ikke fungere før Bluetooth er aktivert. Du vil ikke motta blodsukkermålinger, eller være i stand til å gi bolus."; + +/* Warning displayed when user is adding a meal from an missed meal notification */ +"Loop has detected an missed meal and estimated its size. Edit the carb amount to match the amount of any carbs you may have eaten." = "Loop har oppdaget et glemt måltid og estimert størrelsen. Rediger karbohydratmengden for å matche mengden av karbohydrater du måtte ha spist."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ -"Loop has not completed successfully in %@" = "Loop har ikke kjørt vellykket på %@"; +"Loop has not completed successfully in %@" = "Loop er ikke fullført i %@"; /* Description string for automatic bolus dosing strategy */ -"Loop will automatically bolus when bg is predicted to be higher than target range, and will use temp basals when bg is predicted to be lower than target range. Please use caution when selecting this option for the first time. You may need re-evaluate your settings, even if you have been having success with those settings when using Loop's original temp basal strategy." = "Loop vil automatisk bolus når bg er spådd å være høyere enn målområdet, og vil bruke temp basals når bg er spådd å være lavere enn målområdet. Vær forsiktig når du velger dette alternativet for første gang. Det kan hende du må evaluere innstillingene på nytt, selv om du har hatt suksess med disse innstillingene når du bruker Loops opprinnelige temp basal-strategi."; +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Lopp vil sette bolus når insulinbehovet er over planlagt basal, og vil bruke midlertidige basale rater når det er nødvendig for å redusere insulintilførselen under planlagt basal"; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop vil ikke fungere før Bluetooth er aktivert. Du vil ikke motta blodsukkermålinger, eller være i stand til å gi bolus."; /* Description string for temp basal only dosing strategy */ -"Loop will dose insulin using 30 minute temporary basal rates, limited by your max temp basal setting. This is the same strategy that Loop used in previous versions." = "Loop vil dosere insulin ved hjelp av 30 minutters midlertidige basale priser, begrenset av din maksimale temp basal innstilling. Dette er den samme strategien som Loop brukte i tidligere versjoner."; +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop vil sette midlertidige basal rater for å øke og redusere insulin levering."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Lavt blodsukker"; -/* Format string for body for notification of upcoming provisioning profile expiration. (1: amount of time until expiration */ -"Loop will stop working in %@. You will need to update Loop before that, with a new provisioning profile." = "Loop vil slutte å fungere om %@. Løkken slutter å fungere om %@. Du må oppdatere Loop før det, med en ny klargjøringsprofil."; +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Behandle tillatelser i Innstillinger"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Manuell dose: %1$@ %2$@"; -/* The recovery message displayed after a bolus attempt fails - The recovery message displayed after a carb entry send attempt fails - The recovery message displayed after a glucose range override send attempt fails */ -"Make sure your iPhone is nearby and try again" = "Kontroller at iPhone er i nærheten, og prøv på nytt"; +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Maksimal basalrate per time"; -/* Title text for bolus screen following a carb entry */ +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maks bolus"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Maksimal bolus overskredet"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Maksimal varighet overskredet"; + +/* Title for bolus entry screen when also entering carbs */ "Meal Bolus" = "Måltidsbolus"; /* The short unit display string for milligrams of glucose per decilter */ "mg/dL" = "mg/dL"; /* The error message for missing data. (1: missing data details) */ -"Missing data: %1$@" = "Mangler data: %1$@"; +"Missing data: %1$@" = "Manglende data: %1$@"; + +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Mangler maksimalt tillatt bolus i innstillingene"; /* The short unit display string for millimoles of glucose per liter */ "mmol/L" = "mmol/L"; /* Details for missing data error when momentum effects are missing */ -"Momentum effects" = "Momentumeffekter"; +"Momentum effects" = "Momentum effekt"; /* Text for more info action on notification of upcoming profile expiration */ "More Info" = "Mer info"; -/* HUD row title for Net Basal Rate */ -"Net Basal Rate" = "Netto basal rate"; +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Demp alle varsler"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Trenger tilsyn"; + +/* Remote command error description: negative duration error. */ +"Negative duration not allowed" = "Negativ varighet ikke tillatt"; /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Ingen varsler høres når de er dempet. Når denne perioden er over, vil varslene og alarmene gjenopptas som normalt."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Ingen anbefalt bolus"; + /* The error message displayed for device connection errors. */ -"No connected devices, or failure during device connection" = "Ingen tilkoblede enheter, eller feil under tilkobling til enhet"; +"No connected devices, or failure during device connection" = "Ingen tilkoblede enheter, eller feil under enhetstilkobling"; -/* Button text to acknowledge an updated bolus recommendation alert - Button text to dismiss unconfigured pump alert. - Text for ok action on notification of upcoming profile expiration */ -"OK" = "OK"; +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Ingen maksimal bolus er konfigurert"; -/* The text for the Watch button for enabling a temporary override */ -"Override" = "Overstyre"; +/* Alert title for a missing pump error */ +"No Pump Configured" = "Ingen pumpe er konfigurert"; -/* Alert message for attempting to change basal rates before pump was configured. */ -"Please configure a pump to view or edit scheduled basal rates." = "Konfigurer en pumpe for å vise eller redigere planlagte basal rater."; +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Ingen ny blodsukkermåling"; -/* Name of pre-meal workout override */ -"Pre-Meal" = "Før måltid"; +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Ingen nye blodsukkerdata"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Mangler relevant pumpdata"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Nei, rediger mengde"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Varslingslevering"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Varslingslevering er satt til Planlagt sammendrag i telefonens innstillinger. \n\n For å unngå forsinkelser i mottak av varsler fra %1$@ , anbefaler vi at varslingslevering settes til Umiddelbar levering."; + +/* Notifications Status text */ +"Notifications" = "Varsler"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Varsler forsinket"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Varslinger gir deg viktig %1$@ app informasjon uten at du behøver å åpne appen."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Varsler gir deg viktig %1$@ appinformasjon uten at du trenger å åpne appen. \n\n Hold disse slått PÅ i telefonens innstillinger for å sikre at du mottar %1$@ -varsler, kritiske varsler og tidssensitive varsler."; + +/* Notification Setting Status is Off */ +"Off" = "Av"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Å nei! Loop krasjet under dosering, og insulinjusteringer er satt på pause til denne dialogen er lukket. Doseringshistorikken er kanskje ikke nøyaktig. Vennligst sjekk diagrammer for insulin levering, og overvåk blodsukkeret nøye."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "Ok"; + +/* Notification Setting Status is On */ +"On" = "På"; + +/* The title text for the override presets */ +"Override Presets" = "Egendefinerte overstyringer"; + +/* The notification title for a meal that was possibly not logged in Loop. */ +"Possible Missed Meal" = "Mulig savnet måltid"; /* The label of the pre-meal mode toggle button */ -"Pre-Meal Targets" = "Pre-måltids mål"; +"Pre-Meal Targets" = "Målområde før måltid"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Forventet blodsukker om 1$@ er %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Forventet blodsukker kl %1$@ er %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Forventet blodsukker er innenfor målområdet."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Forventet blodsukker på %1$@ er lavere enn innstillingen for blodsukkersikkerhet."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet blodsukker %1$@ er under innstilling for insulinstopp"; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Forventet blodsukker %1$@ er lavere enn innstilling for insulinstopp"; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ -"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Forespeilet: %1$@\nFaktisk: %2$@ (%3$@)"; +"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Forventet: %1$@\nFaktisk: %2$@ ( %3$@ )"; + +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Forbereder logg av kritiske hendelser"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Profilens utløp"; + +/* Time that profile expires */ +"Profile expires " = "Profil utløper"; /* The title for notification of upcoming profile expiration */ "Profile Expires Soon" = "Profil utløper snart"; @@ -485,67 +835,87 @@ "Pump" = "Pumpe"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Pumpebatteri lavt"; +"Pump Battery Low" = "Lavt pumpebatteri"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ -"Pump data is %1$@ old" = "Pumpedata er %1$@ gammelt"; +"Pump data is %1$@ old" = "Pumpedata er %1$@ gamle"; + +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pumpehendelse"; /* Details for configuration error when pump manager is missing */ -"Pump Manager" = "Pumpeinnstilling"; +"Pump Manager" = "Pumpe manager"; + +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Pump Manager-feil: %1$@"; /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Pumpereservoar tomt"; +"Pump Reservoir Empty" = "Pumpereservoar Tomt"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Pumpereservoar lavt"; +"Pump Reservoir Low" = "Pumpereservoar Lavt"; -/* The error message when loop failed because the pump was encountered. - The title of the cell indicating the pump is suspended */ -"Pump Suspended" = "Pumpe satt på pause"; +/* The title of the cell indicating the pump is suspended */ +"Pump Suspended" = "Pumpe Utsatt"; -/* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Hurtigvirkende – voksen"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pumpe suspendert. Automatisk dosing er deaktivert."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* Title of insulin model preset */ -"Rapid-Acting – Children" = "Hurtigvirkende - barn"; +"Rapid-Acting – Adults" = "Hurtigvirkende - Voksen"; -/* The label and value showing the recommended bolus */ -"Rec: %@ U" = "Anb: %@ E"; +/* Title of insulin model preset */ +"Rapid-Acting – Children" = "Hurtigvirkende - Barn"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ "Recommendation expired: %1$@ old" = "Anbefaling utløpt: %1$@ gammelt"; -/* The title of the cell displaying a recommended automatic bolus value */ -"Recommended Auto-Bolus" = "Anbefalt auto bolus"; - /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Anbefalt basal"; +"Recommended Basal" = "Anbefalt Basal"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Anbefalt bolus"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Anbefalt bolus overskrider maksimal bolus"; /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Anbefalt bolus: %@ enheter"; -/* The title of the cell displaying a recommended dose */ -"Recommended Dose" = "Anbefalt dose"; +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Ekstern bolusregistrering: %@ E"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Ekstern karbohydratregistrering: %d gram"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Ekstern kommando utløpt"; /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Reservoar"; -/* HUD row title for remaining reservoir volume */ -"Reservoir Volume" = "Reservorarvolum"; - /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Retrospektiv korreksjon"; -/* The button text for attempting a manual loop - The title of the notification action to retry a bolus command */ -"Retry" = "Prøv igjen"; +/* The title of the notification action to retry a bolus command */ +"Retry" = "Prøv på nytt"; -/* The button text to save a carb entry without bolusing */ +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Lagre og gi bolus"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ "Save without Bolusing" = "Lagre uten å sette bolus"; -/* The title of the alert controller displayed after a carb entry send attempt fails - The title of the alert controller displayed after a glucose range override send attempt fails */ -"Send Failed" = "Send feilet"; +/* Scheduled Delivery status text */ +"Scheduled" = "Planlagt"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Velg tidsrom for Mute"; /* The title of the services section in settings */ "Services" = "Tjenester"; @@ -553,154 +923,223 @@ /* The label of the settings button */ "Settings" = "Innstillinger"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Ufullstendig oppsett"; + /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Viser siste Loop-feil"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Enkel bolus-kalkulator"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Enkelt måltid kalkulator"; + /* Format fragment for a start time */ "since %@" = "siden %@"; /* The title of the nightscout site URL credential */ -"Site URL" = "Site URL"; +"Site URL" = "Nettstedslenke (URL)"; + +/* Software update button link text */ +"Software Update" = "Programvare oppdatering"; + +/* Remote command error description: invalid start time is out of range. */ +"Start time is out of range: %@" = "Starttiden er utenfor området: %@"; /* The format for the description of a temporary override start date */ -"starting at %@" = "startet %@"; +"starting at %@" = "starter på %@"; /* The title of the cell indicating a bolus is being sent */ -"Starting Bolus" = "Starter bolus"; +"Starting Bolus" = "Starter Bolus"; + +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Support"; /* The title text in settings */ -"Suspend Threshold" = "Grense for insulinstopp"; +"Suspend Threshold" = "Terskel for utsettelse"; + +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Trykk her for å sette opp en CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Trykk her for å sette opp en pumpe"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Trykk her for å sette opp en tjeneste"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Trykk for å legge til"; /* The subtitle of the cell displaying an action to resume insulin delivery */ -"Tap to Resume" = "Trykk for å gjenoppta"; +"Tap to Resume" = "Trykk for å fortsette"; + +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Trykk for å stoppe"; -/* Title string for temp basal only dosing strategy */ -"Temp Basal Only" = "Bare midlertidig basal"; +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Midlertidig demping av varsler"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Den angitte bolusmengden er mindre enn minimumsleveransen."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Bolusdoseringsalgoritmen bruker et mer konservativt estimat av anslått blodsukker enn det som brukes til å justere basalhastigheten. \n\n Som et resultat kan det anslåtte blodsukkeret ditt etter en bolus fortsatt være høyere enn målområdet ditt."; /* Alert message for an updated bolus recommendation */ "The bolus recommendation has updated. Please reconfirm the bolus amount." = "Bolus-anbefalingen er oppdatert. Bekreft bolusverdien på nytt."; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Den gamle modellen brukt av Loop, tillater endring av varighet for handling."; +"The legacy model used by Loop, allowing customization of action duration." = "Den eldre modellen som brukes av Loop, tillater tilpasning av handlingsvarighet."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Maksimal absorpsjonstid er %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "Maksimalt tillatt mengde er %@ gram."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "Maksimal tillatt mengde er %1$@ ."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Maksimal bolus er satt til %@ E."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ -"The maximum bolus amount is %@ Units" = "Maks bolus er satt til %@ enheter"; +"The maximum bolus amount is %@ Units" = "Maksimal bolusmengde er %@ enheter"; + +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Innstillingen for maksimal bolus må konfigureres før bolus kan leveres."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Den eksterne kommandoen utløp for %.0f minutter siden."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Behandlingsinnstillinger"; + +/* Title of the carb entry date picker cell */ +"Time" = "Tid"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Tidssensitive varsler"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Prøv på nytt"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Slå på Bluetooth for å motta varsler, alarmer eller avlesninger fra glukosesensor."; /* The short unit display string for international units of insulin */ "U" = "E"; -/* The short unit display string for international units of insulin delivery per hour */ -"U/hr" = "E/hr"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Kan ikke fjerne varsel"; -/* Alert title for unconfigured pump */ -"Unconfigured Pump" = "Ukonfigurert pumpe"; +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Kommunikasjonsfeil"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Kunne ikke lagre karbohydrater"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Kan ikke lagre manuell blodsukkerregistrering"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Kan ikke stoppe bolusen som pågår. Flytt iPhone nærmere pumpen og prøv igjen. Sjekk insulinleveringshistorikken for detaljer, og overvåk glukosen nøye."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Ukjent"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Ukjent feil: %1$@"; + +/* Remote command error description: unknown preset (1: preset name). */ +"Unknown preset: %1$@" = "Ukjent forhåndsinnstilling: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Ukjent tid"; /* The format for the description of a temporary override end date */ -"until %@" = "frem til %@"; +"until %@" = "til %@"; + +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Frem til jeg legger inn karbohydrater"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Frem til jeg skrur av"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Bruk pre-måltidsmål"; /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Bruk treningsmodus for glukosemålområde"; +"Use Workout Glucose Targets" = "Bruk treningsmodus for BS-målområde"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Bruk forhåndsinnstilling for treningsøkt"; /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Advarsel! Sikkerhetsvarsler er slått AV"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Når gjeldende eller anslått glukose er under glukosesikkerhetsgrensen, vil ikke Loop anbefale en bolus, og vil alltid anbefale en midlertidig basalrate på 0 enheter per time."; + /* Explanation of suspend threshold */ -"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Når nåværende eller forventet blodsukker er under grensen for insulinstopp, vil ikke Loop anbefale en bolus, og vil alltid anbefale en midlertidig basalrate på 0 enheter per time."; +"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Når gjeldende eller anslått glukose er under suspenderingsterskelen, vil ikke Loop anbefale en bolus, og vil alltid anbefale en midlertidig basalrate på 0 enheter per time."; + +/* Description of missed meal notifications. */ +"When enabled, Loop can notify you when it detects a meal that wasn't logged." = "Når den er aktivert, kan Loop varsle deg når den oppdager et måltid som ikke ble logget."; -/* Name of legacy workout override - The text for the Watch button for enabling workout mode */ -"Workout" = "Trening"; +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Når den er ute av lukket Loop-modus, bruker appen en forenklet boluskalkulator som en vanlig pumpe."; /* The label of the workout mode toggle button */ -"Workout Targets" = "Treningsmål"; +"Workout Targets" = "Målområder for trening"; -/* Customs strings added from manually debugging */ +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Temp Adjust for trening har vært slått på i mer enn 24 timer. Forsikre deg om at du fortsatt vil ha den aktivert, eller slå den av i appen."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Midlertidig justering for treningsøkter er fortsatt på"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Ja"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Du får kanskje ikke lyd-, visuelle eller vibrasjonsvarsler angående kritisk sikkerhetsinformasjon. \n\n For å fikse problemet, trykk på \"Innstillinger\" og sørg for at varsler, kritiske varsler og tidssensitive varsler er slått PÅ."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Tidsinnstillingen til %1$@ er endret. %2$@ trenger nøyaktige tidsregistreringer for å gi spådommer om blodsukker og justere insulinet deretter. \n\nSjekk inn %1$@ innstillingene (Generelt / Dato og klokkeslett) og bekreft at 'Sett automatisk' er slått PÅ. Unnlatelse av å løse problemet kan føre til alvorlig under- eller overlevering av insulin."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Blodsukkeret ditt er under %1$@ . Er du sikker på at du vil gi bolus?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Blodsukkeret ditt er under eller forventes å gå under BS-sikkerhetsgrensen din, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Din glukose er under din glukosesikkerhetsgrense, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Din glukose er lav. Spis karbohydrater og vurder å vente med bolus til glukosen er innenfor et trygt område."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Din glukose er lav. Spis karbohydrater og følg nøye med."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Din maksimale bolusmengde er %1$@ ."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Pumpedataene er foreldede. %1$@ kan ikke anbefale en bolusmengde."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Pumpen leverer en manuell midlertidig basaldose."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Den anbefalte bolusen overskrider den maksimale bolusmengden på %1$@ ."; -"Review Alert Permissions" = "Sjekk varslingsinnstillinger"; -"Alert Permissions" = "Varslingsinnstillinger"; -"Alert Permissions Need Attention" = "Varslingsinnstillinger trenger tilsyn"; -"mmol/L" = "mmol/L"; -"No Recent Glucose" = "Ingen ny glukose"; -"No Recent Glucose Data" = "Ingen ny glukosedata"; -"Tap to Add" = "Trykk for å legge til"; -"Closed Loop requires an active CGM Sensor Session" = "Lukket Loop krever en aktiv glukosemåler"; -"Dosing Strategy" = "Doseringsstrategi"; -"Automatic Bolus" = "Automatisk bolus"; -"Tap here to set up a pump" = "Trykk her for å sette opp en pumpe"; -"Tap here to set up a Service" = "Trykk her for å sette opp en tjeneste"; -"Support" = "Hjelp"; -"Enter Bolus" = "Skriv inn bolus"; -"Active Carbs" = "Aktive karbohydrater"; -"Fingerstick Glucose" = "Blodsukkerverdi fra fingerstikk"; -"Enter Fingerstick Glucose" = "Legg inn blodsukkerverdi fra fingerstikk"; -"Bolus Summary" = "Bolusoppsummering"; -"Recommended Bolus" = "Anbefalt bolus"; -"Carb Entry" = "Legg til karbohydrater"; -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Velg en lengre absorpsjonstid for større måltider, eller de som inneholder fett og proteiner. Dette er bare veiledning til algoritmen og trenger ikke være nøyaktig."; -"Use Pre-Meal Preset" = "Bruk pre-måltidsmål"; -"Until I enter carbs" = "Til jeg legger inn karbohydrater"; -"Enter a blood glucose from a meter for a recommended bolus amount." = "Legg inn glukoseverdi fra en måler for anbefalt mengede bolus"; -"Custom Preset" = "Egendefinerte tilpasninger"; -"History" = "Historie"; -"Tap '+' to create a new custom preset." = "Trykk '+' for å opprette ny egendefinert tilpasning"; -"Enable" = "Aktiver"; -"Get help with Alert Permissions" = "Få hjelp med varslingsinnstillinger"; -"On" = "På"; -"OK" = "OK"; -"Notifications give you important %1$@ app information without requiring you to open the app." = "Varslinger gir deg viktig %1$@ app informasjon uten at du behøver å åpne appen."; -"It is important that you always keep %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications turned ON in your phone’s settings to ensure that you get notified by the app." = "Det er viktig at du alltid holder %1$@ varsler, kritiske varsler og tidssensitive varsler aktivert i telefonens innstillinger for å sikre at du blir varslet av appen."; -"– – –" = "– – –"; -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; -"Tap here to set up a CGM" = "Trykk her for å sette opp en glucosemåler"; -"Off" = "Av"; -"Critical" = "Kristisk"; -"Critical Alerts" = "Kristiske varsler"; -"Manage Permissions in Settings" = "Behandle tillatelser i Innstillinger"; -"Notifications" = "Varsler"; -"Done" = "Ferdig"; -"carb-entry-title-add" = "Legg til karbohydrater"; -"Absorption Time" = "Absorpsjonstid"; -"Delete" = "Slett"; -"Temp Basal Only" = "Kun midlertidig basal"; -"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Lopp vil sette bolus når insulinbehovet er over planlagt basal, og vil bruke midlertidige basale rater når det er nødvendig for å redusere insulintilførselen under planlagt basal"; -"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop vil sette midlertidige basal rater for å øke og redusere insulin levering."; -"CGM Settings" = "Innstillinger for glukosemåler"; -"-" = "-"; -"Pump Settings" = "Innstillinger for pumpe"; -"Novolog" = "Novolog"; -"Delete Testing Pump Data" = "Slett data for testpumpe"; -"Insulin Pump" = "Insulinpumpe"; -"Therapy Settings" = "Behandlingsinnstillinger"; -"Diabetes Treatment" = "Diabetesbehandling"; -"Clear Last Version Check Alert" = "Fjern varsel om kontroll av siste versjon"; -"Mock Version Check %@" = "Test versjonssjekk %@"; -"Export Critical Event Logs" = "Eksporter kritiske hendelseslogger"; -"How should the simulator respond to a version check?" = "Hvordan skal simulatoren svar på en versjonssjekk?"; -"Version Check Response" = "Svar på versjonssjekk"; -"Critical Update" = "Kristisk oppdatering"; -"Recommended Update" = "Anbefalt oppdatering"; -"Update Available" = "Oppdatering tilgjnegelig"; -"No Update" = "Ingen oppdatering"; -"Glucose Safety Limit" = "Glukose sikkerhetsgrense"; -"%1$@ will deliver basal and recommend bolus insulin only if your glucose is predicted to be above this limit for the next three hours." = "%1$@ leverer basal og anbefaler bolusinsulin bare hvis glukose forventes å være over denne grensen for de neste tre timene"; -"Correction Range" = "Korreksjonsområde"; -"%@ Range" = "%@ område"; -"Pre-Meal" = "Pre-måltid"; -"Temporarily lower your glucose target before a meal to impact post-meal glucose spikes." = "Senk glokusemålet midlertidig før et måltid for å påvirke blodsukkertopper etter måltidet."; -"Carb Ratios" = "Karbohydratsforhold"; -"Your Carb Ratio is the number of grams of carbohydrates covered by one unit of insulin." = "Karbohydratforholdet er antall gram karbohydrater dekket av en enhet insulin."; -"Basal Rates" = "Basal ratio"; -"Your Basal Rate of insulin is the number of units per hour that you want to use to cover your background insulin needs." = "Din basalrate av insulin er antall enheter per time som du ønsker å bruke for å dekke ditt grunnleggende insulin behov."; -"Delivery Limits" = "Leveringsgrenser"; -"Maximum Basal Rate is the highest temporary basal rate %1$@ is allowed to set automatically." = "Maksimal basalrate er den høyeste midlertidige basalhastigheten %1$@ kan angis automatisk."; -"Maximum Bolus" = "Maks bolus"; -"Maximum Basal Rate" = "Maks basalrate"; -"Insulin Model" = "Insulinmodell"; -"For fast acting insulin, %1$@ assumes it is actively working for 6 hours. You can choose from different models for the peak activity." = "For hurtigvirkende insulin antar %1$@ at det arbeider aktivt i 6 timer. Du kan velge mellom forskjellige modeller for toppaktivitet."; -"Rapid-Acting – Children" = "Hurtigvirkende – Barn"; -"This model assumes peak insulin activity at 65 minutes." = "Denne modellen antar topp insulinaktivitet på 65 minutter."; -"Insulin Sensitivities" = "Insulinfølsomhet"; -"Maximum Bolus is the highest bolus amount you can deliver at one time to cover carbs or bring down high glucose." = "Maksimal bolus er den høyeste bolusmengden du kan levere på en gang for å dekke karbohydrater eller få ned høy glukose."; -"Notification delivery is set to Scheduled Summary in your phone’s settings." = "Varslingslevering er satt til planlagt oppsummering i telefonens innstillinger."; -"Delete Testing CGM Data" = "Slett data for testglukosemåler"; -"Notifications Delayed" = "Varsler forsinket"; diff --git a/Loop/nb.lproj/Main.strings b/Loop/nb.lproj/Main.strings index 9df15070f8..c366e5007c 100644 --- a/Loop/nb.lproj/Main.strings +++ b/Loop/nb.lproj/Main.strings @@ -1,141 +1,111 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Status"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3,5 E/timen @ 12:12 PM"; - -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Pumpe-ID"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Bolusmengde"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; +"5gz-kZ-iF1.text" = "3,5 E/time @ 12:12"; /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Forventet"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detaljer"; +"aCb-Qs-bpu.text" = "Detalj"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Type mat"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "Etikett"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Blodsukkerendring"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Enheter"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "E"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Etikett"; +"bq4-98-cQU.text" = "Glukose endring"; /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g totalt"; +"d3X-AN-tA5.text" = "g Totalt"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "Fremtidig blodsukker forutsies ved å kombinere effektene av flere parametre. Bruk dette verktøyet til å bytte ulike parametre for å se hvordan de påvirker den endelige prediksjonen."; +"D4C-I2-dhA.text" = "Fremtidig glukose er spådd ved å kombinere effekten av flere inndata. Bruk dette verktøyet til å veksle mellom ulike inndata for å se hvordan de er sammenlignet med den endelige prediksjonen."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Etikett"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Innstillinger"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "APPARATER"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "omsider 92 mg/dL"; +"E41-FN-nkk.text" = "etterhvert 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Observert"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Aktive karbohydrater: 40g"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3,5 E/time @ 12:12"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Effekt av karbohydrater"; +"hZZ-2S-lrd.title" = "Karbohydrat effekt"; /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Observerte endringer i blodsukker, minus endringer fra levert insulin, kan brukes for å estimere absorpsjon av karbohydrater."; +"IxU-As-glo.text" = "Observerte endringer i glukose, subtrahering av endringer modellert fra insulintilførsel, kan brukes til å estimere karbohydratabsorpsjon."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detaljer"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Forventet blodsukker under område"; +"J7x-W5-gwo.text" = "Detalj"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Anbefalt basal"; +"k3F-Na-7mn.text" = "Anbefalt Basal"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Etikett"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Etikett"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Trykk for å velge"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Enheter"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "E"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Etikett"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Forventet blodsukker"; +"PA3-sP-cWY.title" = "Forventet Glukose"; + +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insulinmodell"; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "En insulinaktivitetsmodell brukes til å estimere effekten av insulin på blodsukkeret. En nøyaktig modell kan bidra til å forhindre insulinstacking samt anbefale korrigerende tiltak"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Type mat"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ -"Rse-x8-amW.text" = "omsider 92 mg/dL"; +"Rse-x8-amW.text" = "etterhvert 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g KaB"; +"SQx-au-ZcM.text" = "g Aktive karbohydrater"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glukose"; +"tuw-av-A3x.text" = "Blodsukker"; + +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Legg til/endre karbohydrater"; /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ "ufi-Kj-33k.text" = "Etikett"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Aktivt insulin: 1,5E"; - /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Karbohydrater"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 timer"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Mengde karbohydrater\n(Mengde inntatt)"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Anbefalt Basal"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Lever"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Anbefalt"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "Tittel"; diff --git a/Loop/nl.lproj/InfoPlist.strings b/Loop/nl.lproj/InfoPlist.strings index f8b78ef480..6309d4246c 100644 --- a/Loop/nl.lproj/InfoPlist.strings +++ b/Loop/nl.lproj/InfoPlist.strings @@ -1,18 +1,27 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth wordt gebruikt om te communiceren met de insuline pomp en de continue glucose meter."; +"NSBluetoothAlwaysUsageDescription" = "Bluetooth wordt gebruikt om te communiceren met de insulinepomp en de continue glucosemeters."; /* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Bluetooth wordt gebruikt om te communiceren met de insuline pomp en de continue glucose meter."; +"NSBluetoothPeripheralUsageDescription" = "Bluetooth wordt gebruikt om te communiceren met de insulinepomp en de continue glucosemeters."; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Camera wordt gebruikt om barcodes van apparaten te scannen."; /* Privacy - Face ID Usage Description */ -"NSFaceIDUsageDescription" = "Face ID wordt gebruikt om de insuline bolus te verifiëren."; +"NSFaceIDUsageDescription" = "Face ID wordt gebruikt om de insulinebolus te authenticeren en om wijzigingen in de therapieinstellingen op te slaan."; /* Privacy - Health Share Usage Description */ -"NSHealthShareUsageDescription" = "Maaltijd data van de Health database wordt gebruikt om de effecten op glucose te bepalen.Glucose data vanuit de Health database worden gebruikt voor het berekenen en weergeven van het momentum "; +"NSHealthShareUsageDescription" = "Maaltijdgegevens uit de database Gezondheid worden gebruikt om glucoseëffecten te bepalen. Glucosegegevens uit de database Gezondheid worden gebruikt voor grafieken en het berekenen van trendlijnen. Slaapgegevens uit de database Gezondheid worden gebruikt om de Apple Watch complicatie bij te werken."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Koolhydraten van de maaltijd die worden ingevoerd in de app op de apple watch worden opgeslagen in de Gezondheid database. Glucose gegevens ontvangen van de CGM wordt veilig opgeslagen in Gezondheid."; +"NSHealthUpdateUsageDescription" = "Maaltijdkoolhydraten die worden ingevoerd in de app en met de watch worden opgeslagen in de database Gezondheid. Ontvangen glucosegegevens van de CGM worden veilig opgeslagen in HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop gebruikt Siri om programma's met je stem te laten uitvoeren."; diff --git a/Loop/nl.lproj/Localizable.strings b/Loop/nl.lproj/Localizable.strings index 01804fc54a..8c433b6c6c 100644 --- a/Loop/nl.lproj/Localizable.strings +++ b/Loop/nl.lproj/Localizable.strings @@ -1,32 +1,83 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (Wachten: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Pre-Meal Programma"; + +/* remaining time in setting's profile expiration section */ +" remaining" = " resterend"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = " Veiligheidsmeldingen staan UIT"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Trainingsprogramma"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– –"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ -"%@ absorbed" = "%@ opgenomen"; +"%@ absorbed" = "%@ geabsorbeerd"; + +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ resterend"; /* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ E totaal"; +"%@ U Total" = "%@ E Totaal"; /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ kon je huidige tijdelijke basaalsnelheid niet annuleren, die hoger is dan de nieuwe Maximale Basaallimiet die je hebt ingesteld. Dit kan leiden tot een hogere insulinetoediening dan gewenst. \n\nOverweeg om de insulinetoediening handmatig te onderbreken en dan direct het hervatten van de basaaltoediening uit te laten voeren met de nieuwe geldende limiet."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +"%1$@ – %2$@ %3$@" = "%1$@ - %2$@ %3$@"; + +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; /* Format string for carb ratio average. (1: value)(2: carb unit) */ -"%1$@ %2$@/U" = "%1$@ %2$@/E"; +"%1$@ %2$@/U" = "%1$@ %2$@ /E"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ werkt met Gesloten Loop in de UIT stand. Je pomp en CGM blijven werken, maar de app past de dosering niet automatisch aan."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ kan de melding niet wissen van je apparaat"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ kan niet communiceren met je insulinepomp. De app blijft proberen je pomp te bereiken, maar de insulinetoedieningsinformatie kan niet worden bijgewerkt en automatisering kan niet plaatsvinden.\nJe kunt enkele minuten wachten om te zien of het probleem is opgelost of tik op de onderstaande knop voor meer informatie over andere opties."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Tijdinstellingen Hebben Aandacht Nodig"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ E"; + /* Low reservoir alert format string. (1: Number of units remaining) */ -"%1$@ U left" = "%1$@ E resterend"; +"%1$@ U left" = "%1$@ E over"; /* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ -"%1$@ U left: %2$@" = "%1$@ E resterend: %2$@"; +"%1$@ U left: %2$@" = "%1$@ E over: %2$@"; /* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ "%1$@ U/hour @ %2$@" = "%1$@ E/uur @ %2$@"; @@ -34,118 +85,239 @@ /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ stopt met werken in %2$@. Je zult eerder moeten updaten, met een nieuw beschikbaargesteld profiel."; + /* Formats (1: carb value) and (2: food type) */ -"%1$@: %2$@" = "%1$@: %2$@"; +"%1$@: %2$@" = "%1$@ : %2$@"; + +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; /* Description of the prediction input effect for glucose momentum */ -"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 minuten glucose regressie coëficient (b1), continue zonder afbouw over 30 min"; +"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 min glucose regressiecoëficiënt (b₁), gevolgd door afbouw over 30 min"; /* Description of the prediction input effect for retrospective correction */ -"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min vergelijking van glucose voorspelling versus actueel, gevolgd door afbouw over 60 min"; +"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min vergelijking van glucosevoorspelling versus de werkelijke, gevolgd door afbouw over 60 min"; + +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Nog een paar seconden"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Een handmatige glucose-invoer moet tussen %1$@ en %2$@ liggen"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Een handmatige glucose-invoer moet tussen %1$@ en %2$@ liggen."; /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "Een model gebaseerd op de gepubliceerde opname van Fiasp insuline."; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Een model gebaseerd op de gepubliceerde opname van Humalog, Novorapid, en Apidra insuline bij volwassenen."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Een model gebaseerd op de gepubliceerde absorptie van Humalog-, Novolog- en Apidra-insuline bij volwassenen."; + +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "Er is een nieuwe versie van %@ beschikbaar die aanbevolen wordt om de app te kunnen blijven gebruiken."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Er is een nieuwe versie van %@ beschikbaar."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Een pomp moet worden geconfigureerd voordat een bolus kan worden toegediend."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Opnametijd"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AccepteerVoorgesteldeBolus"; /* The title of the Carbs On-Board graph */ -"Active Carbohydrates" = "Actieve koolhydraten"; +"Active Carbohydrates" = "Actieve Koolhydraten"; /* The string format describing active carbohydrates. (1: localized glucose value description) */ -"Active Carbohydrates: %@" = "Actieve koolhydraten: %@"; +"Active Carbohydrates: %@" = "Actieve Koolhydraten: %@"; + +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Actieve Koolhydraten"; /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Actieve insuline"; +"Active Insulin" = "Actieve Insuline"; /* The string format describing active insulin. (1: localized insulin value description) */ -"Active Insulin: %@" = "Actieve insuline: %@"; +"Active Insulin: %@" = "Actieve Insuline: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Voeg koolhydraten toe"; +"Add Carb Entry" = "Kh. Inv. Toevoegen"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "Voeg CGM toe"; -/* The label of the carb entry button */ -"Add Meal" = "Voeg maaltijd toe"; +/* The label of the meal button */ +"Add Meal" = "Voeg Maaltijd toe"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ -"Add Pump" = "Voeg pomp toe"; +"Add Pump" = "Voeg Pomp toe"; /* Title text for button to set up a service */ -"Add Service" = "Add Service"; +"Add Service" = "Service Toevoegen"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* No comment provided by engineer. */ +"Adjusted for" = "Aangepast voor"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Meldingbeheer"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Toestemming Meldingen"; /* The title of the section containing algorithm settings */ -"Algorithm Settings" = "Algoritme instellingen"; +"Algorithm Settings" = "Algoritme-instellingen"; + +/* The title of the Amplitude service */ +"Amplitude" = "Amplitude"; + +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Een actieve override wijzigt je koolhydraatratio en je insulinegevoeligheid. Als je niet wilt dat dit je bolusberekening en voorspelde glucose beïnvloedt, kun je overwegen de override uit te schakelen."; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Een aanpassing aan het volwassen model gebaseerd om praktijk effecten bij kinderen."; +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Er is een fout opgetreden tijdens het opslaan van je koolhydraatinvoer."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Er is een fout opgetreden tijdens het opslaan van je handmatige glucose-invoer."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Er is een onverwachte onboarding-foutstatus opgetreden"; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Een bijgewerkte aanbevolen bolus is beschikbaar."; + +/* The title of the amplitude API key credential */ +"API Key" = "API Key"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* Settings app profile section */ +"App Profile" = "App-Profiel"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Weet je zeker dat je de gehele pompgeschiedenis wilt verwijderen?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Weet je zeker dat je de gehele doseringsgeschiedenis wilt verwijderen?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Weet je zeker dat je alle waarden van het reservoir wilt verwijderen?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Weet je zeker dat je al je %@ Gegevens wilt verwijderen?\n(Deze actie is niet omkeerbaar)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Weet je zeker dat je de CGM wilt verwijderen"; +"Are you sure you want to delete this CGM?" = "Weet je zeker dat je deze CGM wilt verwijderen"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Weet je zeker dat je deze service wil verwijderen?"; /* Format fragment for a specific time */ -"at %@" = "bij %@"; +"at %@" = "om %@"; /* The message displayed during a device authentication prompt for bolus specification */ -"Authenticate to Bolus %@ Units" = "Authenticeer om te bolussen %@ E"; +"Authenticate to Bolus %@ Units" = "Authenticeer om %@ E te Bolussen"; + +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Authenticeer om %@ Eenheden te registreren"; /* Details for configuration error when basal rate schedule is missing */ -"Basal Rate Schedule" = "Basaal schema"; +"Basal Rate Schedule" = "Basaalsnelheidschema"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Basaal waardes"; +"Basal Rates" = "Basaalsnelheden"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Op basis van je voorspelde glucose, wordt een bolus niet aanbevolen."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth\nUit"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth\nNiet Beschikbaar"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Bluetooth Uit Melding"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Bluetooth Niet Beschikbaar Melding"; /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Bolus"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Bolusprobleem"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Aanbevolen Bolus Bijgewerkt"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Bolussamenvatting"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus Te Klein"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ -"Bolused %1$@ of %2$@" = "Bolused %1$@ van %2$@"; +"Bolused %1$@ of %2$@" = "%1$@ van %2$@ gebolust"; /* The format string for bolus in progress showing total volume. (1: total volume) */ -"Bolusing %1$@" = "Geef bolus %1$@"; +"Bolusing %1$@" = "Bolussen %1$@"; /* The title of the cancel action in an action sheet */ "Cancel" = "Annuleer"; /* The title of the cell indicating a bolus is being canceled */ -"Canceling Bolus" = "Annuleer Bolus"; +"Canceling Bolus" = "Bolus Annuleren"; /* Details for missing data error when carb effects are missing */ -"Carb effects" = "Koolhydraten impact"; +"Carb effects" = "Koolhydraateffecten"; + +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Koolhydraatinvoer"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Koolhydraatratioschema"; /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Koolhydraten ratio's"; +"Carb Ratios" = "Koolhydraatratio's"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Kh. Inv. Toevoegen"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Kh. Inv. Bewerken"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Koolhydraatinvoer Te Veel"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Koolhydraten"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Koolhydraten geabsorbeerd (gr) ÷ Koolhydraten per eenheid insuline (gr/E) × Insuline gevoeligheid (%1$@/E)"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Opgenomen Koolhydraten (g) ÷ Koolhydraatratio (g/E) × Insulinegevoeligheid (%1$@/E)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Vervang direct de pomp batterij"; +"Change the pump battery immediately" = "Vervang direct de batterij van de pomp"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Vervang direct het pomp reservoir"; +"Change the pump reservoir now" = "Vervang het pompreservoir nu"; /* Details for configuration error when one or more loop settings are missing */ -"Check settings" = "Controleer je instellingen"; +"Check settings" = "Controleer instellingen"; /* Recovery suggestion when reservoir data is missing */ "Check that your pump is in range" = "Controleer of je pomp binnen bereik is"; @@ -153,237 +325,827 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Controleer je CGM gegevensbron"; +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Controleer de tijd op je apparaat en/of verwijder eventuele ongeldige invoer uit Apple Gezondheid."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Kies een langere opnametijd voor grotere maaltijden of voor maaltijden die vetten en eiwitten bevatten. Dit is alleen een leidraad voor het algoritme en hoeft niet exact te zijn."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Sluiten"; + /* The title text for the looping enabled switch cell */ -"Closed Loop" = "Gesloten loop"; +"Closed Loop" = "Gesloten Loop"; + +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Gesloten Loop UIT"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Gesloten Loop vereist een actieve CGM Sensorsessie"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Gesloten Loop vereist dat Installatie is Voltooid"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "om %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "sinds %1$@"; /* The title of the action used to dismiss an error alert */ -"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +"com.loudnate.LoopKit.errorAlertActionTitle" = "Ok"; + +/* Title text for button to complete setup */ +"Complete Setup" = "Volledige Installatie"; /* The title of the configuration section in settings */ "Configuration" = "Configuratie"; /* The error message displayed for configuration errors. (1: configuration error details) */ -"Configuration Error: %1$@" = "Configuratie fout: %1$@"; +"Configuration Error: %1$@" = "Configuratiefout: %1$@"; + +/* Default alert dismissal */ +"Continue" = "Ga Verder"; /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Continue Glucose Monitor"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "Correctie bereik"; +"Correction Range" = "Correctiebereik"; + +/* Critical Alerts Status text */ +"Critical Alerts" = "Kritieke Meldingen"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Kritieke Gebeurtenislogboek Klaar"; + +/* Critical event log export title */ +"Critical Event Logs" = "Kritieke Gebeurtenislogboek"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Kritieke Gebeurtenislogboek konden niet worden geëxporteerd."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Huidige Glucose"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Huidige glucose van %1$@ is lager dan het correctie bereik"; +"Current glucose of %1$@ is below correction range." = "Huidige glucose %1$@ is lager dan het correctiebereik."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Aangepast programma"; +"Custom Override" = "Aangepaste Override"; + +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Aangepast Programma"; + +/* Date picker label */ +"Date" = "Datum"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Delete" = "Verwijderen"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Verwijder Account"; + +/* Button title to delete all objects */ +"Delete All" = "Verwijder Alles"; /* Button title to delete CGM */ "Delete CGM" = "Verwijder CGM"; -/* The title of the button to remove the credentials for a service */ -"Delete Account" = "Verwijder account"; +/* Button title to delete a service */ +"Delete Service" = "Service Verwijderen"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Verwijder test-CGM-gegevens"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Testgegevens Verwijderen"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Testpompgegevens Verwijderen"; + +/* Button text to deliver a bolus */ +"Deliver" = "Toedienen"; /* Title text for delivery limits */ -"Delivery Limits" = "Toediening limieten"; +"Delivery Limits" = "Toedieningslimieten"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Diabetesbehandeling"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Was je van plan om %1$@ gram in te voeren als hoeveelheid koolhydraten voor deze maaltijd?"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Uitschakelen"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Sluiten"; + +/* No comment provided by engineer. */ +"Done" = "Gereed"; + +/* Title for card to log dose */ +"Dose Summary" = "Doseersamenvatting"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Doseerstrategie"; + +/* Remote command error description: duration exceed max (1: max duration in hours). */ +"Duration exceeds: %1$.1f hours" = "Duur overschrijdt: %1$.1f uur"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Bluetooth\nInschakelen"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Inschakelen"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Verkrijg een bloedglucose waarde van een meter voor een aanbevolen bolus hoeveelheid."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Bolus Invoeren"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Vul Vingerprikglucose In"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Voer glucoseveiligheidslimiet in"; + /* The placeholder text instructing users to enter a suspend treshold */ -"Enter suspend threshold" = "Voer drempel voor onderbreking insuline in"; +"Enter suspend threshold" = "Voer drempel voor onderbreking in"; /* The alert title for an error while canceling a bolus */ -"Error Canceling Bolus" = "Fout bij annuleren van bolus"; +"Error Canceling Bolus" = "Fout bij Annuleren Bolus"; + +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Fout bij exporteren logboeken"; /* The alert title for a resume error */ -"Error Resuming" = "Fout bij vervolgen"; +"Error Resuming" = "Fout Bij Hervatten"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Logboek"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Uiteindelijk %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Overschrijdt maximale toegestane bolus in instellingen"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Overschrijdt maximale toegestane koolhydraten"; + /* The title of the alert describing a maximum bolus validation error */ -"Exceeds Maximum Bolus" = "Overschrijdt maximale bolus"; +"Exceeds Maximum Bolus" = "Overschrijdt Maximale Bolus"; + +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Exporteer Kritieke Gebeurtenislogboek"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Exporteren: %1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Insulinetoediening Hervatten Mislukt"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Vingerprikglucose"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Los nu op door Meldingen, Kritieke Meldingen en Tijdgevoelige Meldingen AAN te zetten."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Voor %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Voorspelde bloedglucose kan nog steeds hoger zijn dan het streefbereik."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Voorspelde Glucose"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Krijg hulp bij Toestemming Meldingen"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glucose"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Glucose gegevens is %1$@ oud"; +"Glucose data is %1$@ old" = "Glucosegegevens zijn %1$@ oud"; /* Description of error when glucose data is missing */ -"Glucose data not available" = "Glucose gegevens niet beschikbaar"; +"Glucose data not available" = "Glucosegegevens niet beschikbaar"; + +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Glucosegegevens Nu Beschikbaar"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Glucose-invoer Buiten Bereik"; /* Title of the prediction input effect for glucose momentum */ -"Glucose Momentum" = "Glucose momentum"; +"Glucose Momentum" = "Glucosetrendlijn"; + +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Glucosestreefbereikschema"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Hoe bij te werken (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Onmiddellijk"; /* The title of a target alert action specifying an indefinitely long workout targets duration */ -"Indefinitely" = "Oneindig"; +"Indefinitely" = "Voor onbepaalde tijd"; + +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Maximale Invoer Overschreden"; /* Title of the prediction input effect for insulin */ "Insulin" = "Insuline"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Opgenomen insuline (E) x insuline gevoeligheid (%1$@/E)"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Opgenomen Insuline (E) x Insulinegevoeligheid (%1$@/E)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Insulineaanpassingen zijn uitgeschakeld!"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insuline toediening"; +"Insulin Delivery" = "Insulinetoediening"; /* Details for missing data error when insulin effects are missing */ -"Insulin effects" = "Insuline impact"; +"Insulin effects" = "Insulineëffecten"; /* Details for configuration error when insulin model is missing The title text for the insulin model setting row */ -"Insulin Model" = "Insuline model"; +"Insulin Model" = "Insulinemodel"; + +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Insulinepomp"; /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Insuline gevoeligheden"; +"Insulin Sensitivities" = "Insulinegevoeligheden"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Insulinegevoeligheidschema"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insuline Onderbroken"; + +/* Insulin type label */ +"Insulin Type" = "Insulinetype"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Onderbroken %1$@: %2$@ van %3$@ %4$@"; + +/* Remote command error description: invalid absorption time. */ +"Invalid absorption time: %d hours" = "Ongeldige opnametijd: %d uur"; + +/* Remote command error description: invalid bolus amount. */ +"Invalid Bolus Amount" = "Ongeldige bolushoeveelheid"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Ongeldige hoeveelheid koolhydraten"; /* The error message when invalid data was encountered. (1: details of invalid data) */ -"Invalid data: %1$@" = "Niet valide gegevens: %1$@"; +"Invalid data: %1$@" = "Ongeldige gegevens: %1$@"; + +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Ongeldige Toekomstige Glucose"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Ongeldige glucosemeting met een tijdstempel dat %1$@ in de toekomst ligt."; /* The title text for the issue report cell */ -"Issue Report" = "Incidenten rapportage"; +"Issue Report" = "Probleemrapportage"; + +/* The notification description for a meal that was possibly not logged in Loop. */ +"It looks like you may not have logged a meal you ate. Tap to log it now." = "Het lijkt erop dat je een maaltijd die je hebt gegeten niet hebt toegevoegd. Tik om het nu toe te voegen."; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Grote Maaltijd Ingevoerd"; /* Glucose HUD accessibility hint */ -"Launches CGM app" = "Start de CGM app op"; +"Launches CGM app" = "Lanceert CGM app"; + +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Meer Informatie"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Minder dan een minuut resterend"; /* The loading message for the diagnostic report screen */ "Loading..." = "Laden..."; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Registreer Dosis"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Geregistreerde Insulinedosis"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop is Vastgelopen"; + /* The notification title for a loop failure */ -"Loop Failure" = "Loop fout"; +"Loop Failure" = "Loopstoring"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop heeft een probleem met je Bluetoothinstellingen gedetecteerd en zal niet goed werken totdat Bluetooth wordt ingeschakeld. Je ontvangt geen glucosemetingen en je kunt niet bolussen."; + +/* Warning displayed when user is adding a meal from an missed meal notification */ +"Loop has detected an missed meal and estimated its size. Edit the carb amount to match the amount of any carbs you may have eaten." = "Loop heeft een gemiste maaltijd gedetecteerd en een schatting van de hoeveelheid gedaan. Bewerk de hoeveelheid koolhydraten, zodat deze overeenkomt met de hoeveelheid koolhydraten die je mogelijk hebt gegeten."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop is niet goed afgerond in %@"; +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop zal automatisch bolussen geven wanneer de insulinebehoefte groter is dan het ingestelde basaal, en Loop zal wanneer dat nodig is gebruik maken van tijdelijke basaalsnelheden om insulinetoediening te verlagen."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop werkt pas als Bluetooth is ingeschakeld. Je zult geen glucosemetingen ontvangen of een bolus kunnen toedienen."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop stelt tijdelijke basaalsnelheden in om de insulinetoediening te verhogen of te verlagen."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Lage Glucose"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Beheer Toestemming in Instellingen"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Doseer Handmatig: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Maximale Basaalsnelheid Per Uur"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maximale Bolus"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Maximale Bolus Overschreden"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Maximale Duur Overschreden"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Maaltijd Bolus"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* Title for missed meal notifications toggle */ +"Missed Meal Notifications" = "Gemiste Maaltijdmeldingen"; + /* The error message for missing data. (1: missing data details) */ -"Missing data: %1$@" = "Missende gegevens: %1$@"; +"Missing data: %1$@" = "Ontbrekende gegevens: %1$@"; + +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Maximaal toegestane bolus ontbreekt in instellingen"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* Details for missing data error when momentum effects are missing */ -"Momentum effects" = "Momentum impact"; +"Momentum effects" = "Trendlijneffecten"; + +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Meer Informatie"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Alle Waarschuwingen Dempen"; /* Sensor state description for the non-valid state */ -"Needs Attention" = "Aandacht vereist"; +"Needs Attention" = "Aandacht Nodig"; + +/* Remote command error description: negative duration error. */ +"Negative duration not allowed" = "Negatieve duur niet toegestaan"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Wanneer gedempt zijn waarschuwingen niet hoorbaar. Zodra beëindigd, zullen je waarschuwingen en alarmen weer afgaan zoals normaal."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Geen Bolus Aanbevolen"; /* The error message displayed for device connection errors. */ -"No connected devices, or failure during device connection" = "Geen gekoppelde apparaten, of fout bij apparaat verbinding"; +"No connected devices, or failure during device connection" = "Geen aangesloten apparaten of storingen tijdens het verbinden met het apparaat"; + +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Geen Maximale Bolus Geconfigureerd"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Geen Pomp Geconfigureerd"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Geen Recente Glucose"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Geen Recente Glucosegegevens"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Geen Recente Pompgegevens"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Nee, hoeveelheid aanpassen"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Afleveren Meldingen"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "De aflevering van meldingen in de instellingen van je telefoon staat op Gepland Overzicht.\n\nOm vertraging bij het ontvangen van meldingen van %1$@ te voorkomen, raden we je aan om de aflevering van meldingen in te stellen op Onmiddellijk Afleveren."; + +/* Notifications Status text */ +"Notifications" = "Sta meldingen toe"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Meldingen Vertraagd"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Meldingen geven je belangrijke %1$@ appinformatie zonder dat je de app hoeft te openen."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Meldingen geven je belangrijke %1$@ appinformatie zonder dat je de app hoeft te openen.\n\nHoud deze instellingen AAN in je telefooninstellingen om ervoor te zorgen dat %1$@ je Meldingen, Kritieke Meldingen en Tijdgevoelige Meldingen ontvangt."; + +/* Notification Setting Status is Off */ +"Off" = "Uit"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Oh nee! Loop is vastgelopen tijdens het toedienen, en insulineaanpassingen zijn gepauzeerd totdat dit dialoogvenster wordt gesloten. De doseringsgeschiedenis is mogelijk niet nauwkeurig. Bekijk de Insulinetoedieningsgrafieken en controleer je bloedglucose nauwkeurig."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "Ok"; + +/* Notification Setting Status is On */ +"On" = "Aan"; /* The title text for the override presets */ -"Override Presets" = "Aangepast programma’s"; +"Override Presets" = "Override Programma's"; + +/* The notification title for a meal that was possibly not logged in Loop. */ +"Possible Missed Meal" = "Mogelijk Gemiste Maaltijd"; /* The label of the pre-meal mode toggle button */ -"Pre-Meal Targets" = "Voor de maaltijd doelen"; +"Pre-Meal Targets" = "Pre-Meal Doelen"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Verwachte glucose op %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Voorspelde glucose om %1$@ is %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Voorspelde glucose is binnen bereik."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Voorspelde glucose van %1$@ ligt onder je ingestelde glucoseveiligheidslimiet."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Verwachte glucose van %1$@ is lager dan de onderbroken insuline drempel instelling."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Verwachte glucose van %1$@ is lager dan je ingestelde insulineonderbrekingsdrempel."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Voorspeld: %1$@\nActueel: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Kritieke Gebeurtenislogboek Voorbereiden"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Profiel Vervaldatum"; + +/* Time that profile expires */ +"Profile expires " = "Profiel verloopt "; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Profiel Verloopt Binnenkort"; + /* The title of the pump section in settings */ "Pump" = "Pomp"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Pomp batterij bijna leeg"; +"Pump Battery Low" = "Pompbatterij Bijna Leeg"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ -"Pump data is %1$@ old" = "Pomp gegevens is %1$@ oud"; +"Pump data is %1$@ old" = "Pompgegevens zijn %1$@ oud"; + +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pompgebeurtenis"; /* Details for configuration error when pump manager is missing */ -"Pump Manager" = "Pompbeheer"; +"Pump Manager" = "Pomp Manager"; + +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Pompmanager Fout: %1$@"; /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Pomp reservoir leeg"; +"Pump Reservoir Empty" = "Pompreservoir Leeg"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Pomp reservoir bijna leeg"; +"Pump Reservoir Low" = "Pompreservoir Bijna Leeg"; /* The title of the cell indicating the pump is suspended */ -"Pump Suspended" = "Pomp tijdelijk uitgeschakeld"; +"Pump Suspended" = "Pomp Onderbroken"; + +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pomp Onderbroken. Automatisch doseren is uitgeschakeld."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Snelwerkende - volwassenen"; +"Rapid-Acting – Adults" = "Snelwerkend - Volwassenen"; /* Title of insulin model preset */ -"Rapid-Acting – Children" = "Snelwerkende - kinderen"; +"Rapid-Acting – Children" = "Snelwerkend - Kinderen"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ "Recommendation expired: %1$@ old" = "Aanbeveling verlopen: %1$@ oud"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Voorgestelde basaal"; +"Recommended Basal" = "Aanbevolen Basaal"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Aanbevolen Bolus"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Aanbevolen Bolus Overschrijdt Maximale Bolus"; /* Accessibility hint describing recommended bolus units */ -"Recommended Bolus: %@ Units" = "Voorgestelde bolus: %@ Eenheden"; +"Recommended Bolus: %@ Units" = "Aanbevolen Bolus: %@ Eenheden"; + +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Remote Bolusinvoer: %@ E"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Remote Koolhydraatinvoer: %d gram"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Remote Opdracht Verlopen"; /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Reservoir"; /* Title of the prediction input effect for retrospective correction */ -"Retrospective Correction" = "Retroperspectieve correctie"; +"Retrospective Correction" = "Retroperspectieve Correctie"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Opnieuw proberen"; +"Retry" = "Opnieuw Proberen"; + +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Opslaan en Toedienen"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Opslaan zonder Bolussen"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Gepland"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Selecteer Periode Dempen"; /* The title of the services section in settings */ -"Services" = "Diensten"; +"Services" = "Services"; /* The label of the settings button */ "Settings" = "Instellingen"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Installatie Onvolledig"; + /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Toont laatste loop foutmelding"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Eenvoudige Boluscalculator"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Eenvoudige Maaltijdcalculator"; + /* Format fragment for a start time */ -"since %@" = "na %@"; +"since %@" = "sinds %@"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "Site URL"; + +/* Software update button link text */ +"Software Update" = "Software Update"; + +/* Remote command error description: invalid start time is out of range. */ +"Start time is out of range: %@" = "Starttijd is buiten bereik: %@"; /* The format for the description of a temporary override start date */ -"starting at %@" = "start op %@"; +"starting at %@" = "start om %@"; /* The title of the cell indicating a bolus is being sent */ -"Starting Bolus" = "Start bolus"; +"Starting Bolus" = "Bolus Starten"; + +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Ondersteuning"; /* The title text in settings */ "Suspend Threshold" = "Onderbrekingsdrempel"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Tik hier om een CGM in te stellen"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Tik hier om een pomp in te stellen"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Tik hier om een Service in te stellen"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Tik voor Toevoegen"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ -"Tap to Resume" = "Klik om te herstarten"; +"Tap to Resume" = "Tik voor Hervatten"; + +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Tik voor Stoppen"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Meldingen Tijdelijk Gedempt"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "De ingevoerde bolushoeveelheid is kleiner dan die minimaal toegediend kan worden."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Het bolusdoseeralgoritme gebruikt een meer conservatieve schatting van de verwachte bloedglucose dan wat wordt gebruikt om uw basaalsnelheid aan te passen.\n\nHierdoor kan je voorspelde bloedglucose na een bolus nog steeds hoger zijn dan je streefbereik."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "De aanbevolen bolus is bijgewerkt. Bevestig de bolus opnieuw."; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Het oude model dat door Loop wordt gebruikt, waardoor de actieduur kan worden aangepast."; +"The legacy model used by Loop, allowing customization of action duration." = "Het model gebruikt bij Loop, staat verandering van actieduur toe."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "De maximale opnametijd is %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "De maximaal toegestane hoeveelheid is %@ gram."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "De maximaal toegestane hoeveelheid is %1$@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "De maximale bolushoeveelheid is %@ E."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "De maximale bolushoeveelheid is %@ Eenheden"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "De maximale bolusinstelling moet worden ingesteld voordat een bolus kan worden afgeleverd."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "De opdracht op afstand is %.0f minuten geleden verlopen."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Therapieinstellingen"; + +/* Title of the carb entry date picker cell */ +"Time" = "Tijd"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Tijdgevoelige Meldingen"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Probeer Opnieuw"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Schakel Bluetooth in om waarschuwingen, alarmen of sensorglucosemetingen te ontvangen."; + /* The short unit display string for international units of insulin */ "U" = "E"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Kan Waarschuwing Niet Wissen"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Kan Pomp Niet Bereiken"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Kan Koolhydraatinvoer Niet Opslaan"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Kan Handmatige Glucose-invoer Niet Opslaan"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Kan de toedienende bolus niet stoppen. Plaats je iPhone dichter bij de pomp en probeer het opnieuw. Controleer je insulinetoedieningsgeschiedenis voor details, en houd je glucose nauwlettend in de gaten."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Onbekend"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Onbekende Fout: %1$@"; + +/* Remote command error description: unknown preset (1: preset name). */ +"Unknown preset: %1$@" = "Onbekende voorinstelling: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Onbekende tijd"; + /* The format for the description of a temporary override end date */ "until %@" = "tot %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Totdat ik koolhydraten invoer"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Totdat ik uitschakel"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Gebruik Pre-Meal Programma"; + /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Gebruik training glucose doelen"; +"Use Workout Glucose Targets" = "Gebruik Trainingsglucosedoelen"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Gebruik Trainingsprogramma"; /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Waarschuwing! Veiligheidsmeldingen staan UIT"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Wanneer de huidige of voorspelde glucose onder de glucoseveiligheidslimiet ligt, zal Loop geen bolus aanbevelen en zal het altijd een tijdelijke basissnelheid van 0 eenheden per uur aanbevelen."; + /* Explanation of suspend threshold */ -"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Wanneer de huidige of voorspelde glucose onder de drempel voor onderbreken ligt, zal Loop geen bolus aanbevelen en zal altijd een tijdelijke basaal van 0 eenheden per uur aanbevelen."; +"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Wanneer de huidige of voorspelde glucose onder de onderbrekingsdrempel ligt, zal Loop geen bolus aanbevelen en zal Loop altijd een tijdelijke basaalsnelheid van 0 eenheden per uur aanbevelen."; + +/* Description of missed meal notifications. */ +"When enabled, Loop can notify you when it detects a meal that wasn't logged." = "Indien ingeschakeld, kan Loop je op de hoogte stellen wanneer het een maaltijd detecteert die niet is toegevoegd."; + +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Als de Gesloten Loop modus is uitgeschakeld, gebruikt de app een vereenvoudigde boluscalculator zoals bij een gewone pomp."; /* The label of the workout mode toggle button */ -"Workout Targets" = "Trainings doel waardes"; +"Workout Targets" = "Trainingsdoelen"; + +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Tijdelijk Trainingsprogramma staat meer dan 24 uur ingeschakeld. Zorg ervoor dat je deze nog steeds wilt inschakelen of schakel deze uit in de app."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Tijdelijk Trainingsprogramma Nog Steeds Aan"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Ja"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Mogelijk ontvangt je geen geluids-, visuele of trillingswaarschuwingen met betrekking tot kritieke veiligheidsinformatie. \n\nOm het probleem op te lossen, tikt op 'Instellingen' en zorg ervoor dat Meldingen, Kritieke Meldingen en Tijdgevoelige Meldingen AAN staan."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Je %1$@'s tijd is veranderd. %2$@ heeft nauwkeurige tijdsregistraties nodig om voorspellingen te doen over je glucose en dienovereenkomstig je insuline aan te passen.\n\nControleer in je %1$@ Instellingen (Algemeen / Datum & Tijd) en controleer of 'Automatisch Instellen' is INGESCHAKKELD. Als dit niet wordt opgelost, kan dit leiden tot ernstig te weinig toediening of tot ernstige overmatige toediening van insuline."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Je glucose is lager dan %1$@. Weet je zeker dat je een bolus wilt toedienen?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Je glucose is onder of zal naar verwachting onder je glucoseveiligheidslimiet komen, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Je glucose is onder je glucoseveiligheidslimiet, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Je glucose is laag. Eet koolhydraten en overweeg te wachten met een bolus totdat je glucose binnen een veilig bereik is."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Je glucose is laag. Eet koolhydraten en houd alles nauwlettend in de gaten."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Je maximale bolushoeveelheid is %1$@."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Je pompgegevens zijn verouderd. %1$@ kan geen bolushoeveelheid aanbevelen."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Je pomp geeft een handmatig ingestelde tijdelijke basaalsnelheid af."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Je aanbevolen bolus overschrijdt je maximale bolushoeveelheid van %1$@."; diff --git a/Loop/nl.lproj/Main.strings b/Loop/nl.lproj/Main.strings index 5096ca4576..3e4238380b 100644 --- a/Loop/nl.lproj/Main.strings +++ b/Loop/nl.lproj/Main.strings @@ -1,141 +1,111 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Status"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3,5 E/U @ 12:12 PM"; - -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Pomp ID"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Bolus hoeveelheid"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; +"5gz-kZ-iF1.text" = "3,5 E/uur @ 12:12 uur"; /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ -"87H-N1-0vJ.text" = "Voorspelde"; +"87H-N1-0vJ.text" = "Voorspeld"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ "aCb-Qs-bpu.text" = "Detail"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Type Eten"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "Etiket"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Glucose verandering"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Eenheden"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "E"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Etiket"; +"bq4-98-cQU.text" = "Glucoseverandering"; /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "gr totaal"; +"d3X-AN-tA5.text" = "g Totaal"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "De toekomstige glucose waarde wordt voorspeld door de effecten van meerdere input waardes mee te nemen. Gebruik deze tool om verschillende inputs aan en uit te zetten om ze zo te kunnen vergelijken met de uiteindelijke voorspelde waarde."; +"D4C-I2-dhA.text" = "De toekomstige glucosewaarde wordt voorspeld door de effecten van meerdere inputwaarden te combineren. Gebruik dit hulpmiddel om verschillende inputwaarden aan en uit te zetten om ze zo te kunnen vergelijken met de uiteindelijke voorspelde glucosewaarde."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Etiket"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Instellingen"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "Apparaten"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "uiteindelijk 92 mg/dL"; +"E41-FN-nkk.text" = "uiteindelijk 5,1 mmol/L"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ -"EAn-Ja-S1d.text" = "Geobserveerd"; +"EAn-Ja-S1d.text" = "Waargenomen"; + +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Actieve koolhydraten: 40gr"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3,5 E/uur @ 12:12 uur"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Effect koolhydraten"; +"hZZ-2S-lrd.title" = "Koolhydraateffect"; /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Geobserveerde veranderingen in glucose. Kan gebruikt worden om de verhouding insuline/koolhydraten in te schatten, minus de veranderingen die reeds door insuline toediening hebben plaatsgevonden."; +"IxU-As-glo.text" = "Waargenomen glucoseveranderingen, minus de veranderingen die al door insulinetoediening hebben plaatsgevonden, kunnen worden gebruikt om de koolhydraatopname in te schatten."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Detail"; -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Verwachte glucose lager dan bereik"; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Voorgestelde basaal"; +"k3F-Na-7mn.text" = "Aanbevolen Basaal"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Etiket"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Etiket"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Instellen…"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Eenheden"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "E"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Etiket"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Voorspelde glucose"; +"PA3-sP-cWY.title" = "Voorspelde bloedsuiker"; + +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insuline model"; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Een model voor insuline gevoeligheid wordt gebruikt om de effecten van insuline op de glucose waarde in te schatten. Het kiezen van het juiste model die jij gebruikt, helpt voorkomen dat insuline zich opstapelt en zorgt zo voor beter voorgestelde correcties."; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Type Eten"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ -"Rse-x8-amW.text" = "uiteindelijk 92 mg/dL"; +"Rse-x8-amW.text" = "uiteindelijk 5,1 mmol/L"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "gr KaB"; +"SQx-au-ZcM.text" = "g Actieve Kh"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ "tuw-av-A3x.text" = "Glucose"; +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Toevoegen/Bewerken Koolhydraatinvoer"; + /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ "ufi-Kj-33k.text" = "Etiket"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Actieve insuline: 1,5E"; - /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Koolhydraten"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 uur"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Hoeveelheid Gegeten"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Aanbevolen Basaal"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Toedienen"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Voorgestelde"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "Titel"; diff --git a/Loop/pl.lproj/InfoPlist.strings b/Loop/pl.lproj/InfoPlist.strings index d71717c5f8..f9c24ced75 100644 --- a/Loop/pl.lproj/InfoPlist.strings +++ b/Loop/pl.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; @@ -7,6 +10,9 @@ /* Privacy - Bluetooth Peripheral Usage Description */ "NSBluetoothPeripheralUsageDescription" = "Bluetooth jest używany do komunikacji z pompą i urządzeniami ciągłego monitoringu glukozy."; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Aparat służy do skanowania kodów kreskowych urządzeń."; + /* Privacy - Face ID Usage Description */ "NSFaceIDUsageDescription" = "Face ID jest używane do autoryzacji podaży bolusa."; @@ -15,3 +21,7 @@ /* Privacy - Health Update Usage Description */ "NSHealthUpdateUsageDescription" = "Posiłek węglowodanowy wprowadzony w aplikacji i na zegarku oraz dane o poziomie cukru pobrane z ciągłego monitoringu glukozy są bezpiecznie przechowywane w aplikacji Zdrowie."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop używa Siri, aby umożliwić wprowadzanie ustawień za pomocą głosu."; + diff --git a/Loop/pl.lproj/Localizable.strings b/Loop/pl.lproj/Localizable.strings index 0a8955060c..a8947c7975 100644 --- a/Loop/pl.lproj/Localizable.strings +++ b/Loop/pl.lproj/Localizable.strings @@ -1,12 +1,78 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (oczekujące: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Przed Posiłkiem"; + +/* remaining time in setting's profile expiration section */ +" remaining" = " pozostały"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = "Powiadomienia dotyczące bezpieczeństwa są WYŁĄCZONE"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Wstępne ustawienia treningu"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + +/* The format for an active override preset. (1: preset symbol)(2: preset name) */ +"%@ %@" = "%1$@ %2$@"; + +/* Formats absorbed carb value */ +"%@ absorbed" = "%@ zaabsorbowane"; + +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "Pozostało %@"; + +/* The subtitle format describing total insulin. (1: localized insulin total) */ +"%@ U Total" = "%@ J łącznie"; + +/* Appends a full-stop to a statement */ +"%@." = "%@."; + +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ nie mógł anulować bieżącej tymczasowej dawki podstawowej, która jest wyższa niż nowy ustawiony limit maksymalnej dawki podstawowej. Może to skutkować wyższym niż pożądane podawaniem insuliny. \n\n Rozważ ręczne wstrzymanie podawania insuliny, a następnie natychmiastowe wznowienie podawania dawki podstawowej z obowiązującym nowym limitem."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + +/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/J"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ działa z zamkniętą pętlą w pozycji OFF. Twoja pompa i CGM będą nadal działać, ale aplikacja nie będzie automatycznie dostosowywać insuliny."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ nie może usunąć alertu z Twojego urządzenia"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ nie może skomunikować się z Twoją pompą insulinową. Aplikacja będzie nadal próbowała połączyć się z pompą, ale nie można aktualizować informacji o podawaniu insuliny i nie można kontynuować automatyzacji.\n Możesz poczekać kilka minut, aby sprawdzić, czy problem został rozwiązany, lub nacisnąć poniższy przycisk, aby dowiedzieć się więcej o innych opcjach."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Ustawienia czasu wymagają uwagi"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ J"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ J pozostało"; @@ -19,23 +85,15 @@ /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; -/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ przestanie działać za %2$@ . Wcześniej konieczna będzie aktualizacja przy użyciu nowego profilu udostępniania."; /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; -/* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%1$@ %2$@"; - -/* Formats absorbed carb value */ -"%@ absorbed" = "%@ zaabsorbowane"; - -/* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ J łącznie"; - -/* Appends a full-stop to a statement */ -"%@." = "%@."; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 minutowy współczynnik regresji glukozy (b₁), kontynuowany z rozkładem przez 30 min."; @@ -43,12 +101,33 @@ /* Description of the prediction input effect for retrospective correction */ "30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 minutowe porównanie przewidywania stężenia glukozy w stosunku do rzeczywistego, kontynuowane z rozkładem przez 60 min."; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Pozostało kilka sekund"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Ręczny wpis poziomu glukozy musi mieścić się w przedziale od %1$@ do %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Ręczny wpis poziomu glukozy musi mieścić się w przedziale od %1$@ do %2$@ ."; + /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "Model oparty na opublikowanej absorpcji insulin Fiasp."; /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Model oparty na opublikowanej absorpcji insulin Humalog, Novolog/Novorapid i Apidra u dorosłych."; +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "Dostępna jest nowa wersja %@, która jest zalecana do dalszego korzystania z aplikacji."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Dostępna jest nowa wersja %@ ."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Przed podaniem bolusa należy skonfigurować pompę."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Czas absorpcji"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AcceptRecommendedBolus"; @@ -58,62 +137,140 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Aktywne węglowodany: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Aktywne węglowodany"; + /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Aktywna Insulina"; +"Active Insulin" = "Aktywna insulina"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "Aktywna Insulina: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Dodaj pozycję dla węglowodanów"; +"Add Carb Entry" = "Wprowadź węglowodany"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "Dodaj CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Dodaj posiłek"; -/* Title text for button to set up a new pump */ +/* Action sheet title selecting Pump + Title text for button to set up a new pump */ "Add Pump" = "Dodaj pompę"; /* Title text for button to set up a service */ -"Add Service" = "Add Service"; +"Add Service" = "Dodaj usługę"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* No comment provided by engineer. */ +"Adjusted for" = "Dostosowane do"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Zarządzanie alertami"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Uprawnienia alertów"; /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Ustawienia algorytmu"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Dostosowanie do modelu dorosłego opartego na efektach empirycznych u dzieci."; +/* The title of the Amplitude service */ +"Amplitude" = "Amplituda"; + +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Aktywny Cel Tymczasowy (Override) modyfikuje stosunek węglowodanów i wrażliwość na insulinę. Jeśli nie chcesz, aby wpłynęło to na obliczenie bolusa i przewidywaną glikemię, rozważ wyłączenie Celu Tymczasowego."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Wystąpił błąd podczas próby zapisania wpisu dotyczącego węglowodanów."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Wystąpił błąd podczas próby zapisania ręcznego wpisu o glukozie."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Niespodziewany błąd wdrażania"; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Dostępna jest zaktualizowana rekomendacja bolusa."; + +/* The title of the amplitude API key credential */ +"API Key" = "API Key"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* Settings app profile section */ +"App Profile" = "Profil aplikacji"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Czy jesteś pewien, że chcesz usunąć z Loop wszystkie dane historyczne pompy?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Czy na pewno chcesz usunąć wszystkie zapisane wpisy dawek?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Czy jesteś pewien, że chcesz usunąć wszystkie wartości zbiornika?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Czy na pewno chcesz usunąć wszystkie swoje dane %@ ?\n (Ta czynność jest nieodwracalna)"; /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Czy na pewno chcesz usunąć ten CGM?"; +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Czy na pewno chcesz usunąć tę usługę?"; + /* Format fragment for a specific time */ "at %@" = "o %@"; /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Autoryzacja Bolusa %@ jednostek"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Autoryzuj, aby podać %@ Jednostki"; + /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Harmonogram dawki standardowej"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Wartości bazy"; +"Basal Rates" = "Dawka Podstawowa (Baza)"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Na podstawie przewidywanej glikemii nie zaleca się podawania bolusa."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth jest wyłączony"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth niedostępny"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Alert! Bluetooth jest wyłączony!"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Alarm! Bluetooth niedostępny"; /* The label of the bolus entry button The notification title for a bolus failure */ -"Bolus" = "Bolusa"; +"Bolus" = "Bolus"; + +/* The notification title for a bolus issue */ +"Bolus Issue" = "Problem z bolusem"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Zaktualizowano rekomendowanego Bolus"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Podsumowanie bolusa"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Za mały Bolus"; /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ -"Bolused %1$@ of %2$@" = "Zbolusowano %1$@ of %2$@"; +"Bolused %1$@ of %2$@" = "Podano %1$@ of %2$@"; /* The format string for bolus in progress showing total volume. (1: total volume) */ "Bolusing %1$@" = "Bolusowanie %1$@"; @@ -127,9 +284,25 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "wpływ węglowodanów"; +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Wprowadź węglowodany"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Harmonogram Współczynnika Węglowodanowego"; + /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Wartości Węglowodanów"; +"Carb Ratios" = "Współczynniki węglowodanowe"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Wprowadź węglowodany"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Edytuj wprowadzone węglowodany"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Wpis węglowodanów za duży"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Węglowodany"; @@ -138,10 +311,10 @@ "Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Ilość węglowodanów (g) ÷ stosunek węglowodanów (g/J) × czułość insuliny (%1$@/J)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Zmień pilnie baterię w pompie"; +"Change the pump battery immediately" = "Natychmiast wymienić baterię pompy"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Uzupełnij insulinę w pompie"; +"Change the pump reservoir now" = "Zmień zbiorniczek w pompie"; /* Details for configuration error when one or more loop settings are missing */ "Check settings" = "Sprawdź ustawienia"; @@ -152,67 +325,218 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Sprawdź swój CGM"; +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Sprawdź czas urządzenia i/lub usuń wszelkie nieprawidłowe dane z aplikacji Zdrowie."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Wybierz dłuższy czas absorpcji dla większych, bogatobiałkowych lub wysokotłuszczowych posiłków. To tylko wskazówka dla algorytmu i nie musi być bardzo dokładna."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Zamknij"; + /* The title text for the looping enabled switch cell */ -"Closed Loop" = "Zamknięta Loop"; +"Closed Loop" = "Pętla Zamknięta"; + +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Pętla zamknięta WYŁĄCZONA"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Zamknięta pętla wymaga aktywnego sensora CGM"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Zamknięta pętla wymaga zakończenia konfiguracji"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "o %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "od %1$@"; /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +/* Title text for button to complete setup */ +"Complete Setup" = "Zakończ konfigurację"; + /* The title of the configuration section in settings */ "Configuration" = "Konfiguracja"; /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Błąd konfiguracji: %1$@"; +/* Default alert dismissal */ +"Continue" = "Kontynuuj"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Ciągły Monitoring Glukozy"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "Zakres korekty"; +"Correction Range" = "Zakres docelowy"; + +/* Critical Alerts Status text */ +"Critical Alerts" = "Alerty krytyczne"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Dziennik zdarzeń krytycznych gotowy"; + +/* Critical event log export title */ +"Critical Event Logs" = "Dzienniki zdarzeń krytycznych"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Nie można wyeksportować dzienników zdarzeń krytycznych."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Aktualna glukoza"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = "Poziom glukozy %1$@ jest poniżej wartości korekcji."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Pominięcie niestandardowe"; +"Custom Override" = "Custom Override"; -/* Button title to delete CGM */ -"Delete CGM" = "Usuń CGM"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Cel Tymczasowy"; + +/* Date picker label */ +"Date" = "Data"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Delete" = "Usunąć"; /* The title of the button to remove the credentials for a service */ "Delete Account" = "Usuń konto"; +/* Button title to delete all objects */ +"Delete All" = "Usuń wszystko"; + +/* Button title to delete CGM */ +"Delete CGM" = "Usuń CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Usuń usługę"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Usuń testowe dane CGM"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Usuń dane testowe"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Usuń dane pompy testowej"; + +/* Button text to deliver a bolus */ +"Deliver" = "Podaj Bolus"; + /* Title text for delivery limits */ -"Delivery Limits" = "Limit podaży"; +"Delivery Limits" = "Limity podawania"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "w leczeniu cukrzycy"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Czy zamierzałeś wprowadzić %1$@ gramów jako ilość węglowodanów dla tego posiłku?"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Wyłącza"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Odrzucać"; + +/* No comment provided by engineer. */ +"Done" = "Gotowe"; + +/* Title for card to log dose */ +"Dose Summary" = "Podsumowanie dawki"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Strategia dawkowania"; + +/* Remote command error description: duration exceed max (1: max duration in hours). */ +"Duration exceeds: %1$.1f hours" = "Czas trwania przekracza: %1$.1f godzin"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Włączać\nBluetooth"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Włącza"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Wprowadź poziom glukozy z glukometru, aby uzyskać zalecaną wielkość bolusa."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Wprowadź bolus"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Wprowadź glukozę z glukometru"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Wprowadź bezpieczny limit glukozy"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Wprowadź próg zawieszenia pompy"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Błąd anulowania bolusa"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Błąd podczas eksportowania dzienników"; + /* The alert title for a resume error */ "Error Resuming" = "Błąd wznawiania"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Historia zdarzeń"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "docelowo %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Przekracza maksymalny dozwolony bolus."; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Przekracza maksymalną dopuszczalną ilość węglowodanów"; + /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Osiągnięto bolus maksymalny"; +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Eksportuj dzienniki zdarzeń krytycznych"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Eksportuj- %1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Nie udało się wznowić podawania insuliny"; + /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Glukoza z krwi"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Włącz powiadomienia i alerty krytyczne."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Do %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Prognozowany poziom glukozy we krwi może nadal być wyższy niż zakres docelowy."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Prognozowana glukoza"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Uzyskaj pomoc dotyczącą uprawnień alertów"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glukoza"; @@ -222,20 +546,42 @@ /* Description of error when glucose data is missing */ "Glucose data not available" = "Dane o glukozie są niedostępne"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Dane dotyczące glukozy są już dostępne"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Wprowadzanie glukoza jest poza zakresem"; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Pęd glukozy"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Harmonogram zakresu docelowego glukozy"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Jak zaktualizować (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Natychmiastowy"; + /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Niemożliwy do określenia"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Za dużo węglowodanów"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Insulina"; /* Description of the prediction input effect for insulin */ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulina podana (U) × czułość insuliny (%1$@/J)"; +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Korekty insuliny zostały wyłączone!"; + /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Podaż insuliny"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "wpływ insuliny"; @@ -244,42 +590,222 @@ The title text for the insulin model setting row */ "Insulin Model" = "Model insuliny"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Pompa insulinowa"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Wrażliwość na insulinę"; +"Insulin Sensitivities" = "Wrażliwość na insulinę (ISF)"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Harmonogram wrażliwości na insulinę"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Podawanie insuliny zawieszone"; + +/* Insulin type label */ +"Insulin Type" = "Rodzaj insuliny"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Przerwane %1$@ : %2$@ z %3$@ %4$@"; + +/* Remote command error description: invalid absorption time. */ +"Invalid absorption time: %d hours" = "Nieprawidłowy czas absorpcji: %d godzin"; + +/* Remote command error description: invalid bolus amount. */ +"Invalid Bolus Amount" = "Nieprawidłowa wielkość bolusa"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Nieprawidłowa ilość węglowodanów"; /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Błędne dane: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Przyszła glukoza nie jest znana"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Nieprawidłowy odczyt glukozy ze znacznikiem czasu, który wynosi %1$@ w przyszłości"; + /* The title text for the issue report cell */ "Issue Report" = "Zgłaszanie błędów"; +/* The notification description for a meal that was possibly not logged in Loop. */ +"It looks like you may not have logged a meal you ate. Tap to log it now." = "Wygląda na to, że nie wprowadziłeś zjedzonego posiłku. Stuknij, aby dodać zaległy posiłek."; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Wprowadzono duży posiłek"; + /* Glucose HUD accessibility hint */ "Launches CGM app" = "Uruchamia aplikację CGM"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Dowiedz się więcej"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Pozostało mniej niż minutę"; + /* The loading message for the diagnostic report screen */ "Loading..." = "Ładowanie..."; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Zarejestruj dawkę"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Zarejestrowana dawka insuliny"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Pętla uległa awarii"; + /* The notification title for a loop failure */ -"Loop Failure" = "Błąd Loop"; +"Loop Failure" = "Awaria pętli"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop wykrył problem z ustawieniami Bluetooth i nie będzie działać poprawnie, dopóki Bluetooth nie zostanie włączony. Nie będziesz otrzymywać odczytów poziomu glukozy ani możliwości podania bolusa."; + +/* Warning displayed when user is adding a meal from an missed meal notification */ +"Loop has detected an missed meal and estimated its size. Edit the carb amount to match the amount of any carbs you may have eaten." = "Pętla wykryła pominięty posiłek i oszacowała jego wielkość. Edytuj ilość węglowodanów, aby odpowiadała ilości węglowodanów, które mogłeś zjeść."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop nie działał poprawnie przez %@"; +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Pętla automatycznie poda bolusa, kiedy zapotrzebowanie na insulinę przekroczy zaplanowaną dawkę podstawową, a w razie potrzeby zredukuje zaplanowaną dawkę podstawową (bazę)."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Pętla nie będzie działać pomyślnie, dopóki Bluetooth nie zostanie włączony. Nie będziesz otrzymywać odczytów poziomu glukozy ani możliwości podania bolusa."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Pętla ustawi tymczasowe dawki podstawowe, aby zwiększać lub zmniejszyć podawanie insuliny."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Niski poziom glukozy"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Zarządzaj uprawnieniami w Ustawieniach"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Dawka ręczna: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Maksymalna dawka podstawowa na godzinę"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maksymalny bolus"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Przekroczono maksymalny bolus"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Przekroczono maksymalny czas trwania"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Bolus Posiłkowy"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* Title for missed meal notifications toggle */ +"Missed Meal Notifications" = "Powiadomienia o pominiętych posiłkach"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Brakujące dane: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Brak ustawionego maksymalnego dozwolonego bolusa"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "wpływ pędu"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Więcej informacji"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Wycisz wszystkie alerty"; + /* Sensor state description for the non-valid state */ "Needs Attention" = "Potrzebuje uwagi"; +/* Remote command error description: negative duration error. */ +"Negative duration not allowed" = "Ujemny czas trwania nie jest dozwolony"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Po wyciszeniu nie będą emitowane żadne alerty. Po zakończeniu tego okresu alerty i alarmy zostaną wznowione normalnie."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Bolus nie jest zalecany"; + /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Brak podłączonych urządzeń lub awaria podczas połączenia urządzenia"; +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Nie skonfigurowano maksymalnego bolusa"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Nie skonfigurowano pompy"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Brak aktualnej glukozy"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Brak ostatnich danych dotyczących glukozy"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Brak ostatnich danych pompy"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Nie, edytuj ilość"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Dostarczanie powiadomień"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Dostarczanie powiadomień jest ustawione na Zaplanowane podsumowanie w ustawieniach telefonu. \n\nAby uniknąć opóźnień w otrzymywaniu powiadomień od %1$@ , zalecamy ustawienie dostarczania powiadomień na Natychmiastowe dostarczanie."; + +/* Notifications Status text */ +"Notifications" = "Powiadomienia"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Spóźnione Powiadomienia"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Powiadomienia zawierają ważne informacje o aplikacji %1$@ bez konieczności otwierania aplikacji."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Powiadomienia dostarczają ważnych informacji o aplikacji %1$@ bez konieczności otwierania aplikacji. \n\n Włącz je w ustawieniach telefonu, aby mieć pewność, że będziesz otrzymywać powiadomienia %1$@ , alerty krytyczne i powiadomienia czasowe."; + +/* Notification Setting Status is Off */ +"Off" = "Wyłącz"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "O nie! Pętla uległa awarii podczas dozowania, a regulacja insuliny została wstrzymana do czasu zamknięcia tego okna dialogowego. Historia dawkowania może nie być dokładna. Przejrzyj wykresy podawania insuliny i uważnie monitoruj poziom glukozy we krwi."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Włącz"; + /* The title text for the override presets */ -"Override Presets" = "Wstępne ustawienia pominięcia"; +"Override Presets" = "Override Presets"; + +/* The notification title for a meal that was possibly not logged in Loop. */ +"Possible Missed Meal" = "Możliwe pominięcie posiłku"; /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Poziom przed posiłkiem"; @@ -287,11 +813,29 @@ /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "Przewidywany poziom cukru o %1$@ wyniesie %2$@"; +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Przewidywane stężenie glukozy jest w zakresie."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Przewidywana glukoza %1$@ jest poniżej ustawionego bezpiecznego limitu glukozy."; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Przewidywany poziom cukru %1$@ jest poniżej progu zawieszenia."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ -"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Przewidywana: %1$@\Rzeczywista: %2$@ (%3$@)"; +"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Przewidywana: %1$@Rzeczywista: %2$@ (%3$@)"; + +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Przygotowywanie dzienników zdarzeń krytycznych"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Wygaśnięcie profilu:"; + +/* Time that profile expires */ +"Profile expires " = "Profil wygasa "; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Profil wkrótce wygaśnie"; /* The title of the pump section in settings */ "Pump" = "Pompa"; @@ -302,41 +846,82 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Dane z pompy są nieaktualne od %1$@"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Zdarzenie pompy"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Zarządzanie Pompą"; +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Błąd menedżera pompy: %1$@"; + /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Zbiornik w pompie jest pusty"; +"Pump Reservoir Empty" = "Zbiorniczek w pompie jest pusty"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Niski stan zbiornika w pompie"; +"Pump Reservoir Low" = "Niski poziom w zbiorniczku pompy"; /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pump Suspended"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pompa zawieszona. Automatyczne dozowanie jest wyłączone."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Szybko-działająca - Dorośli"; +"Rapid-Acting – Adults" = "Szybko działające – dorośli"; /* Title of insulin model preset */ -"Rapid-Acting – Children" = "Szybko-działająca - Dzieci"; +"Rapid-Acting – Children" = "Szybko działająca – dzieci"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ "Recommendation expired: %1$@ old" = "Rekomendacja nieaktualna od %1$@"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Rekomendowana baza"; +"Recommended Basal" = "Zalecana baza"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Zalecany bolus"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Zalecany bolus przekracza maksymalny bolus"; /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Rekomendowany bolus: %@ jednostek"; +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Zdalne podanie bolusa: %@ J"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Zdalne wprowadzanie węglowodanów: %d gramów"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Zdalne polecenie wygasło"; + /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "Zbiornik"; +"Reservoir" = "Zbiorniczek"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Korekcja retrospektywna"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Ponów"; +"Retry" = "Spróbuj ponownie"; + +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Zapisz i podaj"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Zapisz bez podania Bolusa"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Zaplanowane"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Wybierz okres wyciszenia"; /* The title of the services section in settings */ "Services" = "Usługi"; @@ -344,45 +929,223 @@ /* The label of the settings button */ "Settings" = "Ustawienia"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Konfiguracja niekompletna"; + /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Pokazuje ostatni błąd Loop"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Prosty kalkulator bolusa"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Prosty kalkulator posiłków"; + /* Format fragment for a start time */ "since %@" = "od %@"; +/* The title of the nightscout site URL credential */ +"Site URL" = "Strona URL"; + +/* Software update button link text */ +"Software Update" = "Aktualizacja oprogramowania"; + +/* Remote command error description: invalid start time is out of range. */ +"Start time is out of range: %@" = "Czas rozpoczęcia jest poza zakresem: %@"; + /* The format for the description of a temporary override start date */ "starting at %@" = "starting at %@"; /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Rozpoczynam podawanie bolusa"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Wsparcie"; + /* The title text in settings */ "Suspend Threshold" = "Próg zawieszenia pompy"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Stuknij tutaj, aby skonfigurować CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Stuknij tutaj, aby skonfigurować pompę"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Stuknij tutaj, aby skonfigurować usługę"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Dodaj glikemię"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ -"Tap to Resume" = "Dotknij, aby wznowić"; +"Tap to Resume" = "Stuknij, aby wznowić"; + +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Bolus STOP!"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Alarmy tymczasowo wyciszone"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Wprowadzona wielkość bolusa jest mniejsza niż minimalna możliwa do podania."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Algorytm dawkowania bolusa wykorzystuje bardziej ostrożne oszacowanie przewidywanego poziomu glukozy we krwi niż to, które jest używane do dostosowania dawki podstawowej. \n\nW rezultacie przewidywany poziom glukozy we krwi po podaniu bolusa może nadal być wyższy niż zakres docelowy."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "Rekomendacja dotycząca bolusa została zaktualizowana. Potwierdź ponownie wielkość bolusa."; /* Subtitle description of Walsh insulin model setting */ "The legacy model used by Loop, allowing customization of action duration." = "Model umożliwiający dostosowanie czasu działania insuliny."; +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Maksymalny czas absorpcji wynosi %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "Maksymalna dozwolona ilość to %@ gramów"; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "Maksymalna dozwolona ilość to: %1$@"; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Maksymalna wielkość bolusa to %@ J."; + /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Maksymalny bolus wynosi %@ jednostek"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Przed podaniem bolusa musi zostać skonfigurowane ustawienie maksymalnego bolusa."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Zdalne polecenie wygasło %.0f minut(y) temu."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Ustawienia terapii"; + +/* Title of the carb entry date picker cell */ +"Time" = "Czas"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Powiadomienia zależne od czasu"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Spróbuj ponownie"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Włącz Bluetooth, aby otrzymywać powiadomienia, alarmy lub odczyty poziomu glukozy z sensora."; + /* The short unit display string for international units of insulin */ "U" = "J"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Nie można wyczyścić alertu"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Nie można połączyć się z pompą"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Nie można zapisać wprowadzonych węglowodanów"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Nie można zapisać ręcznie wprowadzonego poziomu glukozy"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Nie można zatrzymać podawanego bolusa. Przybliż iPhone'a do pompy i spróbuj ponownie. Aby uzyskać szczegółowe informacje, sprawdź historię podawania insuliny i uważnie monitoruj poziom glukozy."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Nieznany"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Nieznany błąd: %1$@"; + +/* Remote command error description: unknown preset (1: preset name). */ +"Unknown preset: %1$@" = "Nieznane ustawienie: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Nieznany czas"; + /* The format for the description of a temporary override end date */ "until %@" = "do %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Dopóki nie wprowadzę węglowodanów"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Dopóki nie wyłączę"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Użyj ustawień przed posiłkiem"; + /* The title of the alert controller used to select a duration for workout targets */ "Use Workout Glucose Targets" = "Użyj zakresu glukozy dla wysiłku fizycznego"; +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Użyj wstępnego ustawienia treningu"; + /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Uwaga! Powiadomienia dotyczące bezpieczeństwa są WYŁĄCZONE"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Kiedy aktualny lub prognozowany poziom glukozy znajduje się poniżej granicy bezpieczeństwa, Loop nie zaleca bolusa i zawsze zaleca tymczasową dawkę podstawową wynoszącą 0 jednostek na godzinę."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Kiedy aktualna lub prognozowana glukoza znajduje się poniżej progu zawieszenia, Loop nie zaleca bolusa i zawsze zaleca tymczasową dawkę podstawową wynoszącą 0 jednostek na godzinę."; +/* Description of missed meal notifications. */ +"When enabled, Loop can notify you when it detects a meal that wasn't logged." = "Po włączeniu Loop może powiadomić Cię, gdy wykryje posiłek, który nie został wprowadzony."; + +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Poza trybem pętli zamkniętej aplikacja korzysta z uproszczonego kalkulatora bolusa, takiego jak typowa pompa."; + /* The label of the workout mode toggle button */ "Workout Targets" = "Zakres w czasie wysiłku fizycznego"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Cel Tymczasowy (trening) był włączony przez ponad 24 godziny. Upewnij się, że nadal chcesz, aby był włączony, lub wyłącz go w aplikacji."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Tymczasowy profil treningowy nadal działa"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Tak"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Możesz nie otrzymywać alertów dźwiękowych, wizualnych lub wibracyjnych dotyczących krytycznych informacji o bezpieczeństwie. \n\nAby rozwiązać ten problem, wybierz „Ustawienia” i upewnij się, że Powiadomienia, Alerty Krytyczne i Powiadomienia Zależne od Czasu są WŁĄCZONE."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Czas %1$@ został zmieniony. %2$@ potrzebuje dokładnych zapisów czasu, aby przewidywać poziom glukozy i odpowiednio dostosowywać poziom insuliny. \n\nSprawdź w ustawieniach %1$@ (Ogólne / Data i godzina) i upewnij się, że opcja „Ustaw automatycznie” jest WŁĄCZONA. Niepowodzenie w rozwiązaniu problemu może prowadzić do poważnego niedostatecznego lub nadmiernego podawania insuliny."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Twój poziom glukozy jest poniżej %1$@ . Czy na pewno chcesz podać bolus?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Twój poziom glukozy jest poniżej lub przewiduje się, że spadnie poniżej granicy bezpieczeństwa, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Twój poziom glukozy jest poniżej granicy bezpieczeństwa, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Twój poziom glukozy jest niski. Zjedz węglowodany i rozważ odczekanie z podaniem bolusa, aż poziom glukozy znajdzie się w bezpiecznym zakresie."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Twój poziom glukozy jest niski. Zjedz węglowodany i uważnie monitoruj poziom glikemii."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Twoja maksymalna wielkość bolusa to %1$@ ."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Dane Twojej pompy są nieaktualne. %1$@ nie może zalecić wielkości bolusa."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Pompa podaje tymczasową dawkę podstawową ustawioną ręcznie."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Twój zalecany bolus przekracza maksymalną wartość bolusa wynoszącą %1$@ ."; + diff --git a/Loop/pl.lproj/Main.strings b/Loop/pl.lproj/Main.strings index 79f9db9ab4..5921fb72fa 100644 --- a/Loop/pl.lproj/Main.strings +++ b/Loop/pl.lproj/Main.strings @@ -1,39 +1,35 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Status"; -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "ID pompy"; - /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 J/godzinę @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Ilość bolusa"; +/* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ +"87H-N1-0vJ.text" = "Przewidywane"; -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; +/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ +"aCb-Qs-bpu.text" = "Detail"; -/* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ -"87H-N1-0vJ.text" = "Przewidywany"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Rodzaj żywności"; -/* Class = "UILabel"; text = "Title"; ObjectID = "B9F-K3-7RI"; */ -"B9F-K3-7RI.text" = "Tytuł"; +/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ +"bIL-Ub-qYp.text" = "Etykieta"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Jednostki"; +/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ +"bq4-98-cQU.text" = "Zmiana poziomu glukozy"; -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "J"; +/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ +"d3X-AN-tA5.text" = "g łącznie"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ "D4C-I2-dhA.text" = "Poziom glukozy jest przewidywany dzięki syntezie wielu wprowadzonych danych z różnych źródeł. Użyj tego narzędzia, aby przełączyć różne źródła i zobaczyć jak wpływają na ostateczny wynik."; -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "URZĄDZENIA"; +/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ +"d6m-qV-wWi.text" = "Etykieta"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "docelowo 92 mg/dL"; @@ -41,11 +37,23 @@ /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Obserwowany"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 J/godzinę @ 12:12 PM"; + +/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ +"hZZ-2S-lrd.title" = "Efekty wywołane przez węglowodany"; + /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ "IxU-As-glo.text" = "Obserwowane zmiany w poziomie glukozy i uwzględnianie zmian podaży insuliny mogą być użyte do oszacowania czasu absorpcji węglowodanów."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Szczegóły"; +"J7x-W5-gwo.text" = "Detail"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ +"k3F-Na-7mn.text" = "Zalecana baza"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Etykieta"; @@ -56,8 +64,14 @@ /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Przewidywany poziom cukru"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Model aktywności insuliny jest używany do oszacowania wpływu insuliny na poziom glukozy. Dokładny model może uchronić przed chaotycznym/nadmiernym podawaniem insuliny i pozwala na zarekomendowanie prawidłowych dawek."; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; + +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; + +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Rodzaj żywności"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "docelowo 92 mg/dL"; @@ -65,83 +79,36 @@ /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ "SQx-au-ZcM.text" = "g Active Carbs"; -/* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ -"Vpi-5b-bY5.title" = "Węglowodany"; - -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 godziny"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Podaj"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Szczegóły"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolusa"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Etykieta"; - -/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Zmiana poziomu glukozy"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Etykieta"; - -/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g łącznie"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Etykieta"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Ustawienia"; - -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Aktywne węglowodany: 40g"; - -/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Efekty wywołane przez węglowodany"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Przewidywana glukoza poniżej zakresu"; - -/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Rekomendowana dawka podstawowa"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Etykieta"; +/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ +"tuw-av-A3x.text" = "Glukoza"; -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Kliknij, aby ustawić"; +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Dodaj/edytuj wpis dotyczący węglowodanów"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Jednostki"; +/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ +"ufi-Kj-33k.text" = "Etykieta"; -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "J"; +/* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ +"Vpi-5b-bY5.title" = "Węglowodany"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Typ insuliny"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Ilość węglowodanów"; -/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glukoza"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Zalecana baza"; -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Etykieta"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Aktywna insulina: 1.5J"; +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Rekomendowane"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Tytuł"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; + diff --git a/Loop/pt-BR.lproj/InfoPlist.strings b/Loop/pt-BR.lproj/InfoPlist.strings index 96a0de7f0b..4bcdbc5113 100644 --- a/Loop/pt-BR.lproj/InfoPlist.strings +++ b/Loop/pt-BR.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Loop/pt-BR.lproj/Localizable.strings b/Loop/pt-BR.lproj/Localizable.strings index 1b620804c6..89b0992539 100644 --- a/Loop/pt-BR.lproj/Localizable.strings +++ b/Loop/pt-BR.lproj/Localizable.strings @@ -1,6 +1,12 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (pendente: %@)"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "—"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; @@ -16,6 +22,9 @@ /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; @@ -49,6 +58,9 @@ /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Um modelo baseado na absorção publicada das insulinas Humalog, Novolog e Apidra em adultos."; +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Tempo de Absorção"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AceitarBolusRecomendado"; @@ -58,6 +70,9 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Carboidratos Ativos: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Carboidratos Ativos"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "Insulina Ativa"; @@ -71,7 +86,7 @@ Title text for button to set up a CGM */ "Add CGM" = "Adicionar CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Adicionar Refeição"; /* Action sheet title selecting Pump @@ -81,14 +96,17 @@ /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Um ajuste do modelo para adultos baseado nos efeitos empíricos em crianças."; - /* The title of the amplitude API key credential */ "API Key" = "API Key"; /* The title of the nightscout API secret credential */ -"API Secret" = "API Secret"; +"API Secret" = "Chave API"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Tem certeza de que deseja excluir todas as entradas do histórico?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Tem certeza de que deseja excluir todos os valores do reservatório?"; /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Você está certo que quer remover este CGM?"; @@ -104,7 +122,7 @@ /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Taxa Basal"; +"Basal Rates" = "Taxas Basais"; /* The label of the bolus entry button The notification title for a bolus failure */ @@ -127,7 +145,13 @@ /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Relação Carb"; +"Carb Ratios" = "Taxas de Carbs"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Adicionar Carb"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Editar Carb"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Carboidratos"; @@ -150,43 +174,71 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Verifique seu dispositivo CGM"; +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Escolha um tempo de absorção mais longo para refeições maiores ou aquelas que contenham gorduras e proteínas. Esta é apenas uma orientação para o algoritmo e não precisa ser exata."; + /* The title text for the looping enabled switch cell */ "Closed Loop" = "Ciclo Fechado"; +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "em %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "desde %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; /* The title of the configuration section in settings */ -"Configuration" = "Configurações"; +"Configuration" = "Configuração"; /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Erro de Configuração: %1$@"; +/* Default alert dismissal */ +"Continue" = "Continuar"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Monitoramento Contínuo de Glicose"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "Zona de correção"; +"Correction Range" = "Faixa de Correção"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = " Glicemia atual %1$@ está abaixo da zona de correção."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Sobreposições"; +"Custom Override" = "Sobreposição Personalizada"; + +/* Date picker label */ +"Date" = "Data"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Remover Conta"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Token do Cliente"; +/* Button title to delete all objects */ +"Delete All" = "Remover Todos"; /* Button title to delete CGM */ "Delete CGM" = "Remover CGM"; +/* Button title to delete a service */ +"Delete Service" = "Delete Service"; + /* Title text for delivery limits */ -"Delivery Limits" = "Limites de entrega"; +"Delivery Limits" = "Limites de Entrega"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Desativa"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Dispensar"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Ativar"; @@ -199,6 +251,9 @@ /* The alert title for a resume error */ "Error Resuming" = "Erro ao Retomar"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Event History"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Eventualmente %@"; @@ -211,6 +266,9 @@ /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Por %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glicose"; @@ -223,9 +281,6 @@ /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Aceleração da Glicose"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://mysite.herokuapp.com"; - /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Indefinidamente"; @@ -236,7 +291,7 @@ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulina Absorvida (U) × Sensibilidade a Insulina (%1$@/U)"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insulina Entregue"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Efeitos da Insulina"; @@ -261,27 +316,50 @@ /* The loading message for the diagnostic report screen */ "Loading..." = "Carregando..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; - /* The notification title for a loop failure */ "Loop Failure" = "Falha no Loop"; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Nenhum ciclo completo com sucesso em %@"; +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Bolus Máximo"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Dados ausentes: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Efeitos de aceleração"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Mais Info"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Precisa de Atenção"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Nenhum dispositivo conectado ou falha durante a conexão"; +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Ligado"; + /* The title text for the override presets */ "Override Presets" = "Sobreposições Predefinidas"; @@ -306,6 +384,9 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Dados da bomba são de %1$@ atrás"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Eventos da Bomba"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Gerenciamento da Bomba"; @@ -318,6 +399,9 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Bomba Suspensa"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Ação-Rápida – Adultos"; @@ -334,13 +418,13 @@ "Recommended Bolus: %@ Units" = "Bolus Recomendado: %@ Unidades"; /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "Reservatório"; +"Reservoir" = "Reservoir"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Correção Retrospectiva"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Tentar novamente"; +"Retry" = "Tentar de Novo"; /* The title of the services section in settings */ "Services" = "Serviços"; @@ -372,12 +456,19 @@ /* Subtitle description of Walsh insulin model setting */ "The legacy model used by Loop, allowing customization of action duration." = "O modelo antigo utilizado pelo Loop permitindo personalização da duração da ação."; +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "O tempo máximo de absorção é %@"; + /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "O bolus máximo é %@ Unidades"; /* The short unit display string for international units of insulin */ "U" = "U"; +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Desconhecido"; + /* The format for the description of a temporary override end date */ "until %@" = "até %@"; diff --git a/Loop/pt-BR.lproj/Main.strings b/Loop/pt-BR.lproj/Main.strings index ce306c7a7e..a78e3c7a40 100644 --- a/Loop/pt-BR.lproj/Main.strings +++ b/Loop/pt-BR.lproj/Main.strings @@ -1,29 +1,17 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ -"3kU-n2-fha.title" = "Status"; +"3kU-n2-fha.title" = "Estado"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/hora @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = " ID da Bomba"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Quantidade de Bolus"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Prevista"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detalhes"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +"aCb-Qs-bpu.text" = "Detail"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "Rótulo"; @@ -31,15 +19,6 @@ /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Variação de Glicose"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Unidades"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Rótulo"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g Total"; @@ -49,20 +28,14 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Rótulo"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Configurações"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "DISPOSITIVOS"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "eventualmente 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Observada"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Carboidratos Ativos: 40g"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/hora @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Efeitos dos Carboidratos"; @@ -71,10 +44,7 @@ "IxU-As-glo.text" = "Alterações observadas na glicose, subtraindo alterações modeladas da administração de insulina, podem ser usadas para estimar a absorção de carboidratos."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detalhes"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Previsão de glicose abaixo da meta"; +"J7x-W5-gwo.text" = "Detail"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Basal Recomendada"; @@ -82,30 +52,12 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Rótulo"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Rótulo"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "toque para definir"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Unidades"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Rótulo"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Glicose Prevista"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Modelo de Insulina"; - -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Um modelo de atividade da insulina é usado para estimar os efeitos da insulina nos níveis de glicose. Um modelo preciso pode ajudar a evitar o acúmulo de insulina e recomendar com segurança tratamentos corretivos."; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "eventualmente 92 mg/dL"; @@ -118,26 +70,17 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ "ufi-Kj-33k.text" = "Rótulo"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Insulina Ativa: 1.5U"; - /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Carboidratos"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 horas"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Entregue"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Basal Recomendada"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Recomendado"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Título"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; diff --git a/Loop/ro.lproj/InfoPlist.strings b/Loop/ro.lproj/InfoPlist.strings index cdc998d2e0..342b12482c 100644 --- a/Loop/ro.lproj/InfoPlist.strings +++ b/Loop/ro.lproj/InfoPlist.strings @@ -1,12 +1,18 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth este folosit pentru a comunica cu pompa de insulină, precum și cu dispozitivele de monitorizare glicemică continuă"; +"NSBluetoothAlwaysUsageDescription" = "Bluetooth este folosit pentru a comunica cu pompa de insulină, precum și cu dispozitivele de monitorizare glicemică continuă."; /* Privacy - Bluetooth Peripheral Usage Description */ "NSBluetoothPeripheralUsageDescription" = "Bluetooth este folosit pentru a comunica cu pompa de insulină, precum și cu dispozitivele de monitorizare glicemică continuă."; +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Camera este folosită pentru a scana codurile de bare ale dispozitivelor."; + /* Privacy - Face ID Usage Description */ "NSFaceIDUsageDescription" = "Face ID este folosit la autentificarea pentru bolus."; @@ -14,5 +20,8 @@ "NSHealthShareUsageDescription" = "Informațiile despre nutriție din baza de date Sănătate sunt folosite pentru a determina efectele glucozei. Informațiile despre glucoză din baza de date Sănătate sunt folosite pentru construirea de grafice și calcule de trend/momentum."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Carbohidrații introduși în aplicație și pe ceas sunt stocați în baza de date Sănătate. Glicemiile din GCM sunt stocate în mod confidențial în HealthKit."; +"NSHealthUpdateUsageDescription" = "Carbohidrații introduși în aplicație și pe ceas sunt stocați în baza de date Sănătate. Glicemiile din GCM sunt stocate în siguranță în HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop folosește Siri pentru a vă permite să activați presetări cu ajutorul vocii."; diff --git a/Loop/ro.lproj/Localizable.strings b/Loop/ro.lproj/Localizable.strings index 18ca58ac8a..2aa2fcb600 100644 --- a/Loop/ro.lproj/Localizable.strings +++ b/Loop/ro.lproj/Localizable.strings @@ -1,27 +1,78 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (urmează a fi administrate: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Presetare înainte de masă"; + +/* remaining time in setting's profile expiration section */ +" remaining" = " rămas"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = " Notificările de siguranță sunt dezactivate"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Presetare antrenament"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%1$@ %2$@"; +"%@ %@" = "%1$@%2$@"; /* Formats absorbed carb value */ "%@ absorbed" = "%@ absorbiți"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ rămase"; + /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ U total"; /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ nu a putut anula rata bazală temporară actuală, care este mai mare decât noua limită bazală maximă pe care ați setat-o. Acest lucru poate duce la o administrare de insulină mai mare decât se dorește. \n\nLuați în considerare suspendarea manuală a administrării insulinei și apoi reluarea imediată pentru a pune în aplicare administrarea bazală cu noua limită în vigoare."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@%2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ operează cu bucla închisă în poziția OFF. Pompa și CGM-ul vor continua să funcționeze, dar aplicația nu va ajusta automat dozarea."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ nu poate șterge alerta de pe dispozitiv"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ nu poate comunica cu pompa de insulină. Aplicația va continua să încerce să comunice cu pompa, dar informațiile despre administrarea insulinei nu pot fi actualizate și automatizarea nu poate continua.\nPuteți aștepta câteva minute pentru a vedea dacă problema se rezolvă sau apăsați butonul de mai jos pentru a afla mai multe despre alte opțiuni."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Setările de timp necesită atenție"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ U"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ U rămase"; @@ -34,21 +85,49 @@ /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ nu va mai funcționa în %2$@. Va trebui să actualizați înainte de aceasta, cu un nou profil de asigurare a accesului."; + /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "coeficient de regresie glicemică pe 15 min (b₁), continuat cu o diminuare pe 30 min."; /* Description of the prediction input effect for retrospective correction */ "30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "Comparație pe 30 min a glicemiei anticipate față de cea observată, continuată cu o diminuare pe 60 min."; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Câteva secunde rămase"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "O intrare manuală de glicermie trebuie să fie între %1$@ și %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "O intrare manuală de glicemie trebuie să fie între %1$@ și %2$@ ."; + /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "Un model bazat pe absorbția declarată a insulinei Fiasp."; /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Un model bazat pe absorbția declarată a insulinei Humalog, Novolog și Apidra la adulți."; +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "O nouă versiune de %@ este disponibilă și se recomandă să continuați să utilizați aplicația."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Este disponibilă o nouă versiune de %@ ."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "O pompă trebuie configurată înainte ca un bolus să poată fi livrat."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Timp de absorbție"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AcceptRecommendedBolus"; @@ -58,6 +137,9 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Carbohidrați activi: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Carbohidrați activi"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "Insulină activă"; @@ -65,33 +147,80 @@ "Active Insulin: %@" = "Insulină activă: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Adăugare carbohidrați"; +"Add Carb Entry" = "Adaugă carbohidrați"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "Adaugă CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Adaugă masă"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ "Add Pump" = "Adaugă pompă"; +/* Title text for button to set up a service */ +"Add Service" = "Adaugă Serviciu"; + +/* No comment provided by engineer. */ +"Adjusted for" = "Ajustat pentru"; + +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Gestionarea alertelor"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Permisiuni pentru alarme"; + +/* The title of the section containing algorithm settings */ +"Algorithm Settings" = "Setări algoritm"; + /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "O ajustare a modelului de adulți, bazată pe efecte empirice observate la copii."; +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Un modificator activa a schimbat raportul dintre carbohidrați și insulină cât și sensibilitatea la insulină. Dacă nu doriți ca acest lucru să vă afecteze calculul bolusului și gllicemia prognozată, luați în considerare dezactivarea modificatorului."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Eroare la încercarea de salvare a carbohidraților."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Eroare la încercarea de salvare a glicemiei introduse manual."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "A apărut o eroare neașteptată de stare la inițiere."; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Este disponibilă o recomandare de bolus nouă."; /* The title of the amplitude API key credential */ "API Key" = "API Key"; /* The title of the nightscout API secret credential */ -"API Secret" = "API Secret"; +"API Secret" = "Secretul API"; + +/* Settings app profile section */ +"App Profile" = "Profil"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Sigur doriți să ștergeți toate înregistrările din istoric?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Sigur doriți să ștergeți toate înregistrările despre dozele de insulina?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Sigur doriți să ștergeți toate valorile de rezervor?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Sunteţi sigur că doriţi să ştergeţi toate datele %@.\n(Această acţiune nu este reversibilă)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Sigur doriți să ștergeți acest CGM?"; +"Are you sure you want to delete this CGM?" = "Sunteți sigur că doriți să ștergeți acest CGM?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Ești sigur că vrei să ștergi acest serviciu?"; /* Format fragment for a specific time */ "at %@" = "la %@"; @@ -99,6 +228,9 @@ /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Autentificare pentru bolus %@ unități"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Autentifică-te pentru a înregistra %@ unități"; + /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Orar rate bazale"; @@ -106,10 +238,37 @@ The title text for the basal rate schedule */ "Basal Rates" = "Rate bazale"; +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Pe baza glicemiei prognozate, nu se recomandă niciun bolus."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth \nOprit"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth \nIndisponibil"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Alertă Bluetooth dezactivat"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Alertă Bluetooth indisponibil"; + /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Bolus"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Problemă bolus"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Actualizare Recomandare bolus"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Rezumat Bolus"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus prea mic"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Bolus administrat %1$@ of %2$@"; @@ -125,10 +284,26 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "Efecte carbohidrați"; +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Cantitate CH"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Programul raportului de carbohidrați"; + /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ "Carb Ratios" = "Raport carbohidrați/insulină"; +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Adaugă carbohidrați"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Editează carbohidrați"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Intrarea de carbohidrați este prea mare"; + /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Carbohidrați"; @@ -136,10 +311,10 @@ "Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Carbohidrați absorbiți (g) ÷ Raport carbohidrați (g/U) × Factor de sensibilitate la insulină (%1$@/U)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Schimbați bateria pompei imediat"; +"Change the pump battery immediately" = "Schimbați imediat bateria pompei"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Schimbați bateria pompei acum"; +"Change the pump reservoir now" = "Schimbați rezervorul pompei acum"; /* Details for configuration error when one or more loop settings are missing */ "Check settings" = "Verificați setările"; @@ -150,18 +325,48 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Verificați sursa de date CGM"; +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Verificați ora dispozitivului și/sau eliminați orice date incorecte din Apple Health."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Alegeți o durată mai lungă de absorbție pentru mese mai mari sau pentru cele care conțin grăsimi și proteine. Nu e necesară o valoare exactă, scopul e să oferim doar o ghidare pentru algoritm."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Închide"; + /* The title text for the looping enabled switch cell */ "Closed Loop" = "Loop automat"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Buclă închisă dezactivata"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Buclă închisă necesită o sesiune activă de senzor CGM"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Bucla închisă necesită ca setarea să fie finalizată"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "la %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "de la %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +/* Title text for button to complete setup */ +"Complete Setup" = "Configurare finalizată"; + /* The title of the configuration section in settings */ "Configuration" = "Configurare"; /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Eroare configurare: %1$@"; +/* Default alert dismissal */ +"Continue" = "Continuă"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Monitorizare glicemică continuă"; @@ -169,50 +374,171 @@ The title text for the glucose target range schedule */ "Correction Range" = "Interval țintă pentru corecție"; +/* Critical Alerts Status text */ +"Critical Alerts" = "Alerte critice"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Jurnal evenimente critice pregătit"; + +/* Critical event log export title */ +"Critical Event Logs" = "Jurnal de evenimente critice"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Jurnalele de evenimente critice nu au putut fi exportate."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Glicemia curentă"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = " Glicemia curentă de %1$@ se situează sub intervalul țintă de corecție."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Înlocuire"; +"Custom Override" = "Modificare personalizată"; + +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Presetare particularizată"; + +/* Date picker label */ +"Date" = "Data"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Delete" = "Șterge"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Șterge cont"; + +/* Button title to delete all objects */ +"Delete All" = "Șterge tot"; /* Button title to delete CGM */ -"Delete CGM" = "Șterge CGM"; +"Delete CGM" = "Ștergeți CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Șterge serviciul"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Șterge date CGM de testare"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Șterge date de testare"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Ștergere date pompă de testare"; + +/* Button text to deliver a bolus */ +"Deliver" = "Livrează"; /* Title text for delivery limits */ -"Delivery Limits" = "Limite administrare"; +"Delivery Limits" = "Limite de livrare"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Tratament Diabet"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Ați intenționat să introduceți %1$@ grame ca cantitate de carbohidrați pentru această masă?"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Dezactivează"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Renunță"; + +/* No comment provided by engineer. */ +"Done" = "Realizat"; + +/* Title for card to log dose */ +"Dose Summary" = "Rezumat doză"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Strategie de dozare"; + +/* Remote command error description: duration exceed max (1: max duration in hours). */ +"Duration exceeds: %1$.1f hours" = "Durata depășește: %1$.1f ore"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Activează Bluetooth"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Activează"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Introduceți o glicemie luata cu glucometrul pentru o recomandare de bolus."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Introdu bolusul"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Introduceți glicemia din deget"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Introduceți limita de siguranță pentru glicemie"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Introduceți limita pentru suspendare"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Eroare la anularea bolusului"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Eroare la exportarea jurnalelor"; + /* The alert title for a resume error */ "Error Resuming" = "Eroare în timpul reluării"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Istoric evenimente"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Ajunge la %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Depășește bolusul maxim permis în setări"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Depășește maximul de carbohidrați permis"; + /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Depășește bolusul maxim"; +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Exportă jurnalul de evenimente critice"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Export-%1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Nu s-a reușit reluarea administrării de insulină"; + /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Glicemie din deget"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Remediați acum activând Notificări, Alerte critice și Notificări sensibile la timp."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "Timp de %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Glicemia prognozată poate fi în continuare mai mare decât intervalul țintă."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Glicemia prognozată"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Obțineți ajutor cu permisiunile de alertă"; + /* The title of the glucose and prediction graph */ -"Glucose" = "Glicemie"; +"Glucose" = "Glucoza"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ "Glucose data is %1$@ old" = "Datele despre glicemie au o vechime de %1$@"; @@ -220,85 +546,299 @@ /* Description of error when glucose data is missing */ "Glucose data not available" = "Nu sunt disponibile date despre glicemie"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Valorile glicemiei sunt disponibile"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Valoarea glicemică introdusă este în afara intervalului"; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Momentum glicemie"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://mysite.herokuapp.com"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "Programul intervalului țintă de glucoză"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Cum se actualizează (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Imediat"; /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Nedeterminat"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Maximul de intrare a fost depășit"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Insulină"; /* Description of the prediction input effect for insulin */ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulină absorbită (U) × factor de sensibilitate la insulină (%1$@/U)"; +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Ajustările de insulină au fost dezactivate!"; + /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Administrare insulină"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Efecte insulină"; /* Details for configuration error when insulin model is missing The title text for the insulin model setting row */ -"Insulin Model" = "Model insulină"; +"Insulin Model" = "Modelul de insulină"; + +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Pompa de insulină"; /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Sensibilitate insulină"; +"Insulin Sensitivities" = "Factor de sensibilitate la insulină"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "Programul Factorului de Sensibilitate la Insulină"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Administrarea insulinei suspendată"; + +/* Insulin type label */ +"Insulin Type" = "Tipul de insulină"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Întrerupere %1$@: %2$@ din %3$@ %4$@"; + +/* Remote command error description: invalid absorption time. */ +"Invalid absorption time: %d hours" = "Timp invalid de absorbție: %li ore"; + +/* Remote command error description: invalid bolus amount. */ +"Invalid Bolus Amount" = "Cantitate invalidă de bolus"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Cantitate de carbohidrați invalidă"; /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Date invalide: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Glicemie Viitoare Invalidă"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Citirea invalidă a glicemiei cu un marcaj temporal care este %1$@ în viitor"; + /* The title text for the issue report cell */ "Issue Report" = "Raportare probleme"; +/* The notification description for a meal that was possibly not logged in Loop. */ +"It looks like you may not have logged a meal you ate. Tap to log it now." = "Se pare că nu ați înregistrat o masă pe care ați mâncat-o. Atingeți pentru a o înregistra acum."; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "O cantitate mare de carbohidrați a fost introdusă"; + /* Glucose HUD accessibility hint */ "Launches CGM app" = "Lansează aplicația CGM"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Aflați mai multe"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "A rămas mai puțin de un minut"; + /* The loading message for the diagnostic report screen */ "Loading..." = "Se încarcă..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Înregistrează Doză"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Doza de insulină înregistrată"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop s-a închis"; /* The notification title for a loop failure */ "Loop Failure" = "Eșec Loop"; +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop a detectat o problemă cu setările Bluetooth și nu va funcționa cu succes până când Bluetooth nu este activat. Nu veţi primi valori ale glicemiei sau nu veţi putea face bolus."; + +/* Warning displayed when user is adding a meal from an missed meal notification */ +"Loop has detected an missed meal and estimated its size. Edit the carb amount to match the amount of any carbs you may have eaten." = "Loop a detectat o masă neanunțată și a estimat dimensiunea acesteia. Editați cantitatea de carbohidrați pentru a se potrivi cu cantitatea de carbohidrați pe care ați consumat-o."; + /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop nu a rulat cu succes timp de %@"; +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop va bolusa automat când necesarul de insulină este deasupra bazalei programate, și va utiliza rate bazale temporare atunci când este necesar, pentru a reduce cantitatea de insulină administrată sub nivelul bazal programat."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop nu va funcționa cu succes până când Bluetooth nu este activat. Nu veți primi citiri de glicemie sau nu veți putea să bolusați."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop va stabili ratele bazale temporare pentru a crește și reduce cantitatea de insulina livrata."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Glicemie scăzută"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Gestionați permisiunile din Setări"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Doză manuală: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Rata bazală maximă pe oră"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Bolus maxim"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Bolusul maxim depășit"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Durata maximă depășită"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Bolus prandial"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* Title for missed meal notifications toggle */ +"Missed Meal Notifications" = "Notificări privind mesele pierdute"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Date lipsă: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Lipsește bolusul maxim permis în setări"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Efecte momentum"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Detalii"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Dezactivați toate alertele"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Necesită atenție"; + +/* Remote command error description: negative duration error. */ +"Negative duration not allowed" = "Durata negativă nu este permisă"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Nicio alertă nu va suna când este dezactivat sunetul. Odată ce această perioadă se încheie, alertele și alarmele dvs. vor relua normal."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Niciun bolus recomandat"; + /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Nu este conectat niciun dispozitiv sau s-a produs o eroare la conectare"; +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Bolusul Maxim nu este setat"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Nicio pompă configurată"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Nu există date recente despre glicemie"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Nu există date recente despre glicemie"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Nu există date recente despre pompă"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Nu, modificați cantitatea"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Livrare notificare"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Livrarea notificărilor este setată la Rezumat programat în setările telefonului dvs. \n\nPentru a evita întârzierea primirii notificărilor de la %1$@ , vă recomandăm ca livrarea notificărilor să fie setată la Livrare imediată."; + +/* Notifications Status text */ +"Notifications" = "Notificări"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Notificări întârziate"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Notificările vă oferă informații importante despre aplicație %1$@ fără a fi necesar să deschideți aplicația."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Notificările vă oferă informații importante despre aplicație %1$@ fără a fi necesar să deschideți aplicația. \n\n Păstrați-le activate în setările telefonului pentru a vă asigura că primiți notificări %1$@ , alerte critice și notificări sensibile la timp."; + +/* Notification Setting Status is Off */ +"Off" = "Oprit"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Oh nu! Loop s-a blocat în timpul administrării, iar ajustările insulinei au fost întrerupte până când acest dialog este închis. Istoricul administrării poate să nu fie exact. Vă rugăm să consultați tabelele de livrare a insulinei și să vă monitorizați cu atenție glicemia."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Pornit"; + /* The title text for the override presets */ "Override Presets" = "Presetări de înlocuire"; +/* The notification title for a meal that was possibly not logged in Loop. */ +"Possible Missed Meal" = "Posibilă masă neanunțată"; + /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Ținte preprandiale"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "Glicemia prognozată pentru %1$@ este %2$@."; +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Glicemia prognozată este în interval."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Glicemia prognozată de %1$@ se situează sub limita de siguranță configurată."; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Glicemia prognozată de %1$@ se situează sub limita de suspendare configurată"; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Prognozată: %1$@\nActuală: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Pregătire jurnal de evenimente critice"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Expirarea profilului"; + +/* Time that profile expires */ +"Profile expires " = "Profilul expiră "; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Profilul expiră în curând"; + /* The title of the pump section in settings */ -"Pump" = "Pompă"; +"Pump" = "Pompa"; /* The notification title for a low pump battery */ "Pump Battery Low" = "Nivel scăzut baterie pompă"; @@ -306,33 +846,62 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Datele din pompă sunt vechi de %1$@"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Eveniment de pompă"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Manager pompă"; +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Eroare de gestionare a pompei: %1$@"; + /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Rezervor pompă gol"; +"Pump Reservoir Empty" = "Rezervorul pompei este gol"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Nivel scăzut rezervor pompă"; +"Pump Reservoir Low" = "Rezervor de pompare scăzut"; /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pompă suspendată"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pompă suspendată. Administrarea automată este dezactivată."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@%2$@"; + /* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Rapid-Acting – Adulți"; +"Rapid-Acting – Adults" = "Acțiune rapidă – Adulți"; /* Title of insulin model preset */ -"Rapid-Acting – Children" = "Rapid-Acting – Copii"; +"Rapid-Acting – Children" = "Acțiune rapidă - Copii"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ "Recommendation expired: %1$@ old" = "Recomandare expirată: acum %1$@"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Bazal recomandat"; +"Recommended Basal" = "Bazala recomandată"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Bolus recomandat"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Bolusul recomandat depășește bolusul maxim"; /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Bolus recomandat: %@ unități"; +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Introducere de la distanță a bolusului: %@ U"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Introducere de la distanță a carbohidraților: %d grame"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Comanda de la distanță a expirat"; + /* Details for missing data error when reservoir data is missing */ "Reservoir" = "Rezervor"; @@ -342,20 +911,47 @@ /* The title of the notification action to retry a bolus command */ "Retry" = "Reîncearcă"; +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Salvează si Livrează"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Salvează fără bolusare"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Programat"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Selectați perioada de dezactivare"; + /* The title of the services section in settings */ "Services" = "Servicii"; /* The label of the settings button */ "Settings" = "Setări"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Configurare nefinalizată"; + /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Afișează ultima eroare de loop"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Calculator simplu de bolus"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Calculator simplu al mesei"; + /* Format fragment for a start time */ "since %@" = "de la %@"; /* The title of the nightscout site URL credential */ -"Site URL" = "Site URL"; +"Site URL" = "URL site"; + +/* Software update button link text */ +"Software Update" = "Actualizare de software"; + +/* Remote command error description: invalid start time is out of range. */ +"Start time is out of range: %@" = "Ora de începere este în afara intervalului: %@"; /* The format for the description of a temporary override start date */ "starting at %@" = "începând de la %@"; @@ -363,33 +959,193 @@ /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Start Bolus"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Asistenţă"; + /* The title text in settings */ "Suspend Threshold" = "Limită suspendare"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Apăsați aici pentru a configura un CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Apăsați aici pentru a configura o pompă de insulină"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Apăsați aici pentru a configura un Serviciu"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Atinge pentru a adăuga"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ "Tap to Resume" = "Apăsați pentru a relua"; +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Atingeți pentru a opri"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Dezactivare temporară a alertelor"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Cantitatea de bolus introdusă este mai mică decât valoarea minimă administrabilă."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Algoritmul de dozare al bolusurilor folosește o estimare mai conservatoare a glicemiei prognozate decât cea utilizată pentru a ajusta rata bazală. \n\n Ca rezultat, glicemia estimată după un bolus poate fi în continuare mai mare decât intervalul țintă."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "Recomandarea pentru bolus a fost actualizată. Vă rugăm să reconfirmaţi valoarea bolusului."; + /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Modelul învechit utilizat de Loop, permite personalizarea duratei de acțiune."; +"The legacy model used by Loop, allowing customization of action duration." = "Modelul vechi utilizat de Loop, permite personalizarea duratei de acțiune."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Timpul maxim de absorbție este %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "Cantitatea maximă admisă este de %@ grame."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "Cantitatea maximă permisă este %1$@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Valoarea maximă bolus este %@ U."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Cantitatea maximă de bolus este de %@ unități"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Trebuie sa configurați o valoare maxima pentru bolus înainte ca acesta să poată fi livrat."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Comanda de la distanță a expirat acum %.0f minute."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Setări Terapie"; + +/* Title of the carb entry date picker cell */ +"Time" = "Timp"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Notificări urgente"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Reîncercați"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Activați Bluetooth pentru a primi alerte, alarme sau citiri de glicemie de la senzor."; + /* The short unit display string for international units of insulin */ "U" = "U"; +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Nu se poate șterge alerta"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Nu se poate conecta la pompă"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Nu se pot salva Carbohidrații"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Nu se poate salva glicemia manuala"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Nu s-a putut opri livrarea bolusului. Mutați iPhone-ul mai aproape de pompă și încercați din nou. Verificați istoricul administrării insulinei pentru detalii și monitorizați îndeaproape glicemia."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Necunoscut"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Eroare necunoscută: %1$@"; + +/* Remote command error description: unknown preset (1: preset name). */ +"Unknown preset: %1$@" = "Presetare necunoscută: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Timp necunoscut"; + /* The format for the description of a temporary override end date */ "until %@" = "până la %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Până când introduc carbohidrații"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Până mă opresc"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Utilizare presetare înainte de masă"; + /* The title of the alert controller used to select a duration for workout targets */ "Use Workout Glucose Targets" = "Folosește țintele glicemice de activitate sportivă"; +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Utilizare presetare antrenament"; + /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Atenție! Notificările de siguranță sunt DEZACTIVATE"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "În momentul în care glicemia actuală sau cea prognozată se situează sub limita de siguranța, Loop nu va recomanda un bolus și va recomanda întotdeauna o rată bazală temporară de 0 unități pe ora."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "În momentul în care glicemia actuală sau cea prognozată se situează sub limita de suspendare, Loop nu va recomanda un bolus și va recomanda întotdeauna o rată bazală temporară de 0 unități pe ora."; +/* Description of missed meal notifications. */ +"When enabled, Loop can notify you when it detects a meal that wasn't logged." = "Când este activat, Loop vă poate notifica când detectează o masă care nu a fost înregistrată."; + +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Când modul Buclă închisa nu este activat, aplicația folosește un calculator simplificat pentru bolus similar cu cel al unei pompe tipice."; + /* The label of the workout mode toggle button */ "Workout Targets" = "Ținte de activitate sportivă"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Ajustarea temporară de antrenament fost activată de mai mult de 24 de ore. Asigură-te că încă dorești să fie activată sau dezactiveaz-o din aplicație."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Ajustare temporara antrenament încă activa"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Da"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Este posibil să nu primiți alerte sonore, vizuale sau cu vibrații referitoare la informații critice de siguranță. \n\nPentru a remedia problema, atingeți „Setări” și asigurați-vă că notificările, alertele critice și notificările sensibile la timp sunt activate."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Ora %1$@ dumneavoastră a fost schimbată. %2$@ are nevoie de înregistrări precise ale timpului pentru a face predicții despre glicemia și pentru a ajusta insulina în consecință. \n\nVerificați setările %1$@ (General / Data și Ora) și verificați dacă „Setare automată” este activată. Nerezolvarea poate duce la o administrare insuficientă sau excesivă de insulină."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Glicemia dumneavoastră este sub %1$@. Sunteți sigur/ă că doriți să bolusați?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Glicemia ta este sub sau se anticipează că va scădea sub limita de siguranță, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Glicemia ta este sub limita de siguranță, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "Glicemia dumneavoastră este scăzută. Consumați carbohidrați și luați în considerare posibilitatea de a aștepta să faceți un bolus până când glicemia se află într-un interval sigur."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "Glicemia dumneavoastră este scăzută. Mâncați carbohidrați și monitorizați cu atenție."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Valoarea maximă a bolusului este %1$@ ."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Datele pompei dumneavoastră sunt învechite. %1$@ nu poate recomanda o cantitate de bolus."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Pompa dumneavoastră furnizează o rată bazală temporară manuală."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Bolusul recomandat depășește cantitatea maximă de bolus de %1$@ ."; + diff --git a/Loop/ro.lproj/Main.strings b/Loop/ro.lproj/Main.strings index 73c15f11f8..ee20499b61 100644 --- a/Loop/ro.lproj/Main.strings +++ b/Loop/ro.lproj/Main.strings @@ -1,29 +1,20 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ -"3kU-n2-fha.title" = "Status"; +"3kU-n2-fha.title" = "Stare"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/oră @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "ID pompă"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Cantitate bolus"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Estimată"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detaliu"; +"aCb-Qs-bpu.text" = "Detail"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Tip mâncare"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "Etichetă"; @@ -31,15 +22,6 @@ /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Glucose Change"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "unități"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Etichetă"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g în total"; @@ -49,20 +31,17 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "Etichetă"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Setări"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "DEVICES"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "estimată să ajungă la 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Observată"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Carbohidrați activi: 40g"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/oră @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Efecte carbohidrați"; @@ -71,40 +50,28 @@ "IxU-As-glo.text" = "Modificările observate ale glicemiei, eliminând modificările modelate din administrarea insulinei, pot fi folosite pentru a estima absorbția carbohidraților."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detaliu"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Glicemia estimată se situează sub intervalul țintă"; +"J7x-W5-gwo.text" = "Detail"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Bazal recomandat"; +"k3F-Na-7mn.text" = "Bazala recomandată"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Etichetă"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Etichetă"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Apăsați pentru a seta"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Unități"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Etichetă"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Glicemie estimată"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Model insulină"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; + +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Pentru a estima efectele insulinei asupra glicemiei, se folosește un model de acțiune a insulinei. Acuratețea modelului poate preveni suprapunerea insulinei și recomanda corecții într-un mod sigur"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Tip mâncare"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "estimată să ajungă la 92 mg/dL"; @@ -113,31 +80,34 @@ "SQx-au-ZcM.text" = "g CLB"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glicemie"; +"tuw-av-A3x.text" = "Glucoza"; -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Eticheă"; +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Adaugă/Editează carbohidrați"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Insulină activă: 1.5U"; +/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ +"ufi-Kj-33k.text" = "Etichetă"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Carbohidrați"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 ore"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Cantitate consumată"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Bazala recomandată"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Administrează"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Recomandat"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Titlu"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; diff --git a/Loop/ru.lproj/InfoPlist.strings b/Loop/ru.lproj/InfoPlist.strings index 0f388ab0de..758641c73e 100644 --- a/Loop/ru.lproj/InfoPlist.strings +++ b/Loop/ru.lproj/InfoPlist.strings @@ -1,14 +1,20 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices."; +"NSBluetoothAlwaysUsageDescription" = "Bluetooth используется для связи с инсулиновой помпой и устройствами непрерывного мониторинга глюкозы."; /* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Блутус применяется для коммуникации с инсулиновой помпой и устройствами непрерывного мониторинга СК"; +"NSBluetoothPeripheralUsageDescription" = "Bluetooth используется для связи с инсулиновой помпой и устройствами непрерывного мониторинга глюкозы."; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Камера используется для сканирования штрих-кодов устройств."; /* Privacy - Face ID Usage Description */ -"NSFaceIDUsageDescription" = "Идентификатор Face ID применяется для авторизации болюса инсулина"; +"NSFaceIDUsageDescription" = "Идентификатор Face ID применяется для авторизации ввода инсулина"; /* Privacy - Health Share Usage Description */ "NSHealthShareUsageDescription" = "Данные о пище из базы данных Здоровье используются для определения влияния на гликемию. Данные гликемии из базы данных Здоровье используются для графического отображения и вычисления скорости изменений"; @@ -16,3 +22,6 @@ /* Privacy - Health Update Usage Description */ "NSHealthUpdateUsageDescription" = "Данные об углеводах в приложении и на смарт-часах хранятся в базе данных Здоровье. Данные о гликемии полученные от систем непрерывного мониторинга хранятся в безопасности в Комплексе Здоровья HealthKit "; +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop использует Siri, чтобы вы могли активировать пресеты своим голосом."; + diff --git a/Loop/ru.lproj/Localizable.strings b/Loop/ru.lproj/Localizable.strings index fbf1352941..7ce5322937 100644 --- a/Loop/ru.lproj/Localizable.strings +++ b/Loop/ru.lproj/Localizable.strings @@ -1,50 +1,132 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (В ожидании: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = "Пресет до еды"; + +/* remaining time in setting's profile expiration section */ +" remaining" = " осталось"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = " Оповещения о безопасности выключены"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = "Пресет физнагрузки"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ "%@ absorbed" = "%@ усвоено"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "Осталось %@"; + /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ всего ед"; /* Appends a full-stop to a statement */ "%@." = "%@."; +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@%2$@ не смог отменить вашу текущую ВБС, которая превышает установленный вами новый предел максимальной ВБС. Это может привести к большему количеству подаваемого инсулина, чем хотелось бы.\n\nРассмотрите возможность приостановить введение инсулина вручную, а затем немедленно возобновить введение базального инсулина с новым установленным лимитом."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@ %2$@"; + /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/ед"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ работает с замкнутым циклом в положении ВЫКЛ. Ваша помпа и CGM будут продолжать работать, но приложение не будет регулировать дозировку автоматически."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ не удается удалить предупреждение с вашего устройства"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ не может связаться с вашей инсулиновой помпой. Приложение будет продолжать попытки связаться с вашей помпой, но информация о доставке инсулина не может быть обновлена, и автоматизация не может продолжаться.\nВы можете подождать несколько минут и посмотреть, разрешится ли проблема, или нажать кнопку ниже, чтобы узнать о других возможностях."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Настройки времени требуют внимания"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ Ед."; + /* Low reservoir alert format string. (1: Number of units remaining) */ -"%1$@ U left" = "%1$@ Осталось ед"; +"%1$@ U left" = "%1$@ Ед осталось"; /* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ -"%1$@ U left: %2$@" = "%1$@ Осталось ед: %2$@ "; +"%1$@ U left: %2$@" = "%1$@ Ед осталось: %2$@"; /* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ "%1$@ U/hour @ %2$@" = "%1$@ ед/час @ %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ против %2$@"; + +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ перестанет работать в %2$@. Вам нужно будет обновить его до этого, используя новую подпись."; + /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15-мин коэффициент регрессии гликемии (b1), продолжен с угасанием 30 мин"; /* Description of the prediction input effect for retrospective correction */ "30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 мин сравнение предсказанной гликемии с действительной, продолжено с угасанием 60 мин"; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Осталось несколько секунд"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Ручной ввод глюкозы должен находиться между %1$@ и %2$@"; + +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Ручной ввод глюкозы должен находиться между %1$@ и %2$@"; + /* Subtitle of Fiasp preset */ -"A model based on the published absorption of Fiasp insulin." = "модель, основанная на опубликованных данных усвоения FIASP инсулина."; +"A model based on the published absorption of Fiasp insulin." = "Модель, основанная на опубликованных данных усвоения FIASP инсулина."; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "модель, основанная на опубликованных данных усвоения Humalog, Novolog и Apidra у взрослых."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Модель, основанная на опубликованных данных усвоения Humalog, Novolog и Apidra у взрослых."; + +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "Новая версия %@ доступна и рекомендуется для продолжения использования приложения."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Доступна новая версия %@ ."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Перед введением болюса необходимо настроить помпу."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Длительность усвоения"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "Принятьрекомендуемыйболюс"; @@ -55,8 +137,11 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Действующие углеводы: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Активные углеводы"; + /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Действующий инсулин"; +"Active Insulin" = "Активный инсулин"; /* The string format describing active insulin. (1: localized insulin value description) */ "Active Insulin: %@" = "Действующий инсулин: %@"; @@ -66,32 +151,76 @@ /* Action sheet title selecting CGM Title text for button to set up a CGM */ -"Add CGM" = "добавить мониторинг"; +"Add CGM" = "Добавить CGM"; -/* The label of the carb entry button */ -"Add Meal" = "Добавить продукт"; +/* The label of the meal button */ +"Add Meal" = "Добавить еду"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ "Add Pump" = "Добавить помпу"; /* Title text for button to set up a service */ -"Add Service" = "Add Service"; +"Add Service" = "Добавить сервис"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* No comment provided by engineer. */ +"Adjusted for" = "Скорректировано на"; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Управление оповещениями"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Разрешение оповещений"; /* The title of the section containing algorithm settings */ "Algorithm Settings" = "Настройки алгоритма"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Поправка к модели для взрослых основанная на эмпирических данных для детей."; +/* The title of the Amplitude service */ +"Amplitude" = "Amplitude"; + +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Активные временные цели изменяют соотношение углеводов и чувствительность к инсулину. Если вы не хотите, чтобы это влияло на расчет болюса и прогнозируемый уровень глюкозы, отключите эту функцию."; + +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Произошла ошибка при попытке сохранить запись об углеводах."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Произошла ошибка при попытке сохранить данные о глюкозе, введенные вручную."; + +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Возникла непредвиденная ошибка подключения."; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Доступна обновленная рекомендация болюса."; + +/* The title of the amplitude API key credential */ +"API Key" = "API-ключ"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Секрет"; + +/* Settings app profile section */ +"App Profile" = "Профиль приложения"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Подтвердите удаление всех записей истории?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Вы уверены, что хотите удалить все зарегистрированные записи о дозах?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Подтвердите удаление всех записей резервуара?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Вы уверены, что хотите удалить все свои данные %@ ?\n (Это действие необратимо)"; /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Стереть этот мониторинг?"; +"Are you sure you want to delete this CGM?" = "Вы уверены, что хотите удалить этот CGM?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Вы уверены, что хотите удалить этот сервис?"; /* Format fragment for a specific time */ "at %@" = "В %@"; @@ -99,6 +228,9 @@ /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Подтверждение болюса %@ ед"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Пройдите аутентификацию для подтверждения болюса %@ Единиц"; + /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Скорости базала"; @@ -106,10 +238,37 @@ The title text for the basal rate schedule */ "Basal Rates" = "Скорости базала"; +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Основываясь на вашей прогнозируемой глюкозе, болюс не рекомендуется."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth\n Выключен"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth\n Недоступен"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Оповещение об отключении Bluetooth"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Оповещение о недоступности Bluetooth"; + /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Болюс"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Проблема с подачей болюса"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Рекомендации по болюсу обновлены"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Суммарно болюса"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Болюс слишком маленький"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Подан болюс%1$@ из %2$@"; @@ -125,18 +284,34 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "Влияние углеводов"; +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Добавить запись углеводов"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Расписание соотношения углеводов"; + /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ "Carb Ratios" = "Соотношения углеводов"; +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Добавить запись углеводов"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Редактировать запись углеводов"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Слишком много углеводов"; + /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Углеводы"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Усвоенные углеводы (г) : соотношение углеводов (гр/ед)х чувствительность к инсулину"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Усвоенные углеводы (г) ÷ Коэффициент углеводов (г/U) × Чувствительность к инсулину (%1$@/U)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Замените батарею помпы немедленно"; +"Change the pump battery immediately" = "Немедленно замените батарейку в помпе"; /* The notification alert describing an empty pump reservoir */ "Change the pump reservoir now" = "Замените резервуар помпы сейчас"; @@ -150,18 +325,48 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Проверьте источник мониторинга СК"; +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Проверьте время вашего устройства и/или удалите недействительные данные из Apple Health."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Выберите более высокую длительность усвоения для обильной пищи или для пищи с белками и протеинами. Это единственное указание для алгоритма не нуждается в дополнительных уточнениях."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Закрыть"; + /* The title text for the looping enabled switch cell */ "Closed Loop" = "Замкнутый цикл"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Замкнутый цикл ВЫКЛ"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Замкнутый цикл требует активного подключенного датчика CGM"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Замкнутый цикл требует завершения настройки"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "в %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "с %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +/* Title text for button to complete setup */ +"Complete Setup" = "Завершить настройку"; + /* The title of the configuration section in settings */ "Configuration" = "Конфигурация"; /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Ошибка конфигурации: %1$@"; +/* Default alert dismissal */ +"Continue" = "Продолжить"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Непрерывный мониторинг гликемии"; @@ -169,26 +374,108 @@ The title text for the glucose target range schedule */ "Correction Range" = "Диапазон коррекции"; +/* Critical Alerts Status text */ +"Critical Alerts" = "Критические оповещения"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Логи критических событий готовы"; + +/* Critical event log export title */ +"Critical Event Logs" = "Логи критических событий"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Не удалось экспортировать журналы критических событий."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Текущая глюкоза"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = "Гликемия %1$@ ниже диапазона коррекции"; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Настраиваемая перезапись"; +"Custom Override" = "Настраиваемое ручное управление"; -/* Button title to delete CGM */ -"Delete CGM" = "Удалить мониторинг"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Пользовательский пресет"; + +/* Date picker label */ +"Date" = "Дата"; + +/* The short unit display string for decibles */ +"dB" = "дБ"; + +/* No comment provided by engineer. */ +"Delete" = "Удалить"; /* The title of the button to remove the credentials for a service */ "Delete Account" = "Удалить аккаунт"; +/* Button title to delete all objects */ +"Delete All" = "Стереть все"; + +/* Button title to delete CGM */ +"Delete CGM" = "Удалить CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Удалить сервис"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Удалить данные тестирования CGM"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Удалить данные тестирования"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Удалить данные тестирования помпы"; + +/* Button text to deliver a bolus */ +"Deliver" = "Подать"; + /* Title text for delivery limits */ -"Delivery Limits" = "Предел подачи"; +"Delivery Limits" = "Пределы подачи"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Лечение диабета"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Вы намеревались ввести %1$@ граммов углеводов для этого блюда?"; /* The action hint of the workout mode toggle button when enabled */ -"Disables" = "Деактивирует"; +"Disables" = "Отключает"; + +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Отклонить"; + +/* No comment provided by engineer. */ +"Done" = "Готово"; + +/* Title for card to log dose */ +"Dose Summary" = "Сводная информация о дозе"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Стратегия дозирования"; + +/* Remote command error description: duration exceed max (1: max duration in hours). */ +"Duration exceeds: %1$.1f hours" = "Продолжительность превышает: %1$.1f часов"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Включить\nBluetooth"; /* The action hint of the workout mode toggle button when disabled */ -"Enables" = "Активирует"; +"Enables" = "Включает"; + +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Введите глюкозу крови, полученную с помощью глюкометра, для получения рекомендуемого количества болюса."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Ввести болюс"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Введите глюкозу по глюкометру"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Введите безопасный предел глюкозы"; /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Введите рубеж приостановки"; @@ -196,44 +483,105 @@ /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Ошибка отмены болюса"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Ошибка экспорта логов"; + /* The alert title for a resume error */ "Error Resuming" = "Ошибка возобновления"; +/* Segmented button title for insulin delivery log event history */ +"Event History" = "История событий"; + /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "В конечном итоге %@"; +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Превышен максимально допустимый болюс в настройках"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "Превышено максимально допустимое количество углеводов"; + /* The title of the alert describing a maximum bolus validation error */ -"Exceeds Maximum Bolus" = "Превышает макс болюс"; +"Exceeds Maximum Bolus" = "Превышает максимальный болюс"; + +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Экспорт логов критических событий"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Экспорт -%1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Не удалось возобновить подачу инсулина"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Глюкоза по глюкометру"; + +/* Secondary text for alerts disabled warning, which appears on the main status screen. */ +"Fix now by turning Notifications, Critical Alerts and Time Sensitive Notifications ON." = "Исправьте ситуацию, включив уведомления, критические оповещения и уведомления, чувствительные к времени."; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "В течение %1$@"; +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Прогнозируемый уровень глюкозы в крови все еще может быть выше целевого диапазона."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Прогнозируемый уровень глюкозы"; + +/* The short unit display string for grams */ +"g" = "г"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Справка по разрешениям на оповещения"; + /* The title of the glucose and prediction graph */ -"Glucose" = "Гликемия"; +"Glucose" = "Глюкоза"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Данным гликемии %1$@"; +"Glucose data is %1$@ old" = "Данные о глюкозе устарели на %1$@"; /* Description of error when glucose data is missing */ "Glucose data not available" = "Данные гликемии недоступны"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Данные о глюкозе теперь доступны"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Ввод глюкозы вне допустимого диапазона"; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Динамика гликемии"; +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "График целевого диапазона глюкозы"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Как обновить (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Немедленно"; + /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "На неопределенное время"; +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Входной максимум превышен"; + /* Title of the prediction input effect for insulin */ "Insulin" = "Инсулин"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Инсулин усвоен х чувствительность к инсулину"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Усвоенный инсулин (U) × Чувствительность к инсулину (%1$@/U)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "Регулировка инсулина была отключена!"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Подача инсулина"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Влияние инсулина"; @@ -242,48 +590,228 @@ The title text for the insulin model setting row */ "Insulin Model" = "Модель инсулина"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Инсулиновая помпа"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ "Insulin Sensitivities" = "Факторы чувствительности инсулина"; +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "График чувствительности к инсулину"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Подача инсулина приостановлена"; + +/* Insulin type label */ +"Insulin Type" = "Тип инсулина"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Прервано %1$@: %2$@ из %3$@ %4$@"; + +/* Remote command error description: invalid bolus amount. */ +"Invalid Bolus Amount" = "Неверный объем болюса"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Неверное количество углеводов"; + /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Неверные данные: %1$@"; +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Недействительная будущая глюкоза"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Неверное показание глюкозы с временной меткой, которая находится на %1$@ в будущем"; + /* The title text for the issue report cell */ "Issue Report" = "Сообщить об ошибе"; +/* The notification description for a meal that was possibly not logged in Loop. */ +"It looks like you may not have logged a meal you ate. Tap to log it now." = "Похоже, что Вы не ввели съеденную Вами еду. Нажмите , чтобы записать ее сейчас."; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Введена большая порция еды"; + /* Glucose HUD accessibility hint */ "Launches CGM app" = "Запускает приложение непрерывного мониторинга CGM"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Подробнее"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Осталось меньше минуты"; + /* The loading message for the diagnostic report screen */ "Loading..." = "Загрузка..."; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Доза из лога"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Зарегистрированная доза инсулина"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Произошел сбой приложения"; + /* The notification title for a loop failure */ -"Loop Failure" = "Ошибка в работе цикла/контура"; +"Loop Failure" = "Ошибка в работе петли"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop обнаружил проблему в настройках Bluetooth и не будет успешно работать, пока Bluetooth не будет включен. Вы не будете получать показания глюкозы и не сможете вводить болюс."; + +/* Warning displayed when user is adding a meal from an missed meal notification */ +"Loop has detected an missed meal and estimated its size. Edit the carb amount to match the amount of any carbs you may have eaten." = "Loop обнаружил пропущенный прием пищи и оценил его размер. Отредактируйте количество углеводов, чтобы оно соответствовало количеству тех углеводов, которые вы, возможно, съели."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Ну удалось успешно замкнуть цикл/контур в %@"; +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop автоматически вводит болюсы, когда потребность в инсулине превышает запланированную базу, и при необходимости использует ВБС, чтобы снизить подачу инсулина ниже запланированной базы."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop не будет успешно работать, пока не будет включен Bluetooth. Вы не сможете получать показания уровня глюкозы или вводить болюсы."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Петля установит ВБС для увеличения или уменьшения подачи инсулина."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Низкий уровень глюкозы"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Управление разрешениями в настройках"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Ручная доза: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Максимальная базальная скорость в час"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Максимальный Болюс"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Превышен максимальный объем болюса"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Превышена максимальная продолжительность"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Болюс на еду"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "мг/дл"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Пропущены данные: %1$@"; +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Отсутствие максимально допустимого болюса в настройках"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Влияние динамики СК"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Доп. инфо"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Выключить все оповещения"; + /* Sensor state description for the non-valid state */ "Needs Attention" = "Требует внимания"; +/* Remote command error description: negative duration error. */ +"Negative duration not allowed" = "Отрицательная продолжительность не допускается"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Во время отключения звуковые сигналы не будут подаваться. По окончании этого периода оповещения и сигналы тревоги возобновятся в обычном режиме."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Нет рекомендации болюса"; + /* The error message displayed for device connection errors. */ -"No connected devices, or failure during device connection" = "Устройства не сопряжены или ошибка во время сопряжения"; +"No connected devices, or failure during device connection" = "Устройства не сопряжены или произошла ошибка во время сопряжения"; + +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Не установлен максимальный болюс"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Нет настроенной помпы"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Нет актуальных данных о глюкозе"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Нет актуальных данных о глюкозе"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Нет актуальных данных от помпы"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Нет, редактировать сумму"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Доставка уведомлений"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "В настройках телефона для доставки уведомлений установлено значение \"Сводка по расписанию\".\n\nЧтобы избежать задержки в получении уведомлений от %1$@, мы рекомендуем установить доставку уведомлений на Немедленную доставку."; + +/* Notifications Status text */ +"Notifications" = "Уведомления"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Уведомления временно отключены"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Уведомления предоставляют важную информацию о приложении %1$@, не требуя открытия приложения."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Уведомления предоставляют важную информацию о приложении %1$@, не требуя открытия приложения.\n\nВключите их в настройках телефона, чтобы получать уведомления %1$@, критические предупреждения и уведомления, чувствительные к времени."; + +/* Notification Setting Status is Off */ +"Off" = "Выключено"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Внимание! Во время подачи произошел сбой петли, и управление помпой было приостановлено до закрытия этого диалога. История событий может быть неточной. Пожалуйста, просмотрите графики введения инсулина в помпе и внимательно следите за уровнем глюкозы в крови."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Включено"; /* The title text for the override presets */ -"Override Presets" = "Перезапись настроек"; +"Override Presets" = "Редактировать параметры"; + +/* The notification title for a meal that was possibly not logged in Loop. */ +"Possible Missed Meal" = "Возможный пропуск приема пищи"; /* The label of the pre-meal mode toggle button */ -"Pre-Meal Targets" = "Целевые значения до приема пищи"; +"Pre-Meal Targets" = "Целевые значения до еды"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Предсказываемая гликемия в %1$@ -- %2$@"; +"Predicted glucose at %1$@ is %2$@." = "Прогнозируемый уровень глюкозы на %1$@ составляет %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Прогнозируемый уровень глюкозы находится в диапазоне."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Прогнозируемое значение глюкозы %1$@ ниже установленного вами предела безопасности глюкозы."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Предсказываемая гликемия %1$@ ниже ваших настроек порога приостановки помпы"; @@ -291,29 +819,53 @@ /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Прогноз: %1$@\nФакт: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Подготовка логов критических событий"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Истечение срока действия профиля"; + +/* Time that profile expires */ +"Profile expires " = "Срок действия профиля истекает"; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Скоро истечет срок действия профиля"; + /* The title of the pump section in settings */ "Pump" = "Помпа"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Низкий заряд батареи помпы"; +"Pump Battery Low" = "Батарея помпы разряжена"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Данные помпы от %1$@ "; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Событие помпы"; + /* Details for configuration error when pump manager is missing */ -"Pump Manager" = "Управление помпой"; +"Pump Manager" = "Менеджер помпо"; + +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Ошибка менеджера помп: %1$@"; /* The notification title for an empty pump reservoir */ "Pump Reservoir Empty" = "Резервуар помпы пуст"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Низкий уровень резервуара помпы"; +"Pump Reservoir Low" = "Мало инсулина в резервуаре"; /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Помпа приостановлена"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Помпа приостановлена. Авто болюсы и ВБС отключены."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Боыстродействующий - взрослые"; +"Rapid-Acting – Adults" = "Быстродействующий - взрослые"; /* Title of insulin model preset */ "Rapid-Acting – Children" = "Быстродействующий - дети"; @@ -324,17 +876,46 @@ /* The title of the cell displaying a recommended temp basal value */ "Recommended Basal" = "Рекомендуемый базал"; +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Рекомендуемый болюс"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Рекомендуемый болюс превышает максимальный болюс"; + /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Рекомендуемый болюс: %@ ед"; +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Удаленный ввод болюса: %@ U"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Удаленный ввод углеводов: %d грамм"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Срок действия удаленной команды истек"; + /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "Резервуар"; +"Reservoir" = "Reservoir"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Ретроспективная коррекция"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Повторить попытку"; +"Retry" = "Повторить"; + +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Сохранить и подать болюс"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Сохранить без болюса"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Запланировано"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Выберите период отключения звука"; /* The title of the services section in settings */ "Services" = "Службы"; @@ -342,45 +923,223 @@ /* The label of the settings button */ "Settings" = "Настройки"; +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Настройка не завершена"; + /* Loop Completion HUD accessibility hint */ -"Shows last loop error" = "Показывает крайнюю ошибку помпы"; +"Shows last loop error" = "Показывает крайнюю ошибку петли"; + +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Простой калькулятор болюса"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Простой калькулятор еды"; /* Format fragment for a start time */ "since %@" = "от %@"; +/* The title of the nightscout site URL credential */ +"Site URL" = "URL сайта"; + +/* Software update button link text */ +"Software Update" = "Обновление программного обеспечения"; + +/* Remote command error description: invalid start time is out of range. */ +"Start time is out of range: %@" = "Время начала вне допустимого диапазона: %@"; + /* The format for the description of a temporary override start date */ "starting at %@" = "начало с %@"; /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Начинаю болюс"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Поддержка"; + /* The title text in settings */ "Suspend Threshold" = "Порог приостановки"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Нажмите здесь, чтобы настроить CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Нажмите здесь, чтобы настроить помпу"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Нажмите здесь, чтобы настроить службу"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Нажмите, чтобы добавить"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ "Tap to Resume" = "Нажмите чтобы возобновить"; +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Нажмите, чтобы остановить"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Временное отключение звуковых оповещений"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Введенное количество болюса меньше минимально допустимого в помпе"; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Алгоритм авто болюса использует более консервативную оценку прогнозируемого уровня глюкозы в крови, чем та, которая используется для корректировки с помощью ВБС.\n\nВ результате прогнозируемый уровень глюкозы в крови после болюса может оказаться выше целевого диапазона."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "Рекомендация по болюсу была обновлена. Пожалуйста, подтвердите новое количество инсулина."; + /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Модель, используемая для цикла/контура, позволяет настройку длительности действия."; +"The legacy model used by Loop, allowing customization of action duration." = "Устаревшая модель, используемая Loop, позволяющая настраивать продолжительность действия."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Максимальная длительность усвоения %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "Максимально допустимое количество составляет %@ грамм."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "Максимально допустимая сумма составляет %1$@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Максимальный объем болюса составляет %@ ед."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "максимальный болюс %@ ед"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Перед подачей болюса необходимо настроить максимальное значение болюса."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Срок действия удаленной команды истек %.0f минут назад."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Настройки терапии"; + +/* Title of the carb entry date picker cell */ +"Time" = "Время"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Уведомления, чувствительные к времени"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Попробуйте еще раз"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Включите Bluetooth для получения предупреждений, сигналов тревоги или показаний датчика глюкозы."; + /* The short unit display string for international units of insulin */ -"U" = "U"; +"U" = "ед"; + +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Невозможно снять предупреждение"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Невозможно достучаться до помпы"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Не удается сохранить запись углеводов"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Невозможно сохранить ручной ввод глюкозы"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Не удается остановить текущий болюс. Переместите свой iPhone ближе к помпе и попробуйте еще раз. Проверьте историю введения инсулина и внимательно следите за уровнем глюкозы."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Неизвестно"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Неизвестная ошибка: %1$@"; + +/* Remote command error description: unknown preset (1: preset name). */ +"Unknown preset: %1$@" = "Неизвестный пресет: %1$@"; + +/* Unknown amount of time in settings' profile expiration section */ +"Unknown time" = "Неизвестное время"; /* The format for the description of a temporary override end date */ "until %@" = "до %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Пока я не введу углеводы"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Пока я не выключу"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Использовать функцию до еды"; + /* The title of the alert controller used to select a duration for workout targets */ "Use Workout Glucose Targets" = "Применить цели гликемии как для физической нагрузки"; +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Использовать пресет физнагрузки"; + /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Внимание! Уведомления о безопасности отключены"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Если текущий или прогнозируемый уровень глюкозы ниже безопасного предела глюкозы, Loop не будет рекомендовать болюс и всегда будет рекомендовать временную базальную скорость 0 единиц в час."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Если текущая или предсказываемая гликемия ниже порога приостановки помпы, алгоритм цикла ипж не рекомендует болюс и всегда рекомендует временный базал 0 ед/час"; +/* Description of missed meal notifications. */ +"When enabled, Loop can notify you when it detects a meal that wasn't logged." = "Если эта функция включена, Loop может уведомить вас, когда обнаружит прием пищи, который не был внесен."; + +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Когда приложение выходит из режима замкнутого цикла, оно использует упрощенный калькулятор болюса, как в обычной помпе."; + /* The label of the workout mode toggle button */ "Workout Targets" = "Целевые значения при физической нагрузке"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Функция физнагрузки была включена более 24 часов. Убедитесь, что вы все еще хотите, чтобы она была включена, или выключите ее в приложении."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Физнагрузка все еще включена"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Да"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Вы можете не получать звуковые, визуальные или вибрационные предупреждения о важной информации по безопасности.\n\nЧтобы решить эту проблему, нажмите \"Настройки\" и убедитесь, что уведомления, критические предупреждения и уведомления с учетом времени включены."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "Время вашего %1$@ было изменено. %2$@ нуждается в точном учете времени, чтобы делать прогнозы уровня глюкозы и соответствующим образом корректировать инсулин.\n\nПроверьте настройки %1$@ (Общие / Дата и время) и убедитесь, что опция \"Устанавливать автоматически\" включена. Невыполнение этого требования может привести к серьезному дефициту или избытку инсулина."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "Ваш уровень глюкозы ниже %1$@. Вы уверены, что хотите ввести болюс?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Ваш уровень глюкозы ниже или прогнозируется, что он будет ниже безопасного предела глюкозы, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Ваш уровень глюкозы ниже безопасного предела глюкозы, %1$@."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "У вас низкий уровень глюкозы. Ешьте углеводы и подумайте о том, чтобы подождать с болюсом, пока уровень глюкозы не достигнет безопасного диапазона."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "У вас низкий уровень глюкозы. Съешьте углеводы и внимательно следите за состоянием здоровья."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Ваш максимальный объем болюса составляет %1$@."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Данные вашей помпы устарели. %1$@ не может рекомендовать количество инсулина."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Ваша помпа вводит ВБС вручную."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Рекомендуемый вами объем болюса превышает лимит подачи болюса %1$@."; + diff --git a/Loop/ru.lproj/Main.strings b/Loop/ru.lproj/Main.strings index 997bf34623..365558fd77 100644 --- a/Loop/ru.lproj/Main.strings +++ b/Loop/ru.lproj/Main.strings @@ -1,45 +1,27 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "г"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ -"3kU-n2-fha.title" = "Состояние"; +"3kU-n2-fha.title" = "Статус"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3,5 ед./час @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Болюс"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "идентификационный № помпы"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Величина болюса"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Предсказываемый"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Детали"; +"aCb-Qs-bpu.text" = "Detail"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Болюс"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Тип еды"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Пометка"; +"bIL-Ub-qYp.text" = "Ярлык"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Изменение глюкозы"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Единицы"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "ед"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Пометка"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "всего грамм"; @@ -47,13 +29,7 @@ "D4C-I2-dhA.text" = "Будущие значения СК предсказываются на основе определения эффекта множественных факторов. Пользуйтесь этим инструментом для перехода между разными вводными чтобы увидеть как они сопоставимы с окончательным предсказанием"; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Пометка"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Настройки"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "Устройства"; +"d6m-qV-wWi.text" = "Ярлык"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "в конечном итоге 92 мг/дл"; @@ -61,8 +37,11 @@ /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Наблюдается"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Активные углеводы : 40 г"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3,5 ед./час @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Действие углеводов"; @@ -71,73 +50,64 @@ "IxU-As-glo.text" = "Наблюдаются изменения СК, вычитаются изменения смоделированные на подаваемом инсулине, могут использоваться для оценки усвоения углеводов"; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Детали"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Предсказываемая гликемия ниже диапазона"; +"J7x-W5-gwo.text" = "Detail"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Рекомендуемый базал"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "Пометка"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Пометка"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Коснуться для установки"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Единицы"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "Ед"; +"Krd-Aa-ret.text" = "Ярлык"; /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "Пометка"; +"OFA-qT-ZAg.text" = "Ярлык"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Предсказываемый СК"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Модель инсулина"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; + +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Модель действия инсулина применяется для оценки влияния инсулина на уровни гликемии. Точная модель может помочь предотвратить переизбыток инсулина и рекомендовать безопасную коррекцию"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Тип еды"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "в конечном итоге 92 мг/дл"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "г COB"; +"SQx-au-ZcM.text" = "г активных углеводов"; /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Гликемия"; +"tuw-av-A3x.text" = "Глюкоза"; -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Пометка"; +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Добавить/редактировать запись об углеводах"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Активный инсулин: 1,5 ед"; +/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ +"ufi-Kj-33k.text" = "Ярлык"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Углеводы"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 часа"; +/* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ +"Wx8-Tf-FnG.text" = "Потребляемое количество"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Рекомендуемый базал"; -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Доставить"; +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Рекомендовано"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Название"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; diff --git a/Loop/sk.lproj/InfoPlist.strings b/Loop/sk.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f9fb85298d --- /dev/null +++ b/Loop/sk.lproj/InfoPlist.strings @@ -0,0 +1,24 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + +/* Privacy - Bluetooth Always Usage Description */ +"NSBluetoothAlwaysUsageDescription" = "Bluetooth sa používa na komunikáciu s inzulínovou pumpou a zariadeniami pre kontinuálne snímanie glykémie."; + +/* Privacy - Bluetooth Peripheral Usage Description */ +"NSBluetoothPeripheralUsageDescription" = "Bluetooth sa používa na komunikáciu s inzulínovou pumpou a zariadeniami pre kontinuálne snímanie glykémie."; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Fotoaparát sa používa na skenovanie čiarových kódov zariadení."; + +/* Privacy - Face ID Usage Description */ +"NSFaceIDUsageDescription" = "Face ID sa používa na overenie podania bolusu inzulínu a na uloženie zmien v nastaveniach terapie."; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Údaje o jedle z databázy Health sa používajú na určenie účinkov glukózy. Údaje o glukóze z databázy Health sa používajú na vytváranie grafov a výpočet hybnosti. Údaje o spánku z databázy Health slúžia na vylepšenie komplikácie Apple Watch."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Údaje o uhlohydrátoch zadané v aplikácii a na hodinkách sú uložené v databáze Health. Údaje o glukóze získané z CGM sú bezpečne uložené v HealthKit."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop používa Siri, aby vám umožnila aktivovať predvoľby pomocou vášho hlasu."; + diff --git a/Loop/sk.lproj/Localizable.strings b/Loop/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..624aba7ec4 --- /dev/null +++ b/Loop/sk.lproj/Localizable.strings @@ -0,0 +1,276 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* The format for an active override preset. (1: preset symbol)(2: preset name) */ +"%@ %@" = "%1$@ %2$@"; + +/* Formats absorbed carb value */ +"%@ absorbed" = "%@ absorbované"; + +/* The subtitle format describing total insulin. (1: localized insulin total) */ +"%@ U Total" = "%@ j Celkom"; + +/* Appends a full-stop to a statement */ +"%@." = "%@ ."; + +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@%2$@ nedokázal zrušiť vašu aktuálnu dočasnú bazálnu dávku, ktorá je vyššia ako nový maximálny bazálny limit, ktorý ste nastavili. To môže viesť k vyššiemu dodávaniu inzulínu, ako je požadované.\n\nZvážte ručné pozastavenie podávania inzulínu a následné okamžité obnovenie, aby ste uplatnili novým bazálny limit."; + +/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + +/* Format string for carb ratio average. (1: value)(2: carb unit) */ +"%1$@ %2$@/U" = "%1$@ %2$@ /j"; + +/* Formats (1: carb start time) and (2: carb absorption duration) */ +"%1$@ + %2$@" = "%1$@ + %2$@"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ nedokáže komunikovať s vašou inzulínovou pumpou. Aplikácia sa bude naďalej pokúšať kontaktovať vašu pumpu, ale informácie o podávaní inzulínu nemožno aktualizovať a nemôže pokračovať žiadna automatizácia.\nMôžete počkať niekoľko minút, aby ste zistili, či sa problém vyriešil, alebo klepnutím na tlačidlo nižšie sa dozviete viac o ďalších možnostiach."; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%@ j"; + +/* Low reservoir alert format string. (1: Number of units remaining) */ +"%1$@ U left" = "Zostáva %1$@ j"; + +/* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ +"%1$@ U left: %2$@" = "Zostáva %1$@ j: %2$@"; + +/* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ +"%1$@ U/hour @ %2$@" = "%1$@ j/hod @ %2$@"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* Formats (1: carb value) and (2: food type) */ +"%1$@: %2$@" = "%1$@ : %2$@"; + +/* Description of the prediction input effect for glucose momentum */ +"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 minútový regresný koeficient glykémie (b1), pokračujúci s poklesom počas 30 minút"; + +/* Subtitle of Fiasp preset */ +"A model based on the published absorption of Fiasp insulin." = "Model založený na publikovanej absorpcii inzulínu Fiasp."; + +/* Subtitle of Rapid-Acting – Adult preset */ +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Model založený na publikovanej absorpcii inzulínu Humalog, Novolog a Apidra u dospelých."; + +/* Action to copy the recommended Bolus value to the actual Bolus Field */ +"AcceptRecommendedBolus" = "Akceptovať Odporúčaný Bolus"; + +/* The title of the Carbs On-Board graph */ +"Active Carbohydrates" = "Aktívne sacharidy"; + +/* The string format describing active carbohydrates. (1: localized glucose value description) */ +"Active Carbohydrates: %@" = "Aktívne sacharidy: %@"; + +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Aktívne sacharidy"; + +/* The title of the Insulin On-Board graph */ +"Active Insulin" = "Aktívny inzulín"; + +/* The string format describing active insulin. (1: localized insulin value description) */ +"Active Insulin: %@" = "Aktívny inzulín: %@"; + +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Zadať sacharidy"; + +/* Action sheet title selecting CGM + Title text for button to set up a CGM */ +"Add CGM" = "Pridať CGM"; + +/* The label of the meal button */ +"Add Meal" = "Zadať jedlo"; + +/* Action sheet title selecting Pump + Title text for button to set up a new pump */ +"Add Pump" = "Pridať pumpu"; + +/* The title of the amplitude API key credential */ +"API Key" = "Kľúč API"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* Confirmation message for deleting a CGM */ +"Are you sure you want to delete this CGM?" = "Naozaj chcete odstrániť toto CGM?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Naozaj chcete odstrániť túto službu?"; + +/* Format fragment for a specific time */ +"at %@" = "o %@"; + +/* The message displayed during a device authentication prompt for bolus specification */ +"Authenticate to Bolus %@ Units" = "Potvrdiť pre Bolus %@ Jednotky"; + +/* Details for configuration error when basal rate schedule is missing */ +"Basal Rate Schedule" = "Harmonogram bazálnej dávky"; + +/* The title of the basal rate profile screen + The title text for the basal rate schedule */ +"Basal Rates" = "Bazálne dávky"; + +/* The label of the bolus entry button + The notification title for a bolus failure */ +"Bolus" = "Bolus"; + +/* The format string for bolus progress. (1: delivered volume)(2: total volume) */ +"Bolused %1$@ of %2$@" = "Podaný bolus %1$@ z %2$@"; + +/* The format string for bolus in progress showing total volume. (1: total volume) */ +"Bolusing %1$@" = "Bolus sa podáva"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Zrušiť"; + +/* The title of the cell indicating a bolus is being canceled */ +"Canceling Bolus" = "Bolus sa ruší"; + +/* Details for missing data error when carb effects are missing */ +"Carb effects" = "Účinky sacharidov"; + +/* The title of the carb ratios schedule screen + The title text for the carb ratio schedule */ +"Carb Ratios" = "Inzulínovo sacharidový pomer"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Zadať sacharidy"; + +/* Title of the prediction input effect for carbohydrates */ +"Carbohydrates" = "Sacharidy"; + +/* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Absorbované sacharidy (g) ÷ Inzulínovo sacharidový pomer (g/j) × Faktor citlivosti na inzulín (%1$@/j)"; + +/* The notification alert describing a low pump battery */ +"Change the pump battery immediately" = "Ihneď vymeňte batériu pumpy"; + +/* The notification alert describing an empty pump reservoir */ +"Change the pump reservoir now" = "Ihneď vymeňte zásobník pumpy"; + +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfigurácia"; + +/* Default alert dismissal */ +"Continue" = "Pokračovať"; + +/* Critical Alerts Status text */ +"Critical Alerts" = "Kritické výstrahy"; + +/* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ +"Current glucose of %1$@ is below correction range." = "Aktuálna glykémie %1$@ je pod cieľovým rozsahom."; + +/* Date picker label */ +"Date" = "Dátum"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Odstrániť účet"; + +/* Button title to delete CGM */ +"Delete CGM" = "Odstrániť CGM"; + +/* Button title to delete a service */ +"Delete Service" = "Odstrániť službu"; + +/* Button text to deliver a bolus */ +"Deliver" = "Podať"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Limity podávania"; + +/* No comment provided by engineer. */ +"Done" = "Hotovo"; + +/* The alert title for a resume error */ +"Error Resuming" = "Chyba pri obnovení"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Obnovenie podávania inzulínu zlyhalo"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The title of the glucose and prediction graph */ +"Glucose" = "Glykémia"; + +/* The title of the insulin delivery graph */ +"Insulin Delivery" = "Podávanie inzulínu"; + +/* Details for configuration error when insulin model is missing + The title text for the insulin model setting row */ +"Insulin Model" = "Inzulínový model"; + +/* Insulin type label */ +"Insulin Type" = "Typ inzulínu"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* Notification Setting Status is Off */ +"Off" = "Vypnuté"; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "Zapnuté"; + +/* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ +"Predicted glucose at %1$@ is %2$@." = "Predpokladaná glykémia o %1$@ je %2$@ ."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Predpokladaná glykémia je v cieľovom rozsahu."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The title of the cell displaying a recommended temp basal value */ +"Recommended Basal" = "Odporúčaný bazal"; + +/* Details for missing data error when reservoir data is missing */ +"Reservoir" = "Rezervoár"; + +/* The title of the notification action to retry a bolus command */ +"Retry" = "Skúsiť znova"; + +/* The label of the settings button */ +"Settings" = "Nastavenia"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "URL adresa webu"; + +/* Title of the carb entry date picker cell */ +"Time" = "Čas"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Neznáme"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Áno"; + diff --git a/Loop/sk.lproj/Main.strings b/Loop/sk.lproj/Main.strings new file mode 100644 index 0000000000..6bca0ce1cc --- /dev/null +++ b/Loop/sk.lproj/Main.strings @@ -0,0 +1,63 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + +/* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ +"3kU-n2-fha.title" = "Stav"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ +"5gz-kZ-iF1.text" = "3,5 i/hod o 12:12"; + +/* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ +"87H-N1-0vJ.text" = "Predpoklad"; + +/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ +"aCb-Qs-bpu.text" = "Detail"; + +/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ +"bq4-98-cQU.text" = "Zmena glykémie"; + +/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ +"d3X-AN-tA5.text" = "g Celkom"; + +/* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ +"D4C-I2-dhA.text" = "Budúca glykémia sa predpovedá kombináciou účinkov viacerých vstupov. Pomocou tohto nástroja môžete prepínať rôzne vstupy, aby ste videli, ako vplývajú v porovnaní s konečnou predpoveďou."; + +/* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ +"E41-FN-nkk.text" = "pravdepodobne 92mg/dl"; + +/* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ +"EAn-Ja-S1d.text" = "Pozorované"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3,5 i/hod o 12:12"; + +/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ +"hZZ-2S-lrd.title" = "Účinky sacharidov"; + +/* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ +"J7x-W5-gwo.text" = "Detail"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ +"k3F-Na-7mn.text" = "Odporúčaný bazal"; + +/* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ +"PA3-sP-cWY.title" = "Predpokladaná glykémia"; + +/* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ +"Rse-x8-amW.text" = "pravdepodobne 92mg/dl"; + +/* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ +"SQx-au-ZcM.text" = "g Aktívne sacharidy"; + +/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ +"tuw-av-A3x.text" = "Glykémia"; + +/* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ +"Vpi-5b-bY5.title" = "Sacharidy"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Odporúčaný bazal"; + +/* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ +"zbc-87-wxZ.text" = "Názov"; + diff --git a/Loop/sv.lproj/InfoPlist.strings b/Loop/sv.lproj/InfoPlist.strings index 8c66331009..11a27169c4 100644 --- a/Loop/sv.lproj/InfoPlist.strings +++ b/Loop/sv.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Loop/sv.lproj/Localizable.strings b/Loop/sv.lproj/Localizable.strings index f2ebc702b2..5dafbda241 100644 --- a/Loop/sv.lproj/Localizable.strings +++ b/Loop/sv.lproj/Localizable.strings @@ -1,12 +1,30 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (återstår: %@)"; +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = " Preprandiellt förval"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = " Träningsförval"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; /* Formats absorbed carb value */ "%@ absorbed" = "%@ absorberat"; +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ återstår"; + /* The subtitle format describing total insulin. (1: localized insulin total) */ "%@ U Total" = "%@ E totalt"; @@ -16,12 +34,21 @@ /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/E"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ kan inte kommunicera med din insulinpump. Appen kommer att fortsätta att försöka nå din pump, men under tiden kan information om insulintillförsel inte uppdateras och automatisering inte fortsätta.\nDu kan vänta flera minuter för att se om problemet löser sig eller klicka på knappen nedan för att läsa mer om andra alternativ."; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ E"; + /* Low reservoir alert format string. (1: Number of units remaining) */ "%1$@ U left" = "%1$@ E kvar"; @@ -37,18 +64,31 @@ /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; + /* Description of the prediction input effect for glucose momentum */ "15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 minuters glukosregressionskoefficient (b₁), fortsatt med 30 minuters avklingande"; /* Description of the prediction input effect for retrospective correction */ "30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min jämförelse av glukosprediktion och faktiskt värde, fortsatt med 60 miuters avklingande."; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Några sekunder återstår"; + +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Det manuellt inmatade blodsockervärdet måste vara mellan %1$@ och %2$@"; + /* Subtitle of Fiasp preset */ "A model based on the published absorption of Fiasp insulin." = "Insulinmodell baserad på publicerade studier av absorption av Fiasp-insulin."; /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Insulinmodell baserad på publicerade studier av absorption av Humalog-, Novolog- samt Apidra-insulin hos vuxna."; +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "En pump måste ha lagts till och konfigurerats innan en bolus ge ges."; + /* Title of the carb entry absorption time cell */ "Absorption Time" = "Absorptionstid"; @@ -61,6 +101,9 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Aktiva kolhydrater: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Aktiva kolhydrater"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "Aktivt insulin"; @@ -74,18 +117,37 @@ Title text for button to set up a CGM */ "Add CGM" = "Lägg till CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Lägg till måltid"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ "Add Pump" = "Lägg till pump"; +/* Title text for button to set up a service */ +"Add Service" = "Lägg till tjänst"; + +/* No comment provided by engineer. */ +"Adjusted for" = "Justerad för"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Behörigheter för Varningar"; + +/* The title of the section containing algorithm settings */ +"Algorithm Settings" = "Algoritminställningar"; + /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "En justering av vuxenmodellen baserad på empirisk effekt på barn."; +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Ett fel uppstod när du skulle spara dina kolhydrater."; + +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Ett fel uppstod när du skulle spara ditt blodsockervärde."; + +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Det finns nu en ny bolusrekommendation."; /* The title of the amplitude API key credential */ "API Key" = "API Key"; @@ -93,15 +155,33 @@ /* The title of the nightscout API secret credential */ "API Secret" = "API Secret"; +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Säkert att du vill radera all händelsehistorik?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Är du säker på att du vill ta bort alla dina loggade doser?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Säkert att du vill radera alla reservoarvärden?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Vill du ta bort alla dina %@data?\n(Denna åtgärd är inte reversibel)"; + /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Är du säker på att du vill radera denna CGM?"; +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Vill du ta bort den här tjänsten?"; + /* Format fragment for a specific time */ "at %@" = "kl. %@"; /* The message displayed during a device authentication prompt for bolus specification */ "Authenticate to Bolus %@ Units" = "Godkänn bolus på %@ enheter"; +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "Godkänn att logga %@ enheter"; + /* Details for configuration error when basal rate schedule is missing */ "Basal Rate Schedule" = "Basaldosschema"; @@ -109,13 +189,27 @@ The title text for the basal rate schedule */ "Basal Rates" = "Basaldoser"; +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth Av"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth är inte tillgängligt"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Varning Bluetooth är Av"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Varning Bluetooth är inte tillgänglig"; + /* The label of the bolus entry button - The notification title for a bolus failure - Title text for bolus screen (manual correction) */ + The notification title for a bolus failure */ "Bolus" = "Bolus"; /* Alert title for an updated bolus recommendation */ -"Bolus Recommendation Updated" = "Bolusrekommendation uppdaterad"; +"Bolus Recommendation Updated" = "Det finns en ny bolusrekommendation"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Bolus sammanfattning"; /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Givit bolus %1$@ av %2$@"; @@ -132,18 +226,19 @@ /* Details for missing data error when carb effects are missing */ "Carb effects" = "Kolhydrateffekter"; -/* Back button text for bolus screen to return to carb entry screen */ +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ "Carb Entry" = "Kolhydrater"; /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Kolhydratskvoter"; +"Carb Ratios" = "Insulinkvoter"; /* The title of the view controller to create a new carb entry */ "carb-entry-title-add" = "Lägg till kolhydrater"; /* The title of the view controller to edit an existing carb entry */ -"carb-entry-title-edit" = "Editera kolhydrater"; +"carb-entry-title-edit" = "Ändra kolhydrater"; /* Title of the prediction input effect for carbohydrates */ "Carbohydrates" = "Kolhydrater"; @@ -167,11 +262,26 @@ "Check your CGM data source" = "Kontrollera din CGM:s datakälla"; /* Carb entry section footer text explaining absorption time */ -"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Välj en längre absorbtionstid för stora måltider eller måltider som innehåller fett och protein. Detta är endast en rekommendation till algoritmen och behöver inte vara exakt."; +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Välj en längre absorptionstid för måltid med mycket fett eller protein. Ofta är det bäst att dela upp måltiden i snabba och långsamma kolhydrater och mata in dessa var för sig."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Stäng"; /* The title text for the looping enabled switch cell */ "Closed Loop" = "Sluten loop"; +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Sluten Loop är AV"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Sluten Loop kräver en aktiv CGM-sensor"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "kl %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "sedan %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; @@ -181,6 +291,9 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Konfigurationsfel %1$@"; +/* Default alert dismissal */ +"Continue" = "Fortsätt"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Kontinuerlig glukosmätning"; @@ -188,42 +301,114 @@ The title text for the glucose target range schedule */ "Correction Range" = "Målvärde"; +/* Critical event log ready text */ +"Critical Event Log Ready" = "Kritisk händelselogg klar"; + +/* Critical event log export title */ +"Critical Event Logs" = "Kritiska händelseloggar"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Kritiska händelseloggar kunde inte exporteras."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Nuvarande blodglukosvärde"; + /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = "Nuvarande glukosvärde %1$@ är under målvärde."; -/* Name of custom override - The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Anpassad override"; +/* The title of the cell indicating a generic temporary override is enabled */ +"Custom Override" = "Anpassad Override"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Inloggningsuppgift"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Anpassad förinställning"; -/* Title of the carb entry date picker cell */ +/* Date picker label */ "Date" = "Tid"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Delete" = "Ta bort"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Radera konto"; + +/* Button title to delete all objects */ +"Delete All" = "Radera allt"; + /* Button title to delete CGM */ "Delete CGM" = "Radera CGM"; -/* The button text to initiate a bolus */ +/* Button title to delete a service */ +"Delete Service" = "Ta bort tjänst"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Ta bort simulerade testvärden från CGM"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Ta bort simulerade testvärden"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Ta bort simulerade pumpvärden"; + +/* Button text to deliver a bolus */ "Deliver" = "Ge bolus"; /* Title text for delivery limits */ "Delivery Limits" = "Maxdoser"; +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Diabetesbehandling"; + /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Stänger av"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Avfärda"; + +/* No comment provided by engineer. */ +"Done" = "Färdig"; + +/* Title for card to log dose */ +"Dose Summary" = "Sammanfattning av dos"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Strategi för insulinbehandling"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Aktivera Bluetooth"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Slår på"; +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Du behöver mata in ett blodsockervärde för att få en rekommenderad bolus."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Ange Bolus"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Ange kapillärt blodsocker"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "Ange tröskelvärde för blodsocker"; + /* The placeholder text instructing users to enter a suspend treshold */ "Enter suspend threshold" = "Ange tröskelvärde"; /* The alert title for an error while canceling a bolus */ "Error Canceling Bolus" = "Fel vid försök att avbryta bolus"; +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Fel vid export av loggar"; + /* The alert title for a resume error */ -"Error Resuming" = "Fel vid försök att återgå"; +"Error Resuming" = "Fel vid återupptagande"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Händelsehistorik"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Förväntat %@"; @@ -231,12 +416,27 @@ /* The title of the alert describing a maximum bolus validation error */ "Exceeds Maximum Bolus" = "Överstiger maxbolusdos"; +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Exportera kritiska händelseloggar"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Exportera-%1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "Misslyckades att återuppta insulintillförsel"; + /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Kapillärt blodsocker"; + /* The format string used to describe a finite workout targets duration */ "For %1$@" = "I %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "Glukos"; @@ -246,12 +446,16 @@ /* Description of error when glucose data is missing */ "Glucose data not available" = "Glukosvärde saknas"; +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "Blodglukosvärde finns nu tillgängligt"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "Det manuellt inmatade blodsockervärdet utanför gränsvärden"; + /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Glukosförändring"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://mysite.herokuapp.com"; - /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Oändligt"; @@ -262,7 +466,7 @@ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulin absorberat (E) × Insulinkänslighet (%1$@/E)"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insulin doserat"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Insulineffekter"; @@ -271,10 +475,22 @@ The title text for the insulin model setting row */ "Insulin Model" = "Insulinmodell"; +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "Insulinpump"; + /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ "Insulin Sensitivities" = "Insulinkänslighet"; +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "Insulintillförsel pausad"; + +/* Insulin type label */ +"Insulin Type" = "Insulintyp"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "Avbruten %1$@: %2$@ av %3$@ %4$@"; + /* The error message when invalid data was encountered. (1: details of invalid data) */ "Invalid data: %1$@" = "Ogiltigt värde: %1$@"; @@ -284,55 +500,122 @@ /* Glucose HUD accessibility hint */ "Launches CGM app" = "Startar CGM-app"; +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Lär dig mer"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Mindre än en minut återstår"; + /* The loading message for the diagnostic report screen */ "Loading..." = "Laddar..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Logga Dos"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Loggad insulindos"; /* The notification title for a loop failure */ -"Loop Failure" = "Loop-fel"; +"Loop Failure" = "Loopfel"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop har upptäckt ett problem med dina Bluetooth-inställningar och kommer inte att fungera förrän Bluetooth är aktiverat. Du kommer varken att kunna se dina blodsockervärden eller att kunna ge någon bolus."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop har inte lyckats köra på %@"; -/* Title text for bolus screen following a carb entry */ +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop kommer att ge bolus automatiskt när insulinbehovet är större än ordinarie basal och kommer, vid behov, att minska din ordinarie basal med temporära basaldoser för att minska insulintillförseln."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop kommer att ställa in tillfälliga basalnivåer för att öka eller minska insulintillförsel."; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maximal bolus"; + +/* Title for bolus entry screen when also entering carbs */ "Meal Bolus" = "Måltidsbolus"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Saknar data: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Momentumeffekter"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Mer info"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Kräver uppmärksamhet"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Ingen bolus rekommenderas"; + /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Ingen ansluten enhet, eller fel vid anslutning till enhet"; -/* Button text to acknowledge an updated bolus recommendation alert - Button text to dismiss unconfigured pump alert. */ +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Ingen maximal bolus har blivit inställd"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Ingen pump konfigurerad"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Inga senaste blodglukosvärde"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Inget aktuellt blodsockervärde"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Det finns inga aktuella pumpdata"; + +/* Notification Setting Status is Off */ +"Off" = "Av"; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ "OK" = "OK"; +/* Notification Setting Status is On */ +"On" = "På"; + /* The title text for the override presets */ "Override Presets" = "Override förinställningar"; -/* Name of pre-meal workout override */ -"Pre-Meal" = "Före måltid"; - /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Målvärden före måltid"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ "Predicted glucose at %1$@ is %2$@." = "Förväntat glukosvärde vid %1$@ är %2$@."; +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "Förväntat blodsocker på %1$@ är under ditt tröskelvärde."; + /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ "Predicted glucose of %1$@ is below your suspend threshold setting." = "Förväntat glukosvärde %1$@ är under ditt tröskelvärde."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ "Predicted: %1$@\nActual: %2$@ (%3$@)" = "Förväntat: %1$@\nFaktiskt: %2$@ (%3$@)"; +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Förbereder kritiska händelseloggar"; + /* The title of the pump section in settings */ "Pump" = "Pump"; @@ -342,6 +625,9 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Pumpvärdena är %1$@ gamla"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pumphändelse"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Pumphantering"; @@ -354,6 +640,12 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Pumpen är pausad"; +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pump pausad. Automatisk dosering är inaktiverad."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Snabbverkande – vuxna"; @@ -364,7 +656,11 @@ "Recommendation expired: %1$@ old" = "Rekommendationen gick ut för %1$@ sedan"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Rekommenderat basalvärde"; +"Recommended Basal" = "Rekommenderad basaldos"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Rekommenderad bolus"; /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Rekommenderad bolus: %@ enheter"; @@ -375,11 +671,13 @@ /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Retrospektiv korrigering"; -/* The button text for attempting a manual loop - The title of the notification action to retry a bolus command */ +/* The title of the notification action to retry a bolus command */ "Retry" = "Försök igen"; -/* The button text to save a carb entry without bolusing */ +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Spara och ge"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ "Save without Bolusing" = "Spara utan att ge bolus"; /* The title of the services section in settings */ @@ -391,11 +689,17 @@ /* Loop Completion HUD accessibility hint */ "Shows last loop error" = "Visar senaste loopfelet"; +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Förenklad bolusdoskalkylator"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Förenklad bolusdoskalkylator"; + /* Format fragment for a start time */ "since %@" = "sedan %@"; /* The title of the nightscout site URL credential */ -"Site URL" = "Adress (URL)"; +"Site URL" = "Nightscout-URL"; /* The format for the description of a temporary override start date */ "starting at %@" = "Börjar kl. %@"; @@ -403,39 +707,124 @@ /* The title of the cell indicating a bolus is being sent */ "Starting Bolus" = "Påbörjar bolus"; +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Support"; + /* The title text in settings */ "Suspend Threshold" = "Tröskelvärde"; +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Tryck här för att ställa in en CGM"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Tryck här för att ställa in en pump"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Tryck här för att ställa in en tjänst"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Tryck för att ange"; + /* The subtitle of the cell displaying an action to resume insulin delivery */ "Tap to Resume" = "Tryck för att återuppta"; +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Tryck för att stoppa"; + /* Alert message for an updated bolus recommendation */ "The bolus recommendation has updated. Please reconfirm the bolus amount." = "Bolusrekommendationen har uppdaterats. Konfirmera bolus"; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "Äldre modell använd av Loop, vilken tillåter anpassing av effektvaraktighet."; +"The legacy model used by Loop, allowing customization of action duration." = "Äldre modell använd av Loop, vilken tillåter anpassning av insulinets verkningstid."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Maximala absorptionstiden är %@"; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Den högst tillåtna bolusmängden är %@ E."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Den maximala bolusdosen är %@ enheter"; +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Den högst tillåtna bolusmängden måste ställas in innan en bolus kan ges."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Behandlingsinställningar"; + +/* Title of the carb entry date picker cell */ +"Time" = "Tid"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Försök igen"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Aktivera Bluetooth för att ta emot varningar, larm eller blodglukosavläsningar."; + /* The short unit display string for international units of insulin */ "U" = "E"; +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Det går inte att nå pump"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Det går inte att spara kolhydrater"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Det går inte att spara manuellt inmatat blodsockervärde"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Det går inte att stoppa pågående bolus. Flytta din iPhone närmare din pump och försök igen. Kontrollera händelsehistorik för insulin för mer detaljerad information och var vaksam på sjunkande blodsocker."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Okänd"; + /* The format for the description of a temporary override end date */ "until %@" = "fram till %@"; +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Tills jag anger kolhydrater"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Tills jag stänger av"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Använd förval 'Före måltid'"; + /* The title of the alert controller used to select a duration for workout targets */ "Use Workout Glucose Targets" = "Använd målvärden för träning"; +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Preset" = "Använd förval 'Träning'"; + /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "När nuvarande eller förväntat blodglukosvärde är under tröskelvärde kommer Loop inte att rekommendera en bolus, och kommer också alltid att föreslå en temporär basal på 0 enheter per timme."; + /* Explanation of suspend threshold */ "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "När nuvarande eller förväntat slutglukosvärde är under tröskelvärdet kommer Loop inte att rekommendera en bolus, utan kommer alltid att föreslå en temporär basal på 0 enheter per timme."; -/* Name of legacy workout override */ -"Workout" = "Träning"; +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "När läget sluten Loop inte används, kommer appen använda en förenklad bolusdoskalkylator likt den en vanlig pump använder."; /* The label of the workout mode toggle button */ "Workout Targets" = "Målvärden för träning"; +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Ett träningsförval har varit aktivt i mer än 24 timmar. Kontrollera om du fortfarande vill ha den på, eller stäng av den i appen."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Träningsförval fortfarande på"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "Ditt blodsocker är lägre än eller förväntas bli lägre än ditt inställda tröskelvärde, %@."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "Ditt blodsocker är lägre än ditt tröskelvärde, %1$@."; + diff --git a/Loop/sv.lproj/Main.strings b/Loop/sv.lproj/Main.strings index fd2b28d404..352f1e692a 100644 --- a/Loop/sv.lproj/Main.strings +++ b/Loop/sv.lproj/Main.strings @@ -1,48 +1,27 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Status"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 E/h kl. 12:12"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Pump-ID"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Bolusmängd"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0,0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Förväntat"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detalj"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Bolus"; +"aCb-Qs-bpu.text" = "Detail"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ "ap1-M6-naG.text" = "Typ av mat"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Etikett"; +"bIL-Ub-qYp.text" = "Label"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Glukosförändring"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Enheter"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "E"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Titel"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g totalt"; @@ -50,20 +29,20 @@ "D4C-I2-dhA.text" = "Förväntat glukosvärde beräknas genom kombination av flera inmatningar. Använd det här verktyget för att jämföra hur de påverkar det förväntade resultatet."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Titel"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Inställningar"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "ENHETER"; +"d6m-qV-wWi.text" = "Label"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "förväntat 5,1 mmol/l"; +"E41-FN-nkk.text" = "Förväntat 5,1 mmol/l"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Observerad"; +/* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ +"Fal-Vf-lfh.normalTitle" = "🍭"; + +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 E/h kl. 12:12"; + /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Kolhydrateffekter"; @@ -71,13 +50,7 @@ "IxU-As-glo.text" = "Observerad glukosförändring, med borttagen förändring modellerad från insulindoser, kan användas för att uppskatta kolhydratabsorptionen."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detalj"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "jQv-xb-gwu"; */ -"jQv-xb-gwu.text" = "Detalj"; - -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Förväntat glukosvärde hamnar under målvärdet"; +"J7x-W5-gwo.text" = "Detail"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Rekommenderad basaldos"; @@ -85,29 +58,17 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "Label"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Titel"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Klicka för att ange"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Enheter"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "E"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "Label"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Förväntat glukosvärde"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insulinmodell"; +/* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ +"Qe9-uc-vPR.normalTitle" = "🍽"; -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "En insulinaktivitetsmodell används för att beräkna effekterna på blodglukosnivåerna. En rättvisande modell kan hjälpa till att förhindra att flera insulindoser läggs på varandra, och istället rekommendera en säkrare korrigering."; +/* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ +"QhO-Yi-AqQ.normalTitle" = "🌮"; /* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ "qPH-vU-xlu.text" = "Typ av mat"; @@ -121,26 +82,32 @@ /* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ "tuw-av-A3x.text" = "Glukos"; +/* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ +"Tz7-80-bJ7.title" = "Lägg till/Ändra kolhydrater"; + /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Titel"; +"ufi-Kj-33k.text" = "Label"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Kolhydrater"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 timmar"; - /* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ "Wx8-Tf-FnG.text" = "Mängd"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Rekommenderad basaldos"; + +/* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ +"xl9-Wc-Pdu.normalTitle" = "🍕"; + +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; + /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Rekommenderad"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Titel"; +"zbc-87-wxZ.text" = "Title"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; diff --git a/Loop/tr.lproj/InfoPlist.strings b/Loop/tr.lproj/InfoPlist.strings index b422a039c4..2c9bfbe1b8 100644 --- a/Loop/tr.lproj/InfoPlist.strings +++ b/Loop/tr.lproj/InfoPlist.strings @@ -1,18 +1,27 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; /* Privacy - Bluetooth Always Usage Description */ -"NSBluetoothAlwaysUsageDescription" = "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices."; +"NSBluetoothAlwaysUsageDescription" = "Bluetooth, insülin pompası ve sürekli glikoz izleme cihazlarıyla iletişim kurmak için kullanılır."; /* Privacy - Bluetooth Peripheral Usage Description */ -"NSBluetoothPeripheralUsageDescription" = "Bluetooth is used to communicate with insulin pump and continuous glucose monitor devices."; +"NSBluetoothPeripheralUsageDescription" = "Bluetooth, insülin pompası ve sürekli glikoz izleme cihazlarıyla iletişim kurmak için kullanılır."; + +/* Privacy - Camera Usage Description */ +"NSCameraUsageDescription" = "Kamera, cihazların barkodlarını taramak için kullanılır."; /* Privacy - Face ID Usage Description */ -"NSFaceIDUsageDescription" = "Face ID is used to authenticate insulin bolus and to save changes to therapy settings."; +"NSFaceIDUsageDescription" = "Face ID, bolus insülini doğrulamak ve tedavi ayarlarındaki değişiklikleri kaydetmek için kullanılır."; /* Privacy - Health Share Usage Description */ -"NSHealthShareUsageDescription" = "Meal data from the Health database is used to determine glucose effects. Glucose data from the Health database is used for graphing and momentum calculation. Sleep data from the Health database is used to improve the Apple Watch complication."; +"NSHealthShareUsageDescription" = "Sağlık veri tabanından alınan yemek verileri, glikoz etkilerini belirlemek için kullanılır. Sağlık veri tabanından alınan glikoz verileri, grafik ve momentum hesaplaması için kullanılır. Sağlık veritabanındaki uyku verileri, Apple Watch komplikasyonunu iyileştirmek için kullanılır."; /* Privacy - Health Update Usage Description */ -"NSHealthUpdateUsageDescription" = "Carbohydrate meal data entered in the app and on the watch is stored in the Health database. Glucose data retrieved from the CGM is stored securely in HealthKit."; +"NSHealthUpdateUsageDescription" = "Uygulamaya ve saate girilen öğün karbonhidrat verileri Sağlık veritabanında saklanır. CGM'den alınan KŞ verileri, HealthKit'te güvenli bir şekilde saklanır."; + +/* Privacy - Siri Usage Description */ +"NSSiriUsageDescription" = "Loop, ön ayarları sesinizle gerçekleştirmenize izin vermek için Siri'yi kullanır."; diff --git a/Loop/tr.lproj/LaunchScreen.strings b/Loop/tr.lproj/LaunchScreen.strings deleted file mode 100644 index 8b13789179..0000000000 --- a/Loop/tr.lproj/LaunchScreen.strings +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Loop/tr.lproj/Localizable.strings b/Loop/tr.lproj/Localizable.strings index 7020b95773..6beb2db149 100644 --- a/Loop/tr.lproj/Localizable.strings +++ b/Loop/tr.lproj/Localizable.strings @@ -1,407 +1,1112 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ -" (pending: %@)" = " (pending: %@)"; +" (pending: %@)" = " (bekliyor: %@)"; + +/* Status row title for premeal override enabled (leading space is to separate from symbol) */ +" Pre-meal Preset" = "Yemek-Öncesi Ön Ayarı"; + +/* remaining time in setting's profile expiration section */ +" remaining" = "kalan"; + +/* Warning text for when Notifications or Critical Alerts Permissions is disabled */ +" Safety Notifications are OFF" = "Güvenlik Bildirimleri KAPALI"; + +/* Status row title for workout override enabled (leading space is to separate from symbol) */ +" Workout Preset" = "Egzersiz Ön Ayarı"; + +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "–"; + +/* No comment provided by engineer. */ +"– –" = "– –"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Full stop character */ +"." = "."; + +/* The format for an active override preset. (1: preset symbol)(2: preset name) */ +"%@ %@" = "%1$@ %2$@"; + +/* Formats absorbed carb value */ +"%@ absorbed" = "Emilen %@"; + +/* Estimated remaining duration with more than a minute */ +"%@ remaining" = "%@ kaldı"; + +/* The subtitle format describing total insulin. (1: localized insulin total) */ +"%@ U Total" = "Toplam %@ Ü"; + +/* Appends a full-stop to a statement */ +"%@." = "%@."; + +/* Alert text for failing to cancel temp basal (1: reason description, 2: app name) */ +"%@%@ was unable to cancel your current temporary basal rate, which is higher than the new Max Basal limit you have set. This may result in higher insulin delivery than desired.\n\nConsider suspending insulin delivery manually and then immediately resuming to enact basal delivery with the new limit in place." = "%1$@ %2$@ , ayarladığınız yeni Maks Bazal limitinden daha yüksek olan mevcut geçici bazal oranınızı iptal edemedi. Bu, istenenden daha yüksek insülin iletimi ile sonuçlanabilir. \n\n İnsülin iletimini manuel olarak askıya almayı ve ardından yeni limit geçerliyken bazal iletimi etkinleştirmek için hemen devam etmeyi düşünün."; + +/* Adds a full-stop to a statement (1: statement, 2: full stop character) */ +"%1@%2@" = "%1$@%2$@"; + +/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; /* Format string for carb ratio average. (1: value)(2: carb unit) */ -"%1$@ %2$@/U" = "%1$@ %2$@/U"; +"%1$@ %2$@/U" = "%1$@ %2$@/Ü"; /* Formats (1: carb start time) and (2: carb absorption duration) */ "%1$@ + %2$@" = "%1$@ + %2$@"; +/* Alert message for closed loop off informational modal. (1: app name) */ +"%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically." = "%1$@ , KAPALI konumda Kapalı Döngü ile çalışıyor. Pompanız ve CGM çalışmaya devam edecek, ancak uygulama dozajı otomatik olarak ayarlamayacaktır."; + +/* Message for alert shown when alert acknowledgement fails for a device, and the device does not provide a LocalizedError. (1: app name) */ +"%1$@ is unable to clear the alert from your device" = "%1$@ , uyarıyı cihazınızdan silemiyor"; + +/* Message for alert shown when delivery status is uncertain. (1: app name) */ +"%1$@ is unable to communicate with your insulin pump. The app will continue trying to reach your pump, but insulin delivery information cannot be updated and no automation can continue.\nYou can wait several minutes to see if the issue resolves or tap the button below to learn more about other options." = "%1$@ insülin pompanızla iletişim kuramıyor. Uygulama pompanıza ulaşmaya çalışmaya devam edecek, ancak insülin iletim bilgileri güncellenemeyecek ve hiçbir otomasyon devam edemeyecektir.\nSorunun çözülüp çözülmediğini görmek için birkaç dakika bekleyebilir veya diğer seçenekler hakkında daha fazla bilgi edinmek için aşağıdaki butona dokunabilirsiniz."; + +/* Time change alert title */ +"%1$@ Time Settings Need Attention" = "%1$@ Zaman Ayarlarına Dikkat Edilmesi Gerekiyor"; + +/* Reservoir entry (1: volume value) */ +"%1$@ U" = "%1$@ Ü"; + /* Low reservoir alert format string. (1: Number of units remaining) */ -"%1$@ U left" = "%1$@ U left"; +"%1$@ U left" = "%1$@ Ü kaldı"; /* Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) */ -"%1$@ U left: %2$@" = "%1$@ U left: %2$@"; +"%1$@ U left: %2$@" = "%1$@ Ü kalan: %2$@"; /* The format for recommended temp basal rate and time. (1: localized rate number)(2: localized time) */ -"%1$@ U/hour @ %2$@" = "%1$@ U/hour @ %2$@"; +"%1$@ U/hour @ %2$@" = "%1$@ Ü/saat @ %2$@"; /* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ "%1$@ v%2$@" = "%1$@ v%2$@"; -/* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ -"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string for body for notification of upcoming provisioning profile expiration. (1: app name) (2: amount of time until expiration */ +"%1$@ will stop working in %2$@. You will need to update before that, with a new provisioning profile." = "%1$@ %2$@ içinde çalışmayı durduracaktır. Bundan önce yeni bir provizyon profili ile güncelleme yapmanız gerekecektir."; /* Formats (1: carb value) and (2: food type) */ "%1$@: %2$@" = "%1$@: %2$@"; -/* The format for an active override preset. (1: preset symbol)(2: preset name) */ -"%@ %@" = "%1$@ %2$@"; +/* Description of a basal temp basal dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) + Description of a bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: unit) */ +"%1$@: %2$@ %3$@" = "%1$@: %2$@ %3$@"; -/* Formats absorbed carb value */ -"%@ absorbed" = "%@ absorbed"; +/* Description of the prediction input effect for glucose momentum */ +"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 dakikalık glikoz regresyon katsayısı (b₁), 30 dakika boyunca bozuk devam etti"; -/* The subtitle format describing total insulin. (1: localized insulin total) */ -"%@ U Total" = "%@ U Total"; +/* Description of the prediction input effect for retrospective correction */ +"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 dakikalık glikoz tahmini ile gerçek karşılaştırması, 60 dakika boyunca bozuk devam etti"; -/* Appends a full-stop to a statement */ -"%@." = "%@."; +/* Estimated remaining duration with a few seconds */ +"A few seconds remaining" = "Birkaç saniye kaldı"; -/* Description of the prediction input effect for glucose momentum */ -"15 min glucose regression coefficient (b₁), continued with decay over 30 min" = "15 min glucose regression coefficient (b₁), continued with decay over 30 min"; +/* Alert message for a manual glucose entry out of range error */ +"A manual glucose entry must be between %@ and %@" = "Manuel KŞ girişi %1$@ ile %2$@ arasında olmalıdır"; -/* Description of the prediction input effect for retrospective correction */ -"30 min comparison of glucose prediction vs actual, continued with decay over 60 min" = "30 min comparison of glucose prediction vs actual, continued with decay over 60 min"; +/* Warning for simple bolus when glucose entry is out of range. (1: upper bound) (2: lower bound) */ +"A manual glucose entry must be between %1$@ and %2$@." = "Manuel KŞ girişi %1$@ ile %2$@ arasında olmalıdır."; /* Subtitle of Fiasp preset */ -"A model based on the published absorption of Fiasp insulin." = "A model based on the published absorption of Fiasp insulin."; +"A model based on the published absorption of Fiasp insulin." = "Fiasp insülininin yayınlanmış emilimine dayanan bir model."; /* Subtitle of Rapid-Acting – Adult preset */ -"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults."; +"A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Yetişkinlerde yayınlanmış Humalog, Novolog ve Apidra insülin emilimine dayalı bir model."; + +/* Software update available section footer (1: app name) */ +"A new version of %@ is available and is recommended to continue using the app." = "%@ 'ın yeni bir sürümü mevcut ve uygulamayı kullanmaya devam etmeniz önerilir."; + +/* Required software update section footer (1: app name) */ +"A new version of %@ is available." = "Yeni bir %@ sürümü mevcuttur."; + +/* Alert message for a missing pump error */ +"A pump must be configured before a bolus can be delivered." = "Bolus iletilmeden önce bir pompanın yapılandırılması gerek."; + +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Emilim Süresi"; /* Action to copy the recommended Bolus value to the actual Bolus Field */ -"AcceptRecommendedBolus" = "AcceptRecommendedBolus"; +"AcceptRecommendedBolus" = "ÖnerilenBolusuKabulEt"; /* The title of the Carbs On-Board graph */ -"Active Carbohydrates" = "Active Carbohydrates"; +"Active Carbohydrates" = "Aktif Karbonhidrat"; /* The string format describing active carbohydrates. (1: localized glucose value description) */ -"Active Carbohydrates: %@" = "Active Carbohydrates: %@"; +"Active Carbohydrates: %@" = "Aktif Karbonhidrat: %@"; + +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Aktif Karb."; /* The title of the Insulin On-Board graph */ -"Active Insulin" = "Active Insulin"; +"Active Insulin" = "Aktif İnsülin"; /* The string format describing active insulin. (1: localized insulin value description) */ -"Active Insulin: %@" = "Active Insulin: %@"; +"Active Insulin: %@" = "Aktif İnsülin: %@"; + +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Karb Girişi Ekle"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ -"Add CGM" = "Add CGM"; +"Add CGM" = "CGM Ekle"; /* The label of the meal button */ -"Add Meal" = "Add Meal"; +"Add Meal" = "Öğün ekle"; /* Action sheet title selecting Pump Title text for button to set up a new pump */ -"Add Pump" = "Add Pump"; +"Add Pump" = "Pompa Ekle"; + +/* Title text for button to set up a service */ +"Add Service" = "Servis Ekle"; + +/* No comment provided by engineer. */ +"Adjusted for" = "için düzeltilmiş"; + +/* Alert Permissions button text + Title of alert management screen */ +"Alert Management" = "Uyarı Yönetimi"; + +/* Alert Permissions button text + Notification & Critical Alert Permissions screen title */ +"Alert Permissions" = "Uyarı İzinleri"; + +/* The title of the section containing algorithm settings */ +"Algorithm Settings" = "Algoritma Ayarları"; /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Title text for button to set up a service */ -"Add Service" = "Add Service"; +/* Warning to ensure the carb entry is accurate during an override */ +"An active override is modifying your carb ratio and insulin sensitivity. If you don't want this to affect your bolus calculation and projected glucose, consider turning off the override." = "Aktif bir geçersiz kılma, karbonhidrat oranınızı ve insülin duyarlılığınızı değiştiriyor. Bunun bolus hesaplamanızı ve öngörülen glikozu etkilemesini istemiyorsanız geçersiz kılmayı kapatmayı düşünün."; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; +/* Alert message for a carb entry persistence error */ +"An error occurred while trying to save your carb entry." = "Karbonhidrat girişinizi kaydetmeye çalışırken bir hata oluştu."; -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; +/* Alert message for a manual glucose entry persistence error */ +"An error occurred while trying to save your manual glucose entry." = "Manuel KŞ girişinizi kaydetmeye çalışırken bir hata oluştu."; -/* The title of the section containing algorithm settings */ -"Algorithm Settings" = "Algorithm Settings"; +/* Invalid onboarding state */ +"An unexpected onboarding error state occurred." = "Beklenmeyen bir ekleme hatası durumu oluştu."; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "An adjustment to the adult model based on empirical effects in children."; +/* Alert message when glucose data returns while on bolus screen */ +"An updated bolus recommendation is available." = "Güncellenmiş bir bolus önerisi mevcuttur."; /* The title of the amplitude API key credential */ -"API Key" = "API Key"; +"API Key" = "API Anahtarı"; /* The title of the nightscout API secret credential */ "API Secret" = "API Secret"; +/* Settings app profile section */ +"App Profile" = "Uygulama Profili"; + +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Tüm geçmiş girişlerini silmek istediğinizden emin misiniz?"; + +/* Action sheet confirmation message for logged dose deletion */ +"Are you sure you want to delete all logged dose entries?" = "Günlüğe kaydedilen tüm doz girişlerini silmek istediğinizden emin misiniz?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Tüm rezervuar değerlerini silmek istediğinizden emin misiniz?"; + +/* No comment provided by engineer. */ +"Are you sure you want to delete all your %@ Data?\n(This action is not reversible)" = "Tüm %@ Verilerinizi silmek istediğinizden emin misiniz?\n (Bu eylem geri alınamaz)"; + /* Confirmation message for deleting a CGM */ -"Are you sure you want to delete this CGM?" = "Are you sure you want to delete this CGM?"; +"Are you sure you want to delete this CGM?" = "Bu CGM'i silmek istediğinizden emin misiniz?"; + +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Bu servisi silmek istediğinizden emin misiniz?"; /* Format fragment for a specific time */ -"at %@" = "at %@"; +"at %@" = "%@"; /* The message displayed during a device authentication prompt for bolus specification */ -"Authenticate to Bolus %@ Units" = "Authenticate to Bolus %@ Units"; +"Authenticate to Bolus %@ Units" = "Bolus için kimlik doğrula %@ Ünite"; + +/* The message displayed during a device authentication prompt to log an insulin dose */ +"Authenticate to log %@ Units" = "%@ Ünite günlüğe kaydetmek için kimlik doğrulaması yapın"; /* Details for configuration error when basal rate schedule is missing */ -"Basal Rate Schedule" = "Basal Rate Schedule"; +"Basal Rate Schedule" = "Bazal Oran Çizelgesi"; /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Basal Rates"; +"Basal Rates" = "Bazal Oranlar"; + +/* Caption for bolus screen notice when no bolus is recommended for the predicted glucose */ +"Based on your predicted glucose, no bolus is recommended." = "Tahmini KŞ'ne bağlı olarak bolus önerilmez."; + +/* Message to the user to that the bluetooth is off */ +"Bluetooth\nOff" = "Bluetooth\nKapalı"; + +/* Message to the user that bluetooth is unavailable to the app */ +"Bluetooth\nUnavailable" = "Bluetooth\nKullanılamıyor"; + +/* Bluetooth off alert title */ +"Bluetooth Off Alert" = "Bluetooth Kapalı Uyarısı"; + +/* Bluetooth unavailable alert title */ +"Bluetooth Unavailable Alert" = "Bluetooth Kullanılamıyor Uyarısı"; /* The label of the bolus entry button The notification title for a bolus failure */ "Bolus" = "Bolus"; +/* The notification title for a bolus issue */ +"Bolus Issue" = "Bolus Sorunu"; + +/* Alert title for an updated bolus recommendation */ +"Bolus Recommendation Updated" = "Bolus Önerisi Güncellendi"; + +/* Title for card displaying carb entry and bolus recommendation */ +"Bolus Summary" = "Bolus Özeti"; + +/* Alert title for a bolus too small validation error */ +"Bolus Too Small" = "Bolus Çok Küçük"; + /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ -"Bolused %1$@ of %2$@" = "Bolused %1$@ of %2$@"; +"Bolused %1$@ of %2$@" = "İletilen Bolus %1$@ / %2$@"; /* The format string for bolus in progress showing total volume. (1: total volume) */ -"Bolusing %1$@" = "Bolusing %1$@"; +"Bolusing %1$@" = "Bolus %1$@"; /* The title of the cancel action in an action sheet */ -"Cancel" = "Cancel"; +"Cancel" = "İptal"; /* The title of the cell indicating a bolus is being canceled */ -"Canceling Bolus" = "Canceling Bolus"; +"Canceling Bolus" = "Bolus İptal ediliyor"; /* Details for missing data error when carb effects are missing */ -"Carb effects" = "Carb effects"; +"Carb effects" = "Karbonhidrat etkileri"; + +/* Back button text for bolus screen to return to carb entry screen + Label for carb entry row on bolus screen */ +"Carb Entry" = "Karb Girişi"; + +/* Details for configuration error when carb ratio schedule is missing */ +"Carb Ratio Schedule" = "Karb Oranı Programı"; /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Carb Ratios"; +"Carb Ratios" = "Karbonhidrat Oranları"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Karb Girişi Ekle"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Karb Girişini Düzenle"; + +/* Title for bolus screen warning when carbohydrate entry is too large */ +"Carbohydrate Entry Too Large" = "Karbonhidrat Girişi Çok Büyük"; /* Title of the prediction input effect for carbohydrates */ -"Carbohydrates" = "Carbohydrates"; +"Carbohydrates" = "Karbonhidratlar"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ -"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)"; +"Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Emilen Karb. (gr) ÷ Karb. Oranı (gr/Ü) × İnsulin duyarlılığı (%1$@/Ü)"; /* The notification alert describing a low pump battery */ -"Change the pump battery immediately" = "Change the pump battery immediately"; +"Change the pump battery immediately" = "Pompa pilini hemen değiştirin"; /* The notification alert describing an empty pump reservoir */ -"Change the pump reservoir now" = "Change the pump reservoir now"; +"Change the pump reservoir now" = "Pompa rezervuarını şimdi değiştirin"; /* Details for configuration error when one or more loop settings are missing */ -"Check settings" = "Check settings"; +"Check settings" = "Ayarları kontrol et"; /* Recovery suggestion when reservoir data is missing */ -"Check that your pump is in range" = "Check that your pump is in range"; +"Check that your pump is in range" = "Pompanızın menzil içinde olup olmadığını kontrol edin"; /* Recovery suggestion when glucose data is missing */ -"Check your CGM data source" = "Check your CGM data source"; +"Check your CGM data source" = "CGM veri kaynağınızı kontrol edin"; + +/* Caption for bolus screen notice when glucose data is in the future */ +"Check your device time and/or remove any invalid data from Apple Health." = "Aygıtınızın saatini kontrol edin ve/veya tüm geçersiz verileri Apple Sağlık'tan kaldırın."; + +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Daha büyük öğünler veya yağ ve protein içeren besinler için daha uzun bir emilim süresi seçin. Bu değer yalnızca algoritmaya rehberlik eder ve kesin olması gerekmez."; + +/* The button label of the action used to dismiss the unsafe notification permission alert */ +"Close" = "Kapat"; /* The title text for the looping enabled switch cell */ -"Closed Loop" = "Closed Loop"; +"Closed Loop" = "Kapalı Döngü"; + +/* Alert title for closed loop off informational modal */ +"Closed Loop OFF" = "Kapalı Döngü KAPALI"; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the sensor is inactive */ +"Closed Loop requires an active CGM Sensor Session" = "Kapalı Döngü, aktif bir CGM Sensör Oturumu gerektirir"; + +/* The description text for the looping enabled switch cell when onboarding is not complete */ +"Closed Loop requires Setup to be Complete" = "Kapalı Döngü, Kurulumun Tamamlanmasını gerektirir"; + +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "%1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "%1$@ den beri"; /* The title of the action used to dismiss an error alert */ -"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; +"com.loudnate.LoopKit.errorAlertActionTitle" = "Tamam"; + +/* Title text for button to complete setup */ +"Complete Setup" = "Kurulumu Tamamla"; /* The title of the configuration section in settings */ -"Configuration" = "Configuration"; +"Configuration" = "Konfigürasyon"; /* The error message displayed for configuration errors. (1: configuration error details) */ -"Configuration Error: %1$@" = "Configuration Error: %1$@"; +"Configuration Error: %1$@" = "Konfigürasyon Hatası: %1$@"; + +/* Default alert dismissal */ +"Continue" = "Devam et"; /* The title of the continuous glucose monitor section in settings */ -"Continuous Glucose Monitor" = "Continuous Glucose Monitor"; +"Continuous Glucose Monitor" = "Sürekli Glikoz İzleme"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "Correction Range"; +"Correction Range" = "Düzeltme Aralığı"; + +/* Critical Alerts Status text */ +"Critical Alerts" = "Kritik Uyarılar"; + +/* Critical event log ready text */ +"Critical Event Log Ready" = "Kritik Olay Günlüğü Hazır"; + +/* Critical event log export title */ +"Critical Event Logs" = "Kritik Olay Günlükleri"; + +/* Critical event log export error alert message */ +"Critical Event Logs were not able to be exported." = "Kritik Olay Günlükleri dışa aktarılamadı."; + +/* Label for glucose entry row on simple bolus screen */ +"Current Glucose" = "Mevcut KŞ"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ -"Current glucose of %1$@ is below correction range." = "Current glucose of %1$@ is below correction range."; +"Current glucose of %1$@ is below correction range." = "%1$@ Mevcut KŞ düzeltme aralığının altında."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Custom Override"; +"Custom Override" = "Özel Geçersiz kılma"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; +/* The title of the cell indicating a generic custom preset is enabled */ +"Custom Preset" = "Özel Ön Ayar"; -/* Button title to delete CGM */ -"Delete CGM" = "Delete CGM"; +/* Date picker label */ +"Date" = "Tarih"; /* The short unit display string for decibles */ "dB" = "dB"; +/* No comment provided by engineer. */ +"Delete" = "Sil"; + /* The title of the button to remove the credentials for a service */ -"Delete Account" = "Delete Account"; +"Delete Account" = "Hesabı sil"; + +/* Button title to delete all objects */ +"Delete All" = "Hepsini sil"; + +/* Button title to delete CGM */ +"Delete CGM" = "CGM Sil"; + +/* Button title to delete a service */ +"Delete Service" = "Servisi Sil"; + +/* No comment provided by engineer. */ +"Delete Testing CGM Data" = "Test CGM Verilerini Sil"; + +/* No comment provided by engineer. */ +"Delete Testing Data" = "Test Verilerini Sil"; + +/* No comment provided by engineer. */ +"Delete Testing Pump Data" = "Test Pompası Verilerini Sil"; + +/* Button text to deliver a bolus */ +"Deliver" = "İlet"; /* Title text for delivery limits */ -"Delivery Limits" = "Delivery Limits"; +"Delivery Limits" = "İletim Limitleri"; + +/* Descriptive text for Therapy Settings */ +"Diabetes Treatment" = "Diyabet Tedavisi"; + +/* Alert body when entered carbohydrates is greater than threshold (1: entered quantity in grams) */ +"Did you intend to enter %1$@ grams as the amount of carbohydrates for this meal?" = "Bu yemek için karbonhidrat miktarı olarak %1$@ gram girmeyi düşündünüz mü?"; /* The action hint of the workout mode toggle button when enabled */ -"Disables" = "Disables"; +"Disables" = "Devre Dışı"; + +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Reddet"; + +/* No comment provided by engineer. */ +"Done" = "Tamamlandı"; + +/* Title for card to log dose */ +"Dose Summary" = "Doz Özeti"; + +/* The title of the Dosing Strategy section in settings */ +"Dosing Strategy" = "Dozlama Stratejisi"; + +/* Message to the user to enable bluetooth */ +"Enable\nBluetooth" = "Etkinleştir\nBluetooth"; /* The action hint of the workout mode toggle button when disabled */ -"Enables" = "Enables"; +"Enables" = "Etkin"; + +/* Caption for bolus screen notice when glucose data is missing or stale */ +"Enter a blood glucose from a meter for a recommended bolus amount." = "Önerilen bolus miktarı için bir ölçüm cihazından bir kan şekeri girin."; + +/* Button text to begin entering a bolus */ +"Enter Bolus" = "Bolus girin"; + +/* Button text prompting manual glucose entry on bolus screen */ +"Enter Fingerstick Glucose" = "Parmak Ucu KŞ Girin"; + +/* The placeholder text instructing users to enter a glucose safety limit */ +"Enter glucose safety limit" = "KŞ güvenlik limitini girin"; /* The placeholder text instructing users to enter a suspend treshold */ -"Enter suspend threshold" = "Enter suspend threshold"; +"Enter suspend threshold" = "Askıya alma eşiğini girin"; /* The alert title for an error while canceling a bolus */ -"Error Canceling Bolus" = "Error Canceling Bolus"; +"Error Canceling Bolus" = "Bolus İptali Hatası"; + +/* Critical event log export error alert title */ +"Error Exporting Logs" = "Günlükleri Dışa Aktarırken Hata"; /* The alert title for a resume error */ -"Error Resuming" = "Error Resuming"; +"Error Resuming" = "Sürdürme Hatası"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Etkinlik Geçmişi"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ -"Eventually %@" = "Eventually %@"; +"Eventually %@" = "Nihai KŞ %@"; + +/* Remote command error description: bolus exceeds maximum bolus in settings. */ +"Exceeds maximum allowed bolus in settings" = "Ayarlarda izin verilen maksimum bolusu aşıyor"; + +/* Remote command error description: carbs exceed maximum amount. */ +"Exceeds maximum allowed carbs" = "İzin verilen maksimum karbonhidrat miktarını aşıyor"; /* The title of the alert describing a maximum bolus validation error */ -"Exceeds Maximum Bolus" = "Exceeds Maximum Bolus"; +"Exceeds Maximum Bolus" = "Maksimum Bolusu Aşıyor"; + +/* The title of the export critical event logs in support */ +"Export Critical Event Logs" = "Kritik Olay Günlüklerini Dışa Aktarma"; + +/* The export file name formatted string (1: timestamp) */ +"Export-%1$@" = "Dışa Aktar- %1$@"; + +/* The alert title for a resume error */ +"Failed to Resume Insulin Delivery" = "İnsülin İletimine Devam Edilemedi"; /* Title of insulin model preset */ "Fiasp" = "Fiasp"; +/* Label for manual glucose entry row on bolus screen */ +"Fingerstick Glucose" = "Parmak Ucu KŞ"; + /* The format string used to describe a finite workout targets duration */ -"For %1$@" = "For %1$@"; +"For %1$@" = "%1$@ için"; + +/* No comment provided by engineer. */ +"Forecasted blood glucose may still be higher than target range." = "Öngörülen KŞ, hala hedef aralıktan yüksek olabilir."; + +/* Title for forecast explanation modal on bolus view */ +"Forecasted Glucose" = "Tahmini KŞ"; + +/* The short unit display string for grams */ +"g" = "gr"; + +/* Get help with Alert Permissions support button text */ +"Get help with Alert Permissions" = "Uyarı İzinleri ile ilgili yardım alın"; /* The title of the glucose and prediction graph */ -"Glucose" = "Glucose"; +"Glucose" = "Kan şekeri"; /* The error message when glucose data is too old to be used. (1: glucose data age in minutes) */ -"Glucose data is %1$@ old" = "Glucose data is %1$@ old"; +"Glucose data is %1$@ old" = "%1$@ eski KŞ verisi"; /* Description of error when glucose data is missing */ -"Glucose data not available" = "Glucose data not available"; +"Glucose data not available" = "KŞ verisi mevcut değil"; + +/* Alert title when glucose data returns while on bolus screen */ +"Glucose Data Now Available" = "KŞ Verileri Artık Kullanılabilir"; + +/* Alert title for a manual glucose entry out of range error + Title for bolus screen warning when glucose entry is out of range */ +"Glucose Entry Out of Range" = "KŞ Girişi Aralık Dışında"; /* Title of the prediction input effect for glucose momentum */ -"Glucose Momentum" = "Glucose Momentum"; +"Glucose Momentum" = "KŞ Momentumu"; + +/* Details for configuration error when glucose target range schedule is missing */ +"Glucose Target Range Schedule" = "KŞ Hedef Aralığı Programı"; + +/* The title text for how to update */ +"How to update (LoopDocs)" = "Nasıl güncellenir (LoopDocs)"; + +/* Immediate Delivery status text */ +"Immediate" = "Acilen"; /* The title of a target alert action specifying an indefinitely long workout targets duration */ -"Indefinitely" = "Indefinitely"; +"Indefinitely" = "Süresiz"; + +/* Title of the alert when carb input maximum was exceeded. */ +"Input Maximum Exceeded" = "Maksimum Giriş Değeri Aşıldı"; /* Title of the prediction input effect for insulin */ -"Insulin" = "Insulin"; +"Insulin" = "İnsülin"; /* Description of the prediction input effect for insulin */ -"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)"; +"Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Emilen İnsulin (Ü) × İnsulin Duyarlılığı (%1$@/Ü)"; + +/* Notification body for crash recovery alert */ +"Insulin adjustments have been disabled!" = "İnsülin ayarlamaları devre dışı bırakıldı!"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Insulin Delivery"; +"Insulin Delivery" = "İnsulin İletimi"; /* Details for missing data error when insulin effects are missing */ -"Insulin effects" = "Insulin effects"; +"Insulin effects" = "İnsülin etkileri"; /* Details for configuration error when insulin model is missing The title text for the insulin model setting row */ -"Insulin Model" = "Insulin Model"; +"Insulin Model" = "İnsülin Modeli"; + +/* Descriptive text for Insulin Pump */ +"Insulin Pump" = "İnsülin pompası"; /* The title of the insulin sensitivities schedule screen The title text for the insulin sensitivity schedule */ -"Insulin Sensitivities" = "Insulin Sensitivities"; +"Insulin Sensitivities" = "İnsülin Duyarlılığı"; + +/* Details for configuration error when insulin sensitivity schedule is missing */ +"Insulin Sensitivity Schedule" = "İnsülin Duyarlılık Programı"; + +/* The title of the cell indicating the pump is suspended */ +"Insulin Suspended" = "İnsülin Askıya Alındı"; + +/* Insulin type label */ +"Insulin Type" = "İnsülin Tipi"; + +/* Description of an interrupted bolus dose entry (1: title for dose type, 2: value (? if no value) in bold, 3: programmed value (? if no value), 4: unit) */ +"Interrupted %1$@: %2$@ of %3$@ %4$@" = "%1$@ kesintiye uğradı: %3$@ %4$@'nın %2$@ 'si"; + +/* Remote command error description: invalid carb amount. */ +"Invalid carb amount" = "Geçersiz karb miktarı"; /* The error message when invalid data was encountered. (1: details of invalid data) */ -"Invalid data: %1$@" = "Invalid data: %1$@"; +"Invalid data: %1$@" = "Geçersiz veri: %1$@"; + +/* Title for bolus screen notice when glucose data is in the future */ +"Invalid Future Glucose" = "Geçersiz Gelecek Glikoz"; + +/* The error message when glucose data is in the future. (1: glucose data time in future in minutes) */ +"Invalid glucose reading with a timestamp that is %1$@ in the future" = "Gelecekte %1$@ olan bir zaman damgasıyla geçersiz KŞ okuması"; /* The title text for the issue report cell */ -"Issue Report" = "Issue Report"; +"Issue Report" = "Sorun Raporu"; + +/* Title of the warning shown when a large meal was entered */ +"Large Meal Entered" = "Büyük Yemek Girildi"; /* Glucose HUD accessibility hint */ -"Launches CGM app" = "Launches CGM app"; +"Launches CGM app" = "CGM uygulamasına erişim"; + +/* OK button title for alert shown when delivery status is uncertain */ +"Learn More" = "Daha fazla bilgi edin"; + +/* Estimated remaining duration with less than a minute */ +"Less than a minute remaining" = "Bir dakikadan az kaldı"; /* The loading message for the diagnostic report screen */ -"Loading..." = "Loading..."; +"Loading..." = "Yükleniyor..."; + +/* Button text to log a dose + Title for dose logging screen */ +"Log Dose" = "Günlük Doz"; + +/* The title of the screen displaying a manually entered insulin dose */ +"Logged Insulin Dose" = "Kayıtlı İnsülin Dozu"; + +/* Title for crash recovery alert */ +"Loop Crashed" = "Loop Çöktü"; /* The notification title for a loop failure */ -"Loop Failure" = "Loop Failure"; +"Loop Failure" = "Döngü Hatası"; + +/* Bluetooth unavailable alert body. */ +"Loop has detected an issue with your Bluetooth settings, and will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Loop, Bluetooth ayarlarınızla ilgili bir sorun algıladı ve Bluetooth etkinleştirilene kadar başarılı bir şekilde çalışmayacaktır. KŞ okumaları almayacaksınız veya bolus yapamayacaksınız."; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ -"Loop has not completed successfully in %@" = "Loop has not completed successfully in %@"; +"Loop has not completed successfully in %@" = "Döngü %@ içinde başarıyla tamamlanamadı"; + +/* Description string for automatic bolus dosing strategy */ +"Loop will automatically bolus when insulin needs are above scheduled basal, and will use temporary basal rates when needed to reduce insulin delivery below scheduled basal." = "Loop, insülin ihtiyaçları programlanan bazalın üzerine çıktığında otomatik olarak bolus yapacak ve gerektiğinde insülin iletimini planlanan bazalın altına düşürmek için geçici bazal oranları kullanacaktır."; + +/* Bluetooth off background alert body. */ +"Loop will not work successfully until Bluetooth is enabled. You will not receive glucose readings, or be able to bolus." = "Bluetooth etkinleştirilene kadar döngü başarılı bir şekilde çalışmayacaktır. KŞ ölçümleri alamayacak veya bolus yapamayacaksınız."; + +/* Description string for temp basal only dosing strategy */ +"Loop will set temporary basal rates to increase and decrease insulin delivery." = "Loop, insülin iletimini artırmak ve azaltmak için geçici bazal oranlar ayarlayacaktır."; + +/* Title for bolus screen warning when glucose is below glucose warning limit. + Title for bolus screen warning when glucose is below suspend threshold, but a bolus is recommended */ +"Low Glucose" = "Düşük KŞ"; + +/* Manage Permissions in Settings button text */ +"Manage Permissions in Settings" = "Ayarlarda İzinleri Yönetin"; + +/* Description of a bolus dose entry (1: value (? if no value) in bold, 2: unit) */ +"Manual Dose: %1$@ %2$@" = "Manuel Doz: %1$@ %2$@"; + +/* Details for configuration error when maximum basal rate per hour is missing */ +"Maximum Basal Rate Per Hour" = "Saat Başı Maksimum Bazal Oran"; + +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Maksimum Bolus"; + +/* Title for bolus screen warning when max bolus is exceeded */ +"Maximum Bolus Exceeded" = "Maksimum Bolus Aşıldı"; + +/* Alert title when maximum duration exceeded. */ +"Maximum Duration Exceeded" = "Maksimum Süre Aşıldı"; + +/* Title for bolus entry screen when also entering carbs */ +"Meal Bolus" = "Yemek Bolusu"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; /* The error message for missing data. (1: missing data details) */ -"Missing data: %1$@" = "Missing data: %1$@"; +"Missing data: %1$@" = "Eksik veri: %1$@"; + +/* Remote command error description: missing maximum bolus in settings. */ +"Missing maximum allowed bolus in settings" = "Ayarlarda izin verilen maksimum bolus eksik"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* Details for missing data error when momentum effects are missing */ -"Momentum effects" = "Momentum effects"; +"Momentum effects" = "Momentum etkileri"; + +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Daha fazla bilgi"; + +/* Label for toggle to mute all alerts */ +"Mute All Alerts" = "Tüm Uyarıları Sessize Al"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "İlgilenmeniz gerekiyor"; /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; -/* Sensor state description for the non-valid state */ -"Needs Attention" = "Needs Attention"; +/* Description of temporary mute alerts */ +"No alerts will sound while muted. Once this period ends, your alerts and alarms will resume as normal." = "Sessiz durumdayken hiçbir uyarı çalmaz. Bu süre sona erdiğinde, uyarılarınız ve alarmlarınız normal şekilde devam edecektir."; + +/* Title for bolus screen notice when no bolus is recommended + Title for bolus screen warning when glucose is below suspend threshold, and a bolus is not recommended + Title for bolus screen warning when no bolus is recommended */ +"No Bolus Recommended" = "Bolus Önerilmez"; /* The error message displayed for device connection errors. */ -"No connected devices, or failure during device connection" = "No connected devices, or failure during device connection"; +"No connected devices, or failure during device connection" = "Bağlı cihaz yok veya cihaz bağlantısı sırasında hata"; + +/* Alert title for a missing maximum bolus setting error */ +"No Maximum Bolus Configured" = "Yapılandırılmış Maksimum Bolus Yok"; + +/* Alert title for a missing pump error */ +"No Pump Configured" = "Yapılandırılmış Pompa Yok"; + +/* The title of the cell indicating that there is no recent glucose */ +"No Recent Glucose" = "Son KŞ Yok"; + +/* Title for bolus screen notice when glucose data is missing or stale */ +"No Recent Glucose Data" = "Son KŞ Verisi Yok"; + +/* Title for bolus screen notice when pump data is missing or stale */ +"No Recent Pump Data" = "Son Pompa Verisi Yok"; + +/* The title of the action used when rejecting the the amount of carbohydrates entered. */ +"No, edit amount" = "Hayır, miktarı düzenle"; + +/* Notification Delivery Status text */ +"Notification Delivery" = "Bildirim Gönderimi"; + +/* Format for Critical Alerts permissions disabled alert body. (1: app name) */ +"Notification delivery is set to Scheduled Summary in your phone’s settings.\n\nTo avoid delay in receiving notifications from %1$@, we recommend notification delivery be set to Immediate Delivery." = "Bildirim gönderimi, telefonunuzun ayarlarında Zamanlanmış Özet olarak ayarlanmıştır.\n\n%1$@ adresinden bildirim almakta gecikmeyi önlemek için bildirim gönderimini Anında Gönderim olarak ayarlanmasını öneririz."; + +/* Notifications Status text */ +"Notifications" = "Bildirimler"; + +/* Scheduled Delivery Enabled alert title */ +"Notifications Delayed" = "Bildirimler Gecikti"; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app." = "Bildirimler, uygulamayı açmanıza gerek kalmadan size önemli %1$@ uygulama bilgilerini verir."; + +/* Alert Permissions descriptive text (1: app name) */ +"Notifications give you important %1$@ app information without requiring you to open the app.\n\nKeep these turned ON in your phone’s settings to ensure you receive %1$@ Notifications, Critical Alerts, and Time Sensitive Notifications." = "Bildirimler, uygulamayı açmanıza gerek kalmadan size önemli %1$@ uygulama bilgilerini verir. \n\n %1$@ Bildirimler, Kritik Uyarılar ve Zamana Duyarlı Bildirimler aldığınızdan emin olmak için telefonunuzun ayarlarında bunları AÇIK durumda tutun."; + +/* Notification Setting Status is Off */ +"Off" = "Kapalı"; + +/* Modal body for crash recovery alert */ +"Oh no! Loop crashed while dosing, and insulin adjustments have been paused until this dialog is closed. Dosing history may not be accurate. Please review Insulin Delivery charts, and monitor your blood glucose carefully." = "Oh hayır! Dozlama sırasında Loop çöktü ve bu iletişim kutusu kapatılana kadar insülin ayarlamaları duraklatıldı. Dozlama geçmişi doğru olmayabilir. Lütfen İnsülin İletim tablolarını gözden geçirin ve kan şekerinizi dikkatle izleyin."; + +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "Tamam"; + +/* Notification Setting Status is On */ +"On" = "Açık"; /* The title text for the override presets */ -"Override Presets" = "Override Presets"; +"Override Presets" = "Geçersiz Kılma Ön Ayarları"; /* The label of the pre-meal mode toggle button */ -"Pre-Meal Targets" = "Pre-Meal Targets"; +"Pre-Meal Targets" = "Yemek Öncesi Hedefler"; /* Message when offering bolus recommendation even though bg is below range and minBG is in future. (1: glucose time)(2: glucose number) */ -"Predicted glucose at %1$@ is %2$@." = "Predicted glucose at %1$@ is %2$@."; +"Predicted glucose at %1$@ is %2$@." = "Tahmini KŞ %1$@ %2$@."; + +/* Notice when predicted glucose for bolus recommendation is in range */ +"Predicted glucose is in range." = "Tahmini KŞ aralık içinde."; + +/* Notice message when recommending bolus when BG is below the glucose safety limit. (1: glucose value) */ +"Predicted glucose of %1$@ is below your glucose safety limit setting." = "%1$@ tahmini KŞ, KŞ güvenlik limiti ayarınızın altında."; /* Notice message when recommending bolus when BG is below the suspend threshold. (1: glucose value) */ -"Predicted glucose of %1$@ is below your suspend threshold setting." = "Predicted glucose of %1$@ is below your suspend threshold setting."; +"Predicted glucose of %1$@ is below your suspend threshold setting." = "Tahmini KŞ %1$@ askıya alma eşiği ayarınızın altında."; /* Format string describing retrospective glucose prediction comparison. (1: Predicted glucose)(2: Actual glucose)(3: difference) */ -"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Predicted: %1$@\nActual: %2$@ (%3$@)"; +"Predicted: %1$@\nActual: %2$@ (%3$@)" = "Tahmini: %1$@\nGüncel: %2$@ (%3$@)"; + +/* Preparing critical event log text */ +"Preparing Critical Event Logs" = "Kritik Olay Günlüklerinin Hazırlanması"; + +/* Settings App Profile expiration view */ +"Profile Expiration" = "Profil Sona Erme"; + +/* Time that profile expires */ +"Profile expires " = "Profilin süresi doluyor"; + +/* The title for notification of upcoming profile expiration */ +"Profile Expires Soon" = "Profil Yakında Sona Eriyor"; /* The title of the pump section in settings */ -"Pump" = "Pump"; +"Pump" = "Pompa"; /* The notification title for a low pump battery */ -"Pump Battery Low" = "Pump Battery Low"; +"Pump Battery Low" = "Pompa Pili Düşük"; /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ -"Pump data is %1$@ old" = "Pump data is %1$@ old"; +"Pump data is %1$@ old" = "Pompa verisi %1$@ eski"; + +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pompa Etkinliği"; /* Details for configuration error when pump manager is missing */ -"Pump Manager" = "Pump Manager"; +"Pump Manager" = "Pompa Yöneticisi"; + +/* The error message displayed for pump manager errors. (1: pump manager error) */ +"Pump Manager Error: %1$@" = "Pompa Yöneticisi Hatası: %1$@"; /* The notification title for an empty pump reservoir */ -"Pump Reservoir Empty" = "Pump Reservoir Empty"; +"Pump Reservoir Empty" = "Pompa Rezervuarı Boş"; /* The notification title for a low pump reservoir */ -"Pump Reservoir Low" = "Pump Reservoir Low"; +"Pump Reservoir Low" = "Pompa Rezervuarı Düşük"; /* The title of the cell indicating the pump is suspended */ -"Pump Suspended" = "Pump Suspended"; +"Pump Suspended" = "Pompa Askıya Alındı"; + +/* The error message displayed for pumpSuspended errors. */ +"Pump Suspended. Automatic dosing is disabled." = "Pompa Askıya Alındı. Otomatik dozlama devre dışı bırakıldı."; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* Title of insulin model preset */ -"Rapid-Acting – Adults" = "Rapid-Acting – Adults"; +"Rapid-Acting – Adults" = "Hızlı Etkili – Yetişkinler"; /* Title of insulin model preset */ -"Rapid-Acting – Children" = "Rapid-Acting – Children"; +"Rapid-Acting – Children" = "Hızlı Etkili – Çocuklar"; /* The error message when a recommendation has expired. (1: age of recommendation in minutes) */ -"Recommendation expired: %1$@ old" = "Recommendation expired: %1$@ old"; +"Recommendation expired: %1$@ old" = "Önerinin süresi doldu: %1$@ eski"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Recommended Basal"; +"Recommended Basal" = "Önerilen Bazal"; + +/* Label for recommended bolus row on bolus screen + Label for recommended bolus row on simple bolus screen */ +"Recommended Bolus" = "Önerilen Bolus"; + +/* Title for bolus screen warning when recommended bolus exceeds max bolus */ +"Recommended Bolus Exceeds Maximum Bolus" = "Önerilen Bolus Maksimum Bolusu Aşıyor"; /* Accessibility hint describing recommended bolus units */ -"Recommended Bolus: %@ Units" = "Recommended Bolus: %@ Units"; +"Recommended Bolus: %@ Units" = "Önerilen Bolus: %@ Ünite"; + +/* The notification title for a remote bolus. (1: Bolus amount) + The notification title for a remote failure. (1: Bolus amount) */ +"Remote Bolus Entry: %@ U" = "Uzak Bolus Girişi: %@ U"; + +/* The carb amount message for a remote carbs entry notification. (1: Carb amount in grams) */ +"Remote Carbs Entry: %d grams" = "Uzak Karbonhidrat Girişi: %d gram"; + +/* The notification title for the remote command expiration error */ +"Remote Command Expired" = "Uzak Komutun Süresi Doldu"; /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "Reservoir"; +"Reservoir" = "Rezervuar"; /* Title of the prediction input effect for retrospective correction */ -"Retrospective Correction" = "Retrospective Correction"; +"Retrospective Correction" = "Geçmişe Dönük Düzeltme"; /* The title of the notification action to retry a bolus command */ -"Retry" = "Retry"; +"Retry" = "Yeniden dene"; + +/* Button text to save carbs and/or manual glucose entry and deliver a bolus */ +"Save and Deliver" = "Kaydet ve İlet"; + +/* Button text to save carbs and/or manual glucose entry without a bolus */ +"Save without Bolusing" = "Bolus olmadan Kaydet"; + +/* Scheduled Delivery status text */ +"Scheduled" = "Planlanan"; + +/* List header for mute all alerts period */ +"Select Mute Period" = "Sessize Alma Dönemi'ni seçin"; /* The title of the services section in settings */ -"Services" = "Services"; +"Services" = "Servisler"; /* The label of the settings button */ -"Settings" = "Settings"; +"Settings" = "Ayarlar"; + +/* The title of the cell indicating that onboarding is suspended */ +"Setup Incomplete" = "Kurulum Tamamlanmadı"; /* Loop Completion HUD accessibility hint */ -"Shows last loop error" = "Shows last loop error"; +"Shows last loop error" = "Son döngü hatasını gösterir"; + +/* Title of simple bolus view when not displaying meal entry */ +"Simple Bolus Calculator" = "Basit Bolus Hesaplayıcı"; + +/* Title of simple bolus view when displaying meal entry */ +"Simple Meal Calculator" = "Basit Yemek Hesaplayıcı"; /* Format fragment for a start time */ -"since %@" = "since %@"; +"since %@" = "%@ den beri"; /* The title of the nightscout site URL credential */ -"Site URL" = "Site URL"; +"Site URL" = "Nightscout URL"; + +/* Software update button link text */ +"Software Update" = "Yazılım güncellemesi"; /* The format for the description of a temporary override start date */ -"starting at %@" = "starting at %@"; +"starting at %@" = "%@ tarihinde başladı"; /* The title of the cell indicating a bolus is being sent */ -"Starting Bolus" = "Starting Bolus"; +"Starting Bolus" = "Bolus başlatılıyor"; + +/* Section title for Support + Support screen title + The title of the support item in settings + The title of the support section in settings */ +"Support" = "Destek"; /* The title text in settings */ -"Suspend Threshold" = "Suspend Threshold"; +"Suspend Threshold" = "Eşiği Askıya Al"; + +/* Descriptive text for button to add CGM device */ +"Tap here to set up a CGM" = "Bir CGM ayarlamak için buraya dokunun"; + +/* Descriptive text for button to add pump device */ +"Tap here to set up a pump" = "Bir pompa ayarlamak için buraya dokunun"; + +/* The descriptive text of the add service button in settings */ +"Tap here to set up a Service" = "Bir Servis ayarlamak için buraya dokunun"; + +/* The subtitle of the cell displaying an action to add a manually measurement glucose value */ +"Tap to Add" = "Eklemek için dokunun"; /* The subtitle of the cell displaying an action to resume insulin delivery */ -"Tap to Resume" = "Tap to Resume"; +"Tap to Resume" = "Sürdürmek için dokunun"; + +/* Message presented in the status row instructing the user to tap this row to stop a bolus */ +"Tap to Stop" = "Durdurmak için dokunun"; + +/* The title of the cell indicating alerts are temporarily muted */ +"Temp Mute Alerts" = "Geçici Sessize Alınan Uyarılar"; + +/* Alert message for a bolus too small validation error */ +"The bolus amount entered is smaller than the minimum deliverable." = "Girilen bolus miktarı, minimum teslim edilebilir miktardan daha küçük."; + +/* Forecast explanation modal on bolus view */ +"The bolus dosing algorithm uses a more conservative estimate of forecasted blood glucose than what is used to adjust your basal rate.\n\nAs a result, your forecasted blood glucose after a bolus may still be higher than your target range." = "Bolus dozlama algoritması, bazal hızınızı ayarlamak için kullanılandan daha ihtiyatlı bir kan şekeri tahmini kullanır. \n\n Sonuç olarak, bir bolustan sonra tahmin edilen kan şekeriniz, hedef aralığınızdan daha yüksek olabilir."; + +/* Alert message for an updated bolus recommendation */ +"The bolus recommendation has updated. Please reconfirm the bolus amount." = "Bolus önerisi güncellendi. Lütfen bolus miktarını yeniden onaylayın."; /* Subtitle description of Walsh insulin model setting */ -"The legacy model used by Loop, allowing customization of action duration." = "The legacy model used by Loop, allowing customization of action duration."; +"The legacy model used by Loop, allowing customization of action duration." = "Loop tarafından kullanılan ve eylem süresinin özelleştirilmesine izin veren eski model."; + +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Maksimum emilim süresi %@"; + +/* Alert body displayed for quantity greater than max (1: maximum quantity in grams) */ +"The maximum allowed amount is %@ grams." = "İzin verilen maksimum miktar %@ gramdır."; + +/* Warning for simple bolus when carbohydrate entry is too large. (1: maximum carbohydrate entry) */ +"The maximum amount allowed is %1$@." = "İzin verilen maksimum tutar %1$@."; + +/* Alert message for a maximum bolus validation error (1: max bolus value) */ +"The maximum bolus amount is %@ U." = "Maksimum bolus miktarı %@ Ü."; /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ -"The maximum bolus amount is %@ Units" = "The maximum bolus amount is %@ Units"; +"The maximum bolus amount is %@ Units" = "Maksimum bolus miktarı %@ Ünitedir"; + +/* Alert message for a missing maximum bolus setting error */ +"The maximum bolus setting must be configured before a bolus can be delivered." = "Bir bolus verilmeden önce maksimum bolus ayarı yapılandırılmalıdır."; + +/* The notification body for a remote command expiration. (1: Expiration in minutes) */ +"The remote command expired %.0f minutes ago." = "Uzak komutun süresi %.0f dakika önce doldu."; + +/* Title text for button to Therapy Settings */ +"Therapy Settings" = "Tedavi Ayarları"; + +/* Title of the carb entry date picker cell */ +"Time" = "Zaman"; + +/* Time Sensitive Status text */ +"Time Sensitive Notifications" = "Zamana Duyarlı Bildirimler"; + +/* Critical event log export error alert try again button */ +"Try Again" = "Tekrar deneyin"; + +/* Bluetooth off foreground alert body */ +"Turn on Bluetooth to receive alerts, alarms or sensor glucose readings." = "Uyarıları, alarmları veya sensör KŞ okumalarını almak için Bluetooth'u açın."; /* The short unit display string for international units of insulin */ -"U" = "U"; +"U" = "Ü"; + +/* Title for alert shown when alert acknowledgement fails */ +"Unable To Clear Alert" = "Uyarı Silinemiyor"; + +/* Title for alert shown when delivery status is uncertain */ +"Unable To Reach Pump" = "Pompaya Ulaşılamıyor"; + +/* Alert title for a carb entry persistence error */ +"Unable to Save Carb Entry" = "Karb Girişi Kaydedilemiyor"; + +/* Alert title for a manual glucose entry persistence error */ +"Unable to Save Manual Glucose Entry" = "Manuel KŞ Girişi Kaydedilemiyor"; + +/* The alert body for an error while canceling a bolus */ +"Unable to stop the bolus in progress. Move your iPhone closer to the pump and try again. Check your insulin delivery history for details, and monitor your glucose closely." = "Devam etmekte olan bolus durdurulamıyor. iPhone'unuzu pompaya yaklaştırın ve tekrar deneyin. Ayrıntılar için insülin uygulama geçmişinizi kontrol edin ve kan şekerinizi yakından takip edin."; + +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Bilinmeyen"; + +/* The error message displayed for unknown errors. (1: unknown error) */ +"Unknown Error: %1$@" = "Bilinmeyen Hata: %1$@"; /* The format for the description of a temporary override end date */ -"until %@" = "until %@"; +"until %@" = "%@ tarihine kadar"; + +/* The title of a target alert action specifying pre-meal targets duration for 1 hour or until the user enters carbs (whichever comes first). */ +"Until I enter carbs" = "Karb girene kadar"; + +/* The title of a target alert action specifying workout targets duration until it is turned off by the user */ +"Until I turn off" = "Ben kapatana kadar"; + +/* The title of the alert controller used to select a duration for pre-meal targets */ +"Use Pre-Meal Preset" = "Yemek Öncesi Ön Ayarı Kullanın"; + +/* The title of the alert controller used to select a duration for workout targets */ +"Use Workout Glucose Targets" = "Egzersiz KŞ Hedeflerini Kullanın"; /* The title of the alert controller used to select a duration for workout targets */ -"Use Workout Glucose Targets" = "Use Workout Glucose Targets"; +"Use Workout Preset" = "Egzersiz Ön Ayarını Kullan"; /* Title of insulin model setting */ "Walsh" = "Walsh"; +/* Alert Permissions Need Attention alert title */ +"Warning! Safety notifications are turned OFF" = "Uyarı! Güvenlik bildirimleri KAPALI"; + +/* Explanation of glucose safety limit */ +"When current or forecasted glucose is below the glucose safety limit, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Mevcut veya tahmin edilen KŞ, KŞ güvenlik sınırının altında olduğunda Loop bir bolus önermez ve her zaman saatte 0 ünite geçici bazal oran önerir."; + /* Explanation of suspend threshold */ -"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour."; +"When current or forecasted glucose is below the suspend threshold, Loop will not recommend a bolus, and will always recommend a temporary basal rate of 0 units per hour." = "Mevcut veya tahmin edilen KŞ askıya alma eşiğinin altında olduğunda, Loop bir bolus önermez ve her zaman saatte 0 birimlik geçici bir bazal hız önerir."; + +/* No comment provided by engineer. */ +"When out of Closed Loop mode, the app uses a simplified bolus calculator like a typical pump." = "Uygulama, Kapalı Döngü modundan çıktığında, tipik bir pompa gibi basitleştirilmiş bir bolus hesaplayıcı kullanır."; /* The label of the workout mode toggle button */ -"Workout Targets" = "Workout Targets"; +"Workout Targets" = "Egzersiz Hedefleri"; + +/* Workout override still on reminder alert body. */ +"Workout Temp Adjust has been turned on for more than 24 hours. Make sure you still want it enabled, or turn it off in the app." = "Geçici Egzersiz Ayarı 24 saatten uzun süredir açık. Hala etkin olmasını istediğinizden emin olun veya uygulamadan kapatın."; + +/* Workout override still on reminder alert title */ +"Workout Temp Adjust Still On" = "Geçici Egzersiz Ayarı Hala Açık"; + +/* The title of the action used when confirming entered amount of carbohydrates. */ +"Yes" = "Evet"; + +/* Format for Notifications permissions disabled alert body. (1: app name) */ +"You may not get sound, visual or vibration alerts regarding critical safety information.\n\nTo fix the issue, tap ‘Settings’ and make sure Notifications, Critical Alerts and Time Sensitive Notifications are turned ON." = "Kritik güvenlik bilgileriyle ilgili sesli, görsel veya titreşimli uyarılar alamayabilirsiniz. \n\n Sorunu çözmek için 'Ayarlar'a dokunun ve Bildirimlerin, Kritik Uyarıların ve Zamana Duyarlı Bildirimlerin AÇIK olduğundan emin olun."; + +/* Time change alert body. (1: app name) */ +"Your %1$@’s time has been changed. %2$@ needs accurate time records to make predictions about your glucose and adjust your insulin accordingly.\n\nCheck in your %1$@ Settings (General / Date & Time) and verify that 'Set Automatically' is turned ON. Failure to resolve could lead to serious under-delivery or over-delivery of insulin." = "%1$@ 'inizin saati değiştirildi. %2$@ KŞ ile ilgili tahminlerde bulunmak ve insülininizi buna göre ayarlamak için doğru zaman kayıtlarına ihtiyaç duyar. \n\n %1$@ Ayarlarınızı (Genel / Tarih ve Saat) kontrol edin ve 'Otomatik Olarak Ayarla' seçeneğinin AÇIK olduğunu doğrulayın. Çözülmemesi, insülinin ciddi şekilde yetersiz veya fazla verilmesine yol açabilir."; + +/* Format string for simple bolus screen warning when glucose is below glucose warning limit. */ +"Your glucose is below %1$@. Are you sure you want to bolus?" = "KŞ %1$@ altında. Bolus yapmak istediğinizden emin misiniz?"; + +/* Caption for bolus screen notice when no bolus is recommended due to prediction dropping below glucose safety limit */ +"Your glucose is below or predicted to go below your glucose safety limit, %@." = "KŞ güvenlik sınırınızın %@ altındadır veya altına düşeceği tahmin edilmektedir."; + +/* Format string for bolus screen warning when no bolus is recommended due input value below glucose safety limit. (1: suspendThreshold) */ +"Your glucose is below your glucose safety limit, %1$@." = "KŞ güvenlik sınırınızın altında, %1$@ ."; + +/* Format string for meal bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold */ +"Your glucose is low. Eat carbs and consider waiting to bolus until your glucose is in a safe range." = "KŞ düşük. Karbonhidrat yiyin ve KŞ güvenli bir aralığa gelene kadar bolus yapmayı erteleyin."; + +/* Bolus screen warning when no bolus is recommended due to glucose input value below recommendation threshold for meal bolus */ +"Your glucose is low. Eat carbs and monitor closely." = "KŞ düşük. Karbonhidrat yiyin ve yakından izleyin."; + +/* Warning for simple bolus when max bolus is exceeded. (1: maximum bolus) */ +"Your maximum bolus amount is %1$@." = "Maksimum bolus miktarınız %1$@ ."; + +/* Caption for bolus screen notice when pump data is missing or stale */ +"Your pump data is stale. %1$@ cannot recommend a bolus amount." = "Pompa verileriniz eski. %1$@ bir bolus miktarı öneremez."; + +/* The description text for the looping enabled switch cell when closed loop is not allowed because the pump is delivering a manual temp basal. */ +"Your pump is delivering a manual temporary basal rate." = "Pompanız manuel bir geçici bazal oran veriyor."; + +/* Warning for simple bolus when recommended bolus exceeds max bolus. (1: maximum bolus) */ +"Your recommended bolus exceeds your maximum bolus amount of %1$@." = "Önerilen bolus miktarı, maksimum bolus miktarınız olan %1$@ değerini aşıyor."; diff --git a/Loop/tr.lproj/Main.strings b/Loop/tr.lproj/Main.strings index 4070b6d595..3218454054 100644 --- a/Loop/tr.lproj/Main.strings +++ b/Loop/tr.lproj/Main.strings @@ -1,42 +1,68 @@ - /* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ -"0RV-d5-muE.text" = "g"; +"0RV-d5-muE.text" = "gr"; /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ -"3kU-n2-fha.title" = "Status"; +"3kU-n2-fha.title" = "Durum"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ -"5gz-kZ-iF1.text" = "3.5 U/hour @ 12:12 PM"; +"5gz-kZ-iF1.text" = "3.5 Ü/saat @ 12:12 PM"; /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ -"87H-N1-0vJ.text" = "Predicted"; +"87H-N1-0vJ.text" = "Tahmini"; + +/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ +"aCb-Qs-bpu.text" = "Detay"; + +/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ +"ap1-M6-naG.text" = "Yemek Tipi"; + +/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ +"bIL-Ub-qYp.text" = "Etiket"; + +/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ +"bq4-98-cQU.text" = "KŞ Değişimi"; + +/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ +"d3X-AN-tA5.text" = "gr Toplam"; /* Class = "UILabel"; text = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; ObjectID = "D4C-I2-dhA"; */ -"D4C-I2-dhA.text" = "Future glucose is predicted by combining the effects of multiple inputs. Use this tool to toggle various inputs to see how they compare to the final prediction."; +"D4C-I2-dhA.text" = "Gelecekteki KŞ, çoklu girdilerin etkilerini birleştirerek tahmin edilir. Son tahminle nasıl karşılaştırıldıklarını görmek üzere çeşitli girdiler arasında geçiş yapmak için bu aracı kullanın."; + +/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ +"d6m-qV-wWi.text" = "Etiket"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "eventually 92 mg/dL"; +"E41-FN-nkk.text" = "Nihai KŞ 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ -"EAn-Ja-S1d.text" = "Observed"; +"EAn-Ja-S1d.text" = "Gözlendi"; /* Class = "UIButton"; normalTitle = "🍭"; ObjectID = "Fal-Vf-lfh"; */ "Fal-Vf-lfh.normalTitle" = "🍭"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 Ü/saat @ 12:12 PM"; + +/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ +"hZZ-2S-lrd.title" = "Karbonhidrat Etkileri"; + /* Class = "UILabel"; text = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; ObjectID = "IxU-As-glo"; */ -"IxU-As-glo.text" = "Observed changes in glucose, subtracting changes modeled from insulin delivery, can be used to estimate carbohydrate absorption."; +"IxU-As-glo.text" = "İnsülin iletiminden modellenen değişiklikler çıkarılarak KŞ değerlerinde gözlemlenen değişiklikler, karbonhidrat emilimini tahmin etmek için kullanılabilir."; /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ -"J7x-W5-gwo.text" = "Detail"; +"J7x-W5-gwo.text" = "Detay"; + +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ +"k3F-Na-7mn.text" = "Önerilen Bazal"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "Label"; +"Krd-Aa-ret.text" = "Etiket"; /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "Label"; +"OFA-qT-ZAg.text" = "Etiket"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ -"PA3-sP-cWY.title" = "Predicted Glucose"; +"PA3-sP-cWY.title" = "Tahmini KŞ"; /* Class = "UIButton"; normalTitle = "🍽"; ObjectID = "Qe9-uc-vPR"; */ "Qe9-uc-vPR.normalTitle" = "🍽"; @@ -44,71 +70,45 @@ /* Class = "UIButton"; normalTitle = "🌮"; ObjectID = "QhO-Yi-AqQ"; */ "QhO-Yi-AqQ.normalTitle" = "🌮"; +/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ +"qPH-vU-xlu.text" = "Yemek Tipi"; + /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ -"Rse-x8-amW.text" = "eventually 92 mg/dL"; +"Rse-x8-amW.text" = "Nihai KŞ 92 mg/dL"; /* Class = "UILabel"; text = "g Active Carbs"; ObjectID = "SQx-au-ZcM"; */ -"SQx-au-ZcM.text" = "g Active Carbs"; +"SQx-au-ZcM.text" = "gr Aktif Karb."; + +/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ +"tuw-av-A3x.text" = "Kan şekeri"; /* Class = "UINavigationItem"; title = "Add/Edit Carb Entry"; ObjectID = "Tz7-80-bJ7"; */ -"Tz7-80-bJ7.title" = "Add/Edit Carb Entry"; +"Tz7-80-bJ7.title" = "Karb. Girişi Ekle/Düzenle"; + +/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ +"ufi-Kj-33k.text" = "Etiket"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ -"Vpi-5b-bY5.title" = "Carbohydrates"; +"Vpi-5b-bY5.title" = "Karbonhidratlar"; /* Class = "UILabel"; text = "Amount Consumed"; ObjectID = "Wx8-Tf-FnG"; */ -"Wx8-Tf-FnG.text" = "Amount Consumed"; - -/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ -"Yf6-fw-Gex.placeholder" = "0"; - -/* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Detail"; - -/* Class = "UILabel"; text = "Food Type"; ObjectID = "ap1-M6-naG"; */ -"ap1-M6-naG.text" = "Food Type"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Label"; - -/* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ -"bq4-98-cQU.text" = "Glucose Change"; - -/* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ -"d3X-AN-tA5.text" = "g Total"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Label"; - -/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ -"fWV-jg-ICt.text" = "3.5 U/hour @ 12:12 PM"; - -/* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ -"hZZ-2S-lrd.title" = "Carbohydrate Effects"; - -/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ -"k3F-Na-7mn.text" = "Recommended Basal"; - -/* Class = "UILabel"; text = "Food Type"; ObjectID = "qPH-vU-xlu"; */ -"qPH-vU-xlu.text" = "Food Type"; - -/* Class = "UILabel"; text = "Glucose"; ObjectID = "tuw-av-A3x"; */ -"tuw-av-A3x.text" = "Glucose"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Label"; +"Wx8-Tf-FnG.text" = "Tüketilen Miktar"; /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ -"xhx-PI-bBI.text" = "Recommended Basal"; +"xhx-PI-bBI.text" = "Önerilen Bazal"; /* Class = "UIButton"; normalTitle = "🍕"; ObjectID = "xl9-Wc-Pdu"; */ "xl9-Wc-Pdu.normalTitle" = "🍕"; +/* Class = "UITextField"; placeholder = "0"; ObjectID = "Yf6-fw-Gex"; */ +"Yf6-fw-Gex.placeholder" = "0"; + /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ -"zbc-87-wxZ.text" = "Title"; +"zbc-87-wxZ.text" = "Başlık"; /* Class = "UILabel"; text = "0"; ObjectID = "zvZ-uf-zMX"; */ "zvZ-uf-zMX.text" = "0"; + diff --git a/Loop/vi.lproj/InfoPlist.strings b/Loop/vi.lproj/InfoPlist.strings index 8f2686ff2e..26e6ae78c3 100644 --- a/Loop/vi.lproj/InfoPlist.strings +++ b/Loop/vi.lproj/InfoPlist.strings @@ -1,3 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Loop"; + /* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Loop/vi.lproj/Localizable.strings b/Loop/vi.lproj/Localizable.strings index 2ac05b150c..a05cd34651 100644 --- a/Loop/vi.lproj/Localizable.strings +++ b/Loop/vi.lproj/Localizable.strings @@ -1,6 +1,12 @@ /* The string format appended to active insulin that describes pending insulin. (1: pending insulin) */ " (pending: %@)" = " (đang chờ xử lý: %@)"; +/* String denoting lack of a recommended bolus amount in the simple bolus calculator */ +"–" = "—"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* The format for an active override preset. (1: preset symbol)(2: preset name) */ "%@ %@" = "%1$@ %2$@"; @@ -16,6 +22,9 @@ /* Format string for glucose target range. (1: Min target)(2: Max target)(3: glucose unit) */ "%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; +/* Format string combining carb entry quantity and absorption time emoji */ +"%1$@ %2$@" = "%1$@ %2$@"; + /* Format string for carb ratio average. (1: value)(2: carb unit) */ "%1$@ %2$@/U" = "%1$@ %2$@/U"; @@ -49,6 +58,9 @@ /* Subtitle of Rapid-Acting – Adult preset */ "A model based on the published absorption of Humalog, Novolog, and Apidra insulin in adults." = "Mô hình dựa trên sự hấp thụ được công bố của các loại insulin Humalog, Novolog và Apidra ở người lớn."; +/* Title of the carb entry absorption time cell */ +"Absorption Time" = "Thời gian Hấp thụ"; + /* Action to copy the recommended Bolus value to the actual Bolus Field */ "AcceptRecommendedBolus" = "AcceptRecommendedBolus"; @@ -58,6 +70,9 @@ /* The string format describing active carbohydrates. (1: localized glucose value description) */ "Active Carbohydrates: %@" = "Lượng Carbohydrates còn hoạt động: %@"; +/* Title describing quantity of still-absorbing carbohydrates */ +"Active Carbs" = "Lượng Carbs còn hoạt động"; + /* The title of the Insulin On-Board graph */ "Active Insulin" = "Lượng Insulin còn hoạt động"; @@ -65,13 +80,13 @@ "Active Insulin: %@" = "Lượng Insulin còn hoạt động: %@"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Khai báo khối lượng Carb"; +"Add Carb Entry" = "Khai báo Carb"; /* Action sheet title selecting CGM Title text for button to set up a CGM */ "Add CGM" = "Khai báo CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "Khai báo bữa ăn"; /* Action sheet title selecting Pump @@ -81,15 +96,18 @@ /* The title of the Amplitude service */ "Amplitude" = "Amplitude"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "Sự điều chỉnh cho mẫu người lớn dựa trên hiệu ứng theo kinh nghiệm ở trẻ em."; - /* The title of the amplitude API key credential */ "API Key" = "API Key"; /* The title of the nightscout API secret credential */ "API Secret" = "API Secret"; +/* Action sheet confirmation message for pump history deletion */ +"Are you sure you want to delete all history entries?" = "Bạn có chắc muốn xóa hết các dữ liệu cũ?"; + +/* Action sheet confirmation message for reservoir deletion */ +"Are you sure you want to delete all reservoir values?" = "Bạn có chắc muốn xóa hết mọi giá trị của ngăn chứa insulin?"; + /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "Bạn có chắc sẽ xóa CGM này?"; @@ -104,11 +122,11 @@ /* The title of the basal rate profile screen The title text for the basal rate schedule */ -"Basal Rates" = "Basal Rates"; +"Basal Rates" = "Lịch biểu tiêm liều nền"; /* The label of the bolus entry button The notification title for a bolus failure */ -"Bolus" = "Liều Bolus"; +"Bolus" = "Bolus"; /* The format string for bolus progress. (1: delivered volume)(2: total volume) */ "Bolused %1$@ of %2$@" = "Đã thực hiện Bolus %1$@ của %2$@"; @@ -127,10 +145,16 @@ /* The title of the carb ratios schedule screen The title text for the carb ratio schedule */ -"Carb Ratios" = "Tỷ lệ Carb"; +"Carb Ratios" = "Carb Ratios"; + +/* The title of the view controller to create a new carb entry */ +"carb-entry-title-add" = "Khai báo Carb"; + +/* The title of the view controller to edit an existing carb entry */ +"carb-entry-title-edit" = "Chỉnh sửa Carb"; /* Title of the prediction input effect for carbohydrates */ -"Carbohydrates" = "Các bon hydrat"; +"Carbohydrates" = "Carbohydrates"; /* Description of the prediction input effect for carbohydrates. (1: The glucose unit string) */ "Carbs Absorbed (g) ÷ Carb Ratio (g/U) × Insulin Sensitivity (%1$@/U)" = "Khối lượng carb tiêu thụ (g) ÷ Tỷ lệ Carb (g/U) × Độ nhạy của Insulin (%1$@/U)"; @@ -150,9 +174,18 @@ /* Recovery suggestion when glucose data is missing */ "Check your CGM data source" = "Kiểm tra nguồn dữ liệu CGM của bạn"; +/* Carb entry section footer text explaining absorption time */ +"Choose a longer absorption time for larger meals, or those containing fats and proteins. This is only guidance to the algorithm and need not be exact." = "Lựa chọn khoảng thời gian tiêu hóa dài hơn cho các bữa ăn no, hoặc những bữa ăn nhiều chất béo và protein. Đây chỉ là hướng dẫn cho thuật toán Algorithm và không cần phải chính xác."; + /* The title text for the looping enabled switch cell */ "Closed Loop" = "Vòng lặp kín"; +/* The format string describing the date of an IOB value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.IOBDateLabel" = "lúc %1$@"; + +/* The format string describing the starting date of a total value. The first format argument is the localized date. */ +"com.loudnate.InsulinKit.totalDateLabel" = "từ lúc %1$@"; + /* The title of the action used to dismiss an error alert */ "com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; @@ -162,31 +195,50 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "Lỗi cấu hình: %1$@"; +/* Default alert dismissal */ +"Continue" = "Tiếp tục"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "Kiểm soát đường huyết liên tục"; /* The title of the glucose target range schedule screen The title text for the glucose target range schedule */ -"Correction Range" = "Phạm vi Điều chỉnh"; +"Correction Range" = "Phạm vi liều Bổ sung"; /* Message when offering bolus recommendation even though bg is below range. (1: glucose value) */ "Current glucose of %1$@ is below correction range." = " Chỉ số glucose hiện tại %1$@ nằm dưới Phạm vi Điều chỉnh."; /* The title of the cell indicating a generic temporary override is enabled */ -"Custom Override" = "Chồng liều"; +"Custom Override" = "Thói quen Chồng liều"; + +/* Date picker label */ +"Date" = "Ngày"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Xóa Tài khoản"; -/* The title of the Loggly customer token credential */ -"Customer Token" = "Customer Token"; +/* Button title to delete all objects */ +"Delete All" = "Xóa hết"; /* Button title to delete CGM */ "Delete CGM" = "Xóa CGM"; +/* Button title to delete a service */ +"Delete Service" = "Delete Service"; + /* Title text for delivery limits */ -"Delivery Limits" = "Giới hạn tiêm"; +"Delivery Limits" = "Giới hạn liều tiêm"; /* The action hint of the workout mode toggle button when enabled */ "Disables" = "Vô hiệu hóa"; +/* Default alert dismissal + The button label of the action used to dismiss an error alert */ +"Dismiss" = "Từ bỏ"; + /* The action hint of the workout mode toggle button when disabled */ "Enables" = "Cho phép"; @@ -197,7 +249,10 @@ "Error Canceling Bolus" = "Lỗi hủy liều Bolus"; /* The alert title for a resume error */ -"Error Resuming" = "Lỗi trong việc Bắt đầu lại"; +"Error Resuming" = "Lỗi khi đang tái thực hiện"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "Event History"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "Kết quả %@"; @@ -211,6 +266,9 @@ /* The format string used to describe a finite workout targets duration */ "For %1$@" = "For %1$@"; +/* The short unit display string for grams */ +"g" = "g"; + /* The title of the glucose and prediction graph */ "Glucose" = "Đường huyết"; @@ -223,9 +281,6 @@ /* Title of the prediction input effect for glucose momentum */ "Glucose Momentum" = "Chuyển động của Glucose"; -/* The placeholder text for the nightscout site URL credential */ -"https://mysite.herokuapp.com" = "https://mysite.herokuapp.com"; - /* The title of a target alert action specifying an indefinitely long workout targets duration */ "Indefinitely" = "Vô hạn định"; @@ -236,7 +291,7 @@ "Insulin Absorbed (U) × Insulin Sensitivity (%1$@/U)" = "Lượng insulin tiêu hao (U) × Độ nhạy của insulin (%1$@/U)"; /* The title of the insulin delivery graph */ -"Insulin Delivery" = "Khối lượng tiêm insulin"; +"Insulin Delivery" = "Insulin Delivery"; /* Details for missing data error when insulin effects are missing */ "Insulin effects" = "Tác dụng của insulin"; @@ -261,29 +316,52 @@ /* The loading message for the diagnostic report screen */ "Loading..." = "Đang tải..."; -/* The title of the loggly service */ -"Loggly" = "Loggly"; - /* The notification title for a loop failure */ "Loop Failure" = "Loop lỗi"; /* The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop */ "Loop has not completed successfully in %@" = "Loop không hoạt động thành công trong %@"; +/* Details for configuration error when maximum bolus is missing */ +"Maximum Bolus" = "Liều Bolus tối đa"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + /* The error message for missing data. (1: missing data details) */ "Missing data: %1$@" = "Dữ liệu thiếu: %1$@"; +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Details for missing data error when momentum effects are missing */ "Momentum effects" = "Hiệu ứng động lượng"; +/* Text for more info action on notification of upcoming profile expiration */ +"More Info" = "Thêm thông tin"; + +/* Sensor state description for the non-valid state */ +"Needs Attention" = "Cần chú ý"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "Không có thiết bị nào được kết nối, hoặc lỗi trong quá trình kết nối"; +/* Alert acknowledgment OK button + Critical Alert permissions disabled alert button + Default action for alert when alert acknowledgment fails + Notifications permissions disabled alert button + Text for ok action on notification of upcoming profile expiration + The title of the notification action to acknowledge a device alert */ +"OK" = "OK"; + +/* Notification Setting Status is On */ +"On" = "On"; + /* The title text for the override presets */ -"Override Presets" = "Ghi đè cài đặt trước"; +"Override Presets" = "Cài đặt chồng liều"; /* The label of the pre-meal mode toggle button */ "Pre-Meal Targets" = "Mục tiêu trước bữa ăn"; @@ -306,6 +384,9 @@ /* The error message when pump data is too old to be used. (1: pump data age in minutes) */ "Pump data is %1$@ old" = "Dữ liệu bơm %1$@ là cũ"; +/* The title of the screen displaying a pump event */ +"Pump Event" = "Pump Event"; + /* Details for configuration error when pump manager is missing */ "Pump Manager" = "Trình quản lý bơm"; @@ -318,6 +399,9 @@ /* The title of the cell indicating the pump is suspended */ "Pump Suspended" = "Bơm đã tạm ngưng"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Title of insulin model preset */ "Rapid-Acting – Adults" = "Thuốc tác động nhanh cho người lớn"; @@ -328,13 +412,13 @@ "Recommendation expired: %1$@ old" = "Khuyến cáo hết hạn: %1$@ phút"; /* The title of the cell displaying a recommended temp basal value */ -"Recommended Basal" = "Liều Basal khuyến nghị"; +"Recommended Basal" = "Khuyến nghị liều Basal"; /* Accessibility hint describing recommended bolus units */ "Recommended Bolus: %@ Units" = "Liều Bolus khuyến nghị: %@ Units"; /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "Ngăn chứa insulin"; +"Reservoir" = "Reservoir"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "Liều Bổ sung còn hiệu lực"; @@ -372,12 +456,19 @@ /* Subtitle description of Walsh insulin model setting */ "The legacy model used by Loop, allowing customization of action duration." = "Mô hình cũ được Loop sử dụng, cho phép tùy chỉnh thời lượng hành động."; +/* Alert body displayed absorption time greater than max (1: maximum absorption time) */ +"The maximum absorption time is %@" = "Thời gian tiêu hóa tối đa là %@"; + /* Body of the alert describing a maximum bolus validation error. (1: The localized max bolus value) */ "The maximum bolus amount is %@ Units" = "Số lượng bolus tối đa là %@ Units"; /* The short unit display string for international units of insulin */ "U" = "U"; +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "Không nhận ra"; + /* The format for the description of a temporary override end date */ "until %@" = "cho đến khi %@"; diff --git a/Loop/vi.lproj/Main.strings b/Loop/vi.lproj/Main.strings index 18dd8ff02d..b05737c3a9 100644 --- a/Loop/vi.lproj/Main.strings +++ b/Loop/vi.lproj/Main.strings @@ -1,45 +1,24 @@ +/* Class = "UILabel"; text = "g"; ObjectID = "0RV-d5-muE"; */ +"0RV-d5-muE.text" = "g"; + /* Class = "UINavigationItem"; title = "Status"; ObjectID = "3kU-n2-fha"; */ "3kU-n2-fha.title" = "Tình trạng"; /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5 U/hour @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "Liều Bolus"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "Số ID của bơm"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "Khối lượng liều Bolus"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "Được dự đoán"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ -"aCb-Qs-bpu.text" = "Chi tiết"; - -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "Liều Bolus"; +"aCb-Qs-bpu.text" = "Detail"; /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ -"bIL-Ub-qYp.text" = "Nhãn"; +"bIL-Ub-qYp.text" = "Label"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "Mức đường huyết thay đổi"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "Units"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "U"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "Nhãn"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "g Tổng cộng"; @@ -47,22 +26,16 @@ "D4C-I2-dhA.text" = "Glucose trong tương lai được dự đoán bằng cách kết hợp các tác động của nhiều dữ liệu đầu vào. Sử dụng công cụ này để chuyển đổi các đầu vào khác nhau để xem cách chúng so sánh với dự đoán cuối cùng."; /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ -"d6m-qV-wWi.text" = "Nhãn"; - -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "Cài đặt"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "THIẾT BỊ"; +"d6m-qV-wWi.text" = "Label"; /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ -"E41-FN-nkk.text" = "kết quả 92 mg/dL"; +"E41-FN-nkk.text" = "kết quả là 92 mg/dL"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "Được quan sát"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "Lượng Carbohydrates còn hoạt động: 40g"; +/* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "fWV-jg-ICt"; */ +"fWV-jg-ICt.text" = "3.5 U/hour @ 12:12 PM"; /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = "Carbohydrate Effects"; @@ -73,39 +46,18 @@ /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "Detail"; -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ Đường huyết dự đoán nằm dưới phạm vi"; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "Khuyến nghị liều Basal"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ -"Krd-Aa-ret.text" = "Nhãn"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "Nhãn"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "Chạm để cài đặt"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "Units"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "U"; +"Krd-Aa-ret.text" = "Label"; /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ -"OFA-qT-ZAg.text" = "Nhãn"; +"OFA-qT-ZAg.text" = "Label"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "Đường huyết được dự đoán"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "Insulin Model"; - -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "Mô hình hoạt động của insulin được sử dụng để ước tính tác động của insulin lên mức glucose. Một mô hình chính xác có thể giúp ngăn việc chồng liều và đưa ra khuyến nghị một liều bổ sung an toàn."; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "kết quả là 92 mg/dL"; @@ -116,26 +68,17 @@ "tuw-av-A3x.text" = "Đường huyết"; /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ -"ufi-Kj-33k.text" = "Nhãn"; - -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "Lượng insulin còn hoạt động: 1.5U"; +"ufi-Kj-33k.text" = "Label"; /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "Carbohydrates"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4 giờ"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "Deliver"; +/* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "xhx-PI-bBI"; */ +"xhx-PI-bBI.text" = "Khuyến nghị liều Basal"; /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "Được khuyến nghị"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "Title"; diff --git a/Loop/zh-Hans.lproj/Localizable.strings b/Loop/zh-Hans.lproj/Localizable.strings index 940a7a8e58..683fc6c287 100644 --- a/Loop/zh-Hans.lproj/Localizable.strings +++ b/Loop/zh-Hans.lproj/Localizable.strings @@ -71,7 +71,7 @@ Title text for button to set up a CGM */ "Add CGM" = "添加CGM"; -/* The label of the carb entry button */ +/* The label of the meal button */ "Add Meal" = "添加用餐信息"; /* Action sheet title selecting Pump @@ -81,21 +81,15 @@ /* Title text for button to set up a service */ "Add Service" = "Add Service"; -/* Button title to delete a service */ -"Delete Service" = "Delete Service"; - -/* Confirmation message for deleting a service */ -"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; - /* The title of the section containing algorithm settings */ "Algorithm Settings" = "算法设置"; -/* Subtitle of Rapid-Acting – Children preset */ -"An adjustment to the adult model based on empirical effects in children." = "在成人胰岛素模型基础上专为儿童修改的胰岛素代谢模型"; - /* Confirmation message for deleting a CGM */ "Are you sure you want to delete this CGM?" = "确定要删除该CGM数据源?"; +/* Confirmation message for deleting a service */ +"Are you sure you want to delete this service?" = "Are you sure you want to delete this service?"; + /* Format fragment for a specific time */ "at %@" = "%@分钟内"; @@ -165,6 +159,9 @@ /* The error message displayed for configuration errors. (1: configuration error details) */ "Configuration Error: %1$@" = "配置错误:%1$@"; +/* Default alert dismissal */ +"Continue" = "继续"; + /* The title of the continuous glucose monitor section in settings */ "Continuous Glucose Monitor" = "连续葡萄糖监测"; @@ -178,11 +175,14 @@ /* The title of the cell indicating a generic temporary override is enabled */ "Custom Override" = "自定义覆盖"; +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "删除账户"; + /* Button title to delete CGM */ "Delete CGM" = "删除CGM数据源"; -/* The title of the button to remove the credentials for a service */ -"Delete Account" = "删除账户"; +/* Button title to delete a service */ +"Delete Service" = "Delete Service"; /* Title text for delivery limits */ "Delivery Limits" = "输注限制"; @@ -200,7 +200,10 @@ "Error Canceling Bolus" = "无法取消大剂量"; /* The alert title for a resume error */ -"Error Resuming" = "无法恢复输注"; +"Error Resuming" = "恢复输注错误"; + +/* Segmented button title for insulin delivery log event history */ +"Event History" = "历史事件"; /* The subtitle format describing eventual glucose. (1: localized glucose value description) */ "Eventually %@" = "最终 %@"; @@ -279,6 +282,9 @@ /* The error message displayed for device connection errors. */ "No connected devices, or failure during device connection" = "没有连接的设备,或设备连接期间发生故障"; +/* Notification Setting Status is On */ +"On" = "开"; + /* The title text for the override presets */ "Override Presets" = "覆盖预设置"; @@ -331,7 +337,7 @@ "Recommended Bolus: %@ Units" = "推荐大剂量:%@单位"; /* Details for missing data error when reservoir data is missing */ -"Reservoir" = "储药器"; +"Reservoir" = "胰岛素容量"; /* Title of the prediction input effect for retrospective correction */ "Retrospective Correction" = "回顾性修正"; @@ -372,6 +378,10 @@ /* The short unit display string for international units of insulin */ "U" = "U"; +/* Event title displayed when StoredPumpEvent.title is not set + The default description to use when an entry has no dose description */ +"Unknown" = "未知"; + /* The format for the description of a temporary override end date */ "until %@" = "直到 %@"; diff --git a/Loop/zh-Hans.lproj/Main.strings b/Loop/zh-Hans.lproj/Main.strings index a835bde645..ed66f0b26f 100644 --- a/Loop/zh-Hans.lproj/Main.strings +++ b/Loop/zh-Hans.lproj/Main.strings @@ -4,42 +4,18 @@ /* Class = "UILabel"; text = "3.5 U/hour @ 12:12 PM"; ObjectID = "5gz-kZ-iF1"; */ "5gz-kZ-iF1.text" = "3.5u/小时 @ 12:12 PM"; -/* Class = "UILabel"; text = "Bolus"; ObjectID = "5oA-6d-ZTL"; */ -"5oA-6d-ZTL.text" = "大剂量"; - -/* Class = "UILabel"; text = "Pump ID"; ObjectID = "5TX-kX-nBo"; */ -"5TX-kX-nBo.text" = "胰岛素泵序列号"; - -/* Class = "UITextField"; accessibilityLabel = "Bolus Amount"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.accessibilityLabel" = "大剂量剂量"; - -/* Class = "UITextField"; placeholder = "0.0"; ObjectID = "7LT-50-ZzK"; */ -"7LT-50-ZzK.placeholder" = "0.0"; - /* Class = "UILabel"; text = "Predicted"; ObjectID = "87H-N1-0vJ"; */ "87H-N1-0vJ.text" = "预计"; /* Class = "UILabel"; text = "Detail"; ObjectID = "aCb-Qs-bpu"; */ "aCb-Qs-bpu.text" = "详细"; -/* Class = "UINavigationItem"; title = "Bolus"; ObjectID = "aiu-ZA-zVa"; */ -"aiu-ZA-zVa.title" = "大剂量"; - /* Class = "UILabel"; text = "Label"; ObjectID = "bIL-Ub-qYp"; */ "bIL-Ub-qYp.text" = "标签"; /* Class = "UILabel"; text = "Glucose Change"; ObjectID = "bq4-98-cQU"; */ "bq4-98-cQU.text" = "葡萄糖变化"; -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.accessibilityLabel" = "单位"; - -/* Class = "UILabel"; text = "U"; ObjectID = "BR0-dr-Fj2"; */ -"BR0-dr-Fj2.text" = "单位"; - -/* Class = "UILabel"; text = "Label"; ObjectID = "cpo-Po-gFM"; */ -"cpo-Po-gFM.text" = "标签"; - /* Class = "UILabel"; text = "g Total"; ObjectID = "d3X-AN-tA5"; */ "d3X-AN-tA5.text" = "克 总计"; @@ -49,21 +25,12 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "d6m-qV-wWi"; */ "d6m-qV-wWi.text" = "标签"; -/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "dmB-PQ-B44"; */ -"dmB-PQ-B44.title" = "设置"; - -/* Class = "UILabel"; text = "DEVICES"; ObjectID = "DyC-Sv-qP8"; */ -"DyC-Sv-qP8.text" = "设备"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "E41-FN-nkk"; */ "E41-FN-nkk.text" = "最终血糖为92 毫克/分升"; /* Class = "UILabel"; text = "Observed"; ObjectID = "EAn-Ja-S1d"; */ "EAn-Ja-S1d.text" = "观察值"; -/* Class = "UILabel"; text = "Active Carbohydrates: 40g"; ObjectID = "hHZ-uY-aKw"; */ -"hHZ-uY-aKw.text" = "活性碳水化合物:40克"; - /* Class = "UITableViewController"; title = "Carbohydrate Effects"; ObjectID = "hZZ-2S-lrd"; */ "hZZ-2S-lrd.title" = " 碳水化合物的影响"; @@ -73,39 +40,18 @@ /* Class = "UILabel"; text = "Detail"; ObjectID = "J7x-W5-gwo"; */ "J7x-W5-gwo.text" = "详情"; -/* Class = "UILabel"; text = "⚠ Glucose Predicted Below Range"; ObjectID = "k0g-P7-OVN"; */ -"k0g-P7-OVN.text" = "⚠ 预测葡萄糖低于目标范围"; - /* Class = "UILabel"; text = "Recommended Basal"; ObjectID = "k3F-Na-7mn"; */ "k3F-Na-7mn.text" = "推荐基础率"; /* Class = "UILabel"; text = "Label"; ObjectID = "Krd-Aa-ret"; */ "Krd-Aa-ret.text" = "标签"; -/* Class = "UILabel"; text = "Label"; ObjectID = "l7l-mw-Oc9"; */ -"l7l-mw-Oc9.text" = "标签"; - -/* Class = "UILabel"; text = "Tap to set"; ObjectID = "m9c-SQ-djE"; */ -"m9c-SQ-djE.text" = "点击设置"; - -/* Class = "UILabel"; accessibilityLabel = "Units"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.accessibilityLabel" = "单位"; - -/* Class = "UILabel"; text = "U"; ObjectID = "mVz-dr-xLU"; */ -"mVz-dr-xLU.text" = "单位"; - /* Class = "UILabel"; text = "Label"; ObjectID = "OFA-qT-ZAg"; */ "OFA-qT-ZAg.text" = "标签"; /* Class = "UITableViewController"; title = "Predicted Glucose"; ObjectID = "PA3-sP-cWY"; */ "PA3-sP-cWY.title" = "预测的血糖"; -/* Class = "UITableViewController"; title = "Insulin Model"; ObjectID = "pi6-Dh-72V"; */ -"pi6-Dh-72V.title" = "胰岛素模型"; - -/* Class = "UILabel"; text = "An insulin activity model is used to estimate effects of insulin on glucose levels. An accurate model can help prevent insulin stacking and safely recommend corrective treatments."; ObjectID = "PJv-p9-cFe"; */ -"PJv-p9-cFe.text" = "胰岛素代谢模型用于估计胰岛素对葡萄糖水平的影响。 准确的模型可以帮助预防胰岛素蓄积并安全地推荐校正剂量。"; - /* Class = "UILabel"; text = "eventually 92 mg/dL"; ObjectID = "Rse-x8-amW"; */ "Rse-x8-amW.text" = "最终血糖为92 毫克/分升"; @@ -118,24 +64,12 @@ /* Class = "UILabel"; text = "Label"; ObjectID = "ufi-Kj-33k"; */ "ufi-Kj-33k.text" = "标签"; -/* Class = "UILabel"; text = "Active Insulin: 1.5U"; ObjectID = "viU-7a-kbI"; */ -"viU-7a-kbI.text" = "活性胰岛素:1.5单位"; - /* Class = "UINavigationItem"; title = "Carbohydrates"; ObjectID = "Vpi-5b-bY5"; */ "Vpi-5b-bY5.title" = "碳水化合物"; -/* Class = "UITextField"; text = "4 hour"; ObjectID = "Wk3-xv-IM5"; */ -"Wk3-xv-IM5.text" = "4小时"; - -/* Class = "UIButton"; normalTitle = "Deliver"; ObjectID = "Ya0-9b-ZAS"; */ -"Ya0-9b-ZAS.normalTitle" = "输注"; - /* Class = "UILabel"; text = "0"; ObjectID = "yn7-2M-jZz"; */ "yn7-2M-jZz.text" = "0"; -/* Class = "UILabel"; text = "Recommended"; ObjectID = "ywT-OR-NnU"; */ -"ywT-OR-NnU.text" = "建议"; - /* Class = "UILabel"; text = "Title"; ObjectID = "zbc-87-wxZ"; */ "zbc-87-wxZ.text" = "标题"; diff --git a/LoopCore/LocalizedString.swift b/LoopCore/LocalizedString.swift new file mode 100644 index 0000000000..14206ef981 --- /dev/null +++ b/LoopCore/LocalizedString.swift @@ -0,0 +1,21 @@ +// +// LocalizedString.swift +// Loop +// +// Created by Pete Schwamb on 1/29/23. +// Copyright © 2023 LoopKit Authors. All rights reserved. +// + +import Foundation + +private class FrameworkBundle { + static let main = Bundle(for: FrameworkBundle.self) +} + +func LocalizedString(_ key: String, tableName: String? = nil, value: String? = nil, comment: String) -> String { + if let value = value { + return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment) + } else { + return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, comment: comment) + } +} diff --git a/LoopCore/LoopCoreConstants.swift b/LoopCore/LoopCoreConstants.swift index 35abbb941e..d56f2ab9b6 100644 --- a/LoopCore/LoopCoreConstants.swift +++ b/LoopCore/LoopCoreConstants.swift @@ -13,6 +13,9 @@ public enum LoopCoreConstants { /// The amount of time since a given date that input data should be considered valid public static let inputDataRecencyInterval = TimeInterval(minutes: 15) + /// The amount of time in the future a glucose value should be considered valid + public static let futureGlucoseDataInterval = TimeInterval(minutes: 5) + public static let defaultCarbAbsorptionTimes: CarbStore.DefaultAbsorptionTimes = (fast: .minutes(30), medium: .hours(3), slow: .hours(5)) /// How much historical glucose to include in a dosing decision diff --git a/LoopCore/LoopSettings.swift b/LoopCore/LoopSettings.swift index fa7bc4325d..63418ad4aa 100644 --- a/LoopCore/LoopSettings.swift +++ b/LoopCore/LoopSettings.swift @@ -12,9 +12,9 @@ public extension AutomaticDosingStrategy { var title: String { switch self { case .tempBasalOnly: - return NSLocalizedString("Temp Basal Only", comment: "Title string for temp basal only dosing strategy") + return LocalizedString("Temp Basal Only", comment: "Title string for temp basal only dosing strategy") case .automaticBolus: - return NSLocalizedString("Automatic Bolus", comment: "Title string for automatic bolus dosing strategy") + return LocalizedString("Automatic Bolus", comment: "Title string for automatic bolus dosing strategy") } } } diff --git a/LoopCore/MissedMealNotification.swift b/LoopCore/MissedMealNotification.swift new file mode 100644 index 0000000000..2cbf61b0e5 --- /dev/null +++ b/LoopCore/MissedMealNotification.swift @@ -0,0 +1,20 @@ +// +// MissedMealNotification.swift +// Loop +// +// Created by Anna Quinlan on 11/18/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import Foundation + +/// Information about a missed meal notification +public struct MissedMealNotification: Equatable, Codable { + public let deliveryTime: Date + public let carbAmount: Double + + public init(deliveryTime: Date, carbAmount: Double) { + self.deliveryTime = deliveryTime + self.carbAmount = carbAmount + } +} diff --git a/LoopCore/NSUserDefaults.swift b/LoopCore/NSUserDefaults.swift index 4aaf4cb17d..31e4cc80fc 100644 --- a/LoopCore/NSUserDefaults.swift +++ b/LoopCore/NSUserDefaults.swift @@ -20,6 +20,7 @@ extension UserDefaults { case lastProfileExpirationAlertDate = "com.loopkit.Loop.lastProfileExpirationAlertDate" case allowDebugFeatures = "com.loopkit.Loop.allowDebugFeatures" case allowSimulators = "com.loopkit.Loop.allowSimulators" + case LastMissedMealNotification = "com.loopkit.Loop.lastMissedMealNotification" } public static let appGroup = UserDefaults(suiteName: Bundle.main.appGroupSuiteName) @@ -114,6 +115,29 @@ extension UserDefaults { } } + public var lastMissedMealNotification: MissedMealNotification? { + get { + let decoder = JSONDecoder() + guard let data = object(forKey: Key.LastMissedMealNotification.rawValue) as? Data else { + return nil + } + return try? decoder.decode(MissedMealNotification.self, from: data) + } + set { + do { + if let newValue = newValue { + let encoder = JSONEncoder() + let data = try encoder.encode(newValue) + set(data, forKey: Key.LastMissedMealNotification.rawValue) + } else { + set(nil, forKey: Key.LastMissedMealNotification.rawValue) + } + } catch { + assertionFailure("Unable to encode MissedMealNotification") + } + } + } + public var allowDebugFeatures: Bool { get { bool(forKey: Key.allowDebugFeatures.rawValue) diff --git a/LoopCore/ar.lproj/Localizable.strings b/LoopCore/ar.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/LoopCore/ar.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/LoopCore/da.lproj/Localizable.strings b/LoopCore/da.lproj/Localizable.strings new file mode 100644 index 0000000000..27d6531a53 --- /dev/null +++ b/LoopCore/da.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automatisk bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Kun midlertidig basal"; + diff --git a/LoopCore/de.lproj/Localizable.strings b/LoopCore/de.lproj/Localizable.strings index f4c7654481..a427cdcfa1 100644 --- a/LoopCore/de.lproj/Localizable.strings +++ b/LoopCore/de.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Title string for automatic bolus dosing strategy */ "Automatic Bolus" = "Automatischer Bolus"; diff --git a/LoopCore/en.lproj/Localizable.strings b/LoopCore/en.lproj/Localizable.strings new file mode 100644 index 0000000000..e6696dee56 --- /dev/null +++ b/LoopCore/en.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automatic Bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Temp Basal Only"; + diff --git a/LoopCore/es.lproj/Localizable.strings b/LoopCore/es.lproj/Localizable.strings new file mode 100644 index 0000000000..9093a7b504 --- /dev/null +++ b/LoopCore/es.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Bolo automático"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Solo basal temporal"; + diff --git a/LoopCore/fi.lproj/Localizable.strings b/LoopCore/fi.lproj/Localizable.strings new file mode 100644 index 0000000000..ec6c550592 --- /dev/null +++ b/LoopCore/fi.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automaattinen bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Vain tilapäinen basaali"; + diff --git a/LoopCore/fr.lproj/Localizable.strings b/LoopCore/fr.lproj/Localizable.strings new file mode 100644 index 0000000000..fe045511be --- /dev/null +++ b/LoopCore/fr.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Bolus Automatique"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Basal temporaire uniquement"; + diff --git a/LoopCore/he.lproj/Localizable.strings b/LoopCore/he.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/LoopCore/he.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/LoopCore/it.lproj/Localizable.strings b/LoopCore/it.lproj/Localizable.strings new file mode 100644 index 0000000000..61672471fd --- /dev/null +++ b/LoopCore/it.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ contro %2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Bolo Automatico"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Solo basale temporanea"; + diff --git a/LoopCore/ja.lproj/Localizable.strings b/LoopCore/ja.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/LoopCore/ja.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/LoopCore/nb.lproj/Localizable.strings b/LoopCore/nb.lproj/Localizable.strings new file mode 100644 index 0000000000..42420f59bb --- /dev/null +++ b/LoopCore/nb.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automatisk bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Kun midlertidig basal"; + diff --git a/LoopCore/nl.lproj/Localizable.strings b/LoopCore/nl.lproj/Localizable.strings new file mode 100644 index 0000000000..42056d378b --- /dev/null +++ b/LoopCore/nl.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automatisch Bolussen"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Alleen Tijdelijk Basaal"; + diff --git a/LoopCore/pl.lproj/Localizable.strings b/LoopCore/pl.lproj/Localizable.strings new file mode 100644 index 0000000000..21d751b260 --- /dev/null +++ b/LoopCore/pl.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automatyczny bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Tymczasowa dawka podstawowa"; + diff --git a/LoopCore/pt-BR.lproj/Localizable.strings b/LoopCore/pt-BR.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/LoopCore/pt-BR.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/LoopCore/ro.lproj/Localizable.strings b/LoopCore/ro.lproj/Localizable.strings new file mode 100644 index 0000000000..0941237859 --- /dev/null +++ b/LoopCore/ro.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Bolus automat"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Doar bazală temporară"; + diff --git a/LoopCore/ru.lproj/Localizable.strings b/LoopCore/ru.lproj/Localizable.strings new file mode 100644 index 0000000000..cc71e5f763 --- /dev/null +++ b/LoopCore/ru.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ против %2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Автоматические болюсы"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Только ВБС (без автоболюсов)"; + diff --git a/LoopCore/sk.lproj/Localizable.strings b/LoopCore/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..0039fc241d --- /dev/null +++ b/LoopCore/sk.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + diff --git a/LoopCore/sv.lproj/Localizable.strings b/LoopCore/sv.lproj/Localizable.strings new file mode 100644 index 0000000000..17a990cf25 --- /dev/null +++ b/LoopCore/sv.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Automatisk bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Endast temporär basal"; + diff --git a/LoopCore/tr.lproj/Localizable.strings b/LoopCore/tr.lproj/Localizable.strings new file mode 100644 index 0000000000..bcee9de97d --- /dev/null +++ b/LoopCore/tr.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Title string for automatic bolus dosing strategy */ +"Automatic Bolus" = "Otomatik Bolus"; + +/* Title string for temp basal only dosing strategy */ +"Temp Basal Only" = "Sadece Geçici Bazal"; + diff --git a/LoopCore/vi.lproj/Localizable.strings b/LoopCore/vi.lproj/Localizable.strings new file mode 100644 index 0000000000..f4d2b4576f --- /dev/null +++ b/LoopCore/vi.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + diff --git a/LoopTests/Fixtures/meal_detection/dynamic_autofill_counteraction_effect.json b/LoopTests/Fixtures/meal_detection/dynamic_autofill_counteraction_effect.json new file mode 100644 index 0000000000..6f979e79cc --- /dev/null +++ b/LoopTests/Fixtures/meal_detection/dynamic_autofill_counteraction_effect.json @@ -0,0 +1,1730 @@ +[ + { + "startDate": "2022-10-16T20:30:55", + "endDate": "2022-10-16T20:35:55", + "unit": "mg\/min·dL", + "value": -0.2845291412399927 + }, + { + "startDate": "2022-10-16T20:35:55", + "endDate": "2022-10-16T20:40:55", + "unit": "mg\/min·dL", + "value": -0.720332507317587 + }, + { + "startDate": "2022-10-16T20:40:55", + "endDate": "2022-10-16T20:45:55", + "unit": "mg\/min·dL", + "value": 0.0420715382145751 + }, + { + "startDate": "2022-10-16T20:45:55", + "endDate": "2022-10-16T20:50:55", + "unit": "mg\/min·dL", + "value": 0.0038033636146233146 + }, + { + "startDate": "2022-10-16T20:50:55", + "endDate": "2022-10-16T20:55:55", + "unit": "mg\/min·dL", + "value": 0.36479459077661286 + }, + { + "startDate": "2022-10-16T20:55:55", + "endDate": "2022-10-16T21:00:55", + "unit": "mg\/min·dL", + "value": 0.12560308127768485 + }, + { + "startDate": "2022-10-16T21:00:55", + "endDate": "2022-10-16T21:05:55", + "unit": "mg\/min·dL", + "value": 0.2871269278384104 + }, + { + "startDate": "2022-10-16T21:05:55", + "endDate": "2022-10-16T21:10:55", + "unit": "mg\/min·dL", + "value": 0.24698121433301015 + }, + { + "startDate": "2022-10-16T21:10:55", + "endDate": "2022-10-16T21:15:55", + "unit": "mg\/min·dL", + "value": 0.4090910045267783 + }, + { + "startDate": "2022-10-16T21:15:55", + "endDate": "2022-10-16T21:20:56", + "unit": "mg\/min·dL", + "value": 0.36970428418744017 + }, + { + "startDate": "2022-10-16T21:20:56", + "endDate": "2022-10-16T21:25:55", + "unit": "mg\/min·dL", + "value": 0.9356144093998734 + }, + { + "startDate": "2022-10-16T21:25:55", + "endDate": "2022-10-16T21:30:55", + "unit": "mg\/min·dL", + "value": 0.3045237460699238 + }, + { + "startDate": "2022-10-16T21:30:55", + "endDate": "2022-10-16T21:35:55", + "unit": "mg\/min·dL", + "value": -0.12222077929078642 + }, + { + "startDate": "2022-10-16T21:35:55", + "endDate": "2022-10-16T21:40:55", + "unit": "mg\/min·dL", + "value": 1.8610345585630323 + }, + { + "startDate": "2022-10-16T21:40:55", + "endDate": "2022-10-16T21:45:56", + "unit": "mg\/min·dL", + "value": 1.0401503514922685 + }, + { + "startDate": "2022-10-16T21:45:56", + "endDate": "2022-10-16T21:50:55", + "unit": "mg\/min·dL", + "value": 1.2329955169598097 + }, + { + "startDate": "2022-10-16T21:50:55", + "endDate": "2022-10-16T21:55:55", + "unit": "mg\/min·dL", + "value": -0.372691168979093 + }, + { + "startDate": "2022-10-16T21:55:55", + "endDate": "2022-10-16T22:00:56", + "unit": "mg\/min·dL", + "value": 1.0320426981004522 + }, + { + "startDate": "2022-10-16T22:00:56", + "endDate": "2022-10-16T22:05:55", + "unit": "mg\/min·dL", + "value": 1.2446535840823372 + }, + { + "startDate": "2022-10-16T22:05:55", + "endDate": "2022-10-16T22:10:55", + "unit": "mg\/min·dL", + "value": 1.4513990428468961 + }, + { + "startDate": "2022-10-16T22:10:55", + "endDate": "2022-10-16T22:15:55", + "unit": "mg\/min·dL", + "value": 1.662878682899968 + }, + { + "startDate": "2022-10-16T22:15:55", + "endDate": "2022-10-16T22:20:55", + "unit": "mg\/min·dL", + "value": 1.6776600731029174 + }, + { + "startDate": "2022-10-16T22:20:55", + "endDate": "2022-10-16T22:25:55", + "unit": "mg\/min·dL", + "value": 2.0945857017085485 + }, + { + "startDate": "2022-10-16T22:25:55", + "endDate": "2022-10-16T22:30:56", + "unit": "mg\/min·dL", + "value": 2.3253439979429293 + }, + { + "startDate": "2022-10-16T22:30:56", + "endDate": "2022-10-16T22:35:55", + "unit": "mg\/min·dL", + "value": 2.762596869393967 + }, + { + "startDate": "2022-10-16T22:35:55", + "endDate": "2022-10-16T22:40:55", + "unit": "mg\/min·dL", + "value": 2.8086729434998707 + }, + { + "startDate": "2022-10-16T22:40:55", + "endDate": "2022-10-16T22:45:56", + "unit": "mg\/min·dL", + "value": 2.252477346032686 + }, + { + "startDate": "2022-10-16T22:45:56", + "endDate": "2022-10-16T22:50:55", + "unit": "mg\/min·dL", + "value": 1.5612654702448618 + }, + { + "startDate": "2022-10-16T22:50:55", + "endDate": "2022-10-16T22:55:55", + "unit": "mg\/min·dL", + "value": 1.4645801980357367 + }, + { + "startDate": "2022-10-16T22:55:55", + "endDate": "2022-10-16T23:00:55", + "unit": "mg\/min·dL", + "value": 0.754887677850649 + }, + { + "startDate": "2022-10-16T23:00:55", + "endDate": "2022-10-16T23:05:55", + "unit": "mg\/min·dL", + "value": 0.6300240922287167 + }, + { + "startDate": "2022-10-16T23:05:55", + "endDate": "2022-10-16T23:10:55", + "unit": "mg\/min·dL", + "value": 0.687012158407236 + }, + { + "startDate": "2022-10-16T23:10:55", + "endDate": "2022-10-16T23:15:55", + "unit": "mg\/min·dL", + "value": 0.9327353913928134 + }, + { + "startDate": "2022-10-16T23:15:55", + "endDate": "2022-10-16T23:20:55", + "unit": "mg\/min·dL", + "value": 1.567929156289032 + }, + { + "startDate": "2022-10-16T23:20:55", + "endDate": "2022-10-16T23:25:55", + "unit": "mg\/min·dL", + "value": 0.5902090457631002 + }, + { + "startDate": "2022-10-16T23:25:55", + "endDate": "2022-10-16T23:30:56", + "unit": "mg\/min·dL", + "value": 0.0041194999268927 + }, + { + "startDate": "2022-10-16T23:30:56", + "endDate": "2022-10-16T23:35:55", + "unit": "mg\/min·dL", + "value": -0.5903810118195975 + }, + { + "startDate": "2022-10-16T23:35:55", + "endDate": "2022-10-16T23:40:56", + "unit": "mg\/min·dL", + "value": -0.7888201851294322 + }, + { + "startDate": "2022-10-16T23:40:56", + "endDate": "2022-10-16T23:45:55", + "unit": "mg\/min·dL", + "value": -0.19719045325679185 + }, + { + "startDate": "2022-10-16T23:45:55", + "endDate": "2022-10-16T23:50:55", + "unit": "mg\/min·dL", + "value": 1.391481925699727 + }, + { + "startDate": "2022-10-16T23:50:55", + "endDate": "2022-10-16T23:55:55", + "unit": "mg\/min·dL", + "value": 0.7714860788525394 + }, + { + "startDate": "2022-10-16T23:55:55", + "endDate": "2022-10-17T00:00:55", + "unit": "mg\/min·dL", + "value": 1.148931071940478 + }, + { + "startDate": "2022-10-17T00:00:55", + "endDate": "2022-10-17T00:05:55", + "unit": "mg\/min·dL", + "value": 0.7236798330387322 + }, + { + "startDate": "2022-10-17T00:05:55", + "endDate": "2022-10-17T00:10:55", + "unit": "mg\/min·dL", + "value": 0.8960938670797415 + }, + { + "startDate": "2022-10-17T00:10:55", + "endDate": "2022-10-17T00:15:55", + "unit": "mg\/min·dL", + "value": 0.8719274942897706 + }, + { + "startDate": "2022-10-17T00:15:55", + "endDate": "2022-10-17T00:20:55", + "unit": "mg\/min·dL", + "value": 1.4509978874832035 + }, + { + "startDate": "2022-10-17T00:20:55", + "endDate": "2022-10-17T00:25:55", + "unit": "mg\/min·dL", + "value": 3.633991893395394 + }, + { + "startDate": "2022-10-17T00:25:55", + "endDate": "2022-10-17T00:30:55", + "unit": "mg\/min·dL", + "value": 5.219533814878678 + }, + { + "startDate": "2022-10-17T00:30:55", + "endDate": "2022-10-17T00:35:56", + "unit": "mg\/min·dL", + "value": -0.7755871939106258 + }, + { + "startDate": "2022-10-17T00:35:56", + "endDate": "2022-10-17T00:40:56", + "unit": "mg\/min·dL", + "value": 1.6450492189675925 + }, + { + "startDate": "2022-10-17T00:40:56", + "endDate": "2022-10-17T00:45:55", + "unit": "mg\/min·dL", + "value": 2.2932552815173004 + }, + { + "startDate": "2022-10-17T00:45:55", + "endDate": "2022-10-17T00:50:56", + "unit": "mg\/min·dL", + "value": 1.5190954507889283 + }, + { + "startDate": "2022-10-17T00:50:56", + "endDate": "2022-10-17T00:55:56", + "unit": "mg\/min·dL", + "value": 2.9516354434782834 + }, + { + "startDate": "2022-10-17T00:55:56", + "endDate": "2022-10-17T01:00:56", + "unit": "mg\/min·dL", + "value": 0.5732859864418134 + }, + { + "startDate": "2022-10-17T01:00:56", + "endDate": "2022-10-17T01:05:55", + "unit": "mg\/min·dL", + "value": -1.20756468395372 + }, + { + "startDate": "2022-10-17T01:05:55", + "endDate": "2022-10-17T01:10:55", + "unit": "mg\/min·dL", + "value": -0.7867304872657194 + }, + { + "startDate": "2022-10-17T01:10:55", + "endDate": "2022-10-17T01:15:56", + "unit": "mg\/min·dL", + "value": -1.5694673963202832 + }, + { + "startDate": "2022-10-17T01:15:56", + "endDate": "2022-10-17T01:20:55", + "unit": "mg\/min·dL", + "value": -0.1643639957386131 + }, + { + "startDate": "2022-10-17T01:20:55", + "endDate": "2022-10-17T01:25:56", + "unit": "mg\/min·dL", + "value": -2.3577500064743524 + }, + { + "startDate": "2022-10-17T01:25:56", + "endDate": "2022-10-17T01:30:56", + "unit": "mg\/min·dL", + "value": 0.8323428726747981 + }, + { + "startDate": "2022-10-17T01:30:56", + "endDate": "2022-10-17T01:35:56", + "unit": "mg\/min·dL", + "value": 1.2228081822030008 + }, + { + "startDate": "2022-10-17T01:35:56", + "endDate": "2022-10-17T01:40:55", + "unit": "mg\/min·dL", + "value": 0.8048056766676048 + }, + { + "startDate": "2022-10-17T01:40:55", + "endDate": "2022-10-17T01:45:55", + "unit": "mg\/min·dL", + "value": 0.38224475602652913 + }, + { + "startDate": "2022-10-17T01:45:55", + "endDate": "2022-10-17T01:50:55", + "unit": "mg\/min·dL", + "value": -0.4440735677784057 + }, + { + "startDate": "2022-10-17T01:50:55", + "endDate": "2022-10-17T01:55:56", + "unit": "mg\/min·dL", + "value": 0.5243983931271272 + }, + { + "startDate": "2022-10-17T01:55:56", + "endDate": "2022-10-17T02:00:55", + "unit": "mg\/min·dL", + "value": 0.2931345766919252 + }, + { + "startDate": "2022-10-17T02:00:55", + "endDate": "2022-10-17T02:05:56", + "unit": "mg\/min·dL", + "value": 0.4561831643005171 + }, + { + "startDate": "2022-10-17T02:05:56", + "endDate": "2022-10-17T02:10:55", + "unit": "mg\/min·dL", + "value": 4.632973330858247 + }, + { + "startDate": "2022-10-17T02:10:55", + "endDate": "2022-10-17T02:15:55", + "unit": "mg\/min·dL", + "value": 3.3923410537792185 + }, + { + "startDate": "2022-10-17T02:15:55", + "endDate": "2022-10-17T02:20:55", + "unit": "mg\/min·dL", + "value": 2.7692455985225015 + }, + { + "startDate": "2022-10-17T02:20:55", + "endDate": "2022-10-17T02:25:56", + "unit": "mg\/min·dL", + "value": 0.7675601718208241 + }, + { + "startDate": "2022-10-17T02:25:56", + "endDate": "2022-10-17T02:30:55", + "unit": "mg\/min·dL", + "value": 1.0000691322446786 + }, + { + "startDate": "2022-10-17T02:30:55", + "endDate": "2022-10-17T02:35:55", + "unit": "mg\/min·dL", + "value": 0.6611668014658957 + }, + { + "startDate": "2022-10-17T02:35:55", + "endDate": "2022-10-17T02:40:56", + "unit": "mg\/min·dL", + "value": -0.08596328117482305 + }, + { + "startDate": "2022-10-17T02:40:56", + "endDate": "2022-10-17T02:45:56", + "unit": "mg\/min·dL", + "value": 0.7540608960491663 + }, + { + "startDate": "2022-10-17T02:45:56", + "endDate": "2022-10-17T02:50:55", + "unit": "mg\/min·dL", + "value": -0.818006344776246 + }, + { + "startDate": "2022-10-17T02:50:55", + "endDate": "2022-10-17T02:55:56", + "unit": "mg\/min·dL", + "value": 2.39887981869481 + }, + { + "startDate": "2022-10-17T02:55:56", + "endDate": "2022-10-17T03:00:56", + "unit": "mg\/min·dL", + "value": 0.20930108912543072 + }, + { + "startDate": "2022-10-17T03:00:56", + "endDate": "2022-10-17T03:05:56", + "unit": "mg\/min·dL", + "value": 0.8097746905008025 + }, + { + "startDate": "2022-10-17T03:05:56", + "endDate": "2022-10-17T03:10:56", + "unit": "mg\/min·dL", + "value": 0.6033947886970124 + }, + { + "startDate": "2022-10-17T03:10:56", + "endDate": "2022-10-17T03:15:56", + "unit": "mg\/min·dL", + "value": 0.9898220114011889 + }, + { + "startDate": "2022-10-17T03:15:56", + "endDate": "2022-10-17T03:20:56", + "unit": "mg\/min·dL", + "value": -0.22832265899703647 + }, + { + "startDate": "2022-10-17T03:20:56", + "endDate": "2022-10-17T03:25:56", + "unit": "mg\/min·dL", + "value": -0.4511116066129434 + }, + { + "startDate": "2022-10-17T03:25:56", + "endDate": "2022-10-17T03:30:55", + "unit": "mg\/min·dL", + "value": -2.477086162741612 + }, + { + "startDate": "2022-10-17T03:30:55", + "endDate": "2022-10-17T03:35:56", + "unit": "mg\/min·dL", + "value": -1.3028794753131472 + }, + { + "startDate": "2022-10-17T03:35:56", + "endDate": "2022-10-17T03:40:56", + "unit": "mg\/min·dL", + "value": 0.6617447275509728 + }, + { + "startDate": "2022-10-17T03:40:56", + "endDate": "2022-10-17T03:45:56", + "unit": "mg\/min·dL", + "value": 1.0257874848496134 + }, + { + "startDate": "2022-10-17T03:45:56", + "endDate": "2022-10-17T03:50:56", + "unit": "mg\/min·dL", + "value": 1.5904120793516692 + }, + { + "startDate": "2022-10-17T03:50:56", + "endDate": "2022-10-17T03:55:56", + "unit": "mg\/min·dL", + "value": 1.350173285305319 + }, + { + "startDate": "2022-10-17T03:55:56", + "endDate": "2022-10-17T04:00:56", + "unit": "mg\/min·dL", + "value": 2.313304809362078 + }, + { + "startDate": "2022-10-17T04:00:56", + "endDate": "2022-10-17T04:05:56", + "unit": "mg\/min·dL", + "value": 1.472727094038384 + }, + { + "startDate": "2022-10-17T04:05:56", + "endDate": "2022-10-17T04:10:56", + "unit": "mg\/min·dL", + "value": 1.2459875080276552 + }, + { + "startDate": "2022-10-17T04:10:56", + "endDate": "2022-10-17T04:15:56", + "unit": "mg\/min·dL", + "value": 0.4290145455866161 + }, + { + "startDate": "2022-10-17T04:15:56", + "endDate": "2022-10-17T04:20:56", + "unit": "mg\/min·dL", + "value": 0.6263357321101345 + }, + { + "startDate": "2022-10-17T04:20:56", + "endDate": "2022-10-17T04:25:56", + "unit": "mg\/min·dL", + "value": -0.36841711164706026 + }, + { + "startDate": "2022-10-17T04:25:56", + "endDate": "2022-10-17T04:30:56", + "unit": "mg\/min·dL", + "value": 1.0381399131596578 + }, + { + "startDate": "2022-10-17T04:30:56", + "endDate": "2022-10-17T04:35:56", + "unit": "mg\/min·dL", + "value": 2.449160211321216 + }, + { + "startDate": "2022-10-17T04:35:56", + "endDate": "2022-10-17T04:40:56", + "unit": "mg\/min·dL", + "value": 0.8519932553148932 + }, + { + "startDate": "2022-10-17T04:40:56", + "endDate": "2022-10-17T04:45:56", + "unit": "mg\/min·dL", + "value": 0.25545807211354093 + }, + { + "startDate": "2022-10-17T04:45:56", + "endDate": "2022-10-17T04:50:56", + "unit": "mg\/min·dL", + "value": 0.2672233629275522 + }, + { + "startDate": "2022-10-17T04:50:56", + "endDate": "2022-10-17T04:55:56", + "unit": "mg\/min·dL", + "value": -0.3192664353132631 + }, + { + "startDate": "2022-10-17T04:55:56", + "endDate": "2022-10-17T05:00:56", + "unit": "mg\/min·dL", + "value": -1.513791537638646 + }, + { + "startDate": "2022-10-17T05:00:56", + "endDate": "2022-10-17T05:05:56", + "unit": "mg\/min·dL", + "value": -1.7044380808946273 + }, + { + "startDate": "2022-10-17T05:05:56", + "endDate": "2022-10-17T05:10:56", + "unit": "mg\/min·dL", + "value": -1.712644832803029 + }, + { + "startDate": "2022-10-17T05:10:56", + "endDate": "2022-10-17T05:15:56", + "unit": "mg\/min·dL", + "value": -0.9190525555156 + }, + { + "startDate": "2022-10-17T05:15:56", + "endDate": "2022-10-17T05:20:56", + "unit": "mg\/min·dL", + "value": -0.3311164563982576 + }, + { + "startDate": "2022-10-17T05:20:56", + "endDate": "2022-10-17T05:25:56", + "unit": "mg\/min·dL", + "value": 0.6520001664415103 + }, + { + "startDate": "2022-10-17T05:25:56", + "endDate": "2022-10-17T05:30:56", + "unit": "mg\/min·dL", + "value": 1.233062198641944 + }, + { + "startDate": "2022-10-17T05:30:56", + "endDate": "2022-10-17T05:35:56", + "unit": "mg\/min·dL", + "value": 1.2076048576203615 + }, + { + "startDate": "2022-10-17T05:35:56", + "endDate": "2022-10-17T05:40:56", + "unit": "mg\/min·dL", + "value": 1.18294662356514 + }, + { + "startDate": "2022-10-17T05:40:56", + "endDate": "2022-10-17T05:45:56", + "unit": "mg\/min·dL", + "value": 0.9530329092590353 + }, + { + "startDate": "2022-10-17T05:45:56", + "endDate": "2022-10-17T05:50:56", + "unit": "mg\/min·dL", + "value": 0.32623717759217646 + }, + { + "startDate": "2022-10-17T05:50:56", + "endDate": "2022-10-17T05:55:56", + "unit": "mg\/min·dL", + "value": 0.8983368506804443 + }, + { + "startDate": "2022-10-17T05:55:56", + "endDate": "2022-10-17T06:00:56", + "unit": "mg\/min·dL", + "value": 0.47971971019911824 + }, + { + "startDate": "2022-10-17T06:00:56", + "endDate": "2022-10-17T06:05:56", + "unit": "mg\/min·dL", + "value": 0.26323063620005377 + }, + { + "startDate": "2022-10-17T06:05:56", + "endDate": "2022-10-17T06:10:56", + "unit": "mg\/min·dL", + "value": 0.2527988070184891 + }, + { + "startDate": "2022-10-17T06:10:56", + "endDate": "2022-10-17T06:15:56", + "unit": "mg\/min·dL", + "value": 0.44391960463529634 + }, + { + "startDate": "2022-10-17T06:15:56", + "endDate": "2022-10-17T06:20:56", + "unit": "mg\/min·dL", + "value": 0.0338159426958477 + }, + { + "startDate": "2022-10-17T06:20:56", + "endDate": "2022-10-17T06:25:56", + "unit": "mg\/min·dL", + "value": 0.42080301326849073 + }, + { + "startDate": "2022-10-17T06:25:56", + "endDate": "2022-10-17T06:30:56", + "unit": "mg\/min·dL", + "value": 0.009200834959802624 + }, + { + "startDate": "2022-10-17T06:30:56", + "endDate": "2022-10-17T06:35:56", + "unit": "mg\/min·dL", + "value": -0.0034976034396666947 + }, + { + "startDate": "2022-10-17T06:35:56", + "endDate": "2022-10-17T06:40:56", + "unit": "mg\/min·dL", + "value": -0.01574338703246741 + }, + { + "startDate": "2022-10-17T06:40:56", + "endDate": "2022-10-17T06:45:56", + "unit": "mg\/min·dL", + "value": -0.028328548453654148 + }, + { + "startDate": "2022-10-17T06:45:56", + "endDate": "2022-10-17T06:50:56", + "unit": "mg\/min·dL", + "value": -0.042803942449195886 + }, + { + "startDate": "2022-10-17T06:50:56", + "endDate": "2022-10-17T06:55:56", + "unit": "mg\/min·dL", + "value": -0.05933842985149843 + }, + { + "startDate": "2022-10-17T06:55:56", + "endDate": "2022-10-17T07:00:56", + "unit": "mg\/min·dL", + "value": -0.07734206261505443 + }, + { + "startDate": "2022-10-17T07:00:56", + "endDate": "2022-10-17T07:05:57", + "unit": "mg\/min·dL", + "value": 0.10354020565314719 + }, + { + "startDate": "2022-10-17T07:05:57", + "endDate": "2022-10-17T07:10:56", + "unit": "mg\/min·dL", + "value": 0.2848604801395987 + }, + { + "startDate": "2022-10-17T07:10:56", + "endDate": "2022-10-17T07:15:56", + "unit": "mg\/min·dL", + "value": -0.5351997683038484 + }, + { + "startDate": "2022-10-17T07:15:56", + "endDate": "2022-10-17T07:20:56", + "unit": "mg\/min·dL", + "value": -0.5561162558548638 + }, + { + "startDate": "2022-10-17T07:20:56", + "endDate": "2022-10-17T07:25:56", + "unit": "mg\/min·dL", + "value": 1.026446015181327 + }, + { + "startDate": "2022-10-17T07:25:56", + "endDate": "2022-10-17T07:30:56", + "unit": "mg\/min·dL", + "value": -1.3889750203453213 + }, + { + "startDate": "2022-10-17T07:30:56", + "endDate": "2022-10-17T07:35:56", + "unit": "mg\/min·dL", + "value": 3.5926136152071413 + }, + { + "startDate": "2022-10-17T07:35:56", + "endDate": "2022-10-17T07:40:56", + "unit": "mg\/min·dL", + "value": 2.7749093320580926 + }, + { + "startDate": "2022-10-17T07:40:56", + "endDate": "2022-10-17T07:45:57", + "unit": "mg\/min·dL", + "value": 3.746086706283121 + }, + { + "startDate": "2022-10-17T07:45:57", + "endDate": "2022-10-17T07:50:57", + "unit": "mg\/min·dL", + "value": 4.955723649353499 + }, + { + "startDate": "2022-10-17T07:50:57", + "endDate": "2022-10-17T07:55:56", + "unit": "mg\/min·dL", + "value": 4.996640987612763 + }, + { + "startDate": "2022-10-17T07:55:56", + "endDate": "2022-10-17T08:00:57", + "unit": "mg\/min·dL", + "value": 3.0304810395539663 + }, + { + "startDate": "2022-10-17T08:00:57", + "endDate": "2022-10-17T08:05:56", + "unit": "mg\/min·dL", + "value": 4.332986252787241 + }, + { + "startDate": "2022-10-17T08:05:56", + "endDate": "2022-10-17T08:10:57", + "unit": "mg\/min·dL", + "value": 3.7965717213147436 + }, + { + "startDate": "2022-10-17T08:10:57", + "endDate": "2022-10-17T08:15:56", + "unit": "mg\/min·dL", + "value": 0.6920745985592388 + }, + { + "startDate": "2022-10-17T08:15:56", + "endDate": "2022-10-17T08:20:57", + "unit": "mg\/min·dL", + "value": 1.380230886893775 + }, + { + "startDate": "2022-10-17T08:20:57", + "endDate": "2022-10-17T08:25:57", + "unit": "mg\/min·dL", + "value": -0.31528831809019864 + }, + { + "startDate": "2022-10-17T08:25:57", + "endDate": "2022-10-17T08:30:56", + "unit": "mg\/min·dL", + "value": 0.18164411041348966 + }, + { + "startDate": "2022-10-17T08:30:56", + "endDate": "2022-10-17T08:35:56", + "unit": "mg\/min·dL", + "value": 0.06938282997424218 + }, + { + "startDate": "2022-10-17T08:35:56", + "endDate": "2022-10-17T08:40:57", + "unit": "mg\/min·dL", + "value": -0.6569780599920586 + }, + { + "startDate": "2022-10-17T08:40:57", + "endDate": "2022-10-17T08:45:56", + "unit": "mg\/min·dL", + "value": -2.002245300154777 + }, + { + "startDate": "2022-10-17T08:45:56", + "endDate": "2022-10-17T08:50:57", + "unit": "mg\/min·dL", + "value": -1.549451452214076 + }, + { + "startDate": "2022-10-17T08:50:57", + "endDate": "2022-10-17T08:55:56", + "unit": "mg\/min·dL", + "value": -1.322155355994713 + }, + { + "startDate": "2022-10-17T08:55:56", + "endDate": "2022-10-17T09:00:56", + "unit": "mg\/min·dL", + "value": -0.6943400893385767 + }, + { + "startDate": "2022-10-17T09:00:56", + "endDate": "2022-10-17T09:05:56", + "unit": "mg\/min·dL", + "value": -0.48121967301796426 + }, + { + "startDate": "2022-10-17T09:05:56", + "endDate": "2022-10-17T09:10:56", + "unit": "mg\/min·dL", + "value": -0.27611861679495037 + }, + { + "startDate": "2022-10-17T09:10:56", + "endDate": "2022-10-17T09:15:57", + "unit": "mg\/min·dL", + "value": 0.12006679946502295 + }, + { + "startDate": "2022-10-17T09:15:57", + "endDate": "2022-10-17T09:20:57", + "unit": "mg\/min·dL", + "value": 0.9113005453156893 + }, + { + "startDate": "2022-10-17T09:20:57", + "endDate": "2022-10-17T09:25:56", + "unit": "mg\/min·dL", + "value": 0.09388318724059296 + }, + { + "startDate": "2022-10-17T09:25:56", + "endDate": "2022-10-17T09:30:56", + "unit": "mg\/min·dL", + "value": 0.871487757074061 + }, + { + "startDate": "2022-10-17T09:30:56", + "endDate": "2022-10-17T09:35:57", + "unit": "mg\/min·dL", + "value": 1.2446560973111296 + }, + { + "startDate": "2022-10-17T09:35:57", + "endDate": "2022-10-17T09:40:56", + "unit": "mg\/min·dL", + "value": 1.0166924505981447 + }, + { + "startDate": "2022-10-17T09:40:56", + "endDate": "2022-10-17T09:45:57", + "unit": "mg\/min·dL", + "value": 0.5813199722905042 + }, + { + "startDate": "2022-10-17T09:45:57", + "endDate": "2022-10-17T09:50:56", + "unit": "mg\/min·dL", + "value": 0.9470217340786014 + }, + { + "startDate": "2022-10-17T09:50:56", + "endDate": "2022-10-17T09:55:57", + "unit": "mg\/min·dL", + "value": 1.1063805177477521 + }, + { + "startDate": "2022-10-17T09:55:57", + "endDate": "2022-10-17T10:00:57", + "unit": "mg\/min·dL", + "value": 1.0678400294991015 + }, + { + "startDate": "2022-10-17T10:00:57", + "endDate": "2022-10-17T10:05:56", + "unit": "mg\/min·dL", + "value": 0.6343386087427577 + }, + { + "startDate": "2022-10-17T10:05:56", + "endDate": "2022-10-17T10:10:56", + "unit": "mg\/min·dL", + "value": 0.8006679951794808 + }, + { + "startDate": "2022-10-17T10:10:56", + "endDate": "2022-10-17T10:15:57", + "unit": "mg\/min·dL", + "value": 1.1757271031846188 + }, + { + "startDate": "2022-10-17T10:15:57", + "endDate": "2022-10-17T10:20:57", + "unit": "mg\/min·dL", + "value": 0.9549561105429651 + }, + { + "startDate": "2022-10-17T10:20:57", + "endDate": "2022-10-17T10:25:56", + "unit": "mg\/min·dL", + "value": 0.9395422101128353 + }, + { + "startDate": "2022-10-17T10:25:56", + "endDate": "2022-10-17T10:30:57", + "unit": "mg\/min·dL", + "value": 0.7213247424132531 + }, + { + "startDate": "2022-10-17T10:30:57", + "endDate": "2022-10-17T10:35:57", + "unit": "mg\/min·dL", + "value": 0.7122028044445942 + }, + { + "startDate": "2022-10-17T10:35:57", + "endDate": "2022-10-17T10:40:57", + "unit": "mg\/min·dL", + "value": 0.9052517663340723 + }, + { + "startDate": "2022-10-17T10:40:57", + "endDate": "2022-10-17T10:45:56", + "unit": "mg\/min·dL", + "value": 0.699122847987222 + }, + { + "startDate": "2022-10-17T10:45:56", + "endDate": "2022-10-17T10:50:56", + "unit": "mg\/min·dL", + "value": 0.6913335747487636 + }, + { + "startDate": "2022-10-17T10:50:56", + "endDate": "2022-10-17T10:55:56", + "unit": "mg\/min·dL", + "value": 0.8872653413930243 + }, + { + "startDate": "2022-10-17T10:55:56", + "endDate": "2022-10-17T11:00:56", + "unit": "mg\/min·dL", + "value": 0.8821124122832216 + }, + { + "startDate": "2022-10-17T11:00:56", + "endDate": "2022-10-17T11:05:57", + "unit": "mg\/min·dL", + "value": 1.0762823125902266 + }, + { + "startDate": "2022-10-17T11:05:57", + "endDate": "2022-10-17T11:10:57", + "unit": "mg\/min·dL", + "value": 0.8705356061523262 + }, + { + "startDate": "2022-10-17T11:10:57", + "endDate": "2022-10-17T11:15:57", + "unit": "mg\/min·dL", + "value": 2.270378271296252 + }, + { + "startDate": "2022-10-17T11:15:57", + "endDate": "2022-10-17T11:20:57", + "unit": "mg\/min·dL", + "value": 2.0675398966404512 + }, + { + "startDate": "2022-10-17T11:20:57", + "endDate": "2022-10-17T11:25:57", + "unit": "mg\/min·dL", + "value": 1.672835991153337 + }, + { + "startDate": "2022-10-17T11:25:57", + "endDate": "2022-10-17T11:30:57", + "unit": "mg\/min·dL", + "value": 1.282134118615466 + }, + { + "startDate": "2022-10-17T11:30:57", + "endDate": "2022-10-17T11:35:57", + "unit": "mg\/min·dL", + "value": 1.1042760922545358 + }, + { + "startDate": "2022-10-17T11:35:57", + "endDate": "2022-10-17T11:40:57", + "unit": "mg\/min·dL", + "value": -0.0715803708831969 + }, + { + "startDate": "2022-10-17T11:40:57", + "endDate": "2022-10-17T11:45:57", + "unit": "mg\/min·dL", + "value": 0.5562508834174531 + }, + { + "startDate": "2022-10-17T11:45:57", + "endDate": "2022-10-17T11:50:57", + "unit": "mg\/min·dL", + "value": 1.3791757347276055 + }, + { + "startDate": "2022-10-17T11:50:57", + "endDate": "2022-10-17T11:55:57", + "unit": "mg\/min·dL", + "value": 0.7975595824531685 + }, + { + "startDate": "2022-10-17T11:55:57", + "endDate": "2022-10-17T12:00:56", + "unit": "mg\/min·dL", + "value": 1.0107065963916195 + }, + { + "startDate": "2022-10-17T12:00:56", + "endDate": "2022-10-17T12:05:57", + "unit": "mg\/min·dL", + "value": 1.619041638687975 + }, + { + "startDate": "2022-10-17T12:05:57", + "endDate": "2022-10-17T12:10:56", + "unit": "mg\/min·dL", + "value": 0.2289011705408734 + }, + { + "startDate": "2022-10-17T12:10:56", + "endDate": "2022-10-17T12:15:57", + "unit": "mg\/min·dL", + "value": 0.8341745845319312 + }, + { + "startDate": "2022-10-17T12:15:57", + "endDate": "2022-10-17T12:20:57", + "unit": "mg\/min·dL", + "value": 1.043486724815214 + }, + { + "startDate": "2022-10-17T12:20:57", + "endDate": "2022-10-17T12:25:57", + "unit": "mg\/min·dL", + "value": 0.6465113919254944 + }, + { + "startDate": "2022-10-17T12:25:57", + "endDate": "2022-10-17T12:30:57", + "unit": "mg\/min·dL", + "value": 0.8497079852663679 + }, + { + "startDate": "2022-10-17T12:30:57", + "endDate": "2022-10-17T12:35:57", + "unit": "mg\/min·dL", + "value": 0.8516497402932928 + }, + { + "startDate": "2022-10-17T12:35:57", + "endDate": "2022-10-17T12:40:57", + "unit": "mg\/min·dL", + "value": 0.4544982669966845 + }, + { + "startDate": "2022-10-17T12:40:57", + "endDate": "2022-10-17T12:45:57", + "unit": "mg\/min·dL", + "value": 0.45502813749310494 + }, + { + "startDate": "2022-10-17T12:45:57", + "endDate": "2022-10-17T12:50:57", + "unit": "mg\/min·dL", + "value": 0.053607228109501304 + }, + { + "startDate": "2022-10-17T12:50:57", + "endDate": "2022-10-17T12:55:57", + "unit": "mg\/min·dL", + "value": 3.850030747446343 + }, + { + "startDate": "2022-10-17T12:55:57", + "endDate": "2022-10-17T13:00:57", + "unit": "mg\/min·dL", + "value": -2.5605776759549843 + }, + { + "startDate": "2022-10-17T13:00:57", + "endDate": "2022-10-17T13:05:58", + "unit": "mg\/min·dL", + "value": -0.16929980570474054 + }, + { + "startDate": "2022-10-17T13:05:58", + "endDate": "2022-10-17T13:10:57", + "unit": "mg\/min·dL", + "value": -0.17024253181035856 + }, + { + "startDate": "2022-10-17T13:10:57", + "endDate": "2022-10-17T13:15:57", + "unit": "mg\/min·dL", + "value": 0.22396575670759422 + }, + { + "startDate": "2022-10-17T13:15:57", + "endDate": "2022-10-17T13:20:57", + "unit": "mg\/min·dL", + "value": 0.2131383127213337 + }, + { + "startDate": "2022-10-17T13:20:57", + "endDate": "2022-10-17T13:25:57", + "unit": "mg\/min·dL", + "value": -0.0036422184008190975 + }, + { + "startDate": "2022-10-17T13:25:57", + "endDate": "2022-10-17T13:30:57", + "unit": "mg\/min·dL", + "value": -0.024307494393551208 + }, + { + "startDate": "2022-10-17T13:30:57", + "endDate": "2022-10-17T13:35:57", + "unit": "mg\/min·dL", + "value": 0.7504265623640302 + }, + { + "startDate": "2022-10-17T13:35:57", + "endDate": "2022-10-17T13:40:57", + "unit": "mg\/min·dL", + "value": 0.12395887249486975 + }, + { + "startDate": "2022-10-17T13:40:57", + "endDate": "2022-10-17T13:45:57", + "unit": "mg\/min·dL", + "value": -0.5054765171613136 + }, + { + "startDate": "2022-10-17T13:45:57", + "endDate": "2022-10-17T13:50:57", + "unit": "mg\/min·dL", + "value": 0.2650315439906281 + }, + { + "startDate": "2022-10-17T13:50:57", + "endDate": "2022-10-17T13:55:57", + "unit": "mg\/min·dL", + "value": 0.235027270256946 + }, + { + "startDate": "2022-10-17T13:55:57", + "endDate": "2022-10-17T14:00:57", + "unit": "mg\/min·dL", + "value": 0.004825228772659867 + }, + { + "startDate": "2022-10-17T14:00:57", + "endDate": "2022-10-17T14:05:57", + "unit": "mg\/min·dL", + "value": 0.17631247206302156 + }, + { + "startDate": "2022-10-17T14:05:57", + "endDate": "2022-10-17T14:10:57", + "unit": "mg\/min·dL", + "value": 0.3494460554759167 + }, + { + "startDate": "2022-10-17T14:10:57", + "endDate": "2022-10-17T14:15:57", + "unit": "mg\/min·dL", + "value": -0.07881975737358604 + }, + { + "startDate": "2022-10-17T14:15:57", + "endDate": "2022-10-17T14:20:57", + "unit": "mg\/min·dL", + "value": 0.09501914368510557 + }, + { + "startDate": "2022-10-17T14:20:57", + "endDate": "2022-10-17T14:25:57", + "unit": "mg\/min·dL", + "value": 0.26962224455049527 + }, + { + "startDate": "2022-10-17T14:25:57", + "endDate": "2022-10-17T14:30:58", + "unit": "mg\/min·dL", + "value": 1.0461918213992094 + }, + { + "startDate": "2022-10-17T14:30:58", + "endDate": "2022-10-17T14:35:58", + "unit": "mg\/min·dL", + "value": 0.2233686770059514 + }, + { + "startDate": "2022-10-17T14:35:58", + "endDate": "2022-10-17T14:40:57", + "unit": "mg\/min·dL", + "value": -0.7968131225503261 + }, + { + "startDate": "2022-10-17T14:40:57", + "endDate": "2022-10-17T14:45:57", + "unit": "mg\/min·dL", + "value": -0.00755583436261384 + }, + { + "startDate": "2022-10-17T14:45:57", + "endDate": "2022-10-17T14:50:58", + "unit": "mg\/min·dL", + "value": -0.017988670741366602 + }, + { + "startDate": "2022-10-17T14:50:58", + "endDate": "2022-10-17T14:55:57", + "unit": "mg\/min·dL", + "value": 0.16860756482113998 + }, + { + "startDate": "2022-10-17T14:55:57", + "endDate": "2022-10-17T15:00:57", + "unit": "mg\/min·dL", + "value": 0.15258695408591513 + }, + { + "startDate": "2022-10-17T15:00:57", + "endDate": "2022-10-17T15:05:57", + "unit": "mg\/min·dL", + "value": 0.3366705688171287 + }, + { + "startDate": "2022-10-17T15:05:57", + "endDate": "2022-10-17T15:10:57", + "unit": "mg\/min·dL", + "value": 0.12225745161360409 + }, + { + "startDate": "2022-10-17T15:10:57", + "endDate": "2022-10-17T15:15:57", + "unit": "mg\/min·dL", + "value": 0.3057494415391212 + }, + { + "startDate": "2022-10-17T15:15:57", + "endDate": "2022-10-17T15:20:57", + "unit": "mg\/min·dL", + "value": 1.6878262062492664 + }, + { + "startDate": "2022-10-17T15:20:57", + "endDate": "2022-10-17T15:25:57", + "unit": "mg\/min·dL", + "value": -0.12540003293832777 + }, + { + "startDate": "2022-10-17T15:25:57", + "endDate": "2022-10-17T15:30:58", + "unit": "mg\/min·dL", + "value": 3.2579639609054944 + }, + { + "startDate": "2022-10-17T15:30:58", + "endDate": "2022-10-17T15:35:57", + "unit": "mg\/min·dL", + "value": -2.33882331116317 + }, + { + "startDate": "2022-10-17T15:35:57", + "endDate": "2022-10-17T15:40:57", + "unit": "mg\/min·dL", + "value": -1.3337321869891747 + }, + { + "startDate": "2022-10-17T15:40:57", + "endDate": "2022-10-17T15:45:57", + "unit": "mg\/min·dL", + "value": -0.717298126861785 + }, + { + "startDate": "2022-10-17T15:45:57", + "endDate": "2022-10-17T15:50:57", + "unit": "mg\/min·dL", + "value": -1.3071661542366684 + }, + { + "startDate": "2022-10-17T15:50:57", + "endDate": "2022-10-17T15:55:57", + "unit": "mg\/min·dL", + "value": -1.4985287049008267 + }, + { + "startDate": "2022-10-17T15:55:57", + "endDate": "2022-10-17T16:00:57", + "unit": "mg\/min·dL", + "value": -0.29630881245414115 + }, + { + "startDate": "2022-10-17T16:00:57", + "endDate": "2022-10-17T16:05:57", + "unit": "mg\/min·dL", + "value": -0.2973617987728701 + }, + { + "startDate": "2022-10-17T16:05:57", + "endDate": "2022-10-17T16:10:58", + "unit": "mg\/min·dL", + "value": -0.10233458926668869 + }, + { + "startDate": "2022-10-17T16:10:58", + "endDate": "2022-10-17T16:15:58", + "unit": "mg\/min·dL", + "value": 0.08971198167566777 + }, + { + "startDate": "2022-10-17T16:15:58", + "endDate": "2022-10-17T16:20:57", + "unit": "mg\/min·dL", + "value": -0.32128769588079303 + }, + { + "startDate": "2022-10-17T16:20:57", + "endDate": "2022-10-17T16:25:58", + "unit": "mg\/min·dL", + "value": -0.1333543684979505 + }, + { + "startDate": "2022-10-17T16:25:58", + "endDate": "2022-10-17T16:30:57", + "unit": "mg\/min·dL", + "value": 0.05179539206684855 + }, + { + "startDate": "2022-10-17T16:30:57", + "endDate": "2022-10-17T16:35:57", + "unit": "mg\/min·dL", + "value": 0.03525249389131893 + }, + { + "startDate": "2022-10-17T16:35:57", + "endDate": "2022-10-17T16:40:57", + "unit": "mg\/min·dL", + "value": 0.21730726337856762 + }, + { + "startDate": "2022-10-17T16:40:57", + "endDate": "2022-10-17T16:45:58", + "unit": "mg\/min·dL", + "value": 1.3965937622299813 + }, + { + "startDate": "2022-10-17T16:45:58", + "endDate": "2022-10-17T16:50:57", + "unit": "mg\/min·dL", + "value": 1.580064623999398 + }, + { + "startDate": "2022-10-17T16:50:57", + "endDate": "2022-10-17T16:55:58", + "unit": "mg\/min·dL", + "value": 0.7568514241319295 + }, + { + "startDate": "2022-10-17T16:55:58", + "endDate": "2022-10-17T17:00:58", + "unit": "mg\/min·dL", + "value": 1.1430376620243732 + }, + { + "startDate": "2022-10-17T17:00:58", + "endDate": "2022-10-17T17:05:57", + "unit": "mg\/min·dL", + "value": 0.7341003445506363 + }, + { + "startDate": "2022-10-17T17:05:57", + "endDate": "2022-10-17T17:10:58", + "unit": "mg\/min·dL", + "value": 1.1268541295706538 + }, + { + "startDate": "2022-10-17T17:10:58", + "endDate": "2022-10-17T17:15:57", + "unit": "mg\/min·dL", + "value": 0.9347439999943791 + }, + { + "startDate": "2022-10-17T17:15:57", + "endDate": "2022-10-17T17:20:57", + "unit": "mg\/min·dL", + "value": -0.05849178159961313 + }, + { + "startDate": "2022-10-17T17:20:57", + "endDate": "2022-10-17T17:25:58", + "unit": "mg\/min·dL", + "value": -0.043980150922760856 + }, + { + "startDate": "2022-10-17T17:25:58", + "endDate": "2022-10-17T17:30:58", + "unit": "mg\/min·dL", + "value": 1.172267021770458 + }, + { + "startDate": "2022-10-17T17:30:58", + "endDate": "2022-10-17T17:35:58", + "unit": "mg\/min·dL", + "value": 0.9867370663288156 + }, + { + "startDate": "2022-10-17T17:35:58", + "endDate": "2022-10-17T17:40:58", + "unit": "mg\/min·dL", + "value": 0.5971550847739795 + }, + { + "startDate": "2022-10-17T17:40:58", + "endDate": "2022-10-17T17:45:57", + "unit": "mg\/min·dL", + "value": 0.007334399026725797 + }, + { + "startDate": "2022-10-17T17:45:57", + "endDate": "2022-10-17T17:50:57", + "unit": "mg\/min·dL", + "value": 0.4211816970126617 + }, + { + "startDate": "2022-10-17T17:50:57", + "endDate": "2022-10-17T17:55:58", + "unit": "mg\/min·dL", + "value": 1.0317341149283863 + }, + { + "startDate": "2022-10-17T17:55:58", + "endDate": "2022-10-17T18:00:58", + "unit": "mg\/min·dL", + "value": 1.4451839309800605 + }, + { + "startDate": "2022-10-17T18:00:58", + "endDate": "2022-10-17T18:05:58", + "unit": "mg\/min·dL", + "value": 1.6521747464530774 + }, + { + "startDate": "2022-10-17T18:05:58", + "endDate": "2022-10-17T18:10:57", + "unit": "mg\/min·dL", + "value": 1.6670375773385095 + }, + { + "startDate": "2022-10-17T18:10:57", + "endDate": "2022-10-17T18:15:58", + "unit": "mg\/min·dL", + "value": 1.6815570963307955 + }, + { + "startDate": "2022-10-17T18:15:58", + "endDate": "2022-10-17T18:20:58", + "unit": "mg\/min·dL", + "value": 1.9055447248731132 + }, + { + "startDate": "2022-10-17T18:20:58", + "endDate": "2022-10-17T18:25:57", + "unit": "mg\/min·dL", + "value": 1.7396687349251063 + }, + { + "startDate": "2022-10-17T18:25:57", + "endDate": "2022-10-17T18:30:57", + "unit": "mg\/min·dL", + "value": 1.176224616460157 + }, + { + "startDate": "2022-10-17T18:30:57", + "endDate": "2022-10-17T18:35:58", + "unit": "mg\/min·dL", + "value": 0.8161964326183754 + }, + { + "startDate": "2022-10-17T18:35:58", + "endDate": "2022-10-17T18:40:57", + "unit": "mg\/min·dL", + "value": 1.069405878974623 + }, + { + "startDate": "2022-10-17T18:40:57", + "endDate": "2022-10-17T18:45:57", + "unit": "mg\/min·dL", + "value": 0.7149637327769314 + }, + { + "startDate": "2022-10-17T18:45:57", + "endDate": "2022-10-17T18:50:58", + "unit": "mg\/min·dL", + "value": 0.7580055677633227 + }, + { + "startDate": "2022-10-17T18:50:58", + "endDate": "2022-10-17T18:55:57", + "unit": "mg\/min·dL", + "value": 0.39954773081158734 + }, + { + "startDate": "2022-10-17T18:55:57", + "endDate": "2022-10-17T19:00:57", + "unit": "mg\/min·dL", + "value": 0.6322656375672243 + }, + { + "startDate": "2022-10-17T19:00:57", + "endDate": "2022-10-17T19:05:58", + "unit": "mg\/min·dL", + "value": 0.6601567890512666 + }, + { + "startDate": "2022-10-17T19:05:58", + "endDate": "2022-10-17T19:10:58", + "unit": "mg\/min·dL", + "value": 0.28254788027999844 + }, + { + "startDate": "2022-10-17T19:10:58", + "endDate": "2022-10-17T19:15:57", + "unit": "mg\/min·dL", + "value": 0.29810083959368033 + }, + { + "startDate": "2022-10-17T19:15:57", + "endDate": "2022-10-17T19:20:58", + "unit": "mg\/min·dL", + "value": 0.50675343533354 + }, + { + "startDate": "2022-10-17T19:20:58", + "endDate": "2022-10-17T19:25:58", + "unit": "mg\/min·dL", + "value": 0.5137649628645453 + }, + { + "startDate": "2022-10-17T19:25:58", + "endDate": "2022-10-17T19:30:58", + "unit": "mg\/min·dL", + "value": 0.5169966515232866 + }, + { + "startDate": "2022-10-17T19:30:58", + "endDate": "2022-10-17T19:35:58", + "unit": "mg\/min·dL", + "value": 0.7146717742568007 + }, + { + "startDate": "2022-10-17T19:35:58", + "endDate": "2022-10-17T19:40:57", + "unit": "mg\/min·dL", + "value": 0.9088903732995701 + }, + { + "startDate": "2022-10-17T19:40:57", + "endDate": "2022-10-17T19:45:58", + "unit": "mg\/min·dL", + "value": 1.100742556000779 + }, + { + "startDate": "2022-10-17T19:45:58", + "endDate": "2022-10-17T19:50:58", + "unit": "mg\/min·dL", + "value": 1.292926565538361 + }, + { + "startDate": "2022-10-17T19:50:58", + "endDate": "2022-10-17T19:55:58", + "unit": "mg\/min·dL", + "value": 1.0930916176029168 + }, + { + "startDate": "2022-10-17T19:55:58", + "endDate": "2022-10-17T20:00:58", + "unit": "mg\/min·dL", + "value": 1.0936289317791132 + }, + { + "startDate": "2022-10-17T20:00:58", + "endDate": "2022-10-17T20:05:57", + "unit": "mg\/min·dL", + "value": 0.8987065716926492 + }, + { + "startDate": "2022-10-17T20:05:57", + "endDate": "2022-10-17T20:10:58", + "unit": "mg\/min·dL", + "value": 0.7075247469377013 + }, + { + "startDate": "2022-10-17T20:10:58", + "endDate": "2022-10-17T20:15:58", + "unit": "mg\/min·dL", + "value": 0.5191499097513893 + }, + { + "startDate": "2022-10-17T20:15:58", + "endDate": "2022-10-17T20:20:58", + "unit": "mg\/min·dL", + "value": 0.3324377735152427 + }, + { + "startDate": "2022-10-17T20:20:58", + "endDate": "2022-10-17T20:25:58", + "unit": "mg\/min·dL", + "value": 0.3452106927143431 + }, + { + "startDate": "2022-10-17T20:25:58", + "endDate": "2022-10-17T20:30:58", + "unit": "mg\/min·dL", + "value": 0.5526530110663183 + } +] diff --git a/LoopTests/Fixtures/meal_detection/long_interval_counteraction_effect.json b/LoopTests/Fixtures/meal_detection/long_interval_counteraction_effect.json new file mode 100644 index 0000000000..fd52dc5698 --- /dev/null +++ b/LoopTests/Fixtures/meal_detection/long_interval_counteraction_effect.json @@ -0,0 +1,14 @@ +[ + { + "startDate": "2022-10-17T01:06:47", + "endDate": "2022-10-17T02:49:16", + "unit": "mg\/min·dL", + "value": 1.0556978820387204 + }, + { + "startDate": "2022-10-17T02:49:16", + "endDate": "2022-10-17T02:57:50", + "unit": "mg\/min·dL", + "value": 2.0566560442527893 + } +] diff --git a/LoopTests/Fixtures/meal_detection/missed_meal_counteraction_effect.json b/LoopTests/Fixtures/meal_detection/missed_meal_counteraction_effect.json new file mode 100644 index 0000000000..64b5f498a4 --- /dev/null +++ b/LoopTests/Fixtures/meal_detection/missed_meal_counteraction_effect.json @@ -0,0 +1,122 @@ +[ + { + "startDate": "2022-10-17T21:08:45", + "endDate": "2022-10-17T21:13:45", + "unit": "mg\/min·dL", + "value": 0.8019261605973419 + }, + { + "startDate": "2022-10-17T21:13:45", + "endDate": "2022-10-17T21:18:45", + "unit": "mg\/min·dL", + "value": -0.5784692917036025 + }, + { + "startDate": "2022-10-17T21:18:45", + "endDate": "2022-10-17T21:23:45", + "unit": "mg\/min·dL", + "value": 0.1655312713905142 + }, + { + "startDate": "2022-10-17T21:23:45", + "endDate": "2022-10-17T21:28:45", + "unit": "mg\/min·dL", + "value": 1.7504524257718737 + }, + { + "startDate": "2022-10-17T21:28:45", + "endDate": "2022-10-17T21:33:45", + "unit": "mg\/min·dL", + "value": -0.0922608525680516 + }, + { + "startDate": "2022-10-17T21:33:45", + "endDate": "2022-10-17T21:38:45", + "unit": "mg\/min·dL", + "value": -0.3598634421205699 + }, + { + "startDate": "2022-10-17T21:38:45", + "endDate": "2022-10-17T21:54:19", + "unit": "mg\/min·dL", + "value": 0.8027570693463704 + }, + { + "startDate": "2022-10-17T21:54:19", + "endDate": "2022-10-17T22:12:04", + "unit": "mg\/min·dL", + "value": 1.4477572210086778 + }, + { + "startDate": "2022-10-17T22:12:04", + "endDate": "2022-10-17T22:18:45", + "unit": "mg\/min·dL", + "value": 1.4975396644708778 + }, + { + "startDate": "2022-10-17T22:18:45", + "endDate": "2022-10-17T22:28:45", + "unit": "mg\/min·dL", + "value": 1.5245986218389043 + }, + { + "startDate": "2022-10-17T22:28:45", + "endDate": "2022-10-17T22:33:45", + "unit": "mg\/min·dL", + "value": 2.3929007506455973 + }, + { + "startDate": "2022-10-17T22:33:45", + "endDate": "2022-10-17T22:38:45", + "unit": "mg\/min·dL", + "value": 2.2706182546903664 + }, + { + "startDate": "2022-10-17T22:38:45", + "endDate": "2022-10-17T22:43:45", + "unit": "mg\/min·dL", + "value": 1.7258552314883575 + }, + { + "startDate": "2022-10-17T22:43:45", + "endDate": "2022-10-17T22:48:45", + "unit": "mg\/min·dL", + "value": 2.760986190856003 + }, + { + "startDate": "2022-10-17T22:48:45", + "endDate": "2022-10-17T22:53:45", + "unit": "mg\/min·dL", + "value": 2.578233617155381 + }, + { + "startDate": "2022-10-17T22:53:45", + "endDate": "2022-10-17T22:58:45", + "unit": "mg\/min·dL", + "value": 0.7795720392241906 + }, + { + "startDate": "2022-10-17T22:58:45", + "endDate": "2022-10-17T23:03:45", + "unit": "mg\/min·dL", + "value": 2.766911269858242 + }, + { + "startDate": "2022-10-17T23:03:45", + "endDate": "2022-10-17T23:18:42", + "unit": "mg\/min·dL", + "value": 1.9079807396410984 + }, + { + "startDate": "2022-10-17T23:18:42", + "endDate": "2022-10-17T23:23:45", + "unit": "mg\/min·dL", + "value": 2.5862132855399116 + }, + { + "startDate": "2022-10-17T23:23:45", + "endDate": "2022-10-17T23:28:45", + "unit": "mg\/min·dL", + "value": 1.346722448222869 + } +] diff --git a/LoopTests/Fixtures/meal_detection/needs_clamping_counteraction_effect.json b/LoopTests/Fixtures/meal_detection/needs_clamping_counteraction_effect.json new file mode 100644 index 0000000000..44ab9719b6 --- /dev/null +++ b/LoopTests/Fixtures/meal_detection/needs_clamping_counteraction_effect.json @@ -0,0 +1,14 @@ +[ + { + "startDate": "2022-10-16T01:06:47", + "endDate": "2022-10-17T02:49:16", + "unit": "mg\/min·dL", + "value": 0.5556978820387204 + }, + { + "startDate": "2022-10-17T02:49:16", + "endDate": "2022-10-20T02:57:50", + "unit": "mg\/min·dL", + "value": 0.0566560442527893 + } +] diff --git a/LoopTests/Fixtures/meal_detection/noisy_cgm_counteraction_effect.json b/LoopTests/Fixtures/meal_detection/noisy_cgm_counteraction_effect.json new file mode 100644 index 0000000000..63cb6285f0 --- /dev/null +++ b/LoopTests/Fixtures/meal_detection/noisy_cgm_counteraction_effect.json @@ -0,0 +1,386 @@ +[ + { + "startDate": "2022-10-18T20:43:08", + "endDate": "2022-10-18T20:50:42", + "unit": "mg\/min·dL", + "value": 2.1413880378038854 + }, + { + "startDate": "2022-10-18T20:50:42", + "endDate": "2022-10-18T20:58:27", + "unit": "mg\/min·dL", + "value": 2.4011098101277946 + }, + { + "startDate": "2022-10-18T20:58:27", + "endDate": "2022-10-18T21:14:25", + "unit": "mg\/min·dL", + "value": 2.057214771814263 + }, + { + "startDate": "2022-10-18T21:14:25", + "endDate": "2022-10-18T21:22:05", + "unit": "mg\/min·dL", + "value": 1.991425926715544 + }, + { + "startDate": "2022-10-18T21:22:05", + "endDate": "2022-10-18T21:42:38", + "unit": "mg\/min·dL", + "value": 2.0051308533580032 + }, + { + "startDate": "2022-10-18T21:42:38", + "endDate": "2022-10-18T22:43:11", + "unit": "mg\/min·dL", + "value": 2.180566858455272 + }, + { + "startDate": "2022-10-18T22:43:11", + "endDate": "2022-10-18T23:13:29", + "unit": "mg\/min·dL", + "value": 1.9197677207835058 + }, + { + "startDate": "2022-10-18T23:13:29", + "endDate": "2022-10-18T23:23:44", + "unit": "mg\/min·dL", + "value": 1.6582944320917057 + }, + { + "startDate": "2022-10-18T23:23:44", + "endDate": "2022-10-18T23:31:29", + "unit": "mg\/min·dL", + "value": 2.9251517652457917 + }, + { + "startDate": "2022-10-18T23:31:29", + "endDate": "2022-10-18T23:39:02", + "unit": "mg\/min·dL", + "value": 0.16546279064227673 + }, + { + "startDate": "2022-10-18T23:39:02", + "endDate": "2022-10-18T23:46:51", + "unit": "mg\/min·dL", + "value": 3.5246556156903477 + }, + { + "startDate": "2022-10-18T23:46:51", + "endDate": "2022-10-19T00:01:55", + "unit": "mg\/min·dL", + "value": 1.6837264254514583 + }, + { + "startDate": "2022-10-19T00:01:55", + "endDate": "2022-10-19T00:09:24", + "unit": "mg\/min·dL", + "value": 0.6255424707941111 + }, + { + "startDate": "2022-10-19T00:09:24", + "endDate": "2022-10-19T00:17:11", + "unit": "mg\/min·dL", + "value": 3.5624118067540476 + }, + { + "startDate": "2022-10-19T00:17:11", + "endDate": "2022-10-19T00:26:34", + "unit": "mg\/min·dL", + "value": 3.4181695387179754 + }, + { + "startDate": "2022-10-19T00:26:34", + "endDate": "2022-10-19T00:34:20", + "unit": "mg\/min·dL", + "value": -0.3706991177681455 + }, + { + "startDate": "2022-10-19T00:34:20", + "endDate": "2022-10-19T00:42:23", + "unit": "mg\/min·dL", + "value": 2.408865149934943 + }, + { + "startDate": "2022-10-19T00:42:23", + "endDate": "2022-10-19T00:50:58", + "unit": "mg\/min·dL", + "value": 1.5845764542225527 + }, + { + "startDate": "2022-10-19T00:50:58", + "endDate": "2022-10-19T01:07:52", + "unit": "mg\/min·dL", + "value": 2.0292268456298372 + }, + { + "startDate": "2022-10-19T01:07:52", + "endDate": "2022-10-19T01:15:47", + "unit": "mg\/min·dL", + "value": 2.402478504248885 + }, + { + "startDate": "2022-10-19T01:15:47", + "endDate": "2022-10-19T01:23:21", + "unit": "mg\/min·dL", + "value": 1.9234931834453135 + }, + { + "startDate": "2022-10-19T01:23:21", + "endDate": "2022-10-19T01:31:11", + "unit": "mg\/min·dL", + "value": 2.557351249850377 + }, + { + "startDate": "2022-10-19T01:31:11", + "endDate": "2022-10-19T01:38:53", + "unit": "mg\/min·dL", + "value": 1.8865201976400663 + }, + { + "startDate": "2022-10-19T01:38:53", + "endDate": "2022-10-19T01:46:38", + "unit": "mg\/min·dL", + "value": 2.188515989682273 + }, + { + "startDate": "2022-10-19T01:46:38", + "endDate": "2022-10-19T01:55:13", + "unit": "mg\/min·dL", + "value": 2.446288202801156 + }, + { + "startDate": "2022-10-19T01:55:13", + "endDate": "2022-10-19T02:02:55", + "unit": "mg\/min·dL", + "value": 1.8874025096295566 + }, + { + "startDate": "2022-10-19T02:02:55", + "endDate": "2022-10-19T03:03:30", + "unit": "mg\/min·dL", + "value": 1.9901048084934858 + }, + { + "startDate": "2022-10-19T03:03:30", + "endDate": "2022-10-19T03:44:04", + "unit": "mg\/min·dL", + "value": 1.7104947217909385 + }, + { + "startDate": "2022-10-19T03:44:04", + "endDate": "2022-10-19T04:24:37", + "unit": "mg\/min·dL", + "value": 2.0313009513772373 + }, + { + "startDate": "2022-10-19T04:24:37", + "endDate": "2022-10-19T14:58:20", + "unit": "mg\/min·dL", + "value": 0.6779229200420821 + }, + { + "startDate": "2022-10-19T17:47:43", + "endDate": "2022-10-19T17:52:43", + "unit": "mg\/min·dL", + "value": -1.764725420239631 + }, + { + "startDate": "2022-10-19T17:52:43", + "endDate": "2022-10-19T18:02:43", + "unit": "mg\/min·dL", + "value": -0.2854672410290561 + }, + { + "startDate": "2022-10-19T18:02:43", + "endDate": "2022-10-19T18:07:43", + "unit": "mg\/min·dL", + "value": 1.423225171907336 + }, + { + "startDate": "2022-10-19T18:07:43", + "endDate": "2022-10-19T18:12:43", + "unit": "mg\/min·dL", + "value": -3.18226150417708 + }, + { + "startDate": "2022-10-19T18:12:43", + "endDate": "2022-10-19T18:17:43", + "unit": "mg\/min·dL", + "value": -4.787369366471273 + }, + { + "startDate": "2022-10-19T18:17:43", + "endDate": "2022-10-19T18:22:43", + "unit": "mg\/min·dL", + "value": 3.6083669362007353 + }, + { + "startDate": "2022-10-19T18:22:43", + "endDate": "2022-10-19T18:27:43", + "unit": "mg\/min·dL", + "value": -0.3949565747393592 + }, + { + "startDate": "2022-10-19T18:27:43", + "endDate": "2022-10-19T18:32:43", + "unit": "mg\/min·dL", + "value": -0.3973978843060308 + }, + { + "startDate": "2022-10-19T18:32:43", + "endDate": "2022-10-19T18:37:43", + "unit": "mg\/min·dL", + "value": 2.6009873496056284 + }, + { + "startDate": "2022-10-19T18:37:43", + "endDate": "2022-10-19T18:42:43", + "unit": "mg\/min·dL", + "value": -4.199854242276523 + }, + { + "startDate": "2022-10-19T18:42:43", + "endDate": "2022-10-19T18:47:43", + "unit": "mg\/min·dL", + "value": 3.199988677140936 + }, + { + "startDate": "2022-10-19T18:47:43", + "endDate": "2022-10-19T18:52:43", + "unit": "mg\/min·dL", + "value": 1.7999880977313012 + }, + { + "startDate": "2022-10-19T18:52:43", + "endDate": "2022-10-19T18:57:43", + "unit": "mg\/min·dL", + "value": -0.8000123609487502 + }, + { + "startDate": "2022-10-19T18:57:43", + "endDate": "2022-10-19T19:02:43", + "unit": "mg\/min·dL", + "value": -2.400012711019661 + }, + { + "startDate": "2022-10-19T19:02:43", + "endDate": "2022-10-19T19:07:43", + "unit": "mg\/min·dL", + "value": 5.199987036372721 + }, + { + "startDate": "2022-10-19T19:07:43", + "endDate": "2022-10-19T19:12:43", + "unit": "mg\/min·dL", + "value": -4.60001312901278 + }, + { + "startDate": "2022-10-19T19:12:43", + "endDate": "2022-10-19T19:22:43", + "unit": "mg\/min·dL", + "value": 2.299993391711052 + }, + { + "startDate": "2022-10-19T19:22:43", + "endDate": "2022-10-19T19:27:43", + "unit": "mg\/min·dL", + "value": -1.000013234945743 + }, + { + "startDate": "2022-10-19T19:27:43", + "endDate": "2022-10-19T19:32:43", + "unit": "mg\/min·dL", + "value": -2.600013192017644 + }, + { + "startDate": "2022-10-19T19:32:43", + "endDate": "2022-10-19T19:37:43", + "unit": "mg\/min·dL", + "value": 2.3999869049740195 + }, + { + "startDate": "2022-10-19T19:37:43", + "endDate": "2022-10-19T19:42:43", + "unit": "mg\/min·dL", + "value": -2.2000129505836123 + }, + { + "startDate": "2022-10-19T19:42:43", + "endDate": "2022-10-19T19:47:43", + "unit": "mg\/min·dL", + "value": 2.9999872352701686 + }, + { + "startDate": "2022-10-19T19:47:43", + "endDate": "2022-10-19T19:52:43", + "unit": "mg\/min·dL", + "value": -1.8000125429732121 + }, + { + "startDate": "2022-10-19T19:52:43", + "endDate": "2022-10-19T19:57:43", + "unit": "mg\/min·dL", + "value": -1.000012290331557 + }, + { + "startDate": "2022-10-19T19:57:43", + "endDate": "2022-10-19T20:02:43", + "unit": "mg\/min·dL", + "value": 0.1999879886309827 + }, + { + "startDate": "2022-10-19T20:02:43", + "endDate": "2022-10-19T20:07:43", + "unit": "mg\/min·dL", + "value": -0.8000117102307285 + }, + { + "startDate": "2022-10-19T20:07:43", + "endDate": "2022-10-19T20:12:43", + "unit": "mg\/min·dL", + "value": 2.3999886093249985 + }, + { + "startDate": "2022-10-19T20:12:43", + "endDate": "2022-10-19T20:17:43", + "unit": "mg\/min·dL", + "value": -2.2000110561032553 + }, + { + "startDate": "2022-10-19T20:17:43", + "endDate": "2022-10-19T20:22:43", + "unit": "mg\/min·dL", + "value": 0.39998929041208836 + }, + { + "startDate": "2022-10-19T20:22:43", + "endDate": "2022-10-19T20:27:43", + "unit": "mg\/min·dL", + "value": 2.19998964610175 + }, + { + "startDate": "2022-10-19T20:27:43", + "endDate": "2022-10-19T20:32:43", + "unit": "mg\/min·dL", + "value": -1.2000099915245013 + }, + { + "startDate": "2022-10-19T20:32:43", + "endDate": "2022-10-19T20:37:43", + "unit": "mg\/min·dL", + "value": 1.399990375299808 + }, + { + "startDate": "2022-10-19T20:37:43", + "endDate": "2022-10-19T20:42:43", + "unit": "mg\/min·dL", + "value": -0.8000092554229123 + }, + { + "startDate": "2022-10-19T20:42:43", + "endDate": "2022-10-19T20:47:43", + "unit": "mg\/min·dL", + "value": 3.799991114526437 + } +] diff --git a/LoopTests/Fixtures/meal_detection/realistic_report_counteraction_effect.json b/LoopTests/Fixtures/meal_detection/realistic_report_counteraction_effect.json new file mode 100644 index 0000000000..c8e82f11f5 --- /dev/null +++ b/LoopTests/Fixtures/meal_detection/realistic_report_counteraction_effect.json @@ -0,0 +1,1724 @@ +[ + { + "startDate": "2022-10-18T21:40:00", + "endDate": "2022-10-18T21:45:00", + "unit": "mg\/min·dL", + "value": 0.9043847043689791 + }, + { + "startDate": "2022-10-18T21:45:00", + "endDate": "2022-10-18T21:50:01", + "unit": "mg\/min·dL", + "value": 0.8701737681583791 + }, + { + "startDate": "2022-10-18T21:50:01", + "endDate": "2022-10-18T21:55:01", + "unit": "mg\/min·dL", + "value": 0.44559430294201047 + }, + { + "startDate": "2022-10-18T21:55:01", + "endDate": "2022-10-18T22:00:00", + "unit": "mg\/min·dL", + "value": 0.41686359006411966 + }, + { + "startDate": "2022-10-18T22:00:00", + "endDate": "2022-10-18T22:05:01", + "unit": "mg\/min·dL", + "value": 0.38648385789866685 + }, + { + "startDate": "2022-10-18T22:05:01", + "endDate": "2022-10-18T22:10:01", + "unit": "mg\/min·dL", + "value": 0.3578544271635854 + }, + { + "startDate": "2022-10-18T22:10:01", + "endDate": "2022-10-18T22:15:01", + "unit": "mg\/min·dL", + "value": 0.32931115774406733 + }, + { + "startDate": "2022-10-18T22:15:01", + "endDate": "2022-10-18T22:20:01", + "unit": "mg\/min·dL", + "value": 0.10057626183015964 + }, + { + "startDate": "2022-10-18T22:20:01", + "endDate": "2022-10-18T22:25:00", + "unit": "mg\/min·dL", + "value": 0.4729780858945708 + }, + { + "startDate": "2022-10-18T22:25:00", + "endDate": "2022-10-18T22:30:00", + "unit": "mg\/min·dL", + "value": -0.3546781456753047 + }, + { + "startDate": "2022-10-18T22:30:00", + "endDate": "2022-10-18T22:35:01", + "unit": "mg\/min·dL", + "value": -0.18131076193035978 + }, + { + "startDate": "2022-10-18T22:35:01", + "endDate": "2022-10-18T22:40:00", + "unit": "mg\/min·dL", + "value": -1.010247144263618 + }, + { + "startDate": "2022-10-18T22:40:00", + "endDate": "2022-10-18T22:45:00", + "unit": "mg\/min·dL", + "value": -0.3668240075057755 + }, + { + "startDate": "2022-10-18T22:45:00", + "endDate": "2022-10-18T22:50:01", + "unit": "mg\/min·dL", + "value": 1.559394854618121 + }, + { + "startDate": "2022-10-18T22:50:01", + "endDate": "2022-10-18T22:55:00", + "unit": "mg\/min·dL", + "value": 2.071374628866257 + }, + { + "startDate": "2022-10-18T22:55:00", + "endDate": "2022-10-18T23:00:01", + "unit": "mg\/min·dL", + "value": 1.5603433296934301 + }, + { + "startDate": "2022-10-18T23:00:01", + "endDate": "2022-10-18T23:05:00", + "unit": "mg\/min·dL", + "value": 1.4440744498686167 + }, + { + "startDate": "2022-10-18T23:05:00", + "endDate": "2022-10-18T23:10:00", + "unit": "mg\/min·dL", + "value": 1.5156883860813217 + }, + { + "startDate": "2022-10-18T23:10:00", + "endDate": "2022-10-18T23:15:00", + "unit": "mg\/min·dL", + "value": 1.7727836419735754 + }, + { + "startDate": "2022-10-18T23:15:00", + "endDate": "2022-10-18T23:20:01", + "unit": "mg\/min·dL", + "value": 1.6191783680941592 + }, + { + "startDate": "2022-10-18T23:20:01", + "endDate": "2022-10-18T23:25:00", + "unit": "mg\/min·dL", + "value": 1.2614262583288534 + }, + { + "startDate": "2022-10-18T23:25:00", + "endDate": "2022-10-18T23:30:00", + "unit": "mg\/min·dL", + "value": 0.28656922575226085 + }, + { + "startDate": "2022-10-18T23:30:00", + "endDate": "2022-10-18T23:35:01", + "unit": "mg\/min·dL", + "value": 0.5040272887218451 + }, + { + "startDate": "2022-10-18T23:35:01", + "endDate": "2022-10-18T23:40:01", + "unit": "mg\/min·dL", + "value": -0.88797938985592 + }, + { + "startDate": "2022-10-18T23:40:01", + "endDate": "2022-10-18T23:45:00", + "unit": "mg\/min·dL", + "value": 0.3102981695282373 + }, + { + "startDate": "2022-10-18T23:45:00", + "endDate": "2022-10-18T23:50:00", + "unit": "mg\/min·dL", + "value": 0.2990145023827218 + }, + { + "startDate": "2022-10-18T23:50:00", + "endDate": "2022-10-18T23:55:00", + "unit": "mg\/min·dL", + "value": 0.2813549886870839 + }, + { + "startDate": "2022-10-18T23:55:00", + "endDate": "2022-10-19T00:00:00", + "unit": "mg\/min·dL", + "value": 0.25803373961516457 + }, + { + "startDate": "2022-10-19T00:00:00", + "endDate": "2022-10-19T00:05:00", + "unit": "mg\/min·dL", + "value": 0.029882256677400014 + }, + { + "startDate": "2022-10-19T00:05:00", + "endDate": "2022-10-19T00:10:00", + "unit": "mg\/min·dL", + "value": -0.0018539363122007967 + }, + { + "startDate": "2022-10-19T00:10:00", + "endDate": "2022-10-19T00:15:01", + "unit": "mg\/min·dL", + "value": -0.4362035671247494 + }, + { + "startDate": "2022-10-19T00:15:01", + "endDate": "2022-10-19T00:20:00", + "unit": "mg\/min·dL", + "value": 0.12697827245171217 + }, + { + "startDate": "2022-10-19T00:20:00", + "endDate": "2022-10-19T00:25:01", + "unit": "mg\/min·dL", + "value": -0.1137114895201975 + }, + { + "startDate": "2022-10-19T00:25:01", + "endDate": "2022-10-19T00:30:00", + "unit": "mg\/min·dL", + "value": 0.8404650492430689 + }, + { + "startDate": "2022-10-19T00:30:00", + "endDate": "2022-10-19T00:35:01", + "unit": "mg\/min·dL", + "value": -0.011742501835059939 + }, + { + "startDate": "2022-10-19T00:35:01", + "endDate": "2022-10-19T00:40:00", + "unit": "mg\/min·dL", + "value": 0.5345114838195776 + }, + { + "startDate": "2022-10-19T00:40:00", + "endDate": "2022-10-19T00:45:00", + "unit": "mg\/min·dL", + "value": 0.47586430649907935 + }, + { + "startDate": "2022-10-19T00:45:00", + "endDate": "2022-10-19T00:50:00", + "unit": "mg\/min·dL", + "value": 0.2178093373305446 + }, + { + "startDate": "2022-10-19T00:50:00", + "endDate": "2022-10-19T00:55:00", + "unit": "mg\/min·dL", + "value": 0.5578754706878531 + }, + { + "startDate": "2022-10-19T00:55:00", + "endDate": "2022-10-19T01:00:00", + "unit": "mg\/min·dL", + "value": -0.9011291440087709 + }, + { + "startDate": "2022-10-19T01:00:00", + "endDate": "2022-10-19T01:05:00", + "unit": "mg\/min·dL", + "value": 0.03906347621778584 + }, + { + "startDate": "2022-10-19T01:05:00", + "endDate": "2022-10-19T01:10:00", + "unit": "mg\/min·dL", + "value": -0.02020473697510492 + }, + { + "startDate": "2022-10-19T01:10:00", + "endDate": "2022-10-19T01:15:00", + "unit": "mg\/min·dL", + "value": -0.07837275714453532 + }, + { + "startDate": "2022-10-19T01:15:00", + "endDate": "2022-10-19T01:20:00", + "unit": "mg\/min·dL", + "value": 1.4649496777138962 + }, + { + "startDate": "2022-10-19T01:20:00", + "endDate": "2022-10-19T01:25:01", + "unit": "mg\/min·dL", + "value": 3.401845866546212 + }, + { + "startDate": "2022-10-19T01:25:01", + "endDate": "2022-10-19T01:30:01", + "unit": "mg\/min·dL", + "value": 3.3542079394357533 + }, + { + "startDate": "2022-10-19T01:30:01", + "endDate": "2022-10-19T01:35:01", + "unit": "mg\/min·dL", + "value": 2.107098415709067 + }, + { + "startDate": "2022-10-19T01:35:01", + "endDate": "2022-10-19T01:40:00", + "unit": "mg\/min·dL", + "value": 0.4658451108604793 + }, + { + "startDate": "2022-10-19T01:40:00", + "endDate": "2022-10-19T01:45:01", + "unit": "mg\/min·dL", + "value": -0.1632488253614695 + }, + { + "startDate": "2022-10-19T01:45:01", + "endDate": "2022-10-19T01:50:01", + "unit": "mg\/min·dL", + "value": -0.5885867519773967 + }, + { + "startDate": "2022-10-19T01:50:01", + "endDate": "2022-10-19T01:55:00", + "unit": "mg\/min·dL", + "value": -1.0062735825086297 + }, + { + "startDate": "2022-10-19T01:55:00", + "endDate": "2022-10-19T02:00:00", + "unit": "mg\/min·dL", + "value": -1.2185933300337954 + }, + { + "startDate": "2022-10-19T02:00:00", + "endDate": "2022-10-19T02:05:01", + "unit": "mg\/min·dL", + "value": -0.8326700677766216 + }, + { + "startDate": "2022-10-19T02:05:01", + "endDate": "2022-10-19T02:10:01", + "unit": "mg\/min·dL", + "value": -2.84257051980203 + }, + { + "startDate": "2022-10-19T02:10:01", + "endDate": "2022-10-19T02:15:00", + "unit": "mg\/min·dL", + "value": -0.8562035248873597 + }, + { + "startDate": "2022-10-19T02:15:00", + "endDate": "2022-10-19T02:20:01", + "unit": "mg\/min·dL", + "value": -0.26526876046429276 + }, + { + "startDate": "2022-10-19T02:20:01", + "endDate": "2022-10-19T02:25:01", + "unit": "mg\/min·dL", + "value": -0.27929377419252777 + }, + { + "startDate": "2022-10-19T02:25:01", + "endDate": "2022-10-19T02:30:00", + "unit": "mg\/min·dL", + "value": -0.09615878507465565 + }, + { + "startDate": "2022-10-19T02:30:00", + "endDate": "2022-10-19T02:35:00", + "unit": "mg\/min·dL", + "value": 0.2853641733897771 + }, + { + "startDate": "2022-10-19T02:35:00", + "endDate": "2022-10-19T02:40:01", + "unit": "mg\/min·dL", + "value": 2.2630294082591282 + }, + { + "startDate": "2022-10-19T02:40:01", + "endDate": "2022-10-19T02:45:00", + "unit": "mg\/min·dL", + "value": 2.935184435842075 + }, + { + "startDate": "2022-10-19T02:45:00", + "endDate": "2022-10-19T02:50:01", + "unit": "mg\/min·dL", + "value": 3.4054208562036465 + }, + { + "startDate": "2022-10-19T02:50:01", + "endDate": "2022-10-19T02:55:01", + "unit": "mg\/min·dL", + "value": 2.7032681066820055 + }, + { + "startDate": "2022-10-19T02:55:01", + "endDate": "2022-10-19T03:00:00", + "unit": "mg\/min·dL", + "value": 2.80018879273112 + }, + { + "startDate": "2022-10-19T03:00:00", + "endDate": "2022-10-19T03:05:01", + "unit": "mg\/min·dL", + "value": 2.4965292339587837 + }, + { + "startDate": "2022-10-19T03:05:01", + "endDate": "2022-10-19T03:10:01", + "unit": "mg\/min·dL", + "value": 1.6113117856204644 + }, + { + "startDate": "2022-10-19T03:10:01", + "endDate": "2022-10-19T03:15:01", + "unit": "mg\/min·dL", + "value": 1.1148901778931035 + }, + { + "startDate": "2022-10-19T03:15:01", + "endDate": "2022-10-19T03:25:01", + "unit": "mg\/min·dL", + "value": 1.2465705652221148 + }, + { + "startDate": "2022-10-19T03:25:01", + "endDate": "2022-10-19T03:30:00", + "unit": "mg\/min·dL", + "value": 0.5552565109650426 + }, + { + "startDate": "2022-10-19T03:30:00", + "endDate": "2022-10-19T03:35:01", + "unit": "mg\/min·dL", + "value": 0.4093372449598604 + }, + { + "startDate": "2022-10-19T03:35:01", + "endDate": "2022-10-19T03:40:01", + "unit": "mg\/min·dL", + "value": 0.6526956800529764 + }, + { + "startDate": "2022-10-19T03:40:01", + "endDate": "2022-10-19T03:45:00", + "unit": "mg\/min·dL", + "value": 0.2837328512839709 + }, + { + "startDate": "2022-10-19T03:45:00", + "endDate": "2022-10-19T03:50:01", + "unit": "mg\/min·dL", + "value": -0.2965329523104659 + }, + { + "startDate": "2022-10-19T03:50:01", + "endDate": "2022-10-19T03:55:01", + "unit": "mg\/min·dL", + "value": 0.11264296048927881 + }, + { + "startDate": "2022-10-19T03:55:01", + "endDate": "2022-10-19T04:00:01", + "unit": "mg\/min·dL", + "value": 0.11365480733176563 + }, + { + "startDate": "2022-10-19T04:00:01", + "endDate": "2022-10-19T04:05:01", + "unit": "mg\/min·dL", + "value": 0.7079504519365847 + }, + { + "startDate": "2022-10-19T04:05:01", + "endDate": "2022-10-19T04:10:00", + "unit": "mg\/min·dL", + "value": 0.29539031027196594 + }, + { + "startDate": "2022-10-19T04:10:00", + "endDate": "2022-10-19T04:15:00", + "unit": "mg\/min·dL", + "value": 0.4750368523506627 + }, + { + "startDate": "2022-10-19T04:15:00", + "endDate": "2022-10-19T04:20:01", + "unit": "mg\/min·dL", + "value": 0.2516481493765345 + }, + { + "startDate": "2022-10-19T04:20:01", + "endDate": "2022-10-19T04:25:00", + "unit": "mg\/min·dL", + "value": 0.42687884270523624 + }, + { + "startDate": "2022-10-19T04:25:00", + "endDate": "2022-10-19T04:30:01", + "unit": "mg\/min·dL", + "value": 0.1970294938484129 + }, + { + "startDate": "2022-10-19T04:30:01", + "endDate": "2022-10-19T04:35:01", + "unit": "mg\/min·dL", + "value": -0.6325663853295713 + }, + { + "startDate": "2022-10-19T04:35:01", + "endDate": "2022-10-19T04:40:00", + "unit": "mg\/min·dL", + "value": -1.6671946453873905 + }, + { + "startDate": "2022-10-19T04:40:00", + "endDate": "2022-10-19T04:45:01", + "unit": "mg\/min·dL", + "value": -1.095982136517308 + }, + { + "startDate": "2022-10-19T04:45:01", + "endDate": "2022-10-19T04:50:00", + "unit": "mg\/min·dL", + "value": -0.5411661721419859 + }, + { + "startDate": "2022-10-19T04:50:00", + "endDate": "2022-10-19T04:55:00", + "unit": "mg\/min·dL", + "value": 0.028358336047663885 + }, + { + "startDate": "2022-10-19T04:55:00", + "endDate": "2022-10-19T05:00:01", + "unit": "mg\/min·dL", + "value": -0.20955099234535207 + }, + { + "startDate": "2022-10-19T05:00:01", + "endDate": "2022-10-19T05:05:01", + "unit": "mg\/min·dL", + "value": 0.30207612513942395 + }, + { + "startDate": "2022-10-19T05:05:01", + "endDate": "2022-10-19T05:10:00", + "unit": "mg\/min·dL", + "value": 0.04103782125221336 + }, + { + "startDate": "2022-10-19T05:10:00", + "endDate": "2022-10-19T05:15:01", + "unit": "mg\/min·dL", + "value": 0.3809787987795194 + }, + { + "startDate": "2022-10-19T05:15:01", + "endDate": "2022-10-19T05:20:01", + "unit": "mg\/min·dL", + "value": -0.0772329850138329 + }, + { + "startDate": "2022-10-19T05:20:01", + "endDate": "2022-10-19T05:25:01", + "unit": "mg\/min·dL", + "value": 0.2837794247411642 + }, + { + "startDate": "2022-10-19T05:25:01", + "endDate": "2022-10-19T05:30:00", + "unit": "mg\/min·dL", + "value": 0.4091244566696956 + }, + { + "startDate": "2022-10-19T05:30:00", + "endDate": "2022-10-19T05:35:00", + "unit": "mg\/min·dL", + "value": -0.040777547570781135 + }, + { + "startDate": "2022-10-19T05:35:00", + "endDate": "2022-10-19T05:40:01", + "unit": "mg\/min·dL", + "value": -0.28963383865548703 + }, + { + "startDate": "2022-10-19T05:40:01", + "endDate": "2022-10-19T05:45:00", + "unit": "mg\/min·dL", + "value": 0.8815079785477252 + }, + { + "startDate": "2022-10-19T05:45:00", + "endDate": "2022-10-19T05:50:00", + "unit": "mg\/min·dL", + "value": 0.4431363092446005 + }, + { + "startDate": "2022-10-19T05:50:00", + "endDate": "2022-10-19T05:55:00", + "unit": "mg\/min·dL", + "value": 0.21446766128625064 + }, + { + "startDate": "2022-10-19T05:55:00", + "endDate": "2022-10-19T06:00:01", + "unit": "mg\/min·dL", + "value": 0.3745668250547948 + }, + { + "startDate": "2022-10-19T06:00:01", + "endDate": "2022-10-19T06:05:01", + "unit": "mg\/min·dL", + "value": 0.34009354076149223 + }, + { + "startDate": "2022-10-19T06:05:01", + "endDate": "2022-10-19T06:10:01", + "unit": "mg\/min·dL", + "value": 0.909838642145608 + }, + { + "startDate": "2022-10-19T06:10:01", + "endDate": "2022-10-19T06:15:01", + "unit": "mg\/min·dL", + "value": 0.6925767053834189 + }, + { + "startDate": "2022-10-19T06:15:01", + "endDate": "2022-10-19T06:20:01", + "unit": "mg\/min·dL", + "value": 0.48208611056098555 + }, + { + "startDate": "2022-10-19T06:20:01", + "endDate": "2022-10-19T06:25:00", + "unit": "mg\/min·dL", + "value": 0.2831925640399337 + }, + { + "startDate": "2022-10-19T06:25:00", + "endDate": "2022-10-19T06:30:01", + "unit": "mg\/min·dL", + "value": 0.29029277640990603 + }, + { + "startDate": "2022-10-19T06:30:01", + "endDate": "2022-10-19T06:35:01", + "unit": "mg\/min·dL", + "value": -0.2977661275897406 + }, + { + "startDate": "2022-10-19T06:35:01", + "endDate": "2022-10-19T06:40:01", + "unit": "mg\/min·dL", + "value": -1.4835473972248248 + }, + { + "startDate": "2022-10-19T06:40:01", + "endDate": "2022-10-19T06:45:01", + "unit": "mg\/min·dL", + "value": -0.06684185693201271 + }, + { + "startDate": "2022-10-19T06:45:01", + "endDate": "2022-10-19T06:50:01", + "unit": "mg\/min·dL", + "value": -0.05240734057580225 + }, + { + "startDate": "2022-10-19T06:50:01", + "endDate": "2022-10-19T06:55:00", + "unit": "mg\/min·dL", + "value": -0.24556517930204355 + }, + { + "startDate": "2022-10-19T06:55:00", + "endDate": "2022-10-19T07:00:00", + "unit": "mg\/min·dL", + "value": -0.44211478120218145 + }, + { + "startDate": "2022-10-19T07:00:00", + "endDate": "2022-10-19T07:05:01", + "unit": "mg\/min·dL", + "value": -1.03857881100502 + }, + { + "startDate": "2022-10-19T07:05:01", + "endDate": "2022-10-19T07:10:01", + "unit": "mg\/min·dL", + "value": -0.43890261619044063 + }, + { + "startDate": "2022-10-19T07:10:01", + "endDate": "2022-10-19T07:15:01", + "unit": "mg\/min·dL", + "value": -0.6439573640191639 + }, + { + "startDate": "2022-10-19T07:15:01", + "endDate": "2022-10-19T07:20:01", + "unit": "mg\/min·dL", + "value": -0.4532385550898397 + }, + { + "startDate": "2022-10-19T07:20:01", + "endDate": "2022-10-19T07:25:01", + "unit": "mg\/min·dL", + "value": -0.8660471979684273 + }, + { + "startDate": "2022-10-19T07:25:01", + "endDate": "2022-10-19T07:30:01", + "unit": "mg\/min·dL", + "value": -0.281574959738387 + }, + { + "startDate": "2022-10-19T07:30:01", + "endDate": "2022-10-19T07:35:01", + "unit": "mg\/min·dL", + "value": 0.30063941285933987 + }, + { + "startDate": "2022-10-19T07:35:01", + "endDate": "2022-10-19T07:40:01", + "unit": "mg\/min·dL", + "value": -0.3188112289597015 + }, + { + "startDate": "2022-10-19T07:40:01", + "endDate": "2022-10-19T07:45:00", + "unit": "mg\/min·dL", + "value": 0.062436338615094615 + }, + { + "startDate": "2022-10-19T07:45:00", + "endDate": "2022-10-19T07:50:00", + "unit": "mg\/min·dL", + "value": 0.4478691259722767 + }, + { + "startDate": "2022-10-19T07:50:00", + "endDate": "2022-10-19T07:55:01", + "unit": "mg\/min·dL", + "value": 0.8352780727089159 + }, + { + "startDate": "2022-10-19T07:55:01", + "endDate": "2022-10-19T08:00:01", + "unit": "mg\/min·dL", + "value": 0.22900532179424257 + }, + { + "startDate": "2022-10-19T08:00:01", + "endDate": "2022-10-19T08:05:01", + "unit": "mg\/min·dL", + "value": 0.02347733142306274 + }, + { + "startDate": "2022-10-19T08:05:01", + "endDate": "2022-10-19T08:10:01", + "unit": "mg\/min·dL", + "value": -0.7783748292358011 + }, + { + "startDate": "2022-10-19T08:10:01", + "endDate": "2022-10-19T08:15:01", + "unit": "mg\/min·dL", + "value": 0.6272885060509404 + }, + { + "startDate": "2022-10-19T08:15:01", + "endDate": "2022-10-19T08:20:01", + "unit": "mg\/min·dL", + "value": 0.23419734350722396 + }, + { + "startDate": "2022-10-19T08:20:01", + "endDate": "2022-10-19T08:25:00", + "unit": "mg\/min·dL", + "value": 0.2428650510584241 + }, + { + "startDate": "2022-10-19T08:25:00", + "endDate": "2022-10-19T08:30:01", + "unit": "mg\/min·dL", + "value": 0.2524272001329743 + }, + { + "startDate": "2022-10-19T08:30:01", + "endDate": "2022-10-19T08:35:01", + "unit": "mg\/min·dL", + "value": 0.06685058482744398 + }, + { + "startDate": "2022-10-19T08:35:01", + "endDate": "2022-10-19T08:40:01", + "unit": "mg\/min·dL", + "value": -0.11765785383167682 + }, + { + "startDate": "2022-10-19T08:40:01", + "endDate": "2022-10-19T08:45:01", + "unit": "mg\/min·dL", + "value": 0.2974449346156582 + }, + { + "startDate": "2022-10-19T08:45:01", + "endDate": "2022-10-19T08:50:01", + "unit": "mg\/min·dL", + "value": 0.11291581770004194 + }, + { + "startDate": "2022-10-19T08:50:01", + "endDate": "2022-10-19T08:55:01", + "unit": "mg\/min·dL", + "value": -0.07123242642898692 + }, + { + "startDate": "2022-10-19T08:55:01", + "endDate": "2022-10-19T09:00:01", + "unit": "mg\/min·dL", + "value": -0.05448916692972083 + }, + { + "startDate": "2022-10-19T09:00:01", + "endDate": "2022-10-19T09:05:01", + "unit": "mg\/min·dL", + "value": 0.16099146820008903 + }, + { + "startDate": "2022-10-19T09:05:01", + "endDate": "2022-10-19T09:10:01", + "unit": "mg\/min·dL", + "value": 0.17549047688591932 + }, + { + "startDate": "2022-10-19T09:10:01", + "endDate": "2022-10-19T09:15:01", + "unit": "mg\/min·dL", + "value": -0.21178831469440673 + }, + { + "startDate": "2022-10-19T09:15:01", + "endDate": "2022-10-19T09:20:00", + "unit": "mg\/min·dL", + "value": -0.4010107502180188 + }, + { + "startDate": "2022-10-19T09:20:00", + "endDate": "2022-10-19T09:25:01", + "unit": "mg\/min·dL", + "value": -0.38816196596823593 + }, + { + "startDate": "2022-10-19T09:25:01", + "endDate": "2022-10-19T09:30:01", + "unit": "mg\/min·dL", + "value": -0.3803371601566195 + }, + { + "startDate": "2022-10-19T09:30:01", + "endDate": "2022-10-19T09:35:01", + "unit": "mg\/min·dL", + "value": 0.027318177225786312 + }, + { + "startDate": "2022-10-19T09:35:01", + "endDate": "2022-10-19T09:40:01", + "unit": "mg\/min·dL", + "value": 0.23321816158317168 + }, + { + "startDate": "2022-10-19T09:40:01", + "endDate": "2022-10-19T09:45:01", + "unit": "mg\/min·dL", + "value": 0.03823915818460353 + }, + { + "startDate": "2022-10-19T09:45:01", + "endDate": "2022-10-19T09:50:01", + "unit": "mg\/min·dL", + "value": 0.04214613731129099 + }, + { + "startDate": "2022-10-19T09:50:01", + "endDate": "2022-10-19T09:55:01", + "unit": "mg\/min·dL", + "value": -0.3547462209861638 + }, + { + "startDate": "2022-10-19T09:55:01", + "endDate": "2022-10-19T10:00:01", + "unit": "mg\/min·dL", + "value": -0.1528813572718399 + }, + { + "startDate": "2022-10-19T10:00:01", + "endDate": "2022-10-19T10:05:01", + "unit": "mg\/min·dL", + "value": 0.0487369632008895 + }, + { + "startDate": "2022-10-19T10:05:01", + "endDate": "2022-10-19T10:10:01", + "unit": "mg\/min·dL", + "value": -0.15044460943490148 + }, + { + "startDate": "2022-10-19T10:10:01", + "endDate": "2022-10-19T10:15:01", + "unit": "mg\/min·dL", + "value": -0.34944869885912044 + }, + { + "startDate": "2022-10-19T10:15:01", + "endDate": "2022-10-19T10:20:01", + "unit": "mg\/min·dL", + "value": 0.6507861066920333 + }, + { + "startDate": "2022-10-19T10:20:01", + "endDate": "2022-10-19T10:25:01", + "unit": "mg\/min·dL", + "value": 0.24969999327567519 + }, + { + "startDate": "2022-10-19T10:25:01", + "endDate": "2022-10-19T10:30:01", + "unit": "mg\/min·dL", + "value": 0.048794343384953386 + }, + { + "startDate": "2022-10-19T10:30:01", + "endDate": "2022-10-19T10:35:01", + "unit": "mg\/min·dL", + "value": -1.7526382442657054 + }, + { + "startDate": "2022-10-19T10:35:01", + "endDate": "2022-10-19T10:40:01", + "unit": "mg\/min·dL", + "value": -0.3534383576597841 + }, + { + "startDate": "2022-10-19T10:40:01", + "endDate": "2022-10-19T10:45:01", + "unit": "mg\/min·dL", + "value": 0.4455757100573625 + }, + { + "startDate": "2022-10-19T10:45:01", + "endDate": "2022-10-19T10:50:01", + "unit": "mg\/min·dL", + "value": -0.7586169858263023 + }, + { + "startDate": "2022-10-19T10:50:01", + "endDate": "2022-10-19T10:55:01", + "unit": "mg\/min·dL", + "value": -0.3648598606818268 + }, + { + "startDate": "2022-10-19T10:55:01", + "endDate": "2022-10-19T11:00:01", + "unit": "mg\/min·dL", + "value": 0.42939657423429517 + }, + { + "startDate": "2022-10-19T11:00:01", + "endDate": "2022-10-19T11:05:00", + "unit": "mg\/min·dL", + "value": 0.42225019302974154 + }, + { + "startDate": "2022-10-19T11:05:00", + "endDate": "2022-10-19T11:10:01", + "unit": "mg\/min·dL", + "value": 0.21186447917983653 + }, + { + "startDate": "2022-10-19T11:10:01", + "endDate": "2022-10-19T11:15:01", + "unit": "mg\/min·dL", + "value": -0.19565062644910516 + }, + { + "startDate": "2022-10-19T11:15:01", + "endDate": "2022-10-19T11:20:01", + "unit": "mg\/min·dL", + "value": 0.19783593524528145 + }, + { + "startDate": "2022-10-19T11:20:01", + "endDate": "2022-10-19T11:25:01", + "unit": "mg\/min·dL", + "value": -0.008068324764244858 + }, + { + "startDate": "2022-10-19T11:25:01", + "endDate": "2022-10-19T11:30:01", + "unit": "mg\/min·dL", + "value": -0.21297518811277394 + }, + { + "startDate": "2022-10-19T11:30:01", + "endDate": "2022-10-19T11:35:01", + "unit": "mg\/min·dL", + "value": -1.4154392414184709 + }, + { + "startDate": "2022-10-19T11:35:01", + "endDate": "2022-10-19T11:40:01", + "unit": "mg\/min·dL", + "value": 0.18063367404695194 + }, + { + "startDate": "2022-10-19T11:40:01", + "endDate": "2022-10-19T11:45:01", + "unit": "mg\/min·dL", + "value": -0.024732221844547427 + }, + { + "startDate": "2022-10-19T11:45:01", + "endDate": "2022-10-19T11:50:01", + "unit": "mg\/min·dL", + "value": 0.36890313428117716 + }, + { + "startDate": "2022-10-19T11:50:01", + "endDate": "2022-10-19T11:55:01", + "unit": "mg\/min·dL", + "value": -0.037138331257601985 + }, + { + "startDate": "2022-10-19T11:55:01", + "endDate": "2022-10-19T12:00:01", + "unit": "mg\/min·dL", + "value": 0.15833000430373778 + }, + { + "startDate": "2022-10-19T12:00:01", + "endDate": "2022-10-19T12:05:01", + "unit": "mg\/min·dL", + "value": 0.5559567576354827 + }, + { + "startDate": "2022-10-19T12:05:01", + "endDate": "2022-10-19T12:10:01", + "unit": "mg\/min·dL", + "value": 0.5530172956564566 + }, + { + "startDate": "2022-10-19T12:10:01", + "endDate": "2022-10-19T12:15:01", + "unit": "mg\/min·dL", + "value": -0.44852664362951983 + }, + { + "startDate": "2022-10-19T12:15:01", + "endDate": "2022-10-19T12:20:01", + "unit": "mg\/min·dL", + "value": -2.6477415901684105 + }, + { + "startDate": "2022-10-19T12:20:01", + "endDate": "2022-10-19T12:25:01", + "unit": "mg\/min·dL", + "value": 0.1552977678286194 + }, + { + "startDate": "2022-10-19T12:25:01", + "endDate": "2022-10-19T12:30:01", + "unit": "mg\/min·dL", + "value": 0.35583861287686863 + }, + { + "startDate": "2022-10-19T12:30:01", + "endDate": "2022-10-19T12:35:01", + "unit": "mg\/min·dL", + "value": 0.15178321128801062 + }, + { + "startDate": "2022-10-19T12:35:01", + "endDate": "2022-10-19T12:40:01", + "unit": "mg\/min·dL", + "value": -0.054382641516428916 + }, + { + "startDate": "2022-10-19T12:40:01", + "endDate": "2022-10-19T12:45:01", + "unit": "mg\/min·dL", + "value": 0.34013478086255156 + }, + { + "startDate": "2022-10-19T12:45:01", + "endDate": "2022-10-19T12:50:01", + "unit": "mg\/min·dL", + "value": 0.3382845937498871 + }, + { + "startDate": "2022-10-19T12:50:01", + "endDate": "2022-10-19T12:55:01", + "unit": "mg\/min·dL", + "value": 0.3348726530312953 + }, + { + "startDate": "2022-10-19T12:55:01", + "endDate": "2022-10-19T13:00:01", + "unit": "mg\/min·dL", + "value": 0.13375947107729694 + }, + { + "startDate": "2022-10-19T13:00:01", + "endDate": "2022-10-19T13:05:01", + "unit": "mg\/min·dL", + "value": 0.33363760645792245 + }, + { + "startDate": "2022-10-19T13:05:01", + "endDate": "2022-10-19T13:10:01", + "unit": "mg\/min·dL", + "value": 0.13416151687489303 + }, + { + "startDate": "2022-10-19T13:10:01", + "endDate": "2022-10-19T13:15:01", + "unit": "mg\/min·dL", + "value": 0.13637905971035752 + }, + { + "startDate": "2022-10-19T13:15:01", + "endDate": "2022-10-19T13:20:01", + "unit": "mg\/min·dL", + "value": -0.05841515325947949 + }, + { + "startDate": "2022-10-19T13:20:01", + "endDate": "2022-10-19T13:25:01", + "unit": "mg\/min·dL", + "value": 0.34745831602294186 + }, + { + "startDate": "2022-10-19T13:25:01", + "endDate": "2022-10-19T13:30:01", + "unit": "mg\/min·dL", + "value": 0.15356560530275998 + }, + { + "startDate": "2022-10-19T13:30:01", + "endDate": "2022-10-19T13:35:01", + "unit": "mg\/min·dL", + "value": 0.15814886769556477 + }, + { + "startDate": "2022-10-19T13:35:01", + "endDate": "2022-10-19T13:40:01", + "unit": "mg\/min·dL", + "value": 0.1643211476796707 + }, + { + "startDate": "2022-10-19T13:40:01", + "endDate": "2022-10-19T13:45:01", + "unit": "mg\/min·dL", + "value": -0.42819858626465096 + }, + { + "startDate": "2022-10-19T13:45:01", + "endDate": "2022-10-19T13:50:01", + "unit": "mg\/min·dL", + "value": -0.4246398182972079 + }, + { + "startDate": "2022-10-19T13:50:01", + "endDate": "2022-10-19T13:55:01", + "unit": "mg\/min·dL", + "value": -1.6170221190514171 + }, + { + "startDate": "2022-10-19T13:55:01", + "endDate": "2022-10-19T14:00:01", + "unit": "mg\/min·dL", + "value": -0.01458102994261643 + }, + { + "startDate": "2022-10-19T14:00:01", + "endDate": "2022-10-19T14:05:01", + "unit": "mg\/min·dL", + "value": -0.013310698763393285 + }, + { + "startDate": "2022-10-19T14:05:01", + "endDate": "2022-10-19T14:10:01", + "unit": "mg\/min·dL", + "value": -3.0229583310838355 + }, + { + "startDate": "2022-10-19T14:10:01", + "endDate": "2022-10-19T14:15:01", + "unit": "mg\/min·dL", + "value": -0.6231747533325243 + }, + { + "startDate": "2022-10-19T14:15:01", + "endDate": "2022-10-19T14:20:01", + "unit": "mg\/min·dL", + "value": -0.031222581685987863 + }, + { + "startDate": "2022-10-19T14:20:01", + "endDate": "2022-10-19T14:25:01", + "unit": "mg\/min·dL", + "value": -0.24248441048452055 + }, + { + "startDate": "2022-10-19T14:25:01", + "endDate": "2022-10-19T14:30:01", + "unit": "mg\/min·dL", + "value": -0.2576185319073888 + }, + { + "startDate": "2022-10-19T14:30:01", + "endDate": "2022-10-19T14:35:01", + "unit": "mg\/min·dL", + "value": -0.07416048984164367 + }, + { + "startDate": "2022-10-19T14:35:01", + "endDate": "2022-10-19T14:40:02", + "unit": "mg\/min·dL", + "value": 0.10654218048278917 + }, + { + "startDate": "2022-10-19T14:40:02", + "endDate": "2022-10-19T14:45:01", + "unit": "mg\/min·dL", + "value": 0.2868467771919189 + }, + { + "startDate": "2022-10-19T14:45:01", + "endDate": "2022-10-19T14:50:01", + "unit": "mg\/min·dL", + "value": 3.859662943460218 + }, + { + "startDate": "2022-10-19T14:50:01", + "endDate": "2022-10-19T14:55:01", + "unit": "mg\/min·dL", + "value": 2.0426250789551563 + }, + { + "startDate": "2022-10-19T14:55:01", + "endDate": "2022-10-19T15:00:02", + "unit": "mg\/min·dL", + "value": 0.8274726282751605 + }, + { + "startDate": "2022-10-19T15:00:02", + "endDate": "2022-10-19T15:05:01", + "unit": "mg\/min·dL", + "value": -0.1647373172917607 + }, + { + "startDate": "2022-10-19T15:05:01", + "endDate": "2022-10-19T15:10:01", + "unit": "mg\/min·dL", + "value": -0.3383393318533003 + }, + { + "startDate": "2022-10-19T15:10:01", + "endDate": "2022-10-19T15:15:01", + "unit": "mg\/min·dL", + "value": -1.3010751993501548 + }, + { + "startDate": "2022-10-19T15:15:01", + "endDate": "2022-10-19T15:20:01", + "unit": "mg\/min·dL", + "value": -1.0578507825421526 + }, + { + "startDate": "2022-10-19T15:20:01", + "endDate": "2022-10-19T15:25:01", + "unit": "mg\/min·dL", + "value": -1.2236208075979995 + }, + { + "startDate": "2022-10-19T15:25:01", + "endDate": "2022-10-19T15:30:01", + "unit": "mg\/min·dL", + "value": -0.1898106156676509 + }, + { + "startDate": "2022-10-19T15:30:01", + "endDate": "2022-10-19T15:35:01", + "unit": "mg\/min·dL", + "value": -0.16517201004765142 + }, + { + "startDate": "2022-10-19T15:35:01", + "endDate": "2022-10-19T15:40:01", + "unit": "mg\/min·dL", + "value": -0.9484454909505492 + }, + { + "startDate": "2022-10-19T15:40:01", + "endDate": "2022-10-19T15:45:01", + "unit": "mg\/min·dL", + "value": 0.056840842438597564 + }, + { + "startDate": "2022-10-19T15:45:01", + "endDate": "2022-10-19T15:50:01", + "unit": "mg\/min·dL", + "value": 1.6894159072949382 + }, + { + "startDate": "2022-10-19T15:50:01", + "endDate": "2022-10-19T15:55:01", + "unit": "mg\/min·dL", + "value": 3.4370337711808054 + }, + { + "startDate": "2022-10-19T15:55:01", + "endDate": "2022-10-19T16:00:01", + "unit": "mg\/min·dL", + "value": 4.154314244332858 + }, + { + "startDate": "2022-10-19T16:00:01", + "endDate": "2022-10-19T16:05:01", + "unit": "mg\/min·dL", + "value": 4.291317248669294 + }, + { + "startDate": "2022-10-19T16:05:01", + "endDate": "2022-10-19T16:10:01", + "unit": "mg\/min·dL", + "value": 3.5995338405154502 + }, + { + "startDate": "2022-10-19T16:10:01", + "endDate": "2022-10-19T16:15:01", + "unit": "mg\/min·dL", + "value": 2.503912693304304 + }, + { + "startDate": "2022-10-19T16:15:01", + "endDate": "2022-10-19T16:20:01", + "unit": "mg\/min·dL", + "value": 1.6066437038993249 + }, + { + "startDate": "2022-10-19T16:20:01", + "endDate": "2022-10-19T16:25:02", + "unit": "mg\/min·dL", + "value": 0.6934545720681625 + }, + { + "startDate": "2022-10-19T16:25:02", + "endDate": "2022-10-19T16:30:01", + "unit": "mg\/min·dL", + "value": -0.03221607567498431 + }, + { + "startDate": "2022-10-19T16:30:01", + "endDate": "2022-10-19T16:35:01", + "unit": "mg\/min·dL", + "value": -0.37750668609914667 + }, + { + "startDate": "2022-10-19T16:35:01", + "endDate": "2022-10-19T16:40:02", + "unit": "mg\/min·dL", + "value": -0.5366513932315495 + }, + { + "startDate": "2022-10-19T16:40:02", + "endDate": "2022-10-19T16:45:01", + "unit": "mg\/min·dL", + "value": -0.7149824772770897 + }, + { + "startDate": "2022-10-19T16:45:01", + "endDate": "2022-10-19T16:50:01", + "unit": "mg\/min·dL", + "value": -0.5044701021773266 + }, + { + "startDate": "2022-10-19T16:50:01", + "endDate": "2022-10-19T16:55:01", + "unit": "mg\/min·dL", + "value": -2.109505339654445 + }, + { + "startDate": "2022-10-19T16:55:01", + "endDate": "2022-10-19T17:00:01", + "unit": "mg\/min·dL", + "value": 0.4716914633278851 + }, + { + "startDate": "2022-10-19T17:00:01", + "endDate": "2022-10-19T17:05:01", + "unit": "mg\/min·dL", + "value": -2.5569783763841247 + }, + { + "startDate": "2022-10-19T17:05:01", + "endDate": "2022-10-19T17:10:01", + "unit": "mg\/min·dL", + "value": -0.5931422423549346 + }, + { + "startDate": "2022-10-19T17:10:01", + "endDate": "2022-10-19T17:15:01", + "unit": "mg\/min·dL", + "value": 0.9651429840342454 + }, + { + "startDate": "2022-10-19T17:15:01", + "endDate": "2022-10-19T17:20:01", + "unit": "mg\/min·dL", + "value": 1.7185111311450811 + }, + { + "startDate": "2022-10-19T17:20:01", + "endDate": "2022-10-19T17:25:01", + "unit": "mg\/min·dL", + "value": 3.261097657377394 + }, + { + "startDate": "2022-10-19T17:25:01", + "endDate": "2022-10-19T17:30:01", + "unit": "mg\/min·dL", + "value": 2.218111960607878 + }, + { + "startDate": "2022-10-19T17:30:01", + "endDate": "2022-10-19T17:35:01", + "unit": "mg\/min·dL", + "value": 1.9614989874606985 + }, + { + "startDate": "2022-10-19T17:35:01", + "endDate": "2022-10-19T17:40:01", + "unit": "mg\/min·dL", + "value": 2.310030719935431 + }, + { + "startDate": "2022-10-19T17:40:01", + "endDate": "2022-10-19T17:45:01", + "unit": "mg\/min·dL", + "value": 2.2796929226444966 + }, + { + "startDate": "2022-10-19T17:45:01", + "endDate": "2022-10-19T17:50:01", + "unit": "mg\/min·dL", + "value": 1.3070330004516437 + }, + { + "startDate": "2022-10-19T17:50:01", + "endDate": "2022-10-19T17:55:01", + "unit": "mg\/min·dL", + "value": 1.3369831256626694 + }, + { + "startDate": "2022-10-19T17:55:01", + "endDate": "2022-10-19T18:00:01", + "unit": "mg\/min·dL", + "value": 0.7637465872357964 + }, + { + "startDate": "2022-10-19T18:00:01", + "endDate": "2022-10-19T18:05:01", + "unit": "mg\/min·dL", + "value": 2.982136459448906 + }, + { + "startDate": "2022-10-19T18:05:01", + "endDate": "2022-10-19T18:10:02", + "unit": "mg\/min·dL", + "value": 1.7816453872682723 + }, + { + "startDate": "2022-10-19T18:10:02", + "endDate": "2022-10-19T18:15:01", + "unit": "mg\/min·dL", + "value": 1.3895013557358005 + }, + { + "startDate": "2022-10-19T18:15:01", + "endDate": "2022-10-19T18:20:02", + "unit": "mg\/min·dL", + "value": 1.7750958006672506 + }, + { + "startDate": "2022-10-19T18:20:02", + "endDate": "2022-10-19T18:25:01", + "unit": "mg\/min·dL", + "value": -0.0325518583724865 + }, + { + "startDate": "2022-10-19T18:25:01", + "endDate": "2022-10-19T18:30:01", + "unit": "mg\/min·dL", + "value": 2.5531676738470956 + }, + { + "startDate": "2022-10-19T18:30:01", + "endDate": "2022-10-19T18:35:01", + "unit": "mg\/min·dL", + "value": 1.541259298963333 + }, + { + "startDate": "2022-10-19T18:35:01", + "endDate": "2022-10-19T18:40:01", + "unit": "mg\/min·dL", + "value": 2.7233457312657436 + }, + { + "startDate": "2022-10-19T18:40:01", + "endDate": "2022-10-19T18:45:02", + "unit": "mg\/min·dL", + "value": 1.3138886583696006 + }, + { + "startDate": "2022-10-19T18:45:02", + "endDate": "2022-10-19T18:50:02", + "unit": "mg\/min·dL", + "value": -0.8787840983987345 + }, + { + "startDate": "2022-10-19T18:50:02", + "endDate": "2022-10-19T18:55:01", + "unit": "mg\/min·dL", + "value": 4.349193045733724 + }, + { + "startDate": "2022-10-19T18:55:01", + "endDate": "2022-10-19T19:00:01", + "unit": "mg\/min·dL", + "value": 0.957056782908769 + }, + { + "startDate": "2022-10-19T19:00:01", + "endDate": "2022-10-19T19:05:01", + "unit": "mg\/min·dL", + "value": 1.1801653071785538 + }, + { + "startDate": "2022-10-19T19:05:01", + "endDate": "2022-10-19T19:10:01", + "unit": "mg\/min·dL", + "value": -0.38564618768177417 + }, + { + "startDate": "2022-10-19T19:10:01", + "endDate": "2022-10-19T19:15:02", + "unit": "mg\/min·dL", + "value": 0.4529340515641141 + }, + { + "startDate": "2022-10-19T19:15:02", + "endDate": "2022-10-19T19:20:01", + "unit": "mg\/min·dL", + "value": 0.3289978439895736 + }, + { + "startDate": "2022-10-19T19:20:01", + "endDate": "2022-10-19T19:25:01", + "unit": "mg\/min·dL", + "value": 1.1342381510013801 + }, + { + "startDate": "2022-10-19T19:25:01", + "endDate": "2022-10-19T19:30:01", + "unit": "mg\/min·dL", + "value": 2.1251594326202325 + }, + { + "startDate": "2022-10-19T19:30:01", + "endDate": "2022-10-19T19:35:01", + "unit": "mg\/min·dL", + "value": 2.6903281741958516 + }, + { + "startDate": "2022-10-19T19:35:01", + "endDate": "2022-10-19T19:40:01", + "unit": "mg\/min·dL", + "value": 2.4470085889667157 + }, + { + "startDate": "2022-10-19T19:40:01", + "endDate": "2022-10-19T19:45:01", + "unit": "mg\/min·dL", + "value": 4.7634008664345195 + }, + { + "startDate": "2022-10-19T19:45:01", + "endDate": "2022-10-19T19:50:02", + "unit": "mg\/min·dL", + "value": 1.8652478945159814 + }, + { + "startDate": "2022-10-19T19:50:02", + "endDate": "2022-10-19T19:55:01", + "unit": "mg\/min·dL", + "value": 0.34772059751605466 + }, + { + "startDate": "2022-10-19T19:55:01", + "endDate": "2022-10-19T20:00:02", + "unit": "mg\/min·dL", + "value": 1.806746991288012 + }, + { + "startDate": "2022-10-19T20:00:02", + "endDate": "2022-10-19T20:05:01", + "unit": "mg\/min·dL", + "value": 0.2464776812075047 + }, + { + "startDate": "2022-10-19T20:05:01", + "endDate": "2022-10-19T20:10:01", + "unit": "mg\/min·dL", + "value": -0.9376351386189138 + }, + { + "startDate": "2022-10-19T20:10:01", + "endDate": "2022-10-19T20:15:01", + "unit": "mg\/min·dL", + "value": 0.05860685806376006 + }, + { + "startDate": "2022-10-19T20:15:01", + "endDate": "2022-10-19T20:20:02", + "unit": "mg\/min·dL", + "value": 2.0363173703859756 + }, + { + "startDate": "2022-10-19T20:20:02", + "endDate": "2022-10-19T20:25:01", + "unit": "mg\/min·dL", + "value": 3.4046523515645477 + }, + { + "startDate": "2022-10-19T20:25:01", + "endDate": "2022-10-19T20:30:01", + "unit": "mg\/min·dL", + "value": 3.345839857833783 + }, + { + "startDate": "2022-10-19T20:30:01", + "endDate": "2022-10-19T20:35:01", + "unit": "mg\/min·dL", + "value": 3.2841929027812276 + }, + { + "startDate": "2022-10-19T20:35:01", + "endDate": "2022-10-19T20:40:02", + "unit": "mg\/min·dL", + "value": 3.2232532666739027 + }, + { + "startDate": "2022-10-19T20:40:02", + "endDate": "2022-10-19T20:45:01", + "unit": "mg\/min·dL", + "value": 1.9676584040493557 + }, + { + "startDate": "2022-10-19T20:45:01", + "endDate": "2022-10-19T20:50:01", + "unit": "mg\/min·dL", + "value": 2.299368111515345 + }, + { + "startDate": "2022-10-19T20:50:01", + "endDate": "2022-10-19T20:55:02", + "unit": "mg\/min·dL", + "value": 4.034026725887583 + }, + { + "startDate": "2022-10-19T20:55:02", + "endDate": "2022-10-19T21:00:01", + "unit": "mg\/min·dL", + "value": 2.3799054220542706 + }, + { + "startDate": "2022-10-19T21:00:01", + "endDate": "2022-10-19T21:05:01", + "unit": "mg\/min·dL", + "value": 2.3167018765165173 + }, + { + "startDate": "2022-10-19T21:05:01", + "endDate": "2022-10-19T21:10:01", + "unit": "mg\/min·dL", + "value": 1.8556929650115728 + }, + { + "startDate": "2022-10-19T21:10:01", + "endDate": "2022-10-19T21:15:01", + "unit": "mg\/min·dL", + "value": 3.616009538834508 + }, + { + "startDate": "2022-10-19T21:15:01", + "endDate": "2022-10-19T21:20:01", + "unit": "mg\/min·dL", + "value": 2.1720784828835176 + }, + { + "startDate": "2022-10-19T21:20:01", + "endDate": "2022-10-19T21:25:01", + "unit": "mg\/min·dL", + "value": 1.3496070250759875 + }, + { + "startDate": "2022-10-19T21:25:01", + "endDate": "2022-10-19T21:30:01", + "unit": "mg\/min·dL", + "value": 0.9670380126484306 + }, + { + "startDate": "2022-10-19T21:30:01", + "endDate": "2022-10-19T21:35:01", + "unit": "mg\/min·dL", + "value": -0.16076892735619985 + }, + { + "startDate": "2022-10-19T21:35:01", + "endDate": "2022-10-19T21:40:01", + "unit": "mg\/min·dL", + "value": -0.9050254515029905 + } +] diff --git a/LoopTests/Managers/Alerts/AlertManagerTests.swift b/LoopTests/Managers/Alerts/AlertManagerTests.swift index 0347645323..18026c1e82 100644 --- a/LoopTests/Managers/Alerts/AlertManagerTests.swift +++ b/LoopTests/Managers/Alerts/AlertManagerTests.swift @@ -186,6 +186,7 @@ class AlertManagerTests: XCTestCase { fileManager: mockFileManager, alertStore: mockAlertStore, bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager(), preventIssuanceBeforePlayback: false) } @@ -263,7 +264,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) alertManager.playbackAlertsFromPersistence() XCTAssertEqual(alert, mockModalScheduler.scheduledAlert) XCTAssertNil(mockUserNotificationScheduler.scheduledAlert) @@ -284,7 +286,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) alertManager.playbackAlertsFromPersistence() let expected = Alert(identifier: Self.mockIdentifier, foregroundContent: content, backgroundContent: content, trigger: .immediate) XCTAssertEqual(expected, mockModalScheduler.scheduledAlert) @@ -306,7 +309,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) alertManager.playbackAlertsFromPersistence() // The trigger for this should be `.delayed` by "something less than 15 seconds", @@ -336,7 +340,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) alertManager.playbackAlertsFromPersistence() XCTAssertEqual(alert, mockModalScheduler.scheduledAlert) @@ -358,7 +363,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) alertManager.lookupAllUnretracted(managerIdentifier: Self.mockManagerIdentifier) { result in try? XCTAssertEqual([PersistedAlert(alert: alert, issuedDate: date, retractedDate: nil, acknowledgedDate: nil)], XCTUnwrap(result.successValue)) @@ -380,7 +386,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) alertManager.lookupAllUnacknowledgedUnretracted(managerIdentifier: Self.mockManagerIdentifier) { result in try? XCTAssertEqual([PersistedAlert(alert: alert, issuedDate: date, retractedDate: nil, acknowledgedDate: nil)], XCTUnwrap(result.successValue)) @@ -402,7 +409,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) let identifierExists = Self.mockIdentifier let identifierDoesNotExist = Alert.Identifier(managerIdentifier: "TestManagerIdentifier", alertIdentifier: "TestAlertIdentifier") alertManager.doesIssuedAlertExist(identifier: identifierExists) { result in @@ -425,7 +433,8 @@ class AlertManagerTests: XCTestCase { userNotificationAlertScheduler: mockUserNotificationScheduler, fileManager: mockFileManager, alertStore: mockAlertStore, - bluetoothProvider: MockBluetoothProvider()) + bluetoothProvider: MockBluetoothProvider(), + analyticsServicesManager: AnalyticsServicesManager()) let now = Date() alertManager.recordRetractedAlert(alert, at: now) XCTAssertEqual(mockAlertStore.retractedAlert, alert) diff --git a/LoopTests/Managers/DoseEnactorTests.swift b/LoopTests/Managers/DoseEnactorTests.swift index 7ab7add2e4..72359793e6 100644 --- a/LoopTests/Managers/DoseEnactorTests.swift +++ b/LoopTests/Managers/DoseEnactorTests.swift @@ -42,6 +42,8 @@ class MockPumpManager: PumpManager { static var onboardingSupportedMaximumBolusVolumes: [Double] = [1,2,3] + let deliveryUnitsPerMinute = 1.5 + var supportedBasalRates: [Double] = [1,2,3] var supportedBolusVolumes: [Double] = [1,2,3] @@ -57,7 +59,6 @@ class MockPumpManager: PumpManager { var pumpRecordsBasalProfileStartEvents: Bool = false var pumpReservoirCapacity: Double = 50 - var deliveryUnitsPerMinute = 1.5 var lastSync: Date? @@ -115,8 +116,8 @@ class MockPumpManager: PumpManager { func syncDeliveryLimits(limits deliveryLimits: DeliveryLimits, completion: @escaping (Result) -> Void) { } - - public func estimatedDuration(toBolus units: Double) -> TimeInterval { + + func estimatedDuration(toBolus units: Double) -> TimeInterval { .minutes(units / deliveryUnitsPerMinute) } diff --git a/LoopTests/Managers/LoopDataManagerDosingTests.swift b/LoopTests/Managers/LoopDataManagerDosingTests.swift new file mode 100644 index 0000000000..7506ba83f8 --- /dev/null +++ b/LoopTests/Managers/LoopDataManagerDosingTests.swift @@ -0,0 +1,536 @@ +// +// LoopDataManagerDosingTests.swift +// LoopTests +// +// Created by Anna Quinlan on 10/19/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import XCTest +import HealthKit +import LoopKit +@testable import LoopCore +@testable import Loop + +class MockDelegate: LoopDataManagerDelegate { + let pumpManager = MockPumpManager() + + var bolusUnits: Double? + func loopDataManager(_ manager: Loop.LoopDataManager, estimateBolusDuration units: Double) -> TimeInterval? { + self.bolusUnits = units + return pumpManager.estimatedDuration(toBolus: units) + } + + var recommendation: AutomaticDoseRecommendation? + var error: LoopError? + func loopDataManager(_ manager: LoopDataManager, didRecommend automaticDose: (recommendation: AutomaticDoseRecommendation, date: Date), completion: @escaping (LoopError?) -> Void) { + self.recommendation = automaticDose.recommendation + completion(error) + } + func roundBasalRate(unitsPerHour: Double) -> Double { Double(Int(unitsPerHour / 0.05)) * 0.05 } + func roundBolusVolume(units: Double) -> Double { Double(Int(units / 0.05)) * 0.05 } + var pumpManagerStatus: PumpManagerStatus? + var cgmManagerStatus: CGMManagerStatus? + var pumpStatusHighlight: DeviceStatusHighlight? +} + +class LoopDataManagerDosingTests: LoopDataManagerTests { + // MARK: Functions to load fixtures + func loadGlucoseEffect(_ name: String) -> [GlucoseEffect] { + let fixture: [JSONDictionary] = loadFixture(name) + let dateFormatter = ISO8601DateFormatter.localTimeDate() + + return fixture.map { + return GlucoseEffect(startDate: dateFormatter.date(from: $0["date"] as! String)!, quantity: HKQuantity(unit: HKUnit(from: $0["unit"] as! String), doubleValue:$0["amount"] as! Double)) + } + } + + // MARK: Tests + func testFlatAndStable() { + setUp(for: .flatAndStable) + let predictedGlucoseOutput = loadGlucoseEffect("flat_and_stable_predicted_glucose") + + let updateGroup = DispatchGroup() + updateGroup.enter() + var predictedGlucose: [PredictedGlucoseValue]? + var recommendedDose: AutomaticDoseRecommendation? + self.loopDataManager.getLoopState { _, state in + predictedGlucose = state.predictedGlucose + recommendedDose = state.recommendedAutomaticDose?.recommendation + updateGroup.leave() + } + // We need to wait until the task completes to get outputs + updateGroup.wait() + + XCTAssertNotNil(predictedGlucose) + XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) + + for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { + XCTAssertEqual(expected.startDate, calculated.startDate) + XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) + } + + let recommendedTempBasal = recommendedDose?.basalAdjustment + + XCTAssertEqual(1.40, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) + } + + func testHighAndStable() { + setUp(for: .highAndStable) + let predictedGlucoseOutput = loadGlucoseEffect("high_and_stable_predicted_glucose") + + let updateGroup = DispatchGroup() + updateGroup.enter() + var predictedGlucose: [PredictedGlucoseValue]? + var recommendedBasal: TempBasalRecommendation? + self.loopDataManager.getLoopState { _, state in + predictedGlucose = state.predictedGlucose + recommendedBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment + updateGroup.leave() + } + // We need to wait until the task completes to get outputs + updateGroup.wait() + + XCTAssertNotNil(predictedGlucose) + XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) + + for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { + XCTAssertEqual(expected.startDate, calculated.startDate) + XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) + } + + XCTAssertEqual(4.63, recommendedBasal!.unitsPerHour, accuracy: defaultAccuracy) + } + + func testHighAndFalling() { + setUp(for: .highAndFalling) + let predictedGlucoseOutput = loadGlucoseEffect("high_and_falling_predicted_glucose") + + let updateGroup = DispatchGroup() + updateGroup.enter() + var predictedGlucose: [PredictedGlucoseValue]? + var recommendedTempBasal: TempBasalRecommendation? + self.loopDataManager.getLoopState { _, state in + predictedGlucose = state.predictedGlucose + recommendedTempBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment + updateGroup.leave() + } + // We need to wait until the task completes to get outputs + updateGroup.wait() + + XCTAssertNotNil(predictedGlucose) + XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) + + for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { + XCTAssertEqual(expected.startDate, calculated.startDate) + XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) + } + + XCTAssertEqual(0, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) + } + + func testHighAndRisingWithCOB() { + setUp(for: .highAndRisingWithCOB) + let predictedGlucoseOutput = loadGlucoseEffect("high_and_rising_with_cob_predicted_glucose") + + let updateGroup = DispatchGroup() + updateGroup.enter() + var predictedGlucose: [PredictedGlucoseValue]? + var recommendedBolus: ManualBolusRecommendation? + self.loopDataManager.getLoopState { _, state in + predictedGlucose = state.predictedGlucose + recommendedBolus = try? state.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: true) + updateGroup.leave() + } + // We need to wait until the task completes to get outputs + updateGroup.wait() + + XCTAssertNotNil(predictedGlucose) + XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) + + for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { + XCTAssertEqual(expected.startDate, calculated.startDate) + XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) + } + + XCTAssertEqual(1.6, recommendedBolus!.amount, accuracy: defaultAccuracy) + } + + func testLowAndFallingWithCOB() { + setUp(for: .lowAndFallingWithCOB) + let predictedGlucoseOutput = loadGlucoseEffect("low_and_falling_predicted_glucose") + + let updateGroup = DispatchGroup() + updateGroup.enter() + var predictedGlucose: [PredictedGlucoseValue]? + var recommendedTempBasal: TempBasalRecommendation? + self.loopDataManager.getLoopState { _, state in + predictedGlucose = state.predictedGlucose + recommendedTempBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment + updateGroup.leave() + } + // We need to wait until the task completes to get outputs + updateGroup.wait() + + XCTAssertNotNil(predictedGlucose) + XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) + + for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { + XCTAssertEqual(expected.startDate, calculated.startDate) + XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) + } + + XCTAssertEqual(0, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) + } + + func testLowWithLowTreatment() { + setUp(for: .lowWithLowTreatment) + let predictedGlucoseOutput = loadGlucoseEffect("low_with_low_treatment_predicted_glucose") + + let updateGroup = DispatchGroup() + updateGroup.enter() + var predictedGlucose: [PredictedGlucoseValue]? + var recommendedTempBasal: TempBasalRecommendation? + self.loopDataManager.getLoopState { _, state in + predictedGlucose = state.predictedGlucose + recommendedTempBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment + updateGroup.leave() + } + // We need to wait until the task completes to get outputs + updateGroup.wait() + + XCTAssertNotNil(predictedGlucose) + XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) + + for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { + XCTAssertEqual(expected.startDate, calculated.startDate) + XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) + } + + XCTAssertEqual(0, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) + } + + func waitOnDataQueue(timeout: TimeInterval = 1.0) { + let e = expectation(description: "dataQueue") + loopDataManager.getLoopState { _, _ in + e.fulfill() + } + wait(for: [e], timeout: timeout) + } + + func testValidateMaxTempBasalDoesntCancelTempBasalIfHigher() { + let dose = DoseEntry(type: .tempBasal, startDate: Date(), endDate: nil, value: 3.0, unit: .unitsPerHour, deliveredUnits: nil, description: nil, syncIdentifier: nil, scheduledBasalRate: nil) + setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) + // This wait is working around the issue presented by LoopDataManager.init(). It cancels the temp basal if + // `isClosedLoop` is false (which it is from `setUp` above). When that happens, it races with + // `maxTempBasalSavePreflight` below. This ensures only one happens at a time. + waitOnDataQueue() + let delegate = MockDelegate() + loopDataManager.delegate = delegate + var error: Error? + let exp = expectation(description: #function) + XCTAssertNil(delegate.recommendation) + loopDataManager.maxTempBasalSavePreflight(unitsPerHour: 5.0) { + error = $0 + exp.fulfill() + } + wait(for: [exp], timeout: 1.0) + XCTAssertNil(error) + XCTAssertNil(delegate.recommendation) + XCTAssertTrue(dosingDecisionStore.dosingDecisions.isEmpty) + } + + func testValidateMaxTempBasalCancelsTempBasalIfLower() { + let dose = DoseEntry(type: .tempBasal, startDate: Date(), endDate: nil, value: 5.0, unit: .unitsPerHour, deliveredUnits: nil, description: nil, syncIdentifier: nil, scheduledBasalRate: nil) + setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) + // This wait is working around the issue presented by LoopDataManager.init(). It cancels the temp basal if + // `isClosedLoop` is false (which it is from `setUp` above). When that happens, it races with + // `maxTempBasalSavePreflight` below. This ensures only one happens at a time. + waitOnDataQueue() + let delegate = MockDelegate() + loopDataManager.delegate = delegate + var error: Error? + let exp = expectation(description: #function) + XCTAssertNil(delegate.recommendation) + loopDataManager.maxTempBasalSavePreflight(unitsPerHour: 3.0) { + error = $0 + exp.fulfill() + } + wait(for: [exp], timeout: 1.0) + XCTAssertNil(error) + XCTAssertEqual(delegate.recommendation, AutomaticDoseRecommendation(basalAdjustment: .cancel)) + XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "maximumBasalRateChanged") + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, AutomaticDoseRecommendation(basalAdjustment: .cancel)) + } + + func testChangingMaxBasalUpdatesLoopData() { + setUp(for: .highAndStable) + waitOnDataQueue() + var loopDataUpdated = false + let exp = expectation(description: #function) + let observer = NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: nil, queue: nil) { _ in + loopDataUpdated = true + exp.fulfill() + } + XCTAssertFalse(loopDataUpdated) + loopDataManager.mutateSettings { $0.maximumBasalRatePerHour = 2.0 } + wait(for: [exp], timeout: 1.0) + XCTAssertTrue(loopDataUpdated) + NotificationCenter.default.removeObserver(observer) + } + + func testOpenLoopCancelsTempBasal() { + let dose = DoseEntry(type: .tempBasal, startDate: Date(), value: 1.0, unit: .unitsPerHour) + setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) + waitOnDataQueue() + let delegate = MockDelegate() + loopDataManager.delegate = delegate + let exp = expectation(description: #function) + let observer = NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: nil, queue: nil) { _ in + exp.fulfill() + } + automaticDosingStatus.automaticDosingEnabled = false + wait(for: [exp], timeout: 1.0) + let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: .cancel) + XCTAssertEqual(delegate.recommendation, expectedAutomaticDoseRecommendation) + XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "automaticDosingDisabled") + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) + NotificationCenter.default.removeObserver(observer) + } + + func testReceivedUnreliableCGMReadingCancelsTempBasal() { + let dose = DoseEntry(type: .tempBasal, startDate: Date(), value: 5.0, unit: .unitsPerHour) + setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) + waitOnDataQueue() + let delegate = MockDelegate() + loopDataManager.delegate = delegate + let exp = expectation(description: #function) + let observer = NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: nil, queue: nil) { _ in + exp.fulfill() + } + loopDataManager.receivedUnreliableCGMReading() + wait(for: [exp], timeout: 1.0) + let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: .cancel) + XCTAssertEqual(delegate.recommendation, expectedAutomaticDoseRecommendation) + XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "unreliableCGMData") + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) + NotificationCenter.default.removeObserver(observer) + } + + func testLoopEnactsTempBasalWithoutManualBolusRecommendation() { + setUp(for: .highAndStable) + waitOnDataQueue() + let delegate = MockDelegate() + loopDataManager.delegate = delegate + let exp = expectation(description: #function) + let observer = NotificationCenter.default.addObserver(forName: .LoopCompleted, object: nil, queue: nil) { _ in + exp.fulfill() + } + loopDataManager.loop() + wait(for: [exp], timeout: 1.0) + let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: TempBasalRecommendation(unitsPerHour: 4.55, duration: .minutes(30))) + XCTAssertEqual(delegate.recommendation, expectedAutomaticDoseRecommendation) + XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) + if dosingDecisionStore.dosingDecisions.count == 1 { + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "loop") + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) + XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRecommendation) + XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRequested) + } + NotificationCenter.default.removeObserver(observer) + } + + func testLoopRecommendsTempBasalWithoutEnactingIfOpenLoop() { + setUp(for: .highAndStable) + automaticDosingStatus.automaticDosingEnabled = false + waitOnDataQueue() + let delegate = MockDelegate() + loopDataManager.delegate = delegate + let exp = expectation(description: #function) + let observer = NotificationCenter.default.addObserver(forName: .LoopCompleted, object: nil, queue: nil) { _ in + exp.fulfill() + } + loopDataManager.loop() + wait(for: [exp], timeout: 1.0) + let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: TempBasalRecommendation(unitsPerHour: 4.55, duration: .minutes(30))) + XCTAssertNil(delegate.recommendation) + XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "loop") + XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) + XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRecommendation) + XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRequested) + NotificationCenter.default.removeObserver(observer) + } + + func testLoopGetStateRecommendsManualBolus() { + setUp(for: .highAndStable) + let exp = expectation(description: #function) + var recommendedBolus: ManualBolusRecommendation? + loopDataManager.getLoopState { (_, loopState) in + recommendedBolus = try? loopState.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: true) + exp.fulfill() + } + wait(for: [exp], timeout: 100000.0) + XCTAssertEqual(recommendedBolus!.amount, 1.82, accuracy: 0.01) + } + + func testLoopGetStateRecommendsManualBolusWithMomentum() { + setUp(for: .highAndRisingWithCOB) + let exp = expectation(description: #function) + var recommendedBolus: ManualBolusRecommendation? + loopDataManager.getLoopState { (_, loopState) in + recommendedBolus = try? loopState.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: true) + exp.fulfill() + } + wait(for: [exp], timeout: 1.0) + XCTAssertEqual(recommendedBolus!.amount, 1.62, accuracy: 0.01) + } + + func testLoopGetStateRecommendsManualBolusWithoutMomentum() { + setUp(for: .highAndRisingWithCOB) + let exp = expectation(description: #function) + var recommendedBolus: ManualBolusRecommendation? + loopDataManager.getLoopState { (_, loopState) in + recommendedBolus = try? loopState.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: false) + exp.fulfill() + } + wait(for: [exp], timeout: 1.0) + XCTAssertEqual(recommendedBolus!.amount, 1.52, accuracy: 0.01) + } + + func testIsClosedLoopAvoidsTriggeringTempBasalCancelOnCreation() { + let settings = LoopSettings( + dosingEnabled: false, + glucoseTargetRangeSchedule: glucoseTargetRangeSchedule, + maximumBasalRatePerHour: 5, + maximumBolus: 10, + suspendThreshold: suspendThreshold + ) + + let doseStore = MockDoseStore() + let glucoseStore = MockGlucoseStore() + let carbStore = MockCarbStore() + + let currentDate = Date() + + dosingDecisionStore = MockDosingDecisionStore() + automaticDosingStatus = AutomaticDosingStatus(automaticDosingEnabled: false, isAutomaticDosingAllowed: true) + let existingTempBasal = DoseEntry( + type: .tempBasal, + startDate: currentDate.addingTimeInterval(-.minutes(2)), + endDate: currentDate.addingTimeInterval(.minutes(28)), + value: 1.0, + unit: .unitsPerHour, + deliveredUnits: nil, + description: "Mock Temp Basal", + syncIdentifier: "asdf", + scheduledBasalRate: nil, + insulinType: .novolog, + automatic: true, + manuallyEntered: false, + isMutable: true) + loopDataManager = LoopDataManager( + lastLoopCompleted: currentDate.addingTimeInterval(-.minutes(5)), + basalDeliveryState: .tempBasal(existingTempBasal), + settings: settings, + overrideHistory: TemporaryScheduleOverrideHistory(), + analyticsServicesManager: AnalyticsServicesManager(), + localCacheDuration: .days(1), + doseStore: doseStore, + glucoseStore: glucoseStore, + carbStore: carbStore, + dosingDecisionStore: dosingDecisionStore, + latestStoredSettingsProvider: MockLatestStoredSettingsProvider(), + now: { currentDate }, + pumpInsulinType: .novolog, + automaticDosingStatus: automaticDosingStatus, + trustedTimeOffset: { 0 } + ) + let mockDelegate = MockDelegate() + loopDataManager.delegate = mockDelegate + + // Dose enacting happens asynchronously, as does receiving isClosedLoop signals + waitOnMain(timeout: 5) + XCTAssertNil(mockDelegate.recommendation) + } + + func testAutoBolusMaxIOBClamping() { + /// `maxBolus` is set to clamp the automatic dose + /// Autobolus without clamping: 0.65 U. Clamped recommendation: 0.2 U. + setUp(for: .highAndRisingWithCOB, maxBolus: 5, dosingStrategy: .automaticBolus) + + // This sets up dose rounding + let delegate = MockDelegate() + loopDataManager.delegate = delegate + + let updateGroup = DispatchGroup() + updateGroup.enter() + + var insulinOnBoard: InsulinValue? + var recommendedBolus: Double? + self.loopDataManager.getLoopState { _, state in + insulinOnBoard = state.insulinOnBoard + recommendedBolus = state.recommendedAutomaticDose?.recommendation.bolusUnits + updateGroup.leave() + } + updateGroup.wait() + + XCTAssertEqual(recommendedBolus!, 0.5, accuracy: 0.01) + XCTAssertEqual(insulinOnBoard?.value, 9.5) + + /// Set the `maximumBolus` to 10U so there's no clamping + updateGroup.enter() + self.loopDataManager.mutateSettings { settings in settings.maximumBolus = 10 } + self.loopDataManager.getLoopState { _, state in + insulinOnBoard = state.insulinOnBoard + recommendedBolus = state.recommendedAutomaticDose?.recommendation.bolusUnits + updateGroup.leave() + } + updateGroup.wait() + + XCTAssertEqual(recommendedBolus!, 0.65, accuracy: 0.01) + XCTAssertEqual(insulinOnBoard?.value, 9.5) + } + + func testTempBasalMaxIOBClamping() { + /// `maximumBolus` is set to 5U to clamp max IOB at 10U + /// Without clamping: 4.25 U/hr. Clamped recommendation: 2.0 U/hr. + setUp(for: .highAndRisingWithCOB, maxBolus: 5) + + // This sets up dose rounding + let delegate = MockDelegate() + loopDataManager.delegate = delegate + + let updateGroup = DispatchGroup() + updateGroup.enter() + + var insulinOnBoard: InsulinValue? + var recommendedBasal: TempBasalRecommendation? + self.loopDataManager.getLoopState { _, state in + insulinOnBoard = state.insulinOnBoard + recommendedBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment + updateGroup.leave() + } + updateGroup.wait() + + XCTAssertEqual(recommendedBasal!.unitsPerHour, 2.0, accuracy: 0.01) + XCTAssertEqual(insulinOnBoard?.value, 9.5) + + /// Set the `maximumBolus` to 10U so there's no clamping + updateGroup.enter() + self.loopDataManager.mutateSettings { settings in settings.maximumBolus = 10 } + self.loopDataManager.getLoopState { _, state in + insulinOnBoard = state.insulinOnBoard + recommendedBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment + updateGroup.leave() + } + updateGroup.wait() + + XCTAssertEqual(recommendedBasal!.unitsPerHour, 4.25, accuracy: 0.01) + XCTAssertEqual(insulinOnBoard?.value, 9.5) + } + +} diff --git a/LoopTests/Managers/LoopDataManagerTests.swift b/LoopTests/Managers/LoopDataManagerTests.swift index cfa92eb61e..5c24cfc97e 100644 --- a/LoopTests/Managers/LoopDataManagerTests.swift +++ b/LoopTests/Managers/LoopDataManagerTests.swift @@ -14,7 +14,7 @@ import LoopKit public typealias JSONDictionary = [String: Any] -enum DataManagerTestType { +enum DosingTestScenario { case flatAndStable case highAndStable case highAndRisingWithCOB @@ -45,7 +45,7 @@ extension ISO8601DateFormatter { } } -class LoopDataManagerDosingTests: XCTestCase { +class LoopDataManagerTests: XCTestCase { // MARK: Constants for testing let retrospectiveCorrectionEffectDuration = TimeInterval(hours: 1) let retrospectiveCorrectionGroupingInterval = 1.01 @@ -54,10 +54,6 @@ class LoopDataManagerDosingTests: XCTestCase { let dateFormatter = ISO8601DateFormatter.localTimeDate() let defaultAccuracy = 1.0 / 40.0 - // MARK: Settings - let maxBasalRate = 5.0 - let maxBolus = 10.0 - var suspendThreshold: GlucoseThreshold { return GlucoseThreshold(unit: HKUnit.milligramsPerDeciliter, value: 75) } @@ -73,20 +69,35 @@ class LoopDataManagerDosingTests: XCTestCase { } // MARK: Mock stores + var now: Date! var dosingDecisionStore: MockDosingDecisionStore! var automaticDosingStatus: AutomaticDosingStatus! var loopDataManager: LoopDataManager! - func setUp(for test: DataManagerTestType, basalDeliveryState: PumpManagerStatus.BasalDeliveryState? = nil) { + func setUp(for test: DosingTestScenario, + basalDeliveryState: PumpManagerStatus.BasalDeliveryState? = nil, + maxBolus: Double = 10, + maxBasalRate: Double = 5.0, + dosingStrategy: AutomaticDosingStrategy = .tempBasalOnly) + { let basalRateSchedule = loadBasalRateScheduleFixture("basal_profile") + let carbRatioSchedule = CarbRatioSchedule( + unit: .gram(), + dailyItems: [ + RepeatingScheduleValue(startTime: 0.0, value: 10.0), + ], + timeZone: .utcTimeZone + )! let settings = LoopSettings( dosingEnabled: false, glucoseTargetRangeSchedule: glucoseTargetRangeSchedule, basalRateSchedule: basalRateSchedule, + carbRatioSchedule: carbRatioSchedule, maximumBasalRatePerHour: maxBasalRate, maximumBolus: maxBolus, - suspendThreshold: suspendThreshold + suspendThreshold: suspendThreshold, + automaticDosingStrategy: dosingStrategy ) let doseStore = MockDoseStore(for: test) @@ -96,6 +107,7 @@ class LoopDataManagerDosingTests: XCTestCase { let carbStore = MockCarbStore(for: test) let currentDate = glucoseStore.latestGlucose!.startDate + now = currentDate dosingDecisionStore = MockDosingDecisionStore() automaticDosingStatus = AutomaticDosingStatus(automaticDosingEnabled: true, isAutomaticDosingAllowed: true) @@ -121,446 +133,9 @@ class LoopDataManagerDosingTests: XCTestCase { override func tearDownWithError() throws { loopDataManager = nil } - - // MARK: Functions to load fixtures - func loadGlucoseEffect(_ name: String) -> [GlucoseEffect] { - let fixture: [JSONDictionary] = loadFixture(name) - let dateFormatter = ISO8601DateFormatter.localTimeDate() - - return fixture.map { - return GlucoseEffect(startDate: dateFormatter.date(from: $0["date"] as! String)!, quantity: HKQuantity(unit: HKUnit(from: $0["unit"] as! String), doubleValue:$0["amount"] as! Double)) - } - } - - // MARK: Tests - func testFlatAndStable() { - setUp(for: .flatAndStable) - let predictedGlucoseOutput = loadGlucoseEffect("flat_and_stable_predicted_glucose") - - let updateGroup = DispatchGroup() - updateGroup.enter() - var predictedGlucose: [PredictedGlucoseValue]? - var recommendedDose: AutomaticDoseRecommendation? - self.loopDataManager.getLoopState { _, state in - predictedGlucose = state.predictedGlucose - recommendedDose = state.recommendedAutomaticDose?.recommendation - updateGroup.leave() - } - // We need to wait until the task completes to get outputs - updateGroup.wait() - - XCTAssertNotNil(predictedGlucose) - XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) - - for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { - XCTAssertEqual(expected.startDate, calculated.startDate) - XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) - } - - let recommendedTempBasal = recommendedDose?.basalAdjustment - - XCTAssertEqual(1.40, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) - } - - func testHighAndStable() { - setUp(for: .highAndStable) - let predictedGlucoseOutput = loadGlucoseEffect("high_and_stable_predicted_glucose") - - let updateGroup = DispatchGroup() - updateGroup.enter() - var predictedGlucose: [PredictedGlucoseValue]? - var recommendedBasal: TempBasalRecommendation? - self.loopDataManager.getLoopState { _, state in - predictedGlucose = state.predictedGlucose - recommendedBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment - updateGroup.leave() - } - // We need to wait until the task completes to get outputs - updateGroup.wait() - - XCTAssertNotNil(predictedGlucose) - XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) - - for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { - XCTAssertEqual(expected.startDate, calculated.startDate) - XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) - } - - XCTAssertEqual(4.63, recommendedBasal!.unitsPerHour, accuracy: defaultAccuracy) - } - - func testHighAndFalling() { - setUp(for: .highAndFalling) - let predictedGlucoseOutput = loadGlucoseEffect("high_and_falling_predicted_glucose") - - let updateGroup = DispatchGroup() - updateGroup.enter() - var predictedGlucose: [PredictedGlucoseValue]? - var recommendedTempBasal: TempBasalRecommendation? - self.loopDataManager.getLoopState { _, state in - predictedGlucose = state.predictedGlucose - recommendedTempBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment - updateGroup.leave() - } - // We need to wait until the task completes to get outputs - updateGroup.wait() - - XCTAssertNotNil(predictedGlucose) - XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) - - for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { - XCTAssertEqual(expected.startDate, calculated.startDate) - XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) - } - - XCTAssertEqual(0, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) - } - - func testHighAndRisingWithCOB() { - setUp(for: .highAndRisingWithCOB) - let predictedGlucoseOutput = loadGlucoseEffect("high_and_rising_with_cob_predicted_glucose") - - let updateGroup = DispatchGroup() - updateGroup.enter() - var predictedGlucose: [PredictedGlucoseValue]? - var recommendedBolus: ManualBolusRecommendation? - self.loopDataManager.getLoopState { _, state in - predictedGlucose = state.predictedGlucose - recommendedBolus = try? state.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: true) - updateGroup.leave() - } - // We need to wait until the task completes to get outputs - updateGroup.wait() - - XCTAssertNotNil(predictedGlucose) - XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) - - for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { - XCTAssertEqual(expected.startDate, calculated.startDate) - XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) - } - - XCTAssertEqual(1.6, recommendedBolus!.amount, accuracy: defaultAccuracy) - } - - func testLowAndFallingWithCOB() { - setUp(for: .lowAndFallingWithCOB) - let predictedGlucoseOutput = loadGlucoseEffect("low_and_falling_predicted_glucose") - - let updateGroup = DispatchGroup() - updateGroup.enter() - var predictedGlucose: [PredictedGlucoseValue]? - var recommendedTempBasal: TempBasalRecommendation? - self.loopDataManager.getLoopState { _, state in - predictedGlucose = state.predictedGlucose - recommendedTempBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment - updateGroup.leave() - } - // We need to wait until the task completes to get outputs - updateGroup.wait() - - XCTAssertNotNil(predictedGlucose) - XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) - - for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { - XCTAssertEqual(expected.startDate, calculated.startDate) - XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) - } - - XCTAssertEqual(0, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) - } - - func testLowWithLowTreatment() { - setUp(for: .lowWithLowTreatment) - let predictedGlucoseOutput = loadGlucoseEffect("low_with_low_treatment_predicted_glucose") - - let updateGroup = DispatchGroup() - updateGroup.enter() - var predictedGlucose: [PredictedGlucoseValue]? - var recommendedTempBasal: TempBasalRecommendation? - self.loopDataManager.getLoopState { _, state in - predictedGlucose = state.predictedGlucose - recommendedTempBasal = state.recommendedAutomaticDose?.recommendation.basalAdjustment - updateGroup.leave() - } - // We need to wait until the task completes to get outputs - updateGroup.wait() - - XCTAssertNotNil(predictedGlucose) - XCTAssertEqual(predictedGlucoseOutput.count, predictedGlucose!.count) - - for (expected, calculated) in zip(predictedGlucoseOutput, predictedGlucose!) { - XCTAssertEqual(expected.startDate, calculated.startDate) - XCTAssertEqual(expected.quantity.doubleValue(for: .milligramsPerDeciliter), calculated.quantity.doubleValue(for: .milligramsPerDeciliter), accuracy: defaultAccuracy) - } - - XCTAssertEqual(0, recommendedTempBasal!.unitsPerHour, accuracy: defaultAccuracy) - } - - class MockDelegate: LoopDataManagerDelegate { - var recommendation: AutomaticDoseRecommendation? - var error: LoopError? - func loopDataManager(_ manager: LoopDataManager, didRecommend automaticDose: (recommendation: AutomaticDoseRecommendation, date: Date), completion: @escaping (LoopError?) -> Void) { - self.recommendation = automaticDose.recommendation - completion(error) - } - func roundBasalRate(unitsPerHour: Double) -> Double { unitsPerHour } - func roundBolusVolume(units: Double) -> Double { units } - var pumpManagerStatus: PumpManagerStatus? - var cgmManagerStatus: CGMManagerStatus? - var pumpStatusHighlight: DeviceStatusHighlight? - } - - func waitOnDataQueue(timeout: TimeInterval = 1.0) { - let e = expectation(description: "dataQueue") - loopDataManager.getLoopState { _, _ in - e.fulfill() - } - wait(for: [e], timeout: timeout) - } - - func testValidateMaxTempBasalDoesntCancelTempBasalIfHigher() { - let dose = DoseEntry(type: .tempBasal, startDate: Date(), endDate: nil, value: 3.0, unit: .unitsPerHour, deliveredUnits: nil, description: nil, syncIdentifier: nil, scheduledBasalRate: nil) - setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) - // This wait is working around the issue presented by LoopDataManager.init(). It cancels the temp basal if - // `isClosedLoop` is false (which it is from `setUp` above). When that happens, it races with - // `maxTempBasalSavePreflight` below. This ensures only one happens at a time. - waitOnDataQueue() - let delegate = MockDelegate() - loopDataManager.delegate = delegate - var error: Error? - let exp = expectation(description: #function) - XCTAssertNil(delegate.recommendation) - loopDataManager.maxTempBasalSavePreflight(unitsPerHour: 5.0) { - error = $0 - exp.fulfill() - } - wait(for: [exp], timeout: 1.0) - XCTAssertNil(error) - XCTAssertNil(delegate.recommendation) - XCTAssertTrue(dosingDecisionStore.dosingDecisions.isEmpty) - } - - func testValidateMaxTempBasalCancelsTempBasalIfLower() { - let dose = DoseEntry(type: .tempBasal, startDate: Date(), endDate: nil, value: 5.0, unit: .unitsPerHour, deliveredUnits: nil, description: nil, syncIdentifier: nil, scheduledBasalRate: nil) - setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) - // This wait is working around the issue presented by LoopDataManager.init(). It cancels the temp basal if - // `isClosedLoop` is false (which it is from `setUp` above). When that happens, it races with - // `maxTempBasalSavePreflight` below. This ensures only one happens at a time. - waitOnDataQueue() - let delegate = MockDelegate() - loopDataManager.delegate = delegate - var error: Error? - let exp = expectation(description: #function) - XCTAssertNil(delegate.recommendation) - loopDataManager.maxTempBasalSavePreflight(unitsPerHour: 3.0) { - error = $0 - exp.fulfill() - } - wait(for: [exp], timeout: 1.0) - XCTAssertNil(error) - XCTAssertEqual(delegate.recommendation, AutomaticDoseRecommendation(basalAdjustment: .cancel)) - XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "maximumBasalRateChanged") - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, AutomaticDoseRecommendation(basalAdjustment: .cancel)) - } - - func testChangingMaxBasalUpdatesLoopData() { - setUp(for: .highAndStable) - waitOnDataQueue() - var loopDataUpdated = false - let exp = expectation(description: #function) - let observer = NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: nil, queue: nil) { _ in - loopDataUpdated = true - exp.fulfill() - } - XCTAssertFalse(loopDataUpdated) - loopDataManager.mutateSettings { $0.maximumBasalRatePerHour = 2.0 } - wait(for: [exp], timeout: 1.0) - XCTAssertTrue(loopDataUpdated) - NotificationCenter.default.removeObserver(observer) - } - - func testOpenLoopCancelsTempBasal() { - let dose = DoseEntry(type: .tempBasal, startDate: Date(), value: 1.0, unit: .unitsPerHour) - setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) - waitOnDataQueue() - let delegate = MockDelegate() - loopDataManager.delegate = delegate - let exp = expectation(description: #function) - let observer = NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: nil, queue: nil) { _ in - exp.fulfill() - } - automaticDosingStatus.automaticDosingEnabled = false - wait(for: [exp], timeout: 1.0) - let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: .cancel) - XCTAssertEqual(delegate.recommendation, expectedAutomaticDoseRecommendation) - XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "automaticDosingDisabled") - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) - NotificationCenter.default.removeObserver(observer) - } - - func testReceivedUnreliableCGMReadingCancelsTempBasal() { - let dose = DoseEntry(type: .tempBasal, startDate: Date(), value: 5.0, unit: .unitsPerHour) - setUp(for: .highAndStable, basalDeliveryState: .tempBasal(dose)) - waitOnDataQueue() - let delegate = MockDelegate() - loopDataManager.delegate = delegate - let exp = expectation(description: #function) - let observer = NotificationCenter.default.addObserver(forName: .LoopDataUpdated, object: nil, queue: nil) { _ in - exp.fulfill() - } - loopDataManager.receivedUnreliableCGMReading() - wait(for: [exp], timeout: 1.0) - let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: .cancel) - XCTAssertEqual(delegate.recommendation, expectedAutomaticDoseRecommendation) - XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "unreliableCGMData") - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) - NotificationCenter.default.removeObserver(observer) - } - - func testLoopEnactsTempBasalWithoutManualBolusRecommendation() { - setUp(for: .highAndStable) - waitOnDataQueue() - let delegate = MockDelegate() - loopDataManager.delegate = delegate - let exp = expectation(description: #function) - let observer = NotificationCenter.default.addObserver(forName: .LoopCompleted, object: nil, queue: nil) { _ in - exp.fulfill() - } - loopDataManager.loop() - wait(for: [exp], timeout: 1.0) - let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: TempBasalRecommendation(unitsPerHour: 4.577747629410191, duration: .minutes(30))) - XCTAssertEqual(delegate.recommendation, expectedAutomaticDoseRecommendation) - XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) - if dosingDecisionStore.dosingDecisions.count == 1 { - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "loop") - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) - XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRecommendation) - XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRequested) - } - NotificationCenter.default.removeObserver(observer) - } - - func testLoopRecommendsTempBasalWithoutEnactingIfOpenLoop() { - setUp(for: .highAndStable) - automaticDosingStatus.automaticDosingEnabled = false - waitOnDataQueue() - let delegate = MockDelegate() - loopDataManager.delegate = delegate - let exp = expectation(description: #function) - let observer = NotificationCenter.default.addObserver(forName: .LoopCompleted, object: nil, queue: nil) { _ in - exp.fulfill() - } - loopDataManager.loop() - wait(for: [exp], timeout: 1.0) - let expectedAutomaticDoseRecommendation = AutomaticDoseRecommendation(basalAdjustment: TempBasalRecommendation(unitsPerHour: 4.577747629410191, duration: .minutes(30))) - XCTAssertNil(delegate.recommendation) - XCTAssertEqual(dosingDecisionStore.dosingDecisions.count, 1) - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].reason, "loop") - XCTAssertEqual(dosingDecisionStore.dosingDecisions[0].automaticDoseRecommendation, expectedAutomaticDoseRecommendation) - XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRecommendation) - XCTAssertNil(dosingDecisionStore.dosingDecisions[0].manualBolusRequested) - NotificationCenter.default.removeObserver(observer) - } - - func testLoopGetStateRecommendsManualBolus() { - setUp(for: .highAndStable) - let exp = expectation(description: #function) - var recommendedBolus: ManualBolusRecommendation? - loopDataManager.getLoopState { (_, loopState) in - recommendedBolus = try? loopState.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: true) - exp.fulfill() - } - wait(for: [exp], timeout: 100000.0) - XCTAssertEqual(recommendedBolus!.amount, 1.82, accuracy: 0.01) - } - - func testLoopGetStateRecommendsManualBolusWithMomentum() { - setUp(for: .highAndRisingWithCOB) - let exp = expectation(description: #function) - var recommendedBolus: ManualBolusRecommendation? - loopDataManager.getLoopState { (_, loopState) in - recommendedBolus = try? loopState.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: true) - exp.fulfill() - } - wait(for: [exp], timeout: 1.0) - XCTAssertEqual(recommendedBolus!.amount, 1.62, accuracy: 0.01) - } - - func testLoopGetStateRecommendsManualBolusWithoutMomentum() { - setUp(for: .highAndRisingWithCOB) - let exp = expectation(description: #function) - var recommendedBolus: ManualBolusRecommendation? - loopDataManager.getLoopState { (_, loopState) in - recommendedBolus = try? loopState.recommendBolus(consideringPotentialCarbEntry: nil, replacingCarbEntry: nil, considerPositiveVelocityAndRC: false) - exp.fulfill() - } - wait(for: [exp], timeout: 1.0) - XCTAssertEqual(recommendedBolus!.amount, 1.52, accuracy: 0.01) - } - - func testIsClosedLoopAvoidsTriggeringTempBasalCancelOnCreation() { - let settings = LoopSettings( - dosingEnabled: false, - glucoseTargetRangeSchedule: glucoseTargetRangeSchedule, - maximumBasalRatePerHour: maxBasalRate, - maximumBolus: maxBolus, - suspendThreshold: suspendThreshold - ) - - let doseStore = MockDoseStore() - let glucoseStore = MockGlucoseStore() - let carbStore = MockCarbStore() - - let currentDate = Date() - - dosingDecisionStore = MockDosingDecisionStore() - automaticDosingStatus = AutomaticDosingStatus(automaticDosingEnabled: false, isAutomaticDosingAllowed: true) - let existingTempBasal = DoseEntry( - type: .tempBasal, - startDate: currentDate.addingTimeInterval(-.minutes(2)), - endDate: currentDate.addingTimeInterval(.minutes(28)), - value: 1.0, - unit: .unitsPerHour, - deliveredUnits: nil, - description: "Mock Temp Basal", - syncIdentifier: "asdf", - scheduledBasalRate: nil, - insulinType: .novolog, - automatic: true, - manuallyEntered: false, - isMutable: true) - loopDataManager = LoopDataManager( - lastLoopCompleted: currentDate.addingTimeInterval(-.minutes(5)), - basalDeliveryState: .tempBasal(existingTempBasal), - settings: settings, - overrideHistory: TemporaryScheduleOverrideHistory(), - analyticsServicesManager: AnalyticsServicesManager(), - localCacheDuration: .days(1), - doseStore: doseStore, - glucoseStore: glucoseStore, - carbStore: carbStore, - dosingDecisionStore: dosingDecisionStore, - latestStoredSettingsProvider: MockLatestStoredSettingsProvider(), - now: { currentDate }, - pumpInsulinType: .novolog, - automaticDosingStatus: automaticDosingStatus, - trustedTimeOffset: { 0 } - ) - let mockDelegate = MockDelegate() - loopDataManager.delegate = mockDelegate - - // Dose enacting happens asynchronously, as does receiving isClosedLoop signals - waitOnMain(timeout: 5) - XCTAssertNil(mockDelegate.recommendation) - } - } -extension LoopDataManagerDosingTests { +extension LoopDataManagerTests { public var bundle: Bundle { return Bundle(for: type(of: self)) } diff --git a/LoopTests/Managers/MealDetectionManagerTests.swift b/LoopTests/Managers/MealDetectionManagerTests.swift new file mode 100644 index 0000000000..d987e3cc3f --- /dev/null +++ b/LoopTests/Managers/MealDetectionManagerTests.swift @@ -0,0 +1,450 @@ +// +// MealDetectionManagerTests.swift +// LoopTests +// +// Created by Anna Quinlan on 11/28/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import XCTest +import HealthKit +import LoopCore +import LoopKit +@testable import Loop + +enum MissedMealTestType { + private static var dateFormatter = ISO8601DateFormatter.localTimeDate() + + /// No meal is present + case noMeal + /// No meal is present, but if the counteraction effects aren't clamped properly it will look like there's a missed meal + case noMealCounteractionEffectsNeedClamping + // No meal is present and there is COB + case noMealWithCOB + /// Missed meal with no carbs on board + case missedMealNoCOB + /// Missed meal with carbs logged prior to it + case missedMealWithCOB + /// CGM data is noisy, but no meal is present + case noisyCGM + /// Realistic counteraction effects with multiple meals + case manyMeals + /// Test case to test dynamic computation of missed meal carb amount + case dynamicCarbAutofill + /// Test case for purely testing the notifications (not the algorithm) + case notificationTest +} + +extension MissedMealTestType { + var counteractionEffectFixture: String { + switch self { + case .missedMealNoCOB, .noMealWithCOB, .notificationTest: + return "missed_meal_counteraction_effect" + case .noMeal: + return "long_interval_counteraction_effect" + case .noMealCounteractionEffectsNeedClamping: + return "needs_clamping_counteraction_effect" + case .noisyCGM: + return "noisy_cgm_counteraction_effect" + case .manyMeals, .missedMealWithCOB: + return "realistic_report_counteraction_effect" + case .dynamicCarbAutofill: + return "dynamic_autofill_counteraction_effect" + } + } + + var currentDate: Date { + switch self { + case .missedMealNoCOB, .noMealWithCOB, .notificationTest: + return Self.dateFormatter.date(from: "2022-10-17T23:28:45")! + case .noMeal, .noMealCounteractionEffectsNeedClamping: + return Self.dateFormatter.date(from: "2022-10-17T02:49:16")! + case .noisyCGM: + return Self.dateFormatter.date(from: "2022-10-19T20:46:23")! + case .missedMealWithCOB: + return Self.dateFormatter.date(from: "2022-10-19T19:50:15")! + case .manyMeals: + return Self.dateFormatter.date(from: "2022-10-19T21:50:15")! + case .dynamicCarbAutofill: + return Self.dateFormatter.date(from: "2022-10-17T07:51:09")! + } + } + + var missedMealDate: Date? { + switch self { + case .missedMealNoCOB: + return Self.dateFormatter.date(from: "2022-10-17T21:55:00") + case .missedMealWithCOB: + return Self.dateFormatter.date(from: "2022-10-19T19:00:00") + case .manyMeals: + return Self.dateFormatter.date(from: "2022-10-19T20:40:00 ") + case .dynamicCarbAutofill: + return Self.dateFormatter.date(from: "2022-10-17T07:20:00")! + default: + return nil + } + } + + var carbEntries: [NewCarbEntry] { + switch self { + case .missedMealWithCOB: + return [ + NewCarbEntry(quantity: HKQuantity(unit: .gram(), doubleValue: 30), + startDate: Self.dateFormatter.date(from: "2022-10-19T15:41:36")!, + foodType: nil, + absorptionTime: nil), + NewCarbEntry(quantity: HKQuantity(unit: .gram(), doubleValue: 10), + startDate: Self.dateFormatter.date(from: "2022-10-19T17:36:58")!, + foodType: nil, + absorptionTime: nil) + ] + case .noMealWithCOB: + return [ + NewCarbEntry(quantity: HKQuantity(unit: .gram(), doubleValue: 30), + startDate: Self.dateFormatter.date(from: "2022-10-17T22:40:00")!, + foodType: nil, + absorptionTime: nil) + ] + case .manyMeals: + return [ + NewCarbEntry(quantity: HKQuantity(unit: .gram(), doubleValue: 30), + startDate: Self.dateFormatter.date(from: "2022-10-19T15:41:36")!, + foodType: nil, + absorptionTime: nil), + NewCarbEntry(quantity: HKQuantity(unit: .gram(), doubleValue: 10), + startDate: Self.dateFormatter.date(from: "2022-10-19T17:36:58")!, + foodType: nil, + absorptionTime: nil), + NewCarbEntry(quantity: HKQuantity(unit: .gram(), doubleValue: 40), + startDate: Self.dateFormatter.date(from: "2022-10-19T19:11:43")!, + foodType: nil, + absorptionTime: nil) + ] + default: + return [] + } + } + + var carbSchedule: CarbRatioSchedule { + CarbRatioSchedule( + unit: .gram(), + dailyItems: [ + RepeatingScheduleValue(startTime: 0.0, value: 15.0), + ], + timeZone: .utcTimeZone + )! + } + + var insulinSensitivitySchedule: InsulinSensitivitySchedule { + InsulinSensitivitySchedule( + unit: HKUnit.milligramsPerDeciliter, + dailyItems: [ + RepeatingScheduleValue(startTime: 0.0, value: 50.0) + ], + timeZone: .utcTimeZone + )! + } +} + +class MealDetectionManagerTests: XCTestCase { + let dateFormatter = ISO8601DateFormatter.localTimeDate() + let pumpManager = MockPumpManager() + + var mealDetectionManager: MealDetectionManager! + var carbStore: CarbStore! + + var now: Date { + mealDetectionManager.test_currentDate! + } + + var bolusUnits: Double? + var bolusDurationEstimator: ((Double) -> TimeInterval?)! + + @discardableResult func setUp(for testType: MissedMealTestType) -> [GlucoseEffectVelocity] { + let healthStore = HKHealthStoreMock() + + carbStore = CarbStore( + healthStore: healthStore, + cacheStore: PersistenceController(directoryURL: URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(UUID().uuidString, isDirectory: true)), + cacheLength: .hours(24), + defaultAbsorptionTimes: (fast: .minutes(30), medium: .hours(3), slow: .hours(5)), + observationInterval: 0, + overrideHistory: TemporaryScheduleOverrideHistory(), + provenanceIdentifier: Bundle.main.bundleIdentifier!, + test_currentDate: testType.currentDate) + + // Set up schedules + carbStore.carbRatioSchedule = testType.carbSchedule + carbStore.insulinSensitivitySchedule = testType.insulinSensitivitySchedule + + // Add any needed carb entries to the carb store + let updateGroup = DispatchGroup() + testType.carbEntries.forEach { carbEntry in + updateGroup.enter() + carbStore.addCarbEntry(carbEntry) { result in + if case .failure(_) = result { + XCTFail("Failed to add carb entry to carb store") + } + + updateGroup.leave() + } + } + _ = updateGroup.wait(timeout: .now() + .seconds(5)) + + mealDetectionManager = MealDetectionManager( + carbRatioScheduleApplyingOverrideHistory: carbStore.carbRatioScheduleApplyingOverrideHistory, + insulinSensitivityScheduleApplyingOverrideHistory: carbStore.insulinSensitivityScheduleApplyingOverrideHistory, + maximumBolus: 5, + test_currentDate: testType.currentDate + ) + + bolusDurationEstimator = { units in + self.bolusUnits = units + return self.pumpManager.estimatedDuration(toBolus: units) + } + + // Fetch & return the counteraction effects for the test + return counteractionEffects(for: testType) + } + + private func counteractionEffects(for testType: MissedMealTestType) -> [GlucoseEffectVelocity] { + let fixture: [JSONDictionary] = loadFixture(testType.counteractionEffectFixture) + let dateFormatter = ISO8601DateFormatter.localTimeDate() + + return fixture.map { + GlucoseEffectVelocity(startDate: dateFormatter.date(from: $0["startDate"] as! String)!, + endDate: dateFormatter.date(from: $0["endDate"] as! String)!, + quantity: HKQuantity(unit: HKUnit(from: $0["unit"] as! String), + doubleValue:$0["value"] as! Double)) + } + } + + private func mealDetectionCarbEffects(using insulinCounteractionEffects: [GlucoseEffectVelocity]) -> [GlucoseEffect] { + let carbEffectStart = now.addingTimeInterval(-MissedMealSettings.maxRecency) + + var carbEffects: [GlucoseEffect] = [] + + let updateGroup = DispatchGroup() + updateGroup.enter() + carbStore.getGlucoseEffects(start: carbEffectStart, end: now, effectVelocities: insulinCounteractionEffects) { result in + defer { updateGroup.leave() } + + guard case .success((_, let effects)) = result else { + XCTFail("Failed to fetch glucose effects to check for missed meal") + return + } + carbEffects = effects + } + _ = updateGroup.wait(timeout: .now() + .seconds(5)) + + return carbEffects + } + + override func tearDown() { + mealDetectionManager.lastMissedMealNotification = nil + mealDetectionManager = nil + UserDefaults.standard.missedMealNotificationsEnabled = false + } + + // MARK: - Algorithm Tests + func testNoMissedMeal() { + let counteractionEffects = setUp(for: .noMeal) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .noMissedMeal) + updateGroup.leave() + } + updateGroup.wait() + } + + func testNoMissedMeal_WithCOB() { + let counteractionEffects = setUp(for: .noMealWithCOB) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .noMissedMeal) + updateGroup.leave() + } + updateGroup.wait() + } + + func testMissedMeal_NoCarbEntry() { + let testType = MissedMealTestType.missedMealNoCOB + let counteractionEffects = setUp(for: testType) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .hasMissedMeal(startTime: testType.missedMealDate!, carbAmount: 55)) + updateGroup.leave() + } + updateGroup.wait() + } + + func testDynamicCarbAutofill() { + let testType = MissedMealTestType.dynamicCarbAutofill + let counteractionEffects = setUp(for: testType) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .hasMissedMeal(startTime: testType.missedMealDate!, carbAmount: 25)) + updateGroup.leave() + } + updateGroup.wait() + } + + func testMissedMeal_MissedMealAndCOB() { + let testType = MissedMealTestType.missedMealWithCOB + let counteractionEffects = setUp(for: testType) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .hasMissedMeal(startTime: testType.missedMealDate!, carbAmount: 50)) + updateGroup.leave() + } + updateGroup.wait() + } + + func testNoisyCGM() { + let counteractionEffects = setUp(for: .noisyCGM) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .noMissedMeal) + updateGroup.leave() + } + updateGroup.wait() + } + + func testManyMeals() { + let testType = MissedMealTestType.manyMeals + let counteractionEffects = setUp(for: testType) + + let updateGroup = DispatchGroup() + updateGroup.enter() + mealDetectionManager.hasMissedMeal(insulinCounteractionEffects: counteractionEffects, carbEffects: mealDetectionCarbEffects(using: counteractionEffects)) { status in + XCTAssertEqual(status, .hasMissedMeal(startTime: testType.missedMealDate!, carbAmount: 40)) + updateGroup.leave() + } + updateGroup.wait() + } + + // MARK: - Notification Tests + func testNoMissedMealLastNotificationTime() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let status = MissedMealStatus.noMissedMeal + mealDetectionManager.manageMealNotifications(for: status, bolusDurationEstimator: { _ in nil }) + + XCTAssertNil(mealDetectionManager.lastMissedMealNotification) + } + + func testMissedMealUpdatesLastNotificationTime() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: 40) + mealDetectionManager.manageMealNotifications(for: status, bolusDurationEstimator: { _ in nil }) + + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.deliveryTime, now) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.carbAmount, 40) + } + + func testMissedMealWithoutNotificationsEnabled() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = false + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: 40) + mealDetectionManager.manageMealNotifications(for: status, bolusDurationEstimator: { _ in nil }) + + XCTAssertNil(mealDetectionManager.lastMissedMealNotification) + } + + func testMissedMealWithTooRecentNotificationTime() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let oldTime = now.addingTimeInterval(.hours(1)) + let oldNotification = MissedMealNotification(deliveryTime: oldTime, carbAmount: 40) + mealDetectionManager.lastMissedMealNotification = oldNotification + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: MissedMealSettings.minCarbThreshold) + mealDetectionManager.manageMealNotifications(for: status, bolusDurationEstimator: { _ in nil }) + + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification, oldNotification) + } + + func testMissedMealCarbClamping() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: 120) + mealDetectionManager.manageMealNotifications(for: status, bolusDurationEstimator: { _ in nil }) + + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.deliveryTime, now) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.carbAmount, 75) + } + + func testMissedMealNoPendingBolus() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: 40) + mealDetectionManager.manageMealNotifications(for: status, pendingAutobolusUnits: 0, bolusDurationEstimator: bolusDurationEstimator) + + /// The bolus units time delegate should never be called if there are 0 pending units + XCTAssertNil(bolusUnits) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.deliveryTime, now) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.carbAmount, 40) + } + + func testMissedMealLongPendingBolus() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: 40) + mealDetectionManager.manageMealNotifications(for: status, pendingAutobolusUnits: 10, bolusDurationEstimator: bolusDurationEstimator) + + XCTAssertEqual(bolusUnits, 10) + /// There shouldn't be a delay in delivering notification, since the autobolus will take the length of the notification window to deliver + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.deliveryTime, now) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.carbAmount, 40) + } + + func testNoMissedMealShortPendingBolus_DelaysNotificationTime() { + setUp(for: .notificationTest) + UserDefaults.standard.missedMealNotificationsEnabled = true + + let status = MissedMealStatus.hasMissedMeal(startTime: now, carbAmount: 30) + mealDetectionManager.manageMealNotifications(for: status, pendingAutobolusUnits: 2, bolusDurationEstimator: bolusDurationEstimator) + + let expectedDeliveryTime = now.addingTimeInterval(TimeInterval(80)) + XCTAssertEqual(bolusUnits, 2) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.deliveryTime, expectedDeliveryTime) + + mealDetectionManager.lastMissedMealNotification = nil + mealDetectionManager.manageMealNotifications(for: status, pendingAutobolusUnits: 4.5, bolusDurationEstimator: bolusDurationEstimator) + + let expectedDeliveryTime2 = now.addingTimeInterval(TimeInterval(minutes: 3)) + XCTAssertEqual(bolusUnits, 4.5) + XCTAssertEqual(mealDetectionManager.lastMissedMealNotification?.deliveryTime, expectedDeliveryTime2) + } +} + +extension MealDetectionManagerTests { + public var bundle: Bundle { + return Bundle(for: type(of: self)) + } + + public func loadFixture(_ resourceName: String) -> T { + let path = bundle.path(forResource: resourceName, ofType: "json")! + return try! JSONSerialization.jsonObject(with: Data(contentsOf: URL(fileURLWithPath: path)), options: []) as! T + } +} diff --git a/LoopTests/Managers/SupportManagerTests.swift b/LoopTests/Managers/SupportManagerTests.swift index b2b20b89ce..d1fd0d5163 100644 --- a/LoopTests/Managers/SupportManagerTests.swift +++ b/LoopTests/Managers/SupportManagerTests.swift @@ -23,12 +23,18 @@ class SupportManagerTests: XCTestCase { nil } var mockResult: Result = .success(.default) - func checkVersion(bundleIdentifier: String, currentVersion: String, completion: @escaping (Result) -> Void) { - completion(mockResult) + func checkVersion(bundleIdentifier: String, currentVersion: String) async -> VersionUpdate? { + switch mockResult { + case .success(let update): + return update + case .failure: + return nil + } } weak var delegate: SupportUIDelegate? } class MockSupport: Mixin, SupportUI { + func configurationMenuItems() -> [AnyView] { return [] } static var supportIdentifier: String { "SupportManagerTestsMockSupport" } override init() { super.init() } required init?(rawState: RawStateValue) { super.init() } @@ -40,6 +46,7 @@ class SupportManagerTests: XCTestCase { func resetLoop() {} } class AnotherMockSupport: Mixin, SupportUI { + func configurationMenuItems() -> [AnyView] { return [] } static var supportIdentifier: String { "SupportManagerTestsAnotherMockSupport" } override init() { super.init() } required init?(rawState: RawStateValue) { super.init() } @@ -70,37 +77,35 @@ class SupportManagerTests: XCTestCase { supportManager.addSupport(mockSupport) } - func getVersion(fn: String = #function) -> VersionUpdate? { - let e = expectation(description: fn) - var result: VersionUpdate? - supportManager.checkVersion { - result = $0 - e.fulfill() - } - wait(for: [e], timeout: 1.0) - return result - } - - func testVersionCheckOneService() throws { - XCTAssertEqual(VersionUpdate.none, getVersion()) + func testVersionCheckOneService() async throws { + let result = await supportManager.checkVersion() + XCTAssertEqual(VersionUpdate.noUpdateNeeded, result) mockSupport.mockResult = .success(.required) - XCTAssertEqual(.required, getVersion()) + + let result2 = await supportManager.checkVersion() + XCTAssertEqual(.required, result2) } - func testVersionCheckOneServiceError() throws { + func testVersionCheckOneServiceError() async throws { // Error doesn't really do anything but log mockSupport.mockResult = .failure(MockError.nothing) - XCTAssertEqual(VersionUpdate.none, getVersion()) + let result = await supportManager.checkVersion() + XCTAssertEqual(VersionUpdate.noUpdateNeeded, result) } - func testVersionCheckMultipleServices() throws { + func testVersionCheckMultipleServices() async throws { let anotherSupport = AnotherMockSupport() supportManager.addSupport(anotherSupport) - XCTAssertEqual(VersionUpdate.none, getVersion()) + let result = await supportManager.checkVersion() + XCTAssertEqual(VersionUpdate.noUpdateNeeded, result) + anotherSupport.mockResult = .success(.required) - XCTAssertEqual(.required, getVersion()) + let result2 = await supportManager.checkVersion() + XCTAssertEqual(.required, result2) + + let result3 = await supportManager.checkVersion() mockSupport.mockResult = .success(.recommended) - XCTAssertEqual(.required, getVersion()) + XCTAssertEqual(.required, result3) } } diff --git a/LoopTests/Mock Stores/HKHealthStoreMock.swift b/LoopTests/Mock Stores/HKHealthStoreMock.swift new file mode 100644 index 0000000000..6f8127d3e4 --- /dev/null +++ b/LoopTests/Mock Stores/HKHealthStoreMock.swift @@ -0,0 +1,82 @@ +// +// HKHealthStoreMock.swift +// LoopTests +// +// Created by Anna Quinlan on 11/28/22. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import HealthKit +import Foundation +import LoopKit + + +class HKHealthStoreMock: HKHealthStore { + var saveError: Error? + var deleteError: Error? + var queryResults: (samples: [HKSample]?, error: Error?)? + var lastQuery: HKQuery? + var authorizationStatus: HKAuthorizationStatus? + + private var saveHandler: ((_ objects: [HKObject], _ success: Bool, _ error: Error?) -> Void)? + private var deleteObjectsHandler: ((_ objectType: HKObjectType, _ predicate: NSPredicate, _ success: Bool, _ count: Int, _ error: Error?) -> Void)? + + let queue = DispatchQueue(label: "HKHealthStoreMock") + + override func save(_ object: HKObject, withCompletion completion: @escaping (Bool, Error?) -> Void) { + queue.async { + self.saveHandler?([object], self.saveError == nil, self.saveError) + completion(self.saveError == nil, self.saveError) + } + } + + override func save(_ objects: [HKObject], withCompletion completion: @escaping (Bool, Error?) -> Void) { + queue.async { + self.saveHandler?(objects, self.saveError == nil, self.saveError) + completion(self.saveError == nil, self.saveError) + } + } + + override func delete(_ objects: [HKObject], withCompletion completion: @escaping (Bool, Error?) -> Void) { + queue.async { + completion(self.deleteError == nil, self.deleteError) + } + } + + override func deleteObjects(of objectType: HKObjectType, predicate: NSPredicate, withCompletion completion: @escaping (Bool, Int, Error?) -> Void) { + queue.async { + self.deleteObjectsHandler?(objectType, predicate, self.deleteError == nil, 0, self.deleteError) + completion(self.deleteError == nil, 0, self.deleteError) + } + } + + func setSaveHandler(_ saveHandler: ((_ objects: [HKObject], _ success: Bool, _ error: Error?) -> Void)?) { + queue.sync { + self.saveHandler = saveHandler + } + } + + override func requestAuthorization(toShare typesToShare: Set?, read typesToRead: Set?, completion: @escaping (Bool, Error?) -> Void) { + DispatchQueue.main.async { + completion(true, nil) + } + } + + override func authorizationStatus(for type: HKObjectType) -> HKAuthorizationStatus { + return authorizationStatus ?? .notDetermined + } + + func setDeletedObjectsHandler(_ deleteObjectsHandler: ((_ objectType: HKObjectType, _ predicate: NSPredicate, _ success: Bool, _ count: Int, _ error: Error?) -> Void)?) { + queue.sync { + self.deleteObjectsHandler = deleteObjectsHandler + } + } +} + +extension HKHealthStoreMock { + + override func execute(_ query: HKQuery) { + self.lastQuery = query + } +} + diff --git a/LoopTests/Mock Stores/MockCarbStore.swift b/LoopTests/Mock Stores/MockCarbStore.swift index f61fcd70ed..0b2555039d 100644 --- a/LoopTests/Mock Stores/MockCarbStore.swift +++ b/LoopTests/Mock Stores/MockCarbStore.swift @@ -11,11 +11,11 @@ import LoopKit @testable import Loop class MockCarbStore: CarbStoreProtocol { - init(for test: DataManagerTestType = .flatAndStable) { - self.testType = test // The store returns different effect values based on the test type + init(for scenario: DosingTestScenario = .flatAndStable) { + self.scenario = scenario // The store returns different effect values based on the scenario } - var testType: DataManagerTestType + var scenario: DosingTestScenario var sampleType: HKSampleType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryCarbohydrates)! @@ -119,7 +119,7 @@ extension MockCarbStore { } var fixtureToLoad: String { - switch testType { + switch scenario { case .flatAndStable: return "flat_and_stable_carb_effect" case .highAndStable: diff --git a/LoopTests/Mock Stores/MockDoseStore.swift b/LoopTests/Mock Stores/MockDoseStore.swift index 62cd924118..d85f54d1ee 100644 --- a/LoopTests/Mock Stores/MockDoseStore.swift +++ b/LoopTests/Mock Stores/MockDoseStore.swift @@ -12,15 +12,15 @@ import LoopKit class MockDoseStore: DoseStoreProtocol { - init(for test: DataManagerTestType = .flatAndStable) { - self.testType = test // The store returns different effect values based on the test type - self.pumpEventQueryAfterDate = MockDoseStore.currentDate(for: test) - self.lastAddedPumpData = MockDoseStore.currentDate(for: test) + init(for scenario: DosingTestScenario = .flatAndStable) { + self.scenario = scenario // The store returns different effect values based on the scenario + self.pumpEventQueryAfterDate = MockDoseStore.currentDate(for: scenario) + self.lastAddedPumpData = MockDoseStore.currentDate(for: scenario) } static let dateFormatter = ISO8601DateFormatter.localTimeDate() - var testType: DataManagerTestType + var scenario: DosingTestScenario var basalProfileApplyingOverrideHistory: BasalRateSchedule? @@ -50,7 +50,7 @@ class MockDoseStore: DoseStoreProtocol { var lastReservoirValue: ReservoirValue? var lastAddedPumpData: Date - + func addPumpEvents(_ events: [NewPumpEvent], lastReconciliation: Date?, completion: @escaping (DoseStore.DoseStoreError?) -> Void) { completion(nil) } @@ -60,7 +60,7 @@ class MockDoseStore: DoseStoreProtocol { } func insulinOnBoard(at date: Date, completion: @escaping (DoseStoreResult) -> Void) { - completion(.failure(.configurationError)) + completion(.success(.init(startDate: MockDoseStore.currentDate(for: scenario), value: 9.5))) } func generateDiagnosticReport(_ completion: @escaping (String) -> Void) { @@ -102,7 +102,7 @@ class MockDoseStore: DoseStoreProtocol { })) } - static func currentDate(for testType: DataManagerTestType) -> Date { + static func currentDate(for testType: DosingTestScenario) -> Date { switch testType { case .flatAndStable: return dateFormatter.date(from: "2020-08-11T20:45:02")! @@ -131,7 +131,7 @@ extension MockDoseStore { } var fixtureToLoad: String { - switch testType { + switch scenario { case .flatAndStable: return "flat_and_stable_insulin_effect" case .highAndStable: diff --git a/LoopTests/Mock Stores/MockGlucoseStore.swift b/LoopTests/Mock Stores/MockGlucoseStore.swift index 2a5e1d2123..e036bcbfb5 100644 --- a/LoopTests/Mock Stores/MockGlucoseStore.swift +++ b/LoopTests/Mock Stores/MockGlucoseStore.swift @@ -12,13 +12,13 @@ import LoopKit class MockGlucoseStore: GlucoseStoreProtocol { - init(for test: DataManagerTestType = .flatAndStable) { - self.testType = test // The store returns different effect values based on the test type + init(for scenario: DosingTestScenario = .flatAndStable) { + self.scenario = scenario // The store returns different effect values based on the scenario } let dateFormatter = ISO8601DateFormatter.localTimeDate() - var testType: DataManagerTestType + var scenario: DosingTestScenario var latestGlucose: GlucoseSampleValue? { return StoredGlucoseSample( @@ -107,7 +107,7 @@ extension MockGlucoseStore { } var counteractionEffectToLoad: String { - switch testType { + switch scenario { case .flatAndStable: return "flat_and_stable_counteraction_effect" case .highAndStable: @@ -124,7 +124,7 @@ extension MockGlucoseStore { } var momentumEffectToLoad: String { - switch testType { + switch scenario { case .flatAndStable: return "flat_and_stable_momentum_effect" case .highAndStable: @@ -141,7 +141,7 @@ extension MockGlucoseStore { } var glucoseStartDate: Date { - switch testType { + switch scenario { case .flatAndStable: return dateFormatter.date(from: "2020-08-11T20:45:02")! case .highAndStable: @@ -158,7 +158,7 @@ extension MockGlucoseStore { } var latestGlucoseValue: Double { - switch testType { + switch scenario { case .flatAndStable: return 123.42849966275706 case .highAndStable: diff --git a/LoopTests/Models/Remote/BolusActionTests.swift b/LoopTests/Models/Remote/BolusActionTests.swift new file mode 100644 index 0000000000..2129ea68b4 --- /dev/null +++ b/LoopTests/Models/Remote/BolusActionTests.swift @@ -0,0 +1,101 @@ +// +// BolusActionTests.swift +// LoopKitTests +// +// Created by Bill Gestrich on 1/14/23. +// Copyright © 2023 LoopKit Authors. All rights reserved. +// + +import XCTest +@testable import Loop +import LoopKit + +final class BolusActionTests: XCTestCase { + + override func setUpWithError() throws { + } + + override func tearDownWithError() throws { + } + + func testToValidBolusAtMaxAmount_Succeeds() throws { + + //Arrange + let maxBolusAmount = 10.0 + let bolusAmount = maxBolusAmount + let action = BolusAction(amountInUnits: bolusAmount) + + //Act + let validatedBolusAmount = try action.toValidBolusAmount(maximumBolus: 10.0) + + //Assert + XCTAssertEqual(validatedBolusAmount, bolusAmount) + + } + + func testToValidBolusAmount_AboveMaxAmount_Fails() throws { + + //Arrange + let maxBolusAmount = 10.0 + let bolusAmount = maxBolusAmount + 0.1 + let action = BolusAction(amountInUnits: bolusAmount) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidBolusAmount(maximumBolus: maxBolusAmount) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? BolusActionError, case .exceedsMaxBolus = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidBolusAmount_AtZero_Fails() throws { + + //Arrange + let bolusAmount = 0.0 + let action = BolusAction(amountInUnits: bolusAmount) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidBolusAmount(maximumBolus: 10.0) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? BolusActionError, case .invalidBolus = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidBolusAmount_NegativeAmount_Fails() throws { + + //Arrange + let bolusAmount = -1.0 + let action = BolusAction(amountInUnits: bolusAmount) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidBolusAmount(maximumBolus: 10.0) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? BolusActionError, case .invalidBolus = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + +} diff --git a/LoopTests/Models/Remote/CarbActionTests.swift b/LoopTests/Models/Remote/CarbActionTests.swift new file mode 100644 index 0000000000..277051252a --- /dev/null +++ b/LoopTests/Models/Remote/CarbActionTests.swift @@ -0,0 +1,402 @@ +// +// CarbActionTests.swift +// LoopTests +// +// Created by Bill Gestrich on 1/14/23. +// Copyright © 2022 LoopKit Authors. All rights reserved. +// + +import XCTest +import HealthKit +@testable import Loop +import LoopKit + +class CarbActionTests: XCTestCase { + + override func setUpWithError() throws { + } + + override func tearDownWithError() throws { + } + + + func testToValidCarbEntry_Succeeds() throws { + + //Arrange + let expectedCarbsInGrams = 15.0 + let expectedDate = Date() + let expectedAbsorptionTime = TimeInterval(hours: 4.0) + let foodType = "🍕" + + let action = CarbAction(amountInGrams: expectedCarbsInGrams, absorptionTime: expectedAbsorptionTime, foodType: foodType, startDate: expectedDate) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: expectedCarbsInGrams, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1) + ) + + //Assert + XCTAssertEqual(carbEntry.startDate, expectedDate) + XCTAssertEqual(carbEntry.absorptionTime, expectedAbsorptionTime) + XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: expectedCarbsInGrams)) + XCTAssertEqual(carbEntry.foodType, foodType) + } + + func testToValidCarbEntry_MissingAbsorptionHours_UsesDefaultAbsorption() throws { + + //Arrange + let defaultAbsorptionTime = TimeInterval(hours: 4.0) + let action = CarbAction(amountInGrams: 15.0, startDate: Date()) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: defaultAbsorptionTime, + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1)) + + //Assert + XCTAssertEqual(carbEntry.absorptionTime, defaultAbsorptionTime) + } + + func testToValidCarbEntry_AtMinAbsorptionHours_Succeeds() throws { + + //Arrange + let minAbsorptionTime = TimeInterval(hours: 0.5) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: minAbsorptionTime, + startDate: Date()) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: minAbsorptionTime, + minAbsorptionTime: minAbsorptionTime, + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1)) + + //Assert + XCTAssertEqual(carbEntry.absorptionTime, minAbsorptionTime) + } + + func testToValidCarbEntry_BelowMinAbsorptionHours_Fails() throws { + + //Arrange + let minAbsorptionTime = TimeInterval(hours: 0.5) + let aborptionOverrideTime = TimeInterval(hours: 0.4) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: aborptionOverrideTime, + startDate: Date()) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: minAbsorptionTime, + minAbsorptionTime: minAbsorptionTime, + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1) + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .invalidAbsorptionTime = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidCarbEntry_AtMaxAbsorptionHours_Succeeds() throws { + + //Arrange + let maxAbsorptionTime = TimeInterval(hours: 5.0) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: maxAbsorptionTime, + startDate: Date()) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: maxAbsorptionTime, + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: maxAbsorptionTime, + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1) + ) + + //Assert + XCTAssertEqual(carbEntry.absorptionTime, maxAbsorptionTime) + } + + func testToValidCarbEntry_AboveMaxAbsorptionHours_Fails() throws { + + //Arrange + let maxAbsorptionTime = TimeInterval(hours: 5.0) + let absorptionTime = TimeInterval(hours: 5.1) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: absorptionTime, + startDate: Date()) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: maxAbsorptionTime, + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: maxAbsorptionTime, + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1) + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .invalidAbsorptionTime = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidCarbEntry_AtMinStartTime_Succeeds() throws { + + //Arrange + let maxCarbEntryPastTime = TimeInterval(hours: -12) + let nowDate = Date() + let startDate = nowDate.addingTimeInterval(maxCarbEntryPastTime) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: TimeInterval(hours: 5.0), + startDate: startDate) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: maxCarbEntryPastTime, + maxCarbEntryFutureTime: .hours(1), + nowDate: nowDate + ) + + //Assert + XCTAssertEqual(carbEntry.startDate, startDate) + } + + func testToValidCarbEntry_BeforeMinStartTime_Fails() throws { + + //Arrange + let maxCarbEntryPastTime = TimeInterval(hours: -12) + let nowDate = Date() + let startDate = nowDate.addingTimeInterval(maxCarbEntryPastTime - 1) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: TimeInterval(hours: 5.0), + startDate: startDate) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: maxCarbEntryPastTime, + maxCarbEntryFutureTime: .hours(1) + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .invalidStartDate = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidCarbEntry_AtMaxStartTime_Succeeds() throws { + + //Arrange + let maxCarbEntryFutureTime = TimeInterval(hours: 1) + let nowDate = Date() + let startDate = nowDate.addingTimeInterval(maxCarbEntryFutureTime) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: TimeInterval(hours: 5.0), + startDate: startDate) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: maxCarbEntryFutureTime, + nowDate: nowDate + ) + + //Assert + XCTAssertEqual(carbEntry.startDate, startDate) + } + + func testToValidCarbEntry_AfterMaxStartTime_Fails() throws { + + //Arrange + let maxCarbEntryFutureTime = TimeInterval(hours: 1) + let nowDate = Date() + let startDate = nowDate.addingTimeInterval(maxCarbEntryFutureTime + 1) + let action = CarbAction(amountInGrams: 15.0, + absorptionTime: TimeInterval(hours: 5.0), + startDate: startDate) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: maxCarbEntryFutureTime + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .invalidStartDate = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidCarbEntry_AtMaxCarbs_Succeeds() throws { + + let maxCarbsAmount = 200.0 + let carbsAmount = maxCarbsAmount + + //Arrange + let action = CarbAction(amountInGrams: carbsAmount, + absorptionTime: TimeInterval(hours: 5.0), + startDate: Date()) + + //Act + let carbEntry = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: maxCarbsAmount, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: TimeInterval(hours: 1) + ) + + //Assert + XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: carbsAmount)) + } + + func testToValidCarbEntry_AboveMaxCarbs_Fails() throws { + + let maxCarbsAmount = 200.0 + let carbsAmount = maxCarbsAmount + 1 + + //Arrange + let action = CarbAction(amountInGrams: carbsAmount, + absorptionTime: TimeInterval(hours: 5.0), + startDate: Date()) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1.0) + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .exceedsMaxCarbs = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidCarbEntry_NegativeCarbs_Fails() throws { + + let carbsAmount = -1.0 + + //Arrange + let action = CarbAction(amountInGrams: carbsAmount, + absorptionTime: TimeInterval(hours: 5.0), + startDate: Date()) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1.0) + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .invalidCarbs = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidCarbEntry_ZeroCarbs_Fails() throws { + + let carbsAmount = 0.0 + + //Arrange + let action = CarbAction(amountInGrams: carbsAmount, + absorptionTime: TimeInterval(hours: 5.0), + startDate: Date()) + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidCarbEntry(defaultAbsorptionTime: TimeInterval(hours: 3.0), + minAbsorptionTime: TimeInterval(hours: 0.5), + maxAbsorptionTime: TimeInterval(hours: 5.0), + maxCarbEntryQuantity: 200, + maxCarbEntryPastTime: .hours(-12), + maxCarbEntryFutureTime: .hours(1.0) + ) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? CarbActionError, case .invalidCarbs = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + +} + + +//MARK: Utils + +func dateFormatter() -> ISO8601DateFormatter { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + return formatter +} + diff --git a/LoopTests/Models/Remote/OverrideActionTests.swift b/LoopTests/Models/Remote/OverrideActionTests.swift new file mode 100644 index 0000000000..fe9f5d7fb3 --- /dev/null +++ b/LoopTests/Models/Remote/OverrideActionTests.swift @@ -0,0 +1,152 @@ +// +// OverrideActionTests.swift +// LoopKitTests +// +// Created by Bill Gestrich on 1/14/23. +// Copyright © 2023 LoopKit Authors. All rights reserved. +// + +import XCTest +@testable import Loop +import LoopKit + +final class OverrideActionTests: XCTestCase { + + override func setUpWithError() throws { + + } + + override func tearDownWithError() throws { + + } + + func testToValidOverride_Succeeds() throws { + + //Arrange + let durationTime = TimeInterval(hours: 1.0) + let remoteAddress = "1234-54321" + let overrideName = "My-Override" + let action = OverrideAction(name: overrideName, durationTime: durationTime, remoteAddress: remoteAddress) + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: overrideName, settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + let validOverride = try action.toValidOverride(allowedPresets: presets) + + //Assert + XCTAssertEqual(validOverride.duration, .finite(durationTime)) + switch validOverride.enactTrigger { + case .remote(let triggerAddress): + XCTAssertEqual(triggerAddress, remoteAddress) + default: + XCTFail("Unexpected trigger trigger type") + } + } + + func testToValidOverride_WhenOverrideNotInPresets_Fails() throws { + + //Arrange + let action = OverrideAction(name: "Unknown-Override", durationTime: TimeInterval(hours: 1.0), remoteAddress: "1234-54321") + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: "My-Override", settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidOverride(allowedPresets: presets) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? OverrideActionError, case .unknownPreset = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + func testToValidOverride_WhenNoDuration_YieldsIndefiniteOverride() throws { + + //Arrange + let action = OverrideAction(name: "My-Override", durationTime: nil, remoteAddress: "1234-54321") + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: "My-Override", settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + let validOverride = try action.toValidOverride(allowedPresets: presets) + + //Assert + XCTAssertEqual(validOverride.duration, .indefinite) + } + + func testToValidOverride_WhenDurationZero_YieldsIndefiniteOverride() throws { + + //Arrange + let action = OverrideAction(name: "My-Override", durationTime: TimeInterval(hours: 0), remoteAddress: "1234-54321") + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: "My-Override", settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + let validOverride = try action.toValidOverride(allowedPresets: presets) + + //Assert + XCTAssertEqual(validOverride.duration, .indefinite) + } + + func testToValidOverride_WhenNegativeDuration_Fails() throws { + + //Arrange + let action = OverrideAction(name: "My-Override", durationTime: TimeInterval(hours: -1.0), remoteAddress: "1234-54321") + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: "My-Override", settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidOverride(allowedPresets: presets) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? OverrideActionError, case .negativeDuration = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + + //Limit to 24 hour duration + + func testToValidOverride_WhenAtMaxDuration_Succeeds() throws { + + //Arrange + let duration = TimeInterval(hours: 24) + let action = OverrideAction(name: "My-Override", durationTime: duration, remoteAddress: "1234-54321") + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: "My-Override", settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + let validOverride = try action.toValidOverride(allowedPresets: presets) + + //Assert + XCTAssertEqual(validOverride.duration, .finite(duration)) + + } + + func testToValidOverride_WhenAtMaxDuration_Fails() throws { + + //Arrange + let duration = TimeInterval(hours: 24) + 1 + let action = OverrideAction(name: "My-Override", durationTime: duration, remoteAddress: "1234-54321") + let presets = [TemporaryScheduleOverridePreset(symbol: "", name: "My-Override", settings: .init(targetRange: .none), duration: .indefinite)] + + //Act + var thrownError: Error? = nil + do { + let _ = try action.toValidOverride(allowedPresets: presets) + } catch { + thrownError = error + } + + //Assert + guard let validationError = thrownError as? OverrideActionError, case .durationExceedsMax = validationError else { + XCTFail("Unexpected type \(thrownError.debugDescription)") + return + } + } + +} diff --git a/LoopTests/Models/RemoteCommandTests.swift b/LoopTests/Models/RemoteCommandTests.swift deleted file mode 100644 index 58cd8c650c..0000000000 --- a/LoopTests/Models/RemoteCommandTests.swift +++ /dev/null @@ -1,225 +0,0 @@ -// -// RemoteCommandTests.swift -// LoopTests -// -// Created by Bill Gestrich on 8/13/22. -// Copyright © 2022 LoopKit Authors. All rights reserved. -// - -import XCTest -import HealthKit -@testable import Loop - -class RemoteCommandTests: XCTestCase { - - override func setUpWithError() throws { - } - - override func tearDownWithError() throws { - } - - - //MARK: Carb Entry Command - - func testParseCarbEntryNotification_ValidPayload_Succeeds() throws { - - //Arrange - let expectedStartDateString = "2022-08-14T03:08:00.000Z" - let expectedCarbsInGrams = 15.0 - let expectedDate = dateFormatter().date(from: expectedStartDateString)! - let expectedAbsorptionTimeInHours = 3.0 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry":expectedCarbsInGrams, - "absorption-time": expectedAbsorptionTimeInHours, - "otp": otp, - "start-time": expectedStartDateString - ] - - //Act - let command = try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0)).get() - - //Assert - guard case .carbsEntry(let carbEntry) = command else { - XCTFail("Incorrect case") - return - } - XCTAssertEqual(carbEntry.startDate, expectedDate) - XCTAssertEqual(carbEntry.absorptionTime, TimeInterval(hours: expectedAbsorptionTimeInHours)) - XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: expectedCarbsInGrams)) - } - - func testParseCarbEntryNotification_MissingCreatedDate_Succeeds() throws { - - //Arrange - let expectedStartDate = Date() - let expectedCarbsInGrams = 15.0 - let expectedAbsorptionTimeInHours = 3.0 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry":expectedCarbsInGrams, - "absorption-time": expectedAbsorptionTimeInHours, - "otp": otp - ] - - //Act - let command = try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0), nowDate: expectedStartDate).get() - - //Assert - guard case .carbsEntry(let carbEntry) = command else { - XCTFail("Incorrect case") - return - } - - XCTAssertEqual(carbEntry.startDate, expectedStartDate) - XCTAssertEqual(carbEntry.absorptionTime, TimeInterval(hours: expectedAbsorptionTimeInHours)) - XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: expectedCarbsInGrams)) - } - - func testParseCarbEntryNotification_InvalidCreatedDate_Fails() throws { - - //Arrange - let expectedCarbsInGrams = 15.0 - let expectedAbsorptionTimeInHours = 3.0 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry": expectedCarbsInGrams, - "absorption-time":expectedAbsorptionTimeInHours, - "otp": otp, - "start-time": "invalid-date-string" - ] - - //Act + Assert - XCTAssertThrowsError(try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0)).get()) - } - - func testParseCarbEntryNotification_MissingAbsorptionHours_UsesDefaultAbsorption() throws { - - //Arrange - let expectedStartDateString = "2022-08-14T03:08:00.000Z" - let expectedCarbsInGrams = 15.0 - let expectedDate = dateFormatter().date(from: expectedStartDateString)! - let expectedAbsorptionTimeInHours = 4.0 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry": expectedCarbsInGrams, - "otp": otp, - "start-time": expectedStartDateString - ] - - //Act - let command = try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: expectedAbsorptionTimeInHours)).get() - - //Assert - guard case .carbsEntry(let carbEntry) = command else { - XCTFail("Incorrect case") - return - } - XCTAssertEqual(carbEntry.startDate, expectedDate) - XCTAssertEqual(carbEntry.absorptionTime, TimeInterval(hours: expectedAbsorptionTimeInHours)) - XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: expectedCarbsInGrams)) - } - - - func testParseCarbEntryNotification_AtMinAbsorptionHours_Succeeds() throws { - - //Arrange - let expectedStartDateString = "2022-08-14T03:08:00.000Z" - let expectedCarbsInGrams = 15.0 - let expectedDate = dateFormatter().date(from: expectedStartDateString)! - let expectedAbsorptionTimeInHours = 0.5 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry": expectedCarbsInGrams, - "absorption-time":expectedAbsorptionTimeInHours, - "otp": otp, - "start-time": expectedStartDateString - ] - - //Act - let command = try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0)).get() - - //Assert - guard case .carbsEntry(let carbEntry) = command else { - XCTFail("Incorrect case") - return - } - XCTAssertEqual(carbEntry.startDate, expectedDate) - XCTAssertEqual(carbEntry.absorptionTime, TimeInterval(hours: expectedAbsorptionTimeInHours)) - XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: expectedCarbsInGrams)) - } - - func testParseCarbEntryNotification_BelowMinAbsorptionHours_Fails() throws { - - //Arrange - let expectedStartDateString = "2022-08-14T03:08:00.000Z" - let expectedCarbsInGrams = 15.0 - let expectedAbsorptionTimeInHours = 0.4 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry": expectedCarbsInGrams, - "absorption-time":expectedAbsorptionTimeInHours, - "otp": otp, - "start-time": expectedStartDateString - ] - - //Act + Assert - XCTAssertThrowsError(try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0)).get()) - } - - func testParseCarbEntryNotification_AtMaxAbsorptionHours_Succeeds() throws { - - //Arrange - let expectedStartDateString = "2022-08-14T03:08:00.000Z" - let expectedCarbsInGrams = 15.0 - let expectedDate = dateFormatter().date(from: expectedStartDateString)! - let expectedAbsorptionTimeInHours = 8.0 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry": expectedCarbsInGrams, - "absorption-time":expectedAbsorptionTimeInHours, - "otp": otp, - "start-time": expectedStartDateString - ] - - //Act - let command = try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0)).get() - - //Assert - guard case .carbsEntry(let carbEntry) = command else { - XCTFail("Incorrect case") - return - } - XCTAssertEqual(carbEntry.startDate, expectedDate) - XCTAssertEqual(carbEntry.absorptionTime, TimeInterval(hours: expectedAbsorptionTimeInHours)) - XCTAssertEqual(carbEntry.quantity, HKQuantity(unit: .gram(), doubleValue: expectedCarbsInGrams)) - } - - func testParseCarbEntryNotification_AboveMaxAbsorptionHours_Fails() throws { - - //Arrange - let expectedStartDateString = "2022-08-14T03:08:00.000Z" - let expectedCarbsInGrams = 15.0 - let expectedAbsorptionTimeInHours = 8.1 - let otp = 12345 - let notification: [String: Any] = [ - "carbs-entry": expectedCarbsInGrams, - "absorption-time":expectedAbsorptionTimeInHours, - "otp": otp, - "start-time": expectedStartDateString - ] - - //Act + Assert - XCTAssertThrowsError(try RemoteCommand.createRemoteCommand(notification: notification, allowedPresets: [], defaultAbsorptionTime: TimeInterval(hours: 4.0)).get()) - } - - - //MARK: Utils - - func dateFormatter() -> ISO8601DateFormatter { - let formatter = ISO8601DateFormatter() - formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] - return formatter - } - -} diff --git a/LoopTests/ViewModels/BolusEntryViewModelTests.swift b/LoopTests/ViewModels/BolusEntryViewModelTests.swift index ac356e04a6..259a810f69 100644 --- a/LoopTests/ViewModels/BolusEntryViewModelTests.swift +++ b/LoopTests/ViewModels/BolusEntryViewModelTests.swift @@ -14,6 +14,7 @@ import SwiftUI import XCTest @testable import Loop +@MainActor class BolusEntryViewModelTests: XCTestCase { // Some of the tests depend on a date on the hour @@ -63,17 +64,20 @@ class BolusEntryViewModelTests: XCTestCase { let mockUUID = BolusEntryViewModelTests.mockUUID.uuidString let queue = DispatchQueue(label: "BolusEntryViewModelTests") var saveAndDeliverSuccess = false - - override func setUpWithError() throws { + + override func setUp(completion: @escaping (Error?) -> Void) { now = Self.now delegate = MockBolusEntryViewModelDelegate() delegate.mostRecentGlucoseDataDate = now delegate.mostRecentPumpDataDate = now saveAndDeliverSuccess = false - setUpViewModel() + Task { + await setUpViewModel() + completion(nil) + } } - - func setUpViewModel(originalCarbEntry: StoredCarbEntry? = nil, potentialCarbEntry: NewCarbEntry? = nil, selectedCarbAbsorptionTimeEmoji: String? = nil) { + + func setUpViewModel(originalCarbEntry: StoredCarbEntry? = nil, potentialCarbEntry: NewCarbEntry? = nil, selectedCarbAbsorptionTimeEmoji: String? = nil) async { bolusEntryViewModel = BolusEntryViewModel(delegate: delegate, now: { self.now }, screenWidth: 512, @@ -83,22 +87,11 @@ class BolusEntryViewModelTests: XCTestCase { originalCarbEntry: originalCarbEntry, potentialCarbEntry: potentialCarbEntry, selectedCarbAbsorptionTimeEmoji: selectedCarbAbsorptionTimeEmoji) - bolusEntryViewModel.authenticate = authenticateOverride + bolusEntryViewModel.authenticationHandler = { _ in return true } + bolusEntryViewModel.maximumBolus = HKQuantity(unit: .internationalUnit(), doubleValue: 10) - - let exp = expectation(description: "wait for initial recommendation generation") - exp.assertForOverFulfill = false - bolusEntryViewModel.generateRecommendationAndStartObserving() { - exp.fulfill() - } - try! triggerLoopStateResult(with: MockLoopState()) - wait(for: [exp], timeout: 1.0) - } - - var authenticateOverrideCompletion: ((Swift.Result) -> Void)? - private func authenticateOverride(_ message: String, _ completion: @escaping (Swift.Result) -> Void) { - authenticateOverrideCompletion = completion + await bolusEntryViewModel.generateRecommendationAndStartObserving() } func testInitialConditions() throws { @@ -130,38 +123,40 @@ class BolusEntryViewModelTests: XCTestCase { // MARK: updating state - func testUpdateDisableManualGlucoseEntryIfNecessary() throws { + func testUpdateDisableManualGlucoseEntryIfNecessary() async throws { bolusEntryViewModel.isManualGlucoseEntryEnabled = true bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - try triggerLoopStateUpdated(with: MockLoopState()) + await bolusEntryViewModel.update() XCTAssertFalse(bolusEntryViewModel.isManualGlucoseEntryEnabled) XCTAssertNil(bolusEntryViewModel.manualGlucoseQuantity) XCTAssertEqual(.glucoseNoLongerStale, bolusEntryViewModel.activeAlert) } - func testUpdateDisableManualGlucoseEntryIfNecessaryStaleGlucose() throws { + func testUpdateDisableManualGlucoseEntryIfNecessaryStaleGlucose() async throws { delegate.mostRecentGlucoseDataDate = Date.distantPast bolusEntryViewModel.isManualGlucoseEntryEnabled = true bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - try triggerLoopStateUpdated(with: MockLoopState()) + await bolusEntryViewModel.update() XCTAssertTrue(bolusEntryViewModel.isManualGlucoseEntryEnabled) XCTAssertEqual(Self.exampleManualGlucoseQuantity, bolusEntryViewModel.manualGlucoseQuantity) XCTAssertNil(bolusEntryViewModel.activeAlert) } - func testUpdateGlucoseValues() throws { + func testUpdateGlucoseValues() async throws { XCTAssertEqual(0, bolusEntryViewModel.glucoseValues.count) - try triggerLoopStateUpdatedWithDataAndWait() + delegate.getGlucoseSamplesResponse = [StoredGlucoseSample(sample: Self.exampleCGMGlucoseSample)] + await bolusEntryViewModel.update() XCTAssertEqual(1, bolusEntryViewModel.glucoseValues.count) XCTAssertEqual([100.4], bolusEntryViewModel.glucoseValues.map { return $0.quantity.doubleValue(for: .milligramsPerDeciliter) }) } - func testUpdateGlucoseValuesWithManual() throws { + func testUpdateGlucoseValuesWithManual() async throws { XCTAssertEqual(0, bolusEntryViewModel.glucoseValues.count) bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - try triggerLoopStateUpdatedWithDataAndWait() + delegate.getGlucoseSamplesResponse = [StoredGlucoseSample(sample: Self.exampleCGMGlucoseSample)] + await bolusEntryViewModel.update() XCTAssertEqual([100.4, 123.4], bolusEntryViewModel.glucoseValues.map { return $0.quantity.doubleValue(for: .milligramsPerDeciliter) }) @@ -170,38 +165,29 @@ class BolusEntryViewModelTests: XCTestCase { func testManualEntryClearsEnteredBolus() throws { bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - XCTAssertEqual(Self.exampleBolusQuantity, bolusEntryViewModel.enteredBolus) - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() XCTAssertEqual(HKQuantity(unit: .internationalUnit(), doubleValue: 0), bolusEntryViewModel.enteredBolus) } - func testUpdatePredictedGlucoseValues() throws { - let mockLoopState = MockLoopState() - mockLoopState.predictGlucoseValueResult = [PredictedGlucoseValue(startDate: Self.exampleStartDate, quantity: Self.exampleCGMGlucoseQuantity)] - try triggerLoopStateUpdated(with: mockLoopState) - waitOnMain() - XCTAssertEqual(mockLoopState.predictGlucoseValueResult, - bolusEntryViewModel.predictedGlucoseValues.map { - PredictedGlucoseValue(startDate: $0.startDate, quantity: $0.quantity) - }) + func testUpdatePredictedGlucoseValues() async throws { + let prediction = [PredictedGlucoseValue(startDate: Self.exampleStartDate, quantity: Self.exampleCGMGlucoseQuantity)] + delegate.loopState.predictGlucoseValueResult = prediction + await bolusEntryViewModel.update() + XCTAssertEqual(prediction, bolusEntryViewModel.predictedGlucoseValues.map { PredictedGlucoseValue(startDate: $0.startDate, quantity: $0.quantity) }) } - func testUpdatePredictedGlucoseValuesWithManual() throws { + func testUpdatePredictedGlucoseValuesWithManual() async throws { + let prediction = [PredictedGlucoseValue(startDate: Self.exampleStartDate, quantity: Self.exampleCGMGlucoseQuantity)] + delegate.loopState.predictGlucoseValueResult = prediction + await bolusEntryViewModel.update() + bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - let mockLoopState = MockLoopState() - mockLoopState.predictGlucoseValueResult = [PredictedGlucoseValue(startDate: Self.exampleStartDate, quantity: Self.exampleCGMGlucoseQuantity)] - try triggerLoopStateUpdated(with: mockLoopState) - waitOnMain() - XCTAssertEqual(mockLoopState.predictGlucoseValueResult, + XCTAssertEqual(prediction, bolusEntryViewModel.predictedGlucoseValues.map { PredictedGlucoseValue(startDate: $0.startDate, quantity: $0.quantity) }) } - func testUpdateSettings() throws { + func testUpdateSettings() async throws { XCTAssertNil(bolusEntryViewModel.preMealOverride) XCTAssertNil(bolusEntryViewModel.scheduleOverride) XCTAssertEqual(bolusEntryViewModel.targetGlucoseSchedule, BolusEntryViewModelTests.exampleGlucoseRangeSchedule) @@ -219,16 +205,16 @@ class BolusEntryViewModelTests: XCTestCase { newSettings.preMealOverride = TemporaryScheduleOverride(context: .preMeal, settings: settings, startDate: Self.exampleStartDate, duration: .indefinite, enactTrigger: .local, syncIdentifier: UUID()) newSettings.scheduleOverride = TemporaryScheduleOverride(context: .custom, settings: settings, startDate: Self.exampleStartDate, duration: .indefinite, enactTrigger: .local, syncIdentifier: UUID()) delegate.settings = newSettings - try triggerLoopStateUpdatedWithDataAndWait() - waitOnMain() + bolusEntryViewModel.updateSettings() + await bolusEntryViewModel.update() XCTAssertEqual(newSettings.preMealOverride, bolusEntryViewModel.preMealOverride) XCTAssertEqual(newSettings.scheduleOverride, bolusEntryViewModel.scheduleOverride) XCTAssertEqual(newGlucoseTargetRangeSchedule, bolusEntryViewModel.targetGlucoseSchedule) } - func testUpdateSettingsWithCarbs() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + func testUpdateSettingsWithCarbs() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) XCTAssertNil(bolusEntryViewModel.preMealOverride) XCTAssertNil(bolusEntryViewModel.scheduleOverride) XCTAssertEqual(bolusEntryViewModel.targetGlucoseSchedule, BolusEntryViewModelTests.exampleGlucoseRangeSchedule) @@ -245,9 +231,8 @@ class BolusEntryViewModelTests: XCTestCase { newSettings.preMealOverride = Self.examplePreMealOverride newSettings.scheduleOverride = Self.exampleCustomScheduleOverride delegate.settings = newSettings - try triggerLoopStateUpdatedWithDataAndWait() - waitOnMain() - + bolusEntryViewModel.updateSettings() + // Pre-meal override should be ignored if we have carbs (LOOP-1964), and cleared in settings XCTAssertEqual(newSettings.scheduleOverride, bolusEntryViewModel.scheduleOverride) XCTAssertEqual(newGlucoseTargetRangeSchedule, bolusEntryViewModel.targetGlucoseSchedule) @@ -256,158 +241,168 @@ class BolusEntryViewModelTests: XCTestCase { bolusEntryViewModel = nil } - func testManualGlucoseChangesPredictedGlucoseValues() throws { + func testManualGlucoseChangesPredictedGlucoseValues() async throws { bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - let mockLoopState = MockLoopState() - mockLoopState.predictGlucoseValueResult = [PredictedGlucoseValue(startDate: Self.exampleStartDate, quantity: Self.exampleCGMGlucoseQuantity)] - waitOnMain() - try triggerLoopStateUpdatedWithDataAndWait(with: mockLoopState) - waitOnMain() + let prediction = [PredictedGlucoseValue(startDate: Self.exampleStartDate, quantity: Self.exampleCGMGlucoseQuantity)] + delegate.loopState.predictGlucoseValueResult = prediction + await bolusEntryViewModel.update() - XCTAssertEqual(mockLoopState.predictGlucoseValueResult, + XCTAssertEqual(prediction, bolusEntryViewModel.predictedGlucoseValues.map { PredictedGlucoseValue(startDate: $0.startDate, quantity: $0.quantity) }) } - func testUpdateInsulinOnBoard() throws { + func testUpdateInsulinOnBoard() async throws { delegate.insulinOnBoardResult = .success(InsulinValue(startDate: Self.exampleStartDate, value: 1.5)) XCTAssertNil(bolusEntryViewModel.activeInsulin) - try triggerLoopStateUpdatedWithDataAndWait() + await bolusEntryViewModel.update() XCTAssertEqual(HKQuantity(unit: .internationalUnit(), doubleValue: 1.5), bolusEntryViewModel.activeInsulin) } - func testUpdateCarbsOnBoard() throws { + func testUpdateCarbsOnBoard() async throws { delegate.carbsOnBoardResult = .success(CarbValue(startDate: Self.exampleStartDate, endDate: Self.exampleEndDate, quantity: Self.exampleCarbQuantity)) XCTAssertNil(bolusEntryViewModel.activeCarbs) - try triggerLoopStateUpdatedWithDataAndWait() + await bolusEntryViewModel.update() XCTAssertEqual(Self.exampleCarbQuantity, bolusEntryViewModel.activeCarbs) } - func testUpdateCarbsOnBoardFailure() throws { + func testUpdateCarbsOnBoardFailure() async throws { delegate.carbsOnBoardResult = .failure(CarbStore.CarbStoreError.notConfigured) - try triggerLoopStateUpdatedWithDataAndWait() + await bolusEntryViewModel.update() XCTAssertNil(bolusEntryViewModel.activeCarbs) } - func testUpdateRecommendedBolusNoNotice() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) - let mockState = MockLoopState() + func testUpdateRecommendedBolusNoNotice() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationResult = ManualBolusRecommendation(amount: 1.234, pendingInsulin: 4.321) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + let recommendation = ManualBolusRecommendation(amount: 1.25, pendingInsulin: 4.321) + delegate.loopState.bolusRecommendationResult = recommendation + await bolusEntryViewModel.update() XCTAssertTrue(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNotNil(recommendedBolus) - XCTAssertEqual(delegate.roundBolusVolume(units: mockState.bolusRecommendationResult!.amount), recommendedBolus?.doubleValue(for: .internationalUnit())) - let consideringPotentialCarbEntryPassed = try XCTUnwrap(mockState.consideringPotentialCarbEntryPassed) + XCTAssertEqual(recommendation.amount, recommendedBolus?.doubleValue(for: .internationalUnit())) + let consideringPotentialCarbEntryPassed = try XCTUnwrap(delegate.loopState.consideringPotentialCarbEntryPassed) XCTAssertEqual(mockPotentialCarbEntry, consideringPotentialCarbEntryPassed) - let replacingCarbEntryPassed = try XCTUnwrap(mockState.replacingCarbEntryPassed) + let replacingCarbEntryPassed = try XCTUnwrap(delegate.loopState.replacingCarbEntryPassed) XCTAssertEqual(mockOriginalCarbEntry, replacingCarbEntryPassed) XCTAssertNil(bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusWithNotice() throws { - let mockState = MockLoopState() + func testUpdateRecommendedBolusWithNotice() async throws { delegate.settings.suspendThreshold = GlucoseThreshold(unit: .milligramsPerDeciliter, value: Self.exampleCGMGlucoseQuantity.doubleValue(for: .milligramsPerDeciliter)) XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationResult = ManualBolusRecommendation(amount: 1.234, pendingInsulin: 4.321, notice: BolusRecommendationNotice.glucoseBelowSuspendThreshold(minGlucose: Self.exampleGlucoseValue)) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + let recommendation = ManualBolusRecommendation(amount: 1.25, pendingInsulin: 4.321, notice: BolusRecommendationNotice.glucoseBelowSuspendThreshold(minGlucose: Self.exampleGlucoseValue)) + delegate.loopState.bolusRecommendationResult = recommendation + await bolusEntryViewModel.update() XCTAssertTrue(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNotNil(recommendedBolus) - XCTAssertEqual(delegate.roundBolusVolume(units: mockState.bolusRecommendationResult!.amount), recommendedBolus!.doubleValue(for: .internationalUnit())) + XCTAssertEqual(recommendation.amount, recommendedBolus?.doubleValue(for: .internationalUnit())) XCTAssertEqual(BolusEntryViewModel.Notice.predictedGlucoseBelowSuspendThreshold(suspendThreshold: Self.exampleCGMGlucoseQuantity), bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusWithNoticeMissingSuspendThreshold() throws { - let mockState = MockLoopState() + func testUpdateRecommendedBolusWithNoticeMissingSuspendThreshold() async throws { XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) delegate.settings.suspendThreshold = nil - mockState.bolusRecommendationResult = ManualBolusRecommendation(amount: 1.234, pendingInsulin: 4.321, notice: BolusRecommendationNotice.glucoseBelowSuspendThreshold(minGlucose: Self.exampleGlucoseValue)) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + let recommendation = ManualBolusRecommendation(amount: 1.25, pendingInsulin: 4.321, notice: BolusRecommendationNotice.glucoseBelowSuspendThreshold(minGlucose: Self.exampleGlucoseValue)) + delegate.loopState.bolusRecommendationResult = recommendation + await bolusEntryViewModel.update() XCTAssertTrue(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNotNil(recommendedBolus) - XCTAssertEqual(delegate.roundBolusVolume(units: mockState.bolusRecommendationResult!.amount), recommendedBolus!.doubleValue(for: .internationalUnit())) + XCTAssertEqual(recommendation.amount, recommendedBolus?.doubleValue(for: .internationalUnit())) XCTAssertNil(bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusWithOtherNotice() throws { - let mockState = MockLoopState() + func testUpdateRecommendedBolusWithOtherNotice() async throws { XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationResult = ManualBolusRecommendation(amount: 1.234, pendingInsulin: 4.321, notice: BolusRecommendationNotice.currentGlucoseBelowTarget(glucose: Self.exampleGlucoseValue)) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + let recommendation = ManualBolusRecommendation(amount: 1.25, pendingInsulin: 4.321, notice: BolusRecommendationNotice.currentGlucoseBelowTarget(glucose: Self.exampleGlucoseValue)) + delegate.loopState.bolusRecommendationResult = recommendation + await bolusEntryViewModel.update() XCTAssertTrue(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNotNil(recommendedBolus) - XCTAssertEqual(delegate.roundBolusVolume(units: mockState.bolusRecommendationResult!.amount), recommendedBolus!.doubleValue(for: .internationalUnit())) + XCTAssertEqual(recommendation.amount, recommendedBolus?.doubleValue(for: .internationalUnit())) XCTAssertNil(bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusThrowsMissingDataError() throws { - let mockState = MockLoopState() + func testUpdateRecommendedBolusThrowsMissingDataError() async throws { XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationError = LoopError.missingDataError(.glucose) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + delegate.loopState.bolusRecommendationError = LoopError.missingDataError(.glucose) + await bolusEntryViewModel.update() XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNil(recommendedBolus) XCTAssertEqual(.staleGlucoseData, bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusThrowsPumpDataTooOld() throws { - let mockState = MockLoopState() + func testUpdateRecommendedBolusThrowsPumpDataTooOld() async throws { XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationError = LoopError.pumpDataTooOld(date: now) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + delegate.loopState.bolusRecommendationError = LoopError.pumpDataTooOld(date: now) + await bolusEntryViewModel.update() XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNil(recommendedBolus) XCTAssertEqual(.stalePumpData, bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusThrowsOtherError() throws { - let mockState = MockLoopState() + func testUpdateRecommendedBolusThrowsGlucoseTooOld() async throws { + XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) + delegate.loopState.bolusRecommendationError = LoopError.glucoseTooOld(date: now) + await bolusEntryViewModel.update() + XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) + let recommendedBolus = bolusEntryViewModel.recommendedBolus + XCTAssertNil(recommendedBolus) + XCTAssertEqual(.staleGlucoseData, bolusEntryViewModel.activeNotice) + } + + func testUpdateRecommendedBolusThrowsInvalidFutureGlucose() async throws { + XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) + delegate.loopState.bolusRecommendationError = LoopError.invalidFutureGlucose(date: now) + await bolusEntryViewModel.update() + XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) + let recommendedBolus = bolusEntryViewModel.recommendedBolus + XCTAssertNil(recommendedBolus) + XCTAssertEqual(.futureGlucoseData, bolusEntryViewModel.activeNotice) + } + + func testUpdateRecommendedBolusThrowsOtherError() async throws { XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationError = LoopError.pumpSuspended - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + delegate.loopState.bolusRecommendationError = LoopError.pumpSuspended + await bolusEntryViewModel.update() XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNil(recommendedBolus) XCTAssertNil(bolusEntryViewModel.activeNotice) } - func testUpdateRecommendedBolusWithManual() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) - let mockState = MockLoopState() + func testUpdateRecommendedBolusWithManual() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity XCTAssertFalse(bolusEntryViewModel.isBolusRecommended) - mockState.bolusRecommendationResult = ManualBolusRecommendation(amount: 1.234, pendingInsulin: 4.321) - try triggerLoopStateUpdatedWithDataAndWait(with: mockState) + let recommendation = ManualBolusRecommendation(amount: 1.25, pendingInsulin: 4.321) + delegate.loopState.bolusRecommendationResult = recommendation + await bolusEntryViewModel.update() XCTAssertTrue(bolusEntryViewModel.isBolusRecommended) let recommendedBolus = bolusEntryViewModel.recommendedBolus XCTAssertNotNil(recommendedBolus) - XCTAssertEqual(delegate.roundBolusVolume(units: mockState.bolusRecommendationResult!.amount), recommendedBolus!.doubleValue(for: .internationalUnit())) - let consideringPotentialCarbEntryPassed = try XCTUnwrap(mockState.consideringPotentialCarbEntryPassed) + XCTAssertEqual(recommendation.amount, recommendedBolus?.doubleValue(for: .internationalUnit())) + let consideringPotentialCarbEntryPassed = try XCTUnwrap(delegate.loopState.consideringPotentialCarbEntryPassed) XCTAssertEqual(mockPotentialCarbEntry, consideringPotentialCarbEntryPassed) - let replacingCarbEntryPassed = try XCTUnwrap(mockState.replacingCarbEntryPassed) + let replacingCarbEntryPassed = try XCTUnwrap(delegate.loopState.replacingCarbEntryPassed) XCTAssertEqual(mockOriginalCarbEntry, replacingCarbEntryPassed) XCTAssertNil(bolusEntryViewModel.activeNotice) } // MARK: save data and bolus delivery - func testDeliverBolusOnlyRecommendationChanged() throws { + func testDeliverBolusOnlyRecommendationChanged() async throws { bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity - var success = false - bolusEntryViewModel.saveAndDeliver { - success = true - } - // Pretend authentication succeeded - let authenticateOverrideCompletion = try XCTUnwrap(self.authenticateOverrideCompletion) - authenticateOverrideCompletion(.success(())) - + + let success = await bolusEntryViewModel.saveAndDeliver() + XCTAssertEqual(1.0, delegate.enactedBolusUnits) XCTAssertEqual(.manualRecommendationChanged, delegate.enactedBolusActivationType) XCTAssertTrue(success) @@ -419,12 +414,9 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.1, now) } - func testBolusTooSmall() throws { + func testBolusTooSmall() async throws { bolusEntryViewModel.enteredBolus = HKQuantity(unit: .internationalUnit(), doubleValue: 0.01) - var success = false - bolusEntryViewModel.saveAndDeliver { - success = true - } + let success = await bolusEntryViewModel.saveAndDeliver() XCTAssertEqual(.bolusTooSmall, bolusEntryViewModel.activeAlert) XCTAssertNil(delegate.enactedBolusUnits) XCTAssertFalse(success) @@ -432,16 +424,11 @@ class BolusEntryViewModelTests: XCTestCase { } - func testDeliverBolusOnlyRecommendationAccepted() throws { + func testDeliverBolusOnlyRecommendationAccepted() async throws { bolusEntryViewModel.recommendedBolus = Self.exampleBolusQuantity bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity - var success = false - bolusEntryViewModel.saveAndDeliver { - success = true - } - // Pretend authentication succeeded - let authenticateOverrideCompletion = try XCTUnwrap(self.authenticateOverrideCompletion) - authenticateOverrideCompletion(.success(())) + + let success = await bolusEntryViewModel.saveAndDeliver() XCTAssertEqual(1.0, delegate.enactedBolusUnits) XCTAssertEqual(.manualRecommendationAccepted, delegate.enactedBolusActivationType) @@ -454,16 +441,11 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.1, now) } - func testDeliverBolusOnlyNoRecommendation() throws { + func testDeliverBolusOnlyNoRecommendation() async throws { bolusEntryViewModel.recommendedBolus = nil bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity - var success = false - bolusEntryViewModel.saveAndDeliver { - success = true - } - // Pretend authentication succeeded - let authenticateOverrideCompletion = try XCTUnwrap(self.authenticateOverrideCompletion) - authenticateOverrideCompletion(.success(())) + + let success = await bolusEntryViewModel.saveAndDeliver() XCTAssertEqual(1.0, delegate.enactedBolusUnits) XCTAssertEqual(.manualNoRecommendation, delegate.enactedBolusActivationType) @@ -477,16 +459,14 @@ class BolusEntryViewModelTests: XCTestCase { } struct MockError: Error {} - func testDeliverBolusAuthFail() throws { + func testDeliverBolusAuthFail() async throws { bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity - var success = false - bolusEntryViewModel.saveAndDeliver { - success = true - } - // Pretend authentication succeeded - let authenticateOverrideCompletion = try XCTUnwrap(self.authenticateOverrideCompletion) - authenticateOverrideCompletion(.failure(MockError())) - + + // Mock failed authentication + bolusEntryViewModel.authenticationHandler = { _ in return false } + + let success = await bolusEntryViewModel.saveAndDeliver() + XCTAssertNil(delegate.enactedBolusUnits) XCTAssertNil(delegate.enactedBolusActivationType) XCTAssertFalse(success) @@ -495,54 +475,47 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertTrue(delegate.bolusDosingDecisionsAdded.isEmpty) } - private func saveAndDeliver(_ bolus: HKQuantity, file: StaticString = #file, line: UInt = #line) throws { + private func saveAndDeliver(_ bolus: HKQuantity, file: StaticString = #file, line: UInt = #line) async throws { bolusEntryViewModel.enteredBolus = bolus - bolusEntryViewModel.saveAndDeliver { self.saveAndDeliverSuccess = true } - if bolus != BolusEntryViewModelTests.noBolus { - let authenticateOverrideCompletion = try XCTUnwrap(self.authenticateOverrideCompletion, file: file, line: line) - authenticateOverrideCompletion(.success(())) - } + + self.saveAndDeliverSuccess = await bolusEntryViewModel.saveAndDeliver() } - func testSaveManualGlucoseNoBolus() throws { + func testSaveManualGlucoseNoBolus() async throws { bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - // manualGlucoseSample updates asynchronously on main - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() - try saveAndDeliver(BolusEntryViewModelTests.noBolus) + bolusEntryViewModel.enteredBolus = BolusEntryViewModelTests.noBolus + + delegate.addGlucoseSamplesResult = .success([Self.exampleManualStoredGlucoseSample]) + + let saveAndDeliverSuccess = await bolusEntryViewModel.saveAndDeliver() let expectedGlucoseSample = NewGlucoseSample(date: now, quantity: Self.exampleManualGlucoseQuantity, condition: nil, trend: nil, trendRate: nil, isDisplayOnly: false, wasUserEntered: true, syncIdentifier: mockUUID) + XCTAssertEqual([expectedGlucoseSample], delegate.glucoseSamplesAdded) - delegate.addGlucoseCompletion?(.success([Self.exampleManualStoredGlucoseSample])) - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() - XCTAssertTrue(delegate.carbEntriesAdded.isEmpty) XCTAssertEqual(1, delegate.bolusDosingDecisionsAdded.count) XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.reason, .normalBolus) - XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualGlucoseSample, Self.exampleManualStoredGlucoseSample) XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualBolusRequested, 0.0) + + let addedGlucose = delegate.bolusDosingDecisionsAdded.first!.0.manualGlucoseSample + XCTAssertEqual(addedGlucose?.quantity, Self.exampleManualGlucoseQuantity) + XCTAssertEqual(addedGlucose?.startDate, now) + XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.1, now) XCTAssertNil(delegate.enactedBolusUnits) XCTAssertNil(delegate.enactedBolusActivationType) XCTAssertTrue(saveAndDeliverSuccess) } - func testSaveCarbGlucoseNoBolus() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + func testSaveCarbGlucoseNoBolus() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + + delegate.addGlucoseSamplesResult = .success([Self.exampleManualStoredGlucoseSample]) + delegate.addCarbEntryResult = .success(mockFinalCarbEntry) - try saveAndDeliver(BolusEntryViewModelTests.noBolus) - delegate.addGlucoseCompletion?(.success([Self.exampleManualStoredGlucoseSample])) - waitOnMain() - let addCarbEntryCompletion = try XCTUnwrap(delegate.addCarbEntryCompletion) - addCarbEntryCompletion(.success(mockFinalCarbEntry)) - waitOnMain() + try await saveAndDeliver(BolusEntryViewModelTests.noBolus) XCTAssertTrue(delegate.glucoseSamplesAdded.isEmpty) XCTAssertEqual(1, delegate.carbEntriesAdded.count) @@ -559,52 +532,37 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertTrue(saveAndDeliverSuccess) } - func testSaveManualGlucoseAndBolus() throws { + func testSaveManualGlucoseAndBolus() async throws { bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - // manualGlucoseSample updates asynchronously on main - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() - try saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) + delegate.addGlucoseSamplesResult = .success([Self.exampleManualStoredGlucoseSample]) + + try await saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) let expectedGlucoseSample = NewGlucoseSample(date: now, quantity: Self.exampleManualGlucoseQuantity, condition: nil, trend: nil, trendRate: nil, isDisplayOnly: false, wasUserEntered: true, syncIdentifier: mockUUID) XCTAssertEqual([expectedGlucoseSample], delegate.glucoseSamplesAdded) - delegate.addGlucoseCompletion?(.success([Self.exampleManualStoredGlucoseSample])) - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() - XCTAssertTrue(delegate.carbEntriesAdded.isEmpty) XCTAssertEqual(1, delegate.bolusDosingDecisionsAdded.count) XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.reason, .normalBolus) - XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualGlucoseSample, Self.exampleManualStoredGlucoseSample) XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualBolusRequested, 1.0) + + let addedGlucose = delegate.bolusDosingDecisionsAdded.first!.0.manualGlucoseSample + XCTAssertEqual(addedGlucose?.quantity, Self.exampleManualGlucoseQuantity) + XCTAssertEqual(addedGlucose?.startDate, now) + XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.1, now) XCTAssertEqual(1.0, delegate.enactedBolusUnits) XCTAssertEqual(.manualRecommendationChanged, delegate.enactedBolusActivationType) XCTAssertTrue(saveAndDeliverSuccess) } - func testSaveCarbAndBolus() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) - // manualGlucoseSample updates asynchronously on main - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() + func testSaveCarbAndBolus() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) - try saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) - - let addCarbEntryCompletion = try XCTUnwrap(delegate.addCarbEntryCompletion) - addCarbEntryCompletion(.success(mockFinalCarbEntry)) - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() + delegate.addCarbEntryResult = .success(mockFinalCarbEntry) + + try await saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) XCTAssertTrue(delegate.glucoseSamplesAdded.isEmpty) XCTAssertEqual(1, delegate.carbEntriesAdded.count) @@ -621,8 +579,8 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertTrue(saveAndDeliverSuccess) } - func testSaveCarbAndBolusClearsSavedPreMealOverride() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + func testSaveCarbAndBolusClearsSavedPreMealOverride() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) // set up user specified pre-meal override let newGlucoseTargetRangeSchedule = GlucoseRangeSchedule(unit: .millimolesPerLiter, dailyItems: [ RepeatingScheduleValue(startTime: TimeInterval(0), value: DoubleRange(minValue: 100, maxValue: 110)), @@ -637,55 +595,44 @@ class BolusEntryViewModelTests: XCTestCase { newSettings.preMealOverride = Self.examplePreMealOverride newSettings.scheduleOverride = Self.exampleCustomScheduleOverride delegate.settings = newSettings - try triggerLoopStateUpdatedWithDataAndWait() - waitOnMain() + bolusEntryViewModel.updateSettings() + + delegate.addCarbEntryResult = .success(mockFinalCarbEntry) + + try await saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) - try saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) - let addCarbEntryCompletion = try XCTUnwrap(delegate.addCarbEntryCompletion) - addCarbEntryCompletion(.success(mockFinalCarbEntry)) - waitOnMain() XCTAssertTrue(saveAndDeliverSuccess) // ... make sure the "restoring" of the saved pre-meal override does not happen bolusEntryViewModel = nil } - func testSaveManualGlucoseAndCarbAndBolus() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + func testSaveManualGlucoseAndCarbAndBolus() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity - // manualGlucoseSample updates asynchronously on main - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() - try saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) + delegate.addGlucoseSamplesResult = .success([Self.exampleManualStoredGlucoseSample]) + delegate.addCarbEntryResult = .success(mockFinalCarbEntry) + + try await saveAndDeliver(BolusEntryViewModelTests.exampleBolusQuantity) let expectedGlucoseSample = NewGlucoseSample(date: now, quantity: Self.exampleManualGlucoseQuantity, condition: nil, trend: nil, trendRate: nil, isDisplayOnly: false, wasUserEntered: true, syncIdentifier: mockUUID) XCTAssertEqual([expectedGlucoseSample], delegate.glucoseSamplesAdded) - - delegate.addGlucoseCompletion?(.success([Self.exampleManualStoredGlucoseSample])) - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() - - let addCarbEntryCompletion = try XCTUnwrap(delegate.addCarbEntryCompletion) - addCarbEntryCompletion(.success(mockFinalCarbEntry)) - // For some reason, starting with Xcode 12.5, in order for these tests to pass we need to call `waitOnMain()` - // _twice_ here. Not exactly sure why, needs investigation. - waitOnMain() - waitOnMain() XCTAssertEqual(1, delegate.carbEntriesAdded.count) XCTAssertEqual(mockPotentialCarbEntry, delegate.carbEntriesAdded.first?.0) XCTAssertEqual(mockOriginalCarbEntry, delegate.carbEntriesAdded.first?.1) XCTAssertEqual(1, delegate.bolusDosingDecisionsAdded.count) XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.reason, .normalBolus) + XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualBolusRequested, 1.0) + XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.originalCarbEntry, mockOriginalCarbEntry) XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.carbEntry, mockFinalCarbEntry) - XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualGlucoseSample, Self.exampleManualStoredGlucoseSample) - XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.0.manualBolusRequested, 1.0) + + let addedGlucose = delegate.bolusDosingDecisionsAdded.first!.0.manualGlucoseSample + XCTAssertEqual(addedGlucose?.quantity, Self.exampleManualGlucoseQuantity) + XCTAssertEqual(addedGlucose?.startDate, now) + XCTAssertEqual(delegate.bolusDosingDecisionsAdded.first?.1, now) XCTAssertEqual(1.0, delegate.enactedBolusUnits) XCTAssertEqual(.manualRecommendationChanged, delegate.enactedBolusActivationType) @@ -706,22 +653,22 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertNil(bolusEntryViewModel.carbEntryAmountAndEmojiString) } - func testCarbEntryAmountAndEmojiString() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + func testCarbEntryAmountAndEmojiString() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) XCTAssertEqual("234 g foodType", bolusEntryViewModel.carbEntryAmountAndEmojiString) } - func testCarbEntryAmountAndEmojiStringNoFoodType() throws { + func testCarbEntryAmountAndEmojiStringNoFoodType() async throws { let potentialCarbEntry = NewCarbEntry(quantity: BolusEntryViewModelTests.exampleCarbQuantity, startDate: Self.exampleStartDate, foodType: nil, absorptionTime: 1) - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: potentialCarbEntry) + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: potentialCarbEntry) XCTAssertEqual("234 g", bolusEntryViewModel.carbEntryAmountAndEmojiString) } - func testCarbEntryAmountAndEmojiStringWithEmoji() throws { + func testCarbEntryAmountAndEmojiStringWithEmoji() async throws { let potentialCarbEntry = NewCarbEntry(quantity: BolusEntryViewModelTests.exampleCarbQuantity, startDate: Self.exampleStartDate, foodType: nil, absorptionTime: 1) - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: potentialCarbEntry, selectedCarbAbsorptionTimeEmoji: "😀") + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: potentialCarbEntry, selectedCarbAbsorptionTimeEmoji: "😀") XCTAssertEqual("234 g 😀", bolusEntryViewModel.carbEntryAmountAndEmojiString) } @@ -730,15 +677,15 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertNil(bolusEntryViewModel.carbEntryDateAndAbsorptionTimeString) } - func testCarbEntryDateAndAbsorptionTimeString() throws { - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) + func testCarbEntryDateAndAbsorptionTimeString() async throws { + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: mockPotentialCarbEntry) XCTAssertEqual("12:00 PM + 0m", bolusEntryViewModel.carbEntryDateAndAbsorptionTimeString) } - func testCarbEntryDateAndAbsorptionTimeString2() throws { + func testCarbEntryDateAndAbsorptionTimeString2() async throws { let potentialCarbEntry = NewCarbEntry(quantity: BolusEntryViewModelTests.exampleCarbQuantity, startDate: Self.exampleStartDate, foodType: nil, absorptionTime: nil) - setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: potentialCarbEntry) + await setUpViewModel(originalCarbEntry: mockOriginalCarbEntry, potentialCarbEntry: potentialCarbEntry) XCTAssertEqual("12:00 PM", bolusEntryViewModel.carbEntryDateAndAbsorptionTimeString) } @@ -795,13 +742,13 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertEqual(.saveWithoutBolusing, bolusEntryViewModel.actionButtonAction) } - func testActionButtonPotentialCarbEntry() { - setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) + func testActionButtonPotentialCarbEntry() async { + await setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) XCTAssertEqual(.saveWithoutBolusing, bolusEntryViewModel.actionButtonAction) } - func testActionButtonManualGlucoseAndPotentialCarbEntry() { - setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) + func testActionButtonManualGlucoseAndPotentialCarbEntry() async { + await setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity XCTAssertEqual(.saveWithoutBolusing, bolusEntryViewModel.actionButtonAction) } @@ -817,73 +764,28 @@ class BolusEntryViewModelTests: XCTestCase { XCTAssertEqual(.saveAndDeliver, bolusEntryViewModel.actionButtonAction) } - func testActionButtonSaveAndDeliverPotentialCarbEntry() { - setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) + func testActionButtonSaveAndDeliverPotentialCarbEntry() async { + await setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity XCTAssertEqual(.saveAndDeliver, bolusEntryViewModel.actionButtonAction) } - func testActionButtonSaveAndDeliverBothManualGlucoseAndPotentialCarbEntry() { - setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) + func testActionButtonSaveAndDeliverBothManualGlucoseAndPotentialCarbEntry() async { + await setUpViewModel(potentialCarbEntry: mockPotentialCarbEntry) bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity bolusEntryViewModel.enteredBolus = Self.exampleBolusQuantity XCTAssertEqual(.saveAndDeliver, bolusEntryViewModel.actionButtonAction) } - - func testManualGlucoseStringMatchesDisplayGlucoseUnit() { - // used "260" mg/dL ("14.4" mmol/L) since 14.40 mmol/L -> 259 mg/dL and 14.43 mmol/L -> 260 mg/dL - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "") - bolusEntryViewModel.manualGlucoseString = "260" - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "260") - delegate.displayGlucoseUnitObservable.displayGlucoseUnitDidChange(to: .millimolesPerLiter) - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "14.4") - delegate.displayGlucoseUnitObservable.displayGlucoseUnitDidChange(to: .milligramsPerDeciliter) - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "260") - delegate.displayGlucoseUnitObservable.displayGlucoseUnitDidChange(to: .millimolesPerLiter) - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "14.4") - - bolusEntryViewModel.manualGlucoseString = "14.0" - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "14.0") - bolusEntryViewModel.manualGlucoseString = "14.4" - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "14.4") - delegate.displayGlucoseUnitObservable.displayGlucoseUnitDidChange(to: .milligramsPerDeciliter) - XCTAssertEqual(bolusEntryViewModel.manualGlucoseString, "259") - } } // MARK: utilities -extension BolusEntryViewModelTests { - - func triggerLoopStateUpdatedWithDataAndWait(with state: LoopState = MockLoopState(), function: String = #function) throws { - delegate.getGlucoseSamplesResponse = [StoredGlucoseSample(sample: Self.exampleCGMGlucoseSample)] - try triggerLoopStateUpdated(with: state) - waitOnMain() - } - - func triggerLoopStateUpdated(with state: LoopState, function: String = #function) throws { - NotificationCenter.default.post(name: .LoopDataUpdated, object: nil, userInfo: [ - LoopDataManager.LoopUpdateContextKey: LoopDataManager.LoopUpdateContext.loopFinished.rawValue - ]) - try triggerLoopStateResult(with: state, function: function) - } - - func triggerLoopStateResult(with state: LoopState, function: String = #function) throws { - let exp = expectation(description: function) - let block = try XCTUnwrap(delegate.loopStateCallBlock) - queue.async { - block(state) - exp.fulfill() - } - wait(for: [exp], timeout: 1.0) - } -} - - fileprivate class MockLoopState: LoopState { var carbsOnBoard: CarbValue? + var insulinOnBoard: InsulinValue? + var error: LoopError? var insulinCounteractionEffects: [GlucoseEffectVelocity] = [] @@ -926,7 +828,20 @@ fileprivate class MockLoopState: LoopState { } } +public enum BolusEntryViewTestError: Error { + case responseUndefined +} + fileprivate class MockBolusEntryViewModelDelegate: BolusEntryViewModelDelegate { + + fileprivate var loopState = MockLoopState() + + private let dataAccessQueue = DispatchQueue(label: "com.loopKit.tests.dataAccessQueue", qos: .utility) + + + func updateRemoteRecommendation() { + } + func roundBolusVolume(units: Double) -> Double { // 0.05 units for rates between 0.05-30U/hr // 0 is not a supported bolus volume @@ -942,23 +857,29 @@ fileprivate class MockBolusEntryViewModelDelegate: BolusEntryViewModelDelegate { var displayGlucoseUnitObservable: DisplayGlucoseUnitObservable = DisplayGlucoseUnitObservable(displayGlucoseUnit: .milligramsPerDeciliter) - var loopStateCallBlock: ((LoopState) -> Void)? func withLoopState(do block: @escaping (LoopState) -> Void) { - loopStateCallBlock = block + dataAccessQueue.async { + block(self.loopState) + } } - + + func saveGlucose(sample: LoopKit.NewGlucoseSample) async -> LoopKit.StoredGlucoseSample? { + glucoseSamplesAdded.append(sample) + return StoredGlucoseSample(sample: sample.quantitySample) + } + var glucoseSamplesAdded = [NewGlucoseSample]() - var addGlucoseCompletion: ((Swift.Result<[StoredGlucoseSample], Error>) -> Void)? + var addGlucoseSamplesResult: Swift.Result<[StoredGlucoseSample], Error> = .failure(BolusEntryViewTestError.responseUndefined) func addGlucoseSamples(_ samples: [NewGlucoseSample], completion: ((Swift.Result<[StoredGlucoseSample], Error>) -> Void)?) { glucoseSamplesAdded.append(contentsOf: samples) - addGlucoseCompletion = completion + completion?(addGlucoseSamplesResult) } var carbEntriesAdded = [(NewCarbEntry, StoredCarbEntry?)]() - var addCarbEntryCompletion: ((Result) -> Void)? + var addCarbEntryResult: Result = .failure(BolusEntryViewTestError.responseUndefined) func addCarbEntry(_ carbEntry: NewCarbEntry, replacing replacingEntry: StoredCarbEntry?, completion: @escaping (Result) -> Void) { carbEntriesAdded.append((carbEntry, replacingEntry)) - addCarbEntryCompletion = completion + completion(addCarbEntryResult) } var bolusDosingDecisionsAdded = [(BolusDosingDecision, Date)]() @@ -982,6 +903,8 @@ fileprivate class MockBolusEntryViewModelDelegate: BolusEntryViewModelDelegate { func insulinOnBoard(at date: Date, completion: @escaping (DoseStoreResult) -> Void) { if let insulinOnBoardResult = insulinOnBoardResult { completion(insulinOnBoardResult) + } else { + completion(.failure(.configurationError)) } } diff --git a/LoopUI/Charts/IOBChart.swift b/LoopUI/Charts/IOBChart.swift index 256d2685d7..a78699ea64 100644 --- a/LoopUI/Charts/IOBChart.swift +++ b/LoopUI/Charts/IOBChart.swift @@ -9,9 +9,13 @@ import Foundation import LoopKit import LoopKitUI import SwiftCharts +import HealthKit public class IOBChart: ChartProviding { + + static let chartUnit = HKUnit.internationalUnit() + public init() { } @@ -106,7 +110,7 @@ public extension IOBChart { iobPoints = iobValues.map { return ChartPoint( x: ChartAxisValueDate(date: $0.startDate, formatter: dateFormatter), - y: ChartAxisValueDoubleUnit($0.value, unitString: "U", formatter: doseFormatter) + y: ChartAxisValueDoubleUnit($0.value, unitString: Self.chartUnit.localizedShortUnitString, formatter: doseFormatter) ) } } diff --git a/LoopUI/StatusBarHUDView.xib b/LoopUI/StatusBarHUDView.xib index b397049968..f603d7cf91 100644 --- a/LoopUI/StatusBarHUDView.xib +++ b/LoopUI/StatusBarHUDView.xib @@ -355,7 +355,7 @@ - + diff --git a/LoopUI/Views/LoopCompletionHUDView.swift b/LoopUI/Views/LoopCompletionHUDView.swift index 39a1bf8512..b0e6b1387b 100644 --- a/LoopUI/Views/LoopCompletionHUDView.swift +++ b/LoopUI/Views/LoopCompletionHUDView.swift @@ -121,7 +121,7 @@ public final class LoopCompletionHUDView: BaseHUDView { private var lastLoopMessage: String = "" - private lazy var formatter: DateComponentsFormatter = { + private lazy var timeAgoFormatter: DateComponentsFormatter = { let formatter = DateComponentsFormatter() formatter.allowedUnits = [.day, .hour, .minute] @@ -131,14 +131,31 @@ public final class LoopCompletionHUDView: BaseHUDView { return formatter }() + private lazy var timeFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .none + formatter.timeStyle = .short + return formatter + }() + + private lazy var timeDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .medium + formatter.timeStyle = .short + formatter.locale = Locale.current + return formatter + }() + @objc private func updateDisplay(_: Timer?) { lastLoopMessage = "" + let timeAgoToIncludeTimeStamp: TimeInterval = .minutes(20) + let timeAgoToIncludeDate: TimeInterval = .hours(4) if let date = lastLoopCompleted { let ago = abs(min(0, date.timeIntervalSinceNow)) freshness = LoopCompletionFreshness(age: ago) - if let timeString = formatter.string(from: ago) { + if let timeString = timeAgoFormatter.string(from: ago) { switch traitCollection.preferredContentSizeCategory { case UIContentSizeCategory.extraSmall, UIContentSizeCategory.small, @@ -152,9 +169,17 @@ public final class LoopCompletionHUDView: BaseHUDView { accessibilityLabel = String(format: LocalizedString("Loop ran %@ ago", comment: "Accessbility format label describing the time interval since the last completion date. (1: The localized date components)"), timeString) - if let fullTimeStr = formatterFull.string(from: ago) { - lastLoopMessage = String(format: LocalizedString("%1$@ last successfully completed a loop %2$@ ago.", comment: "Last loop time completed message (1: app name) (2: last loop time string)"), Bundle.main.bundleDisplayName, fullTimeStr) + var fullTimeStr: String = "" + if ago >= timeAgoToIncludeDate { + fullTimeStr = String(format: LocalizedString("was at %1$@", comment: "Format string describing last completion. (1: the date"), timeDateFormatter.string(from: date)) + } else if ago >= timeAgoToIncludeTimeStamp { + fullTimeStr = String(format: LocalizedString("%1$@ ago at %2$@", comment: "Format string describing last completion. (1: time ago, (2: the date"), timeAgoFormatter.string(from: ago)!, timeFormatter.string(from: date)) + } else if ago < .minutes(1) { + fullTimeStr = String(format: LocalizedString("<1 min ago", comment: "Format string describing last completion")) + } else { + fullTimeStr = String(format: LocalizedString("%1$@ ago", comment: "Format string describing last completion. (1: time ago"), timeAgoFormatter.string(from: ago)!) } + lastLoopMessage = String(format: LocalizedString("Last completed loop %1$@.", comment: "Last loop time completed message (1: last loop time string)"), fullTimeStr) } else { caption?.text = "–" accessibilityLabel = nil @@ -183,12 +208,12 @@ extension LoopCompletionHUDView { switch freshness { case .fresh: if loopStateView.open { - let reason = closedLoopDisallowedLocalizedDescription ?? NSLocalizedString("Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin.", comment: "Instructions for user to close loop if it is allowed.") + let reason = closedLoopDisallowedLocalizedDescription ?? LocalizedString("Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin.", comment: "Instructions for user to close loop if it is allowed.") return (title: LocalizedString("Closed Loop OFF", comment: "Title of green open loop OFF message"), - message: String(format: NSLocalizedString("\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@", comment: "Green closed loop OFF message (1: app name)(2: reason for open loop)"), Bundle.main.bundleDisplayName, reason)) + message: String(format: LocalizedString("\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@", comment: "Green closed loop OFF message (1: app name)(2: reason for open loop)"), Bundle.main.bundleDisplayName, reason)) } else { return (title: LocalizedString("Closed Loop ON", comment: "Title of green closed loop ON message"), - message: String(format: LocalizedString("\n%1$@ is operating with Closed Loop in the ON position. %2$@", comment: "Green closed loop ON message (1: app name) (2: last loop string)"), Bundle.main.bundleDisplayName, lastLoopMessage)) + message: String(format: LocalizedString("\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position.", comment: "Green closed loop ON message (1: last loop string) (2: app name)"), lastLoopMessage, Bundle.main.bundleDisplayName)) } case .aging: return (title: LocalizedString("Loop Warning", comment: "Title of yellow loop message"), diff --git a/LoopUI/ar.lproj/InfoPlist.strings b/LoopUI/ar.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/ar.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/ar.lproj/Localizable.strings b/LoopUI/ar.lproj/Localizable.strings new file mode 100644 index 0000000000..7da2dd2672 --- /dev/null +++ b/LoopUI/ar.lproj/Localizable.strings @@ -0,0 +1,60 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string describing the time interval since the last completion date. (1: The localized date components */ +"%@ ago" = "%@ ago"; + +/* The format string describing the basal rate. */ +"%@ U" = "%@ U"; + +/* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ +"%1$@ at %2$@" = "%1$@ at %2$@"; + +/* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ +"%1$@ units per hour at %2$@" = "%1$@ units per hour at %2$@"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Format string describing glucose units per minute (1: glucose unit string) */ +"%1$@/min" = "%1$@/min"; + +/* Accessibility hint describing completion HUD for a closed loop */ +"Closed loop" = "Closed loop"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Title of red loop message */ +"Loop Failure" = "فشل في الحلقة المغلقة"; + +/* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ +"Loop ran %@ ago" = "Loop ran %@ ago"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Accessibility label component for glucose HUD describing an invalid state */ +"Needs attention" = "Needs attention"; + +/* Accessbility hint describing completion HUD for an open loop */ +"Open loop" = "Open loop"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "وحدة"; + +/* Accessibility value for an unknown value */ +"Unknown" = "Unknown"; + +/* Acessibility label describing completion HUD waiting for first run */ +"Waiting for first run" = "Waiting for first run"; + diff --git a/LoopUI/cs.lproj/Localizable.strings b/LoopUI/cs.lproj/Localizable.strings new file mode 100644 index 0000000000..cf9c1665a4 --- /dev/null +++ b/LoopUI/cs.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + diff --git a/LoopUI/da.lproj/InfoPlist.strings b/LoopUI/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/da.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/da.lproj/Localizable.strings b/LoopUI/da.lproj/Localizable.strings index deda259d07..df0acc7364 100644 --- a/LoopUI/da.lproj/Localizable.strings +++ b/LoopUI/da.lproj/Localizable.strings @@ -1,29 +1,95 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ kører med Lukket Loop i ON-position."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nTryk på dine CGM- og insulinpumpestatussymboler for at få flere oplysninger. %2$@ fortsætter med at forsøge at fuldføre et loop, men kontrollér, om der er potentielle kommunikationsproblemer med din pumpe og CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nTryk på dine CGM- og insulinpumpestatussymboler for at få flere oplysninger. %2$@ fortsætter med at forsøge at fuldføre et loop, men hold øje med potentielle kommunikationsproblemer med din pumpe og CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ kører med Lukket Loop i OFF-positionen. Din pumpe og CGM fortsætter med at fungere, men appen justerer ikke doseringen automatisk.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ siden"; /* The format string describing the basal rate. */ "%@ U" = "%@ E"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ siden"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ siden ved %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ ved %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ enheder per time ved %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "<1 min siden"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Lukket loop"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Lukket loop FRA"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Lukket loop TIL"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HØJ"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Sidst afsluttet Loop %1$@."; + +/* Title of red loop message */ +"Loop Failure" = "Loop-fejl"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop kørte for %@ siden"; +/* Title of yellow loop message */ +"Loop Warning" = "Loop advarsel"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "LAV"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ -"Needs attention" = "Behøver opmærksomhed"; +"Needs attention" = "Handling påkrævet"; /* Accessbility hint describing completion HUD for an open loop */ -"Open loop" = "Åben loop"; +"Open loop" = "Åben Loop"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Tryk på Indstillinger for at slå Lukket Loop til, hvis du ønsker, at appen skal automatisere dit insulin."; /* The short unit display string for international units of insulin */ "U" = "E"; @@ -34,3 +100,6 @@ /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Venter på første kørsel"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "var %1$@"; + diff --git a/LoopUI/de.lproj/InfoPlist.strings b/LoopUI/de.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/de.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/de.lproj/Localizable.strings b/LoopUI/de.lproj/Localizable.strings index 5a4c6503a5..4ef4ec616d 100644 --- a/LoopUI/de.lproj/Localizable.strings +++ b/LoopUI/de.lproj/Localizable.strings @@ -1,33 +1,45 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ wird mit Closed Loop in der Position EIN betrieben."; + /* Red loop message (1: last loop string) (2: app name) */ -"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nTippe auf die Statussymbole für das CGM oder die Insulinpumpe, um weitere Informationen zu erhalten. %2$@ wird weiterhin versuchen, eine Schleife abzuschließen, aber achte auf mögliche Kommunikationsprobleme mit Deiner Pumpe und Deinem CGM."; +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nTippen Sie auf die Statussymbole für das CGM oder die Insulinpumpe, um weitere Informationen zu erhalten. %2$@ wird weiterhin versuchen, einen Loop abzuschließen, aber achten Sie auf mögliche Kommunikationsprobleme mit Ihrer Pumpe und CGM."; /* Yellow loop message (1: last loop string) (2: app name) */ -"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nTippe auf die Statussymbole für das CGM oder die Insulinpumpe, um weitere Informationen zu erhalten. %2$@ wird weiterhin versuchen, eine Schleife abzuschließen, aber achte auf mögliche Kommunikationsprobleme mit Deiner Pumpe und Deinem CGM."; +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nTippen Sie auf die Statussymbole für das CGM oder die Insulinpumpe, um weitere Informationen zu erhalten. %2$@ wird weiterhin versuchen, einen Loop abzuschließen, aber achten Sie auf mögliche Kommunikationsprobleme mit Ihrer Pumpe und CGM."; /* Green closed loop OFF message (1: app name)(2: reason for open loop) */ "\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ arbeitet mit geschlossenem Regelkreis in der AUS-Position. Ihre Pumpe und CGM funktionieren weiter, aber die App passt die Dosierung nicht automatisch an.\n\n%2$@"; -/* Green closed loop ON message (1: app name) (2: last loop string) */ -"\n%1$@ is operating with Closed Loop in the ON position. %2$@" = "\n%1$@ arbeitet mit geschlossenem Regelkreis in der EIN-Position. %2$@"; +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; /* Format string describing the time interval since the last completion date. (1: The localized date components */ -"%@ ago" = "vor %@"; +"%@ ago" = "%@ vor"; /* The format string describing the basal rate. */ "%@ U" = "%@ IE"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ vor"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "Vor %1$@ am %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ in %2$@"; -/* Last loop time completed message (1: app name) (2: last loop time string) */ -"%1$@ last successfully completed a loop %2$@ ago." = "%1$@ hat zuletzt vor %2$@ erfolgreich eine Schleife beendet."; - /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ Einheiten pro Stunde in %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "vor <1 min"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Geschlossener Loop"; @@ -37,11 +49,20 @@ /* Title of green closed loop ON message */ "Closed Loop ON" = "Closed Loop AN"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + /* String displayed instead of a glucose value above the CGM range */ "HIGH" = "HOCH"; +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Loop wurde nicht erfolgreich abgeschlossen seit %@"; + /* Title of red loop message */ -"Loop Failure" = "Loop Fehler"; +"Loop Failure" = "Loop fehlgeschlagen"; /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop lief seit %@"; @@ -52,14 +73,23 @@ /* String displayed instead of a glucose value below the CGM range */ "LOW" = "NIEDRIG"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Erfordert Aufmerksamkeit"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Offener Loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* Instructions for user to close loop if it is allowed. */ -"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Tippe auf Einstellungen, um Closed Loop einzuschalten, wenn Du möchtest, dass die App Dein Insulin automatisiert."; +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Tippen Sie auf Einstellungen, um Closed Loop einzuschalten, wenn Sie möchten, dass die App Ihr Insulin automatisiert."; /* The short unit display string for international units of insulin */ "U" = "IE"; @@ -70,3 +100,6 @@ /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Warten auf die erste Ausführung"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "Zuletzt abgeschlossen %1$@"; + diff --git a/LoopUI/es.lproj/InfoPlist.strings b/LoopUI/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/es.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/es.lproj/Localizable.strings b/LoopUI/es.lproj/Localizable.strings index 392cf073d9..34d3a8c848 100644 --- a/LoopUI/es.lproj/Localizable.strings +++ b/LoopUI/es.lproj/Localizable.strings @@ -1,33 +1,105 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "%1$@\n\n%2$@ está funcionando con Loop Cerrado en posición de prendido."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nPulse los iconos de estado del CGM y de la bomba de insulina para obtener más información. %2$@ continuará intentando completarel loop, pero compruebe si existen posibles problemas de comunicación con la bomba y el CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nPulse los iconos de estado del CGM y de la bomba de insulina para obtener más información. %2$@ seguirá intentando completar el loop, pero esté atento a posibles problemas de comunicación con la bomba y el CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ está funcionando con el circuito cerrado en la posición de apagado. La bomba y el CGM seguirán funcionando, pero la aplicación no ajustará la dosis automáticamente.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ -"%@ ago" = "hace %@"; +"%@ ago" = "Hace %@"; /* The format string describing the basal rate. */ "%@ U" = "%@ U"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "Hace %@"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "Hace %1$@ a las %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ en %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ unidades por hora en %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "Hace <1 minuto"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Asa cerrada"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Asa cerrada APAGADA"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Asa cerrada ACTIVADA"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "ALTO"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Último loop completado %1$@."; + +/* Title of red loop message */ +"Loop Failure" = "Falla del Loop"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop corrió hace %@"; +/* Title of yellow loop message */ +"Loop Warning" = "Advertencia de Loop"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "BAJO"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Necesita atención"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Asa abierta"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Pulse Ajustes para activar el loop cerrado si desea que la aplicación automatice su administracion de insulina."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Desconocido"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Esperando el primer uso"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "estaba en %1$@"; + diff --git a/LoopUI/fi.lproj/InfoPlist.strings b/LoopUI/fi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/fi.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/fi.lproj/Localizable.strings b/LoopUI/fi.lproj/Localizable.strings index b2b65c2bf0..d50b185502 100644 --- a/LoopUI/fi.lproj/Localizable.strings +++ b/LoopUI/fi.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@"; @@ -10,21 +13,57 @@ /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ yksikköä tunnissa klo %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Suljettu säätö"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Suljettu säätö pois päältä"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Suljettu säätö päällä"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "KORKEA"; + +/* Title of red loop message */ +"Loop Failure" = "Loopin häiriö"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Viimeisin säätö %@ sitten"; +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "MATALA"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Tarvitsee huomiota"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Avoin säätö"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Tuntematon"; diff --git a/LoopUI/fr.lproj/InfoPlist.strings b/LoopUI/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/fr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/fr.lproj/Localizable.strings b/LoopUI/fr.lproj/Localizable.strings index 3784a86b91..c112b82f3b 100644 --- a/LoopUI/fr.lproj/Localizable.strings +++ b/LoopUI/fr.lproj/Localizable.strings @@ -1,23 +1,83 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n %2$@ fonctionne avec la boucle fermée en position MARCHE."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nAppuyer sur les icônes du CGM ou de la pompe à insulie pour plus d'information. %2$@ va continuer de tenter de compléter une boucle, mais vérifiez pour des problèmes de communication potentiels avec votre pompe et le CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nAppuyer sur les icônes du CGM ou de la pompe à insuline pour plus d'information. %2$@ va continuer de tenter de compléter une boucle, mais surveillez pour des problèmes de communication potentiels avec votre pompe et le CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ fonctionne avec la boucle fermée en position ARRÊT. Votre pompe et votre CGM continueront de fonctionner, mais l'application n'ajustera pas automatiquement le dosage.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "Il y a %@"; /* The format string describing the basal rate. */ "%@ U" = "%@ U"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "Il y a %@"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "Il y a %@ à %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ à %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ unités par heure à %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "moins qu'une minute"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Loop fermée"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Boucle Ouverte"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Boucle Fermée"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HAUT"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Dernière boucle terminée %1$@."; + +/* Title of red loop message */ +"Loop Failure" = "Echec de Loop"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ -"Loop ran %@ ago" = "Loop a roulé il y a %@"; +"Loop ran %@ ago" = "Loop a bouclé il y a %@"; + +/* Title of yellow loop message */ +"Loop Warning" = "Avertissement de Loop"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "BAS"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Nécessite de l'attention"; @@ -25,9 +85,21 @@ /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Loop ouverte"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Appuyez sur Paramètres pour activer la boucle fermée si vous souhaitez que l'application automatise l'administration d'insuline."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Inconnu"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "En attente de la première exécution"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "était à %1$@"; + diff --git a/LoopUI/he.lproj/Localizable.strings b/LoopUI/he.lproj/Localizable.strings index 0afa563329..6177f0dd64 100644 --- a/LoopUI/he.lproj/Localizable.strings +++ b/LoopUI/he.lproj/Localizable.strings @@ -1,32 +1,66 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string describing the time interval since the last completion date. (1: The localized date components */ +"%@ ago" = "%@ ago"; + +/* The format string describing the basal rate. */ +"%@ U" = "%@ U"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ at %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ units per hour at %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; -/* Format string describing the time interval since the last completion date. (1: The localized date components */ -"%@ ago" = "%@ ago"; - -/* The format string describing the basal rate. */ -"%@ U" = "%@ U"; - /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Closed loop"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "גבוה"; + +/* Title of red loop message */ +"Loop Failure" = "Loop Failure"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop ran %@ ago"; +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "נמוך"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Needs attention"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Open loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Unknown"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Waiting for first run"; + diff --git a/LoopUI/hi.lproj/Localizable.strings b/LoopUI/hi.lproj/Localizable.strings new file mode 100644 index 0000000000..b30804332b --- /dev/null +++ b/LoopUI/hi.lproj/Localizable.strings @@ -0,0 +1,9 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HIGH"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "LOW"; + diff --git a/LoopUI/it.lproj/InfoPlist.strings b/LoopUI/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/it.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/it.lproj/Localizable.strings b/LoopUI/it.lproj/Localizable.strings index f0ed716021..37c6c625cb 100644 --- a/LoopUI/it.lproj/Localizable.strings +++ b/LoopUI/it.lproj/Localizable.strings @@ -1,33 +1,105 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ sta funzionando con il ciclo chiuso in posizione ON."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nPer ulteriori informazioni, toccare le icone di stato del CGM e del microinfusore d'insulina. %2$@ continuerà a tentare di completare un ciclo, ma controlla eventuali problemi di comunicazione con il microinfusore e il CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nPer ulteriori informazioni, toccare le icone di stato del CGM e del microinfusore d'insulina. %2$@ continuerà a tentare di completare un ciclo, ma è necessario prestare attenzione a potenziali problemi di comunicazione con il microinfusore e il CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ sta funzionando con il ciclo chiuso in posizione OFF. Il microinfusore e il CGM continueranno a funzionare, ma l'applicazione non regolerà automaticamente il dosaggio.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ fa"; /* The format string describing the basal rate. */ "%@ U" = "%@ U"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ fa"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ fa alle %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ a %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ unità per ora a %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ contro %2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "< 1 minuto fa"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Loop chiuso"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Circuito chiuso OFF"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Circuito chiuso ON"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "ALTO"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Ultimo ciclo completato %1$@ ."; + +/* Title of red loop message */ +"Loop Failure" = "Malfunzionamento di Loop"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop funziona %@ fa"; +/* Title of yellow loop message */ +"Loop Warning" = "Avviso Loop"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "BASSO"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Esige attenzione"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Loop aperto"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Tocca impostazioni per attivare il ciclo chiuso se si desidera che l'app automatizzi l'insulina."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Sconosciuto"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "In attesa di prima esecuzione"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "era a %1$@"; + diff --git a/LoopUI/ja.lproj/InfoPlist.strings b/LoopUI/ja.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f8e9a2b43f --- /dev/null +++ b/LoopUI/ja.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/ja.lproj/Localizable.strings b/LoopUI/ja.lproj/Localizable.strings index dc0fe55bca..6e658af6b2 100644 --- a/LoopUI/ja.lproj/Localizable.strings +++ b/LoopUI/ja.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ 前"; @@ -10,21 +13,45 @@ /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ U/時 @ %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/分"; /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "クローズドループ"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Title of red loop message */ +"Loop Failure" = "ループの不良"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "ループは %@ 前に作動しました"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "注意が必要です"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "オープンループ"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "不明"; diff --git a/LoopUI/nb.lproj/InfoPlist.strings b/LoopUI/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/nb.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/nb.lproj/Localizable.strings b/LoopUI/nb.lproj/Localizable.strings index e2ee3e2432..cf8aa03166 100644 --- a/LoopUI/nb.lproj/Localizable.strings +++ b/LoopUI/nb.lproj/Localizable.strings @@ -1,30 +1,96 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ opererer med Closed Loop i ON-posisjon."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\n Trykk på statusikonene for CGM og insulinpumpe for mer informasjon. %2$@ vil fortsette å prøve å fullføre en sløyfe, men se etter potensielle kommunikasjonsproblemer med pumpen og CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nTrykk på statusikonene for CGM og insulinpumpe for mer informasjon. %2$@ vil fortsette å prøve å fullføre en loop, men se etter potensielle kommunikasjonsproblemer med pumpen og CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ opererer med Closed Loop i OFF posisjon. Pumpen og CGM vil fortsette å fungere, men appen vil ikke justere doseringen automatisk.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ siden"; /* The format string describing the basal rate. */ "%@ U" = "%@ E"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ siden"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ siden kl. %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ kl. %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ enheter per time kl. %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "< 1 min siden"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Lukket Loop"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Lukket Loop AV"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Lukket Loop PÅ"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HØY"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Sist fullført loop %1$@."; + +/* Title of red loop message */ +"Loop Failure" = "Loop-feil"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop kjørte %@ siden"; +/* Title of yellow loop message */ +"Loop Warning" = "Loop Varsel"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "LAV"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Trenger tilsyn"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Åpen Loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Trykk på Innstillinger for å slå Closed Loop PÅ om du ønsker at appen skal automatisere insulinet ditt."; + /* The short unit display string for international units of insulin */ "U" = "E"; @@ -34,3 +100,6 @@ /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Venter på første kjøring"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "var på %1$@"; + diff --git a/LoopUI/nl.lproj/InfoPlist.strings b/LoopUI/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/nl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/nl.lproj/Localizable.strings b/LoopUI/nl.lproj/Localizable.strings index b5ca322d7d..c806ba96ac 100644 --- a/LoopUI/nl.lproj/Localizable.strings +++ b/LoopUI/nl.lproj/Localizable.strings @@ -1,30 +1,96 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ werkt met Gesloten Loop in de AAN stand"; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nTik op je CGM- en insulinepompstatuspictogram voor meer informatie. %2$@ blijft proberen een loop te voltooien, maar let op mogelijke communicatieproblemen met je pomp en CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nTik op je CGM- en insulinepompstatuspictogram voor meer informatie. %2$@ blijft proberen een loop te voltooien, maar let op mogelijke communicatieproblemen met je pomp en CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ werkt met Gesloten Loop in de UIT stand. Je pomp en CGM blijven werken, maar de app past de dosering niet automatisch aan.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ geleden"; /* The format string describing the basal rate. */ "%@ U" = "%@ E"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ geleden"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ geleden om %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ -"%1$@ at %2$@" = "%1$@ at %2$@"; +"%1$@ at %2$@" = "%1$@ om %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ -"%1$@ units per hour at %2$@" = "%1$@ eenheden per uur op %2$@"; +"%1$@ units per hour at %2$@" = "%1$@ eenheden per uur om %2$@"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "<1 min geleden"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Gesloten loop"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Gesloten Loop UIT"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Gesloten Loop AAN"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HOOG"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Laatst voltooide loop %1$@."; + +/* Title of red loop message */ +"Loop Failure" = "Loopstoring"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop heeft %@ geleden gedraaid"; +/* Title of yellow loop message */ +"Loop Warning" = "Loopwaarschuwing"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "LAAG"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Aandacht vereist"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Open loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Tik op Instellingen om Gesloten Loop AAN te zetten als je wilt dat de app je insulinetoediening automatiseert."; + /* The short unit display string for international units of insulin */ "U" = "E"; @@ -32,5 +98,8 @@ "Unknown" = "Onbekend"; /* Acessibility label describing completion HUD waiting for first run */ -"Waiting for first run" = "Wachten op eerste run"; +"Waiting for first run" = "Aan het wachten op eerste run"; + +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "was om %1$@"; diff --git a/LoopUI/pl.lproj/InfoPlist.strings b/LoopUI/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/pl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/pl.lproj/Localizable.strings b/LoopUI/pl.lproj/Localizable.strings index cc07569b5c..e1364eb1ba 100644 --- a/LoopUI/pl.lproj/Localizable.strings +++ b/LoopUI/pl.lproj/Localizable.strings @@ -1,32 +1,105 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n %2$@ działa z zamkniętą pętlą w pozycji WŁĄCZONA."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nStuknij ikonę stanu CGM i pompy insulinowej, aby uzyskać więcej informacji. %2$@ będzie nadal próbował ukończyć pętlę, ale uważaj na potencjalne problemy z komunikacją z pompą i CGM."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nStuknij ikony stanu CGM i pompy insulinowej, aby uzyskać więcej informacji. %2$@ będzie nadal próbował ukończyć pętlę, ale uważaj na potencjalne problemy z komunikacją z pompą i CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ działa z zamkniętą pętlą w pozycji WYŁĄCZONA. Twoja pompa i CGM będą nadal działać, ale aplikacja nie będzie automatycznie dostosowywać dawkowania. \n\n %2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Format string describing the time interval since the last completion date. (1: The localized date components */ +"%@ ago" = "%@ temu"; + +/* The format string describing the basal rate. */ +"%@ U" = "%@ J"; + +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ temu"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ temu o %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ o %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ jednostek na godzinę o %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; -/* Format string describing the time interval since the last completion date. (1: The localized date components */ -"%@ ago" = "%@ temu"; - -/* The format string describing the basal rate. */ -"%@ U" = "%@ J"; +/* Format string describing last completion */ +"<1 min ago" = "< 1 minutę temu"; /* Accessibility hint describing completion HUD for a closed loop */ -"Closed loop" = "Zamknięta Loop"; +"Closed loop" = "Pętla zamknięta"; + +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Pętla zamknięta WYŁĄCZONA"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Zamknięta pętla WŁĄCZONA"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "WYSOKI"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Ostatnia ukończona pętla %1$@ ."; + +/* Title of red loop message */ +"Loop Failure" = "Awaria pętli"; /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Pętla była uruchomiona %@ temu"; +/* Title of yellow loop message */ +"Loop Warning" = "Ostrzeżenie o pętli"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "NISKI"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Wymaga uwagi"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Otwarta Loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Stuknij Ustawienia, aby włączyć Pętlę zamkniętą, jeśli chcesz, aby aplikacja zautomatyzowała podawanie insuliny."; + +/* The short unit display string for international units of insulin */ +"U" = "J"; + /* Accessibility value for an unknown value */ "Unknown" = "Nieznany"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Oczekiwanie na pierwsze uruchomienie"; + +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "był na %1$@"; + diff --git a/LoopUI/pt-BR.lproj/InfoPlist.strings b/LoopUI/pt-BR.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f8e9a2b43f --- /dev/null +++ b/LoopUI/pt-BR.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/pt-BR.lproj/Localizable.strings b/LoopUI/pt-BR.lproj/Localizable.strings index 78b767baeb..917f3065f2 100644 --- a/LoopUI/pt-BR.lproj/Localizable.strings +++ b/LoopUI/pt-BR.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ atrás"; @@ -10,21 +13,45 @@ /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ unidades por hora em %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Ciclo fechado"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Title of red loop message */ +"Loop Failure" = "Falha no Loop"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Ciclo executado %@ atrás"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Precisa de atenção"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Ciclo aberto"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Desconhecido"; diff --git a/LoopUI/ro.lproj/InfoPlist.strings b/LoopUI/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/ro.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/ro.lproj/Localizable.strings b/LoopUI/ro.lproj/Localizable.strings index 2b63178cfe..640e17f369 100644 --- a/LoopUI/ro.lproj/Localizable.strings +++ b/LoopUI/ro.lproj/Localizable.strings @@ -1,33 +1,105 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n %2$@ operează cu bucla închisă în poziția ON."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nAtingeți pictogramele de stare ale CGM și ale pompei de insulină pentru mai multe informații. %2$@ va continua să încerce să finalizeze o buclă, dar verificați eventualele probleme de comunicare cu pompa și CGM-ul dvs."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\n Atingeți pictogramele de stare pentru CGM și pompa de insulină pentru mai multe informații. %2$@ va continua să încerce să finalizeze o buclă, dar urmăriți eventualele probleme de comunicare cu pompa și CGM."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ operează cu bucla închisă în poziția OFF. Pompa și CGM vor continua să funcționeze, dar aplicația nu va ajusta automat dozarea. \n\n %2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ -"%@ ago" = "acum %@"; +"%@ ago" = "%@ în urmă"; /* The format string describing the basal rate. */ "%@ U" = "%@ U"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%@ în urmă"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "Acum %1$@ la %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ la %2$@"; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ unități pe oră la %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; +/* Format string describing last completion */ +"<1 min ago" = "< 1 min în urmă"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Loop automat"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Buclă închisă dezactivata"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Buclă închisă activata"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HIPER"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Ultima buclă finalizată %1$@ ."; + +/* Title of red loop message */ +"Loop Failure" = "Eșec Loop"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop a rulat acum %@"; +/* Title of yellow loop message */ +"Loop Warning" = "Avertizare Loop"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "HIPO"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Necesită atenție"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Loop manual"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@%2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Atingeți Setări pentru a activa bucla închisă dacă doriți ca aplicația să vă automatizeze administrarea de insulină."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ -"Unknown" = "Necunoscută"; +"Unknown" = "Necunoscut"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Se așteaptă prima rulare"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "a fost la %1$@"; + diff --git a/LoopUI/ru.lproj/InfoPlist.strings b/LoopUI/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/ru.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/ru.lproj/Localizable.strings b/LoopUI/ru.lproj/Localizable.strings index 0d5c9a60c6..b4492143d5 100644 --- a/LoopUI/ru.lproj/Localizable.strings +++ b/LoopUI/ru.lproj/Localizable.strings @@ -1,33 +1,105 @@ +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ работает с замкнутым циклом в положении ON."; + +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nДля получения дополнительной информации коснитесь значков состояния мониторинга и инсулиновой помпы. %2$@ будет продолжать попытки завершить цикл, но следите за возможными проблемами связи с вашей помпой и мониторингом."; + +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nДля получения дополнительной информации коснитесь значков состояния мониторинга и инсулиновой помпы. %2$@ будет продолжать попытки завершить цикл, но следите за возможными проблемами связи с вашей помпой и мониторингом."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ работает с замкнутым контуром в положении ВЫКЛ. Ваша помпа и мониторинг будут продолжать работать, но приложение не будет автоматически регулировать дозировку.\n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ назад"; /* The format string describing the basal rate. */ "%@ U" = "%@ ед"; +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ назад"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ назад в %2$@"; + /* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ "%1$@ at %2$@" = "%1$@ в %2$@ "; /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ ед/час в %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ против %2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/минут"; +/* Format string describing last completion */ +"<1 min ago" = "<1 мин. назад"; + /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Алгоритм замкнутого цикла"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Замкнутый цикл ВЫКЛ"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Замкнутый контур ВКЛ"; + +/* The short unit display string for decibles */ +"dB" = "дБ"; + +/* The short unit display string for grams */ +"g" = "г"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "ВЫСОКИЙ"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Последняя завершенная петля %1$@."; + +/* Title of red loop message */ +"Loop Failure" = "Ошибка в работе петли"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Алгоритм цикла запущен %@ назад"; +/* Title of yellow loop message */ +"Loop Warning" = "Предупреждение о петле"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "НИЗКИЙ"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "мг/дл"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Требует внимания"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Алгоритм открытого цикла"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Нажмите \"Настройки\", чтобы включить \"Замкнутый цикл\", если вы хотите, чтобы приложение автоматизировало подачу инсулина."; + +/* The short unit display string for international units of insulin */ +"U" = "ед"; + /* Accessibility value for an unknown value */ "Unknown" = "Неизвестно"; /* Acessibility label describing completion HUD waiting for first run */ "Waiting for first run" = "Ожидает первичного запуска"; +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "был в %1$@"; + diff --git a/LoopUI/sk.lproj/Localizable.strings b/LoopUI/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..38e5a37cea --- /dev/null +++ b/LoopUI/sk.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Format string describing the time interval since the last completion date. (1: The localized date components */ +"%@ ago" = "pred %@"; + +/* The format string describing the basal rate. */ +"%@ U" = "%@ j"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "VYSOKÁ"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "NÍZKA"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + +/* Accessibility value for an unknown value */ +"Unknown" = "Neznáme"; + diff --git a/LoopUI/sv.lproj/InfoPlist.strings b/LoopUI/sv.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5c1fb13406 --- /dev/null +++ b/LoopUI/sv.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "LoopUI"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/sv.lproj/Localizable.strings b/LoopUI/sv.lproj/Localizable.strings index 2acafe0cbf..542e0e6240 100644 --- a/LoopUI/sv.lproj/Localizable.strings +++ b/LoopUI/sv.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ sedan"; @@ -10,21 +13,54 @@ /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ enheter/h kl. %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/min"; /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Sluten loop"; +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Sluten Loop är AV"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Sluten Loop är PÅ"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "HÖGT"; + +/* Title of red loop message */ +"Loop Failure" = "Loopfel"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop kördes för %@ sedan"; +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "LÅGT"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Kräver åtgärd"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Öppen loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The short unit display string for international units of insulin */ "U" = "E"; diff --git a/LoopUI/tr.lproj/Localizable.strings b/LoopUI/tr.lproj/Localizable.strings index 0afa563329..87166dd6bf 100644 --- a/LoopUI/tr.lproj/Localizable.strings +++ b/LoopUI/tr.lproj/Localizable.strings @@ -1,32 +1,105 @@ -/* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ -"%1$@ at %2$@" = "%1$@ at %2$@"; +/* Green closed loop ON message (1: last loop string) (2: app name) */ +"\n%1$@\n\n%2$@ is operating with Closed Loop in the ON position." = "\n%1$@\n\n%2$@ Kapalı Döngü AÇIK konumdayken çalışıyor."; -/* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ -"%1$@ units per hour at %2$@" = "%1$@ units per hour at %2$@"; +/* Red loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but check for potential communication issues with your pump and CGM." = "\n%1$@\n\nDaha fazla bilgi için CGM ve insülin pompası durum simgelerine dokunun. %2$@ döngüyü tamamlamaya çalışacak, ancak pompanız ve CGM ile olası iletişim sorunlarını kontrol edin."; -/* Format string describing glucose units per minute (1: glucose unit string) */ -"%1$@/min" = "%1$@/min"; +/* Yellow loop message (1: last loop string) (2: app name) */ +"\n%1$@\n\nTap your CGM and insulin pump status icons for more information. %2$@ will continue trying to complete a loop, but watch for potential communication issues with your pump and CGM." = "\n%1$@\n\nDaha fazla bilgi için CGM ve insülin pompası durum simgelerinize dokunun. %2$@ döngüyü tamamlamaya çalışacak, ancak pompanız ve CGM ile olası iletişim sorunlarına dikkat edin."; + +/* Green closed loop OFF message (1: app name)(2: reason for open loop) */ +"\n%1$@ is operating with Closed Loop in the OFF position. Your pump and CGM will continue operating, but the app will not adjust dosing automatically.\n\n%2$@" = "\n%1$@ KAPALI konumda ve Kapalı Döngü ile çalışıyor. Pompanız ve CGM çalışmaya devam edecek, ancak uygulama dozajı otomatik olarak ayarlamayacaktır. \n\n%2$@"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; /* Format string describing the time interval since the last completion date. (1: The localized date components */ -"%@ ago" = "%@ ago"; +"%@ ago" = "%@ önce"; /* The format string describing the basal rate. */ -"%@ U" = "%@ U"; +"%@ U" = "%@ Ü"; + +/* Format string describing last completion. (1: time ago */ +"%1$@ ago" = "%1$@ önce"; + +/* Format string describing last completion. (1: time ago, (2: the date */ +"%1$@ ago at %2$@" = "%1$@ önce %2$@"; + +/* Accessbility format value describing glucose: (1: glucose number)(2: glucose time) */ +"%1$@ at %2$@" = "%1$@ %2$@"; + +/* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ +"%1$@ units per hour at %2$@" = "her %2$@ saatte %1$@ ünite"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* Format string describing glucose units per minute (1: glucose unit string) */ +"%1$@/min" = "%1$@/dk"; + +/* Format string describing last completion */ +"<1 min ago" = "< 1 dakika önce"; /* Accessibility hint describing completion HUD for a closed loop */ -"Closed loop" = "Closed loop"; +"Closed loop" = "Kapalı Döngü"; + +/* Title of green open loop OFF message */ +"Closed Loop OFF" = "Kapalı Döngü KAPALI"; + +/* Title of green closed loop ON message */ +"Closed Loop ON" = "Kapalı Döngü AÇIK"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "gr"; + +/* String displayed instead of a glucose value above the CGM range */ +"HIGH" = "YÜKSEK"; + +/* Last loop time completed message (1: last loop time string) */ +"Last completed loop %1$@." = "Son tamamlanan döngü %1$@ ."; + +/* Title of red loop message */ +"Loop Failure" = "Döngü Hatası"; /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ -"Loop ran %@ ago" = "Loop ran %@ ago"; +"Loop ran %@ ago" = "Döngü %@ önce çalıştı"; + +/* Title of yellow loop message */ +"Loop Warning" = "Döngü Uyarısı"; + +/* String displayed instead of a glucose value below the CGM range */ +"LOW" = "DÜŞÜK"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* Accessibility label component for glucose HUD describing an invalid state */ -"Needs attention" = "Needs attention"; +"Needs attention" = "İlgilenmeniz gerekiyor"; /* Accessbility hint describing completion HUD for an open loop */ -"Open loop" = "Open loop"; +"Open loop" = "Açık döngü"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Instructions for user to close loop if it is allowed. */ +"Tap Settings to toggle Closed Loop ON if you wish for the app to automate your insulin." = "Uygulamanın insülininizi otomatikleştirmesini istiyorsanız, Kapalı Döngüyü AÇIK duruma getirmek için Ayarlar'a dokunun."; + +/* The short unit display string for international units of insulin */ +"U" = "Ü"; /* Accessibility value for an unknown value */ -"Unknown" = "Unknown"; +"Unknown" = "Bilinmeyen"; /* Acessibility label describing completion HUD waiting for first run */ -"Waiting for first run" = "Waiting for first run"; +"Waiting for first run" = "İlk çalıştırma için bekleniyor"; + +/* Format string describing last completion. (1: the date */ +"was at %1$@" = "%1$@ de idi"; + diff --git a/LoopUI/vi.lproj/InfoPlist.strings b/LoopUI/vi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f8e9a2b43f --- /dev/null +++ b/LoopUI/vi.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/LoopUI/vi.lproj/Localizable.strings b/LoopUI/vi.lproj/Localizable.strings index 8461c5fb21..18ad4de1d1 100644 --- a/LoopUI/vi.lproj/Localizable.strings +++ b/LoopUI/vi.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + /* Format string describing the time interval since the last completion date. (1: The localized date components */ "%@ ago" = "%@ trước đó"; @@ -10,21 +13,45 @@ /* Accessibility format string describing the basal rate. (1: localized basal rate value)(2: last updated time) */ "%1$@ units per hour at %2$@" = "%1$@ units một giờ lúc %2$@"; +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + /* Format string describing glucose units per minute (1: glucose unit string) */ "%1$@/min" = "%1$@/phút"; /* Accessibility hint describing completion HUD for a closed loop */ "Closed loop" = "Closed loop"; +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* Title of red loop message */ +"Loop Failure" = "Loop lỗi"; + /* Accessbility format label describing the time interval since the last completion date. (1: The localized date components) */ "Loop ran %@ ago" = "Loop hoạt động %@ trước đó"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* Accessibility label component for glucose HUD describing an invalid state */ "Needs attention" = "Cần chú ý"; /* Accessbility hint describing completion HUD for an open loop */ "Open loop" = "Open loop"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* Accessibility value for an unknown value */ "Unknown" = "Không nhận ra"; diff --git a/Scripts/apply-info-customizations.sh b/Scripts/apply-info-customizations.sh new file mode 100755 index 0000000000..705390103b --- /dev/null +++ b/Scripts/apply-info-customizations.sh @@ -0,0 +1,61 @@ +#!/bin/sh -e + +# apply-info-customizations.sh +# Loop +# +# Created by Pete Schwamb on 4/25/23. +# Copyright © 2023 LoopKit Authors. All rights reserved. + + +SCRIPT="$(basename "${0}")" +SCRIPT_DIRECTORY="$(dirname "${0}")" + +error() { + echo "ERROR: ${*}" >&2 + echo "Usage: ${SCRIPT} [-i|--info-plist-path info-plist-path]" >&2 + echo "Parameters:" >&2 + echo " -i|--info-plist-path path to the Info.plist file to modify; optional, defaults to \${BUILT_PRODUCTS_DIR}/\${INFOPLIST_PATH}" >&2 + exit 1 +} + +warn() { + echo "WARN: ${*}" >&2 +} + +info() { + echo "INFO: ${*}" >&2 +} + +info_plist_path="${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}" +while [[ $# -gt 0 ]] +do + case $1 in + -i|--info-plist-path) + info_plist_path="${2}" + shift 2 + ;; + esac +done + +if [ ${#} -ne 0 ]; then + error "Unexpected arguments: ${*}" +fi + +if [ "${info_plist_path}" == "/" -o ! -e "${info_plist_path}" ]; then + error "Must provide valid --info-plist-path, or have valid \${BUILT_PRODUCTS_DIR} and \${INFOPLIST_PATH} set." +fi + +info "Applying info.plist customizations from ../InfoCustomizations.txt" + +while read -r -a words; do # iterate over lines of input + set -- "${words[@]}" # update positional parameters + for word; do + if [[ $word = *"="* ]]; then # if a word contains an "="... + key=${word%%=*} + value=${word#*=} + echo "Key = $key" + echo "Value = $value" + plutil -replace $key -string "${value}" "${info_plist_path}" + fi + done +done <"../InfoCustomizations.txt" diff --git a/Scripts/capture-build-details.sh b/Scripts/capture-build-details.sh index 8bd458b205..7543ec579c 100755 --- a/Scripts/capture-build-details.sh +++ b/Scripts/capture-build-details.sh @@ -89,7 +89,7 @@ fi # determine if this is a workspace build # if so, fill out the git revision and branch -if [ -e ../Loop.xcworkspace ] +if [ -e ../LoopWorkspace.xcworkspace ] then pushd . > /dev/null cd .. diff --git a/Scripts/copy-plugins.sh b/Scripts/copy-plugins.sh index 5be20f32e6..a81e221569 100755 --- a/Scripts/copy-plugins.sh +++ b/Scripts/copy-plugins.sh @@ -14,7 +14,7 @@ function copy_plugins { for f in "$1"/*.loopplugin; do plugin=$(basename "$f") echo Copying plugin: $plugin to frameworks directory in app - plugin_path="$(readlink "$f" || echo "$f")" + plugin_path="$(readlink -f "$f" || echo "$f")" plugin_as_framework_path="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/${plugin%.*}.framework" rsync -va --exclude=Frameworks "$plugin_path/." "${plugin_as_framework_path}" # Rename .plugin to .framework @@ -29,7 +29,7 @@ function copy_plugins { framework=$(basename "$framework_path") echo "Copying plugin's framework $framework_path to ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/." cp -avf "$framework_path" "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/." - plugin_path="$(readlink "$f" || echo "$f")" + plugin_path="$(readlink -f "$f" || echo "$f")" if [ "$EXPANDED_CODE_SIGN_IDENTITY" != "-" ] && [ "$EXPANDED_CODE_SIGN_IDENTITY" != "" ]; then echo "Signing $framework for $plugin with $EXPANDED_CODE_SIGN_IDENTITY_NAME" /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --timestamp=none --preserve-metadata=identifier,entitlements,flags "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/${framework}" diff --git a/StatusWidget/LoopCircleView.swift b/StatusWidget/LoopCircleView.swift index 0b06c3c968..4ebec4b119 100644 --- a/StatusWidget/LoopCircleView.swift +++ b/StatusWidget/LoopCircleView.swift @@ -37,14 +37,4 @@ struct LoopCircleView: View { return Color.red } } - - static let formatter: DateComponentsFormatter = { - let formatter = DateComponentsFormatter() - - formatter.allowedUnits = [.day, .hour, .minute] - formatter.maximumUnitCount = 1 - formatter.unitsStyle = .short - - return formatter - }() } diff --git a/StatusWidget/ar.lproj/Localizable.strings b/StatusWidget/ar.lproj/Localizable.strings new file mode 100644 index 0000000000..1b5e22003d --- /dev/null +++ b/StatusWidget/ar.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "وحدة"; + diff --git a/StatusWidget/da.lproj/InfoPlist.strings b/StatusWidget/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..cf4441a6fd --- /dev/null +++ b/StatusWidget/da.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 LoopKit Authors. All rights reserved."; + diff --git a/StatusWidget/da.lproj/Localizable.strings b/StatusWidget/da.lproj/Localizable.strings new file mode 100644 index 0000000000..9fa3086f1a --- /dev/null +++ b/StatusWidget/da.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-E"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Eventuel"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Widget til loop-status"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Se dit nuværende blodsukker og insulindosering."; + +/* The short unit display string for international units of insulin */ +"U" = "E"; + diff --git a/StatusWidget/de.lproj/InfoPlist.strings b/StatusWidget/de.lproj/InfoPlist.strings new file mode 100644 index 0000000000..bcc161e3bf --- /dev/null +++ b/StatusWidget/de.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 LoopKit-Autoren. Alle Rechte vorbehalten."; + diff --git a/StatusWidget/de.lproj/Localizable.strings b/StatusWidget/de.lproj/Localizable.strings new file mode 100644 index 0000000000..825d7e7e30 --- /dev/null +++ b/StatusWidget/de.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-IE"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ IE"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Eventuell"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Loop Status Widget"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Sehen Sie sich Ihre aktuelle Blutzucker- und Insulinabgabe an."; + +/* The short unit display string for international units of insulin */ +"U" = "IE"; + diff --git a/StatusWidget/es.lproj/InfoPlist.strings b/StatusWidget/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..801339d7c8 --- /dev/null +++ b/StatusWidget/es.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 Autores del LoopKit. Todos los derechos reservados."; + diff --git a/StatusWidget/es.lproj/Localizable.strings b/StatusWidget/es.lproj/Localizable.strings new file mode 100644 index 0000000000..10a11e8f2a --- /dev/null +++ b/StatusWidget/es.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-U"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Eventual"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Widget de Estado de Loop"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Mira tu glucosa en sangre actual y la administración de insulina."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/fi.lproj/Localizable.strings b/StatusWidget/fi.lproj/Localizable.strings new file mode 100644 index 0000000000..01fd5fd8c8 --- /dev/null +++ b/StatusWidget/fi.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/fr.lproj/InfoPlist.strings b/StatusWidget/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..ee7f998a4e --- /dev/null +++ b/StatusWidget/fr.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 LoopKit Authors. Tous droits réservés."; + diff --git a/StatusWidget/fr.lproj/Localizable.strings b/StatusWidget/fr.lproj/Localizable.strings new file mode 100644 index 0000000000..e1adf8e712 --- /dev/null +++ b/StatusWidget/fr.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-U"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Éventuel"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Widget d'état de Loop"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Voir votre glycémie actuelle et votre administration d'insuline."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/he.lproj/Localizable.strings b/StatusWidget/he.lproj/Localizable.strings new file mode 100644 index 0000000000..45356883ff --- /dev/null +++ b/StatusWidget/he.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/it.lproj/InfoPlist.strings b/StatusWidget/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f19b22e58e --- /dev/null +++ b/StatusWidget/it.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 Autori di LoopKit. Tutti i diritti riservati."; + diff --git a/StatusWidget/it.lproj/Localizable.strings b/StatusWidget/it.lproj/Localizable.strings new file mode 100644 index 0000000000..e048bd3a2f --- /dev/null +++ b/StatusWidget/it.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-U"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ contro %2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Eventuale"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Widget Stato loop"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Vedi la tua attuale glicemia e l'erogazione d'insulina."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/ja.lproj/Localizable.strings b/StatusWidget/ja.lproj/Localizable.strings new file mode 100644 index 0000000000..45356883ff --- /dev/null +++ b/StatusWidget/ja.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/nb.lproj/InfoPlist.strings b/StatusWidget/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f86e5bc45f --- /dev/null +++ b/StatusWidget/nb.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 LoopKit Authors. Alle rettigheter forbeholdt."; + diff --git a/StatusWidget/nb.lproj/Localizable.strings b/StatusWidget/nb.lproj/Localizable.strings new file mode 100644 index 0000000000..2b15f8378d --- /dev/null +++ b/StatusWidget/nb.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-E"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Eventuell"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Loop Status Widget"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Se ditt nåværende blodsukker- og insulintilførsel."; + +/* The short unit display string for international units of insulin */ +"U" = "E"; + diff --git a/StatusWidget/nl.lproj/InfoPlist.strings b/StatusWidget/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..4208dc1c17 --- /dev/null +++ b/StatusWidget/nl.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtentension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 LoopKit Auteurs. Alle rechten voorbehouden."; + diff --git a/StatusWidget/nl.lproj/Localizable.strings b/StatusWidget/nl.lproj/Localizable.strings new file mode 100644 index 0000000000..3d99d1bbd0 --- /dev/null +++ b/StatusWidget/nl.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "--"; + +/* No comment provided by engineer. */ +"-U" = "-E"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Uiteindelijk"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Loop"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Zie je huidige bloedglucose en insulinetoediening."; + +/* The short unit display string for international units of insulin */ +"U" = "E"; + diff --git a/StatusWidget/pl.lproj/InfoPlist.strings b/StatusWidget/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..a6a3d53ba7 --- /dev/null +++ b/StatusWidget/pl.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2023 Autorzy LoopKit. Wszelkie prawa zastrzeżone."; + diff --git a/StatusWidget/pl.lproj/Localizable.strings b/StatusWidget/pl.lproj/Localizable.strings new file mode 100644 index 0000000000..ebb661750e --- /dev/null +++ b/StatusWidget/pl.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-J"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ J"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Możliwy"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Widżet Stanu Pętli"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Zobacz aktualną dawkę glukozy i insuliny we krwi."; + +/* The short unit display string for international units of insulin */ +"U" = "J"; + diff --git a/StatusWidget/pt-BR.lproj/Localizable.strings b/StatusWidget/pt-BR.lproj/Localizable.strings new file mode 100644 index 0000000000..45356883ff --- /dev/null +++ b/StatusWidget/pt-BR.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/ro.lproj/InfoPlist.strings b/StatusWidget/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..15494bcee9 --- /dev/null +++ b/StatusWidget/ro.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 Autori LoopKit. Toate drepturile rezervate."; + diff --git a/StatusWidget/ro.lproj/Localizable.strings b/StatusWidget/ro.lproj/Localizable.strings new file mode 100644 index 0000000000..55292e65db --- /dev/null +++ b/StatusWidget/ro.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-U"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Eventual"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Extensie stare Loop"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@%2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Vedeți nivelul actual al glicemiei și al administrării de insulină."; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/StatusWidget/ru.lproj/InfoPlist.strings b/StatusWidget/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..34760b8f57 --- /dev/null +++ b/StatusWidget/ru.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Copyright © 2022 LoopKit Authors. Все права защищены."; + diff --git a/StatusWidget/ru.lproj/Localizable.strings b/StatusWidget/ru.lproj/Localizable.strings new file mode 100644 index 0000000000..f00c8af85e --- /dev/null +++ b/StatusWidget/ru.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-Ед"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ ед"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ против %2$@"; + +/* The short unit display string for decibles */ +"dB" = "дБ"; + +/* No comment provided by engineer. */ +"Eventual" = "В конечном итоге"; + +/* The short unit display string for grams */ +"g" = "г"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Виджет состояния петли"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "мг/дл"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Смотрите текущий уровень глюкозы в крови и ввод инсулина."; + +/* The short unit display string for international units of insulin */ +"U" = "ед"; + diff --git a/StatusWidget/sk.lproj/Localizable.strings b/StatusWidget/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..c85e705210 --- /dev/null +++ b/StatusWidget/sk.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* No comment provided by engineer. */ +"%@ U" = "%@ j"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v %2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + diff --git a/StatusWidget/sv.lproj/Localizable.strings b/StatusWidget/sv.lproj/Localizable.strings new file mode 100644 index 0000000000..e3c1e4c52d --- /dev/null +++ b/StatusWidget/sv.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ E"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "E"; + diff --git a/StatusWidget/tr.lproj/InfoPlist.strings b/StatusWidget/tr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..085534a40b --- /dev/null +++ b/StatusWidget/tr.lproj/InfoPlist.strings @@ -0,0 +1,9 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "SmallStatusWidget"; + +/* Bundle name */ +"CFBundleName" = "SmallStatusWidgetExtension"; + +/* Copyright (human-readable) */ +"NSHumanReadableCopyright" = "Telif Hakkı © 2022 LoopKit Yazarları. Tüm hakları Saklıdır."; + diff --git a/StatusWidget/tr.lproj/Localizable.strings b/StatusWidget/tr.lproj/Localizable.strings new file mode 100644 index 0000000000..0b07c31cb7 --- /dev/null +++ b/StatusWidget/tr.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* No comment provided by engineer. */ +"---" = "---"; + +/* No comment provided by engineer. */ +"-U" = "-Ü"; + +/* No comment provided by engineer. */ +"??" = "??"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* No comment provided by engineer. */ +"%@ U" = "%@ Ü"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* No comment provided by engineer. */ +"Eventual" = "Nihai"; + +/* The short unit display string for grams */ +"g" = "gr"; + +/* No comment provided by engineer. */ +"Loop Status Widget" = "Döngü Durumu Widget'ı"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* No comment provided by engineer. */ +"See your current blood glucose and insulin delivery." = "Mevcut kan şekerinizi ve insülin iletiminizi görün."; + +/* The short unit display string for international units of insulin */ +"U" = "Ü"; + diff --git a/StatusWidget/vi.lproj/Localizable.strings b/StatusWidget/vi.lproj/Localizable.strings new file mode 100644 index 0000000000..45356883ff --- /dev/null +++ b/StatusWidget/vi.lproj/Localizable.strings @@ -0,0 +1,24 @@ +/* No comment provided by engineer. */ +"%@ U" = "%@ U"; + +/* The format string for the app name and version number. (1: bundle name)(2: bundle version) */ +"%1$@ v%2$@" = "%1$@ v%2$@"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + diff --git a/Version.xcconfig b/Version.xcconfig index 1d70d06ea7..373efdca05 100644 --- a/Version.xcconfig +++ b/Version.xcconfig @@ -7,7 +7,7 @@ // // Version [DEFAULT] -LOOP_MARKETING_VERSION = 2.3.0 +LOOP_MARKETING_VERSION = 3.3.0 CURRENT_PROJECT_VERSION = 57 // Optional override diff --git a/WatchApp Extension/ComplicationController.swift b/WatchApp Extension/ComplicationController.swift index 05b9871116..9f79aad280 100644 --- a/WatchApp Extension/ComplicationController.swift +++ b/WatchApp Extension/ComplicationController.swift @@ -212,7 +212,15 @@ final class ComplicationController: NSObject, CLKComplicationDataSource { return nil } case .graphicExtraLarge: - return nil + if #available(watchOSApplicationExtension 5.0, *) { + return CLKComplicationTemplateGraphicExtraLargeCircularOpenGaugeSimpleText( + gaugeProvider: CLKSimpleGaugeProvider(style: .fill, gaugeColor: .tintColor, fillFraction: 1), + bottomTextProvider: glucoseText, + centerTextProvider: CLKSimpleTextProvider(text: "↘︎") + ) + } else { + return nil + } @unknown default: return nil } diff --git a/WatchApp Extension/Controllers/CarbAndBolusFlowController.swift b/WatchApp Extension/Controllers/CarbAndBolusFlowController.swift index a6e38bd6c8..102bc98de8 100644 --- a/WatchApp Extension/Controllers/CarbAndBolusFlowController.swift +++ b/WatchApp Extension/Controllers/CarbAndBolusFlowController.swift @@ -25,7 +25,7 @@ final class CarbAndBolusFlowController: WKHostingController, I ) }() - private var configuration: CarbAndBolusFlow.Configuration = .carbEntry + private var configuration: CarbAndBolusFlow.Configuration = .carbEntry(nil) override var body: CarbAndBolusFlow { CarbAndBolusFlow(viewModel: viewModel) diff --git a/WatchApp Extension/Controllers/HUDInterfaceController.swift b/WatchApp Extension/Controllers/HUDInterfaceController.swift index a0bb8f6aa5..b23dc56680 100644 --- a/WatchApp Extension/Controllers/HUDInterfaceController.swift +++ b/WatchApp Extension/Controllers/HUDInterfaceController.swift @@ -8,12 +8,14 @@ import WatchKit import LoopCore +import LoopKit class HUDInterfaceController: WKInterfaceController { private var activeContextObserver: NSObjectProtocol? @IBOutlet weak var loopHUDImage: WKInterfaceImage! @IBOutlet weak var glucoseLabel: WKInterfaceLabel! + @IBOutlet weak var eventualGlucoseLabel: WKInterfaceLabel! var loopManager = ExtensionDelegate.shared().loopManager @@ -71,6 +73,12 @@ class HUDInterfaceController: WKInterfaceController { if date != nil { glucoseLabel.setText(NSLocalizedString("– – –", comment: "No glucose value representation (3 dashes for mg/dL)")) glucoseLabel.setHidden(false) + + let showEventualGlucose = FeatureFlags.showEventualBloodGlucoseOnWatchEnabled + if showEventualGlucose { + eventualGlucoseLabel.setHidden(true) + } + if let glucose = activeContext.glucose, let glucoseDate = activeContext.glucoseDate, let unit = activeContext.displayGlucoseUnit, glucoseDate.timeIntervalSinceNow > -LoopCoreConstants.inputDataRecencyInterval { let formatter = NumberFormatter.glucoseFormatter(for: unit) @@ -78,13 +86,22 @@ class HUDInterfaceController: WKInterfaceController { let trend = activeContext.glucoseTrend?.symbol ?? "" glucoseLabel.setText(glucoseValue + trend) } + + if showEventualGlucose, let eventualGlucose = activeContext.eventualGlucose, let eventualGlucoseValue = formatter.string(from: eventualGlucose.doubleValue(for: unit)) { + eventualGlucoseLabel.setText(eventualGlucoseValue) + eventualGlucoseLabel.setHidden(false) + } } } } @IBAction func addCarbs() { - presentController(withName: CarbAndBolusFlowController.className, context: CarbAndBolusFlow.Configuration.carbEntry) + presentController(withName: CarbAndBolusFlowController.className, context: CarbAndBolusFlow.Configuration.carbEntry(nil)) + } + + func addCarbs(initialEntry: NewCarbEntry) { + presentController(withName: CarbAndBolusFlowController.className, context: CarbAndBolusFlow.Configuration.carbEntry(initialEntry)) } @IBAction func setBolus() { diff --git a/WatchApp Extension/ExtensionDelegate.swift b/WatchApp Extension/ExtensionDelegate.swift index 20fd1b45fc..1ef1d13d75 100644 --- a/WatchApp Extension/ExtensionDelegate.swift +++ b/WatchApp Extension/ExtensionDelegate.swift @@ -13,6 +13,7 @@ import Intents import os import os.log import UserNotifications +import LoopKit final class ExtensionDelegate: NSObject, WKExtensionDelegate { @@ -245,6 +246,39 @@ extension ExtensionDelegate: WCSessionDelegate { extension ExtensionDelegate: UNUserNotificationCenterDelegate { + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + switch response.actionIdentifier { + case UNNotificationDefaultActionIdentifier: + guard + response.notification.request.identifier == LoopNotificationCategory.missedMeal.rawValue, + let statusController = WKExtension.shared().visibleInterfaceController as? HUDInterfaceController + else { + break + } + + let userInfo = response.notification.request.content.userInfo + // If we have info about a meal, the carb entry UI should reflect it + if + let mealTime = userInfo[LoopNotificationUserInfoKey.missedMealTime.rawValue] as? Date, + let carbAmount = userInfo[LoopNotificationUserInfoKey.missedMealCarbAmount.rawValue] as? Double + { + let missedEntry = NewCarbEntry(quantity: HKQuantity(unit: .gram(), + doubleValue: carbAmount), + startDate: mealTime, + foodType: nil, + absorptionTime: nil) + statusController.addCarbs(initialEntry: missedEntry) + // Otherwise, just provide the ability to add carbs + } else { + statusController.addCarbs() + } + default: + break + } + + completionHandler() + } + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.badge, .sound, .list, .banner]) } diff --git a/WatchApp Extension/Extensions/CLKComplicationTemplate.swift b/WatchApp Extension/Extensions/CLKComplicationTemplate.swift index 5214294e7e..f49a9f2db0 100644 --- a/WatchApp Extension/Extensions/CLKComplicationTemplate.swift +++ b/WatchApp Extension/Extensions/CLKComplicationTemplate.swift @@ -184,7 +184,15 @@ extension CLKComplicationTemplate { return nil } case .graphicExtraLarge: - return nil + if #available(watchOSApplicationExtension 5.0, *) { + return CLKComplicationTemplateGraphicExtraLargeCircularOpenGaugeSimpleText( + gaugeProvider: CLKSimpleGaugeProvider(style: .fill, gaugeColor: tintColor, fillFraction: 1), + bottomTextProvider: CLKSimpleTextProvider(text: trendString), + centerTextProvider: CLKSimpleTextProvider(text: glucoseString) + ) + } else { + return nil + } @unknown default: return nil } diff --git a/WatchApp Extension/Info.plist b/WatchApp Extension/Info.plist index 2811bb3e48..e0a8a9a98f 100644 --- a/WatchApp Extension/Info.plist +++ b/WatchApp Extension/Info.plist @@ -31,6 +31,7 @@ CLKComplicationFamilyGraphicBezel CLKComplicationFamilyGraphicCircular CLKComplicationFamilyGraphicCorner + CLKComplicationFamilyGraphicExtraLarge CLKComplicationFamilyGraphicRectangular CLKComplicationFamilyModularLarge CLKComplicationFamilyModularSmall diff --git a/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift b/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift index 7528e71d9c..0c27958fe9 100644 --- a/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift +++ b/WatchApp Extension/Views/Carb Entry & Bolus/CarbAndBolusFlow.swift @@ -12,8 +12,8 @@ import LoopKit struct CarbAndBolusFlow: View { - enum Configuration { - case carbEntry + enum Configuration: Equatable { + case carbEntry(NewCarbEntry?) case manualBolus } @@ -34,8 +34,10 @@ struct CarbAndBolusFlow: View { @Environment(\.sizeClass) private var sizeClass // MARK: - State: Carb Entry + // Date the user last changed the carb entry with the UI @State private var carbLastEntryDate = Date() @State private var carbAmount = 15 + // Date of the carb entry @State private var carbEntryDate = Date() @State private var carbAbsorptionTime: CarbAbsorptionTime = .medium @State private var inputMode: CarbEntryInputMode = .carbs @@ -54,8 +56,15 @@ struct CarbAndBolusFlow: View { init(viewModel: CarbAndBolusFlowViewModel) { switch viewModel.configuration { - case .carbEntry: + case .carbEntry(let entry): _flowState = State(initialValue: .carbEntry) + + if let entry = entry { + _carbEntryDate = State(initialValue: entry.startDate) + + let initialCarbAmount = entry.quantity.doubleValue(for: .gram()) + _carbAmount = State(initialValue: Int(initialCarbAmount)) + } case .manualBolus: _flowState = State(initialValue: .bolusEntry) } @@ -159,7 +168,11 @@ extension CarbAndBolusFlow { case .size42mm: return 0 case .size40mm, .size41mm: - return configuration == .carbEntry ? 7 : 19 + if case .carbEntry = configuration { + return 7 + } else { + return 19 + } case .size44mm, .size45mm: return 5 } @@ -205,7 +218,7 @@ extension CarbAndBolusFlow { withAnimation { self.flowState = .bolusConfirmation } - } else if self.configuration == .carbEntry { + } else if case .carbEntry = self.configuration { self.viewModel.addCarbsWithoutBolusing() } } diff --git a/WatchApp Extension/ar.lproj/InfoPlist.strings b/WatchApp Extension/ar.lproj/InfoPlist.strings new file mode 100644 index 0000000000..f77dc07d1c --- /dev/null +++ b/WatchApp Extension/ar.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "بيانات كربوهيدرات الوجبة المدخلة للتطبيق و الساعة محفوظة في قواعد بيانات تطبيق صحتي. يتم تخزين بيانات سكر الدم المستردة من نظام متابعة سكر الدم المستمرة بشكل آمن في تطبيق صحتي."; + diff --git a/WatchApp Extension/ar.lproj/Localizable.strings b/WatchApp Extension/ar.lproj/Localizable.strings index e7d8aee0e5..a592945b1d 100644 --- a/WatchApp Extension/ar.lproj/Localizable.strings +++ b/WatchApp Extension/ar.lproj/Localizable.strings @@ -1,25 +1,62 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "كارب النشط"; /* HUD row title for IOB */ "Active Insulin" = "أنسولين نشط"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Add Carb Entry"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "فشل في إعطاء الجرعة"; +"Bolus Failed" = "Bolus Failed"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ "Dismiss" = "تجاهل"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "تأكد من أن الآيفون الخاص بك قريب ثم حاول مرة أخرى"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "صافي الضخ المستمر"; +/* No comment provided by engineer. */ +"OK" = "موافق"; + +/* Label for on button */ +"On" = "On"; + /* The text for the Watch button for enabling a temporary override */ -"Override" = "تجاوز"; +"Override" = "Override"; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pre-Meal"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "التوصية: %@ U"; @@ -31,8 +68,12 @@ The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "فشل الإرسال"; +/* The short unit display string for international units of insulin */ +"U" = "وحدة"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "وحدة لكل ساعة"; /* The text for the Watch button for enabling workout mode */ "Workout" = "التمارين"; + diff --git a/WatchApp Extension/ar.lproj/ckcomplication.strings b/WatchApp Extension/ar.lproj/ckcomplication.strings new file mode 100644 index 0000000000..8c414cbcf9 --- /dev/null +++ b/WatchApp Extension/ar.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/cs.lproj/Localizable.strings b/WatchApp Extension/cs.lproj/Localizable.strings new file mode 100644 index 0000000000..74ce94ddb8 --- /dev/null +++ b/WatchApp Extension/cs.lproj/Localizable.strings @@ -0,0 +1,18 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Pokračovat"; + +/* Label for off button */ +"Off" = "Vypnuto"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Zapnuto"; + +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Uložit"; + diff --git a/WatchApp Extension/da.lproj/InfoPlist.strings b/WatchApp Extension/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..4cfb717ce2 --- /dev/null +++ b/WatchApp Extension/da.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp-udvidelse"; + +/* Bundle name */ +"CFBundleName" = "WatchApp-udvidelse"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Mad-data fra Health-databasen bruges til at bestemme blodsukkereffekten. Blodsukkerdata fra Health-databasen bruges til graftegning og momentumberegning. Søvndata fra sundhedsdatabasen bruges til at optimere leveringen af opdateringer om komplikationer af Apple Watch i den tid, du er vågen."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Data om kulhydratmåltider, der indtastes i appen og på uret, gemmes i Apples Health-database. Glukosedata, der hentes fra CGM'en, gemmes sikkert i HealthKit."; + diff --git a/WatchApp Extension/da.lproj/Localizable.strings b/WatchApp Extension/da.lproj/Localizable.strings index 40a68205f9..3098b33856 100644 --- a/WatchApp Extension/da.lproj/Localizable.strings +++ b/WatchApp Extension/da.lproj/Localizable.strings @@ -1,38 +1,112 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ -"Active Carbs" = "Aktive Kulhydrater"; +"Active Carbs" = "Aktive kulhydrater"; /* HUD row title for IOB */ -"Active Insulin" = "Activt Insulin"; +"Active Insulin" = "Aktivt insulin"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Tilføj Kulhydrat indtastning"; +"Add Carb Entry" = "Tilføj kulhydrater"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Bolus Fejlede"; +"Bolus Failed" = "Bolus fejlede"; + +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Bolusanbefaling opdateret"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Fortsæt"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ -"Dismiss" = "Ignorer"; +"Dismiss" = "Afvis"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ -"Make sure your iPhone is nearby and try again" = "Sørg for at din iPhone er i nærheden, og prøv igen"; +"Make sure your iPhone is nearby and try again" = "Sørg for, at din iPhone er i nærheden og prøv igen"; + +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Sørg for, at din iPhone er tæt på og prøv igen."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* HUD row title for Net Basal Rate */ -"Net Basal Rate" = "Netto Basal Rate"; +"Net Basal Rate" = "Netto basalrate"; + +/* Label for off button */ +"Off" = "Slukket"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Tændt"; /* The text for the Watch button for enabling a temporary override */ -"Override" = "Overstyr"; +"Override" = "Override"; + +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Bekræft venligst bolus igen."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Før-måltid"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Forudindstillet"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Anb: %@ E"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "Rec: %@ U"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "REC: Beregner..."; + /* HUD row title for remaining reservoir volume */ -"Reservoir Volume" = "Reservoir Mængde"; +"Reservoir Volume" = "Reservoimængde"; + +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Gem"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Gem & bolus"; /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ -"Send Failed" = "Sending Fejlede"; +"Send Failed" = "Send mislykkedes"; + +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Drej det digitale hjul for bolus"; /* The short unit display string for international units of insulin */ "U" = "E"; @@ -40,6 +114,9 @@ /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "E/t"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "iPhone er uden for urets rækkevidde"; + /* The text for the Watch button for enabling workout mode */ "Workout" = "Motion"; diff --git a/WatchApp Extension/da.lproj/ckcomplication.strings b/WatchApp Extension/da.lproj/ckcomplication.strings new file mode 100644 index 0000000000..5a6c193ff5 --- /dev/null +++ b/WatchApp Extension/da.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "6,5"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "6,5↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/de.lproj/InfoPlist.strings b/WatchApp Extension/de.lproj/InfoPlist.strings index c8001fbbb7..0099ce3950 100644 --- a/WatchApp Extension/de.lproj/InfoPlist.strings +++ b/WatchApp Extension/de.lproj/InfoPlist.strings @@ -1,5 +1,11 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp-Erweiterung"; + +/* Bundle name */ +"CFBundleName" = "WatchApp-Erweiterung"; + /* Privacy - Health Share Usage Description */ -"NSHealthShareUsageDescription" = "Mahlzeitendaten aus der HealthKit-Datenbank werden verwendet, um Glukoseeffekte zu bestimmen. Glukosedaten aus der HealthKit-Datenbank werden für die grafische Darstellung und Impulsberechnung verwendet. Schlafdaten aus der HealthKit-Datenbank werden verwendet, um die Bereitstellung von Apple Watch-Komplikationsupdates während der Zeit, in der Du wach bist, zu optimieren."; +"NSHealthShareUsageDescription" = "Mahlzeitendaten aus der Health Datenbank werden verwendet, um die Glukoseeffekte zu bestimmen. Glukosedaten aus der Health Datenbank werden zur grafischen Darstellung und Impulsberechnung verwendet. Schlafdaten aus der Health-Datenbank werden verwendet, um die Bereitstellung von Apple Watch-Komplikationsupdates während Ihrer Wachzeit zu optimieren."; /* Privacy - Health Update Usage Description */ "NSHealthUpdateUsageDescription" = "In der App und auf der Uhr eingegebene Daten zu Kohlenhydratmahlzeiten werden in der HealthKit-Datenbank gespeichert. Vom CGM abgerufene Glukosedaten werden sicher in HealthKit-Datenbank gespeichert."; diff --git a/WatchApp Extension/de.lproj/Localizable.strings b/WatchApp Extension/de.lproj/Localizable.strings index 7dd9ed474d..00e61b976e 100644 --- a/WatchApp Extension/de.lproj/Localizable.strings +++ b/WatchApp Extension/de.lproj/Localizable.strings @@ -1,3 +1,15 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Aktive KH"; @@ -5,7 +17,7 @@ "Active Insulin" = "Aktives Insulin"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "KH-Eintrag hinzufügen"; +"Add Carb Entry" = "Kohlenhydrate hinzufügen"; /* Button text to confirm manual bolus on Apple Watch */ "Bolus" = "Bolus"; @@ -19,17 +31,30 @@ /* Button text to continue from carb entry to bolus entry on Apple Watch */ "Continue" = "Weiter"; +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ -"Dismiss" = "Verwerfen"; +"Dismiss" = "Schließen"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ -"Make sure your iPhone is nearby and try again" = "Stelle sicher, dass Dein iPhone in der Nähe ist, und versuche es erneut."; +"Make sure your iPhone is nearby and try again" = "Stellen Sie sicher, dass Ihr iPhone in der Nähe ist, und versuchen Sie es erneut."; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a potential carb entry send attempt fails */ -"Make sure your iPhone is nearby and try again." = "Stelle sicher, dass Dein iPhone in der Nähe ist, und versuche es erneut."; +"Make sure your iPhone is nearby and try again." = "Stellen Sie sicher, dass Ihr iPhone in der Nähe ist, und versuchen Sie es erneut."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Net Basalrate"; @@ -47,7 +72,7 @@ "Override" = "Voreinstellung"; /* Alert message for updated bolus recommendation on Apple Watch */ -"Please reconfirm the bolus amount." = "Bitte bestätige die Bolusmenge erneut."; +"Please reconfirm the bolus amount." = "Bitte Bolusmenge erneut bestätigen."; /* Title for sheet to enable/disable pre-meal on watch */ "Pre-Meal" = "Vor dem Essen"; @@ -55,9 +80,15 @@ /* The text for the Watch button for enabling a custom preset */ "Preset" = "Voreinstellung"; +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Empfohlen: %@ IE"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "Empf: %@ U"; + /* Indicator that recommended bolus computation is in progress on Apple Watch */ "REC: Calculating..." = "REC: berechne…"; @@ -68,14 +99,14 @@ "Save" = "Speichern"; /* Button text to confirm carb entry and bolus on Apple Watch */ -"Save & Bolus" = "Speichern & Bolen"; +"Save & Bolus" = "Speichern & Bolus abgeben"; /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Senden fehlgeschlagen"; /* Help text for bolus confirmation on Apple Watch */ -"Turn Digital Crown\nto bolus" = "Drehe die digitale \nKrone zum Bolen"; +"Turn Digital Crown\nto bolus" = "Drehe die digitale \nKrone für einen Bolus"; /* The short unit display string for international units of insulin */ "U" = "IE"; @@ -84,7 +115,7 @@ "U/hr" = "IE/h"; /* The title of the alert controller displayed after a potential carb entry send attempt fails */ -"Unable to Reach iPhone" = "Dein iPhone kann nicht erreicht werden"; +"Unable to Reach iPhone" = "Ihr iPhone kann nicht erreicht werden"; /* The text for the Watch button for enabling workout mode */ "Workout" = "Training"; diff --git a/WatchApp Extension/de.lproj/ckcomplication.strings b/WatchApp Extension/de.lproj/ckcomplication.strings new file mode 100644 index 0000000000..8c414cbcf9 --- /dev/null +++ b/WatchApp Extension/de.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/es.lproj/InfoPlist.strings b/WatchApp Extension/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..6b2f80b2af --- /dev/null +++ b/WatchApp Extension/es.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Extensión de WatchApp"; + +/* Bundle name */ +"CFBundleName" = "Extensión de WatchApp"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Los datos de alimentos de la base de datos de Salud se utilizan para determinar los efectos en el nivel de glucosa. Los datos de glucosa de la base de datos de Salud se utilizan para graficar y determinar cálculos de momento. Los datos de Sueño de la base de datos de Salud se utilizan para optimizar la entrega de actualizaciones de las complicaciones del Apple Watch durante el tiempo que está despierto."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Datos de alimentos ingresados en la aplicación y en el reloj son almacenados en la base de datos de Salud. Los datos de glucosa extraídos del monitor continuo de glucosa se almacenan de manera segura en HealthKit."; + diff --git a/WatchApp Extension/es.lproj/Localizable.strings b/WatchApp Extension/es.lproj/Localizable.strings index a5a6b23181..6dcbce1045 100644 --- a/WatchApp Extension/es.lproj/Localizable.strings +++ b/WatchApp Extension/es.lproj/Localizable.strings @@ -1,42 +1,122 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ -"Active Carbs" = "Carbs Activos"; +"Active Carbs" = "Carbohidratos Activos"; /* HUD row title for IOB */ "Active Insulin" = "Insulina activa"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Agregar Entrada de Carbohydratos"; +"Add Carb Entry" = "Agregar Entrada de Carb"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolo"; /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolo Falló"; +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Recomendación de bolo fue actualicada"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Continuar"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ "Dismiss" = "Ignorar"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Asegúrate que tu iPhone se encuentre cerca e inténtalo de nuevo"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Asegúrate que tu iPhone se encuentre cerca e inténtalo de nuevo."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Tasa basal neta"; +/* Label for off button */ +"Off" = "Apagado"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Encendido"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Sobreescritura"; +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Por favor, vuelva a confirmar la cantidad del bolo."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pre-Comida"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Preestablecido"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ U"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "REC: %@ U"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "REC: Calculando..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Volumen de Reservorio"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Agregar"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Guardar & administrar bolo"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Envío Falló"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Gire el Digital Crown \npara administrar bolo"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/hra"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "No se puede contactar al iPhone"; + /* The text for the Watch button for enabling workout mode */ "Workout" = "Ejercicio"; diff --git a/WatchApp Extension/es.lproj/ckcomplication.strings b/WatchApp Extension/es.lproj/ckcomplication.strings new file mode 100644 index 0000000000..5b1e3674cc --- /dev/null +++ b/WatchApp Extension/es.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@ %@ %@"; + diff --git a/WatchApp Extension/fi.lproj/InfoPlist.strings b/WatchApp Extension/fi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..eca830a0a9 --- /dev/null +++ b/WatchApp Extension/fi.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp-laajennus"; + +/* Bundle name */ +"CFBundleName" = "WatchApp-laajennus"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Terveys-sovelluksen ateriatietoja käytetään glukoosivaikutusten määrittämiseen. Terveys-sovelluksen glukoositietoja käytetään graafeissa ja laskelmissa. Unitietoja käytetään Apple Watch -komplikaation toiminnan optimointiin hereillä olon aikana."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Sovelluksen ja kellon kautta tallennetut hiilihydraattitiedot tallennetaan Terveys-sovellukseen. Glukoosiseurannan kautta saadut glukoositiedot tallennetaan turvallisesti HealthKitiin."; + diff --git a/WatchApp Extension/fi.lproj/Localizable.strings b/WatchApp Extension/fi.lproj/Localizable.strings index 42effaed9a..7f4af4de98 100644 --- a/WatchApp Extension/fi.lproj/Localizable.strings +++ b/WatchApp Extension/fi.lproj/Localizable.strings @@ -1,3 +1,15 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Akt. hiilari"; @@ -5,38 +17,106 @@ "Active Insulin" = "Akt. insuliini"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Lisää hiilari"; +"Add Carb Entry" = "Lisää hiilihydraatteja"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolus epäonnistui"; +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Bolussuositus päivitetty"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Jatka"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ -"Dismiss" = "Hylkää"; +"Dismiss" = "Ohita"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Varmista, että iPhone on riittävän lähellä ja yritä uudelleen"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Varmista, että iPhone on riittävän lähellä ja yritä uudelleen."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Basaali netto"; +/* Label for off button */ +"Off" = "Pois päältä"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Päällä"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Tilapäisas."; +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Vahvista bolus uudelleen."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Ennen ateriaa"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Esiasetus"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Suosit: %@ U"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "SUOSIT: %@ U"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "SUOSIT: Lasketaan..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Säiliön määrä"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Tallenna"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Tallenna & Bolus"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Lähetys epäonnistui"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Vahvista pyörittämällä Digital Crownia"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/h"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "iPhoneen ei saada yhteyttä"; + /* The text for the Watch button for enabling workout mode */ "Workout" = "Liikunta"; diff --git a/WatchApp Extension/fr.lproj/InfoPlist.strings b/WatchApp Extension/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..77897147b9 --- /dev/null +++ b/WatchApp Extension/fr.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp Extension"; + +/* Bundle name */ +"CFBundleName" = "WatchApp Extension"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Les données sur les repas provenant de la base de données Santé sont utilisées pour déterminer les effets du glucose. Les données relatives au glucose provenant de la base de données Santé sont utilisées pour la création de graphiques et le calcul de l'élan. Les données relatives au sommeil provenant de la base de données Santé sont utilisées pour optimiser l'envoi des mises à jour des complications de l'Apple Watch pendant la période où vous êtes éveillé(e)."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Les données de glucides des repas entrées dans l'application ou la montre sont enregistrées dans la base de donnée Santé. Les données de taux de glucose provenant du CGM sont enregistrées de manière sécurisée dans HealthKit."; + diff --git a/WatchApp Extension/fr.lproj/Localizable.strings b/WatchApp Extension/fr.lproj/Localizable.strings index 7fe28958a0..d433047a67 100644 --- a/WatchApp Extension/fr.lproj/Localizable.strings +++ b/WatchApp Extension/fr.lproj/Localizable.strings @@ -1,39 +1,122 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Glucides actifs"; /* HUD row title for IOB */ "Active Insulin" = "Insuline active"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Ajouter des glucides"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Bolus Échoué"; +"Bolus Failed" = "Échec du bolus"; + +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Recommandation de Bolus modifiée"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Continuer"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ -"Dismiss" = "Rejeter"; +"Dismiss" = "Fermer"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Assurez-vous que votre iPhone est à proximité et réessayez"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Assurez-vous que votre iPhone est à proximité et réessayez."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ -"Net Basal Rate" = "Débit de basale net"; +"Net Basal Rate" = "Débit basal net"; + +/* Label for off button */ +"Off" = "Désactivé"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Activé"; /* The text for the Watch button for enabling a temporary override */ -"Override" = "Surcharge"; +"Override" = "Ajustement"; + +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Veuillez reconfirmer le bolus."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pré-Repas"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Préréglage"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ U"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "REC : %@ U"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "REC: Calcul en cours..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Volume du réservoir"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Sauvegarder"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Sauvegarder & envoyer Bolus"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Echec de l'envoi"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Tourner la Digital Crown pour envoyer le bolus"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/h"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Impossible d’atteindre l’iPhone"; + /* The text for the Watch button for enabling workout mode */ -"Workout" = "Sport"; +"Workout" = "Exercice"; diff --git a/WatchApp Extension/fr.lproj/ckcomplication.strings b/WatchApp Extension/fr.lproj/ckcomplication.strings new file mode 100644 index 0000000000..8c414cbcf9 --- /dev/null +++ b/WatchApp Extension/fr.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/he.lproj/InfoPlist.strings b/WatchApp Extension/he.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7d477d677c --- /dev/null +++ b/WatchApp Extension/he.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Carbohydrate meal data entered in the app and on the watch is stored in the Health database. Glucose data retrieved from the CGM is stored securely in HealthKit."; + diff --git a/WatchApp Extension/he.lproj/Localizable.strings b/WatchApp Extension/he.lproj/Localizable.strings index 4cbccfb6cc..936389eac0 100644 --- a/WatchApp Extension/he.lproj/Localizable.strings +++ b/WatchApp Extension/he.lproj/Localizable.strings @@ -1,38 +1,88 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Active Carbs"; /* HUD row title for IOB */ "Active Insulin" = "Active Insulin"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Add Carb Entry"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolus Failed"; +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Continue"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ "Dismiss" = "Dismiss"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Make sure your iPhone is nearby and try again"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Net Basal Rate"; +/* Label for off button */ +"Off" = "כבוי"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "דולק"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Override"; +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pre-Meal"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ U"; /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Reservoir Volume"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Save"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Send Failed"; +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/hr"; /* The text for the Watch button for enabling workout mode */ "Workout" = "Workout"; + diff --git a/WatchApp Extension/hi.lproj/Localizable.strings b/WatchApp Extension/hi.lproj/Localizable.strings new file mode 100644 index 0000000000..6af2a264c5 --- /dev/null +++ b/WatchApp Extension/hi.lproj/Localizable.strings @@ -0,0 +1,6 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "जारी"; + diff --git a/WatchApp Extension/it.lproj/InfoPlist.strings b/WatchApp Extension/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..15dcd10c34 --- /dev/null +++ b/WatchApp Extension/it.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Estensione WatchApp"; + +/* Bundle name */ +"CFBundleName" = "Estensione WatchApp"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "I dati sui pasti del database Salute vengono utilizzati per determinare gli effetti del glucosio. I dati sul glucosio del database Salute vengono utilizzati per la rappresentazione grafica e il calcolo del momento. I dati sul sonno del database Salute vengono utilizzati per ottimizzare la consegna degli aggiornamenti delle complicazioni di Apple Watch durante il periodo di veglia."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "I dati sui carboidrati dei pasti inseriti nell'app e sull'orologio sono trasferiti nel database di Salute. I dati recuperati dal sensore CGM sono storati nel database di HealthKit."; + diff --git a/WatchApp Extension/it.lproj/Localizable.strings b/WatchApp Extension/it.lproj/Localizable.strings index 820a206a89..49989cb3fa 100644 --- a/WatchApp Extension/it.lproj/Localizable.strings +++ b/WatchApp Extension/it.lproj/Localizable.strings @@ -1,42 +1,122 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ -"Active Carbs" = "Carboidrati attivi"; +"Active Carbs" = "Carb Attivi"; /* HUD row title for IOB */ "Active Insulin" = "Insulina attiva"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Aggiungi carboidrati assunti"; +"Add Carb Entry" = "Agg. Carb. Assunti"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolo"; /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolo Fallito"; +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Raccomandazioni sul bolo aggiornate"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Continua"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ -"Dismiss" = "Rimuovere"; +"Dismiss" = "OK"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Assicurati che il tuo iPhone sia vicino e riprova"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Assicurati che il tuo iPhone sia vicino e riprova."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Velocità basale netta"; +/* Label for off button */ +"Off" = "Spento"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Acceso"; + /* The text for the Watch button for enabling a temporary override */ -"Override" = "Attiva regolazione manuale"; +"Override" = "Programma Alternativo"; + +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Si prega di riconfermare la quantità di bolo."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pre-Pasto"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Preimpostato"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ U"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "REC: %@ U"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "REC: Calcolo..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Volume serbatoio"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Salva"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Salva & Bolo"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Invio Fallito"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Ruotare la corona digitale\nper il bolo"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/ora"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Impossibile raggiungere iPhone"; + /* The text for the Watch button for enabling workout mode */ -"Workout" = "Attività fisica"; +"Workout" = "Allenarsi"; diff --git a/WatchApp Extension/it.lproj/ckcomplication.strings b/WatchApp Extension/it.lproj/ckcomplication.strings new file mode 100644 index 0000000000..5b1e3674cc --- /dev/null +++ b/WatchApp Extension/it.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@ %@ %@"; + diff --git a/WatchApp Extension/ja.lproj/InfoPlist.strings b/WatchApp Extension/ja.lproj/InfoPlist.strings new file mode 100644 index 0000000000..697e081734 --- /dev/null +++ b/WatchApp Extension/ja.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "健康データベースからの食事データは、グルコース効果を決定するために使用される。 グルコースデータはグラフ作成と解析のためにHealthKitから検索されます"; + diff --git a/WatchApp Extension/ja.lproj/Localizable.strings b/WatchApp Extension/ja.lproj/Localizable.strings index c341eac1a8..4128891d83 100644 --- a/WatchApp Extension/ja.lproj/Localizable.strings +++ b/WatchApp Extension/ja.lproj/Localizable.strings @@ -1,3 +1,9 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "残存糖質"; @@ -5,35 +11,72 @@ "Active Insulin" = "残存インスリン"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "カーボを追加"; +"Add Carb Entry" = "糖質の記入を追加"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "ボーラス"; /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "ボーラス不成功"; +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "次へ"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ "Dismiss" = "閉じる"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "iPhone が近くにあることを確認して、再実行してください"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "正味基礎インスリン"; +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "オン"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "オーバーライド"; +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "食前"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "推奨: %@ U"; /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "リザーバ残量"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "保存"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "送信に失敗"; +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/時"; diff --git a/WatchApp Extension/nb.lproj/InfoPlist.strings b/WatchApp Extension/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..ef0afdf065 --- /dev/null +++ b/WatchApp Extension/nb.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp-utvidelse"; + +/* Bundle name */ +"CFBundleName" = "WatchApp-utvidelse"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Måltidsdata fra helsedatabasen brukes til å bestemme glukoseeffekter. Glukosedata fra helsedatabasen brukes til grafer og momentumberegning. Søvndata fra helsedatabasen brukes til å optimalisere leveringen av Apple Watch-komplikasjonsoppdateringer når du er våken."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Karbohydratmåltidsdata som legges inn i appen og på klokken lagres i Helsedatabasen. Glukosedata hentet fra CGM lagres sikkert i HealthKit."; + diff --git a/WatchApp Extension/nb.lproj/Localizable.strings b/WatchApp Extension/nb.lproj/Localizable.strings index 18e9f83afe..d498deb27c 100644 --- a/WatchApp Extension/nb.lproj/Localizable.strings +++ b/WatchApp Extension/nb.lproj/Localizable.strings @@ -1,42 +1,122 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Aktive karbohydrater"; /* HUD row title for IOB */ "Active Insulin" = "Aktivt insulin"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Legg til karbohydrater"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Bolus mislyktes"; +"Bolus Failed" = "Bolus feilet"; + +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Bolus anbefaling er oppdatert"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Fortsett"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ -"Dismiss" = "Avskjedige"; +"Dismiss" = "Avvis"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Pass på at iPhone er i nærheten, og prøv igjen"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Sjekk at din iPhone er i nærheten og prøv igjen."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Netto Basaldose"; +/* Label for off button */ +"Off" = "Av"; + +/* No comment provided by engineer. */ +"OK" = "Ok"; + +/* Label for on button */ +"On" = "På"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Overstyr"; +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Vennligst bekreft bolus på nytt."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pre-måltid"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Overstyring"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ E"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "REC: %@ E"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "Beregner anbefalt bolus..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Reservoarstørrelse"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Lagre"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Lagre & bolus"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Send mislyktes"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Snu \"Digital Crown\" for å gi bolus"; + /* The short unit display string for international units of insulin */ "U" = "E"; /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "E/t"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Kan ikke nå iPhone"; + /* The text for the Watch button for enabling workout mode */ "Workout" = "Trening"; diff --git a/WatchApp Extension/nb.lproj/ckcomplication.strings b/WatchApp Extension/nb.lproj/ckcomplication.strings new file mode 100644 index 0000000000..5b1e3674cc --- /dev/null +++ b/WatchApp Extension/nb.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@ %@ %@"; + diff --git a/WatchApp Extension/nl.lproj/InfoPlist.strings b/WatchApp Extension/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..7460a2f47b --- /dev/null +++ b/WatchApp Extension/nl.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp Extensie"; + +/* Bundle name */ +"CFBundleName" = "WatchApp Extensie"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Maaltijdgegevens uit de database Gezondheid worden gebruikt om glucose-effecenten te bepalen. Glucosegegevens uit de database Gezondheid worden gebruikt voor grafieken en het berekenen van trendlijnen. Slaapgegevens uit de database Gezondheid worden gebruikt om de Apple Watch complicatie bij te werken wanneer je wakker bent."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Maaltijdkoolhydraten die worden ingevoerd in de app en met de watch worden opgeslagen in de database Gezondheid. Ontvangen glucosegegevens van de CGM worden veilig opgeslagen in HealthKit."; + diff --git a/WatchApp Extension/nl.lproj/Localizable.strings b/WatchApp Extension/nl.lproj/Localizable.strings index 65bb8274fb..e3401838f3 100644 --- a/WatchApp Extension/nl.lproj/Localizable.strings +++ b/WatchApp Extension/nl.lproj/Localizable.strings @@ -1,38 +1,112 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "--"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ - %2$@ %3$@"; + /* HUD row title for COB */ -"Active Carbs" = "Actieve koolhydraten"; +"Active Carbs" = "Actieve Koolhydraten"; /* HUD row title for IOB */ -"Active Insulin" = "Actieve insuline"; +"Active Insulin" = "Actieve Insuline"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Voeg koolhydraten toe"; +"Add Carb Entry" = "Kh. Inv. Toevoegen"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Bolus mislukt"; +"Bolus Failed" = "Bolus Mislukt"; + +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Aanbevolen Bolus Bijgewerkt"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Ga Verder"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ -"Dismiss" = "Verwerp"; +"Dismiss" = "Sluiten"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Zorg dat je iPhone in de buurt is en probeer opnieuw"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Zorg dat je iPhone in de buurt is en probeer het opnieuw."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ -"Net Basal Rate" = "Netto basaalsnelheid"; +"Net Basal Rate" = "Netto Basaalsnelheid"; + +/* Label for off button */ +"Off" = "Uit"; + +/* No comment provided by engineer. */ +"OK" = "Ok"; + +/* Label for on button */ +"On" = "Aan"; /* The text for the Watch button for enabling a temporary override */ -"Override" = "Aangepast programma"; +"Override" = "Override"; + +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Bevestig bolus opnieuw."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pre-Meal"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Override"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Voorgesteld: %@ E"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "AANBEVOLEN: %@ E"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "AANBEVOLEN: Berekenen..."; + /* HUD row title for remaining reservoir volume */ -"Reservoir Volume" = "Reservoir inhoud"; +"Reservoir Volume" = "Reservoirinhoud"; + +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Opslaan"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Opslaan & Bolussen"; /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ -"Send Failed" = "Versturen mislukt"; +"Send Failed" = "Versturen Mislukt"; + +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Turn Digital Crown\nom te bolussen"; /* The short unit display string for international units of insulin */ "U" = "E"; @@ -40,6 +114,9 @@ /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "E/uur"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Kan iPhone niet bereiken"; + /* The text for the Watch button for enabling workout mode */ "Workout" = "Training"; diff --git a/WatchApp Extension/nl.lproj/ckcomplication.strings b/WatchApp Extension/nl.lproj/ckcomplication.strings new file mode 100644 index 0000000000..3cb7cc5e4b --- /dev/null +++ b/WatchApp Extension/nl.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "6,7"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "6,7 ↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@%@"; + diff --git a/WatchApp Extension/pl.lproj/InfoPlist.strings b/WatchApp Extension/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..ba5be3fab7 --- /dev/null +++ b/WatchApp Extension/pl.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp Extension"; + +/* Bundle name */ +"CFBundleName" = "WatchApp Extension"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Dane posiłków z bazy danych aplikacji Zdrowie służą do określania wpływu glukozy. Dane dotyczące glukozy z bazy danych aplikacji Zdrowie są wykorzystywane do tworzenia wykresów i wyznaczania trendu. Dane dotyczące snu z bazy danych aplikacji Zdrowie służą do optymalizacji dostarczania aktualizacji komplikacji Apple Watch w czasie, gdy nie śpisz."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Posiłek węglowodanowy wprowadzony w aplikacji i na zegarku oraz dane o poziomie cukru pobrane z ciągłego monitoringu glukozy są bezpiecznie przechowywane w aplikacji Zdrowie."; + diff --git a/WatchApp Extension/pl.lproj/Localizable.strings b/WatchApp Extension/pl.lproj/Localizable.strings index 3368448e7d..3e167590d6 100644 --- a/WatchApp Extension/pl.lproj/Localizable.strings +++ b/WatchApp Extension/pl.lproj/Localizable.strings @@ -1,38 +1,122 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Aktywne węglowodany"; /* HUD row title for IOB */ "Active Insulin" = "Aktywna insulina"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Wprowadź węglowodany"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Podanie bolusa nie powiodło się"; +"Bolus Failed" = "Bolus nie podany"; + +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Zaktualizowano rekomendowanego Bolus"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Kontynuuj"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ -"Dismiss" = "Zignoruj"; +"Dismiss" = "Odrzucać"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Upewnij się, że Twój iPhone jest w pobliżu i spróbuj ponownie"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Upewnij się, że Twój iPhone jest w pobliżu i spróbuj ponownie."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Dawka podstawowa netto"; +/* Label for off button */ +"Off" = "Wyłącz"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Włącz"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Pominięcie"; +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Potwierdź ponownie wielkość bolusa."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Przed posiłkiem"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Ustawienie wstępne"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rekomendowane: %@ J"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "Rek: %@ J"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "Rek: Obliczanie..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Objętość w zbiorniku"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Zapisz"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Zapisz i bolus"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Wysyłanie nie powiodło się"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Przekręć Digital Crown aby podać bolus"; + +/* The short unit display string for international units of insulin */ +"U" = "J"; + /* The short unit display string for international units of insulin delivery per hour */ -"U/hr" = "J/godz."; +"U/hr" = "J/godz"; + +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Nie można połączyć się z iPhone'em"; /* The text for the Watch button for enabling workout mode */ "Workout" = "Wysiłek fizyczny"; + diff --git a/WatchApp Extension/pl.lproj/ckcomplication.strings b/WatchApp Extension/pl.lproj/ckcomplication.strings new file mode 100644 index 0000000000..a607e4abcc --- /dev/null +++ b/WatchApp Extension/pl.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3min"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/pt-BR.lproj/InfoPlist.strings b/WatchApp Extension/pt-BR.lproj/InfoPlist.strings new file mode 100644 index 0000000000..4be038b8fb --- /dev/null +++ b/WatchApp Extension/pt-BR.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Dados de carboidratos inseridos no aplicativo e no Apple Watch são armazenados no banco de dados de saúde. Dados de glicemia recebidos do CGM são armazenados de modo seguro no HealthKit."; + diff --git a/WatchApp Extension/pt-BR.lproj/Localizable.strings b/WatchApp Extension/pt-BR.lproj/Localizable.strings index 0c6e9b3731..6075041cd4 100644 --- a/WatchApp Extension/pt-BR.lproj/Localizable.strings +++ b/WatchApp Extension/pt-BR.lproj/Localizable.strings @@ -1,36 +1,82 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Carboidratos Ativos"; /* HUD row title for IOB */ "Active Insulin" = "Insulina Ativa"; +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Adicionar Carb"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolus Falhou"; +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Continuar"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ "Dismiss" = "Dispensar"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Verifique se o iPhone está próximo e tente novamente"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Taxa Basal Líquida"; +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Ligado"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Sobrepor"; +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Pré-Refeição"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ U"; /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Volume do Reservatório"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Salvar"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Envio falhou"; +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/hr"; diff --git a/WatchApp Extension/ro.lproj/InfoPlist.strings b/WatchApp Extension/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..8a41547138 --- /dev/null +++ b/WatchApp Extension/ro.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Extensie WatchApp"; + +/* Bundle name */ +"CFBundleName" = "Extensie WatchApp"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Datele mesei din baza de date din aplicația Sănătate sunt folosite pentru a determina efectele glicemice. Datele despre glicemie din baza de date Sănătate sunt folosite pentru construirea graficelor și calcularea influențelor glicemice. Datele de somn din baza de date Sănătate sunt folosite pentru a optimiza livrarea de actualizări de date pentru ceasul Apple pe perioada când sunteți treaz."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Carbohidrații introduși în aplicație și pe ceas sunt stocați în baza de date Sănătate. Glicemiile din GCM sunt stocate în siguranță în HealthKit."; + diff --git a/WatchApp Extension/ro.lproj/Localizable.strings b/WatchApp Extension/ro.lproj/Localizable.strings index 8b9c22dc37..7283a04a92 100644 --- a/WatchApp Extension/ro.lproj/Localizable.strings +++ b/WatchApp Extension/ro.lproj/Localizable.strings @@ -1,3 +1,15 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Carbohidrați activi"; @@ -7,36 +19,104 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Adaugă carbohidrați"; +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolus eșuat"; +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Actualizare Recomandare bolus"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Continuă"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ -"Dismiss" = "Închide"; +"Dismiss" = "Renunță"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Asigurați-vă că iPhone-ul este în apropiere, după care încercați din nou"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Asigurați-vă că iPhone-ul este în apropiere, după care încercați din nou."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Rată bazală netă"; +/* Label for off button */ +"Off" = "Oprit"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Pornit"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Înlocuire"; +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Vă rugăm să reconfirmați valoarea bolusului."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Preprandial"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Presetare"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@%2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rec: %@ U"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "REC: %@ U"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "REC: Se calculează..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Volum rezervor"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Salvează"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Salvează & Bolus"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Transmitere eșuată"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Rotiți pentru a confirma bolusul"; + +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/oră"; +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Nu se poate conecta la iPhone"; + /* The text for the Watch button for enabling workout mode */ "Workout" = "Activitate sportivă"; diff --git a/WatchApp Extension/ro.lproj/ckcomplication.strings b/WatchApp Extension/ro.lproj/ckcomplication.strings new file mode 100644 index 0000000000..5b1e3674cc --- /dev/null +++ b/WatchApp Extension/ro.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3MIN"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@ %@ %@"; + diff --git a/WatchApp Extension/ru.lproj/InfoPlist.strings b/WatchApp Extension/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..e21f47fdc1 --- /dev/null +++ b/WatchApp Extension/ru.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "Расширение WatchApp"; + +/* Bundle name */ +"CFBundleName" = "Расширение WatchApp"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Данные о приеме пищи из базы данных Health используются для определения влияния глюкозы. Данные о глюкозе из базы данных Health используются для построения графиков и расчетов. Данные о сне из базы данных Health используются для оптимизации доставки обновлений усложнений Apple Watch во время вашего бодрствования."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Данные об углеводах в приложении и на смарт-часах хранятся в базе данных Здоровье. Данные о гликемии полученные от систем непрерывного мониторинга хранятся в безопасности в Комплексе Здоровья HealthKit "; + diff --git a/WatchApp Extension/ru.lproj/Localizable.strings b/WatchApp Extension/ru.lproj/Localizable.strings index 0dfa7d4169..a6a4063876 100644 --- a/WatchApp Extension/ru.lproj/Localizable.strings +++ b/WatchApp Extension/ru.lproj/Localizable.strings @@ -1,3 +1,15 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Активные углеводы"; @@ -7,36 +19,104 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Добавить запись углеводов"; +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Болюс"; + /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Болюс не состоялся"; +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Рекомендации по болюсу обновлены"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Продолжить"; + +/* The short unit display string for decibles */ +"dB" = "дБ"; + /* The action button title to dismiss an error message */ -"Dismiss" = "Пропустить"; +"Dismiss" = "Отклонить"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "г"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Убедитесь, что ваш iPhone поблизости и повторите попытку"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Убедитесь, что ваш iPhone находится поблизости, и повторите попытку."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "мг/дл"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ -"Net Basal Rate" = "Нетто скорость базала"; +"Net Basal Rate" = "Чистая базальная доза"; + +/* Label for off button */ +"Off" = "Выключено"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Включено"; /* The text for the Watch button for enabling a temporary override */ -"Override" = "Перезаписать"; +"Override" = "Включить"; + +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Пожалуйста, подтвердите болюс."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "До еды"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Пресеты"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Рекомендовано: %@ ед"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "Рекомендовано: %@ ед"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "Рекомендовано: Расчет..."; + /* HUD row title for remaining reservoir volume */ -"Reservoir Volume" = "Остаток картриджа"; +"Reservoir Volume" = "Остаток резервуара"; + +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Сохранить"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Сохранить и ввести болюс"; /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Ошибка отправки"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Покрутите колесико\nдля болюса"; + +/* The short unit display string for international units of insulin */ +"U" = "ед"; + /* The short unit display string for international units of insulin delivery per hour */ -"U/hr" = "Ед./ч."; +"U/hr" = "U/hr"; + +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Не удается подключиться к iPhone"; /* The text for the Watch button for enabling workout mode */ -"Workout" = "Нагрузка"; +"Workout" = "Физическая нагрузка"; diff --git a/WatchApp Extension/ru.lproj/ckcomplication.strings b/WatchApp Extension/ru.lproj/ckcomplication.strings new file mode 100644 index 0000000000..3936ce995a --- /dev/null +++ b/WatchApp Extension/ru.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3МИН"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/sk.lproj/InfoPlist.strings b/WatchApp Extension/sk.lproj/InfoPlist.strings new file mode 100644 index 0000000000..075d65454b --- /dev/null +++ b/WatchApp Extension/sk.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Údaje o jedle z databázy Health sa používajú na určenie účinkov glukózy. Údaje o glukóze z databázy Health sa používajú na vytváranie grafov a výpočet hybnosti. Údaje o spánku z databázy Health sa používajú na optimalizáciu doručovania aktualizácií komplikácií Apple Watch v čase, keď ste hore."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Údaje o uhlohydrátoch zadané v aplikácii a na hodinkách sú uložené v databáze Health. Údaje o glukóze získané z CGM sú bezpečne uložené v HealthKit."; + diff --git a/WatchApp Extension/sk.lproj/Localizable.strings b/WatchApp Extension/sk.lproj/Localizable.strings new file mode 100644 index 0000000000..3c82924847 --- /dev/null +++ b/WatchApp Extension/sk.lproj/Localizable.strings @@ -0,0 +1,52 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + +/* HUD row title for COB */ +"Active Carbs" = "Aktívne sacharidy"; + +/* HUD row title for IOB */ +"Active Insulin" = "Aktívny inzulín"; + +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Zadať sacharidy"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Pokračovať"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + +/* Label for off button */ +"Off" = "Vypnuté"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "Zapnuté"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Uložiť"; + +/* The short unit display string for international units of insulin */ +"U" = "j"; + diff --git a/WatchApp Extension/sv.lproj/InfoPlist.strings b/WatchApp Extension/sv.lproj/InfoPlist.strings new file mode 100644 index 0000000000..4bd26fa9db --- /dev/null +++ b/WatchApp Extension/sv.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp Extension"; + +/* Bundle name */ +"CFBundleName" = "WatchApp Extension"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Kolhydratdata från Apple Health-databasen används för att avgöra blodsockereffekt. Blodsockervärden från Apple Health-databasen används i diagram och för beräkning av förändring."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Kolhydratvärden inmatade i appen i klockan lagras i Apple Health-databasen. Glukosvärden mottagna från CGM lagras krypterat i HealthKit."; + diff --git a/WatchApp Extension/sv.lproj/Localizable.strings b/WatchApp Extension/sv.lproj/Localizable.strings index 34a0cdd6fa..4899f2cc69 100644 --- a/WatchApp Extension/sv.lproj/Localizable.strings +++ b/WatchApp Extension/sv.lproj/Localizable.strings @@ -1,3 +1,15 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Aktiva kolhydrater"; @@ -7,38 +19,103 @@ /* Title of the user activity for adding carbs */ "Add Carb Entry" = "Lägg till kolhydrater"; +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; + /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolus misslyckades"; +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Det finns en ny bolusrekommendation"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Fortsätt"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ "Dismiss" = "Avfärda"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Säkerställ att telefonen är inom räckhåll och försök igen"; +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "Säkerställ att din telefon är inom räckhåll och försök igen."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dl"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Nettobasaldos"; +/* Label for off button */ +"Off" = "Av"; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "På"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "Override"; +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Bekräfta bolusmängd."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Före måltid"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "Förinställning"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; + /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Rek: %@ E"; +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "Rek: %@ E"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "Rek: Beräknar..."; + /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Reservoarvolym"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Spara"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Spara & Bolus"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Sändning misslyckades"; +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Vrid på krona för att ge bolus"; + /* The short unit display string for international units of insulin */ "U" = "E"; /* The short unit display string for international units of insulin delivery per hour */ -"U/hr" = "E/h"; +"U/hr" = "E/timme"; + +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "Det går inte att nå iPhone"; /* The text for the Watch button for enabling workout mode */ "Workout" = "Träning"; diff --git a/WatchApp Extension/tr.lproj/InfoPlist.strings b/WatchApp Extension/tr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..78bab3d446 --- /dev/null +++ b/WatchApp Extension/tr.lproj/InfoPlist.strings @@ -0,0 +1,12 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "WatchApp Uzantısı"; + +/* Bundle name */ +"CFBundleName" = "WatchApp Uzantısı"; + +/* Privacy - Health Share Usage Description */ +"NSHealthShareUsageDescription" = "Sağlık veri tabanından alınan yemek verileri, KŞ etkilerini belirlemek için kullanılır. Sağlık veri tabanından alınan KŞ verileri, grafik ve momentum hesaplaması için kullanılır. Sağlık veritabanındaki uyku verileri, uyanık olduğunuz süre boyunca Apple Watch komplikasyon güncellemelerinin teslimini optimize etmek için kullanılır."; + +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Uygulamaya ve saate girilen öğün karbonhidrat verileri Sağlık veritabanında saklanır. CGM'den alınan KŞ verileri, HealthKit'te güvenli bir şekilde saklanır."; + diff --git a/WatchApp Extension/tr.lproj/Localizable.strings b/WatchApp Extension/tr.lproj/Localizable.strings index 4cbccfb6cc..7566f1dfd2 100644 --- a/WatchApp Extension/tr.lproj/Localizable.strings +++ b/WatchApp Extension/tr.lproj/Localizable.strings @@ -1,38 +1,122 @@ +/* No glucose value representation (3 dashes for mg/dL; no spaces as this will get truncated in the watch complication) */ +"---" = "---"; + +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "– – –"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ -"Active Carbs" = "Active Carbs"; +"Active Carbs" = "Aktif Karb."; /* HUD row title for IOB */ -"Active Insulin" = "Active Insulin"; +"Active Insulin" = "Aktif İnsülin"; + +/* Title of the user activity for adding carbs */ +"Add Carb Entry" = "Karb Girişi Ekle"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; /* The title of the alert controller displayed after a bolus attempt fails */ -"Bolus Failed" = "Bolus Failed"; +"Bolus Failed" = "Bolus Başarısız"; + +/* Alert title for updated bolus recommendation on Apple Watch */ +"Bolus Recommendation Updated" = "Bolus Önerisi Güncellendi"; + +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Devam et"; + +/* The short unit display string for decibles */ +"dB" = "dB"; /* The action button title to dismiss an error message */ -"Dismiss" = "Dismiss"; +"Dismiss" = "Reddet"; + +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "gr"; /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ -"Make sure your iPhone is nearby and try again" = "Make sure your iPhone is nearby and try again"; +"Make sure your iPhone is nearby and try again" = "iPhone'nunuzun yakında olduğundan emin olun ve tekrar deneyin"; + +/* The recovery message displayed after a bolus attempt fails + The recovery message displayed after a potential carb entry send attempt fails */ +"Make sure your iPhone is nearby and try again." = "iPhone'unuzun yakında olduğundan emin olun ve tekrar deneyin."; + +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; /* HUD row title for Net Basal Rate */ -"Net Basal Rate" = "Net Basal Rate"; +"Net Basal Rate" = "Net Bazal Oran"; + +/* Label for off button */ +"Off" = "Kapalı"; + +/* No comment provided by engineer. */ +"OK" = "Tamam"; + +/* Label for on button */ +"On" = "Açık"; /* The text for the Watch button for enabling a temporary override */ -"Override" = "Override"; +"Override" = "Geçersiz kıl"; + +/* Alert message for updated bolus recommendation on Apple Watch */ +"Please reconfirm the bolus amount." = "Lütfen bolus miktarını tekrar onaylayın."; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Yemek öncesi"; + +/* The text for the Watch button for enabling a custom preset */ +"Preset" = "ön ayar"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ -"Rec: %@ U" = "Rec: %@ U"; +"Rec: %@ U" = "Önrln: %@ Ü"; + +/* Recommended bolus amount label on Apple Watch */ +"REC: %@ U" = "Önerilen: %@ Ü"; + +/* Indicator that recommended bolus computation is in progress on Apple Watch */ +"REC: Calculating..." = "Önerilen: Hesaplanıyor..."; /* HUD row title for remaining reservoir volume */ -"Reservoir Volume" = "Reservoir Volume"; +"Reservoir Volume" = "Rezervuar Hacmi"; + +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Kaydet"; + +/* Button text to confirm carb entry and bolus on Apple Watch */ +"Save & Bolus" = "Kaydet & Bolus"; /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ -"Send Failed" = "Send Failed"; +"Send Failed" = "Gönderme Başarısız"; + +/* Help text for bolus confirmation on Apple Watch */ +"Turn Digital Crown\nto bolus" = "Digital Crown'u bolusa\nçevirin"; + +/* The short unit display string for international units of insulin */ +"U" = "Ü"; /* The short unit display string for international units of insulin delivery per hour */ -"U/hr" = "U/hr"; +"U/hr" = "Ü/sa"; + +/* The title of the alert controller displayed after a potential carb entry send attempt fails */ +"Unable to Reach iPhone" = "iPhone'a Ulaşılamıyor"; /* The text for the Watch button for enabling workout mode */ -"Workout" = "Workout"; +"Workout" = "Egzersiz"; + diff --git a/WatchApp Extension/tr.lproj/ckcomplication.strings b/WatchApp Extension/tr.lproj/ckcomplication.strings new file mode 100644 index 0000000000..15532b5b45 --- /dev/null +++ b/WatchApp Extension/tr.lproj/ckcomplication.strings @@ -0,0 +1,12 @@ +/* The complication template example time string */ +"3MIN" = "3DK"; + +/* The complication template example glucose string */ +"120" = "120"; + +/* The complication template example glucose and trend string */ +"120↘︎" = "120↘︎"; + +/* Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time) */ +"UtilitarianLargeFlat" = "%@%@ %@"; + diff --git a/WatchApp Extension/vi.lproj/InfoPlist.strings b/WatchApp Extension/vi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..20fe32df1b --- /dev/null +++ b/WatchApp Extension/vi.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Privacy - Health Update Usage Description */ +"NSHealthUpdateUsageDescription" = "Dữ liệu Carbohydrate của bữa ăn được nhập trên phần mềm và trên đồng hồ thông minh sẽ được lưu trữ tại app Health. Các thông số glucose được lấy từ thiết bị theo dõi đường huyết liên tục/CGM sẽ được lưu trữ an toàn trong HealthKit."; + diff --git a/WatchApp Extension/vi.lproj/Localizable.strings b/WatchApp Extension/vi.lproj/Localizable.strings index eedc89b522..81a9491471 100644 --- a/WatchApp Extension/vi.lproj/Localizable.strings +++ b/WatchApp Extension/vi.lproj/Localizable.strings @@ -1,3 +1,9 @@ +/* No glucose value representation (3 dashes for mg/dL) */ +"– – –" = "---"; + +/* Format string for glucose range (1: lower bound)(2: upper bound)(3: unit) */ +"%1$@ – %2$@ %3$@" = "%1$@ – %2$@ %3$@"; + /* HUD row title for COB */ "Active Carbs" = "Lượng Carbs còn hoạt động"; @@ -5,24 +11,55 @@ "Active Insulin" = "Lượng Insulin còn hoạt động"; /* Title of the user activity for adding carbs */ -"Add Carb Entry" = "Khai báo khối lượng Carb"; +"Add Carb Entry" = "Khai báo Carb"; + +/* Button text to confirm manual bolus on Apple Watch */ +"Bolus" = "Bolus"; /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "Bolus lỗi"; +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "Tiếp tục"; + +/* The short unit display string for decibles */ +"dB" = "dB"; + /* The action button title to dismiss an error message */ "Dismiss" = "Từ bỏ"; +/* Short unit label for gram measurement + The short unit display string for grams */ +"g" = "g"; + /* The recovery message displayed after a bolus attempt fails The recovery message displayed after a carb entry send attempt fails The recovery message displayed after a glucose range override send attempt fails */ "Make sure your iPhone is nearby and try again" = "Đảm bảo rằng iPhone của bạn đang ở gần và thử lại"; +/* The short unit display string for milligrams of glucose per decilter */ +"mg/dL" = "mg/dL"; + +/* The short unit display string for millimoles of glucose per liter */ +"mmol/L" = "mmol/L"; + /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "Tỷ lệ liều basal ròng"; +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Label for on button */ +"On" = "On"; + /* The text for the Watch button for enabling a temporary override */ -"Override" = "Chồng liều"; +"Override" = "Chồng lên"; + +/* Title for sheet to enable/disable pre-meal on watch */ +"Pre-Meal" = "Trước bữa ăn"; + +/* Format string for combining localized numeric value and unit. (1: numeric value)(2: unit) */ +"QUANTITY_VALUE_AND_UNIT" = "%1$@ %2$@"; /* The label and value showing the recommended bolus */ "Rec: %@ U" = "Khuyến nghị: %@ U"; @@ -30,13 +67,19 @@ /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "Khối lượng ngăn chứa insulin"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "Lưu"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "Chuyển bị lỗi"; +/* The short unit display string for international units of insulin */ +"U" = "U"; + /* The short unit display string for international units of insulin delivery per hour */ "U/hr" = "U/giờ"; /* The text for the Watch button for enabling workout mode */ -"Workout" = "Tập luyện"; +"Workout" = "Workout"; diff --git a/WatchApp Extension/zh-Hans.lproj/Localizable.strings b/WatchApp Extension/zh-Hans.lproj/Localizable.strings index d9a27d7dbd..e03baf967a 100644 --- a/WatchApp Extension/zh-Hans.lproj/Localizable.strings +++ b/WatchApp Extension/zh-Hans.lproj/Localizable.strings @@ -10,6 +10,9 @@ /* The title of the alert controller displayed after a bolus attempt fails */ "Bolus Failed" = "大剂量输注失败"; +/* Button text to continue from carb entry to bolus entry on Apple Watch */ +"Continue" = "继续"; + /* The action button title to dismiss an error message */ "Dismiss" = "忽略"; @@ -21,6 +24,9 @@ /* HUD row title for Net Basal Rate */ "Net Basal Rate" = "净基础率"; +/* Label for on button */ +"On" = "开"; + /* The text for the Watch button for enabling a temporary override */ "Override" = "覆盖"; @@ -30,6 +36,9 @@ /* HUD row title for remaining reservoir volume */ "Reservoir Volume" = "储药器容量"; +/* Button text to confirm carb entry without bolusing on Apple Watch */ +"Save" = "保存"; + /* The title of the alert controller displayed after a carb entry send attempt fails The title of the alert controller displayed after a glucose range override send attempt fails */ "Send Failed" = "发送失败"; diff --git a/WatchApp/Base.lproj/Interface.storyboard b/WatchApp/Base.lproj/Interface.storyboard index d0c87951d1..03cdd19a1b 100644 --- a/WatchApp/Base.lproj/Interface.storyboard +++ b/WatchApp/Base.lproj/Interface.storyboard @@ -34,6 +34,9 @@ + @@ -155,6 +158,7 @@ + @@ -193,6 +197,9 @@ + @@ -264,6 +271,7 @@ + diff --git a/WatchApp/ar.lproj/InfoPlist.strings b/WatchApp/ar.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/ar.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/ar.lproj/Interface.strings b/WatchApp/ar.lproj/Interface.strings index c746b40682..24928b657b 100644 --- a/WatchApp/ar.lproj/Interface.strings +++ b/WatchApp/ar.lproj/Interface.strings @@ -1,96 +1,32 @@ - -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "—"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Add"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Subtract"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Running"; - -/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ -"MZU-QV-PtZ.text" = "TITLE"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ -"UVY-pa-SUL.text" = "🏃‍♀️"; - -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - -/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ -"XkS-y5-khE.text" = ""; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Add Carbs"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 hours"; - /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "TOTAL CARBS"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Add"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pre-Meal"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 hours"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Subtract"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Carbs"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "—"; + /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolus Failed"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ +"JXa-s1-PJx.text" = "Running"; + +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "—"; + +/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ +"MZU-QV-PtZ.text" = "TITLE"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Override"; @@ -98,23 +34,27 @@ /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "UNITS"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; +/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ +"T4U-wP-dSW.text" = "Label"; + +/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ +"UVY-pa-SUL.text" = "🏃‍♀️"; + /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 hour"; +/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ +"XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "ACTIVE CARBS"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Label"; + diff --git a/WatchApp/cs.lproj/Interface.strings b/WatchApp/cs.lproj/Interface.strings new file mode 100644 index 0000000000..3a926b93b6 --- /dev/null +++ b/WatchApp/cs.lproj/Interface.strings @@ -0,0 +1,6 @@ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; + +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; + diff --git a/WatchApp/da.lproj/InfoPlist.strings b/WatchApp/da.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/da.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/da.lproj/Interface.strings b/WatchApp/da.lproj/Interface.strings index 0a9ce82f38..b631717d30 100644 --- a/WatchApp/da.lproj/Interface.strings +++ b/WatchApp/da.lproj/Interface.strings @@ -1,101 +1,44 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Tilføj Kulhydrater"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "TOTALE KULHYDRATER"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Fratræk"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 timer"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Tilføj"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Tilføj"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ -"f5G-bS-9pd.text" = "Før-Måltid"; - -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 timer"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Fratræk"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; +"f5G-bS-9pd.text" = "Før-måltid"; /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Kulhydrater"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ -"jj3-Gq-HBy.text" = "Bolus Fejlede"; +"jj3-Gq-HBy.text" = "Bolus fejlede"; /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Løber"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITEL"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Overstyr"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; +"nC0-X3-oFJ.text" = "Override"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "ENHEDER"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; +"T4U-wP-dSW.text" = "Etiket"; /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; @@ -103,18 +46,15 @@ /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 time"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "AKTIVE KULHYDRATER"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ -"zO8-x6-bZd.text" = "Label"; +"zO8-x6-bZd.text" = "Etiket"; diff --git a/WatchApp/de.lproj/InfoPlist.strings b/WatchApp/de.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/de.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/de.lproj/Interface.strings b/WatchApp/de.lproj/Interface.strings index 10392d4195..e2bd9d8688 100644 --- a/WatchApp/de.lproj/Interface.strings +++ b/WatchApp/de.lproj/Interface.strings @@ -20,7 +20,7 @@ "jj3-Gq-HBy.text" = "Bolus fehlgeschlagen"; /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Läuft"; +"JXa-s1-PJx.text" = "Laufen"; /* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "–"; diff --git a/WatchApp/en.lproj/Interface.strings b/WatchApp/en.lproj/Interface.strings index c746b40682..de919648ad 100644 --- a/WatchApp/en.lproj/Interface.strings +++ b/WatchApp/en.lproj/Interface.strings @@ -1,120 +1,15 @@ - -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "—"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Add"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Subtract"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "---"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ "IRi-4t-ESO.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Running"; - -/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ -"MZU-QV-PtZ.text" = "TITLE"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "—"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ -"UVY-pa-SUL.text" = "🏃‍♀️"; - -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - -/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ -"XkS-y5-khE.text" = ""; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Add Carbs"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 hours"; - -/* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ -"dea-qG-va8.text" = "TOTAL CARBS"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Add"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; - -/* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ -"f5G-bS-9pd.text" = "Pre-Meal"; - -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 hours"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Subtract"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - -/* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Carbs"; - -/* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ -"jj3-Gq-HBy.text" = "Bolus Failed"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; - -/* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Override"; - -/* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ -"rNf-Mh-tID.title" = "Loop"; - -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "UNITS"; - -/* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ -"smL-Rc-IZh.text" = "Bolus"; - -/* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ -"v5b-sO-bb8.title" = "Loop"; - -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 hour"; - -/* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ -"ycL-5X-a05.text" = "ACTIVE CARBS"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ -"zO8-x6-bZd.text" = "Label"; diff --git a/WatchApp/es.lproj/InfoPlist.strings b/WatchApp/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/es.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/es.lproj/Interface.strings b/WatchApp/es.lproj/Interface.strings index e50ceafb6d..5611ae9b58 100644 --- a/WatchApp/es.lproj/Interface.strings +++ b/WatchApp/es.lproj/Interface.strings @@ -1,65 +1,20 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Agregar Carbs"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "--"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "CARBS"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Sustraer"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 horas"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Agregar"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Agregar"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pre-Comida"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 horas"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Sustraer"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Carbs"; +"hln-CI-MRP.text" = "Carbohidratos"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolo Falló"; @@ -67,11 +22,8 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Correr"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TÍTULO"; @@ -79,44 +31,29 @@ /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Sobreescritura"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolo"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "UNIDADES"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolo"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Etiqueta"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 a.m."; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 hora"; - -/* Class = "WKInterfaceLabel"; text = "Turn Digital Crown to bolus"; ObjectID = "Xcr-jO-0IQ"; */ -"Xcr-jO-0IQ.text" = "Gire el Digital Crown para administrar bolo"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "CARBS ACTIVOS"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Etiqueta"; diff --git a/WatchApp/fi.lproj/InfoPlist.strings b/WatchApp/fi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/fi.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/fi.lproj/Interface.strings b/WatchApp/fi.lproj/Interface.strings index 98ed9614cd..5fb2f12a56 100644 --- a/WatchApp/fi.lproj/Interface.strings +++ b/WatchApp/fi.lproj/Interface.strings @@ -1,65 +1,20 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Lisää hiilari"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "--"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "HIILARI YHT."; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Vähennä"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 tuntia"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Lisää"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Lisää"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ -"f5G-bS-9pd.text" = "E. ateriaa"; - -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 tuntia"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Vähennä"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; +"f5G-bS-9pd.text" = "Ennen ateriaa"; /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Hiilari"; +"hln-CI-MRP.text" = "Hiilihydraatit"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolus epäonnistui"; @@ -67,11 +22,8 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Juoksu"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "OTSIKKO"; @@ -79,44 +31,29 @@ /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Tilapäisas."; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "YKSIKKÖÄ"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Nimiö"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 tunti"; - -/* Class = "WKInterfaceLabel"; text = "Turn Digital Crown to bolus"; ObjectID = "Xcr-jO-0IQ"; */ -"Xcr-jO-0IQ.text" = "Vahvista bolus pyörittämällä Digital Crownia"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "AKT. HIILARI"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Nimiö"; diff --git a/WatchApp/fr.lproj/InfoPlist.strings b/WatchApp/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/fr.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/fr.lproj/Interface.strings b/WatchApp/fr.lproj/Interface.strings index b85e3c11ad..b05a7fb86a 100644 --- a/WatchApp/fr.lproj/Interface.strings +++ b/WatchApp/fr.lproj/Interface.strings @@ -1,123 +1,60 @@ - -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceLabel"; text = "--"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "--"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Ajouter"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Soustraire"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Course"; - -/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ -"MZU-QV-PtZ.text" = "TITLE"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ -"UVY-pa-SUL.text" = "🏃‍♀️"; - -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - -/* Class = "WKInterfaceLabel"; text = "Turn Digital Crown to bolus"; ObjectID = "Xcr-jO-0IQ"; */ -"Xcr-jO-0IQ.text" = "Tourn la couronne Digital Crown pour gérer le bolus"; - -/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ -"XkS-y5-khE.text" = ""; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Ajouter des glucides"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 heures"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "GLUCIDES TOTAUX"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Ajouter"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pré-Repas"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 heures"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Soustraire"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Glucides"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; + /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Échec du bolus"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ +"JXa-s1-PJx.text" = "En marche"; + +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; + +/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ +"MZU-QV-PtZ.text" = "TITLE"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Surcharge"; +"nC0-X3-oFJ.text" = "Ajustement"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "Unités"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; +/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ +"T4U-wP-dSW.text" = "Label"; + +/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ +"UVY-pa-SUL.text" = "🏃‍♀️"; + /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 heure"; +/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ +"XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "GLUCIDES ACTIFS"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Label"; + diff --git a/WatchApp/he.lproj/Interface.strings b/WatchApp/he.lproj/Interface.strings index 68d32f1e82..cc20662d50 100644 --- a/WatchApp/he.lproj/Interface.strings +++ b/WatchApp/he.lproj/Interface.strings @@ -1,43 +1,33 @@ - /* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "–"; - -/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "– – –"; - -/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "–"; - -/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Running"; - -/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ -"MZU-QV-PtZ.text" = "TITLE"; - -/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "–"; - -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ -"UVY-pa-SUL.text" = "🏃‍♀️"; - -/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ -"XkS-y5-khE.text" = ""; +"CsQ-fc-KLC.text" = "-"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "TOTAL CARBS"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "---"; + /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pre-Meal"; /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Carbs"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "-"; + /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolus Failed"; +/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ +"JXa-s1-PJx.text" = "Running"; + +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "-"; + +/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ +"MZU-QV-PtZ.text" = "TITLE"; + /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Override"; @@ -47,14 +37,24 @@ /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; +/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ +"T4U-wP-dSW.text" = "Label"; + +/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ +"UVY-pa-SUL.text" = "🏃‍♀️"; + /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; +/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ +"XkS-y5-khE.text" = ""; + /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "ACTIVE CARBS"; /* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "– – –"; +"yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Label"; + diff --git a/WatchApp/hi.lproj/Interface.strings b/WatchApp/hi.lproj/Interface.strings new file mode 100644 index 0000000000..3a926b93b6 --- /dev/null +++ b/WatchApp/hi.lproj/Interface.strings @@ -0,0 +1,6 @@ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; + +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; + diff --git a/WatchApp/it.lproj/InfoPlist.strings b/WatchApp/it.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/it.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/it.lproj/Interface.strings b/WatchApp/it.lproj/Interface.strings index ef86a11670..e7f8c1ef97 100644 --- a/WatchApp/it.lproj/Interface.strings +++ b/WatchApp/it.lproj/Interface.strings @@ -1,118 +1,58 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Aggiungi Carb"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "TOTALE CARBOIDRATI"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Sottrarre"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 ore"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "---"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Aggiungi"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Aggiungi"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; - /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pre-Pasto"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 ore"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Sottrarre"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Carboidrati"; +"hln-CI-MRP.text" = "Carb."; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolo Fallito"; /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Attività fisica"; +"JXa-s1-PJx.text" = "Corsa"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITOLO"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Override"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolo"; +"nC0-X3-oFJ.text" = "Programma Alternativo"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "Unità"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolo"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Etichetta"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 ora"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "CARBOIDRATI ATTIVI"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ diff --git a/WatchApp/ja.lproj/InfoPlist.strings b/WatchApp/ja.lproj/InfoPlist.strings new file mode 100644 index 0000000000..de9898d5ad --- /dev/null +++ b/WatchApp/ja.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "ループ"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/ja.lproj/Interface.strings b/WatchApp/ja.lproj/Interface.strings index ae0a5e3d21..fa66ec3dd0 100644 --- a/WatchApp/ja.lproj/Interface.strings +++ b/WatchApp/ja.lproj/Interface.strings @@ -1,64 +1,19 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "糖質を追加"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "カーボ合計"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "消去"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2時間"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "---"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "追加"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "追加"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; - /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "食前"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3時間"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "消去"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "糖質"; +"hln-CI-MRP.text" = "カーボ"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ "IRi-4t-ESO.text" = "—"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ @@ -67,52 +22,37 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "動作中"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; - /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "タイトル"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "オーバーライド"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "ボーラス"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "ループ"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "単位"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "ボーラス"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "ラベル"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "ループ"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1時間"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "残存糖質"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ diff --git a/WatchApp/nb.lproj/InfoPlist.strings b/WatchApp/nb.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/nb.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/nb.lproj/Interface.strings b/WatchApp/nb.lproj/Interface.strings index b4bd40f052..92d8e5a056 100644 --- a/WatchApp/nb.lproj/Interface.strings +++ b/WatchApp/nb.lproj/Interface.strings @@ -1,65 +1,20 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Legg til karbohydrater"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "KARBOHYDRATER TOTALT"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Trekk fra"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 timer"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Legg til"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Legg til"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pre-måltid"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 timer"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Trekk fra"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Karbohydrater"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolus feilet"; @@ -67,11 +22,8 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Løper"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITTEL"; @@ -79,41 +31,29 @@ /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Overstyr"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "ENHETER"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Etikett"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 time"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "AKTIVE KARBOHYDRATER"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Etikett"; diff --git a/WatchApp/nl.lproj/InfoPlist.strings b/WatchApp/nl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/nl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/nl.lproj/Interface.strings b/WatchApp/nl.lproj/Interface.strings index 6726c43fa7..daf7473d97 100644 --- a/WatchApp/nl.lproj/Interface.strings +++ b/WatchApp/nl.lproj/Interface.strings @@ -1,101 +1,44 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Koolhydraten toevoegen"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ -"dea-qG-va8.text" = "Totaal koolhydraten"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Aftrekken"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 uur"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Toevoegen"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; +"dea-qG-va8.text" = "Totaal Koolhydraten"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Toevoegen"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ -"f5G-bS-9pd.text" = "Voor de maaltijd"; - -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 uur"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Aftrekken"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; +"f5G-bS-9pd.text" = "Pre-Meal"; /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Koolhydraten"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ -"jj3-Gq-HBy.text" = "Bolus mislukt"; +"jj3-Gq-HBy.text" = "Bolus Mislukt"; /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Actief"; +"JXa-s1-PJx.text" = "Hardlopen"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITEL"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Aangepast programma"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; +"nC0-X3-oFJ.text" = "Override"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "Eenheden"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; +"T4U-wP-dSW.text" = "Etiket"; /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; @@ -103,18 +46,15 @@ /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 uur"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ -"ycL-5X-a05.text" = "Actieve koolhydraten"; +"ycL-5X-a05.text" = "ACTIEVE KOOLHYDRATEN"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ -"zO8-x6-bZd.text" = "Label"; +"zO8-x6-bZd.text" = "Etiket"; diff --git a/WatchApp/pl.lproj/InfoPlist.strings b/WatchApp/pl.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/pl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/pl.lproj/Interface.strings b/WatchApp/pl.lproj/Interface.strings index 87f8350f03..6199faad1e 100644 --- a/WatchApp/pl.lproj/Interface.strings +++ b/WatchApp/pl.lproj/Interface.strings @@ -1,96 +1,32 @@ - -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Dodaj"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Odejmij"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Pracuje"; - -/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ -"MZU-QV-PtZ.text" = "TYTUŁ"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolusa"; - -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Etykieta"; - -/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ -"UVY-pa-SUL.text" = "🏃‍♀️"; - -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - -/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ -"XkS-y5-khE.text" = ""; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Dodaj węglowodany"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 godziny"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "WĘGLOWODANY OGÓŁEM"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Dodaj"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Przed posiłkiem"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 godziny"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Odejmij"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Węglowodany"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; + /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ -"jj3-Gq-HBy.text" = "Bolusa nie podany"; +"jj3-Gq-HBy.text" = "Bolus nie podany"; + +/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ +"JXa-s1-PJx.text" = "Pracuje"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; + +/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ +"MZU-QV-PtZ.text" = "TYTUŁ"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Pominięcie"; @@ -98,23 +34,27 @@ /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "JEDNOSTKI"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ -"smL-Rc-IZh.text" = "Bolusa"; +"smL-Rc-IZh.text" = "Bolus"; + +/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ +"T4U-wP-dSW.text" = "Etykieta"; + +/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ +"UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 godzina"; +/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ +"XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "AKTYWNE WĘGLOWODANY"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Etykieta"; + diff --git a/WatchApp/pt-BR.lproj/InfoPlist.strings b/WatchApp/pt-BR.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/pt-BR.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/pt-BR.lproj/Interface.strings b/WatchApp/pt-BR.lproj/Interface.strings index 24fdd6bff4..c84db2cb98 100644 --- a/WatchApp/pt-BR.lproj/Interface.strings +++ b/WatchApp/pt-BR.lproj/Interface.strings @@ -1,64 +1,19 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Adicionar Carbs"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "CARBS TOTAL"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Subtrair"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 horas"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "---"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Adicionar"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Adicionar"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; - /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Pré-Refeição"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 horas"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Subtrair"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Carbs"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ "IRi-4t-ESO.text" = "—"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ @@ -67,52 +22,37 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Executando"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; - /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TÍTULO"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Sobrepor"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "UNIDADES"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Rótulo"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 hora"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "CARBS ATIVOS"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ diff --git a/WatchApp/ro.lproj/InfoPlist.strings b/WatchApp/ro.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/ro.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/ro.lproj/Interface.strings b/WatchApp/ro.lproj/Interface.strings index 278e385ab9..fc462cb690 100644 --- a/WatchApp/ro.lproj/Interface.strings +++ b/WatchApp/ro.lproj/Interface.strings @@ -1,77 +1,29 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Adaugă carbohidrați"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "CARBOHIDRAȚI TOTALI"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Scade"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 ore"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Adaugă"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Adaugă"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Preprandial"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 ore"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Scade"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Carbohidrați"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolus eșuat"; /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Rulează"; +"JXa-s1-PJx.text" = "Se rulează"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITLU"; @@ -79,41 +31,29 @@ /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Înlocuire"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "UNITĂȚI"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Etichetă"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 oră"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "CARBOHIDRAȚI ACTIVI"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Etichetă"; diff --git a/WatchApp/ru.lproj/InfoPlist.strings b/WatchApp/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/ru.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/ru.lproj/Interface.strings b/WatchApp/ru.lproj/Interface.strings index cbccbed6d0..cf2c90d48d 100644 --- a/WatchApp/ru.lproj/Interface.strings +++ b/WatchApp/ru.lproj/Interface.strings @@ -1,119 +1,59 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Добавить углеводов"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ -"dea-qG-va8.text" = "ВСЕГО УГЛ"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "вычитать"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 часа"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Добавить"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; +"dea-qG-va8.text" = "ВСЕГО УГЛЕВОДОВ"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Добавить"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "До еды"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 часа"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "вычитать"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "Углеводы"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Болюс не состоялся"; /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Бег"; +"JXa-s1-PJx.text" = "Выполнение"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "НАЗВАНИЕ"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Перезаписать"; - -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Болюс"; +"nC0-X3-oFJ.text" = "Включить"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "ед"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Болюс"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Ярлык"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 час"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ -"ycL-5X-a05.text" = "АКТИВНЫЕ УГЛ"; +"ycL-5X-a05.text" = "АКТИВНЫЕ УГЛЕВОДЫ"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Ярлык"; diff --git a/WatchApp/sk.lproj/InfoPlist.strings b/WatchApp/sk.lproj/InfoPlist.strings new file mode 100644 index 0000000000..273b97d2be --- /dev/null +++ b/WatchApp/sk.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + diff --git a/WatchApp/sk.lproj/Interface.strings b/WatchApp/sk.lproj/Interface.strings new file mode 100644 index 0000000000..39844f8142 --- /dev/null +++ b/WatchApp/sk.lproj/Interface.strings @@ -0,0 +1,15 @@ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; + +/* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ +"rNf-Mh-tID.title" = "Loop"; + +/* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ +"smL-Rc-IZh.text" = "Bolus"; + +/* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ +"v5b-sO-bb8.title" = "Loop"; + +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; + diff --git a/WatchApp/sv.lproj/InfoPlist.strings b/WatchApp/sv.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/sv.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/sv.lproj/Interface.strings b/WatchApp/sv.lproj/Interface.strings index d43289bf96..668835726b 100644 --- a/WatchApp/sv.lproj/Interface.strings +++ b/WatchApp/sv.lproj/Interface.strings @@ -1,65 +1,20 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Kolhydrater"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ -"CsQ-fc-KLC.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ +"CsQ-fc-KLC.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "Kolh. totalt"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Subtrahera"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 timmar"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ -"Dt1-kz-jMZ.text" = "---"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Lägg till"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Lägg till"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ +"Dt1-kz-jMZ.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Före måltid"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 timmar"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Subtrahera"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Kolh."; +"hln-CI-MRP.text" = "Kolhydrater"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ -"IRi-4t-ESO.text" = "—"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ +"IRi-4t-ESO.text" = "–"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ "jj3-Gq-HBy.text" = "Bolus misslyckades"; @@ -67,11 +22,8 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Löpning"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ -"Mhe-aR-kQQ.text" = "—"; - -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0,000"; +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ +"Mhe-aR-kQQ.text" = "–"; /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITLE"; @@ -79,41 +31,29 @@ /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Override"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "ENHETER"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Label"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 timme"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "AKTIVA KOLH."; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ -"yl8-ZP-c3l.text" = "---"; +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ +"yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ "zO8-x6-bZd.text" = "Label"; diff --git a/WatchApp/tr.lproj/Interface.strings b/WatchApp/tr.lproj/Interface.strings index 68d32f1e82..6de4cf4758 100644 --- a/WatchApp/tr.lproj/Interface.strings +++ b/WatchApp/tr.lproj/Interface.strings @@ -1,45 +1,35 @@ - /* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "–"; +/* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ +"dea-qG-va8.text" = "TOPLAM KARB"; + /* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "– – –"; +/* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ +"f5G-bS-9pd.text" = "Yemek öncesi"; + +/* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ +"hln-CI-MRP.text" = "Karb"; + /* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ "IRi-4t-ESO.text" = "–"; -/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ -"JXa-s1-PJx.text" = "Running"; +/* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ +"jj3-Gq-HBy.text" = "Bolus Başarısız"; -/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ -"MZU-QV-PtZ.text" = "TITLE"; +/* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ +"JXa-s1-PJx.text" = "Çalışıyor"; /* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "–"; -/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ -"T4U-wP-dSW.text" = "Label"; - -/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ -"UVY-pa-SUL.text" = "🏃‍♀️"; - -/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ -"XkS-y5-khE.text" = ""; - -/* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ -"dea-qG-va8.text" = "TOTAL CARBS"; - -/* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ -"f5G-bS-9pd.text" = "Pre-Meal"; - -/* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Carbs"; - -/* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ -"jj3-Gq-HBy.text" = "Bolus Failed"; +/* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ +"MZU-QV-PtZ.text" = "BAŞLIK"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ -"nC0-X3-oFJ.text" = "Override"; +"nC0-X3-oFJ.text" = "Geçersiz kıl"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; @@ -47,14 +37,24 @@ /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; +/* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ +"T4U-wP-dSW.text" = "Etiket"; + +/* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ +"UVY-pa-SUL.text" = "🏃‍♀️"; + /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; +/* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ +"XkS-y5-khE.text" = ""; + /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ -"ycL-5X-a05.text" = "ACTIVE CARBS"; +"ycL-5X-a05.text" = "AKTİF KARB"; /* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "– – –"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ -"zO8-x6-bZd.text" = "Label"; +"zO8-x6-bZd.text" = "Etiket"; + diff --git a/WatchApp/vi.lproj/InfoPlist.strings b/WatchApp/vi.lproj/InfoPlist.strings new file mode 100644 index 0000000000..9250064a26 --- /dev/null +++ b/WatchApp/vi.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* (No Comment) */ +"CFBundleDisplayName" = "Loop"; + +/* (No Comment) */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/WatchApp/vi.lproj/Interface.strings b/WatchApp/vi.lproj/Interface.strings index fbfe111916..0f58d40ea9 100644 --- a/WatchApp/vi.lproj/Interface.strings +++ b/WatchApp/vi.lproj/Interface.strings @@ -1,64 +1,19 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "Khai báo lượng Carbs"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "TỔNG CỘNG LƯỢNG CARBS"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "Trừ đi"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2 giờ"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "---"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "Thêm vào"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "Thêm vào"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; - /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "Trước bữa ăn"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3 giờ"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "Trừ đi"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ -"hln-CI-MRP.text" = "Lượng Carbs"; +"hln-CI-MRP.text" = "Carbs"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ "IRi-4t-ESO.text" = "—"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ @@ -67,52 +22,37 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "Đang chạy"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; - /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "TITLE"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Chồng lên"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "Bolus"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "ĐƠN VỊ"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "Bolus"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "Label"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1 giờ"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "LƯỢNG CARBS CÒN HOẠT ĐỘNG"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */ diff --git a/WatchApp/zh-Hans.lproj/Interface.strings b/WatchApp/zh-Hans.lproj/Interface.strings index 49378f974d..a493bb05ef 100644 --- a/WatchApp/zh-Hans.lproj/Interface.strings +++ b/WatchApp/zh-Hans.lproj/Interface.strings @@ -1,64 +1,19 @@ -/* Class = "WKInterfaceButton"; title = "🌮"; ObjectID = "0fo-Z3-hTi"; */ -"0fo-Z3-hTi.title" = "🌮"; - -/* Class = "WKInterfaceButton"; title = "Add Carbs"; ObjectID = "b6f-3I-jki"; */ -"b6f-3I-jki.title" = "添加碳水化合物"; - -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "CsQ-fc-KLC"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "CsQ-fc-KLC"; */ "CsQ-fc-KLC.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "15"; ObjectID = "CWt-7U-cnK"; */ -"CWt-7U-cnK.text" = "15"; - /* Class = "WKInterfaceLabel"; text = "TOTAL CARBS"; ObjectID = "dea-qG-va8"; */ "dea-qG-va8.text" = "碳水总量"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.accessibilityLabel" = "减去"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "Dh9-HV-fXy"; */ -"Dh9-HV-fXy.title" = "−"; - -/* Class = "WKInterfaceButton"; title = "🍕"; ObjectID = "dPF-QZ-sh6"; */ -"dPF-QZ-sh6.title" = "🍕"; - -/* Class = "WKInterfaceMenuItem"; title = "2 hours"; ObjectID = "dPh-7b-Tfv"; */ -"dPh-7b-Tfv.title" = "2小时"; - -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "Dt1-kz-jMZ"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "Dt1-kz-jMZ"; */ "Dt1-kz-jMZ.text" = "---"; -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.accessibilityLabel" = "添加"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "DZc-Gn-RLu"; */ -"DZc-Gn-RLu.title" = "+"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Add"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.accessibilityLabel" = "添加"; - -/* Class = "WKInterfaceButton"; title = "+"; ObjectID = "eu3-pj-GH3"; */ -"eu3-pj-GH3.title" = "+"; - /* Class = "WKInterfaceLabel"; text = "Pre-Meal"; ObjectID = "f5G-bS-9pd"; */ "f5G-bS-9pd.text" = "餐前模式"; -/* Class = "WKInterfaceMenuItem"; title = "3 hours"; ObjectID = "fR1-7h-SNe"; */ -"fR1-7h-SNe.title" = "3小时"; - -/* Class = "WKInterfaceButton"; title = "🍭"; ObjectID = "gAn-qe-OvX"; */ -"gAn-qe-OvX.title" = "🍭"; - -/* Class = "WKInterfaceButton"; accessibilityLabel = "Subtract"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.accessibilityLabel" = "减去"; - -/* Class = "WKInterfaceButton"; title = "−"; ObjectID = "hjF-xr-cwO"; */ -"hjF-xr-cwO.title" = "−"; - /* Class = "WKInterfaceLabel"; text = "Carbs"; ObjectID = "hln-CI-MRP"; */ "hln-CI-MRP.text" = "碳水化合物"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "IRi-4t-ESO"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "IRi-4t-ESO"; */ "IRi-4t-ESO.text" = "—"; /* Class = "WKInterfaceLabel"; text = "Bolus Failed"; ObjectID = "jj3-Gq-HBy"; */ @@ -67,52 +22,37 @@ /* Class = "WKInterfaceLabel"; text = "Running"; ObjectID = "JXa-s1-PJx"; */ "JXa-s1-PJx.text" = "运行中"; -/* Class = "WKInterfaceLabel"; text = "—"; ObjectID = "Mhe-aR-kQQ"; */ +/* Class = "WKInterfaceLabel"; text = "–"; ObjectID = "Mhe-aR-kQQ"; */ "Mhe-aR-kQQ.text" = "—"; -/* Class = "WKInterfaceLabel"; text = "0.000"; ObjectID = "mpK-zY-UvA"; */ -"mpK-zY-UvA.text" = "0.000"; - /* Class = "WKInterfaceLabel"; text = "TITLE"; ObjectID = "MZU-QV-PtZ"; */ "MZU-QV-PtZ.text" = "名称"; /* Class = "WKInterfaceLabel"; text = "Override"; ObjectID = "nC0-X3-oFJ"; */ "nC0-X3-oFJ.text" = "Override"; -/* Class = "WKInterfaceButton"; title = "Bolus"; ObjectID = "Qsq-p5-1J0"; */ -"Qsq-p5-1J0.title" = "大剂量"; - /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "rNf-Mh-tID"; */ "rNf-Mh-tID.title" = "Loop"; -/* Class = "WKInterfaceLabel"; text = "UNITS"; ObjectID = "rV7-d9-n6u"; */ -"rV7-d9-n6u.text" = "单位"; - /* Class = "WKInterfaceLabel"; text = "Bolus"; ObjectID = "smL-Rc-IZh"; */ "smL-Rc-IZh.text" = "大剂量"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "T4U-wP-dSW"; */ "T4U-wP-dSW.text" = "标签"; -/* Class = "WKInterfaceLabel"; text = "10:09 AM"; ObjectID = "Ury-of-vQg"; */ -"Ury-of-vQg.text" = "10:09 AM"; - /* Class = "WKInterfaceLabel"; text = "🏃‍♀️"; ObjectID = "UVY-pa-SUL"; */ "UVY-pa-SUL.text" = "🏃‍♀️"; /* Class = "WKInterfaceController"; title = "Loop"; ObjectID = "v5b-sO-bb8"; */ "v5b-sO-bb8.title" = "Loop"; -/* Class = "WKInterfaceMenuItem"; title = "1 hour"; ObjectID = "vL1-NA-WZ1"; */ -"vL1-NA-WZ1.title" = "1小时"; - /* Class = "WKInterfaceLabel"; text = ""; ObjectID = "XkS-y5-khE"; */ "XkS-y5-khE.text" = ""; /* Class = "WKInterfaceLabel"; text = "ACTIVE CARBS"; ObjectID = "ycL-5X-a05"; */ "ycL-5X-a05.text" = "ACTIVE CARBS"; -/* Class = "WKInterfaceLabel"; text = "---"; ObjectID = "yl8-ZP-c3l"; */ +/* Class = "WKInterfaceLabel"; text = "– – –"; ObjectID = "yl8-ZP-c3l"; */ "yl8-ZP-c3l.text" = "---"; /* Class = "WKInterfaceLabel"; text = "Label"; ObjectID = "zO8-x6-bZd"; */