{"_id":"@emdzej/ncsx-identity","_rev":"6-58be49e05603140f0f4ec71f6203e018","name":"@emdzej/ncsx-identity","dist-tags":{"latest":"0.9.0"},"versions":{"0.4.0":{"name":"@emdzej/ncsx-identity","version":"0.4.0","_id":"@emdzej/ncsx-identity@0.4.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"c90191698f1a45bbc09018815a2ff721accd9ad9","tarball":"https://registry.npmjs.org/@emdzej/ncsx-identity/-/ncsx-identity-0.4.0.tgz","fileCount":27,"integrity":"sha512-ylYAQ+JYx/B9JOSVnzwlGfj5WGti6VSDzV3o3ERfKLznchg+qoNXvHnWyXVVt1u4/9hzls2aR4bDc65JikxcEg==","signatures":[{"sig":"MEQCIE//yCjSGq/2TwuyKH6sVfYIu6K4k3cAlKweWuwa5q1ZAiAFA7rvWRuvqApUxLzdIANDBg/ZbduracIc6RIeuBMtbA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48304},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-identity-0.4.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/c2873e425a86062f3106908a563209b3/emdzej-ncsx-identity-0.4.0.tgz","_integrity":"sha512-ylYAQ+JYx/B9JOSVnzwlGfj5WGti6VSDzV3o3ERfKLznchg+qoNXvHnWyXVVt1u4/9hzls2aR4bDc65JikxcEg==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/identity"},"_npmVersion":"11.14.1","description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-wire":"0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-identity_0.4.0_1779705637720_0.15782735317581809","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@emdzej/ncsx-identity","version":"0.5.1","_id":"@emdzej/ncsx-identity@0.5.1","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"50d5c21ad35c120017c6ee14191bbbe6498518ca","tarball":"https://registry.npmjs.org/@emdzej/ncsx-identity/-/ncsx-identity-0.5.1.tgz","fileCount":27,"integrity":"sha512-iaQQ1Obv6WcIMiR+HuevNmZx2xWlw8Rjw7Mn94GSXnJpJKrOYnN69uJwRbQ4AkyXbwbeSYIGgnodyWd3VnpZjw==","signatures":[{"sig":"MEUCIQC2F7xzSGHxu4ULJZvFqmBzvIWJKxRpr+8xqAm2VOhWKgIgcGtdmXJ0w+1DgFVnNkVRc6ie12lO/aJ9FjzreadKZeA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48304},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-identity-0.5.1.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/44d184d54fc05b8b62045c37064aaa98/emdzej-ncsx-identity-0.5.1.tgz","_integrity":"sha512-iaQQ1Obv6WcIMiR+HuevNmZx2xWlw8Rjw7Mn94GSXnJpJKrOYnN69uJwRbQ4AkyXbwbeSYIGgnodyWd3VnpZjw==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/identity"},"_npmVersion":"11.14.1","description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-wire":"0.5.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-identity_0.5.1_1779876447375_0.01736984898775784","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@emdzej/ncsx-identity","version":"0.6.0","_id":"@emdzej/ncsx-identity@0.6.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"88a87b371e24a9c38a4554ed1aea8044aef9187f","tarball":"https://registry.npmjs.org/@emdzej/ncsx-identity/-/ncsx-identity-0.6.0.tgz","fileCount":27,"integrity":"sha512-au/sdvofgI38Vau503JHU86RVjNHS+j0vdHk6JbsiLHsPLBLw8ZxqCjb4cIw/6ocR4bYq0iQ3pPeHuOmLPJ+6w==","signatures":[{"sig":"MEYCIQDBDHrXRdsOdUNboFawW+MZnLlL/2pHdTRY2ddPelp2/QIhAL5P5CMVu0ilwlnKYOMZNtyTNjfNgh1DHAuhb43qqG1c","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48304},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-identity-0.6.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/033953bc5742d4881f265ac067ea7d4a/emdzej-ncsx-identity-0.6.0.tgz","_integrity":"sha512-au/sdvofgI38Vau503JHU86RVjNHS+j0vdHk6JbsiLHsPLBLw8ZxqCjb4cIw/6ocR4bYq0iQ3pPeHuOmLPJ+6w==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/identity"},"_npmVersion":"11.14.1","description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-wire":"0.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-identity_0.6.0_1779981250705_0.6177073311155448","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@emdzej/ncsx-identity","version":"0.7.0","_id":"@emdzej/ncsx-identity@0.7.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"8dee2429a02eb70387cc344fb6d959ecd338b812","tarball":"https://registry.npmjs.org/@emdzej/ncsx-identity/-/ncsx-identity-0.7.0.tgz","fileCount":27,"integrity":"sha512-n6TTZF/9ZnOioPfJyhBOHF7f+/6c2UKGDS0wZAs1f4V+OqDV3ihoAO8C2+nfZR4WBILl/ASmmORTRJk7rpf2WQ==","signatures":[{"sig":"MEUCIFJ95ZZi9GpUrewAEuVof6tICI9b3N5TXsC+otxU8wKOAiEAzeOmYrszLLSeW5exP7HZmzf9/g3LGuIV27ScvC1WB3w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48304},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-identity-0.7.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/c653eef34de9a5a07a5487debb341f3d/emdzej-ncsx-identity-0.7.0.tgz","_integrity":"sha512-n6TTZF/9ZnOioPfJyhBOHF7f+/6c2UKGDS0wZAs1f4V+OqDV3ihoAO8C2+nfZR4WBILl/ASmmORTRJk7rpf2WQ==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/identity"},"_npmVersion":"11.14.1","description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-wire":"0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-identity_0.7.0_1780063017032_0.7614292091872426","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@emdzej/ncsx-identity","version":"0.8.0","_id":"@emdzej/ncsx-identity@0.8.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/ncsx#readme","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"dist":{"shasum":"d36aef72eeba50a6dca1cd623c762dd7a112d93c","tarball":"https://registry.npmjs.org/@emdzej/ncsx-identity/-/ncsx-identity-0.8.0.tgz","fileCount":27,"integrity":"sha512-DQgstswVr0sU+G/LJtVGm38oi7tYmzleyMXImvogsop+d+tk5KhUTvYTp436xsHnp8xzKwBpo4inUV5xtW50KQ==","signatures":[{"sig":"MEUCIQDdxwR/TQde8UPwZL72wY0Txp5G8+maqou+1ytBSPzI7AIgU6ut8JkU68SCjGn20jAmzthAtbpzyc2WZ8Xi4mAOyRk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45149},"main":"dist/index.js","type":"module","_from":"file:emdzej-ncsx-identity-0.8.0.tgz","types":"dist/index.d.ts","scripts":{"lint":"eslint .","test":"vitest run --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/9987df0455753123a923d453d23c0db5/emdzej-ncsx-identity-0.8.0.tgz","_integrity":"sha512-DQgstswVr0sU+G/LJtVGm38oi7tYmzleyMXImvogsop+d+tk5KhUTvYTp436xsHnp8xzKwBpo4inUV5xtW50KQ==","repository":{"url":"git+https://github.com/emdzej/ncsx.git","type":"git","directory":"packages/identity"},"_npmVersion":"11.16.0","description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/ncsx-wire":"0.8.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.8","@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/ncsx-identity_0.8.0_1780758426325_0.9901818457041269","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@emdzej/ncsx-identity","version":"0.9.0","description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","main":"dist/index.js","types":"dist/index.d.ts","type":"module","dependencies":{"@emdzej/ncsx-wire":"0.9.0"},"devDependencies":{"@types/node":"^22.13.1","vitest":"^2.1.8"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/emdzej/ncsx.git","directory":"packages/identity"},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run --passWithNoTests","test:watch":"vitest","lint":"eslint .","typecheck":"tsc --noEmit","clean":"rm -rf dist .turbo *.tsbuildinfo"},"_id":"@emdzej/ncsx-identity@0.9.0","bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"homepage":"https://github.com/emdzej/ncsx#readme","_integrity":"sha512-RYGmX4z8dTylLCvAP//Dm1EfKDJGuPymJrCOvYoPB2oIEoC3rE99TnkHAWr506UsML4FVlshI/GVC1R8WOn1jA==","_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/ef57028533afe592663dd84a3586c263/emdzej-ncsx-identity-0.9.0.tgz","_from":"file:emdzej-ncsx-identity-0.9.0.tgz","_nodeVersion":"22.22.1","_npmVersion":"11.16.0","dist":{"integrity":"sha512-RYGmX4z8dTylLCvAP//Dm1EfKDJGuPymJrCOvYoPB2oIEoC3rE99TnkHAWr506UsML4FVlshI/GVC1R8WOn1jA==","shasum":"cf2185c287c117524b11632319929310c924bdd7","tarball":"https://registry.npmjs.org/@emdzej/ncsx-identity/-/ncsx-identity-0.9.0.tgz","fileCount":27,"unpackedSize":45149,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDyN/FUNDOfiZSMoZV2yi1vxlBllhATZMww1iJJy16f3AiEA1kvbvNWpcNWiUlvPj34abaGcFaPLntezT5kUy34W5SM="}]},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"directories":{},"maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ncsx-identity_0.9.0_1783336569914_0.2115035703506012"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-25T10:40:37.548Z","modified":"2026-07-06T11:16:10.178Z","0.4.0":"2026-05-25T10:40:37.847Z","0.5.1":"2026-05-27T10:07:27.526Z","0.6.0":"2026-05-28T15:14:10.862Z","0.7.0":"2026-05-29T13:56:57.160Z","0.8.0":"2026-06-06T15:07:06.464Z","0.9.0":"2026-07-06T11:16:10.072Z"},"bugs":{"url":"https://github.com/emdzej/ncsx/issues"},"homepage":"https://github.com/emdzej/ncsx#readme","repository":{"type":"git","url":"git+https://github.com/emdzej/ncsx.git","directory":"packages/identity"},"description":"Read VIN / FA / ZCS from a connected BMW ECU. Picks the right identity SG per chassis using SGFAM's FA/ZCS flags (no hardcoded chassis tables).","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"readme":"# @emdzej/ncsx-identity\n\nRead **VIN**, **FA**, and **ZCS** from a connected BMW ECU. Picks the right identity\nSG per chassis using SGFAM's FA/ZCS flags — no hardcoded chassis tables, no\nper-generation switch statements.\n\nDifferent chassis generations carry vehicle identity in different ways:\n\n- **FA-master chassis** (post-E60-ish): a single token string — `E89_#0306&N6SW%0354$167…`\n  — handed back verbatim by the SG. Edited by adding / removing tokens.\n- **ZCS-master chassis** (E36 / E38 / E39 / E46 / E53): three structured fields —\n  `GM` (base-model code), `SA` (hex-encoded bit-set indexed by `<BR>ZST.*`), `VN`\n  (version number).\n\nVIN comes through on both paths via a separate `FGNR_LESEN` job.\n\n## Usage\n\n```ts\nimport {\n  readVin,\n  readFa,\n  readZcs,\n  formatFahrgestellNr,\n} from \"@emdzej/ncsx-identity\";\n\nconst { vin } = await readVin(sgbd, ediabas);\nconst { fa } = await readFa(sgbd, ediabas);          // FA chassis\nconst { zcs } = await readZcs(sgbd, ediabas);        // ZCS chassis\n\n// Format VIN as the 18-char FAHRGESTELL_NR the IPO expects in\n// `C_FG_AUFTRAG`'s `para` — appends the BMW Mod-36 check char.\nconst fgnr = formatFahrgestellNr(vin);\n// \"WBAAA00000PM10277\" → \"WBAAA00000PM10277L\"\n```\n\n`sgbd` is an EDIABAS module name (`\"C_KMB46\"`, `\"D_KOMBI\"`, …) — typically derived\nfrom SGFAM's identity row. `ediabas` is anything matching `EdiabasLike` from\n`@emdzej/ncsx-wire` — `@emdzej/ediabasx-ediabas`'s `Ediabas` class satisfies it.\n\n## Picking the right identity SG\n\n```ts\nimport { findIdentitySg } from \"@emdzej/ncsx-chassis\";  // chassis-bundle helper\n\nconst idRow = findIdentitySg(chassis);\nconst { vin } = await readVin(idRow.sgbd, ediabas);\n```\n\n`findIdentitySg` walks SGFAM looking for the row whose FA-master or ZCS-master\nflag is set. Falls back to a deterministic per-chassis-code map if SGFAM doesn't\nmark one.\n\n## BMW Mod-36 checksum\n\n`mod36Checksum(input)` and `formatFahrgestellNr(vin)` are direct ports of\nNCSEXPER's `coapiSetFgNr` → `CalcMod36CheckSum`. The algorithm sums the input's\ncharacter codes weighted by position modulo 36, mapping the remainder back to\n`[0-9A-Z]` (skipping I, O for visual disambiguation).\n\nWorked example, unit-tested: `\"FPWBAAA00000PM10277\"` → `'L'`.\n\n## Exports\n\n```ts\nexport { readVin, padFgnrToVin, type VinReadResult, type PaddedVin };\nexport { readFa, type FaReadResult };\nexport { readZcs, type ZcsRead, type ZcsReadResult };\nexport { mod36Checksum, formatFahrgestellNr };\nexport type { IdentityReadResult };\n```\n\n## Consumers\n\n- `apps/web/src/components/IdentityPanel.svelte` — drives the identity card\n  in the UI.\n- `apps/web/src/lib/process-ecu.ts` — `processWriteCoding` calls\n  `formatFahrgestellNr(app.identity.vin)` and seeds it as `FAHRGESTELL_NR` via\n  `CDHSetSystemData` so `SG_CODIEREN`'s post-write `C_FG_AUFTRAG` has the right\n  18-byte chassis number to thread into the SGBD.\n","readmeFilename":"README.md"}