{
  "schemaVersion": 1,
  "slug": "chinese-zodiac-calculator",
  "category": "party",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "8676ba196aafc4ff0412b0e319d5162535c05c32f92f9d06660ef079867c9b55",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/chinese-zodiac-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": "a = (Y − 4) mod 12;  e = ⌊((Y − 4) mod 10) ÷ 2⌋;  p ∈ {Yang, Yin};  Y ≡ 0 (mod 2) → Yang;  Y ≡ 1 (mod 2) → Yin",
    "vars": [
      [
        "Y",
        "Birth year"
      ],
      [
        "a",
        "Animal index (0 = Rat)"
      ],
      [
        "e",
        "Element index (0–4)"
      ],
      [
        "p",
        "Polarity (Yang/Yin)"
      ]
    ],
    "note": "Elements cycle Wood, Fire, Earth, Metal, Water; even years are Yang, odd years Yin."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const empty={animal:null,element:null,yinYang:null,fullSign:null,nextSameAnimal:null,cyclePosition:null};if(!Number.isInteger(year)||year<1900||year>2100)return{...empty,__error:'inputError'};const animals=['Rat','Ox','Tiger','Rabbit','Dragon','Snake','Horse','Goat','Monkey','Rooster','Dog','Pig'];const elements=['Wood','Fire','Earth','Metal','Water'];const a=((year-4)%12+12)%12;const e=Math.floor((((year-4)%10+10)%10)/2);const animal=animals[a],element=elements[e],yy=year%2===0?'Yang':'Yin';return{animal,element,yinYang:yy,fullSign:element+' '+animal,nextSameAnimal:year+12,cyclePosition:a+1};",
    "inputs": [
      {
        "name": "year",
        "type": "number",
        "default": 1990,
        "min": 1900,
        "max": 2100,
        "step": 1,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "animal",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "element",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "yinYang",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "fullSign",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "nextSameAnimal",
        "precision": 0,
        "unit": "year"
      },
      {
        "name": "cyclePosition",
        "precision": 0,
        "unit": ""
      }
    ],
    "interpret": null
  }
}
