@stll/anonymize 0.0.9 → 1.0.1
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.d.ts → index.d.mts} +17 -37
- package/dist/{index.js → index.mjs} +99 -540
- package/dist/index.mjs.map +1 -0
- package/package.json +7 -7
- package/dist/index.js.map +0 -1
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
import { TextSearch } from "@stll/text-search";
|
|
1
2
|
import { at, be, bg, cy, cz, de, dk, ee, es, fi, fr, gb, gr, hr, hu, ie, it, lt, lu, lv, mt, nl, pl, pt, ro, se, si, sk } from "@stll/stdnum";
|
|
2
3
|
import { toRegex } from "@stll/stdnum/patterns";
|
|
3
|
-
import
|
|
4
|
+
import charGroupsJson from "@stll/anonymize-data/config/char-groups.json";
|
|
5
|
+
//#region src/search-engine.ts
|
|
6
|
+
let _TextSearch;
|
|
7
|
+
const initTextSearch = (ctor) => {
|
|
8
|
+
_TextSearch = ctor;
|
|
9
|
+
};
|
|
10
|
+
const getTextSearch = () => {
|
|
11
|
+
if (!_TextSearch) throw new Error("TextSearch not initialized. Import from @stll/anonymize or @stll/anonymize-wasm, not from internal modules.");
|
|
12
|
+
return _TextSearch;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
4
15
|
//#region src/types.ts
|
|
5
16
|
/**
|
|
6
17
|
* Source of a detected entity span.
|
|
@@ -565,7 +576,37 @@ const getNameCorpusFirstNames = (ctx = defaultContext) => ctx.nameCorpus?.firstN
|
|
|
565
576
|
const getNameCorpusSurnames = (ctx = defaultContext) => ctx.nameCorpus?.surnamesList ?? [];
|
|
566
577
|
const getNameCorpusTitles = (ctx = defaultContext) => ctx.nameCorpus?.titlesList ?? [];
|
|
567
578
|
/**
|
|
568
|
-
*
|
|
579
|
+
* Languages with per-language first/surname
|
|
580
|
+
* dictionaries in @stll/anonymize-data.
|
|
581
|
+
*/
|
|
582
|
+
const NAME_LANGUAGES = [
|
|
583
|
+
"cs",
|
|
584
|
+
"sk",
|
|
585
|
+
"de",
|
|
586
|
+
"pl",
|
|
587
|
+
"hu",
|
|
588
|
+
"ro",
|
|
589
|
+
"fr",
|
|
590
|
+
"es",
|
|
591
|
+
"it",
|
|
592
|
+
"en",
|
|
593
|
+
"sv"
|
|
594
|
+
];
|
|
595
|
+
/**
|
|
596
|
+
* Try importing a JSON module; return empty array
|
|
597
|
+
* if not found.
|
|
598
|
+
*/
|
|
599
|
+
const tryImportArray = async (path) => {
|
|
600
|
+
try {
|
|
601
|
+
return (await import(path)).default;
|
|
602
|
+
} catch {
|
|
603
|
+
return [];
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
/**
|
|
607
|
+
* Load name corpus data from per-language dictionary
|
|
608
|
+
* files and legacy config files. Merges all sources.
|
|
609
|
+
*
|
|
569
610
|
* Safe to call multiple times; only loads once per
|
|
570
611
|
* context. Must be called before detectNameCorpus or
|
|
571
612
|
* the getNameCorpus*() accessors are used.
|
|
@@ -574,23 +615,40 @@ const initNameCorpus = (ctx = defaultContext) => {
|
|
|
574
615
|
if (ctx.nameCorpusPromise) return ctx.nameCorpusPromise;
|
|
575
616
|
const promise = (async () => {
|
|
576
617
|
try {
|
|
577
|
-
const [
|
|
618
|
+
const [legacyFirstMod, legacySurnameMod, titleMod, exclusionMod] = await Promise.all([
|
|
578
619
|
import("@stll/anonymize-data/config/names-first.json"),
|
|
579
620
|
import("@stll/anonymize-data/config/names-surnames.json"),
|
|
580
621
|
import("@stll/anonymize-data/config/names-title-tokens.json"),
|
|
581
622
|
import("@stll/anonymize-data/config/names-exclusions.json")
|
|
582
623
|
]);
|
|
583
|
-
const
|
|
584
|
-
const
|
|
624
|
+
const firstImports = NAME_LANGUAGES.map((lang) => tryImportArray(`@stll/anonymize-data/dictionaries/names/first/${lang}.json`));
|
|
625
|
+
const surnameImports = NAME_LANGUAGES.map((lang) => tryImportArray(`@stll/anonymize-data/dictionaries/names/surnames/${lang}.json`));
|
|
626
|
+
const [firstResults, surnameResults] = await Promise.all([Promise.all(firstImports), Promise.all(surnameImports)]);
|
|
627
|
+
const firstNames = [...legacyFirstMod.default.names];
|
|
628
|
+
for (const names of firstResults) for (const name of names) firstNames.push(name);
|
|
629
|
+
const surnames = [...legacySurnameMod.default.names];
|
|
630
|
+
for (const names of surnameResults) for (const name of names) surnames.push(name);
|
|
631
|
+
const dedup = (arr) => {
|
|
632
|
+
const seen = /* @__PURE__ */ new Set();
|
|
633
|
+
const result = [];
|
|
634
|
+
for (const item of arr) {
|
|
635
|
+
if (seen.has(item)) continue;
|
|
636
|
+
seen.add(item);
|
|
637
|
+
result.push(item);
|
|
638
|
+
}
|
|
639
|
+
return result;
|
|
640
|
+
};
|
|
641
|
+
const dedupFirst = dedup(firstNames);
|
|
642
|
+
const dedupSurnames = dedup(surnames);
|
|
585
643
|
const titles = titleMod.default.tokens;
|
|
586
644
|
const exclusions = exclusionMod.default.words;
|
|
587
645
|
ctx.nameCorpus = {
|
|
588
|
-
firstNames: Object.freeze(new Set(
|
|
589
|
-
surnames: Object.freeze(new Set(
|
|
646
|
+
firstNames: Object.freeze(new Set(dedupFirst)),
|
|
647
|
+
surnames: Object.freeze(new Set(dedupSurnames)),
|
|
590
648
|
titleTokens: Object.freeze(new Set(titles)),
|
|
591
649
|
excludedWords: Object.freeze(new Set(exclusions)),
|
|
592
|
-
firstNamesList: Object.freeze(
|
|
593
|
-
surnamesList: Object.freeze(
|
|
650
|
+
firstNamesList: Object.freeze(dedupFirst),
|
|
651
|
+
surnamesList: Object.freeze(dedupSurnames),
|
|
594
652
|
titlesList: Object.freeze(titles),
|
|
595
653
|
excludedList: Object.freeze(exclusions)
|
|
596
654
|
};
|
|
@@ -994,519 +1052,28 @@ const POST_NOMINALS = [
|
|
|
994
1052
|
"CIPP"
|
|
995
1053
|
];
|
|
996
1054
|
//#endregion
|
|
997
|
-
//#region src/util/char-groups-data.json
|
|
998
|
-
var char_groups_data_default = {
|
|
999
|
-
_comment: "Unicode character equivalence groups. Used to build regex character classes that match all variants of a character type.",
|
|
1000
|
-
groups: {
|
|
1001
|
-
"dash": {
|
|
1002
|
-
"description": "Dash-like characters (hyphens, en-dash, em-dash, minus)",
|
|
1003
|
-
"chars": [
|
|
1004
|
-
{
|
|
1005
|
-
"char": "-",
|
|
1006
|
-
"name": "hyphen-minus",
|
|
1007
|
-
"code": "U+002D"
|
|
1008
|
-
},
|
|
1009
|
-
{
|
|
1010
|
-
"char": "–",
|
|
1011
|
-
"name": "en-dash",
|
|
1012
|
-
"code": "U+2013"
|
|
1013
|
-
},
|
|
1014
|
-
{
|
|
1015
|
-
"char": "—",
|
|
1016
|
-
"name": "em-dash",
|
|
1017
|
-
"code": "U+2014"
|
|
1018
|
-
},
|
|
1019
|
-
{
|
|
1020
|
-
"char": "‐",
|
|
1021
|
-
"name": "hyphen",
|
|
1022
|
-
"code": "U+2010"
|
|
1023
|
-
},
|
|
1024
|
-
{
|
|
1025
|
-
"char": "‑",
|
|
1026
|
-
"name": "non-breaking hyphen",
|
|
1027
|
-
"code": "U+2011"
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
"char": "−",
|
|
1031
|
-
"name": "minus sign",
|
|
1032
|
-
"code": "U+2212"
|
|
1033
|
-
},
|
|
1034
|
-
{
|
|
1035
|
-
"char": "⁃",
|
|
1036
|
-
"name": "hyphen bullet",
|
|
1037
|
-
"code": "U+2043"
|
|
1038
|
-
},
|
|
1039
|
-
{
|
|
1040
|
-
"char": "‒",
|
|
1041
|
-
"name": "figure dash",
|
|
1042
|
-
"code": "U+2012"
|
|
1043
|
-
},
|
|
1044
|
-
{
|
|
1045
|
-
"char": "―",
|
|
1046
|
-
"name": "horizontal bar",
|
|
1047
|
-
"code": "U+2015"
|
|
1048
|
-
},
|
|
1049
|
-
{
|
|
1050
|
-
"char": "⸺",
|
|
1051
|
-
"name": "two-em dash",
|
|
1052
|
-
"code": "U+2E3A"
|
|
1053
|
-
},
|
|
1054
|
-
{
|
|
1055
|
-
"char": "⸻",
|
|
1056
|
-
"name": "three-em dash",
|
|
1057
|
-
"code": "U+2E3B"
|
|
1058
|
-
},
|
|
1059
|
-
{
|
|
1060
|
-
"char": "־",
|
|
1061
|
-
"name": "Hebrew maqaf",
|
|
1062
|
-
"code": "U+05BE"
|
|
1063
|
-
}
|
|
1064
|
-
]
|
|
1065
|
-
},
|
|
1066
|
-
"space": {
|
|
1067
|
-
"description": "Space-like characters",
|
|
1068
|
-
"chars": [
|
|
1069
|
-
{
|
|
1070
|
-
"char": " ",
|
|
1071
|
-
"name": "space",
|
|
1072
|
-
"code": "U+0020"
|
|
1073
|
-
},
|
|
1074
|
-
{
|
|
1075
|
-
"char": "\xA0",
|
|
1076
|
-
"name": "no-break space",
|
|
1077
|
-
"code": "U+00A0"
|
|
1078
|
-
},
|
|
1079
|
-
{
|
|
1080
|
-
"char": " ",
|
|
1081
|
-
"name": "en space",
|
|
1082
|
-
"code": "U+2002"
|
|
1083
|
-
},
|
|
1084
|
-
{
|
|
1085
|
-
"char": " ",
|
|
1086
|
-
"name": "em space",
|
|
1087
|
-
"code": "U+2003"
|
|
1088
|
-
},
|
|
1089
|
-
{
|
|
1090
|
-
"char": " ",
|
|
1091
|
-
"name": "thin space",
|
|
1092
|
-
"code": "U+2009"
|
|
1093
|
-
},
|
|
1094
|
-
{
|
|
1095
|
-
"char": " ",
|
|
1096
|
-
"name": "hair space",
|
|
1097
|
-
"code": "U+200A"
|
|
1098
|
-
},
|
|
1099
|
-
{
|
|
1100
|
-
"char": " ",
|
|
1101
|
-
"name": "narrow no-break space",
|
|
1102
|
-
"code": "U+202F"
|
|
1103
|
-
},
|
|
1104
|
-
{
|
|
1105
|
-
"char": " ",
|
|
1106
|
-
"name": "Ogham space mark",
|
|
1107
|
-
"code": "U+1680"
|
|
1108
|
-
},
|
|
1109
|
-
{
|
|
1110
|
-
"char": " ",
|
|
1111
|
-
"name": "en quad",
|
|
1112
|
-
"code": "U+2000"
|
|
1113
|
-
},
|
|
1114
|
-
{
|
|
1115
|
-
"char": " ",
|
|
1116
|
-
"name": "em quad",
|
|
1117
|
-
"code": "U+2001"
|
|
1118
|
-
},
|
|
1119
|
-
{
|
|
1120
|
-
"char": " ",
|
|
1121
|
-
"name": "three-per-em space",
|
|
1122
|
-
"code": "U+2004"
|
|
1123
|
-
},
|
|
1124
|
-
{
|
|
1125
|
-
"char": " ",
|
|
1126
|
-
"name": "four-per-em space",
|
|
1127
|
-
"code": "U+2005"
|
|
1128
|
-
},
|
|
1129
|
-
{
|
|
1130
|
-
"char": " ",
|
|
1131
|
-
"name": "six-per-em space",
|
|
1132
|
-
"code": "U+2006"
|
|
1133
|
-
},
|
|
1134
|
-
{
|
|
1135
|
-
"char": " ",
|
|
1136
|
-
"name": "figure space",
|
|
1137
|
-
"code": "U+2007"
|
|
1138
|
-
},
|
|
1139
|
-
{
|
|
1140
|
-
"char": " ",
|
|
1141
|
-
"name": "punctuation space",
|
|
1142
|
-
"code": "U+2008"
|
|
1143
|
-
},
|
|
1144
|
-
{
|
|
1145
|
-
"char": " ",
|
|
1146
|
-
"name": "medium mathematical space",
|
|
1147
|
-
"code": "U+205F"
|
|
1148
|
-
},
|
|
1149
|
-
{
|
|
1150
|
-
"char": " ",
|
|
1151
|
-
"name": "ideographic space",
|
|
1152
|
-
"code": "U+3000"
|
|
1153
|
-
},
|
|
1154
|
-
{
|
|
1155
|
-
"char": "",
|
|
1156
|
-
"name": "zero width space",
|
|
1157
|
-
"code": "U+200B"
|
|
1158
|
-
}
|
|
1159
|
-
]
|
|
1160
|
-
},
|
|
1161
|
-
"quote-double": {
|
|
1162
|
-
"description": "Double quotation marks",
|
|
1163
|
-
"chars": [
|
|
1164
|
-
{
|
|
1165
|
-
"char": "\"",
|
|
1166
|
-
"name": "quotation mark",
|
|
1167
|
-
"code": "U+0022"
|
|
1168
|
-
},
|
|
1169
|
-
{
|
|
1170
|
-
"char": "“",
|
|
1171
|
-
"name": "left double quotation mark",
|
|
1172
|
-
"code": "U+201C"
|
|
1173
|
-
},
|
|
1174
|
-
{
|
|
1175
|
-
"char": "”",
|
|
1176
|
-
"name": "right double quotation mark",
|
|
1177
|
-
"code": "U+201D"
|
|
1178
|
-
},
|
|
1179
|
-
{
|
|
1180
|
-
"char": "„",
|
|
1181
|
-
"name": "double low-9 quotation mark",
|
|
1182
|
-
"code": "U+201E"
|
|
1183
|
-
},
|
|
1184
|
-
{
|
|
1185
|
-
"char": "«",
|
|
1186
|
-
"name": "left guillemet",
|
|
1187
|
-
"code": "U+00AB"
|
|
1188
|
-
},
|
|
1189
|
-
{
|
|
1190
|
-
"char": "»",
|
|
1191
|
-
"name": "right guillemet",
|
|
1192
|
-
"code": "U+00BB"
|
|
1193
|
-
}
|
|
1194
|
-
]
|
|
1195
|
-
},
|
|
1196
|
-
"quote-single": {
|
|
1197
|
-
"description": "Single quotation marks and apostrophes",
|
|
1198
|
-
"chars": [
|
|
1199
|
-
{
|
|
1200
|
-
"char": "'",
|
|
1201
|
-
"name": "apostrophe",
|
|
1202
|
-
"code": "U+0027"
|
|
1203
|
-
},
|
|
1204
|
-
{
|
|
1205
|
-
"char": "‘",
|
|
1206
|
-
"name": "left single quotation mark",
|
|
1207
|
-
"code": "U+2018"
|
|
1208
|
-
},
|
|
1209
|
-
{
|
|
1210
|
-
"char": "’",
|
|
1211
|
-
"name": "right single quotation mark",
|
|
1212
|
-
"code": "U+2019"
|
|
1213
|
-
},
|
|
1214
|
-
{
|
|
1215
|
-
"char": "‚",
|
|
1216
|
-
"name": "single low-9 quotation mark",
|
|
1217
|
-
"code": "U+201A"
|
|
1218
|
-
},
|
|
1219
|
-
{
|
|
1220
|
-
"char": "‹",
|
|
1221
|
-
"name": "left single guillemet",
|
|
1222
|
-
"code": "U+2039"
|
|
1223
|
-
},
|
|
1224
|
-
{
|
|
1225
|
-
"char": "›",
|
|
1226
|
-
"name": "right single guillemet",
|
|
1227
|
-
"code": "U+203A"
|
|
1228
|
-
},
|
|
1229
|
-
{
|
|
1230
|
-
"char": "ʼ",
|
|
1231
|
-
"name": "modifier letter apostrophe",
|
|
1232
|
-
"code": "U+02BC"
|
|
1233
|
-
},
|
|
1234
|
-
{
|
|
1235
|
-
"char": "´",
|
|
1236
|
-
"name": "acute accent",
|
|
1237
|
-
"code": "U+00B4"
|
|
1238
|
-
},
|
|
1239
|
-
{
|
|
1240
|
-
"char": "`",
|
|
1241
|
-
"name": "grave accent",
|
|
1242
|
-
"code": "U+0060"
|
|
1243
|
-
},
|
|
1244
|
-
{
|
|
1245
|
-
"char": "ʽ",
|
|
1246
|
-
"name": "modifier letter reversed comma",
|
|
1247
|
-
"code": "U+02BD"
|
|
1248
|
-
},
|
|
1249
|
-
{
|
|
1250
|
-
"char": "ʾ",
|
|
1251
|
-
"name": "modifier letter right half ring",
|
|
1252
|
-
"code": "U+02BE"
|
|
1253
|
-
},
|
|
1254
|
-
{
|
|
1255
|
-
"char": "ʿ",
|
|
1256
|
-
"name": "modifier letter left half ring",
|
|
1257
|
-
"code": "U+02BF"
|
|
1258
|
-
},
|
|
1259
|
-
{
|
|
1260
|
-
"char": "ˈ",
|
|
1261
|
-
"name": "modifier letter vertical line",
|
|
1262
|
-
"code": "U+02C8"
|
|
1263
|
-
}
|
|
1264
|
-
]
|
|
1265
|
-
},
|
|
1266
|
-
"dot": {
|
|
1267
|
-
"description": "Dot-like characters",
|
|
1268
|
-
"chars": [
|
|
1269
|
-
{
|
|
1270
|
-
"char": ".",
|
|
1271
|
-
"name": "full stop",
|
|
1272
|
-
"code": "U+002E"
|
|
1273
|
-
},
|
|
1274
|
-
{
|
|
1275
|
-
"char": "·",
|
|
1276
|
-
"name": "middle dot",
|
|
1277
|
-
"code": "U+00B7"
|
|
1278
|
-
},
|
|
1279
|
-
{
|
|
1280
|
-
"char": "•",
|
|
1281
|
-
"name": "bullet",
|
|
1282
|
-
"code": "U+2022"
|
|
1283
|
-
},
|
|
1284
|
-
{
|
|
1285
|
-
"char": "․",
|
|
1286
|
-
"name": "one dot leader",
|
|
1287
|
-
"code": "U+2024"
|
|
1288
|
-
},
|
|
1289
|
-
{
|
|
1290
|
-
"char": "。",
|
|
1291
|
-
"name": "CJK full stop",
|
|
1292
|
-
"code": "U+3002"
|
|
1293
|
-
},
|
|
1294
|
-
{
|
|
1295
|
-
"char": "׃",
|
|
1296
|
-
"name": "Hebrew sof pasuq",
|
|
1297
|
-
"code": "U+05C3"
|
|
1298
|
-
}
|
|
1299
|
-
]
|
|
1300
|
-
},
|
|
1301
|
-
"slash": {
|
|
1302
|
-
"description": "Slash-like characters",
|
|
1303
|
-
"chars": [
|
|
1304
|
-
{
|
|
1305
|
-
"char": "/",
|
|
1306
|
-
"name": "solidus",
|
|
1307
|
-
"code": "U+002F"
|
|
1308
|
-
},
|
|
1309
|
-
{
|
|
1310
|
-
"char": "⁄",
|
|
1311
|
-
"name": "fraction slash",
|
|
1312
|
-
"code": "U+2044"
|
|
1313
|
-
},
|
|
1314
|
-
{
|
|
1315
|
-
"char": "∕",
|
|
1316
|
-
"name": "division slash",
|
|
1317
|
-
"code": "U+2215"
|
|
1318
|
-
}
|
|
1319
|
-
]
|
|
1320
|
-
},
|
|
1321
|
-
"colon": {
|
|
1322
|
-
"description": "Colon-like characters",
|
|
1323
|
-
"chars": [
|
|
1324
|
-
{
|
|
1325
|
-
"char": ":",
|
|
1326
|
-
"name": "colon",
|
|
1327
|
-
"code": "U+003A"
|
|
1328
|
-
},
|
|
1329
|
-
{
|
|
1330
|
-
"char": "꞉",
|
|
1331
|
-
"name": "modifier letter colon",
|
|
1332
|
-
"code": "U+A789"
|
|
1333
|
-
},
|
|
1334
|
-
{
|
|
1335
|
-
"char": "∶",
|
|
1336
|
-
"name": "ratio",
|
|
1337
|
-
"code": "U+2236"
|
|
1338
|
-
},
|
|
1339
|
-
{
|
|
1340
|
-
"char": ":",
|
|
1341
|
-
"name": "full-width colon",
|
|
1342
|
-
"code": "U+FF1A"
|
|
1343
|
-
},
|
|
1344
|
-
{
|
|
1345
|
-
"char": "፥",
|
|
1346
|
-
"name": "Ethiopic colon",
|
|
1347
|
-
"code": "U+1365"
|
|
1348
|
-
}
|
|
1349
|
-
]
|
|
1350
|
-
},
|
|
1351
|
-
"comma": {
|
|
1352
|
-
"description": "Comma-like characters",
|
|
1353
|
-
"chars": [
|
|
1354
|
-
{
|
|
1355
|
-
"char": ",",
|
|
1356
|
-
"name": "comma",
|
|
1357
|
-
"code": "U+002C"
|
|
1358
|
-
},
|
|
1359
|
-
{
|
|
1360
|
-
"char": "‚",
|
|
1361
|
-
"name": "single low-9 quotation mark (used as comma)",
|
|
1362
|
-
"code": "U+201A"
|
|
1363
|
-
},
|
|
1364
|
-
{
|
|
1365
|
-
"char": "،",
|
|
1366
|
-
"name": "Arabic comma",
|
|
1367
|
-
"code": "U+060C"
|
|
1368
|
-
},
|
|
1369
|
-
{
|
|
1370
|
-
"char": "、",
|
|
1371
|
-
"name": "ideographic comma",
|
|
1372
|
-
"code": "U+3001"
|
|
1373
|
-
},
|
|
1374
|
-
{
|
|
1375
|
-
"char": ",",
|
|
1376
|
-
"name": "full-width comma",
|
|
1377
|
-
"code": "U+FF0C"
|
|
1378
|
-
},
|
|
1379
|
-
{
|
|
1380
|
-
"char": "﹐",
|
|
1381
|
-
"name": "small comma",
|
|
1382
|
-
"code": "U+FE50"
|
|
1383
|
-
},
|
|
1384
|
-
{
|
|
1385
|
-
"char": "՝",
|
|
1386
|
-
"name": "Armenian comma",
|
|
1387
|
-
"code": "U+055D"
|
|
1388
|
-
}
|
|
1389
|
-
]
|
|
1390
|
-
},
|
|
1391
|
-
"ellipsis": {
|
|
1392
|
-
"description": "Ellipsis characters",
|
|
1393
|
-
"chars": [{
|
|
1394
|
-
"char": "…",
|
|
1395
|
-
"name": "horizontal ellipsis",
|
|
1396
|
-
"code": "U+2026"
|
|
1397
|
-
}]
|
|
1398
|
-
},
|
|
1399
|
-
"question-mark": {
|
|
1400
|
-
"description": "Question mark variants",
|
|
1401
|
-
"chars": [
|
|
1402
|
-
{
|
|
1403
|
-
"char": "?",
|
|
1404
|
-
"name": "question mark",
|
|
1405
|
-
"code": "U+003F"
|
|
1406
|
-
},
|
|
1407
|
-
{
|
|
1408
|
-
"char": "?",
|
|
1409
|
-
"name": "full-width question mark",
|
|
1410
|
-
"code": "U+FF1F"
|
|
1411
|
-
},
|
|
1412
|
-
{
|
|
1413
|
-
"char": "⁇",
|
|
1414
|
-
"name": "double question mark",
|
|
1415
|
-
"code": "U+2047"
|
|
1416
|
-
},
|
|
1417
|
-
{
|
|
1418
|
-
"char": "⁈",
|
|
1419
|
-
"name": "question exclamation mark",
|
|
1420
|
-
"code": "U+2048"
|
|
1421
|
-
},
|
|
1422
|
-
{
|
|
1423
|
-
"char": "؟",
|
|
1424
|
-
"name": "Arabic question mark",
|
|
1425
|
-
"code": "U+061F"
|
|
1426
|
-
},
|
|
1427
|
-
{
|
|
1428
|
-
"char": "‽",
|
|
1429
|
-
"name": "interrobang",
|
|
1430
|
-
"code": "U+203D"
|
|
1431
|
-
}
|
|
1432
|
-
]
|
|
1433
|
-
},
|
|
1434
|
-
"exclamation-mark": {
|
|
1435
|
-
"description": "Exclamation mark variants",
|
|
1436
|
-
"chars": [
|
|
1437
|
-
{
|
|
1438
|
-
"char": "!",
|
|
1439
|
-
"name": "exclamation mark",
|
|
1440
|
-
"code": "U+0021"
|
|
1441
|
-
},
|
|
1442
|
-
{
|
|
1443
|
-
"char": "!",
|
|
1444
|
-
"name": "full-width exclamation mark",
|
|
1445
|
-
"code": "U+FF01"
|
|
1446
|
-
},
|
|
1447
|
-
{
|
|
1448
|
-
"char": "‼",
|
|
1449
|
-
"name": "double exclamation mark",
|
|
1450
|
-
"code": "U+203C"
|
|
1451
|
-
},
|
|
1452
|
-
{
|
|
1453
|
-
"char": "¡",
|
|
1454
|
-
"name": "inverted exclamation mark",
|
|
1455
|
-
"code": "U+00A1"
|
|
1456
|
-
}
|
|
1457
|
-
]
|
|
1458
|
-
},
|
|
1459
|
-
"semicolon": {
|
|
1460
|
-
"description": "Semicolon variants",
|
|
1461
|
-
"chars": [
|
|
1462
|
-
{
|
|
1463
|
-
"char": ";",
|
|
1464
|
-
"name": "semicolon",
|
|
1465
|
-
"code": "U+003B"
|
|
1466
|
-
},
|
|
1467
|
-
{
|
|
1468
|
-
"char": "؛",
|
|
1469
|
-
"name": "Arabic semicolon",
|
|
1470
|
-
"code": "U+061B"
|
|
1471
|
-
},
|
|
1472
|
-
{
|
|
1473
|
-
"char": ";",
|
|
1474
|
-
"name": "full-width semicolon",
|
|
1475
|
-
"code": "U+FF1B"
|
|
1476
|
-
},
|
|
1477
|
-
{
|
|
1478
|
-
"char": "፤",
|
|
1479
|
-
"name": "Ethiopic semicolon",
|
|
1480
|
-
"code": "U+1364"
|
|
1481
|
-
}
|
|
1482
|
-
]
|
|
1483
|
-
},
|
|
1484
|
-
"underscore": {
|
|
1485
|
-
"description": "Underscore variants",
|
|
1486
|
-
"chars": [{
|
|
1487
|
-
"char": "_",
|
|
1488
|
-
"name": "low line",
|
|
1489
|
-
"code": "U+005F"
|
|
1490
|
-
}, {
|
|
1491
|
-
"char": "_",
|
|
1492
|
-
"name": "full-width low line",
|
|
1493
|
-
"code": "U+FF3F"
|
|
1494
|
-
}]
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
};
|
|
1498
|
-
//#endregion
|
|
1499
1055
|
//#region src/util/char-groups.ts
|
|
1056
|
+
/**
|
|
1057
|
+
* Centralized Unicode character equivalence groups.
|
|
1058
|
+
*
|
|
1059
|
+
* Loads char-groups.json from @stll/anonymize-data and
|
|
1060
|
+
* provides helpers to build regex character classes that
|
|
1061
|
+
* match all typographic variants of a character type
|
|
1062
|
+
* (dashes, spaces, quotes, etc.).
|
|
1063
|
+
*
|
|
1064
|
+
* The JSON is statically imported so the bundler inlines
|
|
1065
|
+
* it, avoiding a runtime require() that breaks browsers.
|
|
1066
|
+
*/
|
|
1500
1067
|
/** Chars that need escaping inside a regex char class. */
|
|
1501
1068
|
const REGEX_CLASS_SPECIAL = /[\\\]^-]/;
|
|
1502
1069
|
const escapeForCharClass = (ch) => REGEX_CLASS_SPECIAL.test(ch) ? `\\${ch}` : ch;
|
|
1503
|
-
const
|
|
1070
|
+
const config = charGroupsJson;
|
|
1504
1071
|
/**
|
|
1505
1072
|
* Get the raw characters for a named group.
|
|
1506
1073
|
* Throws if the group does not exist.
|
|
1507
1074
|
*/
|
|
1508
1075
|
const charSet = (group) => {
|
|
1509
|
-
const g =
|
|
1076
|
+
const g = config.groups[group];
|
|
1510
1077
|
if (!g) throw new Error(`Unknown char group: "${group}"`);
|
|
1511
1078
|
return g.chars.map((entry) => entry.char);
|
|
1512
1079
|
};
|
|
@@ -1696,7 +1263,7 @@ const CZ_BIRTH_NUMBER = {
|
|
|
1696
1263
|
validator: cz.rc
|
|
1697
1264
|
};
|
|
1698
1265
|
const DATE_NUMERIC = {
|
|
1699
|
-
pattern: "\\b(?:\\d{1,2}[./]\\d{1,2}[./]\\d{2,4}|\\d{4}-\\d{2}-\\d{2})\\b",
|
|
1266
|
+
pattern: "\\b(?:\\d{1,2}[./]\\d{1,2}[./]\\d{2,4}|\\d{4}-\\d{2}-\\d{2}|\\d{4}\\.\\d{2}\\.\\d{2})\\b",
|
|
1700
1267
|
label: "date",
|
|
1701
1268
|
score: 1
|
|
1702
1269
|
};
|
|
@@ -1782,6 +1349,11 @@ const ALL_REGEX_DEFS = [
|
|
|
1782
1349
|
label: "url",
|
|
1783
1350
|
score: .9
|
|
1784
1351
|
},
|
|
1352
|
+
{
|
|
1353
|
+
pattern: "\\b(?:1[0-2]|0?[1-9]):[0-5]\\d[^\\S\\n]?(?:[aApP]\\.?[mM]\\.?)(?=[\\s,;!?)]|$)",
|
|
1354
|
+
label: "date",
|
|
1355
|
+
score: .9
|
|
1356
|
+
},
|
|
1785
1357
|
...STDNUM_ENTRIES
|
|
1786
1358
|
];
|
|
1787
1359
|
/** Flat pattern array for text-search. */
|
|
@@ -2765,6 +2337,7 @@ const TEMPLATE_PLACEHOLDER_RE = /^(?:\.{3,}|_{3,}|\[[\w\s]+\]|\{[\w\s]+\})$/;
|
|
|
2765
2337
|
const POSTAL_CODE_RE = /\d{3}\s?\d{2}/;
|
|
2766
2338
|
const HAS_DIGIT_RE = /\d/;
|
|
2767
2339
|
const ADDRESS_COMPONENTS_RE = /(?:^|\s)(?:ul\.|ulice|nám\.|náměstí|tř\.|třída|nábř\.|nábřeží|č\.p\.|č\.ev\.|č\.|sídliště|bulvár)(?=[\s,./]|$)/i;
|
|
2340
|
+
const JURISDICTION_RE = /^(?:state|commonwealth|district|territory)\s+of\s+/i;
|
|
2768
2341
|
const MAX_ENTITY_LENGTH = {
|
|
2769
2342
|
organization: 80,
|
|
2770
2343
|
person: 60
|
|
@@ -2816,8 +2389,8 @@ const filterFalsePositives = (entities, ctx = defaultContext) => {
|
|
|
2816
2389
|
if (STANDALONE_YEAR_RE.test(trimmed)) continue;
|
|
2817
2390
|
if (entity.label === "person" && HAS_DIGIT_RE.test(trimmed)) continue;
|
|
2818
2391
|
if ((entity.label === "person" || entity.label === "organization") && roles.has(trimmed.toLowerCase())) continue;
|
|
2819
|
-
if (entity.label === "address" && trimmed.length > 40 && !POSTAL_CODE_RE.test(trimmed) && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed)) continue;
|
|
2820
|
-
if (entity.label === "address" && entity.source === "trigger" && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed)) continue;
|
|
2392
|
+
if (entity.label === "address" && trimmed.length > 40 && !POSTAL_CODE_RE.test(trimmed) && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed) && !JURISDICTION_RE.test(trimmed)) continue;
|
|
2393
|
+
if (entity.label === "address" && entity.source === "trigger" && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed) && !JURISDICTION_RE.test(trimmed)) continue;
|
|
2821
2394
|
filtered.push(entity);
|
|
2822
2395
|
}
|
|
2823
2396
|
return filtered;
|
|
@@ -4090,7 +3663,7 @@ const loadRules = async () => {
|
|
|
4090
3663
|
mapping.push(ruleIdx);
|
|
4091
3664
|
}
|
|
4092
3665
|
}
|
|
4093
|
-
const builtSearch = patterns.length > 0 ? new
|
|
3666
|
+
const builtSearch = patterns.length > 0 ? new (getTextSearch())(patterns, {
|
|
4094
3667
|
overlapStrategy: "all",
|
|
4095
3668
|
caseInsensitive: true,
|
|
4096
3669
|
wholeWords: true
|
|
@@ -4482,24 +4055,6 @@ const enforceBoundaryConsistency = (entities, fullText) => {
|
|
|
4482
4055
|
};
|
|
4483
4056
|
//#endregion
|
|
4484
4057
|
//#region src/build-unified-search.ts
|
|
4485
|
-
/**
|
|
4486
|
-
* Build the unified search instances from all
|
|
4487
|
-
* detector pattern sources.
|
|
4488
|
-
*
|
|
4489
|
-
* Two TextSearch instances (not one) to avoid
|
|
4490
|
-
* 200K per-pattern object allocations:
|
|
4491
|
-
* 1. regex + triggers + legal-forms (mixed, ~140
|
|
4492
|
-
* patterns, caseInsensitive for trigger AC)
|
|
4493
|
-
* 2. deny-list + street-types + gazetteer
|
|
4494
|
-
* (caseInsensitive, overlap "all";
|
|
4495
|
-
* deny-list/street-type use per-pattern
|
|
4496
|
-
* wholeWords: true; gazetteer exact use
|
|
4497
|
-
* wholeWords: false; gazetteer fuzzy use
|
|
4498
|
-
* distance: 2 via @stll/fuzzy-search)
|
|
4499
|
-
*
|
|
4500
|
-
* All patterns are PatternEntry objects with
|
|
4501
|
-
* per-pattern literal/wholeWords settings.
|
|
4502
|
-
*/
|
|
4503
4058
|
const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultContext) => {
|
|
4504
4059
|
const [legalForms, triggers, denyListData, streetTypes, currencyPatterns, datePatterns, signingPatterns] = await Promise.all([
|
|
4505
4060
|
buildLegalFormPatterns(),
|
|
@@ -4545,11 +4100,12 @@ const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultCo
|
|
|
4545
4100
|
literal: true,
|
|
4546
4101
|
caseInsensitive: true
|
|
4547
4102
|
}));
|
|
4548
|
-
const
|
|
4103
|
+
const regexAllPatterns = [
|
|
4549
4104
|
...allRegex,
|
|
4550
4105
|
...legalForms,
|
|
4551
4106
|
...triggerEntries
|
|
4552
|
-
]
|
|
4107
|
+
];
|
|
4108
|
+
const tsRegex = new (getTextSearch())(regexAllPatterns);
|
|
4553
4109
|
offset = 0;
|
|
4554
4110
|
const denyListOriginals = denyListData?.originals ?? [];
|
|
4555
4111
|
const denyListSlice = {
|
|
@@ -4580,10 +4136,10 @@ const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultCo
|
|
|
4580
4136
|
];
|
|
4581
4137
|
return {
|
|
4582
4138
|
tsRegex,
|
|
4583
|
-
tsLiterals: literalAllPatterns.length > 0 ? new
|
|
4139
|
+
tsLiterals: literalAllPatterns.length > 0 ? new (getTextSearch())(literalAllPatterns, {
|
|
4584
4140
|
caseInsensitive: true,
|
|
4585
4141
|
overlapStrategy: "all"
|
|
4586
|
-
}) : new
|
|
4142
|
+
}) : new (getTextSearch())([]),
|
|
4587
4143
|
slices: {
|
|
4588
4144
|
regex: regexSlice,
|
|
4589
4145
|
legalForms: legalFormsSlice,
|
|
@@ -5551,6 +5107,9 @@ const levenshtein = (rawA, rawB) => {
|
|
|
5551
5107
|
return row[aLen] ?? 0;
|
|
5552
5108
|
};
|
|
5553
5109
|
//#endregion
|
|
5110
|
+
//#region src/index.ts
|
|
5111
|
+
initTextSearch(TextSearch);
|
|
5112
|
+
//#endregion
|
|
5554
5113
|
export { CURRENCY_PATTERN_META, DATE_PATTERN_META, DEFAULT_ENTITY_LABELS, DEFAULT_OPERATOR_CONFIG, DETECTION_SOURCES, DETECTOR_PRIORITY, OPERATOR_REGISTRY, OPERATOR_TYPES, REGEX_META, REGEX_PATTERNS, REGIONS, ZONE_SCORE_ADJUSTMENTS, applyHotwordRules, applyZoneAdjustments, boostNearMissEntities, buildDenyList, buildGazetteerPatterns, buildLegalFormPatterns, buildPlaceholderMap, buildStreetTypePatterns, buildTriggerPatterns, buildUnifiedSearch, chunkText, classifyZones, computeChunkOffsets, corefKey, createPipelineContext, deanonymise, decodeSpans, decodeTokenSpans, detectNameCorpus, ensureDenyListData, exportRedactionKey, extractDefinedTerms, filterFalsePositives, findCoreferenceSpans, getCurrencyPatterns, getDatePatterns, initHotwordRules, initNameCorpus, initZoneClassifier, levenshtein, mergeAndDedup, mergeChunkEntities, normalizeForSearch, prepareBatch, processAddressSeeds, processDenyListMatches, processGazetteerMatches, processLegalFormMatches, processRegexMatches, processTriggerMatches, propagateOrgNames, redactText, resolveCountries, resolveOperator, runPipeline, runUnifiedSearch, sanitizeEntities, tokenizeText };
|
|
5555
5114
|
|
|
5556
|
-
//# sourceMappingURL=index.
|
|
5115
|
+
//# sourceMappingURL=index.mjs.map
|