# `optimizer/merge/merge.ts` — adjacent-rect merge pass _(no submodules)_ ## Purpose This module owns `mergeAdjacentRects`, the post-processing pass that combines pairs of edge-sharing same-extent rectangles into a single larger rectangle, provided the merged span lies entirely inside the available mask. It is the cheapest of the optimiser passes and runs after every covering strategy in the layer pipeline. ## Features - Merges along both axes: two rects with the same `y` and `h` merge horizontally when adjacent; two rects with the same `x` and `w` merge vertically when adjacent. - Iterates until a full pass produces no merges, so chains of three or more rects collapse to one in `O(n²)` per pass and `O(k · n²)` overall for `k` passes (bounded by the rect count). - Available-mask check (`isFullyAvailable`) guarantees the merged span never paints transparent cells. ## Usage: Basic ```ts import { mergeAdjacentRects } from "@suaveplan/emblem-solver"; const merged = mergeAdjacentRects( [ { x: 0, y: 0, w: 1, h: 1 }, { x: 1, y: 0, w: 1, h: 1 }, ], fullyAvailableGrid ); // merged === [{ x: 0, y: 0, w: 2, h: 1 }] ``` ## Usage: Advanced ```ts import { mergeAdjacentRects } from "@suaveplan/emblem-solver"; let rects = greedyCover; rects = mergeAdjacentRects(rects, available); rects = mergeAdjacentRects(rects, available); // idempotent — no further change ``` ## API Reference | Symbol | Kind | Description | |---|---|---| | `mergeAdjacentRects(rects, available)` | fn | Greedily merge edge-sharing same-extent rects | ## Implementation Notes The inner `tryMerge` first tests the horizontal merge (same `y`, same `h`, sharing an edge in `x`), then the vertical merge (same `x`, same `w`, sharing an edge in `y`). Either form checks the combined rectangle against `available` before accepting; this avoids painting through transparent pixels. The outer loop terminates when a full pass produces zero merges, so each call is idempotent. We deliberately do not try *non*-same-extent merges here — that is the job of `optimiseOverlap`, which can produce overlapping output and is therefore a strictly stronger (but more expensive) operation.