@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.
@@ -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 → original pattern text. */
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
- /** Position of the definition in the source text */
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 JSON config files.
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.ts.map
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
- import charGroupsJson from "@stll/anonymize-data/config/char-groups.json";
4
- import { TextSearch } from "@stll/text-search";
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
- * Load name corpus data from JSON config files.
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 [firstMod, surnameMod, titleMod, exclusionMod] = await Promise.all([
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 firstNames = firstMod.default.names;
585
- const surnames = surnameMod.default.names;
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(firstNames)),
590
- surnames: Object.freeze(new Set(surnames)),
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(firstNames),
594
- surnamesList: Object.freeze(surnames),
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
- const loadConfig = () => charGroupsJson;
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 TextSearch(patterns, {
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 tsRegex = new TextSearch([
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 TextSearch(literalAllPatterns, {
4136
+ tsLiterals: literalAllPatterns.length > 0 ? new (getTextSearch())(literalAllPatterns, {
4083
4137
  caseInsensitive: true,
4084
4138
  overlapStrategy: "all"
4085
- }) : new TextSearch([]),
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.js.map
5112
+ //# sourceMappingURL=index.mjs.map