{
  "schemaVersion": 1,
  "slug": "priming-sugar-calculator",
  "category": "cooking",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "e41a26fef5590c4e3736bbed14a24f26cceb7a8b18c24a3384ff510b913995f0",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/priming-sugar-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "m = V × max(T − r(t), 0) × F_i, i ∈ {1,2,3,4}; F₁ = 3.8; F₂ = 3.6; F₃ = 4.9; F₄ = 5.3",
    "vars": [
      [
        "V",
        "Beer volume (L)"
      ],
      [
        "T",
        "Target CO₂ (volumes)"
      ],
      [
        "r(t)",
        "Residual CO₂ at temperature t"
      ],
      [
        "i",
        "Sugar type index"
      ],
      [
        "F_i",
        "Factor for sugar type i"
      ],
      [
        "m",
        "Priming sugar (g)"
      ]
    ],
    "note": "r(t) is a 36-entry lookup for 0–35 °C (1.70 down to 0.56), index clamped. F₁ corn sugar = 3.8, F₂ table sugar = 3.6, F₃ DME = 4.9, F₄ honey = 5.3. Cups = m ÷ 200; sugar per litre = max(T − r, 0) × F_i."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const chart = [1.70,1.65,1.60,1.55,1.50,1.45,1.40,1.35,1.30,1.25,1.20,1.16,1.12,1.08,1.05,1.02,0.99,0.96,0.93,0.91,0.88,0.86,0.83,0.81,0.78,0.76,0.74,0.72,0.70,0.68,0.66,0.64,0.62,0.60,0.58,0.56]; const idx = Math.min(Math.max(Math.round(tempC),0), chart.length-1); const residual = chart[idx]; const need = Math.max(targetVolumes - residual, 0); const F = { corn:3.8, table:3.6, dme:4.9, honey:5.3 }; const perL = need*(F[sugarType]||3.8); return { sugarGrams: perL*volumeLitres, sugarPerLitre: perL, residualCO2: residual, sugarCups: perL*volumeLitres/200 };",
    "inputs": [
      {
        "name": "volumeLitres",
        "type": "number",
        "default": 20,
        "min": 0,
        "max": 1000,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "targetVolumes",
        "type": "number",
        "default": 2.4,
        "min": 1,
        "max": 5,
        "step": 0.1,
        "slider": true
      },
      {
        "name": "tempC",
        "type": "number",
        "default": 20,
        "min": 0,
        "max": 35,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "sugarType",
        "type": "select",
        "default": "corn",
        "options": [
          {
            "value": "corn"
          },
          {
            "value": "table"
          },
          {
            "value": "dme"
          },
          {
            "value": "honey"
          }
        ]
      }
    ],
    "outputs": [
      {
        "name": "sugarGrams",
        "precision": 1,
        "unit": "g"
      },
      {
        "name": "sugarPerLitre",
        "precision": 2,
        "unit": "g/L"
      },
      {
        "name": "residualCO2",
        "precision": 2,
        "unit": "vol"
      },
      {
        "name": "sugarCups",
        "precision": 3,
        "unit": "cups"
      }
    ],
    "interpret": null
  }
}
