@mleonard9/vin-scanner 0.1.10 → 0.2.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.
- package/lib/commonjs/vinUtils.js +247 -10
- package/lib/commonjs/vinUtils.js.map +1 -1
- package/lib/module/vinUtils.js +247 -10
- package/lib/module/vinUtils.js.map +1 -1
- package/lib/typescript/src/vinUtils.d.ts +14 -0
- package/lib/typescript/src/vinUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/vinUtils.ts +260 -21
package/lib/commonjs/vinUtils.js
CHANGED
|
@@ -4,6 +4,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.resolveOptions = exports.pickBestCandidate = exports.isValidVin = exports.buildVinCandidates = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* VIN Scanner Utilities
|
|
9
|
+
*
|
|
10
|
+
* This module provides advanced VIN (Vehicle Identification Number) detection
|
|
11
|
+
* and validation capabilities with the following features:
|
|
12
|
+
*
|
|
13
|
+
* 1. OCR Error Correction: Automatically corrects common OCR misreads (O/0, I/1, etc.)
|
|
14
|
+
* 2. Context-Aware Detection: Looks for VIN prefixes like "VIN:", "Vehicle ID", etc.
|
|
15
|
+
* 3. Check Digit Validation: Validates VINs using ISO 3779 standard algorithm
|
|
16
|
+
* 4. Smart Confidence Scoring: Assigns reliability scores based on multiple factors
|
|
17
|
+
* 5. Multi-Level Processing: Extracts from element, line, and block level text
|
|
18
|
+
*
|
|
19
|
+
* @see https://en.wikipedia.org/wiki/Vehicle_identification_number
|
|
20
|
+
*/
|
|
21
|
+
|
|
7
22
|
const DEFAULT_RESOLVED_OPTIONS = {
|
|
8
23
|
barcode: {
|
|
9
24
|
enabled: true,
|
|
@@ -21,6 +36,8 @@ const DEFAULT_RESOLVED_OPTIONS = {
|
|
|
21
36
|
}
|
|
22
37
|
};
|
|
23
38
|
const resolveOptions = options => {
|
|
39
|
+
'worklet';
|
|
40
|
+
|
|
24
41
|
var _options$detection, _options$detection2, _options$barcode, _options$barcode2, _options$text, _options$text2, _options$detection3, _options$detection4;
|
|
25
42
|
const resultMode = (options === null || options === void 0 || (_options$detection = options.detection) === null || _options$detection === void 0 ? void 0 : _options$detection.resultMode) ?? DEFAULT_RESOLVED_OPTIONS.detection.resultMode;
|
|
26
43
|
const emitDuplicates = (options === null || options === void 0 || (_options$detection2 = options.detection) === null || _options$detection2 === void 0 ? void 0 : _options$detection2.emitDuplicates) ?? (resultMode === 'all' ? true : DEFAULT_RESOLVED_OPTIONS.detection.emitDuplicates);
|
|
@@ -42,7 +59,6 @@ const resolveOptions = options => {
|
|
|
42
59
|
};
|
|
43
60
|
};
|
|
44
61
|
exports.resolveOptions = resolveOptions;
|
|
45
|
-
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
46
62
|
const transliteration = {
|
|
47
63
|
A: 1,
|
|
48
64
|
B: 2,
|
|
@@ -69,25 +85,156 @@ const transliteration = {
|
|
|
69
85
|
Z: 9
|
|
70
86
|
};
|
|
71
87
|
const weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
88
|
+
|
|
89
|
+
// Common OCR misreads that need correction
|
|
90
|
+
const OCR_SUBSTITUTIONS = {
|
|
91
|
+
'O': ['0'],
|
|
92
|
+
// O often misread as 0 (and vice versa)
|
|
93
|
+
'0': ['O'],
|
|
94
|
+
'I': ['1'],
|
|
95
|
+
// I often misread as 1 (and vice versa)
|
|
96
|
+
'1': ['I'],
|
|
97
|
+
'Q': ['0', 'O'],
|
|
98
|
+
// Q should not appear in VINs
|
|
99
|
+
'S': ['5'],
|
|
100
|
+
// S can be misread as 5
|
|
101
|
+
'5': ['S'],
|
|
102
|
+
'B': ['8'],
|
|
103
|
+
// B can be misread as 8
|
|
104
|
+
'8': ['B'],
|
|
105
|
+
'Z': ['2'],
|
|
106
|
+
// Z can be misread as 2
|
|
107
|
+
'2': ['Z'],
|
|
108
|
+
'G': ['6'],
|
|
109
|
+
// G can be misread as 6
|
|
110
|
+
'6': ['G'],
|
|
111
|
+
'D': ['0'],
|
|
112
|
+
// D can be misread as 0
|
|
113
|
+
'U': ['V'],
|
|
114
|
+
// U can be misread as V
|
|
115
|
+
'V': ['U']
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// VIN prefix patterns to detect context
|
|
119
|
+
const VIN_PREFIX_PATTERNS = [/(?:^|[\s:])VIN[:\s]+([A-Z0-9]{17,})/i, /(?:^|[\s:])V\.?I\.?N\.?[:\s]+([A-Z0-9]{17,})/i, /Vehicle\s+(?:Identification\s+)?(?:Number|ID|Id)[:\s]+([A-Z0-9]{17,})/i, /(?:^|[\s:])Chassis\s+(?:Number|No\.?)[:\s]+([A-Z0-9]{17,})/i, /(?:^|[\s:])Serial\s+(?:Number|No\.?)[:\s]+([A-Z0-9]{17,})/i];
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Generate character substitution candidates for OCR error correction
|
|
123
|
+
* This creates variations of the input by substituting commonly misread characters
|
|
124
|
+
*/
|
|
125
|
+
const generateSubstitutionCandidates = (value, maxSubstitutions = 3) => {
|
|
126
|
+
'worklet';
|
|
127
|
+
|
|
128
|
+
const candidates = new Set([value]);
|
|
129
|
+
|
|
130
|
+
// Find positions that might need substitution
|
|
131
|
+
const positions = [];
|
|
132
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
133
|
+
const char = value[i];
|
|
134
|
+
if (char && OCR_SUBSTITUTIONS[char]) {
|
|
135
|
+
positions.push(i);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Limit the number of positions to try (combinatorial explosion prevention)
|
|
140
|
+
const positionsToTry = positions.slice(0, maxSubstitutions);
|
|
141
|
+
|
|
142
|
+
// Generate candidates by substituting at different positions
|
|
143
|
+
const generate = (current, posIndex, substitutionCount) => {
|
|
144
|
+
if (posIndex >= positionsToTry.length || substitutionCount >= maxSubstitutions) {
|
|
145
|
+
candidates.add(current);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Don't substitute at this position
|
|
150
|
+
generate(current, posIndex + 1, substitutionCount);
|
|
151
|
+
|
|
152
|
+
// Try substituting at this position
|
|
153
|
+
const pos = positionsToTry[posIndex];
|
|
154
|
+
if (pos !== undefined) {
|
|
155
|
+
const char = current[pos];
|
|
156
|
+
const replacements = char ? OCR_SUBSTITUTIONS[char] : undefined;
|
|
157
|
+
if (replacements) {
|
|
158
|
+
replacements.forEach(replacement => {
|
|
159
|
+
const newValue = current.slice(0, pos) + replacement + current.slice(pos + 1);
|
|
160
|
+
generate(newValue, posIndex + 1, substitutionCount + 1);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
generate(value, 0, 0);
|
|
166
|
+
return Array.from(candidates);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Extract VINs using context-aware patterns (looking for VIN: prefix, etc.)
|
|
171
|
+
*/
|
|
172
|
+
const extractWithContext = text => {
|
|
173
|
+
'worklet';
|
|
174
|
+
|
|
175
|
+
const matches = new Set();
|
|
176
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
177
|
+
VIN_PREFIX_PATTERNS.forEach(pattern => {
|
|
178
|
+
const match = pattern.exec(text);
|
|
179
|
+
if (match && match[1]) {
|
|
180
|
+
const captured = match[1].replace(/[^A-Z0-9]/gi, '');
|
|
181
|
+
// Extract exactly 17 characters
|
|
182
|
+
if (captured.length >= 17) {
|
|
183
|
+
const candidate = captured.slice(0, 17).toUpperCase();
|
|
184
|
+
if (VIN_PATTERN.test(candidate)) {
|
|
185
|
+
matches.add(candidate);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
return Array.from(matches);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Tokenize and extract VIN candidates from raw text
|
|
195
|
+
* Includes OCR error correction and context-aware extraction
|
|
196
|
+
*/
|
|
72
197
|
const tokenizeCandidate = value => {
|
|
73
198
|
'worklet';
|
|
74
199
|
|
|
200
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
75
201
|
if (!value) {
|
|
76
202
|
return [];
|
|
77
203
|
}
|
|
78
204
|
const normalized = value.toUpperCase();
|
|
205
|
+
const matches = new Set();
|
|
206
|
+
|
|
207
|
+
// First, try context-aware extraction (VIN: prefix, etc.)
|
|
208
|
+
extractWithContext(normalized).forEach(vin => matches.add(vin));
|
|
209
|
+
|
|
210
|
+
// Then do regular tokenization
|
|
79
211
|
const cleaned = normalized.replace(/[^A-Z0-9]/g, ' ');
|
|
80
212
|
const tokens = cleaned.split(/\s+/).filter(token => token.length > 0);
|
|
81
|
-
const matches = new Set();
|
|
82
213
|
tokens.forEach(token => {
|
|
83
214
|
if (token.length < 17) {
|
|
84
215
|
return;
|
|
85
216
|
}
|
|
217
|
+
|
|
218
|
+
// Try every 17-character substring
|
|
86
219
|
for (let i = 0; i <= token.length - 17; i += 1) {
|
|
87
220
|
const candidate = token.slice(i, i + 17);
|
|
221
|
+
|
|
222
|
+
// Direct match
|
|
88
223
|
if (VIN_PATTERN.test(candidate)) {
|
|
89
224
|
matches.add(candidate);
|
|
90
225
|
}
|
|
226
|
+
|
|
227
|
+
// Try with OCR substitutions for candidates that are close
|
|
228
|
+
// Only if they contain substitutable characters and don't match directly
|
|
229
|
+
const hasSubstitutableChars = /[OISQBZGDUV]/.test(candidate);
|
|
230
|
+
if (hasSubstitutableChars) {
|
|
231
|
+
const substitutions = generateSubstitutionCandidates(candidate, 2);
|
|
232
|
+
substitutions.forEach(sub => {
|
|
233
|
+
if (VIN_PATTERN.test(sub)) {
|
|
234
|
+
matches.add(sub);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
91
238
|
}
|
|
92
239
|
});
|
|
93
240
|
return Array.from(matches);
|
|
@@ -95,6 +242,7 @@ const tokenizeCandidate = value => {
|
|
|
95
242
|
const isValidVin = value => {
|
|
96
243
|
'worklet';
|
|
97
244
|
|
|
245
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
98
246
|
if (!VIN_PATTERN.test(value)) {
|
|
99
247
|
return false;
|
|
100
248
|
}
|
|
@@ -167,6 +315,25 @@ const toBoundingBox = (candidate, preferred) => {
|
|
|
167
315
|
}
|
|
168
316
|
return blockBox || lineBox || elementBox;
|
|
169
317
|
};
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Calculate confidence score for a barcode-based VIN candidate
|
|
321
|
+
* Barcodes are generally more reliable than text recognition
|
|
322
|
+
*/
|
|
323
|
+
const calculateBarcodeConfidence = (value, validateChecksum) => {
|
|
324
|
+
'worklet';
|
|
325
|
+
|
|
326
|
+
let confidence = 0.85; // Base confidence for barcode
|
|
327
|
+
|
|
328
|
+
// Check digit validation
|
|
329
|
+
const checksumValid = isValidVin(value);
|
|
330
|
+
if (checksumValid) {
|
|
331
|
+
confidence = 0.98; // Very high confidence
|
|
332
|
+
} else if (!validateChecksum) {
|
|
333
|
+
confidence = 0.9; // Still high if validation disabled
|
|
334
|
+
}
|
|
335
|
+
return confidence;
|
|
336
|
+
};
|
|
170
337
|
const candidateFromBarcode = (detection, validateChecksum) => {
|
|
171
338
|
'worklet';
|
|
172
339
|
|
|
@@ -175,31 +342,101 @@ const candidateFromBarcode = (detection, validateChecksum) => {
|
|
|
175
342
|
tokenizeCandidate(detection.displayValue ?? '').forEach(value => values.add(value));
|
|
176
343
|
const boundingBox = toBoundingBox(detection, 'barcode');
|
|
177
344
|
return Array.from(values).map(value => {
|
|
178
|
-
const
|
|
345
|
+
const confidence = calculateBarcodeConfidence(value, validateChecksum);
|
|
179
346
|
return {
|
|
180
347
|
value,
|
|
181
348
|
source: 'barcode',
|
|
182
|
-
confidence
|
|
349
|
+
confidence,
|
|
183
350
|
boundingBox,
|
|
184
351
|
origin: detection.displayValue ? 'displayValue' : 'rawValue',
|
|
185
352
|
rawPayload: detection
|
|
186
353
|
};
|
|
187
354
|
});
|
|
188
355
|
};
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Calculate confidence score for a text-based VIN candidate
|
|
359
|
+
* Higher confidence for:
|
|
360
|
+
* - Valid check digit
|
|
361
|
+
* - Found with VIN prefix context
|
|
362
|
+
* - Element/line level detection (vs block level)
|
|
363
|
+
*/
|
|
364
|
+
const calculateTextConfidence = (value, rawText, origin, validateChecksum) => {
|
|
365
|
+
'worklet';
|
|
366
|
+
|
|
367
|
+
let confidence = 0.5; // Base confidence for text recognition
|
|
368
|
+
|
|
369
|
+
// Check digit validation significantly increases confidence
|
|
370
|
+
const checksumValid = isValidVin(value);
|
|
371
|
+
if (checksumValid) {
|
|
372
|
+
confidence += 0.35; // Boost to 0.85
|
|
373
|
+
} else if (!validateChecksum) {
|
|
374
|
+
confidence += 0.2; // Still boost if validation is disabled
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Context-aware detection (VIN prefix found) increases confidence
|
|
378
|
+
const hasVinPrefix = /VIN|Vehicle\s+(?:Identification|ID|Id)|Chassis|Serial/i.test(rawText);
|
|
379
|
+
if (hasVinPrefix) {
|
|
380
|
+
confidence += 0.1; // Boost to 0.95 if checksum valid, 0.6 if not
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Element-level text is more accurate than block-level
|
|
384
|
+
if (origin === 'element') {
|
|
385
|
+
confidence += 0.05;
|
|
386
|
+
} else if (origin === 'line') {
|
|
387
|
+
confidence += 0.03;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Cap at 0.98 (never 1.0 for text recognition)
|
|
391
|
+
return Math.min(confidence, 0.98);
|
|
392
|
+
};
|
|
189
393
|
const candidateFromText = (detection, validateChecksum) => {
|
|
190
394
|
'worklet';
|
|
191
395
|
|
|
192
|
-
const
|
|
193
|
-
|
|
396
|
+
const valueMap = new Map();
|
|
397
|
+
|
|
398
|
+
// Process each text level, with priority ordering
|
|
399
|
+
[{
|
|
400
|
+
text: detection.elementText,
|
|
401
|
+
order: 1
|
|
402
|
+
}, {
|
|
403
|
+
text: detection.lineText,
|
|
404
|
+
order: 2
|
|
405
|
+
}, {
|
|
406
|
+
text: detection.blockText,
|
|
407
|
+
order: 3
|
|
408
|
+
}, {
|
|
409
|
+
text: detection.resultText,
|
|
410
|
+
order: 4
|
|
411
|
+
}].forEach(({
|
|
412
|
+
text,
|
|
413
|
+
order
|
|
414
|
+
}) => {
|
|
415
|
+
if (text) {
|
|
416
|
+
tokenizeCandidate(text).forEach(v => {
|
|
417
|
+
var _valueMap$get;
|
|
418
|
+
if (!valueMap.has(v) || (((_valueMap$get = valueMap.get(v)) === null || _valueMap$get === void 0 ? void 0 : _valueMap$get.order) ?? 999) > order) {
|
|
419
|
+
valueMap.set(v, {
|
|
420
|
+
rawText: text,
|
|
421
|
+
order
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
});
|
|
194
427
|
const boundingBox = toBoundingBox(detection, 'line') ?? toBoundingBox(detection, 'element') ?? toBoundingBox(detection, 'block');
|
|
195
|
-
return Array.from(
|
|
196
|
-
|
|
428
|
+
return Array.from(valueMap.entries()).map(([value, {
|
|
429
|
+
rawText
|
|
430
|
+
}]) => {
|
|
431
|
+
var _detection$elementTex, _detection$lineText;
|
|
432
|
+
const origin = (_detection$elementTex = detection.elementText) !== null && _detection$elementTex !== void 0 && _detection$elementTex.includes(value) ? 'element' : (_detection$lineText = detection.lineText) !== null && _detection$lineText !== void 0 && _detection$lineText.includes(value) ? 'line' : 'block';
|
|
433
|
+
const confidence = calculateTextConfidence(value, rawText, origin, validateChecksum);
|
|
197
434
|
return {
|
|
198
435
|
value,
|
|
199
436
|
source: 'text',
|
|
200
|
-
confidence
|
|
437
|
+
confidence,
|
|
201
438
|
boundingBox,
|
|
202
|
-
origin
|
|
439
|
+
origin,
|
|
203
440
|
rawPayload: detection
|
|
204
441
|
};
|
|
205
442
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DEFAULT_RESOLVED_OPTIONS","barcode","enabled","formats","text","language","detection","resultMode","preferBarcode","validateChecksum","emitDuplicates","resolveOptions","options","_options$detection","_options$detection2","_options$barcode","_options$barcode2","_options$text","_options$text2","_options$detection3","_options$detection4","length","exports","VIN_PATTERN","transliteration","A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z","weights","tokenizeCandidate","value","normalized","toUpperCase","cleaned","replace","tokens","split","filter","token","matches","Set","forEach","i","candidate","slice","test","add","Array","from","isValidVin","chars","sum","char","numeric","Number","parseInt","undefined","weight","remainder","expected","toString","checkDigit","toBoundingBox","preferred","maybe","top","bottom","left","right","width","height","block","blockBox","blockFrameTop","blockFrameBottom","blockFrameLeft","blockFrameRight","lineBox","lineFrameTop","lineFrameBottom","lineFrameLeft","lineFrameRight","elementBox","elementFrameTop","elementFrameBottom","elementFrameLeft","elementFrameRight","candidateFromBarcode","values","rawValue","displayValue","boundingBox","map","checksumValid","source","confidence","origin","rawPayload","candidateFromText","lineText","elementText","blockText","resultText","v","dedupeCandidates","candidates","Map","_candidate$boundingBo","_candidate$boundingBo2","key","join","existing","get","set","buildVinCandidates","payload","list","barcodes","push","textBlocks","textBlock","pickBestCandidate","sorted","sort","a","b"],"sourceRoot":"../../src","sources":["vinUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["DEFAULT_RESOLVED_OPTIONS","barcode","enabled","formats","text","language","detection","resultMode","preferBarcode","validateChecksum","emitDuplicates","resolveOptions","options","_options$detection","_options$detection2","_options$barcode","_options$barcode2","_options$text","_options$text2","_options$detection3","_options$detection4","length","exports","transliteration","A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z","weights","OCR_SUBSTITUTIONS","VIN_PREFIX_PATTERNS","generateSubstitutionCandidates","value","maxSubstitutions","candidates","Set","positions","i","char","push","positionsToTry","slice","generate","current","posIndex","substitutionCount","add","pos","undefined","replacements","forEach","replacement","newValue","Array","from","extractWithContext","matches","VIN_PATTERN","pattern","match","exec","captured","replace","candidate","toUpperCase","test","tokenizeCandidate","normalized","vin","cleaned","tokens","split","filter","token","hasSubstitutableChars","substitutions","sub","isValidVin","chars","sum","numeric","Number","parseInt","weight","remainder","expected","toString","checkDigit","toBoundingBox","preferred","maybe","top","bottom","left","right","width","height","block","blockBox","blockFrameTop","blockFrameBottom","blockFrameLeft","blockFrameRight","lineBox","lineFrameTop","lineFrameBottom","lineFrameLeft","lineFrameRight","elementBox","elementFrameTop","elementFrameBottom","elementFrameLeft","elementFrameRight","calculateBarcodeConfidence","confidence","checksumValid","candidateFromBarcode","values","rawValue","displayValue","boundingBox","map","source","origin","rawPayload","calculateTextConfidence","rawText","hasVinPrefix","Math","min","candidateFromText","valueMap","Map","elementText","order","lineText","blockText","resultText","v","_valueMap$get","has","get","set","entries","_detection$elementTex","_detection$lineText","includes","dedupeCandidates","_candidate$boundingBo","_candidate$boundingBo2","key","join","existing","buildVinCandidates","payload","list","barcodes","textBlocks","textBlock","pickBestCandidate","sorted","sort","a","b"],"sourceRoot":"../../src","sources":["vinUtils.ts"],"mappings":"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","ignoreList":[]}
|
package/lib/module/vinUtils.js
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIN Scanner Utilities
|
|
3
|
+
*
|
|
4
|
+
* This module provides advanced VIN (Vehicle Identification Number) detection
|
|
5
|
+
* and validation capabilities with the following features:
|
|
6
|
+
*
|
|
7
|
+
* 1. OCR Error Correction: Automatically corrects common OCR misreads (O/0, I/1, etc.)
|
|
8
|
+
* 2. Context-Aware Detection: Looks for VIN prefixes like "VIN:", "Vehicle ID", etc.
|
|
9
|
+
* 3. Check Digit Validation: Validates VINs using ISO 3779 standard algorithm
|
|
10
|
+
* 4. Smart Confidence Scoring: Assigns reliability scores based on multiple factors
|
|
11
|
+
* 5. Multi-Level Processing: Extracts from element, line, and block level text
|
|
12
|
+
*
|
|
13
|
+
* @see https://en.wikipedia.org/wiki/Vehicle_identification_number
|
|
14
|
+
*/
|
|
15
|
+
|
|
1
16
|
const DEFAULT_RESOLVED_OPTIONS = {
|
|
2
17
|
barcode: {
|
|
3
18
|
enabled: true,
|
|
@@ -15,6 +30,8 @@ const DEFAULT_RESOLVED_OPTIONS = {
|
|
|
15
30
|
}
|
|
16
31
|
};
|
|
17
32
|
export const resolveOptions = options => {
|
|
33
|
+
'worklet';
|
|
34
|
+
|
|
18
35
|
var _options$detection, _options$detection2, _options$barcode, _options$barcode2, _options$text, _options$text2, _options$detection3, _options$detection4;
|
|
19
36
|
const resultMode = (options === null || options === void 0 || (_options$detection = options.detection) === null || _options$detection === void 0 ? void 0 : _options$detection.resultMode) ?? DEFAULT_RESOLVED_OPTIONS.detection.resultMode;
|
|
20
37
|
const emitDuplicates = (options === null || options === void 0 || (_options$detection2 = options.detection) === null || _options$detection2 === void 0 ? void 0 : _options$detection2.emitDuplicates) ?? (resultMode === 'all' ? true : DEFAULT_RESOLVED_OPTIONS.detection.emitDuplicates);
|
|
@@ -35,7 +52,6 @@ export const resolveOptions = options => {
|
|
|
35
52
|
}
|
|
36
53
|
};
|
|
37
54
|
};
|
|
38
|
-
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
39
55
|
const transliteration = {
|
|
40
56
|
A: 1,
|
|
41
57
|
B: 2,
|
|
@@ -62,25 +78,156 @@ const transliteration = {
|
|
|
62
78
|
Z: 9
|
|
63
79
|
};
|
|
64
80
|
const weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
81
|
+
|
|
82
|
+
// Common OCR misreads that need correction
|
|
83
|
+
const OCR_SUBSTITUTIONS = {
|
|
84
|
+
'O': ['0'],
|
|
85
|
+
// O often misread as 0 (and vice versa)
|
|
86
|
+
'0': ['O'],
|
|
87
|
+
'I': ['1'],
|
|
88
|
+
// I often misread as 1 (and vice versa)
|
|
89
|
+
'1': ['I'],
|
|
90
|
+
'Q': ['0', 'O'],
|
|
91
|
+
// Q should not appear in VINs
|
|
92
|
+
'S': ['5'],
|
|
93
|
+
// S can be misread as 5
|
|
94
|
+
'5': ['S'],
|
|
95
|
+
'B': ['8'],
|
|
96
|
+
// B can be misread as 8
|
|
97
|
+
'8': ['B'],
|
|
98
|
+
'Z': ['2'],
|
|
99
|
+
// Z can be misread as 2
|
|
100
|
+
'2': ['Z'],
|
|
101
|
+
'G': ['6'],
|
|
102
|
+
// G can be misread as 6
|
|
103
|
+
'6': ['G'],
|
|
104
|
+
'D': ['0'],
|
|
105
|
+
// D can be misread as 0
|
|
106
|
+
'U': ['V'],
|
|
107
|
+
// U can be misread as V
|
|
108
|
+
'V': ['U']
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// VIN prefix patterns to detect context
|
|
112
|
+
const VIN_PREFIX_PATTERNS = [/(?:^|[\s:])VIN[:\s]+([A-Z0-9]{17,})/i, /(?:^|[\s:])V\.?I\.?N\.?[:\s]+([A-Z0-9]{17,})/i, /Vehicle\s+(?:Identification\s+)?(?:Number|ID|Id)[:\s]+([A-Z0-9]{17,})/i, /(?:^|[\s:])Chassis\s+(?:Number|No\.?)[:\s]+([A-Z0-9]{17,})/i, /(?:^|[\s:])Serial\s+(?:Number|No\.?)[:\s]+([A-Z0-9]{17,})/i];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Generate character substitution candidates for OCR error correction
|
|
116
|
+
* This creates variations of the input by substituting commonly misread characters
|
|
117
|
+
*/
|
|
118
|
+
const generateSubstitutionCandidates = (value, maxSubstitutions = 3) => {
|
|
119
|
+
'worklet';
|
|
120
|
+
|
|
121
|
+
const candidates = new Set([value]);
|
|
122
|
+
|
|
123
|
+
// Find positions that might need substitution
|
|
124
|
+
const positions = [];
|
|
125
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
126
|
+
const char = value[i];
|
|
127
|
+
if (char && OCR_SUBSTITUTIONS[char]) {
|
|
128
|
+
positions.push(i);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Limit the number of positions to try (combinatorial explosion prevention)
|
|
133
|
+
const positionsToTry = positions.slice(0, maxSubstitutions);
|
|
134
|
+
|
|
135
|
+
// Generate candidates by substituting at different positions
|
|
136
|
+
const generate = (current, posIndex, substitutionCount) => {
|
|
137
|
+
if (posIndex >= positionsToTry.length || substitutionCount >= maxSubstitutions) {
|
|
138
|
+
candidates.add(current);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Don't substitute at this position
|
|
143
|
+
generate(current, posIndex + 1, substitutionCount);
|
|
144
|
+
|
|
145
|
+
// Try substituting at this position
|
|
146
|
+
const pos = positionsToTry[posIndex];
|
|
147
|
+
if (pos !== undefined) {
|
|
148
|
+
const char = current[pos];
|
|
149
|
+
const replacements = char ? OCR_SUBSTITUTIONS[char] : undefined;
|
|
150
|
+
if (replacements) {
|
|
151
|
+
replacements.forEach(replacement => {
|
|
152
|
+
const newValue = current.slice(0, pos) + replacement + current.slice(pos + 1);
|
|
153
|
+
generate(newValue, posIndex + 1, substitutionCount + 1);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
generate(value, 0, 0);
|
|
159
|
+
return Array.from(candidates);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Extract VINs using context-aware patterns (looking for VIN: prefix, etc.)
|
|
164
|
+
*/
|
|
165
|
+
const extractWithContext = text => {
|
|
166
|
+
'worklet';
|
|
167
|
+
|
|
168
|
+
const matches = new Set();
|
|
169
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
170
|
+
VIN_PREFIX_PATTERNS.forEach(pattern => {
|
|
171
|
+
const match = pattern.exec(text);
|
|
172
|
+
if (match && match[1]) {
|
|
173
|
+
const captured = match[1].replace(/[^A-Z0-9]/gi, '');
|
|
174
|
+
// Extract exactly 17 characters
|
|
175
|
+
if (captured.length >= 17) {
|
|
176
|
+
const candidate = captured.slice(0, 17).toUpperCase();
|
|
177
|
+
if (VIN_PATTERN.test(candidate)) {
|
|
178
|
+
matches.add(candidate);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return Array.from(matches);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Tokenize and extract VIN candidates from raw text
|
|
188
|
+
* Includes OCR error correction and context-aware extraction
|
|
189
|
+
*/
|
|
65
190
|
const tokenizeCandidate = value => {
|
|
66
191
|
'worklet';
|
|
67
192
|
|
|
193
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
68
194
|
if (!value) {
|
|
69
195
|
return [];
|
|
70
196
|
}
|
|
71
197
|
const normalized = value.toUpperCase();
|
|
198
|
+
const matches = new Set();
|
|
199
|
+
|
|
200
|
+
// First, try context-aware extraction (VIN: prefix, etc.)
|
|
201
|
+
extractWithContext(normalized).forEach(vin => matches.add(vin));
|
|
202
|
+
|
|
203
|
+
// Then do regular tokenization
|
|
72
204
|
const cleaned = normalized.replace(/[^A-Z0-9]/g, ' ');
|
|
73
205
|
const tokens = cleaned.split(/\s+/).filter(token => token.length > 0);
|
|
74
|
-
const matches = new Set();
|
|
75
206
|
tokens.forEach(token => {
|
|
76
207
|
if (token.length < 17) {
|
|
77
208
|
return;
|
|
78
209
|
}
|
|
210
|
+
|
|
211
|
+
// Try every 17-character substring
|
|
79
212
|
for (let i = 0; i <= token.length - 17; i += 1) {
|
|
80
213
|
const candidate = token.slice(i, i + 17);
|
|
214
|
+
|
|
215
|
+
// Direct match
|
|
81
216
|
if (VIN_PATTERN.test(candidate)) {
|
|
82
217
|
matches.add(candidate);
|
|
83
218
|
}
|
|
219
|
+
|
|
220
|
+
// Try with OCR substitutions for candidates that are close
|
|
221
|
+
// Only if they contain substitutable characters and don't match directly
|
|
222
|
+
const hasSubstitutableChars = /[OISQBZGDUV]/.test(candidate);
|
|
223
|
+
if (hasSubstitutableChars) {
|
|
224
|
+
const substitutions = generateSubstitutionCandidates(candidate, 2);
|
|
225
|
+
substitutions.forEach(sub => {
|
|
226
|
+
if (VIN_PATTERN.test(sub)) {
|
|
227
|
+
matches.add(sub);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
84
231
|
}
|
|
85
232
|
});
|
|
86
233
|
return Array.from(matches);
|
|
@@ -88,6 +235,7 @@ const tokenizeCandidate = value => {
|
|
|
88
235
|
export const isValidVin = value => {
|
|
89
236
|
'worklet';
|
|
90
237
|
|
|
238
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
91
239
|
if (!VIN_PATTERN.test(value)) {
|
|
92
240
|
return false;
|
|
93
241
|
}
|
|
@@ -159,6 +307,25 @@ const toBoundingBox = (candidate, preferred) => {
|
|
|
159
307
|
}
|
|
160
308
|
return blockBox || lineBox || elementBox;
|
|
161
309
|
};
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Calculate confidence score for a barcode-based VIN candidate
|
|
313
|
+
* Barcodes are generally more reliable than text recognition
|
|
314
|
+
*/
|
|
315
|
+
const calculateBarcodeConfidence = (value, validateChecksum) => {
|
|
316
|
+
'worklet';
|
|
317
|
+
|
|
318
|
+
let confidence = 0.85; // Base confidence for barcode
|
|
319
|
+
|
|
320
|
+
// Check digit validation
|
|
321
|
+
const checksumValid = isValidVin(value);
|
|
322
|
+
if (checksumValid) {
|
|
323
|
+
confidence = 0.98; // Very high confidence
|
|
324
|
+
} else if (!validateChecksum) {
|
|
325
|
+
confidence = 0.9; // Still high if validation disabled
|
|
326
|
+
}
|
|
327
|
+
return confidence;
|
|
328
|
+
};
|
|
162
329
|
const candidateFromBarcode = (detection, validateChecksum) => {
|
|
163
330
|
'worklet';
|
|
164
331
|
|
|
@@ -167,31 +334,101 @@ const candidateFromBarcode = (detection, validateChecksum) => {
|
|
|
167
334
|
tokenizeCandidate(detection.displayValue ?? '').forEach(value => values.add(value));
|
|
168
335
|
const boundingBox = toBoundingBox(detection, 'barcode');
|
|
169
336
|
return Array.from(values).map(value => {
|
|
170
|
-
const
|
|
337
|
+
const confidence = calculateBarcodeConfidence(value, validateChecksum);
|
|
171
338
|
return {
|
|
172
339
|
value,
|
|
173
340
|
source: 'barcode',
|
|
174
|
-
confidence
|
|
341
|
+
confidence,
|
|
175
342
|
boundingBox,
|
|
176
343
|
origin: detection.displayValue ? 'displayValue' : 'rawValue',
|
|
177
344
|
rawPayload: detection
|
|
178
345
|
};
|
|
179
346
|
});
|
|
180
347
|
};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Calculate confidence score for a text-based VIN candidate
|
|
351
|
+
* Higher confidence for:
|
|
352
|
+
* - Valid check digit
|
|
353
|
+
* - Found with VIN prefix context
|
|
354
|
+
* - Element/line level detection (vs block level)
|
|
355
|
+
*/
|
|
356
|
+
const calculateTextConfidence = (value, rawText, origin, validateChecksum) => {
|
|
357
|
+
'worklet';
|
|
358
|
+
|
|
359
|
+
let confidence = 0.5; // Base confidence for text recognition
|
|
360
|
+
|
|
361
|
+
// Check digit validation significantly increases confidence
|
|
362
|
+
const checksumValid = isValidVin(value);
|
|
363
|
+
if (checksumValid) {
|
|
364
|
+
confidence += 0.35; // Boost to 0.85
|
|
365
|
+
} else if (!validateChecksum) {
|
|
366
|
+
confidence += 0.2; // Still boost if validation is disabled
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Context-aware detection (VIN prefix found) increases confidence
|
|
370
|
+
const hasVinPrefix = /VIN|Vehicle\s+(?:Identification|ID|Id)|Chassis|Serial/i.test(rawText);
|
|
371
|
+
if (hasVinPrefix) {
|
|
372
|
+
confidence += 0.1; // Boost to 0.95 if checksum valid, 0.6 if not
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Element-level text is more accurate than block-level
|
|
376
|
+
if (origin === 'element') {
|
|
377
|
+
confidence += 0.05;
|
|
378
|
+
} else if (origin === 'line') {
|
|
379
|
+
confidence += 0.03;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Cap at 0.98 (never 1.0 for text recognition)
|
|
383
|
+
return Math.min(confidence, 0.98);
|
|
384
|
+
};
|
|
181
385
|
const candidateFromText = (detection, validateChecksum) => {
|
|
182
386
|
'worklet';
|
|
183
387
|
|
|
184
|
-
const
|
|
185
|
-
|
|
388
|
+
const valueMap = new Map();
|
|
389
|
+
|
|
390
|
+
// Process each text level, with priority ordering
|
|
391
|
+
[{
|
|
392
|
+
text: detection.elementText,
|
|
393
|
+
order: 1
|
|
394
|
+
}, {
|
|
395
|
+
text: detection.lineText,
|
|
396
|
+
order: 2
|
|
397
|
+
}, {
|
|
398
|
+
text: detection.blockText,
|
|
399
|
+
order: 3
|
|
400
|
+
}, {
|
|
401
|
+
text: detection.resultText,
|
|
402
|
+
order: 4
|
|
403
|
+
}].forEach(({
|
|
404
|
+
text,
|
|
405
|
+
order
|
|
406
|
+
}) => {
|
|
407
|
+
if (text) {
|
|
408
|
+
tokenizeCandidate(text).forEach(v => {
|
|
409
|
+
var _valueMap$get;
|
|
410
|
+
if (!valueMap.has(v) || (((_valueMap$get = valueMap.get(v)) === null || _valueMap$get === void 0 ? void 0 : _valueMap$get.order) ?? 999) > order) {
|
|
411
|
+
valueMap.set(v, {
|
|
412
|
+
rawText: text,
|
|
413
|
+
order
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
});
|
|
186
419
|
const boundingBox = toBoundingBox(detection, 'line') ?? toBoundingBox(detection, 'element') ?? toBoundingBox(detection, 'block');
|
|
187
|
-
return Array.from(
|
|
188
|
-
|
|
420
|
+
return Array.from(valueMap.entries()).map(([value, {
|
|
421
|
+
rawText
|
|
422
|
+
}]) => {
|
|
423
|
+
var _detection$elementTex, _detection$lineText;
|
|
424
|
+
const origin = (_detection$elementTex = detection.elementText) !== null && _detection$elementTex !== void 0 && _detection$elementTex.includes(value) ? 'element' : (_detection$lineText = detection.lineText) !== null && _detection$lineText !== void 0 && _detection$lineText.includes(value) ? 'line' : 'block';
|
|
425
|
+
const confidence = calculateTextConfidence(value, rawText, origin, validateChecksum);
|
|
189
426
|
return {
|
|
190
427
|
value,
|
|
191
428
|
source: 'text',
|
|
192
|
-
confidence
|
|
429
|
+
confidence,
|
|
193
430
|
boundingBox,
|
|
194
|
-
origin
|
|
431
|
+
origin,
|
|
195
432
|
rawPayload: detection
|
|
196
433
|
};
|
|
197
434
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DEFAULT_RESOLVED_OPTIONS","barcode","enabled","formats","text","language","detection","resultMode","preferBarcode","validateChecksum","emitDuplicates","resolveOptions","options","_options$detection","_options$detection2","_options$barcode","_options$barcode2","_options$text","_options$text2","_options$detection3","_options$detection4","length","VIN_PATTERN","transliteration","A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z","weights","tokenizeCandidate","value","normalized","toUpperCase","cleaned","replace","tokens","split","filter","token","matches","Set","forEach","i","candidate","slice","test","add","Array","from","isValidVin","chars","sum","char","numeric","Number","parseInt","undefined","weight","remainder","expected","toString","checkDigit","toBoundingBox","preferred","maybe","top","bottom","left","right","width","height","block","blockBox","blockFrameTop","blockFrameBottom","blockFrameLeft","blockFrameRight","lineBox","lineFrameTop","lineFrameBottom","lineFrameLeft","lineFrameRight","elementBox","elementFrameTop","elementFrameBottom","elementFrameLeft","elementFrameRight","candidateFromBarcode","values","rawValue","displayValue","boundingBox","map","checksumValid","source","confidence","origin","rawPayload","candidateFromText","lineText","elementText","blockText","resultText","v","dedupeCandidates","candidates","Map","_candidate$boundingBo","_candidate$boundingBo2","key","join","existing","get","set","buildVinCandidates","payload","list","barcodes","push","textBlocks","textBlock","pickBestCandidate","sorted","sort","a","b"],"sourceRoot":"../../src","sources":["vinUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["DEFAULT_RESOLVED_OPTIONS","barcode","enabled","formats","text","language","detection","resultMode","preferBarcode","validateChecksum","emitDuplicates","resolveOptions","options","_options$detection","_options$detection2","_options$barcode","_options$barcode2","_options$text","_options$text2","_options$detection3","_options$detection4","length","transliteration","A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z","weights","OCR_SUBSTITUTIONS","VIN_PREFIX_PATTERNS","generateSubstitutionCandidates","value","maxSubstitutions","candidates","Set","positions","i","char","push","positionsToTry","slice","generate","current","posIndex","substitutionCount","add","pos","undefined","replacements","forEach","replacement","newValue","Array","from","extractWithContext","matches","VIN_PATTERN","pattern","match","exec","captured","replace","candidate","toUpperCase","test","tokenizeCandidate","normalized","vin","cleaned","tokens","split","filter","token","hasSubstitutableChars","substitutions","sub","isValidVin","chars","sum","numeric","Number","parseInt","weight","remainder","expected","toString","checkDigit","toBoundingBox","preferred","maybe","top","bottom","left","right","width","height","block","blockBox","blockFrameTop","blockFrameBottom","blockFrameLeft","blockFrameRight","lineBox","lineFrameTop","lineFrameBottom","lineFrameLeft","lineFrameRight","elementBox","elementFrameTop","elementFrameBottom","elementFrameLeft","elementFrameRight","calculateBarcodeConfidence","confidence","checksumValid","candidateFromBarcode","values","rawValue","displayValue","boundingBox","map","source","origin","rawPayload","calculateTextConfidence","rawText","hasVinPrefix","Math","min","candidateFromText","valueMap","Map","elementText","order","lineText","blockText","resultText","v","_valueMap$get","has","get","set","entries","_detection$elementTex","_detection$lineText","includes","dedupeCandidates","_candidate$boundingBo","_candidate$boundingBo2","key","join","existing","buildVinCandidates","payload","list","barcodes","textBlocks","textBlock","pickBestCandidate","sorted","sort","a","b"],"sourceRoot":"../../src","sources":["vinUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIN Scanner Utilities
|
|
3
|
+
*
|
|
4
|
+
* This module provides advanced VIN (Vehicle Identification Number) detection
|
|
5
|
+
* and validation capabilities with the following features:
|
|
6
|
+
*
|
|
7
|
+
* 1. OCR Error Correction: Automatically corrects common OCR misreads (O/0, I/1, etc.)
|
|
8
|
+
* 2. Context-Aware Detection: Looks for VIN prefixes like "VIN:", "Vehicle ID", etc.
|
|
9
|
+
* 3. Check Digit Validation: Validates VINs using ISO 3779 standard algorithm
|
|
10
|
+
* 4. Smart Confidence Scoring: Assigns reliability scores based on multiple factors
|
|
11
|
+
* 5. Multi-Level Processing: Extracts from element, line, and block level text
|
|
12
|
+
*
|
|
13
|
+
* @see https://en.wikipedia.org/wiki/Vehicle_identification_number
|
|
14
|
+
*/
|
|
1
15
|
import type { DetectionOptions, ScanBarcodeOptions, TextRecognitionLanguage, VinCandidate, VinResultMode, VinScannerOptions, WorkletPayload } from './types';
|
|
2
16
|
export type ResolvedVinScannerOptions = {
|
|
3
17
|
barcode: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vinUtils.d.ts","sourceRoot":"","sources":["../../../src/vinUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,kBAAkB,EAElB,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,kBAAkB,CAAC;KAC7B,CAAC;IACF,IAAI,EAAE;QACJ,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,uBAAuB,CAAC;KACnC,CAAC;IACF,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG;QAAE,UAAU,EAAE,aAAa,CAAA;KAAE,CAAC;CACvE,CAAC;AAmBF,eAAO,MAAM,cAAc,GACzB,UAAU,iBAAiB,KAC1B,
|
|
1
|
+
{"version":3,"file":"vinUtils.d.ts","sourceRoot":"","sources":["../../../src/vinUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAEV,gBAAgB,EAChB,kBAAkB,EAElB,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,kBAAkB,CAAC;KAC7B,CAAC;IACF,IAAI,EAAE;QACJ,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,uBAAuB,CAAC;KACnC,CAAC;IACF,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG;QAAE,UAAU,EAAE,aAAa,CAAA;KAAE,CAAC;CACvE,CAAC;AAmBF,eAAO,MAAM,cAAc,GACzB,UAAU,iBAAiB,KAC1B,yBAmCF,CAAC;AAmMF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,OA6B1C,CAAC;AAgQF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,cAAc,EACvB,SAAS,yBAAyB,KACjC,YAAY,EAkBd,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,YAAY,YAAY,EAAE,EAC1B,SAAS,yBAAyB,KACjC,YAAY,GAAG,IAejB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mleonard9/vin-scanner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "High-performance VIN scanner for React Native Vision Camera powered by Google ML Kit barcode + text recognition.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
package/src/vinUtils.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIN Scanner Utilities
|
|
3
|
+
*
|
|
4
|
+
* This module provides advanced VIN (Vehicle Identification Number) detection
|
|
5
|
+
* and validation capabilities with the following features:
|
|
6
|
+
*
|
|
7
|
+
* 1. OCR Error Correction: Automatically corrects common OCR misreads (O/0, I/1, etc.)
|
|
8
|
+
* 2. Context-Aware Detection: Looks for VIN prefixes like "VIN:", "Vehicle ID", etc.
|
|
9
|
+
* 3. Check Digit Validation: Validates VINs using ISO 3779 standard algorithm
|
|
10
|
+
* 4. Smart Confidence Scoring: Assigns reliability scores based on multiple factors
|
|
11
|
+
* 5. Multi-Level Processing: Extracts from element, line, and block level text
|
|
12
|
+
*
|
|
13
|
+
* @see https://en.wikipedia.org/wiki/Vehicle_identification_number
|
|
14
|
+
*/
|
|
15
|
+
|
|
1
16
|
import type {
|
|
2
17
|
BarcodeDetection,
|
|
3
18
|
DetectionOptions,
|
|
@@ -42,6 +57,7 @@ const DEFAULT_RESOLVED_OPTIONS: ResolvedVinScannerOptions = {
|
|
|
42
57
|
export const resolveOptions = (
|
|
43
58
|
options?: VinScannerOptions
|
|
44
59
|
): ResolvedVinScannerOptions => {
|
|
60
|
+
'worklet';
|
|
45
61
|
const resultMode: VinResultMode =
|
|
46
62
|
options?.detection?.resultMode ??
|
|
47
63
|
DEFAULT_RESOLVED_OPTIONS.detection.resultMode;
|
|
@@ -77,8 +93,6 @@ export const resolveOptions = (
|
|
|
77
93
|
};
|
|
78
94
|
};
|
|
79
95
|
|
|
80
|
-
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
81
|
-
|
|
82
96
|
const transliteration: Record<string, number> = {
|
|
83
97
|
A: 1,
|
|
84
98
|
B: 2,
|
|
@@ -107,31 +121,174 @@ const transliteration: Record<string, number> = {
|
|
|
107
121
|
|
|
108
122
|
const weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
109
123
|
|
|
124
|
+
// Common OCR misreads that need correction
|
|
125
|
+
const OCR_SUBSTITUTIONS: Record<string, string[]> = {
|
|
126
|
+
'O': ['0'], // O often misread as 0 (and vice versa)
|
|
127
|
+
'0': ['O'],
|
|
128
|
+
'I': ['1'], // I often misread as 1 (and vice versa)
|
|
129
|
+
'1': ['I'],
|
|
130
|
+
'Q': ['0', 'O'], // Q should not appear in VINs
|
|
131
|
+
'S': ['5'], // S can be misread as 5
|
|
132
|
+
'5': ['S'],
|
|
133
|
+
'B': ['8'], // B can be misread as 8
|
|
134
|
+
'8': ['B'],
|
|
135
|
+
'Z': ['2'], // Z can be misread as 2
|
|
136
|
+
'2': ['Z'],
|
|
137
|
+
'G': ['6'], // G can be misread as 6
|
|
138
|
+
'6': ['G'],
|
|
139
|
+
'D': ['0'], // D can be misread as 0
|
|
140
|
+
'U': ['V'], // U can be misread as V
|
|
141
|
+
'V': ['U'],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// VIN prefix patterns to detect context
|
|
145
|
+
const VIN_PREFIX_PATTERNS = [
|
|
146
|
+
/(?:^|[\s:])VIN[:\s]+([A-Z0-9]{17,})/i,
|
|
147
|
+
/(?:^|[\s:])V\.?I\.?N\.?[:\s]+([A-Z0-9]{17,})/i,
|
|
148
|
+
/Vehicle\s+(?:Identification\s+)?(?:Number|ID|Id)[:\s]+([A-Z0-9]{17,})/i,
|
|
149
|
+
/(?:^|[\s:])Chassis\s+(?:Number|No\.?)[:\s]+([A-Z0-9]{17,})/i,
|
|
150
|
+
/(?:^|[\s:])Serial\s+(?:Number|No\.?)[:\s]+([A-Z0-9]{17,})/i,
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Generate character substitution candidates for OCR error correction
|
|
155
|
+
* This creates variations of the input by substituting commonly misread characters
|
|
156
|
+
*/
|
|
157
|
+
const generateSubstitutionCandidates = (
|
|
158
|
+
value: string,
|
|
159
|
+
maxSubstitutions: number = 3
|
|
160
|
+
): string[] => {
|
|
161
|
+
'worklet';
|
|
162
|
+
const candidates = new Set<string>([value]);
|
|
163
|
+
|
|
164
|
+
// Find positions that might need substitution
|
|
165
|
+
const positions: number[] = [];
|
|
166
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
167
|
+
const char = value[i];
|
|
168
|
+
if (char && OCR_SUBSTITUTIONS[char]) {
|
|
169
|
+
positions.push(i);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Limit the number of positions to try (combinatorial explosion prevention)
|
|
174
|
+
const positionsToTry = positions.slice(0, maxSubstitutions);
|
|
175
|
+
|
|
176
|
+
// Generate candidates by substituting at different positions
|
|
177
|
+
const generate = (
|
|
178
|
+
current: string,
|
|
179
|
+
posIndex: number,
|
|
180
|
+
substitutionCount: number
|
|
181
|
+
) => {
|
|
182
|
+
if (
|
|
183
|
+
posIndex >= positionsToTry.length ||
|
|
184
|
+
substitutionCount >= maxSubstitutions
|
|
185
|
+
) {
|
|
186
|
+
candidates.add(current);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Don't substitute at this position
|
|
191
|
+
generate(current, posIndex + 1, substitutionCount);
|
|
192
|
+
|
|
193
|
+
// Try substituting at this position
|
|
194
|
+
const pos = positionsToTry[posIndex];
|
|
195
|
+
if (pos !== undefined) {
|
|
196
|
+
const char = current[pos];
|
|
197
|
+
const replacements = char ? OCR_SUBSTITUTIONS[char] : undefined;
|
|
198
|
+
if (replacements) {
|
|
199
|
+
replacements.forEach((replacement) => {
|
|
200
|
+
const newValue =
|
|
201
|
+
current.slice(0, pos) + replacement + current.slice(pos + 1);
|
|
202
|
+
generate(newValue, posIndex + 1, substitutionCount + 1);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
generate(value, 0, 0);
|
|
209
|
+
return Array.from(candidates);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Extract VINs using context-aware patterns (looking for VIN: prefix, etc.)
|
|
214
|
+
*/
|
|
215
|
+
const extractWithContext = (text: string): string[] => {
|
|
216
|
+
'worklet';
|
|
217
|
+
const matches = new Set<string>();
|
|
218
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
219
|
+
|
|
220
|
+
VIN_PREFIX_PATTERNS.forEach((pattern) => {
|
|
221
|
+
const match = pattern.exec(text);
|
|
222
|
+
if (match && match[1]) {
|
|
223
|
+
const captured = match[1].replace(/[^A-Z0-9]/gi, '');
|
|
224
|
+
// Extract exactly 17 characters
|
|
225
|
+
if (captured.length >= 17) {
|
|
226
|
+
const candidate = captured.slice(0, 17).toUpperCase();
|
|
227
|
+
if (VIN_PATTERN.test(candidate)) {
|
|
228
|
+
matches.add(candidate);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
return Array.from(matches);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Tokenize and extract VIN candidates from raw text
|
|
239
|
+
* Includes OCR error correction and context-aware extraction
|
|
240
|
+
*/
|
|
110
241
|
const tokenizeCandidate = (value: string): string[] => {
|
|
111
242
|
'worklet';
|
|
243
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
112
244
|
if (!value) {
|
|
113
245
|
return [];
|
|
114
246
|
}
|
|
247
|
+
|
|
115
248
|
const normalized = value.toUpperCase();
|
|
249
|
+
const matches = new Set<string>();
|
|
250
|
+
|
|
251
|
+
// First, try context-aware extraction (VIN: prefix, etc.)
|
|
252
|
+
extractWithContext(normalized).forEach((vin) => matches.add(vin));
|
|
253
|
+
|
|
254
|
+
// Then do regular tokenization
|
|
116
255
|
const cleaned = normalized.replace(/[^A-Z0-9]/g, ' ');
|
|
117
256
|
const tokens = cleaned.split(/\s+/).filter((token) => token.length > 0);
|
|
118
|
-
|
|
257
|
+
|
|
119
258
|
tokens.forEach((token) => {
|
|
120
259
|
if (token.length < 17) {
|
|
121
260
|
return;
|
|
122
261
|
}
|
|
262
|
+
|
|
263
|
+
// Try every 17-character substring
|
|
123
264
|
for (let i = 0; i <= token.length - 17; i += 1) {
|
|
124
265
|
const candidate = token.slice(i, i + 17);
|
|
266
|
+
|
|
267
|
+
// Direct match
|
|
125
268
|
if (VIN_PATTERN.test(candidate)) {
|
|
126
269
|
matches.add(candidate);
|
|
127
270
|
}
|
|
271
|
+
|
|
272
|
+
// Try with OCR substitutions for candidates that are close
|
|
273
|
+
// Only if they contain substitutable characters and don't match directly
|
|
274
|
+
const hasSubstitutableChars = /[OISQBZGDUV]/.test(candidate);
|
|
275
|
+
if (hasSubstitutableChars) {
|
|
276
|
+
const substitutions = generateSubstitutionCandidates(candidate, 2);
|
|
277
|
+
substitutions.forEach((sub) => {
|
|
278
|
+
if (VIN_PATTERN.test(sub)) {
|
|
279
|
+
matches.add(sub);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
128
283
|
}
|
|
129
284
|
});
|
|
285
|
+
|
|
130
286
|
return Array.from(matches);
|
|
131
287
|
};
|
|
132
288
|
|
|
133
289
|
export const isValidVin = (value: string): boolean => {
|
|
134
290
|
'worklet';
|
|
291
|
+
const VIN_PATTERN = /^[A-HJ-NPR-Z0-9]{17}$/;
|
|
135
292
|
if (!VIN_PATTERN.test(value)) {
|
|
136
293
|
return false;
|
|
137
294
|
}
|
|
@@ -253,6 +410,28 @@ const toBoundingBox = (
|
|
|
253
410
|
return blockBox || lineBox || elementBox;
|
|
254
411
|
};
|
|
255
412
|
|
|
413
|
+
/**
|
|
414
|
+
* Calculate confidence score for a barcode-based VIN candidate
|
|
415
|
+
* Barcodes are generally more reliable than text recognition
|
|
416
|
+
*/
|
|
417
|
+
const calculateBarcodeConfidence = (
|
|
418
|
+
value: string,
|
|
419
|
+
validateChecksum: boolean
|
|
420
|
+
): number => {
|
|
421
|
+
'worklet';
|
|
422
|
+
let confidence = 0.85; // Base confidence for barcode
|
|
423
|
+
|
|
424
|
+
// Check digit validation
|
|
425
|
+
const checksumValid = isValidVin(value);
|
|
426
|
+
if (checksumValid) {
|
|
427
|
+
confidence = 0.98; // Very high confidence
|
|
428
|
+
} else if (!validateChecksum) {
|
|
429
|
+
confidence = 0.9; // Still high if validation disabled
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return confidence;
|
|
433
|
+
};
|
|
434
|
+
|
|
256
435
|
const candidateFromBarcode = (
|
|
257
436
|
detection: BarcodeDetection,
|
|
258
437
|
validateChecksum: boolean
|
|
@@ -267,11 +446,11 @@ const candidateFromBarcode = (
|
|
|
267
446
|
);
|
|
268
447
|
const boundingBox = toBoundingBox(detection, 'barcode');
|
|
269
448
|
return Array.from(values).map((value) => {
|
|
270
|
-
const
|
|
449
|
+
const confidence = calculateBarcodeConfidence(value, validateChecksum);
|
|
271
450
|
return {
|
|
272
451
|
value,
|
|
273
452
|
source: 'barcode' as const,
|
|
274
|
-
confidence
|
|
453
|
+
confidence,
|
|
275
454
|
boundingBox,
|
|
276
455
|
origin: detection.displayValue ? 'displayValue' : 'rawValue',
|
|
277
456
|
rawPayload: detection,
|
|
@@ -279,36 +458,96 @@ const candidateFromBarcode = (
|
|
|
279
458
|
});
|
|
280
459
|
};
|
|
281
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Calculate confidence score for a text-based VIN candidate
|
|
463
|
+
* Higher confidence for:
|
|
464
|
+
* - Valid check digit
|
|
465
|
+
* - Found with VIN prefix context
|
|
466
|
+
* - Element/line level detection (vs block level)
|
|
467
|
+
*/
|
|
468
|
+
const calculateTextConfidence = (
|
|
469
|
+
value: string,
|
|
470
|
+
rawText: string,
|
|
471
|
+
origin: string,
|
|
472
|
+
validateChecksum: boolean
|
|
473
|
+
): number => {
|
|
474
|
+
'worklet';
|
|
475
|
+
let confidence = 0.5; // Base confidence for text recognition
|
|
476
|
+
|
|
477
|
+
// Check digit validation significantly increases confidence
|
|
478
|
+
const checksumValid = isValidVin(value);
|
|
479
|
+
if (checksumValid) {
|
|
480
|
+
confidence += 0.35; // Boost to 0.85
|
|
481
|
+
} else if (!validateChecksum) {
|
|
482
|
+
confidence += 0.2; // Still boost if validation is disabled
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Context-aware detection (VIN prefix found) increases confidence
|
|
486
|
+
const hasVinPrefix =
|
|
487
|
+
/VIN|Vehicle\s+(?:Identification|ID|Id)|Chassis|Serial/i.test(rawText);
|
|
488
|
+
if (hasVinPrefix) {
|
|
489
|
+
confidence += 0.1; // Boost to 0.95 if checksum valid, 0.6 if not
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Element-level text is more accurate than block-level
|
|
493
|
+
if (origin === 'element') {
|
|
494
|
+
confidence += 0.05;
|
|
495
|
+
} else if (origin === 'line') {
|
|
496
|
+
confidence += 0.03;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Cap at 0.98 (never 1.0 for text recognition)
|
|
500
|
+
return Math.min(confidence, 0.98);
|
|
501
|
+
};
|
|
502
|
+
|
|
282
503
|
const candidateFromText = (
|
|
283
504
|
detection: TextDetection,
|
|
284
505
|
validateChecksum: boolean
|
|
285
506
|
): VinCandidate[] => {
|
|
286
507
|
'worklet';
|
|
287
|
-
const
|
|
508
|
+
const valueMap = new Map<string, { rawText: string; order: number }>();
|
|
509
|
+
|
|
510
|
+
// Process each text level, with priority ordering
|
|
288
511
|
[
|
|
289
|
-
detection.
|
|
290
|
-
detection.
|
|
291
|
-
detection.blockText,
|
|
292
|
-
detection.resultText,
|
|
293
|
-
].forEach((
|
|
294
|
-
|
|
295
|
-
|
|
512
|
+
{ text: detection.elementText, order: 1 },
|
|
513
|
+
{ text: detection.lineText, order: 2 },
|
|
514
|
+
{ text: detection.blockText, order: 3 },
|
|
515
|
+
{ text: detection.resultText, order: 4 },
|
|
516
|
+
].forEach(({ text, order }) => {
|
|
517
|
+
if (text) {
|
|
518
|
+
tokenizeCandidate(text).forEach((v) => {
|
|
519
|
+
if (!valueMap.has(v) || (valueMap.get(v)?.order ?? 999) > order) {
|
|
520
|
+
valueMap.set(v, { rawText: text, order });
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
|
|
296
526
|
const boundingBox =
|
|
297
527
|
toBoundingBox(detection, 'line') ??
|
|
298
528
|
toBoundingBox(detection, 'element') ??
|
|
299
529
|
toBoundingBox(detection, 'block');
|
|
300
|
-
|
|
301
|
-
|
|
530
|
+
|
|
531
|
+
return Array.from(valueMap.entries()).map(([value, { rawText }]) => {
|
|
532
|
+
const origin = detection.elementText?.includes(value)
|
|
533
|
+
? 'element'
|
|
534
|
+
: detection.lineText?.includes(value)
|
|
535
|
+
? 'line'
|
|
536
|
+
: 'block';
|
|
537
|
+
|
|
538
|
+
const confidence = calculateTextConfidence(
|
|
539
|
+
value,
|
|
540
|
+
rawText,
|
|
541
|
+
origin,
|
|
542
|
+
validateChecksum
|
|
543
|
+
);
|
|
544
|
+
|
|
302
545
|
return {
|
|
303
546
|
value,
|
|
304
547
|
source: 'text' as const,
|
|
305
|
-
confidence
|
|
548
|
+
confidence,
|
|
306
549
|
boundingBox,
|
|
307
|
-
origin
|
|
308
|
-
? 'element'
|
|
309
|
-
: detection.lineText
|
|
310
|
-
? 'line'
|
|
311
|
-
: 'block',
|
|
550
|
+
origin,
|
|
312
551
|
rawPayload: detection,
|
|
313
552
|
};
|
|
314
553
|
});
|