Select Your Language
{{ currentSubtitle }}
English
ગુજરાતી
(Gujarati)
हिन्दी
(Hindi)
ಕನ್ನಡ
(Kannada)
తెలుగు
(Telugu)
मराठी
(Marathi)
বাংলা - সাধু
(Bengali Sadhu)
বাংলা - চলিত
(Bengali Cholito)
தமிழ்
(Tamil)
മലയാളം
(Malayalam)
ਪੰਜਾਬੀ
(Punjabi)
ଓଡ଼ିଆ
(Odia)
অসমীয়া
(Assamese)
भोजपुरी
(Bhojpuri)
मैथिली
(Maithili)
अवधी
(Awadhi)
{{ progressState.title }}
{{ progressState.message }}
{{ i18n.t('cancel') }}
{{ i18n.t('whatIsPpm') }}
{{ i18n.t('theBasicFormula') }}
{{ i18n.t('breakDownEachPart') }}
{{ i18n.t('noCalculationYet') }}
{{ i18n.t('addFertilizersToSeeBreakdown') }}
{{ i18n.t('calculatorShowsStepByStep') }}
{{ i18n.t('yourCurrentCalculation') }}
{{ i18n.t('solutionVolumeLabel') }} {{ formatNumber(modalData.volume) }} {{ i18n.t('litersUnit') }}
{{ i18n.t('fertilizersUsedLabel') }} {{ modalData.activeFertilizers.length }}
{{ i18n.t('stepByStepBreakdown') }}
{{ i18n.t('howEachFertilizerContributesToPpm') }}
{{ index + 1 }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.t('amountUsedLabel') }} {{ formatNumber(fert.grams) }} {{ i18n.t('gramsUnit') }}
{{ i18n.t('nutrientPpmValues') }}:
{{ nutrient.name }}
{{ formatNumber(nutrient.ppm, 2) }} ppm
{{ formatNumber(fert.grams) }} g × {{ formatNumber(1000) }} × ({{ formatNumber(nutrient.percent, 2) }}% ÷ {{ formatNumber(100) }}) ÷ {{ formatNumber(modalData.volume) }} {{ i18n.t('litersUnit') }} = {{ formatNumber(nutrient.ppm, 2) }} ppm
{{ i18n.t('aboutOxideConversions') }}
{{ i18n.t('oxideFormHeader') }}
{{ i18n.t('elementalFormHeader') }}
{{ i18n.t('conversionFactorHeader') }}
{{ conv.oxideName }}
{{ conv.elementalName }}
× {{ conv.factor }}
{{ i18n.t('quickTips') }}
{{ i18n.t('tip1PpmEquals') }}
{{ i18n.t('tip2StartLower') }}
{{ i18n.t('tip3DifferentPlants') }}
{{ i18n.t('tip4BalanceIsKey') }}
{{ i18n.t('whatIsIonBalance') }}
{{ i18n.t('understandingMeqL') }}
{{ i18n.t('meqLAnalogy') }}
{{ i18n.t('noCalculationYet') }}
{{ i18n.t('addFertilizersForIonBalance') }}
{{ i18n.t('yourCurrentSolution') }}
{{ i18n.t('solutionVolumeLabel') }} {{ formatNumber(modalData.volume) }} {{ i18n.t('litersUnit') }}
{{ i18n.t('fertilizersUsedLabel') }} {{ modalData.activeFertilizers.length }}
{{ i18n.t('stepByStepIonCalculation') }}
{{ i18n.t('howEachFertilizerContributesIons') }}
{{ index + 1 }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.t('amountUsedLabel') }} {{ formatNumber(fert.grams) }} {{ i18n.t('gramsUnit') }}
{{ i18n.t('molarMassLabel') }} {{ formatNumber(getIonDataForFert(fert).molarMass, 2) }} g/mol
{{ i18n.t('molesLabel') }} {{ formatNumber(fert.grams) }} g ÷ {{ formatNumber(getIonDataForFert(fert).molarMass, 2) }} g/mol = {{ formatNumber(fert.grams / getIonDataForFert(fert).molarMass, 6) }} mol
Ion Contributions:
{{ ionInfo.ion }} ({{ ionInfo.type === 'cation' ? '+' : '-' }})
{{ formatNumber(calculateIonMeq(fert, ionInfo), 3) }} meq/L
{{ formatNumber(fert.grams / getIonDataForFert(fert).molarMass, 6) }} mol × {{ formatNumber(ionInfo.count) }} {{ i18n.t('ionsUnit') }} × {{ formatNumber(ionInfo.charge) }} {{ i18n.t('chargeUnit') }} × {{ formatNumber(1000) }} ÷ {{ formatNumber(modalData.volume) }} {{ i18n.t('litersUnit') }} = {{ formatNumber(calculateIonMeq(fert, ionInfo), 3) }} meq/L
Cations subtotal:
{{ formatNumber(calculateFertCationTotal(fert), 3) }} meq/L
Anions subtotal:
{{ formatNumber(calculateFertAnionTotal(fert), 3) }} meq/L
{{ i18n.t('nutrientTotalsSummary') }}
{{ i18n.t('whenNutrientsFromMultiple') }}
{{ i18n.t('cations') }} (+)
{{ ion }}
{{ formatNumber(data.meq, 3) }} meq/L
{{ i18n.t('totalCations') }}
{{ formatNumber(modalData.ionBalance.totalCations, 3) }} meq/L
{{ i18n.t('anions') }} (-)
{{ ion }}
{{ formatNumber(data.meq, 3) }} meq/L
{{ i18n.t('totalAnions') }}
{{ formatNumber(modalData.ionBalance.totalAnions, 3) }} meq/L
{{ i18n.t('finalIonBalanceResults') }}
{{ i18n.t('totalCationsPlus') }}
{{ formatNumber(modalData.ionBalance.totalCations, 3) }} meq/L
vs
{{ i18n.t('totalAnionsMinus') }}
{{ formatNumber(modalData.ionBalance.totalAnions, 3) }} meq/L
{{ i18n.t('imbalancePercentage') }}
{{ formatNumber(modalData.ionBalance.imbalance, 1) }}%
{{ modalData.ionBalance.statusText }}
{{ i18n.t('howWeCalculatedImbalance') }}
|{{ formatNumber(modalData.ionBalance.totalCations, 3) }} - {{ formatNumber(modalData.ionBalance.totalAnions, 3) }}| ÷ (({{ formatNumber(modalData.ionBalance.totalCations, 3) }} + {{ formatNumber(modalData.ionBalance.totalAnions, 3) }}) ÷ 2) × 100 = {{ formatNumber(modalData.ionBalance.imbalance, 1) }}%
{{ i18n.t('interpretingResults') }}
{{ i18n.t('imbalanceLessThan10') }} {{ i18n.t('imbalanceLessThan10Desc') }}
{{ i18n.t('imbalance10To20') }} {{ i18n.t('imbalance10To20Desc') }}
{{ i18n.t('imbalanceOver20') }} {{ i18n.t('imbalanceOver20Desc') }}
{{ i18n.t('whyDoesThisMatter') }} {{ i18n.t('whyDoesThisMatterExplanation') }}
{{ i18n.t('ecCalculationMethod') }}
{{ i18n.t('lambdaReferenceTable') }}
{{ i18n.t('lambdaTableDescription') }}
{{ i18n.t('cations') }} (+)
{{ i18n.t('ionHeader') }}
{{ i18n.t('molarMassHeader') }}
λ
K⁺ ({{ i18n.t('potassium') }}) {{ formatNumber(39.098) }} {{ formatNumber(73.5) }}
NH₄⁺ ({{ i18n.t('ammonium') }}) {{ formatNumber(14.007) }} {{ formatNumber(73.5) }}
Ca²⁺ ({{ i18n.t('calciumSimple') }}) {{ formatNumber(40.078) }} {{ formatNumber(119.0) }}
Mg²⁺ ({{ i18n.t('magnesiumSimple') }}) {{ formatNumber(24.305) }} {{ formatNumber(106.0) }}
Fe²⁺ ({{ i18n.t('ironII') }}) {{ formatNumber(55.845) }} {{ formatNumber(108.0) }}
Fe³⁺ ({{ i18n.t('ironIII') }}) {{ formatNumber(55.845) }} {{ formatNumber(204.0) }}
Mn²⁺ ({{ i18n.t('manganese') }}) {{ formatNumber(54.938) }} {{ formatNumber(107.0) }}
Zn²⁺ ({{ i18n.t('zinc') }}) {{ formatNumber(65.38) }} {{ formatNumber(105.6) }}
Cu²⁺ ({{ i18n.t('copper') }}) {{ formatNumber(63.546) }} {{ formatNumber(107.2) }}
{{ i18n.t('anions') }} (-)
{{ i18n.t('ionHeader') }}
{{ i18n.t('molarMassHeader') }}
λ
NO₃⁻ ({{ i18n.t('nitrate') }}) {{ formatNumber(14.007) }} {{ formatNumber(71.5) }}
Cl⁻ ({{ i18n.t('chloride') }}) {{ formatNumber(35.453) }} {{ formatNumber(76.3) }}
SO₄²⁻ ({{ i18n.t('sulfate') }}) {{ formatNumber(32.065) }} {{ formatNumber(160.0) }}
H₂PO₄⁻ ({{ i18n.t('dihydrogenPhosphate') }}) {{ formatNumber(30.974) }} {{ formatNumber(33.5) }}
HPO₄²⁻ ({{ i18n.t('hydrogenPhosphate') }}) {{ formatNumber(30.974) }} {{ formatNumber(114.0) }}
HCO₃⁻ ({{ i18n.t('bicarbonate') }}) {{ formatNumber(61.017) }} {{ formatNumber(44.5) }}
{{ i18n.t('lambdaUnitsNote') }}
{{ i18n.t('ecRangesTitle') }}
< 1.0 mS/cm: {{ i18n.t('ecRangeLow') }}
1.0 - 1.5 mS/cm: {{ i18n.t('ecRangeMild') }}
1.5 - 2.5 mS/cm: {{ i18n.t('ecRangeOptimal') }}
2.5 - 3.0 mS/cm: {{ i18n.t('ecRangeStrong') }}
> 3.0 mS/cm: {{ i18n.t('ecRangeHigh') }}
{{ i18n.t('ecBreakdownByIon') }}
{{ i18n.t('ecBreakdownDescription') }}
{{ i18n.t('tableColumnsExplained') }}:
{{ i18n.t('ionHeader') }} - {{ i18n.t('ionColumnDesc') }}
{{ i18n.t('concMmolLHeader') }} - {{ i18n.t('concColumnDesc') }}
λ ({{ i18n.t('lambdaHeader') }}) - {{ i18n.t('lambdaColumnDesc') }}
{{ i18n.t('ecContribHeader') }} - {{ i18n.t('contribColumnDesc') }}
{{ i18n.t('howConcentrationCalculated') }}:
{{ i18n.t('concentrationFormula') }}
{{ i18n.t('concentrationFormulaDesc') }}
{{ i18n.t('ppmLearnMoreNote') }}
{{ i18n.t('ionHeader') }}
PPM
{{ i18n.t('concentrationCalcHeader') }}
λ
{{ i18n.t('ecContribHeader') }}
%
{{ ion }}
{{ data.ppm ? i18n.formatNumber(data.ppm.toFixed(2)) : '-' }}
{{ i18n.formatNumber(data.ppm.toFixed(2)) }} ÷ {{ i18n.formatNumber(data.molarMass.toFixed(3)) }} = {{ i18n.formatNumber(data.concentration_mmolL.toFixed(3)) }}
{{ i18n.formatNumber(data.concentration_mmolL.toFixed(3)) }}
{{ i18n.formatNumber(data.lambda) }}
{{ i18n.formatNumber(data.contribution_mS_cm.toFixed(4)) }}
{{ i18n.formatNumber((data.contribution_mS_cm / modalData.rawEC * 100).toFixed(1)) }}%
{{ i18n.t('totalLabel') }}
{{ i18n.formatNumber(modalData.rawEC?.toFixed(4) || 0) }} mS/cm
{{ formatNumber(100) }}%
{{ i18n.t('howEachRowCalculated') }}:
{{ i18n.t('ecContribFormula') }}
{{ i18n.t('ecContribFormulaDesc') }}
{{ i18n.t('rawEcLabel') }}: {{ i18n.formatNumber(modalData.rawEC?.toFixed(3) || 0) }} mS/cm
{{ i18n.t('ionicStrength') }}: {{ i18n.formatNumber(modalData.ionicStrength?.toFixed(4) || 0) }} mol/L
{{ i18n.t('ionicStrengthCorrectionNote') }}
{{ i18n.t('ecTips') }}
{{ i18n.t('ecTip1') }}
{{ i18n.t('ecTip2') }}
{{ i18n.t('ecTip3') }}
{{ i18n.t('ecTip4') }}
{{ i18n.t('whatIsKCaRatio') }}
{{ i18n.t('kCaYourCurrentRatio') }}
{{ i18n.formatNumber(modalData.kCaRatio) }} : 1
{{ modalData.kCaStatus.text }}
{{ i18n.t('kCaOptimalRange') }}
{{ i18n.t('kCaContextualWarning') }}
{{ i18n.t('kCaWhenTooHigh') }}
{{ i18n.t('kCaHighSymptoms') }}
{{ i18n.t('kCaHighSymptom1') }}
{{ i18n.t('kCaHighSymptom2') }}
{{ i18n.t('kCaHighSymptom3') }}
{{ i18n.t('kCaHighCauses') }}
{{ i18n.t('kCaHighCause1') }}
{{ i18n.t('kCaHighCause2') }}
{{ i18n.t('kCaHighFixes') }}
{{ i18n.t('kCaHighFix2') }}
{{ i18n.t('kCaHighFixWarning') }}
{{ i18n.t('kCaWhenTooLow') }}
{{ i18n.t('kCaLowSymptoms') }}
{{ i18n.t('kCaLowSymptom1') }}
{{ i18n.t('kCaLowSymptom2') }}
{{ i18n.t('kCaLowCauses') }}
{{ i18n.t('kCaLowCause1') }}
{{ i18n.t('kCaLowCause2') }}
{{ i18n.t('kCaLowFixes') }}
{{ i18n.t('kCaLowFix1') }}
{{ i18n.t('kCaLowFix2') }}
{{ i18n.t('kCaCommonMistakes') }}
{{ i18n.t('kCaMistake1Title') }}
{{ i18n.t('kCaMistake1Why') }}
{{ i18n.t('kCaMistake2Title') }}
{{ i18n.t('kCaMistake2Why') }}
{{ i18n.t('kCaMistake3Title') }}
{{ i18n.t('kCaMistake3Why') }}
{{ i18n.t('kCaWhenToAdjust') }}
{{ i18n.t('kCaIncreaseKWhen') }}
{{ i18n.t('kCaIncreaseK1') }}
{{ i18n.t('kCaIncreaseK2') }}
{{ i18n.t('kCaIncreaseCaWhen') }}
{{ i18n.t('kCaIncreaseCa1') }}
{{ i18n.t('kCaIncreaseCa2') }}
{{ i18n.t('kCaReduceKWhen') }}
{{ i18n.t('kCaReduceK1') }}
{{ i18n.t('kCaRealityCheck') }}
{{ i18n.t('kCaRealityCheckText') }}
{{ i18n.t('kCaRealityCheck1') }}
{{ i18n.t('kCaRealityCheck2') }}
{{ i18n.t('kCaRealityCheck3') }}
{{ i18n.t('kCaRealityCheckConclusion') }}
{{ i18n.t('whatIsNo3Nh4Ratio') }}
{{ i18n.t('no3Nh4YourCurrentRatio') }}
{{ i18n.formatNumber(modalData.no3Nh4Ratio?.toFixed(1) || '0') }} : 1
{{ modalData.no3Nh4Status.text }}
{{ i18n.t('no3Nh4OptimalRange') }}
{{ i18n.t('no3Nh4ContextualWarning') }}
{{ i18n.t('no3Nh4YourCurrentRatio') }}
100% NO₃
{{ i18n.t('no3Nh4StatusVeryHigh') }}
{{ i18n.t('no3Nh4VeryHighNote') }}
{{ i18n.t('no3Nh4ThresholdsTitle') }}
{{ i18n.t('no3Nh4Threshold1') }}
{{ i18n.t('no3Nh4Threshold2') }}
{{ i18n.t('no3Nh4Threshold3') }}
{{ i18n.t('no3Nh4Threshold4') }}
{{ i18n.t('no3Nh4WhenTooLow') }}
{{ i18n.t('no3Nh4LowSymptoms') }}
{{ i18n.t('no3Nh4LowSymptom1') }}
{{ i18n.t('no3Nh4LowSymptom2') }}
{{ i18n.t('no3Nh4LowSymptom3') }}
{{ i18n.t('no3Nh4LowSymptom4') }}
{{ i18n.t('no3Nh4LowCauses') }}
{{ i18n.t('no3Nh4LowCause1') }}
{{ i18n.t('no3Nh4LowCause2') }}
{{ i18n.t('no3Nh4LowCause3') }}
{{ i18n.t('no3Nh4LowFixes') }}
{{ i18n.t('no3Nh4LowFixWarning') }}
{{ i18n.t('no3Nh4LowWhenToAct') }}
{{ i18n.t('no3Nh4WhenVeryHigh') }}
{{ i18n.t('no3Nh4VeryHighNote') }}
{{ i18n.t('no3Nh4VeryHighSymptoms') }}
{{ i18n.t('no3Nh4VeryHighSymptom1') }}
{{ i18n.t('no3Nh4VeryHighSymptom2') }}
{{ i18n.t('no3Nh4VeryHighSymptom3') }}
{{ i18n.t('no3Nh4VeryHighCauses') }}
{{ i18n.t('no3Nh4VeryHighCause1') }}
{{ i18n.t('no3Nh4VeryHighFixes') }}
{{ i18n.t('no3Nh4VeryHighFix1') }}
{{ i18n.t('no3Nh4VeryHighFix2') }}
{{ i18n.t('no3Nh4VeryHighWhenToAct') }}
{{ i18n.t('no3Nh4CommonMistakes') }}
{{ i18n.t('no3Nh4Mistake1Title') }}
{{ i18n.t('no3Nh4Mistake1Why') }}
{{ i18n.t('no3Nh4Mistake2Title') }}
{{ i18n.t('no3Nh4Mistake2Why') }}
{{ i18n.t('no3Nh4Mistake3Title') }}
{{ i18n.t('no3Nh4Mistake3Why') }}
{{ i18n.t('no3Nh4TimingTitle') }}
{{ i18n.t('no3Nh4PreferNitrate') }}
{{ i18n.t('no3Nh4PreferNitrate1') }}
{{ i18n.t('no3Nh4PreferNitrate2') }}
{{ i18n.t('no3Nh4PreferNitrate3') }}
{{ i18n.t('no3Nh4AllowNh4') }}
{{ i18n.t('no3Nh4AllowNh41') }}
{{ i18n.t('no3Nh4AllowNh42') }}
{{ i18n.t('no3Nh4AllowNh43') }}
{{ i18n.t('no3Nh4RealityCheck') }}
{{ i18n.t('no3Nh4RealityCheckText') }}
{{ i18n.t('no3Nh4RealityCheck1') }}
{{ i18n.t('no3Nh4RealityCheck2') }}
{{ i18n.t('no3Nh4RealityCheck3') }}
{{ i18n.t('no3Nh4RealityCheck4') }}
{{ i18n.t('no3Nh4RealityCheckConclusion') }}
{{ i18n.t('whatIsNKRatio') }}
{{ i18n.t('nkYourCurrentRatio') }}
{{ i18n.formatNumber(modalData.nkRatio?.toFixed(2) || '0') }} : 1
{{ modalData.nkStatus.text }}
{{ i18n.t('nkOptimalRange') }}
{{ i18n.t('nkContextualWarning') }}
{{ i18n.t('nkThresholdsTitle') }}
{{ i18n.t('nkThreshold1') }}
{{ i18n.t('nkThreshold2') }}
{{ i18n.t('nkThreshold3') }}
{{ i18n.t('nkThreshold4') }}
{{ i18n.t('nkThreshold5') }}
{{ i18n.t('nkWhenTooHigh') }}
{{ i18n.t('nkHighSymptoms') }}
{{ i18n.t('nkHighSymptom1') }}
{{ i18n.t('nkHighSymptom2') }}
{{ i18n.t('nkHighSymptom3') }}
{{ i18n.t('nkHighCauses') }}
{{ i18n.t('nkHighCause1') }}
{{ i18n.t('nkHighCause2') }}
{{ i18n.t('nkHighFixes') }}
{{ i18n.t('nkHighFixWarning') }}
{{ i18n.t('nkHighWhenToAct') }}
{{ i18n.t('nkWhenTooLow') }}
{{ i18n.t('nkLowSymptoms') }}
{{ i18n.t('nkLowSymptom1') }}
{{ i18n.t('nkLowSymptom2') }}
{{ i18n.t('nkLowSymptom3') }}
{{ i18n.t('nkLowSymptom4') }}
{{ i18n.t('nkLowCauses') }}
{{ i18n.t('nkLowCause1') }}
{{ i18n.t('nkLowCause2') }}
{{ i18n.t('nkLowFixes') }}
{{ i18n.t('nkLowFix3') }}
{{ i18n.t('nkLowFixWarning') }}
{{ i18n.t('nkLowWhenToAct') }}
{{ i18n.t('nkCommonMistakes') }}
{{ i18n.t('nkMistake1Title') }}
{{ i18n.t('nkMistake1Why') }}
{{ i18n.t('nkMistake2Title') }}
{{ i18n.t('nkMistake2Why') }}
{{ i18n.t('nkMistake3Title') }}
{{ i18n.t('nkMistake3Why') }}
{{ i18n.t('nkTimingTitle') }}
{{ i18n.t('nkPreferHigherNK') }}
{{ i18n.t('nkPreferHigherNK1') }}
{{ i18n.t('nkPreferHigherNK2') }}
{{ i18n.t('nkPreferHigherNK3') }}
{{ i18n.t('nkPreferLowerNK') }}
{{ i18n.t('nkPreferLowerNK1') }}
{{ i18n.t('nkPreferLowerNK2') }}
{{ i18n.t('nkPreferLowerNK3') }}
{{ i18n.t('nkRealityCheck') }}
{{ i18n.t('nkRealityCheckText') }}
{{ i18n.t('nkRealityCheck1') }}
{{ i18n.t('nkRealityCheck2') }}
{{ i18n.t('nkRealityCheck3') }}
{{ i18n.t('nkRealityCheck4') }}
{{ i18n.t('nkRealityCheckConclusion') }}
{{ i18n.t('whatIsCaMgRatio') }}
{{ i18n.t('caMgYourCurrentRatio') }}
{{ i18n.formatNumber(modalData.caMgRatio?.toFixed(2) || '0') }} : 1
{{ modalData.caMgStatus.text }}
{{ i18n.t('caMgOptimalRange') }}
{{ i18n.t('caMgContextualWarning') }}
{{ i18n.t('caMgThresholdsTitle') }}
{{ i18n.t('caMgThreshold1') }}
{{ i18n.t('caMgThreshold2') }}
{{ i18n.t('caMgThreshold3') }}
{{ i18n.t('caMgThreshold4') }}
{{ i18n.t('caMgWhenTooHigh') }}
{{ i18n.t('caMgHighSymptoms') }}
{{ i18n.t('caMgHighSymptom1') }}
{{ i18n.t('caMgHighSymptom2') }}
{{ i18n.t('caMgHighSymptom3') }}
{{ i18n.t('caMgHighCauses') }}
{{ i18n.t('caMgHighCause1') }}
{{ i18n.t('caMgHighCause2') }}
{{ i18n.t('caMgHighCause3') }}
{{ i18n.t('caMgHighFixes') }}
{{ i18n.t('caMgHighFix2') }}
{{ i18n.t('caMgHighFixWarning') }}
{{ i18n.t('caMgHighWhenToAct') }}
{{ i18n.t('caMgWhenTooLow') }}
{{ i18n.t('caMgLowSymptoms') }}
{{ i18n.t('caMgLowSymptom1') }}
{{ i18n.t('caMgLowSymptom2') }}
{{ i18n.t('caMgLowSymptom3') }}
{{ i18n.t('caMgLowSymptom4') }}
{{ i18n.t('caMgLowCauses') }}
{{ i18n.t('caMgLowCause1') }}
{{ i18n.t('caMgLowCause2') }}
{{ i18n.t('caMgLowCause3') }}
{{ i18n.t('caMgLowFixes') }}
{{ i18n.t('caMgLowFix1') }}
{{ i18n.t('caMgLowFix3') }}
{{ i18n.t('caMgLowFixWarning') }}
{{ i18n.t('caMgLowWhenToAct') }}
{{ i18n.t('caMgCommonMistakes') }}
{{ i18n.t('caMgMistake1Title') }}
{{ i18n.t('caMgMistake1Text') }}
{{ i18n.t('caMgMistake2Title') }}
{{ i18n.t('caMgMistake2Text') }}
{{ i18n.t('caMgMistake3Title') }}
{{ i18n.t('caMgMistake3Text') }}
{{ i18n.t('caMgTiming') }}
{{ i18n.t('caMgTimingCa') }}
{{ i18n.t('caMgTimingMg') }}
{{ i18n.t('caMgOneLiner') }}
{{ i18n.t('whatIsBoronLevel') }}
{{ i18n.t('boronYourCurrentLevel') }}
{{ i18n.formatNumber(modalData.boronPpm?.toFixed(2) || '0') }} ppm
{{ modalData.boronStatus.text }}
{{ i18n.t('boronTargetRange') }}
{{ i18n.t('boronThresholdsTitle') }}
{{ i18n.t('boronThreshold1') }}
{{ i18n.t('boronThreshold2') }}
{{ i18n.t('boronThreshold3') }}
{{ i18n.t('boronThreshold4') }}
{{ i18n.t('boronToxicityTitle') }}
{{ i18n.t('boronToxicitySymptom1') }}
{{ i18n.t('boronToxicitySymptom2') }}
{{ i18n.t('boronToxicitySymptom3') }}
{{ i18n.t('boronToxicitySymptom4') }}
{{ i18n.t('boronCausesTitle') }}
{{ i18n.t('boronCause1') }}
{{ i18n.t('boronCause2') }}
{{ i18n.t('boronCause3') }}
{{ i18n.t('boronCause4') }}
{{ i18n.t('boronFixesTitle') }}
{{ i18n.t('boronFix1') }}
{{ i18n.t('boronFix2') }}
{{ i18n.t('boronFix3') }}
{{ i18n.t('boronFix4') }}
{{ i18n.t('boronRecirculatingTitle') }}
{{ i18n.t('boronRecirculatingText') }}
{{ i18n.t('boronResearchNote') }}
Fertilizer Calculator
Language
English
ગુજરાતી (Gujarati)
हिन्दी (Hindi)
ಕನ್ನಡ (Kannada)
తెలుగు (Telugu)
मराठी (Marathi)
বাংলা - সাধু (Bengali Sadhu)
বাংলা - চলিত (Bengali Cholito)
தமிழ் (Tamil)
മലയാളം (Malayalam)
ਪੰਜਾਬੀ (Punjabi)
ଓଡ଼ିଆ (Odia)
অসমীয়া (Assamese)
भोजपुरी (Bhojpuri)
मैथिली (Maithili)
अवधी (Awadhi)
What would you like to do?
Choose a calculator mode based on what information you have.
Grams → PPM
Calculate what nutrient concentrations (PPM) you'll get from specific amounts of fertilizers.
Best for:
You have fertilizers weighed out and want to know the resulting nutrient levels in your solution.
PPM → Grams
Enter your target PPM values and get the exact fertilizer amounts needed to achieve them.
Best for:
You have specific PPM targets (e.g., from a recipe or plant requirements) and need to know how much of each fertilizer to use.
NPK Ratio → Grams
Enter nutrient ratios (like 3-1-2) and a target EC to get fertilizer amounts that match your desired balance.
Best for:
You know the nutrient ratio you want (e.g., for a specific growth stage) and want to scale it to your desired EC/strength.
Acidify Mix with PeKacid
Introduce PeKacid into your existing fertilizer mix for acidification, while keeping nutrient levels balanced.
Best for:
You have a recipe and want to add PeKacid for pH control while maintaining the same nutrient profile.
Stock Solution Maker
Create concentrated A/B stock solutions with dosing instructions for multiple target ratios and EC levels.
Best for:
You want to pre-mix concentrated stock solutions that can serve multiple growth stages by varying the dosing amounts.
{{ getStepIndicator('volume-step') }}
How much solution are you making?
Enter the total volume of water you'll be mixing your fertilizers into.
liters
Continue →
← Back
{{ getStepIndicator('calc-mode-step') }}
How do you want to enter values?
Choose between commercial fertilizer notation or pure elemental values.
Continue →
← Back
{{ getStepIndicator('ec-step') }}
What strength solution do you want?
Choose the EC (electrical conductivity) you want the mix to reach. It tells us how concentrated the nutrients should be, and we'll scale the fertilizer amounts to hit that strength for your batch.
0.2 mS/cm - Plain Water Supplement
0.4 mS/cm - Recovery/Flush
0.6 mS/cm - Fresh Clones/Cuttings
0.8 mS/cm - Rooted Cuttings
1.0 mS/cm - Seedlings/Young Plants
1.2 mS/cm - General Purpose
1.5 mS/cm - Vegetative Growth
1.8 mS/cm - Active Growth
2.0 mS/cm - Heavy Feeders
2.5 mS/cm - Flowering/Fruiting
3.0 mS/cm - Maximum (experienced growers)
{{ wizardECDescription }}
Continue →
← Back
{{ fert.index }}. {{ i18n.getFertilizerName(fert) }}
{{ fert.composition }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(gramsToPpmDisplayData.fertilizers.length) }) }}
{{ i18n.formatNumber(gramsToPpmDisplayData.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.formatNumber((gramsToPpmDisplayData.totalGrams / gramsToPpmDisplayData.volume).toFixed(3)) }} {{ i18n.t('gramsPerLiter') }}
({{ i18n.t('totalConcentration') }})
{{ i18n.t('resultsPpm') }}
?
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.imbalance.toFixed(1)) }}%
{{ gramsToPpmDisplayData.ionBalance.statusText }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.boronWarning.ppm.toFixed(2)) }} ppm
{{ gramsToPpmDisplayData.boronWarning.text }}
{{ i18n.t('achievedEc') }} ?
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ gramsToPpmDisplayData.ecPrediction.text }}
{{ i18n.t('ionicStrength') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ionicStrength.toFixed(4)) }} mol/L
{{ i18n.t('warningsAndRecommendations') }}
{{ warning.level === 'warning' ? '⚠️' : warning.level === 'error' ? '❌' : 'ℹ️' }} {{ warning.category }}
{{ warning.message }}
{{ i18n.getFertilizerName(fert) }}
{{ fert.composition }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(formulaResultsData.fertilizers.length) }) }}
{{ i18n.formatNumber(formulaResultsData.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.formatNumber((formulaResultsData.totalGrams / formulaResultsData.volume).toFixed(3)) }} {{ i18n.t('gramsPerLiter') }}
({{ i18n.t('totalConcentration') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsDescription') }}
{{ i18n.t('targetVsAchieved') || 'Target vs Achieved' }}
{{ item.label }}
{{ i18n.formatNumber((item.achieved || 0).toFixed(2)) }} {{ item.status }}
{{ i18n.t('targetLabel') || 'Target:' }} {{ i18n.formatNumber(item.target.toFixed(2)) }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(formulaResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(formulaResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(formulaResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ formulaResultsData.ionBalance.statusText }}
{{ i18n.t('predictedEc') }} ?
{{ i18n.formatNumber(formulaResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ formulaResultsData.ecPrediction.text }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(formulaResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ formulaResultsData.boronWarning.text }}
{{ i18n.t('warningsAndRecommendations') }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
{{ i18n.getFertilizerName(fert) }}
{{ fert.composition }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(reverseResultsData.fertilizers.length) }) }}
{{ i18n.formatNumber(reverseResultsData.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.formatNumber((reverseResultsData.totalGrams / reverseResultsData.volume).toFixed(3)) }} {{ i18n.t('gramsPerLiter') }}
({{ i18n.t('totalConcentration') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsDescription') }}
{{ i18n.t('targetVsAchievedRatios') || 'Achieved PPM' }}
{{ item.label }}
{{ i18n.formatNumber((item.achievedPPM || 0).toFixed(2)) }} {{ item.status }}
{{ i18n.t('ratioLabel') || 'Ratio:' }} {{ item.userInput }} → {{ i18n.formatNumber((item.achievedRatio || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormLabel') }}
{{ i18n.formatNumber(reverseResultsData.result.achieved.N_NH4.toFixed(1)) }} ppm NH₄-N
({{ i18n.formatNumber(reverseResultsData.nh4Percent.toFixed(1)) }}% {{ i18n.t('ofTotalN') }}),
{{ i18n.formatNumber(reverseResultsData.result.achieved.N_NO3.toFixed(1)) }} ppm NO₃-N
({{ i18n.formatNumber((100 - reverseResultsData.nh4Percent).toFixed(1)) }}% {{ i18n.t('ofTotalN') }})
, {{ i18n.formatNumber(reverseResultsData.result.achieved.N_Urea.toFixed(1)) }} ppm {{ i18n.t('ureaN') || 'Urea-N' }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(reverseResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ reverseResultsData.ionBalance.statusText }}
{{ i18n.t('estimatedEC') }} ?
{{ i18n.formatNumber(reverseResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ reverseResultsData.ecPrediction.text }}
{{ i18n.t('targetEC') }}
{{ i18n.formatNumber(reverseResultsData.ecPrediction.targetEC) }} mS/cm
{{ i18n.t('scaledToMatch') }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(reverseResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ reverseResultsData.boronWarning.text }}
{{ i18n.t('warningsAndRecommendations') }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
{{ i18n.t('stockSettings') || 'Stock Solution Settings' }}
{{ i18n.t('concentration') || 'Concentration' }}: {{ stockResultsData.settings?.concentrationFactor }}×
{{ i18n.t('tankVolume') || 'Tank Volume' }}: {{ stockResultsData.settings?.tankVolume }} L
{{ i18n.t('baselineEC') || 'Baseline EC' }}: {{ stockResultsData.settings?.baselineEC }} mS/cm
{{ i18n.t('maxDosing') || 'Max Dosing' }}: {{ stockResultsData.settings?.maxDosing }} mL/L
{{ tank.name || ('Tank ' + String.fromCharCode(65 + tankIdx)) }}
({{ tank.description || '' }})
{{ i18n.getFertilizerName(fert) || fert.name }}
{{ i18n.formatNumber(fert.gPerL.toFixed(2)) }} g/L
({{ i18n.formatNumber((fert.gPerL * stockResultsData.settings?.tankVolume).toFixed(1)) }} g total)
{{ i18n.t('total') || 'Total' }}
{{ i18n.formatNumber(tank.fertilizers.reduce((sum, f) => sum + f.gPerL, 0).toFixed(2)) }} g/L
⚠️ {{ i18n.t('nearSolubilityLimit') || 'Near Solubility Limit' }}
{{ i18n.t('nearSolubilityLimitDesc') || 'Some fertilizers are near their solubility limit. Ensure complete dissolution.' }}
{{ i18n.t('dosingInstructions') || 'Dosing Instructions' }}
{{ i18n.t('dosingInstructionsDesc') || 'Add these amounts of each stock to your reservoir per liter of final solution:' }}
{{ i18n.t('target') || 'Target' }}
{{ i18n.t('targetEC') || 'EC' }}
{{ tank.name || ('Tank ' + String.fromCharCode(65 + idx)) }}
{{ dosing.targetName }}
{{ dosing.ratio }}
{{ dosing.ec }} mS/cm
{{ i18n.formatNumber((dose || 0).toFixed(2)) }} mL/L
{{ i18n.t('targetResults') || 'Target Results' }}
{{ dosing.targetName }}
{{ i18n.t('targetECLabel') || 'Target EC' }}: {{ dosing.ec }} mS/cm
{{ i18n.t('achievedEC') || 'Achieved' }}: {{ i18n.formatNumber((dosing.predicted.EC || 0).toFixed(2)) }} mS/cm
{{ Math.abs(dosing.predicted.EC - dosing.ec) / dosing.ec < 0.05 ? '✓' : '~' }}
{{ i18n.t('achievedNutrients') || 'Achieved Nutrients' }} (ppm):
{{ nutrient }}
{{ i18n.formatNumber((dosing.predicted.nutrients[nutrient] || 0).toFixed(1)) }}
ratio: {{ dosing.predicted.ratio[nutrient] }}
{{ i18n.t('ionBalance') || 'Ion Balance' }}:
+ {{ i18n.formatNumber((dosing.predicted.ionBalance.cations || 0).toFixed(2)) }} meq/L
vs
− {{ i18n.formatNumber((dosing.predicted.ionBalance.anions || 0).toFixed(2)) }} meq/L
{{ i18n.t('imbalance') || 'Imbalance' }}: {{ i18n.formatNumber((dosing.predicted.ionBalance.imbalance || 0).toFixed(1)) }}%
{{ warning.level === 'warning' ? '⚠️' : warning.level === 'error' ? '❌' : 'ℹ️' }}
{{ warning.message }}
{{ nutrient }}:
target ratio {{ i18n.formatNumber((err.target || 0).toFixed(2)) }} →
achieved {{ i18n.formatNumber((err.achieved || 0).toFixed(2)) }}
({{ i18n.formatNumber(((err.error || 0) * 100).toFixed(1)) }}% off)
Required: {{ i18n.formatNumber((warning.details.required || 0).toFixed(1)) }} mL/L,
Max allowed: {{ i18n.formatNumber((warning.details.max || 0).toFixed(1)) }} mL/L
Target: {{ i18n.formatNumber((warning.details.target || 0).toFixed(2)) }} mS/cm,
Predicted: {{ i18n.formatNumber((warning.details.predicted || 0).toFixed(2)) }} mS/cm
{{ i18n.t('warningsAndRecommendations') }}
{{ warning.level === 'warning' ? '⚠️' : warning.level === 'error' ? '❌' : 'ℹ️' }} {{ warning.category }}
{{ warning.message }}
{{ nutrient }}:
target ratio {{ i18n.formatNumber((err.target || 0).toFixed(2)) }} →
achieved {{ i18n.formatNumber((err.achieved || 0).toFixed(2)) }}
({{ i18n.formatNumber(((err.error || 0) * 100).toFixed(1)) }}% off)
Required: {{ i18n.formatNumber((warning.details.required_gL || 0).toFixed(1)) }} g/L,
Max solubility: {{ i18n.formatNumber((warning.details.max_gL || 0).toFixed(0)) }} g/L
{{ i18n.t('acidifySuccessMessage') || 'Success! Your recipe has been adjusted to include PeKacid while maintaining nutrient balance.' }}
{{ i18n.t('acidifyNutrientChangeWarning') || 'Note: Other nutrients changed' }}
{{ i18n.t('acidifyNutrientChangeDetails', { changes: acidifyResultsData.nutrientChangesText }) || ('Reducing fertilizers to compensate for PeKacid also affected: ' + acidifyResultsData.nutrientChangesText + '. This is expected because those fertilizers provided multiple nutrients.') }}
{{ i18n.t('acidifyBeforeTitle') || 'Original Recipe' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('total') || 'Total' }}
{{ i18n.formatNumber(acidifyResultsData.beforeTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('acidifyAfterTitle') || 'With PeKacid' }}
{{ i18n.getFertilizerName(fert) }}{{ fert.id === 'icl_pekacid_pk_acid' ? ' ✓' : '' }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}{{ fert.adjustment ? ' (' + (fert.adjustment > 0 ? '+' : '') + i18n.formatNumber(fert.adjustment.toFixed(2)) + ')' : '' }}
{{ i18n.t('total') || 'Total' }}
{{ i18n.formatNumber(acidifyResultsData.afterTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('acidifyAdjustmentsTitle') || 'Adjustments Made' }}
{{ i18n.getFertilizerName(adj) }}:
{{ i18n.formatNumber(adj.originalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }} →
{{ i18n.formatNumber(adj.newGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
({{ adj.reduction > 0 ? '-' : '+' }}{{ i18n.formatNumber(Math.abs(adj.reduction).toFixed(2)) }} {{ i18n.t('gramsShort') }})
{{ i18n.t('acidifyPpmComparisonTitle') || 'Nutrient Levels (PPM)' }}
{{ i18n.t('acidifyPpmComparisonDesc') || 'Values should remain the same before and after PeKacid addition.' }}
{{ item.label }}
{{ i18n.t('before') || 'Before' }}: {{ i18n.formatNumber(item.before.toFixed(1)) }}
{{ i18n.t('after') || 'After' }}: {{ i18n.formatNumber(item.after.toFixed(1)) }}
{{ i18n.t('diffLabel') || 'Diff' }}: {{ item.diff > 0 ? '+' : '' }}{{ i18n.formatNumber(item.diff.toFixed(1)) }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(acidifyResultsData.afterIonBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(acidifyResultsData.afterIonBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(acidifyResultsData.afterIonBalance.imbalance.toFixed(1)) }}%
{{ acidifyResultsData.afterIonBalance.statusText }}
{{ i18n.t('achievedEc') }} ?
{{ i18n.formatNumber(acidifyResultsData.afterEcPrediction.ec.toFixed(2)) }}
mS/cm
{{ acidifyResultsData.afterEcPrediction.text }}
{{ acidifyResultsData.failureReason || i18n.t('acidifyFailedMessage') || 'Cannot maintain the same nutrient profile with the requested PeKacid amount.' }}
{{ i18n.t('acidifyWhyFailed') || 'Why did this fail?' }}
{{ acidifyResultsData.failureDetails || i18n.t('acidifyFailedExplanation') || 'The PeKacid amount requested would add more P or K than can be compensated by reducing other fertilizers in your mix. Your recipe may not have enough P or K sources to reduce.' }}
{{ i18n.t('acidifySuggestions') || 'Suggestions' }}
{{ i18n.t('acidifySuggestion1') || 'Try a smaller amount of PeKacid' }}
{{ i18n.t('acidifySuggestion2') || 'Add more P or K sources to your original recipe' }}
{{ i18n.t('acidifySuggestion3') || 'Use the PPM to Grams calculator to build a new recipe with PeKacid included' }}
{{ i18n.t('acidifyOriginalRecipe') || 'Your Original Recipe' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('twoTankStockSolutionSystem') }}
{{ copiedButtonId === 'two-tank' ? i18n.t('copied') || 'Copied!' : i18n.t('copyResults') }}
{{ i18n.t('backToNormalView') || 'Back to Normal View' }}
{{ i18n.t('twoTankSeparationNote') }}
{{ twoTankDisplayData.tankA.name }}
{{ twoTankDisplayData.tankA.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankA.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ fert.name }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.P : twoTankDisplayData.tankA.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.K : twoTankDisplayData.tankA.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }}
{{ i18n.t('ppmHeader') }}
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.target.label }) }}
{{ twoTankDisplayData.tankA.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankA.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.kLabel }}:Ca
?
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.status.text }}
{{ twoTankDisplayData.tankB.name }}
{{ twoTankDisplayData.tankB.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankB.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ fert.name }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.P : twoTankDisplayData.tankB.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.K : twoTankDisplayData.tankB.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }}
{{ i18n.t('ppmHeader') }}
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.target.label }) }}
{{ twoTankDisplayData.tankB.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankB.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.kLabel }}:Ca
?
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.status.text }}
{{ i18n.t('combinedSolutionWhenMixed') }}
{{ i18n.t('combinedSolutionDescription') }}
{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }})
{{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
(Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
{{ i18n.t('targetVsAchieved') || 'Target vs Achieved' }}
{{ item.label }}
{{ i18n.formatNumber((item.achieved || 0).toFixed(2)) }} {{ item.status }}
{{ i18n.t('targetLabel') || 'Target:' }} {{ i18n.formatNumber(item.target.toFixed(2)) }}
{{ i18n.t('targetVsAchievedRatios') || 'Achieved PPM' }} ?
{{ item.label }}
{{ i18n.formatNumber((item.achievedPPM || 0).toFixed(2)) }} {{ item.status }}
{{ i18n.t('ratioLabel') || 'Ratio:' }} {{ item.userInput }} → {{ i18n.formatNumber((item.achievedRatio || 0).toFixed(2)) }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(formulaResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(formulaResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(formulaResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ formulaResultsData.ionBalance.statusText }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(reverseResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ reverseResultsData.ionBalance.statusText }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.imbalance.toFixed(1)) }}%
{{ gramsToPpmDisplayData.ionBalance.statusText }}
{{ i18n.t('predictedEc') }} ?
{{ i18n.formatNumber(formulaResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ formulaResultsData.ecPrediction.text }}
{{ i18n.t('estimatedEC') }} ?
{{ i18n.formatNumber(reverseResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ reverseResultsData.ecPrediction.text }}
{{ i18n.t('targetEcLabel') }}
{{ i18n.formatNumber(reverseResultsData.ecPrediction.targetEC) }} mS/cm
{{ i18n.t('scaledToMatch') }}
{{ i18n.t('predictedEc') }} ?
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ gramsToPpmDisplayData.ecPrediction.text }}
{{ i18n.t('ionicStrength') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ionicStrength.toFixed(4)) }} mol/L
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(formulaResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ formulaResultsData.boronWarning.text }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(reverseResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ reverseResultsData.boronWarning.text }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.boronWarning.ppm.toFixed(2)) }} ppm
{{ gramsToPpmDisplayData.boronWarning.text }}
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsDescription') }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsDescription') }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
{{ i18n.t('warningsAndRecommendations') }}
{{ warning.category }}: {{ warning.message }}
{{ devLogsExpanded ? '▼' : '▶' }}
Developer Logs ({{ devLogs.length }})
Clear
Copy All
No logs yet. Run a calculation to see logs.
{{ log.time }}
{{ log.message }}
{{ fert.index }}. {{ i18n.getFertilizerName(fert) }}
{{ fert.composition }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(gramsToPpmDisplayData.fertilizers.length) }) }}
{{ i18n.formatNumber(gramsToPpmDisplayData.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.formatNumber((gramsToPpmDisplayData.totalGrams / gramsToPpmDisplayData.volume).toFixed(3)) }} {{ i18n.t('gramsPerLiter') }}
({{ i18n.t('totalConcentration') }})
{{ i18n.t('resultsPpm') }}
?
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
ppm
{{ i18n.t('noteLabel') }} {{ i18n.t('oxideConversionNote') }}
{{ i18n.t('ionBalance') }}
?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.imbalance.toFixed(1)) }}%
{{ gramsToPpmDisplayData.ionBalance.statusText }}
{{ i18n.t('whatIsIonBalanceQuestion') }} {{ i18n.t('ionBalanceExplanationFull') }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.boronWarning.ppm.toFixed(2)) }} ppm
{{ gramsToPpmDisplayData.boronWarning.text }}
{{ i18n.t('whatAreNutrientRatios') }} {{ i18n.t('nutrientRatioExplanationFull') }}
{{ i18n.t('achievedEc') }} ?
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ gramsToPpmDisplayData.ecPrediction.text }}
{{ i18n.t('ionicStrength') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ionicStrength.toFixed(4)) }} mol/L
{{ i18n.t('warningsAndRecommendations') }}
{{ warning.level === 'warning' ? '⚠️' : warning.level === 'error' ? '❌' : 'ℹ️' }} {{ warning.category }}
{{ warning.message }}
{{ i18n.t('twoTankStockSolutionSystem') }}
{{ copiedButtonId === 'two-tank' ? i18n.t('copied') || 'Copied!' : i18n.t('copyResults') }}
{{ i18n.t('backToNormalView') || 'Back to Normal View' }}
{{ i18n.t('twoTankSeparationNote') }}
{{ twoTankDisplayData.tankA.name }}
{{ twoTankDisplayData.tankA.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankA.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.P : twoTankDisplayData.tankA.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.K : twoTankDisplayData.tankA.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }}
{{ i18n.t('ppmHeader') }}
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.target.label }) }}
{{ twoTankDisplayData.tankA.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankA.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.kLabel }}:Ca
?
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.status.text }}
{{ twoTankDisplayData.tankB.name }}
{{ twoTankDisplayData.tankB.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankB.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.P : twoTankDisplayData.tankB.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.K : twoTankDisplayData.tankB.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }}
{{ i18n.t('ppmHeader') }}
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.target.label }) }}
{{ twoTankDisplayData.tankB.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankB.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.kLabel }}:Ca
?
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.status.text }}
{{ i18n.t('combinedSolutionWhenMixed') }}
{{ i18n.t('combinedSolutionDescription') }}
{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }})
{{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
(Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
{{ i18n.t('warningsAndRecommendations') }}
{{ warning.category }}: {{ warning.message }}
{{ i18n.t('twoTankStockSolutionSystem') }}
{{ copiedButtonId === 'two-tank' ? i18n.t('copied') || 'Copied!' : i18n.t('copyResults') }}
{{ i18n.t('backToNormalView') || 'Back to Normal View' }}
{{ i18n.t('twoTankSeparationNote') }}
{{ twoTankDisplayData.tankA.name }}
{{ twoTankDisplayData.tankA.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankA.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}
{{ twoTankDisplayData.tankB.name }}
{{ twoTankDisplayData.tankB.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankB.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('combinedSolutionWhenMixed') }}
{{ i18n.t('combinedSolutionDescription') }}
{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }})
{{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
(Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsDescription') }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsConsider') }}
{{ i18n.t('considerSelectingAdditionalFertilizers') }}
{{ i18n.t('considerAdjustingTargetValues') }}
{{ i18n.t('considerAcceptingDeviations') }}
✓ {{ i18n.t('targetsSuccessfullyAchieved') }}
{{ i18n.t('allNutrientValuesWithinRange') }}
{{ i18n.t('targetVsAchievedRatios') }} ?
{{ i18n.t('nutrient') }}
{{ i18n.t('yourInput') }}
{{ i18n.t('achievedRatio') }}
{{ i18n.t('ppmAchieved') }}
{{ item.label }}
{{ i18n.t('ppmLabel') }}
{{ i18n.formatNumber(Number(item.userInput || 0).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.formatNumber(Number(item.userInput || 0).toFixed(2)) }}
{{ i18n.formatNumber(Number(item.achievedRatio || 0).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ item.status }}
{{ i18n.formatNumber(Number(item.achievedRatio || 0).toFixed(2)) }} {{ item.status }}
{{ i18n.formatNumber(Number(item.achievedPPM || 0).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('elementalModeLabel') }} {{ i18n.t('elementalModeNote') }}
{{ i18n.t('elementalToOxideConversion') }}
{{ i18n.t('oxideModeLabel') }} {{ i18n.t('oxideModeNote') }}
{{ i18n.t('oxideToElementalConversion') }}
{{ i18n.t('nitrogenFormLabel') }}
{{ i18n.formatNumber(reverseResultsData.result.achieved.N_NH4.toFixed(1)) }} ppm NH₄-N
({{ i18n.formatNumber(reverseResultsData.nh4Percent.toFixed(1)) }}% {{ i18n.t('ofTotalN') }}),
{{ i18n.formatNumber(reverseResultsData.result.achieved.N_NO3.toFixed(1)) }} ppm NO₃-N
({{ i18n.formatNumber((100 - reverseResultsData.nh4Percent).toFixed(1)) }}% {{ i18n.t('ofTotalN') }})
{{ i18n.t('ionBalance') }} ?
{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(reverseResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ reverseResultsData.ionBalance.statusText }}
{{ i18n.t('estimatedEC') }}
{{ i18n.formatNumber(reverseResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ reverseResultsData.ecPrediction.text }}
{{ i18n.t('targetEC') }}
{{ i18n.formatNumber(reverseResultsData.ecPrediction.targetEC) }} mS/cm
{{ i18n.t('scaledToMatch') }}
{{ i18n.t('nutrientRatioAnalysis') }}
?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(reverseResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ reverseResultsData.boronWarning.text }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
{{ i18n.t('twoTankStockSolutionSystem') }}
{{ copiedButtonId === 'two-tank' ? i18n.t('copied') || 'Copied!' : i18n.t('copyResults') }}
{{ i18n.t('backToNormalView') || 'Back to Normal View' }}
{{ i18n.t('twoTankSeparationNote') }}
{{ twoTankDisplayData.tankA.name }}
{{ twoTankDisplayData.tankA.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankA.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.P : twoTankDisplayData.tankA.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.K : twoTankDisplayData.tankA.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }}
{{ i18n.t('ppmHeader') }}
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.target.label }) }}
{{ twoTankDisplayData.tankA.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankA.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.kLabel }}:Ca
?
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.status.text }}
{{ twoTankDisplayData.tankB.name }}
{{ twoTankDisplayData.tankB.detailsExpanded ? (i18n.t('hideDetails') || 'Hide Details') : (i18n.t('showDetails') || 'Show Details') }}
{{ twoTankDisplayData.tankB.description }}
{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }}
{{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.P : twoTankDisplayData.tankB.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.K : twoTankDisplayData.tankB.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }}
{{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }}
{{ i18n.t('ppmHeader') }}
{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.target.label }) }}
{{ twoTankDisplayData.tankB.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankB.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.kLabel }}:Ca
?
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.status.text }}
{{ i18n.t('combinedSolutionWhenMixed') }}
{{ i18n.t('combinedSolutionDescription') }}
{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }})
{{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
(Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
{{ i18n.t('cannotAchieveExactTargetsDescription') }}
{{ i18n.t('nutritionalConsiderations') }}
{{ warning.category }}: {{ warning.message }}
v1.7.0