idmission-web-sdk 2.3.200 → 2.3.201
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/dist/components/submission/SubmissionProvider.d.ts.map +1 -1
- package/dist/lib/barcode/AAMVAParser.d.ts +7 -0
- package/dist/lib/barcode/AAMVAParser.d.ts.map +1 -1
- package/dist/lib/barcode/AAMVAParser.test.d.ts +2 -0
- package/dist/lib/barcode/AAMVAParser.test.d.ts.map +1 -0
- package/dist/sdk2.cjs.development.js +467 -452
- package/dist/sdk2.cjs.development.js.map +1 -1
- package/dist/sdk2.cjs.production.js +1 -1
- package/dist/sdk2.cjs.production.js.map +1 -1
- package/dist/sdk2.esm.js +467 -452
- package/dist/sdk2.esm.js.map +1 -1
- package/dist/sdk2.umd.development.js +2727 -2712
- package/dist/sdk2.umd.development.js.map +1 -1
- package/dist/sdk2.umd.production.js +1 -1
- package/dist/sdk2.umd.production.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -235,7 +235,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
235
235
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
236
236
|
};
|
|
237
237
|
|
|
238
|
-
var webSdkVersion = '2.3.
|
|
238
|
+
var webSdkVersion = '2.3.201';
|
|
239
239
|
|
|
240
240
|
function getPlatform() {
|
|
241
241
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -1239,57 +1239,476 @@ function AuthProvider(_a) {
|
|
|
1239
1239
|
}, children));
|
|
1240
1240
|
}
|
|
1241
1241
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1242
|
+
/**
|
|
1243
|
+
* Parser for AAMVA (American Association of Motor Vehicle Administrators)
|
|
1244
|
+
* PDF417 barcode data found on US and Canadian driver's licenses.
|
|
1245
|
+
*/
|
|
1246
|
+
// AAMVA field codes to human-readable labels
|
|
1247
|
+
var AAMVA_FIELD_LABELS = {
|
|
1248
|
+
// Required fields
|
|
1249
|
+
DCS: 'Last Name',
|
|
1250
|
+
DAC: 'First Name',
|
|
1251
|
+
DAD: 'Middle Name',
|
|
1252
|
+
DAA: 'Full Name',
|
|
1253
|
+
// Older AAMVA versions (1-3) use this instead of separate name fields
|
|
1254
|
+
DBB: 'Date of Birth',
|
|
1255
|
+
DBC: 'Sex',
|
|
1256
|
+
DAY: 'Eye Color',
|
|
1257
|
+
DAU: 'Height',
|
|
1258
|
+
DAG: 'Street Address',
|
|
1259
|
+
DAI: 'City',
|
|
1260
|
+
DAJ: 'State',
|
|
1261
|
+
DAK: 'ZIP Code',
|
|
1262
|
+
DAQ: 'License Number',
|
|
1263
|
+
DCF: 'Document Discriminator',
|
|
1264
|
+
DCG: 'Country',
|
|
1265
|
+
DDE: 'Last Name Truncation',
|
|
1266
|
+
DDF: 'First Name Truncation',
|
|
1267
|
+
DDG: 'Middle Name Truncation',
|
|
1268
|
+
// Optional fields
|
|
1269
|
+
DBD: 'Document Issue Date',
|
|
1270
|
+
DBA: 'Document Expiration Date',
|
|
1271
|
+
DCD: 'Jurisdiction Restriction Codes',
|
|
1272
|
+
DCB: 'Jurisdiction Endorsement Codes',
|
|
1273
|
+
DCA: 'Vehicle Class',
|
|
1274
|
+
DCE: 'Weight Range',
|
|
1275
|
+
DCL: 'Race/Ethnicity',
|
|
1276
|
+
DCM: 'Standard Vehicle Classification',
|
|
1277
|
+
DCN: 'Standard Endorsement Code',
|
|
1278
|
+
DCO: 'Standard Restriction Code',
|
|
1279
|
+
DCP: 'Jurisdiction Vehicle Class Description',
|
|
1280
|
+
DCQ: 'Jurisdiction Endorsement Code Description',
|
|
1281
|
+
DCR: 'Jurisdiction Restriction Code Description',
|
|
1282
|
+
DDA: 'Compliance Type',
|
|
1283
|
+
DDB: 'Card Revision Date',
|
|
1284
|
+
DDC: 'HAZMAT Endorsement Expiration Date',
|
|
1285
|
+
DDD: 'Limited Duration Document Indicator',
|
|
1286
|
+
DDH: 'Under 18 Until',
|
|
1287
|
+
DDI: 'Under 19 Until',
|
|
1288
|
+
DDJ: 'Under 21 Until',
|
|
1289
|
+
DDK: 'Organ Donor Indicator',
|
|
1290
|
+
DDL: 'Veteran Indicator',
|
|
1291
|
+
DAW: 'Weight (lbs)',
|
|
1292
|
+
DAX: 'Weight (kg)',
|
|
1293
|
+
DAZ: 'Hair Color',
|
|
1294
|
+
DBN: 'Alias/AKA Last Name',
|
|
1295
|
+
DBG: 'Alias/AKA First Name',
|
|
1296
|
+
DBS: 'Alias/AKA Suffix',
|
|
1297
|
+
DCU: 'Name Suffix',
|
|
1298
|
+
DCT: 'First Name Alias',
|
|
1299
|
+
DAH: 'Street Address Line 2',
|
|
1300
|
+
DAL: 'Residence Street Address',
|
|
1301
|
+
DAN: 'Residence City',
|
|
1302
|
+
DAO: 'Residence State',
|
|
1303
|
+
DAP: 'Residence ZIP'
|
|
1304
|
+
};
|
|
1305
|
+
// Sex code mappings
|
|
1306
|
+
var SEX_CODES = {
|
|
1307
|
+
'1': 'Male',
|
|
1308
|
+
'2': 'Female',
|
|
1309
|
+
'9': 'Not Specified'
|
|
1310
|
+
};
|
|
1311
|
+
// Eye color code mappings
|
|
1312
|
+
var EYE_COLOR_CODES = {
|
|
1313
|
+
BLK: 'Black',
|
|
1314
|
+
BLU: 'Blue',
|
|
1315
|
+
BRO: 'Brown',
|
|
1316
|
+
GRY: 'Gray',
|
|
1317
|
+
GRN: 'Green',
|
|
1318
|
+
HAZ: 'Hazel',
|
|
1319
|
+
MAR: 'Maroon',
|
|
1320
|
+
PNK: 'Pink',
|
|
1321
|
+
DIC: 'Dichromatic',
|
|
1322
|
+
UNK: 'Unknown'
|
|
1323
|
+
};
|
|
1324
|
+
// Hair color code mappings
|
|
1325
|
+
var HAIR_COLOR_CODES = {
|
|
1326
|
+
BAL: 'Bald',
|
|
1327
|
+
BLK: 'Black',
|
|
1328
|
+
BLN: 'Blond',
|
|
1329
|
+
BRO: 'Brown',
|
|
1330
|
+
GRY: 'Gray',
|
|
1331
|
+
RED: 'Red/Auburn',
|
|
1332
|
+
SDY: 'Sandy',
|
|
1333
|
+
WHI: 'White',
|
|
1334
|
+
UNK: 'Unknown'
|
|
1335
|
+
};
|
|
1336
|
+
/**
|
|
1337
|
+
* Formats a date string from AAMVA format to readable format (MM/DD/YYYY).
|
|
1338
|
+
* AAMVA versions 1-3 use YYYYMMDD (CCYYMMDD) format.
|
|
1339
|
+
* AAMVA versions 4+ use MMDDYYYY (MMDDCCYY) format.
|
|
1340
|
+
*/
|
|
1341
|
+
function formatDate(value, aamvaVersion) {
|
|
1342
|
+
if (value.length !== 8) return value;
|
|
1343
|
+
// AAMVA versions 1-3 (pre-2000) use YYYYMMDD format
|
|
1344
|
+
// AAMVA versions 4+ (2000 onwards) use MMDDYYYY format
|
|
1345
|
+
var usesYYYYMMDD = aamvaVersion !== undefined && aamvaVersion <= 3;
|
|
1346
|
+
var month, day, year;
|
|
1347
|
+
if (usesYYYYMMDD) {
|
|
1348
|
+
// YYYYMMDD format (older versions)
|
|
1349
|
+
year = value.substring(0, 4);
|
|
1350
|
+
month = value.substring(4, 6);
|
|
1351
|
+
day = value.substring(6, 8);
|
|
1352
|
+
} else {
|
|
1353
|
+
// MMDDYYYY format (newer versions, default)
|
|
1354
|
+
month = value.substring(0, 2);
|
|
1355
|
+
day = value.substring(2, 4);
|
|
1356
|
+
year = value.substring(4, 8);
|
|
1357
|
+
}
|
|
1358
|
+
return "".concat(month, "/").concat(day, "/").concat(year);
|
|
1245
1359
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1360
|
+
/**
|
|
1361
|
+
* Formats a value based on its field code
|
|
1362
|
+
*/
|
|
1363
|
+
function formatValue$1(code, value, aamvaVersion) {
|
|
1364
|
+
// Date fields
|
|
1365
|
+
if (['DBB', 'DBD', 'DBA', 'DDB', 'DDC', 'DDH', 'DDI', 'DDJ'].includes(code)) {
|
|
1366
|
+
return formatDate(value, aamvaVersion);
|
|
1367
|
+
}
|
|
1368
|
+
// Sex field
|
|
1369
|
+
if (code === 'DBC') {
|
|
1370
|
+
return SEX_CODES[value] || value;
|
|
1371
|
+
}
|
|
1372
|
+
// Eye color
|
|
1373
|
+
if (code === 'DAY') {
|
|
1374
|
+
return EYE_COLOR_CODES[value] || value;
|
|
1375
|
+
}
|
|
1376
|
+
// Hair color
|
|
1377
|
+
if (code === 'DAZ') {
|
|
1378
|
+
return HAIR_COLOR_CODES[value] || value;
|
|
1379
|
+
}
|
|
1380
|
+
// Height - format as feet and inches
|
|
1381
|
+
if (code === 'DAU') {
|
|
1382
|
+
// Format is typically "XXX in" or "FT IN"
|
|
1383
|
+
var match = value.match(/^(\d{3})/);
|
|
1384
|
+
if (match) {
|
|
1385
|
+
var inches = parseInt(match[1], 10);
|
|
1386
|
+
var feet = Math.floor(inches / 12);
|
|
1387
|
+
var remainingInches = inches % 12;
|
|
1388
|
+
return "".concat(feet, "'").concat(remainingInches, "\"");
|
|
1389
|
+
}
|
|
1390
|
+
return value;
|
|
1391
|
+
}
|
|
1392
|
+
// ZIP code - format with hyphen if 9 digits
|
|
1393
|
+
if (code === 'DAK' && value.length === 9) {
|
|
1394
|
+
return "".concat(value.substring(0, 5), "-").concat(value.substring(5));
|
|
1395
|
+
}
|
|
1396
|
+
return value.trim();
|
|
1249
1397
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1398
|
+
/**
|
|
1399
|
+
* Extracts the AAMVA version from the barcode header.
|
|
1400
|
+
* Header format: ANSI <IIN(6 digits)><AAMVA Version(2 digits)><Jurisdiction Version(2 digits)>...
|
|
1401
|
+
* Returns undefined if version cannot be determined.
|
|
1402
|
+
*/
|
|
1403
|
+
function extractAAMVAVersion(rawData) {
|
|
1404
|
+
// Match ANSI followed by at least 8 digits (6 for IIN + 2 for version)
|
|
1405
|
+
var headerMatch = rawData.match(/ANSI\s*(\d{6})(\d{2})/);
|
|
1406
|
+
if (headerMatch) {
|
|
1407
|
+
var version = parseInt(headerMatch[2], 10);
|
|
1408
|
+
// Valid AAMVA versions are 1-99 (realistically 1-10 as of 2024)
|
|
1409
|
+
if (version >= 1 && version <= 99) {
|
|
1410
|
+
return version;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
return undefined;
|
|
1254
1414
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
};
|
|
1267
|
-
var sanitizeMetadata = function sanitizeMetadata(metadata) {
|
|
1268
|
-
var entries = Object.entries(metadata).filter(function (_a) {
|
|
1269
|
-
var value = _a[1];
|
|
1270
|
-
return value !== undefined && value !== null;
|
|
1415
|
+
/**
|
|
1416
|
+
* Parses the DAA field (full name) used in older AAMVA versions.
|
|
1417
|
+
* Format is typically "LAST,FIRST,MIDDLE" or "LAST,FIRST MIDDLE".
|
|
1418
|
+
* Returns an array of ParsedAAMVAField for LastName, FirstName, and MiddleName.
|
|
1419
|
+
*/
|
|
1420
|
+
function parseDAAField(value) {
|
|
1421
|
+
var fields = [];
|
|
1422
|
+
// DAA format is typically "LASTNAME,FIRSTNAME,MIDDLENAME" or "LASTNAME,FIRSTNAME MIDDLENAME"
|
|
1423
|
+
// Some jurisdictions use spaces instead of commas
|
|
1424
|
+
var parts = value.split(',').map(function (p) {
|
|
1425
|
+
return p.trim();
|
|
1271
1426
|
});
|
|
1272
|
-
if (
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1427
|
+
if (parts.length >= 1 && parts[0]) {
|
|
1428
|
+
fields.push({
|
|
1429
|
+
code: 'DCS',
|
|
1430
|
+
label: 'Last Name',
|
|
1431
|
+
value: parts[0]
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
if (parts.length >= 2 && parts[1]) {
|
|
1435
|
+
// The second part might contain "FIRSTNAME MIDDLENAME"
|
|
1436
|
+
var nameParts = parts[1].split(/\s+/);
|
|
1437
|
+
if (nameParts[0]) {
|
|
1438
|
+
fields.push({
|
|
1439
|
+
code: 'DAC',
|
|
1440
|
+
label: 'First Name',
|
|
1441
|
+
value: nameParts[0]
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
// If there's more after the first name, treat it as middle name
|
|
1445
|
+
if (nameParts.length > 1) {
|
|
1446
|
+
fields.push({
|
|
1447
|
+
code: 'DAD',
|
|
1448
|
+
label: 'Middle Name',
|
|
1449
|
+
value: nameParts.slice(1).join(' ')
|
|
1280
1450
|
});
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
// If there's a third comma-separated part, it's the middle name
|
|
1454
|
+
if (parts.length >= 3 && parts[2]) {
|
|
1455
|
+
// Check if we already added a middle name from the second part
|
|
1456
|
+
var existingMiddle = fields.find(function (f) {
|
|
1457
|
+
return f.code === 'DAD';
|
|
1281
1458
|
});
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1459
|
+
if (!existingMiddle) {
|
|
1460
|
+
fields.push({
|
|
1461
|
+
code: 'DAD',
|
|
1462
|
+
label: 'Middle Name',
|
|
1463
|
+
value: parts[2]
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
return fields;
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Parses AAMVA PDF417 barcode data into structured fields
|
|
1471
|
+
*/
|
|
1472
|
+
function parseAAMVABarcode(rawData) {
|
|
1473
|
+
var result = {
|
|
1474
|
+
fields: [],
|
|
1475
|
+
rawData: rawData
|
|
1476
|
+
};
|
|
1477
|
+
// Extract AAMVA version first - needed for date format detection
|
|
1478
|
+
result.aamvaVersion = extractAAMVAVersion(rawData);
|
|
1479
|
+
// Extract jurisdiction ID from header
|
|
1480
|
+
var headerMatch = rawData.match(/ANSI\s*(\d{6})/);
|
|
1481
|
+
if (headerMatch) {
|
|
1482
|
+
result.jurisdictionId = headerMatch[1];
|
|
1483
|
+
}
|
|
1484
|
+
// Clean up the data - remove control characters but keep newlines for parsing
|
|
1485
|
+
// AAMVA uses various separators: \n, \r, record separator (0x1E), etc.
|
|
1486
|
+
// eslint-disable-next-line no-control-regex
|
|
1487
|
+
var controlCharRegex = /[\x00-\x09\x0B\x0C\x0E-\x1F]/g;
|
|
1488
|
+
var cleanData = rawData.replace(controlCharRegex, '\n') // Replace control chars with newlines
|
|
1489
|
+
.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
1490
|
+
// Split into lines
|
|
1491
|
+
var lines = cleanData.split('\n').filter(function (line) {
|
|
1492
|
+
return line.trim();
|
|
1493
|
+
});
|
|
1494
|
+
// Extract fields using regex - AAMVA fields are 3-letter codes followed by data
|
|
1495
|
+
var fieldRegex = /^([A-Z]{3})(.*)$/;
|
|
1496
|
+
// Track if we've seen separate name fields (DCS, DAC, DAD)
|
|
1497
|
+
var hasSeenNameFields = {
|
|
1498
|
+
DCS: false,
|
|
1499
|
+
DAC: false,
|
|
1500
|
+
DAD: false
|
|
1501
|
+
};
|
|
1502
|
+
var daaValue = null;
|
|
1503
|
+
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
|
|
1504
|
+
var line = lines_1[_i];
|
|
1505
|
+
var match = line.match(fieldRegex);
|
|
1506
|
+
if (match) {
|
|
1507
|
+
var code = match[1],
|
|
1508
|
+
rawValue = match[2];
|
|
1509
|
+
var value = rawValue.trim();
|
|
1510
|
+
// Skip empty values and header/version info
|
|
1511
|
+
if (!value || code === 'ANS') continue;
|
|
1512
|
+
// Track name fields
|
|
1513
|
+
if (code === 'DCS' || code === 'DAC' || code === 'DAD') {
|
|
1514
|
+
hasSeenNameFields[code] = true;
|
|
1515
|
+
}
|
|
1516
|
+
// Store DAA value for later processing (in case no separate name fields exist)
|
|
1517
|
+
if (code === 'DAA') {
|
|
1518
|
+
daaValue = value;
|
|
1519
|
+
continue; // Don't add DAA directly, we'll process it below
|
|
1520
|
+
}
|
|
1521
|
+
var label = AAMVA_FIELD_LABELS[code] || code;
|
|
1522
|
+
var formattedValue = formatValue$1(code, value, result.aamvaVersion);
|
|
1523
|
+
result.fields.push({
|
|
1524
|
+
code: code,
|
|
1525
|
+
label: label,
|
|
1526
|
+
value: formattedValue
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
// If we have a DAA field and are missing any separate name fields, parse DAA
|
|
1531
|
+
if (daaValue && (!hasSeenNameFields.DCS || !hasSeenNameFields.DAC)) {
|
|
1532
|
+
var daaFields = parseDAAField(daaValue);
|
|
1533
|
+
var _loop_1 = function _loop_1(field) {
|
|
1534
|
+
// Only add if we don't already have this field
|
|
1535
|
+
var existingField = result.fields.find(function (f) {
|
|
1536
|
+
return f.code === field.code;
|
|
1537
|
+
});
|
|
1538
|
+
if (!existingField) {
|
|
1539
|
+
result.fields.push(field);
|
|
1540
|
+
}
|
|
1541
|
+
};
|
|
1542
|
+
for (var _a = 0, daaFields_1 = daaFields; _a < daaFields_1.length; _a++) {
|
|
1543
|
+
var field = daaFields_1[_a];
|
|
1544
|
+
_loop_1(field);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
return result;
|
|
1548
|
+
}
|
|
1549
|
+
/**
|
|
1550
|
+
* Gets a specific field value from parsed AAMVA data
|
|
1551
|
+
*/
|
|
1552
|
+
function getAAMVAField(parsed, code) {
|
|
1553
|
+
var field = parsed.fields.find(function (f) {
|
|
1554
|
+
return f.code === code;
|
|
1555
|
+
});
|
|
1556
|
+
return field === null || field === void 0 ? void 0 : field.value;
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Converts a date from MM/DD/YYYY format to DD/MM/YYYY format.
|
|
1560
|
+
* Returns empty string if input is empty or invalid.
|
|
1561
|
+
*/
|
|
1562
|
+
function convertToApiDateFormat(dateStr) {
|
|
1563
|
+
if (!dateStr) return '';
|
|
1564
|
+
var parts = dateStr.split('/');
|
|
1565
|
+
if (parts.length !== 3) return dateStr;
|
|
1566
|
+
var month = parts[0],
|
|
1567
|
+
day = parts[1],
|
|
1568
|
+
year = parts[2];
|
|
1569
|
+
return "".concat(day, "/").concat(month, "/").concat(year);
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Converts parsed AAMVA barcode data to ocrMetadata format for submission API.
|
|
1573
|
+
* Returns the IDData object ready to be stringified for the ocrMetadata field.
|
|
1574
|
+
*/
|
|
1575
|
+
function convertAAMVAToOCRMetadata(parsed) {
|
|
1576
|
+
var getField = function getField(code) {
|
|
1577
|
+
return getAAMVAField(parsed, code);
|
|
1578
|
+
};
|
|
1579
|
+
// Get state code for various fields
|
|
1580
|
+
var state = getField('DAJ') || '';
|
|
1581
|
+
// Determine gender from sex code
|
|
1582
|
+
var sexCode = getField('DBC');
|
|
1583
|
+
var gender = '';
|
|
1584
|
+
if (sexCode === 'Male' || sexCode === '1') gender = 'M';else if (sexCode === 'Female' || sexCode === '2') gender = 'F';
|
|
1585
|
+
// Get dates and convert from MM/DD/YYYY to DD/MM/YYYY format
|
|
1586
|
+
var expiryDate = convertToApiDateFormat(getField('DBA') || '');
|
|
1587
|
+
var issueDate = convertToApiDateFormat(getField('DBD') || '');
|
|
1588
|
+
var dateOfBirth = convertToApiDateFormat(getField('DBB') || '');
|
|
1589
|
+
// Calculate Under21 status based on DOB (using original MM/DD/YYYY format)
|
|
1590
|
+
var under21 = 'N';
|
|
1591
|
+
var rawDob = getField('DBB') || '';
|
|
1592
|
+
if (rawDob) {
|
|
1593
|
+
var parts = rawDob.split('/');
|
|
1594
|
+
if (parts.length === 3) {
|
|
1595
|
+
var month = parseInt(parts[0], 10);
|
|
1596
|
+
var day = parseInt(parts[1], 10);
|
|
1597
|
+
var year = parseInt(parts[2], 10);
|
|
1598
|
+
var dob = new Date(year, month - 1, day);
|
|
1599
|
+
var today = new Date();
|
|
1600
|
+
var age = today.getFullYear() - dob.getFullYear();
|
|
1601
|
+
var monthDiff = today.getMonth() - dob.getMonth();
|
|
1602
|
+
if (monthDiff < 0 || monthDiff === 0 && today.getDate() < dob.getDate()) {
|
|
1603
|
+
if (age - 1 < 21) under21 = 'Y';
|
|
1604
|
+
} else {
|
|
1605
|
+
if (age < 21) under21 = 'Y';
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
var idData = {
|
|
1610
|
+
IDCountry: 'USA',
|
|
1611
|
+
IDCountry_ISO2: 'US',
|
|
1612
|
+
IssuingCountry: 'USA',
|
|
1613
|
+
IDType: 'DL',
|
|
1614
|
+
DocumentTypeCode: 'DL',
|
|
1615
|
+
IDNumber: getField('DAQ') || '',
|
|
1616
|
+
IDState: state,
|
|
1617
|
+
State: state,
|
|
1618
|
+
FirstName: getField('DAC') || '',
|
|
1619
|
+
MiddleName: getField('DAD') || '',
|
|
1620
|
+
LastName: getField('DCS') || '',
|
|
1621
|
+
Gender: gender,
|
|
1622
|
+
DateofBirth: dateOfBirth,
|
|
1623
|
+
DateOfExpiry: expiryDate,
|
|
1624
|
+
ExpiryDate: expiryDate,
|
|
1625
|
+
DateOfIssue: issueDate,
|
|
1626
|
+
IssueDate: issueDate,
|
|
1627
|
+
AddressLine1: getField('DAG') || '',
|
|
1628
|
+
City: getField('DAI') || '',
|
|
1629
|
+
ZipCode: (getField('DAK') || '').replace(/-/g, ''),
|
|
1630
|
+
// Remove hyphen for API
|
|
1631
|
+
Country: 'USA',
|
|
1632
|
+
Eyes: getField('DAY') || '',
|
|
1633
|
+
Under21: under21,
|
|
1634
|
+
BarcodeDataParsed: 'Y'
|
|
1635
|
+
};
|
|
1636
|
+
// Remove empty string values to keep the payload clean
|
|
1637
|
+
var cleanedIdData = Object.fromEntries(Object.entries(idData).filter(function (_a) {
|
|
1638
|
+
var value = _a[1];
|
|
1639
|
+
return value !== '';
|
|
1640
|
+
}));
|
|
1641
|
+
// Always include BarcodeDataParsed
|
|
1642
|
+
cleanedIdData.BarcodeDataParsed = 'Y';
|
|
1643
|
+
return {
|
|
1644
|
+
IDData: cleanedIdData
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
/**
|
|
1648
|
+
* Builds the ocrMetadata payload reported when a barcode capture flow ran
|
|
1649
|
+
* but no barcode was successfully parsed. Records the attempt count so the
|
|
1650
|
+
* backend can distinguish "user never tried" from "user tried N times".
|
|
1651
|
+
*/
|
|
1652
|
+
function buildNoBarcodeOCRMetadata(attemptCount) {
|
|
1653
|
+
return {
|
|
1654
|
+
IDData: {
|
|
1655
|
+
BarcodeDataParsed: 'N',
|
|
1656
|
+
BarcodeAttemptCount: String(attemptCount)
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
exports.defaultSubmissionUrl = 'https://portal-api.idmission.com/swagger';
|
|
1662
|
+
function setDefaultSubmissionUrl(url) {
|
|
1663
|
+
exports.defaultSubmissionUrl = url;
|
|
1664
|
+
}
|
|
1665
|
+
var defaultDocumentServiceUrl = 'https://portal-api.idmission.com/files/';
|
|
1666
|
+
function setDefaultDocumentServiceUrl(url) {
|
|
1667
|
+
defaultDocumentServiceUrl = url;
|
|
1668
|
+
}
|
|
1669
|
+
function setServerUrl(url) {
|
|
1670
|
+
setDefaultAuthUrl(url);
|
|
1671
|
+
setDefaultSubmissionUrl(url + '/swagger');
|
|
1672
|
+
setDefaultDocumentServiceUrl(url + '/files/');
|
|
1673
|
+
}
|
|
1674
|
+
var capturedDocumentTypeToSubmissionKey = {
|
|
1675
|
+
idCardFront: 'idFrontImage',
|
|
1676
|
+
idCardBack: 'idBackImage',
|
|
1677
|
+
passport: 'passportImage',
|
|
1678
|
+
singlePage: 'idFrontImage',
|
|
1679
|
+
selfie: 'selfieImage',
|
|
1680
|
+
idFrontIrImage: 'idFrontIrImage',
|
|
1681
|
+
idBackIrImage: 'idBackIrImage',
|
|
1682
|
+
idFrontUvImage: 'idFrontUvImage',
|
|
1683
|
+
idBackUvImage: 'idBackUvImage',
|
|
1684
|
+
idBarcodeImage: 'idBarcodeImage'
|
|
1685
|
+
};
|
|
1686
|
+
var sanitizeMetadata = function sanitizeMetadata(metadata) {
|
|
1687
|
+
var entries = Object.entries(metadata).filter(function (_a) {
|
|
1688
|
+
var value = _a[1];
|
|
1689
|
+
return value !== undefined && value !== null;
|
|
1690
|
+
});
|
|
1691
|
+
if (!entries.length) return null;
|
|
1692
|
+
return Object.fromEntries(entries);
|
|
1693
|
+
};
|
|
1694
|
+
var SubmissionContext = /*#__PURE__*/React.createContext({
|
|
1695
|
+
submit: function submit() {
|
|
1696
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
1697
|
+
return __generator(this, function (_a) {
|
|
1698
|
+
return [2 /*return*/, null];
|
|
1699
|
+
});
|
|
1700
|
+
});
|
|
1701
|
+
},
|
|
1702
|
+
submissionStatus: SubmissionStatus.READY,
|
|
1703
|
+
submissionRequest: null,
|
|
1704
|
+
submissionResponse: null,
|
|
1705
|
+
submissionError: null,
|
|
1706
|
+
submissionEnvironment: 'prod',
|
|
1707
|
+
idFrontImage: null,
|
|
1708
|
+
idBackImage: null,
|
|
1709
|
+
passportImage: null,
|
|
1710
|
+
idFrontIrImage: null,
|
|
1711
|
+
idBackIrImage: null,
|
|
1293
1712
|
idFrontUvImage: null,
|
|
1294
1713
|
idBackUvImage: null,
|
|
1295
1714
|
idBarcodeImage: null,
|
|
@@ -1931,6 +2350,8 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
1931
2350
|
}
|
|
1932
2351
|
if (ocrMetadata) {
|
|
1933
2352
|
submissionRequest.additionalData.ocrMetadata = ocrMetadata;
|
|
2353
|
+
} else if (barcodeCaptureAttempts.length > 0) {
|
|
2354
|
+
submissionRequest.additionalData.ocrMetadata = JSON.stringify(buildNoBarcodeOCRMetadata(barcodeCaptureAttempts.length));
|
|
1934
2355
|
}
|
|
1935
2356
|
if (signatureData) {
|
|
1936
2357
|
submissionRequest.customerData.signatureData = {
|
|
@@ -10593,412 +11014,6 @@ var Card = styled__default.default.div(templateObject_1$G || (templateObject_1$G
|
|
|
10593
11014
|
var FlexCard = styled__default.default(Card)(templateObject_2$C || (templateObject_2$C = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n"], ["\n display: flex;\n flex-direction: column;\n"])));
|
|
10594
11015
|
var templateObject_1$G, templateObject_2$C;
|
|
10595
11016
|
|
|
10596
|
-
/**
|
|
10597
|
-
* Parser for AAMVA (American Association of Motor Vehicle Administrators)
|
|
10598
|
-
* PDF417 barcode data found on US and Canadian driver's licenses.
|
|
10599
|
-
*/
|
|
10600
|
-
// AAMVA field codes to human-readable labels
|
|
10601
|
-
var AAMVA_FIELD_LABELS = {
|
|
10602
|
-
// Required fields
|
|
10603
|
-
DCS: 'Last Name',
|
|
10604
|
-
DAC: 'First Name',
|
|
10605
|
-
DAD: 'Middle Name',
|
|
10606
|
-
DAA: 'Full Name',
|
|
10607
|
-
// Older AAMVA versions (1-3) use this instead of separate name fields
|
|
10608
|
-
DBB: 'Date of Birth',
|
|
10609
|
-
DBC: 'Sex',
|
|
10610
|
-
DAY: 'Eye Color',
|
|
10611
|
-
DAU: 'Height',
|
|
10612
|
-
DAG: 'Street Address',
|
|
10613
|
-
DAI: 'City',
|
|
10614
|
-
DAJ: 'State',
|
|
10615
|
-
DAK: 'ZIP Code',
|
|
10616
|
-
DAQ: 'License Number',
|
|
10617
|
-
DCF: 'Document Discriminator',
|
|
10618
|
-
DCG: 'Country',
|
|
10619
|
-
DDE: 'Last Name Truncation',
|
|
10620
|
-
DDF: 'First Name Truncation',
|
|
10621
|
-
DDG: 'Middle Name Truncation',
|
|
10622
|
-
// Optional fields
|
|
10623
|
-
DBD: 'Document Issue Date',
|
|
10624
|
-
DBA: 'Document Expiration Date',
|
|
10625
|
-
DCD: 'Jurisdiction Restriction Codes',
|
|
10626
|
-
DCB: 'Jurisdiction Endorsement Codes',
|
|
10627
|
-
DCA: 'Vehicle Class',
|
|
10628
|
-
DCE: 'Weight Range',
|
|
10629
|
-
DCL: 'Race/Ethnicity',
|
|
10630
|
-
DCM: 'Standard Vehicle Classification',
|
|
10631
|
-
DCN: 'Standard Endorsement Code',
|
|
10632
|
-
DCO: 'Standard Restriction Code',
|
|
10633
|
-
DCP: 'Jurisdiction Vehicle Class Description',
|
|
10634
|
-
DCQ: 'Jurisdiction Endorsement Code Description',
|
|
10635
|
-
DCR: 'Jurisdiction Restriction Code Description',
|
|
10636
|
-
DDA: 'Compliance Type',
|
|
10637
|
-
DDB: 'Card Revision Date',
|
|
10638
|
-
DDC: 'HAZMAT Endorsement Expiration Date',
|
|
10639
|
-
DDD: 'Limited Duration Document Indicator',
|
|
10640
|
-
DDH: 'Under 18 Until',
|
|
10641
|
-
DDI: 'Under 19 Until',
|
|
10642
|
-
DDJ: 'Under 21 Until',
|
|
10643
|
-
DDK: 'Organ Donor Indicator',
|
|
10644
|
-
DDL: 'Veteran Indicator',
|
|
10645
|
-
DAW: 'Weight (lbs)',
|
|
10646
|
-
DAX: 'Weight (kg)',
|
|
10647
|
-
DAZ: 'Hair Color',
|
|
10648
|
-
DBN: 'Alias/AKA Last Name',
|
|
10649
|
-
DBG: 'Alias/AKA First Name',
|
|
10650
|
-
DBS: 'Alias/AKA Suffix',
|
|
10651
|
-
DCU: 'Name Suffix',
|
|
10652
|
-
DCT: 'First Name Alias',
|
|
10653
|
-
DAH: 'Street Address Line 2',
|
|
10654
|
-
DAL: 'Residence Street Address',
|
|
10655
|
-
DAN: 'Residence City',
|
|
10656
|
-
DAO: 'Residence State',
|
|
10657
|
-
DAP: 'Residence ZIP'
|
|
10658
|
-
};
|
|
10659
|
-
// Sex code mappings
|
|
10660
|
-
var SEX_CODES = {
|
|
10661
|
-
'1': 'Male',
|
|
10662
|
-
'2': 'Female',
|
|
10663
|
-
'9': 'Not Specified'
|
|
10664
|
-
};
|
|
10665
|
-
// Eye color code mappings
|
|
10666
|
-
var EYE_COLOR_CODES = {
|
|
10667
|
-
BLK: 'Black',
|
|
10668
|
-
BLU: 'Blue',
|
|
10669
|
-
BRO: 'Brown',
|
|
10670
|
-
GRY: 'Gray',
|
|
10671
|
-
GRN: 'Green',
|
|
10672
|
-
HAZ: 'Hazel',
|
|
10673
|
-
MAR: 'Maroon',
|
|
10674
|
-
PNK: 'Pink',
|
|
10675
|
-
DIC: 'Dichromatic',
|
|
10676
|
-
UNK: 'Unknown'
|
|
10677
|
-
};
|
|
10678
|
-
// Hair color code mappings
|
|
10679
|
-
var HAIR_COLOR_CODES = {
|
|
10680
|
-
BAL: 'Bald',
|
|
10681
|
-
BLK: 'Black',
|
|
10682
|
-
BLN: 'Blond',
|
|
10683
|
-
BRO: 'Brown',
|
|
10684
|
-
GRY: 'Gray',
|
|
10685
|
-
RED: 'Red/Auburn',
|
|
10686
|
-
SDY: 'Sandy',
|
|
10687
|
-
WHI: 'White',
|
|
10688
|
-
UNK: 'Unknown'
|
|
10689
|
-
};
|
|
10690
|
-
/**
|
|
10691
|
-
* Formats a date string from AAMVA format to readable format (MM/DD/YYYY).
|
|
10692
|
-
* AAMVA versions 1-3 use YYYYMMDD (CCYYMMDD) format.
|
|
10693
|
-
* AAMVA versions 4+ use MMDDYYYY (MMDDCCYY) format.
|
|
10694
|
-
*/
|
|
10695
|
-
function formatDate(value, aamvaVersion) {
|
|
10696
|
-
if (value.length !== 8) return value;
|
|
10697
|
-
// AAMVA versions 1-3 (pre-2000) use YYYYMMDD format
|
|
10698
|
-
// AAMVA versions 4+ (2000 onwards) use MMDDYYYY format
|
|
10699
|
-
var usesYYYYMMDD = aamvaVersion !== undefined && aamvaVersion <= 3;
|
|
10700
|
-
var month, day, year;
|
|
10701
|
-
if (usesYYYYMMDD) {
|
|
10702
|
-
// YYYYMMDD format (older versions)
|
|
10703
|
-
year = value.substring(0, 4);
|
|
10704
|
-
month = value.substring(4, 6);
|
|
10705
|
-
day = value.substring(6, 8);
|
|
10706
|
-
} else {
|
|
10707
|
-
// MMDDYYYY format (newer versions, default)
|
|
10708
|
-
month = value.substring(0, 2);
|
|
10709
|
-
day = value.substring(2, 4);
|
|
10710
|
-
year = value.substring(4, 8);
|
|
10711
|
-
}
|
|
10712
|
-
return "".concat(month, "/").concat(day, "/").concat(year);
|
|
10713
|
-
}
|
|
10714
|
-
/**
|
|
10715
|
-
* Formats a value based on its field code
|
|
10716
|
-
*/
|
|
10717
|
-
function formatValue$1(code, value, aamvaVersion) {
|
|
10718
|
-
// Date fields
|
|
10719
|
-
if (['DBB', 'DBD', 'DBA', 'DDB', 'DDC', 'DDH', 'DDI', 'DDJ'].includes(code)) {
|
|
10720
|
-
return formatDate(value, aamvaVersion);
|
|
10721
|
-
}
|
|
10722
|
-
// Sex field
|
|
10723
|
-
if (code === 'DBC') {
|
|
10724
|
-
return SEX_CODES[value] || value;
|
|
10725
|
-
}
|
|
10726
|
-
// Eye color
|
|
10727
|
-
if (code === 'DAY') {
|
|
10728
|
-
return EYE_COLOR_CODES[value] || value;
|
|
10729
|
-
}
|
|
10730
|
-
// Hair color
|
|
10731
|
-
if (code === 'DAZ') {
|
|
10732
|
-
return HAIR_COLOR_CODES[value] || value;
|
|
10733
|
-
}
|
|
10734
|
-
// Height - format as feet and inches
|
|
10735
|
-
if (code === 'DAU') {
|
|
10736
|
-
// Format is typically "XXX in" or "FT IN"
|
|
10737
|
-
var match = value.match(/^(\d{3})/);
|
|
10738
|
-
if (match) {
|
|
10739
|
-
var inches = parseInt(match[1], 10);
|
|
10740
|
-
var feet = Math.floor(inches / 12);
|
|
10741
|
-
var remainingInches = inches % 12;
|
|
10742
|
-
return "".concat(feet, "'").concat(remainingInches, "\"");
|
|
10743
|
-
}
|
|
10744
|
-
return value;
|
|
10745
|
-
}
|
|
10746
|
-
// ZIP code - format with hyphen if 9 digits
|
|
10747
|
-
if (code === 'DAK' && value.length === 9) {
|
|
10748
|
-
return "".concat(value.substring(0, 5), "-").concat(value.substring(5));
|
|
10749
|
-
}
|
|
10750
|
-
return value.trim();
|
|
10751
|
-
}
|
|
10752
|
-
/**
|
|
10753
|
-
* Extracts the AAMVA version from the barcode header.
|
|
10754
|
-
* Header format: ANSI <IIN(6 digits)><AAMVA Version(2 digits)><Jurisdiction Version(2 digits)>...
|
|
10755
|
-
* Returns undefined if version cannot be determined.
|
|
10756
|
-
*/
|
|
10757
|
-
function extractAAMVAVersion(rawData) {
|
|
10758
|
-
// Match ANSI followed by at least 8 digits (6 for IIN + 2 for version)
|
|
10759
|
-
var headerMatch = rawData.match(/ANSI\s*(\d{6})(\d{2})/);
|
|
10760
|
-
if (headerMatch) {
|
|
10761
|
-
var version = parseInt(headerMatch[2], 10);
|
|
10762
|
-
// Valid AAMVA versions are 1-99 (realistically 1-10 as of 2024)
|
|
10763
|
-
if (version >= 1 && version <= 99) {
|
|
10764
|
-
return version;
|
|
10765
|
-
}
|
|
10766
|
-
}
|
|
10767
|
-
return undefined;
|
|
10768
|
-
}
|
|
10769
|
-
/**
|
|
10770
|
-
* Parses the DAA field (full name) used in older AAMVA versions.
|
|
10771
|
-
* Format is typically "LAST,FIRST,MIDDLE" or "LAST,FIRST MIDDLE".
|
|
10772
|
-
* Returns an array of ParsedAAMVAField for LastName, FirstName, and MiddleName.
|
|
10773
|
-
*/
|
|
10774
|
-
function parseDAAField(value) {
|
|
10775
|
-
var fields = [];
|
|
10776
|
-
// DAA format is typically "LASTNAME,FIRSTNAME,MIDDLENAME" or "LASTNAME,FIRSTNAME MIDDLENAME"
|
|
10777
|
-
// Some jurisdictions use spaces instead of commas
|
|
10778
|
-
var parts = value.split(',').map(function (p) {
|
|
10779
|
-
return p.trim();
|
|
10780
|
-
});
|
|
10781
|
-
if (parts.length >= 1 && parts[0]) {
|
|
10782
|
-
fields.push({
|
|
10783
|
-
code: 'DCS',
|
|
10784
|
-
label: 'Last Name',
|
|
10785
|
-
value: parts[0]
|
|
10786
|
-
});
|
|
10787
|
-
}
|
|
10788
|
-
if (parts.length >= 2 && parts[1]) {
|
|
10789
|
-
// The second part might contain "FIRSTNAME MIDDLENAME"
|
|
10790
|
-
var nameParts = parts[1].split(/\s+/);
|
|
10791
|
-
if (nameParts[0]) {
|
|
10792
|
-
fields.push({
|
|
10793
|
-
code: 'DAC',
|
|
10794
|
-
label: 'First Name',
|
|
10795
|
-
value: nameParts[0]
|
|
10796
|
-
});
|
|
10797
|
-
}
|
|
10798
|
-
// If there's more after the first name, treat it as middle name
|
|
10799
|
-
if (nameParts.length > 1) {
|
|
10800
|
-
fields.push({
|
|
10801
|
-
code: 'DAD',
|
|
10802
|
-
label: 'Middle Name',
|
|
10803
|
-
value: nameParts.slice(1).join(' ')
|
|
10804
|
-
});
|
|
10805
|
-
}
|
|
10806
|
-
}
|
|
10807
|
-
// If there's a third comma-separated part, it's the middle name
|
|
10808
|
-
if (parts.length >= 3 && parts[2]) {
|
|
10809
|
-
// Check if we already added a middle name from the second part
|
|
10810
|
-
var existingMiddle = fields.find(function (f) {
|
|
10811
|
-
return f.code === 'DAD';
|
|
10812
|
-
});
|
|
10813
|
-
if (!existingMiddle) {
|
|
10814
|
-
fields.push({
|
|
10815
|
-
code: 'DAD',
|
|
10816
|
-
label: 'Middle Name',
|
|
10817
|
-
value: parts[2]
|
|
10818
|
-
});
|
|
10819
|
-
}
|
|
10820
|
-
}
|
|
10821
|
-
return fields;
|
|
10822
|
-
}
|
|
10823
|
-
/**
|
|
10824
|
-
* Parses AAMVA PDF417 barcode data into structured fields
|
|
10825
|
-
*/
|
|
10826
|
-
function parseAAMVABarcode(rawData) {
|
|
10827
|
-
var result = {
|
|
10828
|
-
fields: [],
|
|
10829
|
-
rawData: rawData
|
|
10830
|
-
};
|
|
10831
|
-
// Extract AAMVA version first - needed for date format detection
|
|
10832
|
-
result.aamvaVersion = extractAAMVAVersion(rawData);
|
|
10833
|
-
// Extract jurisdiction ID from header
|
|
10834
|
-
var headerMatch = rawData.match(/ANSI\s*(\d{6})/);
|
|
10835
|
-
if (headerMatch) {
|
|
10836
|
-
result.jurisdictionId = headerMatch[1];
|
|
10837
|
-
}
|
|
10838
|
-
// Clean up the data - remove control characters but keep newlines for parsing
|
|
10839
|
-
// AAMVA uses various separators: \n, \r, record separator (0x1E), etc.
|
|
10840
|
-
// eslint-disable-next-line no-control-regex
|
|
10841
|
-
var controlCharRegex = /[\x00-\x09\x0B\x0C\x0E-\x1F]/g;
|
|
10842
|
-
var cleanData = rawData.replace(controlCharRegex, '\n') // Replace control chars with newlines
|
|
10843
|
-
.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
10844
|
-
// Split into lines
|
|
10845
|
-
var lines = cleanData.split('\n').filter(function (line) {
|
|
10846
|
-
return line.trim();
|
|
10847
|
-
});
|
|
10848
|
-
// Extract fields using regex - AAMVA fields are 3-letter codes followed by data
|
|
10849
|
-
var fieldRegex = /^([A-Z]{3})(.*)$/;
|
|
10850
|
-
// Track if we've seen separate name fields (DCS, DAC, DAD)
|
|
10851
|
-
var hasSeenNameFields = {
|
|
10852
|
-
DCS: false,
|
|
10853
|
-
DAC: false,
|
|
10854
|
-
DAD: false
|
|
10855
|
-
};
|
|
10856
|
-
var daaValue = null;
|
|
10857
|
-
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
|
|
10858
|
-
var line = lines_1[_i];
|
|
10859
|
-
var match = line.match(fieldRegex);
|
|
10860
|
-
if (match) {
|
|
10861
|
-
var code = match[1],
|
|
10862
|
-
rawValue = match[2];
|
|
10863
|
-
var value = rawValue.trim();
|
|
10864
|
-
// Skip empty values and header/version info
|
|
10865
|
-
if (!value || code === 'ANS') continue;
|
|
10866
|
-
// Track name fields
|
|
10867
|
-
if (code === 'DCS' || code === 'DAC' || code === 'DAD') {
|
|
10868
|
-
hasSeenNameFields[code] = true;
|
|
10869
|
-
}
|
|
10870
|
-
// Store DAA value for later processing (in case no separate name fields exist)
|
|
10871
|
-
if (code === 'DAA') {
|
|
10872
|
-
daaValue = value;
|
|
10873
|
-
continue; // Don't add DAA directly, we'll process it below
|
|
10874
|
-
}
|
|
10875
|
-
var label = AAMVA_FIELD_LABELS[code] || code;
|
|
10876
|
-
var formattedValue = formatValue$1(code, value, result.aamvaVersion);
|
|
10877
|
-
result.fields.push({
|
|
10878
|
-
code: code,
|
|
10879
|
-
label: label,
|
|
10880
|
-
value: formattedValue
|
|
10881
|
-
});
|
|
10882
|
-
}
|
|
10883
|
-
}
|
|
10884
|
-
// If we have a DAA field and are missing any separate name fields, parse DAA
|
|
10885
|
-
if (daaValue && (!hasSeenNameFields.DCS || !hasSeenNameFields.DAC)) {
|
|
10886
|
-
var daaFields = parseDAAField(daaValue);
|
|
10887
|
-
var _loop_1 = function _loop_1(field) {
|
|
10888
|
-
// Only add if we don't already have this field
|
|
10889
|
-
var existingField = result.fields.find(function (f) {
|
|
10890
|
-
return f.code === field.code;
|
|
10891
|
-
});
|
|
10892
|
-
if (!existingField) {
|
|
10893
|
-
result.fields.push(field);
|
|
10894
|
-
}
|
|
10895
|
-
};
|
|
10896
|
-
for (var _a = 0, daaFields_1 = daaFields; _a < daaFields_1.length; _a++) {
|
|
10897
|
-
var field = daaFields_1[_a];
|
|
10898
|
-
_loop_1(field);
|
|
10899
|
-
}
|
|
10900
|
-
}
|
|
10901
|
-
return result;
|
|
10902
|
-
}
|
|
10903
|
-
/**
|
|
10904
|
-
* Gets a specific field value from parsed AAMVA data
|
|
10905
|
-
*/
|
|
10906
|
-
function getAAMVAField(parsed, code) {
|
|
10907
|
-
var field = parsed.fields.find(function (f) {
|
|
10908
|
-
return f.code === code;
|
|
10909
|
-
});
|
|
10910
|
-
return field === null || field === void 0 ? void 0 : field.value;
|
|
10911
|
-
}
|
|
10912
|
-
/**
|
|
10913
|
-
* Converts a date from MM/DD/YYYY format to DD/MM/YYYY format.
|
|
10914
|
-
* Returns empty string if input is empty or invalid.
|
|
10915
|
-
*/
|
|
10916
|
-
function convertToApiDateFormat(dateStr) {
|
|
10917
|
-
if (!dateStr) return '';
|
|
10918
|
-
var parts = dateStr.split('/');
|
|
10919
|
-
if (parts.length !== 3) return dateStr;
|
|
10920
|
-
var month = parts[0],
|
|
10921
|
-
day = parts[1],
|
|
10922
|
-
year = parts[2];
|
|
10923
|
-
return "".concat(day, "/").concat(month, "/").concat(year);
|
|
10924
|
-
}
|
|
10925
|
-
/**
|
|
10926
|
-
* Converts parsed AAMVA barcode data to ocrMetadata format for submission API.
|
|
10927
|
-
* Returns the IDData object ready to be stringified for the ocrMetadata field.
|
|
10928
|
-
*/
|
|
10929
|
-
function convertAAMVAToOCRMetadata(parsed) {
|
|
10930
|
-
var getField = function getField(code) {
|
|
10931
|
-
return getAAMVAField(parsed, code);
|
|
10932
|
-
};
|
|
10933
|
-
// Get state code for various fields
|
|
10934
|
-
var state = getField('DAJ') || '';
|
|
10935
|
-
// Determine gender from sex code
|
|
10936
|
-
var sexCode = getField('DBC');
|
|
10937
|
-
var gender = '';
|
|
10938
|
-
if (sexCode === 'Male' || sexCode === '1') gender = 'M';else if (sexCode === 'Female' || sexCode === '2') gender = 'F';
|
|
10939
|
-
// Get dates and convert from MM/DD/YYYY to DD/MM/YYYY format
|
|
10940
|
-
var expiryDate = convertToApiDateFormat(getField('DBA') || '');
|
|
10941
|
-
var issueDate = convertToApiDateFormat(getField('DBD') || '');
|
|
10942
|
-
var dateOfBirth = convertToApiDateFormat(getField('DBB') || '');
|
|
10943
|
-
// Calculate Under21 status based on DOB (using original MM/DD/YYYY format)
|
|
10944
|
-
var under21 = 'N';
|
|
10945
|
-
var rawDob = getField('DBB') || '';
|
|
10946
|
-
if (rawDob) {
|
|
10947
|
-
var parts = rawDob.split('/');
|
|
10948
|
-
if (parts.length === 3) {
|
|
10949
|
-
var month = parseInt(parts[0], 10);
|
|
10950
|
-
var day = parseInt(parts[1], 10);
|
|
10951
|
-
var year = parseInt(parts[2], 10);
|
|
10952
|
-
var dob = new Date(year, month - 1, day);
|
|
10953
|
-
var today = new Date();
|
|
10954
|
-
var age = today.getFullYear() - dob.getFullYear();
|
|
10955
|
-
var monthDiff = today.getMonth() - dob.getMonth();
|
|
10956
|
-
if (monthDiff < 0 || monthDiff === 0 && today.getDate() < dob.getDate()) {
|
|
10957
|
-
if (age - 1 < 21) under21 = 'Y';
|
|
10958
|
-
} else {
|
|
10959
|
-
if (age < 21) under21 = 'Y';
|
|
10960
|
-
}
|
|
10961
|
-
}
|
|
10962
|
-
}
|
|
10963
|
-
var idData = {
|
|
10964
|
-
IDCountry: 'USA',
|
|
10965
|
-
IDCountry_ISO2: 'US',
|
|
10966
|
-
IssuingCountry: 'USA',
|
|
10967
|
-
IDType: 'DL',
|
|
10968
|
-
DocumentTypeCode: 'DL',
|
|
10969
|
-
IDNumber: getField('DAQ') || '',
|
|
10970
|
-
IDState: state,
|
|
10971
|
-
State: state,
|
|
10972
|
-
FirstName: getField('DAC') || '',
|
|
10973
|
-
MiddleName: getField('DAD') || '',
|
|
10974
|
-
LastName: getField('DCS') || '',
|
|
10975
|
-
Gender: gender,
|
|
10976
|
-
DateofBirth: dateOfBirth,
|
|
10977
|
-
DateOfExpiry: expiryDate,
|
|
10978
|
-
ExpiryDate: expiryDate,
|
|
10979
|
-
DateOfIssue: issueDate,
|
|
10980
|
-
IssueDate: issueDate,
|
|
10981
|
-
AddressLine1: getField('DAG') || '',
|
|
10982
|
-
City: getField('DAI') || '',
|
|
10983
|
-
ZipCode: (getField('DAK') || '').replace(/-/g, ''),
|
|
10984
|
-
// Remove hyphen for API
|
|
10985
|
-
Country: 'USA',
|
|
10986
|
-
Eyes: getField('DAY') || '',
|
|
10987
|
-
Under21: under21,
|
|
10988
|
-
BarcodeDataParsed: 'Y'
|
|
10989
|
-
};
|
|
10990
|
-
// Remove empty string values to keep the payload clean
|
|
10991
|
-
var cleanedIdData = Object.fromEntries(Object.entries(idData).filter(function (_a) {
|
|
10992
|
-
var value = _a[1];
|
|
10993
|
-
return value !== '';
|
|
10994
|
-
}));
|
|
10995
|
-
// Always include BarcodeDataParsed
|
|
10996
|
-
cleanedIdData.BarcodeDataParsed = 'Y';
|
|
10997
|
-
return {
|
|
10998
|
-
IDData: cleanedIdData
|
|
10999
|
-
};
|
|
11000
|
-
}
|
|
11001
|
-
|
|
11002
11017
|
var imageDisplayOrder = ['idCardFront', 'idCardBack', 'idBarcodeImage', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
|
|
11003
11018
|
var downloadImage = function downloadImage(dataUrl, filename) {
|
|
11004
11019
|
var link = document.createElement('a');
|