{
  "schemaVersion": 1,
  "slug": "passport-renewal-timeline-calculator",
  "category": "travel",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "d42b43175734538d54c128bfaa3d0183393b523b5fb52d469b0e844ad43f6041",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/passport-renewal-timeline-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_apply = D_t − P − 2 × m − B",
    "vars": [
      [
        "D_t",
        "Travel or destination-exit date"
      ],
      [
        "P",
        "Processing estimate (calendar days)"
      ],
      [
        "m",
        "Mailing days each way (calendar days)"
      ],
      [
        "B",
        "User-selected buffer (calendar days)"
      ],
      [
        "D_apply",
        "Suggested application date"
      ]
    ],
    "note": "Suggested latest application date = travel/departure date − processing days − 2 × mailing days − user buffer. Uses calendar dates, not official deadlines; years 1–99 are parsed as written."
  },
  "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"
      },
      {
        "name": "U.S. Department of State — Passport Agency Appointments",
        "url": "https://travel.state.gov/en/passports/apply/get-fast/make-appointment.html"
      }
    ]
  },
  "contract": {
    "compute": "const utc=(y,m,day)=>{const x=new Date(0);x.setUTCHours(0,0,0,0);x.setUTCFullYear(y,m,day);return x;},parse=s=>{const m=/^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(String(s));if(!m)return null;const y=+m[1],mo=+m[2]-1,day=+m[3],d=utc(y,mo,day);return d.getUTCFullYear()===y&&d.getUTCMonth()===mo&&d.getUTCDate()===day?d:null;},start=parse(today),travel=parse(travelDate);if(!start||!travel||travel<start)return{__error:'inputError',latestApplyDate:null,daysUntilDeadline:null,totalLeadTimeDays:null,onTrack:null,urgency:null,advice:null};const lead=processingDays+mailDaysEachWay*2+safetyBufferDays,latest=new Date(travel.getTime()-lead*86400000),daysUntilTravel=Math.round((travel-start)/86400000),daysUntilDeadline=Math.round((latest-start)/86400000);return{latestApplyDate:latest.toISOString().slice(0,10),daysUntilDeadline,totalLeadTimeDays:lead,onTrack:start<=latest?'Within the entered planning window':'Past the entered planning window',urgency:daysUntilTravel<=14?'Travel is within 14 days':daysUntilTravel<=lead?'Start or verify the application now':'Time remains based on your inputs',advice:'Planning estimate only. Enter current processing and mailing ranges from the issuing authority; appointment availability and urgent-service rules vary.'};",
    "inputs": [
      {
        "name": "travelDate",
        "type": "date",
        "default": "@today+6m",
        "step": 1
      },
      {
        "name": "today",
        "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
      },
      {
        "name": "safetyBufferDays",
        "type": "number",
        "default": 14,
        "min": 0,
        "max": 120,
        "step": 1,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "latestApplyDate",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "daysUntilDeadline",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "totalLeadTimeDays",
        "precision": 0,
        "unit": "days"
      },
      {
        "name": "onTrack",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "urgency",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "advice",
        "precision": 0,
        "unit": "",
        "type": "text"
      }
    ],
    "interpret": null
  }
}
