import type { ResponseField } from '@velrim/sdk'; /** Scale a top-left anchor onto an uncropped page with matching orientation. */ export function sourceHighlight(field: ResponseField, page: number, width: number, height: number) { const anchor = field.anchor; if ( field.state !== 'present' || !anchor || anchor.page !== page || !Number.isInteger(page) || page < 1 || field.grounding === 'ungrounded' || (field.grounding !== 'verified' && field.grounding !== 'cited') ) return null; const { width: pw, height: ph } = anchor.page_dims; const [x0, y0, x1, y1] = anchor.bbox; if ( ![width, height, pw, ph, x0, y0, x1, y1].every(Number.isFinite) || Math.min(width, height, pw, ph) <= 0 || x0 < 0 || y0 < 0 || x1 <= x0 || y1 <= y0 || x1 > pw || y1 > ph ) return null; // A mismatch usually means letterboxing, a crop, or an orientation change. if (Math.abs(width / height / (pw / ph) - 1) > 0.01) return null; return { left: (x0 * width) / pw, top: (y0 * height) / ph, width: ((x1 - x0) * width) / pw, height: ((y1 - y0) * height) / ph, label: field.grounding === 'verified' ? 'Value located in source' : 'Citation; value unconfirmed', }; }