@mikashboks/capture-intelligence-core 0.1.0

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/dist/cjs/__fixtures__/address-flow.fixtures.d.ts +35 -0
  2. package/dist/cjs/__fixtures__/address-flow.fixtures.d.ts.map +1 -0
  3. package/dist/cjs/__fixtures__/address-flow.fixtures.js +186 -0
  4. package/dist/cjs/__fixtures__/address-flow.fixtures.js.map +1 -0
  5. package/dist/cjs/__fixtures__/metadata-review.fixtures.d.ts +11 -0
  6. package/dist/cjs/__fixtures__/metadata-review.fixtures.d.ts.map +1 -0
  7. package/dist/cjs/__fixtures__/metadata-review.fixtures.js +69 -0
  8. package/dist/cjs/__fixtures__/metadata-review.fixtures.js.map +1 -0
  9. package/dist/cjs/address-proof.d.ts +33 -0
  10. package/dist/cjs/address-proof.d.ts.map +1 -0
  11. package/dist/cjs/address-proof.js +97 -0
  12. package/dist/cjs/address-proof.js.map +1 -0
  13. package/dist/cjs/document-classifier.d.ts +19 -0
  14. package/dist/cjs/document-classifier.d.ts.map +1 -0
  15. package/dist/cjs/document-classifier.js +213 -0
  16. package/dist/cjs/document-classifier.js.map +1 -0
  17. package/dist/cjs/flow-routing.d.ts +7 -0
  18. package/dist/cjs/flow-routing.d.ts.map +1 -0
  19. package/dist/cjs/flow-routing.js +45 -0
  20. package/dist/cjs/flow-routing.js.map +1 -0
  21. package/dist/cjs/index.d.ts +25 -0
  22. package/dist/cjs/index.d.ts.map +1 -0
  23. package/dist/cjs/index.js +83 -0
  24. package/dist/cjs/index.js.map +1 -0
  25. package/dist/cjs/metadata-review.d.ts +10 -0
  26. package/dist/cjs/metadata-review.d.ts.map +1 -0
  27. package/dist/cjs/metadata-review.js +93 -0
  28. package/dist/cjs/metadata-review.js.map +1 -0
  29. package/dist/cjs/metrics.d.ts +115 -0
  30. package/dist/cjs/metrics.d.ts.map +1 -0
  31. package/dist/cjs/metrics.js +302 -0
  32. package/dist/cjs/metrics.js.map +1 -0
  33. package/dist/cjs/quality-checks.d.ts +170 -0
  34. package/dist/cjs/quality-checks.d.ts.map +1 -0
  35. package/dist/cjs/quality-checks.js +417 -0
  36. package/dist/cjs/quality-checks.js.map +1 -0
  37. package/dist/cjs/sobel.d.ts +61 -0
  38. package/dist/cjs/sobel.d.ts.map +1 -0
  39. package/dist/cjs/sobel.js +179 -0
  40. package/dist/cjs/sobel.js.map +1 -0
  41. package/dist/cjs/types.d.ts +98 -0
  42. package/dist/cjs/types.d.ts.map +1 -0
  43. package/dist/cjs/types.js +38 -0
  44. package/dist/cjs/types.js.map +1 -0
  45. package/dist/esm/__fixtures__/address-flow.fixtures.d.ts +35 -0
  46. package/dist/esm/__fixtures__/address-flow.fixtures.d.ts.map +1 -0
  47. package/dist/esm/__fixtures__/address-flow.fixtures.js +183 -0
  48. package/dist/esm/__fixtures__/address-flow.fixtures.js.map +1 -0
  49. package/dist/esm/__fixtures__/metadata-review.fixtures.d.ts +11 -0
  50. package/dist/esm/__fixtures__/metadata-review.fixtures.d.ts.map +1 -0
  51. package/dist/esm/__fixtures__/metadata-review.fixtures.js +66 -0
  52. package/dist/esm/__fixtures__/metadata-review.fixtures.js.map +1 -0
  53. package/dist/esm/address-proof.d.ts +33 -0
  54. package/dist/esm/address-proof.d.ts.map +1 -0
  55. package/dist/esm/address-proof.js +86 -0
  56. package/dist/esm/address-proof.js.map +1 -0
  57. package/dist/esm/document-classifier.d.ts +19 -0
  58. package/dist/esm/document-classifier.d.ts.map +1 -0
  59. package/dist/esm/document-classifier.js +209 -0
  60. package/dist/esm/document-classifier.js.map +1 -0
  61. package/dist/esm/flow-routing.d.ts +7 -0
  62. package/dist/esm/flow-routing.d.ts.map +1 -0
  63. package/dist/esm/flow-routing.js +41 -0
  64. package/dist/esm/flow-routing.js.map +1 -0
  65. package/dist/esm/index.d.ts +25 -0
  66. package/dist/esm/index.d.ts.map +1 -0
  67. package/dist/esm/index.js +19 -0
  68. package/dist/esm/index.js.map +1 -0
  69. package/dist/esm/metadata-review.d.ts +10 -0
  70. package/dist/esm/metadata-review.d.ts.map +1 -0
  71. package/dist/esm/metadata-review.js +90 -0
  72. package/dist/esm/metadata-review.js.map +1 -0
  73. package/dist/esm/metrics.d.ts +115 -0
  74. package/dist/esm/metrics.d.ts.map +1 -0
  75. package/dist/esm/metrics.js +291 -0
  76. package/dist/esm/metrics.js.map +1 -0
  77. package/dist/esm/quality-checks.d.ts +170 -0
  78. package/dist/esm/quality-checks.d.ts.map +1 -0
  79. package/dist/esm/quality-checks.js +400 -0
  80. package/dist/esm/quality-checks.js.map +1 -0
  81. package/dist/esm/sobel.d.ts +61 -0
  82. package/dist/esm/sobel.d.ts.map +1 -0
  83. package/dist/esm/sobel.js +173 -0
  84. package/dist/esm/sobel.js.map +1 -0
  85. package/dist/esm/types.d.ts +98 -0
  86. package/dist/esm/types.d.ts.map +1 -0
  87. package/dist/esm/types.js +35 -0
  88. package/dist/esm/types.js.map +1 -0
  89. package/package.json +65 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Frame metrics computation on raw pixel arrays.
3
+ *
4
+ * DOM-free: all functions accept Uint8Array / numeric data. No
5
+ * HTMLVideoElement, HTMLCanvasElement, or any browser API.
6
+ *
7
+ * The caller is responsible for capturing pixel data from the video/camera
8
+ * source and providing the overlay region. This module computes brightness,
9
+ * blur (Laplacian variance), edge energy, frame-to-frame stability, and
10
+ * document rectangle detection.
11
+ */
12
+ import type { FrameMetrics, OverlayRegion, OverlayVariant } from './types.js';
13
+ /**
14
+ * Convert an RGBA pixel buffer to greyscale in-place into a pre-allocated
15
+ * output array. Uses fixed-point ITU-R BT.601 weights.
16
+ *
17
+ * @param rgba - RGBA pixel buffer (length = pixelCount * 4)
18
+ * @param out - Pre-allocated Uint8Array to write greyscale values into
19
+ * @param pixelCount - Total pixel count (width * height)
20
+ */
21
+ export declare function rgbaToGreyInPlace(rgba: Uint8ClampedArray | Uint8Array, out: Uint8Array, pixelCount: number): void;
22
+ /**
23
+ * Compute average brightness within a rectangular sub-region of a greyscale
24
+ * image. The region is defined as fractional overlay coordinates [0..1].
25
+ *
26
+ * @param grey - Greyscale pixel array
27
+ * @param w - Image width
28
+ * @param h - Image height
29
+ * @param region - Overlay region in fractional coordinates
30
+ */
31
+ export declare function computeBrightness(grey: Uint8Array, w: number, h: number, region: OverlayRegion): number;
32
+ /**
33
+ * Compute Laplacian variance for sharpness detection.
34
+ * Higher values indicate sharper images.
35
+ *
36
+ * @param grey - Greyscale pixel array
37
+ * @param w - Image width
38
+ * @param h - Image height
39
+ */
40
+ export declare function computeLaplacianVariance(grey: Uint8Array, w: number, h: number): number;
41
+ /**
42
+ * Compute Laplacian variance using floating-point greyscale values.
43
+ * Used for static image quality checks where Float32Array precision is
44
+ * preferred.
45
+ *
46
+ * @param grey - Floating-point greyscale pixel array
47
+ * @param w - Image width
48
+ * @param h - Image height
49
+ */
50
+ export declare function computeLaplacianVarianceFloat(grey: Float32Array, w: number, h: number): number;
51
+ /**
52
+ * Result of edge energy analysis in a sub-region.
53
+ */
54
+ export interface EdgeAnalysisResult {
55
+ /** Average edge magnitude in the region */
56
+ avgEdge: number;
57
+ /** Fraction of pixels with edge magnitude above CAM_EDGE_PIXEL_THRESHOLD */
58
+ edgeCoverage: number;
59
+ /** Per-row accumulated Sobel magnitude (relative to region) */
60
+ rowEnergy: Float32Array;
61
+ /** Per-column accumulated Sobel magnitude (relative to region) */
62
+ colEnergy: Float32Array;
63
+ /** Width of the analysis region */
64
+ regionW: number;
65
+ /** Height of the analysis region */
66
+ regionH: number;
67
+ }
68
+ /**
69
+ * Compute Sobel edge energy within an overlay sub-region of a greyscale image.
70
+ *
71
+ * @param grey - Greyscale pixel array
72
+ * @param w - Full image width
73
+ * @param h - Full image height
74
+ * @param region - Overlay region in fractional coordinates
75
+ */
76
+ export declare function computeEdgeEnergy(grey: Uint8Array, w: number, h: number, region: OverlayRegion): EdgeAnalysisResult;
77
+ /**
78
+ * Detect a document rectangle within edge energy profiles.
79
+ *
80
+ * @returns Area ratio, aspect ratio, and center offset of the detected region.
81
+ */
82
+ export declare function detectDocumentRect(rowEnergy: Float32Array, colEnergy: Float32Array, regionW: number, regionH: number): {
83
+ docAreaRatio: number;
84
+ docAspectRatio: number;
85
+ docCenterOffset: number;
86
+ };
87
+ /**
88
+ * Compute mean absolute difference between two greyscale frames.
89
+ * Returns 999 if no previous frame is available.
90
+ *
91
+ * @param current - Current greyscale frame
92
+ * @param previous - Previous greyscale frame (or null if first frame)
93
+ */
94
+ export declare function computeFrameDiff(current: Uint8Array, previous: Uint8Array | null): number;
95
+ /**
96
+ * Compute all frame metrics from a greyscale image and an overlay region.
97
+ * This is the DOM-free equivalent of `camAnalyzeFrame()`.
98
+ *
99
+ * @param grey - Greyscale pixel array (w * h bytes)
100
+ * @param w - Image width
101
+ * @param h - Image height
102
+ * @param region - Overlay region in fractional coordinates
103
+ * @param prevGreyData - Previous frame's greyscale data (for stability), or null
104
+ * @returns FrameMetrics for the frame
105
+ */
106
+ export declare function analyzeFrame(grey: Uint8Array, w: number, h: number, region: OverlayRegion, prevGreyData: Uint8Array | null): FrameMetrics;
107
+ /**
108
+ * Check whether frame metrics indicate a document-like shape for the given
109
+ * overlay variant. DOM-free: the overlay variant is passed as a value.
110
+ *
111
+ * @param metrics - Computed frame metrics
112
+ * @param variant - Overlay variant ('card', 'passport', or 'a4')
113
+ */
114
+ export declare function looksLikeDocument(metrics: FrameMetrics, variant: OverlayVariant): boolean;
115
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAS9E;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,iBAAiB,GAAG,UAAU,EACpC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,GACjB,IAAI,CAKN;AAID;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,EAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,aAAa,GACpB,MAAM,CAcR;AAID;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB9F;AAID;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,SAAS,EAAE,YAAY,CAAC;IACxB,kEAAkE;IAClE,SAAS,EAAE,YAAY,CAAC;IACxB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,EAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,aAAa,GACpB,kBAAkB,CAiDpB;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CA0D3E;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI,GAAG,MAAM,CAOzF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,UAAU,GAAG,IAAI,GAC9B,YAAY,CA+Bd;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAoBzF"}
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ /**
3
+ * Frame metrics computation on raw pixel arrays.
4
+ *
5
+ * DOM-free: all functions accept Uint8Array / numeric data. No
6
+ * HTMLVideoElement, HTMLCanvasElement, or any browser API.
7
+ *
8
+ * The caller is responsible for capturing pixel data from the video/camera
9
+ * source and providing the overlay region. This module computes brightness,
10
+ * blur (Laplacian variance), edge energy, frame-to-frame stability, and
11
+ * document rectangle detection.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.rgbaToGreyInPlace = rgbaToGreyInPlace;
15
+ exports.computeBrightness = computeBrightness;
16
+ exports.computeLaplacianVariance = computeLaplacianVariance;
17
+ exports.computeLaplacianVarianceFloat = computeLaplacianVarianceFloat;
18
+ exports.computeEdgeEnergy = computeEdgeEnergy;
19
+ exports.detectDocumentRect = detectDocumentRect;
20
+ exports.computeFrameDiff = computeFrameDiff;
21
+ exports.analyzeFrame = analyzeFrame;
22
+ exports.looksLikeDocument = looksLikeDocument;
23
+ const types_js_1 = require("./types.js");
24
+ /* -- Greyscale conversion ------------------------------------------------- */
25
+ /**
26
+ * Convert an RGBA pixel buffer to greyscale in-place into a pre-allocated
27
+ * output array. Uses fixed-point ITU-R BT.601 weights.
28
+ *
29
+ * @param rgba - RGBA pixel buffer (length = pixelCount * 4)
30
+ * @param out - Pre-allocated Uint8Array to write greyscale values into
31
+ * @param pixelCount - Total pixel count (width * height)
32
+ */
33
+ function rgbaToGreyInPlace(rgba, out, pixelCount) {
34
+ for (let i = 0; i < pixelCount; i++) {
35
+ const p = i * 4;
36
+ out[i] = (rgba[p] * 77 + rgba[p + 1] * 150 + rgba[p + 2] * 29) >> 8;
37
+ }
38
+ }
39
+ /* -- Brightness ----------------------------------------------------------- */
40
+ /**
41
+ * Compute average brightness within a rectangular sub-region of a greyscale
42
+ * image. The region is defined as fractional overlay coordinates [0..1].
43
+ *
44
+ * @param grey - Greyscale pixel array
45
+ * @param w - Image width
46
+ * @param h - Image height
47
+ * @param region - Overlay region in fractional coordinates
48
+ */
49
+ function computeBrightness(grey, w, h, region) {
50
+ const bx1 = Math.max(0, Math.round(region.x1 * w));
51
+ const by1 = Math.max(0, Math.round(region.y1 * h));
52
+ const bx2 = Math.min(w, Math.round(region.x2 * w));
53
+ const by2 = Math.min(h, Math.round(region.y2 * h));
54
+ let brightSum = 0;
55
+ let brightCount = 0;
56
+ for (let by = by1; by < by2; by++) {
57
+ for (let bx = bx1; bx < bx2; bx++) {
58
+ brightSum += grey[by * w + bx];
59
+ brightCount++;
60
+ }
61
+ }
62
+ return brightCount > 0 ? brightSum / brightCount : 0;
63
+ }
64
+ /* -- Blur (Laplacian variance) -------------------------------------------- */
65
+ /**
66
+ * Compute Laplacian variance for sharpness detection.
67
+ * Higher values indicate sharper images.
68
+ *
69
+ * @param grey - Greyscale pixel array
70
+ * @param w - Image width
71
+ * @param h - Image height
72
+ */
73
+ function computeLaplacianVariance(grey, w, h) {
74
+ let lapSum = 0;
75
+ let lapCount = 0;
76
+ for (let ly = 1; ly < h - 1; ly++) {
77
+ for (let lx = 1; lx < w - 1; lx++) {
78
+ const ci = ly * w + lx;
79
+ const lap = -4 * grey[ci] + grey[ci - w] + grey[ci + w] + grey[ci - 1] + grey[ci + 1];
80
+ lapSum += lap * lap;
81
+ lapCount++;
82
+ }
83
+ }
84
+ return lapCount > 0 ? lapSum / lapCount : 0;
85
+ }
86
+ /**
87
+ * Compute Laplacian variance using floating-point greyscale values.
88
+ * Used for static image quality checks where Float32Array precision is
89
+ * preferred.
90
+ *
91
+ * @param grey - Floating-point greyscale pixel array
92
+ * @param w - Image width
93
+ * @param h - Image height
94
+ */
95
+ function computeLaplacianVarianceFloat(grey, w, h) {
96
+ let lapSum = 0;
97
+ let lapCount = 0;
98
+ for (let ly = 1; ly < h - 1; ly++) {
99
+ for (let lx = 1; lx < w - 1; lx++) {
100
+ const lap = -4 * grey[ly * w + lx] +
101
+ grey[(ly - 1) * w + lx] +
102
+ grey[(ly + 1) * w + lx] +
103
+ grey[ly * w + lx - 1] +
104
+ grey[ly * w + lx + 1];
105
+ lapSum += lap * lap;
106
+ lapCount++;
107
+ }
108
+ }
109
+ return lapCount > 0 ? lapSum / lapCount : 0;
110
+ }
111
+ /**
112
+ * Compute Sobel edge energy within an overlay sub-region of a greyscale image.
113
+ *
114
+ * @param grey - Greyscale pixel array
115
+ * @param w - Full image width
116
+ * @param h - Full image height
117
+ * @param region - Overlay region in fractional coordinates
118
+ */
119
+ function computeEdgeEnergy(grey, w, h, region) {
120
+ const rx1 = Math.max(1, Math.round(region.x1 * w));
121
+ const ry1 = Math.max(1, Math.round(region.y1 * h));
122
+ const rx2 = Math.min(w - 2, Math.round(region.x2 * w));
123
+ const ry2 = Math.min(h - 2, Math.round(region.y2 * h));
124
+ const regionW = Math.max(1, rx2 - rx1);
125
+ const regionH = Math.max(1, ry2 - ry1);
126
+ const rowEnergy = new Float32Array(regionH);
127
+ const colEnergy = new Float32Array(regionW);
128
+ let edgeSum = 0;
129
+ let edgeCount = 0;
130
+ let strongEdgeCount = 0;
131
+ for (let ey = ry1; ey < ry2; ey++) {
132
+ for (let ex = rx1; ex < rx2; ex++) {
133
+ const ei = ey * w + ex;
134
+ const gx2 = -grey[ei - w - 1] +
135
+ grey[ei - w + 1] -
136
+ 2 * grey[ei - 1] +
137
+ 2 * grey[ei + 1] -
138
+ grey[ei + w - 1] +
139
+ grey[ei + w + 1];
140
+ const gy2 = -grey[ei - w - 1] -
141
+ 2 * grey[ei - w] -
142
+ grey[ei - w + 1] +
143
+ grey[ei + w - 1] +
144
+ 2 * grey[ei + w] +
145
+ grey[ei + w + 1];
146
+ const mag2 = Math.abs(gx2) + Math.abs(gy2);
147
+ const rRow = ey - ry1;
148
+ const rCol = ex - rx1;
149
+ if (rRow >= 0 && rRow < regionH)
150
+ rowEnergy[rRow] += mag2;
151
+ if (rCol >= 0 && rCol < regionW)
152
+ colEnergy[rCol] += mag2;
153
+ edgeSum += mag2;
154
+ edgeCount++;
155
+ if (mag2 > types_js_1.CAM_EDGE_PIXEL_THRESHOLD)
156
+ strongEdgeCount++;
157
+ }
158
+ }
159
+ return {
160
+ avgEdge: edgeCount > 0 ? edgeSum / edgeCount : 0,
161
+ edgeCoverage: edgeCount > 0 ? strongEdgeCount / edgeCount : 0,
162
+ rowEnergy,
163
+ colEnergy,
164
+ regionW,
165
+ regionH,
166
+ };
167
+ }
168
+ /* -- Document rectangle detection ----------------------------------------- */
169
+ /**
170
+ * Detect a document rectangle within edge energy profiles.
171
+ *
172
+ * @returns Area ratio, aspect ratio, and center offset of the detected region.
173
+ */
174
+ function detectDocumentRect(rowEnergy, colEnergy, regionW, regionH) {
175
+ let docAreaRatio = 0;
176
+ let docAspectRatio = 0;
177
+ let docCenterOffset = 1;
178
+ const energyThreshold = 0.24;
179
+ let rowMax = 0, colMax = 0;
180
+ for (let ri = 0; ri < regionH; ri++)
181
+ if (rowEnergy[ri] > rowMax)
182
+ rowMax = rowEnergy[ri];
183
+ for (let ci2 = 0; ci2 < regionW; ci2++)
184
+ if (colEnergy[ci2] > colMax)
185
+ colMax = colEnergy[ci2];
186
+ if (rowMax > 0 && colMax > 0) {
187
+ let docTop = 0, docBot = regionH - 1, docLeft = 0, docRight = regionW - 1;
188
+ for (let rt = 0; rt < regionH - 1; rt++) {
189
+ if (rowEnergy[rt] / rowMax > energyThreshold) {
190
+ docTop = rt;
191
+ break;
192
+ }
193
+ }
194
+ for (let rb = regionH - 1; rb > docTop; rb--) {
195
+ if (rowEnergy[rb] / rowMax > energyThreshold) {
196
+ docBot = rb;
197
+ break;
198
+ }
199
+ }
200
+ for (let cl = 0; cl < regionW - 1; cl++) {
201
+ if (colEnergy[cl] / colMax > energyThreshold) {
202
+ docLeft = cl;
203
+ break;
204
+ }
205
+ }
206
+ for (let cr = regionW - 1; cr > docLeft; cr--) {
207
+ if (colEnergy[cr] / colMax > energyThreshold) {
208
+ docRight = cr;
209
+ break;
210
+ }
211
+ }
212
+ const docW = docRight - docLeft + 1;
213
+ const docH = docBot - docTop + 1;
214
+ if (docW > 2 && docH > 2) {
215
+ docAreaRatio = (docW * docH) / (regionW * regionH);
216
+ docAspectRatio = docW / docH;
217
+ const docCenterX = (docLeft + docRight) / 2;
218
+ const docCenterY = (docTop + docBot) / 2;
219
+ const regionCenterX = regionW / 2;
220
+ const regionCenterY = regionH / 2;
221
+ docCenterOffset = Math.max(Math.abs(docCenterX - regionCenterX) / regionW, Math.abs(docCenterY - regionCenterY) / regionH);
222
+ }
223
+ }
224
+ return { docAreaRatio, docAspectRatio, docCenterOffset };
225
+ }
226
+ /* -- Frame-to-frame difference (stability) -------------------------------- */
227
+ /**
228
+ * Compute mean absolute difference between two greyscale frames.
229
+ * Returns 999 if no previous frame is available.
230
+ *
231
+ * @param current - Current greyscale frame
232
+ * @param previous - Previous greyscale frame (or null if first frame)
233
+ */
234
+ function computeFrameDiff(current, previous) {
235
+ if (!previous || previous.length !== current.length)
236
+ return 999;
237
+ let diffSum = 0;
238
+ for (let di = 0; di < current.length; di++) {
239
+ diffSum += Math.abs(current[di] - previous[di]);
240
+ }
241
+ return diffSum / current.length;
242
+ }
243
+ /* -- Full frame analysis -------------------------------------------------- */
244
+ /**
245
+ * Compute all frame metrics from a greyscale image and an overlay region.
246
+ * This is the DOM-free equivalent of `camAnalyzeFrame()`.
247
+ *
248
+ * @param grey - Greyscale pixel array (w * h bytes)
249
+ * @param w - Image width
250
+ * @param h - Image height
251
+ * @param region - Overlay region in fractional coordinates
252
+ * @param prevGreyData - Previous frame's greyscale data (for stability), or null
253
+ * @returns FrameMetrics for the frame
254
+ */
255
+ function analyzeFrame(grey, w, h, region, prevGreyData) {
256
+ // 1. Brightness
257
+ const brightness = computeBrightness(grey, w, h, region);
258
+ // 2. Blur (Laplacian variance)
259
+ const blurScore = computeLaplacianVariance(grey, w, h);
260
+ // 3. Edge energy
261
+ const edgeResult = computeEdgeEnergy(grey, w, h, region);
262
+ // 4. Document rectangle detection
263
+ const docRect = detectDocumentRect(edgeResult.rowEnergy, edgeResult.colEnergy, edgeResult.regionW, edgeResult.regionH);
264
+ // 5. Frame-to-frame difference (stability)
265
+ const frameDiff = computeFrameDiff(grey, prevGreyData);
266
+ return {
267
+ brightness,
268
+ blurScore,
269
+ edgeEnergy: edgeResult.avgEdge,
270
+ frameDiff,
271
+ docAreaRatio: docRect.docAreaRatio,
272
+ docAspectRatio: docRect.docAspectRatio,
273
+ docCenterOffset: docRect.docCenterOffset,
274
+ edgeCoverage: edgeResult.edgeCoverage,
275
+ };
276
+ }
277
+ /* -- Document shape match per overlay variant ----------------------------- */
278
+ /**
279
+ * Check whether frame metrics indicate a document-like shape for the given
280
+ * overlay variant. DOM-free: the overlay variant is passed as a value.
281
+ *
282
+ * @param metrics - Computed frame metrics
283
+ * @param variant - Overlay variant ('card', 'passport', or 'a4')
284
+ */
285
+ function looksLikeDocument(metrics, variant) {
286
+ const areaRatio = metrics.docAreaRatio || 0;
287
+ const aspectRatio = metrics.docAspectRatio || 0;
288
+ const centerOffset = metrics.docCenterOffset || 1;
289
+ const edgeCoverage = metrics.edgeCoverage || 0;
290
+ if (centerOffset > types_js_1.CAM_DOC_CENTER_OFFSET_MAX || edgeCoverage < types_js_1.CAM_EDGE_COVERAGE_THRESHOLD) {
291
+ return false;
292
+ }
293
+ if (variant === 'a4') {
294
+ return areaRatio > 0.2 && areaRatio < 0.98 && aspectRatio > 0.45 && aspectRatio < 1.65;
295
+ }
296
+ if (variant === 'passport') {
297
+ return areaRatio > 0.15 && areaRatio < 0.92 && aspectRatio > 0.5 && aspectRatio < 2.0;
298
+ }
299
+ // Default (ID cards, voter IDs, driver's licences)
300
+ return areaRatio > 0.15 && areaRatio < 0.92 && aspectRatio > 0.5 && aspectRatio < 2.5;
301
+ }
302
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Quality checks -- threshold comparison logic and failure escalation rules.
3
+ *
4
+ * DOM-free: no HTMLElement, no document.*, no navigator.*. All functions
5
+ * operate on plain data (FrameMetrics, QualityCheckResults, numeric values).
6
+ *
7
+ * The DOM-coupled parts of quality-review.ts (banner updates, button state,
8
+ * shake animations, Svelte store, etc.) remain in the SDK. This module
9
+ * exposes the pure decision logic that can be reused in React Native or
10
+ * Node.js environments.
11
+ */
12
+ import type { QualityCheckResults, DetectedFace, QualityBucket, ReviewDecisionOptions, ReviewMode } from './types.js';
13
+ /**
14
+ * Map a step signature string and optional review mode to a quality bucket.
15
+ */
16
+ export declare function getQualityBucket(stepSig: string, reviewMode?: ReviewMode): QualityBucket | '';
17
+ /**
18
+ * Get the number of consecutive failures required before the "submit anyway"
19
+ * override becomes available for a given step signature.
20
+ */
21
+ export declare function getSubmitAnywayThreshold(stepSig: string, reviewMode?: ReviewMode): number;
22
+ /**
23
+ * Mutable failure counter state. Create one per flow session.
24
+ */
25
+ export interface QualityFailureState {
26
+ document_front: number;
27
+ document_back: number;
28
+ selfie: number;
29
+ address_document: number;
30
+ address_front_door: number;
31
+ /** Signature of the last counted failure (prevents double-counting) */
32
+ lastFailedSignature: string;
33
+ }
34
+ /**
35
+ * Create a fresh failure state.
36
+ */
37
+ export declare function createQualityFailureState(): QualityFailureState;
38
+ /**
39
+ * Increment the failure counter for a bucket if this is a new failure
40
+ * (not a re-render of the same failed review).
41
+ *
42
+ * @param state - Mutable failure state
43
+ * @param stepSig - Step signature string
44
+ * @param failSignature - Unique signature for this failure (e.g. bucket + image src)
45
+ * @param anyFail - Whether any quality check actually failed
46
+ * @returns true if the counter was incremented
47
+ */
48
+ export declare function countFailedReview(state: QualityFailureState, stepSig: string, failSignature: string, anyFail: boolean, reviewMode?: ReviewMode): boolean;
49
+ /**
50
+ * Check whether the submit-anyway override should be available.
51
+ */
52
+ export declare function shouldShowSubmitAnyway(state: QualityFailureState, stepSig: string, reviewMode?: ReviewMode): boolean;
53
+ /**
54
+ * Input for running document quality checks on a static (already-captured)
55
+ * image. All values are pre-computed by the caller from raw pixel data.
56
+ */
57
+ export interface DocumentQualityInput {
58
+ /** Average brightness (0-255), computed from RGBA -> luminance */
59
+ avgBrightness: number;
60
+ /** Laplacian variance (sharpness measure) */
61
+ laplacianVariance: number;
62
+ /** Greyscale pixel array for the document classifier */
63
+ grey: Uint8Array;
64
+ /** RGBA pixel array for the document classifier */
65
+ imgData: Uint8ClampedArray;
66
+ /** Analysis width */
67
+ w: number;
68
+ /** Analysis height */
69
+ h: number;
70
+ /** Whether corners were detected as OK by crop detection (null = unknown) */
71
+ cornersOk: boolean | null;
72
+ /** Document type for the classifier (optional) */
73
+ documentType?: string | null;
74
+ /** Whether this is an address proof document */
75
+ isAddressProof: boolean;
76
+ }
77
+ /**
78
+ * Result of document quality checks.
79
+ */
80
+ export interface DocumentQualityResult {
81
+ /** All individual check results */
82
+ checks: QualityCheckResults;
83
+ /** Whether any check explicitly failed */
84
+ anyFail: boolean;
85
+ /** Human-readable failure message (empty if all passed) */
86
+ failMessage: string;
87
+ }
88
+ /**
89
+ * Run quality checks on a static document image. Returns the check results
90
+ * and a human-readable failure message.
91
+ *
92
+ * This is the pure-logic extraction from `runQualityCheck()`. The caller
93
+ * handles image loading, Canvas rasterization, and UI updates.
94
+ */
95
+ export declare function runDocumentQualityChecks(input: DocumentQualityInput): DocumentQualityResult;
96
+ /**
97
+ * Input for running selfie quality checks.
98
+ */
99
+ export interface SelfieQualityInput {
100
+ /** Average brightness (0-255) */
101
+ avgBrightness: number;
102
+ /** Laplacian variance (sharpness measure) */
103
+ laplacianVariance: number;
104
+ }
105
+ /**
106
+ * Run basic selfie quality checks (lighting + sharpness, before face
107
+ * detection). Returns the `good_lighting` check result.
108
+ */
109
+ export declare function runSelfieQualityChecks(input: SelfieQualityInput): QualityCheckResults;
110
+ /**
111
+ * Check face position and size relative to image dimensions.
112
+ * Returns an array of warning strings (empty = face is OK).
113
+ *
114
+ * @param faces - Detected faces
115
+ * @param imageWidth - Full image width
116
+ * @param imageHeight - Full image height
117
+ */
118
+ export declare function checkFaceInImage(faces: DetectedFace[], imageWidth: number, imageHeight: number): string[];
119
+ /**
120
+ * Check whether a detected face is well-centered and appropriately sized
121
+ * for live capture (stricter than static image checks).
122
+ *
123
+ * @param face - Detected face
124
+ * @param videoWidth - Video frame width
125
+ * @param videoHeight - Video frame height
126
+ */
127
+ export declare function isFaceCentered(face: DetectedFace, videoWidth: number, videoHeight: number): boolean;
128
+ /**
129
+ * Evaluate document quality check results and produce a prioritised failure
130
+ * message. Handles address-proof and ID-document modes.
131
+ */
132
+ export declare function evaluateDocumentFailure(checks: QualityCheckResults, isAddressProof: boolean): {
133
+ anyFail: boolean;
134
+ failMessage: string;
135
+ };
136
+ /**
137
+ * Evaluate selfie quality check results and produce a prioritised failure
138
+ * message.
139
+ */
140
+ export declare function evaluateSelfieFailure(checks: QualityCheckResults): {
141
+ anyFail: boolean;
142
+ failMessage: string;
143
+ };
144
+ /**
145
+ * Evaluate quality failures for a specific review mode using the same
146
+ * prioritization rules as the SDK review banner.
147
+ */
148
+ export declare function evaluateReviewFailure(checks: QualityCheckResults, options: ReviewDecisionOptions): {
149
+ anyFail: boolean;
150
+ failMessage: string;
151
+ };
152
+ /**
153
+ * Determine whether the "next" button should be disabled based on the
154
+ * current quality check state.
155
+ *
156
+ * @param checks - Current quality check results
157
+ * @param isSelfie - Whether this is a selfie review
158
+ * @param isAddressProof - Whether this is an address proof review
159
+ * @returns Disabled reason string (empty = should be enabled)
160
+ */
161
+ export declare function getNextButtonDisabledReason(checks: QualityCheckResults, isSelfieOrOptions: boolean | ReviewDecisionOptions, isAddressProof?: boolean): string;
162
+ /**
163
+ * Get the override button text for the submit-anyway flow.
164
+ */
165
+ export declare function getOverrideButtonText(stepSig: string): string;
166
+ /**
167
+ * Get the override banner message based on failure count and bucket.
168
+ */
169
+ export declare function getOverrideBannerMessage(stepSig: string, failCount: number, reviewMode?: ReviewMode): string;
170
+ //# sourceMappingURL=quality-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-checks.d.ts","sourceRoot":"","sources":["../../src/quality-checks.ts"],"names":[],"mappings":"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"}