```
├── .github/
├── workflows/
├── ci.yml (200 tokens)
├── .gitignore
├── .pre-commit-config.yaml
├── README.md (700 tokens)
├── assets/
├── input.png
├── output.png
├── pipeline.png
├── commonforms/
├── __init__.py
├── __main__.py (400 tokens)
├── exceptions.py
├── form_creator.py (1300 tokens)
├── inference.py (1400 tokens)
├── utils.py (100 tokens)
├── dataset/
├── generate_coco.py (1200 tokens)
├── merge_coco.py (700 tokens)
├── split_dataset.py (900 tokens)
├── test.csv (7.9k tokens)
├── val.csv (4.8k tokens)
├── pyproject.toml (100 tokens)
├── tests/
├── inference_test.py (300 tokens)
├── resources/
├── encrypted.pdf
├── input.pdf
```
## /.github/workflows/ci.yml
```yml path="/.github/workflows/ci.yml"
name: CI (uv + pytest)
on:
push:
branches: [ "**" ]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up uv
uses: astral-sh/setup-uv@v3
- name: Cache uv and .venv
uses: actions/cache@v4
with:
path: |
~/.cache/uv
.venv
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml', 'uv.lock') }}
restore-keys: |
uv-${{ runner.os }}-${{ matrix.python-version }}-
- name: Install (uv)
run: |
uv sync --dev
- name: Run tests (pytest)
run: |
uv run -m pytest
```
## /.gitignore
```gitignore path="/.gitignore"
.python-version
.DS_Store
*.pyc
__pycache__
*.egg-info
uv.lock
*.pdf
dist
models/
```
## /.pre-commit-config.yaml
```yaml path="/.pre-commit-config.yaml"
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.13.0
hooks:
# Run the linter.
- id: ruff-check
args: [ --fix ]
# Run the formatter.
- id: ruff-format
```
## /README.md
# CommonForms
🪄 Automatically convert a PDF into a fillable form.
[💻 Hosted Models (detect.semanticdocs.org)](https://detect.semanticdocs.org) | [📄 CommonForms Paper](https://arxiv.org/abs/2509.16506) | [🤗 Dataset](https://huggingface.co/datasets/jbarrow/CommonForms) | [🤗 FFDNet-L](https://huggingface.co/jbarrow/FFDNet-L) | [🤗 FFDNet-S](https://huggingface.co/jbarrow/FFDNet-S)

This repo contains three things:
1. the pip-installable `commonforms` package, which has a CLI and API for converting PDFs into fillable forms
2. the FFDNet-S and FFDNet-L models from the paper [CommonForms: A Large, Diverse Dataset for Form Field Detection](https://arxiv.org/abs/2509.16506)
3. the preprocessing code for the CommonForms dataset, which is hosted on HuggingFace: https://huggingface.co/datasets/jbarrow/CommonForms
## Installation
CommonForms can be installed with either `uv` or `pip`, feel free to choose your package manager flavor:
```sh
uv pip install commonforms
```
Once it's installed, you should be able to run the CLI command on ~any PDF.
## CommonForms CLI
The simplest usage will run inference on your CPU using the default suggested settings:
```
commonforms <input.pdf> <output.pdf>
```
| Input | Output |
|-------|--------|
|  |  |
### Command Line Arguments
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `input` | Path | Required | Path to the input PDF file |
| `output` | Path | Required | Path to save the output PDF file |
| `--model` | str | `FFDNet-L` | Model name (FFDNet-L/FFDNet-S) or path to custom .pt file |
| `--keep-existing-fields` | flag | `False` | Keep existing form fields in the PDF |
| `--use-signature-fields` | flag | `False` | Use signature fields instead of text fields for detected signatures |
| `--device` | str | `cpu` | Device for inference (e.g., `cpu`, `cuda`, `0`) |
| `--image-size` | int | `1600` | Image size for inference |
| `--confidence` | float | `0.3` | Confidence threshold for detection |
| `--fast` | flag | `False` | If running on a CPU, you can trade off accuracy for speed and run in about half the time |
| `--multiline` | flag | `False` | If you want the detected textboxes to allow multiline inputs |
## CommonForms API
In addition to the CLI, you can use
```py
from commonforms import prepare_form
prepare_form(
"path/to/input.pdf",
"path/to/output.pdf"
)
```
All of the above arguments are keyword arguments to the `prepare_form` function.
## Dataset Prep
🚧 Code for dataset prep exists in the `dataset` folder.
# Citation
If you use the tool, models, or code in an academic paper, please cite the CommonForms paper:
```
@misc{barrow2025commonforms,
title = {CommonForms: A Large, Diverse Dataset for Form Field Detection},
author = {Barrow, Joe},
year = {2025},
eprint = {2509.16506},
archivePrefix= {arXiv},
primaryClass = {cs.CV},
doi = {10.48550/arXiv.2509.16506},
url = {https://arxiv.org/abs/2509.16506}
}
```
If you use it in a non-academic setting, please reach out to the author (joseph.d.barrow [at] gmail.com)!
I love to hear when people are using my work!
## /assets/input.png
Binary file available at https://raw.githubusercontent.com/jbarrow/commonforms/refs/heads/main/assets/input.png
## /assets/output.png
Binary file available at https://raw.githubusercontent.com/jbarrow/commonforms/refs/heads/main/assets/output.png
## /assets/pipeline.png
Binary file available at https://raw.githubusercontent.com/jbarrow/commonforms/refs/heads/main/assets/pipeline.png
## /commonforms/__init__.py
```py path="/commonforms/__init__.py"
from commonforms.inference import prepare_form
def main():
from commonforms.__main__ import main as cli_main
cli_main()
__all__ = ["prepare_form", "main"]
```
## /commonforms/__main__.py
```py path="/commonforms/__main__.py"
from commonforms.inference import prepare_form
from argparse import ArgumentParser
from pathlib import Path
def main():
parser = ArgumentParser(
prog="commonforms", description="Automatically Prepare a Fillable PDF Form"
)
parser.add_argument(
"input",
type=Path,
help="Path to the input file (only .pdf files are supported for now.)",
)
parser.add_argument("output", type=Path, help="Path to save the output PDF file.")
parser.add_argument(
"--model",
type=str,
default="FFDNet-L",
help="Model (FFDNet-L/FFDNet-S) or path to a different .pt model",
)
parser.add_argument(
"--keep-existing-fields",
action="store_true",
help="If true, keep existing form fields on the PDF",
)
parser.add_argument(
"--use-signature-fields",
action="store_true",
help="If true, use signature fields instead of text fields for detected signatures",
)
parser.add_argument(
"--device", default="cpu", help="Which device to use for inference."
)
parser.add_argument(
"--image-size",
type=int,
default=1600,
dest="image_size",
help="Image size for inference (default: 1600)",
)
parser.add_argument(
"--confidence",
type=float,
default=0.3,
help="Confidence threshold for detection (default: 0.3)",
)
parser.add_argument(
"--fast",
action="store_true",
help="If running on a CPU, you can use --fast to get a 50% speedup with a small accuracy penalty",
)
parser.add_argument(
"--multiline",
action="store_true",
help="If you want the detected textboxes to allow multiline inputs.",
)
args = parser.parse_args()
prepare_form(
args.input,
args.output,
model_or_path=args.model,
keep_existing_fields=args.keep_existing_fields,
use_signature_fields=args.use_signature_fields,
device=args.device,
image_size=args.image_size,
confidence=args.confidence,
fast=args.fast,
multiline=args.multiline,
)
if __name__ == "__main__":
main()
```
## /commonforms/exceptions.py
```py path="/commonforms/exceptions.py"
class EncryptedPdfError(Exception):
pass
```
## /commonforms/form_creator.py
```py path="/commonforms/form_creator.py"
from pypdf import PdfWriter, PdfReader
from pypdf.annotations import AnnotationDictionary
from pypdf.generic import (
NameObject,
ArrayObject,
NumberObject,
TextStringObject,
DictionaryObject,
)
from commonforms.utils import BoundingBox
def rect_for(bounding_box: BoundingBox, page) -> ArrayObject:
# because the PDFs are rendered to images with the CropBox, we need to use
# that as the offset for where we insert the widgets
page = page.cropbox if page.cropbox else page.mediabox
# here I'm flipping the page.top/page.bottom to change from top-left origin
# to bottom-right origin; this results in a negative height, but the math
# works out in the end
page_x0, page_y0, page_x1, page_y1 = (page.left, page.top, page.right, page.bottom)
page_width = page_x1 - page_x0
page_height = page_y1 - page_y0
x0 = page_x0 + (bounding_box.x0 * page_width)
y0 = page_y0 + (bounding_box.y1 * page_height)
x1 = page_x0 + (bounding_box.x1 * page_width)
y1 = page_y0 + (bounding_box.y0 * page_height)
if x0 > x1:
x0, x1 = x1, x0
if y0 > y1:
y0, y1 = y1, y0
return ArrayObject(
[
NumberObject(x0),
NumberObject(y0),
NumberObject(x1),
NumberObject(y1),
]
)
class Textbox(AnnotationDictionary):
def __init__(
self,
name: str,
rect: ArrayObject,
*,
multiline: bool = False,
value: str | None = None,
default_value: str | None = None,
):
super().__init__()
self.update(
{
NameObject("/Type"): NameObject("/Annot"),
NameObject("/Subtype"): NameObject("/Widget"),
NameObject("/FT"): NameObject("/Tx"),
NameObject("/T"): TextStringObject(name or ""),
NameObject("/V"): TextStringObject(value or ""),
NameObject("/DV"): TextStringObject(default_value or ""),
NameObject("/Ff"): NumberObject(0 if not multiline else (1 << 12)),
NameObject("/Rect"): rect,
NameObject("/DA"): TextStringObject("/Helv 0 Tf 0 0 0 rg"),
}
)
class Checkbox(AnnotationDictionary):
def __init__(
self,
name: str,
rect: ArrayObject,
*,
multiline: bool = False,
value: bool | None = None,
default_value: str | None = None,
):
super().__init__()
pdf_value = NameObject("/Off") if not value else NameObject("/Yes")
self.update(
{
NameObject("/Type"): NameObject("/Annot"),
NameObject("/Subtype"): NameObject("/Widget"),
NameObject("/FT"): NameObject("/Btn"),
NameObject("/Ff"): NumberObject(0),
NameObject("/Rect"): rect,
NameObject("/V"): pdf_value,
NameObject("/AS"): pdf_value,
NameObject("/T"): TextStringObject(name),
}
)
class Signature(AnnotationDictionary):
def __init__(self, name: str, rect: ArrayObject):
super().__init__()
self.update(
{
NameObject("/Type"): NameObject("/Annot"),
NameObject("/Subtype"): NameObject("/Widget"),
NameObject("/FT"): NameObject("/Sig"),
NameObject("/T"): TextStringObject(name),
NameObject("/Rect"): rect,
NameObject("/F"): NumberObject(4),
}
)
class PyPdfFormCreator:
def __init__(self, input_path: str):
self.reader = PdfReader(input_path)
# NOTE: Commenting out add_form_topname as it causes lazy loading issues with pages
# self.reader.add_form_topname("original")
self.writer = PdfWriter(clone_from=self.reader)
# Keep reader open until we're done - pypdf uses lazy loading
zapf_font = DictionaryObject(
{
NameObject("/Type"): NameObject("/Font"),
NameObject("/Subtype"): NameObject("/Type1"),
NameObject("/BaseFont"): NameObject("/ZapfDingbats"),
NameObject("/Name"): NameObject("/ZaDb"),
}
)
self.zapf_font = self.writer._add_object(zapf_font)
def clear_existing_fields(self):
"""Clear all existing form fields from the PDF."""
# Get the root form object if it exists
if hasattr(self.writer, "_root_object"):
root = self.writer._root_object
if NameObject("/AcroForm") in root:
acroform = root[NameObject("/AcroForm")]
if NameObject("/Fields") in acroform:
# Replace with empty array to clear all fields
acroform[NameObject("/Fields")] = ArrayObject()
# Also clear widget annotations from each page
for i in range(len(self.writer.pages)):
page = self.writer.pages[i]
if NameObject("/Annots") in page:
page[NameObject("/Annots")] = ArrayObject()
def add_text_box(
self,
name: str,
page: int,
bounding_box: BoundingBox,
multiline: bool = False,
) -> None:
rect = rect_for(bounding_box, self.writer.pages[page])
textbox = Textbox(name=name, rect=rect, multiline=multiline)
self.writer.add_annotation(page_number=page, annotation=textbox)
def add_checkbox(self, name: str, page: int, bounding_box: BoundingBox) -> None:
rect = rect_for(bounding_box, self.writer.pages[page])
checkbox = Checkbox(name=name, rect=rect)
self.writer.add_annotation(page_number=page, annotation=checkbox)
def add_signature(self, name: str, page: int, bounding_box: BoundingBox) -> None:
rect = rect_for(bounding_box, self.writer.pages[page])
signature = Signature(name=name, rect=rect)
self.writer.add_annotation(page_number=page, annotation=signature)
def save(self, output_path: str) -> None:
self.writer.reattach_fields()
with open(output_path, "wb") as fp:
self.writer.write(fp)
def close(self) -> None:
self.writer.close()
self.reader.close()
```
## /commonforms/inference.py
```py path="/commonforms/inference.py"
from __future__ import annotations
from ultralytics import YOLO
from pathlib import Path
from huggingface_hub import hf_hub_download
from commonforms.utils import BoundingBox, Page, Widget
from commonforms.form_creator import PyPdfFormCreator
from commonforms.exceptions import EncryptedPdfError
import formalpdf
import pypdfium2
# our mapping from (model_name, fast) to (repo_id, filename) for the huggingface hub
models = {
("FFDNET-S", True): ("jbarrow/FFDNet-S-cpu", "FFDNet-S.onnx"),
("FFDNET-S", False): ("jbarrow/FFDNet-S", "FFDNet-S.pt"),
("FFDNET-L", True): ("jbarrow/FFDNet-L-cpu", "FFDNet-L.onnx"),
("FFDNET-L", False): ("jbarrow/FFDNet-L", "FFDNet-L.pt"),
}
class FFDNetDetector:
def __init__(
self, model_or_path: str, device: int | str = "cpu", fast: bool = False
) -> None:
self.device = device
self.fast = fast
model_path = self.get_model_path(model_or_path, device, fast)
self.model = YOLO(model_path, task="detect")
self.id_to_cls = {0: "TextBox", 1: "ChoiceButton", 2: "Signature"}
def get_model_path(
self, model_or_path: str, device: int | str = "cpu", fast: bool = False
) -> str:
"""
Construct the path to the model weights based on:
(a) the requested model (in the package or external path)
(b) --fast (if enabled, use ONNX, otherwise use pt)
"""
model_upper = model_or_path.upper()
if model_upper in ["FFDNET-S", "FFDNET-L"]:
# download the model, will just use the cached version if it already exists
repo_id, filename = models[(model_upper, fast)]
model_path = hf_hub_download(repo_id=repo_id, filename=filename)
else:
model_path = model_or_path
return model_path
def extract_widgets(
self, pages: list[Page], confidence: float = 0.3, image_size: int = 1600
) -> dict[int, list[Widget]]:
if self.fast:
# overrides the image size to 1216, since that's all ONNX supports
results = [
self.model.predict(
p.image, iou=1, conf=confidence, augment=False, imgsz=1216
)
for p in pages
]
else:
results = self.model.predict(
[p.image for p in pages],
iou=0.1,
conf=confidence,
augment=True,
imgsz=image_size,
device=self.device,
)
widgets = {}
for page_ix, result in enumerate(results):
if isinstance(result, list):
result = result[0]
# no predictions, skip page
if result is None or result.boxes is None:
continue
widgets[page_ix] = []
for box in result.boxes.cpu().numpy():
x, y, w, h = box.xywhn[0]
cls_id = int(box.cls.item())
widget_type = self.id_to_cls[cls_id]
widgets[page_ix].append(
Widget(
widget_type=widget_type,
bounding_box=BoundingBox.from_yolo(cx=x, cy=y, w=w, h=h),
page=page_ix,
)
)
# do our best to sort the widgets into something resembling reading
# order; this is important for being able to Tab/Shift-Tab back and
# forth to navigate the page.
widgets[page_ix] = sort_widgets(widgets[page_ix])
return widgets
def sort_widgets(widgets: list[Widget]) -> list[Widget]:
"""
Sort widgets in approximate reading order (left-to-right/top-to-bottom)
which makes the LLMs less likely to mess up.
"""
# Sort first by y coordinate, then x coordinate for reading order
sorted_widgets = sorted(
widgets,
key=lambda w: (
round(
w.bounding_box.y0, 3
), # Round to handle minor vertical alignment differences
w.bounding_box.x0,
),
)
# Find rows of widgets by grouping those with similar y coordinates
y_threshold = 0.01 # Threshold for considering widgets on same line
lines = []
current_line = []
for widget in sorted_widgets:
if (
not current_line
or abs(widget.bounding_box.y0 - current_line[0].bounding_box.y0)
< y_threshold
):
current_line.append(widget)
else:
# Sort widgets in line by x coordinate
current_line.sort(key=lambda w: w.bounding_box.x0)
lines.append(current_line)
current_line = [widget]
if current_line:
current_line.sort(key=lambda w: w.bounding_box.x0)
lines.append(current_line)
# Flatten the lines back into single list
return [widget for line in lines for widget in line]
def render_pdf(pdf_path: str) -> list[Page]:
pages = []
doc = formalpdf.open(pdf_path)
try:
for page in doc:
image = page.render()
pages.append(Page(image=image, width=image.width, height=image.height))
return pages
finally:
doc.document.close()
def prepare_form(
input_path: str | Path,
output_path: str | Path,
*,
model_or_path: str = "FFDNet-L",
keep_existing_fields: bool = False,
use_signature_fields: bool = False,
device: int | str = "cpu",
image_size: int = 1600,
confidence: float = 0.3,
fast: bool = False,
multiline: bool = False,
):
detector = FFDNetDetector(model_or_path, device=device, fast=fast)
try:
pages = render_pdf(input_path)
except pypdfium2._helpers.misc.PdfiumError:
raise EncryptedPdfError
results = detector.extract_widgets(
pages, confidence=confidence, image_size=image_size
)
writer = PyPdfFormCreator(input_path)
if not keep_existing_fields:
writer.clear_existing_fields()
for page_ix, widgets in results.items():
for i, widget in enumerate(widgets):
name = f"{widget.widget_type.lower()}_{widget.page}_{i}"
if widget.widget_type == "TextBox":
writer.add_text_box(name, page_ix, widget.bounding_box, multiline=multiline)
elif widget.widget_type == "ChoiceButton":
writer.add_checkbox(name, page_ix, widget.bounding_box)
elif widget.widget_type == "Signature":
if use_signature_fields:
writer.add_signature(name, page_ix, widget.bounding_box)
else:
writer.add_text_box(name, page_ix, widget.bounding_box)
writer.save(output_path)
writer.close()
```
## /commonforms/utils.py
```py path="/commonforms/utils.py"
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel
from dataclasses import dataclass
from PIL import Image
class BoundingBox(BaseModel):
x0: float
y0: float
x1: float
y1: float
@classmethod
def from_yolo(cls, cx: float, cy: float, w: float, h: float) -> BoundingBox:
return cls(x0=cx - w / 2, y0=cy - h / 2, x1=cx + w / 2, y1=cy + h / 2)
class Widget(BaseModel):
widget_type: Literal[
"TextBox",
"ChoiceButton",
"Signature",
]
bounding_box: BoundingBox
page: int
@dataclass
class Page:
image: Image.Image
width: float
height: float
```
## /dataset/generate_coco.py
```py path="/dataset/generate_coco.py"
import json
import sys
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor, as_completed
import formalpdf
import logging
import pypdfium2.raw as pdfium_c
import ctypes
logging.getLogger("pypdfium2").setLevel(logging.ERROR)
def process_pdf(pdf_path, output_dir):
"""Process all pages of a PDF and generate JSON annotation files"""
json_dir = output_dir / "json"
images_dir = output_dir / "images"
pdf_name = pdf_path.stem
# Check if first page JSON exists - if so, skip entire PDF
first_page_json = json_dir / f"{pdf_name}-0.json"
if first_page_json.exists():
return f"Skipped {pdf_name} (already processed)"
try:
document = formalpdf.open(str(pdf_path))
num_pages = len(document)
total_widgets = 0
for page_idx in range(num_pages):
page = document[page_idx]
pdfium_page = document.document[page_idx]
width_pt, height_pt = pdfium_page.get_size()
target_px = 1680
# Scale based on the smaller dimension
scale = target_px / min(width_pt, height_pt)
image = pdfium_page.render(scale=scale, may_draw_forms=False).to_pil()
widgets = page.widgets()
image_filename = f"{pdf_name}-{page_idx}.jpg"
# Create image info
image_info = {
"file_name": image_filename,
"width": image.width,
"height": image.height,
}
# Save image
image.save(images_dir / image_filename, format="JPEG")
# Process annotations
annotations = []
for widget in widgets:
# Use pypdfium2's page-to-device coordinate transformation
# to properly convert PDF coordinates to image pixel coordinates
page_x1, page_y1 = widget.rect.left, widget.rect.bottom
page_x2, page_y2 = widget.rect.right, widget.rect.top
# Convert page coordinates to device coordinates
# using pypdfium2's FPDF_PageToDevice function
dev_x1 = ctypes.c_int()
dev_y1 = ctypes.c_int()
dev_x2 = ctypes.c_int()
dev_y2 = ctypes.c_int()
# FPDF_PageToDevice(page, start_x, start_y, size_x, size_y, rotate, page_x, page_y, device_x, device_y)
pdfium_c.FPDF_PageToDevice(
pdfium_page.raw, 0, 0, image.width, image.height, 0,
page_x1, page_y1, ctypes.byref(dev_x1), ctypes.byref(dev_y1)
)
pdfium_c.FPDF_PageToDevice(
pdfium_page.raw, 0, 0, image.width, image.height, 0,
page_x2, page_y2, ctypes.byref(dev_x2), ctypes.byref(dev_y2)
)
# Convert to Python ints
left = float(dev_x1.value)
bottom = float(dev_y1.value)
right = float(dev_x2.value)
top = float(dev_y2.value)
# Device coordinates have top-left origin, so y values are already correct
y0 = min(top, bottom)
y1 = max(top, bottom)
# try for the category, otherwise "Text"
categories = { "Text": 0,
"ComboBox": 0,
"CheckBox": 1,
"RadioButton": 1,
"Signature": 2,
"PushButton": 3,
"ListBox": 3,
"Unknown": 3 }
category_id = categories.get(widget.field_type_string, 3)
if category_id > 2:
continue
bbox_width = right - left
bbox_height = y1 - y0
annotations.append({
"category_id": category_id,
"bbox": [left, y0, bbox_width, bbox_height],
"area": bbox_width * bbox_height,
"iscrowd": 0,
"segmentation": [],
})
# Create per-page JSON
page_data = {
"image": image_info,
"annotations": annotations,
}
# Save JSON
json_path = json_dir / f"{pdf_name}-{page_idx}.json"
with json_path.open("w") as fp:
json.dump(page_data, fp, indent=2)
total_widgets += len(widgets)
return f"Processed {pdf_name}: {num_pages} pages, {total_widgets} widgets"
except Exception as e:
return f"Error processing {pdf_name}: {str(e)}"
finally:
document.document.close()
def main():
pdfs_dir = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("pdfs")
output_dir = Path(sys.argv[2]) if len(sys.argv) > 2 else Path("coco")
json_dir = output_dir / "json"
images_dir = output_dir / "images"
# Create directories
output_dir.mkdir(exist_ok=True)
json_dir.mkdir(exist_ok=True)
images_dir.mkdir(exist_ok=True)
# Find all PDF files
pdf_files = list(pdfs_dir.rglob("*.pdf"))
total_pdfs = len(pdf_files)
print(f"Found {total_pdfs} PDF files")
# Check which PDFs are already processed
skipped_count = 0
tasks = []
for pdf_path in pdf_files:
pdf_name = pdf_path.stem
first_page_json = json_dir / f"{pdf_name}-0.json"
if first_page_json.exists():
skipped_count += 1
else:
tasks.append(pdf_path)
print(f"Already processed (skipped): {skipped_count} PDFs")
print(f"New PDFs to process: {len(tasks)}")
if tasks:
# Process PDFs in parallel
with ProcessPoolExecutor() as executor:
futures = {executor.submit(process_pdf, pdf_path, output_dir): pdf_path for pdf_path in tasks}
completed = 0
for future in as_completed(futures):
completed += 1
result = future.result()
print(f"[{completed}/{len(tasks)}] {result}")
if __name__ == "__main__":
main()
```
## /dataset/merge_coco.py
```py path="/dataset/merge_coco.py"
import json
import os
import sys
from pathlib import Path
def merge_coco_annotations():
"""Merge individual JSON files into a single COCO format annotations file"""
coco_dir = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("coco")
json_dir = coco_dir / "json"
output_file = coco_dir / "annotations.json"
# COCO format structure
coco_data = {
"info": {
"year": 2025,
"version": "1.0",
"description": "Form field detection dataset",
"contributor": "",
"url": "",
"date_created": "2025-10-16"
},
"licenses": [
{
"id": 1,
"name": "Unknown",
"url": ""
}
],
"images": [],
"annotations": [],
"categories": [
{"id": 0, "name": "Text", "supercategory": "none"},
{"id": 1, "name": "CheckBox", "supercategory": "none"}
]
}
# Get all JSON files sorted by name
json_files = sorted(json_dir.glob("*.json"))
image_id = 0
annotation_id = 0
for json_file in json_files:
with json_file.open("r") as fp:
page_data = json.load(fp)
# Add image with sequential ID
image_info = page_data["image"].copy()
image_info["id"] = image_id
coco_data["images"].append(image_info)
# Track seen bounding boxes for this page to skip duplicates
seen_bboxes = set()
# Add annotations with sequential IDs and image_id reference
for annotation in page_data["annotations"]:
if json_file.name.startswith("2908641"):
continue
# Round bounding box to integers
bbox = annotation["bbox"]
bbox_int = [round(bbox[0]), round(bbox[1]), round(bbox[2]), round(bbox[3])]
# Skip if any x or y coordinate is negative
if bbox_int[0] < 0 or bbox_int[1] < 0:
continue
# Skip if bbox extends beyond image boundaries
if (bbox_int[0] + bbox_int[2] > image_info["width"] or
bbox_int[1] + bbox_int[3] > image_info["height"]):
continue
# Calculate area from rounded bounding box
area_int = bbox_int[2] * bbox_int[3]
bbox_tuple = tuple(bbox_int)
# Skip if this bounding box was already added for this page
if bbox_tuple in seen_bboxes:
continue
seen_bboxes.add(bbox_tuple)
annotation_copy = annotation.copy()
annotation_copy["id"] = annotation_id
annotation_copy["image_id"] = image_id
annotation_copy["bbox"] = bbox_int
annotation_copy["area"] = area_int
coco_data["annotations"].append(annotation_copy)
annotation_id += 1
image_id += 1
# Save merged COCO format file
with output_file.open("w") as fp:
json.dump(coco_data, fp, indent=2)
print(f"Merged {len(coco_data['images'])} images with {len(coco_data['annotations'])} annotations")
print(f"Saved to {output_file}")
# Create symlink in images folder
images_dir = coco_dir / "images"
symlink_path = images_dir / "_annotations.coco.json"
# Remove existing symlink if it exists
if symlink_path.exists() or symlink_path.is_symlink():
symlink_path.unlink()
# Create relative symlink
os.symlink(os.path.relpath(output_file, images_dir), symlink_path)
print(f"Created symlink at {symlink_path}")
if __name__ == "__main__":
merge_coco_annotations()
```
## /dataset/split_dataset.py
```py path="/dataset/split_dataset.py"
import csv
import shutil
import sys
from pathlib import Path
def read_csv_ids(csv_path):
ids = []
with open(csv_path, 'r') as f:
reader = csv.reader(f)
for row in reader:
if row:
id_value = row[0].strip()
ids.append(id_value)
return ids
def read_all_filenames(coco_dir):
"""Read all filenames once into arrays"""
images_dir = coco_dir / 'images'
json_dir = coco_dir / 'json'
# Get all filenames as lists
image_files = [f for f in images_dir.iterdir() if f.is_file()]
json_files = [f for f in json_dir.iterdir() if f.is_file()]
return image_files, json_files
def build_file_lookup(image_files, json_files):
from collections import defaultdict
image_lookup = defaultdict(list)
json_lookup = defaultdict(list)
for img_file in image_files:
# Extract ID from filename (ID-pagenumber.ext pattern)
id_value = img_file.name.split('-')[0]
image_lookup[id_value].append(img_file)
for json_file in json_files:
# Extract ID from filename (ID-pagenumber.ext pattern)
id_value = json_file.name.split('-')[0]
json_lookup[id_value].append(json_file)
return image_lookup, json_lookup
def move_files(source_files, dest_dir):
dest_dir.mkdir(parents=True, exist_ok=True)
moved_count = 0
for file_path in source_files:
dest_path = dest_dir / file_path.name
try:
shutil.move(str(file_path), str(dest_path))
moved_count += 1
print(f"Moved: {file_path.name}")
except Exception as e:
print(f"Error moving {file_path}: {e}")
return moved_count
def main():
coco_dir = Path(sys.argv[1])
# Validate inputs
if not coco_dir.exists():
print(f"Error: Directory '{coco_dir}' does not exist")
return 1
images_dir = coco_dir / 'images'
json_dir = coco_dir / 'json'
if not images_dir.exists() or not json_dir.exists():
print(f"Error: Directory must contain 'images' and 'json' subdirectories")
return 1
# Read CSV files
test_csv = Path('test.csv')
val_csv = Path('val.csv')
if not test_csv.exists() or not val_csv.exists():
print("Error: test.csv and val.csv must exist in current directory")
return 1
print(f"Reading test IDs from {test_csv}...")
test_ids = read_csv_ids(test_csv)
print(f"Found {len(test_ids)} test IDs")
print(f"\nReading validation IDs from {val_csv}...")
val_ids = read_csv_ids(val_csv)
print(f"Found {len(val_ids)} validation IDs")
# Create test and val directories as siblings to coco_dir
test_dir = coco_dir.parent / 'test'
val_dir = coco_dir.parent / 'val'
test_images_dir = test_dir / 'images'
test_json_dir = test_dir / 'json'
val_images_dir = val_dir / 'images'
val_json_dir = val_dir / 'json'
# Read all filenames once into memory and build lookup
print("\nReading all filenames from coco directory...")
image_files, json_files = read_all_filenames(coco_dir)
print(f"Found {len(image_files)} images and {len(json_files)} JSON files")
print("Building file lookup index...")
image_lookup, json_lookup = build_file_lookup(image_files, json_files)
print(f"Indexed {len(image_lookup)} unique image IDs and {len(json_lookup)} unique JSON IDs")
# Process test files
print("\n" + "="*60)
print("Processing TEST files...")
print("="*60)
test_image_count = 0
test_json_count = 0
for id_value in test_ids:
matching_images = image_lookup.get(id_value, [])
matching_json = json_lookup.get(id_value, [])
if matching_images or matching_json:
test_image_count += move_files(matching_images, test_images_dir)
test_json_count += move_files(matching_json, test_json_dir)
# Process validation files
print("\n" + "="*60)
print("Processing VALIDATION files...")
print("="*60)
val_image_count = 0
val_json_count = 0
for id_value in val_ids:
matching_images = image_lookup.get(id_value, [])
matching_json = json_lookup.get(id_value, [])
if matching_images or matching_json:
val_image_count += move_files(matching_images, val_images_dir)
val_json_count += move_files(matching_json, val_json_dir)
# Summary
print("\n" + "="*60)
print("SUMMARY")
print("="*60)
print(f"Test images moved: {test_image_count}")
print(f"Test JSON files moved: {test_json_count}")
print(f"Validation images moved: {val_image_count}")
print(f"Validation JSON files moved: {val_json_count}")
return 0
if __name__ == '__main__':
main()
```
## /dataset/test.csv
```csv path="/dataset/test.csv"
3080814
4066548
6163967
6186894
2632049
7182331
3356313
5061170
3038685
6679579
6037783
4533417
5182793
0581755
6967232
2460748
3224842
1453453
1010529
6508371
7105569
2261543
2257962
3511349
0650007
6021106
7042807
7662971
4338327
5300462
1807841
4768155
1096293
0751361
1632926
4132756
4796955
1934384
3974674
3311789
7718823
2459546
5109069
0904331
0040898
2571110
2704085
7297190
4775160
2482255
2469395
1413166
2312837
5919875
3241597
0980722
6392057
3258356
3212899
7690950
3140301
2767345
3063647
6037613
3990618
3961443
0235850
3619478
7160301
2485380
6849147
5694987
5676802
0761419
7087802
7718797
3766312
6187813
1919426
3007193
1912478
2804127
7883315
3357457
7545260
0309383
6056985
7315753
4083411
3356545
3742941
7516639
4518559
2392260
2503725
2901339
6141323
4880021
2653252
5259150
5484837
3157025
3808204
5123750
5758693
3243052
0759460
0277709
7830368
6087617
7854208
7392292
4626849
6843297
0957126
7888595
1836022
5997858
1680293
3254294
4673050
3712343
3449104
4197681
2153869
5436488
5379307
1273835
3061513
3017241
0434873
4501339
5505602
6104075
3345952
0314011
3148676
3755986
3396585
7232269
0350276
2139451
7540363
0342848
3464967
5528911
3667529
3626181
1515112
6942521
2476198
3391369
1395145
0250551
7565056
4255282
6221918
5312197
7593796
3125351
0776170
5408245
6948833
4776909
2045632
4898523
1706577
5968269
4483743
6277370
4737971
4839706
4575742
4573176
0541705
4039254
2285521
6931855
6442118
0320936
3352548
6078367
7228040
7329018
1439884
7181180
6332822
0129609
4654023
3333791
2223052
1534531
1297987
1107714
4422725
7928430
2173792
6439680
5680444
4129681
3224801
5530592
2658332
3954759
2562603
5462890
4119534
6897267
6331293
3793328
7223498
2326599
2931264
5841963
7539343
5904831
2362478
2474321
7422882
2751515
2330695
2477770
3153826
6648965
2733334
0121937
0031207
4716633
2716171
3873920
4845655
5473151
5090373
5104620
7478963
3396083
1487337
6828903
5925878
0038642
0270387
3197465
1855423
5936663
0215730
0128745
1540545
6852634
2474089
5969966
6186895
7468780
3761113
4671125
0300197
4143872
6723642
7633239
5994915
2453828
1337627
4122413
0587841
2256459
5068499
7882692
1808311
0679668
1616892
0661244
1250396
3155494
3848784
4147731
4586426
7504544
5720328
6790310
0709638
2910591
1964012
4847588
2249078
2199700
0789106
3901739
1590426
1674996
1718834
1028344
6496948
2756340
6198832
0575948
7722862
1963740
7477442
0762804
1221432
7488010
7734052
1851926
2656642
3393935
7320828
6448912
1830500
0581402
5477660
0575701
0442193
5146404
1298540
3874134
2444665
2456634
1417798
5847068
6774291
2882040
1693380
2158811
7043366
0257464
6896203
7293845
2951409
3168552
2582651
4652080
7329032
2879315
6446005
0773638
4219736
2217249
7333185
6463421
1489160
6519260
6018858
3738606
5276949
7851298
5908088
4313287
5298613
1880880
5984002
5983348
3491161
0069272
2689415
5794664
6006696
0157798
5199503
6987759
7374798
2514285
4297968
5240374
5279063
2915046
3331142
1516914
4064802
5264797
4728179
4412663
0169896
4462727
6234513
5282784
3540880
4630513
0722849
1916103
5642640
6779831
3106492
5168360
1912339
6078838
4293872
2758104
0086392
2418693
3124743
1560053
1144683
2244598
2175177
0205212
6764929
3112272
7384722
0283073
2980895
2126421
1225137
7102879
6392954
2715210
1443934
7349009
0895146
4984847
1734167
4085309
5085008
1262358
7349087
2555168
2844816
7134165
2777972
2129242
4926721
2576060
5967890
5104449
2811172
2625238
2216043
5011109
4949138
7131329
6155294
4845736
5138093
4234291
2517218
3038663
7177097
4059906
5281422
2833384
3253658
7349324
6822108
3288941
1572941
5502876
7567382
4219217
3227008
6300160
1707968
5706445
0762473
5707255
4776560
1712464
0546320
5577011
6703755
5865675
5821829
2547311
5222406
5741060
0210990
6821791
3287211
6897626
5130439
3654165
6803159
2840963
5615014
1049336
1837650
3217783
6354401
0517104
3961226
3767030
3981705
3212727
0686168
5208921
6187296
5188197
4682968
7607347
5564953
7481163
3707269
7307375
4391212
1999283
6763199
4216407
0734881
6984386
1806031
1870535
7837408
6008680
0883067
3652071
5318756
3548579
3362970
2541083
7183385
6826304
1876616
0803643
3181507
0203833
7015933
0957762
7268601
0755317
4353050
2717912
5037781
2965308
3937109
5940830
1097998
0738426
3253058
5833653
1007646
7672491
1360432
7643164
4597666
0146074
5768683
2244408
4017602
3462588
3181779
6902261
6224060
6493603
5603699
1807489
6154728
7470198
1607701
1316102
6048405
7081043
4996061
4291308
3167002
0567525
6128100
4919533
7344081
7157087
2156160
3466026
1327967
0197522
2072118
3818461
7397811
0039700
2581843
2162043
0357000
3089755
3453395
1439885
1220129
3525939
4796857
4122377
4093288
7019282
0118483
5393440
3339265
0762275
2469207
2428210
6756788
5557695
0641873
1616192
5978639
3154825
2034823
3846118
3170412
2959058
4894230
5577234
1108582
4478706
4767365
5179553
3348748
0453700
5688853
1589595
4697747
7422454
7820048
2496395
6977091
2880737
5770144
4541528
5093083
0767493
7457557
5242201
2207503
3637335
0166325
1947407
6469280
5653545
0779050
6111756
6254184
7884001
1834166
6709299
2687213
5109631
0526076
3876911
5514692
6525170
0223626
6379660
2534198
3809424
1172414
5082010
5785419
5189598
4495816
6024059
4027913
0804125
7627648
1746223
4433161
5491163
4976001
4408599
3265403
6874637
6611347
1244881
3810343
7215076
4145879
0950251
2960804
0190486
6563315
6298616
4002487
7139407
6238996
2570831
6353832
5454175
5679235
5157510
4858151
2570156
4345086
5499561
1627009
7003055
2541748
5369281
2305551
4544687
3791416
6876378
5801779
3682567
2068485
5151401
0609946
4315461
7496878
4708562
4307271
1613680
4890295
3670811
7010827
1183866
2910218
3594581
1770733
0204033
4495430
3449140
2805727
2829660
3057038
2062442
2453641
4775794
4247265
7508746
0140613
1717833
2911228
5198249
2349713
4631746
5665730
3979040
7253855
6937524
3109753
5843738
0489753
6395462
4933371
7541128
1622596
0953183
0738547
2463620
2551164
6931335
4684820
1304998
1270463
2442991
6509810
7503462
3429666
7144728
0017802
1069084
3201496
5798832
5513382
3445486
5085469
1659052
4798644
0772280
1758646
7504734
1049293
0161158
2369661
1802179
6056019
1514898
3373274
1652878
6451193
6455034
4733315
0865436
3920879
3045532
4873987
0487885
2742776
0056586
2104568
5476714
5608551
5782496
3898186
0813998
1190137
7277304
4648717
0921681
1668978
2319575
2656019
1023768
7314519
7743419
3058915
7582785
7328532
4801129
0409478
0524180
0913553
4750598
7274063
7762573
6828402
5727863
4492855
0632685
7128532
2119858
6343885
0485545
5517925
1133923
0617506
6373782
1233621
5836060
5990734
5044830
4350068
7919254
0322490
7338020
0355318
1352355
6221487
6589094
4937174
6581672
3059498
4525414
1893177
1255492
2693647
0697637
6279563
7623331
2882291
2100826
7281489
3096212
1218764
6012002
2085955
6411747
3594736
3039303
4989940
3784562
0141545
4171334
0228426
3801290
4333769
4371186
2948246
2872887
3858205
1180466
2248678
0091418
3712708
3749467
6370403
7714216
2796246
2499863
4040437
6048634
1758383
4003467
2730170
0087271
5170685
4466279
2673809
7639191
1520938
6841428
1222744
3455789
1079722
6598243
6122732
2128618
5777892
6228631
5543749
2276376
2719075
2519793
3453138
2000176
2894342
5557089
6297899
6256232
2156509
7677757
0742146
2780556
7521790
3043438
0335430
5078229
3700870
3663249
6478871
0880449
2667376
1474296
3702469
4848673
1825584
6898924
7309777
3353045
3661806
1158191
2443506
7718522
2765346
6862645
5045142
4456132
2513973
7361105
4600616
1044906
0539169
2635450
5450950
0672567
1482300
4533025
1230598
6895205
6342437
4558397
7862317
3554102
5984615
2910756
0248826
6175064
1841592
2637605
5507946
1000873
1371487
1603247
4403935
7016988
3143454
6710565
1718852
4314509
0196565
7416729
4554710
5972885
6010863
3882311
3756407
5767969
4969089
3650778
1479147
7721741
4176864
4994914
2579400
6893239
0794707
7527496
6886262
6197376
3543780
5097713
0305651
0418999
7816618
1419960
4139118
6162815
3872241
4280175
6296360
3902617
2587671
2558698
0091692
1618688
3467826
4775973
4371316
7165789
4018742
3034822
7209788
5217786
5038670
6248205
4849199
2825998
5973064
2260682
5016960
4155175
6503042
4343918
4322022
4552604
1873036
2448206
0282216
4714130
6054652
3778474
6299424
0870395
5636627
4119040
5293898
2363746
2142648
4515679
4876874
7542858
0042025
7728514
6303604
4579738
7252080
5176220
7554231
5559539
0889208
4453648
4517208
6722961
2420586
4168726
7414965
0912362
7491746
0148938
2485797
2128715
2167064
6265113
6857073
5827905
4311086
3069149
3896698
6555354
0973521
4174987
3330249
5405423
5690532
5952206
3097238
4592411
5841870
7778765
2246453
0814425
7755895
2212258
6783129
1773049
6106638
4195770
5401000
6135573
6545430
4000326
5466938
5803208
4048064
1487007
6714057
3114862
6469000
6979814
3712104
7156982
3757648
5216316
4551209
6377006
5675526
0007964
0516963
5161286
1692346
0752198
0247868
2076985
3417134
1024782
2759594
4545333
6288254
0069366
5739962
2663666
2579074
6846060
2033315
5792628
3257361
0585070
6778952
5813215
1237200
0284099
4461459
2063993
6396011
6509638
3064405
4172438
7354155
3381801
5182263
1819135
3218840
5233507
1816507
3647285
3217805
2045220
6957753
5545384
6745214
3265852
3050297
6922134
6567067
6506790
4255560
3855600
2823526
6096375
4715097
0247678
0344291
0202989
6881789
7876958
7238903
1809913
6914809
2178371
0136045
6079658
1508219
7867002
2064970
6291394
7254888
7577400
4268746
5317456
1399685
2829459
3674600
1197350
5043282
2268419
4096255
6251921
4243178
3845663
1357172
3974553
2584689
6733437
6649273
0137263
2728211
1180170
0248267
0058646
0576800
3076150
7382868
3678581
2942652
3160438
6098870
3395856
1985882
5292838
0076509
5846144
2920182
4012657
7597492
1874096
2252842
0587538
5792549
3894272
6741097
6422424
1444555
3629350
1361114
1649446
0621045
1104623
4922658
6241102
6977441
5523109
0587658
7270893
7825196
5711163
2233642
2274658
2426219
1065264
0890840
4111391
4456985
0085353
0052641
5184754
2064834
3070478
3167081
6041550
6443459
5760704
4047818
5850575
2683508
5850938
7311379
4040668
1810206
5076051
1736393
2861471
0177010
1894581
4856120
7428275
6427340
3924815
4951818
7928907
2318067
6656576
7112438
1509977
3978125
4573573
1371140
0987248
7473115
4584292
4693197
6674556
1034461
1754657
6583880
2496749
3893043
1246856
4218223
2202131
4053689
6407052
6614046
1783295
7914468
3215040
0675634
2053343
0326175
4117172
6752603
6434408
6227893
2634920
2103380
7719171
3093852
2295455
4940547
7544272
6628327
7606525
4134996
3954626
3963265
3612039
1688497
7587018
0560497
5359464
2900653
3092568
2829633
2267871
1037588
2443863
1886394
7584799
4558167
5054895
0043691
0772624
0148569
2796515
5424056
2783461
0584867
3396182
0168366
2644713
4201396
2092305
7917193
0633723
7468182
4969649
5703895
7322301
3116613
5125179
3806369
0797175
3175117
5417383
4828144
7750902
6625119
3821793
1709056
1866536
6226674
6261248
0124424
1806158
2834688
2590366
3002782
1934969
4134286
1055314
3016845
0573134
7011086
5661630
7839192
4595886
0894490
4591108
2089292
1612165
5415302
6741054
5388661
6355182
7160629
3915248
7117763
5060904
1418173
7174417
0541939
2848541
5890910
2586354
3330723
5126224
4666099
5190399
6289367
4127273
2591380
5684072
0143669
4720105
0200110
6009710
7626013
0952480
4863791
7812241
5882716
0154166
1914395
6674593
3137971
0511109
7811679
3924489
1254400
2510795
7089633
7705179
6464159
2210046
7287405
5432785
5765865
1570072
1729591
7818909
3536708
1204961
4365152
2869567
3697305
0123038
7913898
6450751
5635299
0871683
0376805
0133194
2943755
3177599
4619143
3608049
5955053
5086574
6753827
4850952
4037089
0643508
2838418
2882263
1981332
0962903
2752740
4581395
5431429
7526792
0611046
6361729
4299952
1269384
3440910
6744886
7121060
1620714
2413748
4744727
0671403
5450783
4091118
2164285
6890517
3200868
7607175
7058416
6726403
6648376
5853063
4082613
5153424
2732606
6391917
7009656
1449805
0868230
1855738
2280988
6514003
6778439
3304346
7225561
6017916
3251719
6841883
7736876
7280646
7293941
4949384
6863353
7246005
4164407
6377428
7141215
3424583
2159837
5701425
6329287
2853953
5224700
4803647
3697183
7075163
7125578
0006348
6650491
5063574
2688884
5950688
0084253
2486795
2824958
1042252
3096845
2899768
2430681
6722359
3250267
6622213
3539279
5229876
4839875
5464509
2361188
7489495
1443238
6425927
7238922
0453606
7306525
7827609
6956519
5339756
5134574
3719126
3207217
6998822
0380873
1588787
1995032
0696211
6977223
5134056
4066036
5320471
3945665
2232040
6072970
0720636
0652526
5075923
0930009
5186282
0878181
0719531
3511193
1676471
5137354
5227076
4485954
4020632
5679315
3424085
5772675
0637050
3280362
5164524
0686630
2854684
4961982
7757711
2217796
7034928
1816376
2269367
4777782
5073139
6748121
2535507
6519848
3307407
5575582
4001857
5189733
0005078
1143117
0308072
0162510
4798640
6592228
1385212
6216441
2186086
0371529
5319326
4581899
6590029
7621777
5064577
2901727
2180831
3188512
0825435
2798393
1230777
4423840
7325301
2935623
4219087
5791893
5465049
0939630
3782688
5134773
3727090
4804988
5838419
3394776
1957747
2683169
1566169
6639390
0340374
3125276
4504954
5999010
6089798
5365419
0664160
0646244
1118202
7771716
5601965
5325218
7628257
6697622
7006497
5404110
1262526
0295404
1740649
0901228
1125522
3066112
4804642
6973531
7559023
0672880
2893483
3507522
7098948
1374072
7439890
3614409
7167755
5928049
2737736
4831974
0114918
6139250
7195185
3797245
3652548
7641853
3705012
5738316
2714383
5930201
0416779
3188150
4331531
7184029
1178065
1494857
2025719
0893149
0827804
6801169
7151695
4151122
1405628
5881213
7125382
2455183
4019696
3882088
0069907
7292946
4560034
7259175
6140267
4447262
5254062
4256393
6596503
0848993
0480416
3670514
2859423
1096377
7486248
3143891
1514851
1537894
7904417
3377579
6818285
7844513
6338370
2396086
4667380
7290584
4390927
7874679
7562221
7322057
3638174
6457014
2117900
2938586
0081416
0191889
5627961
5591272
4861740
1017667
4508882
7167371
0100033
3885029
1578205
7349863
6460701
6740993
1084493
1614016
3836869
0027151
3057891
0957679
6006167
5747582
4439351
3830518
3230551
7339727
5346072
1037687
5271555
3675988
2555201
0417425
6079835
7528696
0163194
0163598
4487584
7664813
7082056
2941627
1057936
6515806
5288481
4423867
2897373
2688788
4857465
3835115
0450218
1090347
5596673
0424237
7017274
4396319
5885347
5148895
0980331
0183812
3776700
0519323
1224167
3746142
1183770
6161330
2891510
0404133
5448952
2399288
3655396
3074816
1892707
5362028
0828157
1818524
2670716
3220652
2833949
1186891
5447067
6423175
1778960
0293483
7235409
5282961
6636175
1578492
7728030
4798290
1860750
0610032
0437257
0345785
7229706
5047519
2224631
0632859
7000535
7817809
3323029
6616395
6983166
7695595
6101926
6322055
1169996
6064258
6517442
7526285
0619636
4700038
5963158
5280883
2708833
5011050
4918063
1208655
2204093
2880915
6578370
1869516
5473024
3164778
7454046
5356799
7347660
0765442
7894944
0336775
7256231
6734006
0179112
3367926
1339192
2149750
6683093
2945534
0476719
6869725
4834974
3860451
1276847
4131672
1821591
6757795
1492340
3801478
2311581
1506672
1903585
6077195
5480376
5589511
6055435
4031914
7147975
4251224
0090852
7769825
4320016
2824175
5946077
7246141
3979548
7868312
2265112
1797824
2219334
7777712
5738344
6344079
5001693
4591684
7509283
6251246
2823317
2003046
4246503
7800168
2207403
2593004
3595704
1582848
0391689
1950357
1102654
2003534
5822755
0532051
0438632
4159250
5194014
6350502
0843041
5663712
7049874
4907910
1271503
7230842
6405785
5769689
5885407
5466683
2138171
2886904
4319822
3974996
6179251
2400375
4739515
3355583
7805188
0951720
2516204
0606935
0909459
0943103
4589434
7645001
1324542
1983575
7447499
3582285
0944317
7288766
2660009
2880836
0629747
2471548
0637991
2240694
2060461
2456168
2653115
6468813
5210314
2869171
3698794
1818732
1323398
2299374
1000160
5519350
3370727
4185312
4963640
2760462
3045758
6458524
5800697
0380174
0604903
3868518
3991122
0500283
0941516
3443549
2763804
3780514
4800077
4991560
2247887
6770086
5589881
1386321
2717907
3663852
2081768
3306328
2195548
5933445
3282750
4423345
3316779
5558428
6442898
1252582
3205205
2764300
7673098
2420451
5998027
4990798
1639742
0422585
6254742
5441733
5251615
0994644
3575626
2862219
6808549
2248087
2476446
1084747
4521419
0955147
2533101
2778310
6373136
1608369
0791448
1643131
2777954
7217965
5390831
2375323
0847062
5686473
4000564
1381832
1903489
2596494
2391101
5600389
6108351
4543639
5206155
2328396
3120048
3791380
5868868
6515099
1530957
2530261
0939501
0203596
6799585
0959929
4276414
5439594
0559960
3040277
4465090
1708611
1205078
4007942
0234210
4153677
3682273
3180022
1852787
5554110
3022365
4168313
5264412
7897738
0973663
6424063
1454037
5629792
4187945
5617489
1357458
7657280
1963708
3483297
4184106
1292222
3340738
1933625
1687048
5066274
6094470
1642708
1842300
1224465
2050565
7804017
3664858
1473695
4747340
5438288
0608727
6648019
5963670
1579740
4476490
5101569
2874146
0668637
0524020
4535407
5516126
7143068
6928450
1799701
1938940
6080154
2150713
1506989
2826842
0992969
6477306
5512287
2797388
6463730
4080037
7877495
1565784
0863381
0132418
5268657
1975296
4919500
3688413
1139851
5908268
3890228
6591677
5364428
7383141
6036387
5419988
2958929
1216496
4255329
2295314
6678655
7367194
0809654
1378972
4789949
3127015
7873653
6348496
2205958
0658157
6625062
5694454
7859551
3119001
2937564
3800144
2915578
6158677
3474710
0006433
4067611
7057817
6142165
3216223
2434451
3685403
3694966
7496574
5504187
5340780
5197583
1544194
1899472
1520114
0833075
3431709
7384836
0812132
4076444
7067887
4825300
1760994
1489234
4547296
0473751
6479159
5303618
7589470
5519419
7506069
4122366
1307049
3474122
0822675
2225262
2630738
4720306
4098088
2468564
5641420
0691367
7652082
2631259
2870935
2708823
0430464
7443906
3853885
2888098
2795420
0239920
2309358
2111646
2584083
6316259
4945726
1576272
2222786
4546970
4498154
2390172
0729995
5109967
7869299
0759858
0824721
1454693
0082672
4330056
2363397
7416379
2360902
6496458
3530496
7807287
3786917
1642704
0022607
0089955
2860601
4370043
2298691
4811987
2368056
6636338
7730830
4772865
7445522
1109979
0481813
1814060
7405759
0383957
4423736
3731009
0453887
4475172
6427684
3703521
7389676
0632816
7355813
0993968
5589193
0427862
0681824
6944907
2839693
4985675
2631453
0962387
3630063
0967359
5693826
7653910
6069195
7828517
0711916
5562850
4442662
5803564
0068787
6944705
1819115
6968133
1199405
0456712
0840966
2878233
4282758
4926814
4305478
0824146
4615523
1160044
3361572
3859328
6247147
2673805
1906015
0658311
3902086
7398887
3423437
7776359
7550272
5918568
5004942
5625005
5084695
2112990
6784931
5441073
5880333
7571667
1423092
4734600
0068357
6476592
5774583
7398475
3231663
3632567
4758273
5533416
1856199
5386328
1567646
2142987
4074334
7142140
1969138
5009677
0179530
1967499
2555784
4947773
5468304
7634639
5081479
6510126
5547893
2096656
2389094
3928293
2109301
4544400
2491836
1522344
4765718
6178090
4361296
3735434
0106273
3443588
6436115
3945959
1610890
5421229
7026924
4152207
6728398
5478544
5897225
5153992
0628515
5348045
5306439
3282509
0055470
6581803
4313918
0211361
5478033
4869474
5171831
2773863
4629247
5527366
6302870
3450421
5619939
2914824
2825052
6951727
0684623
5821315
4603034
7074979
7751884
6743690
5099530
3300127
4986641
3225840
6580594
2053561
6745933
4996820
6639909
3872084
3513249
7406945
6736806
2649670
7432708
0054483
0481960
2606205
6132828
7271102
3926926
4239216
6028207
3115097
2564642
3864742
2926644
4327320
1459736
5628568
2886939
6824109
2092219
1445201
5070083
7484916
4044829
0419711
0561335
2062268
2564808
1691900
1888238
0313012
6108860
6713817
0946066
2436158
3495200
3189944
0091622
1560661
1796216
1083832
3877980
5176010
2056507
1758378
0175041
1105588
4378081
5645283
6129821
3116262
0069012
0098996
4622914
4120936
0345763
7019428
4889672
3483554
1343517
7866767
3268045
7698900
0914094
3839448
3571634
7701649
4339658
2565903
2924567
5272204
7344440
7548535
7198691
3161597
3167215
2746843
0282531
4842648
2001282
7218259
3858021
6175256
0014547
3877684
6380963
6000510
4351186
1969020
0972994
4310902
2489315
7626540
0973681
7889229
1090173
4494386
2479673
1511958
1300153
2699817
3689291
1170614
0785073
5878001
5464917
2047288
7230634
6421314
0621903
6330365
0950082
2836027
2133334
1843029
7437723
4117595
1554461
4549785
2322622
0772961
0501622
5369855
5159290
7204038
4266523
1476004
7237444
2907020
1114946
4592178
7432571
2048787
4030167
7659293
4021956
7089797
0340623
2857599
1030318
2306185
1108492
7888816
1552638
0529484
3679681
2838721
7116523
2292391
5023567
7507768
7856611
4989385
6344096
3696029
0018961
4824664
2678060
4853002
1116688
2125591
6960601
7642798
0753008
5384512
5072676
2727653
3100453
2407745
5127959
0362025
4312451
5244333
5304643
1746182
6645381
0482537
0057647
4860290
0586695
5897731
2173675
7844238
2023455
6224735
5209295
3253381
0822741
4345571
2174088
5655666
2221576
7241532
6825554
6319205
0561495
1338122
3439104
1214423
2480079
2055941
7119283
1681937
5871143
0301649
6753916
7698041
3143684
7143380
6874763
4223331
6714363
3547926
7209243
1102522
0013616
6521043
3050409
1291553
0287782
7083383
5418936
1364984
5734825
5805231
2365758
7342784
3721052
6681179
2893303
4242453
3787429
6027145
7112154
7162499
6096825
7009262
4384047
5410351
7092436
6714383
6892809
2580733
3101675
5604194
6894153
3696262
1081331
0247093
0485440
1551303
3564797
7732444
1436347
0253854
2388007
2416741
2625331
6647716
4898477
5541310
4816016
2044388
3223082
3785899
0122649
0465138
1646564
5560302
6385404
0333683
3760522
7139932
3566912
7496125
1963044
6237184
2494385
2206361
3994989
2755281
0781521
2043523
7609131
3120501
7039983
1271284
6407281
3918486
1847703
3242442
0680724
3386017
5802197
0050247
3240056
0719994
5105321
2505630
7786470
4029517
4016944
1013130
2969485
4425691
1206456
2379156
5646425
6767761
6616876
3865053
6110932
0484195
3110785
2178265
0384488
0818366
2241145
1601372
6613892
5975740
4692486
1774941
4565083
2648122
7309936
5542609
5074315
7469834
2084898
2896472
0204204
1083409
6542269
1928212
0746484
3066520
2371786
6776021
1768456
4170070
3323383
7369767
5868229
2398837
0719216
0977596
7012885
1180200
1173649
2082625
4053312
6757814
5441496
7783293
6271543
7330000
2163454
3808397
3240361
5298773
3377178
0975113
5835313
5763777
4931883
0550334
6187700
3301183
6093859
7527070
1071501
2367712
5110515
3447065
6967957
3087609
0936354
2174107
6868128
0051559
6218509
6359736
6241092
1701561
4279448
6541926
7343043
5527885
5637107
3460802
5460330
1042949
5707410
4507970
3516463
4855934
7311170
3476579
7652086
7838703
5965475
6548463
5869086
4115815
0926609
7294598
4419486
7865427
1563746
7411085
7175834
5514799
6988148
0683487
2323433
6340097
1239365
0644655
2420039
1617424
1889084
0961906
2816377
6507246
2742304
1612556
6895812
1341608
0007937
6444102
4482865
5793361
3463739
5671074
3299498
1623741
0080214
4221124
6235547
1532134
7200647
1286055
6824626
4065090
0733602
4106121
0515669
1817618
7107283
5607286
0697609
1884580
2685546
1103372
3338076
7907706
0564143
5171650
4475542
3902095
4180052
3187419
7009128
3010785
6696169
2330304
5880618
0623392
1556942
7230977
0688725
3547739
5378492
7108363
4249159
0452562
4205182
0431902
2166985
3032267
6506980
0033441
1150243
1533285
4341849
7695918
6542329
0774594
0101928
4127068
5140751
4360653
1645627
5396026
3509634
2130597
7389598
2871415
2239664
2768186
2141745
6936115
5141093
3879586
7860384
4894807
3891949
1920343
7380322
6410091
6052131
5022877
7304794
4328794
0142761
2914141
6653172
4108490
4644610
2630753
3248527
0172479
3873916
0320735
5223188
2390639
3692853
3413626
3845070
5189845
6780120
0067068
1207806
7903749
6738487
4069461
0976712
1209861
6909705
0903433
7560062
4312708
3330011
2119484
0023637
4338334
2558535
7486943
7172265
5780604
0947112
6618406
5608041
1989568
6285399
0961599
7681375
5419822
3024718
6154425
3007137
3016312
7900211
2679584
0676785
2600083
1020060
0492032
5347316
7594754
2162047
2155161
5214600
5841859
2587695
3693148
7571760
5599744
4615992
0913485
7025441
6635150
2442377
1300777
1928711
6787088
3611888
1150699
7245027
2584631
1719154
2914357
4169127
0598362
3340617
1593835
0052148
6888235
3375780
0988824
1372839
6641141
1186864
3025183
6040675
3880512
1966785
6171193
2053087
3837791
2558611
6777089
5708719
7786561
3904606
3733196
7760226
7063229
1933945
0883650
1692368
0506200
5288920
7152252
3814809
4616974
1877851
0151211
1200858
2784781
6175921
2380311
6322515
3444071
0440868
6294228
6986181
6877729
2454186
3462912
1306868
1361592
7079026
2507066
7808618
4099264
4005234
5589217
5489045
3275351
7323889
4920136
7897567
1780089
2877579
6031395
0347826
5775325
6105970
3068896
1512191
3029779
1222087
3938266
2097618
4092584
0020119
4512692
0012613
7544977
2506253
6348437
0478132
1718413
3156004
3783005
4893523
4412402
5400744
4937976
6835145
0592314
2632475
6113942
5884135
1286894
6040173
1393531
5100447
7606966
0871179
4809702
3722933
3195556
7744472
4420834
2454998
0768921
5657714
7288226
6477232
4132077
1729649
7123012
0814786
6713076
1252908
5726413
3004997
3401450
0999141
2487909
4436913
6184117
3048808
2483322
1230954
7194765
4366357
1211186
4798291
1412271
0859146
5002918
5143765
5179496
4107345
0541707
0959123
5120419
3069035
4372055
5894531
4813861
3161062
7000503
7349049
7712616
6611385
2487630
3084361
3331595
7479763
0029197
3906141
1996407
1167377
0253410
2157653
1025214
4951966
1204188
0246064
2973814
1824318
3723283
5285281
0456463
7069390
2829220
4303117
6335133
6740667
6047650
0685183
2350995
4286356
4493393
7331113
1620014
0432312
5838666
7102950
6294853
2347631
1835927
4990726
5911449
3746901
4663617
7335891
1279061
2937270
5666691
7287500
1580856
3084999
6339303
4886634
6485553
6557126
3932885
5523309
2534114
1593150
3794255
0006174
5161882
1284710
3746495
1073467
2898390
0833253
2749793
1740691
5065266
6171756
1806394
3014143
0880345
5996717
5293702
2904281
3267587
2273983
3317345
2162328
2191599
7092156
7031260
2131603
1188356
7774925
0976257
4980114
7304249
6062991
3397151
2375607
4904877
4029823
7529160
3668822
2908840
6702922
1237717
1398180
2553315
6102481
4299134
7885796
0658572
2712770
5558670
4286253
6169979
1705981
5086598
3679705
0824129
4551522
6544254
6520791
5849916
4115787
7205274
3160655
4649935
5671510
5279274
3484547
0782373
4036207
0788943
5392174
4564632
0303191
6928884
4581154
2861307
6370525
7753863
5195855
0352777
5250979
3158817
1165155
1618788
0949035
6928861
5160109
7528886
4736755
4941270
7844894
6812621
3489685
0430171
1364165
5870153
3954488
7205733
4796728
2837635
3339738
6888180
4153990
7010586
7124668
5920499
6561314
3272528
5150431
0350228
4984536
2374428
4579120
6457001
2400697
0322610
5898899
6907097
2064608
5457652
7762539
5054136
5447884
7726297
1464747
4078061
3332317
2872920
4364205
2757751
7197644
0001869
5540636
0925844
3877285
0587446
1305045
5432874
6944769
4361968
3180694
3503254
2284826
1419246
5266530
5287206
2833179
4604018
0294900
4031545
4055478
1214586
5381286
7388923
4376004
6748013
1323855
5754393
2753493
7644213
6737739
7715130
7717027
4848760
2234219
1622465
7304595
1309489
0316759
1637383
3457109
2288389
7393471
0208110
7213991
7903680
7343522
6299160
4198505
0115475
6247291
1596517
7145422
5165798
7193910
6978278
3107759
5528435
7061530
0359341
2098112
5947111
2647193
3051242
5125740
0326980
2138512
2359345
6834522
1290841
5121520
3034873
3795035
2652260
2351397
0343760
3608100
0453970
3848452
1129178
6367640
2888900
0329312
6719949
4039272
5883617
6734965
2632508
6723300
5975131
5088141
7868943
5441292
0796673
4214036
0236750
6786680
7523891
5604577
2836496
3515645
7373980
3173571
6652660
2732183
2523641
0429969
2282029
0065501
3343620
4923407
6789961
4452470
3876242
6511485
0334587
2452530
2389239
6156069
7024329
5912652
5193962
2210148
2374271
4523419
7160119
1478265
0220404
1238074
3984174
2309838
0711803
2248309
6164914
5429247
2467678
3787443
5975594
5313895
2815622
5706060
6068353
3008526
2217918
2368263
0625084
4264195
2062163
7220158
1074791
7534415
0399209
6680259
5289482
7900055
4251856
7580332
4726119
5469124
2661943
4860461
3196183
5313621
5845287
7623586
2753740
5602966
1039029
5670769
2563103
5145141
6708497
6985666
6491782
3058325
1050089
0758943
4016477
3535970
3298916
6509783
1611801
2382132
4987516
3913603
3868995
7191624
1199594
2374966
6307675
6583811
6350863
3686643
6330555
4005193
0139265
3529172
1992977
3476548
7546427
6877403
4069131
2826983
7184356
6606579
2889598
3793617
4173691
1435004
4550740
2130088
6894069
2033888
5509023
5288025
6555827
7060483
7401513
1143992
1246539
0560393
3042329
5064100
0038010
5578759
0229510
0687049
4624741
6295932
7771540
5212246
7281823
0350038
1902208
2088039
0016479
1230338
5450279
2975281
0895293
2891316
0621132
0900261
3294320
4662947
6238116
5173244
4295916
7296467
5578935
3788285
5976832
5823757
1758639
7351393
5250652
6022050
6688395
0867089
0181003
1110183
0271557
1714742
4377046
1564810
1308769
0921154
5089179
3068644
1384898
4834676
2060886
3933580
7421918
5546325
3065169
7184729
3807488
0767236
6622487
2608405
5260423
3099528
3767942
5290891
7194150
5280532
3725317
7869846
5961146
3684824
0074637
4761394
5223528
5091693
6778907
3151738
2876899
3483711
5662661
0807462
2754533
0687021
3697617
0903505
0960903
5075345
3493848
1472972
1956541
3138153
3510013
3298183
3377694
2020970
1493411
3921436
6872085
1728249
0528324
1083037
6619579
3865505
0959781
7057534
7529485
0270809
3553198
7375248
2300323
0486671
6829908
4534240
5795757
3365851
2074824
6293358
7885933
2557188
6567845
3802946
6777151
0298738
7788917
5925369
4748925
2119886
1523187
7386386
1941196
1564837
0577105
0499578
1794178
3570794
4923926
2375403
4942518
3296290
0811757
3666828
4480569
0752500
0640521
7247327
3317135
2286916
0035326
6033943
7719074
2969721
6764348
2500206
4603963
1735125
5691757
2310054
1580625
7187729
6329016
0400824
1128550
7926333
3264482
5712836
7888238
1300108
1015549
5410904
7033073
4557565
2383310
7416554
3592858
6092532
4950555
6810059
3714616
7345614
7185134
5360192
5892193
5553991
4667913
6903101
6875185
0598590
3074501
6034223
4814794
4975561
5924124
2939472
3359706
6077288
0280562
1302446
0737742
4094680
2826810
4183761
1637326
5943774
3190279
7704960
2463673
4650465
6717730
7278606
2005609
0204322
2457188
0750628
3571335
4187117
5795567
7446511
7563918
3045318
7198536
0915198
2119617
3030805
2745794
7811972
6236803
6039571
1753984
0215751
1088348
4691756
1064231
4710567
3105172
4429808
5332572
4234497
0356242
5586802
3324904
6502202
4123449
6005615
0913568
3682479
0381795
4797413
0984816
7136328
0751558
5907342
4884647
5313127
0028007
4691699
4621370
5661628
4215961
2391903
0197786
3745423
1540335
1987208
2632294
2462242
4452985
1516802
6023271
5629690
4367947
2615027
7441259
5848520
6384726
7290468
4543606
6544219
3335593
5093229
5791268
7439461
3672478
6344387
3526852
4167497
2583933
2821592
3676236
6580277
0588294
0421013
6461630
5752498
4367578
6345147
4341881
1516936
3053972
0374181
5804800
2826109
3519865
3204061
0237081
1381459
1844931
0142934
1893259
6435994
2871765
1608535
7516455
0396668
6241610
2855077
7424506
4285627
5144758
3502634
4188595
4978207
5879079
6441875
6608585
1442943
3628835
0968470
1089494
7401947
7181897
2812343
2869864
5096128
7351997
4508322
6367830
7286882
4751223
4546133
6949010
0783374
3647197
3693007
3834372
7277615
0801081
0665167
1589055
5984016
7041043
5315105
5559699
6065311
5568207
4931758
7215921
6030303
3406890
7653308
5350033
3470256
7585999
3516422
4732321
0734753
2269524
3830109
6435178
5853807
7306560
5460846
2143871
1428006
5931692
6312490
6253153
0328900
5035136
4493816
0067425
2307134
1738335
2472146
2003521
1286723
7536351
6478251
7388255
4879628
5964149
3900037
7582912
7382204
6935626
2661428
3778645
3036943
2579731
6243010
1836682
6561802
7551456
5664182
2199853
5855987
5434385
3069913
0589116
7325859
5695847
1675938
3349038
3774692
2371909
7416457
2218013
4690774
3757453
4968299
3270485
0737170
1219757
5367560
6446601
5599482
6645473
4709718
6661609
2921591
7212538
2600754
6625703
0702325
5955547
6119196
5918746
4857309
4507256
6403183
5003594
2856879
6336570
1989628
3621211
1589959
1425246
1898936
1331384
1779579
5506312
3169366
5137615
2185773
1342985
0698834
3971232
3770525
5973638
3016667
6751762
1198798
5167016
4066727
2037208
6864896
2439479
5287986
5847817
0011406
5145876
0460905
2531986
0211925
2040473
6065771
2464143
5621683
2046889
3919044
0238755
7700403
3809989
3581689
2603111
0744670
2867965
7102304
7463934
5621768
2167002
6402527
7176120
7545087
5477174
7587991
2027389
0034156
2936972
6473826
7003597
5487900
1468958
2979918
7911965
0173223
0788380
0710997
5403929
5108161
5716900
3699658
4145975
6605768
0685985
7052749
6302108
2546413
5934795
3654937
0490373
6737724
3314099
1444069
3456548
5553732
1281285
1204572
5440832
0871862
2080122
4443586
0905837
0273090
6875741
6674331
0177487
7535406
3329727
7341317
6870496
7630148
3850287
4327575
4272201
3288721
6195742
7922080
7313957
2090791
1502979
4195169
2373220
7263261
0292986
3482755
2722824
4989674
4072426
2780452
0843958
1375382
1211131
2183669
2007771
0970122
5353246
5246857
2504143
1314120
2508928
4366715
3931226
4076466
0236309
2580987
2049803
5126408
5772472
0746262
5841408
2860852
7502806
1515288
1889849
6105868
3500265
3670920
0369112
4601511
3622387
1196630
1064738
7504659
1637931
7499863
5101564
5112258
1580591
2394541
0713949
1270391
3985989
1160401
3588256
6514494
3882026
3728654
4380830
4029549
0915330
3210384
0834763
2806064
7119101
1503689
3222357
5932331
4788209
7335268
2500572
5582571
6323168
1274964
3600973
6359728
5388215
7814014
2061864
6600452
7212461
3149062
7361600
4533821
4396424
4415673
3366849
5349092
1697992
5863799
6614178
0934569
1546308
4399740
2652476
2503296
3457757
5983771
2673458
1390920
1173996
6329762
5184475
6273629
3078463
0264640
5035385
2395916
3926349
7351836
0463951
7338459
3107890
7889180
3419888
6426821
6688424
4076309
5152685
5197495
4229650
7788009
6422993
3793113
7905903
4464613
5823825
4682026
7686440
3309879
2789776
4037356
5555994
5546513
5142818
4349297
2126608
4113850
6833017
6166167
7274418
7309692
5920519
4003484
6119678
1974209
1548985
4608400
1279909
0193393
6299515
5046181
7009146
1961994
0742047
2158161
2211265
6158451
6549904
0024126
7145289
6586355
0397710
5355866
5954062
2047935
1737077
6712383
7042655
2040732
3118434
4396902
0480764
2351592
1757649
3620044
1455252
4662111
6082435
7479164
5445357
1716134
1822094
4243926
2565297
6164526
5761998
1756574
2663514
5557772
6013858
3603778
4472086
7084626
7737817
6785792
7352706
3257212
1087732
4831801
7473754
5391363
0212936
1953348
6462228
2722280
3455958
6038749
0414407
3114642
7224685
7099996
1851141
3155844
1590578
1599383
7415123
4125024
1631440
7333266
3802473
7773274
4440725
6079671
1704981
2873309
4168643
0037550
4621088
7602193
2774845
6958566
1829160
3950098
2592843
1816571
3476346
5789699
1139264
0549404
0080383
7171855
7700614
5684215
0070616
5855136
2296731
3331280
7539691
2059820
2401362
7370398
3503673
6907077
0679689
7605617
7255765
7167935
3498171
7371700
5473225
6847192
4079068
2692024
1481274
3930903
6718024
1101347
5989421
0613179
3878996
5020619
7351961
4935570
3759558
2450748
3919574
2715543
5091273
1795061
5070674
7153010
1393201
2928041
4164671
6047303
5916061
3231588
1337041
5996642
3367247
6571854
1353049
4390407
2380115
2253335
3590907
2008702
5013848
5024633
4544941
3150826
6971868
3800242
0649185
6894445
2497748
7190253
0337514
2557306
3871751
7475594
2485379
0068248
6838570
7544042
7228987
5790634
3262690
6997866
5204209
3389151
7069975
4216639
3833234
7639155
3049776
7692403
1954142
2413163
6696569
6571329
1773229
5812473
0566121
3847939
0782778
1946600
3216788
0066896
0232507
2205282
0701392
7414596
0679283
6769572
1844266
4948292
1400347
2439915
3363066
6377013
5819496
2352241
6940729
3342004
1102532
7198215
0533333
7051235
7845878
0149543
5418109
5801582
0373509
2253601
6102816
0162127
4223003
2452075
7156544
0646949
4676549
2317796
7165964
7006914
4788960
5505967
1092210
2671453
4444194
7516551
3448982
4192564
2876862
3161392
5051510
6121162
0181711
5386426
6848833
4440100
3435500
0249648
0428466
0071051
5871090
6136839
3389572
3114229
0335217
6945041
3316460
7092371
4716973
5566546
2570464
3100564
5364731
7454157
2639243
7861856
7335393
2872819
4056663
1686958
3748392
0406348
0736163
5322777
4512840
2681245
3797677
2834748
6683377
2518177
6163403
6978263
6244490
7296305
7768540
5839377
7289163
7709800
3099799
3301467
2868620
7590565
3830536
0019965
0266028
6324295
0413026
7416036
3194748
6439780
7104967
5907345
5492997
6079343
0881413
0389517
3156214
6121524
4071416
0779686
1381056
1043484
4450435
7562874
7487886
2904716
3073379
5336295
2252776
2876107
0485582
3200962
6096867
0620101
6603176
5069924
5222525
7682134
7421558
3304950
3378634
7811578
4872320
2834118
6880497
1410252
0373287
7762121
1066444
4574691
4851015
4803677
4441262
0277057
6303349
1292994
2936335
1207004
4470013
6487309
1682231
4309013
5865918
0525840
1047754
3347660
1574368
3017778
0962960
3204288
7245145
5163814
4776053
5051140
0140767
0653117
2695679
7419952
6317339
3596170
1386909
1675265
5387949
1761794
1387791
4200578
6928050
1403827
6946251
5901771
1419677
6178723
4654188
5251274
4273765
3506123
7537777
3910320
7914780
2553049
3899465
1621725
7068055
3022312
5899155
3446912
5933292
1054612
0133127
0385300
6369243
3479708
4048253
3942024
3347965
7297177
4704887
4296551
3563645
6882306
1362391
2320567
3200573
1685786
1547281
7472060
4543412
5327713
7603563
7598899
3586187
1796844
4455221
0530096
0043909
1838903
4961743
5049095
0989039
2144896
0555915
5605810
3128324
7215914
7217296
2489470
4792100
6721617
7742854
0193705
6197429
4585916
3688921
1300877
2963132
5536329
1364818
6919527
4468518
0751143
6128057
1036110
0514207
4802702
4661238
5380017
5937663
5319472
7429327
0891496
7548107
1602333
5702184
3831977
7493414
0831912
5467086
3279875
1325259
5322246
7709418
5794335
7522370
3983462
7676660
2235459
6125212
7063588
4223211
5249445
4912381
5632127
5501258
0810214
0763370
1119473
2810370
7311224
3395593
3730251
0705085
1099314
6570461
4730662
1943183
1182566
5117798
6108754
0608992
3144736
0762021
2091283
4293497
1435436
0907048
2030421
0542915
4321217
6815317
1143745
3619137
3308506
2048119
2633721
2480135
0818053
3613342
4471087
7570127
0824329
4811415
3083444
4157120
6962839
7670827
6538924
0656826
5179117
4768262
0110126
2670908
4185249
1500248
4475760
1689815
7637925
6238777
5293683
4875956
2817275
7575619
1931857
1782107
3364047
4077584
0612619
1832766
1862270
5979518
7457783
6727010
6227174
2355691
3421904
0558790
0467533
2189950
5393983
0296377
7485510
3197134
0948730
0853001
7701053
4973671
4610800
4920346
1756891
3625629
4356402
5680172
3962204
4665953
2791724
0528672
4747949
5531777
2886624
7760039
4062165
4146875
4722927
4933769
6984001
1200008
4112508
6428669
3076548
0555555
6544860
0756409
6997305
1155183
3637184
3452412
7029501
1188205
0731383
0004731
0400467
2340966
6388801
1443872
6827145
1947546
6301021
3957633
6684026
6758122
1448009
0483384
0052230
7495402
4145826
4557887
2486101
3731183
1985809
6030673
5732701
1974293
0296633
3992483
5996148
4283829
1137850
2249343
3258246
4181120
6016222
1154319
0300978
5222261
7240540
3094198
2333380
0782758
3814414
1240741
6230108
1925440
3687334
7828808
5368134
5962598
0225908
4804515
5163212
7178581
4505857
7155572
6094674
1391857
4506932
7433230
4416230
7122786
1715722
3970241
5640729
3553529
6063432
0952684
6548430
3153825
1790946
7552309
5984074
4446132
2932548
7835425
0290454
7428887
3242535
5165170
3891067
4731380
5135370
3780393
3110208
5904456
7902379
6774858
5074086
7744726
2045739
1108799
6083483
5629972
5879320
7803213
0442195
0496485
7291292
2889614
3233429
2969766
7068805
2658259
5457534
2841186
6838038
0849560
1406369
0261129
```
## /dataset/val.csv
```csv path="/dataset/val.csv"
7610053
1803369
6035762
5737269
5070597
7673819
4240365
5582511
5366270
7358354
3972555
5681471
0140240
5948721
2667245
5633143
0339578
0396031
4267517
3344315
7142772
1566393
4800488
7507815
1427902
3820764
5613270
0557501
2278989
5165813
3450184
6252352
4826996
5491050
0339287
3778840
6166956
7322968
1074573
6563373
7457453
5041465
2170063
0935325
6566801
1224854
2796100
5700754
4468682
3750075
4473042
7003086
6408973
7129113
2808139
6025072
6347432
1042719
3349006
4860595
3659115
3383045
5388827
0954290
1279380
4371095
7813427
3923825
4764808
4514495
2563280
2508469
3671441
5271839
1220500
1349742
0003535
1048552
0897354
7532790
4753363
7328898
6636019
2980299
7643443
7344924
1784323
0685500
7611000
6282527
0853230
7437498
2729003
7451758
3725693
2169856
4364110
4673145
2097925
3584308
6865251
1141776
5520817
5431329
7564858
3880397
7246704
1083017
5068403
7217897
2085633
2657124
0660592
2463170
6231397
5659255
3983642
2344749
3182031
1281156
2171164
6578051
6024950
3502843
0358161
1192014
1459258
5803896
7770172
2612435
0174233
4141063
5897646
6555199
4136386
6378362
6368962
4483904
1848024
5945387
3457773
0998131
6614682
6641847
5884594
4977780
1750453
0169078
2936422
3902968
4730989
7743148
0435787
0697364
1604799
2161293
7000262
4510622
5369561
3402256
5755061
4618246
7921675
2934759
3724038
0259757
0854451
2614855
5848787
4881810
4464472
0107954
2551905
3443423
0900006
2970658
7682532
0388893
6549757
0608470
5415112
1374965
6252701
1521686
0592309
3076644
1177844
7485231
0022509
1941759
6621276
1789233
2454695
2250540
4566298
6912491
7837423
4372279
6874163
7270896
6837249
6823694
0228846
2917145
2485075
7106718
1182557
5961021
2731541
6200098
1788873
7012380
4199302
1629805
7379959
5818834
0597518
2629387
7289185
5434193
0953971
2011140
6831207
6762083
6911185
2913627
1388515
3897996
3283594
4366487
7207636
0917075
3116768
1561342
5293852
1949986
0270785
0387752
1293734
4759376
7477924
3920403
5579841
3695072
2944416
2732990
6612570
7475777
3730743
5957502
0148639
2797908
0585787
5132342
0745121
4379914
3361344
4461458
6012253
6315272
2148725
5308114
1259628
5709992
6265668
7546830
3767358
2081315
1974556
6820381
0267894
7382730
2256749
5629906
2212135
6758527
4335810
1649591
1632232
6142825
6169200
7901031
2671715
3316964
2488932
0030616
7370315
6478179
1782521
0355988
4569692
5380201
3386573
1639839
4394303
5829499
2816308
3162740
7003861
7291293
1274486
3533607
2064776
2769420
5866291
1427036
3223647
0120750
4190920
3509851
6147267
2319978
0777693
2687796
6793161
2361283
6157749
2411138
6341437
5326995
7120522
7519238
2078491
2682449
0689115
4357038
7723828
1336517
6190630
5069226
1844254
0157436
2142639
0932015
4539467
2036525
0789590
0297370
7222626
5129258
6104164
3813193
3419494
2579541
2839136
7581337
2308376
3491629
7658311
3367927
1639188
1546373
3620490
3879737
5064458
1062899
7035434
4493580
3863126
3956397
2239768
0572190
1823199
5567527
6878447
0766019
4656577
1141868
1482180
2396729
0598210
7169007
0405374
5500193
0495682
5308615
7445696
3023207
2500800
5487519
3195909
6220427
3415808
4115262
2448790
5362673
2754673
0833987
1089857
2489474
3625171
0524700
6356269
6317438
6060300
5336360
0468584
3912460
4557531
5235266
5601522
5222061
2463011
3676339
0623876
1599215
3744015
1235298
7611869
1794580
7913538
5338422
4053748
1255688
6622502
0270488
1615947
1616364
1778907
4813635
5103488
4517199
1175978
4166207
1601751
5417224
2783680
4247922
0704422
5339513
1774614
1084551
6158852
2368108
0462995
0388895
1771066
2058942
5458253
3609323
3602217
5373573
6137364
7600142
6380882
4504238
3460774
5362532
0049983
4841672
0077112
2081650
2359226
4269809
6334558
5649014
3730586
5462531
4908765
0117529
1904455
1972471
6796507
3369827
2120762
3485675
2713347
2185150
1525413
3463569
2013270
6286213
5449943
7470729
3401879
7332800
0582452
6877538
7361307
4693089
5030029
0331422
5680965
5148232
3924514
1556821
4910551
6484105
4357997
4187684
3172507
1096333
4302679
4625329
5731152
4124379
5165626
5420781
2729016
4571539
4628930
0960975
3589527
6332579
6653784
7104483
2379803
3666406
0823352
4855300
5430469
7678986
4164759
7094677
0188085
1544297
1067961
4158027
7240040
5488255
7648541
7873539
7903437
6430517
0932124
1909729
2094863
3785859
6212951
6560724
5654802
6354800
2370570
5884145
0224582
5607550
2819984
7688248
5218869
6772789
3760295
0912687
2449454
4456229
0411993
2184901
6050319
5128701
0962556
0901529
2123753
7852996
2847582
0926980
3477303
4585443
6480263
5513275
4650595
5738068
6252176
3140720
3357813
1994603
0390831
6868518
2955948
4224726
4074401
3764437
4066357
2604141
2470233
1899752
3192373
5051083
0433742
3245780
7324499
6394407
1638581
1023812
7795672
1078094
4220547
4520567
5076401
1984849
4653574
6314563
1625874
6646324
6045267
5000023
0171715
4871082
6831712
1053485
7848433
0421087
0162957
1834594
2512484
4264924
2962379
0445877
7209787
3526069
0821567
6340724
2590597
3841944
0590998
2459188
1512758
2258407
4514842
4086684
3885937
3614806
3478660
5468491
3757972
0735230
5252769
4036356
0388129
4739386
6701987
3058004
6025251
2977601
3112740
2294727
3405244
4204424
7482219
0093015
4777822
4239182
2815685
5420077
1295618
2936484
3496421
4911592
2018952
6250894
3413740
4619901
6393554
0452662
0665565
7582143
1917811
3291535
5738189
3026373
6169857
5698611
3784612
5631456
3525892
2308379
7151924
1135997
6553037
0351245
4338528
2970975
5045445
0458275
5764306
0551650
7514772
3727137
4035393
5433204
0477817
5346733
1452832
4275753
7069229
5917725
3509290
2495511
3206002
3934671
6295580
5242034
1172374
6857123
0280828
7232590
5869693
4116631
6374827
3891569
2673812
5892687
1946793
0620792
0067361
2138631
3295862
5225104
0101937
5608136
5351442
0977204
4369917
7908426
0517446
3953070
3822815
0784826
1832704
5404317
6716059
1023444
5155496
4107846
1833114
3926367
0140048
1425242
6134718
3077132
1265056
6087973
5529695
3765252
6201682
7358075
1241138
7371621
4807242
1453366
4921404
1758827
5366144
1586562
5950115
4646936
3911582
0092806
5372044
3924357
0921086
0817223
3220539
7330171
7203543
3020699
0213418
3406806
1328770
4785999
0724045
3510809
5440145
4540850
4754267
2242078
0741358
2240712
3363611
0739320
4415320
2419123
3343231
5121715
5222270
2524337
7537294
4409530
4199256
2026334
7001321
5653378
0358744
4995279
7564296
7447435
2039105
7248443
7182398
4683391
7081040
2686030
5031930
5851371
3973552
7746285
0642450
4079734
0497006
1130982
4311322
7724310
4093095
0129334
2271459
6724262
4427312
6827575
6818866
6782628
3150736
4555619
0066172
6201677
0837521
4862334
6489237
0459727
5462455
3532107
7070792
6924981
3662317
1721506
2301621
3738099
1024173
5732554
3802751
3968549
2153288
4135711
1895116
5922418
7553756
4478240
6384180
0702307
0452558
3497517
0282046
2582667
1381838
1664533
3894047
6048245
1279845
6390777
2816780
6963705
7064390
0778211
6955938
1599234
3372465
4485238
1244532
4122404
4475773
5278459
1848411
4367197
5018290
6646360
5000076
2679302
1248438
7306278
2749581
4756975
6376646
7113856
7852892
5371346
2003441
7600110
1641652
6326345
7055530
3158980
0036548
7408621
5324776
7783475
0358619
3746889
6607708
7776891
2930174
4080561
0579588
1262226
4833237
3302527
4428173
0313152
5247587
6569238
2660523
6051561
2174870
4502411
7012345
5142622
1059425
7047011
4265853
1847007
7712653
6228935
4785036
0897911
4999205
7088237
2967745
7011378
0480686
5318368
4211122
2131989
2117876
1044137
3238394
2204754
4761520
2913815
3690974
7711300
0223219
2876869
5829706
6864398
1925627
1821921
5975764
0101164
3189051
6996222
2874479
1929361
2140204
1120724
6080755
4816442
6773138
1469230
2543190
6286845
7835084
4512043
1213057
6577155
5965532
6924251
6247159
5951336
0286114
2921207
7188784
0599050
2616457
7726455
2240888
3006928
5710413
6724704
4061099
7273826
2062956
1883998
3586628
4801706
0859599
6948022
5262283
5525746
5784820
7798200
6703058
1332415
3451552
4818026
4305415
7849528
1895766
6996825
0150843
3993433
6471096
4157465
0005392
4819106
0563686
7598068
7468720
3375742
2095908
4176446
6285663
6615294
6865723
2947968
3228128
0405141
1254376
5151880
6603288
5879590
7090441
5617235
6838013
1008182
3043741
5507366
2491652
7222405
6867370
0216976
4693541
4699175
7092285
2613085
0307057
1780517
7310924
6623307
3114921
2034309
4298591
2071247
4709227
0797847
6740444
7131334
1820814
6216611
1624934
1273572
1090180
5920542
6509484
1968355
6231479
5880954
4442357
4060079
6221266
0541763
3748527
5770334
5776760
2253246
2652703
6689181
0549043
1596336
3930315
5303441
4939136
4202265
6340586
2606320
2929215
2701573
1403475
5286231
6217413
6377822
5211094
2870940
0304073
0414536
0433839
5221032
6289745
6648058
1489092
6428700
2860382
6481834
4320365
3155011
0751455
4847672
4501627
0759493
1924449
4518685
3732701
0008529
3909795
2098389
0777148
2080986
5689969
2407465
1038961
4373134
5571086
6039686
2666498
7579016
1306392
7283411
2088438
1698201
1721050
1627742
7431755
4392720
0841633
3163784
1806704
1660465
4618552
5227479
3480589
6988667
2691630
1297922
3694231
0281985
7200596
5964020
6429593
5535867
2412493
3526519
0058369
7235628
0089616
0729491
7511989
7321079
2725008
2230683
5682107
3364700
4633954
4167029
7722330
1355741
7514682
2574150
3719055
3529898
1729419
2846154
5105172
1023586
4404719
2003851
4937220
7788302
7828772
4567067
1635360
5491996
0984984
5149870
1443946
6942525
1161264
3415813
0460305
4280717
2537558
3884480
2188639
5943281
2188763
2923909
4533238
1794350
0693983
6351724
1014274
2849126
7361248
2929048
7471907
7561503
6794035
7017686
0371557
6646968
2578539
1574765
6214888
1876891
7882380
3520615
0787951
3843698
4105934
0555762
5213427
2220606
0268362
4125852
0565896
0537481
1502312
0502870
0658218
5864533
3940916
6387526
3769534
0972854
6913601
2508040
5033477
5642249
4968671
0549989
7611460
0321275
4268132
3110847
1815823
5077451
1317624
3666196
4205603
7836679
7719236
2066641
4721478
2482305
7883815
2577550
2340021
0430274
0084705
6747076
4526441
6783778
4306388
1502701
6705630
6151715
1354027
2936564
6456929
5435083
4937693
1026700
6415869
2706558
4778763
2699508
0977944
2812209
7657951
5721169
0881785
2219494
1218278
5011637
6074918
6302575
1040832
7471209
7552059
1583266
0307663
7846134
5733363
2355222
6892575
6872907
3776655
4158250
4307549
5877887
3764142
4681209
0458039
0325546
7124561
4333515
1108524
0021918
4795271
1366771
0645043
6397588
7614422
1143324
4590003
6827670
2448961
4630465
4684520
6059701
6466598
6020283
0759577
4081688
1846309
5859466
6394812
0738215
0113418
0933663
4234796
7680214
0666182
5646743
1778771
3909072
0295185
5156496
1966232
6136275
5766574
3388996
2889894
3774433
7511259
6529138
2023097
0488978
3144392
4166987
3812633
2313190
7731866
7285791
1730381
7325597
2501240
2381683
5030134
3958336
2001241
5278665
1309764
5739902
1932163
3423720
3314982
5846531
5784573
1307315
5830717
0513637
1489156
3221292
7426735
1610118
1526882
7313576
6505272
5806734
6352048
5482468
3878885
7022883
4303406
1793699
0616998
2200100
4128589
4274248
6830307
7097963
4237182
1391083
5036048
4615341
4087533
6574568
1924208
3808770
5820374
6828429
2408450
4472434
0948626
0719943
2831315
4624632
6234998
2049621
3456675
4453388
5888290
2273268
4041405
0493096
2888250
6105698
1987593
5796393
6217012
4383986
0163539
6370313
2852254
0398208
4271930
5924620
1576054
4062967
3924871
6574066
3739552
7401594
2541677
1114332
0439068
3831375
5285993
1254899
6855566
2732354
2149319
2316004
2559327
7284653
0656366
4670602
7802709
3041553
3620046
2090516
1482394
2935287
3658850
2225384
1285473
2490535
5133653
7911434
2336084
7237174
2713442
0598171
4460854
0897324
3779615
6330052
0511235
7562928
0240144
4443516
0088180
2813089
6019159
7483606
2755372
1192127
4236189
2626838
2486156
1689154
2578696
2210761
1698874
2063510
4710495
1857629
1788092
0196962
2257741
2436644
2845046
3944365
2625649
2534903
7847909
2312944
4996683
3440897
2805205
5277176
5218054
6770261
7011357
4931895
1664210
1695471
3881601
7851209
0602464
0163876
7064107
3940550
5278445
5501210
3662579
4566804
5844001
4601094
2745885
1344514
1531460
1058946
6980780
0829806
6167335
4501722
2067080
7626922
3330567
4194979
7677056
0982439
0795004
4209796
3569114
2333908
7210516
5435932
5529904
4818185
1419570
5410184
5311189
5627539
4863932
4031941
1253585
5505128
4101696
5958059
5537504
2243846
6434793
7654712
6392940
1279364
2756661
7084881
3024677
7778985
4222077
4764768
1230661
2381232
0263279
1767724
6855935
1923208
5489487
6990447
4804728
0934634
5057216
0412790
7461170
1029253
6144878
2199657
7298728
0588003
1056373
3468055
1192466
4486224
0486179
0132783
0477462
2888604
6921998
3223710
0242189
5538352
5535650
6504516
1463633
3121925
5322687
7432937
3123912
0506259
4167589
7068005
7837867
6466300
6312482
6706623
0659559
0161859
2213111
2820216
1296342
3365541
2371472
5668481
0662105
5813192
4860057
3930387
7930371
7459647
1502803
6089024
6869707
3440681
7914802
1727640
1990655
6698657
2697303
1805086
6288960
7138377
5330317
3192539
6617414
3750634
2445198
0993162
2159493
3010947
5054740
6475834
7292070
6300356
2628057
7007222
3602795
5065303
2511443
0455322
2926090
7181192
3774724
4585837
3369617
2774596
4691673
5232113
0755875
1240010
6521798
5998507
4320274
1333190
1003826
7247808
5232509
6738907
7800223
2494729
7588074
0439794
1722806
5006085
6631283
2315254
3698468
1268475
0875147
3066777
0842705
1652072
1340056
5760507
2852246
1808116
2666731
3902857
5431456
6881440
5124214
7502078
1117003
3576578
1557413
3750721
1216460
2009874
6318907
0172159
0475775
6102834
5509175
7876305
6220597
1411703
3900713
0870226
3679839
5617333
6207909
6600787
4171079
3789112
1291849
3799279
3704692
6842435
0844081
7523653
2086261
4083668
5699788
1724909
4790116
2555490
5401308
0780824
5462669
3250852
6110616
3570460
3714061
5528286
2222777
0969399
7636429
2702243
3486552
1104268
3139484
7593353
4809170
2763528
3238328
6098626
4528592
5718310
2041088
5488855
3577584
2501956
5086882
4122261
5862624
2393188
4131767
6549451
1334142
3944663
3657722
2043810
6671632
4787652
0080990
2326490
1416040
6385961
3019183
1871352
0197321
3765655
5444090
1761765
7750643
4221068
7620421
1854756
6150482
6454551
7474065
0987334
4512552
4876889
1142859
6003955
2800324
0538442
2979564
2101456
3105507
3290405
6052101
5424117
5890163
4318331
6757877
3459123
3973285
2596896
6587780
6816201
1875290
2518863
7073476
6915797
0473613
1588553
0245504
4890586
5517667
6628806
5909718
0353320
3814805
1778443
3367290
6226169
1230927
1414163
7259524
7452912
1174294
1990688
4777589
6187572
0604830
4691088
2678819
5650482
3309874
5348250
2245368
1560704
2445504
1426773
7495178
0685622
0092080
7488312
0522016
6762860
3578325
1260596
0767314
3528668
2684675
3959523
7931421
0115357
2612295
2929470
2533896
7662529
0671138
7092793
2533275
6254416
7606035
1636119
3927764
4747831
5885289
2309635
6641286
1501224
7425500
4268124
7808756
4530863
7749142
2767984
6532361
3601170
5052260
2704692
7629142
5473780
0659761
2576048
2654239
1697688
6803017
1827543
3207268
5252133
3620810
6389949
6026721
3990323
2005103
3962315
2528458
2058174
2117672
6991662
3056242
1385899
0240187
5841437
1998095
4557267
7071299
2845509
2732854
0713906
5871741
3554576
7817120
3500850
4436940
3810253
2795593
4720885
1486562
4941717
1446709
6595100
0498319
0948465
4249304
0905006
1219596
2884251
1128984
2471832
7919429
4193847
0557943
5170173
4257366
2895873
0212700
3431031
1991931
2906589
7715406
3579088
3628769
4912406
7051734
1314662
2454070
4190211
2784760
3707871
2208532
6579155
5317801
0358249
2881048
2142605
7221295
5604881
6689811
6600603
6359442
4187243
1683144
4279798
4744017
1507709
4548218
6567283
5498882
6006204
5856584
1735781
6721056
0649817
3913791
0285089
3400937
7700565
7905249
7445597
5216369
7031921
4478592
1187152
3653951
2703483
4186081
0491233
0625101
5364554
5948717
5154032
6504223
7218668
5311260
5426471
3945465
1970247
4549067
2105120
0914686
2060893
0878032
0474480
2738399
4771312
5836589
1121957
7761065
2769754
6481962
6816277
5583806
3385205
7043409
4132527
4138228
3465836
5460034
5950525
4444279
0111855
6215733
3322282
1530605
6684975
6780225
6117909
0918948
4006334
6936225
3469565
5062578
2208278
2574570
2078432
3635379
7247750
6149505
4863122
2260403
1871425
1649931
0327419
7473928
0229349
2173539
5837183
5448025
7286056
2597784
4902560
4968395
1865998
6005283
1036925
5502517
7132040
2505254
6399591
7033430
5195166
2605321
2832809
5091370
1381409
5788152
2557174
7537223
0735084
0509520
2627901
5365119
1114201
7905299
4506688
6627537
0519212
0181136
2656435
2184199
6324124
5659936
2442218
6306333
5489489
1350645
7853591
4089980
0418060
4863463
1304825
6505527
6555322
1924929
7097287
7858148
5544186
6535419
5536458
7229835
7695653
5900089
5462862
3936154
2831659
1787781
4921053
1037917
2629577
2814700
2090820
0992715
2409070
1870869
7135685
3006023
1908518
5304947
5451555
5956762
5428544
2422974
1958995
2505343
0001104
2593994
4194361
5616137
2237505
4681618
4653103
2072204
2945449
3958267
3686747
1959949
5231324
5000374
2117869
5881790
5860462
7487444
1337392
0851290
3385807
4804666
1299345
5725075
3153592
1087541
7467870
7524761
1743519
1013288
7693654
7322834
6281319
6612055
1239564
3855631
2907388
3188618
1118072
2375101
6305613
1968871
7246835
3520512
3641815
4223269
0515779
0392182
0436379
7344465
4026007
7724897
4127270
2831546
5465004
5752851
1254852
4285905
5425385
6048765
7087472
7797945
6282936
0235450
1431959
1984063
5812069
1620486
1297561
3484562
1919097
2957614
4094610
2146361
7852533
7337857
6324806
6452908
7061489
3204464
1139129
7357503
2642733
4385047
4293004
2608030
4014168
1902546
0103625
7517442
0730044
2008984
1279937
4610349
1218480
6150988
4693820
4356544
3988025
3291924
1823088
5633102
0439675
0670976
7054938
0927268
7631674
7151518
5943623
7690166
7415251
4691383
2812810
5182695
3130221
3056779
3461119
2665278
7701802
0058295
3455606
4957260
0817511
1988555
5507069
3191153
3379794
3644396
0333928
6574341
6635978
3200080
6074267
6130549
4118058
6502251
3236011
3543974
4555253
2631110
4595651
1553756
6502362
2808478
2979558
3642696
2871105
5158040
5327387
3284164
7677416
5774344
7604553
4537675
4289836
1214001
6507585
5757239
2507025
5272379
2286117
5415238
6913413
6368108
3224313
4465657
2703578
4609556
3462789
2112798
5306527
7815174
3128428
2400718
6796454
0406096
4780009
7357136
6756270
7315314
5920956
5952332
3794141
1740952
0745078
7357328
5017955
1009947
4082878
3320449
0466711
2081347
6331950
0730491
4110700
7857536
6687023
3617607
1846031
7509099
6769005
2074045
1938322
4971672
3580727
6757898
7582777
0441120
3618207
6912724
3807294
1956324
7225856
0611879
3835028
7790393
4898025
3628167
7883070
4772610
2428264
1225351
7715426
1797949
3032694
0987968
4204097
0309461
4625459
5261213
1557663
1231237
4900066
7771991
2532656
4880760
5366692
5925911
3911933
5356514
3209057
4891241
1563162
0492786
5517721
2461776
6403665
7339025
4071821
6083926
5722870
6898134
3394206
7238028
7207134
1285408
6173666
7747649
3642013
4241980
4227758
2797958
2573851
5323207
4583604
5147983
2497284
3669302
5560736
4628275
7358040
4262162
4506180
0012555
6548179
7349299
1346719
5551004
3163080
3553513
3488111
4543518
7650785
4600338
3625592
2851555
2525953
1237661
2971532
6296745
0479752
2176353
4041288
7217045
1351978
1962012
6681982
1254831
1425046
0495643
6876033
2531819
2543570
3456925
6340482
5445038
5181493
6959820
5674837
5437860
3851939
7148292
4846371
5766819
3470042
2217768
1392096
0444207
3837354
6187674
5955081
0254472
4358254
6530950
2735859
0036814
4490737
1760757
1953945
0899961
6308669
3492603
2857510
1478596
5839754
5226093
4372612
4534408
3458193
0568479
0132591
1391545
6032681
6686680
7586785
3326197
7188161
7702125
5486175
1572806
4746863
0955286
3193616
1466715
2682736
4736787
0392797
2544135
1231653
3441465
7115899
7217989
1336159
5045547
7628115
7349016
0336204
5772186
5291804
3793676
5713596
4888967
0223380
6396774
4948759
3629061
2522577
6671828
5871764
5999151
7590696
0266155
5891676
7392672
0174819
2861000
0672926
3048664
5331800
4929083
7106968
6985833
0318476
6439638
0421973
7039094
6161871
7613978
3170817
5885167
4930157
4602713
0271754
3864886
4343392
3642233
1677575
3557677
7857859
4574624
2747496
6949442
6140878
3678757
1867634
4491477
2345381
5730309
3214078
2027747
1661113
5112927
0230608
1874170
0969929
0332359
4363741
0209630
2532853
0088856
1654843
1495222
4560899
2887137
0017192
7164132
3083310
5078064
1924392
1341531
6138572
2153151
4969776
2428032
0136582
0942422
1863457
2247418
7407826
0295210
3476300
3648424
0223121
2191388
7818568
0756179
3295932
7059118
3916490
6189398
5683256
2508204
4970511
3457923
6540955
4571389
3185672
6458317
5155646
3161694
4141451
6977000
1883035
2569431
2128856
1591680
6728285
4880711
1312369
7453827
2591874
4845849
3501175
3603621
7872525
0168404
1731311
5711805
3654293
2581124
3089997
3399746
6088399
7392610
7496330
1953009
1468419
5996822
2399568
0212670
6375588
7122125
7418456
2806815
5679693
0813709
2332953
6078218
1099287
1646392
5779162
7074416
7227495
3452530
5511311
1678099
5441606
2137785
5862817
7639044
4243504
6957996
7065210
5403618
3233027
6734009
2933672
4056067
0902005
2013190
4806035
2352853
5339200
7407021
5863791
4534575
3526072
5037695
5796531
2458622
4931180
0383986
5303974
5476597
4830221
6111532
2592424
1397629
6896375
2888834
1819828
6136735
2506231
3264786
3896312
6733549
4731109
5660466
1324153
3444097
0870363
7023140
1011988
1854085
2882336
2142470
1634751
3159193
3035608
6941672
2787135
1860199
2633704
0350874
2302254
6900894
6396842
6980680
4897135
4442786
2613357
4225298
4661502
0586230
3562214
1761176
2152888
4537763
2296003
5978342
6153821
4681666
5107483
6975581
2120309
3734419
4289735
6874458
1154075
2483824
2071993
3008898
3528262
7050739
6076269
2544262
5304365
6996039
1222377
6598303
3242157
7508405
5803199
2460144
5519246
2502100
4546275
1205463
0645917
7457301
3392688
1086721
2382440
0576332
0019944
6003168
7424667
4331240
0991115
6387781
4697231
6624749
7398902
6837870
1596058
0172096
7420016
1998476
1505013
0352578
1986456
0292807
5037341
2026787
0349397
4250143
4169735
2045966
2219053
3520725
5485321
0732404
7097593
4260515
1690043
5426135
4918493
1456498
1021628
4588859
7490237
0620411
7369688
2559588
3624944
0478079
5711634
7239497
2778842
4210558
4244044
0747333
7741813
4646507
7592933
5107870
7512174
6735487
4132963
6166833
7862216
5079571
4266764
2624332
7655311
0361504
5019620
7359174
2760837
6367868
0733392
5148403
5800732
6009115
6202419
6554363
5243653
3572218
5251988
4531836
3177598
2095449
5974164
4392082
6413052
3021170
3326440
1303807
3253109
5973133
5829617
3261396
6174761
1956959
1634402
1666950
2713566
3098934
3994343
5277444
4930597
7586961
4776555
0524076
5659003
5759465
4840327
5012263
6584366
5042585
3133048
6046128
0454548
3053750
2764623
4786217
5274732
7918207
3009860
3595830
2450020
5116481
7170594
1716669
0795432
4007415
3762457
0899437
6493678
6682829
3309819
7709051
6340621
7564013
5824616
0724401
0912004
6041405
1857895
0955479
0090509
5393495
6492838
2580439
1077993
3110536
3922250
2686550
6550518
1052089
6212422
4515541
1111382
0517530
4104588
4072588
1438988
5073070
3166354
5354628
6762783
0636657
6222655
1407942
3053004
4090391
4062570
3819214
1002781
7455027
1793753
3891209
3863924
5379957
1257381
4257654
5298655
3167522
1658509
5022840
0429514
2435368
3479433
5265932
4759330
6263734
4715354
0977749
7680395
6895226
3664002
5770510
2114178
2625928
6171932
3361297
0013995
3341268
2495387
2215160
0116177
2252714
2828179
5538659
4127866
0312433
7342021
4848897
3087474
7441255
3503486
7876898
5868676
1074298
0504691
5251700
0537821
0685174
5076819
2907364
6856884
2959786
1617775
2233432
1858650
6564773
3443855
2632218
6848626
6919846
7230439
4763962
0756688
5663849
1447586
3674433
6723417
4866262
6948660
4845995
7299906
1957278
7009281
6850762
7281279
5226386
6490316
6613847
7015098
2661365
4523472
6221990
6359708
6017516
1867833
7847539
6199727
0326525
6033393
3117631
1302691
5983614
3328419
1070889
0461480
0916333
0259855
4734778
2618434
5801384
7267832
3385735
0429913
2835478
4993177
0243193
3531013
5609356
2896038
3468668
3748551
7673307
7727510
```
## /pyproject.toml
```toml path="/pyproject.toml"
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "commonforms"
version = "0.1.6"
description = "Automatically convert a PDF into a fillable form"
readme = "README.md"
requires-python = ">=3.10"
urls = { Homepage = "https://github.com/jbarrow/commonforms" }
dependencies = [
"cryptography>=3.1",
"formalpdf==0.1.6",
"huggingface-hub>=0.35.3",
"onnx>=1.19.1",
"onnxruntime>=1.23.1",
"onnxslim>=0.1.71",
"pillow>=11.3.0",
"pydantic>=2.11.9",
"pypdf>=6.1.1",
"ultralytics>=8.3.204",
]
[project.scripts]
commonforms = "commonforms:main"
[tool.setuptools]
packages = ["commonforms"]
[dependency-groups]
dev = [
"pytest>=8.4.2",
"ruff>=0.14.0",
]
```
## /tests/inference_test.py
```py path="/tests/inference_test.py"
import commonforms
import commonforms.exceptions
import formalpdf
import pytest
def test_inference(tmp_path):
# tmp_path is a built-in pythest fixture where we'll write the outputs
output_path = tmp_path / "output.pdf"
commonforms.prepare_form("./tests/resources/input.pdf", output_path)
assert output_path.exists()
doc = formalpdf.open(output_path)
assert len(doc[0].widgets()) > 0
doc.document.close()
def test_inference_fast(tmp_path):
output_path = tmp_path / "output.pdf"
commonforms.prepare_form("./tests/resources/input.pdf", output_path, fast=True)
assert output_path.exists()
doc = formalpdf.open(output_path)
assert len(doc[0].widgets()) > 0
doc.document.close()
def test_mutlinline(tmp_path):
output_path = tmp_path / "output.pdf"
commonforms.prepare_form("./tests/resources/input.pdf", output_path, fast=True, multiline=True)
assert output_path.exists()
doc = formalpdf.open(output_path)
assert len(doc[0].widgets()) > 0
doc.document.close()
def test_encrypted_failure(tmp_path):
# Reminder to future Joe: password for encrypted PDF is "kanbanery"
output_path = tmp_path / "output.pdf"
with pytest.raises(commonforms.exceptions.EncryptedPdfError):
commonforms.prepare_form("./tests/resources/encrypted.pdf", output_path)
# TODO(joe): future tests around handling encrypted PDFs
# 1. add a --password flag and test that inference doesn't fail
# 2. if a password is provided, ensure that the _output_ PDF remains encrpyted
# with the same password
```
## /tests/resources/encrypted.pdf
Binary file available at https://raw.githubusercontent.com/jbarrow/commonforms/refs/heads/main/tests/resources/encrypted.pdf
## /tests/resources/input.pdf
Binary file available at https://raw.githubusercontent.com/jbarrow/commonforms/refs/heads/main/tests/resources/input.pdf
The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.