{"_id":"@bwthomas/vicary","_rev":"9-0ddd1d4431d4ae94b1b06c3b8bd2e2d0","name":"@bwthomas/vicary","dist-tags":{"latest":"0.2.15"},"versions":{"0.2.1":{"name":"@bwthomas/vicary","version":"0.2.1","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.1","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary#readme","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"3ce6137e0b4c35a81bbdcd76ec9229498e5b03da","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.1.tgz","fileCount":50,"integrity":"sha512-4n/iM1RpCGoEXiH64LCds5AEB567K3olInmgcrUnYx/HjfeamNOyxakkrTl9Q512f3CDNTUS8S85ekcVtmKl+g==","signatures":[{"sig":"MEUCIFIAs+XIBodWLyY0bWpb9MwywMpdpNlhgzcyebePrY0sAiEAyYatVvRMkHu/YQEL9RRvHNQev3sHE1G5rLmwROiGSh0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2637188},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"f96f49a9b0ccc8d8138f51b25ad5a6426ffff830","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs"},"_npmUser":{"name":"bwthomas","email":"bwthomas@gmail.com"},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"10.2.4","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"18.19.1","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.1_1786495681006_0.42837204771485604","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@bwthomas/vicary","version":"0.2.3","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.3","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"ce92746d3e18d4e016554fb1e04247e42f2063df","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.3.tgz","fileCount":58,"integrity":"sha512-v43Eg4KFXynovWWNPmELizrxGFKUXHqesr4TVhNGm16GVYuq7Vo9ZElgAgd/F8x5dIgLUjN5XYjY629OQp4GNw==","signatures":[{"sig":"MEUCIBdBItvegq29C2slfMH475KeeHiep0QQwCeknZunBVvRAiEA4rNs7ImdCGJp3JF3K0VQ1v8eSX3PbV4Mlr1TojY4Vnw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2740345},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"15f16914873fe9ac1d26161fdba681d717998553","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.19.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.3_1786581044513_0.40046357612776595","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@bwthomas/vicary","version":"0.2.4","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.4","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"0ee47f46dc4ce7d36ad7f540d2bd432b28dd390f","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.4.tgz","fileCount":62,"integrity":"sha512-69io9jITwvMzwBIORO/qmMLOJznnxYkJNv+6jwItvUd1wPjboYyBpKH81VE6tmOUZpXzc879K0s9UXdJHowr4A==","signatures":[{"sig":"MEYCIQDOduubiIW4JOTICJ4JmwAnNusxaK8JR/1GQ2pbOmxtfgIhAPjrYjHuFKCCgosvuVQPn11xNKJNgWkORF2rRLafksH7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2756356},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"b8f8301d2bfcd4f18cda0400287f95839b27d9a1","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.18.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.4_1786584041132_0.9426624694039032","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@bwthomas/vicary","version":"0.2.5","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.5","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"e5da3ed59b908e3bba9a28f427c1cb1f79bd4eec","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.5.tgz","fileCount":62,"integrity":"sha512-PWRfId31hFWLTGAMHuB8rLCob7VvwySCvtQNxeN1ykoqnaWAq1jXT39JYmlL04W/PWgQT+Q5QV+B3OaWvbOW3A==","signatures":[{"sig":"MEUCIQDqwMuySMGjplg0RgEawdUdu9fSNmjOFpZ0ZOQNTSQupQIgDQLLmIZH/2wLUssYiByeYZ4DfRdm/vn0MIEO9FNKO4o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2764973},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"61abb929cb34186c6b4bf18e8bba4c502019e4a3","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.19.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.5_1786643354990_0.6055907647908885","host":"s3://npm-registry-packages-npm-production"}},"0.2.7":{"name":"@bwthomas/vicary","version":"0.2.7","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.7","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"148015698c602b7b4ae6c45e0ab7fe80e09166ac","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.7.tgz","fileCount":66,"integrity":"sha512-sqFracMlHNIQ1vikpiO0BK39lnKqAgGgk1rSeEqbsKE07hqJVq0YPsL6w+Qde9/375X09v1mEtDTZ3PaS9ezuw==","signatures":[{"sig":"MEYCIQDu/jVqr/EZjBw/11oNxAuj4w+FGo90fc8Q62WoG8kargIhAIYPVwkAbZ+QmrazTq88JQHLL+IXE0sGjKGX8T9MgBI0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2784918},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"a6e81f13ecb1aaec1ecfe906aa3b9892bb6b1f7b","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.20.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.7_1788965319855_0.7313178090598982","host":"s3://npm-registry-packages-npm-production"}},"0.2.8":{"name":"@bwthomas/vicary","version":"0.2.8","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.8","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"d8afe073316733d62bedc577336b7bb1126995ff","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.8.tgz","fileCount":66,"integrity":"sha512-CYF/6BGXowCXpmdwKZTfpOFEPJHbja9V9kRj9Y4yZeEi+G51s36kiDRkGFMfFR0nqVHrFcm02lkzc5ngV2jyXQ==","signatures":[{"sig":"MEUCIEfHGCU37BS4gYariNJ+lqxEL8dDVg1bA4ydPTtV+TpHAiEA7gDHDRzNsN+o0Cz2IOPZ8B+tr/YmPUY6UIyuEMYxd1w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2796544},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"ff478739ca9447b6471bf408d319a1e40ffb6eba","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.20.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.8_1789051102992_0.6631402210953381","host":"s3://npm-registry-packages-npm-production"}},"0.2.11":{"name":"@bwthomas/vicary","version":"0.2.11","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.11","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"63b43246795b5b6d290ffd3ce8f8b8f14d2477a5","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.11.tgz","fileCount":67,"integrity":"sha512-hjmWNq6lLh/AC2xHDJYYPRPMTop9zBLGJJEQNWFUePhm0HXpTGiPuLmaCxSYmNRFW6yrAU+hEgMTyz9azz60uQ==","signatures":[{"sig":"MEYCIQD1nhAhFj4Tor5H0gJWGV5idXrhYxKHbnJUfSyROFAkdAIhAIXcK522dkDr5qcyhyXQdTms5dRCzXfOe46h6W7W7mcp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.11","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2826240},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"9eaa5380887485180552924f94d5f02c30c60efa","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.20.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.11_1789077438389_0.23087021366657656","host":"s3://npm-registry-packages-npm-production"}},"0.2.12":{"name":"@bwthomas/vicary","version":"0.2.12","keywords":["redaction","anonymization","privacy","education","names"],"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","_id":"@bwthomas/vicary@0.2.12","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"homepage":"https://github.com/bwthomas/vicary","bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"dist":{"shasum":"adcc1bd9024e684b916bc6a3fc8285740549abd8","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.12.tgz","fileCount":67,"integrity":"sha512-w3SC+2/DkuzQ4Ri8hwem+eFV0xXGTA+awHnOm3sqhJMFqK6UF9nbiNwgJATYPP9YSolqlnV3+wB4uFuEhF2yyQ==","signatures":[{"sig":"MEYCIQCuR1P/JU08ioCOTF4Fal907gBVhGRY3G1qwObKB2/b3AIhAIa1lOfVQFEHWAeTnsawWkn0b/oJYtJZm9ppKbHtCjPn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.12","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2826240},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"5f2b870ecfecd4e62d5feb45a50521e4b32cebda","scripts":{"test":"npm run build:test && node --test dist-test/test/*.test.js","build":"npm run sync-assets && tsc -p tsconfig.json","gates":"npm run build:test && node dist-test/test/gates.test.js","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","conformance":"npm run build:test && node dist-test/test/conformance.test.js","sync-assets":"node scripts/sync-assets.mjs","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"repository":{"url":"git+https://github.com/bwthomas/vicary.git","type":"git","directory":"typescript"},"_npmVersion":"12.0.2","description":"Offline redaction of personal names in student compositions","directories":{},"_nodeVersion":"24.20.0","comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","_npmOperationalInternal":{"tmp":"tmp/vicary_0.2.12_1789077974704_0.6240685841140183","host":"s3://npm-registry-packages-npm-production"}},"0.2.15":{"name":"@bwthomas/vicary","version":"0.2.15","description":"Offline redaction of personal names in student compositions","license":"MIT","author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"homepage":"https://github.com/bwthomas/vicary","comment:repository":"The same three links each front door declares — repository, changelog, issue tracker — except npm has no changelog field. `repository` is kept alongside `homepage` here where the other two ports dropped their second repo key: npm reads this one structurally for provenance attestation and for `directory`, so it is not the display duplicate that makes `gem build` warn.","repository":{"type":"git","url":"git+https://github.com/bwthomas/vicary.git","directory":"typescript"},"bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"comment:name":"Scoped under @bwthomas because npm's typosquat filter refuses the unscoped `vicary` as too similar to the existing `vary`. The name is owned by nobody — registry.npmjs.org/vicary is a 404 — so it reads as available and is not. An appeal is open; this scope is the interim, and PyPI and RubyGems both carry the unscoped name.","publishConfig":{"access":"public"},"keywords":["redaction","anonymization","privacy","education","names"],"type":"module","engines":{"node":">=20"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"comment:dependencies":"None, deliberately, matching the Python package. The redaction path is standard library only: no model, no network, no cloud client. typescript is the only devDependency because the test runner is node:test.","dependencies":{},"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"scripts":{"sync-assets":"node scripts/sync-assets.mjs","build":"npm run sync-assets && tsc -p tsconfig.json","build:test":"npm run sync-assets && tsc -p tsconfig.test.json","test":"npm run build:test && node --test dist-test/test/*.test.js","conformance":"npm run build:test && node dist-test/test/conformance.test.js","gates":"npm run build:test && node dist-test/test/gates.test.js","parity:gazetteer":"npm run build && node scripts/gazetteer-parity.mjs","parity:redaction":"npm run build && node scripts/redaction-parity.mjs","parity":"npm run parity:gazetteer && npm run parity:redaction","prepack":"npm run build"},"gitHead":"fd791be5ee2e834ad7f3c04a532894e05a4addde","_id":"@bwthomas/vicary@0.2.15","_nodeVersion":"24.20.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-rnq5lXAzCcaRRYybII6LBPMKlitwynuiRDoR35NmEGIV03JfURCdjN1t7LvakrSh2gHs6i45Nl3sGSY4KlG2ug==","shasum":"565824c8548aac0e38cd55e77a6d25991a87d047","tarball":"https://registry.npmjs.org/@bwthomas/vicary/-/vicary-0.2.15.tgz","fileCount":67,"unpackedSize":2916901,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bwthomas%2fvicary@0.2.15","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCaiD0hS4JCGK2tFknayVAeV7fLbeDnz0Ru+lmBmU033gIgNEYBBcdlyeb9xMplUNIDVY2MfOlkOfmbKq7As4uuZi8="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2a6ef5ea-4be8-4a6b-b1af-1d83b71f6a17"}},"directories":{},"maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vicary_0.2.15_1789338627453_0.09962256553881166"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-12T00:48:00.829Z","modified":"2026-09-13T22:30:27.976Z","0.2.1":"2026-08-12T00:48:01.269Z","0.2.3":"2026-08-13T00:30:44.745Z","0.2.4":"2026-08-13T01:20:41.462Z","0.2.5":"2026-08-13T17:49:15.295Z","0.2.7":"2026-09-09T14:48:40.042Z","0.2.8":"2026-09-10T14:38:23.213Z","0.2.11":"2026-09-10T21:57:18.630Z","0.2.12":"2026-09-10T22:06:15.110Z","0.2.15":"2026-09-13T22:30:27.652Z"},"bugs":{"url":"https://github.com/bwthomas/vicary/issues"},"author":{"name":"Blake Thomas","email":"bwthomas@gmail.com"},"license":"MIT","homepage":"https://github.com/bwthomas/vicary","keywords":["redaction","anonymization","privacy","education","names"],"repository":{"type":"git","url":"git+https://github.com/bwthomas/vicary.git","directory":"typescript"},"description":"Offline redaction of personal names in student compositions","maintainers":[{"name":"bwthomas","email":"bwthomas@gmail.com"}],"readme":"# vicary (TypeScript)\n\nThe npm front door, published as\n[`@bwthomas/vicary`](https://www.npmjs.com/package/@bwthomas/vicary).\n\n**The scope is interim.** npm refuses the unscoped `vicary` as too similar to the\nexisting `vary` — the name is owned by nobody, so it reads as available in any\n404 check and is not. An appeal is open; PyPI and RubyGems both carry the\nunscoped name, so this is the one front door whose import path differs.\n\nThe detector, the data asset and the measured numbers are described in the\n[project README](https://github.com/bwthomas/vicary#readme). What lives here is a\nport, and the bar it had to clear before it could be published is the shared\nconformance suite in [`conformance/`](../conformance): for every fixture frame it\nmust produce **byte-identical output to the Python implementation, placeholder\nnumbering included**.\n\n`npm run conformance` reports **38 of 38 masking-required frames** and 54 of 54\noverall, against the `local-gazetteer-lowercase` arm. Run it rather than trusting\nthis paragraph — the scoreboard prints on every test run, and this line is a\ncopy of a number that moves.\n\n```ts\nimport { redact } from \"@bwthomas/vicary\";\n\nredact(\"My cousin Vinny came over that summer and never left.\", {\n  firstName: \"Marguerite\",\n  lastName: \"Delacroix-Whitfield\",\n  schoolName: \"Westfield High School\",\n});\n// \"My cousin {NAME_1} came over that summer and never left.\"\n```\n\nPass the student's own identity. Every reference arm interpolates those three\nstrings, so omitting them measures a different system and misses the easiest\nspans in any composition. `redactWithReport` returns the same bytes plus the\n`restoreMap` that `restore` reads to put the originals back.\n\nFor a host that draws on the essay, reversing the text is not enough: a\nplaceholder is not the width of the name it replaced, so an offset measured\nagainst the masked copy is displaced against the composition the student holds.\n`deriveSpans` gives each replacement in both coordinate systems, and\n`toOriginal` / `toRedacted` translate between them; `originalText` reconstructs\nthe whole composition.\n\n```ts\nconst { text, restoreMap } = redactWithReport(essay, identity);\nconst spans = deriveSpans(text, restoreMap);\nhighlight(essay.slice(toOriginal(start, spans), toOriginal(end, spans)));\n\n// Several fields, one pass, and one restore map per field. Numbering is the\n// JOINED document's, so one person keeps one placeholder across every field —\n// masking field by field renumbers and hands `{NAME_1}` to two people.\nconst { texts, restoreMaps, batched } = redactBatchWithReport(fields, identity);\n// `batched === false` means the join did not round-trip and each field was\n// passed separately, so cross-field placeholder identity does NOT hold.\n```\n\nTwo things to know. An offset inside a placeholder resolves to the start of the\nspan it replaced, and an absent or partial map yields no spans and translates as\nthe identity — a caller can handle \"no spans\" and cannot detect a wrong offset.\n**These offsets are code points, not UTF-16 code units**, so they agree with the\nPython and Ruby ports character for character above the BMP as well as below it;\n`conformance/spans.json` carries astral cases that fail a transliteration.\n\n**The gates.** Of the nine in [`conformance/gates.json`](../conformance), this\nport measures the five that need no operator-supplied data, and all five hold:\n\n| gate | bar | measured |\n|---|---|---|\n| held-out recall | >= 100 % | **100 %** (16/16 spans) |\n| KEEP precision | >= 100 % | **100 %** (21/21 spans) |\n| round-trip | >= 100 % | **100 %** (54/54 frames) |\n| unaccounted violations | == 0 | **0** |\n| asset entries | >= 1 | **360,793** |\n\nA sixth — bare-surname exposure — this port measures from the surname table\nshipped in `conformance/census/`, reporting 1.20% of US surname bearers, the same\nfigure Python and Ruby report from the same table. `VICARY_EVAL_CENSUS_CSV`\noverrides it with your own Census copy, and must be the **extracted**\n`Names_2010Census.csv`: a `.zip` is refused by name rather than read as text,\nbecause Node's standard library has no zip reader and a binary read parsed as CSV\nyields zero rows — a *lower* exposure than the truth, and the wrong direction to\nfail in silently. The shipped table is gzip, which `node:zlib` reads, so that\nhazard does not arise on the default path.\n\nTwo of the remaining three — held-out recall (carrier) and over-fire on prose —\nread the corpus the repository now ships in `conformance/corpora/`, so they\nmeasure on a bare checkout with no environment set: 100% carrier recall and 7.400\nover-fired spans per essay against a ≤ 7.40 bar, both identical to Python and\nRuby. `VICARY_EVAL_CORPUS_TSV` is an override for a different corpus, not a\nrequirement. (That over-fire figure sits on the bar in all three ports, which is\na knife-edge rather than noise — the root README says why.)\n\nThe ninth is latency, and it is no longer a p95 or a millisecond bar. It is a\nratio: this checkout against the **last release timed on the same machine**, held\nto ≤ +8%. So it needs a pair record rather than a corpus, and prints `NOT\nMEASURED` with the reason attached until it has one. This is the noisiest port on\nthat ratio — σ 1.98%, against 0.60% in Python and 0.46% in Ruby, which is why it\ntakes three times the rounds — and the least machine-sensitive on the absolute,\nbecause at ~2 ms the JIT dominates the CPU.\n\nGates without their data print `NOT MEASURED` rather than dropping out of the\ndenominator: **eight of nine held is a different statement from nine of nine**,\nand a badge cannot tell them apart.\n\nThe carrier essays are built from offsets recorded in `conformance/carrier.json`\nrather than from a reimplementation of Python's RNG, and the suite asserts their\nsha256 — so agreeing with the reference on a number means agreeing about the\nredactor, not about three different inputs that happened to score alike.\n","readmeFilename":"README.md"}