{
  "method": {
    "corpus": "GovDocs1, the same 4,840 extracted PDFs as the metadata, redaction and split studies",
    "sampleRule": "every file with 3 to 40 pages and at most 3 MB (no sample: sideways pages are rare, so the whole set is read)",
    "classify": "a page with at least 20 characters of text is classified by the direction its text runs as PDF.js draws it (after /Rotate and the CropBox): left to right is upright; 'sideways' means 60% or more of its characters run another way. A page with less text, or no direction with 60%, is not called sideways",
    "fix": "for each sideways page the turn that makes its text run left to right is added to its current /Rotate, written with HerePDF's rotatePdf (lib/pdfPages.js), and the file is read again with PDF.js; the turn's sign is pinned against PDF.js in tests/studySidewaysOrientation.test.js",
    "contentUnchanged": "a page's /Contents streams are the same bytes (by hash) in the rotated file as in the original",
    "limits": "a scan with no text layer cannot be classified this way and is not counted; text that is deliberately sideways on a mostly upright page is not called sideways",
    "sampleIdsSha256": "ade77e5d50db53abe64c3f3a04838ba9fa55eee80575014d3aaacded9b915331",
    "tool": {
      "pdfLib": "2.11.1",
      "pdfjs": "6.3.289"
    },
    "generatedOn": "2026-10-18",
    "commit": "b7f3336"
  },
  "tried": 2995,
  "completed": 2893,
  "notCompleted": {
    "failed": 102
  },
  "encrypted": 99,
  "pages": {
    "total": 37781,
    "text": 36496,
    "rotated": 2715,
    "rotateInherited": 3,
    "landscape": 3775
  },
  "direction": {
    "up": 36331,
    "down": 41,
    "left": 2,
    "right": 100,
    "mixed": 22
  },
  "sideways": {
    "pages": 143,
    "files": 32,
    "filesWithText": 2821,
    "withExistingRotate": 20
  },
  "injected": {
    "files": 374,
    "noTextPage": 15,
    "detected": 374,
    "fixedUpright": 374,
    "rotateRestored": 374,
    "pageCountChanged": 0,
    "pagesInFiles": 5290,
    "contentUnchangedPages": 5290,
    "everyUsedStreamKept": 374,
    "filesThatDroppedUnusedStreams": 252,
    "otherPages": 4916,
    "otherRotationsUnchanged": 4916,
    "byTurn": {
      "90": {
        "files": 126,
        "detected": 126,
        "fixedUpright": 126
      },
      "180": {
        "files": 129,
        "detected": 129,
        "fixedUpright": 129
      },
      "270": {
        "files": 119,
        "detected": 119,
        "fixedUpright": 119
      }
    },
    "sizeRatioVsOriginal": {
      "median": 0.889524752339362,
      "max": 0.9981937760141878
    },
    "sizeRatioVsResaved": {
      "median": 0.997116505229022,
      "max": 1.0004174009832112
    }
  },
  "fix": {
    "files": 32,
    "pagesTried": 143,
    "upright": 143,
    "filesAllUpright": 32,
    "pageCountChanged": 0,
    "pagesInFixedFiles": 530,
    "contentUnchangedPages": 530,
    "otherPages": 387,
    "otherPagesStillAsTheyWere": 387,
    "sizeRatio": {
      "median": 0.9357661589329908,
      "max": 0.9981665521632466
    }
  }
}
