@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,209 @@
1
+ /**
2
+ * Document likelihood classifier -- 5-signal Bayesian heuristic.
3
+ *
4
+ * DOM-free: operates on raw greyscale (Uint8Array) and RGBA (Uint8ClampedArray)
5
+ * pixel data. No Canvas, no HTMLImageElement.
6
+ */
7
+ /* -- Document type normaliser (mirrors host normalizeDocType) ------------- */
8
+ function normalizeDocType(docType) {
9
+ if (!docType)
10
+ return null;
11
+ const raw = String(docType).trim().toLowerCase().replace(/[\s-]+/g, '_');
12
+ switch (raw) {
13
+ case 'national_id':
14
+ case 'sierraleone_national_id':
15
+ return 'id_card';
16
+ case 'sierraleone_voter_id':
17
+ case 'voter':
18
+ return 'voter_id';
19
+ case 'driver_license':
20
+ case 'driver_licence':
21
+ case 'drivers_licence':
22
+ case 'sierraleone_driver_license':
23
+ case 'sierraleone_drivers_license':
24
+ return 'drivers_license';
25
+ case 'sierraleone_passport':
26
+ return 'passport';
27
+ default:
28
+ return raw;
29
+ }
30
+ }
31
+ /* -- Per-document-type aspect ratio profiles ------------------------------ */
32
+ export function getDocumentReviewProfile(documentType) {
33
+ const normalizedType = normalizeDocType(documentType);
34
+ // Passports -- biodata page is taller (~1.42:1 or portrait)
35
+ if (normalizedType === 'passport') {
36
+ return {
37
+ aspectTargets: [1.42],
38
+ threshold: 58,
39
+ expectedOrientation: 'portrait',
40
+ };
41
+ }
42
+ // ID card, voter ID, driver's licence -- standard card-shaped documents
43
+ if (normalizedType === 'id_card' ||
44
+ normalizedType === 'voter_id' ||
45
+ normalizedType === 'voter_card' ||
46
+ normalizedType === 'drivers_license' ||
47
+ normalizedType === 'driving_license' ||
48
+ normalizedType === 'driving_licence') {
49
+ return {
50
+ aspectTargets: [1.585],
51
+ threshold: 62,
52
+ expectedOrientation: 'landscape',
53
+ };
54
+ }
55
+ // Address proof / utility bills -- A4/letter shaped documents
56
+ if (normalizedType === 'address_proof' ||
57
+ normalizedType === 'utility_bill' ||
58
+ normalizedType === 'proof_of_address' ||
59
+ normalizedType === 'bank_statement') {
60
+ return {
61
+ aspectTargets: [1.414, 1.294],
62
+ threshold: 55,
63
+ expectedOrientation: 'either',
64
+ };
65
+ }
66
+ return {
67
+ aspectTargets: [1.585, 1.42],
68
+ threshold: 60,
69
+ expectedOrientation: 'either',
70
+ };
71
+ }
72
+ /* -- 5-signal document likelihood classifier ------------------------------ */
73
+ /**
74
+ * Determine whether a greyscale + RGBA image looks like a document.
75
+ *
76
+ * @param grey - Greyscale pixel array (w * h, one byte per pixel)
77
+ * @param imgData - RGBA pixel array (w * h * 4 bytes)
78
+ * @param w - Image width in pixels
79
+ * @param h - Image height in pixels
80
+ * @param documentType - Optional document type hint for aspect-ratio matching
81
+ */
82
+ export function checkDocumentLikelihood(grey, imgData, w, h, documentType) {
83
+ const reviewProfile = getDocumentReviewProfile(documentType);
84
+ let score = 0;
85
+ // Single-pass Sobel: build edge map AND track gradient direction for
86
+ // horizontal-edge-dominance (text signature) detection.
87
+ const totalPixels = (w - 2) * (h - 2);
88
+ const edgeMap = new Uint8Array(w * h);
89
+ let edgePixels = 0;
90
+ let hEdgeSum = 0;
91
+ let vEdgeSum = 0;
92
+ for (let ey = 1; ey < h - 1; ey++) {
93
+ for (let ex = 1; ex < w - 1; ex++) {
94
+ const gx = -grey[(ey - 1) * w + (ex - 1)] +
95
+ grey[(ey - 1) * w + (ex + 1)] -
96
+ 2 * grey[ey * w + (ex - 1)] +
97
+ 2 * grey[ey * w + (ex + 1)] -
98
+ grey[(ey + 1) * w + (ex - 1)] +
99
+ grey[(ey + 1) * w + (ex + 1)];
100
+ const gy = -grey[(ey - 1) * w + (ex - 1)] -
101
+ 2 * grey[(ey - 1) * w + ex] -
102
+ grey[(ey - 1) * w + (ex + 1)] +
103
+ grey[(ey + 1) * w + (ex - 1)] +
104
+ 2 * grey[(ey + 1) * w + ex] +
105
+ grey[(ey + 1) * w + (ex + 1)];
106
+ const mag = Math.sqrt(gx * gx + gy * gy);
107
+ if (mag > 30) {
108
+ edgeMap[ey * w + ex] = 1;
109
+ edgePixels++;
110
+ }
111
+ hEdgeSum += Math.abs(gy);
112
+ vEdgeSum += Math.abs(gx);
113
+ }
114
+ }
115
+ // 1. Edge density (widened for worn/faded Sierra Leone national IDs)
116
+ const edgeDensity = totalPixels > 0 ? edgePixels / totalPixels : 0;
117
+ if (edgeDensity >= 0.05 && edgeDensity <= 0.22)
118
+ score += 25;
119
+ else if (edgeDensity >= 0.03 && edgeDensity <= 0.28)
120
+ score += 10;
121
+ // E10: Widened penalty threshold -- textured SL surfaces inflate edge density
122
+ else if (edgeDensity > 0.3)
123
+ score -= 10;
124
+ // 2. Aspect ratio -- match against the nearest supported document profile
125
+ const aspect = w > h ? w / h : h / w;
126
+ let bestAspectDiff = Number.POSITIVE_INFINITY;
127
+ for (let aspectIdx = 0; aspectIdx < reviewProfile.aspectTargets.length; aspectIdx++) {
128
+ bestAspectDiff = Math.min(bestAspectDiff, Math.abs(aspect - reviewProfile.aspectTargets[aspectIdx]));
129
+ }
130
+ if (bestAspectDiff < 0.1)
131
+ score += 25;
132
+ else if (bestAspectDiff < 0.25)
133
+ score += 15;
134
+ else if (bestAspectDiff < 0.45)
135
+ score += 5;
136
+ // 3. Color channel variance
137
+ let rSum = 0, gSum = 0, bSum = 0;
138
+ let rSq = 0, gSq = 0, bSq = 0;
139
+ const px = imgData.length / 4;
140
+ for (let ci = 0; ci < imgData.length; ci += 4) {
141
+ rSum += imgData[ci];
142
+ gSum += imgData[ci + 1];
143
+ bSum += imgData[ci + 2];
144
+ rSq += imgData[ci] * imgData[ci];
145
+ gSq += imgData[ci + 1] * imgData[ci + 1];
146
+ bSq += imgData[ci + 2] * imgData[ci + 2];
147
+ }
148
+ const rVar = rSq / px - (rSum / px) * (rSum / px);
149
+ const gVar = gSq / px - (gSum / px) * (gSum / px);
150
+ const bVar = bSq / px - (bSum / px) * (bSum / px);
151
+ const avgVar = (rVar + gVar + bVar) / 3;
152
+ if (avgVar >= 400 && avgVar <= 4000)
153
+ score += 20;
154
+ else if (avgVar >= 200 && avgVar <= 5500)
155
+ score += 10;
156
+ // E11: Removed penalty for low color variance -- faded/BW SL documents are legitimate
157
+ // 4. Rectangular structure -- center 3x3 grid edge density + glare detection
158
+ const gridW = Math.floor(w / 3);
159
+ const gridH = Math.floor(h / 3);
160
+ let centerEdges = 0, centerTotal = 0;
161
+ let maxBrightness = 0;
162
+ for (let ry = 1; ry < h - 1; ry++) {
163
+ const rowZone = ry < gridH ? 0 : ry >= gridH * 2 ? 2 : 1;
164
+ if (rowZone !== 1)
165
+ continue;
166
+ for (let rx = 1; rx < w - 1; rx++) {
167
+ const colZone = rx < gridW ? 0 : rx >= gridW * 2 ? 2 : 1;
168
+ if (colZone !== 1)
169
+ continue;
170
+ centerEdges += edgeMap[ry * w + rx];
171
+ centerTotal++;
172
+ // Track max brightness in center region for glare detection
173
+ const pixBrightness = grey[ry * w + rx];
174
+ if (pixBrightness > maxBrightness)
175
+ maxBrightness = pixBrightness;
176
+ }
177
+ }
178
+ const centerDensity = centerTotal > 0 ? centerEdges / centerTotal : 0;
179
+ const hasGlare = maxBrightness > 245;
180
+ if (centerDensity >= 0.06 && centerDensity <= 0.2)
181
+ score += 15;
182
+ else if (centerDensity >= 0.03 && centerDensity <= 0.18)
183
+ score += 5;
184
+ else if (centerDensity > 0.2)
185
+ score -= 10;
186
+ // 5. Horizontal-edge dominance (text signature)
187
+ const edgeTotal = hEdgeSum + vEdgeSum;
188
+ if (edgeTotal > 0) {
189
+ const hRatio = hEdgeSum / edgeTotal;
190
+ if (hRatio >= 0.56)
191
+ score += 15;
192
+ else if (hRatio >= 0.52)
193
+ score += 5;
194
+ else if (hRatio < 0.46)
195
+ score -= 10;
196
+ }
197
+ // Rescue path: if aspect ratio matches strongly and some edges exist,
198
+ // set a minimum score -- handles clearly card-shaped objects that are too
199
+ // faded to score well on texture (worn Sierra Leone national IDs).
200
+ if (bestAspectDiff < 0.1 && edgeDensity > 0.03 && score < 15) {
201
+ score = 15;
202
+ }
203
+ return {
204
+ isLikelyDoc: score >= reviewProfile.threshold,
205
+ confidence: score,
206
+ glareDetected: hasGlare,
207
+ };
208
+ }
209
+ //# sourceMappingURL=document-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-classifier.js","sourceRoot":"","sources":["../../src/document-classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface FlowStepDefinition {
2
+ id: string;
3
+ type?: string | null;
4
+ }
5
+ export declare function getNextFlowStepId(steps: FlowStepDefinition[], currentStepId: string, skipType?: string): string | undefined;
6
+ export declare function getPreviousFlowStepId(steps: FlowStepDefinition[], currentStepId: string, skipType?: string): string | undefined;
7
+ //# sourceMappingURL=flow-routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-routing.d.ts","sourceRoot":"","sources":["../../src/flow-routing.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAoCD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,kBAAkB,EAAE,EAC3B,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAcpB;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,kBAAkB,EAAE,EAC3B,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAcpB"}
@@ -0,0 +1,41 @@
1
+ function filterFlowStepsByType(steps, skipType) {
2
+ if (!skipType) {
3
+ return steps;
4
+ }
5
+ return steps.filter(step => step.type !== skipType);
6
+ }
7
+ function findCompatibleStepId(steps, fromIndex, direction, skipType) {
8
+ for (let stepIndex = fromIndex + direction; stepIndex >= 0 && stepIndex < steps.length; stepIndex += direction) {
9
+ const step = steps[stepIndex];
10
+ if (!step || (skipType && step.type === skipType)) {
11
+ continue;
12
+ }
13
+ return step.id;
14
+ }
15
+ return undefined;
16
+ }
17
+ export function getNextFlowStepId(steps, currentStepId, skipType) {
18
+ const filteredSteps = filterFlowStepsByType(steps, skipType);
19
+ const filteredIndex = filteredSteps.findIndex(step => step.id === currentStepId);
20
+ if (filteredIndex === -1 && skipType) {
21
+ const sourceIndex = steps.findIndex(step => step.id === currentStepId);
22
+ return sourceIndex === -1 ? undefined : findCompatibleStepId(steps, sourceIndex, 1, skipType);
23
+ }
24
+ if (filteredIndex === -1) {
25
+ return undefined;
26
+ }
27
+ return filteredSteps[filteredIndex + 1]?.id;
28
+ }
29
+ export function getPreviousFlowStepId(steps, currentStepId, skipType) {
30
+ const filteredSteps = filterFlowStepsByType(steps, skipType);
31
+ const filteredIndex = filteredSteps.findIndex(step => step.id === currentStepId);
32
+ if (filteredIndex === -1 && skipType) {
33
+ const sourceIndex = steps.findIndex(step => step.id === currentStepId);
34
+ return sourceIndex === -1 ? undefined : findCompatibleStepId(steps, sourceIndex, -1, skipType);
35
+ }
36
+ if (filteredIndex <= 0) {
37
+ return undefined;
38
+ }
39
+ return filteredSteps[filteredIndex - 1]?.id;
40
+ }
41
+ //# sourceMappingURL=flow-routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-routing.js","sourceRoot":"","sources":["../../src/flow-routing.ts"],"names":[],"mappings":"AAKA,SAAS,qBAAqB,CAC5B,KAA2B,EAC3B,QAAiB;IAEjB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,oBAAoB,CAC3B,KAA2B,EAC3B,SAAiB,EACjB,SAAiB,EACjB,QAAiB;IAEjB,KACE,IAAI,SAAS,GAAG,SAAS,GAAG,SAAS,EACrC,SAAS,IAAI,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,EAC1C,SAAS,IAAI,SAAS,EACtB,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAE9B,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;YAClD,SAAS;QACX,CAAC;QAED,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAA2B,EAC3B,aAAqB,EACrB,QAAiB;IAEjB,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;IAEjF,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;QACvE,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChG,CAAC;IAED,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,aAAa,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAA2B,EAC3B,aAAqB,EACrB,QAAiB;IAEjB,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;IAEjF,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;QACvE,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,aAAa,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @mikashboks/capture-intelligence-core
3
+ *
4
+ * DOM-free algorithmic core for capture intelligence: document classification,
5
+ * Sobel edge detection, frame metrics computation, and quality checks.
6
+ *
7
+ * All exports operate on raw data (Uint8Array pixel arrays, FrameMetrics
8
+ * objects, numeric values). Zero browser dependencies.
9
+ */
10
+ export type { CamStateValue, FrameMetrics, DocumentReviewProfile, DocumentLikelihoodResult, CropRect, DocumentCropResult, OverlayRegion, OverlayVariant, QualityCheckResults, FaceBoundingBox, DetectedFace, MetadataReviewIssue, MetadataReviewResult, ReviewOrientation, ReviewMode, QualityBucket, ReviewDecisionOptions, } from './types.js';
11
+ export { CamState, CAM_ANALYSIS_W, CAM_ANALYSIS_H, CAM_BRIGHTNESS_MIN, CAM_BRIGHTNESS_MAX, CAM_BLUR_THRESHOLD, CAM_EDGE_THRESHOLD, CAM_STABLE_FRAMES_NEEDED, CAM_FRAME_DIFF_THRESHOLD, CAM_EDGE_PIXEL_THRESHOLD, CAM_EDGE_COVERAGE_THRESHOLD, CAM_DOC_CENTER_OFFSET_MAX, DOC_GALLERY_FAILURE_THRESHOLD, DOC_SUBMIT_ANYWAY_FAILURE_THRESHOLD, SELFIE_SUBMIT_ANYWAY_FAILURE_THRESHOLD, ADDRESS_SUBMIT_ANYWAY_FAILURE_THRESHOLD, PICO_ANALYSIS_W, PICO_ANALYSIS_H, } from './types.js';
12
+ export type { AddressMethod, AddressProofMode, AddressCoordinatesLike, AddressStepState, AddressMethodStartBehavior, } from './address-proof.js';
13
+ export { ADDRESS_METHOD_ORDER, isAddressMethod, sanitizeAllowedAddressMethods, getRecommendedAddressMethod, getAddressMethodStartBehavior, getEffectiveAddressMethod, hasAddressProofCoordinates, hasStructuredAddress, isAddressStepComplete, } from './address-proof.js';
14
+ export type { FlowStepDefinition } from './flow-routing.js';
15
+ export { getNextFlowStepId, getPreviousFlowStepId } from './flow-routing.js';
16
+ export { getDocumentReviewProfile, checkDocumentLikelihood, } from './document-classifier.js';
17
+ export type { MetadataReviewInput } from './metadata-review.js';
18
+ export { analyzeImageMetadata } from './metadata-review.js';
19
+ export type { EdgeEnergyProfile } from './sobel.js';
20
+ export { rgbaToGreyscale, rgbaToGreyscalePico, computeEdgeEnergyProfile, detectDocumentCropFromGrey, } from './sobel.js';
21
+ export type { EdgeAnalysisResult } from './metrics.js';
22
+ export { rgbaToGreyInPlace, computeBrightness, computeLaplacianVariance, computeLaplacianVarianceFloat, computeEdgeEnergy, detectDocumentRect, computeFrameDiff, analyzeFrame, looksLikeDocument, } from './metrics.js';
23
+ export type { QualityFailureState, DocumentQualityInput, DocumentQualityResult, SelfieQualityInput, } from './quality-checks.js';
24
+ export { getQualityBucket, getSubmitAnywayThreshold, createQualityFailureState, countFailedReview, shouldShowSubmitAnyway, runDocumentQualityChecks, runSelfieQualityChecks, checkFaceInImage, isFaceCentered, evaluateDocumentFailure, evaluateSelfieFailure, evaluateReviewFailure, getNextButtonDisabledReason, getOverrideButtonText, getOverrideBannerMessage, } from './quality-checks.js';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,YAAY,EACV,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,wBAAwB,EACxB,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,EACnC,sCAAsC,EACtC,uCAAuC,EACvC,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @mikashboks/capture-intelligence-core
3
+ *
4
+ * DOM-free algorithmic core for capture intelligence: document classification,
5
+ * Sobel edge detection, frame metrics computation, and quality checks.
6
+ *
7
+ * All exports operate on raw data (Uint8Array pixel arrays, FrameMetrics
8
+ * objects, numeric values). Zero browser dependencies.
9
+ */
10
+ export { CamState, CAM_ANALYSIS_W, CAM_ANALYSIS_H, CAM_BRIGHTNESS_MIN, CAM_BRIGHTNESS_MAX, CAM_BLUR_THRESHOLD, CAM_EDGE_THRESHOLD, CAM_STABLE_FRAMES_NEEDED, CAM_FRAME_DIFF_THRESHOLD, CAM_EDGE_PIXEL_THRESHOLD, CAM_EDGE_COVERAGE_THRESHOLD, CAM_DOC_CENTER_OFFSET_MAX, DOC_GALLERY_FAILURE_THRESHOLD, DOC_SUBMIT_ANYWAY_FAILURE_THRESHOLD, SELFIE_SUBMIT_ANYWAY_FAILURE_THRESHOLD, ADDRESS_SUBMIT_ANYWAY_FAILURE_THRESHOLD, PICO_ANALYSIS_W, PICO_ANALYSIS_H, } from './types.js';
11
+ export { ADDRESS_METHOD_ORDER, isAddressMethod, sanitizeAllowedAddressMethods, getRecommendedAddressMethod, getAddressMethodStartBehavior, getEffectiveAddressMethod, hasAddressProofCoordinates, hasStructuredAddress, isAddressStepComplete, } from './address-proof.js';
12
+ export { getNextFlowStepId, getPreviousFlowStepId } from './flow-routing.js';
13
+ /* -- Document classifier -------------------------------------------------- */
14
+ export { getDocumentReviewProfile, checkDocumentLikelihood, } from './document-classifier.js';
15
+ export { analyzeImageMetadata } from './metadata-review.js';
16
+ export { rgbaToGreyscale, rgbaToGreyscalePico, computeEdgeEnergyProfile, detectDocumentCropFromGrey, } from './sobel.js';
17
+ export { rgbaToGreyInPlace, computeBrightness, computeLaplacianVariance, computeLaplacianVarianceFloat, computeEdgeEnergy, detectDocumentRect, computeFrameDiff, analyzeFrame, looksLikeDocument, } from './metrics.js';
18
+ export { getQualityBucket, getSubmitAnywayThreshold, createQualityFailureState, countFailedReview, shouldShowSubmitAnyway, runDocumentQualityChecks, runSelfieQualityChecks, checkFaceInImage, isFaceCentered, evaluateDocumentFailure, evaluateSelfieFailure, evaluateReviewFailure, getNextButtonDisabledReason, getOverrideButtonText, getOverrideBannerMessage, } from './quality-checks.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH,OAAO,EACL,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,mCAAmC,EACnC,sCAAsC,EACtC,uCAAuC,EACvC,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAUpB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE7E,+EAA+E;AAC/E,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAStB,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { MetadataReviewResult } from './types.js';
2
+ export interface MetadataReviewInput {
3
+ type: 'document' | 'selfie';
4
+ width: number;
5
+ height: number;
6
+ fileSize?: number | null;
7
+ documentType?: string | null;
8
+ }
9
+ export declare function analyzeImageMetadata(input: MetadataReviewInput): MetadataReviewResult;
10
+ //# sourceMappingURL=metadata-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-review.d.ts","sourceRoot":"","sources":["../../src/metadata-review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AA4BD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CAoFrF"}
@@ -0,0 +1,90 @@
1
+ import { getDocumentReviewProfile } from './document-classifier.js';
2
+ const MIN_WIDTH = 200;
3
+ const MIN_HEIGHT = 150;
4
+ const COMPRESSION_WARNING_MIN_PIXELS = 640 * 480;
5
+ const LOW_DETAIL_BYTES_PER_PIXEL = 0.04;
6
+ function getOrientation(width, height) {
7
+ const ratio = width / Math.max(1, height);
8
+ if (ratio > 1.08)
9
+ return 'landscape';
10
+ if (ratio < 0.92)
11
+ return 'portrait';
12
+ return 'square';
13
+ }
14
+ function buildResult(type, orientation, issues, isDocument = type === 'document') {
15
+ return {
16
+ passed: issues.every(issue => issue.severity !== 'error'),
17
+ issues,
18
+ orientation,
19
+ isDocument,
20
+ };
21
+ }
22
+ export function analyzeImageMetadata(input) {
23
+ const orientation = getOrientation(input.width, input.height);
24
+ const issues = [];
25
+ if (input.width < MIN_WIDTH || input.height < MIN_HEIGHT) {
26
+ issues.push({
27
+ key: 'too_small',
28
+ message: 'Image is too small. Please take a new photo.',
29
+ severity: 'error',
30
+ });
31
+ return buildResult(input.type, orientation, issues, false);
32
+ }
33
+ if (input.type === 'document') {
34
+ const reviewProfile = getDocumentReviewProfile(input.documentType);
35
+ const normalizedAspect = input.width > input.height
36
+ ? input.width / input.height
37
+ : input.height / input.width;
38
+ const bestAspectDiff = Math.min(...reviewProfile.aspectTargets.map(target => Math.abs(normalizedAspect - target)));
39
+ if (bestAspectDiff > 0.33) {
40
+ issues.push({
41
+ key: 'bad_aspect',
42
+ message: "This doesn't match the selected document shape. Retake with the full document visible.",
43
+ severity: 'error',
44
+ });
45
+ }
46
+ else if (bestAspectDiff > 0.2) {
47
+ issues.push({
48
+ key: 'document_shape_warning',
49
+ message: 'Make sure the full document is visible and not tilted too much.',
50
+ severity: 'warning',
51
+ });
52
+ }
53
+ if (reviewProfile.expectedOrientation === 'landscape' &&
54
+ orientation === 'portrait') {
55
+ issues.push({
56
+ key: 'document_rotated',
57
+ message: 'Rotate the document so it is wider than it is tall.',
58
+ severity: 'warning',
59
+ });
60
+ }
61
+ if (reviewProfile.expectedOrientation === 'portrait' &&
62
+ orientation === 'landscape') {
63
+ issues.push({
64
+ key: 'document_rotated',
65
+ message: 'Rotate the document so the page is upright before retaking.',
66
+ severity: 'warning',
67
+ });
68
+ }
69
+ }
70
+ else if (orientation === 'landscape') {
71
+ issues.push({
72
+ key: 'selfie_landscape',
73
+ message: 'Use portrait orientation so the full face and shoulders fit in frame.',
74
+ severity: 'warning',
75
+ });
76
+ }
77
+ if (input.fileSize &&
78
+ input.width * input.height >= COMPRESSION_WARNING_MIN_PIXELS &&
79
+ input.fileSize / (input.width * input.height) < LOW_DETAIL_BYTES_PER_PIXEL) {
80
+ issues.push({
81
+ key: 'low_detail',
82
+ message: 'Photo looks heavily compressed. Retake it without zooming or screenshots.',
83
+ severity: 'warning',
84
+ });
85
+ }
86
+ const isDocument = input.type === 'document' &&
87
+ !issues.some(issue => issue.key === 'bad_aspect');
88
+ return buildResult(input.type, orientation, issues, isDocument);
89
+ }
90
+ //# sourceMappingURL=metadata-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-review.js","sourceRoot":"","sources":["../../src/metadata-review.ts"],"names":[],"mappings":"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"}
@@ -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"}