# PeachSoft Offline Suite

PeachSoft is a local browser-based PDF tool suite built from the v7 template foundation. It uses static HTML, CSS, and vanilla JavaScript.

## Files

- `index.html` - tool hub
- `peach-offline_pdf_studio_v8.html` - PDF editor workspace
- `assets/peach-studio.js`, `assets/peach-studio.css` - studio-specific editing and layout
- `assets/peach-ocr.js`, `assets/peach-ocr-worker.js`, `assets/peach-ocr.css` - local OCR recognition, reading, corrections and searchable export
- `assets/peach-fonts.js` - embedded character maps, original Type 3 glyph rendering and explicit approximate font matching
- `peach-redact.html` - manual and pattern-assisted redaction export
- `peach-encrypt.html` - AES-GCM `.peach` encryption/decryption
- `peach-sign.html` - e-signature creation, placement, and export
- `peach-workflow.html` - repeatable PDF workflow chains
- `peach-transcribe.html` - YouTube transcript cleanup and TXT/HTML/DOCX export
- `peach-library.html` - IndexedDB metadata library
- `assets/peach.css` - shared Peach UI system
- `assets/peach-core.js` - shared local-only viewer and utility layer

## Local Dependencies

The required PDF libraries are bundled in `vendor/`. No installation or CDN fallback is needed:

- PDF.js 5.6.205: `pdf.min.mjs` and its matching `pdf.worker.min.mjs`
- PDF-Lib 1.17.1: `pdf-lib.min.js`
- Lucide 1.8.0: local toolbar icons in `lucide.min.js`
- Tesseract.js / core 7.0.0, English tessdata_fast 4.1.0, and PDF-Lib Fontkit 1.1.1: `vendor/ocr/`
- PDF.js rendering resources: `cmaps/`, `standard_fonts/`, `wasm/`, and `iccs/`

Licenses and source details are in `vendor/README.md`. Update PDF.js, its worker, and its rendering resources together.

## Run

Serve the folder locally (PDF.js uses JavaScript modules, which browsers do not load from `file://` pages):

```bash
python3 serve.py
```

Then open `http://127.0.0.1:8080`. Internet access is not required; keep the local server running while using the app.

This server always serves the current files with caching disabled, so returning to a tool cannot reuse an obsolete HTML page or PDF loader. It binds only to `127.0.0.1` and serves the project directory regardless of the terminal's working directory. Use `python3 serve.py --port 8081` if the default port is occupied. After switching from a different server, reload any already-open PeachSoft tabs once to replace previously cached pages.

## Workspace

The home screen is an operational dashboard with searchable/pinnable tools and real recent-document metadata. The shared navigation and Ctrl/Cmd+K command menu reach every tool, settings and help. Recent document links open library metadata; reopen the original file to work on its content. No PDF bytes are retained for the dashboard.

Settings (`login.html`, retained for existing links) provides light/dark/system appearance and reduced motion, not account authentication. Preferences and pinned tools use localStorage. Standard motion includes staggered tool entry, tactile hover/press feedback and command-dialog transitions; operating-system reduced motion is always respected. The shared layer uses `assets/peach-shell.js` and `assets/peach-workspace.css`, with the original PDF engines and tool controllers unchanged except for the specific review fixes listed in `REVIEW.md`.

The library confirms before discarding unsaved notes. Workflow step values can be edited after insertion, and the last completed workflow can be restored locally. Signatures retain drawn ink when the canvas resizes. Cloud authentication, shared workspaces, team permissions and sync are not implemented.

## Privacy Model

PDF bytes are read from local file inputs and exports are generated as browser downloads. PDF tools have no upload endpoint, analytics, or CDN fallback. The library stores metadata only in IndexedDB: filename, size, page count, tags, notes, timestamps, and tool history. Loading an optional YouTube preview contacts YouTube; importing and formatting transcript files does not.

The transcription tool formats pasted transcripts or imported `.srt`, `.vtt`, and `.txt` caption files locally, then exports `.txt`, `.html`, or `.docx` files from the browser. Direct speech-to-text from a YouTube URL requires a backend or transcription API because static browser HTML cannot access YouTube audio streams.

## Implementation Notes

Redaction exports rasterize each PDF page into a new PDF page after drawing black regions. This prevents covered text from remaining selectable in the exported file, at the cost of making the exported pages image-based.

The Redaction tool defaults to **Text lines**. It reads embedded PDF text automatically on each page and uses local English OCR when a page has no embedded text. Click a line outline or its text in the **Text reader** to queue a tightly padded redaction; click again or use **Remove** to unqueue it. Adjacent PDF text runs on one baseline are joined without spanning distant columns. Selection geometry is retained through zoom, crop and page rotation. **Rectangle** keeps the manual drawing workflow available.

**Read text** supports the current page or up to 200 pages in a batch. **Recognise with OCR** explicitly scans page images, including mixed pages whose images are not represented by embedded text. Recognition is cancellable, stays on-device, and does not queue redactions automatically. OCR may miss or misread text, and unusual PDF font metrics may give imperfect bounds: inspect the black preview and add manual coverage where needed before applying redactions. The exported copy has no OCR search layer, source text, interactive form fields or original attachments. Recognition and queued regions live only in the current session. `tests/redact-lines.cjs` covers native and scanned lines, grouping, rotation, zoom, cancellation, document switching, manual selection, and export pixel/text checks.

Reader-compatible PDF password protection is not implemented because PDF-Lib does not expose standard PDF owner/user encryption. The encryption tool implements a Peach `.peach` AES-GCM package using the Web Crypto API.

Workflow Flatten rasterizes the document at twice its displayed point size. It removes editable form fields and annotations, and searchable text. Steps after Flatten operate on the new document.

## PDF Studio

**Edit text** loads selectable text directly from the current PDF page, without OCR. Click an outlined text block, enter replacement text, then select **Replace text** (or Ctrl/Cmd+Enter). The preview and exported copy change visibly. Empty replacement text removes that block visually. **Original font** is the default for native text, preserving its available font glyphs, point size, bold/italic style and baseline. The detected font and size appear below the font selector. Sans-serif, serif and monospace manual replacements, foreground/background colours, undo/redo and project roundtrips are supported. New page navigation loads that page's text automatically. **Add text** remains separate for new annotations.

Replacements keep their original size instead of shrinking to the old text box. Longer text expands into available space; numeric/currency-only blocks retain their right edge. The editor warns and blocks visible replacement when new text exceeds the page, collides with another text block, or needs glyphs unavailable in the original font. Choose a manual font explicitly when the original cannot supply the replacement characters. There is no surrounding paragraph reflow or original content-stream editing. Background reconstruction is a solid fill, so inspect nearby graphics and table rules before export.

Font detection reads the embedded font name and complete available character mapping, not just characters already drawn on the current page. **Type 3** fonts are supported through their original glyph drawing instructions, including vector paths and bitmap masks; the same PDF.js renderer paints them in the preview and export. Type 3 PDFs often store no recognisable typeface name, so the editor identifies these as **Type 3 (embedded glyphs)** instead of guessing a commercial family. Characters actually omitted from the embedded font still need an explicit replacement font. Studio retains extra PDF.js font metadata for editing; other tools keep the lightweight default. Font rendering uses a small extension to the pinned PDF.js bundle, documented in `vendor/README.md`; rerun `tests/type3-fonts.cjs` and `tests/text-style.cjs` before upgrading it.

When replacement letters are unavailable, the warning lists the missing characters. **Match font** compares up to 12 available original letter/digit shapes at a fixed baseline and size against regular, bold, italic and bold-italic candidates. Candidates are bundled Liberation Sans plus the device's Georgia and Courier New families. The chosen **Matched font (approximate)** preserves the source point size, baseline and text-matrix scaling; it does not shrink longer replacements. It is a closest-available visual estimate, not identification or recovery of the original typeface. Matching only changes the draft font: review it and press **Replace text** to apply. The choice is saved in projects and participates in undo/redo. Original-font mode remains available. Fonts and comparisons stay local, and missing font assets can be retried. Unicode characters absent from the matching fonts still require a different font. Device-provided serif/monospace faces may vary across computers.

Pressing **Replace text** with unavailable original-font characters also runs font matching automatically. It selects an approximate draft font at the original size and asks you to press **Replace text** again to accept it. A failed match leaves the text unchanged; page-boundary and overlap checks still apply before an edit is committed.

Image-only pages offer **Recognise scanned text** within Edit text. This runs local OCR and opens the same replacement controls. Scans have no recoverable font metadata: their size is estimated from the original recognition bounds, never reduced based on the replacement's length, and their font family must be approximated. Individually rotated/vertical or clipped native text blocks are skipped by direct extraction and require OCR. Page rotation itself is supported. A filled form should be exported and reopened before text recognition/editing. To update older replacements, reopen the original PDF and saved project, select the replacement and apply it with **Original font**.

Merely loading native text for selection does not flatten a normal export. Once a replacement is applied, export makes a confirmed flattened, searchable copy, retaining untouched native text in its search layer and excluding replaced source text. Forms, links and digital signatures are not retained in that copy. The original file remains unchanged. This is not a secure-redaction tool.

The studio has page thumbnails, collapsible sidebars, page navigation, zoom presets, fit width/page, panning, and document-wide text search. Search uses corrected OCR text on recognised pages and embedded PDF text on other pages, highlighting matching lines/runs.

Added text supports wrapping, colour, size, bold and italic. Text, highlights, rectangles, whiteout, pen strokes, and PNG/JPEG images can be selected, moved, resized, duplicated, or deleted. Images retain their aspect ratio when resized. A double-click on added text focuses its properties. Page rotation, reordering, duplication, and deletion are included in exported PDFs. Undo/redo covers annotations, form values, and page operations.

The Fill tool edits standard AcroForm text fields, checkboxes, and single-choice lists/dropdowns. Normal exports retain these interactive fields. Reordering, duplicating, or deleting pages flattens form widgets in the exported copy to keep values visible without broken field references. Radio groups, XFA forms, JavaScript-driven forms, and certificate signatures are not supported.

Project format v4 stores OCR results and corrections alongside annotations, page order/rotation, and field values, with a SHA-256 fingerprint of the original PDF. Formats v1-v3 remain supported; legacy files without fingerprints are matched by filename and page count. Keep the original PDF alongside the project. Saving a project marks the session clean; exporting a PDF creates a separate copy and does not save the editable project.

**Download PDF**, the **Save PDF** toolbar icon, and Ctrl/Cmd+S all download the edited document as a real `.pdf` with the `application/pdf` MIME type. **Project JSON** is the separate editable-project backup action; its `.json` file is not a PDF and must be loaded alongside the original PDF to resume editing.

Keyboard shortcuts: Ctrl/Cmd+Z undo, Ctrl/Cmd+Shift+Z redo, Ctrl/Cmd+F find, Ctrl/Cmd+S download PDF, Ctrl/Cmd+O open, Ctrl/Cmd+P print, Ctrl/Cmd+D duplicate selection, Delete remove selection, arrow keys nudge (Shift for larger steps), and Page Up/Down navigate. Text inputs retain their native editing shortcuts; Ctrl/Cmd+S downloads the PDF even when an input has focus.

Studio edits additions and supported form fields, not original PDF content streams in place. OCR offers visual reconstruction of scanned text as described below. Standard-font additions in normal exports remain searchable; characters outside those fonts are exported as transparent text images. Whiteout is visual markup, not secure redaction; use the Redaction tool for sensitive content. Image signatures and freehand marks are visual annotations, not verified digital signatures.

### OCR Reader And Editor

**Match page background** is enabled by default for text replacements. It samples the original rendered PDF around the selected text, ignoring editor overlays, and stores the predominant nearby colour for consistent preview and PDF export. Sampling follows zoom, cropping and page rotation. Disable it to choose a manual fill; that preference is saved with the editable project and participates in undo/redo. Older default-white replacements can be matched by selecting them and applying the replacement again; older custom-colour replacements keep their manual colour. The fill matches solid/tinted backgrounds, not photographs, patterns or gradients.

The OCR toolbar opens local English recognition for the current page or all pages (up to 200 per batch). Automatic, single-column, and sparse-text segmentation are available. PDF.js renders each source page for a Tesseract LSTM worker; images are bounded to 14 megapixels and workers are terminated after the batch or cancellation. All OCR runtime files and English language data are bundled locally. There are no outbound OCR requests or language downloads at runtime. See `vendor/ocr/README.md` for versions, sources, licences and the model checksum.

The Read tab provides selectable text with copy and UTF-8 text download. The Edit tab lists recognised lines and their confidence, with low-confidence values flagged. Apply a correction to update the OCR text layer. Enabling **Replace visible scan text** also repaints that region using the chosen background and text colours, with a confirmation before the first visual replacement. Text keeps its estimated original size, with warnings if it will not fit. Revert restores the original recognition; removing OCR restores the original page preview. Corrections and OCR results participate in undo/redo and follow page operations.

Recognition reads the original page content, not unsaved form-field changes or annotations. To recognise a completed form, export the filled PDF first, reopen that copy, then run OCR. OCR results are a recognition snapshot, not a live transcription of subsequent form-field changes.

OCR exports are explicitly confirmed flattened copies: all pages become images with a new invisible, selectable/searchable text layer. Recognised pages use the corrected OCR results; unrecognised pages retain extracted native text, and added text annotations are included. Existing form fields, links, bookmarks, attachments, metadata and digital signatures are not retained. The original PDF is unchanged. Project files retain the editable OCR work. Normal exports without OCR keep the prior studio behaviour.

OCR is fallible, especially for numbers, handwriting, tables, low-resolution scans and unusual fonts. English is the only bundled recognition language. Page rotation is respected, but automatic orientation detection/deskew is not provided; scans should be upright before recognition. The reader/text download preserve Unicode; searchable PDF export embeds Liberation Sans and reports unsupported characters rather than silently replacing them. Visual replacements use a solid background and can obscure nearby marks if the recognised box is inaccurate. They are not a certified redaction workflow.

Signatures are visual marks, not certificate-backed digital signatures or identity verification. This edition has no authentication service or automatic transcription backend.

## Verification

See `tests/README.md` for the upload and platform browser checks. See `REVIEW.md` for the review scope, fixes, and remaining limitations.
