@discretion/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -0
- package/LICENSE +21 -0
- package/README.md +319 -0
- package/dist/src/checksums/aba.d.ts +25 -0
- package/dist/src/checksums/aba.d.ts.map +1 -0
- package/dist/src/checksums/aba.js +47 -0
- package/dist/src/checksums/aba.js.map +1 -0
- package/dist/src/checksums/digits.d.ts +55 -0
- package/dist/src/checksums/digits.d.ts.map +1 -0
- package/dist/src/checksums/digits.js +114 -0
- package/dist/src/checksums/digits.js.map +1 -0
- package/dist/src/checksums/icao9303.d.ts +29 -0
- package/dist/src/checksums/icao9303.d.ts.map +1 -0
- package/dist/src/checksums/icao9303.js +56 -0
- package/dist/src/checksums/icao9303.js.map +1 -0
- package/dist/src/checksums/index.d.ts +21 -0
- package/dist/src/checksums/index.d.ts.map +1 -0
- package/dist/src/checksums/index.js +21 -0
- package/dist/src/checksums/index.js.map +1 -0
- package/dist/src/checksums/iso7064.d.ts +67 -0
- package/dist/src/checksums/iso7064.d.ts.map +1 -0
- package/dist/src/checksums/iso7064.js +159 -0
- package/dist/src/checksums/iso7064.js.map +1 -0
- package/dist/src/checksums/luhn.d.ts +32 -0
- package/dist/src/checksums/luhn.d.ts.map +1 -0
- package/dist/src/checksums/luhn.js +66 -0
- package/dist/src/checksums/luhn.js.map +1 -0
- package/dist/src/checksums/mod97.d.ts +55 -0
- package/dist/src/checksums/mod97.d.ts.map +1 -0
- package/dist/src/checksums/mod97.js +94 -0
- package/dist/src/checksums/mod97.js.map +1 -0
- package/dist/src/checksums/verhoeff.d.ts +28 -0
- package/dist/src/checksums/verhoeff.d.ts.map +1 -0
- package/dist/src/checksums/verhoeff.js +80 -0
- package/dist/src/checksums/verhoeff.js.map +1 -0
- package/dist/src/checksums/weighted.d.ts +64 -0
- package/dist/src/checksums/weighted.d.ts.map +1 -0
- package/dist/src/checksums/weighted.js +97 -0
- package/dist/src/checksums/weighted.js.map +1 -0
- package/dist/src/context/documentProfile.d.ts +34 -0
- package/dist/src/context/documentProfile.d.ts.map +1 -0
- package/dist/src/context/documentProfile.js +253 -0
- package/dist/src/context/documentProfile.js.map +1 -0
- package/dist/src/context/negativeRules.d.ts +60 -0
- package/dist/src/context/negativeRules.d.ts.map +1 -0
- package/dist/src/context/negativeRules.js +696 -0
- package/dist/src/context/negativeRules.js.map +1 -0
- package/dist/src/context/score.d.ts +52 -0
- package/dist/src/context/score.d.ts.map +1 -0
- package/dist/src/context/score.js +346 -0
- package/dist/src/context/score.js.map +1 -0
- package/dist/src/context/structure.d.ts +46 -0
- package/dist/src/context/structure.d.ts.map +1 -0
- package/dist/src/context/structure.js +528 -0
- package/dist/src/context/structure.js.map +1 -0
- package/dist/src/context/triggers.d.ts +73 -0
- package/dist/src/context/triggers.d.ts.map +1 -0
- package/dist/src/context/triggers.js +172 -0
- package/dist/src/context/triggers.js.map +1 -0
- package/dist/src/context/types.d.ts +137 -0
- package/dist/src/context/types.d.ts.map +1 -0
- package/dist/src/context/types.js +25 -0
- package/dist/src/context/types.js.map +1 -0
- package/dist/src/crypto/keccak256.d.ts +15 -0
- package/dist/src/crypto/keccak256.d.ts.map +1 -0
- package/dist/src/crypto/keccak256.js +89 -0
- package/dist/src/crypto/keccak256.js.map +1 -0
- package/dist/src/crypto/sha256.d.ts +16 -0
- package/dist/src/crypto/sha256.d.ts.map +1 -0
- package/dist/src/crypto/sha256.js +81 -0
- package/dist/src/crypto/sha256.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/auBsb.d.ts +11 -0
- package/dist/src/detect/detectors/bankcodes/auBsb.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/auBsb.js +34 -0
- package/dist/src/detect/detectors/bankcodes/auBsb.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/brAgencia.d.ts +15 -0
- package/dist/src/detect/detectors/bankcodes/brAgencia.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/brAgencia.js +43 -0
- package/dist/src/detect/detectors/bankcodes/brAgencia.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/caTransit.d.ts +13 -0
- package/dist/src/detect/detectors/bankcodes/caTransit.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/caTransit.js +86 -0
- package/dist/src/detect/detectors/bankcodes/caTransit.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/inIfsc.d.ts +13 -0
- package/dist/src/detect/detectors/bankcodes/inIfsc.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/inIfsc.js +37 -0
- package/dist/src/detect/detectors/bankcodes/inIfsc.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/index.d.ts +10 -0
- package/dist/src/detect/detectors/bankcodes/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/index.js +10 -0
- package/dist/src/detect/detectors/bankcodes/index.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/ukSortCode.d.ts +13 -0
- package/dist/src/detect/detectors/bankcodes/ukSortCode.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/ukSortCode.js +36 -0
- package/dist/src/detect/detectors/bankcodes/ukSortCode.js.map +1 -0
- package/dist/src/detect/detectors/bankcodes/usRouting.d.ts +12 -0
- package/dist/src/detect/detectors/bankcodes/usRouting.d.ts.map +1 -0
- package/dist/src/detect/detectors/bankcodes/usRouting.js +45 -0
- package/dist/src/detect/detectors/bankcodes/usRouting.js.map +1 -0
- package/dist/src/detect/detectors/contact/email.d.ts +16 -0
- package/dist/src/detect/detectors/contact/email.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/email.js +111 -0
- package/dist/src/detect/detectors/contact/email.js.map +1 -0
- package/dist/src/detect/detectors/contact/index.d.ts +11 -0
- package/dist/src/detect/detectors/contact/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/index.js +11 -0
- package/dist/src/detect/detectors/contact/index.js.map +1 -0
- package/dist/src/detect/detectors/contact/ipv4.d.ts +12 -0
- package/dist/src/detect/detectors/contact/ipv4.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/ipv4.js +109 -0
- package/dist/src/detect/detectors/contact/ipv4.js.map +1 -0
- package/dist/src/detect/detectors/contact/ipv6.d.ts +16 -0
- package/dist/src/detect/detectors/contact/ipv6.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/ipv6.js +187 -0
- package/dist/src/detect/detectors/contact/ipv6.js.map +1 -0
- package/dist/src/detect/detectors/contact/mac.d.ts +14 -0
- package/dist/src/detect/detectors/contact/mac.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/mac.js +64 -0
- package/dist/src/detect/detectors/contact/mac.js.map +1 -0
- package/dist/src/detect/detectors/contact/phone.d.ts +21 -0
- package/dist/src/detect/detectors/contact/phone.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/phone.js +76 -0
- package/dist/src/detect/detectors/contact/phone.js.map +1 -0
- package/dist/src/detect/detectors/contact/urlCredentials.d.ts +23 -0
- package/dist/src/detect/detectors/contact/urlCredentials.d.ts.map +1 -0
- package/dist/src/detect/detectors/contact/urlCredentials.js +123 -0
- package/dist/src/detect/detectors/contact/urlCredentials.js.map +1 -0
- package/dist/src/detect/detectors/crypto/ada.d.ts +13 -0
- package/dist/src/detect/detectors/crypto/ada.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/ada.js +51 -0
- package/dist/src/detect/detectors/crypto/ada.js.map +1 -0
- package/dist/src/detect/detectors/crypto/btc.d.ts +15 -0
- package/dist/src/detect/detectors/crypto/btc.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/btc.js +78 -0
- package/dist/src/detect/detectors/crypto/btc.js.map +1 -0
- package/dist/src/detect/detectors/crypto/dot.d.ts +13 -0
- package/dist/src/detect/detectors/crypto/dot.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/dot.js +41 -0
- package/dist/src/detect/detectors/crypto/dot.js.map +1 -0
- package/dist/src/detect/detectors/crypto/eth.d.ts +15 -0
- package/dist/src/detect/detectors/crypto/eth.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/eth.js +63 -0
- package/dist/src/detect/detectors/crypto/eth.js.map +1 -0
- package/dist/src/detect/detectors/crypto/index.d.ts +12 -0
- package/dist/src/detect/detectors/crypto/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/index.js +12 -0
- package/dist/src/detect/detectors/crypto/index.js.map +1 -0
- package/dist/src/detect/detectors/crypto/ltc.d.ts +12 -0
- package/dist/src/detect/detectors/crypto/ltc.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/ltc.js +71 -0
- package/dist/src/detect/detectors/crypto/ltc.js.map +1 -0
- package/dist/src/detect/detectors/crypto/sol.d.ts +13 -0
- package/dist/src/detect/detectors/crypto/sol.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/sol.js +39 -0
- package/dist/src/detect/detectors/crypto/sol.js.map +1 -0
- package/dist/src/detect/detectors/crypto/trx.d.ts +8 -0
- package/dist/src/detect/detectors/crypto/trx.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/trx.js +34 -0
- package/dist/src/detect/detectors/crypto/trx.js.map +1 -0
- package/dist/src/detect/detectors/crypto/xmr.d.ts +10 -0
- package/dist/src/detect/detectors/crypto/xmr.d.ts.map +1 -0
- package/dist/src/detect/detectors/crypto/xmr.js +51 -0
- package/dist/src/detect/detectors/crypto/xmr.js.map +1 -0
- package/dist/src/detect/detectors/documents/driversLicense.d.ts +24 -0
- package/dist/src/detect/detectors/documents/driversLicense.d.ts.map +1 -0
- package/dist/src/detect/detectors/documents/driversLicense.js +79 -0
- package/dist/src/detect/detectors/documents/driversLicense.js.map +1 -0
- package/dist/src/detect/detectors/documents/healthData.d.ts +23 -0
- package/dist/src/detect/detectors/documents/healthData.d.ts.map +1 -0
- package/dist/src/detect/detectors/documents/healthData.js +78 -0
- package/dist/src/detect/detectors/documents/healthData.js.map +1 -0
- package/dist/src/detect/detectors/documents/index.d.ts +9 -0
- package/dist/src/detect/detectors/documents/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/documents/index.js +9 -0
- package/dist/src/detect/detectors/documents/index.js.map +1 -0
- package/dist/src/detect/detectors/documents/passportMrz.d.ts +20 -0
- package/dist/src/detect/detectors/documents/passportMrz.d.ts.map +1 -0
- package/dist/src/detect/detectors/documents/passportMrz.js +194 -0
- package/dist/src/detect/detectors/documents/passportMrz.js.map +1 -0
- package/dist/src/detect/detectors/documents/usNpi.d.ts +16 -0
- package/dist/src/detect/detectors/documents/usNpi.d.ts.map +1 -0
- package/dist/src/detect/detectors/documents/usNpi.js +48 -0
- package/dist/src/detect/detectors/documents/usNpi.js.map +1 -0
- package/dist/src/detect/detectors/documents/vin.d.ts +15 -0
- package/dist/src/detect/detectors/documents/vin.d.ts.map +1 -0
- package/dist/src/detect/detectors/documents/vin.js +64 -0
- package/dist/src/detect/detectors/documents/vin.js.map +1 -0
- package/dist/src/detect/detectors/financial/creditCard.d.ts +23 -0
- package/dist/src/detect/detectors/financial/creditCard.d.ts.map +1 -0
- package/dist/src/detect/detectors/financial/creditCard.js +157 -0
- package/dist/src/detect/detectors/financial/creditCard.js.map +1 -0
- package/dist/src/detect/detectors/financial/iban.d.ts +18 -0
- package/dist/src/detect/detectors/financial/iban.d.ts.map +1 -0
- package/dist/src/detect/detectors/financial/iban.js +80 -0
- package/dist/src/detect/detectors/financial/iban.js.map +1 -0
- package/dist/src/detect/detectors/financial/ibanRegistry.d.ts +35 -0
- package/dist/src/detect/detectors/financial/ibanRegistry.d.ts.map +1 -0
- package/dist/src/detect/detectors/financial/ibanRegistry.js +92 -0
- package/dist/src/detect/detectors/financial/ibanRegistry.js.map +1 -0
- package/dist/src/detect/detectors/financial/index.d.ts +7 -0
- package/dist/src/detect/detectors/financial/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/financial/index.js +7 -0
- package/dist/src/detect/detectors/financial/index.js.map +1 -0
- package/dist/src/detect/detectors/financial/swiftBic.d.ts +17 -0
- package/dist/src/detect/detectors/financial/swiftBic.d.ts.map +1 -0
- package/dist/src/detect/detectors/financial/swiftBic.js +55 -0
- package/dist/src/detect/detectors/financial/swiftBic.js.map +1 -0
- package/dist/src/detect/detectors/index.d.ts +15 -0
- package/dist/src/detect/detectors/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/index.js +15 -0
- package/dist/src/detect/detectors/index.js.map +1 -0
- package/dist/src/detect/detectors/location/coordinates.d.ts +14 -0
- package/dist/src/detect/detectors/location/coordinates.d.ts.map +1 -0
- package/dist/src/detect/detectors/location/coordinates.js +79 -0
- package/dist/src/detect/detectors/location/coordinates.js.map +1 -0
- package/dist/src/detect/detectors/location/index.d.ts +7 -0
- package/dist/src/detect/detectors/location/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/location/index.js +7 -0
- package/dist/src/detect/detectors/location/index.js.map +1 -0
- package/dist/src/detect/detectors/location/postalCode.d.ts +13 -0
- package/dist/src/detect/detectors/location/postalCode.d.ts.map +1 -0
- package/dist/src/detect/detectors/location/postalCode.js +53 -0
- package/dist/src/detect/detectors/location/postalCode.js.map +1 -0
- package/dist/src/detect/detectors/location/postalRegistry.d.ts +19 -0
- package/dist/src/detect/detectors/location/postalRegistry.d.ts.map +1 -0
- package/dist/src/detect/detectors/location/postalRegistry.js +73 -0
- package/dist/src/detect/detectors/location/postalRegistry.js.map +1 -0
- package/dist/src/detect/detectors/location/streetAddress.d.ts +21 -0
- package/dist/src/detect/detectors/location/streetAddress.d.ts.map +1 -0
- package/dist/src/detect/detectors/location/streetAddress.js +70 -0
- package/dist/src/detect/detectors/location/streetAddress.js.map +1 -0
- package/dist/src/detect/detectors/natid/africa.d.ts +17 -0
- package/dist/src/detect/detectors/natid/africa.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/africa.js +106 -0
- package/dist/src/detect/detectors/natid/africa.js.map +1 -0
- package/dist/src/detect/detectors/natid/ar.d.ts +14 -0
- package/dist/src/detect/detectors/natid/ar.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/ar.js +62 -0
- package/dist/src/detect/detectors/natid/ar.js.map +1 -0
- package/dist/src/detect/detectors/natid/au.d.ts +13 -0
- package/dist/src/detect/detectors/natid/au.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/au.js +100 -0
- package/dist/src/detect/detectors/natid/au.js.map +1 -0
- package/dist/src/detect/detectors/natid/be.d.ts +8 -0
- package/dist/src/detect/detectors/natid/be.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/be.js +44 -0
- package/dist/src/detect/detectors/natid/be.js.map +1 -0
- package/dist/src/detect/detectors/natid/bg.d.ts +7 -0
- package/dist/src/detect/detectors/natid/bg.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/bg.js +44 -0
- package/dist/src/detect/detectors/natid/bg.js.map +1 -0
- package/dist/src/detect/detectors/natid/br.d.ts +8 -0
- package/dist/src/detect/detectors/natid/br.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/br.js +85 -0
- package/dist/src/detect/detectors/natid/br.js.map +1 -0
- package/dist/src/detect/detectors/natid/ca.d.ts +8 -0
- package/dist/src/detect/detectors/natid/ca.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/ca.js +41 -0
- package/dist/src/detect/detectors/natid/ca.js.map +1 -0
- package/dist/src/detect/detectors/natid/cl.d.ts +9 -0
- package/dist/src/detect/detectors/natid/cl.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/cl.js +47 -0
- package/dist/src/detect/detectors/natid/cl.js.map +1 -0
- package/dist/src/detect/detectors/natid/cn.d.ts +9 -0
- package/dist/src/detect/detectors/natid/cn.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/cn.js +49 -0
- package/dist/src/detect/detectors/natid/cn.js.map +1 -0
- package/dist/src/detect/detectors/natid/co.d.ts +10 -0
- package/dist/src/detect/detectors/natid/co.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/co.js +43 -0
- package/dist/src/detect/detectors/natid/co.js.map +1 -0
- package/dist/src/detect/detectors/natid/cz.d.ts +11 -0
- package/dist/src/detect/detectors/natid/cz.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/cz.js +44 -0
- package/dist/src/detect/detectors/natid/cz.js.map +1 -0
- package/dist/src/detect/detectors/natid/de.d.ts +16 -0
- package/dist/src/detect/detectors/natid/de.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/de.js +77 -0
- package/dist/src/detect/detectors/natid/de.js.map +1 -0
- package/dist/src/detect/detectors/natid/dk.d.ts +9 -0
- package/dist/src/detect/detectors/natid/dk.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/dk.js +31 -0
- package/dist/src/detect/detectors/natid/dk.js.map +1 -0
- package/dist/src/detect/detectors/natid/es.d.ts +12 -0
- package/dist/src/detect/detectors/natid/es.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/es.js +96 -0
- package/dist/src/detect/detectors/natid/es.js.map +1 -0
- package/dist/src/detect/detectors/natid/fi.d.ts +10 -0
- package/dist/src/detect/detectors/natid/fi.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/fi.js +40 -0
- package/dist/src/detect/detectors/natid/fi.js.map +1 -0
- package/dist/src/detect/detectors/natid/fr.d.ts +12 -0
- package/dist/src/detect/detectors/natid/fr.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/fr.js +61 -0
- package/dist/src/detect/detectors/natid/fr.js.map +1 -0
- package/dist/src/detect/detectors/natid/gb.d.ts +10 -0
- package/dist/src/detect/detectors/natid/gb.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/gb.js +72 -0
- package/dist/src/detect/detectors/natid/gb.js.map +1 -0
- package/dist/src/detect/detectors/natid/gr.d.ts +7 -0
- package/dist/src/detect/detectors/natid/gr.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/gr.js +36 -0
- package/dist/src/detect/detectors/natid/gr.js.map +1 -0
- package/dist/src/detect/detectors/natid/gulf.d.ts +16 -0
- package/dist/src/detect/detectors/natid/gulf.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/gulf.js +121 -0
- package/dist/src/detect/detectors/natid/gulf.js.map +1 -0
- package/dist/src/detect/detectors/natid/hk.d.ts +9 -0
- package/dist/src/detect/detectors/natid/hk.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/hk.js +41 -0
- package/dist/src/detect/detectors/natid/hk.js.map +1 -0
- package/dist/src/detect/detectors/natid/hr.d.ts +6 -0
- package/dist/src/detect/detectors/natid/hr.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/hr.js +32 -0
- package/dist/src/detect/detectors/natid/hr.js.map +1 -0
- package/dist/src/detect/detectors/natid/hu.d.ts +7 -0
- package/dist/src/detect/detectors/natid/hu.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/hu.js +37 -0
- package/dist/src/detect/detectors/natid/hu.js.map +1 -0
- package/dist/src/detect/detectors/natid/ie.d.ts +9 -0
- package/dist/src/detect/detectors/natid/ie.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/ie.js +36 -0
- package/dist/src/detect/detectors/natid/ie.js.map +1 -0
- package/dist/src/detect/detectors/natid/il.d.ts +10 -0
- package/dist/src/detect/detectors/natid/il.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/il.js +38 -0
- package/dist/src/detect/detectors/natid/il.js.map +1 -0
- package/dist/src/detect/detectors/natid/in.d.ts +17 -0
- package/dist/src/detect/detectors/natid/in.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/in.js +67 -0
- package/dist/src/detect/detectors/natid/in.js.map +1 -0
- package/dist/src/detect/detectors/natid/index.d.ts +55 -0
- package/dist/src/detect/detectors/natid/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/index.js +55 -0
- package/dist/src/detect/detectors/natid/index.js.map +1 -0
- package/dist/src/detect/detectors/natid/is.d.ts +8 -0
- package/dist/src/detect/detectors/natid/is.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/is.js +42 -0
- package/dist/src/detect/detectors/natid/is.js.map +1 -0
- package/dist/src/detect/detectors/natid/it.d.ts +12 -0
- package/dist/src/detect/detectors/natid/it.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/it.js +62 -0
- package/dist/src/detect/detectors/natid/it.js.map +1 -0
- package/dist/src/detect/detectors/natid/jp.d.ts +9 -0
- package/dist/src/detect/detectors/natid/jp.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/jp.js +46 -0
- package/dist/src/detect/detectors/natid/jp.js.map +1 -0
- package/dist/src/detect/detectors/natid/kr.d.ts +11 -0
- package/dist/src/detect/detectors/natid/kr.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/kr.js +40 -0
- package/dist/src/detect/detectors/natid/kr.js.map +1 -0
- package/dist/src/detect/detectors/natid/kz.d.ts +8 -0
- package/dist/src/detect/detectors/natid/kz.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/kz.js +46 -0
- package/dist/src/detect/detectors/natid/kz.js.map +1 -0
- package/dist/src/detect/detectors/natid/mx.d.ts +16 -0
- package/dist/src/detect/detectors/natid/mx.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/mx.js +82 -0
- package/dist/src/detect/detectors/natid/mx.js.map +1 -0
- package/dist/src/detect/detectors/natid/nl.d.ts +8 -0
- package/dist/src/detect/detectors/natid/nl.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/nl.js +40 -0
- package/dist/src/detect/detectors/natid/nl.js.map +1 -0
- package/dist/src/detect/detectors/natid/no.d.ts +9 -0
- package/dist/src/detect/detectors/natid/no.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/no.js +52 -0
- package/dist/src/detect/detectors/natid/no.js.map +1 -0
- package/dist/src/detect/detectors/natid/nz.d.ts +9 -0
- package/dist/src/detect/detectors/natid/nz.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/nz.js +52 -0
- package/dist/src/detect/detectors/natid/nz.js.map +1 -0
- package/dist/src/detect/detectors/natid/pe.d.ts +7 -0
- package/dist/src/detect/detectors/natid/pe.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/pe.js +26 -0
- package/dist/src/detect/detectors/natid/pe.js.map +1 -0
- package/dist/src/detect/detectors/natid/pl.d.ts +11 -0
- package/dist/src/detect/detectors/natid/pl.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/pl.js +105 -0
- package/dist/src/detect/detectors/natid/pl.js.map +1 -0
- package/dist/src/detect/detectors/natid/pt.d.ts +6 -0
- package/dist/src/detect/detectors/natid/pt.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/pt.js +35 -0
- package/dist/src/detect/detectors/natid/pt.js.map +1 -0
- package/dist/src/detect/detectors/natid/ro.d.ts +8 -0
- package/dist/src/detect/detectors/natid/ro.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/ro.js +48 -0
- package/dist/src/detect/detectors/natid/ro.js.map +1 -0
- package/dist/src/detect/detectors/natid/ru.d.ts +11 -0
- package/dist/src/detect/detectors/natid/ru.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/ru.js +86 -0
- package/dist/src/detect/detectors/natid/ru.js.map +1 -0
- package/dist/src/detect/detectors/natid/se.d.ts +9 -0
- package/dist/src/detect/detectors/natid/se.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/se.js +43 -0
- package/dist/src/detect/detectors/natid/se.js.map +1 -0
- package/dist/src/detect/detectors/natid/seasia.d.ts +19 -0
- package/dist/src/detect/detectors/natid/seasia.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/seasia.js +182 -0
- package/dist/src/detect/detectors/natid/seasia.js.map +1 -0
- package/dist/src/detect/detectors/natid/sg.d.ts +8 -0
- package/dist/src/detect/detectors/natid/sg.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/sg.js +39 -0
- package/dist/src/detect/detectors/natid/sg.js.map +1 -0
- package/dist/src/detect/detectors/natid/si.d.ts +8 -0
- package/dist/src/detect/detectors/natid/si.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/si.js +44 -0
- package/dist/src/detect/detectors/natid/si.js.map +1 -0
- package/dist/src/detect/detectors/natid/tr.d.ts +14 -0
- package/dist/src/detect/detectors/natid/tr.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/tr.js +79 -0
- package/dist/src/detect/detectors/natid/tr.js.map +1 -0
- package/dist/src/detect/detectors/natid/tw.d.ts +9 -0
- package/dist/src/detect/detectors/natid/tw.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/tw.js +40 -0
- package/dist/src/detect/detectors/natid/tw.js.map +1 -0
- package/dist/src/detect/detectors/natid/ua.d.ts +7 -0
- package/dist/src/detect/detectors/natid/ua.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/ua.js +38 -0
- package/dist/src/detect/detectors/natid/ua.js.map +1 -0
- package/dist/src/detect/detectors/natid/us.d.ts +15 -0
- package/dist/src/detect/detectors/natid/us.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/us.js +119 -0
- package/dist/src/detect/detectors/natid/us.js.map +1 -0
- package/dist/src/detect/detectors/natid/za.d.ts +9 -0
- package/dist/src/detect/detectors/natid/za.d.ts.map +1 -0
- package/dist/src/detect/detectors/natid/za.js +44 -0
- package/dist/src/detect/detectors/natid/za.js.map +1 -0
- package/dist/src/detect/detectors/secrets/apiKey.d.ts +14 -0
- package/dist/src/detect/detectors/secrets/apiKey.d.ts.map +1 -0
- package/dist/src/detect/detectors/secrets/apiKey.js +103 -0
- package/dist/src/detect/detectors/secrets/apiKey.js.map +1 -0
- package/dist/src/detect/detectors/secrets/connectionString.d.ts +12 -0
- package/dist/src/detect/detectors/secrets/connectionString.d.ts.map +1 -0
- package/dist/src/detect/detectors/secrets/connectionString.js +70 -0
- package/dist/src/detect/detectors/secrets/connectionString.js.map +1 -0
- package/dist/src/detect/detectors/secrets/genericSecret.d.ts +22 -0
- package/dist/src/detect/detectors/secrets/genericSecret.d.ts.map +1 -0
- package/dist/src/detect/detectors/secrets/genericSecret.js +77 -0
- package/dist/src/detect/detectors/secrets/genericSecret.js.map +1 -0
- package/dist/src/detect/detectors/secrets/index.d.ts +9 -0
- package/dist/src/detect/detectors/secrets/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/secrets/index.js +9 -0
- package/dist/src/detect/detectors/secrets/index.js.map +1 -0
- package/dist/src/detect/detectors/secrets/jwt.d.ts +11 -0
- package/dist/src/detect/detectors/secrets/jwt.d.ts.map +1 -0
- package/dist/src/detect/detectors/secrets/jwt.js +111 -0
- package/dist/src/detect/detectors/secrets/jwt.js.map +1 -0
- package/dist/src/detect/detectors/secrets/pemPrivateKey.d.ts +16 -0
- package/dist/src/detect/detectors/secrets/pemPrivateKey.d.ts.map +1 -0
- package/dist/src/detect/detectors/secrets/pemPrivateKey.js +56 -0
- package/dist/src/detect/detectors/secrets/pemPrivateKey.js.map +1 -0
- package/dist/src/detect/detectors/vat/euVat.d.ts +17 -0
- package/dist/src/detect/detectors/vat/euVat.d.ts.map +1 -0
- package/dist/src/detect/detectors/vat/euVat.js +293 -0
- package/dist/src/detect/detectors/vat/euVat.js.map +1 -0
- package/dist/src/detect/detectors/vat/index.d.ts +5 -0
- package/dist/src/detect/detectors/vat/index.d.ts.map +1 -0
- package/dist/src/detect/detectors/vat/index.js +5 -0
- package/dist/src/detect/detectors/vat/index.js.map +1 -0
- package/dist/src/detect/entropy.d.ts +28 -0
- package/dist/src/detect/entropy.d.ts.map +1 -0
- package/dist/src/detect/entropy.js +64 -0
- package/dist/src/detect/entropy.js.map +1 -0
- package/dist/src/detect/isoCountries.d.ts +10 -0
- package/dist/src/detect/isoCountries.d.ts.map +1 -0
- package/dist/src/detect/isoCountries.js +25 -0
- package/dist/src/detect/isoCountries.js.map +1 -0
- package/dist/src/detect/registry.d.ts +50 -0
- package/dist/src/detect/registry.d.ts.map +1 -0
- package/dist/src/detect/registry.js +110 -0
- package/dist/src/detect/registry.js.map +1 -0
- package/dist/src/detect/runner.d.ts +64 -0
- package/dist/src/detect/runner.d.ts.map +1 -0
- package/dist/src/detect/runner.js +142 -0
- package/dist/src/detect/runner.js.map +1 -0
- package/dist/src/detect/types.d.ts +251 -0
- package/dist/src/detect/types.d.ts.map +1 -0
- package/dist/src/detect/types.js +59 -0
- package/dist/src/detect/types.js.map +1 -0
- package/dist/src/encoding/base58.d.ts +26 -0
- package/dist/src/encoding/base58.d.ts.map +1 -0
- package/dist/src/encoding/base58.js +77 -0
- package/dist/src/encoding/base58.js.map +1 -0
- package/dist/src/encoding/base58monero.d.ts +15 -0
- package/dist/src/encoding/base58monero.d.ts.map +1 -0
- package/dist/src/encoding/base58monero.js +87 -0
- package/dist/src/encoding/base58monero.js.map +1 -0
- package/dist/src/encoding/bech32.d.ts +28 -0
- package/dist/src/encoding/bech32.d.ts.map +1 -0
- package/dist/src/encoding/bech32.js +108 -0
- package/dist/src/encoding/bech32.js.map +1 -0
- package/dist/src/encoding/bytes.d.ts +15 -0
- package/dist/src/encoding/bytes.d.ts.map +1 -0
- package/dist/src/encoding/bytes.js +46 -0
- package/dist/src/encoding/bytes.js.map +1 -0
- package/dist/src/entityFamily.d.ts +18 -0
- package/dist/src/entityFamily.d.ts.map +1 -0
- package/dist/src/entityFamily.js +54 -0
- package/dist/src/entityFamily.js.map +1 -0
- package/dist/src/entityLabel.d.ts +18 -0
- package/dist/src/entityLabel.d.ts.map +1 -0
- package/dist/src/entityLabel.js +53 -0
- package/dist/src/entityLabel.js.map +1 -0
- package/dist/src/entityTypes.d.ts +64 -0
- package/dist/src/entityTypes.d.ts.map +1 -0
- package/dist/src/entityTypes.js +94 -0
- package/dist/src/entityTypes.js.map +1 -0
- package/dist/src/exposure/index.d.ts +86 -0
- package/dist/src/exposure/index.d.ts.map +1 -0
- package/dist/src/exposure/index.js +134 -0
- package/dist/src/exposure/index.js.map +1 -0
- package/dist/src/fuse/calibrate.d.ts +95 -0
- package/dist/src/fuse/calibrate.d.ts.map +1 -0
- package/dist/src/fuse/calibrate.js +165 -0
- package/dist/src/fuse/calibrate.js.map +1 -0
- package/dist/src/fuse/defaultCalibration.d.ts +52 -0
- package/dist/src/fuse/defaultCalibration.d.ts.map +1 -0
- package/dist/src/fuse/defaultCalibration.js +41 -0
- package/dist/src/fuse/defaultCalibration.js.map +1 -0
- package/dist/src/fuse/explain.d.ts +55 -0
- package/dist/src/fuse/explain.d.ts.map +1 -0
- package/dist/src/fuse/explain.js +91 -0
- package/dist/src/fuse/explain.js.map +1 -0
- package/dist/src/fuse/profiles.d.ts +80 -0
- package/dist/src/fuse/profiles.d.ts.map +1 -0
- package/dist/src/fuse/profiles.js +126 -0
- package/dist/src/fuse/profiles.js.map +1 -0
- package/dist/src/fuse/resolve.d.ts +73 -0
- package/dist/src/fuse/resolve.d.ts.map +1 -0
- package/dist/src/fuse/resolve.js +206 -0
- package/dist/src/fuse/resolve.js.map +1 -0
- package/dist/src/gazetteer/index.d.ts +41 -0
- package/dist/src/gazetteer/index.d.ts.map +1 -0
- package/dist/src/gazetteer/index.js +117 -0
- package/dist/src/gazetteer/index.js.map +1 -0
- package/dist/src/generate/bankcodes.d.ts +20 -0
- package/dist/src/generate/bankcodes.d.ts.map +1 -0
- package/dist/src/generate/bankcodes.js +71 -0
- package/dist/src/generate/bankcodes.js.map +1 -0
- package/dist/src/generate/contact.d.ts +31 -0
- package/dist/src/generate/contact.d.ts.map +1 -0
- package/dist/src/generate/contact.js +139 -0
- package/dist/src/generate/contact.js.map +1 -0
- package/dist/src/generate/crypto.d.ts +27 -0
- package/dist/src/generate/crypto.d.ts.map +1 -0
- package/dist/src/generate/crypto.js +88 -0
- package/dist/src/generate/crypto.js.map +1 -0
- package/dist/src/generate/documents.d.ts +24 -0
- package/dist/src/generate/documents.d.ts.map +1 -0
- package/dist/src/generate/documents.js +124 -0
- package/dist/src/generate/documents.js.map +1 -0
- package/dist/src/generate/financial.d.ts +26 -0
- package/dist/src/generate/financial.d.ts.map +1 -0
- package/dist/src/generate/financial.js +136 -0
- package/dist/src/generate/financial.js.map +1 -0
- package/dist/src/generate/index.d.ts +23 -0
- package/dist/src/generate/index.d.ts.map +1 -0
- package/dist/src/generate/index.js +23 -0
- package/dist/src/generate/index.js.map +1 -0
- package/dist/src/generate/location.d.ts +12 -0
- package/dist/src/generate/location.d.ts.map +1 -0
- package/dist/src/generate/location.js +75 -0
- package/dist/src/generate/location.js.map +1 -0
- package/dist/src/generate/natidAmOc.d.ts +22 -0
- package/dist/src/generate/natidAmOc.d.ts.map +1 -0
- package/dist/src/generate/natidAmOc.js +181 -0
- package/dist/src/generate/natidAmOc.js.map +1 -0
- package/dist/src/generate/natidAsia.d.ts +20 -0
- package/dist/src/generate/natidAsia.d.ts.map +1 -0
- package/dist/src/generate/natidAsia.js +147 -0
- package/dist/src/generate/natidAsia.js.map +1 -0
- package/dist/src/generate/natidCee.d.ts +21 -0
- package/dist/src/generate/natidCee.d.ts.map +1 -0
- package/dist/src/generate/natidCee.js +181 -0
- package/dist/src/generate/natidCee.js.map +1 -0
- package/dist/src/generate/natidMeCis.d.ts +17 -0
- package/dist/src/generate/natidMeCis.d.ts.map +1 -0
- package/dist/src/generate/natidMeCis.js +121 -0
- package/dist/src/generate/natidMeCis.js.map +1 -0
- package/dist/src/generate/natidWest.d.ts +32 -0
- package/dist/src/generate/natidWest.d.ts.map +1 -0
- package/dist/src/generate/natidWest.js +187 -0
- package/dist/src/generate/natidWest.js.map +1 -0
- package/dist/src/generate/prng.d.ts +10 -0
- package/dist/src/generate/prng.d.ts.map +1 -0
- package/dist/src/generate/prng.js +18 -0
- package/dist/src/generate/prng.js.map +1 -0
- package/dist/src/generate/secrets.d.ts +23 -0
- package/dist/src/generate/secrets.d.ts.map +1 -0
- package/dist/src/generate/secrets.js +126 -0
- package/dist/src/generate/secrets.js.map +1 -0
- package/dist/src/generate/vat.d.ts +11 -0
- package/dist/src/generate/vat.d.ts.map +1 -0
- package/dist/src/generate/vat.js +233 -0
- package/dist/src/generate/vat.js.map +1 -0
- package/dist/src/index.d.ts +81 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +76 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mask/egressGuard.d.ts +54 -0
- package/dist/src/mask/egressGuard.d.ts.map +1 -0
- package/dist/src/mask/egressGuard.js +67 -0
- package/dist/src/mask/egressGuard.js.map +1 -0
- package/dist/src/mask/masker.d.ts +76 -0
- package/dist/src/mask/masker.d.ts.map +1 -0
- package/dist/src/mask/masker.js +201 -0
- package/dist/src/mask/masker.js.map +1 -0
- package/dist/src/mask/restorer.d.ts +96 -0
- package/dist/src/mask/restorer.d.ts.map +1 -0
- package/dist/src/mask/restorer.js +263 -0
- package/dist/src/mask/restorer.js.map +1 -0
- package/dist/src/mask/surrogatePools.d.ts +33 -0
- package/dist/src/mask/surrogatePools.d.ts.map +1 -0
- package/dist/src/mask/surrogatePools.js +81 -0
- package/dist/src/mask/surrogatePools.js.map +1 -0
- package/dist/src/mask/surrogates.d.ts +45 -0
- package/dist/src/mask/surrogates.d.ts.map +1 -0
- package/dist/src/mask/surrogates.js +241 -0
- package/dist/src/mask/surrogates.js.map +1 -0
- package/dist/src/mask/vault.d.ts +76 -0
- package/dist/src/mask/vault.d.ts.map +1 -0
- package/dist/src/mask/vault.js +141 -0
- package/dist/src/mask/vault.js.map +1 -0
- package/dist/src/ner/align.d.ts +36 -0
- package/dist/src/ner/align.d.ts.map +1 -0
- package/dist/src/ner/align.js +73 -0
- package/dist/src/ner/align.js.map +1 -0
- package/dist/src/ner/chunk.d.ts +27 -0
- package/dist/src/ner/chunk.d.ts.map +1 -0
- package/dist/src/ner/chunk.js +55 -0
- package/dist/src/ner/chunk.js.map +1 -0
- package/dist/src/ner/chunkCache.d.ts +63 -0
- package/dist/src/ner/chunkCache.d.ts.map +1 -0
- package/dist/src/ner/chunkCache.js +99 -0
- package/dist/src/ner/chunkCache.js.map +1 -0
- package/dist/src/ner/engine.d.ts +53 -0
- package/dist/src/ner/engine.d.ts.map +1 -0
- package/dist/src/ner/engine.js +113 -0
- package/dist/src/ner/engine.js.map +1 -0
- package/dist/src/ner/merge.d.ts +26 -0
- package/dist/src/ner/merge.d.ts.map +1 -0
- package/dist/src/ner/merge.js +108 -0
- package/dist/src/ner/merge.js.map +1 -0
- package/dist/src/ner/runStage2.d.ts +17 -0
- package/dist/src/ner/runStage2.d.ts.map +1 -0
- package/dist/src/ner/runStage2.js +43 -0
- package/dist/src/ner/runStage2.js.map +1 -0
- package/dist/src/ner/stage2b.d.ts +59 -0
- package/dist/src/ner/stage2b.d.ts.map +1 -0
- package/dist/src/ner/stage2b.js +51 -0
- package/dist/src/ner/stage2b.js.map +1 -0
- package/dist/src/ner/transformersClassifier.d.ts +45 -0
- package/dist/src/ner/transformersClassifier.d.ts.map +1 -0
- package/dist/src/ner/transformersClassifier.js +40 -0
- package/dist/src/ner/transformersClassifier.js.map +1 -0
- package/dist/src/ner/types.d.ts +93 -0
- package/dist/src/ner/types.d.ts.map +1 -0
- package/dist/src/ner/types.js +12 -0
- package/dist/src/ner/types.js.map +1 -0
- package/dist/src/normalization.d.ts +24 -0
- package/dist/src/normalization.d.ts.map +1 -0
- package/dist/src/normalization.js +92 -0
- package/dist/src/normalization.js.map +1 -0
- package/dist/src/offsetMap.d.ts +165 -0
- package/dist/src/offsetMap.d.ts.map +1 -0
- package/dist/src/offsetMap.js +225 -0
- package/dist/src/offsetMap.js.map +1 -0
- package/dist/src/pipeline.d.ts +58 -0
- package/dist/src/pipeline.d.ts.map +1 -0
- package/dist/src/pipeline.js +57 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/protect.d.ts +146 -0
- package/dist/src/protect.d.ts.map +1 -0
- package/dist/src/protect.js +161 -0
- package/dist/src/protect.js.map +1 -0
- package/dist/src/scripts.d.ts +37 -0
- package/dist/src/scripts.d.ts.map +1 -0
- package/dist/src/scripts.js +145 -0
- package/dist/src/scripts.js.map +1 -0
- package/dist/src/transforms/foldDigits.d.ts +49 -0
- package/dist/src/transforms/foldDigits.d.ts.map +1 -0
- package/dist/src/transforms/foldDigits.js +135 -0
- package/dist/src/transforms/foldDigits.js.map +1 -0
- package/dist/src/transforms/graphemes.d.ts +6 -0
- package/dist/src/transforms/graphemes.d.ts.map +1 -0
- package/dist/src/transforms/graphemes.js +6 -0
- package/dist/src/transforms/graphemes.js.map +1 -0
- package/dist/src/transforms/homoglyphFold.d.ts +5 -0
- package/dist/src/transforms/homoglyphFold.d.ts.map +1 -0
- package/dist/src/transforms/homoglyphFold.js +214 -0
- package/dist/src/transforms/homoglyphFold.js.map +1 -0
- package/dist/src/transforms/nfkc.d.ts +20 -0
- package/dist/src/transforms/nfkc.d.ts.map +1 -0
- package/dist/src/transforms/nfkc.js +48 -0
- package/dist/src/transforms/nfkc.js.map +1 -0
- package/dist/src/transforms/stripInvisibles.d.ts +37 -0
- package/dist/src/transforms/stripInvisibles.d.ts.map +1 -0
- package/dist/src/transforms/stripInvisibles.js +151 -0
- package/dist/src/transforms/stripInvisibles.js.map +1 -0
- package/dist/src/transforms/whitespacePunct.d.ts +21 -0
- package/dist/src/transforms/whitespacePunct.d.ts.map +1 -0
- package/dist/src/transforms/whitespacePunct.js +100 -0
- package/dist/src/transforms/whitespacePunct.js.map +1 -0
- package/dist/src/types.d.ts +212 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +14 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +67 -0
- package/src/checksums/aba.ts +45 -0
- package/src/checksums/digits.ts +108 -0
- package/src/checksums/icao9303.ts +53 -0
- package/src/checksums/index.ts +36 -0
- package/src/checksums/iso7064.ts +168 -0
- package/src/checksums/luhn.ts +66 -0
- package/src/checksums/mod97.ts +91 -0
- package/src/checksums/verhoeff.ts +84 -0
- package/src/checksums/weighted.ts +108 -0
- package/src/context/documentProfile.ts +293 -0
- package/src/context/negativeRules.ts +765 -0
- package/src/context/score.ts +430 -0
- package/src/context/structure.ts +611 -0
- package/src/context/triggers.ts +266 -0
- package/src/context/types.ts +150 -0
- package/src/crypto/keccak256.ts +98 -0
- package/src/crypto/sha256.ts +76 -0
- package/src/detect/AUTHORING.md +50 -0
- package/src/detect/detectors/bankcodes/auBsb.ts +36 -0
- package/src/detect/detectors/bankcodes/brAgencia.ts +46 -0
- package/src/detect/detectors/bankcodes/caTransit.ts +89 -0
- package/src/detect/detectors/bankcodes/inIfsc.ts +40 -0
- package/src/detect/detectors/bankcodes/index.ts +9 -0
- package/src/detect/detectors/bankcodes/ukSortCode.ts +38 -0
- package/src/detect/detectors/bankcodes/usRouting.ts +47 -0
- package/src/detect/detectors/contact/email.ts +113 -0
- package/src/detect/detectors/contact/index.ts +10 -0
- package/src/detect/detectors/contact/ipv4.ts +112 -0
- package/src/detect/detectors/contact/ipv6.ts +188 -0
- package/src/detect/detectors/contact/mac.ts +68 -0
- package/src/detect/detectors/contact/phone.ts +81 -0
- package/src/detect/detectors/contact/urlCredentials.ts +124 -0
- package/src/detect/detectors/crypto/ada.ts +52 -0
- package/src/detect/detectors/crypto/btc.ts +77 -0
- package/src/detect/detectors/crypto/dot.ts +42 -0
- package/src/detect/detectors/crypto/eth.ts +70 -0
- package/src/detect/detectors/crypto/index.ts +11 -0
- package/src/detect/detectors/crypto/ltc.ts +69 -0
- package/src/detect/detectors/crypto/sol.ts +41 -0
- package/src/detect/detectors/crypto/trx.ts +35 -0
- package/src/detect/detectors/crypto/xmr.ts +54 -0
- package/src/detect/detectors/documents/driversLicense.ts +83 -0
- package/src/detect/detectors/documents/healthData.ts +88 -0
- package/src/detect/detectors/documents/index.ts +8 -0
- package/src/detect/detectors/documents/passportMrz.ts +203 -0
- package/src/detect/detectors/documents/usNpi.ts +50 -0
- package/src/detect/detectors/documents/vin.ts +67 -0
- package/src/detect/detectors/financial/creditCard.ts +167 -0
- package/src/detect/detectors/financial/iban.ts +82 -0
- package/src/detect/detectors/financial/ibanRegistry.ts +112 -0
- package/src/detect/detectors/financial/index.ts +6 -0
- package/src/detect/detectors/financial/swiftBic.ts +61 -0
- package/src/detect/detectors/index.ts +14 -0
- package/src/detect/detectors/location/coordinates.ts +84 -0
- package/src/detect/detectors/location/index.ts +6 -0
- package/src/detect/detectors/location/postalCode.ts +56 -0
- package/src/detect/detectors/location/postalRegistry.ts +74 -0
- package/src/detect/detectors/location/streetAddress.ts +84 -0
- package/src/detect/detectors/natid/africa.ts +108 -0
- package/src/detect/detectors/natid/ar.ts +62 -0
- package/src/detect/detectors/natid/au.ts +99 -0
- package/src/detect/detectors/natid/be.ts +45 -0
- package/src/detect/detectors/natid/bg.ts +44 -0
- package/src/detect/detectors/natid/br.ts +81 -0
- package/src/detect/detectors/natid/ca.ts +40 -0
- package/src/detect/detectors/natid/cl.ts +47 -0
- package/src/detect/detectors/natid/cn.ts +48 -0
- package/src/detect/detectors/natid/co.ts +46 -0
- package/src/detect/detectors/natid/cz.ts +44 -0
- package/src/detect/detectors/natid/de.ts +75 -0
- package/src/detect/detectors/natid/dk.ts +31 -0
- package/src/detect/detectors/natid/es.ts +95 -0
- package/src/detect/detectors/natid/fi.ts +41 -0
- package/src/detect/detectors/natid/fr.ts +63 -0
- package/src/detect/detectors/natid/gb.ts +70 -0
- package/src/detect/detectors/natid/gr.ts +35 -0
- package/src/detect/detectors/natid/gulf.ts +116 -0
- package/src/detect/detectors/natid/hk.ts +42 -0
- package/src/detect/detectors/natid/hr.ts +32 -0
- package/src/detect/detectors/natid/hu.ts +36 -0
- package/src/detect/detectors/natid/ie.ts +37 -0
- package/src/detect/detectors/natid/il.ts +37 -0
- package/src/detect/detectors/natid/in.ts +67 -0
- package/src/detect/detectors/natid/index.ts +54 -0
- package/src/detect/detectors/natid/is.ts +42 -0
- package/src/detect/detectors/natid/it.ts +65 -0
- package/src/detect/detectors/natid/jp.ts +48 -0
- package/src/detect/detectors/natid/kr.ts +41 -0
- package/src/detect/detectors/natid/kz.ts +44 -0
- package/src/detect/detectors/natid/mx.ts +83 -0
- package/src/detect/detectors/natid/nl.ts +38 -0
- package/src/detect/detectors/natid/no.ts +50 -0
- package/src/detect/detectors/natid/nz.ts +53 -0
- package/src/detect/detectors/natid/pe.ts +28 -0
- package/src/detect/detectors/natid/pl.ts +100 -0
- package/src/detect/detectors/natid/pt.ts +36 -0
- package/src/detect/detectors/natid/ro.ts +47 -0
- package/src/detect/detectors/natid/ru.ts +82 -0
- package/src/detect/detectors/natid/se.ts +42 -0
- package/src/detect/detectors/natid/seasia.ts +174 -0
- package/src/detect/detectors/natid/sg.ts +39 -0
- package/src/detect/detectors/natid/si.ts +42 -0
- package/src/detect/detectors/natid/tr.ts +76 -0
- package/src/detect/detectors/natid/tw.ts +41 -0
- package/src/detect/detectors/natid/ua.ts +38 -0
- package/src/detect/detectors/natid/us.ts +118 -0
- package/src/detect/detectors/natid/za.ts +42 -0
- package/src/detect/detectors/secrets/apiKey.ts +115 -0
- package/src/detect/detectors/secrets/connectionString.ts +71 -0
- package/src/detect/detectors/secrets/genericSecret.ts +81 -0
- package/src/detect/detectors/secrets/index.ts +8 -0
- package/src/detect/detectors/secrets/jwt.ts +101 -0
- package/src/detect/detectors/secrets/pemPrivateKey.ts +59 -0
- package/src/detect/detectors/vat/euVat.ts +280 -0
- package/src/detect/detectors/vat/index.ts +4 -0
- package/src/detect/entropy.ts +60 -0
- package/src/detect/isoCountries.ts +30 -0
- package/src/detect/registry.ts +134 -0
- package/src/detect/runner.ts +187 -0
- package/src/detect/types.ts +296 -0
- package/src/encoding/base58.ts +85 -0
- package/src/encoding/base58monero.ts +90 -0
- package/src/encoding/bech32.ts +125 -0
- package/src/encoding/bytes.ts +48 -0
- package/src/entityFamily.ts +70 -0
- package/src/entityLabel.ts +56 -0
- package/src/entityTypes.ts +107 -0
- package/src/exposure/index.ts +189 -0
- package/src/fuse/calibrate.ts +224 -0
- package/src/fuse/defaultCalibration.ts +71 -0
- package/src/fuse/explain.ts +114 -0
- package/src/fuse/profiles.ts +187 -0
- package/src/fuse/resolve.ts +237 -0
- package/src/gazetteer/index.ts +139 -0
- package/src/generate/bankcodes.ts +82 -0
- package/src/generate/contact.ts +147 -0
- package/src/generate/crypto.ts +91 -0
- package/src/generate/documents.ts +142 -0
- package/src/generate/financial.ts +149 -0
- package/src/generate/index.ts +22 -0
- package/src/generate/location.ts +80 -0
- package/src/generate/natidAmOc.ts +198 -0
- package/src/generate/natidAsia.ts +162 -0
- package/src/generate/natidCee.ts +196 -0
- package/src/generate/natidMeCis.ts +131 -0
- package/src/generate/natidWest.ts +208 -0
- package/src/generate/prng.ts +17 -0
- package/src/generate/secrets.ts +141 -0
- package/src/generate/vat.ts +239 -0
- package/src/index.ts +186 -0
- package/src/mask/egressGuard.ts +88 -0
- package/src/mask/masker.ts +276 -0
- package/src/mask/restorer.ts +284 -0
- package/src/mask/surrogatePools.ts +96 -0
- package/src/mask/surrogates.ts +248 -0
- package/src/mask/vault.ts +153 -0
- package/src/ner/align.ts +86 -0
- package/src/ner/chunk.ts +65 -0
- package/src/ner/chunkCache.ts +110 -0
- package/src/ner/engine.ts +141 -0
- package/src/ner/merge.ts +123 -0
- package/src/ner/runStage2.ts +51 -0
- package/src/ner/stage2b.ts +73 -0
- package/src/ner/transformersClassifier.ts +79 -0
- package/src/ner/types.ts +99 -0
- package/src/normalization.ts +119 -0
- package/src/offsetMap.ts +271 -0
- package/src/pipeline.ts +96 -0
- package/src/protect.ts +284 -0
- package/src/scripts.ts +164 -0
- package/src/transforms/foldDigits.ts +138 -0
- package/src/transforms/graphemes.ts +5 -0
- package/src/transforms/homoglyphFold.ts +221 -0
- package/src/transforms/nfkc.ts +48 -0
- package/src/transforms/stripInvisibles.ts +158 -0
- package/src/transforms/whitespacePunct.ts +100 -0
- package/src/types.ts +339 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engine.ts — Stage 2 orchestration: window → classify → align → decode,
|
|
3
|
+
* under a HARD deadline with fail-closed semantics.
|
|
4
|
+
*
|
|
5
|
+
* The deadline covers the whole recognize() call (all windows), not one
|
|
6
|
+
* inference: SPEC.md's budget is per user action. On exceed the engine
|
|
7
|
+
* throws DetectionTimeoutError — the same fail-closed contract the Stage 1
|
|
8
|
+
* runner enforces; callers treat it as "block the send", never as "send
|
|
9
|
+
* what we found so far", because a partial scan is indistinguishable from
|
|
10
|
+
* a clean scan on exactly the text that was never reached.
|
|
11
|
+
*
|
|
12
|
+
* warmup() runs one tiny inference so the first real interaction does not
|
|
13
|
+
* absorb model-initialization latency (SPEC: warm at init, not first use).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { DetectionTimeoutError } from '../detect/runner.js';
|
|
17
|
+
import { alignPieces } from './align.js';
|
|
18
|
+
import { chunkText } from './chunk.js';
|
|
19
|
+
import { decodeEntities } from './merge.js';
|
|
20
|
+
import { attachGazetteerHits } from './stage2b.js';
|
|
21
|
+
import type { ChunkCache } from './chunkCache.js';
|
|
22
|
+
import type { NerRecognizer, NerSpan, TokenClassifier } from './types.js';
|
|
23
|
+
|
|
24
|
+
export interface NerEngineOptions {
|
|
25
|
+
/** Hard deadline for one recognize() call. Default 2000 ms. */
|
|
26
|
+
readonly timeBudgetMs?: number;
|
|
27
|
+
/** Window overlap in characters. Default 96. */
|
|
28
|
+
readonly overlapChars?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Stage 2b gazetteer corroboration. Default true.
|
|
31
|
+
*
|
|
32
|
+
* Lives here rather than in Stage 3's options because the lookup lives here:
|
|
33
|
+
* SPEC places the gazetteers in Stage 2, checked in parallel with the model.
|
|
34
|
+
*/
|
|
35
|
+
readonly useGazetteers?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const DEFAULT_BUDGET_MS = 2000;
|
|
39
|
+
const DEFAULT_OVERLAP = 96;
|
|
40
|
+
|
|
41
|
+
export class NerEngine implements NerRecognizer {
|
|
42
|
+
private readonly classifier: TokenClassifier;
|
|
43
|
+
private readonly budgetMs: number;
|
|
44
|
+
private readonly overlap: number;
|
|
45
|
+
private readonly useGazetteers: boolean;
|
|
46
|
+
private warmedUp = false;
|
|
47
|
+
|
|
48
|
+
constructor(classifier: TokenClassifier, options: NerEngineOptions = {}) {
|
|
49
|
+
this.classifier = classifier;
|
|
50
|
+
this.budgetMs = options.timeBudgetMs ?? DEFAULT_BUDGET_MS;
|
|
51
|
+
this.overlap = options.overlapChars ?? DEFAULT_OVERLAP;
|
|
52
|
+
this.useGazetteers = options.useGazetteers ?? true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get id(): string {
|
|
56
|
+
return this.classifier.id;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** One tiny inference so model init cost is paid before first real use. */
|
|
60
|
+
async warmup(): Promise<void> {
|
|
61
|
+
if (this.warmedUp) return;
|
|
62
|
+
await this.classifier.classify('warmup.');
|
|
63
|
+
this.warmedUp = true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Recognize entities in (normalized) `text`. Spans are in the text's own
|
|
68
|
+
* coordinates; runStage2 maps them back through the Stage 0 offset map.
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
71
|
+
* Recognize entities in (normalized) `text`.
|
|
72
|
+
*
|
|
73
|
+
* `cache` is passed IN rather than owned here because its keys are the
|
|
74
|
+
* user's text: it must live and die with one session, and this engine is
|
|
75
|
+
* shared across every session in the process. See chunkCache.ts.
|
|
76
|
+
*/
|
|
77
|
+
async recognize(text: string, cache?: ChunkCache): Promise<NerSpan[]> {
|
|
78
|
+
if (text.length === 0) return [];
|
|
79
|
+
const started = Date.now();
|
|
80
|
+
const deadline = started + this.budgetMs;
|
|
81
|
+
|
|
82
|
+
const chunks = chunkText(text, this.classifier.maxInputChars, this.overlap);
|
|
83
|
+
const spans: NerSpan[] = [];
|
|
84
|
+
|
|
85
|
+
for (const chunk of chunks) {
|
|
86
|
+
// A cache hit costs no inference and therefore no deadline: the budget
|
|
87
|
+
// exists to bound model time, and there is none to bound. Checking the
|
|
88
|
+
// deadline before the lookup would let a document time out on work it
|
|
89
|
+
// was never going to do.
|
|
90
|
+
let local = cache?.get(chunk.text);
|
|
91
|
+
|
|
92
|
+
if (local === undefined) {
|
|
93
|
+
const remaining = deadline - Date.now();
|
|
94
|
+
if (remaining <= 0) {
|
|
95
|
+
throw new DetectionTimeoutError(this.budgetMs, Date.now() - started);
|
|
96
|
+
}
|
|
97
|
+
const predictions = await withDeadline(
|
|
98
|
+
this.classifier.classify(chunk.text),
|
|
99
|
+
remaining,
|
|
100
|
+
() => new DetectionTimeoutError(this.budgetMs, Date.now() - started),
|
|
101
|
+
);
|
|
102
|
+
const aligned = alignPieces(chunk.text, predictions.map((p) => p.piece));
|
|
103
|
+
// Stored in CHUNK-LOCAL coordinates, before the offset shift below:
|
|
104
|
+
// the same chunk text can appear at different offsets in different
|
|
105
|
+
// documents, and a cache keyed on the text must not remember where it
|
|
106
|
+
// happened to sit the first time.
|
|
107
|
+
local = decodeEntities(chunk.text, predictions, aligned);
|
|
108
|
+
cache?.set(chunk.text, local);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const span of local) {
|
|
112
|
+
const mid = chunk.offset + (span.start + span.end) / 2;
|
|
113
|
+
// The owning-core rule from chunk.ts: emit each entity exactly once.
|
|
114
|
+
if (mid >= chunk.coreStart && mid < chunk.coreEnd) {
|
|
115
|
+
spans.push({ ...span, start: chunk.offset + span.start, end: chunk.offset + span.end });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const ordered = spans.sort((a, b) => a.start - b.start);
|
|
121
|
+
// Stage 2b, on the same side of any process boundary as the model: SPEC
|
|
122
|
+
// has the gazetteers "checked in parallel with the model", and they can
|
|
123
|
+
// only corroborate types the model produces.
|
|
124
|
+
return this.useGazetteers ? attachGazetteerHits(ordered) : ordered;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Race a promise against a deadline; the loser's result is discarded. */
|
|
129
|
+
async function withDeadline<T>(work: Promise<T>, ms: number, onTimeout: () => Error): Promise<T> {
|
|
130
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
131
|
+
try {
|
|
132
|
+
return await Promise.race([
|
|
133
|
+
work,
|
|
134
|
+
new Promise<never>((_, reject) => {
|
|
135
|
+
timer = setTimeout(() => reject(onTimeout()), ms);
|
|
136
|
+
}),
|
|
137
|
+
]);
|
|
138
|
+
} finally {
|
|
139
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
140
|
+
}
|
|
141
|
+
}
|
package/src/ner/merge.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* merge.ts — decode per-token BIO labels into entity spans.
|
|
3
|
+
*
|
|
4
|
+
* Handles BOTH tagging conventions the candidate models use:
|
|
5
|
+
* • IOB2 (mBERT/distilmBERT NER-HRL): entities start with B-X.
|
|
6
|
+
* • IOB1 (XLM-R CoNLL fine-tunes): entities may start with I-X after O
|
|
7
|
+
* or at sequence start; B-X appears only to split adjacent same-type
|
|
8
|
+
* entities.
|
|
9
|
+
* Decoding rule that satisfies both: a token starts a NEW entity when its
|
|
10
|
+
* label is B-X, or when it is I-X and the previous token was not part of
|
|
11
|
+
* an X entity. Same-type I-X continues; any other label ends the entity.
|
|
12
|
+
*
|
|
13
|
+
* Unlocated pieces ([UNK] and friends) inside an entity are BRIDGED: the
|
|
14
|
+
* entity's span runs from its first located piece to its last located
|
|
15
|
+
* piece. An entity with no located piece at all is dropped — emitting a
|
|
16
|
+
* guessed span would violate the exact-offsets contract.
|
|
17
|
+
*
|
|
18
|
+
* The entity score is the MINIMUM token score — one uncertain token makes
|
|
19
|
+
* the whole span uncertain. Scores are uncalibrated model softmax until
|
|
20
|
+
* Stage 4 (M8) calibrates; the eval buckets measure what they are worth.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { AlignedPiece } from './align.js';
|
|
24
|
+
import type { NerEntityType, NerSpan, TokenPrediction } from './types.js';
|
|
25
|
+
|
|
26
|
+
/** Model label suffix → Discretion entity type. MISC and friends drop. */
|
|
27
|
+
const DEFAULT_LABEL_TYPES: Readonly<Record<string, NerEntityType>> = {
|
|
28
|
+
PER: 'PERSON',
|
|
29
|
+
PERSON: 'PERSON',
|
|
30
|
+
ORG: 'ORG',
|
|
31
|
+
LOC: 'LOCATION',
|
|
32
|
+
LOCATION: 'LOCATION',
|
|
33
|
+
GPE: 'LOCATION',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
interface Open {
|
|
37
|
+
type: NerEntityType;
|
|
38
|
+
start: number;
|
|
39
|
+
end: number;
|
|
40
|
+
score: number;
|
|
41
|
+
located: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function labelParts(label: string): { prefix: 'B' | 'I' | 'O'; type?: NerEntityType } {
|
|
45
|
+
if (label === 'O' || label === '') return { prefix: 'O' };
|
|
46
|
+
const dash = label.indexOf('-');
|
|
47
|
+
const prefix = label.slice(0, dash === -1 ? undefined : dash);
|
|
48
|
+
const suffix = dash === -1 ? label : label.slice(dash + 1);
|
|
49
|
+
const type = DEFAULT_LABEL_TYPES[suffix.toUpperCase()];
|
|
50
|
+
if ((prefix === 'B' || prefix === 'I') && type !== undefined) {
|
|
51
|
+
return { prefix, type };
|
|
52
|
+
}
|
|
53
|
+
return { prefix: 'O' };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Decode predictions + aligned spans into merged entity spans. */
|
|
57
|
+
export function decodeEntities(
|
|
58
|
+
text: string,
|
|
59
|
+
predictions: readonly TokenPrediction[],
|
|
60
|
+
aligned: readonly AlignedPiece[],
|
|
61
|
+
): NerSpan[] {
|
|
62
|
+
const spans: NerSpan[] = [];
|
|
63
|
+
let open: Open | null = null;
|
|
64
|
+
|
|
65
|
+
const close = (): void => {
|
|
66
|
+
if (open !== null && open.located && open.end > open.start) {
|
|
67
|
+
spans.push({
|
|
68
|
+
type: open.type,
|
|
69
|
+
start: open.start,
|
|
70
|
+
end: open.end,
|
|
71
|
+
text: text.slice(open.start, open.end),
|
|
72
|
+
score: open.score,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
open = null;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
for (let i = 0; i < predictions.length; i++) {
|
|
79
|
+
const pred = predictions[i]!;
|
|
80
|
+
const span = aligned[i];
|
|
81
|
+
if (span === undefined) break; // defensive: prediction/alignment mismatch
|
|
82
|
+
const { prefix, type } = labelParts(pred.label);
|
|
83
|
+
|
|
84
|
+
if (prefix === 'O' || type === undefined) {
|
|
85
|
+
close();
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const continues = open !== null && open.type === type && prefix === 'I';
|
|
90
|
+
if (continues && open !== null) {
|
|
91
|
+
if (span.located) {
|
|
92
|
+
if (!open.located) open.start = span.start; // first located piece
|
|
93
|
+
open.end = span.end;
|
|
94
|
+
open.located = true;
|
|
95
|
+
}
|
|
96
|
+
open.score = Math.min(open.score, pred.score);
|
|
97
|
+
} else {
|
|
98
|
+
close();
|
|
99
|
+
open = {
|
|
100
|
+
type,
|
|
101
|
+
start: span.start,
|
|
102
|
+
end: span.end,
|
|
103
|
+
score: pred.score,
|
|
104
|
+
located: span.located,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
close();
|
|
109
|
+
|
|
110
|
+
return spans.map(trimSpan(text)).filter((s): s is NerSpan => s !== null);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Trim surrounding whitespace the model occasionally absorbs into a span. */
|
|
114
|
+
function trimSpan(text: string): (s: NerSpan) => NerSpan | null {
|
|
115
|
+
return (s) => {
|
|
116
|
+
let { start, end } = s;
|
|
117
|
+
while (start < end && /\s/.test(text[start]!)) start += 1;
|
|
118
|
+
while (end > start && /\s/.test(text[end - 1]!)) end -= 1;
|
|
119
|
+
if (end <= start) return null;
|
|
120
|
+
if (start === s.start && end === s.end) return s;
|
|
121
|
+
return { ...s, start, end, text: text.slice(start, end) };
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* runStage2.ts — produce Stage 2 candidates in the pipeline's shared shape.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the Stage 1 runner's contract: detection runs on NORMALIZED text
|
|
5
|
+
* and every candidate carries its exact ORIGINAL span, resolved through the
|
|
6
|
+
* Stage 0 offset map with mapNormalizedSpan (never raw map indexing — see
|
|
7
|
+
* the M1 offset-map contract).
|
|
8
|
+
*
|
|
9
|
+
* rawConfidence is the model's softmax score, unchanged and explicitly
|
|
10
|
+
* uncalibrated — the eval measures what those scores are worth per bucket,
|
|
11
|
+
* and Stage 4 (M8) calibrates. Inventing a mapping here would launder an
|
|
12
|
+
* unmeasured number into a measured-looking one.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { NormalizationResult } from '../types.js';
|
|
16
|
+
import { mapNormalizedSpan } from '../offsetMap.js';
|
|
17
|
+
import type { NerRecognizer, Stage2Candidate } from './types.js';
|
|
18
|
+
|
|
19
|
+
/** Collapse interior whitespace so trivial layout variants share a key. */
|
|
20
|
+
function canonicalName(text: string): string {
|
|
21
|
+
return text.replace(/\s+/g, ' ').trim();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function runStage2(
|
|
25
|
+
normalization: NormalizationResult,
|
|
26
|
+
engine: NerRecognizer,
|
|
27
|
+
): Promise<Stage2Candidate[]> {
|
|
28
|
+
const { normalizedText, offsetMap } = normalization;
|
|
29
|
+
const spans = await engine.recognize(normalizedText);
|
|
30
|
+
|
|
31
|
+
return spans.map((span) => {
|
|
32
|
+
const original = mapNormalizedSpan(offsetMap, span.start, span.end);
|
|
33
|
+
return {
|
|
34
|
+
text: span.text,
|
|
35
|
+
type: span.type,
|
|
36
|
+
start: span.start,
|
|
37
|
+
end: span.end,
|
|
38
|
+
originalStart: original.start,
|
|
39
|
+
originalEnd: original.end,
|
|
40
|
+
rawConfidence: span.score,
|
|
41
|
+
stage: 'stage2-ner' as const,
|
|
42
|
+
detectorId: `ner:${engine.id}`,
|
|
43
|
+
sensitive: true,
|
|
44
|
+
canonical: canonicalName(span.text),
|
|
45
|
+
metadata: { model: engine.id },
|
|
46
|
+
// Carried rather than re-looked-up: the hit was computed where the
|
|
47
|
+
// gazetteers live, which may be a different process from this one.
|
|
48
|
+
...(span.gazetteer === undefined ? {} : { gazetteer: span.gazetteer }),
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage 2b — gazetteer corroboration, attached to the spans it corroborates.
|
|
3
|
+
*
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* WHY THIS FILE EXISTS, WHICH IS A CORRECTION RATHER THAN A NEW FEATURE
|
|
6
|
+
*
|
|
7
|
+
* SPEC.md places the gazetteers in STAGE 2: "Bundled compressed lookup sets,
|
|
8
|
+
* checked in parallel with the model." The lookup had drifted into Stage 3's
|
|
9
|
+
* scorer, where it ran as one context signal among many.
|
|
10
|
+
*
|
|
11
|
+
* That placement was invisible until the extension was built, and then it was
|
|
12
|
+
* expensive in a way nothing else made visible. Stage 3 runs in the CONTENT
|
|
13
|
+
* SCRIPT. Its scorer statically imported the gazetteer module, so 3.4 MB of
|
|
14
|
+
* base64 Bloom filters were linked into a bundle that is parsed on every page
|
|
15
|
+
* load of all three sites — to serve PERSON, ORG and LOCATION candidates,
|
|
16
|
+
* which only Stage 2 produces, and which cannot exist at all in a build with
|
|
17
|
+
* no model attached.
|
|
18
|
+
*
|
|
19
|
+
* Moving the lookup here is not a size optimisation. It restores the stage
|
|
20
|
+
* boundary SPEC drew, and the size follows from that: the gazetteers now live
|
|
21
|
+
* on the same side of the process boundary as the model, because they answer
|
|
22
|
+
* questions only the model can ask.
|
|
23
|
+
*
|
|
24
|
+
* BEHAVIOUR IS UNCHANGED, and that is checkable rather than asserted: no
|
|
25
|
+
* Stage 1 detector declares PERSON, ORG or LOCATION (31 types, verified by
|
|
26
|
+
* enumeration), so no Stage 1 candidate could ever have reached the lookup in
|
|
27
|
+
* Stage 3. The contribution Stage 3 emits is byte-identical; it is now built
|
|
28
|
+
* from a hit computed here instead of one computed there.
|
|
29
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { lookupGazetteer } from '../gazetteer/index.js';
|
|
33
|
+
import type { GazetteerType } from '../gazetteer/index.js';
|
|
34
|
+
import type { NerEntityType, NerSpan } from './types.js';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The model's label set and the gazetteer's are the same three types.
|
|
38
|
+
*
|
|
39
|
+
* Asserted at COMPILE time rather than guarded at run time. The obvious
|
|
40
|
+
* implementation calls `isGazetteerType(span.type)` before each lookup - but
|
|
41
|
+
* `NerSpan.type` is already exactly those three, so that branch can never be
|
|
42
|
+
* false. A check that cannot fail reads as a safety property and is not one;
|
|
43
|
+
* this fails the BUILD if either union ever gains a member the other lacks,
|
|
44
|
+
* which is the moment the guard would have started mattering.
|
|
45
|
+
*/
|
|
46
|
+
type MissingFromGazetteer = Exclude<NerEntityType, GazetteerType>;
|
|
47
|
+
type MissingFromNer = Exclude<GazetteerType, NerEntityType>;
|
|
48
|
+
// Both must be `never`. A non-never member here is a type the other side does
|
|
49
|
+
// not know about, and it fails the build at exactly the point where the
|
|
50
|
+
// removed runtime guard would have started doing work.
|
|
51
|
+
export type Stage2bTypesAgree = [MissingFromGazetteer, MissingFromNer] extends [never, never]
|
|
52
|
+
? true
|
|
53
|
+
: never;
|
|
54
|
+
const _typesAgree: Stage2bTypesAgree = true;
|
|
55
|
+
void _typesAgree;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Attach gazetteer corroboration to each span.
|
|
59
|
+
*
|
|
60
|
+
* A miss attaches nothing rather than attaching an absent hit: "not in the
|
|
61
|
+
* gazetteer" is not evidence against a name — the sets are large but nowhere
|
|
62
|
+
* near complete — and a field distinguishing "looked and found nothing" from
|
|
63
|
+
* "did not look" would invite a caller to treat the first as a negative
|
|
64
|
+
* signal. `useGazetteers: false` and a genuine miss are meant to be
|
|
65
|
+
* indistinguishable downstream, because they justify the same conclusion:
|
|
66
|
+
* nothing was corroborated.
|
|
67
|
+
*/
|
|
68
|
+
export function attachGazetteerHits(spans: readonly NerSpan[]): NerSpan[] {
|
|
69
|
+
return spans.map((span) => {
|
|
70
|
+
const hit = lookupGazetteer(span.text, span.type);
|
|
71
|
+
return hit === undefined ? span : { ...span, gazetteer: hit };
|
|
72
|
+
});
|
|
73
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transformersClassifier.ts — the Transformers.js/ONNX-backed
|
|
3
|
+
* TokenClassifier. Runs identically in Node (onnxruntime-node) and in a
|
|
4
|
+
* browser Web Worker (onnxruntime-web/WASM); hosting it in a worker is the
|
|
5
|
+
* consumer's concern (extension, M9), which keeps this module free of any
|
|
6
|
+
* environment-specific API.
|
|
7
|
+
*
|
|
8
|
+
* ZERO NETWORK BY DEFAULT: remote model fetching is opt-in
|
|
9
|
+
* (`allowRemoteModels`), used only by build-time tooling (today the eval
|
|
10
|
+
* benchmark and CLI; the extension's bundling step at M9). Production
|
|
11
|
+
* consumers load from the bundled cache and never touch the network — the
|
|
12
|
+
* SPEC non-negotiable.
|
|
13
|
+
*
|
|
14
|
+
* This module is exported through the dedicated `./ner-transformers` entry
|
|
15
|
+
* point, NOT the package root, so consumers who never run Stage 2 never
|
|
16
|
+
* load the ONNX runtime.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { env, pipeline } from '@huggingface/transformers';
|
|
20
|
+
import type { TokenClassifier, TokenPrediction } from './types.js';
|
|
21
|
+
|
|
22
|
+
export interface TransformersClassifierOptions {
|
|
23
|
+
/** HF repo id, e.g. 'Xenova/distilbert-base-multilingual-cased-ner-hrl'. */
|
|
24
|
+
readonly model: string;
|
|
25
|
+
/** Weight precision: 'fp32' | 'fp16' | 'q8' | 'int8' | 'uint8' | …. */
|
|
26
|
+
readonly dtype?: string;
|
|
27
|
+
/** Where model files live (bundle dir in production, cache in tooling). */
|
|
28
|
+
readonly cacheDir?: string;
|
|
29
|
+
/** Allow downloading missing models. Build-time tooling ONLY. */
|
|
30
|
+
readonly allowRemoteModels?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Pinned repo revision (commit hash). HF commits are content-addressed,
|
|
33
|
+
* so a pinned revision pins the exact model bytes — the integrity story
|
|
34
|
+
* for build-time bundling. Default 'main' is acceptable only in
|
|
35
|
+
* exploratory tooling.
|
|
36
|
+
*/
|
|
37
|
+
readonly revision?: string;
|
|
38
|
+
/** Short id for candidate metadata; defaults to model@dtype. */
|
|
39
|
+
readonly id?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Per-window character budget. Default 400: the models' 512-token limit
|
|
42
|
+
* divided by the worst-case one-token-per-character ratio (CJK), with
|
|
43
|
+
* headroom for specials and subword expansion of unusual codepoints.
|
|
44
|
+
*/
|
|
45
|
+
readonly maxInputChars?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface RawTokenOutput {
|
|
49
|
+
readonly entity: string;
|
|
50
|
+
readonly score: number;
|
|
51
|
+
readonly word: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const DEFAULT_MAX_INPUT_CHARS = 400;
|
|
55
|
+
|
|
56
|
+
export async function createTransformersClassifier(
|
|
57
|
+
options: TransformersClassifierOptions,
|
|
58
|
+
): Promise<TokenClassifier> {
|
|
59
|
+
if (options.cacheDir !== undefined) env.cacheDir = options.cacheDir;
|
|
60
|
+
env.allowRemoteModels = options.allowRemoteModels ?? false;
|
|
61
|
+
|
|
62
|
+
const dtype = options.dtype ?? 'q8';
|
|
63
|
+
const nerPipeline = await pipeline('token-classification', options.model, {
|
|
64
|
+
dtype: dtype as never, // the runtime validates; its literal union lags its own docs
|
|
65
|
+
...(options.revision !== undefined ? { revision: options.revision } : {}),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const id = options.id ?? `${options.model.split('/').pop() ?? options.model}@${dtype}`;
|
|
69
|
+
const maxInputChars = options.maxInputChars ?? DEFAULT_MAX_INPUT_CHARS;
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
id,
|
|
73
|
+
maxInputChars,
|
|
74
|
+
async classify(text: string): Promise<readonly TokenPrediction[]> {
|
|
75
|
+
const raw = (await nerPipeline(text, { ignore_labels: [] })) as readonly RawTokenOutput[];
|
|
76
|
+
return raw.map((t) => ({ label: t.entity, score: t.score, piece: t.word }));
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
package/src/ner/types.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage 2 (multilingual NER) — shared types.
|
|
3
|
+
*
|
|
4
|
+
* The model runtime is INJECTED behind `TokenClassifier`, so the pure parts
|
|
5
|
+
* of Stage 2 (piece→character alignment, BIO decoding, chunking, timeout
|
|
6
|
+
* discipline, candidate shaping) are testable without a model and the
|
|
7
|
+
* engine stays environment-agnostic. The Transformers.js-backed classifier
|
|
8
|
+
* lives in `transformersClassifier.ts`, exported through its own package
|
|
9
|
+
* entry point so that consumers who never run NER never load the runtime.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Stage1Candidate } from '../detect/types.js';
|
|
13
|
+
import type { GazetteerHit } from '../gazetteer/index.js';
|
|
14
|
+
|
|
15
|
+
/** One model token prediction, in input order, special tokens excluded. */
|
|
16
|
+
export interface TokenPrediction {
|
|
17
|
+
/** Raw model label, e.g. 'B-PER', 'I-ORG', 'O'. */
|
|
18
|
+
readonly label: string;
|
|
19
|
+
/** Model softmax score for that label. */
|
|
20
|
+
readonly score: number;
|
|
21
|
+
/**
|
|
22
|
+
* The token's surface piece as the runtime reports it: WordPiece
|
|
23
|
+
* continuations keep their '##' prefix; SentencePiece markers ('▁') may
|
|
24
|
+
* or may not be present — the aligner handles both.
|
|
25
|
+
*/
|
|
26
|
+
readonly piece: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** The injected model runtime. */
|
|
30
|
+
export interface TokenClassifier {
|
|
31
|
+
/** Identifies the model in candidate metadata, e.g. 'distilmbert-ner-hrl@q8'. */
|
|
32
|
+
readonly id: string;
|
|
33
|
+
/**
|
|
34
|
+
* Safe per-call input size in CHARACTERS. Text longer than this must be
|
|
35
|
+
* windowed by the caller: transformer runtimes silently truncate past
|
|
36
|
+
* their token limit, and silent truncation would be silent fail-open.
|
|
37
|
+
* The floor of one token per character (CJK) makes chars the safe unit.
|
|
38
|
+
*/
|
|
39
|
+
readonly maxInputChars: number;
|
|
40
|
+
/** Classify one window of text. Pieces arrive in input order. */
|
|
41
|
+
classify(text: string): Promise<readonly TokenPrediction[]>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type NerEntityType = 'PERSON' | 'ORG' | 'LOCATION';
|
|
45
|
+
|
|
46
|
+
/** A merged entity span in NORMALIZED-text coordinates. */
|
|
47
|
+
export interface NerSpan {
|
|
48
|
+
readonly type: NerEntityType;
|
|
49
|
+
readonly start: number;
|
|
50
|
+
readonly end: number;
|
|
51
|
+
readonly text: string;
|
|
52
|
+
/** Minimum token score across the entity — the conservative aggregate. */
|
|
53
|
+
readonly score: number;
|
|
54
|
+
/**
|
|
55
|
+
* Stage 2b corroboration, when the gazetteer knows this name.
|
|
56
|
+
*
|
|
57
|
+
* Attached HERE rather than looked up in Stage 3 because SPEC places the
|
|
58
|
+
* gazetteers in Stage 2 — "checked in parallel with the model" — and
|
|
59
|
+
* because the sets are only meaningful for the types the model produces.
|
|
60
|
+
* See ner/stage2b.ts for what that placement was costing.
|
|
61
|
+
*
|
|
62
|
+
* Absent on a miss. "Not in the gazetteer" is not evidence against a name.
|
|
63
|
+
*/
|
|
64
|
+
readonly gazetteer?: GazetteerHit;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* What Stage 2 needs from whatever performs recognition.
|
|
69
|
+
*
|
|
70
|
+
* An interface rather than the concrete `NerEngine` because the engine may not
|
|
71
|
+
* be in the same PROCESS as the pipeline. The extension runs the model in an
|
|
72
|
+
* offscreen document - a content script cannot compile WebAssembly under the
|
|
73
|
+
* host page's policy - so its Stage 2 is a proxy that forwards `recognize`
|
|
74
|
+
* across a message port and returns the spans that come back.
|
|
75
|
+
*
|
|
76
|
+
* Declared here, next to the span it returns, so that `runStage2` and
|
|
77
|
+
* `detect` can name it without importing `engine.ts`. That matters: engine.ts
|
|
78
|
+
* pulls in Stage 2b and therefore the gazetteers, and a value import of it
|
|
79
|
+
* from the pipeline would link 3.4 MB of Bloom filters into every bundle that
|
|
80
|
+
* runs detection, including the one that has no model at all.
|
|
81
|
+
*/
|
|
82
|
+
export interface NerRecognizer {
|
|
83
|
+
/** Model identity, recorded on every candidate this produces. */
|
|
84
|
+
readonly id: string;
|
|
85
|
+
/** Pay initialization cost before first real use. */
|
|
86
|
+
warmup(): Promise<void>;
|
|
87
|
+
/** Spans in the given text's own coordinates. */
|
|
88
|
+
recognize(text: string): Promise<NerSpan[]>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Stage 2 candidates share Stage 1's shape (SPEC: one candidate contract
|
|
93
|
+
* for the whole pipeline), differing only in the stage tag.
|
|
94
|
+
*/
|
|
95
|
+
export interface Stage2Candidate extends Omit<Stage1Candidate, 'stage'> {
|
|
96
|
+
readonly stage: 'stage2-ner';
|
|
97
|
+
/** Stage 2b corroboration, carried through to Stage 3's scorer. */
|
|
98
|
+
readonly gazetteer?: GazetteerHit;
|
|
99
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage 0 normalization: the composed transform pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Order (each step optional via NormalizationOptions, all on by default):
|
|
5
|
+
*
|
|
6
|
+
* 1. strip invisibles — zero-width & bidi controls are pure noise and
|
|
7
|
+
* interfere with everything downstream
|
|
8
|
+
* 2. NFKC (per grapheme) — compatibility folding with an exact map
|
|
9
|
+
* 3. selective homoglyph — fold ONLY script-anomalous characters
|
|
10
|
+
* folding (see homoglyphFold.ts for the full rationale)
|
|
11
|
+
* 3b. NFKC again, only when folding changed something: a folded character
|
|
12
|
+
* must compose with a following combining mark exactly as a native one
|
|
13
|
+
* would (e.g. Cyrillic а + U+0301 → folded "a" + U+0301 → "á"),
|
|
14
|
+
* otherwise normalizing already-normalized text would not be a no-op
|
|
15
|
+
* 4. whitespace/punct — exotic spaces, dashes, quotes → ASCII forms
|
|
16
|
+
*
|
|
17
|
+
* Each transform independently produces { text, map }; the final offset map
|
|
18
|
+
* is the COMPOSITION of the per-stage maps (see offsetMap.ts for the map
|
|
19
|
+
* format and its invariants). Composing small verified maps is far easier to
|
|
20
|
+
* get right than building one map through four simultaneous transforms.
|
|
21
|
+
*/
|
|
22
|
+
import type { NormalizationOptions, NormalizationResult, TransformationRecord } from './types.js';
|
|
23
|
+
import {
|
|
24
|
+
composeMaps,
|
|
25
|
+
identityMap,
|
|
26
|
+
buildReverseMap,
|
|
27
|
+
mapNormalizedSpan,
|
|
28
|
+
type TransformStepResult,
|
|
29
|
+
} from './offsetMap.js';
|
|
30
|
+
import { detectScripts } from './scripts.js';
|
|
31
|
+
import { stripInvisibles } from './transforms/stripInvisibles.js';
|
|
32
|
+
import { nfkcByGrapheme } from './transforms/nfkc.js';
|
|
33
|
+
import { foldHomoglyphs } from './transforms/homoglyphFold.js';
|
|
34
|
+
import { normalizeWhitespacePunct } from './transforms/whitespacePunct.js';
|
|
35
|
+
import { foldDigits } from './transforms/foldDigits.js';
|
|
36
|
+
|
|
37
|
+
export function normalize(text: string, options?: NormalizationOptions): NormalizationResult {
|
|
38
|
+
const opts = {
|
|
39
|
+
stripInvisibles: true,
|
|
40
|
+
nfkc: true,
|
|
41
|
+
homoglyphFold: true,
|
|
42
|
+
whitespacePunct: true,
|
|
43
|
+
foldDigits: true,
|
|
44
|
+
...options,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** The text after the transforms applied so far. */
|
|
48
|
+
let current = text;
|
|
49
|
+
/**
|
|
50
|
+
* Composed map: current index → ORIGINAL index. null means "identity so
|
|
51
|
+
* far" — kept symbolic so untouched text (the common case) never pays for
|
|
52
|
+
* map allocation or composition.
|
|
53
|
+
*/
|
|
54
|
+
let cumulative: Int32Array | null = null;
|
|
55
|
+
const transformations: TransformationRecord[] = [];
|
|
56
|
+
|
|
57
|
+
const apply = (step: (input: string) => TransformStepResult | null): boolean => {
|
|
58
|
+
const result = step(current);
|
|
59
|
+
if (result === null) return false;
|
|
60
|
+
for (const change of result.changes) {
|
|
61
|
+
// The step reports ranges in ITS input's coordinates; map them back to
|
|
62
|
+
// original-text coordinates through the maps of the earlier steps.
|
|
63
|
+
// mapNormalizedSpan (not plain lookup) so a change inside an earlier
|
|
64
|
+
// expansion widens to the whole original cluster.
|
|
65
|
+
const span = cumulative
|
|
66
|
+
? mapNormalizedSpan(cumulative, change.start, change.end)
|
|
67
|
+
: { start: change.start, end: change.end };
|
|
68
|
+
transformations.push({
|
|
69
|
+
kind: change.kind,
|
|
70
|
+
originalStart: span.start,
|
|
71
|
+
originalEnd: span.end,
|
|
72
|
+
original: text.slice(span.start, span.end),
|
|
73
|
+
replacement: change.after,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
cumulative = cumulative ? composeMaps(cumulative, result.map) : result.map;
|
|
77
|
+
current = result.text;
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Per-cluster NFKC must run to a FIXPOINT: one pass's output can contain
|
|
82
|
+
// clusters that only became composable by being placed next to each other
|
|
83
|
+
// (the canonical case is Hangul compatibility jamo — ㅍ and ㅓ are separate
|
|
84
|
+
// clusters, normalize to the conjoining jamo ᄑ + ᅥ, and only THOSE form a
|
|
85
|
+
// single cluster that composes to 퍼 on the next look). One extra pass
|
|
86
|
+
// settles it in practice; the cap is a defensive bound, and the fuzz suite
|
|
87
|
+
// asserts both termination and idempotency.
|
|
88
|
+
const applyNfkcToFixpoint = (): void => {
|
|
89
|
+
for (let i = 0; i < 8 && apply(nfkcByGrapheme); i++) {
|
|
90
|
+
// apply() advanced the pipeline; loop until it reports no change.
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
if (opts.stripInvisibles) apply(stripInvisibles);
|
|
95
|
+
if (opts.nfkc) applyNfkcToFixpoint();
|
|
96
|
+
if (opts.homoglyphFold) {
|
|
97
|
+
const folded = apply(foldHomoglyphs);
|
|
98
|
+
// 3b — see the file header. Only needed when a fold actually happened,
|
|
99
|
+
// and only meaningful when the NFKC step is enabled at all.
|
|
100
|
+
if (folded && opts.nfkc) applyNfkcToFixpoint();
|
|
101
|
+
}
|
|
102
|
+
if (opts.whitespacePunct) apply(normalizeWhitespacePunct);
|
|
103
|
+
// Last, and after homoglyph folding on purpose: folding digits changes a
|
|
104
|
+
// token's script census, and doing it earlier would alter the
|
|
105
|
+
// dominant-script decision homoglyph folding depends on. ASCII digits are
|
|
106
|
+
// NFKC-stable, so no further normalization pass is owed.
|
|
107
|
+
if (opts.foldDigits) apply(foldDigits);
|
|
108
|
+
|
|
109
|
+
const offsetMap = cumulative ?? identityMap(text.length);
|
|
110
|
+
return {
|
|
111
|
+
normalizedText: current,
|
|
112
|
+
offsetMap,
|
|
113
|
+
reverseMap: buildReverseMap(offsetMap, text.length),
|
|
114
|
+
scripts: detectScripts(current),
|
|
115
|
+
transformations,
|
|
116
|
+
originalLength: text.length,
|
|
117
|
+
normalizedLength: current.length,
|
|
118
|
+
};
|
|
119
|
+
}
|