@mailwoman/match 4.10.0 → 4.12.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/README.md +95 -0
- package/out/blocking.d.ts +1 -1
- package/out/blocking.js +1 -1
- package/out/clustering.d.ts +1 -1
- package/out/clustering.js +1 -1
- package/out/gbt.d.ts +6 -4
- package/out/gbt.d.ts.map +1 -1
- package/out/gbt.js +6 -4
- package/out/gbt.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @mailwoman/match
|
|
2
|
+
|
|
3
|
+
**The geocode-first record matcher** — a three-stage entity resolution pipeline:
|
|
4
|
+
**block → score → cluster**. Resolves whether two records refer to the same
|
|
5
|
+
real-world entity by matching the resolved _place_ (not the address string),
|
|
6
|
+
then comparing names and other fields.
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { block, scorePair, cluster } from "@mailwoman/match"
|
|
10
|
+
|
|
11
|
+
// Stage 1: Block — geo-first candidate generation
|
|
12
|
+
const pairs = block(records, {
|
|
13
|
+
keys: [defaultBlockingKeys.geoCell, defaultBlockingKeys.canonical],
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
// Stage 2: Score — Fellegi-Sunter probabilistic match
|
|
17
|
+
const { probability } = scorePair(recordA, recordB, { model })
|
|
18
|
+
|
|
19
|
+
// Stage 3: Cluster — connected-components resolution
|
|
20
|
+
const entities = cluster(records, links, { threshold: 0.5 })
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## The three-stage pipeline
|
|
24
|
+
|
|
25
|
+
### 1. Block — geo-first candidate generation
|
|
26
|
+
|
|
27
|
+
Instead of comparing every record to every other (O(n²)), blocking generates
|
|
28
|
+
candidate pairs via cheap, high-recall keys:
|
|
29
|
+
|
|
30
|
+
- **Geo cell key** — a generous H3 cell (~5.5 km) so two records at the same
|
|
31
|
+
place meet regardless of how their address is spelled
|
|
32
|
+
- **Canonical address key** — the formatter's deterministic match key
|
|
33
|
+
- **Exact keys** — phone, email, domain for exact-match joins
|
|
34
|
+
|
|
35
|
+
### 2. Score — Fellegi-Sunter probabilistic matching
|
|
36
|
+
|
|
37
|
+
The `scorePair` function computes a match probability using:
|
|
38
|
+
|
|
39
|
+
- **String comparators** — Jaro-Winkler similarity over names and addresses
|
|
40
|
+
- **Distance comparison** — great-circle distance bucketed into same-building /
|
|
41
|
+
same-block / same-area / far
|
|
42
|
+
- **Fellegi-Sunter weight model** — agreement-level log-likelihood ratios
|
|
43
|
+
(`log2(m/u)`) converted to a probability
|
|
44
|
+
- **Label-free EM estimation** — `m`/`u` parameters learned via
|
|
45
|
+
expectation-maximization without labeled training data
|
|
46
|
+
- **Term frequency adjustment** — rare-value agreement (e.g., an unusual
|
|
47
|
+
organization name) up-weighted; common-value agreement down-weighted
|
|
48
|
+
- **Learned (GBT) scorer** — optional gradient-boosted tree scorer for
|
|
49
|
+
single-dataset dedup, available via `scorer` hook
|
|
50
|
+
|
|
51
|
+
### 3. Cluster — connected-components
|
|
52
|
+
|
|
53
|
+
Non-transitive pairwise links (A↔B, B↔C, but not A↔C) are resolved into
|
|
54
|
+
canonical entities via union-find with path compression.
|
|
55
|
+
|
|
56
|
+
## API
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// Blocking — generate candidate record pairs
|
|
60
|
+
block(records, opts: BlockOpts): { pairs: Pair[]; droppedBlocks: BlockDrop[] }
|
|
61
|
+
|
|
62
|
+
// Scoring — pairwise Fellegi-Sunter match probability
|
|
63
|
+
scorePair(a: SourceRecord, b: SourceRecord, opts: ScoreOpts): ScoreResult
|
|
64
|
+
|
|
65
|
+
// Clustering — resolve pairwise links into entities
|
|
66
|
+
cluster(records: SourceRecord[], links: ScoredLink[], opts: ClusterOpts): Entity[]
|
|
67
|
+
|
|
68
|
+
// Distance — great-circle comparison levels
|
|
69
|
+
haversineKm(lat1: number, lon1: number, lat2: number, lon2: number): number
|
|
70
|
+
distanceComparison(distKm: number): ComparisonLevel
|
|
71
|
+
|
|
72
|
+
// Learned scorer — GBT for single-dataset dedup
|
|
73
|
+
trainGBT(pairs: TrainingPair[], opts?: GBTOpts): GBTModel
|
|
74
|
+
gbtPredict(model: GBTModel, features: number[]): number
|
|
75
|
+
|
|
76
|
+
// Label-free EM parameter estimation
|
|
77
|
+
estimateParameters(pairs: Pair[]): EMResult
|
|
78
|
+
|
|
79
|
+
// Term frequency adjustment
|
|
80
|
+
withTermFrequency(model: FSModel, records: SourceRecord[]): FSModel
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Related
|
|
84
|
+
|
|
85
|
+
- [`@mailwoman/record`](../record) — record schemas and normalizers consumed by the matcher
|
|
86
|
+
- [`@mailwoman/formatter`](../formatter) — `canonicalKey` used for blocking
|
|
87
|
+
- [`@mailwoman/address-id`](../address-id) — complementary exact-match join key
|
|
88
|
+
- [`@mailwoman/registry`](../registry) — high-level `resolveEntities` that composes this pipeline
|
|
89
|
+
- [Geocode-First Record Matching](https://mailwoman.sister.software/articles/concepts/geocode-first-record-matching/)
|
|
90
|
+
- [Dedup Entity Truth](https://mailwoman.sister.software/articles/concepts/dedup-entity-truth/)
|
|
91
|
+
- [Spatial Expectation & Density](https://mailwoman.sister.software/articles/concepts/spatial-expectation-and-density/)
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
[AGPL-3.0-only](https://www.gnu.org/licenses/agpl-3.0.html)
|
package/out/blocking.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Recall is the priority — a pair the blocker never proposes can never match, the most dangerous
|
|
18
18
|
* silent failure in record linkage. So the spatial grid is generous and neighbour-expanded by
|
|
19
|
-
* default, and any block too large to scan is _reported_, never
|
|
19
|
+
* default, and any block too large to scan is _reported_, never silently dropped.
|
|
20
20
|
*/
|
|
21
21
|
/** Maps a record to zero or more block keys. Two records sharing any key become a candidate pair. */
|
|
22
22
|
export type BlockingKey<R> = (record: R) => string[];
|
package/out/blocking.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Recall is the priority — a pair the blocker never proposes can never match, the most dangerous
|
|
18
18
|
* silent failure in record linkage. So the spatial grid is generous and neighbour-expanded by
|
|
19
|
-
* default, and any block too large to scan is _reported_, never
|
|
19
|
+
* default, and any block too large to scan is _reported_, never silently dropped.
|
|
20
20
|
*/
|
|
21
21
|
/**
|
|
22
22
|
* A spatial-cell block key: a configurable lat/lon grid. `precisionDegrees` sets the cell size
|
package/out/clustering.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* The pairwise scorer treats each pair independently, and its scores are NOT transitive: A~B at a
|
|
9
9
|
* high weight and B~C at a high weight does not guarantee A~C is a match. So a distinct stage is
|
|
10
10
|
* required to turn the graph of above-threshold links into coherent groups — skip it and your
|
|
11
|
-
* "entities"
|
|
11
|
+
* "entities" silently fracture or fuse.
|
|
12
12
|
*
|
|
13
13
|
* This ships the standard baseline: connected components of the link graph (union-find), with the
|
|
14
14
|
* link threshold as the precision/recall knob — raise it for tighter, purer clusters, lower it
|
package/out/clustering.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* The pairwise scorer treats each pair independently, and its scores are NOT transitive: A~B at a
|
|
9
9
|
* high weight and B~C at a high weight does not guarantee A~C is a match. So a distinct stage is
|
|
10
10
|
* required to turn the graph of above-threshold links into coherent groups — skip it and your
|
|
11
|
-
* "entities"
|
|
11
|
+
* "entities" silently fracture or fuse.
|
|
12
12
|
*
|
|
13
13
|
* This ships the standard baseline: connected components of the link graph (union-find), with the
|
|
14
14
|
* link threshold as the precision/recall knob — raise it for tighter, purer clusters, lower it
|
package/out/gbt.d.ts
CHANGED
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
* truth like an NPI) let a tree learn the over-merge signature the hand-weights miss.
|
|
11
11
|
*
|
|
12
12
|
* This module is feature-agnostic: feature vectors are caller-defined `number[]` (the record
|
|
13
|
-
* matcher builds them in `@mailwoman/registry`'s learned-scorer module — one-hot agreement
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* matcher builds them in `@mailwoman/registry`'s learned-scorer module — one-hot agreement
|
|
14
|
+
* levels
|
|
15
|
+
*
|
|
16
|
+
* - Interaction terms + corpus statistics). It only fits ({@link trainGBT}) and scores
|
|
17
|
+
* ({@link gbtScore}). The trained {@link GBT} is plain JSON (`{trees, lr, base}`), so a model
|
|
18
|
+
* trains offline once and ships as a data file.
|
|
17
19
|
*/
|
|
18
20
|
/** A trained tree: an internal split (feature `f` ≤ `thr` → `lo`, else `hi`) or a `leaf` value. */
|
|
19
21
|
export type TreeNode = {
|
package/out/gbt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gbt.d.ts","sourceRoot":"","sources":["../gbt.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gbt.d.ts","sourceRoot":"","sources":["../gbt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mGAAmG;AACnG,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAA;CAAE,CAAA;AAIhG;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAoBzD;AA0ED,oGAAoG;AACpG,MAAM,WAAW,GAAG;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,4CAA4C;AAC5C,MAAM,WAAW,OAAO;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;CACf;AAED,6FAA6F;AAC7F,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,GAAG,CAqBpF;AAED,yFAAyF;AACzF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAIpD"}
|
package/out/gbt.js
CHANGED
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
* truth like an NPI) let a tree learn the over-merge signature the hand-weights miss.
|
|
11
11
|
*
|
|
12
12
|
* This module is feature-agnostic: feature vectors are caller-defined `number[]` (the record
|
|
13
|
-
* matcher builds them in `@mailwoman/registry`'s learned-scorer module — one-hot agreement
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* matcher builds them in `@mailwoman/registry`'s learned-scorer module — one-hot agreement
|
|
14
|
+
* levels
|
|
15
|
+
*
|
|
16
|
+
* - Interaction terms + corpus statistics). It only fits ({@link trainGBT}) and scores
|
|
17
|
+
* ({@link gbtScore}). The trained {@link GBT} is plain JSON (`{trees, lr, base}`), so a model
|
|
18
|
+
* trains offline once and ships as a data file.
|
|
17
19
|
*/
|
|
18
20
|
const sigmoid = (z) => 1 / (1 + Math.exp(-Math.max(-30, Math.min(30, z))));
|
|
19
21
|
/**
|
package/out/gbt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gbt.js","sourceRoot":"","sources":["../gbt.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gbt.js","sourceRoot":"","sources":["../gbt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE1F;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,CAAa;IAC5C,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAA;IAC7B,MAAM,GAAG,GAAe,EAAE,CAAA;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACb,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAa,EAAE,CAAA;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC/E,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACZ,CAAC;aAAM,CAAC;YACP,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC9C,MAAM,CAAC,GAAa,EAAE,CAAA;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;YACvF,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC;AAED,yEAAyE;AACzE,SAAS,OAAO,CAAC,IAAc,EAAE,CAAW,EAAE,CAAW;IACxD,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,EAAE,GAAG,CAAC,CAAA;IACV,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;QACb,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;IACpB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACrC,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,IAAI,CAAA;QACtB,GAAG,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC;AAED,2FAA2F;AAC3F,SAAS,UAAU,CAClB,IAAc,EACd,CAAa,EACb,CAAW,EACX,CAAW,EACX,UAAsB,EACtB,KAAa,EACb,OAAe;IAEf,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,EAAE,GAAG,CAAC,CAAA;IACV,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;QACb,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;IACpB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACrC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACrC,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;IACd,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,MAAM,GAAa,EAAE,CAAA;IACzB,IAAI,MAAM,GAAa,EAAE,CAAA;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,CAAE,EAAE,CAAC;YAClC,MAAM,EAAE,GAAa,EAAE,CAAA;YACvB,MAAM,EAAE,GAAa,EAAE,CAAA;YACvB,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC1D,IAAI,EAAE,CAAC,MAAM,GAAG,OAAO,IAAI,EAAE,CAAC,MAAM,GAAG,OAAO;gBAAE,SAAQ;YACxD,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAChE,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;gBACrB,QAAQ,GAAG,IAAI,CAAA;gBACf,KAAK,GAAG,CAAC,CAAA;gBACT,OAAO,GAAG,GAAG,CAAA;gBACb,MAAM,GAAG,EAAE,CAAA;gBACX,MAAM,GAAG,EAAE,CAAA;YACZ,CAAC;QACF,CAAC;IACF,CAAC;IACD,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC9B,OAAO;QACN,CAAC,EAAE,KAAK;QACR,GAAG,EAAE,OAAO;QACZ,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC;QAC/D,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC;KAC/D,CAAA;AACF,CAAC;AAED,SAAS,WAAW,CAAC,CAAW,EAAE,CAAW;IAC5C,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,GAAG,IAAI,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,OAAO,CAAC,CAAC,IAAI,CAAA;AACd,CAAC;AAiBD,6FAA6F;AAC7F,MAAM,UAAU,QAAQ,CAAC,CAAa,EAAE,CAAW,EAAE,CAAW,EAAE,IAAa;IAC9E,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;IAClB,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACtD,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;QACb,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAE,CAAA;IAC9B,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA,CAAC,yBAAyB;IAC/E,MAAM,CAAC,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,KAAK,GAAe,EAAE,CAAA;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,CAAA;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA,CAAC,qCAAqC;QAC/F,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,CAAC,CAAE,IAAI,IAAI,CAAC,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;QACvE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAA;AACpC,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,QAAQ,CAAC,CAAM,EAAE,CAAW;IAC3C,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;IACd,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;QAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACtD,OAAO,CAAC,CAAA;AACT,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailwoman/match",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "The geocode-first record matcher: block → score → cluster. This first cut ships the string comparators (Jaro / Jaro-Winkler + an edit-distance fallback for compound surnames) that the Fellegi-Sunter scorer is built on.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|