{"_id":"gtfs-utils","_rev":"49-1740d1583821d6fd7cd47283d6e1bbdc","name":"gtfs-utils","dist-tags":{"latest":"5.1.0","latest-2":"2.1.1","next":"5.0.0-alpha.2"},"versions":{"0.1.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.1.0","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"luxon":"^0.4.0","strip-bom-stream":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"58f5e727ef70e7e0013da6d77dcd6eb6d3ec5828","_id":"gtfs-utils@0.1.0","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-va5OQbjjqCe0EK2RSaV/SQVbO4AoUkXbeV6HIEtSbcPvjsO50L9w2CY20815pIrVaBgQJwh0sObwLybynswOew==","shasum":"9ad64a5e36b0715cfdc8a8deddd81270f0bb5407","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.1.0.tgz","fileCount":8,"unpackedSize":11273,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICWIQZmKzOHHsMBtWVRxUz6g3bVnndqCHiiUKunqVSH0AiEAxYlunmOEBgoP+uO0UxAQbvzSNtRNSOzrsFfrgk/Fg7Y="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.1.0_1518639571858_0.5559546572324516"},"_hasShrinkwrap":false},"0.1.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.1.1","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"luxon":"^0.4.0","strip-bom-stream":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"d7dab42c60c357c945a0eb165b5df00e9c6d60c7","_id":"gtfs-utils@0.1.1","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-nwGoqw2xxlrpnXUtM7gvbF81tsUJv5oW0gk+Rx9r+VOA/rsIH2O5lnm7ZDkzYEhKsn8djKw5gDLjn96xdAY2Cg==","shasum":"8757a902f7433623f7d1cdd8be0c367a90afb62d","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.1.1.tgz","fileCount":8,"unpackedSize":11219,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDGnP+3F+oQCI7hQbBftSpI5iPaSLs1ZY+/mTC0WSXfRAiB3eQkwAbpR7qv2ipLCFS0uEdx3ae1JDn0Ky4Gbu0UMug=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.1.1_1518651924778_0.5157127297780031"},"_hasShrinkwrap":false},"0.2.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.2.0","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.4.0","strip-bom-stream":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"45479841c9418b22470f6573c153fd4c5fbf32ab","_id":"gtfs-utils@0.2.0","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-oWJ7MGhPmKiwEi4e5whLat4gyvyJRp/b0+Vmf+TVzG4TvSn+ddote0McYmq8GTg9EtNRddg+L+5dFHER0oJ64g==","shasum":"fc46323870781650b8dcae9d1bc31e445f39c026","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.2.0.tgz","fileCount":8,"unpackedSize":11423,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDLGW0td7FkJIRBKG7RQ6gwAKsXOiGLeqdejT4ofvoQagIhAPrW1TKjKphchex2NqZZmrs0XOq9eG3EDWnBglr4OU0s"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.2.0_1518651993789_0.4984558148073499"},"_hasShrinkwrap":false},"0.2.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.2.1","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.4.0","strip-bom-stream":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"7789d860b6dc5043cf5ea6fcddce1369735a2b2c","_id":"gtfs-utils@0.2.1","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-YM0cNb3X0Kht979sITCvcAcr0P1A95msL1y/xjnp+N4M54xdK+5iLdZz233qmxneQXLuNU1ck3wyIFLSieH2Eg==","shasum":"1e137dceacd473cc5cf9ad8450816797c52a676a","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.2.1.tgz","fileCount":8,"unpackedSize":11425,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD7OhnNkRJDpwF85Vw7RuENwKIuYTyn8KD38V3vl7h5XAIgWDp2lDSwaw1kFH5+gljhdyqnPzLNvdMlgGKkNfS/fiE="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.2.1_1518652078520_0.07018958619531968"},"_hasShrinkwrap":false},"0.2.2":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.2.2","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.4.0","strip-bom-stream":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"a634d45cbf090c14c421e2f0c161fd2605f3d11d","_id":"gtfs-utils@0.2.2","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-snHblV+V1Qbdk2Qzru/4Qdyko+uJ6iWmymKVGyiSmBc0s/fnhWBO39sqFLJJFGh4feqeGRmu1z7qhvJvmqM7LA==","shasum":"649c145ab4aae0473de8b8321b60d82dc5fa62bf","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.2.2.tgz","fileCount":8,"unpackedSize":11478,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAwrNxFcZe/29iOsJrhNp2OzGQ0ngwlOpMcFxTyJElELAiAFtOcjw/DikxjlNdYOPJ9k355d51KBw9IsmaF2rejT/w=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.2.2_1518653502624_0.07395272756718985"},"_hasShrinkwrap":false},"0.2.3":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.2.3","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.4.0","strip-bom-stream":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"979773526719d29934b14c82a5c495c8d9433460","_id":"gtfs-utils@0.2.3","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-29egoBuHAbEM3omkguJcYa85b2U5NyYpFkUkIwXMb4jTHwlGa6ZoTSGwkniHImTWeTbQbihj46ja+S/e6UnCUQ==","shasum":"d33c56ac1daa4ab57124ca4f8da611b698fc682c","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.2.3.tgz","fileCount":8,"unpackedSize":11537,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDw7r7pDT8PGFsdocAoVSh6P/d07gXOX4i5iAGY3dofXAiEA8h2ml0fd0AMfFhMOsTJoeSMNieIybp+InmeK8Xy+5FY="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.2.3_1518655656625_0.6927347294182242"},"_hasShrinkwrap":false},"0.2.4-alpha.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.2.4-alpha.1","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.4.0","pump":"^3.0.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.csv')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) on [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `computeStopoverTimes(data, filters, timezone)`\n\n```js\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\nconst readCsv = require('gtfs-utils/read-csv')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes({\n\tservices: readCsv('path/to/calendar.csv'),\n\tserviceExceptions: readCsv('path/to/calendar_dates.csv'),\n\ttrips: readCsv('path/to/trips.csv'),\n\tstopovers: readCsv('path/to/stop_times.csv')\n}, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) on [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `data` must be an object, with four fields `services`, `serviceExceptions`, `trips`, `stopovers`, each with the respective readable stream.\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"058d51e6275fbc2f70a5bbdae0a8e3c6ed54a31c","_id":"gtfs-utils@0.2.4-alpha.1","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-AoplE+PRC00D00eFnPT3EMaLurlaE2GuJ+qWZ5kMB0q0IwlGvbaDUphzgDWQ0hIw4sj8JBuEj3ZawEwQWGg/ug==","shasum":"e57f0d9956a28a8d0795aba59e4470f091f77b11","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.2.4-alpha.1.tgz","fileCount":8,"unpackedSize":11798,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZCeU6UzIhRC7kTBaCK8xFzTvADJyKxDV0YWi1vToauAIhANo2sfhFUS71wxAS3CMV148Q1nmipjNGlQO/5rJLZeaB"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.2.4-alpha.1_1518829182668_0.9687173753087661"},"_hasShrinkwrap":false},"0.2.4":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.2.4","files":["parse-date.js","parse-time.js","read-csv.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.4.0","pump":"^3.0.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"740be6c3ab8c4851746e219750d3a944b1e7a0f8","_id":"gtfs-utils@0.2.4","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-WueFBMjdmFj+yzXPk+rghs6Xyc+5V0UDFCDh7xp4NTqaacvrVzvM9TTU4Gav17bLq5PMhRHDFAkxcJOLuMPKFQ==","shasum":"a9e139eb7984ebd6650c6459118e798182670143","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.2.4.tgz","fileCount":8,"unpackedSize":11815,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDa4CChqcBFjOAEBf3VUzwW3+TgOQjAlsbl2v4OTXNaawIhAMj1eFLGlZR4iki7pO9pG1FlbdhO+UYFjYCNHId0uQQu"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.2.4_1518871779051_0.3972098365890784"},"_hasShrinkwrap":false},"0.3.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.3.0","files":["parse-date.js","parse-time.js","read-csv.js","read-services-and-exceptions.js","compute-stopover-times.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"25056a1a1680de223b047559bbc8be8717d34412","_id":"gtfs-utils@0.3.0","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-NYR8spx3hwc35rm4Sf28nw/R5qu9X6mA39EOn+dvYClgjE/B5xNIWFdlvjEIQVICalnjBHkT3qO3chzKa11tPQ==","shasum":"e62044a27101f3c9c6d836df1e5c277bb50da6e0","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.3.0.tgz","fileCount":9,"unpackedSize":15175,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB9FLHDrKpFromwfrgUEfKLItnEpmMOgGUBYHZNpLNkPAiEA1772o66lbK/r2MLMuADzfRrtTnnffUPr2AZVW68Dtbg="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.3.0_1518972365873_0.33936092201826207"},"_hasShrinkwrap":false},"0.3.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.3.1","files":["parse-date.js","parse-time.js","read-csv.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"391a827673647f7ed89a9a97db51e0997dfbb5f6","_id":"gtfs-utils@0.3.1","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-JNIxSWunJkotD6mRYoo3lD1N5+TgEF7wnLuykY7Wb+SsiHot1zVjz6MDI4zIP61dPLT08m8+mCc0F8RVy4GR9Q==","shasum":"613a83e929f315aaf65b87c6452d048ca60a04a6","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.3.1.tgz","fileCount":10,"unpackedSize":19054,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIELuvXnHqiGf6o6TkheCyQFVSoZIpCmjjIrg4V4v9SNWAiBoBVCeg29yBiMkH++fICgOP44Bol0qP7cUcjXUNE4mhg=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.3.1_1518973082145_0.4758187456381955"},"_hasShrinkwrap":false},"0.4.0-alpha.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.1","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tsignature: '248tGP',\n\ttrips: [\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"ec6e3131f91f7475dc7c7c797a7c5520eb62ce75","_id":"gtfs-utils@0.4.0-alpha.1","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-MU6XKpq6Cr6DsbAHU3qZ4VUTBfJnBk67wWzzYAp+u4gECJGNfy7zsLG1s0YvvKXHVDMiU8A7KdwOrZowxZe2rQ==","shasum":"2e6491bc034f7fe869fda80a8c4b1d486389576a","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.1.tgz","fileCount":11,"unpackedSize":19660,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICDDnReX7zKG+ZrPsGhf5UdTu1g1zeXfukJZqoQeokzyAiEA9xAg41egeUhDQ0nuRxy6DVCqLrRFYbDunhvFNIclhlA="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.1_1518992548735_0.24283395522512308"},"_hasShrinkwrap":false},"0.4.0-alpha.2":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.2","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tsignature: '248tGP',\n\ttrips: {\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t'a-downtown-all-day': 55380\n\t},\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"f85a92bc32f44150239d55df25703a7b9be28b1b","_id":"gtfs-utils@0.4.0-alpha.2","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-IXAs9BzCXNmId0+hY8GVrNj8iae8glSeMrzLooKtKiMXZUpUr61RWKYq33u7c9oYjWRWqPiryaM669Lkqb04GA==","shasum":"dbbfaf1b893c2c39e30cafcb345e0494d90bb0c8","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.2.tgz","fileCount":11,"unpackedSize":19630,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCHb+ean6NlR4mIuwjVv7hFuMuLrAFEQfJA52XXzk+3RQIgGic323m9jo0IKEK+UMlu/kJF+wE2BdFpkH3+/4urMHM="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.2_1518994317067_0.2164880056819436"},"_hasShrinkwrap":false},"0.4.0-alpha.3":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.3","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tsignature: '248tGP',\n\ttrips: [\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"919952d5c3a470f6312edcf73b7cbdc5e98df33b","_id":"gtfs-utils@0.4.0-alpha.3","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-NxDi+lOBJngHAIHUXMvwOVwf3yTS58fzAupv0iTj9dIiHS4M/NU+PkAIMSflGl2+odlr4WqBIWGovooJUfUf5A==","shasum":"c7466c16e91137a4e2922aff30b2aef0d205b913","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.3.tgz","fileCount":11,"unpackedSize":19660,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA6iCsnNhnmkmfS6yhEEZtX5jyTwx48SZP5UtylTlOqsAiBJhIG8+fGHHrwPcqsuP4dcK8NyDxrSjWyBQHYYoJfO4g=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.3_1518996389820_0.04174243434131908"},"_hasShrinkwrap":false},"0.4.0-alpha.4":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.4","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tid: '248tGP', // signature\n\ttrips: [\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"d0447338d68720114530ffe05f718c5c98d1f501","_id":"gtfs-utils@0.4.0-alpha.4","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-9YxTiQ901ZNOXAsQKpXKECG0YF0jKnqSpahLUdhCYRpquySA/95/wHQj74D3enINsNTCoOB99ToF+6fe846Exg==","shasum":"b30c52e1404d28368ebab8df11b15bf274f17e66","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.4.tgz","fileCount":11,"unpackedSize":19652,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFwfI2txU8cKAvzCRegwQ4ieeM7obJU1w7FE73WcKSSAIgSAj4eEIivie3REhbw+NesGks7bZY+Dl9Z2cdE2hk6VM="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.4_1519001573684_0.8741229215136375"},"_hasShrinkwrap":false},"0.4.0-alpha.5":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.5","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeConnections(readFile, timezone, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeConnections = require('gtfs-utils/compute-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = stopover => stopover.stop_id === 'some-stop-id'\n\ncomputeConnections(readFile, 'Europe/Berlin', filter)\n.then((connectionSets) => {\n\tfor (let connections of connectionSets) {\n\t\tfor (let connection of connections) {\n\t\t\tconsole.log(connection)\n\t\t}\n\t\tbreak\n\t}\n})\n.catch(console.error)\n```\n\n```js\n{\n\ttrip_Id: 'b-outbound-on-working-days',\n\tfrom_stop: 'center',\n\tto_stop: 'lake',\n\tdeparture: 65640,\n\tarrival: 66000\n}\n```\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).\n\n*Note*: In order to work, `computeConnections` will load (a reduced form of) `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tid: '248tGP', // signature\n\ttrips: [\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"cfc219ff9b0e05b2d1adbaa0505c0e74befa7a73","_id":"gtfs-utils@0.4.0-alpha.5","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-wJ2aUccXn3h/VmXsXG7qouVZsgHBYxHU0XeKVbsq7JR2sAmqlrdQg65FWzHwSSLS+lWUQ91EozF/nn/EqbcRLA==","shasum":"bad6bba94485e646eceee9de33074e8b92368351","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.5.tgz","fileCount":11,"unpackedSize":20675,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDPSD6/trjJ4krkKctT5T5ak8VQ/DbF7FJ+ZeK6ZLRCDQIhANy9suMyQbNQ3WYJX46T9xqF1Acdpy7TNQTIHVgEear5"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.5_1519036024354_0.1448797011079288"},"_hasShrinkwrap":false},"0.4.0-alpha.6":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.6","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","compute-connections.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeConnections(readFile, timezone, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeConnections = require('gtfs-utils/compute-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = stopover => stopover.stop_id === 'some-stop-id'\n\ncomputeConnections(readFile, 'Europe/Berlin', filter)\n.then((connectionSets) => {\n\tfor (let connections of connectionSets) {\n\t\tfor (let connection of connections) {\n\t\t\tconsole.log(connection)\n\t\t}\n\t\tbreak\n\t}\n})\n.catch(console.error)\n```\n\n```js\n{\n\ttrip_Id: 'b-outbound-on-working-days',\n\tfrom_stop: 'center',\n\tto_stop: 'lake',\n\tdeparture: 65640,\n\tarrival: 66000\n}\n```\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).\n\n*Note*: In order to work, `computeConnections` will load (a reduced form of) `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tid: '248tGP', // signature\n\ttrips: [\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"709745ddd5eaa57e24ca406e479b4856682f316c","_id":"gtfs-utils@0.4.0-alpha.6","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-5KeiOe+Trmot+XM48hLc0Kiyshy749Tqp/smCmWv24MgHasurT5Ncv8idSJT+gqx5BvHjC4jddPQbpTKvp71fg==","shasum":"20ed6f4a5f47a6b5c7479168af954923af9c9772","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.6.tgz","fileCount":12,"unpackedSize":23498,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHIKMBliuv6gQJN9j9ylYhn9ltL9gM4YP8uVGYEvHTsZAiBxOpqgO2Hr4jLUEyPc3XJ+VBiWttZyBu19ejIo0bc09Q=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.6_1519036379679_0.8072652097983044"},"_hasShrinkwrap":false},"0.4.0-alpha.7":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0-alpha.7","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","compute-connections.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-csv')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTrip = trips[Object.keys(trips)[0]]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeConnections(readFile, timezone, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeConnections = require('gtfs-utils/compute-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = stopover => stopover.stop_id === 'some-stop-id'\n\ncomputeConnections(readFile, 'Europe/Berlin', filter)\n.then((connectionSets) => {\n\tfor (let connections of connectionSets) {\n\t\tfor (let connection of connections) {\n\t\t\tconsole.log(connection)\n\t\t}\n\t\tbreak\n\t}\n})\n.catch(console.error)\n```\n\n```js\n{\n\ttrip_Id: 'b-outbound-on-working-days',\n\tfrom_stop: 'center',\n\tto_stop: 'lake',\n\tdeparture: 65640,\n\tarrival: 66000\n}\n```\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).\n\n*Note*: In order to work, `computeConnections` will load (a reduced form of) `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we called *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tid: '248tGP', // signature\n\ttrips: [\n\t\t// The trip `a downtown-all-day` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because a schedule will contain *every* trip with its \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someSchedule = schedules[Object.keys(schedules)[0]]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"820d4559bd995c788ce984e49627a05b626af15d","_id":"gtfs-utils@0.4.0-alpha.7","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-qy1UximlIPFejMEApUZx3FGAmNEfdKEjKEPSgjUunWnmYQ3B2tzzRvoPq6ZUx2Lk7y51+4H0nNLu+rN5TKvvHw==","shasum":"35173e6586d849458e50e79a2b33697252d537b6","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0-alpha.7.tgz","fileCount":12,"unpackedSize":23600,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBS57970JAxJqeOAxVPJusC5tCJ1qBl+ZorFgFIsBluZAiB2CpVAFwcuOyajiXeVcmSuMQeM7EBhJS7t8X9FEyytFg=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0-alpha.7_1519037235126_0.33575364088796333"},"_hasShrinkwrap":false},"0.4.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.0","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","compute-connections.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"80ad0c57ebec8b36752458dbcb8562371392fb3a","_id":"gtfs-utils@0.4.0","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-g5X7DZA9EraDnkSB7ZcvaDzcgFIqKPGh0UahorTEf7BFZC7DdxQUmrN274mj2ll3xjYZfqIzpVz9ObqhdVlvsA==","shasum":"4ce52935cee4b16870f22511c8bfbf827d6ae179","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.0.tgz","fileCount":12,"unpackedSize":23594,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAm6QulfqOv+LdZ6UZSkl1BWbEcyST0nOBeXP2YlxIefAiEAngW9sTzUxnylqBTFq4jC7y2bznznjR8QZ3YfFkxlu64="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.0_1519403340181_0.710162659373712"},"_hasShrinkwrap":false},"0.4.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.1","files":["parse-date.js","parse-time.js","read-csv.js","read-trips.js","read-services-and-exceptions.js","compute-stopover-times.js","compute-schedules.js","compute-connections.js","lib"],"keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^0.5.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"1475741f0cf50fdb75d5a400c8d2d9eb4b7c4cf5","_id":"gtfs-utils@0.4.1","_npmVersion":"5.6.0","_nodeVersion":"9.5.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-OLpXhqVzxKEGv2F+xhzmH1axXuGdolbrD02WlbSEPeC0rxoQ/D/Js+5Lk1+hD7AXmbAs4/lL9UgAO6pE8tu3qg==","shasum":"6998f8eee3f73a01dfe41d6fd0edb8f452ca5fb4","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.1.tgz","fileCount":12,"unpackedSize":23940,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF/H/Cnbh6M6WihuXRqdtpAEvP4YC1wQQgHK87Ks0MXxAiBLqRKUpVkRh2ffQbpe4xisN4/y0AnFBOCiDF+6eJBocA=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.1_1519483693010_0.47121966459464204"},"_hasShrinkwrap":false},"0.4.2":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.4.2","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"csv-parser":"^1.12.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"67951950512dfe3c3793c22fd753e8f45b72538f","_id":"gtfs-utils@0.4.2","_npmVersion":"6.2.0","_nodeVersion":"10.8.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-wFKXSKkVZJD7QEKq5Wu6JL6lDVTFi1NGIWKDCPSyAvNTlUUU56YkRQmKBmeUJh8Pjay5bLm5YBF7yFQcEQIKgA==","shasum":"642363133a4b6e9e52da35aa17fe69ae4718c978","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.4.2.tgz","fileCount":12,"unpackedSize":23960,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJblUmoCRA9TVsSAnZWagAA0XwQAJ+cGMSHhhu82jRUd7Kk\nRUrjdcLxQch6ItTewmNWoJBRVxhyC6SkQsHfGcmQGZrVX+ukw8GUrwvd3epm\nEFIjsFtYfLT7aLBiVmzGxjVnw1XF+69UecSeCHy06AxAjnRu38EgP9zCfLe3\n85wqX3TblJ7QMCMhFthweuXIMj3HvDTHwlWjj/KK7u3ackDHmQxRwYXfMsz/\nriSk81gn+P9VgidMCACYj3ezSv63MEsuYUFvajuuEHlRCdcilcXXmGoa1wKE\nHKKfQYVY0LHi+sVGr8oy+d5NsxbpFco1k4Vvswe4G6a66sR+C/XwVimyf8T8\n3RrxnivorqSBaVLbVooIV///B+He9wb9N/B8uk4++BJ9HmZflF7MeGsQeVKU\nbLXPo1DL1qOORii+QbWEEkBEcGJ1DFLmUwj/TVrClQiEAQT0SyFXNeU4I9h9\nG4PZqfZgqMiMD1tZotveZO+L0b+hTUugqT/kZ+gA2cJP3R7aijMfV1mJcAWs\nyCZmTd4fcwIZVOe1yXomiju+h3EdRdpR40dy0QfsXj4lv0jOtYhiicnJ2N2c\n706pkXdR2gZlo4tggbhDyg2ZXij1Bcsh6yAtoh3pEGkwbtxDmjToxICrzXPy\neggT09ibyjkO6WKxLcl1huefujMjBgDynF5ZNUDPxQrHl5kDQSfcmc54+H29\nZNvk\r\n=g0Uo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDI3yW0W7HtDN3t+fxgJ4BW/8XrGSEAJhMB9tYSTaWglAIhAP6hiIrT2DIO8XuxbCmcj1cpFiDY0TYQQ9ej8yWJg0ew"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.4.2_1536510375896_0.424545493188369"},"_hasShrinkwrap":false},"0.5.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.5.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^1.12.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"ec8808a012b53dbbbb3614a14e044e9039f3b42c","_id":"gtfs-utils@0.5.0","_npmVersion":"6.2.0","_nodeVersion":"10.8.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-C9A/pn17oBd64mZE+lx3NEYstnQLrC3mga53y+4Sl030Ke7fhnilZw4LTCZRh+5O9gcEHH8+qLlm3A2z2CgJNQ==","shasum":"1ab1f7a161341d322c4c694839c9ec5fa40d1e0d","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.5.0.tgz","fileCount":13,"unpackedSize":28995,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJblXaFCRA9TVsSAnZWagAAvO4P/2VY81yZs3ipUuIcOeX2\ngjdd8C29tqmYxKku46vXuiRUtzSUf/ZBWXYj980Ue4II3qYCHKTrTYE9ugey\nK7zsOQImRDwAXdk8CJHbES6ro/P7blDYnu7pzlSv8sMS3tr4BGKKX/IIGq0m\nouBl81gfC+4s90jSJ2R3JaOA9tj/ckmjehQf4fx01FV0mAIV+evZ7RSdMUE4\nztgShoYvKYFqoxoq7ChJAB+hKgmF5O0thCtGYtQJHauebGYbi/1t9LsmupxB\njJUt6WByb54ZLl7OcWuXtvaz90xeq3J93LaozxoF/a2yyQ8mOWrzvWsNuaoy\nhNpBwExdV/imvusooMlkNnsZENwPklRhhaJ3T+i/MjqPlzNsKqNi2Ql5jjtE\nKZAwQAafuF2X5qHTj8A+KNrnvXSDt6uobSJEzco/KCdluFRW5gPkc/ErOgsE\n2R6fiiiwturyoNmOKqNq+TAvsGwyrIfzLxpbkIa7iHJQA4sQ+YLWBdphsizF\naSnAttk5IUq+lBp8DKmST4p2D44jitgY/KuUeKEdL9viSxoqpdHosn8nXYw7\n4bnCWdbUn+xZ5YTSGq7tzVkFvEIFN44ygcX/tyZSVhnJy0L2a0zbDTPMEs23\nk4qS9AjYgVRmJ3ZATmovA2o1pMvK/Ja7dxMlbO6DspZMeIZEmlKemvAAZ/qx\nhGF9\r\n=IIXG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC17FprJn7s6V81V0lEInAMIKu/vCgrIpndYdSRFcu5pQIgOQm0YDgY5LXN/AkXGbs3elKLKnlLWoDk3PW2Bj7jw7I="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.5.0_1536521861263_0.45377028851596646"},"_hasShrinkwrap":false},"0.5.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.5.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^1.12.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"87c92887b2664577b0ab3f6d3e478930e8e8c811","_id":"gtfs-utils@0.5.1","_npmVersion":"6.4.1","_nodeVersion":"10.8.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-vO0T9Lub0zmu3e4SjBsuaaZQDpdWKahQJpwt/x/IOWcKtg8351YNejcVHVCSBI1TBWGl6C1bb+6qMlJ/k16d+Q==","shasum":"51bd8aa0c67020fdfb0c74f098baf82231f23991","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.5.1.tgz","fileCount":13,"unpackedSize":28991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbnPEYCRA9TVsSAnZWagAAno8P/iibNmZyiK4JkBV/Jpy+\nIFW3CY/zsg+PjEol/v8YmiM5/h0g04ZaDf24VKeQPsd9/XURjfXy1LvkkY5i\nuyxHc66OrzX9pN0oJ9LBiB5418rv6xt5ZGnDl3HeKdXL4s/VT9nN8LAgO7Up\nEGMM+lgH3MPSW7iiaQ8935gAChZb4nBEyM5q/JWszSZl8jZ0xC3NEA5YdPWF\nyIMNWaSGwrRT67sx+pfR+yMGr8fA9nk94tea029V69zmHkfPqsmLLPGX1gxA\nb5FRcE9/S/17nEIsfg+44t2eXcagCwuXw19gO9AiMkTkfwPXuKC6bERsDaiu\nWVt/qAF+26zQBvRXBQTNgPDaikiue6AnTkPbgXHbCaWr+72JIw/hnyhpNeAa\nJ1KsFUs7nkHs7V6rFo/M0Vn2bekTIMCX49VBalNX2irxQTXjlJiWdf3gJ05H\n88xwWiBY8BLKo8whOG+5Ik4ynGRNAOqhQQasYJ7CKvlgF4Ndm5xoBsmArDzr\nGwBXGkibUyldqQT3Aq1K7BTAOcmDeA1nTbLNJsJ5539HRLieReqsV4d+WUek\nY88sjZhTetXC3iYJfPU1ZWNpepcN9tu8LUCc6nTKQBZdqdQEuSupApXUdsw6\nfA9swHwuwZVm87MsvPNfEIKmvNdoaSx8taw4xjlpOcP7rwekaXsLyk6Rk4kV\n4T3X\r\n=J6Y5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFuWEgDNfo3qTs1Ubw0wkloyu4Z1+hu99Mh+Ql1pNT14AiAn4OoR9ekxaDrMHoKVa6a2+7XRr4WR3Z/8YfWNRuI6UQ=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.5.1_1537011991840_0.49095210867042405"},"_hasShrinkwrap":false},"0.6.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.6.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^1.12.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"^0.2.3","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"1bd0a62739d1c0fc9d6335e5756c1189536bdfc0","_id":"gtfs-utils@0.6.0","_npmVersion":"6.4.1","_nodeVersion":"10.8.0","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-nBZt4Bue40STjN9n/RdV7zo5tS4wtM6tj2dFzGQsGGmb16zB38OwYlbvJlGMyMgBPlUJmg1k2ET6YZfgteMBjA==","shasum":"854ceea388bcbb801e460c6266e2c24a5417c57e","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.6.0.tgz","fileCount":14,"unpackedSize":29608,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbn2ipCRA9TVsSAnZWagAAODoP/27Q3fOvRBRp4DA8Yrvk\nL/usekpaES8oHpQCPfJGTcssOzXVCMV7g+JwFQ7REChQ6oLyMr1SEMiNTBS3\noDujFYFjZfnuX/EU6Vjrv977ZJpQtzeoyZHDlM4yopxkZBqRJ+JjDeW9qqPR\nr7ZGlI2sx5/NCSkyEy+19EZcwY2PQ8yFd03SbY5oeML7+c03nc/SfzI33Idb\ngAkQLhzObFSJhkcLotUxGWYEc/il2W4zHt6GTnZLMNrDEjMbV3QDonz5Th3P\n1b+P6sV33gkiDctU13dz60I2GTDnkAbIIsVQErmGpbmd4MqxW8W0wkvNPubg\njBesZlVaD5w4hsINX56n4KRNbw9hfk4YkCr06x2IGGlLadqbpyaZ8rr54SRA\neYsJ4Y7AZVjeGcaqyD33layq14eEsWQ/fvwQzTwYMNBw3B0W4zvTKZgRvcRn\n7UHM+gqlD9Fd7IbsT8+67ayRPN9Y0MyPT8AR0erJzkoCyU23YbucBYj1kuvV\nEburZ2V3ldXqxA6pRazu5ivwL/eJlmadCZZWdSMykmu/HiEXDJhMtsSLXUaR\ne0sNZkYj6ueEqIUWqZHK3AAPBGOY9uqE3q8vIU/mE4JA6/EI521qlDdlsK4Q\nh2tSEr7XyHl8mAvELN8azaNKNQAEMPyIehaskiBkW7DOJsTc5ZRvn9irD3sm\nVkmu\r\n=DixD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDe77q5PQg+aqyVJtHCZcm2MvWTstBJ76doFoqQWHhZ/wIhAIdSxaa+Ci7OnKrQ6CMy0xXj0W2qaL2Qh3WTXEilQqY1"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.6.0_1537173672627_0.7850754722732682"},"_hasShrinkwrap":false},"0.6.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"0.6.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^1.12.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","strip-bom-stream":"^3.0.0","through2":"^2.0.3"},"devDependencies":{"sample-gtfs-feed":"~0.3.1","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"e8cd2c9f6a0cf6191210e9ab2bd0721909b5827e","_id":"gtfs-utils@0.6.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.2","_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"dist":{"integrity":"sha512-y75c+r/SfRSAf0KuFNECccHnVmmiVsrmJwszV7Wwklh7H7szPhfnxHeGcpupnKFa09GT0AnHilDHfgXGQkkjKA==","shasum":"59306e46e5bf7747474e2e1f15e55f84f8b2b646","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-0.6.1.tgz","fileCount":14,"unpackedSize":32560,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcqf0MCRA9TVsSAnZWagAA57kP/0ODXVHj/z77la/LHcAw\ndAt4yukMLcHk1/2tg8VhUy/knP+y07+AIU61GhtC0RM071e+A81g4VSudPj0\n/HejNqbiKpSru2XfKZDzTiuZUQGK+4zj5xEPnyoIHF5pEzNP+gFObwAyVJV0\neGq2RG9qIcBxLcMudNewjXfA9k9xBXVD3KUtf3kmV1c2wqjeo6QKFXcwToDD\nl8GficKi9nyL43OSpYBy/y/JiLczqh7dvUavron3qrT4iC853geg8HKe2e5b\n4JC3y2pReq8JAzZLMnsbJd1I9uY6OFT5g+6IM2NLqS0yVxRp/qFn9vWR4H1N\nWdMOYu+4J3K1zLddpvEq6XcCFY9zCk+A4xkEWWPaZe00NKpZdIpPMtg21u7x\n+fUjnB7pj9HerdHPjkM1pcli6flXZLAO15Xb3yczEq5OqoVbhoxblCDKuDdE\nyEMN5lHZ8psWHd4G6NSHIvQuFtejtIG6p2h2kvq9fWLkR/cCLjcx+ex5MP7O\nuBfS2cZzskyzzh61xDA/HVGafaGCEvI8CklfDi6HLnZSuwBFMS68E5+tqFpV\naXiG0CHDKgoile1cTzw95MVH6g7Smoxe7jX0e9cMYfnWoaVtsEk7P5c85QuI\nGIKll+hOeqSVPK5+ranO+ZH5fgYzN19u7NFyliqZ58vtNcTfKV0Rw0KwMsNJ\nRPi4\r\n=ob2Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA+bxECOMirDvl0Re5rjl0KL8Q8Em4hOOJF8QkDFCEJSAiEAp1fakktyrCd29j9reri3QyfMYTzaBc3WGKXnYo7IoPI="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_0.6.1_1554644235007_0.17093328647617656"},"_hasShrinkwrap":false},"1.0.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"1.0.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^2.0.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^3.0.0","through2":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"~0.3.1","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"0e05618a4759af4041ee55ca22ae8661795d66f0","_id":"gtfs-utils@1.0.0","_nodeVersion":"12.4.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-BMIESJiMAj9oxbrWt0EE0e9iOA49VcFfeo8sVoWG9Y4F/aiVqTRhOA15ZoyAAgqdTbTPl0UPgUaBIICdS0fM5Q==","shasum":"f6befd4bfbd802682bfee20f9917f47d31ed7fdf","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-1.0.0.tgz","fileCount":15,"unpackedSize":36401,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdK2CuCRA9TVsSAnZWagAAXUAP/izEvWpjlW2uklmrSqle\nmzOrHCx2wBTWKa+2rOC8HFGDuRuJJp48RKw6HCrIg+MR/gEWR7sYId6xLjRy\nLCdeoWKp7LYcs7xlCx8VMjpiuiuvw8Pz/BkKpUoQmRjn/jB+RXs55PawRw93\n6eHDDvcoCIkaNf0/1rEHBOk93H/i8gMQl2zl2FZdP0zATTAoIt9ppP0ctA5N\nfBZ0luoeP6lak/Dx6cBkONLnkKG22vK30IStU3PDNFtMNsQBghYO1Lpn37+q\nKbBcBoamIVE00hrkn60wIVpbJz5RswHSR1Tcg6SkTZvPABjEUeTFY8l16FgU\n4QkZGZfbFzd2n3YZt1LRiAdLJNLpaZ2G68EQIH5OIh06haCXRvLfaC/8ACwj\ndYJaujkYhqmKBk5LgqtxticX+jlCUkj+k/Inh3PTQTxnX+wT200J/shtF0rs\ngW6H+JAcWLRwTMg/qZBtdnHJ1FhTYMux1tBF5t5iSaCuZvKidyuowe7hTRKB\nakAp2N34jBWFBLu88SjGjSVvdXVcgYMLW5fOpNl6TiVQrXWkEcqtoxl74K4I\ncutLgLhCXVPmbM1XDFxX/4KvrVoRIq0KW9cHv+mGM0WcR4wljIeqr2AxJrlF\noKyP4n4RUOy3rQzdRHAoHmQ1mFUhGO0I7INBJCMgxWxwpHIETi6TgmthsatB\nas/X\r\n=gHG4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWWc0VaiYLHMgXOpTnzcu5YcekWM3Ej2SVecmn/ZtAlQIhALOwL8uS6fgxvi14wTsg71d9c6dZLNsce1r5O2v4em3c"}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_1.0.0_1563123885074_0.18618583145783663"},"_hasShrinkwrap":false},"1.0.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"1.0.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils/tree/1","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^2.0.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^3.0.0","through2":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"~0.3.1","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"gitHead":"835ccdd23694aa147ef9775cc52f2233147b2bf4","_id":"gtfs-utils@1.0.1","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-wLF3NoekJvf3ZZGfpEt2UjE6o9R5JQHHfsGQvA0nEw3MZO0o6xCG1Zrq9+/+PlEhiqJBVvjGk23E+wf00ucWZg==","shasum":"c948a57083d5b021569129ab8b0bee7738c969a1","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-1.0.1.tgz","fileCount":23,"unpackedSize":42957,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemyCeCRA9TVsSAnZWagAAYrAP+wfsQ66ogg4yszpLHJth\ns/QN+k51AhjIFa5VS5P6lpwZDbFfxHCz4KNZYeNk6oQEtJuJCxFcxt2rvaeC\ngPJgn3KHvDoa61HHtMIPprAIvytDJeaTZ097TMfwCLsUYCrT4fhSIPzcUeBG\n9lQBv2Yz2j154ERgu43peCJTf/lkAGKvv8LQfUUXLcNUc2lzfIT5wA4/Uhx1\n+1bSE2G6PCLt9E7TIHMxN3kPD7HaOQ8HXDo6xoy6mPELoli7iJayGPYKqp+E\nK8AfMTyY0WJWuLgAlm/U4nvOKAfL4hLKJ7hAKgq/TCADak2p0iAJfLbM2L95\nYuCHLrNvJYBmzbiEckOlpuzNmdagjTSelvJ7M0be4BbsmtlJbMvRr52+WCDz\nzZPyFzsDPJ9pCAjwm6E5IzDsxOALVR/nDlQUOIaEgxDwtnDlWq25nTotZMzQ\nElYnV9sW09g17OLtWy46HlwvRtVqn+6LeUqShcRtYyk5KYJ0hXUVzLbBZSLq\nUz11CdIDnYqtADYrZZKwsl+5VdQozRpWv9oVFx4wRLHB+lcnGgop2bD2vJi4\nUV0zHi9sE5d+Dg5bWVTlNsQRSa8/oMzWNzbK3EnUZPNHwTbR0eC4hr3ltkrL\nNy4Uxmj8f2WhXS0GpeldgeL7P01eVXpUX2zNv4051GvSAZpRckAwsQQ+uWT9\nCZpA\r\n=vAsU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDM6TOH90W5viGoddVB4qFyWGJDzpkgxDiKMohL5Aya/gIgaBvesv4MNU3wWqZB070KgbtWZmiF908svc/HN1CWUXs="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_1.0.1_1587224734289_0.9329024619055621"},"_hasShrinkwrap":false},"2.0.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"2.0.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=10"},"dependencies":{"csv-parser":"^2.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^1.0.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0","through2":"^3.0.0"},"devDependencies":{"benchmark":"^2.1.4","sample-gtfs-feed":"^0.3.2","tap-min":"^2.0.0","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test"},"gitHead":"75652b27a1041cac99abcba823960061a246b7e0","_id":"gtfs-utils@2.0.0","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-jfj5rupy5RWBuS8V9pCH2Dgo3qljVaZbEvE8wWH2ZR8y4zw5RarIS5lEiPRwdRwguk3/G/yIANK2ajQLneRebA==","shasum":"ea56d818371809ae96a8b2653c13f6b7b7fe214c","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-2.0.0.tgz","fileCount":26,"unpackedSize":54046,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJem5GECRA9TVsSAnZWagAA4AYQAKFiQLdUgrMN6mZ12AEa\n5XljdTDZ+pYTZs88cKc5ZpGm55ky26AYOTVYsrSwYVsTq/SUEXNgBXjLRLMy\ni7a7kKWbnKdgTYMxUUS0IiZ6tmTKW3cr54VHVlyrtHmWr1B+WgkWoitMZru+\nV0KNNTaSHFNt+FJXXBhllOT4GCN/EjnK4slViBJHo5pSy+1k1jZ8/La+8P21\n+GNGoPo8XiiGQ71V/liKH+sc3KKy2V20ngMsvS/nZ8v/U3UjYfz9duvUTMc9\nxDyDXO8q/JnERdtDT8rUdNoAEzpl/H1fXGT6aiJDhzcHx6UIcPPAqdpI89L6\nurqK7uD3MTHav09ItZtkllBFGdC6g9MaN2tgCAtR4YK9Ws92JowqrN+O2G7X\nSMREz6kqtJfkDXoAtUB8m/2Zhb6KXVUMs8j6kr/qb83Q0H9q8N22fgRDGwr6\nPOb8PrgwRItvsOF4MA4HjOt1JHArzj/faB0vdLvpWi+tlHzkFpr0izc5BN15\nnOnUtfGkSlUj54YRQvZ4JoB1DUqzDVYXixm4dQGTRS6aZWXJ9S2L44n9KgiZ\nXh6cPaTDZFa3NDuxAeps9cnpqdxwh8tJJqJodwQisfU6jd0tnR2Ki97m6wDV\nh+lhXTh4irv+jfx3lczT/dov76sC+1AqSD6OI9eTWynJETSCXKT8RH0Qhzim\nss76\r\n=TjQV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCMXyGxgt8wJSj/UGFoipkK6E4hHDnfeFMKGxfCFdlXdwIgS8yTrfuk3PKa8Txl7XRZj9soTXfDBShYVw1scWDX3+0="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_2.0.0_1587253635435_0.709371112497228"},"_hasShrinkwrap":false},"2.0.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"2.0.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=10"},"dependencies":{"csv-parser":"^2.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^1.0.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","sample-gtfs-feed":"^0.4.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test"},"gitHead":"abb2a7b9d5a8a2445cc9a907e505bddd09d5c684","_id":"gtfs-utils@2.0.1","_nodeVersion":"14.2.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-n/G+9AY517XfnQh6c4LoqAIB3q9qiMeZz6kOpG9UzgmBpapa6dVDX0inGXIV5fBjiU8nRLSBI6SrAD1gzfdmgQ==","shasum":"4c63aa052597373f60dec75f02a240766fe31316","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-2.0.1.tgz","fileCount":26,"unpackedSize":54529,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2BzBCRA9TVsSAnZWagAAfZsP/3+CBaWO48lAN/LqFeyr\nxtHZq5JCXXb/JNIHRAbzEF94+4189APL8uNeT9+rfB3pA1SyNshXA35xI7Wj\n5otjmuwdYB2C/LjNsxvcF+9pu//pukSljesJpBrPwSDVxnn5gnPh6mcmjiIt\nype7DkOKrhByb/QlGbC/jjf2htJYKNESaRDgsWJhO9iVIfQf3jb+IXiC1uPW\nUhwuOosZsKAzXjPJmJooWlWS/zSUL8FNhD+3TtyejJ8wZb+Q3MUWXJoXZmg3\nN/zgeFuALj3HvA91+gw3Zqvdda639pI43gW0LaNvdtRV3opBmQWFrCTNM7G+\niJOq9zV5OatUNjl0PzMDr5WUBOqqZjlyEYRjQrlV5aj/2kSJFSA/6GJL/Iu+\n5t7mowH8fh7kSz1gXkZsF/NA9POkQpi6tN0kWbnKoaEPaFbRtDsxrsMsXSGr\nT3k6KzutO/cYx8eYso412GNw87axLafN78eB5RMaBEPY1MKTu9E7NAtvEmb3\nc8VRTU28KbJjziSJvD9N9NrmG7VULXk7ch/cvFfj1o+xo48uxFQSabNScFAe\nkuQTtaBMttdfM3YAR4tx0T1pi+UiyHM3qZBmGIXv5hO4LfOlkNfwFRYXPldH\ndHcKUMRJURMDfu+kPcx5oAHT/Y/mS3AKmQUb1U0uJuFZSlo/o+KNbsiIFXkI\nfuoD\r\n=y73s\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGZnv4yYi+yzu2K7QVDDV+DKgTO63a7GzaDgFdtW0RMdAiEA59IOSaSBQ7VMFxpRPUGnf14NuXVgyTDJEkVQZzNISfo="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_2.0.1_1591221440131_0.378841857102614"},"_hasShrinkwrap":false},"1.0.2":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"1.0.2","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils/tree/1","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=6"},"dependencies":{"avl":"^1.4.3","csv-parser":"^2.0.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^0.1.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^3.0.0","through2":"^3.0.0"},"devDependencies":{"sample-gtfs-feed":"~0.3.1","tap-min":"^1.2.2","tape":"^4.8.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","prepublishOnly":"npm test"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n- [`readCsv(path)`](#readcsvpath)\n- [`readTrips(readFile, filter)`](#readtripsreadfile-filter)\n- [`parseDate(dateStr, timezone)`](#parsedatedatestr-timezone)\n- [`formatDate(t, timezone)`](#formatdatet-timezone)\n- [`parseTime(timeStr)`](#parsetimetimestr)\n- [`readServicesAndExceptions(readFile, timezone, filters)`](#readservicesandexceptionsreadfile-timezone-filters)\n- [`computeStopoverTimes(readFile, filters, timezone)`](#computestopovertimesreadfile-filters-timezone)\n- [`computeConnections(readFile, timezone, filter)`](#computeconnectionsreadfile-timezone-filter)\n- [`computeSchedules(readFile, filters, [computeSignature])`](#computeschedulesreadfile-filters-computesignature)\n- [`computeSortedConnections(readFile, filters, timezone)`](#computesortedconnectionsreadfile-filters-timezone)\n- [`findAlternativeTrips(trips, services, schedules) => (fromId, tDep, toId, tArr)`](#findalternativetripstrips-services-schedules--fromid-tdep-toid-tarr)\n- [`computeServiceBreaks(sortedConnections)`](#computeservicebreakssortedconnections)\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-trips')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTripId = Object.keys(trips)[0]\n\tconst someTrip = trips[someTripId]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `formatDate(t, timezone)`\n\n```js\nconst formatDate = require('gtfs-utils/format-date')\n\nformatDate(1551567600, 'Europe/Berlin')\n// '20190303'\n```\n\n- `t` must be a [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeConnections(readFile, timezone, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeConnections = require('gtfs-utils/compute-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = stopover => stopover.stop_id === 'some-stop-id'\n\ncomputeConnections(readFile, 'Europe/Berlin', filter)\n.then((connectionsByTrip) => {\n\tfor (let connectionsOfTrip of connectionsByTrip) {\n\t\tfor (let connection of connectionsOfTrip) {\n\t\t\tconsole.log(connection)\n\t\t}\n\t\tbreak\n\t}\n})\n.catch(console.error)\n```\n\n```js\n{\n\ttrip_id: 'b-outbound-on-working-days',\n\tfrom_stop: 'center',\n\tto_stop: 'lake',\n\tdeparture: 65640,\n\tarrival: 66000\n}\n```\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).\n\n*Note*: In order to work, `computeConnections` will load (a reduced form of) `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we call *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tid: '248tGP', // signature\n\ttrips: [\n\t\t// The trip `a downtown-all-day-1` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day-1', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because one schedule summarizes many trips with a certain \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someScheduleId = Object.keys(schedules)[0]\n\tconst someSchedule = schedules[someScheduleId]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSortedConnections(readFile, filters, timezone)`\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an [`avl` tree](https://www.npmjs.com/package/avl#api) of connections.\n\n*Note*: `computeSortedConnections` will load (reduced forms of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSortedConnections = require('gtfs-utils/compute-sorted-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\ncomputeSortedConnections(readFile, {}, 'Europe/Berlin')\n.then((sortedConnections) => {\n\tconst from = 1552324800 // UNIX timestamp\n\tconst to = 1552393800 // UNIX timestamp\n\tsortedConnections.range(from, to, node => {\n\t\tconsole.log(node.data)\n\t\treturn false // continue walking the build\n\t})\n})\n.catch(console.error)\n```\n\n```js\n{\n\tfromStop: 'lake',\n\tdeparture: 1552324920,\n\ttoStop: 'airport',\n\tarrival: 1552325400,\n\trouteId: 'B',\n\tserviceId: 'on-working-days'\n}\n{\n\tfromStop: 'airport',\n\tdeparture: 1552392840,\n\ttoStop: 'lake',\n\tarrival: 1552393200,\n\trouteId: 'B',\n\tserviceId: 'on-working-days'\n}\n```\n\n### `findAlternativeTrips(trips, services, schedules) => (fromId, tDep, toId, tArr)`\n\n```\n           fromId  --time window-->  toId\ndeparture at tDep                    arrival at tArr\n```\n\nFor a time window `(tDep, tArr)` to get from stop `fromId` to stop `toId`, `findAlternativeTrips` will return a list of all trips that run from `fromId` to `toId` equally fast or faster.\n\n`trips` must be in the format returned by `readTrips`, `services` in the format of `readServicesAndExceptions`, and `schedules` in the format of `computeSchedules`.\n\n*Note*: The purpose of this function is to identify *functionally alternative* trips to a given trip; It *is not* a replacement for a proper routing engine. (There might be a faster way from `fromId` to `toId` via transfer, and `findAlternativeTrips` won't return it.)\n\nAs an example, we're gonna use [`sample-gtfs-feed`](https://npmjs.com/package/sample-gtfs-feed):\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-trips')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\nconst createFindAlternativeTrips = require('gtfs-utils/find-alternative-trips')\n\nconst readFile = (file) => {\n\treturn readCsv(require.resolve('sample-gtfs-feed/gtfs/' + file + '.txt'))\n}\n\nconst timezone = 'Europe/Berlin'\nconst noFilter = () => true\nconst noFilters = {}\n\n// prerequisites\nPromise.all([\n\treadTrips(readFile, noFilter),\n\treadServices(readFile, timezone, noFilters),\n\tcomputeSchedules(readFile, noFilters)\n])\n.then(([trips, services, schedules]) => {\n\tconst findAltTrips = createFindAlternativeTrips(trips, services, schedules)\n\n\t// travel times of a downtown trip of the A line\n\tconst fromId = 'airport'\n\tconst tDep = new Date('2019-03-05T15:24:00+01:00') / 1000\n\tconst toId = 'center'\n\tconst tArr = new Date('2019-03-05T15:35:00+01:00') / 1000\n\n\t// find an alternative trip of the C line\n\tconsole.log(findAltTrips(fromId, tDep, toId, tArr))\n})\n.catch(console.error)\n```\n\n```js\n[ { // This is the trip we were using as query.\n\ttripId: 'a-downtown-all-day',\n\trouteId: 'A',\n\tserviceId: 'all-day',\n\tdeparture: 1551795840, // 2019-03-05T15:24:00+01:00\n\tarrival: 1551796500 // 2019-03-05T15:35:00+01:00\n}, { // This is an alternative trip.\n\ttripId: 'c-downtown-all-day',\n\trouteId: 'C',\n\tserviceId: 'all-day',\n\tdeparture: 1551796080, // 2019-03-05T15:28:00+01:00\n\tarrival: 1551796380 // 2019-03-05T15:33:00+01:00\n} ]\n```\n\n### `computeServiceBreaks(sortedConnections)`\n\nMost public transport networks don't run 24/7, but instead have regular scheduled \"service breaks\", e.g. at night or on Sundays.\n\nGiven [sorted connections](computesortedconnectionsreadfile-filters-timezone), `computeServiceBreaks` finds periods of time without service between two stations.\n\nIt depends on the specific network what period of time can be considered a \"break\": In a large city, it could be no bus/train running from 2am to 3am; In a small town there might only be bus/train every hour, with a break of 8 hours at night. This is why `computeServiceBreaks` optionally takes a second parameter `minLength` in seconds.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSortedConnections = require('gtfs-utils/compute-sorted-connections')\nconst computeServiceBreaks = require('gtfs-utils/compute-service-breaks')\n\nconst serviceBreakMinLength = 30 * 60 // 30 minutes\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\ncomputeSortedConnections(readFile, {}, 'Europe/Berlin')\n.then((connections) => {\n\tconst {findBetween} = computeServiceBreaks(connections, serviceBreakMinLength)\n\tconst start = '2019-05-08T12:00:00Z'\n\tconst end = '2019-05-10T15:00:00Z'\n\tconsole.log(findBetween('airport', 'center', start, end))\n})\n.catch(console.error)\n```\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"bf37283875accbf2d204e5cf677f1ea99b78f1fb","_id":"gtfs-utils@1.0.2","_nodeVersion":"14.2.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-0vCbu1sTpCdLhNPxqvPTBn+mLrEFPWbFUftXW1WmhRgfn+QclBtJUW/ImuksiB87jbejKyN8JnapzZ8LJ1gdaQ==","shasum":"3a19cf744af01c2541a2a397a8cab1a53482951b","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-1.0.2.tgz","fileCount":23,"unpackedSize":42980,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2SdyCRA9TVsSAnZWagAAbAsP/26VE3PWoQ3yr7m/kFxl\nP81DMHC3sCRbvRJHYgZQlO0TAnQoDX4s5GCcmcTnmXzwxlDuvLy+zWF2KZjY\n/bGlwYPVSuokU9o3eZp60ilDmj/2f/7/cjalTRxhClQdf4NqYPchu9Kc1zOY\nf20wZtFN5o9ErEnRY7lXu3E7z3ry3LZF0m7oJ63Dgm2Suu8VyS/KJP+sJKz6\n/74Ob4gR/GUiJuZvwuGW3QYA5wTuGpFwH5YCyF4SmMgcRTLK/eQsizu1AxHb\nUQZ9B3u52FGwsqQ19fRXczIRbt0l/wHly2t205PmlNemrKCkH5qEOMPycQZf\nrfKUijmeChJyaYIVJPxylc1JucIR2kOJTQHRW05ulDsMOQrZRrEBPmdwccb5\npzo1xkhhQvJYRZn9zQqqMmvt2y8aeTSHe0KTbQI5ABNj/UEO8/4DAiKPyvAD\nA7qCQDhDcIfVnYd2B6gRi98xa1pgkl6u09uVCTuTZ0XP7UUOMpiWpx36prPO\ncMmkVBHgEbzn6jrn3mCNhh3/Ftp4JiMHRnyPTx11sOoNyAJMltmgvM2YAf9V\nhPWtKX0tzfuHBB7AHY3/1z+IwGuxgLTICuZp60Nrtors8+op/wxK4v93n3JB\n1XFhnkw8DSsqvXT9kMZm6yJquf0SywajMSdbJ1S+4izyVq5+Q6Y97KcPohbi\nKnXf\r\n=r21J\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC5tfDAOFcDfCoyQvuufXpvVJ9urNg5U+ubd0EHNASesAiA+NoJKdNSHoW30/ZMG29XU2QFgTG0Z6/9Lrrozz9xR/g=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_1.0.2_1591289714219_0.17888271435500247"},"_hasShrinkwrap":false},"2.1.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"2.1.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=10"},"dependencies":{"csv-parser":"^2.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","is-stream":"^2.0.0","luxon":"^1.0.0","pump":"^3.0.0","shorthash":"0.0.2","sort-array-by-another":"^1.0.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","sample-gtfs-feed":"^0.4.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"1d9855b2e44aa11a5ff7633c2e2276edd01c82a3","_id":"gtfs-utils@2.1.0","_nodeVersion":"14.2.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-EuR8xKzcz/xo1zlvygjQFeACiHr+w8f/tACbZB0InUSTtZwTQGBs+XEeu/f9bavA4nL9l9V1b8o0b+bCqJDtNg==","shasum":"b6dbf90390fafb61f48ffb47fad1b8a9949a3e36","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-2.1.0.tgz","fileCount":26,"unpackedSize":54827,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe2TSsCRA9TVsSAnZWagAAEDUP/1WRNJZYHLM4TDVzUwB8\nGFQnsWa5zKuSOK93CKSjKmdkA72pn/LH2Bf6BEqeKwyPARh62yaVzxrYkHOR\na1BLuiT+vdwLS0XtqYeczENlSTyHqZSwwjOChQYy+K1laKVDQFnYBISMkjpT\nOmZ/RBH5b5F38izqdY06s+0JmftImcRyO5LkLHLpZGI9wto5KsFrRvPzyTWN\n/rSwKPyKYmnOp0vTB4Tf8ikXcCV34zxpJU9Yh/SeNu2UZjP1LvHZJQLyA6cw\nrnI65xUX42+z/+n1iYu1Tc2nQ5Mx9kMLa4Zhew5Z9f7heh1lTwfsHA8hgM1x\nfDxbNqA6zaP6rhEs1mLSY33sRc+OrgJL3t75uFf0S6oq/8N+f4hfwasFsMOH\npSilZWKiRSd1czciom+UwttKSkHf8QKV2BgltOlnx5zAPJTlBm6RG91enLKK\namgk0PIcekTM3Zd7eukR+6sPKYn2cB4oUOnxKdfSWFWLdmXBQwsGUMscPlmT\nKlkNcRY7tNbWRut4L53quczBW5Uk+dK0ESvXY6a3qba1Dv53JpGziSnMf1Bv\n6D51zJ3Oa18bN7FspQfY9zQ6B0rIWSEDcngPv6K3i92sQqByjHS+T4/7N+gY\nuKwKEqs0XW4Ue1pxScW9X1nmuJ2jm/WuhOGX4leJc8odJEPYq5oPljGcuSrq\nKxER\r\n=egTv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD0qcJVXB/BueHVNfLAQPbU+UFQx1zGu2Tk3Na/f7K2sQIgKI+pmS5y2qtfevMfcW2oZec2VSSXce4Zwek2RoN6uRg="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_2.1.0_1591293099519_0.7353486349876475"},"_hasShrinkwrap":false},"3.0.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"3.0.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^2.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","sample-gtfs-feed":"^0.6.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"eef2641e62711ff9c7469b676bc8a081b79c65a0","_id":"gtfs-utils@3.0.0","_nodeVersion":"14.7.0","_npmVersion":"6.14.7","dist":{"integrity":"sha512-Qkweru3BEb3m1Er2+4K82jwk2pqbadzb3JIwa6uwPbacIdp7l30oKfw8mKlONJ2Jy1VT2uNZudP421DhbS1r7w==","shasum":"60d4f7284272c10b6811e89bb734c5cc808397b0","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-3.0.0.tgz","fileCount":50,"unpackedSize":201961,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfS7A1CRA9TVsSAnZWagAAIGgP/RGihsovIMMFqWp3xhmA\n2O1smRhplhl6GpzFw44pwaT43y6BoUPjel/Vl4hJ2jUvhosOB2JcBW23PoOi\nWZiGytpIRjUdhDzgOuxUo08Dc4DIFM40htGZkzosqfg1SMFUKp2jc1HUbVkM\nSG6J8D7tUVfY6upNTJa0x4UF+C2OPamBCexOFV7LILGMFeS8b2+mFdLONM3W\nBITgKEyR2oWpHAsgt8tk/5n+NOj/oabUa+ULw+J+9teIRCn2SJZobkL7hsP4\ndpBpxXe6N6yozC63c98ddRf6Ct+wsBT5TU5w2EF/vSo/6tut/e9Xirc5pF65\n+3BU/FzjRR9CI9JxmJgsWL0tFqul/x+6LoCeqBxSfeNzX11m6PV4ow5M0vox\nxuOUqttcLxk8bltM3oZvKJyCiAurGixTxlpX8O1Ted6Fn7D2spndFHI0FS+S\nu3+miYbfC5dKgpVDii0dXwUnMeliaVEuT2pAfpc2AH/udUN2Z0GjdeQG7bR1\naglCr83g9Un+opXjx7t5Oz4Zehn9/jiuHVbBDYNrC4LjjvXZe3msPrny7T9u\nq4pl/ugoDV5FhWrcgVLo+PaC2J3Xcgw+MvejsG+Diu1k4IVcVtzgHkPumy3c\nzzTqDHBwby6ZgvPPORuTsoRwd5SfWD2n/wZyTTHyIghhOmEt3TFycG54i8tB\niOY2\r\n=xxEo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDNQTyZ2ToABas7rWL9bKK6IgX496yMEyI2c2HhbMLZSAiBW75vOthHfyC+rMillVgvttWuURfONPPhj5DHEKAAlrg=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_3.0.0_1598795828973_0.18978950202409983"},"_hasShrinkwrap":false},"3.0.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"3.0.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^2.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","sample-gtfs-feed":"^0.7.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"7b8137e85a73933c2b7e6276d35c2641f96f2789","_id":"gtfs-utils@3.0.1","_nodeVersion":"14.9.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-QPlM1gocOVFp8fpOVjvOTdoUvFQnx6SdIwe2GhXx4hG7CY3qqDApX6G2Nkr78cbqj27tYUL6dJnZkL/gUzOSxg==","shasum":"02c0354625847d93d0c5171801fcb0160b137881","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-3.0.1.tgz","fileCount":51,"unpackedSize":222007,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmudDCRA9TVsSAnZWagAAoTgP/243gZ+mZKsLIMWJQllx\neQ8zabwlrn8y4D8mSPYFGgpvk+Y4GUViqYxlChc0vGcfRiuf7RFOAhQVmGdd\n7Px2Sk/BkS2yUxQPtvbn26qOWz1EJEcFd7Xe26BXtt5Kww4gYyTUyv39JzlE\nYjzsTfLLVkS8/f3EGZRGodlJZR7shZEbFuW/JXgXUFP4anaiKpzOdYaNGqaw\n+T1Z9A9hZKxhb/DALkQm4nQsF8iWi9edKQF07Fio2GgVbQp++zCPTXS9l71Y\n7xe7XfGyHynxDhPQBZRw/CC3tCobHsPOadwb3FDRjun1FoI6yVU/dumzaUxy\nLEAEP0Ss8Llsxn7TpqtnSKVbpno1zFb9hP7wMpcQzdV1RI8PcxLvhcwcwhfN\n6skgCQvej/jq+KEZXnSU4sEnLf6oaiHwX/DTeS4yb5nLtXAP4cn9ZD4kfte2\n0erey69Zc0qj2dsvI9FnrJFPsq4ctKyA4sTKZ2xbP+i1cbiTQyQLW/4Q0Fb3\nt2Xc3rPkqaKv0+dvjc2JexQDRmXvSNkB1p7fAnZYEJs1m8M4nXMIlPZtm123\nX1xcoG62bFDfkaeGLzWV7PXAo8v1oBdVq+2KMUSWpeFdUsrQxxgont51CvZe\n4kFb96sm6USp+WS51nqUZiFoljhLUQ73Oei15fwQ6hKjQ3j34UsWQQ2nFk2w\nkDoG\r\n=Mq+D\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFNWIzNta1XAxjBnOOTq66AJQatDJg3MMHhk4HfT5QNeAiA/cpYyT9EvAaz9skcSLCb5FhWo2cHkoh0FFqbTVSfxRg=="}]},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_3.0.1_1603987266410_0.13803411264837084"},"_hasShrinkwrap":false},"2.1.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"2.1.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=10"},"dependencies":{"csv-parser":"^2.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","is-stream":"^2.0.0","luxon":"^1.0.0","shorthash":"0.0.2","sort-array-by-another":"^1.0.0","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","sample-gtfs-feed":"^0.4.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://developers.google.com/transit/gtfs/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n[![build status](https://api.travis-ci.org/public-transport/gtfs-utils.svg?branch=master)](https://travis-ci.org/public-transport/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n[![chat on gitter](https://badges.gitter.im/public-transport/Lobby.svg)](https://gitter.im/public-transport/Lobby)\n[![support Jannis via GitHub Sponsors](https://img.shields.io/badge/support%20Jannis-donate-fa7664.svg)](https://github.com/sponsors/derhuerst)\n\n- [`readCsv(path)`](#readcsvpath)\n- [`readStops(readFile, filter)`](#readstopsreadfile-filter)\n- [`readTrips(readFile, filter)`](#readtripsreadfile-filter)\n- [`parseDate(dateStr, timezone)`](#parsedatedatestr-timezone)\n- [`formatDate(t, timezone)`](#formatdatet-timezone)\n- [`parseTime(timeStr)`](#parsetimetimestr)\n- [`readServicesAndExceptions(readFile, timezone, filters)`](#readservicesandexceptionsreadfile-timezone-filters)\n- [`computeStopoverTimes(readFile, filters, timezone)`](#computestopovertimesreadfile-filters-timezone)\n- [`computeConnections(readFile, timezone, filter)`](#computeconnectionsreadfile-timezone-filter)\n- [`computeSchedules(readFile, filters, [computeSignature])`](#computeschedulesreadfile-filters-computesignature)\n- [`computeSortedConnections(readFile, filters, timezone)`](#computesortedconnectionsreadfile-filters-timezone)\n- [`findAlternativeTrips(trips, services, schedules) => (fromId, tDep, toId, tArr)`](#findalternativetripstrips-services-schedules--fromid-tdep-toid-tarr)\n- [`computeServiceBreaks(sortedConnections)`](#computeservicebreakssortedconnections)\n- [`routeTypes`](#routetypes)\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n### `readCsv(path)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nreadCsv('path-to-file.txt')\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_object_mode).\n\n`path` can also be a [readable stream](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_readable_streams) like [`process.stdin`](https://nodejs.org/api/process.html#process_process_stdin).\n\n### `readStops(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readStops = require('gtfs-utils/read-stops')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadStops(readFile, filter)\n.then((stops) => {\n\tconst someStopId = Object.keys(stops)[0]\n\tconst someStop = stops[someStopId]\n\tconsole.log(someStop)\n})\n```\n\n```js\n{\n\tstop_id: 'airport',\n\tstop_name: 'International Airport (ABC)',\n\tstop_lat: '52',\n\tstop_lon: '14',\n\tstop_code: '🛫',\n\tstop_desc: 'train station at the Internationl Airport (ABC)',\n\tstop_url: 'https://fta.example.org/stations/airport.html',\n\tlocation_type: '1',\n\tstop_timezone: 'Europe/Berlin',\n\twheelchair_boardings: '1',\n\tparent_station: '',\n\tchild_stops: ['airport-1', 'airport-2'],\n}\n```\n\nWill read `stops.txt`, reduce it into a map `stop_id => stop`, and add stop IDs of a station as `station.child_stops`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `readTrips(readFile, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-trips')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = t => t.route_id === 'A'\n\nreadTrips(readFile, filter)\n.then((trips) => {\n\tconst someTripId = Object.keys(trips)[0]\n\tconst someTrip = trips[someTripId]\n\tconsole.log(someTrip)\n})\n```\n\n```js\n{\n\ttrip_id: 'a-downtown-all-day',\n\troute_id: 'A',\n\tservice_id: 'all-day'\n}\n```\n\nWill read `trips.txt` and reduce it into a map `tripId => trip`. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n### `parseDate(dateStr, timezone)`\n\n```js\nconst parseDate = require('gtfs-utils/parse-date')\n\nparseDate('20190303', 'Europe/Berlin')\n// 1551567600\n```\n\n- `dateStr` must be in the `YYYYMMDD` format, as specific in [GTFS](https://developers.google.com/transit/gtfs/).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `formatDate(t, timezone)`\n\n```js\nconst formatDate = require('gtfs-utils/format-date')\n\nformatDate(1551567600, 'Europe/Berlin')\n// '20190303'\n```\n\n- `t` must be a [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time).\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `parseTime(timeStr)`\n\n```js\nconst parseTime = require('gtfs-utils/parse-date')\n\nparseTime('21:30')\n// {hours: 21, minutes: 30, seconds: null}\nparseTime('21:30:45')\n// {hours: 21, minutes: 30, seconds: 45}\n```\n\n### `readServicesAndExceptions(readFile, timezone, filters)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\nreadServices(readFile, 'Europe/Berlin', filters)\n.then(console.log)\n.catch(console.error)\n```\n\nWill read `calendar.txt` and `calendar_dates.txt` and condense each service into the a list of days it is valid for. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\nThe result might look like this:\n\n```js\n{\n\t'service-1': [\n\t\t1551394800,\n\t\t1551481200,\n\t\t1551567600,\n\t\t1551654000\n\t\t// …\n\t],\n\t'service-2': [\n\t\t1551567600,\n\t\t1552690800,\n\t\t1555797600\n\t]\n\t// …\n}\n```\n\n*Note*: In order to work, `readServicesAndExceptions` will load (a reduced form of) `calendar.txt` and `calendar_dates.txt` into memory. This might fail with huge data sets.\n\n### `computeStopoverTimes(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeStopoverTimes = require('gtfs-utils/compute-stopover-times')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\ttrip: t => t.route_id === 'A',\n\tstopover: s => s.stop_id === 'some-stop-id'\n}\nconst stopovers = computeStopoverTimes(readFile, filters, 'Europe/Berlin')\n\nstopovers\n.on('error', console.error)\n.on('data', console.log)\n```\n\nReturns a [readable stream](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_object_mode).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip`, `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\nA single item from the stream may look like this:\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'b-downtown-on-working-days',\n\tservice_id: 'on-working-days',\n\troute_id: 'B',\n\tsequence: '1',\n\tstart_of_trip: 1563573600,\n\tarrival: 1557486780,\n\tdeparture: 1557486840\n}\n```\n\n*Note*: In order to work, `computeStopoverTimes` must load all of `calendar.txt`, `calendar_dates.txt` and `trips.txt` into memory (not `stop_times.txt` however). This might fail with huge data sets.\n\n### `computeConnections(readFile, timezone, filter)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeConnections = require('gtfs-utils/compute-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filter = stopover => stopover.stop_id === 'some-stop-id'\n\ncomputeConnections(readFile, 'Europe/Berlin', filter)\n.then((connectionsByTrip) => {\n\tfor (let connectionsOfTrip of connectionsByTrip) {\n\t\tfor (let connection of connectionsOfTrip) {\n\t\t\tconsole.log(connection)\n\t\t}\n\t\tbreak\n\t}\n})\n.catch(console.error)\n```\n\n```js\n{\n\ttripId: 'b-outbound-on-working-days',\n\tfromStop: 'center',\n\tdeparture: 65640,\n\ttoStop: 'lake',\n\tarrival: 66000\n}\n```\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).\n\n*Note*: In order to work, `computeConnections` will load (a reduced form of) `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSchedules(readFile, filters, [computeSignature])`\n\nThis utility computes what we call *schedules*, \"patterns\" by which vehicles visit stops. An example schedule:\n\n```js\n{\n\tid: '248tGP', // signature\n\ttrips: [\n\t\t// The trip `a downtown-all-day-1` follows this schedule and starts\n\t\t// 55380 seconds after midnight on each day it runs.\n\t\t{tripId: 'a-downtown-all-day-1', start: 55380}\n\t],\n\t// Arrives at 0s at `airport`, departs 30s later.\n\t// Arrives at 420s at `museum`, departs 60s later.\n\t// Arrives at 720s at `center`, departs 90s later.\n\tstops: ['airport', 'museum', 'center'],\n\tarrivals: [0, 420, 720],\n\tdepartures: [30, 480, 810]\n}\n```\n\n*Schedules* reduce the implicit complexity of GTFS data sets a lot, because one schedule summarizes many trips with a certain \"pattern\". Paired with [`readServicesAndExceptions`](#readservicesandexceptionsreadfile-timezone-filters), you can easily answer questions like *Which vehicles run from X to Y at T?* and *Which other vehicles run as well?*.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\nconst filters = {\n\tservice: s => s.monday === '1',\n\tserviceException: e => e.exception_type === '2'\n}\n\ncomputeSchedules(readFile, filters)\n.then((schedules) => {\n\tconst someScheduleId = Object.keys(schedules)[0]\n\tconst someSchedule = schedules[someScheduleId]\n\tconsole.log(someSchedule)\n})\n.catch(console.error)\n```\n\nWill read `trips.txt` and `stop_times.txt` and compute schedules from it. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise).\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `trip` & `stopover`, each with a filter function.\n\n*Note*: In order to work, `computeSchedules` will load (a reduced form of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n### `computeSortedConnections(readFile, filters, timezone)`\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSortedConnections = require('gtfs-utils/compute-sorted-connections')\n\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\ncomputeSortedConnections(readFile, {}, 'Europe/Berlin')\n.then((sortedConnections) => {\n\tconst from = 1552324800 // UNIX timestamp\n\tconst to = 1552393800 // UNIX timestamp\n\tconst fromI = sortedConnections.findIndex(c => c.departure >= from)\n\tconst endI = sortedConnections.findIndex(c => c.departure > to)\n\tfor (let i = 0; i < endI; i++) {\n\t\tconsole.log(sortedConnections[i])\n\t}\n})\n.catch(console.error)\n```\n\n```js\n{\n\ttripId: 'b-outbound-on-working-days',\n\tfromStop: 'lake',\n\tdeparture: 1552324920,\n\ttoStop: 'airport',\n\tarrival: 1552325400,\n\trouteId: 'B',\n\tserviceId: 'on-working-days'\n}\n{\n\ttripId: 'b-downtown-on-working-days',\n\tfromStop: 'airport',\n\tdeparture: 1552392840,\n\ttoStop: 'lake',\n\tarrival: 1552393200,\n\trouteId: 'B',\n\tserviceId: 'on-working-days'\n}\n```\n\nReturns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise) that will resolve with an array of connections.\n\n*Note*: `computeSortedConnections` will load (reduced forms of) `trips.txt` and `stop_times.txt` into memory. This might fail with huge data sets.\n\n- `readFile` must be a function that, when called with a file name, returns a [readable stream](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_readable_streams) in [`objectMode`](https://nodejs.org/docs/latest-v10.x/api/stream.html#stream_object_mode).\n- `filters` must be an object; It may have the fields `service`, `trip` & `stopover`, each with a filter function.\n- `timezone` must a timezone name from the [tz database](https://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones).\n\n### `findAlternativeTrips(trips, services, schedules) => (fromId, tDep, toId, tArr)`\n\n```\n           fromId  --time window-->  toId\ndeparture at tDep                    arrival at tArr\n```\n\nFor a time window `(tDep, tArr)` to get from stop `fromId` to stop `toId`, `findAlternativeTrips` will return a list of all trips that run from `fromId` to `toId` equally fast or faster.\n\n`trips` must be in the format returned by `readTrips`, `services` in the format of `readServicesAndExceptions`, and `schedules` in the format of `computeSchedules`.\n\n*Note*: The purpose of this function is to identify *direct* alternative trips to a given trip; It *is not* a replacement for a proper routing engine. (There might be a faster way from `fromId` to `toId` via transfer, and `findAlternativeTrips` won't return it.)\n\nAs an example, we're gonna use [`sample-gtfs-feed`](https://npmjs.com/package/sample-gtfs-feed):\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst readTrips = require('gtfs-utils/read-trips')\nconst readServices = require('gtfs-utils/read-services-and-exceptions')\nconst computeSchedules = require('gtfs-utils/compute-schedules')\nconst createFindAlternativeTrips = require('gtfs-utils/find-alternative-trips')\n\nconst readFile = (file) => {\n\treturn readCsv(require.resolve('sample-gtfs-feed/gtfs/' + file + '.txt'))\n}\n\nconst timezone = 'Europe/Berlin'\nconst noFilter = () => true\nconst noFilters = {}\n\n// prerequisites\nPromise.all([\n\treadTrips(readFile, noFilter),\n\treadServices(readFile, timezone, noFilters),\n\tcomputeSchedules(readFile, noFilters)\n])\n.then(([trips, services, schedules]) => {\n\tconst findAltTrips = createFindAlternativeTrips(trips, services, schedules)\n\n\t// travel times of a downtown trip of the A line\n\tconst fromId = 'airport'\n\tconst tDep = new Date('2019-03-05T15:24:00+01:00') / 1000\n\tconst toId = 'center'\n\tconst tArr = new Date('2019-03-05T15:35:00+01:00') / 1000\n\n\t// find an alternative trip of the C line\n\tconsole.log(findAltTrips(fromId, tDep, toId, tArr))\n})\n.catch(console.error)\n```\n\n```js\n[ { // This is the trip we were using as query.\n\ttripId: 'a-downtown-all-day',\n\trouteId: 'A',\n\tserviceId: 'all-day',\n\tdeparture: 1551795840, // 2019-03-05T15:24:00+01:00\n\tarrival: 1551796500 // 2019-03-05T15:35:00+01:00\n}, { // This is an alternative trip.\n\ttripId: 'c-downtown-all-day',\n\trouteId: 'C',\n\tserviceId: 'all-day',\n\tdeparture: 1551796080, // 2019-03-05T15:28:00+01:00\n\tarrival: 1551796380 // 2019-03-05T15:33:00+01:00\n} ]\n```\n\n### `computeServiceBreaks(sortedConnections)`\n\nMost public transport networks don't run 24/7, but instead have regular scheduled \"service breaks\", e.g. at night or on Sundays.\n\nGiven [sorted connections](#computesortedconnectionsreadfile-filters-timezone), `computeServiceBreaks` finds periods of time without service between two stations.\n\nIt depends on the specific network what period of time can be considered a \"break\": In a large city, it could be no bus/train running from 2am to 3am; In a small town there might only be bus/train every hour, with a break of 8 hours at night. This is why `computeServiceBreaks` optionally takes a second parameter `minLength` in seconds.\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\nconst computeSortedConnections = require('gtfs-utils/compute-sorted-connections')\nconst computeServiceBreaks = require('gtfs-utils/compute-service-breaks')\n\nconst serviceBreakMinLength = 30 * 60 // 30 minutes\nconst readFile = name => readCsv('path/to/gtfs/' + name + '.txt')\n\ncomputeSortedConnections(readFile, {}, 'Europe/Berlin')\n.then((connections) => {\n\tconst {findBetween} = computeServiceBreaks(connections, serviceBreakMinLength)\n\tconst start = '2019-05-08T12:00:00Z'\n\tconst end = '2019-05-10T15:00:00Z'\n\tconsole.log(findBetween('airport', 'center', start, end))\n})\n.catch(console.error)\n```\n\n### `routeTypes`\n\n```js\nconst routeTypes = require('gtfs-utils/route-types')\n\nconsole.log(routeTypes.basic.find(type => type.gtfs === 3))\n// { gtfs: 3, fptf: 'bus' }\n```\n\n`fptf` contains the [*Friendly Public Transport Format (FPTF)* mode](https://github.com/public-transport/friendly-public-transport-format/tree/1.2.1/spec#modes).\n\n\n## Related\n\n- [gtfs-stream](https://github.com/staeco/gtfs-stream) – Streaming GTFS and GTFS-RT parser for node\n- [mapzen-gtfs](https://github.com/transitland/mapzen-gtfs) – Python library for reading and writing GTFS feeds. (Python)\n\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"1687461f2fa650a64346a8b5b31d219ac1604423","_id":"gtfs-utils@2.1.1","_nodeVersion":"15.5.0","_npmVersion":"7.3.0","dist":{"integrity":"sha512-XL79AnkohWBVCX75DaFY+pT3XzEuUo7mchWDiLUn0X4nzOh/c+Cc7e+hZ/wJ393cW5+S9ZPAMJuJ8/fApIMrlg==","shasum":"a4ae1f2f48cb3935ced2545fc1553644e0291ae2","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-2.1.1.tgz","fileCount":26,"unpackedSize":54789,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf8hArCRA9TVsSAnZWagAAaFoP/2QxDZ5y/5HczVOv4xqP\nSYrNqGIyP+Fd+W+20hRdrHONfeiPWAsWeV17LbZTWZUdDJmAU1UmUMeQHsAi\nbqWrZYjFoTrWMfCE56nzLH1OHnbBe+PWaRzHYJGO/INmDeGB8Ag+/9GBTzsQ\n/I2xBYStondqHh6YD35W5U70miz6jyO96pLazeE8MtXKFoErD3PskNitwi5k\na9eveH7HxPHWqcvXhszfPBAh1hSauoeftbfl34hFMqS3IWfEcNzCr/z4WpUx\n4b4ryYhfwxgdTShCk7AmQdF8gIpjKJzFmrYT71eaY4gqY1vOy0YEP504xFMc\nXNDYP4wDoNLehsj7nFDSxN+593J1IBPtTfrDzl+f+rev+TRkwXC7n5aOFJiC\nBdHeB/kjTxpYyMRthDHo7lXBPfCUFzcu28wvH+9yf4zfWgRD39fDv4wQqUzq\nv6vOiT6P4rnxsU0qYzzOXengw4NiVrL4hqQXPvRJWatTz+T4xR4Qkm7bC7jX\nvRzfYpfvZ4vlbONiwyU7Gl37fNIgXTmWVSwWW0ZvQh4gJ9jTI2aT2hiZufAu\no2WEFXZTom2nLUVMAJAbaVCwtiFnSpHI4qWu9ggKOez89EDeHyz01HlWXu6t\nWKpnJXkdHVjsiDf75JbTu4Ly2I6JeQCx8HNA0eXgr7qGE0iGmrzyEaLDzKq2\nYdb9\r\n=xD1s\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiUO3km/XPIC6pA819eU1xKlQ1lLaIt0B/hguX7rb0HgIhAPEoO/Tndpjn7E9X+xCgrietLT24K7WT2doQJUETrq7a"}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_2.1.1_1609699370969_0.2741183625073058"},"_hasShrinkwrap":false},"3.1.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"3.1.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","sample-gtfs-feed":"^0.7.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"de05995c139ffd025eba3ccd89e62413f992a56c","_id":"gtfs-utils@3.1.0","_nodeVersion":"15.9.0","_npmVersion":"7.5.3","dist":{"integrity":"sha512-PgHvTdgb4YBNjYp9wfKalvGaUvTrbFcrcVsGXzyzLuyptHxs5h/MA1jogd83sEob/8ndI2nL1WGgd3OmLiGN5w==","shasum":"664a730d1744496b2d8eb2d8022ba03d0e32c4a0","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-3.1.0.tgz","fileCount":51,"unpackedSize":222835,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNXG2CRA9TVsSAnZWagAAz84P/2kAepnKCIrl0WbpSfzZ\n3ga6hTIb8G4w5mpl1YwUnMtET6blzz6JLyyqzI4aWvFkaH8dKdZtVOlU1TTp\n+gExnYJddOyrHaH0TSw3zevHzSekJidB9cBuUkIRQkbPqxSLrlpTJR5TK1aS\ncRWx4Z4fl41Mj11xUsa3k0EyO0iwzL8RMeRfMElsCZtkhivyqEhkTRZYlFQA\nM9a+NR4nBVdISXz0AFC6MhggUx2N2EB/u2qr3rgxl0ZT3d7QqCeDREj+Hf8Q\nhQ/QQBPEpTsnmn7oty0Cd90wms4AukDqDAtnDAoYhfyBGGvrpvtDC9KQDP0h\n63PyNjHCm3p48T9Gc1bqhmXZEjd5ijJWBDB8hsWbLFWgIOTuX3i4sqLfeZ4R\nqGFjkMhaL/cEJb4xRCzl0SDMKdzfvS33gjx5bNnW6jrioT0/hR4rQlIQ0WwQ\nGeXfE5nJVGH3JktbnhKNY2tl2rr+lzxqxfD5mUKzrXH2qSJEFsKr8zV7esfG\no8CxD8qJ9yoX1zfkVbWk8eudNhld8/Tp9AbWY6wSr13bgSvV9ZYbF1gQcuGb\nWm3GxPd3iWdR3O9JN3T7tovri0NzMA6T4dYkmlfVnzwSyZPS8Xa7suD+LC91\n5zGBmx5qBrBbMN0wJeAqiewIOXjD80QhUS6vkvswcysSgWpNmRD2JdWUpsbc\ntTGG\r\n=wYC5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICmlMrGq7ncApDxOrQFGqs2m8vqypYHqayHwj2ryfOIgAiEAlit30I5/bGA+ERW5sRRykWPlDXIQFy2eYnsIzFVK6pA="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_3.1.0_1614115253535_0.8929435406659856"},"_hasShrinkwrap":false},"4.0.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.0.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","sample-gtfs-feed":"^0.7.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"48ba8028de5344aff830dd3783219619d006a23d","_id":"gtfs-utils@4.0.0","_nodeVersion":"15.9.0","_npmVersion":"7.5.3","dist":{"integrity":"sha512-eqA0eDu/iPU64taqDS534obXUX9rAUgOaz5qBKGrZnha7VVKVfr9tc9Zz9fzopVSo+uW59YOrl48UZ2GvXHW5g==","shasum":"75dcd6e5e66103613f2084338283ce613333c9c1","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.0.0.tgz","fileCount":62,"unpackedSize":231705,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgO69/CRA9TVsSAnZWagAAj04QAIqqyHX/k/I04Vsb2BJL\nBLQHQ634gfo6LTjxRaxb0ZsXFul7vvQ9JBbSkrNVxFAcLCmkbu95Yrs+QmmW\nrYNouWm3o+tQtk1WNOPGUyloI/8BXy31veJQx2SLVmdj4x4lhVbkRdnqLySY\n3kvdUXSx8zUb7U3eTwwM/aVF16okdeHD1hbDKFJQMNGbH6/iA6Lm6ubpgLes\nb+icPDKBDnjtzTeC+snJLrAenbwqiBjFGHMbEIT7Zn27lQLYGjOuHYUftXE+\npm+QPmkJoM/K7WLCes/EfeNCTUL/1eDZH1axtwoxcj3lBt6b1gArJX5Y9V2A\n/aNFZfnCkL4ystPfDIaT/X0rjQZx5QQZ+A8wI1PNyQgPGp2fTqNw3qaQ0FQl\nUHlJayaTAVDaN6XWsNg689W0CNASI/ELSEjGHTtoOQHGjabtxR243IuFCDbP\nylRfybO+0xmsEsdOV7/w6OT0hnEtxhlMhnr0y4MRYLVf3E50xdjGYjaUO+Cc\nOjq6wYiAcgyYqT9Le6BUEVriK3O9Y8F0zhAv8QqQbmbq/NP99kv8PdmnUFsQ\nTf5bJtE3I/v4MoPPRYgC6KdWnIvIpQ6OxQKM2r7b2QvB47VRot1H5Sb+gqNY\n1xGES7ulRIGOY0cqFd9fQCT9FFpqd+vtMJW2M+uRq/fDxje/ImMIWXl76H2q\nvgh6\r\n=l3XA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDcQdUFQHDf9KP0u3mWL/DtfuAYWe7R186eEUaY2AsSagIhALZmj5N8oLDsEQ3UjwZlYiKQiq7on9ZHkZjZI+izLUAG"}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.0.0_1614524286584_0.6237520430835453"},"_hasShrinkwrap":false},"4.1.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.1.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.9.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"6f9721954bf0e023501d05e3cf16ab5e37705c3e","_id":"gtfs-utils@4.1.0","_nodeVersion":"15.12.0","_npmVersion":"7.9.0","dist":{"integrity":"sha512-zBhEEghKbtl5FYbtDTBNuM2Ga3kQDhH+VXhmhQVbHknB+VoLWz61naP/Wpf0go+q/o6QVXQGg609YP/ZnmRX1g==","shasum":"286408cf3378c88e632092558490e829d6f15a31","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.1.0.tgz","fileCount":66,"unpackedSize":241382,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgdyl1CRA9TVsSAnZWagAAefUP/R7VYR9v5/gcD32rCap8\nmwfi13g6z/w2dra3dvNX5uzKEab/JbYkTBajhMvgxZWa13cdim9gKGOwj1UB\n0FaE1UucXsbfdKS/9ZNaOs3UgbRPN/3E63yFcMmyLOLy80VYCk0/La8MfPBa\nh8pQLwofNtPXt1ywaXvu4Hwld9V9x5R3tLOtMskI0IJym2A5YoCmD+Iv0Nb0\njsIsAeK9BkdmFeTA9FSiabGLaNbyCZc914k4QtY4AZXBdlUf8P5c41eSRBIb\n4zQCZCBkzVsYLTMruerx3+jx3Qzc34rerqApJN9hQga2gf4L2lGY8QcyGdJg\no5iC30HrPKxfuUgNS73aac/PuvjEWq4oG/bqhN6xhZDhFthsFrGCCJkjwa+i\nzNB/jSZrNj5ixpsFbB6V7ITklEvlSPislhzG3Ik1Pc0DIJmNeyWqGG36r7KP\nst02rtNE7MvOvXhMhDUr+AP5tTes2LlOzEfW43dKDh1adQyGiicKjX6mbKy6\nFTuDlyjqW9FOSDY2SgeuVJf5jEyLePHdkppr3i/o47bFy7SvWjksqXEcEzks\nc8Cgvv8d8rTd9gb4mFskYToXJwASwzx3P+WUPPutg/mcvEIsLhDY4ZUsG1ad\nEnlEAz+Cn/6QehrOgF29lyRToeaLjuWy0cZNGafksrUACKdQmaPQgP1zaku3\nb5up\r\n=0Wbc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGKffJicHfkQEohTerxIPez6k8XxL6Ve3vorze6ss4bOAiAMevqZo2Jr2KnTo8J45uZU8Pgc23L1lFDZxwvYFk2P4w=="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.1.0_1618422132661_0.7514218314847634"},"_hasShrinkwrap":false},"4.2.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.2.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.9.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"f578b01f6769dbd397eb9e4b44b71bdf58a5d759","_id":"gtfs-utils@4.2.0","_nodeVersion":"15.12.0","_npmVersion":"7.9.0","dist":{"integrity":"sha512-SVdfhx3o4qzrFeD7F/DaEcMiL8Xx39o8Wg7v/DveyZa5p7kRABH/ODLcl0YD62g9hYjZ2WdZ6HOjoWdAES1XIw==","shasum":"e095e862e3f6bf0a6ade02eef910a1181c628886","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.2.0.tgz","fileCount":69,"unpackedSize":243005,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJggUyZCRA9TVsSAnZWagAAMbkP/RsTFALbK6YPDXDaRcve\nb95SMaPnIjhxH4DyGeBKeoRFGTXyylezYMO3ak6WrSL03UXEccWr3IIaXsip\nwo3VOMJVGFehhhJ97QysJSjkGID00CFVKO3D0E03VL4EzV9BX+rCP3RjihUS\n8W89gMm1iI86ZULN1wqnN6svsyPsOSGAQulQuBEFBBbNC6u3tRJgncPhigXn\nhn1/5o9Ucoz9YTl+2PGbb7X/8gjlWRGt5i7ei3SomyKV1hm2y0PSLU2lDWwL\nsNY1DWRRzMZ/l3go0Gn3vWRyaDAKjVAcA7hlvW/+6zsXeNmJEtFrmjelUXNq\nxB/ZEy4NBer1AB3kwvp4u7sTqn0DjvU3QbqJpHdyWPy//OmsIN0GI/LIaXik\nU9y6bYYmf2mo43g0jtZvvLAfAwHizEZYZLYVayfP+yQPq1DoIjCSuhb5KyJI\nNPGF3t1C5hRtA02zFNdfkRTCrnJqZO6ZV8hvpMyG/XjBzBz5gvgyumYz/LoK\nWaZhRLWTM0WQAjHWeOqcso+3uRXOiY/mucQTzMJJIkNw/CNmqXiSN90gbJMR\nyEMvhwWG2muKYENA5s4fFNNOUOcbzyWJ1kiZB58/aWVY4OTDXeoIQVbYFE2x\nxym+f1QEctKiotCjjw/V4JZOUd86bR8sJm6LYoIKt0RSGDDsHLErm/BsbInH\nxIsd\r\n=a3x2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICPzaG0R2ACYMf9e0tHUSuT/mfye5LOCEL4a1ODumYjAAiBYnKSTPgv3BbBwD0gGDISecc2Y1iykXgJsubSW74KP9w=="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.2.0_1619086489356_0.7391668801956985"},"_hasShrinkwrap":false},"4.2.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.2.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.9.0","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"4ee271b472d3c9555650d6981b79974156124eb7","_id":"gtfs-utils@4.2.1","_nodeVersion":"16.0.0","_npmVersion":"7.12.0","dist":{"integrity":"sha512-ZNJ2imjiqp6q8yXj0lTYfTWWF8H5YC8CMjJBSZg/hdwyERXEeczK7twKwoS0xFzoPNiPE0O4VmCcGTH6PupmTg==","shasum":"0da4920ed07d24457a88933837247d3af9464caf","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.2.1.tgz","fileCount":69,"unpackedSize":243005,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnXDOCRA9TVsSAnZWagAAnW4P/Ry0KUQWZLEF/+qJteO1\nFzBdYJckzXTQQjT5UaGtisIY+vpYjg9lg41uzSUUN+wxS3TYfy9YyGYkIdTj\neP1siDfCMRIcBg3LnXbhGjnllRA5kVQ49vpxGcMoSOQY8J45WLomvceCkdfv\nXmzZMcf90v/y7yv/ZWyPtXC6C1PEfnezpMcVSfw4x8E2kPTECsaGutQs4O3d\nn+1yxRMewV1Lb0wLuD5903Ge1wVRaBdyvlQLbqzkDnVSmLiwuH2AFCwv4PN7\n6MSR8sZTbjyJSudFIRQanvPYxQtwqqECzhTEnfYig75BNkoyLSL3TeQYEbTk\nyf5JWYRPIgPB23dsiF4pX7oKn0YXK4x+v1jSxUfGxlkF1jES2qkaN5m73Ljs\nICOljzyhxPyGF+RAI/LzNXgNZdyCzvw9eA4X/XlPdQnacfd0ud74lnCHtMF6\nicgTUC5DEksr8ol7VJ5Tl92X+6yNDDpFE+EXzEvCgp9zKrRd8arEZ/dt7Bga\n/YUhGD0vSh5syAwensbx4UQl9iEH/v5Aq2yg35W7XOQfPDQb/a80vA+LUPE6\n/BivfQuZq4E00V0x8iJLKFmq2XKjiA8B93cCplXJlWky9WmAevCJtmpllp1H\nozvLoMWLDqAwT5LtxdH3Eox/94uthGLHXgi1FErJs0sERn5qSBVkR9ZQu4EW\nfowY\r\n=4FVO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEqH8lrgG4mNqOaZkuXTxjt6YG+cmS4m8aqEilDGGFoZAiAEYnll7KPiBBoeO8bNmEHxnxNpG5gAOUhZ+J7P1ozNRQ=="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.2.1_1620930766273_0.4901875997584013"},"_hasShrinkwrap":false},"4.3.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.3.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"ee95b8388b1ee0d16b6a2687fd3b2004ab71edbc","_id":"gtfs-utils@4.3.0","_nodeVersion":"16.0.0","_npmVersion":"7.12.0","dist":{"integrity":"sha512-rXrKl/yNS66NtVJCw5WBYPmpudsOIj3xBEMjrdTPvVBd/sxtMgJKSWUnQsExb8QD3Mbuqfds9+Cj+uIBRhUdTw==","shasum":"aa66dc369613175ae07d0d174c4a5e92704372ec","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.3.0.tgz","fileCount":76,"unpackedSize":259322,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgqYBQCRA9TVsSAnZWagAAgbkP/0zm4DmIFO4nkl83E33D\nyfSEVnN/HGjRKRh+Sf3DjTG+4FGlxxTwK5cZ9LC71tDXDdsJO354rsZvVsgZ\nKJQjGclPkxVG3CLEGu+Bg77dOe0l72YzWlxUoeGed3DrmUOObsqpki+MaalJ\n7KpGpZ6JC4070o9WdTiud36B3k0QAoRrZYBPl+HKZFMorl4kvPTu6cKF1O5v\n/z2aQFoXds4S9jJ+jr0OTl8NViLI//R6AgK9PCcSd72tXdTbgTg9HF5XOWWu\n/jdqKDFiAZdyYYJuRebvaGj/CTwQk4fZUyYo4i88tuj8NVzJEK3al+2t6Z+Y\newLktRKXXl97fsGbVmPIVKdKwVjQov3j+KWVT9S8pMOKzj5qxrJuZrHs7Amk\n4oUXuaxVv/cyh2BW62IdYbLzuJyqMfHjGxAeMtbpH8YepfBEiDDARPLRr+Mj\numdlggoYcekqlTw8VfFiem2bwlsbBcxp8c+6b9a1LbQvchuKl2AcFomKxtWq\nIHgIYe6iTGlYKiCb6ylBWxnJjpx3a0b9s/NFso/St20qJZDxZLvXVLn5wiB2\nOKTmYOQgSb1MmM0KtGfRnjtd1mhJNzLvUhDn95kKrGmL31fzBrt/75F25mpg\nM1fgAAF3AJrZBrul0cl/29ywNA2YRqR3ibJ7JRjw8oocv79UtCWjFzMC5bf5\nVkks\r\n=j4B2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBnph7GJLGBrUP8uex7Pwog/gcjshIIJmM0Cyo5UlInFAiAxChFYldemvuPqtw+lrPfuvtTevW+LMSoRnWmhKVxC2w=="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.3.0_1621721167485_0.6246636150321996"},"_hasShrinkwrap":false},"4.3.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.3.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"a5fdaf08291e90770db94967f86f87669dc0ebc7","_id":"gtfs-utils@4.3.1","_nodeVersion":"16.0.0","_npmVersion":"7.12.0","dist":{"integrity":"sha512-PulRcZ1W0bMAvPfzaJOS04JXCSgYAKaP838Zc3P4WLojbkqFuiJIg8FDJbvYk/abpCarYcK0BwFaAcYhhFTW0g==","shasum":"21702abce2dca22b140fa2ddd97b7e7f8a496803","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.3.1.tgz","fileCount":76,"unpackedSize":259371,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgqYwICRA9TVsSAnZWagAAJEAP/idMZP+2+rCtPpTLVICk\n+PgKdUhyElNOmriliYRgeVL35Q9Pvv9nb6Jw3jo0azfh4KmQBKKiya/amkAa\n9qPScHyrnhX+0xw5EXzChmbtYJScx/6bg2jZGPrq3b8TUg6h7gqS94yIxG1/\ndoamugcwhadj8q4i7kZxlWI5mTjO70b3G3sntlNfbqAOZTzYTITFPcZ/lBwY\n1T6sohbIA/Wv94ejgtajKN6t6wnbAcxr3Ks6TnWyq6WA1pyWP+Mn3tzwfJDM\nfBoKMqmv7sa3OvEqT4WgR0mcIXDbutBXpA6Yoma3g5G6k4RX8XXGJb9A/ztY\nEjOUGssVHv3zkZzfJcsqsbHOlnLeDNhbncDFfwF1UARfJOhO9kAlGzCIr91n\nrEMjfzhkm7z+bIFrINOMxOj+cUV2tMHqvLiepHtbRbGZbucksLuIBAePDBNM\njqpwLNpKE839VNUabmxUk30TuDNUsoa9mRHf3ZgMdc/7zYSJ0T31+6UYL6sE\n9qZCE4c/iDa8anLnqAEZpGJu+3fdlHP7OkquROOhbuJXtMEBwkp3zRr3tRn8\npiCRkygXtK5XBwF2esUXNa8SeajPDR8s+xvBadE5JbsoAiYuMW37LPJkLH0g\nPWa5EC23Se4cKdsdiIAe+uG+Vk6tHPPDXCQ/gEOq/6qJckZN9dOEBYt4njWu\nXvj1\r\n=dKhR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE7WzuUNQH7FG0+eXtmLD53qHOgQKWeirH5tSZjjK7CPAiEAwWjJNn8sFpPqB4d99ROav4QeGCJRJMfBDdoymxcMfrE="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.3.1_1621724168123_0.771840235791341"},"_hasShrinkwrap":false},"5.0.0-alpha.1":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"5.0.0-alpha.1","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=14"},"dependencies":{"@turf/bearing":"^6.3.0","@turf/destination":"^6.3.0","@turf/distance":"^6.3.0","@turf/line-intersect":"^6.3.0","csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark/index.js","prepublishOnly":"npm test && npm run lint"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://gtfs.org/reference/static/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n![minimum Node.js version](https://img.shields.io/node/v/gtfs-utils.svg)\n[![support me via GitHub Sponsors](https://img.shields.io/badge/support%20me-donate-fa7664.svg)](https://github.com/sponsors/derhuerst)\n[![chat with me on Twitter](https://img.shields.io/badge/chat%20with%20me-on%20Twitter-1da1f2.svg)](https://twitter.com/derhuerst)\n\n- ✅ supports `frequencies.txt`\n- ✅ works in the browser\n- ✅ fully asynchronously/streaming\n\n\n## Design goals\n\n### streaming/iterative on sorted data\n\nAs [public transportation systems will hopefully become more integrated](https://github.com/public-transport/why-linked-open-transit-data#why-linked-open-transit-data) over time, GTFS datasets will often be multiple GBs large. GTFS processing should work in memory-constrained Raspberry Pis or [FaaS](https://en.wikipedia.org/wiki/Function_as_a_service) environments as well.\n\nWhenever possible, all `gtfs-utils` tools will only read as little data into memory as possible. For this, the individual files in a GTFS dataset need to be sorted in a way that allows iterative processing (see below).\n\nRead more in the [*performance* section](#performance).\n\n### data-source-agnostic\n\n`gtfs-utils` does not make assumptions about where you read the GTFS data from. Although it has a built-in tool to read CSV from files on disk, anything is possible: [`.zip` archives](docs/zip.md), [HTTP requests](docs/fetch.md), in-memory [buffers](https://nodejs.org/api/buffer.html), [dat](https://dat.foundation)/[IPFS](https://ipfs.io), etc.\n\nThere are too many half-done, slightly opinionated GTFS processing tools out there, so `gtfs-utils` tries to be as universal as possible.\n\n### correct\n\nAside from new features of the ever-expanded GTFS spec that change the expected behavior of old ones (and bugs of course), `gtfs-utils` tries to follow the spec closely.\n\nFor example, it will, when computing the absolute timestamp/instant of an arrival at a stop, always take into account `stop_timezone` or the user-supplied timezone, because [`stop_times.txt` uses \"wall clock time\"](https://gist.github.com/derhuerst/574edc94981a21ef0ce90713f1cff7f6).\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n[API documentation](docs/api.md)\n\n### sorted GTFS files\n\n**`gtfs-utils` assumes that the files in your GTFS dataset are [sorted in a particular way](#sorted-gtfs-files)**; This allows it to compute some data aggregations more memory-efficiently, which means that you can use it to process [very large](#performance) datasets. For example, if [`trips.txt`](https://gtfs.org/reference/static/#tripstxt) and [`stop_times.txt`](https://gtfs.org/reference/static/#stop_timestxt) are both sorted by `trip_id`, `computeStopovers()` can read each file incrementally, only rows for *one* `trip_id` at a time.\n\n[Miller](https://miller.readthedocs.io/) and [`sponge`](https://linux.die.net/man/1/sponge) work very well for this:\n\n```shell\nmlr --csv sort -f agency_id agency.txt | sponge agency.txt\nmlr --csv sort -f parent_station -nr location_type stops.txt | sponge stops.txt\nmlr --csv sort -f route_id routes.txt | sponge routes.txt\nmlr --csv sort -f trip_id trips.txt | sponge trips.txt\nmlr --csv sort -f trip_id -n stop_sequence stop_times.txt | sponge stop_times.txt\nmlr --csv sort -f service_id calendar.txt | sponge calendar.txt\nmlr --csv sort -f service_id,date calendar_dates.txt | sponge calendar_dates.txt\nmlr --csv sort -f trip_id,start_time frequencies.txt | sponge frequencies.txt\n```\n\nThere's also a [`sort.sh` script](sort.sh) included in the npm package, which executes the commands above.\n\n*Note:* For read-only sources (like HTTP requests), sorting the files is not an option. You can solve this by [spawning](https://nodejs.org/docs/latest-v12.x/api/child_process.html#child_process_child_process_spawn_command_args_options) `mlr` and piping data through it.\n\n*Note:* With a bit of extra code, you can also use `gtfs-utils` [with a `.zip` archive](docs/zip.md) or [with a *remote* feed](docs/fetch.md).\n\n### basic example\n\nGiven our [sample GTFS dataset](https://npmjs.com/package/sample-gtfs-feed), we'll answer the following question: **On a specific day, which vehicles of which lines stop at a specific station?**\n\nWe define a function `readFile` that reads our GTFS data into a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams)/[async iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator). In this case we'll read CSV files from disk using the built-in `readCsv` helper:\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nconst readFile = (file) => {\n\treturn readCsv(require.resolve('sample-gtfs-feed/gtfs/' + file + '.txt'))\n}\n```\n\n[`computerStopovers()`](docs/api.md#computestopovers) will read [`calendar.txt`](https://gtfs.org/reference/static/#calendartxt), [`calendar_dates.txt`](https://gtfs.org/reference/static/#calendar_datestxt), [`trips.txt`](https://gtfs.org/reference/static/#tripstxt), [`stop_times.txt`](https://gtfs.org/reference/static/#stop_timestxt) & [`frequencies.txt`](https://gtfs.org/reference/static/#frequenciestxt) and return all *stopovers* of all trips across the full time frame of the dataset.\n\nIt returns an [async generator function](https://javascript.info/async-iterators-generators#async-generators) (which thus is [async-iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator)), so we can use `for await`.\n\nIn the following example, we're going to print all stopovers at `airport` on the 5th of May 2019:\n\n```js\nconst {DateTime} = require('luxon')\nconst computeStopovers = require('gtfs-utils/compute-stopovers')\n\nconst day = '2019-05-15'\nconst isOnDay = (t) => {\n\tconst iso = DateTime.fromMillis(t * 1000, {zone: 'Europe/Berlin'}).toISO()\n\treturn String(t).slice(0, day.length) === day\n}\n\nconst stopovers = await computeStopovers(readFile, 'Europe/Berlin')\nfor await (const stopover of stopovers) {\n\tif (stopover.stop_id !== 'airport') continue\n\tif (!isOnDay(stopover.arrival)) continue\n\tconsole.log(stopover)\n}\n```\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'a-downtown-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'A',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557926580,\n\tdeparture: 1557926640,\n}\n{\n\tstop_id: 'airport',\n\ttrip_id: 'a-outbound-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'A',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557933900,\n\tdeparture: 1557933960,\n}\n// …\n{\n\tstop_id: 'airport',\n\ttrip_id: 'c-downtown-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'C',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557926820,\n\tdeparture: 1557926880,\n}\n```\n\nFor more examples, check the [API documentation](docs/api.md).\n\n\n## Performance\n\nBy default, `gtfs-utils` verifies that the input files are sorted correctly. You can disable this to improve performance slightly by running with the `CHECK_GTFS_SORTING=false` environment variable.\n\n`gtfs-utils` should be fast enough for small to medium-sized GTFS datasets. It won't be as fast as other GTFS tools because it\n\n- uses [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) extensively for memory-efficiency and an easy-of-use, which [currently has significant performance penalties in v8](https://github.com/nodejs/node/issues/31979).\n- is written in JavaScript, so it cannot optimise the memory layout of its data structures.\n- parses all columns of a file it needs information from, into a JavaScript object.\n\nOn my laptop, using `computeStopovers` on the [180mb `2021-02-04` *HVV* GTFS dataset](https://suche.transparenz.hamburg.de/dataset/hvv-fahrplandaten-gtfs-februar-2021-bis-dezember-2021) (25k `stops.txt` rows, 90k `trips.txt` rows, 1.9m `stop_times.txt` rows, ~500m stopovers) finishes in several hours.\n\n*Note:* If you want a faster way to query and transform GTFS datasets, I suggest you to use [`gtfs-via-postgres`](https://github.com/derhuerst/gtfs-via-postgres) to leverage PostgreSQL's query optimizer. Once you have imported the data, it is usually orders of magnitude faster.\n\n\n## Related\n\n- [gtfstidy](https://github.com/patrickbr/gtfstidy) – Go command line tool for validating and tidying GTFS feeds.\n- [gtfs-stream](https://github.com/staeco/gtfs-stream) – Streaming GTFS and GTFS-RT parser for node\n- [mapzen-gtfs](https://github.com/transitland/mapzen-gtfs) – Python library for reading and writing GTFS feeds. (Python)\n- [gtfspy](https://github.com/CxAalto/gtfspy) – Public transport network analysis using Python\n- [extract-gtfs-shapes](https://github.com/derhuerst/extract-gtfs-shapes) – Command-line tool to extract shapes from a GTFS dataset.\n- [extract-gtfs-pathways](https://github.com/derhuerst/extract-gtfs-pathways) – Command-line tool to extract pathways from a GTFS dataset.\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"cb009c4760f6a8919a57c104f041f92af7382b5c","_id":"gtfs-utils@5.0.0-alpha.1","_nodeVersion":"16.2.0","_npmVersion":"7.13.0","dist":{"integrity":"sha512-7nNxAp7MC3C7WKyAq+y0e2BhNruu7qgDUHW0lXlLCiR2YXdLPLdJXVahlsrknU4tAz7VuybNi7K53eEmF5+bkA==","shasum":"e7bf7e87c759ff1f1f9c0174a697b36c32072441","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-5.0.0-alpha.1.tgz","fileCount":85,"unpackedSize":667513,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgv46KCRA9TVsSAnZWagAAQqsQAIB/B2YVxLM2D3sLUzcx\nIh/uvX1T3hY50iGSRuu9eqoTMXtJ7SVM3mfHS0yKyXk3ZohbxG8ZZLZAODqa\n7Wo2TI5T8KRwmdls/QMCkeWc/8u2HxFbW3rO1MFhIbDfyLvcJcpbusy1DLzP\nt44AMHU7PBuYg+7E6+rgXwoIZukdIpZy5Cz8GGUINfDSce3mq4ih32wVemGh\nDaHWXCDWGkpXNrxrvm/yZF57od2W57Fh0k0ql+bH2qfDjMbtFJfxG8rNuQHP\n/DiDdKoZuqJGLCJSw9GpJdZhcw+2682qTvEvjfdUO2PbSl0l4TtzGzofC6MM\nnitA9iciR0TNTkkkcN404ikD+cIct3qoSjyICzhyRbD+UQ5cQFPvj8kJv+eO\nwCWNTry8GrrTRy5RQX63XThi5hs+XlTdO1wLdH6jObi666fNK1Zb2HBEa8gf\nQU5T9sjUBYFvhv+0eaFkaxdIheEHgs0DvK73Si9PARFrDIyY4GK3z6Opry3P\n/jEqdQlGhtEsaI8qBC64Clrj102OJPKkm7xSKo6aqcJiZO6pzEw9pMXqxWfo\ngHb22t0l2tXdRI98VwlJ4rQeyWeUeWvkH8O9wa70fNsXyC/ZJbDMbl0Z1tit\nEqVliA0hmZz45PssQ1qXfkFKf+wy4rI7hP/8mOLJX4yaohhgcyRt2Futxzvt\nSueC\r\n=Cl1l\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF7Jj5/Nj62t4GKH8ghqfb5etfRxzzCWJZLUk35J2+FOAiAKMjGSL40HGsJBfyqM0HWB0QJ4gUQGyWXwlkb7GIwoIw=="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_5.0.0-alpha.1_1623166602579_0.8378066531832613"},"_hasShrinkwrap":false},"5.0.0-alpha.2":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"5.0.0-alpha.2","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=14"},"dependencies":{"@turf/bearing":"^6.3.0","@turf/destination":"^6.3.0","@turf/distance":"^6.3.0","@turf/line-intersect":"^6.3.0","csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark/index.js","prepublishOnly":"npm test && npm run lint"},"readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://gtfs.org/reference/static/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n![minimum Node.js version](https://img.shields.io/node/v/gtfs-utils.svg)\n[![support me via GitHub Sponsors](https://img.shields.io/badge/support%20me-donate-fa7664.svg)](https://github.com/sponsors/derhuerst)\n[![chat with me on Twitter](https://img.shields.io/badge/chat%20with%20me-on%20Twitter-1da1f2.svg)](https://twitter.com/derhuerst)\n\n- ✅ supports `frequencies.txt`\n- ✅ works in the browser\n- ✅ fully asynchronously/streaming\n\n\n## Design goals\n\n### streaming/iterative on sorted data\n\nAs [public transportation systems will hopefully become more integrated](https://github.com/public-transport/why-linked-open-transit-data#why-linked-open-transit-data) over time, GTFS datasets will often be multiple GBs large. GTFS processing should work in memory-constrained Raspberry Pis or [FaaS](https://en.wikipedia.org/wiki/Function_as_a_service) environments as well.\n\nWhenever possible, all `gtfs-utils` tools will only read as little data into memory as possible. For this, the individual files in a GTFS dataset need to be sorted in a way that allows iterative processing (see below).\n\nRead more in the [*performance* section](#performance).\n\n### data-source-agnostic\n\n`gtfs-utils` does not make assumptions about where you read the GTFS data from. Although it has a built-in tool to read CSV from files on disk, anything is possible: [`.zip` archives](docs/zip.md), [HTTP requests](docs/fetch.md), in-memory [buffers](https://nodejs.org/api/buffer.html), [dat](https://dat.foundation)/[IPFS](https://ipfs.io), etc.\n\nThere are too many half-done, slightly opinionated GTFS processing tools out there, so `gtfs-utils` tries to be as universal as possible.\n\n### correct\n\nAside from new features of the ever-expanded GTFS spec that change the expected behavior of old ones (and bugs of course), `gtfs-utils` tries to follow the spec closely.\n\nFor example, it will, when computing the absolute timestamp/instant of an arrival at a stop, always take into account `stop_timezone` or the user-supplied timezone, because [`stop_times.txt` uses \"wall clock time\"](https://gist.github.com/derhuerst/574edc94981a21ef0ce90713f1cff7f6).\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n[API documentation](docs/api.md)\n\n### sorted GTFS files\n\n**`gtfs-utils` assumes that the files in your GTFS dataset are [sorted in a particular way](#sorted-gtfs-files)**; This allows it to compute some data aggregations more memory-efficiently, which means that you can use it to process [very large](#performance) datasets. For example, if [`trips.txt`](https://gtfs.org/reference/static/#tripstxt) and [`stop_times.txt`](https://gtfs.org/reference/static/#stop_timestxt) are both sorted by `trip_id`, `computeStopovers()` can read each file incrementally, only rows for *one* `trip_id` at a time.\n\n[Miller](https://miller.readthedocs.io/) and [`sponge`](https://linux.die.net/man/1/sponge) work very well for this:\n\n```shell\nmlr --csv sort -f agency_id agency.txt | sponge agency.txt\nmlr --csv sort -f parent_station -nr location_type stops.txt | sponge stops.txt\nmlr --csv sort -f route_id routes.txt | sponge routes.txt\nmlr --csv sort -f trip_id trips.txt | sponge trips.txt\nmlr --csv sort -f trip_id -n stop_sequence stop_times.txt | sponge stop_times.txt\nmlr --csv sort -f service_id calendar.txt | sponge calendar.txt\nmlr --csv sort -f service_id,date calendar_dates.txt | sponge calendar_dates.txt\nmlr --csv sort -f trip_id,start_time frequencies.txt | sponge frequencies.txt\n```\n\nThere's also a [`sort.sh` script](sort.sh) included in the npm package, which executes the commands above.\n\n*Note:* For read-only sources (like HTTP requests), sorting the files is not an option. You can solve this by [spawning](https://nodejs.org/docs/latest-v12.x/api/child_process.html#child_process_child_process_spawn_command_args_options) `mlr` and piping data through it.\n\n*Note:* With a bit of extra code, you can also use `gtfs-utils` [with a `.zip` archive](docs/zip.md) or [with a *remote* feed](docs/fetch.md).\n\n### basic example\n\nGiven our [sample GTFS dataset](https://npmjs.com/package/sample-gtfs-feed), we'll answer the following question: **On a specific day, which vehicles of which lines stop at a specific station?**\n\nWe define a function `readFile` that reads our GTFS data into a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams)/[async iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator). In this case we'll read CSV files from disk using the built-in `readCsv` helper:\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nconst readFile = (file) => {\n\treturn readCsv(require.resolve('sample-gtfs-feed/gtfs/' + file + '.txt'))\n}\n```\n\n[`computerStopovers()`](docs/api.md#computestopovers) will read [`calendar.txt`](https://gtfs.org/reference/static/#calendartxt), [`calendar_dates.txt`](https://gtfs.org/reference/static/#calendar_datestxt), [`trips.txt`](https://gtfs.org/reference/static/#tripstxt), [`stop_times.txt`](https://gtfs.org/reference/static/#stop_timestxt) & [`frequencies.txt`](https://gtfs.org/reference/static/#frequenciestxt) and return all *stopovers* of all trips across the full time frame of the dataset.\n\nIt returns an [async generator function](https://javascript.info/async-iterators-generators#async-generators) (which thus is [async-iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator)), so we can use `for await`.\n\nIn the following example, we're going to print all stopovers at `airport` on the 5th of May 2019:\n\n```js\nconst {DateTime} = require('luxon')\nconst computeStopovers = require('gtfs-utils/compute-stopovers')\n\nconst day = '2019-05-15'\nconst isOnDay = (t) => {\n\tconst iso = DateTime.fromMillis(t * 1000, {zone: 'Europe/Berlin'}).toISO()\n\treturn String(t).slice(0, day.length) === day\n}\n\nconst stopovers = await computeStopovers(readFile, 'Europe/Berlin')\nfor await (const stopover of stopovers) {\n\tif (stopover.stop_id !== 'airport') continue\n\tif (!isOnDay(stopover.arrival)) continue\n\tconsole.log(stopover)\n}\n```\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'a-downtown-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'A',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557926580,\n\tdeparture: 1557926640,\n}\n{\n\tstop_id: 'airport',\n\ttrip_id: 'a-outbound-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'A',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557933900,\n\tdeparture: 1557933960,\n}\n// …\n{\n\tstop_id: 'airport',\n\ttrip_id: 'c-downtown-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'C',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557926820,\n\tdeparture: 1557926880,\n}\n```\n\nFor more examples, check the [API documentation](docs/api.md).\n\n\n## Performance\n\nBy default, `gtfs-utils` verifies that the input files are sorted correctly. You can disable this to improve performance slightly by running with the `CHECK_GTFS_SORTING=false` environment variable.\n\n`gtfs-utils` should be fast enough for small to medium-sized GTFS datasets. It won't be as fast as other GTFS tools because it\n\n- uses [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) extensively for memory-efficiency and an easy-of-use, which [currently has significant performance penalties in v8](https://github.com/nodejs/node/issues/31979).\n- is written in JavaScript, so it cannot optimise the memory layout of its data structures.\n- parses all columns of a file it needs information from, into a JavaScript object.\n\nOn my laptop, using `computeStopovers` on the [180mb `2021-02-04` *HVV* GTFS dataset](https://suche.transparenz.hamburg.de/dataset/hvv-fahrplandaten-gtfs-februar-2021-bis-dezember-2021) (25k `stops.txt` rows, 90k `trips.txt` rows, 1.9m `stop_times.txt` rows, ~500m stopovers) finishes in several hours.\n\n*Note:* If you want a faster way to query and transform GTFS datasets, I suggest you to use [`gtfs-via-postgres`](https://github.com/derhuerst/gtfs-via-postgres) to leverage PostgreSQL's query optimizer. Once you have imported the data, it is usually orders of magnitude faster.\n\n\n## Related\n\n- [gtfstidy](https://github.com/patrickbr/gtfstidy) – Go command line tool for validating and tidying GTFS feeds.\n- [gtfs-stream](https://github.com/staeco/gtfs-stream) – Streaming GTFS and GTFS-RT parser for node\n- [mapzen-gtfs](https://github.com/transitland/mapzen-gtfs) – Python library for reading and writing GTFS feeds. (Python)\n- [gtfspy](https://github.com/CxAalto/gtfspy) – Public transport network analysis using Python\n- [extract-gtfs-shapes](https://github.com/derhuerst/extract-gtfs-shapes) – Command-line tool to extract shapes from a GTFS dataset.\n- [extract-gtfs-pathways](https://github.com/derhuerst/extract-gtfs-pathways) – Command-line tool to extract pathways from a GTFS dataset.\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md","gitHead":"d577577487dcbb5a6d3bb1373dfd16c116e2fa4a","_id":"gtfs-utils@5.0.0-alpha.2","_nodeVersion":"16.3.0","_npmVersion":"7.15.1","dist":{"integrity":"sha512-3LGfxgLazB9EMofzg1/pKTKIPRT7929nP9JUeKh2I0hyVAduj9Xbd1JGpcMCzsq5NWf69THx2lsXFtP1hA2sCQ==","shasum":"ac4131f33f18342020df09679750ce96f7f515bf","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-5.0.0-alpha.2.tgz","fileCount":85,"unpackedSize":667515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgv8bzCRA9TVsSAnZWagAA1OQP/A9nR5BAxBG426tBQJ8Z\nLv1f6FXp8Ale4W9pGxlvwV2tMo9MK8b8VmVbYTek5PcfIqHxSYUcZUUd4hqS\nlw79ZKfqUceX/KJwZe/PSvWqPfbgGTP6qfVY3f3wrDliNzCoIDugP23LBVj3\nYfFcUWzCXoSUHSjO4qqG3k70Uf8Ltd8xivv8QFvLR5La6pm9IRMNvgMq8V2m\nnQWcDfQzKML/1Oo/4SX56PcSIuDUoT1EpnCgqxwRPQbZZ8RmGQUTtLVpP0ld\nSsUnGmNN2cd2PDT7KuHcSNuJ+z9SOFEN1TJ+3FKcWjui2850Cuz8sciOJTGa\nwHpxG2UnZ6wXCka2JJLlnuOY1Njl2NmVlPhDSuWP4Sdeql3lMgfEAcvJYPNd\ndYyA1t8DRzQ1+hjMga0yPg3wU52R6q4g2yMHqOAoiuNdwXiihC6wL9noKFrx\nc3fi8BkSZCfRbPY0JrEXAOlNesHqb5zZVnpLrv8htmlG52Nyo5kS9RtfCCfP\nacEHpiC+Q8ZtmTQ185hNiVqFOJ05Yt6zOPmx55xNfN5t3wtspugGHBQi2uy0\n1GC/gqNqX5N2NsEQVZUZ0IBOuOlkDAHOD75s9mJofMvTHMbswtmkiqZal+BN\nWp0WsAsRc2nU8C31OhLRrjztQgZOqNASqmTZSZLRJ8sVtkyN8riyqfgwYRnb\naka1\r\n=wqJI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGMBL9SP74EXNard999MIkJO4crp9VtqoOCNpJoc5vk4AiEA+RMYFF6b6mVA8yPCv9tnN0KGFbALGXdB0OK58rsN/v8="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_5.0.0-alpha.2_1623181043523_0.8578535211836025"},"_hasShrinkwrap":false},"5.0.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"5.0.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=16"},"dependencies":{"@turf/bearing":"^6.3.0","@turf/destination":"^6.3.0","@turf/distance":"^6.3.0","@turf/line-intersect":"^6.3.0","csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^2.3.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^8.7.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark/index.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"8d375761255776faf79bdd06c04d02fb8f793f70","_id":"gtfs-utils@5.0.0","_nodeVersion":"17.4.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-OOb7Ai1AAVQrBZlvHdzepp2lB2ziVJcJn6xZOBQzQ5KFuBzYK8rCzd7GU5bRRmehhEaIHaVhz6kK6TteNvuUQQ==","shasum":"41c99399978a9d56140cc6da9e94e43058ea8ffc","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-5.0.0.tgz","fileCount":94,"unpackedSize":676334,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8KFzCRA9TVsSAnZWagAAKG0QAIRXWAIUEIS5tp2hKnyz\nALIokOo1pqWDyz723tVoZuQCNTFImAXmhv5Fl1PjwzP7G51GJf8iplehX8Iz\nMTxhzBG/RX+rTksEQWbHprrT0eoVTbAxpXF1NmcNA+X54A2hUzr0UBBuPWyy\nGYiPKMafjHBfGKPr+Iy6PeuVpp0OQ9T8X1fY2lRNimV2Taa2LoE6bYpv22Iq\nUnl11yIkE/jRnnsD45xTkxF6cvwmLmHXKfN5WkIFJOdgbWAFL92sXRDKOh9L\nS5VNuwRFqzT8NwwUAqNEHmeWJn/iDTUedUu/AelzGFS+gLpXF018y8L5KsSJ\ngJTdoBgf2eONXWe6dMvH/VzICzi2wYPBk6FHJcBx65MG0qQVwskMo54iyrOT\not6OrcdQLf8svGPcD8ip6aASgDeF61NPCQKsaZnli6IdYZdPgb+vwIRtzeQe\nbiaVTk0Ka22utORWOGte7YGjPGvcvWtkSPnM7rjUlY4a7rummAUWHWzrENse\nqPV4wSMuEjF1iv/f1VmchtyqWO730AOBrxFuI37oHsZi9xabq7ZmH4ZROFcR\nfBv8xNS6nvtl+kl+kgcmxaBNS3HC67YZxeWGTFC2fMScAYTooFkZq1L7m/sJ\nCqjXil+t6gPU3ieZD6m3uRtlAvkCOhQ58WexI/olsAtXzYBbs/Jjkn5Psjd0\nYdmk\r\n=jQcR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHJ1HY8ydre3qTR7sWzgWcsHYQNUytCz3hA5Vps85aeLAiAt/2C3e5n3jht/GaXozTeJK27SOloMfLC6/ZLxijdAyw=="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_5.0.0_1643159923206_0.9677402615231498"},"_hasShrinkwrap":false},"4.3.2":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"4.3.2","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=12"},"dependencies":{"csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^1.0.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^7.1.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"44586c23ffab195fd76cd80cddd39b958012a630","_id":"gtfs-utils@4.3.2","_nodeVersion":"17.4.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-7CSMw1yziHruL23AKWqnN0lP/PQyMJyZuH4qIzlF9B7AzGImxlNe76N+MwqKrs91sY+2ATb6tm6PlQzExTSnxQ==","shasum":"db011af0059028f2c160d7244d4d08561d3c4923","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-4.3.2.tgz","fileCount":78,"unpackedSize":481015,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh8KM+CRA9TVsSAnZWagAAsfsP/j8Nx9eQkA78idZAxvKt\nujUeY29WIrYlUdpg6ZIGRrcxYKMnNU1DTy6UXdd+XVL3hSUWi9hLMFWOUDFE\nDVj509uXa8Onp2BEPn276ixrNVamFIPaqz31kpQuW109WalKfYytBibjmpyL\nvaLChuYaLUsG4A6V6ecUjVsNMe8JqK0lzn81ismrOe48qYF9NW6g+T5zDDtz\nhcPnqwxwz/OEgRp4noA+mmVpKKILqrO7aSo8/F+x9w+AOxBjYV8vllk2rgQ4\nlac/ZwuvPwI3roMbai9i4ibLM0/mpmo1swB4G5OwQMPS4dOwsUaBefBKT+IY\nBZkl+uUbne2szpVT4aLg1B4VLpqZ7nPANvqB9dcjuUx5FgOl+h37033KrxfA\nluwa7bTf9/LiLelLv6qh0UMs88RUx9kuv6Q2U7q5r1nwZh6dZok6QRymKCD8\nxf3pOhA0lMh4eSeZWBJfXOONxwGT+fy3aepNOb1FsWuOWEeDuFpKob3A5Dje\nPK/xavl5uhxIBE+UZIbSLcwd9n9T8wDWSfp24Bl+mdqyYZ4L+FDTuRqouiQb\nOjEOWbVs7kmkPUMJ73KYj//pvwfkywuBu24iRgMECdxPWczcFyeqvoyraOY8\nD3d3CkRdsk0DuMH7txEgUKLT8VdjI4F4KxgpG9facTky4RTNTFf6RTDK527i\n9XKk\r\n=zbtA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpR+jPviQ0BQaCe6UdT6bWkPoDouNbpK03L2lzJEUlZAIgM2NiQVYkVNDTcvBlmOtqLz68KmGaDmtbZ9yqp5fE6u4="}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_4.3.2_1643160382102_0.9110699228230996"},"_hasShrinkwrap":false},"5.1.0":{"name":"gtfs-utils","description":"Utilities to process GTFS data sets.","version":"5.1.0","keywords":["gtfs","public transport","transit"],"author":{"name":"Jannis R","email":"mail@jannisr.de"},"homepage":"https://github.com/public-transport/gtfs-utils","repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","engines":{"node":">=16"},"dependencies":{"@turf/bearing":"^6.3.0","@turf/destination":"^6.3.0","@turf/distance":"^6.3.0","@turf/line-intersect":"^6.3.0","csv-parser":"^3.0.0","date-fns":"^2.12.0","date-fns-tz":"^1.0.10","debug":"^4.1.1","ioredis":"^4.17.3","is-stream":"^2.0.0","luxon":"^2.3.0","quick-lru":"^5.1.1","shorthash":"0.0.2","sorted-array-functions":"^1.2.0","strip-bom-stream":"^4.0.0"},"devDependencies":{"benchmark":"^2.1.4","eslint":"^8.7.0","json5":"^2.1.3","node-stream-zip":"^1.13.2","sample-gtfs-feed":"^0.10.3","tap-min":"^2.0.0","tape":"^5.0.0"},"scripts":{"test":"env NODE_ENV=dev node test/index.js | tap-min","lint":"eslint .","benchmark":"env NODE_ENV=production node benchmark/index.js","prepublishOnly":"npm test && npm run lint"},"gitHead":"2828d0a4f82e3fbca51b7eb9324ea66da8e1870e","_id":"gtfs-utils@5.1.0","_nodeVersion":"17.5.0","_npmVersion":"8.4.1","dist":{"integrity":"sha512-wUhVxvuzdeithRHOzbOP0CcwH/U12C5mw33AbyuGLDZ+XSv7Hc7y6kfuvb0UioruF2UKYcNcuruWEOn7/0D21Q==","shasum":"af2ff678f232f5499fa9040e58e0f63e420d02bb","tarball":"https://registry.npmjs.org/gtfs-utils/-/gtfs-utils-5.1.0.tgz","fileCount":97,"unpackedSize":686624,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiGlTqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrclw//TTyoinzCG+LeP6Hx7mRVx4g3HxSAcysExseZ+ik0cLD5u9fO\r\nvGlPr/7B8rzzjIcM50t18qqiSKY7cN1Z25IyYgRg+YGNERebjN/6IIJnQtys\r\nGLiahvq6DSXX8t4V5CgJKKSyOBKbrb9k6lQm7IrYyBeIS/5VoAl1AxFkcqGd\r\nT5Xa96YNIWWRxaZ1YIM65c4yJsiUVGWV69xQTEXvPlERM5JTEDauDHIXqOyY\r\nkbMtiSErEST5Ov0CbT4HqNMh1MfsegUkj3JNZw9z8iit1VwYJSP6jc6E342c\r\nEU7a8jQuL2m622TGRbYGlnEhrQ3ugn7/F0GGYsHkAwWswawvRXnrcN3fcyOi\r\ndj7rsgl2a+TJ3RLLNdVmpR+8T51BcZUfUecS0GDHFEc5SUCPPuhjm8tCNyZa\r\n3iiKgiCSjhpcG7/4hmh4/UXGHySRcKWjQNMrreHviC5EigNVU3hyz7QxYyjl\r\n15t/gPUgpZOvwGz40S+BFY2nzP+wu4CSf205f/Z4WWk66tv4QZXzucPL8mUd\r\n2jPP6xZi2/OO94iKY0G7SRQ+lo/GPqEWqTgrc7przlaE4Z+w0Y3Tc1NMVOQ1\r\n1RBQ4sMLxH8F7SQMC49/9hpDqS/igbkpub50uvEuvw2/83smQo8H6k4PjJ6t\r\n+H03klzOZXAcammn6lzHMu9oneuyDC6GROw=\r\n=BuIE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/f3BVUbzDUMeJIrgjqfWG6zjWKxuT26njeKMEzaxRtQIhAMcLCtOk/YbDjpD4uSNIMoAQpytUrOXh+bUpzxuizdVY"}]},"_npmUser":{"name":"derhuerst","email":"mail@jannisr.de"},"directories":{},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gtfs-utils_5.1.0_1645892842163_0.2600584168140727"},"_hasShrinkwrap":false}},"time":{"created":"2018-02-14T20:19:31.858Z","0.1.0":"2018-02-14T20:19:32.569Z","modified":"2022-05-04T09:05:02.737Z","0.1.1":"2018-02-14T23:45:25.478Z","0.2.0":"2018-02-14T23:46:34.485Z","0.2.1":"2018-02-14T23:47:59.490Z","0.2.2":"2018-02-15T00:11:43.311Z","0.2.3":"2018-02-15T00:47:37.296Z","0.2.4-alpha.1":"2018-02-17T00:59:42.748Z","0.2.4":"2018-02-17T12:49:39.125Z","0.3.0":"2018-02-18T16:46:05.927Z","0.3.1":"2018-02-18T16:58:02.240Z","0.4.0-alpha.1":"2018-02-18T22:22:28.850Z","0.4.0-alpha.2":"2018-02-18T22:51:57.141Z","0.4.0-alpha.3":"2018-02-18T23:26:29.868Z","0.4.0-alpha.4":"2018-02-19T00:52:53.730Z","0.4.0-alpha.5":"2018-02-19T10:27:04.902Z","0.4.0-alpha.6":"2018-02-19T10:33:00.239Z","0.4.0-alpha.7":"2018-02-19T10:47:15.290Z","0.4.0":"2018-02-23T16:29:00.233Z","0.4.1":"2018-02-24T14:48:13.062Z","0.4.2":"2018-09-09T16:26:16.047Z","0.5.0":"2018-09-09T19:37:41.400Z","0.5.1":"2018-09-15T11:46:31.949Z","0.6.0":"2018-09-17T08:41:12.765Z","0.6.1":"2019-04-07T13:37:15.210Z","1.0.0":"2019-07-14T17:04:45.303Z","1.0.1":"2020-04-18T15:45:34.455Z","2.0.0":"2020-04-18T23:47:15.595Z","2.0.1":"2020-06-03T21:57:20.370Z","1.0.2":"2020-06-04T16:55:14.374Z","2.1.0":"2020-06-04T17:51:39.677Z","3.0.0":"2020-08-30T13:57:09.083Z","3.0.1":"2020-10-29T16:01:06.571Z","2.1.1":"2021-01-03T18:42:51.154Z","3.1.0":"2021-02-23T21:20:53.636Z","4.0.0":"2021-02-28T14:58:06.715Z","4.1.0":"2021-04-14T17:42:12.860Z","4.2.0":"2021-04-22T10:14:49.530Z","4.2.1":"2021-05-13T18:32:46.458Z","4.3.0":"2021-05-22T22:06:07.617Z","4.3.1":"2021-05-22T22:56:08.308Z","5.0.0-alpha.1":"2021-06-08T15:36:42.697Z","5.0.0-alpha.2":"2021-06-08T19:37:23.658Z","5.0.0":"2022-01-26T01:18:43.446Z","4.3.2":"2022-01-26T01:26:22.263Z","5.1.0":"2022-02-26T16:27:22.377Z"},"maintainers":[{"name":"derhuerst","email":"mail@jannisr.de"}],"description":"Utilities to process GTFS data sets.","homepage":"https://github.com/public-transport/gtfs-utils","keywords":["gtfs","public transport","transit"],"repository":{"type":"git","url":"git+https://github.com/public-transport/gtfs-utils.git"},"author":{"name":"Jannis R","email":"mail@jannisr.de"},"bugs":{"url":"https://github.com/public-transport/gtfs-utils/issues"},"license":"ISC","readme":"# gtfs-utils\n\n**Utilities to process [GTFS](https://gtfs.org/reference/static/) data sets.**\n\n[![npm version](https://img.shields.io/npm/v/gtfs-utils.svg)](https://www.npmjs.com/package/gtfs-utils)\n![ISC-licensed](https://img.shields.io/github/license/public-transport/gtfs-utils.svg)\n![minimum Node.js version](https://img.shields.io/node/v/gtfs-utils.svg)\n[![support me via GitHub Sponsors](https://img.shields.io/badge/support%20me-donate-fa7664.svg)](https://github.com/sponsors/derhuerst)\n[![chat with me on Twitter](https://img.shields.io/badge/chat%20with%20me-on%20Twitter-1da1f2.svg)](https://twitter.com/derhuerst)\n\n- ✅ supports `frequencies.txt`\n- ✅ works in the browser\n- ✅ fully asynchronous/streaming\n\n\n## Design goals\n\n### streaming/iterative on sorted data\n\nAs [public transportation systems will hopefully become more integrated](https://github.com/public-transport/why-linked-open-transit-data#why-linked-open-transit-data) over time, GTFS datasets will often be multiple GBs large. GTFS processing should work in memory-constrained Raspberry Pis or [FaaS](https://en.wikipedia.org/wiki/Function_as_a_service) environments as well.\n\nWhenever possible, all `gtfs-utils` tools will only read as little data into memory as possible. For this, the individual files in a GTFS dataset need to be [sorted in a way](#sorted-gtfs-files) that allows iterative processing.\n\nRead more in the [*performance* section](#performance).\n\n### data-source-agnostic\n\n`gtfs-utils` does not make assumptions about where you read the GTFS data from. Although it has a built-in tool to read CSV from files on disk, anything is possible: [`.zip` archives](docs/zip.md), [HTTP requests](docs/fetch.md), in-memory [buffers](https://nodejs.org/api/buffer.html), [dat](https://dat.foundation)/[IPFS](https://ipfs.io), etc.\n\nThere are too many half-done, slightly opinionated GTFS processing tools out there, so `gtfs-utils` tries to be as universal as possible.\n\n### correct\n\nAside from new features of the ever-expanded GTFS spec that change the expected behavior of old ones (and bugs of course), `gtfs-utils` tries to follow the spec closely.\n\nFor example, it will, when computing the absolute timestamp/instant of an arrival at a stop, always take into account `stop_timezone` or the user-supplied timezone, because [`stop_times.txt` uses \"wall clock time\"](https://gist.github.com/derhuerst/574edc94981a21ef0ce90713f1cff7f6).\n\n\n## Installing\n\n```shell\nnpm install gtfs-utils\n```\n\n\n## Usage\n\n[API documentation](docs/api.md)\n\n### sorted GTFS files\n\n**`gtfs-utils` assumes that the files in your GTFS dataset are sorted in a particular way**; This allows it to compute some data aggregations more memory-efficiently, which means that you can use it to process [very large](#performance) datasets. For example, if [`trips.txt`](https://gtfs.org/reference/static/#tripstxt) and [`stop_times.txt`](https://gtfs.org/reference/static/#stop_timestxt) are both sorted by `trip_id`, `computeStopovers()` can read each file incrementally, only rows for *one* `trip_id` at a time.\n\n[Miller](https://miller.readthedocs.io/) and [`sponge`](https://linux.die.net/man/1/sponge) work very well for this:\n\n```shell\nmlr --csv sort -f agency_id agency.txt | sponge agency.txt\nmlr --csv sort -f parent_station -nr location_type stops.txt | sponge stops.txt\nmlr --csv sort -f route_id routes.txt | sponge routes.txt\nmlr --csv sort -f trip_id trips.txt | sponge trips.txt\nmlr --csv sort -f trip_id -n stop_sequence stop_times.txt | sponge stop_times.txt\nmlr --csv sort -f service_id calendar.txt | sponge calendar.txt\nmlr --csv sort -f service_id,date calendar_dates.txt | sponge calendar_dates.txt\nmlr --csv sort -f trip_id,start_time frequencies.txt | sponge frequencies.txt\n```\n\nThere's also a [`sort.sh` script](sort.sh) included in the npm package, which executes the commands above.\n\n*Note:* For read-only sources (like HTTP requests), sorting the files is not an option. You can solve this by [spawning](https://nodejs.org/docs/latest-v12.x/api/child_process.html#child_process_child_process_spawn_command_args_options) `mlr` and piping data through it.\n\n*Note:* With a bit of extra code, you can also use `gtfs-utils` [with a `.zip` archive](docs/zip.md) or [with a *remote* feed](docs/fetch.md).\n\n### basic example\n\nGiven our [sample GTFS dataset](https://npmjs.com/package/sample-gtfs-feed), we'll answer the following question: **On a specific day, which vehicles of which lines stop at a specific station?**\n\nWe define a function `readFile` that reads our GTFS data into a [readable stream](https://nodejs.org/api/stream.html#stream_readable_streams)/[async iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator). In this case we'll read CSV files from disk using the built-in `readCsv` helper:\n\n```js\nconst readCsv = require('gtfs-utils/read-csv')\n\nconst readFile = (file) => {\n\treturn readCsv(require.resolve('sample-gtfs-feed/gtfs/' + file + '.txt'))\n}\n```\n\n[`computerStopovers()`](docs/api.md#computestopovers) will read [`calendar.txt`](https://gtfs.org/reference/static/#calendartxt), [`calendar_dates.txt`](https://gtfs.org/reference/static/#calendar_datestxt), [`trips.txt`](https://gtfs.org/reference/static/#tripstxt), [`stop_times.txt`](https://gtfs.org/reference/static/#stop_timestxt) & [`frequencies.txt`](https://gtfs.org/reference/static/#frequenciestxt) and return all *stopovers* of all trips across the full time frame of the dataset.\n\nIt returns an [async generator function](https://javascript.info/async-iterators-generators#async-generators) (which thus is [async-iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator)), so we can use `for await`.\n\nIn the following example, we're going to print all stopovers at `airport` on the 5th of May 2019:\n\n```js\nconst {DateTime} = require('luxon')\nconst computeStopovers = require('gtfs-utils/compute-stopovers')\n\nconst day = '2019-05-15'\nconst isOnDay = (t) => {\n\tconst iso = DateTime.fromMillis(t * 1000, {zone: 'Europe/Berlin'}).toISO()\n\treturn String(t).slice(0, day.length) === day\n}\n\nconst stopovers = await computeStopovers(readFile, 'Europe/Berlin')\nfor await (const stopover of stopovers) {\n\tif (stopover.stop_id !== 'airport') continue\n\tif (!isOnDay(stopover.arrival)) continue\n\tconsole.log(stopover)\n}\n```\n\n```js\n{\n\tstop_id: 'airport',\n\ttrip_id: 'a-downtown-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'A',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557926580,\n\tdeparture: 1557926640,\n}\n{\n\tstop_id: 'airport',\n\ttrip_id: 'a-outbound-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'A',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557933900,\n\tdeparture: 1557933960,\n}\n// …\n{\n\tstop_id: 'airport',\n\ttrip_id: 'c-downtown-all-day',\n\tservice_id: 'all-day',\n\troute_id: 'C',\n\tstart_of_trip: 1557871200,\n\tarrival: 1557926820,\n\tdeparture: 1557926880,\n}\n```\n\nFor more examples, check the [API documentation](docs/api.md).\n\n\n## Performance\n\nBy default, `gtfs-utils` verifies that the input files are sorted correctly. You can disable this to improve performance slightly by running with the `CHECK_GTFS_SORTING=false` environment variable.\n\n`gtfs-utils` should be fast enough for small to medium-sized GTFS datasets. It won't be as fast as other GTFS tools because it\n\n- uses [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) extensively for memory-efficiency and an easy-of-use, which [currently has significant performance penalties in v8](https://github.com/nodejs/node/issues/31979).\n- is written in JavaScript, so it cannot optimise the memory layout of its data structures.\n- parses all columns of a file it needs information from, into a JavaScript object.\n\nOn my [M1 Macbook Air](https://everymac.com/systems/apple/macbook-air/specs/macbook-air-m1-8-core-7-core-gpu-13-retina-display-2020-specs.html), with the [180mb `2022-02-03` *HVV* GTFS dataset](https://suche.transparenz.hamburg.de/dataset/hvv-fahrplandaten-gtfs-februar-2022-bis-dezember-2022) (17k `stops.txt` rows, 91k `trips.txt` rows, 2m `stop_times.txt` rows, ~500m stopovers), `computeStopovers` computes 18k stopovers per second, and finishes in several hours.\n\n*Note:* If you want a faster way to query and transform GTFS datasets, I suggest you to use [`gtfs-via-postgres`](https://github.com/derhuerst/gtfs-via-postgres) to leverage PostgreSQL's query optimizer. Once you have imported the data, it is usually orders of magnitude faster.\n\n\n## Related\n\n- [gtfstidy](https://github.com/patrickbr/gtfstidy) – Go command line tool for validating and tidying GTFS feeds.\n- [gtfs-stream](https://github.com/staeco/gtfs-stream) – Streaming GTFS and GTFS-RT parser for node\n- [mapzen-gtfs](https://github.com/transitland/mapzen-gtfs) – Python library for reading and writing GTFS feeds. (Python)\n- [gtfspy](https://github.com/CxAalto/gtfspy) – Public transport network analysis using Python\n- [extract-gtfs-shapes](https://github.com/derhuerst/extract-gtfs-shapes) – Command-line tool to extract shapes from a GTFS dataset.\n- [extract-gtfs-pathways](https://github.com/derhuerst/extract-gtfs-pathways) – Command-line tool to extract pathways from a GTFS dataset.\n- [Awesome GTFS: Frameworks and Libraries](https://github.com/andredarcie/awesome-gtfs#frameworks-and-libraries) – A collection of libraries for working with GTFS.\n\n## Contributing\n\nIf you have a question or have difficulties using `gtfs-utils`, please double-check your code and setup first. If you think you have found a bug or want to propose a feature, refer to [the issues page](https://github.com/public-transport/gtfs-utils/issues).\n","readmeFilename":"readme.md"}