{"_id":"@alexwohlbruck/portolan","_rev":"15-571ceefc94ed286843b5c59f7e5e480a","name":"@alexwohlbruck/portolan","dist-tags":{"latest":"0.5.0"},"versions":{"0.3.1":{"name":"@alexwohlbruck/portolan","version":"0.3.1","license":"MIT","_id":"@alexwohlbruck/portolan@0.3.1","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"16bfaf68bf8c41af0df26174be1734f432e4d88d","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.3.1.tgz","fileCount":46,"integrity":"sha512-9xm54wz633RFFJ2XTzO2BwKFY2INtNr/P4alVdLkdUCVP7bpsuqkPQmGCENAiDzEuet9eg0iuKuiVbHgVF/Uow==","signatures":[{"sig":"MEUCIQDA5Z0rY5SJVpQG+oyRlOxxBRQKtirpjxcjdMr6M7jvkQIgZOnhkit4uIVA/qv1okjpOLG3VXkcVkw8XgS08VWe2Hk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54292335},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"10.9.3","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.3.1_1787633442057_0.17778323730411327","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@alexwohlbruck/portolan","version":"0.3.2","license":"MIT","_id":"@alexwohlbruck/portolan@0.3.2","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"14976925454856fbac890c0911f1322be9856df5","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.3.2.tgz","fileCount":46,"integrity":"sha512-9Y1otmXVJqnc3E9dZ0BgsI7+/izdj2lvl5yALnCZWIFkWSscicmjbo2t33pcxLMckrhpjYHjC2OAbpjoRheGiQ==","signatures":[{"sig":"MEYCIQDCJi8D2SpHC2gjMWb/rShmDyItU0ZfhD3YPAiPBjfr3gIhAJz0QVOFrF5brPTvmXUVoWxgpLHvxC74VmKgBHH1aMUC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.3.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":54307443},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"2ba8b357f1dc4347b1dc46307139089e98b0d73b","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.3.2_1787773784710_0.12626237254903439","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@alexwohlbruck/portolan","version":"0.4.0","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.0","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"79a7bb30a4b7d059c479cfbc9249dca9f8ad2dc4","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.0.tgz","fileCount":46,"integrity":"sha512-2D1NeMztYj3kIvAwxgAYI50x+xHjZg00wpCF4vTt6H+tAHkBhE1HMFh+mUiTyolvZG5i9nfYjLNXUeVrI6W2ng==","signatures":[{"sig":"MEUCIQCwOUalhJJfDZth3XZuXtR7rANaM3eZ7hamY6tEuimAmgIgFRhiZJAYsICFfIxvzU1ZD7+YfcPuHbQ1VB/nqZJs/lQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCk8URWsRxqHtOjgnGhKU69yE/xO+QUzCm0DlF/XSO09gIhALflYvKIalAmcGXmlVxCscw0uRh1IpUG+EC64dP6KI8S","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55191427},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"dbfa3da2aeb13b63d3c7d94dc9ec6a84e30fd214","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.0_1788241325559_0.30099646438268324","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@alexwohlbruck/portolan","version":"0.4.1","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.1","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"039f3704188ab6c7a357b8e8c0b72c83da00570e","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.1.tgz","fileCount":46,"integrity":"sha512-O73LmJ3GJBHZ9/Cfq+2GcFC9gEMpLq42XrahIOHYkPCcob4XjdMsDdM28bc8Lm8TjsIq6AcuKC8IWyhcCM75ug==","signatures":[{"sig":"MEUCIQDAtyxxUTn3+xBtgw1Au5fN21l1sgpfNQg9eSDuPd4GXAIgLrK3lMzDf4Ps1QFHC6XxcnjVYhRH+Ew2KVrkcJsIl1k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGxiC1YLdf77Zxfj2iUjXqQtCGlqgaG/4vO6w7CZXMZlAiBvT1Uodc/cPfN+C1yWK1oGvuAhUbzyvj6x13jrdctC1A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55192451},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"871eaa11f5d30383a931839d9aaec9585404b76d","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.1_1788291068126_0.08146330245659894","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@alexwohlbruck/portolan","version":"0.4.2","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.2","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"8b7aa79b9ca1a1dc358b6f75d3b6c726864fe5df","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.2.tgz","fileCount":46,"integrity":"sha512-6CSQ3tknp3b49Q+7chh4LsZi3PkKq8bBwpNQgOcvHf7TlQ2rRQm87AUFtKOl7pe+/jLrVocVz1zHgiWtmsqDwA==","signatures":[{"sig":"MEUCIQDHg9AyfgAg6fpWzoc42LD57D/QqWslB9f1t+hZ2EnRjQIgbFoIWKk27ld6R2cNd8Z3pMESTBfa3ewEJpvYidpP+kQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCXaQNOi/lVOvCk97MKBTtbsw9/qNow25Ry2hK0nQyy5QIhANFOq3YX2EUye+zkUdIifayf4uBrEcLca/Bumg9HOWNX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55283859},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"ac8289bdb074ef85c933484f465490695a701525","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.2_1788297069577_0.11574519607255507","host":"s3://npm-registry-packages-npm-production"}},"0.4.3":{"name":"@alexwohlbruck/portolan","version":"0.4.3","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.3","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"bff4fdc3c5272f093efbe2101c655c17772d533a","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.3.tgz","fileCount":46,"integrity":"sha512-Vjo+EPkzuHL0D81+3BHY2AsZpz4552YBT5Tq+4/w3DcFUNqzDWxEkkQZpzsH+fKfWGEuqN71zBBdVHcEzHeozw==","signatures":[{"sig":"MEYCIQCmSOyk8taB7S9+YP6TtmzAFS2P4spS/hYbFJxIQeZe3wIhAJPz0k3mQMq3hWE1FRhQfO7QdkLDAcFdMRpbRn5HQNfk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIF5YNHSzmUgDzyCQncRfgKa+1uW1qfNUvHxpBEQHM2fHAiEA99yQ1qh/+8NzmonGyK2KcDccxyrs46rQwEdOU4kUrEs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55423331},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"a51862327e5aeafe221a98b64b1166491a64da87","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.3_1788314916368_0.0074918199276523545","host":"s3://npm-registry-packages-npm-production"}},"0.4.4":{"name":"@alexwohlbruck/portolan","version":"0.4.4","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.4","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"c3629ef32b1a90e4502f36b1f8ad1226cb68ef7d","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.4.tgz","fileCount":46,"integrity":"sha512-YawD6j6rA/eilbmUL4/qrOkFK9bHWeWOrmSLrqLlbGA9aZ2/IERqEE6zhlhPYUgNfTU/JQYJwpxTL5ixJpJnqQ==","signatures":[{"sig":"MEQCIAuWgKcoiCwQaq70ob439kaZc/p6owSu70P2PgOVRfgrAiBoXRYPX0d6ghqRQVcl83ROxOdFUg9YsCzoTIBIs6BXVg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIACLKuEvRHxSKeFAYkMwiElp8tPjZbbFCRDSnvzTs9y0AiAAlWi7DMj9eYbHYOO3YNCarN94NTfeGG7OUacbImGbfA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55431011},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"dc4f7ac62cfbb355cdefa3781afe78c06901b15c","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.4_1788466120150_0.297917613032219","host":"s3://npm-registry-packages-npm-production"}},"0.4.5":{"name":"@alexwohlbruck/portolan","version":"0.4.5","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.5","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"48017f85e4884aa1595f3b804e7d9ddb361de7ce","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.5.tgz","fileCount":46,"integrity":"sha512-sUWALtLJqppU1+VGs+vdFLbq/bsXOJSQIb2IUt+VYz752EE6ptkUw/pCbx/+/QER73WlFhUV09Q9tOOpcoIKVQ==","signatures":[{"sig":"MEQCIBgtXRLx6PnqvmHCHD5p1zFG3IiDksXt0xKDA42yKTr1AiAD4lOfHNDF/0EO0qht2krhC/1MKu2GmutTnIuoRNqSKw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCFvpn5zM9yRU5fVf2jxev0MSRsNYPLiNw3pFUwMiD6sgIhAPuqNbkcePrbgGBv2OGtwCFLe/LoU9VO/K14OyMN9ERS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55433587},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"1068a99b2f514e599f246f8dde4be2536c7c5047","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.5_1788473556701_0.5684972570767548","host":"s3://npm-registry-packages-npm-production"}},"0.4.6":{"name":"@alexwohlbruck/portolan","version":"0.4.6","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.6","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"b7191e8fe28f82522fcb844a6da49b07f4f340b4","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.6.tgz","fileCount":46,"integrity":"sha512-TPDmArKxDBKDBwBFjdlIOzCX7DjNB46w298DHzOco9M0at7Sjncqmm1bLEhvK6Nry6w10/mB59yVqF9UdAkyjA==","signatures":[{"sig":"MEUCIAWJV4CqQY9p1RQImOgt4d2N8ueK8fpMCP9S/lcrlZZxAiEAg/lr07tVhKX3FRO5RKhDFe6ApQa8CQjcgveYEHw7N6c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCir5dXY8+LKXXGRTcFx+BrxSm3wpgPq12usNLLhVYsfAIhAPhFQFXLwMJAyB9HpPtpzpeT9tYGNwuFLlyxV68O5WU0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55537843},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"0a152e2ef1ff5f0b01bd3e705214a8842b6fc18d","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.6_1788500663042_0.6812758503643372","host":"s3://npm-registry-packages-npm-production"}},"0.4.7":{"name":"@alexwohlbruck/portolan","version":"0.4.7","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.7","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"d7260edb3389736f9d2b1e0bcaa3574e074d229f","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.7.tgz","fileCount":46,"integrity":"sha512-axTGe2zRjoaBhJD+jeqldAkQhBQhF7oJLqrFBHTpAOZ2x/CWBXgW68ec8pD/Y2j1rbDqqE4ZXtS0txnf8Wr6mQ==","signatures":[{"sig":"MEQCIDk5gBgLqXHyLQkBJhzntAkEKWE++kUE/RcRkcYUF2O7AiBZFjiOM8SHDsOfuRktIvLFwJMdgSByVmsxrvWDBk9SBg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCBtpTi8qAVNiU4wCZyas1u4CWbm7tmb6BTNh+U+Q/sJQIgOGpBoE7Y+aMjGogMAiiCC6DtVXFpnth0FiZo6ykWaN4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55538355},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"897922f7e2e4c01a025476a70335803425ec6be1","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.7_1788501469238_0.9226531610140103","host":"s3://npm-registry-packages-npm-production"}},"0.4.8":{"name":"@alexwohlbruck/portolan","version":"0.4.8","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.8","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"0f1244c774cab9ca0d34f01f4fe4adeb4c4c146e","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.8.tgz","fileCount":46,"integrity":"sha512-8FYzn/PGrp6kQKNOauW1z1QV6NTij0/STa8u5YrQsQVKFxH35N7d3d8+UV4NHqzG5S64JW8d/f/yCItI0rbI8A==","signatures":[{"sig":"MEUCIQCuKJdr3yJUpE0vl6CaLiFxEOuJs7eljkV6zBifwsG9XQIgTLg/+ev67MlZPVeqAzFWB8fVM+ThlPxXSs6uj1KJ0g8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBwlZ5uO2rxHN5I5V9DXu1vZodSbgvJhXx+jpqB5tGgNAiEAj7+2hs4dEbuvqYgtMV5u3LBRKZXfpwQ/uPuImuf8v2M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55538899},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"96b8e2f9afc4f1e83d15e6eb11fa411ea24bf908","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.8_1788546556887_0.39716190604917534","host":"s3://npm-registry-packages-npm-production"}},"0.4.9":{"name":"@alexwohlbruck/portolan","version":"0.4.9","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.9","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"0d653f886b65d13f0411b7ab35af8f2136fef7de","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.9.tgz","fileCount":46,"integrity":"sha512-7NLgB+5gB8rYzqLQqzl6/Wwi8K9RPqqoFmSE1JXTiUCQ6vU4eWpiSNCNVuwPJf/cDcEK32iNImW1aWi8XF5u6g==","signatures":[{"sig":"MEUCIF96pYRr7yVjr+gLLPIChtLwGqHVzthS1aVHdHGV0iGbAiEA5bEYTjOFUAF+M6Y1+dRsl6wsLRKxkPvpPlh7/eBFluc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDxHzuGau4ITt3K8XwXiPdHga8h6lbn2uKj//aHOmytUQIhAJwtLD4mFhYBgaDwyu0xG6J+gQMJjTdgGB92xBrXsZro","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55714979},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"208681f5feb374c827c1fa6b194a99d60182588b","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.9_1788552960904_0.034230692652560624","host":"s3://npm-registry-packages-npm-production"}},"0.4.10":{"name":"@alexwohlbruck/portolan","version":"0.4.10","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.10","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"c7ae0fd2a5c01f2629b405a3e70366bd5ffdf8c3","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.10.tgz","fileCount":46,"integrity":"sha512-1BX5RRGIxHGHg8+tSSCM5EaszErp41lKzdo4kxT9mIxWewSmT6bEBK4OxHb/Y9qizVtOacV6cLqjVLOH9oDhDg==","signatures":[{"sig":"MEUCIQDLqOiS9DMwFknktuO1NT7Ob/a2JQSKsJGS6FK07jTMOAIgZfGb9j6P/TJZChGTYvIkVtuXPddNcY6wkPhQ1u4d96g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBQicHWNCKlpW+3n4Edy3fjaXoPOJUyXCJZPLHAQGOOuAiEAmBxfENkYBSUSTvTxnGqzrVL+XGgxJWc1K9KacwdBLrw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.10","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55714534},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"e141dcf1c2bda4eff115ce4c45ef15874defc95e","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.10_1788647714398_0.43389708584485653","host":"s3://npm-registry-packages-npm-production"}},"0.4.11":{"name":"@alexwohlbruck/portolan","version":"0.4.11","license":"MIT","_id":"@alexwohlbruck/portolan@0.4.11","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"homepage":"https://github.com/alexwohlbruck/portolan#readme","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"026229b8f37b31443f4ce690bd2c064bf09734f8","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.4.11.tgz","fileCount":46,"integrity":"sha512-7drAtgi0U3ujQR/4dMb4h80vi58lkOlCwt7EnHnXhvIy262UIqsvJq3hAEHC62ptB6p/FeWI5Kqdv75rZs6DFA==","signatures":[{"sig":"MEUCIQCeKl+tXyBJbYZnV5j6VicbusgytVlGHVeEfo1LloX93wIgTXWM6FivdRRUHi+oWrkOMBKCMyuSdNXQIsNoePemVwA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDwPQjoaD3s4DZE8BbJHppTGlzVZ3RKfan1gs20ekzR8QIhALQIcRXG0Y1YF7R0Tlft9D19QORapN93myvd1k5UuTYx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.4.11","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":55936998},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"1d36d97a2bbe2ee3629dd87c87ab395d80ef9bcb","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"tmp":"tmp/portolan_0.4.11_1788931788936_0.7450326318469793","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"_id":"@alexwohlbruck/portolan@0.5.0","bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"dist":{"shasum":"47e406de3c8d4c42e6f0ccb9befa3ae789279509","tarball":"https://registry.npmjs.org/@alexwohlbruck/portolan/-/portolan-0.5.0.tgz","fileCount":46,"integrity":"sha512-MegYp2U9Vbm+HeFWg9aF7RfqdHprZzF7g66nS0vFaQvVOunanyab6xpSIythwKYCoXUPfITwtPhBlPNQ4vCgyQ==","signatures":[{"sig":"MEUCICv9jsAhMR1Oa3jDGmN1bcbSE2/0TOf9HevCp/EJ9ShTAiEAlG1OfrgDzdb1qAt8u25Ii3Jp0uR2pi0m3tGVuv2v+Cg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHva7Pre8IgfyIPI/kR1pJAG95CO1h1u7t7iquy0mehpAiEAhuZF++2lX7MUciA1d1XZG4XuL4b8VYROxPvGE9hjhNI="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexwohlbruck%2fportolan@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":56160627},"name":"@alexwohlbruck/portolan","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./plnb":{"types":"./dist/plnb.d.ts","default":"./dist/plnb.js"},"./client":{"types":"./dist/client.d.ts","default":"./dist/client.js"},"./package.json":"./package.json"},"gitHead":"54e9b2ab7d4eed3409e7687f249b4d7f9894db13","license":"MIT","scripts":{"test":"npm run build && node --test test/*.test.js","build":"tsc -p tsconfig.json","check-publish":"node scripts/check-publish.mjs","prepublishOnly":"npm run build && npm run check-publish"},"version":"0.5.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1ddfcb15-68c6-47d2-b618-59454834f812"}},"homepage":"https://github.com/alexwohlbruck/portolan#readme","repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"_npmVersion":"12.0.2","description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","directories":{},"maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"preferUnplugged":true,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/portolan_0.5.0_1789405319461_0.8749320278859318"}}},"time":{"created":"2026-08-25T04:50:41.850Z","modified":"2026-09-14T17:02:00.215Z","0.3.1":"2026-08-25T04:50:42.506Z","0.3.2":"2026-08-26T19:49:45.156Z","0.4.0":"2026-09-01T05:42:06.051Z","0.4.1":"2026-09-01T19:31:08.557Z","0.4.2":"2026-09-01T21:11:10.080Z","0.4.3":"2026-09-02T02:08:36.739Z","0.4.4":"2026-09-03T20:08:40.520Z","0.4.5":"2026-09-03T22:12:37.079Z","0.4.6":"2026-09-04T05:44:23.409Z","0.4.7":"2026-09-04T05:57:49.647Z","0.4.8":"2026-09-04T18:29:17.280Z","0.4.9":"2026-09-04T20:16:01.304Z","0.4.10":"2026-09-05T22:35:14.772Z","0.4.11":"2026-09-09T05:29:49.408Z","0.5.0":"2026-09-14T17:01:59.854Z"},"bugs":{"url":"https://github.com/alexwohlbruck/portolan/issues"},"license":"MIT","homepage":"https://github.com/alexwohlbruck/portolan#readme","repository":{"url":"git+https://github.com/alexwohlbruck/portolan.git","type":"git","directory":"clients/npm"},"description":"Automatic transit line maps. Spawns the portolan engine and speaks its build API, with a typed PLNB decoder.","maintainers":[{"name":"alexwohlbruck","email":"alexwohlbruck@gmail.com"}],"readme":"# @alexwohlbruck/portolan\n\nAutomatic transit line maps, as a Node package. Spawns the\n[portolan](https://github.com/alexwohlbruck/portolan) engine, speaks its\nbuild API, and decodes its binary output.\n\n**The engine ships inside the package.** One binary per platform, pulled\nin as an `optionalDependency`, so npm installs only the one matching your\nmachine and a version bump here ships a new engine. No download step, no\n`postinstall`, nothing to keep in sync.\n\n```bash\nnpm install @alexwohlbruck/portolan\n```\n\n## Use\n\n```ts\nimport { portolan } from \"@alexwohlbruck/portolan\";\n\nawait using p = await portolan();\n\nconst job = await p.chart(\n  {\n    gtfsInline: {\n      \"routes.txt\": \"route_id,route_short_name,route_type,route_color\\nR1,1,1,EE352E\\n\",\n      \"stops.txt\": \"stop_id,stop_name,stop_lat,stop_lon\\ns1,Alpha,37.77,-122.42\\n\",\n    },\n    corridorsInline: graph,   // a GeoJSON corridor graph\n    format: \"bin\",\n    band: 15,\n  },\n  { onProgress: (e) => console.log(e.stage, e.pct) },\n);\n\nconst plnb = await job.plnb();\n```\n\n`await using` stops the engine when the scope ends. It needs TypeScript\n5.2+ and `Symbol.asyncDispose` at runtime (Node 20+); on an older target\njust call **`p.stop()`**, which is always available and is the same\nthing. The syntax is sugar, not the interface.\n\nEither way the package installs a `process.on(\"exit\")` reaper, so an\nengine cannot outlive its parent even on `process.exit()` or an uncaught\nthrow — see *Lifecycle* below for what that does and does not cover.\n\nNothing above touches the filesystem. `gtfsInline` and `corridorsInline`\nput the feed tables and the corridor graph in the request body, which is\nwhat an editor wants: a colour change touches `routes.txt` and every\nroute edit touches `stop_times.txt`, so writing a zip per keystroke is a\nround trip bought for nothing.\n\n## Two processes, one engine\n\nIn Electron, **main owns the process and the renderer owns the\ntraffic.** Routing artifacts through IPC structured-clones them, which\nis exactly the main-thread cost this format exists to remove.\n\n```ts\n// main: own the lifecycle, hand out the address\nconst p = await portolan();\nipcMain.handle(\"portolan:addr\", () => ({\n  origin: p.server.origin,\n  token: p.server.token,\n}));\napp.on(\"before-quit\", () => p.stop());\n```\n\n```ts\n// renderer (or a worker): own the traffic\nimport { PortolanClient } from \"@alexwohlbruck/portolan/client\";\n\nconst { origin, token } = await ipcRenderer.invoke(\"portolan:addr\");\nconst client = PortolanClient.at(origin, token);\nconst job = await client.chart({ ... });\nconst plnb = await job.plnb();          // bytes never cross IPC\n```\n\n**Import from `/client` in the renderer, not from the package root.**\nThe root exports `PortolanServer`, so it pulls `node:child_process`, and\nan Electron renderer with context isolation has no Node — the bundler\nfails the build. `/client` and `/plnb` are Node-free by construction and\nthere is a test that keeps them that way.\n\n| subpath | holds | needs Node |\n| --- | --- | --- |\n| `@alexwohlbruck/portolan` | everything, incl. `portolan()` and `PortolanServer` | yes |\n| `@alexwohlbruck/portolan/client` | `PortolanClient`, `Job`, `PortolanError` | no |\n| `@alexwohlbruck/portolan/plnb` | `decodePlnb`, `Plnb`, `SUPPORTED_PLNB` | no |\n\n`PortolanClient.at()` is the piece that makes this split possible. The\none-liner at the top is the right shape for a CLI or a server; for a UI\nprocess, use this one.\n\n## Reading the output\n\n`job.plnb()` returns a decoded build whose property arrays are **views\nover the response buffer**, so per-feature values are read by index with\nno allocation.\n\n```ts\nconst plnb = await job.plnb();\n\nplnb.degrees();        // Float64Array, flat [lon, lat, lon, lat, …] — for the GPU\nplnb.starts;           // Uint32Array, featureCount + 1 vertex offsets\nplnb.positions;        // Int32Array at 1e-7 degrees — the wire form, rarely what you want\n\nfor (let i = 0; i < plnb.featureCount; i++) {\n  const [a, b] = plnb.vertexRange(i);   // positions[a*2 .. b*2)\n  plnb.colorHex(i);                     // \"#ee352e\"\n  plnb.offsetPx(i);                     // lateral slot offset in px\n  plnb.routes(i);                       // [\"R1\"] — verbatim, never normalised\n  plnb.bandMin(i), plnb.bandMax(i);     // HALF-OPEN: [min, max)\n}\n```\n\n`plnb.feature(i)` gives a plain object, and `plnb.toGeoJSON()` the whole\nthing — both allocate, so neither is the fast path.\n\n### Getting it onto the GPU\n\nUse **`degrees()`**, not `positions`. Every WebGL path — deck.gl,\nMapLibre, raw GL — wants degrees in the vertex buffer, because\nprojection happens in the shader from lng/lat, and nothing off the shelf\ndivides by 1e7.\n\n```ts\nnew PathLayer({\n  data: { length: plnb.featureCount, startIndices: plnb.starts,\n          attributes: { getPath: { value: plnb.degrees(), size: 2 } } },\n  _pathType: \"open\",\n});\n```\n\nIt is `Float64Array` and that is not a preference: a float32 holds about\nseven significant digits where a longitude needs nine, so an f32 buffer\nquantises vertices to roughly two metres and visibly kinks a ribbon —\nthe same reason the wire format is `i32` and not `f32`. deck.gl takes\nf64 and splits it into hi/lo f32 pairs for exactly this.\n\n`degrees()` is one pass over the buffer, cached, so calling it per frame\ncosts nothing after the first.\n\n## Lifecycle\n\nThe package **reaps**; it does not **supervise**.\n\nReaped for you: scope exit via `await using`, an explicit `stop()`, and\na `process.on(\"exit\")` / SIGINT / SIGTERM hook that kills any live engine\non the way out. An engine cannot outlive its parent and sit on a port.\n\n**Yours:** restart policy. Whether to retry a crashed engine, how many\ntimes, with what backoff, and when to give up and degrade are product\ndecisions, and a library guessing them is worse than a caller choosing\nthem. One rule worth stating: an `IncompatibleEngineError` must **not**\nbe retried — it will fail identically every time.\n\n```ts\np.server.running;   // false once it has died\n```\n\n## Version handshake\n\n```ts\np.version;   // { version: \"0.3.1\", plnb: 1, formats, bands, auth }\n```\n\n**Gate on `plnb`, not `version`.** It is the binary layout number, and it\nchanges when a column moves — which is the thing a decoder depends on.\n`version` tells you what you got; `plnb` tells you whether you can read\nit. `portolan()` refuses to start on a mismatch by default; pass\n`requireCompatible: false` and use `format: \"geojson\"` if you would\nrather degrade than fail.\n\n## Security\n\nThe engine is started with a **random bearer token per launch**, and you\nshould leave it that way. A chart request names files for the engine to\nread (`gtfs`, `styleDir`, `corridors`), so an unauthenticated port is a\nfile-read oracle for every other process on the machine — binding to\nloopback is not a boundary between processes on one host.\n\n`/version` and `/healthz` stay open so a supervisor can tell \"not up yet\"\nfrom \"wrong token\".\n\n## Choosing a binary\n\nResolution order, first hit wins:\n\n1. `portolan({ binary: \"/path/to/portolan\" })`\n2. `$PORTOLAN_BIN` — a dev override, or a copy you bundled yourself\n3. the per-platform optional dependency (the default)\n\nIf you are packaging this inside a signed application and would rather\nplace the binary yourself, use `PORTOLAN_BIN` and install with\n`--no-optional` to skip the ~3 MB download.\n\nSupported: `darwin-arm64`, `darwin-x64`, `linux-arm64`, `linux-x64`,\n`win32-arm64`, `win32-x64`.\n\nThe engine package is pinned to this package's exact version and\n`resolveBinary()` checks it, because npm **skips an unresolvable\noptional dependency without failing the install** — so a mismatch would\notherwise surface as a missing binary at the first chart call rather\nthan as the version problem it is. Both errors extend\n`BinaryNotFoundError`; neither is worth retrying.\n\n> Node says `x64` where Go says `amd64`, for the same architecture. The\n> package names use Node's spelling because npm resolves them against\n> `process.arch`; the release archives use Go's because `GOOS`/`GOARCH`\n> built them. The mapping lives in one script and nowhere else.\n\n## Curation\n\nColours, names, bullet shapes and fonts are curation, not feed data —\nand for an editor they are live state, changing whenever the user\nrecolours a line. So send the document, not a path:\n\n```ts\nawait p.chart({\n  ...,\n  styleInline: {\n    routes: { L: { color: \"EE352E\", shape: \"diamond\", font: \"italic\" } },\n    agencies: { CR: { name: \"Commuter Rail\", color: \"80276C\" } },\n  },\n});\n```\n\n`styleInline` replaces `styleDir`/`city` when set, and needs nowhere\nwritable — which matters more than it sounds: a packaged app that must\nwrite a file first needs a writable location AND a way to reach it, and\nthat path is a surface rather than a detail.\n\n`styleDir` still works when your curation genuinely lives on disk:\n\n```ts\nawait p.chart({ ..., city: \"sf\", styleDir: \"/writable/path/style\" });\n```\n\nThe class defaults are compiled into the engine, so a directory holding\nonly your own document is complete — there is nothing to copy out of the\npackage first. Either way the document is **subject-keyed**:\n\n```json\n{ \"routes\": { \"L\": { \"color\": \"EE352E\", \"shape\": \"diamond\", \"font\": \"italic\" } } }\n```\n\nA document using the wrong shape is a hard error naming the right one,\nrather than parsing cleanly and applying nothing.\n\n## Versioning\n\nThis package's version tracks the engine it carries, and the two are\npublished together. Pin an exact version if your renderer depends on the\ngeometry: portolan is pre-1.0, so the map is still allowed to move\nbetween minor versions.\n\nSee [docs/CORRIDORS.md](https://github.com/alexwohlbruck/portolan/blob/main/docs/CORRIDORS.md)\nfor the corridor graph contract and\n[docs/CLI.md](https://github.com/alexwohlbruck/portolan/blob/main/docs/CLI.md)\nfor the full API.\n","readmeFilename":"README.md"}