# PatternAlign Studio **Comparative pantograph / design-map overlay studio** for textile, jacquard, garment, print and line-art comparison. Original implementation, original demo artwork, local-first and installable as a PWA. > এই সংস্করণে অ্যাপটি `index.html` + `sw.js` — কোনো সার্ভার বা বিল্ড ধাপ ছাড়াই চলে। ## Download / deployment ZIP **Current version: 1.5.0.** The ZIP builder bundles **all five original apps**: PatternAlign Studio (`index.html`), the mouza measurement/partition prototype (`bhumi-engine.html`), the satellite **KMZ Maker** (`kmz-engine.html`), the **AnyShape Divider** plot-subdivision engine (`anyshape-divider.html`) and the new multi-sheet **Map Joint** engine v4 (`map-joint.html`), plus both service workers. **Every download now contains a generated `BUILD-INFO.txt`** listing the version, UTC build time, all 20 files, per-file source status (`live` / `fallback` / `missing`) and an explicit OK/WARNING line about whether all five apps were captured. After building, the app reports the exact count and names any missing app — a partial archive can no longer masquerade as a complete one. The canonical full package can also be produced with `bash make-zip.sh`. The large Dashboard card, the Settings deployment card and the per-file download fallback all work without a build step or API key. Some sibling HTML files may not be captured if a preview host blocks direct fetches; deploy the downloaded ZIP normally and all 16 files behave as documented. ### KMZ Maker engine `map-joint.html` is the **multi-sheet map joint engine**: - Sheet upload (JPG/PNG/WebP and PDF pages via pdf.js), sheet metadata, rotation, visibility, opacity, reference selection, auto white-margin trim proposals. - Match pairs stored in each sheet's raw pixel coordinates; 2 pairs → similarity, 3 → affine, 4+ → homography (DLT with Hartley normalisation), optional RANSAC outlier rejection, per-pair residual and RMS in px/ft with a 3 px warning threshold. - Projective joint rendering (triangle-mesh warp for homography; canvas matrix for similarity/affine), hard / feather / top blending, seam overlays and overlap/QC panel. - Non-destructive rect and polygon erase masks per sheet; erased areas reveal the sheet underneath. - Plot measurement in composite space with Bengali land units, calibration (2 points + true feet) and “approximate” badge. - Export PDF (cover, joint map, plot table, sheet list, per-pair QC), PNG, JPG, JSON backup with sheet images, and Web Share for JPG. - IndexedDB persistence (projects + images), autosave, undo/redo, context menu, pinch zoom/rotate, 17 in-app self-tests. **Honest gaps:** no OCR dag-number auto pair suggestions; auto border detection is a white-margin bbox proposal (not Otsu+Hough); GeoTIFF/.tfw export is not implemented; final export renders from capped previews (≤1800 px per sheet) rather than full-resolution originals; homography warping is a 20×20 triangle mesh; the self-test suite covers the maths, not browser E2E; sheet images are stored as data URLs in IndexedDB (not Blobs), so very large multi-sheet projects may hit quota. `anyshape-divider.html` is an original plot-subdivision engine (world units are feet): - Plot from free drawing, a 4-side + diagonal quadrilateral builder, rectangles, or side/angle traverse; Heron triangulation and a Brahmagupta estimate for 4-sided plots without diagonals. - Automatic division by equal shares or percentages using parallel sweep lines and 40–52-step bisection; optional inner margin and cut rotation. - Manual subdivision by drawing inside the plot, draggable/lockable vertices, add/remove points. - Per-part name, colour, area and **target-area edge adjustment** (bisects an edge offset until the clipped area matches). - Roads inside/outside the plot with width, position and per-part reserved-area estimates (clearly labelled approximate grid sampling). - Units: sqft, শতাংশ, কাঠা, বিঘা, একর, হেক্টর, m²; length as feet+inches, decimal feet or links. - Autosave, undo/redo, JSON import/export, PNG export and a printable Bengali report with parts, sides, roads and signature fields. - 17 in-app self-tests for shoelace area, Heron, Brahmagupta, clipping, inset, auto-split reconciliation, target-area adjustment and road sampling. `kmz-engine.html` is a Leaflet + WGS84 land-plot studio: - Satellite / hybrid / street basemaps, place search (Nominatim, Bangladesh-biased), browser GPS. - Tap-to-draw polygons, draggable vertices, add/remove vertices, undo/redo. - Haversine perimeter and spherical polygon area from geographic coordinates. - Compound Bengali land units (শতাংশ, একর, কাঠা, বিঘা) plus free-form notes. - Valid **KML 2.2 + KMZ ZIP** export (`doc.kml`, closed CCW rings, BGR colours, ExtendedData), KML, GeoJSON, CSV, JSON backup and printable report. - Google Earth / Google My Maps import guide, file-share sheet and 16 built-in geodesy/KMZ self-tests. **Google Maps caveat:** consumer Google Maps cannot import a local KMZ. Use Google Earth (Web/Pro/mobile) or Google My Maps. A Google Maps JavaScript API KML layer needs an API key and a publicly hosted KML URL. Coordinates are approximate (±2–10 m from imagery, more from GPS) and are not legal boundaries. এই অ্যাপটি চালু করে **Settings → ডিপ্লয় প্যাকেজ → ZIP ডাউনলোড** চাপলেই `patternalign-studio-deploy.zip` তৈরি হয়ে ডাউনলোড হবে। ZIP বিল্ডার ব্রাউজারেই কাজ করে; কোনো build service বা Node.js লাগে না। প্রয়োজনীয় deploy ফাইল: ``` index.html # PatternAlign comparative pantograph studio bhumi-engine.html # mouza measurement + partition engine (prototype) kmz-engine.html # satellite plot mapping + Google Earth KMZ maker anyshape-divider.html # arbitrary-shaped plot builder, auto/manual subdivision, roads, reports map-joint.html # multi-sheet mauza map point-matching and stitching (engine v4) joint-sw.js # service worker for the map-joint app sw.js # offline cache + PWA manifest.webmanifest # PWA metadata (runtime PNG icons are generated too) icons/icon.svg # original app icon 404.html # branded not-found page _headers # Netlify / Cloudflare cache + security headers netlify.toml # Netlify publish configuration vercel.json # Vercel headers .htaccess # Apache / cPanel configuration .nojekyll # keeps GitHub Pages from filtering files README.md # this document wrangler.toml # Cloudflare Pages CLI configuration DEPLOY.md # step-by-step deployment guide + host comparison make-zip.sh # optional CLI packager: bash make-zip.sh ``` Detailed, Bengali-first instructions live in **[DEPLOY.md](DEPLOY.md)**. ### Cloudflare Pages vs Netlify (2026 free tiers) | | Cloudflare Pages | Netlify | |---|---|---| | Static bandwidth | **Unlimited** | 100 GB/month, then the site can pause | | Requests | Unlimited for static assets | Within monthly allowance | | Builds | 500/month (this app needs none) | 300 build minutes/month | | Custom domain + SSL | Free | Free | | Analytics | Cloudflare Web Analytics free | Paid add-on | | Easiest first deploy | Dashboard upload or `npx wrangler pages deploy .` | **Netlify Drop drag-and-drop** | **Recommendation:** use **Cloudflare Pages** for the long-lived production site (unmetered static bandwidth, strong South-Asia CDN, free analytics). Use **Netlify Drop** when you need a shareable HTTPS demo link in under a minute. The same ZIP works on both; no code changes are needed. ## Run ```bash # any static server is sufficient python3 -m http.server 8080 # open http://localhost:8080 ``` Service worker and installability require `http://localhost` or HTTPS. Opening `index.html` directly (`file://`) still runs every editing/export feature, but offline caching and installation are disabled by the browser. > সব ফাইল unzip করে static host-এর **root**-এ রাখুন (`index.html` ও `sw.js` পাশাপাশি)। Netlify Drop-এ ZIP বা unzipped ফোল্ডার সরাসরি ড্র্যাগ করা যায়। ## Core flow 1. **Dashboard → Demo workspace** (or New Comparative Pantograph). 2. Upload **old / base** and **new / comparison** designs (PNG · JPEG · WebP, up to 50 MB). 3. Each design is decoded with EXIF orientation, normalised, given a bounded editing preview and processed by the background-clean Web Worker. 4. **Map Clean** regenerates the mask with debounce. Manual restore/erase brush is available in the cleanup modal. 5. The project opens in **Colour compare**: old ink = vermilion `#C0392B`, new ink = blue `#1F5FA8`, overlap = violet highlight. 6. Optional **Point Match**: pick two distinct source anchors, then two corresponding target anchors, press **Overlay**. 7. Compare with Both / Old / New / Colour / Difference / Side-by-side / Onion flicker. 8. Erase (non-destructive mask), select, crop, measure, calibrate, save and export. ## Line-colour engine (red / blue pantograph) - Every layer has an `inkColor` property, persisted in the project. - **Layer inspector → Line ink colours** sets the base and comparison colours or one active layer colour. - **Auto** restores the classic vermilion/blue mapping. - Background removal keeps only line art with an alpha mask; the tint is applied at render time (`source-in` fill over the layer's alpha). - **Overlap highlight** intersects the alpha of base and comparison layers and paints the common linework violet. It appears in the workspace and in PNG/JPEG/PDF export. - Old and new colours are independent of image content and never mutate the original asset. ## Built-in demo The demo project is generated locally (no external imagery) as two cadastral-style survey sheets with plot numbers, a road, a nullah, survey marks and deliberate survey changes. It loads in colour compare so reviewers can see the red/blue behaviour immediately. ## Geometry engine (pure, DOM-free) Matrix format `[a, b, c, d, e, f]`: ``` x' = a·x + c·y + e y' = b·x + d·y + f ``` Two-point similarity: ``` vA = A2 − A1 vB = B2 − B1 scale = |vB| / |vA| θ = atan2(vB) − atan2(vA) M = T(B1) · R(θ) · S(scale) · T(−A1) residual = mean(|M(Ai) − Bi|) ``` The target layer's own transform is composed as `targetTransform ∘ localMatch`, so point-match results are correct when the target is already moved/rotated/scaled. An advanced 3-point affine mode is available; the default remains the simple two-point similarity. Open **Help → Engine self-tests** to run the built-in matrix / similarity / residual / composition / coordinate checks. ## Editing and persistence - Undo/redo snapshots (up to 50) include transforms, opacity, blend mode, visibility, masks, ink colours, measurements, point matches and canvas size. - Eraser paints a separate per-layer alpha mask; source pixels are untouched. - Rectangle and lasso selections support move, delete, copy, paste, crop, save-as-layer and **Send to Print Studio**. - Projects auto-save to IndexedDB. **Project JSON** export/import moves work between devices. Export-all creates a JSON archive. - Calibration stores `pixelsPerUnit` and the chosen unit (`mm`, `cm`, `inch`), so measurement annotations survive reloads. - No cloud backend is configured in this build; the app runs fully anonymously and locally. ## Export - **PNG** — transparent or white background. - **JPEG** — white background, high quality. - **PDF** — A4/A3/Letter/custom, portrait/landscape, margins, annotations, jsPDF. If the library is unavailable, a browser-print fallback is offered. - Export renders from the full original asset where available and pre-scales layer geometry from preview space to source space so composition matches the workspace. - **Print Studio** — page setup, preview, project/selection items, optional metadata, two-per-page, browser print, PDF download and saved layouts. ## PWA - `sw.js` caches the app shell, same-origin assets and CDN libraries (stale-while-revalidate). - Manifest is generated at runtime with original canvas icons. - Install prompt appears where the browser supports it; otherwise on-screen instructions are shown for Android, iOS and desktop. ## Known limitations / next steps - Background removal is a deterministic local edge-connected algorithm; no server ML (rembg/U2Net) endpoint is configured. - Four-point homography is not implemented (two-point similarity + three-point affine are). - Cloud auth, Supabase schema/RLS and multi-device sync are not configured in this local build. - Assets are stored as data URLs inside IndexedDB records; a production deployment should move blobs to separate object stores/storage with checksums. - Automated Vitest/Playwright suites are not included in this static single-file build; the in-app geometry tests cover the core matrix contract. - Very large uploads are normalised to a 4096 px longest edge for the high-resolution source (and a 2000 px preview), preventing tab memory exhaustion from a 50 MB original; the file is never mutated on disk. Very large projects may still hit browser storage quotas—save errors are surfaced to the user. - The in-app **Download deploy ZIP** builder creates an uncompressed ZIP (store method) with no external dependency. If ancillary files cannot be fetched by the host, the core `index.html` is still included; the repository's `make-zip.sh` produces the canonical full package.