import { type MarkerShape, type MarkerTone } from '../annotation-marker'; import { type FaceAffine, type FaceAnnotation, type FaceAnnotationInput, type FaceAnnotationKind, type FaceAnnotations, type FaceAnnotationTool, type FaceChart, type FaceFindingType, type FaceRegistration, type FaceViewId, type Point } from './face-scheme-data'; export type FaceDetectStatus = 'idle' | 'loading' | 'detecting' | 'done' | 'no-face' | 'error'; export interface FaceDetectOptions { /** FRONT view (MediaPipe): base URL for the wasm fileset (defaults to the jsDelivr CDN). */ wasmBaseUrl?: string; /** FRONT view (MediaPipe): URL of the `face_landmarker.task` model (defaults to Google's CDN). */ modelAssetPath?: string; /** PROFILE views (YuNet): ESM bundle URL for `onnxruntime-web` (defaults to the jsDelivr CDN). */ ortModuleUrl?: string; /** PROFILE views (YuNet): base URL for the ORT wasm fileset (defaults to the jsDelivr CDN). */ ortWasmBaseUrl?: string; /** PROFILE views (YuNet): URL of the YuNet `.onnx` model (defaults to the kit's bundled copy). */ yunetModelUrl?: string; } export interface FaceSchemeProps { /** Opaque instance id — emitted as `data-component-id` for the agent registry. */ id?: string; /** * Consumer-supplied patient photo for the FRONT view (shorthand for * `viewPhotos.front`). RASTER ONLY (object-URL / `data:image` / app CDN * raster) — never an `.svg`. PHI: the kit renders it into an SVG * `` and does nothing else (no fetch, persist, log, transmit) and * never exposes `src` via the agent snapshot. */ patientPhoto?: { src: string; altKey?: string; }; /** Per-view photos — each view shows its own image, swapped by the switcher. */ viewPhotos?: Partial>; /** Controlled active view (`front` / `profile-left` / `profile-right`). */ view?: FaceViewId; /** Uncontrolled initial view (default `'front'`). */ defaultView?: FaceViewId; /** Fired when the view switcher changes the active view. */ onViewChange?: (view: FaceViewId) => void; /** Show the built-in view switcher tabs (default `true`). */ showViewSwitcher?: boolean; /** Uncontrolled initial layout — `'all'` opens in the three-up view (every * face at once, focused view interactive). Default `'single'`. Only takes * effect with the view switcher shown, which owns the layout buttons. */ defaultLayout?: 'single' | 'all'; /** `'interactive'` enables zone selection, finding edits and registration; `'display'` is read-only. */ mode?: 'interactive' | 'display'; /** Controlled findings — `Record`. */ value?: FaceChart; /** Uncontrolled initial findings. */ defaultValue?: FaceChart; /** Fired whenever the chart changes. */ onChange?: (next: FaceChart) => void; /** Fired when a zone is activated (click / Enter / Space). */ onSelectZone?: (zoneId: string) => void; /** The finding type a zone-click applies in interactive mode (toggles it). */ activeFinding?: FaceFindingType; /** * `'multi'` turns zone activation (click / Enter / Space) into selection * toggling — one diagnosis can then be applied to every selected zone at * once from the panel's Zones section, in a single `onChange` commit. * `activeFinding` no longer stamps in this mode (it only pre-arms the * section); the selection survives view switches. Default `'off'`. */ zoneSelect?: 'off' | 'multi'; /** Controlled selected zone ids (with `zoneSelect="multi"`). */ selectedZones?: string[]; /** Uncontrolled initial selected zone ids. */ defaultSelectedZones?: string[]; /** Fired when the zone selection changes. */ onSelectedZonesChange?: (ids: string[]) => void; /** * Controlled per-view annotations — freehand marks (point-anywhere markers, * pen / highlighter ink, arrows / lines / boxes / ellipses, text callouts) * drawn in the photo's own coordinate space. Distinct from the zone-keyed * `value` findings, and they do NOT ride the registration transform. PHI: a * text annotation's `text` is rendered only — never logged, persisted, * transmitted, or exposed via the agent snapshot. */ annotations?: FaceAnnotations; /** Uncontrolled initial annotations. */ defaultAnnotations?: FaceAnnotations; /** Fired whenever the annotations change. */ onAnnotationsChange?: (next: FaceAnnotations) => void; /** * Fired when the annotation selection changes (`null` = cleared). Selection * is pointer-mode-scoped: it clears on tool or view change, and a freshly * committed mark auto-selects so its panel affordances target it at once. */ onAnnotationSelect?: (id: string | null) => void; /** * Show the built-in Draw section (tool select, colour, marker shape, undo, * clear) inside the edit panel. Requires `mode="interactive"`. Default * `true` — pass `false` to opt a surface out of the drawing tools. */ showAnnotationToolbar?: boolean; /** * Opt into figure zoom + pan: mouse-wheel / panel-button zoom on the focused * figure, drag-pan from empty space while zoomed, plus a Zoom row in the edit * panel. Requires `mode="interactive"`. Default `false` (MuscleScheme parity). */ zoomable?: boolean; /** * Uncontrolled initial open state of the edit panel (Zones / Draw / Fit * sections). Default `true`: the panel is visible everywhere; the control-bar * toggle only collapses it. */ defaultPanelOpen?: boolean; /** Controlled active drawing tool — `null` = none (pointer falls through to * zone selection / registration). */ activeTool?: FaceAnnotationTool | null; /** Uncontrolled initial tool (default `null`). */ defaultTool?: FaceAnnotationTool | null; /** Fired when the active tool changes (built-in toolbar or handle). */ onToolChange?: (tool: FaceAnnotationTool | null) => void; /** Initial marker shape for the marker tool (default `'circle'`). */ defaultAnnotationShape?: MarkerShape; /** Initial annotation tone (default `'accent'`). */ defaultAnnotationColor?: MarkerTone; /** Controlled per-view registration affine. */ registration?: FaceRegistration; /** Uncontrolled initial registration. */ defaultRegistration?: FaceRegistration; /** Fired whenever the registration changes. */ onRegistrationChange?: (next: FaceRegistration) => void; /** `'off'` hides the fit controls; `'adjust'` shows landmark handles + numeric sliders + auto-fit. */ registrationMode?: 'off' | 'adjust'; /** * Enable the in-kit, on-device face detector for Auto-fit. The front view * uses MediaPipe Face Landmarker; the two profile views use YuNet (which, * unlike the near-frontal FaceMesh, locates a 90° profile). Both runtimes and * their models are lazy-loaded only when detection actually runs, so nothing * weighs on the base bundle. Pass options to point at self-hosted models. */ autoDetect?: boolean | FaceDetectOptions; /** Observe the detector lifecycle. */ onDetectStatus?: (status: FaceDetectStatus) => void; /** * Opt-in: show an on-device photo-capture affordance — a live camera * viewfinder (with a file-upload fallback). The captured frame is rendered * into the same `` base and emitted via `onCapture`; it is never * uploaded, persisted, or logged by the kit. The camera stream is torn down * the instant a frame is frozen and on cancel / unmount. Independent of * `mode` — set it wherever the practitioner should be able to (re)take the * photo. */ allowCapture?: boolean; /** Camera to request for capture (default `'user'` — a face self-portrait). */ captureFacingMode?: 'user' | 'environment'; /** * Fired when a photo is captured or chosen — a `data:` URL, its intrinsic * pixel size, and the view it belongs to. PHI: the consumer owns persistence; * the kit only renders it. */ onCapture?: (photo: { src: string; width: number; height: number; view: FaceViewId; }) => void; /** Show the finding-type legend below the figure. */ legend?: boolean; /** Accessible label override for the chart region. */ ariaLabel?: string; /** Extra class names on the wrapper. */ className?: string; } export interface FaceSchemeHandle { /** Focus a zone by id. */ focusZone: (zoneId: string) => void; /** Read the current chart state. */ getChart: () => FaceChart; /** Read the findings on one zone (empty array if none). */ getZone: (zoneId: string) => FaceChart[string]; /** Read the zone ids carrying a given finding type. */ zonesWith: (type: FaceFindingType) => string[]; /** Add a finding to a zone (no-op if already present). */ setFinding: (zoneId: string, type: FaceFindingType, note?: string) => void; /** Remove a finding type from a zone. */ removeFinding: (zoneId: string, type: FaceFindingType) => void; /** Clear every finding from a zone. */ clearZone: (zoneId: string) => void; /** Read the active-view registration affine. */ getRegistration: () => FaceAffine; /** Set the active-view registration affine. */ setRegistration: (m: FaceAffine) => void; /** Reset the active-view registration to the identity. */ resetRegistration: () => void; /** Solve + apply an affine from canonical-anchor → photo-point pairs. */ fitToLandmarks: (pairs: { id: string; photo: Point; }[]) => void; /** Run the on-device detector on the current photo and auto-fit. Resolves * `true` on a successful fit, `false` if detection is disabled / finds no face. */ detect: () => Promise; /** Start the on-device camera viewfinder (no-op if capture is disabled or the * camera API is unavailable — emits an error status in that case). */ startCapture: () => void; /** Stop the camera viewfinder without capturing. */ cancelCapture: () => void; /** Read the active view id (`front` / `profile-left` / `profile-right`). */ getView: () => FaceViewId; /** Switch the active view. */ setView: (view: FaceViewId) => void; /** Read the current zoom factor (1 = base window). */ getZoom: () => number; /** Set the zoom factor (clamped to 1–8), anchored on the window centre. */ setZoom: (factor: number) => void; /** Reset zoom and pan to the base window. */ resetZoom: () => void; /** Read the active-view annotations. */ getAnnotations: () => FaceAnnotation[]; /** Add an annotation to the active view; returns its (generated) id. */ addAnnotation: (annotation: FaceAnnotationInput) => string; /** Remove an annotation from the active view by id. */ removeAnnotation: (id: string) => void; /** Remove the most-recently-added annotation on the active view. */ undoAnnotation: () => void; /** Clear every annotation from the active view. */ clearAnnotations: () => void; /** Read the active drawing tool (`null` = none). */ getTool: () => FaceAnnotationTool | null; /** Set the active drawing tool (`null` = none). */ setTool: (tool: FaceAnnotationTool | null) => void; /** Read the selected annotation (id + kind), or `null` when none. */ getSelectedAnnotation: () => { id: string; kind: FaceAnnotationKind; } | null; /** Select an active-view annotation by id (`null` clears; unknown ids no-op). */ selectAnnotation: (id: string | null) => void; /** Link / unlink an active-view annotation to a zone (`null` = no zone). */ setAnnotationZone: (id: string, zoneId: string | null) => void; /** Read the selected zone ids (`zoneSelect="multi"`). */ getSelectedZones: () => string[]; /** Replace the zone selection (any view's zone ids). */ setSelectedZones: (ids: string[]) => void; /** Clear the zone selection. */ clearZoneSelection: () => void; /** Add a finding to every selected zone in ONE chart commit; the optional * note lands only on zones the finding is newly added to. */ applyFindingToSelection: (type: FaceFindingType, note?: string) => void; /** Remove a finding type from every selected zone in ONE chart commit. */ removeFindingFromSelection: (type: FaceFindingType) => void; /** Selection-independent bulk write — add a finding to each given zone in * ONE chart commit (the agent `set_finding_bulk` path). */ setFindingBulk: (ids: string[], type: FaceFindingType, note?: string) => void; } export type FaceCaptureState = 'idle' | 'requesting' | 'streaming' | 'error'; export type FaceCaptureError = 'permission-denied' | 'no-camera' | 'not-readable' | 'insecure-context' | 'capture-failed'; export declare const FaceScheme: import("react").ForwardRefExoticComponent>; //# sourceMappingURL=face-scheme.d.ts.map