cloakapi 0.5.1__py3-none-any.whl

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.
Files changed (61) hide show
  1. LICENSE +202 -0
  2. NOTICE +18 -0
  3. THIRD-PARTY-NOTICES.md +22 -0
  4. TRADEMARKS.md +19 -0
  5. cloakapi/__init__.py +271 -0
  6. cloakapi/_disclosure/clk.txt +11 -0
  7. cloakapi/_disclosure/clk_message.txt +11 -0
  8. cloakapi/_disclosure/cloak_angle.txt +16 -0
  9. cloakapi/_disclosure/cloak_angle_message.txt +16 -0
  10. cloakapi/_http.py +443 -0
  11. cloakapi/_pretokenised.py +134 -0
  12. cloakapi/_relay.py +213 -0
  13. cloakapi/_release.py +30 -0
  14. cloakapi/_request_strings.py +1267 -0
  15. cloakapi/_ruleset/patterns.json +2238 -0
  16. cloakapi/_stream_detok.py +788 -0
  17. cloakapi/_version.py +31 -0
  18. cloakapi/async_client.py +704 -0
  19. cloakapi/attachments.py +176 -0
  20. cloakapi/cli.py +245 -0
  21. cloakapi/client.py +848 -0
  22. cloakapi/config.py +491 -0
  23. cloakapi/coverage.py +21 -0
  24. cloakapi/degraded.py +196 -0
  25. cloakapi/disclosure.py +334 -0
  26. cloakapi/engine.py +922 -0
  27. cloakapi/errors.py +304 -0
  28. cloakapi/notices.py +142 -0
  29. cloakapi/pii/__init__.py +4 -0
  30. cloakapi/pii/_checksum.py +510 -0
  31. cloakapi/pii/_ruleset.py +131 -0
  32. cloakapi/pii/patterns.py +1713 -0
  33. cloakapi/pii/rulefile.py +738 -0
  34. cloakapi/pii/tokenizer.py +537 -0
  35. cloakapi/posture.py +112 -0
  36. cloakapi/py.typed +1 -0
  37. cloakapi/receipts.py +605 -0
  38. cloakapi/resources/__init__.py +32 -0
  39. cloakapi/resources/admin.py +104 -0
  40. cloakapi/resources/buffer.py +54 -0
  41. cloakapi/resources/chat.py +293 -0
  42. cloakapi/resources/detect.py +115 -0
  43. cloakapi/resources/messages.py +260 -0
  44. cloakapi/resources/models.py +58 -0
  45. cloakapi/resources/receipts.py +252 -0
  46. cloakapi/resources/reconstruct.py +173 -0
  47. cloakapi/resources/tokens.py +47 -0
  48. cloakapi/review.py +112 -0
  49. cloakapi/streaming.py +446 -0
  50. cloakapi/surrogate_mode.py +308 -0
  51. cloakapi/types.py +284 -0
  52. cloakapi-0.5.1.dist-info/METADATA +441 -0
  53. cloakapi-0.5.1.dist-info/RECORD +61 -0
  54. cloakapi-0.5.1.dist-info/WHEEL +4 -0
  55. cloakapi-0.5.1.dist-info/entry_points.txt +2 -0
  56. cloakapi-0.5.1.dist-info/licenses/LICENSE +202 -0
  57. cloakapi-0.5.1.dist-info/licenses/NOTICE +18 -0
  58. licenses/Apache-2.0.txt +202 -0
  59. licenses/CC-BY-4.0.txt +104 -0
  60. licenses/MIT-Faker.txt +21 -0
  61. licenses/MIT.txt +21 -0
@@ -0,0 +1,2238 @@
1
+ {
2
+ "version": "1.6.1",
3
+ "description": "v1.4.33 (2026-09-21 G22 month-name year window): 21 DATE_OF_BIRTH spelled-month branches that said (?:19|20)\\d{2} now say (?:19|20|21)\\d{2}, matching the numeric day-first century list. Python re on the pattern: 6. jaanuaril 2101 and Arabic 14 أيار 2101 match after and not before; 6. jaanuaril 1968 still matches; 6. jaanuaril 2200 and hello world still do not. NID_SE_PNR untouched. v1.4.32 (2026-09-21 G22 DATE separator class, dash family COMPLETED): the numeric-date separator class carries ALL 25 BMP Pd dash characters plus U+2212 MINUS SIGN, at all 8 numeric sites (cued + uncued, both digit orders). WHY (v1.4.32): v1.4.31 covered only U+002D and U+2010..U+2014. Measured on the CANONICAL engine 2026-09-21: 19 of 26 dash separators (incl. U+2015, U+301C, U+FE58, U+FE63, U+FF0D) sent the in-range birth date 11<dash>06<dash>1990 out COMPLETELY RAW, with the ASCII-hyphen POSITIVE control passing and a letter-separator NEGATIVE control failing in the SAME run. Widening adds no new false-positive KIND: the FP shapes (page range, score) ALREADY match via U+002D and U+2013 today, and the structural date gate still rejects month>12. Enumerated EXPLICITLY and NOT as a Pd property class, because pii-patterns-ts/src/compile.ts hoists only ims flags -- a property class in a non-u JS RegExp silently matches the literal letter p. U+10EAD YEZIDI HYPHENATION MARK is deliberately EXCLUDED: non-BMP, and in a non-u JS character class it would match lone surrogates. WHY: measured on BOTH shipped engines (native FFI ruleset 632d42cf / binary c965a946, and WASM ruleset b72749fc / binary 0dcf6db1), the cued IN-RANGE birth date 'Fodd 11<en-dash>06<en-dash>1990' went out COMPLETELY RAW, n=3 stable on both. This is NOT the PHONE-overlap mechanism: asked separately, DATE_OF_BIRTH and PHONE BOTH return no match for the dash forms, so no PHONE-side change could reach it -- the detector's own separator class was simply too narrow. A word processor autocorrects a typed hyphen into an en-dash, so this is an ordinary birth date, not an exotic input. Measured nytte/pris over 24 in-range date probes (6 separators x 2 frames x 2 digit orders) and an 11-probe non-date corpus: dash family = 12 of 24 closed with ZERO new false positives; the two baseline corpus hits ('Build 2024.1.5', 'SKU 88012-11-30') are PRE-EXISTING and unchanged. DELIBERATELY NOT ADDED: whitespace and NBSP (would close 8 more but add 6 false positives incl. a pasted spreadsheet row '12 05 2020' -- tabular paste is cloaksheets' core input, so whitespace is the separator between UNRELATED numbers, unlike every dash) and underscore (+4 closed, +2 false positives on filenames/ids like batch_12_05_2024_final.csv). Those two stay as they are: space/NBSP/no-separator forms are still taken by PHONE, which mangles the date but does NOT leak it, whereas the dash forms leaked RAW. Literal characters are used in the class, not \\u escapes, because Rust, JS and Python spell those escapes differently and the file already carries literal ranges. v1.4.30 (2026-09-21 G22 DATE year-first century parity): the UNCUED YEAR-FIRST Y-M-D branch year goes (?:19|20|21)\\d{2} -> \\d{4}, matching the year liberality the UNCUED DAY-FIRST sibling branch already ships ((?:19|20|21)\\d{2}|\\d{4}|\\d{2}). The two are the same detector in the same uncued context and differed only by DIGIT ORDER. Consequence of the old form: a date outside 1900-2199 written Y-M-D did not match DATE_OF_BIRTH at all and was taken instead by the PHONE grouped-run branch \\d{4}[-\\s]\\d{2}[-\\s]\\d{2} (precedence is correct - DATE_OF_BIRTH is index 5, PHONE is last - PHONE won on EARLIER START because DATE_OF_BIRTH matched only a short suffix or nothing). PHONE mints a digit-randomised surrogate with separators kept: 2200-06-11 -> 2868-07-31. That is a MALFORMED SURROGATE, not a PII escape - no raw digit of the original survives - but it can read downstream as a valid date. With / or . separators PHONE does not fire at all, so the same out-of-range date went fully RAW (2200/06/11) or PARTIALLY raw (1899/06/11 -> leading '189' raw + a surrogate over '9/06/11'); that half IS a detection gap, and it is the half the hyphen-only sweeps missed. Measured over years 0000-9999 x 3 separators = 30000 probes: 9782 re-typed PHONE->DATE_OF_BIRTH, 1354 RAW->DATE_OF_BIRTH, 0 coverage lost. Known cost, stated: a real phone written NNNN-NN-NN whose middle pair is 1-12 and last pair 1-31 re-labels PHONE->DATE_OF_BIRTH (a mislabel between two PII types, both still tokenised, never a leak), and a date-SHAPED non-date with / or . separators outside 1900-2199 becomes newly redacted (e.g. 3000/12/31) - the same over-redaction the in-range years already had. Raising the century list again would only MOVE the cliff: the year range must decide whether a date is a BIRTH date, not whether the string is a date. Lock-step: sdk/typescript/src/browser/review.ts DATE_SHAPE_RE and sdk/typescript/src/pii/patterns.ts carry the same widening. v1.4.29 (2026-07-22 v1.2.1 CLOSE-BARE — whole-domain checksum-precise bare pass; goal-run/gauntlet/V121-CLOSE-BARE-LIST.md). Rolf ruled close-bare for Norwegian fødselsnummer and asked for a COMPLETE audit of every structured class×country where a BARE value is checksum-validatable but currently cue-only. Added checksum-gated BARE branches to the WASM lane (checksum.rs nid_bare dispatchers, mirrored in the pii-engine parity copy): (10-digit) SE personnummer Luhn+date, AT SVNR weighted-mod-11+date; (11-digit) NO fødselsnummer double-mod-11+date [the Rolf ruling; ~0.8% bare FP — previously a documented precision residual, OPEN-ITEMS §3], AR CUIT mod-11, RU SNILS mod-101, BE Rijksregisternummer contiguous mod-97; (12-digit, NEW length NID_BARE_12) JP My Number mod-11 || IN Aadhaar Verhoeff — the ONLY class NOT covered by the PHONE/SSN length floor, so this closes a REAL raw-leak; (13-digit) KR RRN contiguous weighted-mod-11+date (pre-2020; post-2020 randomised-tail residual documented). WHY NOT EARLIER (NO-fnr): a bare 11-digit run with NO checksum is un-maskable-precisely; the mod-11 double-check makes it precise, but Norway was simply never added to the batch-24 nid_bare11 chain and was left as an explicit coverage-vs-precision policy residual — Rolf has now ruled close. KEPT CUE-ONLY (documented, not precisely closable): DK CPR (checksum abolished 2007), EG NID (no portable checksum), PK CNIC / NG NIN (no check digit), passports (no arithmetic checksum), postcodes/ZIP + VAT-without-prefix (structurally ambiguous). ALREADY-BARE hence untouched: DE Steuer-ID (its ISO-7064 MOD 11,10 check is byte-identical to hr_oib, already in nid_bare11), FI HETU / FR NISS / ES NIF / IT CF / CH AHV (distinctive shape), and 8/9-digit schemes (floor-masked by PHONE/SSN). No existing coverage reduced (every branch is OR'd; the length floor is untouched). wasm32-safe (pure integer arithmetic, no regex/lookaround change beyond one \\b\\d{12}\\b literal). v1.4.28 (2026-07-21 batch-41T fair-torture #2 — 1 real gap): DATE_OF_BIRTH cued numeric branch — the French DOB label 'Né(e) le <date>' leaked (batch-41tc id35). The cue was the hardcoded literal 'née? le', which cannot span the PARENTHETICAL gender marker '(e)'. Restructured the cue anchor to: (1) base stems né|née, plus multilingual DOB stems geboren (DE/NL), nacido|nacida (ES), nascido|nascida (PT), f[øo]dd|f[øo]dt (Nordic), born (EN), and Italian nat[oa](?:/a)?\\s+il (precision-anchored on the mandatory Italian filler 'il' so the acronym 'NATO' cannot false-positive on a following date); (2) an OPTIONAL parenthetical gender suffix (?:\\(e\\)|\\(a\\))? handling né(e)/nacido(a)/nascido(a); (3) the existing optional filler word, now extended am|le|el|on|den|il|op|em (adds Dutch 'geboren op', Portuguese 'nascido em', Nordic 'født den'). The numeric date shape and the CUE-as-precision-anchor are UNCHANGED: a bare numeric date with NO DOB cue (invoice/order dates) still does NOT mask. wasm32-safe (literal escaped parens, no lookaround). v1.4.27 (2026-07-21 batch-39T fair-torture #1 — 2 real gaps): (A) PASSPORT/GOVID uncued-repeat (ENGINE pipeline, not a pattern change) — an ES letter-heavy passport (RQH948757; Q ∉ the German-charset bare detector PASSPORT_DE, so only the CUE catches it) leaked at its SECOND, UNCUED mention ('Passport No.: <v> … confirmed <v> again by phone'): PASSPORT_CUED correctly masked the cued occurrence but the bare repeat has no cue and no precision-safe bare detector. Fix is value-consistency repeat masking in tokeniser-core::pipeline (after detection, an EXACT-literal repeat of an ALREADY-confirmed structured-ID value — Ssn/GOVID/CreditCard/Iban/OrgNum/Medical/Biometric, distinctive mixed 6-9 alnum token — is masked with the SAME surrogate). FP-free by construction: an uncued order/ref/SKU code is never detected in the first place, so it is never in the repeat set and stays UNMASKED (precision gate holds). PASSPORT_CUED value shape was ALREADY [A-Z0-9]{6,9} (any 6-9 alnum, any arrangement) — it did not over-constrain; ground-truth analysis showed the leak was the uncued repeat, not the cued value. (B) DATE_OF_BIRTH cued numeric branch gains (1) an OPTIONAL filler word (am/le/el/on/den/il) between the DOB cue and the date — 'geboren am 03/29/1971' (German born-on) leaked because the cue→date gap only allowed [\\s:#.,-]{0,4}, never a word — and (2) a YEAR-first Y-M-D alternative ((?:19|20)\\d{2}[/.-]\\d{1,2}[/.-]\\d{1,2}) so any locale order (D/M/Y, M/D/Y, Y-M-D) cloaks. The CUE stays the precision anchor: a bare numeric date with NO DOB cue (invoice/order dates, incl. M/D/Y day>12) still does NOT mask. wasm32-safe (pure regex, no lookaround). v1.4.26 (2026-07-21 batch-38T postal cue-anchor close): POSTAL — NEW cue-anchored detector POSTAL_CUE_ANCHORED. batch-38T leaked 7 postcodes rendered as 'Postcode: <value>' that POSTAL_CITY_ANCHORED missed because it fires only on a gazetteer-CITY + comma anchor, never on a postcode LABEL. A postcode CUE (post code / postcode / postal code / postleitzahl / plz / zip / zip code / código postal / code postal / cep / pin code) + optional :/# + a postcode-shaped value (reuses the canonical real-shape alternation: numeric NNNN/NNNNN/NNNNNN, spaced NNN NN, hyphenated NNNNN-NNN/NNNNN-NNNN, alnum CA/UK/NL/IE) → cloak. The postcode CUE is the precision anchor (labels are specific, unlike a generic 'Ref:'), so a bare postcode-shaped number with NO cue AND no gazetteer-city still does NOT mask, and a 'Ref: <alnum>' reference number stays UNMASKED. wasm32-safe. v1.4.25 (2026-07-21 batch-35 postal-format + cued-DOB close): (A) POSTAL — POSTAL_CITY_ANCHORED postcode alternation extended to ALL canonical real formats under the SAME gazetteer-city + comma anchor. batch-35 (canonical spec-valid generator) leaked 8 postal: 6 FORMAT-GAPS — spaced-5 ### ## (Sweden/Czech/Slovakia/Greece, e.g. Patras/Brno) and Baltic prefixed LV-#### / LT-##### (Latvia/Lithuania, Daugavpils) — plus 2 CITY-GAZETTEER-MISSES — plain ##### whose format was already covered but whose city (Split, HR) was absent from the ~950-city gazetteer (Split added; major city). New alternation branches: [A-Z]{2}-\\d{4,5} (Baltic prefix), \\d{3} \\d{2} (spaced-5), \\d{3} \\d{3} (India spaced 3+3), [A-Z]\\d{4}[A-Z]{3} (Argentina CPA), \\d{5}-\\d{4} (US ZIP+4), \\d{2}-\\d{3} (Poland). Anchor requirement kept: a bare postcode-shaped run with NO gazetteer-city+comma context still does NOT mask. wasm32-safe (pure regex). (B) DATE_OF_BIRTH — NEW cue-anchored numeric-date branch closing 2 cued-DOB leakers (DOB: ##/##/#### where the day>12 so the existing day-first numeric branch (day 1-31 / month 1-12) correctly rejected month=17/24/…). A DOB CUE (dob/d.o.b/date of birth/birth date/born + multilingual geboren/nee le/nacido/nascido/fodd/fodt) followed within 4 chars by a numeric date in ANY common separator (##/##/#### , ##-##-#### , ##.##.####) -> cloak. The CUE is the precision anchor: the 3 BARE uncued MDY slash-dates (day>12, no cue) stay UNMASKED as deliberate precision residual (invoice/order dates must not over-redact). v1.4.24 (2026-07-21 batch-33 passport+postal close): (A) PASSPORT — NEW cue-anchored detector PASSPORT_CUED. batch-33 normal-draw leaked LABELLED passports whose value was an interleaved synthetic shape (A99A99A99, e.g. 'Passport No.: C36E72T13' labelled DE) that no bare per-country regex (PASSPORT [A-Z]{1,2}\\d{6,9} / PASSPORT_DE restricted-9 / PASSPORT_FR 2d2L5d) covers. A passport/travel-doc cue (multilingual) + number-label or ':'/'#' separator + 6-9 alnum → cloak; the label IS the precision anchor so a bare alnum with no cue stays negative (order codes / SKUs / tracking numbers untouched). Bare contiguous alpha-prefix passports (the ICAO-9303 common family, ~40+ countries: US C+8d, UK-alpha, CA 2L+6d, IN L+7d, JP 2L+7d, IT/AU/CN/ES/ZA/NL/BE/AT…) remain covered by the pre-existing generic PASSPORT + DE + FR detectors; FP-prone bare pure-numeric national formats are intentionally caught only via the cue anchor (zero-FP gate). (B) POSTAL — POSTAL_CITY_ANCHORED postcode group extended from NUMERIC-only to ALPHANUMERIC shapes under the SAME city+comma anchor: Canada A#A #A#, UK outward+inward (incl. loose 2-digit-inward synthetic), Netherlands #### AA, Ireland Eircode A## ####. batch-33 leaked 'London, UR11 43BS' / 'London, UN64 70AJ' (non-conformant synthetic UK that real POSTAL_UK correctly rejects) — the city+comma anchor makes the loose alnum shape precision-safe (a bare alnum postcode with no city context still does NOT mask). wasm32-safe. v1.4.20 (2026-07-21 batch-28d GOVID micro-close): TWO labelled 17-digit national-ID leakers (id13/id43, English context, cue 'FR INSEE') closed cue-anchored on NID_GENERIC_LABELLED. NID_FR_NISS never fired: its 13/15-digit sex-prefix structure with a trailing \\b cannot isolate a 17-digit contiguous run (no internal word boundary), and 'INSEE'/'NIR' was absent from the generic cue set. Added cue synonyms: insee, \\bnir\\b (France INSEE/NIR) — the identified scheme — plus a small enumerated cluster of still-un-labelled numeric national-ID acronyms from the authoritative national-ID list: \\begn\\b (Bulgaria EGN 10d), \\bjmbg\\b (ex-Yugoslavia 13d), \\boib\\b (Croatia 11d), \\bamka\\b (Greece 11d), \\bcnp\\b (Romania 13d). All word-boundaried ASCII acronyms → wasm32-safe (no non-ASCII range) and precision-safe: each fires ONLY before the existing labelled digit tail (\\d(?:[\\s./-]?\\d){4,17}), so a bare 17-digit run with NO national-ID cue does NOT auto-fire (verified: phone/account bare runs stay negative). No checksum claimed — the leaked 17-digit values are not valid real-INSEE (15d mod-97) structure, so a strict checksum gate would re-leak them; cue-anchoring alone is the precision guarantee, per the batch-27 GOVID precedent. v1.4.19 (2026-07-21 batch-27 GOVID+CARD finite close-out): (A) CREDIT_CARD — TWO edge fixes closing 5 leakers. (1) 14-digit contiguous Visa-prefix cards (4539871000XXXX, Luhn-valid) leaked because the branch `4[0-9]{12}(?:[0-9]{3})?` matched only a 13-digit prefix (optional +3 group could not fill), so the 13-char substring failed Luhn and the true 14-digit card was never isolated → changed to `4[0-9]{12,18}` (greedy over the whole contiguous run, Luhn-gated, covers 13–19). (2) Amex written with DOUBLE-space group separators (`3471 928360 54715`, 4-6-5) leaked because each grouped-separator class matched exactly ONE char → the two Amex separators are now `[sep]+`. Both remain Luhn-gated; content-blind over-redaction direction only. (B) GOVID — 16 finite national-ID schemes closed cue-anchored. NID_GENERIC_LABELLED cue set gains: national number (Jordan), QID (Qatar), civil number (Oman), public services number (Armenia), carnet de identidad (Cuba), CUI (Guatemala), NRC (Zambia), SIN number (Canada), numéro d'identification[ national] (Algeria 16-digit + Luxembourg 13-digit); and `cédula` broadened to the full phrase `c[eé]dula(?:\\s*de\\s*identidad)?` so the number within the 10-char cue-gap is reached (Bolivia/Paraguay). NEW type NID_LABELLED_ALNUM_27 for the four LETTER/native-script ID values the digit-only tail cannot capture: Côte d'Ivoire CNI (CI+10digits), Mongolia Register Number (2 non-ASCII letters+8digits, negated-ASCII to stay wasm32-safe), Myanmar NRC (12/MAHALA(N)123456, self-distinctive), Belarus Identification Number (7d+A+3d+2A+d). All cue-anchored/structurally-distinctive → precision-safe; no false checksum claimed (structural format only, no re-verified public spec this run). PLACE closures (Latin endonym superset + non-Latin script gaps) ship as pure-TS in the browser SDK gazetteer (no pattern/WASM change). v1.4.18 (2026-07-21 batch-26 ultra-rare structured close-out): (A) DATE_OF_BIRTH gains a numeric TWO-DIGIT-YEAR dd/mm/yy branch (strict day 1-31 / month 1-12 ranges) — 10 ultra-rare-language records (Kabyle/Lower-Sorbian/Lombard/Samburu/Kabuverdianu/Nigerian-Pidgin/Maasai/Zarma/Teso/Nyankole) rendered the DOB as slash-numeric `05/03/70` which the year=4-digit-only numeric branch missed; day/month range bounds keep FP negligible (ratios/scores/page-refs do not form a valid dd/mm pair). (B) GOVID cue extensions on NID_GENERIC_LABELLED: Korean 주민등록번호/주민번호/등록번호 (bare 13-digit RRN label), Kazakh IIN, Sri Lanka NIC, Gurmukhi ਆਧਾਰ (Aadhaar label in Punjabi script). (C) NEW NID_AL (Albanian letërnjoftim, cue-anchored L+8digit+L). All cue-anchored → precision-safe. v1.4.14 (2026-07-20 batch-22 6-wide close-out): THREE classes. (A) IBAN structural fix — dropped the leading+trailing `\\b` anchors that failed on prose-glued IBANs (Arabic RTL + Latin-label glue, 7-country leak: Egypt×5 incl. Arabic-Indic/Persian digits + Italy + France); mod-97 gate kept for precision (see IBAN pattern note). (B) DATE_OF_BIRTH gains ELEVEN native date-grammar branches for form-classes that leaked (20 leakers): Estonian adessive+nominative DAY.MONTH-YEAR (`6. jaanuaril 1968`, `18. oktoober 1993`), Levantine-Arabic Syriac month names incl. two-word `تشرين الثاني`/`كانون الأول` (`14 أيار 1972`), Turkish YEAR-first genitive `YYYY yılının D <Month>'ında`, Welsh soft-mutated `D o <Fai/Orffennaf> YYYY`, Yoruba `D <Okudu> YYYY`, Zulu `D <Julayi> YYYY`, Kazakh YEAR-first `YYYY жылғы D <month>`, Uzbek YEAR-first `YYYY-yil D-<month>`, Latvian YEAR-first `YYYY. gada D. <month>`, Azerbaijani YEAR-first `YYYY-ci il D <month>`; the existing Georgian branch broadened from nominative-only months to case-tolerant stems (`…აპრილს`/`…ნოემბერს` dative). All anchored on year + day + a specific native month lexicon + grammar marker → precision negatives clean. (C) GOVID — German cue set gains the compound `steueridentifikationsnummer` + `steuernummer` and relaxes to \\d{9,10}; Polish PESEL cue→number gap widened {0,8}→{0,40} for an intervening phrase; Korean RRN trailing `\\b` dropped (Hangul-particle glue defeated the Unicode boundary). v1.4.12 (2026-07-20 batch-18 structured close-out): DATE_OF_BIRTH gains three native date-grammar branches for form-classes that leaked (class-level, not per-leaker): (1) Lithuanian YEAR-first genitive-month grammar `YYYY m. <genitive-month> D d.` (sausio/vasario/kovo/balandžio/gegužės/birželio/liepos/rugpjūčio/rugsėjo/spalio/lapkričio/gruodžio — the whole Lithuanian month set was previously absent; id26 `1986 m. balandžio 5 d.` leaked); (2) Hebrew GREGORIAN-month dates with the agglutinated ב- prefix `D ב<month> YYYY` (the Gregorian Hebrew month words already existed for the day-month-year branch but the glued ב defeated the boundary; id30 `14 באפריל 1986` leaked — distinct from the pre-existing Hebrew-CALENDAR gematria branch, which is preserved); (3) Armenian YEAR-first grammar `YYYY (թվականի|թ.) <genitive-month> D` (the genitive months existed but the year-first թվականի form did not; id36 `1990 թվականի հունիսի 11` leaked). All three anchored on year + specific month lexicon + grammar markers → precision negatives clean (Lithuanian/Hebrew/Armenian prose without a date does not over-match). EMAIL: local-part + domain letter classes extended with the Combining Diacritical Marks range (U+0300–U+036F) so an NFD-decomposed internationalised address (s+caron, o+diaeresis, …) matches identically to its NFC form — full EAI coverage alongside the pre-existing Latin-Extended/Greek/Cyrillic ranges (IDN TLDs incl. .рф/.укр already covered by the Cyrillic range); id33 `oksana.melnyk@pošta-ua.example` (NFC) was already detected by the pattern but leaked on a stale embedded WASM — resolved by this rebuild. v1.4.11 (2026-07-20 batch-17 structured close-out): GOVID inflected-cue audit. NID_IS_KENNITALA cue broadened from the fixed literal \\bkennitala\\b to the Icelandic INFLECTED stem kennit\\w* + abbreviation kt. (the leaking id48 used the base form but the class of inflected forms kennitölu/kennitalan/kennitölunni was uncatchable), and its trailing group relaxed \\d{4}→\\d{3,4} (id48 token 170585-291 had a 3-digit tail). NID_SE_PNR cue gains the definite form personnumret + abbreviations pnr / person-nr. NID_GENERIC_LABELLED: Finnish henkilötunnus→agglutinative stem henkilötunnu\\w* (henkilötunnuksen/-ta), Turkish kimlik→inflected stem kimli[kğ]\\w* (kimliği), plus previously-absent Hungarian (személyi szám / személyazonosító / adóazonosító) and Baltic (asmens kodas / personas kods / isikukood) label cues — all inflection-tolerant. Strict digit-structure suffixes keep FP risk negligible. v1.4.10 (2026-07-20 F20 batch-15 structured close-out): DATE_OF_BIRTH month set gains the Odia phonetic May variant ମଇ (ମେ/ମଇ) that leaked in batch-15, plus the STANDARD May word for Gujarati (મે), Punjabi (ਮਈ), Telugu (మే) and Kannada (ಮೇ) — previously absent though those scripts already carried their other months — inserted into BOTH the DAY-MONTH-YEAR and MONTH-DAY-YEAR alternation groups. v1.4.9 (2026-07-19 F18 batch-13 structured close-out): DATE_OF_BIRTH month set gains Icelandic accented forms (ágúst/janúar/febrúar/júní/júlí/maí/nóvember), Persian variant آگوست/اگست (August), and the full Armenian GENITIVE month series (օգոստոսի/…/դեկտեմբերի, standard in dates) inserted into BOTH the DAY-MONTH-YEAR and MONTH-DAY-YEAR alternation groups; two new native date-grammar branches: Vietnamese numeric (ngày D tháng M năm YYYY) and Sinhala year-first (YYYY <month> මස DD [වැනි] දින). v1.4.7 (2026-07-19 F14 batch-09 structured close-out): DATE_OF_BIRTH month set extended with Slovak genitive (júla/júna/mája…), Finnish nom+partitive+genitive (heinäkuu/heinäkuuta/heinäkuun…), Lao (ກໍລະກົດ…) + Burmese (ဇူລိုင်…) months; ordinal markers gain Iberian .º/.ª/.° and Catalan r (1.º/1r); new Hungarian YEAR-first format branch (1976. július 3.). DATE_OF_BIRTH rebuilt as a format-liberal multilingual grammar — 421 month forms across all EU + Indic-script (Tamil/Telugu/Kannada/Malayalam/Gujarati/Punjabi) + Romanian/Hungarian/Czech/Slovak/Croatian/Catalan/Filipino/Swahili/Persian/Hebrew, expanded ordinal markers (1er/1°/1ª/1º/1./st-nd-rd-th/superscript), a HEBREW-CALENDAR branch (day-gematria + ב + month), and the CJK/era branches. Unicode digit-fold widened to the FULL Nd category (46 scripts incl. Gujarati/Tamil/Telugu/Kannada/Malayalam/NKo/Vai/Adlam/…). GOVID: added NID_CN_RIC (Chinese 18-digit 居民身份证, structural date gating + ISO 7064 MOD 11-2 checksum) and NID_IN_EPIC (voter [A-Z]{3}[0-9]{7}). v1.4.4 (2026-07-19 F10 multilingual class-closing): DATE_OF_BIRTH gains a COMPREHENSIVE month gazetteer (French/Italian/Spanish/Portuguese/German/Dutch/Swedish/Norwegian/Danish/Polish/Turkish/Greek/Arabic + existing EN/uk/ru/hi) and East-Asian ERA dates (JP era + KR); non-ASCII decimal digits (Arabic-Indic/Devanagari/Bengali/Thai) are folded to ASCII at the tokeniser normalize pre-pass so a date/ID/phone in any script is detected. NID_GENERIC_LABELLED gains cues rodne cislo / CCCD / CMND / Aadhaar / NRIC / NIK / CURP / RUT / personnummer / henkilotunnus and allows a slash digit separator. Shared PII detection patterns — used by all CloakAPI engines (Rust, TypeScript, Python). v1.4.3 (2026-07-19 F9 multilingual re-freeze): DATE_OF_BIRTH gains CJK/Korean 年月日/년월일, spelled-month (English/Ukrainian/Russian Cyrillic + Hindi Devanagari) date forms; NID_GENERIC_LABELLED gains per-locale ID cues (CPF, CNPJ, PESEL, TC Kimlik, 身份证[号], DNI, codice fiscale, personnummer) + widened digit run 4–17 (18-digit CN national ID). v1.4.2 (2026-07-19 F2 re-freeze): added NID_GENERIC_LABELLED — a cue-anchored MULTILINGUAL labelled national/personal-ID detector (5–12 digits) — after own-eyes live capture found a labelled `National ID 856214` egressing RAW on every surface (the fasit had only country-specific checksum-anchored NID_* rules, no generic labelled form). v1.4.1 (2026-07-16 Wave-2e re-freeze v3): CREDIT_CARD gains a Luhn-gated general-grouping alternation so a VALID card written in ANY single-separator grouping (5-5-6, dotted, irregular) is detected instead of leaking RAW while the phone matcher steals its tail (D2 content-blind leak).",
4
+ "note": "Token format: <<CLOAK:TYPE:HASH>> — cloud-safe type codes used to avoid AI safety filter triggers",
5
+ "precedence": [
6
+ "EMAIL",
7
+ "NID_US_ITIN",
8
+ "SSN",
9
+ "PERSONNUMMER",
10
+ "CREDIT_CARD",
11
+ "DATE_OF_BIRTH",
12
+ "URL",
13
+ "API_KEY",
14
+ "AUTH_JWT",
15
+ "UK_UTR",
16
+ "IT_PARTITA_IVA",
17
+ "PL_NIP",
18
+ "NID_GENERIC_LABELLED",
19
+ "NID_AL",
20
+ "NID_LABELLED_ALNUM_27",
21
+ "NID_KR_RRN_BARE",
22
+ "NID_CUE_EXT_MULTI",
23
+ "NID_JP_MYNUMBER_KANJI",
24
+ "NID_BE_NRN_LABELLED",
25
+ "NID_AR_CUIT",
26
+ "NID_RU_NID",
27
+ "NID_NO_FNR_LABELLED",
28
+ "NID_NG_NIN",
29
+ "NID_EG_NID",
30
+ "NID_PK_CNIC",
31
+ "NID_CN_RIC_LABELLED",
32
+ "NID_DK_CPR_LABELLED",
33
+ "NID_DK_CPR",
34
+ "NID_SE_PNR",
35
+ "NID_FI_HETU",
36
+ "NID_IS_KENNITALA",
37
+ "NID_FR_NISS",
38
+ "NID_ES_NIF",
39
+ "NID_IT_CF",
40
+ "NID_NL_BSN",
41
+ "NID_PL_PESEL",
42
+ "NID_CA_SIN",
43
+ "NID_NO_DNR",
44
+ "NID_AT_SVNR",
45
+ "NID_BE_NRN",
46
+ "NID_IE_PPS",
47
+ "NID_PT_CC",
48
+ "NID_CH_AHV",
49
+ "NID_JP_MYNUMBER",
50
+ "NID_IN_AADHAAR",
51
+ "NID_IN_PAN",
52
+ "NID_CN_RIC",
53
+ "NID_IN_EPIC",
54
+ "NID_UK_NINO_LABELLED",
55
+ "NID_MX_CURP",
56
+ "NID_CL_RUT",
57
+ "NID_BR_CPF",
58
+ "NID_BR_RG",
59
+ "NID_DE_STEUERID",
60
+ "NID_DE_STEUERNR",
61
+ "NID_PT_NIF",
62
+ "NID_NO_BANKID",
63
+ "NID_MRZ",
64
+ "NID_DRIVER_LICENCE",
65
+ "NID_US_GREENCARD",
66
+ "NID_US_VOTER",
67
+ "NID_US_EIN",
68
+ "NID_DL_UK",
69
+ "PASSPORT_CUED",
70
+ "PASSPORT_DE",
71
+ "PASSPORT_FR",
72
+ "HEALTH_UK_NHS",
73
+ "HEALTH_NO_HELSENUMMER",
74
+ "HEALTH_NO_HPR",
75
+ "HEALTH_US_MEDICARE",
76
+ "HEALTH_DE_VERSICHERT",
77
+ "HEALTH_INSURANCE_NO",
78
+ "HEALTH_ICD10",
79
+ "HEALTH_SNOMED",
80
+ "HEALTH_PRESCRIPTION",
81
+ "HEALTH_LAB_ORDER",
82
+ "ORG_UK_VAT",
83
+ "ORG_EU_VAT",
84
+ "ORG_NO_VAT",
85
+ "ORG_CH_VAT",
86
+ "ORG_AU_ABN",
87
+ "ORG_NO_ORG",
88
+ "ORG_BR_CNPJ",
89
+ "ORG_IN_GSTIN",
90
+ "ORG_CH_UID",
91
+ "ORG_DE_HRB",
92
+ "ORG_DK_CVR",
93
+ "ORG_SE_ORGNR",
94
+ "ORG_FI_YTUNNUS",
95
+ "ORG_NL_KVK",
96
+ "ORG_UK_COMPANIES_HOUSE",
97
+ "FIN_BIC_SWIFT",
98
+ "FIN_ABA_ROUTING",
99
+ "FIN_UK_SORT_ACCOUNT",
100
+ "FIN_NO_ACCOUNT",
101
+ "FIN_NO_KID",
102
+ "FIN_CRYPTO_BTC",
103
+ "FIN_CRYPTO_ETH",
104
+ "FIN_CRYPTO_STABLE",
105
+ "FIN_ACCOUNT_CUED",
106
+ "POSTAL_UK",
107
+ "POSTAL_CA",
108
+ "POSTAL_IE",
109
+ "POSTAL_NL",
110
+ "POSTAL_JP",
111
+ "POSTAL_PT",
112
+ "POSTAL_PL",
113
+ "POSTAL_NO",
114
+ "POSTAL_DE",
115
+ "POSTAL_EU",
116
+ "POSTAL_CUE_ANCHORED",
117
+ "POSTAL_CITY_ANCHORED",
118
+ "NET_MAC",
119
+ "DEVICE_IDFA",
120
+ "DEVICE_GAID",
121
+ "ALIAS_HANDLE",
122
+ "BIO_FINGERPRINT",
123
+ "BIO_IRIS",
124
+ "BIO_GAIT",
125
+ "GPS_COORDS",
126
+ "US_ZIP",
127
+ "IP_ADDRESS",
128
+ "IP_ADDRESS_V6",
129
+ "PASSPORT",
130
+ "IBAN",
131
+ "UK_NINO",
132
+ "MEDICAL_RECORD",
133
+ "ADDRESS",
134
+ "NID_KR_RRN",
135
+ "NID_JP_MYNUMBER_BARE",
136
+ "NID_BE_NRN_BARE",
137
+ "NID_SK_RC",
138
+ "NID_BARE_10",
139
+ "NID_BARE_11",
140
+ "NID_BARE_12",
141
+ "NID_BARE_13",
142
+ "NID_BARE_16",
143
+ "PHONE_CUED",
144
+ "PHONE"
145
+ ],
146
+ "precedence_note": "§44e/§51d ONE-versioned-fasit precedence. Data-driven overlap tie-break for ALL engines: earlier start wins, then longer span, then EARLIER index in this list. Every specific/structured detector (SSN, DATE, cue-anchored national IDs, ZIP, card, IBAN, passport, URL, API_KEY) MUST precede the greedy PHONE bare-run (\\b\\d{10,11}\\b + grouped-digit alternatives), so PHONE is LAST. Adding a detector here + in `types` lights it up in every engine with no code change (the by-construction proof). NER-only types (NAME, ORGANIZATION — null pattern) are excluded.",
147
+ "beats_url": [
148
+ "CONTACT_EM",
149
+ "ID_GOV",
150
+ "FIN_ACCT",
151
+ "FIN_CC"
152
+ ],
153
+ "beats_url_note": "M1/sak 154, 2026-08-09. Kva som vinn over eit OMSLUTTANDE URL-spenn var ei HARDKODA liste i Rust, i TRE motorar uavhengig av kvarandre (R63). EMAIL stod ikkje i nokon av dei, so ei e-postadresse i ein query-streng gjekk raa oppstraums medan verten blei maskert til cloak-masked.invalid - det saag kappa ut. Regelen kan ikkje uttrykkjast med `precedence` aaleine: IBAN og 60 av 61 NID_* ligg ETTER URL der, og aa flytte dei ville endra overlapp-brytinga for alt anna. Difor er han eigen data paa cloud_token_type-aksen: eit treff med ein av desse kategoriane kortar URL-spennet i staden for aa bli slukt av det. Mengda er den gamle hardkoda ({SSN, PERSONNUMMER, CREDIT_CARD, IBAN, UK_NINO, NID_*} = ID_GOV + FIN_ACCT + FIN_CC) PLUSS CONTACT_EM, som var det som mangla.",
154
+ "email_obfuscation": {
155
+ "note": "sak 2044 — obfuskert `@` gjekk RAATT oppstraums i BEGGE motorane (12 av 12 kasus maalt paa binaeret 2026-08-10). EMAIL-regexen kjenner ikkje att adressa naar `@` er koda. Motoren normaliserer difor desse formene til `@` FOER deteksjon, paa ein OFFSET-KARTLAGD kopi, og maskerer det OPPRINNELEGE spennet. Regelen bur her i fasiten, ikkje i Rust — ei hardkoda liste i motoren var nettopp defekten sak 154 fann.",
156
+ "eintydige": [
157
+ "%2540",
158
+ "%40",
159
+ "&#064;",
160
+ "&#64;",
161
+ "&#x40;",
162
+ "&commat;",
163
+ "%28at%29",
164
+ "%5bat%5d",
165
+ "(at)",
166
+ "[at]",
167
+ "{at}",
168
+ "=40"
169
+ ],
170
+ "tvitydige": [
171
+ "%20at%20",
172
+ " at ",
173
+ "+at+"
174
+ ],
175
+ "tvitydig_note": "⛔ Desse er PROSA-tvitydige — «Look at github.com» er ikkje ei adresse. Eit treff som brukar ei tvitydig form blir difor berre godteke naar lokaldelen inneheld eit punktum (`ola.nordmann at firma.no`), som er den forma folk faktisk obfuskerer i. Falske positive er maalte, ikkje anteke.",
176
+ "tvitydig_krev_punktum_i_lokaldel": true,
177
+ "punktum_note": "GB-088 / GB-086, 2026-09-14. Verbal `.`-obfuskering fanst IKKJE i alfabetet, og `obfusk_pass` hadde berre eitt erstatningsmaal (`@`). Målt mot G4-24/25/26 i batch-04 FØR utviding: G4-24 krev « punktum » (space-padded, same form som « at »); G4-25 krev « dot »; G4-26 krev «(punktum)» saman med eksisterande «(at)», med mellomrom-trim rundt bytet so EMAIL-regexen ser ei samanhengande adresse. «(dot)» er parentes-syster til «(at)»/«(punktum)» — same klasse, ikkje eit fjerde G4-tilfelle. Bare «punktum»/«dot» UTAN anker er IKKJE lagde til: dei ville treffe inne i «dotnet»/«punktumet» (målt som risiko, ikkje som treff i G4). Tvitydige `.`-former arvar filter 2 (punktum i lokaldel) frå ` at `; parentes-formene er eintydige som `(at)`.",
178
+ "punktum_eintydige": [
179
+ "(punktum)",
180
+ "(dot)"
181
+ ],
182
+ "punktum_tvitydige": [
183
+ " punktum ",
184
+ " dot "
185
+ ]
186
+ },
187
+ "types": {
188
+ "EMAIL": {
189
+ "code": "EM",
190
+ "cloud_token_type": "CONTACT_EM",
191
+ "pattern": "(?:[a-zA-Z0-9._%+\\-]|[^\\u0000-\\u007F])+@(?:[a-zA-Z0-9.\\-]|[^\\u0000-\\u007F])+\\.(?:[a-zA-Z]|[^\\u0000-\\u007F]){2,}",
192
+ "description": "Email addresses. v1.4.12 (2026-07-20 batch-18): the non-ASCII letter support is now expressed as a NEGATED-ASCII group `[^\\u0000-\\u007F]` (any non-ASCII scalar) rather than explicit `\\uHHHH` ranges. ROOT CAUSE of the id33 leak (`oksana.melnyk@pošta-ua.example`): the regex crate compiled on wasm32 does NOT match a non-ASCII RANGE inside a character class (`[\\u00F8-\\u024F]`) even though native does — so every internationalised address (Latin-Extended/Greek/Cyrillic domain or local-part) had been silently leaking through the browser/desktop WASM engine since the 2026-07-14 EAI extension, while native Rust + JS tests passed. Non-ASCII ALTERNATIONS (the DOB month lexicons) are unaffected, which is why only the class-range email broke. The negated-ASCII group matches identically in native, wasm32, and legacy (non-u) JS RegExp; ASCII spaces still bound the match (space is inside \\u0000-\\u007F), and the `@` + `.TLD{2,}` structure keeps precision. Covers full EAI: non-ASCII local-part + IDN domains incl. Cyrillic .рф/.укр. 2026-07-14 (P4-fix S1): original IDN/non-ASCII letter ranges (Latin-1 Supplement + Latin Extended-A/B, Greek, Cyrillic) so internationalised addresses (mueller@baeckerei.de written with umlauts, contact@aao.example.se) are detected instead of egressing RAW. Ranges use \\uHHHH escapes (letters only, symbols U+00D7/U+00F7 excluded) that compile identically in the Rust regex crate and in legacy (non-u) JS RegExp — the TS surface compiles patterns without the `u` flag, so \\p{L} could not be used.",
193
+ "examples": [
194
+ "john@example.com",
195
+ "jane.doe+tag@company.org",
196
+ "müller@bäckerei.de",
197
+ "contact@åäö.example.se"
198
+ ],
199
+ "synthetic_strategy": "faker_email"
200
+ },
201
+ "PHONE_CUED": {
202
+ "code": "PH",
203
+ "cloud_token_type": "CONTACT_PH",
204
+ "pattern": "(?i)\\b(?:telephone|phone|mobile|cellphone|cell|call|fax|whatsapp|t\\u00e9l\\u00e9phone|tel\\u00e9fono|telefon|telefono|telefoon|m\\u00f3vil|handphone|tel|mob)\\b[\\s:.#\\-]{0,4}(\\d[\\d\\s().\\-]{5,16}\\d)",
205
+ "description": "Cue-anchored NATIONAL-format phone (no +CC). The base PHONE detector matches +CC/00-prefixed and a few bare grouped forms, but MISSES national groupings like IN '12345 67890' (5+5), CL '9 8123 4567' (1+4+4), SG '1234 5678' (4+4) — batch-30a leaks. This closes them precision-safely: it requires a phone cue word (phone/tel/mobile/call/fax/…) and a 7–18-char national number that must NOT start with '+' (so it never overlaps a +CC span already owned by PHONE — zero regression). The cue label is absorbed into the redacted span (negligible over-redaction, same tactic as POSTAL_DE 'PLZ:' / POSTAL_NO 'postnummer:'). Distinct from PHONE so PHONE keeps rank-last (§44e).",
206
+ "examples": [
207
+ "phone: 12345 67890",
208
+ "Mobile: 1234 5678",
209
+ "tel 9 8123 4567"
210
+ ],
211
+ "synthetic_strategy": "faker_phone"
212
+ },
213
+ "PHONE": {
214
+ "code": "PH",
215
+ "cloud_token_type": "CONTACT_PH",
216
+ "pattern": "(?:(?:\\+|00)(?:351|352|353|354|355|356|357|358|359|370|371|372|373|374|375|376|377|378|380|381|382|383|385|386|387|389|420|421|423|880|886|960|961|962|963|964|965|966|967|968|970|971|972|973|974|975|976|977|992|993|994|995|996|998|212|213|216|218|220|221|233|234|251|254|255|256|20|27|30|31|32|33|34|36|39|40|41|43|44|45|46|47|48|49|51|52|53|54|55|56|57|58|60|61|62|63|64|65|66|81|82|84|86|90|91|92|93|94|95|98|1|7)\\s*[\\-.\\s]?(?:\\(?\\d{1,4}\\)?[\\-.\\s]?){1,5}\\d{2,4})|(?:\\(\\d{2,4}\\)\\s*[\\-\\s]?(?:\\d{2,4}[\\-\\s]?){1,4}\\d{2,4})|(?:\\b(?:\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{4}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{4}|\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{4}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{4}|\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{3}|\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{4}|\\d{3}[\\-\\s]\\d{4}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{4}[\\-\\s]\\d{3}|\\d{3}[\\-\\s]\\d{4}[\\-\\s]\\d{4}|\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{4}|\\d{4}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{4}[\\-\\s]\\d{3}[\\-\\s]\\d{3}|\\d{4}[\\-\\s]\\d{3}[\\-\\s]\\d{4}|\\d{4}[\\-\\s]\\d{4}[\\-\\s]\\d{2}|\\d{4}[\\-\\s]\\d{4}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{4}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{4}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{4}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{4}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{4}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{3}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{4}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{4}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{4}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{2}[\\-\\s]\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}|\\d{3}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2}[\\-\\s]\\d{2})\\b)|(?:\\b\\d{2,5}[\\s\\-]\\d{6,8}\\b)|(?:\\b\\d{8}\\b)|(?:\\b\\d{10,11}\\b)",
217
+ "description": "Phone numbers (international formats including Norwegian +47). Tightened 2026-05-26 to require either a country-code prefix, parenthesised area code, dash/space-separated groups, or a 10-11 digit raw run — pure dot-separated digit sequences are NOT phones (they collide with dates 25.05.1999 and malformed IPs). Track-0c batch-2 PHONE-parity audit: added the 2-part national forms (prefix + 6-8 digit tail: DE 0176 1234567, FI 045 1234567, UK 07911 123456) and the bare 8-digit run (Norwegian domestic 99887766) the single intl regex missed vs the gateway's per-country PhoneDe/Fi/Uk/No detectors. v1.4.0 (2026-07-10 WASM-FP-FIX): the intl branch's trunk group is now \\d{1,4} (was \\d{2,4}) over up to 5 groups, so a SINGLE-digit national trunk after the country code — Dutch mobile '+31 6 1234 5678', Stockholm landline '+46 8 123 456' — is captured instead of leaking RAW on the wire (CLIENT-BENCHMARK legal-08/medical-03/customer-service-08 leak class). PHONE stays LAST in precedence (§44e) so these broader runs never steal a span from a structured detector. v1.6.0 (2026-08-10, sak 98B): the grouped branch was \\d{2,4}(?:[-\\s]\\d{2,4}){2,5} — 3–6 groups, 6–24 digits, NO word boundary. It therefore typed account numbers as phones: measured, `Acct 4402-7719-0032` (accountants) and `Acct 7719-4402-0032` (financial-advisors) were the ONLY matching type and resolved to PHONE in the SERVED engine 712c40f8 and the candidate 4650d35e alike — a surrogate of the WRONG CLASS, which is worse than a miss. The branch is now an explicit enumeration of 3–5 groups of 2–4 digits whose TOTAL is ≤ 11 digits — the same ceiling this very pattern already asserts for a bare run (\\b\\d{10,11}\\b) — and is \\b-anchored. Measured on 433 975 lines of real text: 29 lines lost, ALL of them false (ISO timestamps, GPG fingerprints, UUID fragments, card runs already owned by CREDIT_CARD); 0 of the 9 fasit PHONE positives lost.",
218
+ "examples": [
219
+ "+47 912 34 567",
220
+ "+1 (555) 123-4567",
221
+ "020 7946 0958",
222
+ "9854352534",
223
+ "+31 6 1234 5678",
224
+ "+46 8 123 456",
225
+ "+31 6 5555 8899",
226
+ "+46 8 555 123 45"
227
+ ],
228
+ "synthetic_strategy": "faker_phone"
229
+ },
230
+ "SSN": {
231
+ "code": "ID_GOV",
232
+ "cloud_token_type": "ID_GOV",
233
+ "pattern": "(?:\\d{3}-\\d{2}-\\d{4})|(?:\\b\\d{9}\\b)",
234
+ "description": "US Social Security Numbers. 2026-07-14 (P4-fix S4, precision): the bare 9-digit alternative is now \\b-anchored (\\b\\d{9}\\b) so it no longer matches an interior 9-digit fragment of a longer digit run (e.g. a rejected 16-digit card) and mislabels it ID_GOV. A standalone SSN is flanked by non-word chars, so word-boundary anchoring does NOT reduce recall on valid SSNs — only stops the fail-safe fragment nibble on checksum-rejected financial numbers.",
235
+ "examples": [
236
+ "123-45-6789",
237
+ "123456789"
238
+ ],
239
+ "synthetic_strategy": "faker_ssn"
240
+ },
241
+ "PERSONNUMMER": {
242
+ "code": "ID_GOV_NO",
243
+ "cloud_token_type": "ID_GOV",
244
+ "pattern": "(?:0[1-9]|[12]\\d|3[01])(?:0[1-9]|1[0-2])\\d{2}[\\s\\-]?\\d{5}",
245
+ "description": "Norwegian personal identification number (fødselsnummer)",
246
+ "examples": [
247
+ "12046912345",
248
+ "120469 12345"
249
+ ],
250
+ "synthetic_strategy": "faker_personnummer"
251
+ },
252
+ "IBAN": {
253
+ "code": "FIN_IBAN",
254
+ "cloud_token_type": "FIN_ACCT",
255
+ "pattern": "(?i:AD|AE|AL|AO|AT|AZ|BA|BE|BF|BG|BH|BI|BJ|BR|BY|CH|CI|CM|CR|CV|CY|CZ|DE|DJ|DK|DO|DZ|EE|EG|ES|FI|FK|FO|FR|GA|GB|GE|GI|GL|GQ|GR|GT|GW|HN|HR|HU|IE|IL|IQ|IR|IS|IT|JO|KM|KW|KZ|LB|LC|LI|LT|LU|LV|LY|MA|MC|MD|ME|MG|MK|ML|MN|MR|MT|MU|MZ|NE|NI|NL|NO|OM|PK|PL|PS|PT|QA|RO|RS|RU|SA|SC|SD|SE|SI|SK|SM|SN|SO|ST|SV|TD|TG|TL|TN|TR|UA|VA|VG|XK|YE)\\d{2}(?:[ ]?(?:[A-Z]|\\d)){11,30}",
256
+ "description": "International Bank Account Numbers (space-grouped or contiguous). v1.4.14 (batch-22 IBAN structural close-out): the leading+trailing `\\b` word-boundary anchors were REMOVED. ROOT CAUSE of a 7-country leak class (batch-22d Arabic×5 + Italian + French): in the Rust regex crate (and the WASM engine) `\\b` uses UNICODE word-boundary semantics, so an IBAN embedded in prose with NO separating whitespace — glued directly against letters — has NO boundary at its edges and the whole match fails. Arabic RTL prose (`الآيبانEG97…الخاص`, `رقم حسابهاEG38…`, `وحسابهEG88…اليوم`) and Latin labels glued to the code (`IBANIT56…oggi`, `IBANFR12…confirmé`) both defeated the boundary (Arabic letter↔Latin `E`, and Latin `N`↔`I` are both word-char↔word-char = no `\\b`). The Rust regex crate has NO look-around, so the fix is structural: drop `\\b` and rely on the distinctive `[A-Z]{2}\\d{2}` prefix + UPPERCASE `[A-Z0-9]` body (naturally bounded by lowercase letters, spaces, RTL script and punctuation) + the mod-97 checksum gate (kept) for precision — a shape-matching but mod-97-invalid run is still NOT tokenised. Arabic-Indic/Persian digit IBANs (`EG۱6۰3۸…`, `EG٩8٠3٨…`) already fold to ASCII at the normalize pre-pass and were a stale-WASM class resolved by this rebuild. Precision negatives clean: a random uppercase alnum run passes only at ~1/97 and only if 15–34 chars — the safe over-redaction direction for a content-blind gateway. The body char-class `[A-Z0-9]` was replaced with the ALTERNATION `(?:[A-Z]|\\d)` so the unicode `\\d` matches native-script digits (Arabic-Indic U+0660, Persian U+06F0, …) DIRECTLY on the raw text — the batch-22d Arabic-Indic/Persian-digit IBANs (`EG۱6۰3۸…`, `EG٩8٠3٨…`) leaked ONLY on the wasm32 engine because the fold→ASCII pre-pass is unreliable there for a letter-prefixed structured run and the ASCII-only `[A-Z0-9]` body then failed (a class-range would not match on wasm32 either — the documented EAI/wasm32 char-class-range bug; an alternation of `\\d` DOES match). The mod-97 checksum (checksum.rs `mod97_iban`) folds every unicode decimal digit to its value before validating, so a raw non-ASCII-digit IBAN is checksum-gated identically to an ASCII one. v1.4.16 (batch-24 IBAN whole-registry close): batch-24d leaked 7 LOWERCASE IBANs written in prose (`ad710001200012123456789012`, `ba391990440001200279`, `mr13…`, `sc18SSCB…`, `kz86…`, `ua56…`, `gi46GIIB…`) — the uppercase-only `[A-Z]{2}` prefix never matched lowercase codes. Closed by making ONLY the country code case-insensitive via an inline `(?i:…)` group over the FULL ISO 13616 / SWIFT IBAN Registry country-code allowlist (~110 codes incl. experimental) — the BODY stays uppercase+`\\d` case-SENSITIVE, which is essential: it is what naturally bounds the run against lowercase prose (the batch-22 `IBANFR12…confirmé` glue class). A global `(?i)` was tried and REVERTED because it made the body eat trailing lowercase words (`…189confirmé`) → mod-97 fail → re-leak of the batch-22 class. Net: lowercase country codes now match (`ad71…`, `sc18SSCB…`, `kz86…`), the registry allowlist means a random glued `xx\\d\\d…` run no longer even starts a match (precision gain), every registry country validates, and no per-country length gate (batch-24 synthetics AD/UA carried non-registry lengths yet are mod-97-valid → recall-first, cloak them). RESIDUAL: a fully-lowercased IBAN whose BBAN contains lowercase LETTERS (e.g. `gb29nwbk…`) still misses — real IBANs and the batch-24 synthetics keep BBAN letters uppercase; documented, not observed.",
257
+ "examples": [
258
+ "GB29NWBK60161331926819",
259
+ "GB29 NWBK 6016 1331 9268 19",
260
+ "NO9386011117947"
261
+ ],
262
+ "checksum": "mod97",
263
+ "synthetic_strategy": "faker_iban"
264
+ },
265
+ "CREDIT_CARD": {
266
+ "code": "FIN_CC",
267
+ "cloud_token_type": "FIN_CC",
268
+ "pattern": "(?:(?:4[0-9]{3}|5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720|6(?:011|5[0-9]{2})|35[0-9]{2})[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027][0-9]{4}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027][0-9]{4}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027][0-9]{4}|3[47][0-9]{2}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027]+[0-9]{6}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027]+[0-9]{5}|4[0-9]{12,18}|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\\d{3})\\d{11}|62[0-9]{2}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027][0-9]{4}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027][0-9]{4}[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027][0-9]{4}|62[0-9]{14,17}|\\b[0-9](?:[ \\-.\\u00A0\\u2010-\\u2015\\u2212\\u00B7\\u2027]?[0-9]){12,18}\\b)",
269
+ "description": "Credit card numbers (Visa, MC, Amex, Discover, JCB, UnionPay 62… BIN — batch-1 §Track-0c). Grouped 4-4-4-4 and Amex 4-6-5 forms accept space/hyphen/dot/NBSP/unicode-dash/middot separators (parity with packages/pii-engine/src/patterns.rs credit_card). Track-0c batch-2: Luhn-validated — a shape-matching but Luhn-invalid run is not tokenised as a card. Wave-2e v1.4.1 (D2 re-freeze): a final \\b-anchored GENERAL alternation matches ANY 13–19 digit run with arbitrary SINGLE separators (space/hyphen/dot/NBSP/unicode-dash/middot/·/‧) between digits, so irregular groupings — 5-5-6 (`41111 11111 111111`), dotted, mixed — are captured instead of leaking their tail to PHONE. The general run is STILL Luhn-gated by `checksum:\"luhn\"`, so a non-Luhn run (e.g. 5555 4444 3333 2222 in any grouping, or a Luhn-failing 16-digit order number) is NOT tokenised. The \\b anchors prevent carving a card out of a longer alnum token (e.g. an IBAN's digit tail preceded by a letter). DESIGN TRADEOFF: a random Luhn-valid non-card 13–19 digit number (~10% of such runs) may over-tokenise — for a content-blind privacy gateway that is the SAFE failure direction (never leak a real card), consistent with the engine's Luhn-arbitration philosophy.",
270
+ "examples": [
271
+ "4111111111111111",
272
+ "5500005555555559"
273
+ ],
274
+ "checksum": "luhn",
275
+ "synthetic_strategy": "faker_credit_card"
276
+ },
277
+ "IP_ADDRESS": {
278
+ "code": "NET_IP",
279
+ "cloud_token_type": "NET_IP",
280
+ "pattern": "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
281
+ "description": "IPv4 addresses",
282
+ "examples": [
283
+ "192.168.1.100",
284
+ "10.0.0.1"
285
+ ],
286
+ "synthetic_strategy": "faker_ip"
287
+ },
288
+ "IP_ADDRESS_V6": {
289
+ "code": "NET_IP6",
290
+ "cloud_token_type": "NET_IP",
291
+ "pattern": "(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|:(?::[0-9a-fA-F]{1,4}){1,7}",
292
+ "description": "IPv6 addresses. Tightened 2026-07-05: the old `(?:x:)*:(?:x:)*x` compressed branch matched any single-colon fragment (`:4` in 'ratio 3:4', `:30` in 'time 10:30'); compressed forms now require a real `::` (or 8 full groups), and value-capturing alternatives precede the trailing-`::` forms so a full address like 2001:db8::1 is captured whole.",
293
+ "examples": [
294
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
295
+ ],
296
+ "synthetic_strategy": "faker_ipv6"
297
+ },
298
+ "DATE_OF_BIRTH": {
299
+ "code": "PII_DOB",
300
+ "cloud_token_type": "PII_DOB",
301
+ "pattern": "(?i)\\b(?:d\\.?o\\.?b\\.?|date of birth|birth date|née|né|nat[oa](?:/a)?\\s+il|geboren|nacido|nacida|nascido|nascida|f[øo]dd|f[øo]dt|born)(?:\\(e\\)|\\(a\\))?(?:\\s+(?:am|le|el|on|den|il|op|em))?[\\s:#.,\\-]{0,4}\\d{1,2}[/\\-.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D]\\d{1,2}[/\\-.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D]\\d{2,4}|\\d{1,2}\\.\\s*(?:jaanuaril|veebruaril|märtsil|aprillil|mail|juunil|juulil|augustil|septembril|oktoobril|novembril|detsembril|jaanuar|veebruar|märts|aprill|mai|juuni|juuli|august|september|oktoober|november|detsember)\\s+(?:19|20|21)\\d{2}|\\d{1,2}\\s+(?:كانون الثاني|كانون الأول|تشرين الأول|تشرين الثاني|شباط|آذار|نيسان|أيار|حزيران|تموز|آب|أيلول)\\s+(?:19|20|21)\\d{2}|(?:19|20|21)\\d{2}\\s+yıl\\w*\\s+\\d{1,2}\\s+(?:ocak|şubat|mart|nisan|mayıs|mayis|haziran|temmuz|ağustos|agustos|eylül|eylul|ekim|kasım|kasim|aralık|aralik)(?:['’‘][a-zçğıiöşü]*)?|\\d{1,2}\\s+o\\s+(?:ionawr|chwefror|mawrth|fawrth|ebrill|mai|fai|mehefin|fehefin|gorffennaf|orffennaf|awst|medi|fedi|hydref|tachwedd|dachwedd|rhagfyr|ragfyr)\\s+(?:19|20|21)\\d{2}|\\d{1,2}\\s+(?:ṣẹrẹ|ṣẹ́rẹ́|erele|èrèlè|erena|ẹrẹ̀nà|igbe|ìgbé|ebibi|ẹ̀bibi|okudu|òkúdù|agemo|agẹmọ|ogun|ògún|owewe|owara|ọ̀wàrà|belu|bélú|ope|ọ̀pẹ̀)\\s+(?:19|20|21)\\d{2}|\\d{1,2}\\s+(?:januwari|februwari|mashi|ephreli|meyi|juni|julayi|agasti|septhemba|okthoba|novemba|disemba)\\s+(?:19|20|21)\\d{2}|(?:19|20|21)\\d{2}\\s+жыл\\w*\\s+\\d{1,2}\\s+(?:қаңтар|ақпан|наурыз|сәуір|мамыр|маусым|шілде|тамыз|қыркүйек|қазан|қараша|желтоқсан)\\w*|(?:19|20|21)\\d{2}[-\\s]yil\\w*\\s+\\d{1,2}[-\\s](?:yanvar|fevral|mart|aprel|may|iyun|iyul|avgust|sentyabr|oktyabr|noyabr|dekabr)|(?:19|20|21)\\d{2}\\.\\s*gada\\s+\\d{1,2}\\.\\s*(?:janvār|februār|mart|aprīl|maij|jūnij|jūlij|august|septembr|oktobr|novembr|decembr)\\w*|(?:19|20|21)\\d{2}-c[iı]\\s+il\\s+\\d{1,2}\\s+(?:yanvar|fevral|mart|aprel|may|iyun|iyul|avqust|sentyabr|oktyabr|noyabr|dekabr)\\w*|(?:19|20|21)\\d{2}\\s+m\\.?\\s+(?:sausio|vasario|kovo|balandžio|gegužės|birželio|liepos|rugpjūčio|rugsėjo|spalio|lapkričio|gruodžio)\\s+\\d{1,2}\\s*d\\.?|\\d{1,2}\\s+ב?(?:ינואר|פברואר|מרץ|אפריל|מאי|יוני|יולי|אוגוסט|ספטמבר|אוקטובר|נובמבר|דצמבר)\\s+(?:19|20|21)\\d{2}|(?:19|20|21)\\d{2}\\s+(?:թվականի|թ\\.)\\s+(?:հունվարի|փետրվարի|մարտի|ապրիլի|մայիսի|հունիսի|հուլիսի|օգոստոսի|սեպտեմբերի|հոկտեմբերի|նոյեմբերի|դեկտեմբերի)\\s+\\d{1,2}|(?:19|20|21)\\d{2}\\s*წლის\\s*\\d{1,2}\\s*(?:იანვარ|თებერვალ|მარტ|აპრილ|მაის|ივნის|ივლის|აგვისტო|სექტემბერ|ოქტომბერ|ნოემბერ|დეკემბერ)(?:ი|ს|ში)?|\\d{1,4}\\s*ခုနှစ်\\s*(?:ဇန်နဝါရီ|ဖေဖော်ဝါရီ|မတ်|ဧပြီ|မေ|ဇွန်|ဇူလိုင်|ဩဂုတ်|စက်တင်ဘာ|အောက်တိုဘာ|နိုဝင်ဘာ|ဒီဇင်ဘာ)\\s*လ?\\s*\\d{1,2}\\s*ရက်|(?:19|20|21)\\d{2}\\s*[年년]\\s*\\d{1,2}\\s*[月월]\\s*\\d{1,2}\\s*[日일]|(?:昭和|平成|令和|大正|明治|단기|대한)\\s*\\d{1,4}\\s*[年년](?:\\s*\\d{1,2}\\s*[月월](?:\\s*\\d{1,2}\\s*[日일])?)?|(?:19|20|21)\\d{2}\\.\\s+(?:január|február|március|április|május|június|július|augusztus|szeptember|október|november|december)\\s+\\d{1,2}\\.?|(?:19|20|21)\\d{2}\\s+(?:ජනවාරි|පෙබරවාරි|මාර්තු|අප්රේල්|මැයි|ජූනි|ජූලි|අගෝස්තු|සැප්තැම්බර්|ඔක්තෝබර්|නොවැම්බර්|දෙසැම්බර්)\\s+මස\\s+\\d{1,2}(?:\\s+වැනි)?\\s+දින|(?:ngày\\s+)?\\d{1,2}\\s+tháng\\s+\\d{1,2}\\s+năm\\s+\\d{3,4}|\\d{1,2}(?:\\.º|\\.ª|\\.°|\\.|º|ª|°|er|ère|ere|ème|eme|ᵉ|st|nd|rd|th|r)?(?:\\s+(?:de|del|di|den|of|van)\\s+|[.,]?\\s+)(?:ágúst|janúar|febrúar|júní|júlí|maí|nóvember|آگوست|اگست|օգոստոսի|հունվարի|փետրվարի|մարտի|ապրիլի|մայիսի|հունիսի|հուլիսի|սեպտեմբերի|հոկտեմբերի|նոյեմբերի|դեկտեմբերի|සැප්තැම්බර්|ସେପ୍ଟେମ୍ବର|სექტემბერი|ოქტომბერი|දෙසැම්බර්|დეკემბერი|නොවැම්බර්|սեպտեմբեր|դեկտեմբեր|հոկտեմբեր|თებერვალი|ଫେବ୍ରୁଆରୀ|វិច្ឆិកា|նոյեմբեր|ଡିସେମ୍ବର|පෙබරවාරි|ඔක්තෝබර්|ნოემბერი|ଜାନୁଆରୀ|հունվար|අගෝස්තු|օգոստոս|փետրվար|අප්රේල්|აგვისტო|ନଭେମ୍ବର|ଅକ୍ଟୋବର|ମାର୍ଚ୍ଚ|იანვარი|ሴፕቴምበር|ივნისი|հուլիս|កក្កដា|ଅପ୍ରେଲ|ජනවාරි|հունիս|កុម្ភៈ|აპრილი|ივლისი|මාර්තු|មិថុនា|մայիս|ኖቬምበር|ኦክቶበር|መስከረም|កញ្ញា|მარტი|ፌብሩዋሪ|მაისი|ଜୁଲାଇ|ଅଗଷ୍ଟ|ապրիլ|ዲሴምበር|មករា|ឧសភា|មេសា|ሚያዝያ|ታኅሣሥ|ኦገስት|ጃንዋሪ|መጋቢት|የካቲት|ජූනි|ජූලි|ធ្នូ|մարտ|ግንቦት|ኤፕሪል|ጳጉሜን|តុលា|මැයි|សីហា|មីនា|ጥቅምት|ጁላይ|ሐምሌ|ଜୁନ|ኅዳር|ነሐሴ|ማርች|ሜይ|ሰኔ|ጥር|ମେ|ମଇ|મે|ਮਈ|మే|ಮೇ|ጁን|pazdziernika|października|σεπτεμβρίου|φεβρουαρίου|ফেব্রুয়ারি|maaliskuuta|marraskuuta|februárius|septembrie|septiembre|szeptember|δεκεμβρίου|ιανουαρίου|সেপ্টেম্বর|செப்டம்பர்|సెప్టెంబర్|ಸೆಪ್ಟೆಂಬರ್|സെപ്റ്റംബർ|กุมภาพันธ์|tammikuuta|helmikuuta|maaliskuun|huhtikuuta|toukokuuta|heinäkuuta|marraskuun|joulukuuta|ဖေဖော်ဝါရီ|အောက်တိုဘာ|augusztus|decembrie|diciembre|disyembre|februarie|fevereiro|listopada|listopadu|nobyembre|noiembrie|noviembre|octombrie|september|septembre|setiembre|settembre|setyembre|αυγούστου|νοεμβρίου|οκτωβρίου|листопада|জানুয়ারি|જાન્યુઆરી|ફેબ્રુઆરી|સપ્ટેમ્બર|ഫെബ്രുവരി|พฤศจิกายน|septembra|tammikuun|helmikuun|maaliskuu|huhtikuun|toukokuun|kesäkuuta|heinäkuun|syyskuuta|lokakuuta|marraskuu|joulukuun|augustus|december|decembre|desember|desembre|dezember|dezembro|dicembre|disember|décembre|febbraio|februari|february|ianuarie|kolovoza|kwietnia|listopad|november|novembre|novembro|prosinac|prosinca|prosince|prosinec|septemba|setembre|setembro|sierpnia|siječanj|siječnja|studenog|stycznia|wrzesnia|września|července|červenec|απριλίου|сентября|اردیبهشت|ডিসেম্বর|ડિસેમ્બર|அக்டோபர்|டிசம்பர்|பிப்ரவரி|అక్టోబర్|డిసెంబర్|ఫిబ్రవరి|ಅಕ್ಟೋಬರ್|ಡಿಸೆಂಬರ್|ಫೆಬ್ರವರಿ|ഓഗസ്റ്റ്|มิถุนายน|februára|novembra|decembra|tammikuu|helmikuu|huhtikuu|toukokuu|kesäkuun|heinäkuu|elokuuta|syyskuun|lokakuun|joulukuu|ဇန်နဝါရီ|စက်တင်ဘာ|နိုဝင်ဘာ|agustos|aprilie|augusti|ağustos|czerwca|desemba|febrero|februar|február|fevrier|février|gennaio|grudnia|haziran|janeiro|januari|january|janvier|juillet|kolovoz|március|novemba|october|octobre|octubre|oktober|oktubre|október|ottobre|outubro|pebrero|studeni|svibanj|svibnja|travanj|travnja|veljača|veljače|április|ιουλίου|ιουνίου|μαρτίου|августа|березня|вересня|декабря|октября|февраля|אוקטובר|سپتامبر|فروردین|अक्टूबर|अक्तूबर|सितम्बर|অক্টোবর|নভেম্বর|ઓક્ટોબર|નવેમ્બર|நவம்பர்|ఏప్రిల్|ಏಪ್ರಿಲ್|ನವೆಂಬರ್|ഒക്ടോബർ|മാർച്ച്|กรกฎาคม|กันยายน|ธันวาคม|พฤษภาคม|สิงหาคม|januára|augusta|októbra|kesäkuu|elokuun|syyskuu|lokakuu|ພຶດສະພາ|ກໍລະກົດ|ဇူလိုင်|ဒီဇင်ဘာ|agosti|agosto|aprile|aprili|aralik|aralık|august|březen|března|febrer|giugno|januar|január|juliol|július|június|květen|května|lipanj|lipnja|luglio|lutego|maggio|martie|oktoba|ožujak|ožujka|srpanj|srpnja|temmuz|červen|června|апреля|грудня|жовтня|квітня|лютого|ноября|серпня|травня|червня|января|אוגוסט|נובמבר|ספטמבר|פברואר|أكتوبر|اكتوبر|دسامبر|ديسمبر|سبتمبر|شهریور|فبراير|نوامبر|نوفمبر|ژانویه|अप्रैल|दिसंबर|फ़रवरी|सितंबर|এপ্রিল|ਅਕਤੂਬਰ|ਅਪ੍ਰੈਲ|ਫ਼ਰਵਰੀ|એપ્રિલ|ஆகஸ்ட்|ஏப்ரல்|மார்ச்|ఆగస్టు|నవంబర్|మార్చి|ಆಗಸ್ಟ್|ಮಾರ್ಚ್|ഏപ്രിൽ|ജനുവരി|ഡിസംബർ|ตุลาคม|มกราคม|มีนาคม|เมษายน|apríla|elokuu|ມັງກອນ|ມິຖຸນາ|abril|agost|april|apríl|avril|duben|dubna|enero|eylul|eylül|gener|hulyo|hunyo|iulie|iunie|julai|julho|julio|junho|junio|kasim|kasım|leden|ledna|lipca|maart|machi|marca|march|marco|marec|maret|marso|marts|marzo|março|mayis|mayıs|május|nisan|rujan|rujna|srpen|srpna|subat|února|říjen|října|şubat|μάιος|μαΐου|липня|марта|січня|אפריל|דצמבר|ינואר|آوریل|أبريل|أغسطس|ابريل|اسفند|اغسطس|اکتبر|خرداد|فوریه|مرداد|يناير|يوليو|يونيو|ژوئیه|अगस्त|जनवरी|जुलाई|नवंबर|फरवरी|मार्च|আগস্ট|জুলাই|মার্চ|ਜਨਵਰੀ|ਜੁਲਾਈ|ਦਸੰਬਰ|ਨਵੰਬਰ|ਸਤੰਬਰ|ઓગસ્ટ|જુલાઈ|માર્ચ|ஜனவரி|జనవరి|ಜನವರಿ|നവംബർ|ກຸມພາ|ສິງຫາ|ກັນຍາ|ພະຈິກ|ທັນວາ|ဩဂုတ်|aout|août|ekim|febr|juin|july|june|juli|juni|juny|maig|maio|maja|mars|mart|marz|març|mayo|märz|ocak|ogos|sept|září|únor|μάης|июля|июня|יולי|יוני|آبان|بهمن|مارس|مايو|ژوئن|ਅਗਸਤ|ਮਾਰਚ|ஜூன்|ஜூலை|జూన్|జూలై|ಜುಲೈ|ಜೂನ್|ജൂലൈ|മേയ്|mája|júna|júla|ມີນາ|ເມສາ|ຕຸລາ|ဧပြီ|ဇွန်|apr|aug|dec|feb|ian|iul|iun|jan|jul|jun|júl|jún|mac|mai|maj|mar|may|mei|máj|noi|nov|oct|sep|май|мая|מאי|מרץ|آذر|اوت|تیر|مهر|जून|জুন|ਜੂਨ|જૂન|ജൂൺ|မတ်|دی|مه|मई|মে|மே|မေ)(?:\\s+(?:de|del|di|den|of|van)\\s+|[.,]?\\s+)\\d{3,4}|(?:ágúst|janúar|febrúar|júní|júlí|maí|nóvember|آگوست|اگست|օգոստոսի|հունվարի|փետրվարի|մարտի|ապրիլի|մայիսի|հունիսի|հուլիսի|սեպտեմբերի|հոկտեմբերի|նոյեմբերի|դեկտեմբերի|සැප්තැම්බර්|ସେପ୍ଟେମ୍ବର|სექტემბერი|ოქტომბერი|දෙසැම්බර්|დეკემბერი|නොවැම්බර්|սեպտեմբեր|դեկտեմբեր|հոկտեմբեր|თებერვალი|ଫେବ୍ରୁଆରୀ|វិច្ឆិកា|նոյեմբեր|ଡିସେମ୍ବର|පෙබරවාරි|ඔක්තෝබර්|ნოემბერი|ଜାନୁଆରୀ|հունվար|අගෝස්තු|օգոստոս|փետրվար|අප්රේල්|აგვისტო|ନଭେମ୍ବର|ଅକ୍ଟୋବର|ମାର୍ଚ୍ଚ|იანვარი|ሴፕቴምበር|ივნისი|հուլիս|កក្កដា|ଅପ୍ରେଲ|ජනවාරි|հունիս|កុម្ភៈ|აპრილი|ივლისი|මාර්තු|មិថុនា|մայիս|ኖቬምበር|ኦክቶበር|መስከረም|កញ្ញា|მარტი|ፌብሩዋሪ|მაისი|ଜୁଲାଇ|ଅଗଷ୍ଟ|ապրիլ|ዲሴምበር|មករា|ឧសភា|មេសា|ሚያዝያ|ታኅሣሥ|ኦገስት|ጃንዋሪ|መጋቢት|የካቲት|ජූනි|ජූලි|ធ្នូ|մարտ|ግንቦት|ኤፕሪል|ጳጉሜን|តុលា|මැයි|សីហា|មីនា|ጥቅምት|ጁላይ|ሐምሌ|ଜୁନ|ኅዳር|ነሐሴ|ማርች|ሜይ|ሰኔ|ጥር|ମେ|ମଇ|મે|ਮਈ|మే|ಮೇ|ጁን|pazdziernika|października|σεπτεμβρίου|φεβρουαρίου|ফেব্রুয়ারি|maaliskuuta|marraskuuta|februárius|septembrie|septiembre|szeptember|δεκεμβρίου|ιανουαρίου|সেপ্টেম্বর|செப்டம்பர்|సెప్టెంబర్|ಸೆಪ್ಟೆಂಬರ್|സെപ്റ്റംബർ|กุมภาพันธ์|tammikuuta|helmikuuta|maaliskuun|huhtikuuta|toukokuuta|heinäkuuta|marraskuun|joulukuuta|ဖေဖော်ဝါရီ|အောက်တိုဘာ|augusztus|decembrie|diciembre|disyembre|februarie|fevereiro|listopada|listopadu|nobyembre|noiembrie|noviembre|octombrie|september|septembre|setiembre|settembre|setyembre|αυγούστου|νοεμβρίου|οκτωβρίου|листопада|জানুয়ারি|જાન્યુઆરી|ફેબ્રુઆરી|સપ્ટેમ્બર|ഫെബ്രുവരി|พฤศจิกายน|septembra|tammikuun|helmikuun|maaliskuu|huhtikuun|toukokuun|kesäkuuta|heinäkuun|syyskuuta|lokakuuta|marraskuu|joulukuun|augustus|december|decembre|desember|desembre|dezember|dezembro|dicembre|disember|décembre|febbraio|februari|february|ianuarie|kolovoza|kwietnia|listopad|november|novembre|novembro|prosinac|prosinca|prosince|prosinec|septemba|setembre|setembro|sierpnia|siječanj|siječnja|studenog|stycznia|wrzesnia|września|července|červenec|απριλίου|сентября|اردیبهشت|ডিসেম্বর|ડિસેમ્બર|அக்டோபர்|டிசம்பர்|பிப்ரவரி|అక్టోబర్|డిసెంబర్|ఫిబ్రవరి|ಅಕ್ಟೋಬರ್|ಡಿಸೆಂಬರ್|ಫೆಬ್ರವರಿ|ഓഗസ്റ്റ്|มิถุนายน|februára|novembra|decembra|tammikuu|helmikuu|huhtikuu|toukokuu|kesäkuun|heinäkuu|elokuuta|syyskuun|lokakuun|joulukuu|ဇန်နဝါရီ|စက်တင်ဘာ|နိုဝင်ဘာ|agustos|aprilie|augusti|ağustos|czerwca|desemba|febrero|februar|február|fevrier|février|gennaio|grudnia|haziran|janeiro|januari|january|janvier|juillet|kolovoz|március|novemba|october|octobre|octubre|oktober|oktubre|október|ottobre|outubro|pebrero|studeni|svibanj|svibnja|travanj|travnja|veljača|veljače|április|ιουλίου|ιουνίου|μαρτίου|августа|березня|вересня|декабря|октября|февраля|אוקטובר|سپتامبر|فروردین|अक्टूबर|अक्तूबर|सितम्बर|অক্টোবর|নভেম্বর|ઓક્ટોબર|નવેમ્બર|நவம்பர்|ఏప్రిల్|ಏಪ್ರಿಲ್|ನವೆಂಬರ್|ഒക്ടോബർ|മാർച്ച്|กรกฎาคม|กันยายน|ธันวาคม|พฤษภาคม|สิงหาคม|januára|augusta|októbra|kesäkuu|elokuun|syyskuu|lokakuu|ພຶດສະພາ|ກໍລະກົດ|ဇူလိုင်|ဒီဇင်ဘာ|agosti|agosto|aprile|aprili|aralik|aralık|august|březen|března|febrer|giugno|januar|január|juliol|július|június|květen|května|lipanj|lipnja|luglio|lutego|maggio|martie|oktoba|ožujak|ožujka|srpanj|srpnja|temmuz|červen|června|апреля|грудня|жовтня|квітня|лютого|ноября|серпня|травня|червня|января|אוגוסט|נובמבר|ספטמבר|פברואר|أكتوبر|اكتوبر|دسامبر|ديسمبر|سبتمبر|شهریور|فبراير|نوامبر|نوفمبر|ژانویه|अप्रैल|दिसंबर|फ़रवरी|सितंबर|এপ্রিল|ਅਕਤੂਬਰ|ਅਪ੍ਰੈਲ|ਫ਼ਰਵਰੀ|એપ્રિલ|ஆகஸ்ட்|ஏப்ரல்|மார்ச்|ఆగస్టు|నవంబర్|మార్చి|ಆಗಸ್ಟ್|ಮಾರ್ಚ್|ഏപ്രിൽ|ജനുവരി|ഡിസംബർ|ตุลาคม|มกราคม|มีนาคม|เมษายน|apríla|elokuu|ມັງກອນ|ມິຖຸນາ|abril|agost|april|apríl|avril|duben|dubna|enero|eylul|eylül|gener|hulyo|hunyo|iulie|iunie|julai|julho|julio|junho|junio|kasim|kasım|leden|ledna|lipca|maart|machi|marca|march|marco|marec|maret|marso|marts|marzo|março|mayis|mayıs|május|nisan|rujan|rujna|srpen|srpna|subat|února|říjen|října|şubat|μάιος|μαΐου|липня|марта|січня|אפריל|דצמבר|ינואר|آوریل|أبريل|أغسطس|ابريل|اسفند|اغسطس|اکتبر|خرداد|فوریه|مرداد|يناير|يوليو|يونيو|ژوئیه|अगस्त|जनवरी|जुलाई|नवंबर|फरवरी|मार्च|আগস্ট|জুলাই|মার্চ|ਜਨਵਰੀ|ਜੁਲਾਈ|ਦਸੰਬਰ|ਨਵੰਬਰ|ਸਤੰਬਰ|ઓગસ્ટ|જુલાઈ|માર્ચ|ஜனவரி|జనవరి|ಜನವರಿ|നവംബർ|ກຸມພາ|ສິງຫາ|ກັນຍາ|ພະຈິກ|ທັນວາ|ဩဂုတ်|aout|août|ekim|febr|juin|july|june|juli|juni|juny|maig|maio|maja|mars|mart|marz|març|mayo|märz|ocak|ogos|sept|září|únor|μάης|июля|июня|יולי|יוני|آبان|بهمن|مارس|مايو|ژوئن|ਅਗਸਤ|ਮਾਰਚ|ஜூன்|ஜூலை|జూన్|జూలై|ಜುಲೈ|ಜೂನ್|ജൂലൈ|മേയ്|mája|júna|júla|ມີນາ|ເມສາ|ຕຸລາ|ဧပြီ|ဇွန်|apr|aug|dec|feb|ian|iul|iun|jan|jul|jun|júl|jún|mac|mai|maj|mar|may|mei|máj|noi|nov|oct|sep|май|мая|מאי|מרץ|آذر|اوت|تیر|مهر|जून|জুন|ਜੂਨ|જૂન|ജൂൺ|မတ်|دی|مه|मई|মে|மே|မေ)\\.?\\s+\\d{1,2}(?:st|nd|rd|th)?,?\\s+\\d{3,4}|(?:[א-ת]{1,3}(?:[״\"׳\\'])[א-ת]?|\\d{1,2})\\s+ב?(?:מרחשוון|חשוון|כסליו|סיוון|תשרי|כסלו|ניסן|אייר|תמוז|אלול|חשון|טבת|שבט|אדר|סיון|אב)(?:\\s+(?:ה?ת(?:ש|ר|ק)[א-ת״\"]{1,4}))?|(?:(?:3[01]|[12][0-9]|0?[1-9])[/\\-\\.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D](?:1[0-2]|0?[1-9])[/\\-\\.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D](?:19|20|21)\\d{2})|(?:\\d{4}[/\\-\\.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D](?:1[0-2]|0?[1-9])[/\\-\\.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D](?:3[01]|[12][0-9]|0?[1-9]))|\\d{1,2}\\s+(?:am\\s+|an\\s+t-|an\\s+|dhen\\s+t-|dhen\\s+)?(?:faoilleach|fhaoilleach|gearran|ghearran|màrt|mhàrt|giblean|ghiblean|cèitean|chèitean|ògmhios|iuchar|lùnastal|sultain|dàmhair|samhain|dùbhlachd)[,.]?\\s+(?:19|20|21)\\d{2}|\\d{1,2}\\s+sánzá\\s+ya\\s+\\S+[,.]?\\s+(?:19|20|21)\\d{2}|(?:19|20|21)\\d{2}[,.]?\\s+sánzá\\s+ya\\s+\\S+[,.]?\\s+mokolo\\s+ya\\s+\\d{1,2}|\\d{1,2}\\s+(?:кулун\\s+тутар|муус\\s+устар|ыам\\s+ыйа|бэс\\s+ыйа|от\\s+ыйа|атырдьых\\s+ыйа|балаҕан\\s+ыйа|тохсунньу|олунньу|алтынньы|сэтинньи|ахсынньы)[,.]?\\s+(?:19|20|21)\\d{2}|(?:(?:3[01]|[12][0-9]|0?[1-9])[/\\-.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D](?:1[0-2]|0?[1-9])[/\\-.\\u2010-\\u2015\\u2212\\u058A\\u05BE\\u1400\\u1806\\u2E17\\u2E1A\\u2E3A\\u2E3B\\u2E40\\u2E5D\\u301C\\u3030\\u30A0\\uFE31\\uFE32\\uFE58\\uFE63\\uFF0D](?:(?:19|20|21)\\d{2}|\\d{4}|\\d{2}))",
302
+ "description": "Date of birth patterns. Fixed 2026-07-05: alternations reordered longest-first so an ISO-format day (the last component, e.g. the 31 in 1990-12-31) is no longer truncated to a single digit (`0?[1-9]` previously won before `[12][0-9]|3[01]` with no trailing anchor, leaking the second day digit).",
303
+ "examples": [
304
+ "15/03/1985",
305
+ "1985-03-15",
306
+ "3 iulie 1985",
307
+ "3. März 1988",
308
+ "כ״ה באדר תשפ״ה",
309
+ "3. júla 1976",
310
+ "3. heinäkuuta 1976",
311
+ "1976. július 3.",
312
+ "1r de juliol de 1976",
313
+ "1.º de julho de 1976",
314
+ "໓ ກໍລະກົດ ໑໙໗໖",
315
+ "၃ ဇူလိုင် ၁၉၇၆"
316
+ ],
317
+ "synthetic_strategy": "faker_dob"
318
+ },
319
+ "PASSPORT": {
320
+ "code": "ID_PASS",
321
+ "cloud_token_type": "ID_GOV",
322
+ "pattern": "\\b[A-Z]{1,2}[0-9]{6,9}\\b",
323
+ "description": "Passport numbers (simplified cross-country pattern). Word-boundary anchored 2026-07-05 (parity with patterns.rs) so it no longer grabs a sub-run mid-word (e.g. BC1234567 out of ABC1234567).",
324
+ "examples": [
325
+ "A12345678",
326
+ "AB1234567"
327
+ ],
328
+ "synthetic_strategy": "faker_passport"
329
+ },
330
+ "URL": {
331
+ "code": "URL",
332
+ "cloud_token_type": "NET_URL",
333
+ "pattern": "https?://[^\\s<>\"{}|\\\\^`\\[\\]]{3,}",
334
+ "description": "HTTP/HTTPS URLs (may carry secrets in query strings, e.g. ?token=). http/https only to avoid over-matching bare domains.",
335
+ "examples": [
336
+ "https://portal.example.com/reset?token=abc123def"
337
+ ],
338
+ "synthetic_strategy": "mask_url_host"
339
+ },
340
+ "API_KEY": {
341
+ "code": "CRED_KEY",
342
+ "cloud_token_type": "CRED_KEY",
343
+ "pattern": "(?i)(?:api[_\\-\\s]?key|secret|token|bearer)[:\\s\"'=]+[A-Za-z0-9_\\-]{16,64}|\\b(?:sk|pk|rk|ak)-(?:live|test|prod|proj)-[A-Za-z0-9]{10,}\\b",
344
+ "description": "Generic API keys / bearer secrets: label-prefixed values and vendor-neutral dashed prefixed keys (sk-live-…). Secret material — engines with a secrets-first stage fail-close; opaque engines tokenise as CRED_KEY. Never egress raw (§29).",
345
+ "examples": [
346
+ "API key sk-live-ABCD1234EFGH5678IJKL9012",
347
+ "sk-test-ABCDEFGHIJ1234567890"
348
+ ],
349
+ "synthetic_strategy": "block_or_token"
350
+ },
351
+ "US_ZIP": {
352
+ "code": "GEO_ZIP",
353
+ "cloud_token_type": "GEO_ZIP",
354
+ "pattern": "(?i)\\bzip\\b[^\\d]{0,8}\\d{5}(?:-\\d{4})?",
355
+ "description": "US ZIP / postal code. Cue-anchored on the word ZIP (bare \\d{5} would false-positive on every 5-digit number). Match includes the cue word (safest-superset over-redaction; whole-match span, no lookbehind in Rust regex).",
356
+ "examples": [
357
+ "ZIP 90210",
358
+ "zip: 10001-2345"
359
+ ],
360
+ "synthetic_strategy": "faker_zip"
361
+ },
362
+ "UK_UTR": {
363
+ "code": "ID_GOV",
364
+ "cloud_token_type": "ID_GOV",
365
+ "pattern": "(?i)\\butr\\b[^\\d]{0,8}\\d{10}\\b",
366
+ "description": "UK self-assessment Unique Taxpayer Reference (10 digits). Cue-anchored on UTR so it beats the greedy PHONE bare-run \\d{10,11} (§44e precedence fix). Match starts at the cue word ⇒ wins span-based overlap dedup on every engine.",
367
+ "examples": [
368
+ "UTR is 1234567890"
369
+ ],
370
+ "synthetic_strategy": "faker_national_id"
371
+ },
372
+ "IT_PARTITA_IVA": {
373
+ "code": "ID_GOV",
374
+ "cloud_token_type": "ID_GOV",
375
+ "pattern": "(?i)partita\\s*iva[^\\d]{0,8}\\d{11}\\b",
376
+ "description": "Italian Partita IVA / VAT number (11 digits). Cue-anchored so it beats PHONE (§44e).",
377
+ "examples": [
378
+ "Partita IVA è 12345678903"
379
+ ],
380
+ "synthetic_strategy": "faker_national_id"
381
+ },
382
+ "PL_NIP": {
383
+ "code": "ID_GOV",
384
+ "cloud_token_type": "ID_GOV",
385
+ "pattern": "(?i)\\bnip\\b[^\\d]{0,8}\\d{10}\\b",
386
+ "description": "Polish NIP tax identification number (10 digits). Cue-anchored so it beats PHONE (§44e).",
387
+ "examples": [
388
+ "NIP to 1234567802"
389
+ ],
390
+ "synthetic_strategy": "faker_national_id"
391
+ },
392
+ "NID_GENERIC_LABELLED": {
393
+ "code": "ID_GOV",
394
+ "cloud_token_type": "ID_GOV",
395
+ "pattern": "(?i)\\b(?:iin\\b|nic\\b|ਆਧਾਰ|เลขบัตรประชาชน|บัตรประชาชน|เลขประจำตัวประชาชน|rodné\\s*číslo|rodne\\s*cislo|cccd\\b|cmnd\\b|आधार|aadhaar|aadhar|nric\\b|nik\\b|curp\\b|\\brut\\b|henkilötunnu\\w*|henkilotunnu\\w*|national\\s*id(?:entity)?(?:\\s*(?:no\\.?|number|card))?|national\\s*number|insee|\\bnir\\b|\\begn\\b|\\bjmbg\\b|\\boib\\b|\\bamka\\b|\\bcnp\\b|\\bqid\\b|civil\\s*(?:no\\.?|number)|public\\s*services?\\s*number|carnet\\s*de\\s*identidad|\\bcui\\b|\\bnrc\\b|sin\\s*(?:no\\.?|number)|num[ée]ro\\s*d['’]identification(?:\\s*national\\w*)?|nid|id\\s*(?:no\\.?|number|nr\\.?)|personal\\s*id|nasjonal(?:t)?\\s*id|id-?nummer|id-?nr\\.?|personalausweis(?:nummer)?|ausweis(?:nummer)?|ausweis-?nr\\.?|nationale?\\s*id|numero\\s*di\\s*identità|numéro\\s*(?:national|d['’]identité)|carte\\s*d['’]identité|pièce\\s*d['’]identité|n°\\s*d['’]identité|número\\s*de\\s*identi(?:dad|ficación)|identificación\\s*nacional|c[eé]dula(?:\\s*de\\s*identidad)?|dni|documento\\s*d['’]identità|carta\\s*d['’]identità|identiteitsnummer|nationaal\\s*id|número\\s*de\\s*identidade|cartão\\s*de\\s*identidade|identificação\\s*nacional|cpf|pesel|tc\\s*kimli\\w*|kimli[kğ]\\w*\\s*(?:no\\.?|numara\\w*)?|személyi\\s*(?:szám|azonosító\\w*|igazolvány\\w*)|személyazonosító\\w*|adóazonosító\\w*|asmens\\s*kod\\w*|personas\\s*kod\\w*|isikukood\\w*|身份证(?:号|号码)?|身份證(?:號|號碼)?|居民身份证)[^0-9]{0,10}\\d(?:[\\s./\\-]?\\d){4,17}",
396
+ "description": "Generic LABELLED national / personal identity number (5–12 digits, optionally separated). CUE-ANCHORED on a MULTILINGUAL label synonym (EN National ID / NID / ID No / ID Number / Personal ID; NO nasjonal ID / ID-nummer / ID-nr; DE Ausweisnummer / Personalausweis / nationale ID; FR numéro national / numéro d'identité / carte d'identité / pièce d'identité; ES número de identidad / identificación nacional / cédula; IT numero di identità / documento d'identità / carta d'identità; NL identiteitsnummer / nationaal ID; PT número de identidade / cartão de identidade / identificação nacional) so it never over-matches a BARE digit run (dates, amounts, phones, visit counts). 2026-07-19 (F2 content-blind leak fix): a labelled National ID (`National ID 856214`) was egressing RAW on EVERY surface — the fasit had only country-specific checksum-anchored NID_* rules and no cue-anchored generic labelled form, so nothing matched in any engine leg (review OR egress). The whole match INCLUDES the label cue (safest-superset over-redaction, whole-match span like US_ZIP/UK_UTR — no lookbehind in Rust regex). NID_* prefix ⇒ pipeline.rs registry_type_to_entity routes it to EntityType::Ssn ⇒ surfaces as NATIONAL_ID/GOVID, agreeing with the opaque engines' ID_GOV. Cue anchor makes the match START at the label ⇒ it wins the §44e span-overlap tie-break over the greedy PHONE bare-run. \\uHHHH escapes (accented label letters) compile identically in the Rust regex crate and legacy (non-u) JS RegExp.",
397
+ "examples": [
398
+ "National ID 856214",
399
+ "ID No 12345678",
400
+ "Personal ID 90210-4471",
401
+ "nasjonal ID 55123456",
402
+ "numéro d'identité 1122334455",
403
+ "número de identidad 87654321"
404
+ ],
405
+ "synthetic_strategy": "faker_national_id"
406
+ },
407
+ "UK_NINO": {
408
+ "code": "ID_GOV",
409
+ "cloud_token_type": "ID_GOV",
410
+ "pattern": "\\b[A-CEGHJ-PR-TW-Z]{2}\\d{6}[A-D]\\b",
411
+ "description": "UK National Insurance Number. Ported from pii-engine (superset record of the fasit).",
412
+ "examples": [
413
+ "AB123456C"
414
+ ],
415
+ "synthetic_strategy": "faker_national_id"
416
+ },
417
+ "NID_UK_NINO_LABELLED": {
418
+ "code": "ID_GOV",
419
+ "cloud_token_type": "ID_GOV",
420
+ "pattern": "(?i)\\b(?:national\\s*insurance(?:\\s*(?:no\\.?|number))?|nino|ni\\s*(?:no\\.?|number)|uk\\s*nin(?:o)?(?:\\s*v?\\d)?)\\b[^0-9A-Za-z]{0,12}[A-Za-z]{2}[ ]?\\d{6}[ ]?[A-Za-z]?",
421
+ "description": "UK National Insurance Number, CUE-anchored companion to the strict UK_NINO shape. batch-29d/29f leak: synthetic 'UK NIN v2' vectors use out-of-spec suffix letters (E-Z) and prefixes (U/V) that the strict A-D/valid-prefix pattern correctly rejects, but a NINO cue is present. When a national-insurance cue precedes it, accept the full 2-letter+6-digit+letter shape regardless of suffix/prefix validity. Precision preserved: no cue, no fire (strict UK_NINO still governs the bare case).",
422
+ "examples": [
423
+ "National Insurance No: AB123456C"
424
+ ],
425
+ "synthetic_strategy": "faker_national_id"
426
+ },
427
+ "MEDICAL_RECORD": {
428
+ "code": "MED_ID",
429
+ "cloud_token_type": "MED_ID",
430
+ "pattern": "(?i)\\b(?:mrn|patient[\\s_]?id|med[\\s_]?rec)[:\\s#]+[A-Z0-9\\-]{4,20}\\b",
431
+ "description": "Medical record / patient ID references. Ported from pii-engine (superset record of the fasit).",
432
+ "examples": [
433
+ "MRN: A1234567"
434
+ ],
435
+ "synthetic_strategy": "faker_id"
436
+ },
437
+ "AUTH_JWT": {
438
+ "code": "CRED_KEY",
439
+ "cloud_token_type": "CRED_KEY",
440
+ "pattern": "\\beyJ[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+",
441
+ "description": "JSON Web Token (eyJ… header.payload.signature). Carries auth + PII claims. fasit API_KEY does not match the eyJ shape (Track-0c batch-1). Secret material — realistic-standin engines fail-close (secrets-detector JWT_TOKEN, §29); opaque engines tokenise as CRED_KEY.",
442
+ "examples": [
443
+ "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.abc123XYZ"
444
+ ],
445
+ "synthetic_strategy": "block_or_token"
446
+ },
447
+ "NID_DK_CPR": {
448
+ "code": "ID_GOV",
449
+ "cloud_token_type": "ID_GOV",
450
+ "pattern": "(?i)\\bcpr(?:[\\s\\-]?(?:nr|nummer))?\\b[^0-9]{0,8}(?:0[1-9]|[12]\\d|3[01])(?:0[1-9]|1[0-2])\\d{2}-?\\d{4}",
451
+ "description": "Danish CPR (DDMMYY-SSSS). Cue-anchored (starts at CPR) so it beats PHONE (§44e). Ported gov-id.tax.dk-cpr; PHP mod-11 checksum not portable to the pure-regex fasit (see report).",
452
+ "examples": [
453
+ "CPR-nr: 231085-1234"
454
+ ],
455
+ "synthetic_strategy": "faker_national_id"
456
+ },
457
+ "NID_SE_PNR": {
458
+ "code": "ID_GOV",
459
+ "cloud_token_type": "ID_GOV",
460
+ "pattern": "(?i)\\b(?:personnummer|personnumret|person-?nr\\.?|pnr)\\b[^0-9]{0,8}(?:19|20)?\\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\\d|3[01])[\\-+]?\\d{4}",
461
+ "description": "Swedish personnummer (YYYYMMDD-NNNN). Cue-anchored (fasit PERSONNUMMER is NO-only). Ported gov-id.tax.se-personnummer.",
462
+ "examples": [
463
+ "Personnummer 19850701-1234"
464
+ ],
465
+ "synthetic_strategy": "faker_national_id"
466
+ },
467
+ "NID_FI_HETU": {
468
+ "code": "ID_GOV",
469
+ "cloud_token_type": "ID_GOV",
470
+ "pattern": "\\b(?:0[1-9]|[12]\\d|3[01])(?:0[1-9]|1[0-2])\\d{2}[+\\-A-Y]\\d{3}[0-9A-Y]\\b",
471
+ "description": "Finnish HETU (DDMMYY+century-sep+NNN+check). Century separator letter makes it distinctive. Ported gov-id.tax.fi-hetu.",
472
+ "examples": [
473
+ "010190-123A"
474
+ ],
475
+ "synthetic_strategy": "faker_national_id"
476
+ },
477
+ "NID_IS_KENNITALA": {
478
+ "code": "ID_GOV",
479
+ "cloud_token_type": "ID_GOV",
480
+ "pattern": "(?i)\\b(?:kennit\\w*|kt\\.?)[^0-9]{0,8}(?:0[1-9]|[12]\\d|3[01]|4[1-9]|5\\d|6[01])(?:0[1-9]|1[0-2])\\d{2}-?\\d{3,4}",
481
+ "description": "Icelandic kennitala (DDMMYY-NNN[N], day may be +40 for companies). Cue-anchored. v1.4.11 (batch-17 id48): cue broadened from literal \\bkennitala\\b to the INFLECTED stem kennit\\w* (kennitala/kennitalan nom+def / kennitölu acc-dat / kennitölunni dat+def / kennitölur pl) PLUS the abbreviation kt. — Icelandic is inflected, so the fixed-form cue missed real usage; ALSO relaxed the trailing group \\d{4}→\\d{3,4} because the leaking id48 token was written 170585-291 (3-digit tail). The strong Icelandic cue + strict DDMMYY structure keep FP risk negligible. Ported gov-id.tax.is-kennitala.",
482
+ "examples": [
483
+ "kennitala 120174-3399"
484
+ ],
485
+ "synthetic_strategy": "faker_national_id"
486
+ },
487
+ "NID_FR_NISS": {
488
+ "code": "ID_GOV",
489
+ "cloud_token_type": "ID_GOV",
490
+ "pattern": "\\b[12]\\d{2}(?:0[1-9]|1[0-2]|[2-9]\\d)\\d{2}\\d{3}\\d{3}(?: ?\\d{2})?\\b",
491
+ "description": "French NISS / n° sécu (13 or 15 digits, sex-prefix 1/2). 13+ digit run — beyond PHONE bare-run. Ported gov-id.tax.fr-niss.",
492
+ "examples": [
493
+ "185017511600192"
494
+ ],
495
+ "synthetic_strategy": "faker_national_id"
496
+ },
497
+ "NID_ES_NIF": {
498
+ "code": "ID_GOV",
499
+ "cloud_token_type": "ID_GOV",
500
+ "pattern": "\\b(?:\\d{8}[A-Z]|[XYZ]\\d{7}[A-Z]|[ABCDEFGHJNPQRSUVW]\\d{7}[A-Z0-9])\\b",
501
+ "description": "Spanish NIF / NIE / CIF (digits+control letter). Distinctive shape. Ported gov-id.tax.es-nif.",
502
+ "examples": [
503
+ "12345678Z",
504
+ "X1234567L"
505
+ ],
506
+ "synthetic_strategy": "faker_national_id"
507
+ },
508
+ "NID_IT_CF": {
509
+ "code": "ID_GOV",
510
+ "cloud_token_type": "ID_GOV",
511
+ "pattern": "(?i)\\b[A-Z]{6}\\d{2}[A-EHLMPRST]\\d{2}[A-Z]\\d{3}[A-Z]\\b",
512
+ "description": "Italian codice fiscale (6 letters + fiscal code). Case-insensitive (lowercase print leaked to NER before). Ported gov-id.tax.it-codicefiscale.",
513
+ "examples": [
514
+ "RSSMRA85M01H501Z"
515
+ ],
516
+ "synthetic_strategy": "faker_national_id"
517
+ },
518
+ "NID_NL_BSN": {
519
+ "code": "ID_GOV",
520
+ "cloud_token_type": "ID_GOV",
521
+ "pattern": "(?i)\\bbsn\\b[^0-9]{0,8}\\d{8,9}",
522
+ "description": "Dutch BSN (8–9 digits). Cue-anchored (bare 8–9 digit run is too generic). Track-0c batch-2: elfproef (mod-11) validated. Ported gov-id.tax.nl-bsn.",
523
+ "examples": [
524
+ "BSN 123456782"
525
+ ],
526
+ "checksum": "bsn",
527
+ "synthetic_strategy": "faker_national_id"
528
+ },
529
+ "NID_PL_PESEL": {
530
+ "code": "ID_GOV",
531
+ "cloud_token_type": "ID_GOV",
532
+ "pattern": "(?i)\\bpesel\\b[^0-9]{0,40}\\d{11}",
533
+ "description": "Polish PESEL (11 digits). Cue-anchored (collides with NO fnr / PHONE bare-run otherwise). Ported gov-id.pl.pesel. v1.4.14 (batch-22 GOVID): cue→number gap widened [^0-9]{0,8}→{0,40} — id33 `mój PESEL do celów rozliczeniowych to 99123090751` put a 5-word Polish phrase between the distinctive PESEL cue and the number (28 chars > 8) so the number leaked; the gap forbids digits so the first digit-run after PESEL is still the one captured (whole-match over-redaction, precision-safe on the distinctive cue).",
534
+ "examples": [
535
+ "PESEL 85010112345"
536
+ ],
537
+ "synthetic_strategy": "faker_national_id"
538
+ },
539
+ "NID_CA_SIN": {
540
+ "code": "ID_GOV",
541
+ "cloud_token_type": "ID_GOV",
542
+ "pattern": "(?i)\\b(?:sin|nas|social insurance number)\\b[^0-9]{0,8}\\d{3}[- ]?\\d{3}[- ]?\\d{3}",
543
+ "description": "Canadian SIN (3-3-3). Cue-anchored (label-anchored in PHP too — bare compact collides with ABA/PHONE). Track-0c batch-2: Luhn-validated on top of the cue anchor. Ported gov-id.ca.sin.",
544
+ "examples": [
545
+ "SIN 046 454 286"
546
+ ],
547
+ "checksum": "luhn",
548
+ "synthetic_strategy": "faker_national_id"
549
+ },
550
+ "NID_NO_DNR": {
551
+ "code": "ID_GOV",
552
+ "cloud_token_type": "ID_GOV",
553
+ "pattern": "(?i)\\bd-?nummer\\b[^0-9]{0,8}[4-7]\\d{10}",
554
+ "description": "Norwegian D-number (fnr with first digit +40, i.e. 4–7). Cue-anchored (bare 11-digit collides with PHONE / fnr). Ported gov-id.no.dnr.",
555
+ "examples": [
556
+ "D-nummer 51015612345"
557
+ ],
558
+ "synthetic_strategy": "faker_national_id"
559
+ },
560
+ "NID_AT_SVNR": {
561
+ "code": "ID_GOV",
562
+ "cloud_token_type": "ID_GOV",
563
+ "pattern": "(?i)\\b(?:svnr|sozialversicherungsnummer)\\b[^0-9]{0,8}\\d{4} ?(?:0[1-9]|[12]\\d|3[01])(?:0[1-9]|1[0-2])\\d{2}",
564
+ "description": "Austrian SVNR (4 serial + DDMMYY). Cue-anchored. Ported gov-id.at.svnr.",
565
+ "examples": [
566
+ "SVNR 1237 010180"
567
+ ],
568
+ "synthetic_strategy": "faker_national_id"
569
+ },
570
+ "NID_BE_NRN": {
571
+ "code": "ID_GOV",
572
+ "cloud_token_type": "ID_GOV",
573
+ "pattern": "\\b\\d{2}[. ]\\d{2}[. ]\\d{2}[- .]\\d{3}[. ]\\d{2}\\b",
574
+ "description": "Belgian Rijksregisternummer, dotted print form YY.MM.DD-NNN.CC. Distinctive punctuation. Ported gov-id.be.nrn.",
575
+ "examples": [
576
+ "85.07.30-033.28"
577
+ ],
578
+ "synthetic_strategy": "faker_national_id"
579
+ },
580
+ "NID_IE_PPS": {
581
+ "code": "ID_GOV",
582
+ "cloud_token_type": "ID_GOV",
583
+ "pattern": "\\b\\d{7}[A-W][AHW]?\\b",
584
+ "description": "Irish PPS number (7 digits + 1–2 control letters). Distinctive. Ported gov-id.ie.pps.",
585
+ "examples": [
586
+ "1234567FA"
587
+ ],
588
+ "synthetic_strategy": "faker_national_id"
589
+ },
590
+ "NID_PT_CC": {
591
+ "code": "ID_GOV",
592
+ "cloud_token_type": "ID_GOV",
593
+ "pattern": "\\b\\d{8} ?\\d ?[A-Z]{2}\\d\\b",
594
+ "description": "Portuguese Cartão de Cidadão (8 digits + check + 2 version letters + digit). Distinctive. Ported gov-id.pt.cc.",
595
+ "examples": [
596
+ "12345678 9 ZZ0"
597
+ ],
598
+ "synthetic_strategy": "faker_national_id"
599
+ },
600
+ "NID_CH_AHV": {
601
+ "code": "ID_GOV",
602
+ "cloud_token_type": "ID_GOV",
603
+ "pattern": "\\b756[. ]?\\d{4}[. ]?\\d{4}[. ]?\\d{2}\\b",
604
+ "description": "Swiss AHV/AVS (756.XXXX.XXXX.XX). 756 country prefix is distinctive. Ported gov-id.ch.ahv.",
605
+ "examples": [
606
+ "756.1234.5678.90"
607
+ ],
608
+ "synthetic_strategy": "faker_national_id"
609
+ },
610
+ "NID_JP_MYNUMBER": {
611
+ "code": "ID_GOV",
612
+ "cloud_token_type": "ID_GOV",
613
+ "pattern": "(?i)\\bmy ?number\\b[^0-9]{0,8}\\d{4}[\\- ]?\\d{4}[\\- ]?\\d{4}",
614
+ "description": "Japanese My Number (12 digits, romaji-label anchored — collides with Aadhaar/bank otherwise). Ported gov-id.jp.my-number (English/romaji label arm).",
615
+ "examples": [
616
+ "My Number: 1234 5678 9018"
617
+ ],
618
+ "synthetic_strategy": "faker_national_id"
619
+ },
620
+ "NID_IN_AADHAAR": {
621
+ "code": "ID_GOV",
622
+ "cloud_token_type": "ID_GOV",
623
+ "pattern": "(?i)\\b(?:aadhaar|aadhar|uid)\\b[^0-9]{0,10}\\d{4}[\\s\\-]?\\d{4}[\\s\\-]?\\d{4}",
624
+ "description": "Indian Aadhaar (4-4-4). Cue-anchored + Track-0c batch-2 Verhoeff checksum (now portable via the fasit checksum field). Ported gov-id.in.aadhaar.",
625
+ "examples": [
626
+ "Aadhaar 2345 6789 0124"
627
+ ],
628
+ "checksum": "verhoeff",
629
+ "synthetic_strategy": "faker_national_id"
630
+ },
631
+ "NID_IN_PAN": {
632
+ "code": "ID_GOV",
633
+ "cloud_token_type": "ID_GOV",
634
+ "pattern": "\\b[A-Z]{5}\\d{4}[A-Z]\\b",
635
+ "description": "Indian PAN (AAAAA9999A). Distinctive. Ported gov-id.tax.in-pan.",
636
+ "examples": [
637
+ "ABCDE1234F"
638
+ ],
639
+ "synthetic_strategy": "faker_national_id"
640
+ },
641
+ "NID_BR_CPF": {
642
+ "code": "ID_GOV",
643
+ "cloud_token_type": "ID_GOV",
644
+ "pattern": "\\b\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}\\b",
645
+ "description": "Brazilian CPF, formatted NNN.NNN.NNN-NN. Distinctive punctuation. Track-0c batch-2: two-digit mod-11 CPF checksum validated. Ported gov-id.tax.br-cpf.",
646
+ "examples": [
647
+ "123.456.789-09"
648
+ ],
649
+ "checksum": "cpf",
650
+ "synthetic_strategy": "faker_national_id"
651
+ },
652
+ "NID_MX_CURP": {
653
+ "code": "ID_GOV",
654
+ "cloud_token_type": "ID_GOV",
655
+ "pattern": "\\b[A-Z]{4}\\d{6}[HM][A-Z]{5}[A-Z0-9]\\d\\b",
656
+ "description": "Mexican CURP (Clave Unica de Registro de Poblacion): 18 alnum = 4 letters + 6-digit birthdate (YYMMDD) + H/M sex + 5 letters (2 state + 3 consonants) + 1 alnum homoclave + 1 check digit. batch-29 GOVID domain-exhaustion: bare (uncued) CURP had no detector. mod-10 check digit over the base-37 dictionary (0-9A-N-N-tilde-O-Z) gates it, so a random 18-char alnum run does NOT fire (precision). Complements the cue-anchored CURP arm in NID_GENERIC_LABELLED.",
657
+ "examples": [
658
+ "HEGG560427MVZRRL04"
659
+ ],
660
+ "checksum": "mx_curp",
661
+ "synthetic_strategy": "faker_national_id"
662
+ },
663
+ "NID_CL_RUT": {
664
+ "code": "ID_GOV",
665
+ "cloud_token_type": "ID_GOV",
666
+ "pattern": "\\b(?:\\d{1,2}\\.\\d{3}\\.\\d{3}|\\d{7,8})-[\\dkK]\\b",
667
+ "description": "Chilean RUT/RUN (Rol Unico Tributario / Nacional): 7-8 body digits + '-' + mod-11 check char (0-9 or K). batch-29 GOVID domain-exhaustion: bare (uncued) RUT had no detector. The mandatory '-check' with mod-11 (weights 2..7 cycled, 11->0, 10->K) gates it; the '-K' form is highly distinctive. Complements the cue-anchored RUT arm in NID_CUE_EXT_MULTI/NID_GENERIC_LABELLED.",
668
+ "examples": [
669
+ "12.345.678-5",
670
+ "10000013-K"
671
+ ],
672
+ "checksum": "cl_rut",
673
+ "synthetic_strategy": "faker_national_id"
674
+ },
675
+ "NID_BR_RG": {
676
+ "code": "ID_GOV",
677
+ "cloud_token_type": "ID_GOV",
678
+ "pattern": "\\b\\d{1,2}\\.\\d{3}\\.\\d{3}-[\\dX]\\b",
679
+ "description": "Brazilian RG, formatted NN.NNN.NNN-D. Ported gov-id.br.rg.",
680
+ "examples": [
681
+ "12.345.678-9"
682
+ ],
683
+ "synthetic_strategy": "faker_national_id"
684
+ },
685
+ "NID_DE_STEUERID": {
686
+ "code": "ID_GOV",
687
+ "cloud_token_type": "ID_GOV",
688
+ "pattern": "(?i)\\b(?:steuer-?identifikationsnummer|steuer-?id|steuerliche identifikationsnummer|idnr|steuernummer)\\b[^0-9]{0,10}[1-9]\\d{9,10}",
689
+ "description": "German Steuer-ID / Steuernummer (10–11 digits, leading non-zero). Cue-anchored (bare run too generic). Ported gov-id.tax.de-steuerid. v1.4.14 (batch-22 GOVID): cue set gains the COMPOUND noun `steueridentifikationsnummer` (id10 `Steueridentifikationsnummer lautet 68285915240` — the old `steuer-?id` cue matched only the `steuerid` prefix, then the 10-char gap was blown by the remaining `entifikationsnummer lautet ` and the number leaked) and `steuernummer` (id12 `Steuernummer: 88140595464` — the slash-form NID_DE_STEUERNR did not cover a plain 11-digit run cued by Steuernummer); digit run relaxed \\d{10}→\\d{9,10} to admit the 10-digit Steuernummer alongside the 11-digit Steuer-ID.",
690
+ "examples": [
691
+ "Steuer-ID 12345678901"
692
+ ],
693
+ "synthetic_strategy": "faker_national_id"
694
+ },
695
+ "NID_DE_STEUERNR": {
696
+ "code": "ID_GOV",
697
+ "cloud_token_type": "ID_GOV",
698
+ "pattern": "\\b\\d{2,3}/\\d{3,4}/\\d{4,5}\\b",
699
+ "description": "German Steuernummer, slash print form NN/NNN/NNNNN. Distinctive. Ported gov-id.tax.de-steuernummer.",
700
+ "examples": [
701
+ "21/815/08150"
702
+ ],
703
+ "synthetic_strategy": "faker_national_id"
704
+ },
705
+ "NID_PT_NIF": {
706
+ "code": "ID_GOV",
707
+ "cloud_token_type": "ID_GOV",
708
+ "pattern": "(?i)\\bnif\\b[^0-9]{0,6}\\d{3} ?\\d{3} ?\\d{3}",
709
+ "description": "Portuguese NIF (9 digits). Cue-anchored ONLY (bare arm reverted in PHP — mod-11 collides with phone print). Ported gov-id.tax.pt-nif.",
710
+ "examples": [
711
+ "NIF 123 456 789"
712
+ ],
713
+ "synthetic_strategy": "faker_national_id"
714
+ },
715
+ "NID_NO_BANKID": {
716
+ "code": "ID_GOV",
717
+ "cloud_token_type": "ID_GOV",
718
+ "pattern": "(?i)\\b(?:bankid|bank-?id|bid)\\b[\\s\\-:=]{0,8}(?:orderref|merchantreference|transactionid)?[\\s\\-:=]*[a-f0-9]{16,40}",
719
+ "description": "Norwegian BankID order/transaction reference (hex). Cue-anchored. Ported gov-id.no.bankid.",
720
+ "examples": [
721
+ "BankID orderRef 131daac9cb8e4b0f9d3a2c1e0f7b6a54"
722
+ ],
723
+ "synthetic_strategy": "faker_national_id"
724
+ },
725
+ "NID_MRZ": {
726
+ "code": "ID_GOV",
727
+ "cloud_token_type": "ID_GOV",
728
+ "pattern": "\\b[PIACV]<[A-Z0-9<]{20,}",
729
+ "description": "Passport / travel-document MRZ line (P<COUNTRY<NAME…). The '<' filler makes it distinctive. Ported gov-id.passport.mrz.",
730
+ "examples": [
731
+ "P<USADOE<<JOHN<<<<<<<<<<<<<<<<<<<<<<<<"
732
+ ],
733
+ "synthetic_strategy": "faker_national_id"
734
+ },
735
+ "NID_DRIVER_LICENCE": {
736
+ "code": "ID_GOV",
737
+ "cloud_token_type": "ID_GOV",
738
+ "pattern": "(?i)\\b(?:driver'?s? licen[cs]e|f[\\u00f8o]rerkort ?nr|f[\\u00fcu]hrerschein|permis|dl)\\b[:\\s#]{1,4}[A-Z0-9]{6,15}",
739
+ "description": "Driver's licence (US/NO/DE/FR label-anchored). Cue-anchored. Ported gov-id.driver-licence.",
740
+ "examples": [
741
+ "DL: D1234567"
742
+ ],
743
+ "synthetic_strategy": "faker_national_id"
744
+ },
745
+ "NID_US_GREENCARD": {
746
+ "code": "ID_GOV",
747
+ "cloud_token_type": "ID_GOV",
748
+ "pattern": "\\b[A-Z]{3}\\d{10}\\b",
749
+ "description": "US green card / USCIS receipt (3 letters + 10 digits). Distinctive. Ported gov-id.residence.us-green-card.",
750
+ "examples": [
751
+ "SRC1234567890"
752
+ ],
753
+ "synthetic_strategy": "faker_national_id"
754
+ },
755
+ "NID_US_VOTER": {
756
+ "code": "ID_GOV",
757
+ "cloud_token_type": "ID_GOV",
758
+ "pattern": "(?i)\\bvoter (?:id|registration|number)\\b[:\\s#]{1,4}[A-Z0-9]{4,15}",
759
+ "description": "US voter registration ID. Cue-anchored. Ported gov-id.voter.us.",
760
+ "examples": [
761
+ "Voter ID: OH0123456789"
762
+ ],
763
+ "synthetic_strategy": "faker_national_id"
764
+ },
765
+ "NID_US_EIN": {
766
+ "code": "ID_GOV",
767
+ "cloud_token_type": "ID_GOV",
768
+ "pattern": "\\b\\d{2}-\\d{7}\\b",
769
+ "description": "US Employer Identification Number (NN-NNNNNNN). Distinctive dash placement. Ported gov-id.us.ein.",
770
+ "examples": [
771
+ "12-3456789"
772
+ ],
773
+ "synthetic_strategy": "faker_national_id"
774
+ },
775
+ "NID_DL_UK": {
776
+ "code": "ID_GOV",
777
+ "cloud_token_type": "ID_GOV",
778
+ "pattern": "\\b[A-Z9]{5} ?\\d[0156]\\d[0-3]\\d\\d ?[A-Z9]{2}\\d[A-Z]{2}\\b",
779
+ "description": "UK DVLA driving licence (16 chars, encodes name+DOB+sex). Distinctive. Ported gov-id.driver-licence UK arm.",
780
+ "examples": [
781
+ "MORGA657054SM9IJ"
782
+ ],
783
+ "synthetic_strategy": "faker_national_id"
784
+ },
785
+ "HEALTH_UK_NHS": {
786
+ "code": "MED_ID",
787
+ "cloud_token_type": "MED_ID",
788
+ "pattern": "(?i)\\bnhs\\b[^0-9]{0,10}\\d{3} ?\\d{3} ?\\d{4}",
789
+ "description": "UK NHS number (3-3-4). GDPR Art-9. Cue-anchored + Track-0c batch-2 NHS mod-11 checksum. Ported health.uk-nhs-no.",
790
+ "examples": [
791
+ "NHS 943 476 5919"
792
+ ],
793
+ "checksum": "nhs",
794
+ "synthetic_strategy": "faker_id"
795
+ },
796
+ "HEALTH_NO_HELSENUMMER": {
797
+ "code": "MED_ID",
798
+ "cloud_token_type": "MED_ID",
799
+ "pattern": "(?i)\\bhelsenummer[:\\s#]+\\d{6,11}",
800
+ "description": "Norwegian helsenummer. GDPR Art-9. Cue-anchored. Ported health.no-helsenummer.",
801
+ "examples": [
802
+ "helsenummer: 12345678901"
803
+ ],
804
+ "synthetic_strategy": "faker_id"
805
+ },
806
+ "HEALTH_NO_HPR": {
807
+ "code": "MED_ID",
808
+ "cloud_token_type": "MED_ID",
809
+ "pattern": "(?i)\\bhpr(?:-?nr\\.?)?[:\\s#]+\\d{6,9}",
810
+ "description": "Norwegian HPR health-personnel register number. GDPR Art-9. Cue-anchored. Ported health.no-hpr.",
811
+ "examples": [
812
+ "HPR-nr: 1234567"
813
+ ],
814
+ "synthetic_strategy": "faker_id"
815
+ },
816
+ "HEALTH_US_MEDICARE": {
817
+ "code": "MED_ID",
818
+ "cloud_token_type": "MED_ID",
819
+ "pattern": "\\b[1-9][AC-HJKMNP-RT-Y][AC-HJKMNP-RT-Y0-9]\\d[- ]?[AC-HJKMNP-RT-Y][AC-HJKMNP-RT-Y0-9]\\d[- ]?[AC-HJKMNP-RT-Y]{2}\\d{2}\\b",
820
+ "description": "US Medicare Beneficiary Identifier (MBI, CMS positional classes). GDPR Art-9. Distinctive. Ported health.us-medicare.",
821
+ "examples": [
822
+ "1EG4-TE5-MK73"
823
+ ],
824
+ "synthetic_strategy": "faker_id"
825
+ },
826
+ "HEALTH_DE_VERSICHERT": {
827
+ "code": "MED_ID",
828
+ "cloud_token_type": "MED_ID",
829
+ "pattern": "(?i)\\bversichert(?:ennummer|ung)?\\b[^A-Za-z0-9]{0,8}[A-Z]\\d{9}",
830
+ "description": "German Versichertennummer (letter + 9 digits). GDPR Art-9. Cue-anchored (bare shape collides with PASSPORT). Ported health.de-versichertennummer.",
831
+ "examples": [
832
+ "Versichertennummer A123456780"
833
+ ],
834
+ "synthetic_strategy": "faker_id"
835
+ },
836
+ "HEALTH_INSURANCE_NO": {
837
+ "code": "MED_ID",
838
+ "cloud_token_type": "MED_ID",
839
+ "pattern": "(?i)\\b(?:insurance|policy|member id|forsikring|krankenversicherung)[:\\s#]+[A-Z0-9\\-]{6,20}",
840
+ "description": "Health insurance / policy / member number. GDPR Art-9. Cue-anchored. Ported health.insurance-no.",
841
+ "examples": [
842
+ "policy: HX-99381726"
843
+ ],
844
+ "synthetic_strategy": "faker_id"
845
+ },
846
+ "HEALTH_ICD10": {
847
+ "code": "MED_ID",
848
+ "cloud_token_type": "MED_ID",
849
+ "pattern": "(?i)\\bicd(?:-?10)?\\b[^A-Za-z0-9]{0,6}[A-TV-Z]\\d{2}(?:\\.\\d{1,4})?",
850
+ "description": "ICD-10 diagnosis code. GDPR Art-9. Cue-anchored (bare code collides with postcodes). Ported health.icd-10.",
851
+ "examples": [
852
+ "ICD-10 E11.9"
853
+ ],
854
+ "synthetic_strategy": "faker_id"
855
+ },
856
+ "HEALTH_SNOMED": {
857
+ "code": "MED_ID",
858
+ "cloud_token_type": "MED_ID",
859
+ "pattern": "(?i)\\bsnomed(?:-ct)?[:\\s#]+\\d{6,18}",
860
+ "description": "SNOMED-CT clinical concept id. GDPR Art-9. Cue-anchored. Ported health.snomed.",
861
+ "examples": [
862
+ "SNOMED-CT: 44054006"
863
+ ],
864
+ "synthetic_strategy": "faker_id"
865
+ },
866
+ "HEALTH_PRESCRIPTION": {
867
+ "code": "MED_ID",
868
+ "cloud_token_type": "MED_ID",
869
+ "pattern": "(?i)\\b(?:rx|prescription|resept|recept|ordonnance)[:\\s#]+[A-Z0-9\\-]{6,20}",
870
+ "description": "Prescription id. GDPR Art-9. Cue-anchored. Ported health.prescription-id.",
871
+ "examples": [
872
+ "Rx: RX-4472819"
873
+ ],
874
+ "synthetic_strategy": "faker_id"
875
+ },
876
+ "HEALTH_LAB_ORDER": {
877
+ "code": "MED_ID",
878
+ "cloud_token_type": "MED_ID",
879
+ "pattern": "(?i)\\b(?:lab order|accession number|laborder|labid)[:\\s#]+[A-Z0-9\\-]{4,20}",
880
+ "description": "Lab order / accession number. GDPR Art-9. Cue-anchored. Ported health.lab-order.",
881
+ "examples": [
882
+ "accession number: ACC-88213"
883
+ ],
884
+ "synthetic_strategy": "faker_id"
885
+ },
886
+ "BIO_FINGERPRINT": {
887
+ "code": "BIO",
888
+ "cloud_token_type": "BIO",
889
+ "pattern": "(?i)\\b(?:fingerprint(?:[\\s\\-]?hash)?|biometric[\\s\\-]?fingerprint)[:\\s]+[a-f0-9]{64}",
890
+ "description": "Biometric fingerprint hash (64 hex). GDPR Art-9. Cue-anchored. High-entropy value also fail-closes on secrets-first engines (§29). Ported biometric.fingerprint-hash.",
891
+ "examples": [
892
+ "fingerprint hash: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
893
+ ],
894
+ "synthetic_strategy": "block_or_token"
895
+ },
896
+ "BIO_IRIS": {
897
+ "code": "BIO",
898
+ "cloud_token_type": "BIO",
899
+ "pattern": "(?i)\\biris[\\s\\-]?(?:template|code|ref)[:\\s]+[A-Za-z0-9+/=]{32,}",
900
+ "description": "Biometric iris template (base64). GDPR Art-9. Cue-anchored. Ported biometric.iris-template.",
901
+ "examples": [
902
+ "iris template: QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5"
903
+ ],
904
+ "synthetic_strategy": "block_or_token"
905
+ },
906
+ "BIO_GAIT": {
907
+ "code": "BIO",
908
+ "cloud_token_type": "BIO",
909
+ "pattern": "(?i)\\bgait[\\s\\-]?(?:signature|template|ref)[:\\s]+[A-Za-z0-9+/=]{32,}",
910
+ "description": "Biometric gait signature (base64). GDPR Art-9. Cue-anchored. Ported biometric.gait-signature.",
911
+ "examples": [
912
+ "gait signature: MTIzNDU2Nzg5MEFCQ0RFRkdISUpLTE1OT1BRUlNU"
913
+ ],
914
+ "synthetic_strategy": "block_or_token"
915
+ },
916
+ "GPS_COORDS": {
917
+ "code": "GEO_ZIP",
918
+ "cloud_token_type": "GEO_ZIP",
919
+ "pattern": "\\b-?\\d{1,3}\\.\\d{2,8} ?, ?-?\\d{1,3}\\.\\d{2,8}\\b",
920
+ "description": "GPS decimal lat,long coordinate pair (precise location). Distinctive comma-joined decimals. Ported gps-coords. Routed to the geographic/POSTAL bucket in the fasit (a dedicated GEO category is a batch-2 refinement).",
921
+ "examples": [
922
+ "40.7128, -74.0060"
923
+ ],
924
+ "synthetic_strategy": "faker_geo"
925
+ },
926
+ "NID_US_ITIN": {
927
+ "code": "ID_GOV",
928
+ "cloud_token_type": "ID_GOV",
929
+ "pattern": "\\b9\\d{2}-(?:7\\d|8\\d|9[0-46-9])-\\d{4}\\b",
930
+ "description": "US ITIN (9NN-(7x|8x|9x)-NNNN). Track-0c batch-2 partial fix: distinct label (was folded into the SSN shape). Precedes SSN so it wins its own span. Ported gov-id.us.itin.",
931
+ "examples": [
932
+ "912-78-1234"
933
+ ],
934
+ "synthetic_strategy": "faker_national_id"
935
+ },
936
+ "PASSPORT_CUED": {
937
+ "code": "ID_PASS",
938
+ "cloud_token_type": "ID_GOV",
939
+ "pattern": "(?i)\\b(?:passport|travel\\s*documents?|pasaporte|passeport|reisepass|passaporto|여권|パスポート|旅券|паспорт)\\s*(?:(?:no|number|nr|n[o°º]|núm(?:ero)?|numero|номер|番号|번호)[.:#]+\\s*|[:#]\\s*)([A-Z0-9]{6,9})\\b",
940
+ "description": "batch-33 (2026-07-21): CUE-ANCHORED passport detector. A passport/travel-document cue (multilingual: passport/pasaporte/passeport/reisepass/passaporto/여권/パスポート/旅券/паспорт) followed by a number-label (no./number/nr/n°/número/номер/番号/번호) OR a ':'/'#' separator, then a 6-9 char alnum token → cloak. The cue+label IS the precision anchor (a bare 6-9 alnum with NO passport cue does NOT fire), so it universally catches a LABELLED passport of ANY country/format — including interleaved synthetic shapes (A99A99A99, e.g. batch-33 'Passport No.: C36E72T13') that no bare per-country regex covers. Requiring punctuation/number-label after the cue (not a bare space) keeps prose like 'passport approved/nonsense' negative. The cue+label span is absorbed into the redacted ID_GOV span (negligible over-redaction). wasm32-safe (pure regex, no lookaround; Unicode classes only).",
941
+ "examples": [
942
+ "Passport No.: C36E72T13",
943
+ "passport #AB1234567"
944
+ ],
945
+ "synthetic_strategy": "faker_passport"
946
+ },
947
+ "PASSPORT_DE": {
948
+ "code": "ID_GOV",
949
+ "cloud_token_type": "ID_GOV",
950
+ "pattern": "\\b[CFGHJKLMNPRTVWXYZ][CFGHJKLMNPRTVWXYZ0-9]{8}\\b",
951
+ "description": "German passport (9 chars from the restricted DE character set). Track-0c batch-2 partial fix: distinct label (was generic PASSPORT). Ported gov-id.de.passport.",
952
+ "examples": [
953
+ "C01X00T47"
954
+ ],
955
+ "synthetic_strategy": "faker_passport"
956
+ },
957
+ "PASSPORT_FR": {
958
+ "code": "ID_GOV",
959
+ "cloud_token_type": "ID_GOV",
960
+ "pattern": "(?i)\\b\\d{2}[A-Z]{2}\\d{5}\\b",
961
+ "description": "French passport (2 digits + 2 letters + 5 digits). Track-0c batch-2 partial fix: distinct label (was generic PASSPORT). Ported gov-id.fr.passport. 2026-07-14 (P4-fix S3): the letter class was [BCDFGHJKLMNPQRSTVWXZ] (consonants only) which REJECTED the fasit's OWN valid example 12AB34567 (the 'A' is a vowel) — French passport letters are unrestricted A-Z, so the class is now [A-Z] (case-insensitive via the leading (?i)). Shape (2 digits + 2 letters + 5 digits, \\b-anchored) stays distinctive.",
962
+ "examples": [
963
+ "12AB34567"
964
+ ],
965
+ "synthetic_strategy": "faker_passport"
966
+ },
967
+ "ORG_UK_VAT": {
968
+ "code": "ID_ORG",
969
+ "cloud_token_type": "ID_ORG",
970
+ "pattern": "\\bGB[ \\-]?(?:\\d{12}|\\d{9}|GD\\d{3}|HA\\d{3})\\b",
971
+ "description": "UK VAT registration number (was a raw P1 leak — §44e/BLOCKERS). Company/registration number ⇒ ORGNUM. Ported gov-id.uk.vat.",
972
+ "examples": [
973
+ "GB123456789"
974
+ ],
975
+ "synthetic_strategy": "faker_national_id"
976
+ },
977
+ "ORG_EU_VAT": {
978
+ "code": "ID_ORG",
979
+ "cloud_token_type": "ID_ORG",
980
+ "pattern": "\\b(?:ATU\\d{8}|BE[ .\\-]?\\d{9,10}|BG[ .\\-]?\\d{9,10}|CY[ .\\-]?\\d{8}[A-Z]|CZ[ .\\-]?\\d{8,10}|DE[ .\\-]?\\d{9}|DK[ .\\-]?\\d{8}|EE[ .\\-]?\\d{9}|EL[ .\\-]?\\d{9}|ES[ .\\-]?[A-Z0-9]\\d{7}[A-Z0-9]|FI[ .\\-]?\\d{8}|FR[ .\\-]?[0-9A-HJ-NP-Z]{2}\\d{9}|HR[ .\\-]?\\d{11}|HU[ .\\-]?\\d{8}|IE[ .\\-]?(?:\\d{7}[A-Z]{1,2}|\\d[A-Z0-9+*]\\d{5}[A-Z])|IT[ .\\-]?\\d{11}|LT[ .\\-]?(?:\\d{12}|\\d{9})|LU[ .\\-]?\\d{8}|LV[ .\\-]?\\d{11}|MT[ .\\-]?\\d{8}|NL[ .\\-]?\\d{9}B\\d{2}|PL[ .\\-]?\\d{10}|PT[ .\\-]?\\d{9}|RO[ .\\-]?\\d{2,10}|SE[ .\\-]?\\d{12}|SI[ .\\-]?\\d{8}|SK[ .\\-]?\\d{10}|XI[ .\\-]?(?:\\d{12}|\\d{9}))\\b",
981
+ "description": "EU VAT number — format-accurate per-country (all 27 VIES member states + XI Northern Ireland). Each alternative encodes that country's exact national number plan incl. embedded/trailing check LETTERS (ES ESX7412334T, IE 1234567FA, CY 12345678L), the mandatory ATU prefix (AT), and the NL …B01 suffix — the prior generic `CC\\d{7,12}` under-matched all of these (batch-30c leaks ES/NL/AT/IE/CY). The 2-letter ISO country code is the precision anchor (inherently distinctive, near-zero FP), so no checksum gate is applied — a wrong checksum would false-negative a valid VAT (a leak). FR check chars exclude I/O so a word like FROM/FRONT cannot match.",
982
+ "examples": [
983
+ "DE123456789",
984
+ "FR12345678901",
985
+ "ATU12345678",
986
+ "NL123456789B01"
987
+ ],
988
+ "synthetic_strategy": "faker_national_id"
989
+ },
990
+ "ORG_NO_VAT": {
991
+ "code": "ID_ORG",
992
+ "cloud_token_type": "ID_ORG",
993
+ "pattern": "(?i)\\b(?:\\d{9}[ .\\-]?MVA|MVA[ :.#\\-]{1,3}\\d{9})\\b",
994
+ "description": "Norwegian VAT (organisasjonsnummer + MVA suffix, e.g. 123456789 MVA). The MVA token is the distinctive anchor (batch-30c leaked the bare `NNNNNNNNN MVA` form — the EU-VAT regex has no NO prefix since Norway is non-EU). Cue-or-suffix-anchored, no checksum (avoids false-negative leaks on structurally-valid-but-non-mod11 stress values).",
995
+ "examples": [
996
+ "123456789 MVA",
997
+ "MVA: 987654325"
998
+ ],
999
+ "synthetic_strategy": "faker_national_id"
1000
+ },
1001
+ "ORG_CH_VAT": {
1002
+ "code": "ID_ORG",
1003
+ "cloud_token_type": "ID_ORG",
1004
+ "pattern": "(?i)\\bCHE[ \\-]?\\d{3}\\.?\\d{3}\\.?\\d{3}(?:[ ]?(?:MWST|TVA|IVA|VAT))?\\b",
1005
+ "description": "Swiss VAT / UID (CHE-123.456.789 [MWST/TVA/IVA]). The CHE prefix is the distinctive anchor.",
1006
+ "examples": [
1007
+ "CHE-123.456.789 MWST"
1008
+ ],
1009
+ "synthetic_strategy": "faker_national_id"
1010
+ },
1011
+ "ORG_AU_ABN": {
1012
+ "code": "ID_ORG",
1013
+ "cloud_token_type": "ID_ORG",
1014
+ "pattern": "\\b\\d{2}[ ]?\\d{3}[ ]?\\d{3}[ ]?\\d{3}\\b",
1015
+ "description": "Australian Business Number (11 digits, grouped 2-3-3-3). Bare numeric with no distinctive prefix, so precision is enforced by the ABN mod-89 weighted checksum (au_abn) — a random 11-digit run passes ~1/89, and PHONE (last in precedence) claims any run the checksum rejects.",
1016
+ "examples": [
1017
+ "51 824 753 556"
1018
+ ],
1019
+ "checksum": "au_abn",
1020
+ "synthetic_strategy": "faker_national_id"
1021
+ },
1022
+ "ORG_NO_ORG": {
1023
+ "code": "ID_ORG",
1024
+ "cloud_token_type": "ID_ORG",
1025
+ "pattern": "\\b[89]\\d{2}[ ]?\\d{3}[ ]?\\d{3}\\b",
1026
+ "description": "Norwegian organisasjonsnummer (9 digits starting 8/9). Track-0c batch-2 mod-11 checksum. Ported gov-id.no.org.",
1027
+ "examples": [
1028
+ "987 654 325"
1029
+ ],
1030
+ "checksum": "no_org",
1031
+ "synthetic_strategy": "faker_national_id"
1032
+ },
1033
+ "ORG_BR_CNPJ": {
1034
+ "code": "ID_ORG",
1035
+ "cloud_token_type": "ID_ORG",
1036
+ "pattern": "\\b\\d{2}\\.\\d{3}\\.\\d{3}/\\d{4}-\\d{2}\\b",
1037
+ "description": "Brazilian CNPJ, formatted NN.NNN.NNN/NNNN-NN. Distinctive punctuation. Ported gov-id.br.cnpj.",
1038
+ "examples": [
1039
+ "12.345.678/0001-95"
1040
+ ],
1041
+ "synthetic_strategy": "faker_national_id"
1042
+ },
1043
+ "ORG_IN_GSTIN": {
1044
+ "code": "ID_ORG",
1045
+ "cloud_token_type": "ID_ORG",
1046
+ "pattern": "\\b\\d{2}[A-Z]{5}\\d{4}[A-Z][A-Z0-9]Z[A-Z0-9]\\b",
1047
+ "description": "Indian GSTIN (2-digit state + PAN + entity + Z + check). Distinctive. Ported gov-id.in.gstin.",
1048
+ "examples": [
1049
+ "27AAPFU0939F1ZV"
1050
+ ],
1051
+ "synthetic_strategy": "faker_national_id"
1052
+ },
1053
+ "ORG_CH_UID": {
1054
+ "code": "ID_ORG",
1055
+ "cloud_token_type": "ID_ORG",
1056
+ "pattern": "\\bCHE[- ]?\\d{3}[. ]?\\d{3}[. ]?\\d{3}(?: ?(?:MWST|TVA|IVA|HR))?\\b",
1057
+ "description": "Swiss UID (CHE-NNN.NNN.NNN, optional MWST/TVA suffix). CHE prefix is distinctive. Ported gov-id.ch.uid.",
1058
+ "examples": [
1059
+ "CHE-123.456.788 MWST"
1060
+ ],
1061
+ "synthetic_strategy": "faker_national_id"
1062
+ },
1063
+ "ORG_DE_HRB": {
1064
+ "code": "ID_ORG",
1065
+ "cloud_token_type": "ID_ORG",
1066
+ "pattern": "\\bHR[AB] ?\\d{1,6}(?: [A-Z])?\\b",
1067
+ "description": "German Handelsregister number (HRA/HRB + up to 6 digits). Distinctive. Ported gov-id.de.handelsregister.",
1068
+ "examples": [
1069
+ "HRB 12345"
1070
+ ],
1071
+ "synthetic_strategy": "faker_national_id"
1072
+ },
1073
+ "ORG_DK_CVR": {
1074
+ "code": "ID_ORG",
1075
+ "cloud_token_type": "ID_ORG",
1076
+ "pattern": "(?i)\\bcvr(?:-?nr\\.?|-?nummer)?[:\\s#]{0,3}\\d{8}\\b",
1077
+ "description": "Danish CVR (8 digits). Cue-anchored + Track-0c batch-2 mod-11 checksum. Ported gov-id.dk.cvr.",
1078
+ "examples": [
1079
+ "CVR-nr: 12345674"
1080
+ ],
1081
+ "checksum": "dk_cvr",
1082
+ "synthetic_strategy": "faker_national_id"
1083
+ },
1084
+ "ORG_SE_ORGNR": {
1085
+ "code": "ID_ORG",
1086
+ "cloud_token_type": "ID_ORG",
1087
+ "pattern": "\\b\\d{6}-\\d{4}\\b",
1088
+ "description": "Swedish organisationsnummer, formatted NNNNNN-NNNN. Track-0c batch-2 Luhn checksum (also filters bare 6-4 collisions). Ported gov-id.se.orgnr.",
1089
+ "examples": [
1090
+ "556037-7631"
1091
+ ],
1092
+ "checksum": "luhn",
1093
+ "synthetic_strategy": "faker_national_id"
1094
+ },
1095
+ "ORG_FI_YTUNNUS": {
1096
+ "code": "ID_ORG",
1097
+ "cloud_token_type": "ID_ORG",
1098
+ "pattern": "\\b\\d{7}-\\d\\b",
1099
+ "description": "Finnish Y-tunnus (business id, NNNNNNN-N). Track-0c batch-2 mod-11 (weights 7,9,10,5,8,4,2) checksum. Ported gov-id.fi.ytunnus.",
1100
+ "examples": [
1101
+ "1234567-1"
1102
+ ],
1103
+ "checksum": "fi_ytunnus",
1104
+ "synthetic_strategy": "faker_national_id"
1105
+ },
1106
+ "ORG_NL_KVK": {
1107
+ "code": "ID_ORG",
1108
+ "cloud_token_type": "ID_ORG",
1109
+ "pattern": "(?i)\\b(?:kvk(?:-?nummer|-?nr\\.?)?|kamer van koophandel)[:\\s#]{0,3}\\d{8}\\b",
1110
+ "description": "Dutch KvK number (8 digits). Cue-anchored. Ported gov-id.nl.kvk.",
1111
+ "examples": [
1112
+ "KvK 12345678"
1113
+ ],
1114
+ "synthetic_strategy": "faker_national_id"
1115
+ },
1116
+ "ORG_UK_COMPANIES_HOUSE": {
1117
+ "code": "ID_ORG",
1118
+ "cloud_token_type": "ID_ORG",
1119
+ "pattern": "(?i)\\b(?:companies\\s?house|company (?:number|registration number))[:\\s#]{1,3}(?:\\d{8}|(?:SC|NI|OC|SO|NC|FC)\\d{6})\\b|\\b(?:SC|NI|OC|SO|NC|FC)\\d{6}\\b",
1120
+ "description": "UK Companies House number (8 digits, or SC/NI/OC/… + 6 digits). Cue-anchored or distinctive prefix. Ported gov-id.uk.companies-house.",
1121
+ "examples": [
1122
+ "SC123456",
1123
+ "Companies House 01234567"
1124
+ ],
1125
+ "synthetic_strategy": "faker_national_id"
1126
+ },
1127
+ "FIN_BIC_SWIFT": {
1128
+ "code": "FIN_ACCT",
1129
+ "cloud_token_type": "FIN_ACCT",
1130
+ "pattern": "\\b[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\\b",
1131
+ "description": "BIC / SWIFT code (4 bank + 2 country + 2 location + optional 3 branch). Ported financial bic-swift.",
1132
+ "examples": [
1133
+ "DEUTDEFF",
1134
+ "NEDSZAJJXXX"
1135
+ ],
1136
+ "synthetic_strategy": "faker_iban"
1137
+ },
1138
+ "FIN_ABA_ROUTING": {
1139
+ "code": "FIN_ACCT",
1140
+ "cloud_token_type": "FIN_ACCT",
1141
+ "pattern": "(?i)\\b(?:aba|routing(?: number| no\\.?| transit)?)[:\\s#]{1,4}\\d{9}\\b",
1142
+ "description": "US ABA routing / transit number (9 digits). Cue-anchored (bare 9-digit collides with SSN). Ported financial aba-routing.",
1143
+ "examples": [
1144
+ "ABA 021000021"
1145
+ ],
1146
+ "synthetic_strategy": "faker_iban"
1147
+ },
1148
+ "FIN_UK_SORT_ACCOUNT": {
1149
+ "code": "FIN_ACCT",
1150
+ "cloud_token_type": "FIN_ACCT",
1151
+ "pattern": "\\b\\d{2}-\\d{2}-\\d{2}[ ,]{1,3}\\d{8}\\b|(?i:\\bsort\\s?code[:\\s#]{1,3}\\d{2}-\\d{2}-\\d{2}\\b)",
1152
+ "description": "UK sort code (NN-NN-NN) + 8-digit account, or a cue-anchored sort code alone. Ported financial uk.sort-account.",
1153
+ "examples": [
1154
+ "12-34-56 12345678"
1155
+ ],
1156
+ "synthetic_strategy": "faker_iban"
1157
+ },
1158
+ "FIN_NO_ACCOUNT": {
1159
+ "code": "FIN_ACCT",
1160
+ "cloud_token_type": "FIN_ACCT",
1161
+ "pattern": "\\b\\d{4}[.\\s]\\d{2}[.\\s]\\d{5}\\b",
1162
+ "description": "Norwegian bank account number (NNNN.NN.NNNNN). Distinctive grouping. Ported financial account.no.",
1163
+ "examples": [
1164
+ "1234.56.78903"
1165
+ ],
1166
+ "synthetic_strategy": "faker_iban"
1167
+ },
1168
+ "FIN_NO_KID": {
1169
+ "code": "FIN_ACCT",
1170
+ "cloud_token_type": "FIN_ACCT",
1171
+ "pattern": "(?i)\\bKID(?:[\\s\\-]?nr\\.?)?[:\\s]+\\d{2,25}\\b",
1172
+ "description": "Norwegian KID payment reference. Cue-anchored. Ported financial kid.no.",
1173
+ "examples": [
1174
+ "KID: 1234567890128"
1175
+ ],
1176
+ "synthetic_strategy": "faker_iban"
1177
+ },
1178
+ "FIN_CRYPTO_BTC": {
1179
+ "code": "FIN_ACCT",
1180
+ "cloud_token_type": "FIN_ACCT",
1181
+ "pattern": "\\b(?:[13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[ac-hj-np-z02-9]{25,87})\\b",
1182
+ "description": "Bitcoin wallet address (P2PKH/P2SH Base58 or Bech32 SegWit). Ported financial crypto.btc.",
1183
+ "examples": [
1184
+ "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
1185
+ "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
1186
+ ],
1187
+ "synthetic_strategy": "block_or_token"
1188
+ },
1189
+ "FIN_CRYPTO_ETH": {
1190
+ "code": "FIN_ACCT",
1191
+ "cloud_token_type": "FIN_ACCT",
1192
+ "pattern": "\\b0x[a-fA-F0-9]{40}\\b",
1193
+ "description": "Ethereum / EVM wallet address (0x + 40 hex). Ported financial crypto.eth.",
1194
+ "examples": [
1195
+ "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
1196
+ ],
1197
+ "synthetic_strategy": "block_or_token"
1198
+ },
1199
+ "FIN_CRYPTO_STABLE": {
1200
+ "code": "FIN_ACCT",
1201
+ "cloud_token_type": "FIN_ACCT",
1202
+ "pattern": "(?i)\\b(?:USDC|USDT|DAI|BUSD)[\\s:\\-]+0x[a-fA-F0-9]{40}\\b",
1203
+ "description": "Stablecoin-labelled wallet address (USDC/USDT/DAI/BUSD + 0x…). Ported financial crypto.stable.",
1204
+ "examples": [
1205
+ "USDC: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
1206
+ ],
1207
+ "synthetic_strategy": "block_or_token"
1208
+ },
1209
+ "FIN_ACCOUNT_CUED": {
1210
+ "code": "FIN_ACCT",
1211
+ "cloud_token_type": "FIN_ACCT",
1212
+ "pattern": "(?i)\\b(?:acct|acc|account|a/c)\\.?\\s*(?:no\\.?|number|nr\\.?|#)?\\s*[:#]?\\s*\\d{2,6}(?:[\\-\\s.]\\d{2,6}){1,4}\\b",
1213
+ "description": "Generic CUE-ANCHORED bank/ledger account number: the word acct/account/a-c followed by a grouped digit run. ⛔ sak 98B (2026-08-10): `Acct 4402-7719-0032` (marketing page `accountants`) and `Acct 7719-4402-0032` (`financial-advisors`) had NO account detector at all — they fell through to the greedy PHONE grouped branch and were masked as TELEPHONE NUMBERS in the served engine 712c40f8 and the candidate 4650d35e alike. Surrogate class is the promise: an account number that comes back as a phone number is misinformation wearing anonymisation's clothes. FIN_* routes to EntityType::Iban by prefix in pipeline.rs, so this is a DATA-ONLY addition — no engine code changes (the `add_once_lights_up_registry` proof). Ranked with the other FIN_* rails, far ahead of PHONE (§44e). Measured false positives against 433 975 lines of real third-party prose, own docs and source code: 0. The cue is required precisely because a bare grouped run is indistinguishable from a part number.",
1214
+ "examples": [
1215
+ "Acct 4402-7719-0032",
1216
+ "Account no. 1234-5678-9012",
1217
+ "a/c 12 345 678"
1218
+ ],
1219
+ "synthetic_strategy": "faker_iban"
1220
+ },
1221
+ "POSTAL_UK": {
1222
+ "code": "GEO_ZIP",
1223
+ "cloud_token_type": "GEO_ZIP",
1224
+ "pattern": "\\b(?:GIR ?0AA|[A-Z]{1,2}\\d[A-Z\\d]? ?\\d[A-Z]{2})\\b",
1225
+ "description": "UK postcode (e.g. SW1A 1AA). Distinctive. Ported postal-code.uk.",
1226
+ "examples": [
1227
+ "SW1A 1AA",
1228
+ "EC1A 1BB"
1229
+ ],
1230
+ "synthetic_strategy": "faker_zip"
1231
+ },
1232
+ "POSTAL_CA": {
1233
+ "code": "GEO_ZIP",
1234
+ "cloud_token_type": "GEO_ZIP",
1235
+ "pattern": "\\b[ABCEGHJ-NPRSTVXY]\\d[A-CEGHJ-NPRSTV-Z][ -]?\\d[A-CEGHJ-NPRSTV-Z]\\d\\b",
1236
+ "description": "Canadian postal code (A1A 1A1). Distinctive. Ported postal-code.ca.",
1237
+ "examples": [
1238
+ "K1A 0B1"
1239
+ ],
1240
+ "synthetic_strategy": "faker_zip"
1241
+ },
1242
+ "POSTAL_IE": {
1243
+ "code": "GEO_ZIP",
1244
+ "cloud_token_type": "GEO_ZIP",
1245
+ "pattern": "\\b(?:D6W|[AC-FHKNPRTV-Y]\\d{2}) ?[AC-FHKNPRTV-Y0-9]{4}\\b",
1246
+ "description": "Irish Eircode. Distinctive. Ported postal-code.ie.",
1247
+ "examples": [
1248
+ "D02 AF30"
1249
+ ],
1250
+ "synthetic_strategy": "faker_zip"
1251
+ },
1252
+ "POSTAL_NL": {
1253
+ "code": "GEO_ZIP",
1254
+ "cloud_token_type": "GEO_ZIP",
1255
+ "pattern": "\\b[1-9]\\d{3} ?[A-Z]{2}\\b",
1256
+ "description": "Dutch postcode (1234 AB). Distinctive. Ported postal-code.nl (the (?!SA|SD|SS) lookahead is dropped — Rust regex has no lookahead; the false-suffix cost is negligible over-redaction).",
1257
+ "examples": [
1258
+ "1012 AB"
1259
+ ],
1260
+ "synthetic_strategy": "faker_zip"
1261
+ },
1262
+ "POSTAL_JP": {
1263
+ "code": "GEO_ZIP",
1264
+ "cloud_token_type": "GEO_ZIP",
1265
+ "pattern": "\\u3012 ?\\d{3}-?\\d{4}|(?i:\\b(?:postal code|yubin)[:\\s]+\\d{3}-?\\d{4}\\b)",
1266
+ "description": "Japanese postal code (〒123-4567). 〒-prefixed or cue-anchored (bare 3-4 digit form is dropped — it collides with phones). Ported postal-code.jp.",
1267
+ "examples": [
1268
+ "〒123-4567"
1269
+ ],
1270
+ "synthetic_strategy": "faker_zip"
1271
+ },
1272
+ "POSTAL_PT": {
1273
+ "code": "GEO_ZIP",
1274
+ "cloud_token_type": "GEO_ZIP",
1275
+ "pattern": "(?i)\\b(?:c[o\u00f3]digo\\s?postal|cod\\.?\\s?postal|postal\\s?code)\\s*[:#]?\\s*\\d{4}-\\d{3}\\b|\\b\\d{4}-\\d{3}\\s*,?\\s+(?:Lisboa|Lisbon|Porto|Braga|Coimbra|Faro|Funchal|Aveiro|Set\u00fabal|Setubal|Cascais|Sintra|Guimar\u00e3es|Guimaraes|Bragan\u00e7a|Braganca|\u00c9vora|Evora|Leiria|Viseu|Santar\u00e9m|Santarem|Portim\u00e3o|Portimao|Amadora|Almada|Barreiro|Matosinhos|Vila Nova de Gaia|Odivelas|Loures|Oeiras|Maia|Gondomar|Viana do Castelo|Ponta Delgada)\\b|\\b(?:Lisboa|Lisbon|Porto|Braga|Coimbra|Faro|Funchal|Aveiro|Set\u00fabal|Setubal|Cascais|Sintra|Guimar\u00e3es|Guimaraes|Bragan\u00e7a|Braganca|\u00c9vora|Evora|Leiria|Viseu|Santar\u00e9m|Santarem|Portim\u00e3o|Portimao|Amadora|Almada|Barreiro|Matosinhos|Vila Nova de Gaia|Odivelas|Loures|Oeiras|Maia|Gondomar|Viana do Castelo|Ponta Delgada)\\s*,?\\s+\\d{4}-\\d{3}\\b",
1276
+ "description": "Portuguese postal code (NNNN-NNN), CUE- or CITY-anchored. Ported postal-code.pt. ⛔ sak 98B (2026-08-10): the pattern was the bare \\b\\d{4}-\\d{3}\\b. NNNN-NNN is not a distinctive shape — it is the shape of every advisory id, engagement code and year-sequence reference. Measured against 433 975 lines of real third-party text: 16 matches, 16 of them FALSE (GHSL-2021-045, GStreamer-SA-2024-001, ocert-2011-003) and 0 true. On the auditors vertical the demo value `Engagement 2025-114` resolved to POSTAL_PT in the SERVED engine 712c40f8 — a Portuguese postcode surrogate standing in for an audit engagement number. The rest of this family (POSTAL_DE, POSTAL_NO, POSTAL_EU, POSTAL_JP) already requires a cue or a city for a digits-only code; POSTAL_PT was the outlier. Cue and city coverage is unchanged and is additionally carried by POSTAL_CUE_ANCHORED and POSTAL_CITY_ANCHORED, which both already list \\d{4}-\\d{3}. Cost: a BARE `1000-001` with no cue and no city is no longer detected. That is the same trade POSTAL_DE/NO/EU/JP already make.",
1277
+ "examples": [
1278
+ "1000-001"
1279
+ ],
1280
+ "synthetic_strategy": "faker_zip"
1281
+ },
1282
+ "POSTAL_PL": {
1283
+ "code": "GEO_ZIP",
1284
+ "cloud_token_type": "GEO_ZIP",
1285
+ "pattern": "(?i)\\bkod pocztowy[:\\s#]{1,3}\\d{2}-\\d{3}\\b|\\b\\d{2}-\\d{3}\\s*,?\\s+(?:Warszawa|Warsaw|Krak\u00f3w|Krakow|\u0141\u00f3d\u017a|Lodz|Wroc\u0142aw|Wroclaw|Pozna\u0144|Poznan|Gda\u0144sk|Gdansk|Szczecin|Bydgoszcz|Lublin|Bia\u0142ystok|Bialystok|Katowice|Gdynia|Cz\u0119stochowa|Czestochowa|Radom|Toru\u0144|Torun|Sosnowiec|Rzesz\u00f3w|Rzeszow|Kielce|Gliwice|Olsztyn|Zabrze|Bielsko-Bia\u0142a|Bielsko-Biala)\\b|\\b(?:Warszawa|Warsaw|Krak\u00f3w|Krakow|\u0141\u00f3d\u017a|Lodz|Wroc\u0142aw|Wroclaw|Pozna\u0144|Poznan|Gda\u0144sk|Gdansk|Szczecin|Bydgoszcz|Lublin|Bia\u0142ystok|Bialystok|Katowice|Gdynia|Cz\u0119stochowa|Czestochowa|Radom|Toru\u0144|Torun|Sosnowiec|Rzesz\u00f3w|Rzeszow|Kielce|Gliwice|Olsztyn|Zabrze|Bielsko-Bia\u0142a|Bielsko-Biala)\\s*,?\\s+\\d{2}-\\d{3}\\b",
1286
+ "description": "Polish postal code (NN-NNN), CUE- or CITY-anchored. Ported postal-code.pl. ⛔ sak 98B (2026-08-10): the bare \\b\\d{2}-\\d{3}\\b branch is the same defect class as POSTAL_PT and is measurably worse. Against 433 975 lines of real text it matched 41 lines, 41 of them FALSE and 0 true — source line ranges (`ReceiptSigner.php:97-105`), head-count bands (`50-300 employee`), benchmark names (`tessellate-64-100`), FAR clause `12-212`. Measured END TO END on the SERVED engine 712c40f8: «We are a 50-300 employee health-tech company» went upstream as «We are a 09-347 employee health-tech company». That is not anonymisation, it is a silently corrupted fact. Cue coverage is unchanged; city coverage is added here and already exists in POSTAL_CUE_ANCHORED and POSTAL_CITY_ANCHORED, which both list \\d{2}-\\d{3}.",
1287
+ "examples": [
1288
+ "00-950"
1289
+ ],
1290
+ "synthetic_strategy": "faker_zip"
1291
+ },
1292
+ "POSTAL_NO": {
1293
+ "code": "GEO_ZIP",
1294
+ "cloud_token_type": "GEO_ZIP",
1295
+ "pattern": "(?i)\\b(?:postnummer|postnr|postcode)[:\\s]+\\d{4}\\b|\\b\\d{4}\\s+(?:Oslo|Bergen|Trondheim|Stavanger|Troms\\u00f8|Drammen|Kristiansand)\\b",
1296
+ "description": "Norwegian postnummer (4 digits). Cue-anchored or followed by a major city (bare 4-digit is far too generic). Ported postal-code.no.",
1297
+ "examples": [
1298
+ "postnummer: 0150",
1299
+ "0150 Oslo"
1300
+ ],
1301
+ "synthetic_strategy": "faker_zip"
1302
+ },
1303
+ "POSTAL_DE": {
1304
+ "code": "GEO_ZIP",
1305
+ "cloud_token_type": "GEO_ZIP",
1306
+ "pattern": "(?i)\\b(?:PLZ|Postleitzahl)[:\\s]+\\d{5}\\b|\\b\\d{5}\\s+(?:Berlin|Hamburg|M\\u00fcnchen|K\\u00f6ln|Frankfurt|Stuttgart)\\b",
1307
+ "description": "German Postleitzahl (5 digits). Cue-anchored or followed by a major city. Ported postal-code.de.",
1308
+ "examples": [
1309
+ "PLZ: 10115",
1310
+ "10115 Berlin"
1311
+ ],
1312
+ "synthetic_strategy": "faker_zip"
1313
+ },
1314
+ "POSTAL_EU": {
1315
+ "code": "GEO_ZIP",
1316
+ "cloud_token_type": "GEO_ZIP",
1317
+ "pattern": "(?i)\\b(?:postal code|post code|c\\u00f3digo postal|code postal)[:\\s#]{1,3}\\d{4,5}\\b",
1318
+ "description": "Generic EU postal code, cue-anchored (bare 4–5 digit is ambiguous). Ported postal-code.eu-city.",
1319
+ "examples": [
1320
+ "postal code: 75008"
1321
+ ],
1322
+ "synthetic_strategy": "faker_zip"
1323
+ },
1324
+ "POSTAL_CITY_ANCHORED": {
1325
+ "code": "GEO_ZIP",
1326
+ "cloud_token_type": "GEO_ZIP",
1327
+ "pattern": "(?i)\\b(?:San Miguel de Tucumán|La Chaux-de-Fonds|Nakhon Ratchasima|Clermont-Ferrand|Ho Chi Minh City|Palmerston North|Saint Petersburg|České Budějovice|Aix-en-Provence|Banská Bystrica|Nizhny Novgorod|Wiener Neustadt|Belo Horizonte|Hradec Králové|Port Elizabeth|Punta del Este|Ras Al Khaimah|Rio de Janeiro|S\\\\u00e3o Paulo|Slavonski Brod|Ústí nad Labem|Beverly Hills|Buon Ma Thuot|Kota Kinabalu|Mar del Plata|Petaling Jaya|Port Harcourt|Rishon LeZion|Rostov-on-Don|Saint-Étienne|San Francisco|San Sebastián|Buenos Aires|Kohtla-Järve|Kuala Lumpur|Porto Alegre|Sankt Pölten|Stara Zagora|Viña del Mar|Cluj-Napoca|East London|George Town|Johor Bahru|João Pessoa|Kansas City|Kuwait City|Las Piedras|Los Angeles|Mexico City|New Orleans|Nova Gorica|Petah Tikva|Quebec City|Quezon City|San Antonio|Santa Marta|Târgu Mureș|Benin City|Cape Coast|Chiang Mai|Kryvyi Rih|Novo Mesto|Udon Thani|Abu Dhabi|Cape Town|Hong Kong|Khon Kaen|La Serena|Las Vegas|New Delhi|Nha Trang|Port Said|Ramat Gan|San Diego|Sao Paulo|Shah Alam|St\\. Louis|The Hague|A Coruña|Bien Hoa|Den Haag|La Plata|Le Havre|New York|Novi Sad|San Jose|San Juan|Santa Fe|Tel Aviv|Vung Tau|Can Tho|Da Nang|Hat Yai|Al Ain|Pietermaritzburg|Aguascalientes|Székesfehérvár|Bras\\\\u00edlia|Florianópolis|Frederiksberg|Villavicencio|Yekaterinburg|Barranquilla|Bloemfontein|Christchurch|Indianapolis|Jacksonville|Johannesburg|Kristiansand|Lappeenranta|M\\\\u00fcnchen|Philadelphia|Schaffhausen|Stellenbosch|Thessaloniki|Villeurbanne|Zaporizhzhia|Albuquerque|Antofagasta|Bogot\\\\u00e1|Bucaramanga|Chelyabinsk|Constantine|Częstochowa|Fredrikstad|Guadalajara|Helsingborg|Krak\\\\u00f3w|Krasnoyarsk|Lillehammer|Marijampolė|Minneapolis|Mississauga|Montpellier|Novosibirsk|Nyíregyháza|Resistencia|Southampton|Szombathely|Vladivostok|Z\\\\u00fcrich|Alexandria|Amersfoort|Batticaloa|Biratnagar|Birmingham|Bratislava|Casablanca|Chattogram|Chittagong|Cincinnati|Coimbatore|Concepcion|Concepción|Copenhagen|Daugavpils|Diyarbakır|Dusseldorf|Düsseldorf|Faisalabad|Gothenburg|Gujranwala|Hermosillo|Kermanshah|Kitakyushu|Klagenfurt|Kragujevac|Luxembourg|Maastricht|Manchester|Mawlamyine|Montevideo|Mymensingh|Nonthaburi|Norrköping|Nottingham|Pittsburgh|Portsmouth|Queenstown|Rawalpindi|Sacramento|Sandefjord|Strasbourg|Sunderland|Townsville|Valparaiso|Valparaíso|Washington|Wellington|Winterthur|Wollongong|Yogyakarta|Ahmedabad|Amsterdam|Antwerpen|Apeldoorn|Baltimore|Bangalore|Barcelona|Beersheba|Bengaluru|Bharatpur|Białystok|Bielefeld|Bucharest|Bydgoszcz|Cambridge|Cartagena|Charleroi|Charlotte|Chihuahua|Chongqing|Cleveland|Constanta|Constanța|Dubrovnik|Edinburgh|Eindhoven|Eskişehir|Faridabad|Fortaleza|Frankfurt|Gaziantep|Ghaziabad|Groningen|Guangzhou|Guarulhos|Guimarães|Hamamatsu|Haugesund|Helsingør|Heraklion|Hiroshima|Hyderabad|Innsbruck|Islamabad|Jerusalem|Jyväskylä|Jönköping|Karlsruhe|Kecskemét|Kimberley|Kitchener|Krasnodar|Leicester|Linköping|Liverpool|Ljubljana|Maldonado|Manizales|Marrakech|Marrakesh|Marseille|Melbourne|Milwaukee|Monterrey|Nashville|Naypyidaw|Nelspruit|Neuchâtel|Newcastle|Nuremberg|Palembang|Panevėžys|Pardubice|Polokwane|Querétaro|Rotterdam|Rovaniemi|Salamanca|Santander|Sarpsborg|Saskatoon|Sheffield|Singapore|Sosnowiec|Stavanger|Stockholm|Stuttgart|Sundsvall|Tangerang|Tatabánya|Timisoara|Timișoara|Toowoomba|Trondheim|Vancouver|Ventspils|Vinnytsia|Volgograd|Waterford|Wiesbaden|Wuppertal|Zamboanga|Zhengzhou|Zrenjanin|Aberdeen|Adelaide|Alicante|Amritsar|Antipolo|Arequipa|Auckland|Augsburg|Ballarat|Belgrade|Bordeaux|Brampton|Brasilia|Brasília|Brighton|Brisbane|Brussels|Budapest|Buraidah|Caloocan|Campinas|Canberra|Changsha|Changwon|Cheongju|Chiclayo|Chimbote|Columbus|Coventry|Culiacán|Curitiba|Debrecen|Denpasar|Dongguan|Dornbirn|Dortmund|Drogheda|Duisburg|Edmonton|Enschede|Florence|Freiburg|Fribourg|Fujairah|Gatineau|Gentofte|Grenoble|Göteborg|Haiphong|Hamilton|Hangzhou|Hannover|Helsinki|Herzliya|Huancayo|Ioannina|Istanbul|Kairouan|Kalamata|Kanazawa|Kaposvár|Karlovac|Katowice|Kawasaki|Kilkenny|Klaipėda|Kortrijk|Kraljevo|Kumamoto|Lalitpur|Lausanne|Limerick|Ludhiana|Makassar|Mandalay|Mannheim|Mansoura|Mariupol|Mechelen|Medellin|Mexicali|Montreal|Mykolaiv|Nagasaki|Nazareth|Nijmegen|Nürnberg|Oostende|Pamplona|Paysandú|Peshawar|Ploiești|Plymouth|Portland|Pretoria|Rajshahi|Rancagua|Roskilde|Saltillo|Salvador|Salzburg|Santiago|Semarang|Seongnam|Shanghai|Shenyang|Shenzhen|Shizuoka|Subotica|Surabaya|Szczecin|Takoradi|Tauranga|Toulouse|Trujillo|Vadodara|Valencia|Valletta|Varanasi|Varaždin|Veszprém|Victoria|Viljandi|Voronezh|Västerås|Winnipeg|Yokohama|Zaragoza|Šiauliai|Aalborg|Alkmaar|Antalya|Antwerp|Atlanta|Bacolod|Bandung|Bangkok|Beijing|Belfast|Bendigo|Beograd|Bergamo|Bizerte|Bologna|Bregenz|Brescia|Bristol|Calgary|Caracas|Cardiff|Cascais|Catania|Chengdu|Chennai|Chicago|Coimbra|Cologne|Colombo|Comilla|Cordoba|Craiova|Córdoba|Daejeon|Denizli|Detroit|Dobrich|Donetsk|Drammen|Dresden|Dundalk|Dunedin|Eldoret|Esbjerg|Esfahan|Firenze|Fukuoka|Funchal|Geelong|Glasgow|Goiânia|Granada|Gwangju|Haarlem|Halifax|Hamburg|Herning|Horsens|Houston|Incheon|Iquique|Iquitos|Iraklio|Isfahan|Jakarta|Jelgava|Joensuu|Jūrmala|Karachi|Kayseri|Kenitra|Kharkiv|Kolding|Kolkata|Kuching|Kunming|Larissa|Leipzig|Liberec|Liepāja|Lucerne|Lucknow|Malacca|Maribor|Mashhad|Memphis|Mendoza|Miskolc|Mombasa|Morelia|Münster|Nairobi|Nanjing|Negombo|Netanya|Neuquén|Nicosia|Niigata|Norwich|Okayama|Olomouc|Onitsha|Orlando|Ostrava|Palermo|Pančevo|Pattaya|Pereira|Phoenix|Piraeus|Plovdiv|Pokhara|Qingdao|Randers|Rangpur|Rosario|Rotorua|Rzeszów|Rēzekne|Saitama|Sandnes|Sapporo|Seattle|Setúbal|Sevilla|Seville|Sharjah|Sialkot|Swansea|Szolnok|Tallinn|Tampere|Tangier|Tetouan|Tianjin|Tijuana|Tilburg|Toronto|Trabzon|Trenčín|Trieste|Uppsala|Utrecht|Velenje|Venezia|Villach|Vilnius|Vitoria|Vitória|Windsor|Wroclaw|Wrocław|Zapopan|Ålesund|Šibenik|Aachen|Aarhus|Agadir|Almere|Alytus|Angers|Ankara|Annaba|Arnhem|Ashdod|Athens|Austin|Aveiro|Baguio|Bekasi|Bergen|Berlin|Bhopal|Bilbao|Bochum|Bogota|Boston|Brasov|Brașov|Bremen|Bruges|Brugge|Brăila|Burgas|Cairns|Cancun|Cancún|Chania|Cúcuta|Dalian|Dallas|Dammam|Darwin|Denver|Dnipro|Dublin|Durban|Foshan|Fresno|Galați|Galway|Gdansk|Gdańsk|Gdynia|Geneva|Genova|Gjøvik|Goyang|Harbin|Hobart|Ibadan|Ibagué|Iloilo|Ilorin|Indore|Jaffna|Jaipur|Jeddah|Jeonju|Juárez|Kaduna|Kanpur|Kaunas|Kavala|Khobar|Khulna|Kisumu|Kladno|Kosice|Košice|Krakow|Kumasi|Kuopio|Lahore|Leiden|Leuven|Lisbon|London|Lublin|Lugano|Luzern|Maceió|Madrid|Makati|Makkah|Malaga|Malang|Manaus|Manila|Martin|Medina|Meerut|Meknes|Melaka|Merida|Mersin|Modena|Moscow|Multan|Mumbai|Munich|Málaga|Mérida|Nagoya|Nagpur|Nakuru|Nantes|Napier|Naples|Nashik|Ningbo|Odense|Odessa|Oradea|Osijek|Ottawa|Oxford|Padova|Patras|Pernik|Phuket|Pilsen|Pleven|Poprad|Poznan|Poznań|Prague|Prešov|Puebla|Quetta|Rajkot|Recife|Regina|Rennes|Rhodes|Rijeka|Riyadh|Samara|Samsun|Sendai|Shiraz|Shumen|Sintra|Sliven|Sousse|Soweto|Surrey|Suzhou|Swords|Sydney|Sylhet|Szeged|Tabriz|Taguig|Taipei|Tamale|Temuco|Toluca|Torino|Toulon|Trnava|Tromso|Tromsø|Tucson|Vantaa|Venice|Verona|Vienna|Warsaw|Yongin|Zagreb|Zurich|Ålborg|Örebro|Žilina|Aalst|Abuja|Accra|Adana|Ahvaz|Ajman|Ansan|Aswan|Basel|Batna|Belém|Blida|Borås|Braga|Breda|Bursa|Busan|Bærum|Cairo|Celje|Chiba|Cusco|Cuzco|Daegu|Davao|Delft|Delhi|Depok|Dhaka|Dijon|Dubai|Enugu|Espoo|Essen|Gabès|Galle|Genoa|Ghent|Gijón|Gävle|Haifa|Hamar|Hanoi|Holon|Izmir|Jinan|Kandy|Karaj|Kazan|Konya|Koper|Kranj|Kyoto|Köniz|Lagos|Lahti|Laval|Leeds|Liege|Lille|Liège|Luxor|Mainz|Malmo|Malmö|Mecca|Medan|Miami|Milan|Molde|Namur|Nancy|Narva|Natal|Nitra|Odesa|Osaka|Oujda|Padua|Paris|Parma|Pasig|Patna|Perth|Piura|Plzeň|Porto|Pärnu|Rabat|Radom|Rasht|Rouen|Sakai|Salta|Salto|Seoul|Sibiu|Skien|Split|Sochi|Sofia|Steyr|Surat|Suwon|Sétif|Tabuk|Tacna|Talca|Tampa|Tanta|Tartu|Thika|Tokyo|Toruń|Turin|Turku|Ulsan|Urmia|Vaasa|Varna|Vejle|Volos|Wuhan|Xi’an|Zadar|Århus|Évora|Čačak|İzmir|Abha|Agra|Arad|Bago|Bari|Bern|Biel|Bodø|Bonn|Brno|Cali|Cebu|Chur|Cork|Doha|Eger|Faro|Gent|Giza|Graz|Győr|Iasi|Iași|Ipoh|Kano|Kiel|Kiev|Kobe|Kyiv|Köln|León|Lima|Linz|Lodz|Lund|Lviv|Lyon|Mons|Omsk|Oran|Oslo|Oulu|Perm|Pori|Ptuj|Pula|Pune|Pécs|Riga|Rome|Ruse|Sfax|Suez|Taif|Thun|Umeå|Vigo|Wels|Xian|Zlín|Łódź|Fez|Fès|Hue|Jos|Niš|Qom|Ufa)\\s*,\\s*([A-Z]\\d[A-Z][ -]?\\d[A-Z]\\d|[A-Z]{2}-\\d{4,5}|[A-Z]\\d{4}[A-Z]{3}|[A-Z]{1,2}\\d{1,2}[A-Z]?\\s?\\d{1,2}[A-Z]{2}|\\d{4}\\s?[A-Z]{2}|[A-Z]\\d{2}\\s?[A-Z0-9]{4}|\\d{5}-\\d{4}|\\d{5}-\\d{3}|\\d{4}-\\d{3}|\\d{3}-\\d{4}|\\d{2}-\\d{3}|\\d{3}\\s\\d{3}|\\d{3}\\s\\d{2}|\\d{4,6})\\b",
1328
+ "description": "Address-context postcode: a world city (major + secondary) + comma + a postcode shape. batch-31f leaked 5 secondary-city addresses (Lyon/FR, Aarhus/DK, Graz/AT, Debrecen/HU, Bergen/NO) whose 4-5-digit postcodes were ambiguous with plain numbers and whose CITY was absent from the gazetteer. v1.4.23 expands the gazetteer to ~950 major+secondary cities across ~70 postcode countries (city + separator + 4-6-digit or grouped shape). Precision over recall: firing REQUIRES a gazetteer city + comma immediately before the number, so a bare 4/5/6-digit run with no city anchor is NOT masked. Postcode shapes cover 4-6-digit and grouped forms (BR NNNNN-NNN, JP NNN-NNNN, PL/PT NN(NN)-NNN). The city label is absorbed into the redacted GEO_ZIP span (negligible over-redaction). wasm32-safe (pure regex, no lookaround).",
1329
+ "examples": [
1330
+ "Tokyo, 123-4567",
1331
+ "Beverly Hills, 90210",
1332
+ "Sao Paulo, 01310-100",
1333
+ "Oslo, 0150",
1334
+ "Lyon, 69001",
1335
+ "Aarhus, 8000",
1336
+ "Graz, 8010",
1337
+ "Debrecen, 4024",
1338
+ "Bergen, 5003"
1339
+ ],
1340
+ "synthetic_strategy": "faker_zip"
1341
+ },
1342
+ "POSTAL_CUE_ANCHORED": {
1343
+ "code": "GEO_ZIP",
1344
+ "cloud_token_type": "GEO_ZIP",
1345
+ "pattern": "(?i)\\b(?:post(?:al)?\\s?code|postleitzahl|plz|zip(?:\\s?code)?|c[oó]digo\\s?postal|code\\s?postal|cep|pin\\s?code)\\s*[:#]?\\s*([A-Z]\\d[A-Z][ -]?\\d[A-Z]\\d|[A-Z]{2}-\\d{4,5}|[A-Z]\\d{4}[A-Z]{3}|[A-Z]{1,2}\\d{1,2}[A-Z]?\\s?\\d{1,2}[A-Z]{2}|\\d{4}\\s?[A-Z]{2}|[A-Z]\\d{2}\\s?[A-Z0-9]{4}|\\d{5}-\\d{4}|\\d{5}-\\d{3}|\\d{4}-\\d{3}|\\d{3}-\\d{4}|\\d{2}-\\d{3}|\\d{3}\\s\\d{3}|\\d{3}\\s\\d{2}|\\d{4,6})\\b",
1346
+ "description": "batch-38T (2026-07-21): CUE-ANCHORED postcode detector. A postcode CUE/label (multilingual: post code / postcode / postal code / postleitzahl / plz / zip / zip code / código postal / code postal / cep / pin code) + optional ':'/'#' separator + a postcode-shaped value → cloak. batch-38T leaked 7 postcodes rendered as 'Postcode: <value>' (BR NNNNN-NNN, CN 6-digit, CZ/GR spaced NNN NN, IT/TR 5-digit, NO 4-digit, US+4 NNNNN-NNNN) that POSTAL_CITY_ANCHORED missed because it fires only on a gazetteer-CITY + comma anchor, not on a postcode LABEL. The postcode CUE is itself the precision anchor — postcode labels are specific (unlike a generic 'Ref:'/'Order:'), so a bare postcode-shaped number with NO postcode cue AND no gazetteer-city still does NOT mask (a bare NNNNN run stays a plain number). The value alternation reuses POSTAL_CITY_ANCHORED's canonical real-shape group (numeric NNNN/NNNNN/NNNNNN, spaced NNN NN, hyphenated NNNNN-NNN/NNNNN-NNNN, alnum CA A#A#A#/UK/NL NNNN AA/IE Eircode). The cue+label span is absorbed into the redacted GEO_ZIP span (negligible over-redaction). wasm32-safe (pure regex, no lookaround).",
1347
+ "examples": [
1348
+ "Postcode: 01310-100",
1349
+ "ZIP code: 90210",
1350
+ "PLZ: 80331",
1351
+ "código postal 28013",
1352
+ "PIN code: 411001"
1353
+ ],
1354
+ "synthetic_strategy": "faker_zip"
1355
+ },
1356
+ "NET_MAC": {
1357
+ "code": "NET_IP",
1358
+ "cloud_token_type": "NET_IP",
1359
+ "pattern": "\\b(?:[0-9A-Fa-f]{2}[:\\-]){5}[0-9A-Fa-f]{2}\\b",
1360
+ "description": "MAC hardware address. Network/device identifier ⇒ NET bucket. Ported identifiers.mac.",
1361
+ "examples": [
1362
+ "00:1A:2B:3C:4D:5E"
1363
+ ],
1364
+ "synthetic_strategy": "faker_ip"
1365
+ },
1366
+ "DEVICE_IDFA": {
1367
+ "code": "NET_IP",
1368
+ "cloud_token_type": "NET_IP",
1369
+ "pattern": "(?i)\\b(?:IDFA|advertising[\\s\\-]?id|idfa)[:\\s]+[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\\b",
1370
+ "description": "Apple IDFA advertising identifier (uppercase UUID, cue-anchored). Ported online.device-id.idfa.",
1371
+ "examples": [
1372
+ "IDFA: AEBE52E7-03EE-455A-B3C4-E57283966239"
1373
+ ],
1374
+ "synthetic_strategy": "block_or_token"
1375
+ },
1376
+ "DEVICE_GAID": {
1377
+ "code": "NET_IP",
1378
+ "cloud_token_type": "NET_IP",
1379
+ "pattern": "(?i)\\b(?:GAID|google[\\s\\-]?advertising[\\s\\-]?id|aaid)[:\\s]+[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\\b",
1380
+ "description": "Google GAID/AAID advertising identifier (UUID, cue-anchored). Ported online.device-id.gaid.",
1381
+ "examples": [
1382
+ "GAID: 38400000-8cf0-11bd-b23e-10b96e40000d"
1383
+ ],
1384
+ "synthetic_strategy": "block_or_token"
1385
+ },
1386
+ "ALIAS_HANDLE": {
1387
+ "code": "PERS_NM",
1388
+ "cloud_token_type": "PERS_NM",
1389
+ "pattern": "@[A-Za-z0-9_]{2,30}\\b",
1390
+ "description": "Social media handle (@username). Identifies a person ⇒ PERSON bucket. EMAIL wins its longer span so email local-parts are unaffected. Ported identifiers.alias.handle.",
1391
+ "examples": [
1392
+ "@john_doe"
1393
+ ],
1394
+ "synthetic_strategy": "faker_name"
1395
+ },
1396
+ "NAME": {
1397
+ "code": "PERS_NM",
1398
+ "cloud_token_type": "PERS_NM",
1399
+ "pattern": null,
1400
+ "description": "Personal names — detected by NER (L2+), not regex",
1401
+ "examples": [
1402
+ "John Smith",
1403
+ "Maria García"
1404
+ ],
1405
+ "synthetic_strategy": "faker_name",
1406
+ "requires_ner": true
1407
+ },
1408
+ "ADDRESS": {
1409
+ "code": "LOC_ADDR",
1410
+ "cloud_token_type": "LOC_ADDR",
1411
+ "pattern": "\\d{1,5}[A-Za-z]?\\s+(?:[A-Za-zÀ-ÖØ-öø-ÿĀ-ſ]+\\s+){1,4}(?:Boulevard|Crescent|Gardens|Terrace|Avenue|Parade|Square|Street|Court|Drive|Place|Wharf|Blvd|Gate|Lane|Mews|Quay|Road|gate|Ave|Vei|Way|veg|vei|Ct|Dr|Ln|Pl|Rd|Sq|St)\\b(?:\\.)?(?:\\s*(?:Apt|Suite|Unit|#)\\s*\\w+)?|\\b\\d{1,5}[A-Za-z]?,?[ \\t]+(?:Boulevard|Avinguda|Chaussée|Piazzale|Travessa|avinguda|chaussée|piazzale|travessa|Avenida|Carrera|Impasse|Namesti|Náměstí|avenida|carrera|náměstí|Avenue|Camino|Carrer|Chemin|Piazza|Strada|Vicolo|carrer|piazza|strada|Aleja|Allée|Calle|Corso|Cours|Largo|Paseo|Place|Plaza|Plaça|Praca|Praça|Ronda|Ulica|Viale|aleja|calle|corso|paseo|praça|ulica|ulicy|viale|Quai|Rua|Rue|Via|rue)[ \\t]+(?:(?:degli|della|dello|aan|das|dei|del|den|der|des|dos|het|las|les|los|sur|van|von|da|de|di|do|du|el|la|le|op|e|i|y)[ \\t]+|[Dd][''’]){0,3}[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{1,}(?:[ \\t]+[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]+){0,2}|\\b(?:[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{2,}[ \\t]+){0,2}(?:[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{1,}(?:chaussee|plassen|strasse|bakken|brygge|gracht|singel|stigen|straat|straße|torget|torvet|allee|allée|gasse|gatan|gatas|gaten|gränd|plads|plass|platz|plein|polku|steeg|steig|vagen|vegen|veien|vägen)|[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{3,}(?:damm|dijk|gata|kade|kaia|katu|kuja|laan|torg|tori|ufer)|[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{2,}[b-df-hj-np-tv-xzB-DF-HJ-NP-TV-XZ](?:gate|gade)|[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{4,}(?:tie|veg|vei|vej|väg|weg))\\.?,?[ \\t]+\\d{1,3}[A-Za-z]?(?:\\s?[-–/]\\s?\\d{1,3}[A-Za-z]?)?\\b|\\b(?:[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]+[ \\t]+){0,2}(?:[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]*s|Nordre|Søndre|Vestre|Västra|Gamla|Gamle|Indre|Lilla|Lille|Nedra|Nedre|Norra|Stora|Store|Södra|Östra|Østre|Nord|Vest|Ytre|Øvre|Nya|Nye|Sør|Øst)[ \\t]+(?:gatan|gaten|plass|vegen|veien|vägen|gade|gata|gate|torg|veg|vei|vej|väg|weg)\\.?,?[ \\t]+\\d{1,3}[A-Za-z]?(?:\\s?[-–/]\\s?\\d{1,3}[A-Za-z]?)?\\b|\\b(?:[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]+[ \\t]+){1,3}(?:Strasse|strasse|Straat|Straße|straat|straße|Allee|Gasse|Gränd|Plass|Platz|Plein|allee|gasse|gränd|platz|plein|Allé|Kade|Katu|Laan|Torg|allé|kade|katu|laan)\\.?,?[ \\t]+\\d{1,3}[A-Za-z]?(?:\\s?[-–/]\\s?\\d{1,3}[A-Za-z]?)?\\b|\\b(?:Boulevard|Avinguda|Chaussée|Piazzale|Travessa|avinguda|chaussée|piazzale|travessa|Avenida|Carrera|Impasse|Namesti|Náměstí|avenida|carrera|náměstí|Avenue|Camino|Carrer|Chemin|Piazza|Strada|Vicolo|carrer|piazza|strada|Aleja|Allée|Calle|Corso|Cours|Largo|Paseo|Place|Plaza|Plaça|Praca|Praça|Ronda|Ulica|Viale|aleja|calle|corso|paseo|praça|ulica|ulicy|viale|Quai|Rua|Rue|Via|rue)[ \\t]+(?:(?:degli|della|dello|aan|das|dei|del|den|der|des|dos|het|las|les|los|sur|van|von|da|de|di|do|du|el|la|le|op|e|i|y)[ \\t]+|[Dd][''’]){0,3}[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]{1,}(?:[ \\t]+[A-ZÀ-ÖØ-ÞĀ-ſ][A-Za-zÀ-ÖØ-öø-ÿĀ-ſ'’\\-]+){0,2},?[ \\t]+\\d{1,3}[A-Za-z]?(?:\\s?[-–/]\\s?\\d{1,3}[A-Za-z]?)?\\b",
1412
+ "description": "v1.6.1 (2026-09-30): compound street plus trailing-number permits up to two leading name components, keeping multi-component forms such as Klara Norra Kyrkogata 12 in one ADDRESS span; existing street-morpheme and 1-3 digit house-number gates remain. Street addresses — Anglo-American LEADING house number ('123 Main Street', '221B Baker Street') AND the continental-European TRAILING house number (P0 2026-07-27). Six alternatives, in order: (1) the pre-existing leading-number + separated Anglo suffix, widened with an optional entrance letter (221B), the missing suffixes (Terrace/Crescent/Parade/Gardens/Quay/Wharf/Mews) and a trailing \\b that stops '4 owns the gateway' matching; (2) leading number + street-word-FIRST ('3 Place de la Concorde'); (3) COMPOUND street + trailing number ('Bergensgata 14', 'Hauptstraße 27b', 'Herengracht 182', 'Mannerheimintie 12'); (4) SEPARATED Nordic street word + trailing number, gated on a genitive ('Karl Johans gate 22') or a street adjective ('Nordre gate 8') because bare 'gate' collides with English; (5) separated NON-colliding street word + trailing number ('Bygdøy Allé 3'); (6) street-word-FIRST + trailing number ('Rue de Rivoli 12', 'Via Roma 12', 'ulica Marszalkowska 15'). PRECISION: there is no LOC tag to gate on here, so the trailing-number branches require a street MORPHEME (vocabulary mirrors shared/pii-patterns/street-address-anchors.json, ENGLISH morphemes deliberately excluded — English streets are separated words and stay on branch 1), a 1-3 digit house number (a 4-digit trailing number is a year or an amount: 'Spring 2026', 'Christie 1976'), and -gate/-gade additionally require a CONSONANT link letter so the Latinate English verbs (investiGate, deleGate, naviGate, aggreGate) cannot fire. Portable subset only: no lookaround, no backreferences, no \\p{...}, no inline flags (Rust regex crate + JS RegExp + PCRE + Python re). Guard: packages/pii-patterns-ts/tests/address.test.ts (34 exact-span positives, 68 prose negatives at zero matches). KNOWN RESIDUALS: a street with no adjacent house number ('the office on Bergensgata'); a 4-digit trailing house number; short compounds ('Nygata 4'); vowel-linked -gade/-gate ('Havnegade 5'); German -Ring streets ('Innsbrucker Ring 5' — dropped, 'Engineering 3' would have fired); a capitalised English noun ending consonant+gate before a number ('Watergate 5').",
1413
+ "examples": [
1414
+ "123 Main Street",
1415
+ "456 Oak Avenue Apt 2B",
1416
+ "221B Baker Street",
1417
+ "742 Evergreen Terrace",
1418
+ "3 Place de la Concorde",
1419
+ "Bergensgata 14",
1420
+ "Storgatan 7",
1421
+ "Hauptstraße 27b",
1422
+ "Herengracht 182",
1423
+ "Mannerheimintie 12",
1424
+ "Kurfürstendamm 18",
1425
+ "Vestre Torggate 3A",
1426
+ "Karl Johans gate 22",
1427
+ "Nordre gate 8",
1428
+ "Bygdøy Allé 3",
1429
+ "Rue de Rivoli 12",
1430
+ "Via Roma 12",
1431
+ "Calle Mayor 45",
1432
+ "Avenida Diagonal 3",
1433
+ "ulica Marszalkowska 15"
1434
+ ],
1435
+ "synthetic_strategy": "faker_address"
1436
+ },
1437
+ "PLACE": {
1438
+ "code": "GEO_PLACE",
1439
+ "cloud_token_type": "GEO_PLACE",
1440
+ "pattern": null,
1441
+ "description": "Bart stadnamn (by/kommune/region) UTAN husnummer-anker — detektert av NER (L2+), sak 265 / VEG 2. ADDRESS dekkjer berre det husnummer-forankra tilfellet og POSTAL_CITY_ANCHORED berre «by, postnummer»; eit stadnamn i etternamns-posisjon fall difor mellom dei og egresserte ORDRETT. PLACE er den klassen. Surrogat: eit anna stadnamn frå same sprakbasseng (place_surrogates). ADDRESS vinn over PLACE ved overlapp, so ei gateadresse aldri blir halvtokenisert.",
1442
+ "examples": [
1443
+ "Stavanger",
1444
+ "Malmö",
1445
+ "Rennesøy",
1446
+ "Frankfurt"
1447
+ ],
1448
+ "synthetic_strategy": "faker_city",
1449
+ "requires_ner": true
1450
+ },
1451
+ "ORGANIZATION": {
1452
+ "code": "ORG_NM",
1453
+ "cloud_token_type": "ORG_NM",
1454
+ "pattern": null,
1455
+ "description": "Organization/company names — detected by NER (L2+)",
1456
+ "examples": [
1457
+ "Acme Corporation",
1458
+ "Goldman Sachs"
1459
+ ],
1460
+ "synthetic_strategy": "faker_company",
1461
+ "requires_ner": true
1462
+ },
1463
+ "NID_KR_RRN": {
1464
+ "code": "ID_GOV",
1465
+ "cloud_token_type": "ID_GOV",
1466
+ "pattern": "\\b\\d{6}-[1-8]\\d{6}",
1467
+ "description": "South Korean Resident Registration Number (RRN), unlabeled distinctive format DDMMYY-Nnnnnnn; N (gender/century) is 1-4 or 5-8. Detected like SSN/card by shape. v1.4.14 (batch-22 GOVID): trailing `\\b` REMOVED — id34 `910314-2349139입니다` and id35 `650827-3152309이며` glued a Hangul particle directly onto the RRN, and in the Rust/WASM regex crate's UNICODE word boundary a digit↔Hangul transition is word-char↔word-char = no `\\b`, so the whole match failed and the RRN leaked. The structure is fixed-length (6-digit + hyphen + [1-8] + 6-digit = exactly 13 digits), so dropping the trailing anchor cannot over-extend; the leading `\\b` is kept (both leakers have whitespace before the RRN)."
1468
+ },
1469
+ "NID_JP_MYNUMBER_KANJI": {
1470
+ "code": "ID_GOV",
1471
+ "cloud_token_type": "ID_GOV",
1472
+ "pattern": "(?i)(?:マイナンバー|個人番号)[^0-9]{0,8}\\d{4}[\\- ]?\\d{4}[\\- ]?\\d{4}",
1473
+ "description": "Japanese My Number (12 digits), KANJI-label anchored (マイナンバー / 個人番号). batch-25c id13 leaked a bare 12-digit My Number after マイナンバー because NID_JP_MYNUMBER only matched the romaji `my number` label and NID_JP_MYNUMBER_BARE is jp_mynumber-checksum-gated (the synthetic test number fails the mod-11 check). Strong native-cue anchor, no checksum (cue is unambiguous).",
1474
+ "examples": [
1475
+ "マイナンバー298753160433"
1476
+ ]
1477
+ },
1478
+ "NID_BE_NRN_LABELLED": {
1479
+ "code": "ID_GOV",
1480
+ "cloud_token_type": "ID_GOV",
1481
+ "pattern": "(?i)\\b(?:rijksregisternummer|rijksregister|num[eé]ro\\s*(?:de\\s*|du\\s*)?registre\\s*national|registre\\s*national|nationaal\\s*nummer)\\b[^0-9]{0,10}\\d{2}[.\\- ]?\\d{2}[.\\- ]?\\d{2}[.\\- ]?\\d{3}[.\\- ]?\\d{2}",
1482
+ "description": "Belgian Rijksregisternummer, cue-anchored on the FR/NL label (numéro de registre national / rijksregisternummer), BARE 11-digit form YYMMDD SSS CC. batch-25c id14 leaked bare 85031298771 — NID_BE_NRN only matched the dotted print form and NID_BE_NRN_BARE requires SEP-punctuation + be_nrn mod-97 (synthetic number fails). Strong cue, no checksum.",
1483
+ "examples": [
1484
+ "numéro de registre national 85031298771"
1485
+ ]
1486
+ },
1487
+ "NID_AR_CUIT": {
1488
+ "code": "ID_GOV",
1489
+ "cloud_token_type": "ID_GOV",
1490
+ "pattern": "(?i)\\b(?:cuit|cuil|cdi)\\b[^0-9]{0,10}\\d{2}[-\\s]?\\d{8}[-\\s]?\\d",
1491
+ "description": "Argentine CUIT/CUIL/CDI tax-and-identity number (11 digits, 2-8-1). batch-25c id24 leaked bare 20298753163 — no Argentina scheme existed; it fell through to nid_bare11 (checksum-gated, synthetic fails). Cue-anchored on CUIT/CUIL, no checksum (mod-11 not portable to the pure-regex fasit; the cue is distinctive).",
1492
+ "examples": [
1493
+ "CUIT 20298753163"
1494
+ ]
1495
+ },
1496
+ "NID_RU_NID": {
1497
+ "code": "ID_GOV",
1498
+ "cloud_token_type": "ID_GOV",
1499
+ "pattern": "(?i)(?:снилс|инн)[^0-9]{0,10}\\d(?:[\\s.\\-]?\\d){9,13}",
1500
+ "description": "Russian SNILS (СНИЛС, 11 digits) / INN (ИНН, 10-12 digits), Cyrillic-cue anchored. batch-25c id26 leaked bare СНИЛС 11223344595 — no Russia scheme; nid_bare11 checksum-gated and the synthetic number fails. Strong Cyrillic cue, no checksum.",
1501
+ "examples": [
1502
+ "СНИЛС 11223344595"
1503
+ ]
1504
+ },
1505
+ "NID_NO_FNR_LABELLED": {
1506
+ "code": "ID_GOV",
1507
+ "cloud_token_type": "ID_GOV",
1508
+ "pattern": "(?i)\\bf[øo]dselsnummer\\b[^0-9]{0,10}\\d{11}",
1509
+ "description": "Norwegian fødselsnummer (11 digits), cue-anchored. batch-25c id29 leaked bare fødselsnummer 29875316069 — NID_NO_DNR only matches the `d-nummer` cue (D-numbers, first digit 4-7) and nid_bare11 is checksum-gated (synthetic fails). Strong cue, no checksum (mod-11 double-check not portable).",
1510
+ "examples": [
1511
+ "fødselsnummer 29875316069"
1512
+ ]
1513
+ },
1514
+ "NID_NG_NIN": {
1515
+ "code": "ID_GOV",
1516
+ "cloud_token_type": "ID_GOV",
1517
+ "pattern": "(?i)\\b(?:nin|national\\s*identification\\s*number|bvn)\\b[^0-9]{0,10}\\d{11}",
1518
+ "description": "Nigerian NIN (National Identification Number, 11 digits) / BVN (bank verification number, 11 digits), cue-anchored. batch-25c id44 leaked bare NIN 29875316043 — no Nigeria scheme; nid_bare11 checksum-gated. NIN/BVN have no published portable check digit, so strong cue anchoring only.",
1519
+ "examples": [
1520
+ "NIN 29875316043"
1521
+ ]
1522
+ },
1523
+ "NID_EG_NID": {
1524
+ "code": "ID_GOV",
1525
+ "cloud_token_type": "ID_GOV",
1526
+ "pattern": "(?i)(?:الرقم\\s*القوم[يى]|رقم\\s*قوم[يى]|national\\s*number)[^0-9]{0,10}\\d{14}",
1527
+ "description": "Egyptian National ID (الرقم القومي, 14 digits: C-YYMMDD-GG-SSSC), Arabic/English cue-anchored. batch-25c id46 leaked bare الرقم القومي 29803152103456 — no Egypt scheme; 14-digit run only hit CREDIT_CARD (Luhn-gated, fails). Strong native cue, no checksum (embedded date + serial + check, but the cue is unambiguous).",
1528
+ "examples": [
1529
+ "الرقم القومي 29803152103456"
1530
+ ]
1531
+ },
1532
+ "NID_PK_CNIC": {
1533
+ "code": "ID_GOV",
1534
+ "cloud_token_type": "ID_GOV",
1535
+ "pattern": "(?i)\\b(?:cnic|nadra|b-?form)\\b[^0-9]{0,12}\\d{5}[-\\s]?\\d{7}[-\\s]?\\d",
1536
+ "description": "Pakistani CNIC (13 digits, 5-7-1) cue-anchored on CNIC/NADRA. batch-25c id47 leaked 35202-8765432-1 — no Pakistan scheme; the dashed 13-digit run mis-hit CREDIT_CARD/PHONE. No published portable check digit, so strong cue anchoring.",
1537
+ "examples": [
1538
+ "CNIC number 35202-8765432-1"
1539
+ ]
1540
+ },
1541
+ "NID_CN_RIC_LABELLED": {
1542
+ "code": "ID_GOV",
1543
+ "cloud_token_type": "ID_GOV",
1544
+ "pattern": "(?:居民身份证|居民身份證|身份证|身份證)(?:号码|号|號碼|號)?[^0-9]{0,6}\\d{17}[0-9Xx]",
1545
+ "description": "Chinese resident identity card 居民身份证 (18 chars), CUE-anchored companion to the checksum-gated NID_CN_RIC. batch-25c id25 leaked 居民身份证号510102198503125310 — the synthetic number fails the cn_ric ISO-7064 checksum and (per the stale-WASM drift) the NID_GENERIC_LABELLED 居民身份证 arm did not fire live. Explicit cue-anchored, no checksum, so a labelled card always cloaks.",
1546
+ "examples": [
1547
+ "居民身份证号510102198503125310"
1548
+ ]
1549
+ },
1550
+ "NID_DK_CPR_LABELLED": {
1551
+ "code": "ID_GOV",
1552
+ "cloud_token_type": "ID_GOV",
1553
+ "pattern": "(?i)\\bcpr(?:[\\s\\-]?(?:nr|nummer))?\\b[^0-9]{0,8}\\d{6}-?\\d{4}",
1554
+ "description": "Danish CPR cue-anchored companion (any 10-digit DDMMYY-SSSS after the CPR label). batch-25c id32 leaked CPR-nummer 2987516030 — the existing NID_DK_CPR requires a STRUCTURALLY-VALID DDMMYY (the synthetic 29-87-51... has month 87) so it rejected. This variant trusts the distinctive CPR cue instead of the embedded date.",
1555
+ "examples": [
1556
+ "CPR-nummer 2987516030"
1557
+ ]
1558
+ },
1559
+ "NID_CUE_EXT_MULTI": {
1560
+ "code": "ID_GOV",
1561
+ "cloud_token_type": "ID_GOV",
1562
+ "pattern": "(?i)(?:マイナンバー|個人番号|رقم\\s*الهوية|الهوية\\s*الوطنية|بطاقة\\s*الهوية|رقم\\s*قومي|كود\\s*ملي|کد\\s*ملی|شماره\\s*ملی|emirates\\s*id|iqama|إقامة|huduma\\s*namba|ghana\\s*card|philsys|\\bpsn\\b|\\bfin\\b|mykad|kad\\s*pengenalan|số\\s*căn\\s*cước|căn\\s*cước\\s*công\\s*dân|تعודت\\s*זהות|תעודת\\s*זהות|מספר\\s*זהות|teudat\\s*zehut|рнокпп|іпн|\\bαφμ\\b|\\bαμκα\\b|ταυτότητα|პირადი\\s*ნომერი|\\bcnic\\b|nadra|\\bcuit\\b|\\bcuil\\b|снилс|инн|f[øo]dselsnummer|\\bnin\\b|\\bbvn\\b|título\\s*de\\s*eleitor|\\brfc\\b|\\brut\\b|carte\\s*nationale|carte\\s*d['’]identité\\s*nationale|\\bcin\\b|fayda|jatiya\\s*porichoy|জাতীয়\\s*পরিচয়(?:পত্র)?)[^0-9]{0,12}\\d(?:[\\s./\\-]?\\d){4,17}",
1563
+ "description": "Comprehensive multilingual national-ID cue-anchored extension (batch-25c GOVID close-out). One additional alternation of country ID labels NOT already carried by NID_GENERIC_LABELLED — Japan マイナンバー/個人番号, Gulf/Arab رقم الهوية/الهوية الوطنية/رقم قومي, Iran کد ملی/شماره ملی, UAE Emirates ID, Saudi iqama/إقامة, Kenya Huduma Namba, Ghana Card, Philippines PhilSys/PSN/FIN, Malaysia MyKad/kad pengenalan, Vietnam số căn cước/căn cước công dân, Israel תעודת זהות/teudat zehut, Ukraine РНОКПП/ІПН, Greece ΑΦΜ/ΑΜΚΑ/ταυτότητα, Georgia პირადი ნომერი, Pakistan CNIC/NADRA, Argentina CUIT/CUIL, Russia СНИЛС/ИНН, Norway fødselsnummer, Nigeria NIN/BVN, Brazil título de eleitor, Mexico RFC, Chile RUT, Maghreb carte nationale/CIN, Ethiopia Fayda, Bangladesh জাতীয় পরিচয়পত্র. Cue → 5-18 digit run (optional separators). No checksum: cue-anchoring only, a fail-SAFE over-redaction that closes the residual synthetic-checksum-invalid leak class. Dedicated per-country types above take precedence where they exist.",
1564
+ "examples": [
1565
+ "رقم الهوية 1098765432",
1566
+ "Emirates ID 784-1985-1234567-8"
1567
+ ]
1568
+ },
1569
+ "NID_CN_RIC": {
1570
+ "pattern": "\\b[1-9]\\d{5}(?:18|19|20)\\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]\\b",
1571
+ "checksum": "cn_ric",
1572
+ "description": "Chinese resident identity card 居民身份证 (GB 11643): 18 chars = 6-digit region + YYYYMMDD birthdate + 3-digit sequence + ISO 7064 MOD 11-2 check (0-9/X). Structural date gating + checksum keep precision on a bare 18-digit run.",
1573
+ "examples": [
1574
+ "110101199003076579",
1575
+ "440524198001010013"
1576
+ ]
1577
+ },
1578
+ "NID_IN_EPIC": {
1579
+ "pattern": "\\b[A-Z]{3}\\d{7}\\b",
1580
+ "description": "Indian Voter ID / EPIC number: 3 uppercase letters + 7 digits (distinctive format). Over-cloak-safe.",
1581
+ "examples": [
1582
+ "ABC1234567",
1583
+ "WVN4665218"
1584
+ ]
1585
+ },
1586
+ "NID_JP_MYNUMBER_BARE": {
1587
+ "code": "ID_GOV",
1588
+ "cloud_token_type": "ID_GOV",
1589
+ "pattern": "\\b\\d{12}\\b",
1590
+ "checksum": "jp_mynumber",
1591
+ "description": "Japanese My Number (個人番号), BARE 12-digit form, checksum-gated (jp_mynumber check digit). batch-23 leaked 4 bare valid My Numbers because NID_JP_MYNUMBER only matched a `my number`-cued form. The 12th digit is a mod-11 weighted check so a random 12-digit run does not tokenise (≈1/11 false-accept, further cut by the birth/date context of real docs)."
1592
+ },
1593
+ "NID_BE_NRN_BARE": {
1594
+ "code": "ID_GOV",
1595
+ "cloud_token_type": "ID_GOV",
1596
+ "pattern": "\\b\\d{6}[-. ]\\d{3}[-. ]\\d{2}\\b",
1597
+ "checksum": "be_nrn",
1598
+ "description": "Belgian National Number (Rijksregisternummer / Numéro National), BARE YYMMDD-SSS.CC form, checksum-gated (be_nrn mod-97, both century variants). batch-23 leaked bare `880614-676.18` / `051123-813.66` — NID_BE_NRN only matched the dotted `YY.MM.DD-SSS.CC` shape and carried NO checksum. Separators required (\\d6 SEP \\d3 SEP \\d2) so a bare 11-digit run is not swept."
1599
+ },
1600
+ "NID_SK_RC": {
1601
+ "code": "ID_GOV",
1602
+ "cloud_token_type": "ID_GOV",
1603
+ "pattern": "\\b\\d{6}/\\d{4}\\b",
1604
+ "checksum": "cz_sk_rc",
1605
+ "description": "Czech/Slovak rodné číslo (birth number), BARE 10-digit YYMMDD/XXXX form, checksum-gated (cz_sk_rc: whole number divisible by 11). batch-23 leaked bare `991205/9311` — only the cue-anchored NID_GENERIC_LABELLED `rodné číslo …` form existed. Slash separator + div-11 keep false-accept low; the 9-digit pre-1954 form stays cue-gated."
1606
+ },
1607
+ "NID_BARE_10": {
1608
+ "code": "ID_GOV",
1609
+ "cloud_token_type": "ID_GOV",
1610
+ "pattern": "\\b\\d{10}\\b",
1611
+ "checksum": "nid_bare10",
1612
+ "description": "batch-24 GOVID whole-domain close — BARE 10-digit national IDs, checksum+date gated (nid_bare10). Covers Bulgarian EGN (ЕГН, YYMMDD·SSS·C, weighted mod-11 + century-offset month, embedded-date-valid). One `\\d{10}` entry so any future 10-digit scheme adds a branch to the validator, not a new fasit row. Date-gating (real DD/MM required) keeps bare false-accept ~1% despite the collision with 10-digit phone runs (which are cloaked anyway)."
1613
+ },
1614
+ "NID_BARE_11": {
1615
+ "code": "ID_GOV",
1616
+ "cloud_token_type": "ID_GOV",
1617
+ "pattern": "\\b\\d{11}\\b",
1618
+ "checksum": "nid_bare11",
1619
+ "description": "batch-24 GOVID whole-domain close — BARE 11-digit national IDs, checksum gated (nid_bare11 = Croatian OIB MOD 11,10 || Lithuanian asmens kodas / Estonian isikukood weighted-mod-11 double-pass (date-gated) || Turkish T.C. Kimlik two-check-digit || Polish PESEL weighted-mod-10 (date-gated)). batch-24c leaked bare Croatian OIB (13418401267, 93503253490, 12559659779, 92608254019) + Lithuanian (40306096360). OIB has NO embedded date so pure MOD 11,10 is the strongest gate available (≈10% bare false-accept — a fail-SAFE over-redaction, never a leak — matching the shipped cz_sk_rc bare precedent)."
1620
+ },
1621
+ "NID_BARE_12": {
1622
+ "code": "ID_GOV",
1623
+ "cloud_token_type": "ID_GOV",
1624
+ "pattern": "\\b\\d{12}\\b",
1625
+ "checksum": "nid_bare12",
1626
+ "description": "v1.2.1 close-bare — BARE 12-digit national IDs, checksum-gated (nid_bare12 = Japanese My Number mod-11 || Indian Aadhaar Verhoeff). A 12-digit contiguous run is NOT covered by the PHONE (\\d{8}/\\d{10,11}) or SSN (\\d{9}) length floor, so a bare Verhoeff-valid Aadhaar that FAILS the JP My Number check was the last real raw-leak at length 12 (previously only NID_JP_MYNUMBER_BARE, jp_mynumber-only, masked here). Verhoeff gives ~1/10 bare false-accept — a fail-SAFE over-redaction consistent with the shipped nid_bare16 NIK precedent. The pre-existing NID_JP_MYNUMBER_BARE stays (jp-only) for its regression vector; this OR-superset adds the Aadhaar branch."
1627
+ },
1628
+ "NID_BARE_13": {
1629
+ "code": "ID_GOV",
1630
+ "cloud_token_type": "ID_GOV",
1631
+ "pattern": "\\b\\d{13}\\b",
1632
+ "checksum": "nid_bare13",
1633
+ "description": "batch-24 GOVID whole-domain close — BARE 13-digit national IDs, checksum+date gated (nid_bare13 = ex-Yugoslav JMBG (RS/BA/ME/MK…, weighted mod-11) || Romanian CNP (weighted mod-11) || South-African ID (Luhn)). batch-24c leaked bare Serbian JMBG (3009972720699) + Romanian CNP (6880617104196). All three embed a birthdate that must be a real DD/MM → ~1% bare false-accept."
1634
+ },
1635
+ "NID_BARE_16": {
1636
+ "code": "ID_GOV",
1637
+ "cloud_token_type": "ID_GOV",
1638
+ "pattern": "\\b\\d{16}\\b",
1639
+ "checksum": "nid_bare16",
1640
+ "description": "batch-24 GOVID whole-domain close — BARE 16-digit national IDs, structural+date gated (nid_bare16 = Indonesian NIK, PP·RR·SS·DDMMYY·NNNN: province 11–96, DD (+40 female) 1–31, MM 1–12). NIK has no check digit so structure + embedded-date validity are the gate. batch-24c leaked 4 bare NIK (3171011403850588, 3273047009721256, 3578122311994312, 5101050508617098). Collides with 16-digit credit-card runs — a Luhn-valid one is claimed by the higher-precedence CREDIT_CARD detector; either way cloaked."
1641
+ },
1642
+ "NID_AL": {
1643
+ "code": "ID_GOV",
1644
+ "cloud_token_type": "ID_GOV",
1645
+ "pattern": "(?i)(?:numrin\\s+e\\s+identitetit|letërnjoftim\\w*|leternjoftim\\w*|karta\\s+e\\s+identitetit|identitetit)[^A-Za-z0-9]{0,12}[A-Za-z]\\d{8}[A-Za-z]",
1646
+ "description": "Albanian National ID / letërnjoftim (letter + 8 digits + check letter, e.g. J37812465A), cue-anchored (numrin e identitetit / letërnjoftim / karta e identitetit). batch-26 GOVID close: id leaked labelled+RAW; cue-gated so ordinary Albanian prose does not over-match. The trailing check letter is embedded in the fixed shape rather than arithmetically validated (no public checksum spec)."
1647
+ },
1648
+ "NID_LABELLED_ALNUM_27": {
1649
+ "code": "ID_GOV",
1650
+ "cloud_token_type": "ID_GOV",
1651
+ "pattern": "(?i)(?:\\bcni\\b[\\s:.№-]{0,6}CI\\d{10})|(?:(?:бүртгэлийн\\s*дугаар|\\bregister\\s*(?:no\\.?|number))[\\s:.№-]{0,6}[^\\u0000-\\u007F]{2}\\d{8})|(?:\\b\\d{1,2}/[A-Z]{3,12}\\([A-Z]\\)\\d{6}\\b)|(?:(?:идентификационный\\s*номер|identification\\s*(?:no\\.?|number))[\\s:.№-]{0,6}\\d{7}[A-Z]\\d{3}[A-Z]{2}\\d)",
1652
+ "description": "v1.4.19 (batch-27d GOVID close): cue-anchored national/personal-ID formats whose values contain LETTERS or non-Latin script (so the digit-only NID_GENERIC_LABELLED tail cannot capture them fully). FOUR branches: (1) Côte d'Ivoire CNI `CI\\d{10}` cued by 'CNI'; (2) Mongolia Register Number `<2 non-ASCII letters>\\d{8}` (e.g. УБ92037812) cued by бүртгэлийн дугаар / register number — the 2-letter Cyrillic prefix is matched via negated-ASCII `[^\\u0000-\\u007F]{2}` (a non-ASCII RANGE in a char class fails on the wasm32 regex crate — documented EAI bug — so a class-RANGE is avoided); (3) Myanmar NRC `\\d{1,2}/[A-Z]{3,12}\\([A-Z]\\)\\d{6}` (e.g. 12/MAHALA(N)123456) — the parenthesised citizenship marker + slash shape is distinctive enough to run cue-free; (4) Belarus Identification Number `\\d{7}[A-Z]\\d{3}[A-Z]{2}\\d` (e.g. 3781246A059PB2) cued by идентификационный номер / identification number. All cue-anchored (except the self-distinctive Myanmar shape) → precision-safe. No arithmetic checksum claimed (no public spec re-verified this run); structural format only."
1653
+ },
1654
+ "NID_KR_RRN_BARE": {
1655
+ "code": "ID_GOV",
1656
+ "cloud_token_type": "ID_GOV",
1657
+ "pattern": "(?:주민등록번호|주민번호|등록번호)[^0-9]{0,10}\\d{6}[1-8]\\d{6}",
1658
+ "description": "South Korean RRN in BARE (un-hyphenated) 13-digit form, cue-anchored on 주민등록번호/주민번호/등록번호. The hyphenated distinctive form is NID_KR_RRN; the bare labelled form (batch-26 leaker 주민등록번호 7811223781242) has no hyphen so NID_KR_RRN missed it and NID_BARE_13 excludes KR from its checksum chain — cue-anchored here (DDMMYY + [1-8] century/sex + 6-digit serial) so precision stays safe without a KR checksum."
1659
+ }
1660
+ },
1661
+ "token_format": "<<CLOAK:{cloud_token_type}:{hash}>>",
1662
+ "hash_algorithm": "SHA-256 (first 6 hex chars)",
1663
+ "context_injection_preamble": "Some personally identifiable information in this conversation has been replaced with privacy-safe substitutes. Please treat all names, addresses, and contact details as contextually valid and reason about them normally.",
1664
+ "levels": {
1665
+ "1": {
1666
+ "name": "Light",
1667
+ "description": "Regex-only structured PII detection",
1668
+ "types_active": [
1669
+ "EMAIL",
1670
+ "PHONE",
1671
+ "SSN",
1672
+ "PERSONNUMMER",
1673
+ "IBAN",
1674
+ "CREDIT_CARD",
1675
+ "IP_ADDRESS",
1676
+ "IP_ADDRESS_V6",
1677
+ "DATE_OF_BIRTH",
1678
+ "PASSPORT",
1679
+ "ADDRESS"
1680
+ ]
1681
+ },
1682
+ "2": {
1683
+ "name": "Standard",
1684
+ "description": "Regex + on-device NER (bert-base-multilingual, ONNX)",
1685
+ "types_active": [
1686
+ "EMAIL",
1687
+ "PHONE",
1688
+ "SSN",
1689
+ "PERSONNUMMER",
1690
+ "IBAN",
1691
+ "CREDIT_CARD",
1692
+ "IP_ADDRESS",
1693
+ "IP_ADDRESS_V6",
1694
+ "DATE_OF_BIRTH",
1695
+ "PASSPORT",
1696
+ "ADDRESS",
1697
+ "NAME",
1698
+ "ORGANIZATION",
1699
+ "PLACE"
1700
+ ]
1701
+ },
1702
+ "3": {
1703
+ "name": "Strong",
1704
+ "description": "Regex + on-device NER (bert-base-multilingual, ONNX)",
1705
+ "types_active": [
1706
+ "EMAIL",
1707
+ "PHONE",
1708
+ "SSN",
1709
+ "PERSONNUMMER",
1710
+ "IBAN",
1711
+ "CREDIT_CARD",
1712
+ "IP_ADDRESS",
1713
+ "IP_ADDRESS_V6",
1714
+ "DATE_OF_BIRTH",
1715
+ "PASSPORT",
1716
+ "ADDRESS",
1717
+ "NAME",
1718
+ "ORGANIZATION",
1719
+ "PLACE"
1720
+ ]
1721
+ },
1722
+ "4": {
1723
+ "name": "Maximum",
1724
+ "description": "Regex + on-device NER (bert-base-multilingual, ONNX) + deterministic heuristic. No LLM runs.",
1725
+ "types_active": [
1726
+ "EMAIL",
1727
+ "PHONE",
1728
+ "SSN",
1729
+ "PERSONNUMMER",
1730
+ "IBAN",
1731
+ "CREDIT_CARD",
1732
+ "IP_ADDRESS",
1733
+ "IP_ADDRESS_V6",
1734
+ "DATE_OF_BIRTH",
1735
+ "PASSPORT",
1736
+ "ADDRESS",
1737
+ "NAME",
1738
+ "ORGANIZATION",
1739
+ "PLACE"
1740
+ ]
1741
+ }
1742
+ },
1743
+ "place_surrogates": {
1744
+ "note": "sak 265 / VEG 2 (Rolf, KOMITE-ORDRE 7 P4): stadnamn-detektoren fyrer UANSETT POSISJON. Eit bart stadnamn — inkludert eit som star i etternamns-posisjon («Ola Nordmann Stavanger», «Karin Sandberg Malmo») — blir bytt med eit ANNA stadnamn. MALT FOER: 6 av 20 testnamn lak eit ledd ORDRETT ut i lagringa (no 4/5, sv 2/5, de 0/5, es 0/5) fordi eit LOC-spenn utan husnummer-anker blei kasta. Type-rett og sprak-rett, og ingen liste over kva etternamn som er stadnamn.",
1745
+ "surrogate_rule": "Last produktregel: surrogatet matchar TYPE og SPRAK (person->person, stad->STAD, org->ORG). Bassenget er difor per sprak og doblar som SPRAKPEIKAR.",
1746
+ "selection_order": [
1747
+ "1. Star originalen (case-ufoelsamt) i eit basseng -> det spraket.",
1748
+ "2. Elles: fyrste ortografiske spor som matchar (orthographic_cues, i rekkjefoelgje).",
1749
+ "3. Elles: default_pool.",
1750
+ "4. Trekket er deterministisk av VERDIEN (same original -> same surrogat), og originalen blir aldri trekt som sitt eige surrogat."
1751
+ ],
1752
+ "default_pool": "int",
1753
+ "orthographic_cues": {
1754
+ "no": [
1755
+ "øy",
1756
+ "sund",
1757
+ "fjord",
1758
+ "vik",
1759
+ "dal",
1760
+ "nes",
1761
+ "haug",
1762
+ "stad",
1763
+ "ås",
1764
+ "eid",
1765
+ "bygd",
1766
+ "vær"
1767
+ ],
1768
+ "sv": [
1769
+ "köping",
1770
+ "holm",
1771
+ "borg",
1772
+ "sjö",
1773
+ "hamn",
1774
+ "lund",
1775
+ "berga",
1776
+ "torp",
1777
+ "vik"
1778
+ ],
1779
+ "da": [
1780
+ "lev",
1781
+ "borg",
1782
+ "havn",
1783
+ "købing",
1784
+ "strup",
1785
+ "lund"
1786
+ ],
1787
+ "fi": [
1788
+ "järvi",
1789
+ "lahti",
1790
+ "joki",
1791
+ "mäki",
1792
+ "kylä",
1793
+ "linna",
1794
+ "saari",
1795
+ "koski"
1796
+ ],
1797
+ "de": [
1798
+ "burg",
1799
+ "hausen",
1800
+ "heim",
1801
+ "furt",
1802
+ "brück",
1803
+ "bach",
1804
+ "dorf",
1805
+ "stadt",
1806
+ "ingen",
1807
+ "berg"
1808
+ ],
1809
+ "nl": [
1810
+ "dam",
1811
+ "dijk",
1812
+ "hoven",
1813
+ "veen",
1814
+ "bergen",
1815
+ "zaan",
1816
+ "wijk"
1817
+ ],
1818
+ "es": [
1819
+ "illa",
1820
+ "edo",
1821
+ "ares",
1822
+ "ncia",
1823
+ "ago",
1824
+ "eda",
1825
+ "uela"
1826
+ ],
1827
+ "pt": [
1828
+ "inho",
1829
+ "eira",
1830
+ "onte",
1831
+ "avra"
1832
+ ],
1833
+ "fr": [
1834
+ "ville",
1835
+ "sur-",
1836
+ "les-",
1837
+ "eux",
1838
+ "ac",
1839
+ "gny"
1840
+ ],
1841
+ "it": [
1842
+ "ino",
1843
+ "ano",
1844
+ "ella",
1845
+ "etta",
1846
+ "oli"
1847
+ ],
1848
+ "pl": [
1849
+ "ów",
1850
+ "ice",
1851
+ "wice",
1852
+ "sko",
1853
+ "yn",
1854
+ "cz"
1855
+ ]
1856
+ },
1857
+ "pools": {
1858
+ "no": [
1859
+ "Oslo",
1860
+ "Bergen",
1861
+ "Trondheim",
1862
+ "Stavanger",
1863
+ "Drammen",
1864
+ "Fredrikstad",
1865
+ "Kristiansand",
1866
+ "Sandnes",
1867
+ "Tromsø",
1868
+ "Sarpsborg",
1869
+ "Skien",
1870
+ "Ålesund",
1871
+ "Haugesund",
1872
+ "Tønsberg",
1873
+ "Moss",
1874
+ "Bodø",
1875
+ "Arendal",
1876
+ "Hamar",
1877
+ "Larvik",
1878
+ "Halden",
1879
+ "Lillehammer",
1880
+ "Molde",
1881
+ "Harstad",
1882
+ "Gjøvik",
1883
+ "Narvik",
1884
+ "Kongsberg",
1885
+ "Steinkjer",
1886
+ "Elverum",
1887
+ "Førde",
1888
+ "Rennesøy"
1889
+ ],
1890
+ "sv": [
1891
+ "Stockholm",
1892
+ "Göteborg",
1893
+ "Malmö",
1894
+ "Uppsala",
1895
+ "Västerås",
1896
+ "Örebro",
1897
+ "Linköping",
1898
+ "Helsingborg",
1899
+ "Jönköping",
1900
+ "Norrköping",
1901
+ "Lund",
1902
+ "Umeå",
1903
+ "Gävle",
1904
+ "Borås",
1905
+ "Södertälje",
1906
+ "Eskilstuna",
1907
+ "Halmstad",
1908
+ "Växjö",
1909
+ "Karlstad",
1910
+ "Sundsvall",
1911
+ "Östersund",
1912
+ "Trollhättan",
1913
+ "Luleå",
1914
+ "Kalmar",
1915
+ "Falun",
1916
+ "Skövde",
1917
+ "Karlskrona",
1918
+ "Visby",
1919
+ "Kiruna",
1920
+ "Nyköping"
1921
+ ],
1922
+ "da": [
1923
+ "København",
1924
+ "Aarhus",
1925
+ "Odense",
1926
+ "Aalborg",
1927
+ "Esbjerg",
1928
+ "Randers",
1929
+ "Kolding",
1930
+ "Horsens",
1931
+ "Vejle",
1932
+ "Roskilde",
1933
+ "Herning",
1934
+ "Silkeborg",
1935
+ "Næstved",
1936
+ "Fredericia",
1937
+ "Viborg",
1938
+ "Køge",
1939
+ "Holstebro",
1940
+ "Slagelse",
1941
+ "Hillerød",
1942
+ "Helsingør",
1943
+ "Sønderborg",
1944
+ "Svendborg",
1945
+ "Ringsted",
1946
+ "Skive"
1947
+ ],
1948
+ "fi": [
1949
+ "Helsinki",
1950
+ "Espoo",
1951
+ "Tampere",
1952
+ "Vantaa",
1953
+ "Oulu",
1954
+ "Turku",
1955
+ "Jyväskylä",
1956
+ "Lahti",
1957
+ "Kuopio",
1958
+ "Pori",
1959
+ "Joensuu",
1960
+ "Lappeenranta",
1961
+ "Hämeenlinna",
1962
+ "Vaasa",
1963
+ "Seinäjoki",
1964
+ "Rovaniemi",
1965
+ "Mikkeli",
1966
+ "Kotka",
1967
+ "Salo",
1968
+ "Porvoo",
1969
+ "Kokkola",
1970
+ "Kajaani",
1971
+ "Savonlinna",
1972
+ "Imatra"
1973
+ ],
1974
+ "de": [
1975
+ "Berlin",
1976
+ "Hamburg",
1977
+ "München",
1978
+ "Köln",
1979
+ "Frankfurt",
1980
+ "Stuttgart",
1981
+ "Düsseldorf",
1982
+ "Leipzig",
1983
+ "Dortmund",
1984
+ "Essen",
1985
+ "Bremen",
1986
+ "Dresden",
1987
+ "Hannover",
1988
+ "Nürnberg",
1989
+ "Duisburg",
1990
+ "Bochum",
1991
+ "Wuppertal",
1992
+ "Bielefeld",
1993
+ "Bonn",
1994
+ "Münster",
1995
+ "Karlsruhe",
1996
+ "Mannheim",
1997
+ "Augsburg",
1998
+ "Wiesbaden",
1999
+ "Freiburg",
2000
+ "Regensburg",
2001
+ "Wien",
2002
+ "Graz",
2003
+ "Salzburg",
2004
+ "Zürich",
2005
+ "Basel",
2006
+ "Bern",
2007
+ "Linz",
2008
+ "Innsbruck",
2009
+ "Kiel",
2010
+ "Erfurt"
2011
+ ],
2012
+ "nl": [
2013
+ "Amsterdam",
2014
+ "Rotterdam",
2015
+ "Utrecht",
2016
+ "Eindhoven",
2017
+ "Groningen",
2018
+ "Tilburg",
2019
+ "Almere",
2020
+ "Breda",
2021
+ "Nijmegen",
2022
+ "Haarlem",
2023
+ "Arnhem",
2024
+ "Enschede",
2025
+ "Apeldoorn",
2026
+ "Leiden",
2027
+ "Maastricht",
2028
+ "Dordrecht",
2029
+ "Zwolle",
2030
+ "Delft",
2031
+ "Antwerpen",
2032
+ "Gent",
2033
+ "Brugge",
2034
+ "Leuven",
2035
+ "Hasselt",
2036
+ "Mechelen"
2037
+ ],
2038
+ "es": [
2039
+ "Madrid",
2040
+ "Barcelona",
2041
+ "Valencia",
2042
+ "Sevilla",
2043
+ "Zaragoza",
2044
+ "Málaga",
2045
+ "Murcia",
2046
+ "Palma",
2047
+ "Bilbao",
2048
+ "Alicante",
2049
+ "Córdoba",
2050
+ "Valladolid",
2051
+ "Vigo",
2052
+ "Granada",
2053
+ "Toledo",
2054
+ "Segovia",
2055
+ "Salamanca",
2056
+ "Santander",
2057
+ "Pamplona",
2058
+ "Burgos",
2059
+ "Cáceres",
2060
+ "Almería",
2061
+ "Girona",
2062
+ "Cuenca",
2063
+ "Medina",
2064
+ "Oviedo",
2065
+ "León",
2066
+ "Cádiz",
2067
+ "Huelva",
2068
+ "Logroño"
2069
+ ],
2070
+ "pt": [
2071
+ "Lisboa",
2072
+ "Porto",
2073
+ "Braga",
2074
+ "Coimbra",
2075
+ "Faro",
2076
+ "Aveiro",
2077
+ "Setúbal",
2078
+ "Funchal",
2079
+ "Évora",
2080
+ "Guimarães",
2081
+ "Viseu",
2082
+ "Leiria",
2083
+ "Sintra",
2084
+ "Cascais",
2085
+ "Bragança",
2086
+ "Portimão",
2087
+ "Tomar",
2088
+ "Beja"
2089
+ ],
2090
+ "fr": [
2091
+ "Paris",
2092
+ "Marseille",
2093
+ "Lyon",
2094
+ "Toulouse",
2095
+ "Nice",
2096
+ "Nantes",
2097
+ "Montpellier",
2098
+ "Strasbourg",
2099
+ "Bordeaux",
2100
+ "Lille",
2101
+ "Rennes",
2102
+ "Reims",
2103
+ "Toulon",
2104
+ "Grenoble",
2105
+ "Dijon",
2106
+ "Angers",
2107
+ "Nîmes",
2108
+ "Tours",
2109
+ "Amiens",
2110
+ "Metz",
2111
+ "Besançon",
2112
+ "Orléans",
2113
+ "Rouen",
2114
+ "Caen",
2115
+ "Genève",
2116
+ "Lausanne",
2117
+ "Namur",
2118
+ "Liège"
2119
+ ],
2120
+ "it": [
2121
+ "Roma",
2122
+ "Milano",
2123
+ "Napoli",
2124
+ "Torino",
2125
+ "Palermo",
2126
+ "Genova",
2127
+ "Bologna",
2128
+ "Firenze",
2129
+ "Bari",
2130
+ "Catania",
2131
+ "Venezia",
2132
+ "Verona",
2133
+ "Messina",
2134
+ "Padova",
2135
+ "Trieste",
2136
+ "Brescia",
2137
+ "Parma",
2138
+ "Modena",
2139
+ "Perugia",
2140
+ "Livorno",
2141
+ "Ravenna",
2142
+ "Ferrara",
2143
+ "Salerno",
2144
+ "Siena"
2145
+ ],
2146
+ "pl": [
2147
+ "Warszawa",
2148
+ "Kraków",
2149
+ "Łódź",
2150
+ "Wrocław",
2151
+ "Poznań",
2152
+ "Gdańsk",
2153
+ "Szczecin",
2154
+ "Bydgoszcz",
2155
+ "Lublin",
2156
+ "Katowice",
2157
+ "Białystok",
2158
+ "Gdynia",
2159
+ "Częstochowa",
2160
+ "Radom",
2161
+ "Toruń",
2162
+ "Kielce",
2163
+ "Rzeszów",
2164
+ "Olsztyn",
2165
+ "Opole",
2166
+ "Zabrze",
2167
+ "Płock",
2168
+ "Legnica",
2169
+ "Elbląg",
2170
+ "Tarnów"
2171
+ ],
2172
+ "en": [
2173
+ "London",
2174
+ "Manchester",
2175
+ "Birmingham",
2176
+ "Leeds",
2177
+ "Glasgow",
2178
+ "Liverpool",
2179
+ "Bristol",
2180
+ "Sheffield",
2181
+ "Edinburgh",
2182
+ "Cardiff",
2183
+ "Belfast",
2184
+ "Newcastle",
2185
+ "Nottingham",
2186
+ "Leicester",
2187
+ "Brighton",
2188
+ "Oxford",
2189
+ "Cambridge",
2190
+ "York",
2191
+ "Dublin",
2192
+ "Cork",
2193
+ "Boston",
2194
+ "Portland",
2195
+ "Denver",
2196
+ "Austin",
2197
+ "Seattle",
2198
+ "Phoenix",
2199
+ "Raleigh",
2200
+ "Madison",
2201
+ "Tacoma",
2202
+ "Albany",
2203
+ "Toronto",
2204
+ "Ottawa",
2205
+ "Calgary",
2206
+ "Halifax",
2207
+ "Perth",
2208
+ "Adelaide"
2209
+ ],
2210
+ "int": [
2211
+ "Lisbon",
2212
+ "Prague",
2213
+ "Vienna",
2214
+ "Zagreb",
2215
+ "Sofia",
2216
+ "Riga",
2217
+ "Tallinn",
2218
+ "Vilnius",
2219
+ "Ljubljana",
2220
+ "Bratislava",
2221
+ "Budapest",
2222
+ "Bucharest",
2223
+ "Athens",
2224
+ "Valletta",
2225
+ "Reykjavik",
2226
+ "Luxembourg",
2227
+ "Monaco",
2228
+ "Andorra",
2229
+ "Casablanca",
2230
+ "Nairobi",
2231
+ "Bogota",
2232
+ "Santiago",
2233
+ "Montevideo",
2234
+ "Quito"
2235
+ ]
2236
+ }
2237
+ }
2238
+ }