@sekyro/web 0.1.0-rc.7 → 0.1.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +25 -16
  3. package/README.md +3 -5
  4. package/THIRD-PARTY-NOTICES.txt +154 -0
  5. package/dist/background-monitor-A7FKJOAG.js +1 -0
  6. package/dist/capture-session-doc-YBE3UMJJ.js +1 -0
  7. package/dist/{capture-session-v3-Okq0EQHG.d.ts → capture-session-v3-CQK-G-qX.d.ts} +72 -3
  8. package/dist/{capture-session-v3-UQU_WjO2.d.cts → capture-session-v3-Dvob-uH2.d.cts} +72 -3
  9. package/dist/chunk-4RS2YIL4.js +1 -0
  10. package/dist/chunk-7V2M6Y2W.js +1 -0
  11. package/dist/chunk-7ZCZY3ZP.js +1 -0
  12. package/dist/chunk-A3FUGHAH.js +2 -0
  13. package/dist/chunk-BPE5NSQ2.js +1 -0
  14. package/dist/chunk-CJHMFPL6.js +1 -0
  15. package/dist/chunk-DFTCAWMP.js +1 -0
  16. package/dist/chunk-DK5YPBDQ.js +1 -0
  17. package/dist/chunk-DQWW4OCK.js +1 -0
  18. package/dist/chunk-FHJ7HO3M.js +1 -0
  19. package/dist/chunk-G6LKLN4U.js +1 -0
  20. package/dist/chunk-GI3UFGRQ.js +1 -0
  21. package/dist/{chunk-IYUOYINS.js → chunk-LQ7C44JG.js} +1 -1
  22. package/dist/chunk-M43ET4NJ.js +1 -0
  23. package/dist/chunk-MXWLCDFX.js +1 -0
  24. package/dist/chunk-MY6EXEL2.js +1 -0
  25. package/dist/chunk-O5WKNZ2C.js +1 -0
  26. package/dist/chunk-OKWG3PVH.js +1 -0
  27. package/dist/chunk-POIQGEZM.js +1 -0
  28. package/dist/chunk-RI3E7GBN.js +1 -0
  29. package/dist/chunk-RNRFHUJA.js +1 -0
  30. package/dist/chunk-RVHAKRAI.js +1 -0
  31. package/dist/chunk-SMKCBUJL.js +1 -0
  32. package/dist/chunk-TDLIXFDT.js +1 -0
  33. package/dist/chunk-XLN5OT25.js +1 -0
  34. package/dist/chunk-YDQBVWXG.js +1 -0
  35. package/dist/chunk-YPG7CB4O.js +1 -0
  36. package/dist/client/index.cjs +1 -1
  37. package/dist/client/index.d.cts +13 -3
  38. package/dist/client/index.d.ts +13 -3
  39. package/dist/client/index.js +1 -1
  40. package/dist/core/index.cjs +1 -1
  41. package/dist/core/index.d.cts +3 -3
  42. package/dist/core/index.d.ts +3 -3
  43. package/dist/core/index.js +1 -1
  44. package/dist/core/ocr/worker.bundle.js +42 -0
  45. package/dist/core/ocr/worker.cjs +42 -0
  46. package/dist/core/ocr/worker.d.cts +84 -0
  47. package/dist/core/ocr/worker.d.ts +84 -0
  48. package/dist/core/ocr/worker.js +41 -0
  49. package/dist/core/v3/detect-worker.cjs +1 -1
  50. package/dist/core/v3/detect-worker.d.cts +1 -1
  51. package/dist/core/v3/detect-worker.d.ts +1 -1
  52. package/dist/core/v3/detect-worker.js +1 -1
  53. package/dist/create-document-capture-T4APHJMY.js +1 -0
  54. package/dist/create-portrait-capture-B57GE5FU.js +1 -0
  55. package/dist/create-verification-C0AVIcVW.d.ts +2787 -0
  56. package/dist/create-verification-DoFpgzok.d.cts +2787 -0
  57. package/dist/{detect-worker-CKXHlXx9.d.cts → detect-worker-DclNxkZT.d.cts} +6 -0
  58. package/dist/{detect-worker-CKXHlXx9.d.ts → detect-worker-DclNxkZT.d.ts} +6 -0
  59. package/dist/detector-scanic-YCDNLCGV.js +1 -0
  60. package/dist/icao-gate-D8qm1O2t.d.cts +1655 -0
  61. package/dist/icao-gate-D8qm1O2t.d.ts +1655 -0
  62. package/dist/icao-gate-PWBMKRGC.js +1 -0
  63. package/dist/icao-tuning-4GGVX6B4.js +1 -0
  64. package/dist/index.cjs +1 -1
  65. package/dist/index.d.cts +52 -6
  66. package/dist/index.d.ts +52 -6
  67. package/dist/index.js +1 -1
  68. package/dist/internal/index.cjs +1 -1
  69. package/dist/internal/index.d.cts +345 -308
  70. package/dist/internal/index.d.ts +345 -308
  71. package/dist/internal/index.js +1 -1
  72. package/dist/keyframe-rank-YAJLYJYF.js +1 -0
  73. package/dist/landmarker-KB7LVXAU.js +1 -0
  74. package/dist/mrz-band-VYHOTDHY.js +1 -0
  75. package/dist/plan-runner-UBK4B4CG.js +1 -0
  76. package/dist/segmenter-USLNBX65.js +1 -0
  77. package/dist/turnstile-FATNZ4AG.js +1 -0
  78. package/package.json +22 -4
  79. package/sbom.cdx.json +8 -8
  80. package/dist/chunk-B45J4KC3.js +0 -1
  81. package/dist/chunk-BMA36W2W.js +0 -1
  82. package/dist/chunk-P7ECRN47.js +0 -1
  83. package/dist/chunk-YOB4ZTYN.js +0 -1
  84. package/dist/chunk-YQBK6OIM.js +0 -1
  85. package/dist/create-verification-C2JhOO6Y.d.cts +0 -533
  86. package/dist/create-verification-CGazwtAh.d.ts +0 -533
  87. package/dist/detector-scanic-VQFFXKTL.js +0 -1
  88. package/dist/hosted-client-kBeq-mnJ.d.cts +0 -602
  89. package/dist/hosted-client-kBeq-mnJ.d.ts +0 -602
@@ -1,134 +1,30 @@
1
- import { p as DeviceClass, i as CaptureState, b as CaptureArtifacts, c as CaptureErrorKind } from '../capture-session-v3-UQU_WjO2.cjs';
1
+ import { aR as DocCatalogEntry, aS as LiveMrzTuning, aT as TextLockTuning, aU as OcrEngineClient, aV as DocAssistReport, aW as ReadyInfo, aX as LoadFailure, aY as OcrEngineOptions, aZ as SubmitRuntime, Z as LivenessCaptureOptions, Y as LivenessCaptureHandle, aD as VerificationStep, aB as VerificationResult, as as StepSnapshot, U as LivePhotoGateUpdate, a_ as HostedClientLike } from '../create-verification-DoFpgzok.cjs';
2
+ export { a$ as ANALYSIS_LONG_EDGE, b0 as ASPECT_BANDS, b1 as AttestationError, b2 as BLUR_REFUSE_SHARPNESS_MAX, b3 as BlurStatus, b4 as CAPTURE_CANDIDATE_SPACING_MS, b5 as CAPTURE_EXTRA_CANDIDATES, b6 as CLIP_MIME_ALLOWLIST, b7 as CaptureEngine, b8 as CaptureSessionDoc, b9 as CaptureSessionDocEvents, ba as CaptureSessionDocOptions, bb as DOC_ANALYSIS_DEFAULTS, bc as DOC_CADENCE_HZ, bd as DOC_CAMERA_TUNING_DEFAULTS, be as DOC_CATALOG, bf as DOC_DETECT_WIDTH, bg as DOC_FEEDBACK_STATES, bh as DOC_GATE_V1_DEFAULTS, bi as DOC_SHUTTER_DEFAULTS, bj as DeviceReadHint, bk as DocArtifacts, bl as DocAssist, bm as DocAssistEngine, bn as DocAssistTick, bo as DocCameraTuning, bp as DocCaptureReport, bq as DocCaptureVia, br as DocChecksPayload, bs as DocEngineLike, bt as DocFeedbackAggregator, bu as DocFeedbackKey, bv as DocFeedbackState, bw as DocFormat, bx as DocFrameAnalysis, by as DocFrameMeasures, bz as DocGateQuality, bA as DocGateThresholds, bB as DocGateTick, bC as DocGateTickInput, bD as DocGateV1, bE as DocQuad, bF as DocQuadPoint, bG as DocShutterReason, bH as DocShutterTuning, bI as DocSide, bJ as DocumentCaptureController, bK as DocumentCaptureInternals, bL as EMPTY_GUIDE_METRICS, bM as EncodedDocument, bN as FLIP_FILL_MIN, bO as FLIP_GAP_MS, bP as FLIP_TIMEOUT_MS, bQ as FocusCaps, bR as FramingStatus, bS as GUIDE_LOCK_DEFAULTS, bT as GlareStatus, bU as GrabbedFrame, bV as GuideBlocker, bW as GuideLock, bX as GuideLockTick, bY as GuideLockTuning, bZ as GuideMetrics, b_ as GuideRect, b$ as INFERENCE_RETRY_ATTEMPTS, c0 as INFERENCE_RETRY_DEFAULT_S, R as ISSUER_CODES, c1 as LANDMARKER_MODEL, c2 as LENS_STORAGE_KEY, c3 as LENS_TRY_MAX, c4 as LIVE_MRZ_DEFAULTS, c5 as LIVE_PHOTO_IDLE_MS, c6 as LIVE_PHOTO_MAX_HZ, c7 as LandmarkedFace, c8 as LandmarkerLike, c9 as LensKind, ca as LensSource, cb as LightingStatus, cc as LiveMrzCapture, cd as LiveMrzState, ce as LivePhotoGate, cf as LivePhotoKit, cg as LivePhotoKitInternals, ch as LivePhotoKitOptions, ci as LivePhotoStill, cj as LivenessCaptureInternalHandle, ck as LivenessCaptureInternals, cl as LivenessFlowDeps, cm as LivenessFlowOutcome, cn as MANUAL_SHUTTER_MS, co as MR_DOC_CATALOG, cp as NO_REPORT_MS, cq as OpenDocCameraDeps, cr as PORTRAIT_JPEG_QUALITY, cs as PRELOAD_BLAZE_INIT_TIMEOUT_MS, ct as PRELOAD_BUDGET_MS, cu as PROCESSING_POLL_DELAY_MS, cv as PROCESSING_POLL_MAX, cw as PortraitCaptureController, cx as PortraitCaptureInternals, cy as REGISTRY_RETRY_DELAY_MS, cz as ReticleType, cA as SAME_FACE_MAX_DROPS, cB as ScanEvent, cC as ScanLayout, cD as ScanNotice, cE as ScanPhase, cF as ScanReport, cG as ScanSide, cH as ScanState, cI as SubmitExecutor, cJ as TEXT_LOCK_DEFAULTS, cK as TRANSPORT_REPLAY_ATTEMPTS, cL as TRANSPORT_REPLAY_DELAY_MS, cM as VerificationInternals, cN as analyzeDocFrame, cO as analyzeGuide, cP as aspectBand, cQ as aspectFits, cR as buildDeviceReadHint, cS as coverPointToVideo, cT as createDocumentCaptureInternal, cU as createFaceLandmarker, cV as createLivePhotoKit, cW as createLivenessCaptureInternal, cX as createPortraitCaptureInternal, cY as createVerificationInternal, cZ as docZoomFor, c_ as encodeDocumentImage, c$ as facesOf, d0 as feedbackVoteOf, d1 as focusOk, d2 as guideQuad, d3 as guideRegionInFrame, d4 as initialScanState, d5 as lensKindOf, d6 as mapEngineState, d7 as mapErrorKind, d8 as mapGuidanceHint, d9 as nextScanState, da as observePortraitFrame, db as openDocCamera, dc as passportBandOf, dd as portraitMatchStep, de as preloadedDetectorFactory, df as quadAreaFrac, dg as quadBounds, dh as quadIou, di as quadTiltRatio, dj as randomUuid, dk as rankBackCameras, dl as readStoredLens, dm as resetLivenessAssetsForTests, dn as resolveDocCameraTuning, dp as resolveDocShutterTuning, dq as resolveGuideLockTuning, dr as runLivenessFlow, ds as runSubmission, dt as scannerFormatFor, du as setPreloadLoaderForTests, dv as settledHint, dw as singleShotFocusAt, dx as specularFraction, dy as supportsFocusMode, dz as warmDocDetector, dA as writeStoredLens } from '../create-verification-DoFpgzok.cjs';
2
3
  export { C as CENTERED_FACTOR, a as CIRCLE_RADIUS_FACTOR, I as IN_CIRCLE_FACTOR, d as detectIsMobile } from '../capture-constraints-BujkZcfb.cjs';
3
- import { p as VerificationResult } from '../create-verification-C2JhOO6Y.cjs';
4
- export { A as AttestationError, x as CLIP_MIME_ALLOWLIST, y as CaptureEngine, H as HostedClientLike, I as INFERENCE_RETRY_ATTEMPTS, z as INFERENCE_RETRY_DEFAULT_S, B as LivenessCaptureInternalHandle, E as LivenessCaptureInternals, F as LivenessFlowDeps, J as LivenessFlowOutcome, K as PRELOAD_BLAZE_INIT_TIMEOUT_MS, M as PRELOAD_BUDGET_MS, N as PROCESSING_POLL_DELAY_MS, O as PROCESSING_POLL_MAX, Q as REGISTRY_RETRY_DELAY_MS, T as SubmitExecutor, U as SubmitRuntime, W as TRANSPORT_REPLAY_ATTEMPTS, X as TRANSPORT_REPLAY_DELAY_MS, Y as VerificationInternals, Z as createLivenessCaptureInternal, _ as createVerificationInternal, $ as mapEngineState, a0 as mapErrorKind, a1 as mapGuidanceHint, a2 as preloadedDetectorFactory, a3 as randomUuid, a4 as resetLivenessAssetsForTests, a5 as runLivenessFlow, a6 as runSubmission, a7 as setPreloadLoaderForTests } from '../create-verification-C2JhOO6Y.cjs';
5
- import { C as CheckReason, f as HostedSessionView, g as HostedStepView, q as SessionView, b as CheckType } from '../hosted-client-kBeq-mnJ.cjs';
6
- import '../detect-worker-CKXHlXx9.cjs';
4
+ import { w as HostedSessionView, P as IdentityMethod, b as CheckType, a6 as SessionView, C as CheckReason, x as HostedStepView } from '../icao-gate-D8qm1O2t.cjs';
5
+ export { a7 as BackgroundStats, a8 as Box, a9 as CLIPPED_LUMA, aa as FaceGeometry, ab as FaceLighting, H as HeadPose, ac as ICAO_CANVAS, ad as ICAO_FALLBACK, ae as ICAO_GATE_CRITERIA, af as ICAO_SHARP_REF, I as IcaoCaptureTuning, B as IcaoCoachKey, J as IcaoCriterionState, ag as IcaoFrameObservation, ah as IcaoGate, K as IcaoGateCriterion, ai as IcaoGateOptions, L as IcaoGateSummary, M as IcaoGateUpdate, aj as IcaoJudgedCriterion, ak as IcaoMeasures, al as IcaoPixelStats, am as IcaoProfile, an as LumaPlane, ao as Point, ap as RegionStats, aq as ResolvedIcaoTuning, ar as backgroundStats, as as createIcaoGate, at as eyeLineRoll, au as eyeOpenness, av as eyeSpecular, aw as faceGeometry, ax as faceLighting, ay as faceSharpness, az as icaoPixelStats, aA as icaoWindow, aB as judgeIcao, aC as lumaPlane, aD as percentile, aE as portraitCropRegion, aF as poseFromMatrix, aG as regionStats, aH as resolveIcaoTuning, aI as scoreFrame, aJ as windowOverflow } from '../icao-gate-D8qm1O2t.cjs';
6
+ import '../detect-worker-DclNxkZT.cjs';
7
+ import '../capture-session-v3-Dvob-uH2.cjs';
7
8
 
8
- /** Physical geometry the scanner frames (ISO/IEC 7810 / ICAO 9303). */
9
- type DocFormat = "ID-1" | "ID-3";
10
- type DocSide = "recto" | "verso" | "single";
11
- interface DocCatalogEntry {
12
- /** kyc-docs-v2 `document_type`, verbatim. */
13
- docType: "carte_identite" | "passport";
14
- format: DocFormat;
15
- /** Capture sequence the hosted doc step walks, in order. */
16
- sides: readonly DocSide[];
17
- /** MRZ geometry: td1 = 3×30 (ID-1 verso), td3 = 2×44 (passport data page). */
18
- mrz: "none" | "td1" | "td3";
19
- /** Which side carries the holder photo (drives portrait expectations). */
20
- portraitSide: DocSide;
21
- /** Physical width/height ratio of the framed page. */
22
- aspectRatio: number;
23
- /** Where the subject identifier (NNI) is parsed from, when the doc carries one. */
24
- identifierSource?: "mrz";
25
- }
26
- /**
27
- * Plausibility aspect bands per format (Task 34 gate input): ID-1 cards are
28
- * 85.6×53.98mm → 1.586; an ID-3 passport DATA PAGE frames at ≈125×88mm → 1.42
29
- * (wider tolerance — page curl and hinge shadow skew the detected quad).
30
- */
31
- declare const ASPECT_BANDS: Record<DocFormat, {
32
- center: number;
33
- tolerance: number;
34
- }>;
35
- /** Aspect band for a format — helper the DocGateV1 plausibility check calls. */
36
- declare function aspectBand(format: DocFormat): {
37
- center: number;
38
- tolerance: number;
39
- };
40
- /** The MR docTypes facet (findings §4). Order = the hosted picker's display order. */
41
- declare const MR_DOC_CATALOG: readonly DocCatalogEntry[];
42
-
43
- /** Detect-frame width the session downscales to (findings §1: 25ms median).
44
- * Lives HERE (not detector-scanic.ts) so the session can import it without
45
- * statically pulling the scanic chunk into host bundles. */
46
- declare const DOC_DETECT_WIDTH = 480;
47
- interface DocQuadPoint {
48
- x: number;
49
- y: number;
50
- }
51
- /** Detected document quad, image-space pixels (scanic CornerPoints shape). */
52
- interface DocQuad {
53
- topLeft: DocQuadPoint;
54
- topRight: DocQuadPoint;
55
- bottomRight: DocQuadPoint;
56
- bottomLeft: DocQuadPoint;
57
- }
58
- interface DocGateThresholds {
59
- /** Quad area / frame area below which the doc is too far. */
60
- MIN_AREA_FRAC: number;
61
- /** A corner this close to (or past) a frame edge counts as clipped. */
62
- EDGE_CLIP_MARGIN_PX: number;
63
- /** Consecutive stable plausible+quality ticks required to fire. */
64
- STABLE_TICKS: number;
65
- /** Quad-bbox IoU with the previous tick at/above which the streak holds. */
66
- IOU_STABLE_MIN: number;
67
- /** Integrator slopes, per second — mirrors FaceGateV3's gentle drain. */
68
- RISE_PER_S: number;
69
- FALL_PER_S: number;
70
- /** Quality guidance trigger levels (same semantics as the face gate). */
71
- GUIDE_EXPOSURE: number;
72
- GUIDE_SHARPNESS: number;
73
- /** ID-3 (MRZ-band mode): band width / frame width floor. */
74
- ID3_BAND_MIN_WIDTH_FRAC: number;
75
- /** ID-3 (MRZ-band mode): band aspect (w/h) sanity bounds. */
76
- ID3_BAND_ASPECT_MIN: number;
77
- ID3_BAND_ASPECT_MAX: number;
78
- }
79
- /** Frozen defaults (plan Task 34 — do not retune without a golden update). */
80
- declare const DOC_GATE_V1_DEFAULTS: Readonly<DocGateThresholds>;
81
- interface DocGateQuality {
82
- /** frame-quality.sharpness on the quad crop. */
83
- sharpness: number;
84
- /** frame-quality.exposure on the quad crop. */
85
- exposure: number;
86
- /** Mean crop luma — picks more_light vs too_bright. */
87
- meanLuma: number;
88
- }
89
- interface DocGateTickInput {
90
- timestampMs: number;
91
- quad: DocQuad | null;
92
- quality: DocGateQuality;
93
- frameWidth: number;
94
- frameHeight: number;
95
- }
96
- /** Per-tick output — the scanner chrome contract. */
97
- interface DocGateTick {
98
- at: number;
99
- quad: DocQuad | null;
100
- /** Geometry passed: present × big enough × in frame × right shape. */
101
- plausible: boolean;
102
- /** Integrated progress 0..1 (the overlay ring). */
103
- p: number;
104
- /** dcv1.* message key (host translates; never prose). */
105
- guidanceKey: string;
106
- /** Fire signal: plausible × quality × STABLE_TICKS consecutive high-IoU ticks. */
107
- ready: boolean;
108
- /** Current stability streak length (diagnostics/telemetry). */
109
- stableTicks: number;
110
- }
111
- /** Shoelace area of the quad as a fraction of the frame area. */
112
- declare function quadAreaFrac(quad: DocQuad, frameWidth: number, frameHeight: number): number;
113
- /** IoU of the two quads' axis-aligned bounding boxes (stability metric). */
114
- declare function quadIou(a: DocQuad, b: DocQuad): number;
115
- /** Axis-aligned bounds (width/height) of a quad — the ID-3 band-mode geometry. */
116
- declare function quadBounds(quad: DocQuad): {
117
- width: number;
118
- height: number;
119
- };
120
- declare class DocGateV1 {
121
- private readonly t;
122
- private readonly format;
123
- private p;
124
- private lastTickAt;
125
- private lastQuad;
126
- private streak;
127
- constructor(format: DocFormat, overrides?: Partial<DocGateThresholds>);
128
- reset(): void;
129
- tick(input: DocGateTickInput): DocGateTick;
130
- private edgeClipped;
9
+ type DocumentTypeId = DocCatalogEntry["docType"];
10
+ /** Same shape as the hosted view's `acceptedDocuments`. */
11
+ interface AcceptedDocumentsLike {
12
+ default: "*" | readonly DocumentTypeId[];
13
+ byIssuer?: Readonly<Record<string, readonly DocumentTypeId[]>>;
131
14
  }
15
+ /** Picker order. */
16
+ declare const DOCUMENT_TYPE_ORDER: readonly DocumentTypeId[];
17
+ /** Types accepted for documents of `issuer` (ISO alpha-2), in picker order. */
18
+ declare function acceptedTypesFor(accepted: AcceptedDocumentsLike, issuer: string): DocumentTypeId[];
19
+ /** Issuers with at least one accepted type, sorted by code (the UI re-sorts by name). */
20
+ declare function acceptedIssuers(accepted: AcceptedDocumentsLike, codes?: readonly string[]): string[];
21
+ /** `acceptedDocuments`, or — from a server that predates it — MR with the legacy list. */
22
+ declare function resolveAcceptedDocuments(view: {
23
+ acceptedDocuments?: AcceptedDocumentsLike | undefined;
24
+ acceptedDocumentTypes?: readonly DocumentTypeId[] | undefined;
25
+ }): AcceptedDocumentsLike;
26
+ /** 🇲🇷-style flag from an alpha-2 code (regional indicator symbols). */
27
+ declare function flagOf(iso2: string): string;
132
28
 
133
29
  interface MrzBand {
134
30
  x: number;
@@ -162,195 +58,258 @@ declare const MRZ_BAND_DEFAULTS: Readonly<MrzBandThresholds>;
162
58
  */
163
59
  declare function detectMrzBand(frame: ImageData, overrides?: Partial<MrzBandThresholds>): MrzBand | null;
164
60
 
165
- type FramingStatus = "no_document" | "too_far" | "too_close" | "edge_clipped" | "wrong_shape" | "tilted" | "ok";
166
- type LightingStatus = "too_dark" | "too_bright" | "ok";
167
- type BlurStatus = "blurry" | "ok";
168
- type GlareStatus = "glare" | "ok";
169
- /** The per-frame analysis vector (every axis judged independently). */
170
- interface DocFrameAnalysis {
171
- framing: FramingStatus;
172
- lighting: LightingStatus;
173
- blur: BlurStatus;
174
- glare: GlareStatus;
175
- /** All-clear: every axis ok — the gate's integrator/stability input. */
176
- acceptable: boolean;
177
- }
178
- interface DocFrameMeasures {
179
- /** frame-quality sharpness on the doc-region crop (0..1). */
180
- sharpness: number;
181
- /** frame-quality exposure on the doc-region crop (0..1). */
182
- exposure: number;
183
- /** Mean crop luma (0..255) — picks too_dark vs too_bright. */
184
- meanLuma: number;
185
- /** Fraction of crop pixels at/above the specular ceiling (0..1). */
186
- specularFraction: number;
61
+ type CapabilityFailure = "simd" | "worker" | "bitmap" | "memory";
62
+ type Capability = {
63
+ ok: true;
64
+ } | {
65
+ ok: false;
66
+ reason: CapabilityFailure;
67
+ };
68
+ type Probe = {
69
+ WebAssembly?: {
70
+ validate?: (b: BufferSource) => boolean;
71
+ };
72
+ Worker?: unknown;
73
+ createImageBitmap?: unknown;
74
+ navigator?: {
75
+ deviceMemory?: number;
76
+ connection?: {
77
+ saveData?: boolean;
78
+ effectiveType?: string;
79
+ };
80
+ };
81
+ };
82
+ declare function probeCapabilities(t: {
83
+ minDeviceMemoryGb: number;
84
+ }, g?: Probe): Capability;
85
+
86
+ /** This build's engine (packages/sekyro-ocr-wasm wasm-engine.lock.json `engine`). */
87
+ declare const WEB_OCR_ENGINE = "sekyro-ocr-1";
88
+ interface WebOcrPlan {
89
+ /** Create the engine for this session (some OCR path is live). */
90
+ enabled: boolean;
91
+ liveMrz: (LiveMrzTuning & {
92
+ hint: boolean;
93
+ stillConfirm: boolean;
94
+ }) | null;
95
+ textLock: TextLockTuning | null;
96
+ /** The A/B arm per block (`null`: the block is absent or disabled — no report). */
97
+ liveMrzArm: "live" | "control" | null;
98
+ frontLockArm: "live" | "control" | null;
99
+ load: {
100
+ detectorLimit: number;
101
+ loadTimeoutMs: number;
102
+ maxDownloadMs: number;
103
+ minDeviceMemoryGb: number;
104
+ };
105
+ reportSampleRate: number;
187
106
  }
188
- /** Analysis thresholds beyond the gate's — frozen defaults (round 4). */
189
- declare const DOC_ANALYSIS_DEFAULTS: Readonly<{
190
- /** Doc area fraction above which the camera is too close (capture would crop). */
191
- MAX_AREA_FRAC: 0.92;
192
- /** Opposite-side length ratio beyond which the view is too oblique. */
193
- TILT_MAX_SIDE_RATIO: 1.3;
194
- /** Specular-pixel fraction at/above which the frame reads as glare. */
195
- GLARE_MAX_SPECULAR_FRAC: 0.025;
196
- }>;
197
- /** Fraction of crop pixels with luma ≥ 252 — cheap specular-highlight measure. */
198
- declare function specularFraction(crop: ImageData): number;
199
- /** Opposite-side length ratio of the quad (1 = fronto-parallel). */
200
- declare function quadTiltRatio(quad: DocQuad): number;
107
+ /** `capture.document` → the plan. `mode: "off"` (the embedded option) turns every OCR path off. */
108
+ declare function resolveWebOcrPlan(document: unknown, o?: {
109
+ mode?: "auto" | "off";
110
+ engine?: string;
111
+ }): WebOcrPlan;
112
+ type WebOcrStart = {
113
+ ok: true;
114
+ engine: OcrEngineClient;
115
+ } | {
116
+ ok: false;
117
+ reason: "unsupported" | "off";
118
+ };
201
119
  /**
202
- * Judge one frame. `detectionMode` mirrors the gate: ID-1 quads carry
203
- * area/aspect/tilt semantics; ID-3 MRZ bands carry width-fraction semantics
204
- * (band rects are axis-aligned, so tilt/aspect checks are band-specific).
120
+ * Create the engine when the plan, the device (SIMD, workers, bitmaps, memory) and the network allow; else the reason
121
+ * (`off`: nothing enabled for this session; `unsupported`: the device or a slow / Save-Data connection).
205
122
  */
206
- declare function analyzeDocFrame(input: {
207
- format: DocFormat;
208
- quad: DocQuad | null;
209
- frameWidth: number;
210
- frameHeight: number;
211
- measures: DocFrameMeasures;
212
- thresholds?: Partial<DocGateThresholds>;
213
- }): DocFrameAnalysis;
214
-
215
- /** Feedback vocabulary (dcv2.* message keys on the hosted side). */
216
- type DocFeedbackKey = "sensing" | "too_far" | "too_close" | "edge_clipped" | "wrong_shape" | "tilted" | "too_dark" | "too_bright" | "blurry" | "glare" | "hold_still" | "processing" | "side_captured" | "captured";
217
- /** Reticle rendering mode per feedback state (the stage maps to visuals). */
218
- type ReticleType = "searching" | "coaching" | "locking" | "processing" | "flip" | "done";
219
- interface DocFeedbackState {
220
- key: DocFeedbackKey;
221
- reticle: ReticleType;
222
- /** The state holds the UI at least this long (ms) before a switch. */
223
- minDurationMs: number;
123
+ declare function startWebOcr(plan: WebOcrPlan, o: Pick<OcrEngineOptions, "baseUrl" | "salt" | "workerUrl" | "createWorker" | "page"> & {
124
+ probe?: typeof probeCapabilities;
125
+ slow?: () => boolean;
126
+ }): WebOcrStart;
127
+ type BrowserFamily = "chrome" | "safari" | "samsung" | "firefox" | "other";
128
+ /** A fixed browser family (spec §10): from UA brands / tokens, never the UA string itself. */
129
+ declare function browserFamily(ua?: string): BrowserFamily;
130
+ /** The `live_mrz` wire report (identity-backend capture-report.schema.ts LiveMrzReportSchema). Enums and integers only. */
131
+ interface LiveMrzWireReport {
132
+ kind: "live_mrz";
133
+ platform: "web";
134
+ engine: string;
135
+ arm: "live" | "control";
136
+ capture: "recto" | "verso" | "single";
137
+ outcome: "valid" | "locked" | "timeout" | "slow" | "unsupported" | "download" | "integrity" | "error" | "off";
138
+ reads: number;
139
+ format?: "TD1" | "TD2" | "TD3";
140
+ framesToValid?: number;
141
+ msToValid?: number;
142
+ framesToLock?: number;
143
+ msToLock?: number;
144
+ msToCapture?: number;
145
+ warmupMs?: number;
146
+ readP50Ms?: number;
147
+ readP90Ms?: number;
148
+ downloadMs?: number;
149
+ cached?: boolean;
150
+ stillConfirmed?: boolean;
151
+ typeMismatch?: boolean;
152
+ deviceClass?: "fast" | "mid" | "slow";
153
+ browser: BrowserFamily;
224
154
  }
225
- declare const DOC_FEEDBACK_STATES: Readonly<Record<DocFeedbackKey, DocFeedbackState>>;
226
- /** Frame analysis → the feedback vote it casts (worst axis speaks). */
227
- declare function feedbackVoteOf(analysis: DocFrameAnalysis): DocFeedbackKey;
228
- /** Sliding vote window + exponential decay + per-state minimum hold. */
229
- declare class DocFeedbackAggregator {
230
- private readonly windowMs;
231
- /** Per-second decay factor — recent frames outvote stale ones. */
232
- private readonly decayPerSecond;
233
- private votes;
234
- private current;
235
- private currentSinceMs;
236
- constructor(windowMs?: number,
237
- /** Per-second decay factor — recent frames outvote stale ones. */
238
- decayPerSecond?: number);
239
- reset(): void;
240
- /** Force a terminal/choreography state (capture fired, side flip, upload). */
241
- force(key: Extract<DocFeedbackKey, "processing" | "side_captured" | "captured">, nowMs: number): DocFeedbackState;
242
- /** Cast this frame's vote and return the (possibly held) winning state. */
243
- tick(vote: DocFeedbackKey, nowMs: number): DocFeedbackState;
244
- }
245
-
246
155
  /**
247
- * Pre-fetch + cache the scanic chunk (call when the scan surface MOUNTS, before
248
- * the camera is even granted) so the first detect tick pays no chunk-fetch
249
- * latency. Fire-and-forget; failures fall back to the lazy path.
156
+ * One face's report: from the assist's report when it ran, else the engine's load outcome (`unsupported`, `download`,
157
+ * `integrity`, `error`/`timeout` → error) or `off` (the control arm). `arm` = the block's arm for this face.
250
158
  */
251
- declare function warmDocDetector(): void;
252
- /** Doc detect cadence per device class — scanic @480px is ~3–8× a face tick,
253
- * so the doc loop paces slower than the face profiles (findings §1: 2–5 Hz). */
254
- declare const DOC_CADENCE_HZ: Readonly<Record<DeviceClass, number>>;
255
- interface DocChecksPayload {
256
- engine: "docv1";
257
- /** Gate integrator 0..1 — the overlay ring. */
258
- p: number;
259
- plausible: boolean;
260
- stableTicks: number;
261
- quad: DocQuad | null;
262
- /** Detect-frame size the quad coordinates live in (overlay scaling). */
263
- frameWidth: number;
264
- frameHeight: number;
265
- /** Capture-v2 per-frame status vector (framing/lighting/blur/glare). */
266
- analysis: DocFrameAnalysis;
267
- }
268
- /** Artifacts: `keyframe` = the full-res still of the framed side (JPEG). */
269
- type DocArtifacts = CaptureArtifacts & {
270
- side?: DocSide;
271
- };
272
- interface CaptureSessionDocEvents {
273
- statechange: {
274
- state: CaptureState;
275
- };
276
- checks: DocChecksPayload;
277
- /** dcv1.* message KEY — hosts translate; never prose. Deduped. */
278
- guidance: {
279
- key: string;
280
- };
281
- /** Capture-v2 AGGREGATED feedback (time-decay voted, min-duration held) —
282
- * the stage's message + reticle channel. Deduped on state key. */
283
- feedback: DocFeedbackState;
284
- artifacts: DocArtifacts;
285
- error: {
286
- kind: CaptureErrorKind;
287
- retryable: boolean;
159
+ declare function liveMrzWireReport(i: {
160
+ arm: "live" | "control";
161
+ capture: "recto" | "verso" | "single";
162
+ assist?: DocAssistReport | null;
163
+ load?: ReadyInfo | LoadFailure | "off" | null;
164
+ msToCapture?: number;
165
+ stillConfirmed?: boolean;
166
+ typeMismatch?: boolean;
167
+ browser?: BrowserFamily;
168
+ engine?: string;
169
+ }): LiveMrzWireReport;
170
+ /** A valid live read whose format contradicts the picked document (spec D5 state 4): TD3 on a card, TD1/TD2 on a passport. */
171
+ declare function formatMismatch(format: "TD1" | "TD2" | "TD3" | undefined, picked: "passport" | "card"): boolean;
172
+
173
+ declare const OCR_ASSET_SET: {
174
+ readonly fp12: "08390000c48a";
175
+ readonly engine: "sekyro-ocr-1";
176
+ readonly precision: "fp32";
177
+ readonly files: {
178
+ readonly "sekyro-ocr.wasm": {
179
+ readonly bytes: 3550608;
180
+ readonly sha256: "c15968a6de3d2225e2fdbf36d71a9214c2910419056c6878444fd2d0567bb748";
181
+ readonly tier: "live";
182
+ readonly contentType: "application/wasm";
183
+ };
184
+ readonly "sekyro-ocr.mjs": {
185
+ readonly bytes: 4270;
186
+ readonly sha256: "209a78d96ca53344996a0c2300aed4ff8a5c69e142713216975a2840eec08cac";
187
+ readonly tier: "bundled";
188
+ readonly contentType: "text/javascript";
189
+ };
190
+ readonly "det.param": {
191
+ readonly bytes: 24252;
192
+ readonly sha256: "c39ba0b1195e8ad37cfc5bdd7acedcfc1d9cb901e7b8eb1c9c4f6e5a66c04eb3";
193
+ readonly tier: "live";
194
+ readonly contentType: "text/plain";
195
+ };
196
+ readonly "det.bin": {
197
+ readonly bytes: 4685856;
198
+ readonly sha256: "652bafe366565109a1a5766caf482bc46f01481f8044d3a785bd9a1be67c63bb";
199
+ readonly tier: "live";
200
+ readonly contentType: "application/octet-stream";
201
+ };
202
+ readonly "mrz-rec.param": {
203
+ readonly bytes: 3510;
204
+ readonly sha256: "bc69b1b9683e35f6605b21001fadeb81468063459c00c0fc83c67c139f23df01";
205
+ readonly tier: "live";
206
+ readonly contentType: "text/plain";
207
+ };
208
+ readonly "mrz-rec.bin": {
209
+ readonly bytes: 494196;
210
+ readonly sha256: "de93a2aa2f08670cc7dedd17ba378d2f5d7cf6ae409054a9eac863a02c2febae";
211
+ readonly tier: "live";
212
+ readonly contentType: "application/octet-stream";
213
+ };
214
+ readonly "mrz_dict.txt": {
215
+ readonly bytes: 73;
216
+ readonly sha256: "b19858a4de2ccbbbdd4b53982188ea2c7664013183bbd1ae9d20ab52c661f97f";
217
+ readonly tier: "live";
218
+ readonly contentType: "text/plain";
219
+ };
220
+ readonly "latin-rec.param": {
221
+ readonly bytes: 19602;
222
+ readonly sha256: "2ae30dfdc7ee482c6cbbc0419c16ee125e880e9eaf69053d61953694bb0fcf4c";
223
+ readonly tier: "lazy";
224
+ readonly contentType: "text/plain";
225
+ };
226
+ readonly "latin-rec.bin": {
227
+ readonly bytes: 10750388;
228
+ readonly sha256: "f91ebdcf4d6b58c58a87704160e59d07ae56bc2d5021eae09d095c5a20bf7525";
229
+ readonly tier: "lazy";
230
+ readonly contentType: "application/octet-stream";
231
+ };
232
+ readonly "ppocr_keys_v1.txt": {
233
+ readonly bytes: 26249;
234
+ readonly sha256: "28b2362ad4ab2dc38769aa72feb535e3a9ddb3fd2a7585a05920e6393b1dc7f7";
235
+ readonly tier: "lazy";
236
+ readonly contentType: "text/plain";
237
+ };
238
+ readonly "arabic-rec.param": {
239
+ readonly bytes: 9858;
240
+ readonly sha256: "4e5cc85667dfaaa0c67d3f308400645a578c08bd43f952cab6c55b7bce143ea9";
241
+ readonly tier: "lazy";
242
+ readonly contentType: "text/plain";
243
+ };
244
+ readonly "arabic-rec.bin": {
245
+ readonly bytes: 8853572;
246
+ readonly sha256: "5acc3265a1738dc31316258383830d5dbdfa5e8ebc2e710f9001f832ecfbffb0";
247
+ readonly tier: "lazy";
248
+ readonly contentType: "application/octet-stream";
249
+ };
250
+ readonly "arabic_dict.txt": {
251
+ readonly bytes: 405;
252
+ readonly sha256: "637c27c88512c22089bef927b34ada08f748dc132ac70facd68d8202384c2726";
253
+ readonly tier: "lazy";
254
+ readonly contentType: "text/plain";
255
+ };
288
256
  };
289
- }
290
- interface CaptureSessionDocOptions {
291
- /** Host-owned <video playsInline muted>. */
292
- video: HTMLVideoElement;
293
- format?: DocFormat;
294
- /** Side label stamped on the artifacts event (recto→verso sequencing). */
295
- side?: DocSide;
296
- thresholds?: Partial<DocGateThresholds>;
297
- deviceClass?: DeviceClass;
298
- /** (navigator.mediaDevices.getUserMedia — environment camera) */
299
- getUserMedia?: (constraints: MediaStreamConstraints) => Promise<MediaStream>;
300
- /** (vendored scanic detectQuad) */
301
- detect?: (image: ImageData) => Promise<DocQuad | null>;
302
- /** (canvas downscale of the live video to the 480px detect frame) */
303
- grabDetectFrame?: (video: HTMLVideoElement, targetWidth: number) => ImageData | null;
304
- /** (full-res canvas still → JPEG blob + preview; quad passed for telemetry) */
305
- captureStill?: (video: HTMLVideoElement, quad: DocQuad, detectSize: {
306
- width: number;
307
- height: number;
308
- }) => Promise<{
309
- blob: Blob;
310
- previewDataUrl: string;
311
- }>;
312
- /** (performance.now) */
313
- now?: () => number;
314
- /** (setTimeout/clearTimeout) — the cadence pacer. */
315
- setTimer?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;
316
- clearTimer?: (id: ReturnType<typeof setTimeout>) => void;
317
- }
318
- type Handler<K extends keyof CaptureSessionDocEvents> = (payload: CaptureSessionDocEvents[K]) => void;
319
- declare class CaptureSessionDoc {
320
- private readonly opts;
321
- private readonly gate;
322
- private readonly cadenceMs;
323
- private readonly handlers;
324
- private stream;
325
- private timer;
326
- private state;
327
- private lastGuidance;
328
- private attempt;
329
- private capturing;
330
- private readonly feedback;
331
- private lastFeedbackKey;
332
- constructor(opts: CaptureSessionDocOptions);
333
- on<K extends keyof CaptureSessionDocEvents>(event: K, handler: Handler<K>): () => void;
334
- private emit;
335
- start(): Promise<void>;
336
- /** Restart the gate for another side / a retake (same stream). */
337
- rearm(side?: DocSide): void;
338
- destroy(): void;
339
- private setState;
340
- private scheduleTick;
341
- private tick;
257
+ };
258
+
259
+ /** `processing` re-reads (1+2+4+8+15 = 30 s, spec §6.5), then `stalled`. */
260
+ declare const PROCESSING_BACKOFF_MS: readonly number[];
261
+ /** Hosted parity: a resend is offered 30 s after the last send. */
262
+ declare const OTP_RESEND_COOLDOWN_MS = 30000;
263
+ type Executor = (client: HostedClientLike, idempotencyKey: string) => Promise<SessionView>;
264
+ interface RunnerDeps {
265
+ runtime: SubmitRuntime;
266
+ currentView(): HostedSessionView | null;
267
+ ensureView(): Promise<HostedSessionView>;
268
+ refreshView(): Promise<HostedSessionView>;
269
+ ensureConsent(): Promise<void>;
270
+ selectMethod(method: IdentityMethod): Promise<void>;
271
+ liveness(options: LivenessCaptureOptions): LivenessCaptureHandle;
272
+ /** A liveness submission chain is in flight (do not flip the UI mid-upload). */
273
+ chainBusy(): boolean;
274
+ destroyed(): boolean;
275
+ sleep(ms: number): Promise<void>;
276
+ isMobile(): boolean;
277
+ now(): number;
278
+ emitStep(step: VerificationStep): void;
279
+ emitResult(result: VerificationResult): void;
342
280
  /**
343
- * BEST-FRAME capture window (capture-v2): the first ready tick captures a
344
- * candidate immediately, then up to CAPTURE_EXTRA_CANDIDATES more stills are
345
- * taken at CAPTURE_CANDIDATE_SPACING_MS while the user holds — each scored
346
- * by the live detect-tick sharpness at its capture moment — and the SHARPEST
347
- * wins. Beats first-acceptable-frame capture without decoding stills.
281
+ * The promoted face_match probe key of the last liveness submission (profile
282
+ * v2 §4.4 wrong-number re-entry): after the re-entered NNI passes, the
283
+ * `pending` face_match is resubmitted with it — no new capture. `null` when
284
+ * no liveness was submitted from this page (e.g. after a reload).
348
285
  */
349
- private fire;
286
+ keptFaceKey?(): string | null;
287
+ /** Task 4: binds the document step (selectDocument + capture). */
288
+ bindDocument?(snapshot: Extract<StepSnapshot, {
289
+ kind: "document";
290
+ }>, republish: () => void): VerificationStep;
291
+ /** SDK spec §4.9: binds the ICAO portrait step (capture + portrait_icao / face_match submissions). */
292
+ bindPortrait?(snapshot: Extract<StepSnapshot, {
293
+ kind: "portrait";
294
+ }>, republish: () => void): VerificationStep;
295
+ /** Commit a view an action answered (flow model 2026-10-23); absent → re-read the view. */
296
+ setView?(view: HostedSessionView): void;
297
+ /** Step 3 one capture: the ICAO coaching of the running live-photo capture. */
298
+ onLivePhoto?(handler: (gate: LivePhotoGateUpdate) => void): () => void;
350
299
  }
351
- /** Best-frame window: 2 extra candidates, 260ms apart, ≥8% sharper to replace. */
352
- declare const CAPTURE_EXTRA_CANDIDATES = 2;
353
- declare const CAPTURE_CANDIDATE_SPACING_MS = 260;
300
+ interface StepRunner {
301
+ run(): Promise<VerificationStep>;
302
+ current(): VerificationStep | null;
303
+ /** Called by the verification on every view update. */
304
+ onView(view: HostedSessionView): void;
305
+ /** Called when the liveness chain becomes idle. */
306
+ onChainIdle(): void;
307
+ /** Re-derive from the current view and publish even if unchanged (local overlay changed). */
308
+ republish(): void;
309
+ /** Submit one step input (exposed for the document binding, Task 4). */
310
+ submit(checkType: CheckType, executor: Executor, onAccepted?: () => void): Promise<void>;
311
+ }
312
+ declare function createStepRunner(deps: RunnerDeps): StepRunner;
354
313
 
355
314
  /**
356
315
  * Reasons the backend parks at `input_required` while attempts remain
@@ -431,4 +390,82 @@ interface ExecuteTurnstileOptions {
431
390
  */
432
391
  declare function executeTurnstile(siteKey: string, opts?: ExecuteTurnstileOptions): Promise<string>;
433
392
 
434
- export { ASPECT_BANDS, type BlurStatus, CAPTURE_CANDIDATE_SPACING_MS, CAPTURE_EXTRA_CANDIDATES, CaptureSessionDoc, type CaptureSessionDocEvents, type CaptureSessionDocOptions, DOC_ANALYSIS_DEFAULTS, DOC_CADENCE_HZ, DOC_DETECT_WIDTH, DOC_FEEDBACK_STATES, DOC_GATE_V1_DEFAULTS, type DocArtifacts, type DocCatalogEntry, type DocChecksPayload, DocFeedbackAggregator, type DocFeedbackKey, type DocFeedbackState, type DocFormat, type DocFrameAnalysis, type DocFrameMeasures, type DocGateQuality, type DocGateThresholds, type DocGateTick, type DocGateTickInput, DocGateV1, type DocQuad, type DocQuadPoint, type DocSide, type ExecuteTurnstileOptions, type FramingStatus, type GlareStatus, type LightingStatus, MRZ_BAND_DEFAULTS, MR_DOC_CATALOG, type MrzBand, type MrzBandThresholds, RETRYABLE_REASONS, type ReticleType, TURNSTILE_EXECUTE_TIMEOUT_MS, TURNSTILE_SCRIPT_SRC, type TurnstileApi, type TurnstileRenderParams, analyzeDocFrame, aspectBand, detectMrzBand, executeTurnstile, feedbackVoteOf, frontierStep, isExecutable, isTerminalView, loadTurnstile, mapSessionResult, mergeSessionView, quadAreaFrac, quadBounds, quadIou, quadTiltRatio, resetTurnstileForTests, specularFraction, stepOf, warmDocDetector };
393
+ /**
394
+ * Face of a decoded still: an MRZ band means the verso. With `cardOnly` (the still is the card itself) the band must
395
+ * sit in its lower half, where a card's MRZ is: the line of print across a recto's top (the issuing state) is not one.
396
+ */
397
+ declare function classifyCardSideWith(detect: typeof detectMrzBand, still: ImageData, cardOnly?: boolean): "recto" | "verso";
398
+ /** {@link classifyCardSideWith} with the MRZ-band detector loaded on demand. */
399
+ declare function classifyCardSide(still: ImageData, cardOnly?: boolean): Promise<"recto" | "verso">;
400
+ /** Downscale a captured JPEG to a 480 px-wide ImageData for the classifier. */
401
+ declare function stillToImageData(blob: Blob, width?: number): Promise<ImageData | null>;
402
+
403
+ /** Long side the measure runs at (Mattel: about what the recognizer sees of a card). */
404
+ declare const SHARPNESS_LONG_EDGE = 1000;
405
+ /** Inverse-edge-width sharpness of an RGBA image; `-1` for an unusable one (< 16 px). */
406
+ declare function photoSharpness(image: {
407
+ data: ArrayLike<number>;
408
+ width: number;
409
+ height: number;
410
+ }): number;
411
+ /** A rectangle of the full-resolution still, in its pixels. */
412
+ interface StillRegion {
413
+ x: number;
414
+ y: number;
415
+ width: number;
416
+ height: number;
417
+ }
418
+ /** Padding around the card's bounding box, as a fraction of its size per side. */
419
+ declare const REGION_PAD = 0.06;
420
+ /**
421
+ * The card region of the still (Mattel measures the guide region, not the
422
+ * whole photo): the bounding box of the last gate quad — in detect-frame
423
+ * coordinates — scaled to the still, padded by {@link REGION_PAD} and clamped.
424
+ * `null` when there is no usable quad (then the whole still is measured).
425
+ */
426
+ declare function stillRegionOf(quad: {
427
+ topLeft: {
428
+ x: number;
429
+ y: number;
430
+ };
431
+ topRight: {
432
+ x: number;
433
+ y: number;
434
+ };
435
+ bottomRight: {
436
+ x: number;
437
+ y: number;
438
+ };
439
+ bottomLeft: {
440
+ x: number;
441
+ y: number;
442
+ };
443
+ } | null, frame: {
444
+ width: number;
445
+ height: number;
446
+ }, still: {
447
+ width: number;
448
+ height: number;
449
+ }, pad?: number): StillRegion | null;
450
+ type RawImage = {
451
+ data: ArrayLike<number>;
452
+ width: number;
453
+ height: number;
454
+ };
455
+ /** Crop `region` out of an RGBA image (pure; the canvas path does the same with drawImage). */
456
+ declare function cropImage(image: RawImage, region: StillRegion): {
457
+ data: Uint8ClampedArray;
458
+ width: number;
459
+ height: number;
460
+ };
461
+ /** Area-average downscale so the long side is at most `longEdge` (pure; mirrors cv INTER_AREA). */
462
+ declare function resizeLongEdge(image: RawImage, longEdge?: number): RawImage;
463
+ /** The blur-gate measure of a still: its card region (or the whole still), scaled to ≤ 1000 px. */
464
+ declare function measureRegionSharpness(image: RawImage, region: StillRegion | null): number;
465
+ /**
466
+ * Browser path of {@link measureRegionSharpness} on an already decoded still:
467
+ * one drawImage crops and scales the region; the canvas is released after.
468
+ */
469
+ declare function measureBitmapSharpness(bitmap: ImageBitmap, region: StillRegion | null): number;
470
+
471
+ export { type AcceptedDocumentsLike, type BrowserFamily, DOCUMENT_TYPE_ORDER, DocAssistReport, DocCatalogEntry, type DocumentTypeId, type ExecuteTurnstileOptions, HostedClientLike, LiveMrzTuning, type LiveMrzWireReport, LoadFailure, MRZ_BAND_DEFAULTS, type MrzBand, type MrzBandThresholds, OCR_ASSET_SET, OTP_RESEND_COOLDOWN_MS, OcrEngineClient, PROCESSING_BACKOFF_MS, REGION_PAD, RETRYABLE_REASONS, ReadyInfo, type RunnerDeps, SHARPNESS_LONG_EDGE, type StepRunner, type StillRegion, SubmitRuntime, TURNSTILE_EXECUTE_TIMEOUT_MS, TURNSTILE_SCRIPT_SRC, TextLockTuning, type TurnstileApi, type TurnstileRenderParams, WEB_OCR_ENGINE, type WebOcrPlan, type WebOcrStart, acceptedIssuers, acceptedTypesFor, browserFamily, classifyCardSide, classifyCardSideWith, createStepRunner, cropImage, detectMrzBand, executeTurnstile, flagOf, formatMismatch, frontierStep, isExecutable, isTerminalView, liveMrzWireReport, loadTurnstile, mapSessionResult, measureBitmapSharpness, measureRegionSharpness, mergeSessionView, photoSharpness, resetTurnstileForTests, resizeLongEdge, resolveAcceptedDocuments, resolveWebOcrPlan, startWebOcr, stepOf, stillRegionOf, stillToImageData };