@stll/anonymize 0.0.8 → 1.0.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/dist/{index.d.ts → index.d.mts} +17 -37
- package/dist/{index.js → index.mjs} +95 -38
- package/dist/index.mjs.map +1 -0
- package/package.json +7 -7
- package/dist/index.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Validator } from "@stll/stdnum";
|
|
2
1
|
import { Match, PatternEntry, TextSearch } from "@stll/text-search";
|
|
2
|
+
import { Validator } from "@stll/stdnum";
|
|
3
3
|
import { Tokenizer } from "@huggingface/tokenizers";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
@@ -143,9 +143,7 @@ declare const OPERATOR_TYPES: readonly ["replace", "redact"];
|
|
|
143
143
|
type OperatorType = (typeof OPERATOR_TYPES)[number];
|
|
144
144
|
/** Per-label operator selection. Key is the entity label. */
|
|
145
145
|
type OperatorConfig = {
|
|
146
|
-
/** Operator per label. Missing labels default to "replace". */
|
|
147
|
-
operators: Record<string, OperatorType>;
|
|
148
|
-
/** Custom replacement string for the redact operator. */
|
|
146
|
+
/** Operator per label. Missing labels default to "replace". */operators: Record<string, OperatorType>; /** Custom replacement string for the redact operator. */
|
|
149
147
|
redactString: string;
|
|
150
148
|
};
|
|
151
149
|
/** Whether an operator produces a reversible redaction entry. */
|
|
@@ -168,8 +166,7 @@ type RedactionResult = {
|
|
|
168
166
|
* Maps placeholder to original text. Only populated for
|
|
169
167
|
* reversible operators (replace). Empty for redact.
|
|
170
168
|
*/
|
|
171
|
-
redactionMap: Map<string, string>;
|
|
172
|
-
/** Maps placeholder to the operator that produced it. */
|
|
169
|
+
redactionMap: Map<string, string>; /** Maps placeholder to the operator that produced it. */
|
|
173
170
|
operatorMap: Map<string, OperatorType>;
|
|
174
171
|
entityCount: number;
|
|
175
172
|
};
|
|
@@ -209,8 +206,7 @@ declare const DEFAULT_ENTITY_LABELS: readonly ["person", "organization", "phone
|
|
|
209
206
|
//#region src/detectors/regex.d.ts
|
|
210
207
|
type RegexMeta = {
|
|
211
208
|
label: string;
|
|
212
|
-
score: number;
|
|
213
|
-
/** Post-match stdnum validator for confirmation. */
|
|
209
|
+
score: number; /** Post-match stdnum validator for confirmation. */
|
|
214
210
|
validator?: Validator;
|
|
215
211
|
};
|
|
216
212
|
/** Flat pattern array for text-search. */
|
|
@@ -269,10 +265,8 @@ type DenyListData = {
|
|
|
269
265
|
* appears in multiple dictionaries (e.g., "Denver"
|
|
270
266
|
* is both a person name and a city name).
|
|
271
267
|
*/
|
|
272
|
-
labels: string[][];
|
|
273
|
-
/** Maps pattern index →
|
|
274
|
-
originals: string[];
|
|
275
|
-
/** Maps pattern index → source types (plural). */
|
|
268
|
+
labels: string[][]; /** Maps pattern index → original pattern text. */
|
|
269
|
+
originals: string[]; /** Maps pattern index → source types (plural). */
|
|
276
270
|
sources: PatternSource[][];
|
|
277
271
|
};
|
|
278
272
|
/**
|
|
@@ -317,8 +311,7 @@ type PatternSlice = {
|
|
|
317
311
|
end: number;
|
|
318
312
|
};
|
|
319
313
|
type GazetteerData = {
|
|
320
|
-
/** Maps local pattern index to entry label. */
|
|
321
|
-
labels: string[];
|
|
314
|
+
/** Maps local pattern index to entry label. */labels: string[];
|
|
322
315
|
/**
|
|
323
316
|
* Whether each pattern is fuzzy (distance > 0).
|
|
324
317
|
* Used by the post-processor to assign scores.
|
|
@@ -326,9 +319,7 @@ type GazetteerData = {
|
|
|
326
319
|
isFuzzy: boolean[];
|
|
327
320
|
};
|
|
328
321
|
type UnifiedSearchInstance = {
|
|
329
|
-
/** Regex + triggers + legal-forms. */
|
|
330
|
-
tsRegex: TextSearch;
|
|
331
|
-
/** Deny-list + street-types + gazetteer. */
|
|
322
|
+
/** Regex + triggers + legal-forms. */tsRegex: TextSearch; /** Deny-list + street-types + gazetteer. */
|
|
332
323
|
tsLiterals: TextSearch;
|
|
333
324
|
slices: {
|
|
334
325
|
regex: PatternSlice;
|
|
@@ -369,8 +360,7 @@ type NameCorpusData = {
|
|
|
369
360
|
firstNames: ReadonlySet<string>;
|
|
370
361
|
surnames: ReadonlySet<string>;
|
|
371
362
|
titleTokens: ReadonlySet<string>;
|
|
372
|
-
excludedWords: ReadonlySet<string>;
|
|
373
|
-
/** Raw arrays exposed for deny-list AC integration. */
|
|
363
|
+
excludedWords: ReadonlySet<string>; /** Raw arrays exposed for deny-list AC integration. */
|
|
374
364
|
firstNamesList: readonly string[];
|
|
375
365
|
surnamesList: readonly string[];
|
|
376
366
|
titlesList: readonly string[];
|
|
@@ -397,8 +387,7 @@ type PipelineContext = {
|
|
|
397
387
|
allowList: ReadonlySet<string> | null;
|
|
398
388
|
allowListPromise: Promise<ReadonlySet<string>> | null;
|
|
399
389
|
personStopwords: ReadonlySet<string> | null;
|
|
400
|
-
personStopwordsPromise: Promise<ReadonlySet<string>> | null;
|
|
401
|
-
/** First-name exclusions for stopword filtering. */
|
|
390
|
+
personStopwordsPromise: Promise<ReadonlySet<string>> | null; /** First-name exclusions for stopword filtering. */
|
|
402
391
|
firstNameExclusions: ReadonlySet<string> | null;
|
|
403
392
|
firstNameExclusionCorpusLen: number;
|
|
404
393
|
genericRoles: ReadonlySet<string> | null;
|
|
@@ -425,11 +414,6 @@ type PipelineContext = {
|
|
|
425
414
|
};
|
|
426
415
|
/** Create a fresh, empty pipeline context. */
|
|
427
416
|
declare const createPipelineContext: () => PipelineContext;
|
|
428
|
-
/**
|
|
429
|
-
* Module-level default context. Used when callers
|
|
430
|
-
* don't provide an explicit context, preserving full
|
|
431
|
-
* backward compatibility with the existing API.
|
|
432
|
-
*/
|
|
433
417
|
//#endregion
|
|
434
418
|
//#region src/pipeline.d.ts
|
|
435
419
|
/** Strip leading/trailing whitespace and punctuation. */
|
|
@@ -613,10 +597,8 @@ declare const processGazetteerMatches: (allMatches: Match[], sliceStart: number,
|
|
|
613
597
|
//#region src/detectors/coreference.d.ts
|
|
614
598
|
type DefinedTerm = {
|
|
615
599
|
alias: string;
|
|
616
|
-
label: string;
|
|
617
|
-
|
|
618
|
-
definitionStart: number;
|
|
619
|
-
/** Original entity text the alias refers to */
|
|
600
|
+
label: string; /** Position of the definition in the source text */
|
|
601
|
+
definitionStart: number; /** Original entity text the alias refers to */
|
|
620
602
|
sourceText: string;
|
|
621
603
|
};
|
|
622
604
|
declare const extractDefinedTerms: (fullText: string, entities: Entity[], ctx?: PipelineContext) => Promise<DefinedTerm[]>;
|
|
@@ -647,7 +629,9 @@ declare const propagateOrgNames: (entities: Entity[], fullText: string) => Entit
|
|
|
647
629
|
//#endregion
|
|
648
630
|
//#region src/detectors/names.d.ts
|
|
649
631
|
/**
|
|
650
|
-
* Load name corpus data from
|
|
632
|
+
* Load name corpus data from per-language dictionary
|
|
633
|
+
* files and legacy config files. Merges all sources.
|
|
634
|
+
*
|
|
651
635
|
* Safe to call multiple times; only loads once per
|
|
652
636
|
* context. Must be called before detectNameCorpus or
|
|
653
637
|
* the getNameCorpus*() accessors are used.
|
|
@@ -673,8 +657,7 @@ declare const detectNameCorpus: (fullText: string, ctx?: PipelineContext) => Ent
|
|
|
673
657
|
//#endregion
|
|
674
658
|
//#region src/unified-search.d.ts
|
|
675
659
|
type UnifiedResult = {
|
|
676
|
-
/** All matches from both instances combined. */
|
|
677
|
-
regexMatches: Match[];
|
|
660
|
+
/** All matches from both instances combined. */regexMatches: Match[];
|
|
678
661
|
literalMatches: Match[];
|
|
679
662
|
};
|
|
680
663
|
declare const runUnifiedSearch: (instance: UnifiedSearchInstance, fullText: string) => UnifiedResult;
|
|
@@ -740,7 +723,6 @@ declare const filterFalsePositives: (entities: Entity[], ctx?: PipelineContext)
|
|
|
740
723
|
* entities pass through unchanged.
|
|
741
724
|
*/
|
|
742
725
|
declare const boostNearMissEntities: (entities: Entity[], threshold: number) => Entity[];
|
|
743
|
-
/** Ensure preposition data is loaded. */
|
|
744
726
|
//#endregion
|
|
745
727
|
//#region src/filters/hotword-rules.d.ts
|
|
746
728
|
type HotwordRule = {
|
|
@@ -849,8 +831,6 @@ declare const decodeTokenSpans: (batchSize: number, numWords: number, numEntitie
|
|
|
849
831
|
//#region src/gliner/processor.d.ts
|
|
850
832
|
/** Tokenize text into words with character offsets. */
|
|
851
833
|
declare const tokenizeText: (text: string) => [words: string[], starts: number[], ends: number[]];
|
|
852
|
-
/** Pad a 2D or 3D array to uniform inner length. */
|
|
853
|
-
|
|
854
834
|
/** Prepare a complete batch for ONNX inference. */
|
|
855
835
|
declare const prepareBatch: (tokenizer: Tokenizer, texts: string[], entities: string[], maxWidth: number) => {
|
|
856
836
|
inputsIds: number[][];
|
|
@@ -936,4 +916,4 @@ declare const levenshtein: (rawA: string, rawB: string) => number;
|
|
|
936
916
|
declare const normalizeForSearch: (text: string) => string;
|
|
937
917
|
//#endregion
|
|
938
918
|
export { type AnonymisationOperator, CURRENCY_PATTERN_META, type CountryCode, DATE_PATTERN_META, DEFAULT_ENTITY_LABELS, DEFAULT_OPERATOR_CONFIG, DETECTION_SOURCES, DETECTOR_PRIORITY, type DefinitionPattern, type DenyListCategory, type DenyListData, type DetectionSource, type DocumentZone, type Entity, type EntityResult, type GazetteerData, type GazetteerEntry, type HotwordRule, type NameCorpusData, type NerInferenceFn, OPERATOR_REGISTRY, OPERATOR_TYPES, type OperatorConfig, type OperatorType, type PipelineConfig, type PipelineContext, type PipelineOptions, REGEX_META, REGEX_PATTERNS, REGIONS, type RawInferenceResult, type RedactionResult, type RegexMeta, type RegionId, type ReviewDecision, type ReviewedEntity, type TriggerExtension, type TriggerGroupConfig, type TriggerRule, type TriggerStrategy, type TriggerValidation, type UnifiedResult, type UnifiedSearchInstance, ZONE_SCORE_ADJUSTMENTS, type ZoneSpan, 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 };
|
|
939
|
-
//# sourceMappingURL=index.d.
|
|
919
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { TextSearch } from "@stll/text-search";
|
|
1
3
|
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
4
|
import { toRegex } from "@stll/stdnum/patterns";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/search-engine.ts
|
|
9
|
+
let _TextSearch;
|
|
10
|
+
const initTextSearch = (ctor) => {
|
|
11
|
+
_TextSearch = ctor;
|
|
12
|
+
};
|
|
13
|
+
const getTextSearch = () => {
|
|
14
|
+
if (!_TextSearch) throw new Error("TextSearch not initialized. Import from @stll/anonymize or @stll/anonymize-wasm, not from internal modules.");
|
|
15
|
+
return _TextSearch;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
5
18
|
//#region src/types.ts
|
|
6
19
|
/**
|
|
7
20
|
* Source of a detected entity span.
|
|
@@ -566,7 +579,37 @@ const getNameCorpusFirstNames = (ctx = defaultContext) => ctx.nameCorpus?.firstN
|
|
|
566
579
|
const getNameCorpusSurnames = (ctx = defaultContext) => ctx.nameCorpus?.surnamesList ?? [];
|
|
567
580
|
const getNameCorpusTitles = (ctx = defaultContext) => ctx.nameCorpus?.titlesList ?? [];
|
|
568
581
|
/**
|
|
569
|
-
*
|
|
582
|
+
* Languages with per-language first/surname
|
|
583
|
+
* dictionaries in @stll/anonymize-data.
|
|
584
|
+
*/
|
|
585
|
+
const NAME_LANGUAGES = [
|
|
586
|
+
"cs",
|
|
587
|
+
"sk",
|
|
588
|
+
"de",
|
|
589
|
+
"pl",
|
|
590
|
+
"hu",
|
|
591
|
+
"ro",
|
|
592
|
+
"fr",
|
|
593
|
+
"es",
|
|
594
|
+
"it",
|
|
595
|
+
"en",
|
|
596
|
+
"sv"
|
|
597
|
+
];
|
|
598
|
+
/**
|
|
599
|
+
* Try importing a JSON module; return empty array
|
|
600
|
+
* if not found.
|
|
601
|
+
*/
|
|
602
|
+
const tryImportArray = async (path) => {
|
|
603
|
+
try {
|
|
604
|
+
return (await import(path)).default;
|
|
605
|
+
} catch {
|
|
606
|
+
return [];
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
/**
|
|
610
|
+
* Load name corpus data from per-language dictionary
|
|
611
|
+
* files and legacy config files. Merges all sources.
|
|
612
|
+
*
|
|
570
613
|
* Safe to call multiple times; only loads once per
|
|
571
614
|
* context. Must be called before detectNameCorpus or
|
|
572
615
|
* the getNameCorpus*() accessors are used.
|
|
@@ -575,23 +618,40 @@ const initNameCorpus = (ctx = defaultContext) => {
|
|
|
575
618
|
if (ctx.nameCorpusPromise) return ctx.nameCorpusPromise;
|
|
576
619
|
const promise = (async () => {
|
|
577
620
|
try {
|
|
578
|
-
const [
|
|
621
|
+
const [legacyFirstMod, legacySurnameMod, titleMod, exclusionMod] = await Promise.all([
|
|
579
622
|
import("@stll/anonymize-data/config/names-first.json"),
|
|
580
623
|
import("@stll/anonymize-data/config/names-surnames.json"),
|
|
581
624
|
import("@stll/anonymize-data/config/names-title-tokens.json"),
|
|
582
625
|
import("@stll/anonymize-data/config/names-exclusions.json")
|
|
583
626
|
]);
|
|
584
|
-
const
|
|
585
|
-
const
|
|
627
|
+
const firstImports = NAME_LANGUAGES.map((lang) => tryImportArray(`@stll/anonymize-data/dictionaries/names/first/${lang}.json`));
|
|
628
|
+
const surnameImports = NAME_LANGUAGES.map((lang) => tryImportArray(`@stll/anonymize-data/dictionaries/names/surnames/${lang}.json`));
|
|
629
|
+
const [firstResults, surnameResults] = await Promise.all([Promise.all(firstImports), Promise.all(surnameImports)]);
|
|
630
|
+
const firstNames = [...legacyFirstMod.default.names];
|
|
631
|
+
for (const names of firstResults) for (const name of names) firstNames.push(name);
|
|
632
|
+
const surnames = [...legacySurnameMod.default.names];
|
|
633
|
+
for (const names of surnameResults) for (const name of names) surnames.push(name);
|
|
634
|
+
const dedup = (arr) => {
|
|
635
|
+
const seen = /* @__PURE__ */ new Set();
|
|
636
|
+
const result = [];
|
|
637
|
+
for (const item of arr) {
|
|
638
|
+
if (seen.has(item)) continue;
|
|
639
|
+
seen.add(item);
|
|
640
|
+
result.push(item);
|
|
641
|
+
}
|
|
642
|
+
return result;
|
|
643
|
+
};
|
|
644
|
+
const dedupFirst = dedup(firstNames);
|
|
645
|
+
const dedupSurnames = dedup(surnames);
|
|
586
646
|
const titles = titleMod.default.tokens;
|
|
587
647
|
const exclusions = exclusionMod.default.words;
|
|
588
648
|
ctx.nameCorpus = {
|
|
589
|
-
firstNames: Object.freeze(new Set(
|
|
590
|
-
surnames: Object.freeze(new Set(
|
|
649
|
+
firstNames: Object.freeze(new Set(dedupFirst)),
|
|
650
|
+
surnames: Object.freeze(new Set(dedupSurnames)),
|
|
591
651
|
titleTokens: Object.freeze(new Set(titles)),
|
|
592
652
|
excludedWords: Object.freeze(new Set(exclusions)),
|
|
593
|
-
firstNamesList: Object.freeze(
|
|
594
|
-
surnamesList: Object.freeze(
|
|
653
|
+
firstNamesList: Object.freeze(dedupFirst),
|
|
654
|
+
surnamesList: Object.freeze(dedupSurnames),
|
|
595
655
|
titlesList: Object.freeze(titles),
|
|
596
656
|
excludedList: Object.freeze(exclusions)
|
|
597
657
|
};
|
|
@@ -999,7 +1059,12 @@ const POST_NOMINALS = [
|
|
|
999
1059
|
/** Chars that need escaping inside a regex char class. */
|
|
1000
1060
|
const REGEX_CLASS_SPECIAL = /[\\\]^-]/;
|
|
1001
1061
|
const escapeForCharClass = (ch) => REGEX_CLASS_SPECIAL.test(ch) ? `\\${ch}` : ch;
|
|
1002
|
-
|
|
1062
|
+
let cached;
|
|
1063
|
+
const loadConfig = () => {
|
|
1064
|
+
if (cached) return cached;
|
|
1065
|
+
cached = __require("@stll/anonymize-data/config/char-groups.json");
|
|
1066
|
+
return cached;
|
|
1067
|
+
};
|
|
1003
1068
|
/**
|
|
1004
1069
|
* Get the raw characters for a named group.
|
|
1005
1070
|
* Throws if the group does not exist.
|
|
@@ -1195,7 +1260,7 @@ const CZ_BIRTH_NUMBER = {
|
|
|
1195
1260
|
validator: cz.rc
|
|
1196
1261
|
};
|
|
1197
1262
|
const DATE_NUMERIC = {
|
|
1198
|
-
pattern: "\\b(?:\\d{1,2}[./]\\d{1,2}[./]\\d{2,4}|\\d{4}-\\d{2}-\\d{2})\\b",
|
|
1263
|
+
pattern: "\\b(?:\\d{1,2}[./]\\d{1,2}[./]\\d{2,4}|\\d{4}-\\d{2}-\\d{2}|\\d{4}\\.\\d{2}\\.\\d{2})\\b",
|
|
1199
1264
|
label: "date",
|
|
1200
1265
|
score: 1
|
|
1201
1266
|
};
|
|
@@ -1281,6 +1346,11 @@ const ALL_REGEX_DEFS = [
|
|
|
1281
1346
|
label: "url",
|
|
1282
1347
|
score: .9
|
|
1283
1348
|
},
|
|
1349
|
+
{
|
|
1350
|
+
pattern: "\\b(?:1[0-2]|0?[1-9]):[0-5]\\d[^\\S\\n]?(?:[aApP]\\.?[mM]\\.?)(?=[\\s,;!?)]|$)",
|
|
1351
|
+
label: "date",
|
|
1352
|
+
score: .9
|
|
1353
|
+
},
|
|
1284
1354
|
...STDNUM_ENTRIES
|
|
1285
1355
|
];
|
|
1286
1356
|
/** Flat pattern array for text-search. */
|
|
@@ -2264,6 +2334,7 @@ const TEMPLATE_PLACEHOLDER_RE = /^(?:\.{3,}|_{3,}|\[[\w\s]+\]|\{[\w\s]+\})$/;
|
|
|
2264
2334
|
const POSTAL_CODE_RE = /\d{3}\s?\d{2}/;
|
|
2265
2335
|
const HAS_DIGIT_RE = /\d/;
|
|
2266
2336
|
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;
|
|
2337
|
+
const JURISDICTION_RE = /^(?:state|commonwealth|district|territory)\s+of\s+/i;
|
|
2267
2338
|
const MAX_ENTITY_LENGTH = {
|
|
2268
2339
|
organization: 80,
|
|
2269
2340
|
person: 60
|
|
@@ -2315,8 +2386,8 @@ const filterFalsePositives = (entities, ctx = defaultContext) => {
|
|
|
2315
2386
|
if (STANDALONE_YEAR_RE.test(trimmed)) continue;
|
|
2316
2387
|
if (entity.label === "person" && HAS_DIGIT_RE.test(trimmed)) continue;
|
|
2317
2388
|
if ((entity.label === "person" || entity.label === "organization") && roles.has(trimmed.toLowerCase())) continue;
|
|
2318
|
-
if (entity.label === "address" && trimmed.length > 40 && !POSTAL_CODE_RE.test(trimmed) && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed)) continue;
|
|
2319
|
-
if (entity.label === "address" && entity.source === "trigger" && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed)) continue;
|
|
2389
|
+
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;
|
|
2390
|
+
if (entity.label === "address" && entity.source === "trigger" && !HAS_DIGIT_RE.test(trimmed) && !ADDRESS_COMPONENTS_RE.test(trimmed) && !JURISDICTION_RE.test(trimmed)) continue;
|
|
2320
2391
|
filtered.push(entity);
|
|
2321
2392
|
}
|
|
2322
2393
|
return filtered;
|
|
@@ -3589,7 +3660,7 @@ const loadRules = async () => {
|
|
|
3589
3660
|
mapping.push(ruleIdx);
|
|
3590
3661
|
}
|
|
3591
3662
|
}
|
|
3592
|
-
const builtSearch = patterns.length > 0 ? new
|
|
3663
|
+
const builtSearch = patterns.length > 0 ? new (getTextSearch())(patterns, {
|
|
3593
3664
|
overlapStrategy: "all",
|
|
3594
3665
|
caseInsensitive: true,
|
|
3595
3666
|
wholeWords: true
|
|
@@ -3981,24 +4052,6 @@ const enforceBoundaryConsistency = (entities, fullText) => {
|
|
|
3981
4052
|
};
|
|
3982
4053
|
//#endregion
|
|
3983
4054
|
//#region src/build-unified-search.ts
|
|
3984
|
-
/**
|
|
3985
|
-
* Build the unified search instances from all
|
|
3986
|
-
* detector pattern sources.
|
|
3987
|
-
*
|
|
3988
|
-
* Two TextSearch instances (not one) to avoid
|
|
3989
|
-
* 200K per-pattern object allocations:
|
|
3990
|
-
* 1. regex + triggers + legal-forms (mixed, ~140
|
|
3991
|
-
* patterns, caseInsensitive for trigger AC)
|
|
3992
|
-
* 2. deny-list + street-types + gazetteer
|
|
3993
|
-
* (caseInsensitive, overlap "all";
|
|
3994
|
-
* deny-list/street-type use per-pattern
|
|
3995
|
-
* wholeWords: true; gazetteer exact use
|
|
3996
|
-
* wholeWords: false; gazetteer fuzzy use
|
|
3997
|
-
* distance: 2 via @stll/fuzzy-search)
|
|
3998
|
-
*
|
|
3999
|
-
* All patterns are PatternEntry objects with
|
|
4000
|
-
* per-pattern literal/wholeWords settings.
|
|
4001
|
-
*/
|
|
4002
4055
|
const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultContext) => {
|
|
4003
4056
|
const [legalForms, triggers, denyListData, streetTypes, currencyPatterns, datePatterns, signingPatterns] = await Promise.all([
|
|
4004
4057
|
buildLegalFormPatterns(),
|
|
@@ -4044,11 +4097,12 @@ const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultCo
|
|
|
4044
4097
|
literal: true,
|
|
4045
4098
|
caseInsensitive: true
|
|
4046
4099
|
}));
|
|
4047
|
-
const
|
|
4100
|
+
const regexAllPatterns = [
|
|
4048
4101
|
...allRegex,
|
|
4049
4102
|
...legalForms,
|
|
4050
4103
|
...triggerEntries
|
|
4051
|
-
]
|
|
4104
|
+
];
|
|
4105
|
+
const tsRegex = new (getTextSearch())(regexAllPatterns);
|
|
4052
4106
|
offset = 0;
|
|
4053
4107
|
const denyListOriginals = denyListData?.originals ?? [];
|
|
4054
4108
|
const denyListSlice = {
|
|
@@ -4079,10 +4133,10 @@ const buildUnifiedSearch = async (config, gazetteerEntries = [], ctx = defaultCo
|
|
|
4079
4133
|
];
|
|
4080
4134
|
return {
|
|
4081
4135
|
tsRegex,
|
|
4082
|
-
tsLiterals: literalAllPatterns.length > 0 ? new
|
|
4136
|
+
tsLiterals: literalAllPatterns.length > 0 ? new (getTextSearch())(literalAllPatterns, {
|
|
4083
4137
|
caseInsensitive: true,
|
|
4084
4138
|
overlapStrategy: "all"
|
|
4085
|
-
}) : new
|
|
4139
|
+
}) : new (getTextSearch())([]),
|
|
4086
4140
|
slices: {
|
|
4087
4141
|
regex: regexSlice,
|
|
4088
4142
|
legalForms: legalFormsSlice,
|
|
@@ -5050,6 +5104,9 @@ const levenshtein = (rawA, rawB) => {
|
|
|
5050
5104
|
return row[aLen] ?? 0;
|
|
5051
5105
|
};
|
|
5052
5106
|
//#endregion
|
|
5107
|
+
//#region src/index.ts
|
|
5108
|
+
initTextSearch(TextSearch);
|
|
5109
|
+
//#endregion
|
|
5053
5110
|
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 };
|
|
5054
5111
|
|
|
5055
|
-
//# sourceMappingURL=index.
|
|
5112
|
+
//# sourceMappingURL=index.mjs.map
|