{
  "schemaVersion": 1,
  "slug": "passport-renewal-time-calculator",
  "category": "travel",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "70635861fc276b17d296babe0b0f554ecddbbc9ad9ea796f280b92c7c634b967",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/passport-renewal-time-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": "D_delivery = D_sub + P + 2 × m",
    "vars": [
      [
        "D_sub",
        "Application submission date"
      ],
      [
        "P",
        "Processing estimate (calendar days)"
      ],
      [
        "m",
        "Mailing days each way (calendar days)"
      ],
      [
        "D_delivery",
        "Estimated delivery date"
      ]
    ],
    "note": "Estimated delivery = submission date + processing days + 2 × mailing days. Uses calendar-day arithmetic and the editable user assumptions; it does not fetch official current processing estimates, appointment availability, or delivery guarantees."
  },
  "externalEvidence": {
    "reviewedAt": "2026-09-26",
    "sources": [
      {
        "name": "U.S. Department of State — Processing Times",
        "url": "https://travel.state.gov/content/travel/en/passports/how-apply/processing-times.html"
      }
    ]
  },
  "contract": {
    "compute": "const m=/^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(String(submissionDate)),utc=(y,mo,day)=>{const x=new Date(0);x.setUTCHours(0,0,0,0);x.setUTCFullYear(y,mo,day);return x;},y=m?+m[1]:0,mo=m?+m[2]-1:0,da=m?+m[3]:0,start=m?utc(y,mo,da):null;if(!start||start.getUTCFullYear()!==y||start.getUTCMonth()!==mo||start.getUTCDate()!==da)return{__error:'inputError',effectiveProcessingDays:null,totalDays:null,expectedDeliveryDate:null,totalWeeks:null,note:null};const effective=processingDays,total=effective+mailDaysEachWay*2,deliver=new Date(start.getTime()+total*86400000);return{effectiveProcessingDays:effective,totalDays:total,expectedDeliveryDate:deliver.toISOString().slice(0,10),totalWeeks:total/7,note:'Illustrative estimate from the days entered. Official processing ranges exclude mailing, and actual times and appointment availability change; check the issuing authority.'};",
    "inputs": [
      {
        "name": "submissionDate",
        "type": "date",
        "default": "@today",
        "step": 1
      },
      {
        "name": "processingDays",
        "type": "number",
        "default": 42,
        "min": 1,
        "max": 365,
        "step": 1,
        "slider": true
      },
      {
        "name": "mailDaysEachWay",
        "type": "number",
        "default": 14,
        "min": 0,
        "max": 30,
        "step": 1,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "expectedDeliveryDate",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "totalDays",
        "precision": 1,
        "unit": "days"
      },
      {
        "name": "effectiveProcessingDays",
        "precision": 1,
        "unit": "days"
      },
      {
        "name": "totalWeeks",
        "precision": 1,
        "unit": "weeks"
      },
      {
        "name": "note",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
