{"version":3,"sources":["jsdelivr-header.js","/npm/db-vendo-client@6.10.9/index.js"],"names":[],"mappings":"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","file":"/npm/db-vendo-client@6.10.9/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/db-vendo-client@6.10.9/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import distance from 'gps-distance';\n\nimport {defaultProfile} from './lib/default-profile.js';\nimport {validateProfile} from './lib/validate-profile.js';\n\nconst isObj = element => element !== null && 'object' === typeof element && !Array.isArray(element);\n\n// background info: https://github.com/public-transport/hafas-client/issues/286\nconst FORBIDDEN_USER_AGENTS = [\n\t'my-awesome-program', // previously used in readme.md, p/*/readme.md & docs/*.md\n\t'hafas-client-example', // previously used in p/*/example.js\n\t'link-to-your-project-or-email', // now used throughout\n\t'db-vendo-client',\n];\n\nconst isNonEmptyString = str => 'string' === typeof str && str.length > 0;\n\nconst validateLocation = (loc, name = 'location') => {\n\tif (!isObj(loc)) {\n\t\tthrow new TypeError(name + ' must be an object.');\n\t} else if (loc.type !== 'location') {\n\t\tthrow new TypeError('invalid location object.');\n\t} else if ('number' !== typeof loc.latitude) {\n\t\tthrow new TypeError(name + '.latitude must be a number.');\n\t} else if ('number' !== typeof loc.longitude) {\n\t\tthrow new TypeError(name + '.longitude must be a number.');\n\t}\n};\n\nconst loadEnrichedStationData = async (profile) => {\n\tconst dbHafasStations = await import('db-hafas-stations');\n\tconst items = {};\n\tfor await (const station of dbHafasStations.readFullStations()) {\n\t\titems[station.id] = station;\n\t\titems[station.name] = station;\n\t}\n\tif (profile.DEBUG) {\n\t\tconsole.log('Loaded station index.');\n\t}\n\treturn items;\n};\n\nconst applyEnrichedStationData = async (ctx, shouldLoadEnrichedStationData) => {\n\tconst {profile, common} = ctx;\n\tif (shouldLoadEnrichedStationData && !common.locations) {\n\t\tconst locations = await loadEnrichedStationData(profile);\n\t\tcommon.locations = locations;\n\t}\n};\n\nconst createClient = (profile, userAgent, opt = {}) => {\n\tprofile = Object.assign({}, defaultProfile, profile);\n\tvalidateProfile(profile);\n\tconst common = {};\n\tlet shouldLoadEnrichedStationData = false;\n\tif (typeof opt.enrichStations === 'function') {\n\t\tprofile.enrichStation = opt.enrichStations;\n\t} else if (opt.enrichStations !== false) {\n\t\tshouldLoadEnrichedStationData = true;\n\t}\n\n\tif ('string' !== typeof userAgent) {\n\t\tthrow new TypeError('userAgent must be a string');\n\t}\n\tif (FORBIDDEN_USER_AGENTS.includes(userAgent.toLowerCase())) {\n\t\tthrow new TypeError(`userAgent should tell the API operators how to contact you. If you have copied \"${userAgent}\" value from the documentation, please adapt it.`);\n\t}\n\n\tconst _stationBoard = async (station, type, resultsField, parse, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\t\tif (isObj(station) && station.id) {\n\t\t\tstation = station.id;\n\t\t} else if ('string' !== typeof station) {\n\t\t\tthrow new TypeError('station must be an object or a string.');\n\t\t}\n\n\t\tif ('string' !== typeof type || !type) {\n\t\t\tthrow new TypeError('type must be a non-empty string.');\n\t\t}\n\n\t\tif (!profile.departuresGetPasslist && opt.stopovers) {\n\t\t\tthrow new Error('opt.stopovers is not supported by this endpoint');\n\t\t}\n\t\tif (!profile.departuresStbFltrEquiv && 'includeRelatedStations' in opt) {\n\t\t\tthrow new Error('opt.includeRelatedStations is not supported by this endpoint');\n\t\t}\n\n\t\topt = Object.assign({\n\t\t\t// todo: for arrivals(), this is actually a station it *has already* stopped by\n\t\t\tdirection: null, // only show departures stopping by this station\n\t\t\tline: null, // filter by line ID\n\t\t\tduration: 10, // show departures for the next n minutes\n\t\t\tresults: null, // max. number of results; `null` means \"whatever HAFAS wants\"\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tlinesOfStops: false, // parse & expose lines at the stop/station?\n\t\t\tremarks: true, // parse & expose hints & warnings?\n\t\t\tstopovers: false, // fetch & parse previous/next stopovers?\n\t\t\t// departures at related stations\n\t\t\t// e.g. those that belong together on the metro map.\n\t\t\tincludeRelatedStations: true,\n\t\t\tmoreStops: null, // also include departures/arrivals for array of up to nine additional station evaNumbers  (not supported with dbnav and dbweb)\n\t\t}, opt);\n\t\topt.when = new Date(opt.when || Date.now());\n\t\tif (Number.isNaN(Number(opt.when))) {\n\t\t\tthrow new Error('opt.when is invalid');\n\t\t}\n\n\t\tconst req = profile.formatStationBoardReq({profile, opt}, station, resultsField);\n\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\n\t\tconst ctx = {profile, opt, common, res};\n\t\tlet results = (res[resultsField] || res.items || res.bahnhofstafelAbfahrtPositionen || res.bahnhofstafelAnkunftPositionen || res.entries?.flat() || [])\n\t\t\t.map(res => parse(ctx, res)); // TODO sort?, slice\n\n\t\tif (!opt.includeRelatedStations) {\n\t\t\tresults = results.filter(r => !r.stop?.id || r.stop.id == station);\n\t\t}\n\t\tif (opt.direction) {\n\t\t\tresults = results.filter(r => !r.nextStopovers || r.nextStopovers.find(s => s.stop?.id == opt.direction || s.stop?.name == opt.direction));\n\t\t}\n\t\treturn {\n\t\t\t[resultsField]: results,\n\t\t\trealtimeDataUpdatedAt: null, // TODO\n\t\t};\n\t};\n\n\tconst departures = async (station, opt = {}) => {\n\t\treturn await _stationBoard(station, 'DEP', 'departures', profile.parseDeparture, opt);\n\t};\n\tconst arrivals = async (station, opt = {}) => {\n\t\treturn await _stationBoard(station, 'ARR', 'arrivals', profile.parseArrival, opt);\n\t};\n\n\tconst journeys = async (from, to, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\t\tif ('earlierThan' in opt && 'laterThan' in opt) {\n\t\t\tthrow new TypeError('opt.earlierThan and opt.laterThan are mutually exclusive.');\n\t\t}\n\t\tif ('departure' in opt && 'arrival' in opt) {\n\t\t\tthrow new TypeError('opt.departure and opt.arrival are mutually exclusive.');\n\t\t}\n\t\tlet journeysRef = null;\n\t\tif ('earlierThan' in opt) {\n\t\t\tif (!isNonEmptyString(opt.earlierThan)) {\n\t\t\t\tthrow new TypeError('opt.earlierThan must be a non-empty string.');\n\t\t\t}\n\t\t\tif ('departure' in opt || 'arrival' in opt) {\n\t\t\t\tthrow new TypeError('opt.earlierThan and opt.departure/opt.arrival are mutually exclusive.');\n\t\t\t}\n\t\t\tjourneysRef = opt.earlierThan;\n\t\t}\n\t\tif ('laterThan' in opt) {\n\t\t\tif (!isNonEmptyString(opt.laterThan)) {\n\t\t\t\tthrow new TypeError('opt.laterThan must be a non-empty string.');\n\t\t\t}\n\t\t\tif ('departure' in opt || 'arrival' in opt) {\n\t\t\t\tthrow new TypeError('opt.laterThan and opt.departure/opt.arrival are mutually exclusive.');\n\t\t\t}\n\t\t\tjourneysRef = opt.laterThan;\n\t\t}\n\n\t\topt = Object.assign({\n\t\t\tresults: null, // number of journeys – `null` means \"whatever HAFAS returns\"\n\t\t\tvia: null, // let journeys pass this station?\n\t\t\tstopovers: false, // return stations on the way?\n\t\t\ttransfers: null, // maximum nr of transfers\n\t\t\ttransferTime: 0, // minimum time for a single transfer in minutes\n\t\t\t// todo: does this work with every endpoint?\n\t\t\taccessibility: 'none', // 'none', 'partial' or 'complete'\n\t\t\tbike: false, // only bike-friendly journeys\n\t\t\twalkingSpeed: 'normal', // 'slow', 'normal', 'fast'\n\t\t\t// Consider walking to nearby stations at the beginning of a journey?\n\t\t\tstartWithWalking: true,\n\t\t\ttickets: false, // return tickets?\n\t\t\tpolylines: false, // return leg shapes?\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tremarks: true, // parse & expose hints & warnings?\n\t\t\tscheduledDays: false, // parse & expose dates each journey is valid on?\n\t\t\tnotOnlyFastRoutes: false, // if true, also show routes that are mathematically non-optimal\n\t\t\tbestprice: false, // search for lowest prices across the entire day\n\t\t\tdeutschlandTicketDiscount: false,\n\t\t\tdeutschlandTicketConnectionsOnly: false,\n\t\t\tbmisNumber: null, // 7-digit BMIS number for business customer rates\n\t\t}, opt);\n\n\t\tif (opt.when !== undefined) {\n\t\t\tthrow new Error('opt.when is not supported anymore. Use opt.departure/opt.arrival.');\n\t\t}\n\t\tlet when = new Date(), outFrwd = true;\n\t\tif (opt.departure !== undefined && opt.departure !== null) {\n\t\t\twhen = new Date(opt.departure);\n\t\t\tif (Number.isNaN(Number(when))) {\n\t\t\t\tthrow new TypeError('opt.departure is invalid');\n\t\t\t}\n\t\t} else if (opt.arrival !== undefined && opt.arrival !== null) {\n\t\t\tif (!profile.journeysOutFrwd) {\n\t\t\t\tthrow new Error('opt.arrival is unsupported');\n\t\t\t}\n\t\t\twhen = new Date(opt.arrival);\n\t\t\tif (Number.isNaN(Number(when))) {\n\t\t\t\tthrow new TypeError('opt.arrival is invalid');\n\t\t\t}\n\t\t\toutFrwd = false;\n\t\t}\n\n\t\tconst req = profile.formatJourneysReq({profile, opt}, from, to, when, outFrwd, journeysRef);\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\t\tconst ctx = {profile, opt, common, res};\n\t\tif (opt.bestprice) {\n\t\t\tres.verbindungen = (res.intervalle || res.tagesbestPreisIntervalle).flatMap(i => i.verbindungen.map(v => ({...v, ...v.verbindung})));\n\t\t}\n\t\tconst verbindungen = Number.isInteger(opt.results) && opt.results != 3 ? res.verbindungen.slice(0, opt.results) : res.verbindungen; // TODO remove default from hafas-rest-api\n\t\tconst journeys = verbindungen\n\t\t\t.map(j => profile.parseJourney(ctx, j));\n\t\tif (opt.bestprice) {\n\t\t\tjourneys.sort((a, b) => a.price?.amount - b.price?.amount);\n\t\t}\n\n\t\treturn {\n\t\t\tearlierRef: res.verbindungReference?.earlier || res.frueherContext || null,\n\t\t\tlaterRef: res.verbindungReference?.later || res.spaeterContext || null,\n\t\t\tjourneys,\n\t\t\trealtimeDataUpdatedAt: null, // TODO\n\t\t};\n\t};\n\n\tconst refreshJourney = async (refreshToken, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\n\t\tif ('string' !== typeof refreshToken || !refreshToken) {\n\t\t\tthrow new TypeError('refreshToken must be a non-empty string.');\n\t\t}\n\n\t\topt = Object.assign({\n\t\t\tstopovers: false, // return stations on the way?\n\t\t\ttickets: false, // return tickets?\n\t\t\tpolylines: false, // return leg shapes? (not supported by all endpoints)\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tremarks: true, // parse & expose hints & warnings?\n\t\t\tscheduledDays: false, // parse & expose dates the journey is valid on?\n\t\t\tdeutschlandTicketDiscount: false,\n\t\t\tdeutschlandTicketConnectionsOnly: false,\n\t\t\tbmisNumber: null, // 7-digit BMIS number for business customer rates\n\t\t}, opt);\n\n\t\tconst req = profile.formatRefreshJourneyReq({profile, opt}, refreshToken);\n\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\t\tconst ctx = {profile, opt, common, res};\n\n\t\treturn {\n\t\t\tjourney: profile.parseJourney(ctx, res.verbindungen && res.verbindungen[0] || res),\n\t\t\trealtimeDataUpdatedAt: null, // TODO\n\t\t};\n\t};\n\n\tconst locations = async (query, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\n\t\tif (!isNonEmptyString(query)) {\n\t\t\tthrow new TypeError('query must be a non-empty string.');\n\t\t}\n\t\topt = Object.assign({\n\t\t\tfuzzy: true, // find only exact matches?\n\t\t\tresults: 5, // how many search results?\n\t\t\tstops: true, // return stops/stations?\n\t\t\taddresses: true,\n\t\t\tpoi: true, // points of interest\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tlinesOfStops: false, // parse & expose lines at each stop/station?\n\t\t}, opt);\n\t\tconst req = profile.formatLocationsReq({profile, opt}, query);\n\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\n\t\tconst ctx = {profile, opt, common, res};\n\t\tconst results = res.map(loc => profile.parseLocation(ctx, loc));\n\n\t\treturn Number.isInteger(opt.results)\n\t\t\t? results.slice(0, opt.results)\n\t\t\t: results;\n\t};\n\n\tconst stop = async (stop, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\n\t\tif (isObj(stop) && stop.id) {\n\t\t\tstop = stop.id;\n\t\t} else if ('string' !== typeof stop) {\n\t\t\tthrow new TypeError('stop must be an object or a string.');\n\t\t}\n\n\t\topt = Object.assign({\n\t\t\tlinesOfStops: false, // parse & expose lines at the stop/station?\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tremarks: true, // parse & expose hints & warnings?\n\t\t}, opt);\n\n\t\tconst req = profile.formatStopReq({profile, opt}, stop);\n\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\t\tconst ctx = {profile, opt, res, common};\n\t\treturn profile.parseStop(ctx, res, stop);\n\t};\n\n\tconst nearby = async (location, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\n\t\tvalidateLocation(location, 'location');\n\n\t\topt = Object.assign({\n\t\t\tresults: 8, // maximum number of results\n\t\t\tdistance: null, // maximum walking distance in meters\n\t\t\tpoi: false, // return points of interest?\n\t\t\tstops: true, // return stops/stations?\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tlinesOfStops: false, // parse & expose lines at each stop/station?\n\t\t}, opt);\n\n\t\tconst req = profile.formatNearbyReq({profile, opt}, location);\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\n\t\tconst ctx = {profile, opt, common, res};\n\t\tconst results = res.map(loc => {\n\t\t\tconst res = profile.parseLocation(ctx, loc);\n\t\t\tif (res.latitude || res.location?.latitude) {\n\t\t\t\tres.distance = Math.round(distance(location.latitude, location.longitude, res.latitude || res.location?.latitude, res.longitude || res.location?.longitude) * 1000);\n\t\t\t}\n\t\t\treturn res;\n\t\t});\n\n\t\treturn Number.isInteger(opt.results)\n\t\t\t? results.slice(0, opt.results)\n\t\t\t: results;\n\t};\n\n\tconst trip = async (id, opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\n\t\tif (!isNonEmptyString(id)) {\n\t\t\tthrow new TypeError('id must be a non-empty string.');\n\t\t}\n\t\topt = Object.assign({\n\t\t\tstopovers: true, // return stations on the way?\n\t\t\tpolyline: false, // return a track shape?\n\t\t\tsubStops: true, // parse & expose sub-stops of stations?\n\t\t\tentrances: true, // parse & expose entrances of stops/stations?\n\t\t\tremarks: true, // parse & expose hints & warnings?\n\t\t\tscheduledDays: false, // parse & expose dates trip is valid on?\n\t\t}, opt);\n\n\t\tconst req = profile.formatTripReq({profile, opt}, id);\n\n\t\tconst {res} = await profile.request({profile, opt}, userAgent, req);\n\t\tconst ctx = {profile, opt, common, res};\n\n\t\tconst trip = profile.parseTrip(ctx, res, id);\n\n\t\treturn {\n\t\t\ttrip,\n\t\t\trealtimeDataUpdatedAt: null, // TODO\n\t\t};\n\t};\n\n\t// todo [breaking]: rename to trips()?\n\tconst tripsByName = async (_lineNameOrFahrtNr = '*', _opt = {}) => {\n\t\tawait applyEnrichedStationData({profile, common}, shouldLoadEnrichedStationData);\n\n\t\tthrow new Error('not implemented');\n\t};\n\n\tconst client = {\n\t\tdepartures,\n\t\tarrivals,\n\t\tjourneys,\n\t\tlocations,\n\t\tstop,\n\t\tnearby,\n\t};\n\tif (profile.trip) {\n\t\tclient.trip = trip;\n\t}\n\tif (profile.refreshJourney) {\n\t\tclient.refreshJourney = refreshJourney;\n\t}\n\tif (profile.tripsByName) {\n\t\tclient.tripsByName = tripsByName;\n\t}\n\tObject.defineProperty(client, 'profile', {value: profile});\n\treturn client;\n};\n\nconst createBusinessClient = (profile, userAgent, bmisNumber, opt = {}) => {\n\tif (!bmisNumber || typeof bmisNumber !== 'string') {\n\t\tthrow new TypeError('bmisNumber must be a non-empty string');\n\t}\n\n\t// Create a client with BMIS number included in all journey requests\n\tconst client = createClient(profile, userAgent, opt);\n\n\t// Wrap journeys method to always include BMIS number\n\tconst originalJourneys = client.journeys;\n\tclient.journeys = async (from, to, opt = {}) => {\n\t\treturn originalJourneys(from, to, {...opt, bmisNumber});\n\t};\n\n\t// Wrap refreshJourney method to always include BMIS number\n\tif (client.refreshJourney) {\n\t\tconst originalRefreshJourney = client.refreshJourney;\n\t\tclient.refreshJourney = async (refreshToken, opt = {}) => {\n\t\t\treturn originalRefreshJourney(refreshToken, {...opt, bmisNumber});\n\t\t};\n\t}\n\n\treturn client;\n};\n\nexport {\n\tcreateClient,\n\tcreateBusinessClient,\n\tloadEnrichedStationData,\n};\n"]}