@claritylabs/cl-sdk 3.0.32 → 3.0.33
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/index.js +123 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +123 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3337,6 +3337,14 @@ function valueFromNode(node, value, confidence = "medium") {
|
|
|
3337
3337
|
sourceSpanIds: node.sourceSpanIds
|
|
3338
3338
|
};
|
|
3339
3339
|
}
|
|
3340
|
+
function valueFromNodes(nodes, value, confidence = "medium", normalizedValue) {
|
|
3341
|
+
return {
|
|
3342
|
+
value,
|
|
3343
|
+
...normalizedValue ? { normalizedValue } : {},
|
|
3344
|
+
confidence,
|
|
3345
|
+
...sourceIds(nodes)
|
|
3346
|
+
};
|
|
3347
|
+
}
|
|
3340
3348
|
function firstMatch(nodes, patterns) {
|
|
3341
3349
|
for (const node of nodes) {
|
|
3342
3350
|
const text = nodeText(node);
|
|
@@ -3413,8 +3421,65 @@ function cleanNamedInsured(value) {
|
|
|
3413
3421
|
}
|
|
3414
3422
|
return clean;
|
|
3415
3423
|
}
|
|
3424
|
+
var PARTY_LABEL_PATTERNS = {
|
|
3425
|
+
namedInsured: /^(?:item\s*\d+[.)]?\s*)?(?:named insured(?:\s+and\s+address)?|insured name)$/i,
|
|
3426
|
+
insurer: /^(?:carrier|insurer|security)$/i,
|
|
3427
|
+
broker: /^(?:broker(?:\s+of\s+record)?|producer|agent)$/i
|
|
3428
|
+
};
|
|
3429
|
+
function partyLabelKind(value) {
|
|
3430
|
+
const clean = cleanValue(value.replace(/^\s*column\s+\d+\s*:\s*/i, ""));
|
|
3431
|
+
if (!clean) return void 0;
|
|
3432
|
+
if (PARTY_LABEL_PATTERNS.namedInsured.test(clean)) return "namedInsured";
|
|
3433
|
+
if (PARTY_LABEL_PATTERNS.insurer.test(clean)) return "insurer";
|
|
3434
|
+
if (PARTY_LABEL_PATTERNS.broker.test(clean)) return "broker";
|
|
3435
|
+
return void 0;
|
|
3436
|
+
}
|
|
3437
|
+
function isRejectedPartyValue(value) {
|
|
3438
|
+
const clean = normalizeWhitespace3(value);
|
|
3439
|
+
return /^(?:and address|of record|insurer|carrier|security|broker|producer|agent|the|a|an|is|are|was|were|agrees?|means?|includes?|shall|will)\b/i.test(clean);
|
|
3440
|
+
}
|
|
3441
|
+
function identityWithoutAddress(value) {
|
|
3442
|
+
const clean = cleanValue(value.replace(/\b(?:phone|tel|telephone|email|e-mail)\b.*$/i, "").replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b.*$/i, ""));
|
|
3443
|
+
if (!clean) return void 0;
|
|
3444
|
+
const beforeStreet = clean.match(/^(.+?)\s+\d{1,6}\s+[A-Za-z0-9.'-]+(?:\s+[A-Za-z0-9.'-]+){0,5}\s+(?:street|st\.?|avenue|ave\.?|road|rd\.?|drive|dr\.?|lane|ln\.?|boulevard|blvd\.?|suite|ste\.?|floor|fl\.?|way|court|ct\.?)\b/i)?.[1];
|
|
3445
|
+
const beforeCityState = clean.match(/^(.+?)\s+[A-Z][A-Za-z.'-]+(?:\s+[A-Z][A-Za-z.'-]+)*,\s*[A-Z]{2}\s+\d{5}(?:-\d{4})?\b/)?.[1];
|
|
3446
|
+
return cleanValue(beforeStreet ?? beforeCityState ?? clean);
|
|
3447
|
+
}
|
|
3448
|
+
function cleanPartyIdentity(value, clean) {
|
|
3449
|
+
const raw = cleanValue(value);
|
|
3450
|
+
if (!raw || isRejectedPartyValue(raw)) return void 0;
|
|
3451
|
+
const identity = identityWithoutAddress(raw);
|
|
3452
|
+
const cleaned = identity ? clean(identity) : void 0;
|
|
3453
|
+
if (!cleaned || isRejectedPartyValue(cleaned)) return void 0;
|
|
3454
|
+
return {
|
|
3455
|
+
value: cleaned,
|
|
3456
|
+
...cleaned !== raw ? { normalizedValue: cleaned } : {}
|
|
3457
|
+
};
|
|
3458
|
+
}
|
|
3459
|
+
function partyFromTableRows(nodes, wanted, clean) {
|
|
3460
|
+
const children = childMap(nodes);
|
|
3461
|
+
for (const row of compactFactNodes(nodes).filter((node) => node.kind === "table_row")) {
|
|
3462
|
+
const cells = cellRows(row, children);
|
|
3463
|
+
for (const [index, cell] of cells.entries()) {
|
|
3464
|
+
const labelKind = partyLabelKind(cell.value) ?? partyLabelKind(cell.label);
|
|
3465
|
+
if (labelKind !== wanted) continue;
|
|
3466
|
+
const valueCell = cells.slice(index + 1).find((candidate) => !partyLabelKind(candidate.value) && !partyLabelKind(candidate.label));
|
|
3467
|
+
if (!valueCell) continue;
|
|
3468
|
+
const cleaned = cleanPartyIdentity(valueCell.value, clean);
|
|
3469
|
+
if (cleaned) return valueFromNodes([row, valueCell.node], cleaned.value, "high", cleaned.normalizedValue);
|
|
3470
|
+
}
|
|
3471
|
+
const parts = normalizeWhitespace3(row.textExcerpt ?? row.description ?? nodeText(row)).split(/\s+\|\s+|\t/).map(cleanValue).filter((part) => Boolean(part));
|
|
3472
|
+
for (const [index, part] of parts.entries()) {
|
|
3473
|
+
const labelKind = partyLabelKind(part);
|
|
3474
|
+
if (labelKind !== wanted) continue;
|
|
3475
|
+
const cleaned = cleanPartyIdentity(parts[index + 1] ?? "", clean);
|
|
3476
|
+
if (cleaned) return valueFromNodes([row], cleaned.value, "high", cleaned.normalizedValue);
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
return void 0;
|
|
3480
|
+
}
|
|
3416
3481
|
function namedInsuredFromNodes(nodes) {
|
|
3417
|
-
return firstCleanMatch(nodes, [
|
|
3482
|
+
return partyFromTableRows(nodes, "namedInsured", cleanNamedInsured) ?? firstCleanMatch(nodes, [
|
|
3418
3483
|
/\b(?:named insured|insured name)\s*:?\s*(.+?)(?=\s+(?:insurance amount|benefit amount|policy number|policy date|owner|beneficiary|premium|coverage|risk classification|date this)\b|[|;\n]|$)/i,
|
|
3419
3484
|
/\b(?:insured persons?|insured person)\s*:\s*(.+?)(?=\s+(?:insurance amount|benefit amount|policy number|policy date|owner|beneficiary|premium|coverage|risk classification|date this)\b|[|;\n]|$)/i,
|
|
3420
3485
|
/\b(?:applicant|policyholder)\s*:?\s*(.+?)(?=\s+(?:coverage|policy number|insurer|carrier|premium|effective|expiration)\b|[|;\n]|$)/i
|
|
@@ -3423,12 +3488,19 @@ function namedInsuredFromNodes(nodes) {
|
|
|
3423
3488
|
function cleanInsurer(value) {
|
|
3424
3489
|
const clean = cleanValue(value);
|
|
3425
3490
|
if (!clean || clean.length > 140) return void 0;
|
|
3426
|
-
if (/^(mean|means|we|us|our)\b/i.test(clean)) return void 0;
|
|
3491
|
+
if (/^(mean|means|we|us|our|the|a|an|agrees?|shall|will)\b/i.test(clean)) return void 0;
|
|
3427
3492
|
if (/\b(table of contents|policy wording|provided solely|convenience)\b/i.test(clean)) return void 0;
|
|
3428
3493
|
const known = clean.match(/\b(Sun Life Assurance Company of Canada|Manulife|The Manufacturers Life Insurance Company)\b/i)?.[1];
|
|
3429
3494
|
return known ?? clean;
|
|
3430
3495
|
}
|
|
3431
3496
|
function insurerFromNodes(nodes) {
|
|
3497
|
+
const tableValue = partyFromTableRows(nodes, "insurer", cleanInsurer);
|
|
3498
|
+
if (tableValue) return tableValue;
|
|
3499
|
+
for (const node of compactFactNodes(nodes)) {
|
|
3500
|
+
const text = nodeText(node);
|
|
3501
|
+
const value = cleanInsurer(text.match(/\b([A-Z][A-Za-z&.,' -]{2,120}?(?:Insurance|Assurance|Indemnity|Casualty|Underwriting|Mutual|Risk|Reinsurance)\s+Company(?:\s+of\s+[A-Z][A-Za-z .'-]+)?)\s*\(\s*the\s+["']?Insurer["']?\s*\)/i)?.[1] ?? "");
|
|
3502
|
+
if (value) return valueFromNode(node, value, "high");
|
|
3503
|
+
}
|
|
3432
3504
|
return firstCleanMatch(nodes, [
|
|
3433
3505
|
/\bunderwritten by\s+([^|;\n.]{3,160})/i,
|
|
3434
3506
|
/\b(?:insurer|carrier|company|security)\s*:?\s*([^|;\n]{3,120})/i,
|
|
@@ -3474,6 +3546,19 @@ function coverageNameFromRow(text) {
|
|
|
3474
3546
|
);
|
|
3475
3547
|
return cleanCoverageLabel(first);
|
|
3476
3548
|
}
|
|
3549
|
+
function isDeclarationLimitLabel(value) {
|
|
3550
|
+
const label = normalizeLabel(value);
|
|
3551
|
+
return /\bitem\s*\d+[.)]?\s*limits?\s+of\s+liability\b/.test(label) || /^limits?\s+of\s+liability$/.test(label) || /^policy\s+limits?$/.test(label);
|
|
3552
|
+
}
|
|
3553
|
+
function declarationCoverageNameFromRow(row, children) {
|
|
3554
|
+
const cells = cellRows(row, children);
|
|
3555
|
+
const candidates = [
|
|
3556
|
+
row.title,
|
|
3557
|
+
...cells.flatMap((cell) => [cell.label, cell.value])
|
|
3558
|
+
];
|
|
3559
|
+
if (!candidates.some(isDeclarationLimitLabel)) return void 0;
|
|
3560
|
+
return candidates.some((candidate) => /\blimits?\s+of\s+liability\b/i.test(candidate ?? "")) ? "Limits of Liability" : "Policy Limits";
|
|
3561
|
+
}
|
|
3477
3562
|
function limitFromText(text) {
|
|
3478
3563
|
return moneyValue(
|
|
3479
3564
|
text.match(/\b(?:limit|liability|aggregate|occurrence|claim)\s*:?\s*(\$?\d[\d,]*(?:\.\d{2})?|\$?\d[\d,]*\s*(?:each|per|aggregate)[^|;]*)/i)?.[1] ?? text.match(/(\$\s?\d[\d,]*(?:\.\d{2})?)(?=.*\b(limit|aggregate|occurrence|claim|liability)\b)/i)?.[1]
|
|
@@ -3493,7 +3578,12 @@ function premiumFromNodes(nodes) {
|
|
|
3493
3578
|
return void 0;
|
|
3494
3579
|
}
|
|
3495
3580
|
function moneyAmount(value) {
|
|
3496
|
-
const
|
|
3581
|
+
const clean = cleanValue(value);
|
|
3582
|
+
if (!clean) return void 0;
|
|
3583
|
+
const currency = clean.match(/\$\s*([0-9][0-9,]*(?:\.\d+)?)/);
|
|
3584
|
+
const percent = clean.match(/\b([0-9][0-9,]*(?:\.\d+)?)\s*%/);
|
|
3585
|
+
const explicitNumeric = !/\bitem\s*\d+\b/i.test(clean) && /\b(?:limit|aggregate|claim|occurrence|loss|retention|deductible|sir|premium|amount)\b/i.test(clean) ? clean.match(/\b([0-9][0-9,]*(?:\.\d+)?)\b/) : void 0;
|
|
3586
|
+
const match = currency ?? percent ?? explicitNumeric;
|
|
3497
3587
|
if (!match) return void 0;
|
|
3498
3588
|
const amount = Number(match[1].replace(/,/g, ""));
|
|
3499
3589
|
return Number.isFinite(amount) ? amount : void 0;
|
|
@@ -3539,6 +3629,10 @@ function isValueCell(label, value) {
|
|
|
3539
3629
|
}
|
|
3540
3630
|
return /\b(limit|aggregate|retention|deductible|sir|retroactive|premium|amount)\b/.test(normalizedLabel) || moneyAmount(value) !== void 0 || /\b(full prior acts|none|included|not included|as stated)\b/.test(normalizedValue);
|
|
3541
3631
|
}
|
|
3632
|
+
function isCoverageTermLabel(value) {
|
|
3633
|
+
const label = normalizeLabel(value);
|
|
3634
|
+
return /\b(limit|aggregate|retention|deductible|sir|retroactive|premium|amount|sub[-\s]?limit)\b/.test(label);
|
|
3635
|
+
}
|
|
3542
3636
|
function isNameCell(label, value) {
|
|
3543
3637
|
const normalizedLabel = normalizeLabel(label);
|
|
3544
3638
|
const normalizedValue = normalizeLabel(value);
|
|
@@ -3640,6 +3734,16 @@ function termFromCell(params) {
|
|
|
3640
3734
|
function termsFromRow(row, children) {
|
|
3641
3735
|
const cells = cellRows(row, children);
|
|
3642
3736
|
if (cells.length > 0) {
|
|
3737
|
+
const pairedTerms = [];
|
|
3738
|
+
for (const [index, cell] of cells.entries()) {
|
|
3739
|
+
const next = cells[index + 1];
|
|
3740
|
+
if (!next) continue;
|
|
3741
|
+
if (!isCoverageTermLabel(cell.value)) continue;
|
|
3742
|
+
if (isCoverageTermLabel(next.value) && moneyAmount(next.value) === void 0) continue;
|
|
3743
|
+
const term = termFromCell({ row, cell: next.node, label: cell.value, value: next.value });
|
|
3744
|
+
if (term) pairedTerms.push(term);
|
|
3745
|
+
}
|
|
3746
|
+
if (pairedTerms.length > 0) return pairedTerms;
|
|
3643
3747
|
return cells.filter((cell) => isValueCell(cell.label, cell.value)).map((cell) => termFromCell({ row, cell: cell.node, label: cell.label, value: cell.value })).filter((term) => Boolean(term));
|
|
3644
3748
|
}
|
|
3645
3749
|
const text = normalizeWhitespace3(row.textExcerpt ?? row.description ?? nodeText(row));
|
|
@@ -3666,6 +3770,8 @@ function termsFromRow(row, children) {
|
|
|
3666
3770
|
return terms;
|
|
3667
3771
|
}
|
|
3668
3772
|
function nameFromRow(row, children) {
|
|
3773
|
+
const declarationName = declarationCoverageNameFromRow(row, children);
|
|
3774
|
+
if (declarationName) return declarationName;
|
|
3669
3775
|
const cells = cellRows(row, children);
|
|
3670
3776
|
const named = cells.find((cell) => isNameCell(cell.label, cell.value));
|
|
3671
3777
|
if (named) return cleanValue(named.value);
|
|
@@ -3843,7 +3949,7 @@ function buildParties(profile) {
|
|
|
3843
3949
|
if (profile.namedInsured) {
|
|
3844
3950
|
parties.push({
|
|
3845
3951
|
role: "named_insured",
|
|
3846
|
-
name: profile.namedInsured.value,
|
|
3952
|
+
name: profile.namedInsured.normalizedValue ?? profile.namedInsured.value,
|
|
3847
3953
|
sourceNodeIds: profile.namedInsured.sourceNodeIds,
|
|
3848
3954
|
sourceSpanIds: profile.namedInsured.sourceSpanIds
|
|
3849
3955
|
});
|
|
@@ -3851,7 +3957,7 @@ function buildParties(profile) {
|
|
|
3851
3957
|
if (profile.insurer) {
|
|
3852
3958
|
parties.push({
|
|
3853
3959
|
role: "insurer",
|
|
3854
|
-
name: profile.insurer.value,
|
|
3960
|
+
name: profile.insurer.normalizedValue ?? profile.insurer.value,
|
|
3855
3961
|
sourceNodeIds: profile.insurer.sourceNodeIds,
|
|
3856
3962
|
sourceSpanIds: profile.insurer.sourceSpanIds
|
|
3857
3963
|
});
|
|
@@ -3859,7 +3965,7 @@ function buildParties(profile) {
|
|
|
3859
3965
|
if (profile.broker) {
|
|
3860
3966
|
parties.push({
|
|
3861
3967
|
role: "broker",
|
|
3862
|
-
name: profile.broker.value,
|
|
3968
|
+
name: profile.broker.normalizedValue ?? profile.broker.value,
|
|
3863
3969
|
sourceNodeIds: profile.broker.sourceNodeIds,
|
|
3864
3970
|
sourceSpanIds: profile.broker.sourceSpanIds
|
|
3865
3971
|
});
|
|
@@ -11296,9 +11402,19 @@ function sourceTreeToOutline(sourceTree) {
|
|
|
11296
11402
|
});
|
|
11297
11403
|
return (byParent.get(root?.id) ?? []).map(visit);
|
|
11298
11404
|
}
|
|
11405
|
+
var NORMALIZED_COMPATIBILITY_FIELDS = /* @__PURE__ */ new Set([
|
|
11406
|
+
"policyNumber",
|
|
11407
|
+
"namedInsured",
|
|
11408
|
+
"insurer",
|
|
11409
|
+
"broker"
|
|
11410
|
+
]);
|
|
11299
11411
|
function valueOf(profile, key) {
|
|
11300
11412
|
const value = profile[key];
|
|
11301
|
-
|
|
11413
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || !("value" in value)) return void 0;
|
|
11414
|
+
if (NORMALIZED_COMPATIBILITY_FIELDS.has(key) && "normalizedValue" in value && typeof value.normalizedValue === "string" && value.normalizedValue.trim()) {
|
|
11415
|
+
return value.normalizedValue;
|
|
11416
|
+
}
|
|
11417
|
+
return String(value.value);
|
|
11302
11418
|
}
|
|
11303
11419
|
function materializeDocument(params) {
|
|
11304
11420
|
const profile = params.operationalProfile;
|