mirror of
				https://github.com/public-transport/db-vendo-client.git
				synced 2025-11-04 01:56:33 +02:00 
			
		
		
		
	dbnav boards, fixes
This commit is contained in:
		
							parent
							
								
									6538f814aa
								
							
						
					
					
						commit
						3d998de41c
					
				
					 19 changed files with 434 additions and 97 deletions
				
			
		| 
						 | 
					@ -20,7 +20,7 @@ import {parseLine} from '../parse/line.js';
 | 
				
			||||||
import {parseLocation} from '../parse/location.js';
 | 
					import {parseLocation} from '../parse/location.js';
 | 
				
			||||||
import {parsePolyline} from '../parse/polyline.js';
 | 
					import {parsePolyline} from '../parse/polyline.js';
 | 
				
			||||||
import {parseOperator} from '../parse/operator.js';
 | 
					import {parseOperator} from '../parse/operator.js';
 | 
				
			||||||
import {parseRemarks} from '../parse/remarks.js';
 | 
					import {parseRemarks, parseCancelled} from '../parse/remarks.js';
 | 
				
			||||||
import {parseStopover} from '../parse/stopover.js';
 | 
					import {parseStopover} from '../parse/stopover.js';
 | 
				
			||||||
import {parseLoadFactor, parseArrOrDepWithLoadFactor} from '../parse/load-factor.js';
 | 
					import {parseLoadFactor, parseArrOrDepWithLoadFactor} from '../parse/load-factor.js';
 | 
				
			||||||
import {parseHintByCode} from '../parse/hints-by-code.js';
 | 
					import {parseHintByCode} from '../parse/hints-by-code.js';
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ import {formatDate} from '../format/date.js';
 | 
				
			||||||
import {formatProductsFilter} from '../format/products-filter.js';
 | 
					import {formatProductsFilter} from '../format/products-filter.js';
 | 
				
			||||||
import {formatPoi} from '../format/poi.js';
 | 
					import {formatPoi} from '../format/poi.js';
 | 
				
			||||||
import {formatStation} from '../format/station.js';
 | 
					import {formatStation} from '../format/station.js';
 | 
				
			||||||
import {formatTime} from '../format/time.js';
 | 
					import {formatTime, formatTimeOfDay} from '../format/time.js';
 | 
				
			||||||
import {formatLocation} from '../format/location.js';
 | 
					import {formatLocation} from '../format/location.js';
 | 
				
			||||||
import {formatLoyaltyCard} from '../format/loyalty-cards.js';
 | 
					import {formatLoyaltyCard} from '../format/loyalty-cards.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ const defaultProfile = {
 | 
				
			||||||
	ageGroup, ageGroupFromAge, ageGroupLabel,
 | 
						ageGroup, ageGroupFromAge, ageGroupLabel,
 | 
				
			||||||
	transformReqBody: id,
 | 
						transformReqBody: id,
 | 
				
			||||||
	transformReq: id,
 | 
						transformReq: id,
 | 
				
			||||||
	randomizeUserAgent: true,
 | 
						randomizeUserAgent: false,
 | 
				
			||||||
	logRequest,
 | 
						logRequest,
 | 
				
			||||||
	logResponse,
 | 
						logResponse,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +82,7 @@ const defaultProfile = {
 | 
				
			||||||
	parsePolyline,
 | 
						parsePolyline,
 | 
				
			||||||
	parseOperator,
 | 
						parseOperator,
 | 
				
			||||||
	parseRemarks,
 | 
						parseRemarks,
 | 
				
			||||||
 | 
						parseCancelled,
 | 
				
			||||||
	parseStopover,
 | 
						parseStopover,
 | 
				
			||||||
	parseLoadFactor,
 | 
						parseLoadFactor,
 | 
				
			||||||
	parseArrOrDepWithLoadFactor,
 | 
						parseArrOrDepWithLoadFactor,
 | 
				
			||||||
| 
						 | 
					@ -99,6 +100,7 @@ const defaultProfile = {
 | 
				
			||||||
	formatProductsFilter,
 | 
						formatProductsFilter,
 | 
				
			||||||
	formatStation,
 | 
						formatStation,
 | 
				
			||||||
	formatTime,
 | 
						formatTime,
 | 
				
			||||||
 | 
						formatTimeOfDay,
 | 
				
			||||||
	formatTravellers: notImplemented,
 | 
						formatTravellers: notImplemented,
 | 
				
			||||||
	formatRectangle: id,
 | 
						formatRectangle: id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,9 @@ const products = [
 | 
				
			||||||
		short: 'ICE',
 | 
							short: 'ICE',
 | 
				
			||||||
		vendo: 'ICE',
 | 
							vendo: 'ICE',
 | 
				
			||||||
		ris: 'HIGH_SPEED_TRAIN',
 | 
							ris: 'HIGH_SPEED_TRAIN',
 | 
				
			||||||
 | 
							ris_alt: 'HIGH_SPEED_TRAIN',
 | 
				
			||||||
		dbnav: 'HOCHGESCHWINDIGKEITSZUEGE',
 | 
							dbnav: 'HOCHGESCHWINDIGKEITSZUEGE',
 | 
				
			||||||
 | 
							dbnav_short: 'ICE',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -18,7 +20,9 @@ const products = [
 | 
				
			||||||
		short: 'IC/EC',
 | 
							short: 'IC/EC',
 | 
				
			||||||
		vendo: 'EC_IC',
 | 
							vendo: 'EC_IC',
 | 
				
			||||||
		ris: 'INTERCITY_TRAIN',
 | 
							ris: 'INTERCITY_TRAIN',
 | 
				
			||||||
 | 
							ris_alt: 'INTERCITY_TRAIN',
 | 
				
			||||||
		dbnav: 'INTERCITYUNDEUROCITYZUEGE',
 | 
							dbnav: 'INTERCITYUNDEUROCITYZUEGE',
 | 
				
			||||||
 | 
							dbnav_short: 'IC_EC',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -29,7 +33,9 @@ const products = [
 | 
				
			||||||
		short: 'RE/IR',
 | 
							short: 'RE/IR',
 | 
				
			||||||
		vendo: 'IR',
 | 
							vendo: 'IR',
 | 
				
			||||||
		ris: 'INTER_REGIONAL_TRAIN',
 | 
							ris: 'INTER_REGIONAL_TRAIN',
 | 
				
			||||||
 | 
							ris_alt: 'INTER_REGIONAL_TRAIN',
 | 
				
			||||||
		dbnav: 'INTERREGIOUNDSCHNELLZUEGE',
 | 
							dbnav: 'INTERREGIOUNDSCHNELLZUEGE',
 | 
				
			||||||
 | 
							dbnav_short: 'IR',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -40,7 +46,9 @@ const products = [
 | 
				
			||||||
		short: 'RB',
 | 
							short: 'RB',
 | 
				
			||||||
		vendo: 'REGIONAL',
 | 
							vendo: 'REGIONAL',
 | 
				
			||||||
		ris: 'REGIONAL_TRAIN',
 | 
							ris: 'REGIONAL_TRAIN',
 | 
				
			||||||
 | 
							ris_alt: 'REGIONAL_TRAIN',
 | 
				
			||||||
		dbnav: 'NAHVERKEHRSONSTIGEZUEGE',
 | 
							dbnav: 'NAHVERKEHRSONSTIGEZUEGE',
 | 
				
			||||||
 | 
							dbnav_short: 'RB',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -51,7 +59,9 @@ const products = [
 | 
				
			||||||
		short: 'S',
 | 
							short: 'S',
 | 
				
			||||||
		vendo: 'SBAHN',
 | 
							vendo: 'SBAHN',
 | 
				
			||||||
		ris: 'CITY_TRAIN',
 | 
							ris: 'CITY_TRAIN',
 | 
				
			||||||
 | 
							ris_alt: 'CITY_TRAIN',
 | 
				
			||||||
		dbnav: 'SBAHNEN',
 | 
							dbnav: 'SBAHNEN',
 | 
				
			||||||
 | 
							dbnav_short: 'SBAHN',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -62,7 +72,9 @@ const products = [
 | 
				
			||||||
		short: 'B',
 | 
							short: 'B',
 | 
				
			||||||
		vendo: 'BUS',
 | 
							vendo: 'BUS',
 | 
				
			||||||
		ris: 'BUS',
 | 
							ris: 'BUS',
 | 
				
			||||||
 | 
							ris_alt: 'BUS',
 | 
				
			||||||
		dbnav: 'BUSSE',
 | 
							dbnav: 'BUSSE',
 | 
				
			||||||
 | 
							dbnav_short: 'BUS',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -73,7 +85,9 @@ const products = [
 | 
				
			||||||
		short: 'F',
 | 
							short: 'F',
 | 
				
			||||||
		vendo: 'SCHIFF',
 | 
							vendo: 'SCHIFF',
 | 
				
			||||||
		ris: 'FERRY',
 | 
							ris: 'FERRY',
 | 
				
			||||||
 | 
							ris_alt: 'FERRY',
 | 
				
			||||||
		dbnav: 'SCHIFFE',
 | 
							dbnav: 'SCHIFFE',
 | 
				
			||||||
 | 
							dbnav_short: 'SCHIFF',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -84,7 +98,9 @@ const products = [
 | 
				
			||||||
		short: 'U',
 | 
							short: 'U',
 | 
				
			||||||
		vendo: 'UBAHN',
 | 
							vendo: 'UBAHN',
 | 
				
			||||||
		ris: 'SUBWAY',
 | 
							ris: 'SUBWAY',
 | 
				
			||||||
 | 
							ris_alt: 'SUBWAY',
 | 
				
			||||||
		dbnav: 'UBAHN',
 | 
							dbnav: 'UBAHN',
 | 
				
			||||||
 | 
							dbnav_short: 'UBAHN',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -95,7 +111,9 @@ const products = [
 | 
				
			||||||
		short: 'T',
 | 
							short: 'T',
 | 
				
			||||||
		vendo: 'TRAM',
 | 
							vendo: 'TRAM',
 | 
				
			||||||
		ris: 'TRAM',
 | 
							ris: 'TRAM',
 | 
				
			||||||
 | 
							ris_alt: 'TRAM',
 | 
				
			||||||
		dbnav: 'STRASSENBAHN',
 | 
							dbnav: 'STRASSENBAHN',
 | 
				
			||||||
 | 
							dbnav_short: 'STR',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -106,7 +124,9 @@ const products = [
 | 
				
			||||||
		short: 'Taxi',
 | 
							short: 'Taxi',
 | 
				
			||||||
		vendo: 'ANRUFPFLICHTIG',
 | 
							vendo: 'ANRUFPFLICHTIG',
 | 
				
			||||||
		ris: 'TAXI',
 | 
							ris: 'TAXI',
 | 
				
			||||||
 | 
							ris_alt: 'SHUTTLE',
 | 
				
			||||||
		dbnav: 'ANRUFPFLICHTIGEVERKEHRE',
 | 
							dbnav: 'ANRUFPFLICHTIGEVERKEHRE',
 | 
				
			||||||
 | 
							dbnav_short: 'ANRUFPFLICHTIGEVERKEHRE',
 | 
				
			||||||
		default: true,
 | 
							default: true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,6 @@
 | 
				
			||||||
	"locationsEndpoint": "https://app.vendo.noncd.db.de/mob/location/search",
 | 
						"locationsEndpoint": "https://app.vendo.noncd.db.de/mob/location/search",
 | 
				
			||||||
	"nearbyEndpoint": "https://app.vendo.noncd.db.de/mob/location/nearby",
 | 
						"nearbyEndpoint": "https://app.vendo.noncd.db.de/mob/location/nearby",
 | 
				
			||||||
	"tripEndpoint": "https://app.vendo.noncd.db.de/mob/zuglauf",
 | 
						"tripEndpoint": "https://app.vendo.noncd.db.de/mob/zuglauf",
 | 
				
			||||||
	"boardEndpoint": "https://app.vendo.noncd.db.de/mob/bahnhofstafel/abfahrt",
 | 
						"boardEndpoint": "https://app.vendo.noncd.db.de/mob/bahnhofstafel/",
 | 
				
			||||||
	"defaultLanguage": "en"
 | 
						"defaultLanguage": "en"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ const formatStationBoardReq = (ctx, station, type) => {
 | 
				
			||||||
		path: type == 'departures' ? 'abfahrt' : 'ankunft',
 | 
							path: type == 'departures' ? 'abfahrt' : 'ankunft',
 | 
				
			||||||
		body: {anfragezeit: profile.formatTimeOfDay(profile, opt.when), datum: profile.formatDate(profile, opt.when), ursprungsBahnhofId: profile.formatStation(station).lid, verkehrsmittel: profile.formatProductsFilter(ctx, opt.products || {}, 'dbnav')},
 | 
							body: {anfragezeit: profile.formatTimeOfDay(profile, opt.when), datum: profile.formatDate(profile, opt.when), ursprungsBahnhofId: profile.formatStation(station).lid, verkehrsmittel: profile.formatProductsFilter(ctx, opt.products || {}, 'dbnav')},
 | 
				
			||||||
		method: 'POST',
 | 
							method: 'POST',
 | 
				
			||||||
		header: getHeaders('application/x.db.vendo.mob.bahnhofstafeln.v2+json'),
 | 
							headers: getHeaders('application/x.db.vendo.mob.bahnhofstafeln.v2+json'),
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,15 +8,20 @@ const createParseArrOrDep = (prefix) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const parseArrOrDep = (ctx, d) => { // d = raw arrival/departure
 | 
						const parseArrOrDep = (ctx, d) => { // d = raw arrival/departure
 | 
				
			||||||
		const {profile, opt} = ctx;
 | 
							const {profile, opt} = ctx;
 | 
				
			||||||
 | 
							const cancelled = profile.parseCancelled(d);
 | 
				
			||||||
		const res = {
 | 
							const res = {
 | 
				
			||||||
			tripId: d.journeyID || d.train.journeyId,
 | 
								tripId: d.journeyID || d.train?.journeyId || d.zuglaufId,
 | 
				
			||||||
			stop: profile.parseLocation(ctx, d.station),
 | 
								stop: profile.parseLocation(ctx, d.station || d.abfrageOrt),
 | 
				
			||||||
			...profile.parseWhen(ctx, null, d.timeSchedule ? d.timeSchedule : d.time, d.timeType != 'SCHEDULE' ? d.timePredicted ? d.timePredicted : d.time : null, d.canceled),
 | 
								...profile.parseWhen(
 | 
				
			||||||
			...profile.parsePlatform(ctx, d.platformSchedule ? d.platformSchedule : d.platform, d.platformPredicted ? d.platformPredicted : d.platform, d.canceled),
 | 
									ctx,
 | 
				
			||||||
 | 
									null,
 | 
				
			||||||
 | 
									d.timeSchedule || d.time || d.abgangsDatum || d.ankunftsDatum,
 | 
				
			||||||
 | 
									d.timeType != 'SCHEDULE' ? d.timePredicted || d.time || d.ezAbgangsDatum || d.ezAnkunftsDatum : null,
 | 
				
			||||||
 | 
									cancelled),
 | 
				
			||||||
 | 
								...profile.parsePlatform(ctx, d.platformSchedule || d.platform || d.gleis, d.platformPredicted || d.platform || d.ezGleis, cancelled),
 | 
				
			||||||
			// prognosisType: TODO
 | 
								// prognosisType: TODO
 | 
				
			||||||
			direction: d.transport?.direction?.stopPlaces?.length > 0 && profile.parseStationName(ctx, d.transport?.direction?.stopPlaces[0].name) || profile.parseStationName(ctx, d.destination?.name) || null,
 | 
								direction: d.transport?.direction?.stopPlaces?.length > 0 && profile.parseStationName(ctx, d.transport?.direction?.stopPlaces[0].name) || profile.parseStationName(ctx, d.destination?.name || d.richtung) || null,
 | 
				
			||||||
			provenance: profile.parseStationName(ctx, d.transport?.origin?.name) || profile.parseStationName(ctx, d.origin?.name) || null,
 | 
								provenance: profile.parseStationName(ctx, d.transport?.origin?.name || d.origin?.name || d.abgangsOrt?.name) || null,
 | 
				
			||||||
			line: profile.parseLine(ctx, d) || null,
 | 
								line: profile.parseLine(ctx, d) || null,
 | 
				
			||||||
			remarks: [],
 | 
								remarks: [],
 | 
				
			||||||
			origin: profile.parseLocation(ctx, d.transport?.origin || d.origin) || null,
 | 
								origin: profile.parseLocation(ctx, d.transport?.origin || d.origin) || null,
 | 
				
			||||||
| 
						 | 
					@ -26,7 +31,7 @@ const createParseArrOrDep = (prefix) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// TODO pos
 | 
							// TODO pos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (d.canceled) {
 | 
							if (cancelled) {
 | 
				
			||||||
			res.cancelled = true;
 | 
								res.cancelled = true;
 | 
				
			||||||
			Object.defineProperty(res, 'canceled', {value: true});
 | 
								Object.defineProperty(res, 'canceled', {value: true});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,3 @@
 | 
				
			||||||
import {parseRemarks, isStopCancelled} from './remarks.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const locationFallback = (id, name, fallbackLocations) => {
 | 
					const locationFallback = (id, name, fallbackLocations) => {
 | 
				
			||||||
	if (fallbackLocations && (id && fallbackLocations[id] || name && fallbackLocations[name])) {
 | 
						if (fallbackLocations && (id && fallbackLocations[id] || name && fallbackLocations[name])) {
 | 
				
			||||||
		return fallbackLocations[id] || fallbackLocations[name];
 | 
							return fallbackLocations[id] || fallbackLocations[name];
 | 
				
			||||||
| 
						 | 
					@ -20,7 +18,7 @@ const parseJourneyLeg = (ctx, pt, date, fallbackLocations) => { // pt = raw leg
 | 
				
			||||||
		destination: pt.halte?.length > 0 ? profile.parseLocation(ctx, pt.halte[pt.halte.length - 1]) : locationFallback(pt.ankunftsOrtExtId, pt.ankunftsOrt, fallbackLocations),
 | 
							destination: pt.halte?.length > 0 ? profile.parseLocation(ctx, pt.halte[pt.halte.length - 1]) : locationFallback(pt.ankunftsOrtExtId, pt.ankunftsOrt, fallbackLocations),
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const cancelledDep = pt.halte?.length > 0 && isStopCancelled(pt.halte[0]);
 | 
						const cancelledDep = pt.halte?.length > 0 && profile.parseCancelled(pt.halte[0]);
 | 
				
			||||||
	const dep = profile.parseWhen(ctx, date, pt.abfahrtsZeitpunkt, pt.ezAbfahrtsZeitpunkt, cancelledDep);
 | 
						const dep = profile.parseWhen(ctx, date, pt.abfahrtsZeitpunkt, pt.ezAbfahrtsZeitpunkt, cancelledDep);
 | 
				
			||||||
	res.departure = dep.when;
 | 
						res.departure = dep.when;
 | 
				
			||||||
	res.plannedDeparture = dep.plannedWhen;
 | 
						res.plannedDeparture = dep.plannedWhen;
 | 
				
			||||||
| 
						 | 
					@ -29,7 +27,7 @@ const parseJourneyLeg = (ctx, pt, date, fallbackLocations) => { // pt = raw leg
 | 
				
			||||||
		res.prognosedDeparture = dep.prognosedWhen;
 | 
							res.prognosedDeparture = dep.prognosedWhen;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const cancelledArr = pt.halte?.length > 0 && isStopCancelled(pt.halte[pt.halte.length - 1]);
 | 
						const cancelledArr = pt.halte?.length > 0 && profile.parseCancelled(pt.halte[pt.halte.length - 1]);
 | 
				
			||||||
	const arr = profile.parseWhen(ctx, date, pt.ankunftsZeitpunkt, pt.ezAnkunftsZeitpunkt, cancelledArr);
 | 
						const arr = profile.parseWhen(ctx, date, pt.ankunftsZeitpunkt, pt.ezAnkunftsZeitpunkt, cancelledArr);
 | 
				
			||||||
	res.arrival = arr.when;
 | 
						res.arrival = arr.when;
 | 
				
			||||||
	res.plannedArrival = arr.plannedWhen;
 | 
						res.plannedArrival = arr.plannedWhen;
 | 
				
			||||||
| 
						 | 
					@ -84,7 +82,7 @@ const parseJourneyLeg = (ctx, pt, date, fallbackLocations) => { // pt = raw leg
 | 
				
			||||||
				res.stopovers = res.stopovers.filter((x) => !x.passBy);
 | 
									res.stopovers = res.stopovers.filter((x) => !x.passBy);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (opt.remarks) {
 | 
								if (opt.remarks) {
 | 
				
			||||||
				res.remarks = parseRemarks(ctx, pt);
 | 
									res.remarks = profile.parseRemarks(ctx, pt);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,19 +5,19 @@ const parseLine = (ctx, p) => {
 | 
				
			||||||
	const fahrtNr = p.verkehrsmittel?.nummer || p.transport?.number || p.train?.no;
 | 
						const fahrtNr = p.verkehrsmittel?.nummer || p.transport?.number || p.train?.no;
 | 
				
			||||||
	const res = {
 | 
						const res = {
 | 
				
			||||||
		type: 'line',
 | 
							type: 'line',
 | 
				
			||||||
		id: slugg(p.verkehrsmittel?.langText || p.transport?.journeyDescription || p.train?.no), // TODO terrible
 | 
							id: slugg(p.verkehrsmittel?.langText || p.transport?.journeyDescription || p.train && p.train.category + ' ' + p.train.lineName + ' ' + p.train.no || p.langtext || p.mitteltext), // TODO terrible
 | 
				
			||||||
		fahrtNr: fahrtNr ? String(fahrtNr) : undefined,
 | 
							fahrtNr: fahrtNr ? String(fahrtNr) : undefined, // TODO extract from zuglaufId?
 | 
				
			||||||
		name: p.verkehrsmittel?.name || p.zugName || p.transport?.journeyDescription || p.train && p.train.category + ' ' + p.train.lineName,
 | 
							name: p.verkehrsmittel?.name || p.zugName || p.transport?.journeyDescription || p.train && p.train.category + ' ' + p.train.lineName || p.langtext || p.mitteltext,
 | 
				
			||||||
		public: true,
 | 
							public: true,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO res.adminCode
 | 
						// TODO res.adminCode
 | 
				
			||||||
	res.productName = p.verkehrsmittel?.kurzText || p.transport?.category || p.train?.category;
 | 
						res.productName = p.verkehrsmittel?.kurzText || p.transport?.category || p.train?.category || p.kurztext;
 | 
				
			||||||
	const foundProduct = profile.products.find(pp => pp.vendo == p.verkehrsmittel?.produktGattung || pp.ris == p.transport?.type || pp.ris == p.train?.type);
 | 
						const foundProduct = profile.products.find(pp => pp.vendo == p.verkehrsmittel?.produktGattung || pp.ris == p.transport?.type || pp.ris == p.train?.type || pp.ris_alt == p.train?.type || pp.dbnav_short == p.produktGattung);
 | 
				
			||||||
	res.mode = foundProduct?.mode;
 | 
						res.mode = foundProduct?.mode;
 | 
				
			||||||
	res.product = foundProduct?.id;
 | 
						res.product = foundProduct?.id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.operator = profile.parseOperator(ctx, p.verkehrsmittel?.zugattribute || p.zugattribute);
 | 
						res.operator = profile.parseOperator(ctx, p.verkehrsmittel?.zugattribute || p.zugattribute); // TODO regio-guide op
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,15 +28,15 @@ const parseLocation = (ctx, l) => {
 | 
				
			||||||
		res.longitude = lid.X / 1000000;
 | 
							res.longitude = lid.X / 1000000;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (l.type === STATION || l.extId || l.evaNumber || l.evaNo || lid.A == 1) {
 | 
						if (l.type === STATION || l.extId || l.evaNumber || l.evaNo || l.evaNr || lid.A == '1') {
 | 
				
			||||||
		let stop = {
 | 
							let stop = {
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: res.id,
 | 
								id: res.id,
 | 
				
			||||||
			name: name,
 | 
								name: name,
 | 
				
			||||||
			location: 'number' === typeof res.latitude
 | 
					 | 
				
			||||||
				? res
 | 
					 | 
				
			||||||
				: null, // todo: remove `.id`
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
							if ('number' === typeof res.latitude) {
 | 
				
			||||||
 | 
								stop.location = res; // todo: remove `.id`
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// TODO subStops
 | 
							// TODO subStops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ('products' in l) {
 | 
							if ('products' in l) {
 | 
				
			||||||
| 
						 | 
					@ -57,10 +57,10 @@ const parseLocation = (ctx, l) => {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.name = name;
 | 
						res.name = name;
 | 
				
			||||||
	if (l.type === ADDRESS || lid.A == 2) {
 | 
						if (l.type === ADDRESS || lid.A == '2') {
 | 
				
			||||||
		res.address = name;
 | 
							res.address = name;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (l.type === POI || lid.A == 4) {
 | 
						if (l.type === POI || lid.A == '4') {
 | 
				
			||||||
		res.poi = true;
 | 
							res.poi = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,17 +4,17 @@ const parseOperator = (ctx, zugattrib) => {
 | 
				
			||||||
	if (!zugattrib) {
 | 
						if (!zugattrib) {
 | 
				
			||||||
		return null;
 | 
							return null;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const bef = zugattrib.find(z => z.key == 'BEF');
 | 
						const bef = zugattrib.find(z => z.key == 'BEF' || z.key == 'OP');
 | 
				
			||||||
	if (!bef) {
 | 
						if (!bef) {
 | 
				
			||||||
		return null;
 | 
							return null;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const name = bef.value && bef.value.trim();
 | 
						const name = bef.value || bef.text;
 | 
				
			||||||
	if (!name) {
 | 
						if (!name) {
 | 
				
			||||||
		return null;
 | 
							return null;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		type: 'operator',
 | 
							type: 'operator',
 | 
				
			||||||
		id: slugg(name), // todo: find a more reliable way
 | 
							id: slugg(name.trim()), // todo: find a more reliable way
 | 
				
			||||||
		name,
 | 
							name,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,44 +3,53 @@ import flatMap from 'lodash/flatMap.js';
 | 
				
			||||||
const parseRemarks = (ctx, ref) => {
 | 
					const parseRemarks = (ctx, ref) => {
 | 
				
			||||||
	// TODO ereignisZusammenfassung, priorisierteMeldungen?
 | 
						// TODO ereignisZusammenfassung, priorisierteMeldungen?
 | 
				
			||||||
	return flatMap([
 | 
						return flatMap([
 | 
				
			||||||
		ref.risNotizen || [],
 | 
					 | 
				
			||||||
		ref.himMeldungen || [],
 | 
					 | 
				
			||||||
		ref.meldungenAsObject || [],
 | 
					 | 
				
			||||||
		ref.verkehrsmittel?.zugattribute || [],
 | 
					 | 
				
			||||||
		ref.messages || [],
 | 
					 | 
				
			||||||
		ref.attributes || [],
 | 
					 | 
				
			||||||
		ref.disruptions || [],
 | 
							ref.disruptions || [],
 | 
				
			||||||
 | 
							ref.risNotizen || [],
 | 
				
			||||||
 | 
							ref.echtzeitNotizen && ref.echtzeitNotizen.map(e => {
 | 
				
			||||||
 | 
								e.prio = 'HOCH'; return e;
 | 
				
			||||||
 | 
							}) || [],
 | 
				
			||||||
 | 
							ref.himMeldungen || [],
 | 
				
			||||||
 | 
							ref.himNotizen || [],
 | 
				
			||||||
 | 
							ref.serviceNotiz && [ref.serviceNotiz] || [],
 | 
				
			||||||
 | 
							ref.messages || [],
 | 
				
			||||||
 | 
							ref.meldungenAsObject || [],
 | 
				
			||||||
 | 
							ref.attributNotizen || [],
 | 
				
			||||||
 | 
							ref.attributes || [],
 | 
				
			||||||
 | 
							ref.verkehrsmittel?.zugattribute || [],
 | 
				
			||||||
	])
 | 
						])
 | 
				
			||||||
		.map(remark => {
 | 
							.map(remark => {
 | 
				
			||||||
			if (remark.kategorie) {
 | 
								if (remark.kategorie || remark.priority) {
 | 
				
			||||||
				const res = ctx.profile.parseHintByCode(remark);
 | 
									const res = ctx.profile.parseHintByCode(remark);
 | 
				
			||||||
				if (res) {
 | 
									if (res) {
 | 
				
			||||||
					return res;
 | 
										return res;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			let type = 'hint';
 | 
								let type = 'hint';
 | 
				
			||||||
			if (remark.prioritaet || remark.type) {
 | 
								if (remark.prioritaet || remark.prio || remark.type) {
 | 
				
			||||||
				type = 'status';
 | 
									type = 'status';
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (!remark.kategorie && remark.key || remark.disruptionID || remark.prioritaet && remark.prioritaet == 'HOCH') {
 | 
								if (!remark.priority && !remark.kategorie && remark.key || remark.disruptionID
 | 
				
			||||||
 | 
									|| remark.prioritaet && remark.prioritaet == 'HOCH' || remark.prio && remark.prio == 'HOCH' || remark.priority && remark.priority < 100) {
 | 
				
			||||||
				type = 'warning';
 | 
									type = 'warning';
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			let res = {
 | 
								let res = {
 | 
				
			||||||
				code: remark.code || remark.key,
 | 
									code: remark.code || remark.key,
 | 
				
			||||||
				summary: remark.nachrichtKurz || remark.value || remark.ueberschrift || remark.text || Object.values(remark.descriptions || {})
 | 
									summary: remark.nachrichtKurz || remark.value || remark.ueberschrift || remark.text
 | 
				
			||||||
 | 
									|| Object.values(remark.descriptions || {})
 | 
				
			||||||
					.shift()?.textShort,
 | 
										.shift()?.textShort,
 | 
				
			||||||
				text: remark.nachrichtLang || remark.value || remark.text || Object.values(remark.descriptions || {})
 | 
									text: remark.nachrichtLang || remark.value || remark.text
 | 
				
			||||||
 | 
									|| Object.values(remark.descriptions || {})
 | 
				
			||||||
					.shift()?.text,
 | 
										.shift()?.text,
 | 
				
			||||||
				type: type,
 | 
									type: type,
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			if (remark.modDateTime) {
 | 
								if (remark.modDateTime || remark.letzteAktualisierung) {
 | 
				
			||||||
				res.modified = ctx.profile.parseDateTime(ctx, null, remark.modDateTime);
 | 
									res.modified = ctx.profile.parseDateTime(ctx, null, remark.modDateTime || remark.letzteAktualisierung);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// TODO fromStops, toStops = routeIdxFrom ??
 | 
								// TODO fromStops, toStops = routeIdxFrom ??
 | 
				
			||||||
			// TODO prio
 | 
								// TODO prio
 | 
				
			||||||
			return res;
 | 
								return res;
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		.filter(remark => remark.code != 'BEF');
 | 
							.filter(remark => remark.code != 'BEF' && remark.code != 'OP');
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -189,11 +198,15 @@ const parseRemarks = (ctx, ref) => {
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const isStopCancelled = (ref) => {
 | 
					const parseCancelled = (ref) => {
 | 
				
			||||||
	return Boolean(ref.risNotizen.find(r => r.key == 'text.realtime.stop.cancelled' || r.type == 'HALT_AUSFALL'));
 | 
						return ref.canceled || ref.cancelled || (ref.risNotizen || ref.echtzeitNotizen) && Boolean((ref.risNotizen || ref.echtzeitNotizen).find(r => r.key == 'text.realtime.stop.cancelled'
 | 
				
			||||||
 | 
							|| r.type == 'HALT_AUSFALL'
 | 
				
			||||||
 | 
							|| r.text == 'Halt entfällt'
 | 
				
			||||||
 | 
							|| r.text == 'Stop cancelled',
 | 
				
			||||||
 | 
						));
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
	parseRemarks,
 | 
						parseRemarks,
 | 
				
			||||||
	isStopCancelled,
 | 
						parseCancelled,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,7 @@
 | 
				
			||||||
import {parseRemarks, isStopCancelled} from './remarks.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const parseStopover = (ctx, st, date) => { // st = raw stopover
 | 
					const parseStopover = (ctx, st, date) => { // st = raw stopover
 | 
				
			||||||
	const {profile, opt} = ctx;
 | 
						const {profile, opt} = ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const cancelled = isStopCancelled(st);
 | 
						const cancelled = profile.parseCancelled(st);
 | 
				
			||||||
	const arr = profile.parseWhen(ctx, date, st.ankunftsZeitpunkt, st.ezAnkunftsZeitpunkt, cancelled);
 | 
						const arr = profile.parseWhen(ctx, date, st.ankunftsZeitpunkt, st.ezAnkunftsZeitpunkt, cancelled);
 | 
				
			||||||
	const arrPl = profile.parsePlatform(ctx, st.gleis, st.ezGleis);
 | 
						const arrPl = profile.parsePlatform(ctx, st.gleis, st.ezGleis);
 | 
				
			||||||
	const dep = profile.parseWhen(ctx, date, st.abfahrtsZeitpunkt, st.ezAbfahrtsZeitpunkt, cancelled);
 | 
						const dep = profile.parseWhen(ctx, date, st.abfahrtsZeitpunkt, st.ezAbfahrtsZeitpunkt, cancelled);
 | 
				
			||||||
| 
						 | 
					@ -51,7 +49,7 @@ const parseStopover = (ctx, st, date) => { // st = raw stopover
 | 
				
			||||||
	// TODO res.additional = true;
 | 
						// TODO res.additional = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (opt.remarks) {
 | 
						if (opt.remarks) {
 | 
				
			||||||
		res.remarks = parseRemarks(ctx, st);
 | 
							res.remarks = profile.parseRemarks(ctx, st);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										32
									
								
								test/dbnav-departures.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								test/dbnav-departures.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					// todo: use import assertions once they're supported by Node.js & ESLint
 | 
				
			||||||
 | 
					// https://github.com/tc39/proposal-import-assertions
 | 
				
			||||||
 | 
					import {createRequire} from 'module';
 | 
				
			||||||
 | 
					const require = createRequire(import.meta.url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import tap from 'tap';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {createClient} from '../index.js';
 | 
				
			||||||
 | 
					import {profile as rawProfile} from '../p/db/index.js';
 | 
				
			||||||
 | 
					const res = require('./fixtures/dbnav-departures.json');
 | 
				
			||||||
 | 
					import {dbnavDepartures as expected} from './fixtures/dbnav-departures.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const client = createClient(rawProfile, 'public-transport/hafas-client:test');
 | 
				
			||||||
 | 
					const {profile} = client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const opt = {
 | 
				
			||||||
 | 
						direction: null,
 | 
				
			||||||
 | 
						duration: 10,
 | 
				
			||||||
 | 
						linesOfStops: true,
 | 
				
			||||||
 | 
						remarks: true,
 | 
				
			||||||
 | 
						stopovers: true,
 | 
				
			||||||
 | 
						includeRelatedStations: true,
 | 
				
			||||||
 | 
						when: '2019-08-19T20:30:00+02:00',
 | 
				
			||||||
 | 
						products: {},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tap.test('parses a regio-guide departure correctly', (t) => {
 | 
				
			||||||
 | 
						const ctx = {profile, opt, common: null, res};
 | 
				
			||||||
 | 
						const departures = res.bahnhofstafelAbfahrtPositionen.map(d => profile.parseDeparture(ctx, d));
 | 
				
			||||||
 | 
						t.same(departures, expected);
 | 
				
			||||||
 | 
						t.end();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										14
									
								
								test/fixtures/db-arrivals.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								test/fixtures/db-arrivals.js
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -5,7 +5,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8089100',
 | 
								id: '8089100',
 | 
				
			||||||
			name: 'Berlin Jungfernheide (S)',
 | 
								name: 'Berlin Jungfernheide (S)',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:00:00+01:00',
 | 
							when: '2024-12-08T01:00:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:00:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:00:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -37,7 +36,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8089118',
 | 
								id: '8089118',
 | 
				
			||||||
			name: 'Berlin Beusselstraße',
 | 
								name: 'Berlin Beusselstraße',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -47,7 +45,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '730985',
 | 
								id: '730985',
 | 
				
			||||||
			name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
								name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:00:00+01:00',
 | 
							when: '2024-12-08T01:00:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:00:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:00:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -85,7 +82,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '732218',
 | 
								id: '732218',
 | 
				
			||||||
			name: 'Rudow (U), Berlin',
 | 
								name: 'Rudow (U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -95,7 +91,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '730985',
 | 
								id: '730985',
 | 
				
			||||||
			name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
								name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:03:00+01:00',
 | 
							when: '2024-12-08T01:03:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:03:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:03:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -133,7 +128,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '730993',
 | 
								id: '730993',
 | 
				
			||||||
			name: 'Goerdelersteg, Berlin',
 | 
								name: 'Goerdelersteg, Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -143,7 +137,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8089100',
 | 
								id: '8089100',
 | 
				
			||||||
			name: 'Berlin Jungfernheide (S)',
 | 
								name: 'Berlin Jungfernheide (S)',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:05:00+01:00',
 | 
							when: '2024-12-08T01:05:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:05:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:05:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -175,7 +168,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8089118',
 | 
								id: '8089118',
 | 
				
			||||||
			name: 'Berlin Beusselstraße',
 | 
								name: 'Berlin Beusselstraße',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -185,7 +177,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '730985',
 | 
								id: '730985',
 | 
				
			||||||
			name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
								name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:10:00+01:00',
 | 
							when: '2024-12-08T01:10:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:10:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:10:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -223,7 +214,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '732218',
 | 
								id: '732218',
 | 
				
			||||||
			name: 'Rudow (U), Berlin',
 | 
								name: 'Rudow (U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -233,7 +223,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8089100',
 | 
								id: '8089100',
 | 
				
			||||||
			name: 'Berlin Jungfernheide (S)',
 | 
								name: 'Berlin Jungfernheide (S)',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:10:00+01:00',
 | 
							when: '2024-12-08T01:10:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:10:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:10:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -265,7 +254,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8089118',
 | 
								id: '8089118',
 | 
				
			||||||
			name: 'Berlin Beusselstraße',
 | 
								name: 'Berlin Beusselstraße',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -275,7 +263,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '730985',
 | 
								id: '730985',
 | 
				
			||||||
			name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
								name: 'Jungfernheide Bahnhof (S+U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-08T01:10:00+01:00',
 | 
							when: '2024-12-08T01:10:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-08T01:10:00+01:00',
 | 
							plannedWhen: '2024-12-08T01:10:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -313,7 +300,6 @@ const dbArrivals = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '731176',
 | 
								id: '731176',
 | 
				
			||||||
			name: 'Rathaus Spandau (S+U), Berlin',
 | 
								name: 'Rathaus Spandau (S+U), Berlin',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		destination: null,
 | 
							destination: null,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								test/fixtures/db-departures-regio-guide.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								test/fixtures/db-departures-regio-guide.js
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -5,7 +5,6 @@ const dbDepartures = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8000365',
 | 
								id: '8000365',
 | 
				
			||||||
			name: 'Dombühl',
 | 
								name: 'Dombühl',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-12T12:34:00+01:00',
 | 
							when: '2024-12-12T12:34:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-12T12:34:00+01:00',
 | 
							plannedWhen: '2024-12-12T12:34:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -16,7 +15,7 @@ const dbDepartures = [
 | 
				
			||||||
		provenance: null,
 | 
							provenance: null,
 | 
				
			||||||
		line: {
 | 
							line: {
 | 
				
			||||||
			type: 'line',
 | 
								type: 'line',
 | 
				
			||||||
			id: '88617',
 | 
								id: 're-90-88617',
 | 
				
			||||||
			fahrtNr: '88617',
 | 
								fahrtNr: '88617',
 | 
				
			||||||
			name: 'RE 90',
 | 
								name: 'RE 90',
 | 
				
			||||||
			public: true,
 | 
								public: true,
 | 
				
			||||||
| 
						 | 
					@ -31,7 +30,6 @@ const dbDepartures = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '8000284',
 | 
								id: '8000284',
 | 
				
			||||||
			name: 'Nürnberg Hbf',
 | 
								name: 'Nürnberg Hbf',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -40,7 +38,6 @@ const dbDepartures = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '682943',
 | 
								id: '682943',
 | 
				
			||||||
			name: 'Bahnhof, Dombühl',
 | 
								name: 'Bahnhof, Dombühl',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-12T12:50:00+01:00',
 | 
							when: '2024-12-12T12:50:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-12T12:50:00+01:00',
 | 
							plannedWhen: '2024-12-12T12:50:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -51,7 +48,7 @@ const dbDepartures = [
 | 
				
			||||||
		provenance: null,
 | 
							provenance: null,
 | 
				
			||||||
		line: {
 | 
							line: {
 | 
				
			||||||
			type: 'line',
 | 
								type: 'line',
 | 
				
			||||||
			id: '2221',
 | 
								id: 'bus-813-2221',
 | 
				
			||||||
			fahrtNr: '2221',
 | 
								fahrtNr: '2221',
 | 
				
			||||||
			name: 'Bus 813',
 | 
								name: 'Bus 813',
 | 
				
			||||||
			public: true,
 | 
								public: true,
 | 
				
			||||||
| 
						 | 
					@ -66,7 +63,6 @@ const dbDepartures = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '676542',
 | 
								id: '676542',
 | 
				
			||||||
			name: 'Gymnasium, Dinkelsbühl',
 | 
								name: 'Gymnasium, Dinkelsbühl',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -75,7 +71,6 @@ const dbDepartures = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '682943',
 | 
								id: '682943',
 | 
				
			||||||
			name: 'Bahnhof, Dombühl',
 | 
								name: 'Bahnhof, Dombühl',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		when: '2024-12-12T12:50:00+01:00',
 | 
							when: '2024-12-12T12:50:00+01:00',
 | 
				
			||||||
		plannedWhen: '2024-12-12T12:50:00+01:00',
 | 
							plannedWhen: '2024-12-12T12:50:00+01:00',
 | 
				
			||||||
| 
						 | 
					@ -86,7 +81,7 @@ const dbDepartures = [
 | 
				
			||||||
		provenance: null,
 | 
							provenance: null,
 | 
				
			||||||
		line: {
 | 
							line: {
 | 
				
			||||||
			type: 'line',
 | 
								type: 'line',
 | 
				
			||||||
			id: '2177',
 | 
								id: 'bus-807-2177',
 | 
				
			||||||
			fahrtNr: '2177',
 | 
								fahrtNr: '2177',
 | 
				
			||||||
			name: 'Bus 807',
 | 
								name: 'Bus 807',
 | 
				
			||||||
			public: true,
 | 
								public: true,
 | 
				
			||||||
| 
						 | 
					@ -101,7 +96,6 @@ const dbDepartures = [
 | 
				
			||||||
			type: 'station',
 | 
								type: 'station',
 | 
				
			||||||
			id: '683407',
 | 
								id: '683407',
 | 
				
			||||||
			name: 'Bahnhof, Rothenburg ob der Tauber',
 | 
								name: 'Bahnhof, Rothenburg ob der Tauber',
 | 
				
			||||||
			location: null,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										224
									
								
								test/fixtures/dbnav-departures.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								test/fixtures/dbnav-departures.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,224 @@
 | 
				
			||||||
 | 
					const dbnavDepartures = [
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#929785#TA#1#DA#291224#1S#374704#1T#1502#LS#465246#LT#1530#PU#81#RT#1#CA#rfb#ZE#9870#ZB#RUF 9870#PC#9#FR#374704#FT#1502#TO#465246#TT#1530#',
 | 
				
			||||||
 | 
							stop: {
 | 
				
			||||||
 | 
								type: 'station',
 | 
				
			||||||
 | 
								id: '374704',
 | 
				
			||||||
 | 
								name: 'Bahnhof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
								location: {
 | 
				
			||||||
 | 
									type: 'location',
 | 
				
			||||||
 | 
									id: '374704',
 | 
				
			||||||
 | 
									latitude: 49.377189,
 | 
				
			||||||
 | 
									longitude: 10.191107,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							when: '2024-12-29T15:02:00+01:00',
 | 
				
			||||||
 | 
							plannedWhen: '2024-12-29T15:02:00+01:00',
 | 
				
			||||||
 | 
							delay: null,
 | 
				
			||||||
 | 
							platform: null,
 | 
				
			||||||
 | 
							plannedPlatform: null,
 | 
				
			||||||
 | 
							direction: 'ZOB, Creglingen',
 | 
				
			||||||
 | 
							provenance: null,
 | 
				
			||||||
 | 
							line: {
 | 
				
			||||||
 | 
								type: 'line',
 | 
				
			||||||
 | 
								id: 'ruf-9870',
 | 
				
			||||||
 | 
								name: 'RUF 9870',
 | 
				
			||||||
 | 
								fahrtNr: undefined,
 | 
				
			||||||
 | 
								public: true,
 | 
				
			||||||
 | 
								productName: 'RUF',
 | 
				
			||||||
 | 
								mode: 'taxi',
 | 
				
			||||||
 | 
								product: 'taxi',
 | 
				
			||||||
 | 
								operator: null,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							remarks: [],
 | 
				
			||||||
 | 
							origin: null,
 | 
				
			||||||
 | 
							destination: null,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#214076#TA#1#DA#291224#1S#8005190#1T#1505#LS#8000091#LT#1520#PU#81#RT#1#CA#RB#ZE#58904#ZB#RB 58904#PC#3#FR#8005190#FT#1505#TO#8000091#TT#1520#',
 | 
				
			||||||
 | 
							stop: {
 | 
				
			||||||
 | 
								type: 'station',
 | 
				
			||||||
 | 
								id: '8005190',
 | 
				
			||||||
 | 
								name: 'Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
								location: {
 | 
				
			||||||
 | 
									type: 'location',
 | 
				
			||||||
 | 
									id: '8005190',
 | 
				
			||||||
 | 
									latitude: 49.376686,
 | 
				
			||||||
 | 
									longitude: 10.190702,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							when: '2024-12-29T15:05:00+01:00',
 | 
				
			||||||
 | 
							plannedWhen: '2024-12-29T15:05:00+01:00',
 | 
				
			||||||
 | 
							delay: 0,
 | 
				
			||||||
 | 
							platform: '1',
 | 
				
			||||||
 | 
							plannedPlatform: '1',
 | 
				
			||||||
 | 
							direction: 'Steinach(bei Rothenburg ob der Tauber)',
 | 
				
			||||||
 | 
							provenance: null,
 | 
				
			||||||
 | 
							line: {
 | 
				
			||||||
 | 
								type: 'line',
 | 
				
			||||||
 | 
								id: 'rb-82',
 | 
				
			||||||
 | 
								name: 'RB 82',
 | 
				
			||||||
 | 
								fahrtNr: undefined,
 | 
				
			||||||
 | 
								public: true,
 | 
				
			||||||
 | 
								productName: 'RB',
 | 
				
			||||||
 | 
								mode: 'train',
 | 
				
			||||||
 | 
								product: 'regional',
 | 
				
			||||||
 | 
								operator: null,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							remarks: [],
 | 
				
			||||||
 | 
							origin: null,
 | 
				
			||||||
 | 
							destination: null,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#863886#TA#3#DA#291224#1S#682943#1T#1450#LS#683407#LT#1531#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus  807#PC#5#FR#682943#FT#1450#TO#683407#TT#1531#',
 | 
				
			||||||
 | 
							stop: {
 | 
				
			||||||
 | 
								type: 'station',
 | 
				
			||||||
 | 
								id: '680433',
 | 
				
			||||||
 | 
								name: 'Schlachthof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
								location: {
 | 
				
			||||||
 | 
									type: 'location',
 | 
				
			||||||
 | 
									id: '680433',
 | 
				
			||||||
 | 
									latitude: 49.373989,
 | 
				
			||||||
 | 
									longitude: 10.189255,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							when: '2024-12-29T15:30:00+01:00',
 | 
				
			||||||
 | 
							plannedWhen: '2024-12-29T15:30:00+01:00',
 | 
				
			||||||
 | 
							delay: null,
 | 
				
			||||||
 | 
							platform: null,
 | 
				
			||||||
 | 
							plannedPlatform: null,
 | 
				
			||||||
 | 
							direction: 'Bahnhof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
							provenance: null,
 | 
				
			||||||
 | 
							line: {
 | 
				
			||||||
 | 
								type: 'line',
 | 
				
			||||||
 | 
								id: 'bus-807',
 | 
				
			||||||
 | 
								name: 'Bus 807',
 | 
				
			||||||
 | 
								fahrtNr: undefined,
 | 
				
			||||||
 | 
								public: true,
 | 
				
			||||||
 | 
								productName: 'Bus',
 | 
				
			||||||
 | 
								mode: 'bus',
 | 
				
			||||||
 | 
								product: 'bus',
 | 
				
			||||||
 | 
								operator: null,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							remarks: [],
 | 
				
			||||||
 | 
							origin: null,
 | 
				
			||||||
 | 
							destination: null,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus  807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#',
 | 
				
			||||||
 | 
							stop: {
 | 
				
			||||||
 | 
								type: 'station',
 | 
				
			||||||
 | 
								id: '683407',
 | 
				
			||||||
 | 
								name: 'Bahnhof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
								location: {
 | 
				
			||||||
 | 
									type: 'location',
 | 
				
			||||||
 | 
									id: '683407',
 | 
				
			||||||
 | 
									latitude: 49.37718,
 | 
				
			||||||
 | 
									longitude: 10.190711,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							when: '2024-12-29T15:32:00+01:00',
 | 
				
			||||||
 | 
							plannedWhen: '2024-12-29T15:32:00+01:00',
 | 
				
			||||||
 | 
							delay: null,
 | 
				
			||||||
 | 
							platform: null,
 | 
				
			||||||
 | 
							plannedPlatform: null,
 | 
				
			||||||
 | 
							direction: 'Bahnhof, Dombühl',
 | 
				
			||||||
 | 
							provenance: null,
 | 
				
			||||||
 | 
							line: {
 | 
				
			||||||
 | 
								type: 'line',
 | 
				
			||||||
 | 
								id: 'bus-807',
 | 
				
			||||||
 | 
								name: 'Bus 807',
 | 
				
			||||||
 | 
								fahrtNr: undefined,
 | 
				
			||||||
 | 
								public: true,
 | 
				
			||||||
 | 
								productName: 'Bus',
 | 
				
			||||||
 | 
								mode: 'bus',
 | 
				
			||||||
 | 
								product: 'bus',
 | 
				
			||||||
 | 
								operator: null,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							remarks: [],
 | 
				
			||||||
 | 
							origin: null,
 | 
				
			||||||
 | 
							destination: null,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus  807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#',
 | 
				
			||||||
 | 
							stop: {
 | 
				
			||||||
 | 
								type: 'station',
 | 
				
			||||||
 | 
								id: '680433',
 | 
				
			||||||
 | 
								name: 'Schlachthof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
								location: {
 | 
				
			||||||
 | 
									type: 'location',
 | 
				
			||||||
 | 
									id: '680433',
 | 
				
			||||||
 | 
									latitude: 49.373989,
 | 
				
			||||||
 | 
									longitude: 10.189255,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							when: '2024-12-29T15:33:00+01:00',
 | 
				
			||||||
 | 
							plannedWhen: '2024-12-29T15:33:00+01:00',
 | 
				
			||||||
 | 
							delay: null,
 | 
				
			||||||
 | 
							platform: null,
 | 
				
			||||||
 | 
							plannedPlatform: null,
 | 
				
			||||||
 | 
							direction: 'Bahnhof, Dombühl',
 | 
				
			||||||
 | 
							provenance: null,
 | 
				
			||||||
 | 
							line: {
 | 
				
			||||||
 | 
								type: 'line',
 | 
				
			||||||
 | 
								id: 'bus-807',
 | 
				
			||||||
 | 
								name: 'Bus 807',
 | 
				
			||||||
 | 
								fahrtNr: undefined,
 | 
				
			||||||
 | 
								public: true,
 | 
				
			||||||
 | 
								productName: 'Bus',
 | 
				
			||||||
 | 
								mode: 'bus',
 | 
				
			||||||
 | 
								product: 'bus',
 | 
				
			||||||
 | 
								operator: null,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							remarks: [],
 | 
				
			||||||
 | 
							origin: null,
 | 
				
			||||||
 | 
							destination: null,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#864022#TA#1#DA#291224#1S#677019#1T#1458#LS#683407#LT#1548#PU#81#RT#1#CA#Bus#ZE#817#ZB#Bus  817#PC#5#FR#677019#FT#1458#TO#683407#TT#1548#',
 | 
				
			||||||
 | 
							stop: {
 | 
				
			||||||
 | 
								type: 'station',
 | 
				
			||||||
 | 
								id: '680433',
 | 
				
			||||||
 | 
								name: 'Schlachthof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
								location: {
 | 
				
			||||||
 | 
									type: 'location',
 | 
				
			||||||
 | 
									id: '680433',
 | 
				
			||||||
 | 
									latitude: 49.373989,
 | 
				
			||||||
 | 
									longitude: 10.189255,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							when: null,
 | 
				
			||||||
 | 
							plannedWhen: '2024-12-29T15:47:00+01:00',
 | 
				
			||||||
 | 
							prognosedWhen: null,
 | 
				
			||||||
 | 
							delay: null,
 | 
				
			||||||
 | 
							platform: null,
 | 
				
			||||||
 | 
							plannedPlatform: null,
 | 
				
			||||||
 | 
							prognosedPlatform: null,
 | 
				
			||||||
 | 
							direction: 'Bahnhof, Rothenburg ob der Tauber',
 | 
				
			||||||
 | 
							provenance: null,
 | 
				
			||||||
 | 
							line: {
 | 
				
			||||||
 | 
								type: 'line',
 | 
				
			||||||
 | 
								id: 'bus-817',
 | 
				
			||||||
 | 
								name: 'Bus 817',
 | 
				
			||||||
 | 
								fahrtNr: undefined,
 | 
				
			||||||
 | 
								public: true,
 | 
				
			||||||
 | 
								productName: 'Bus',
 | 
				
			||||||
 | 
								mode: 'bus',
 | 
				
			||||||
 | 
								product: 'bus',
 | 
				
			||||||
 | 
								operator: null,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							remarks: [{
 | 
				
			||||||
 | 
								code: undefined,
 | 
				
			||||||
 | 
								summary: 'Halt entfällt',
 | 
				
			||||||
 | 
								text: 'Halt entfällt',
 | 
				
			||||||
 | 
								type: 'warning',
 | 
				
			||||||
 | 
							}],
 | 
				
			||||||
 | 
							origin: null,
 | 
				
			||||||
 | 
							destination: null,
 | 
				
			||||||
 | 
							cancelled: true,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
						dbnavDepartures,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										1
									
								
								test/fixtures/dbnav-departures.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/fixtures/dbnav-departures.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					{"bahnhofstafelAbfahrtPositionen":[{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#929785#TA#1#DA#291224#1S#374704#1T#1502#LS#465246#LT#1530#PU#81#RT#1#CA#rfb#ZE#9870#ZB#RUF 9870#PC#9#FR#374704#FT#1502#TO#465246#TT#1530#","kurztext":"RUF","mitteltext":"RUF 9870","abfrageOrt":{"name":"Bahnhof, Rothenburg ob der Tauber","locationId":"A=1@O=Bahnhof, Rothenburg ob der Tauber@X=10191107@Y=49377189@U=81@L=374704@","evaNr":"374704","stationId":"5393"},"richtung":"ZOB, Creglingen","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:02:00+01:00","produktGattung":"ANRUFPFLICHTIGEVERKEHRE"},{"gleis":"1","zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#214076#TA#1#DA#291224#1S#8005190#1T#1505#LS#8000091#LT#1520#PU#81#RT#1#CA#RB#ZE#58904#ZB#RB 58904#PC#3#FR#8005190#FT#1505#TO#8000091#TT#1520#","kurztext":"RB","mitteltext":"RB 82","abfrageOrt":{"name":"Rothenburg ob der Tauber","locationId":"A=1@O=Rothenburg ob der Tauber@X=10190702@Y=49376686@U=81@L=8005190@i=U×008022698@","evaNr":"8005190","stationId":"5393"},"richtung":"Steinach(bei Rothenburg ob der Tauber)","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:05:00+01:00","produktGattung":"RB","ezAbgangsDatum":"2024-12-29T15:05:00+01:00"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#863886#TA#3#DA#291224#1S#682943#1T#1450#LS#683407#LT#1531#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus  807#PC#5#FR#682943#FT#1450#TO#683407#TT#1531#","kurztext":"Bus","mitteltext":"Bus 807","abfrageOrt":{"name":"Schlachthof, Rothenburg ob der Tauber","locationId":"A=1@O=Schlachthof, Rothenburg ob der Tauber@X=10189255@Y=49373989@U=81@L=680433@","evaNr":"680433"},"richtung":"Bahnhof, Rothenburg ob der Tauber","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:30:00+01:00","produktGattung":"BUS"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus  807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#","kurztext":"Bus","mitteltext":"Bus 807","abfrageOrt":{"name":"Bahnhof, Rothenburg ob der Tauber","locationId":"A=1@O=Bahnhof, Rothenburg ob der Tauber@X=10190711@Y=49377180@U=81@L=683407@","evaNr":"683407","stationId":"5393"},"richtung":"Bahnhof, Dombühl","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:32:00+01:00","produktGattung":"BUS"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus  807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#","kurztext":"Bus","mitteltext":"Bus 807","abfrageOrt":{"name":"Schlachthof, Rothenburg ob der Tauber","locationId":"A=1@O=Schlachthof, Rothenburg ob der Tauber@X=10189255@Y=49373989@U=81@L=680433@","evaNr":"680433"},"richtung":"Bahnhof, Dombühl","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:33:00+01:00","produktGattung":"BUS"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#864022#TA#1#DA#291224#1S#677019#1T#1458#LS#683407#LT#1548#PU#81#RT#1#CA#Bus#ZE#817#ZB#Bus  817#PC#5#FR#677019#FT#1458#TO#683407#TT#1548#","kurztext":"Bus","mitteltext":"Bus 817","abfrageOrt":{"name":"Schlachthof, Rothenburg ob der Tauber","locationId":"A=1@O=Schlachthof, Rothenburg ob der Tauber@X=10189255@Y=49373989@U=81@L=680433@","evaNr":"680433"},"richtung":"Bahnhof, Rothenburg ob der Tauber","echtzeitNotizen":[{"text":"Halt entfällt"}],"abgangsDatum":"2024-12-29T15:47:00+01:00","produktGattung":"BUS"}]}
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,9 @@
 | 
				
			||||||
import tap from 'tap';
 | 
					import tap from 'tap';
 | 
				
			||||||
import {parseLine as parse} from '../../parse/line.js';
 | 
					import {parseLine as parse} from '../../parse/line.js';
 | 
				
			||||||
 | 
					import {products} from '../../lib/products.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const profile = {
 | 
					const profile = {
 | 
				
			||||||
	products: [
 | 
						products: products,
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			id: 'nationalExpress',
 | 
					 | 
				
			||||||
			mode: 'train',
 | 
					 | 
				
			||||||
			name: 'InterCityExpress',
 | 
					 | 
				
			||||||
			short: 'ICE',
 | 
					 | 
				
			||||||
			vendo: 'ICE',
 | 
					 | 
				
			||||||
			ris: 'HIGH_SPEED_TRAIN',
 | 
					 | 
				
			||||||
			default: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			id: 'bus',
 | 
					 | 
				
			||||||
			mode: 'bus',
 | 
					 | 
				
			||||||
			name: 'Bus',
 | 
					 | 
				
			||||||
			short: 'B',
 | 
					 | 
				
			||||||
			vendo: 'BUS',
 | 
					 | 
				
			||||||
			ris: 'BUS',
 | 
					 | 
				
			||||||
			default: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	],
 | 
					 | 
				
			||||||
	parseOperator: _ => null,
 | 
						parseOperator: _ => null,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const ctx = {
 | 
					const ctx = {
 | 
				
			||||||
| 
						 | 
					@ -172,3 +154,39 @@ tap.test('parses ris entry correctly', (t) => {
 | 
				
			||||||
	t.same(parse(ctx, input), expected);
 | 
						t.same(parse(ctx, input), expected);
 | 
				
			||||||
	t.end();
 | 
						t.end();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tap.test('parses dbnav ruf correctly', (t) => {
 | 
				
			||||||
 | 
						const input = {zuglaufId: 'foo', kurztext: 'RUF', mitteltext: 'RUF 9870', produktGattung: 'ANRUFPFLICHTIGEVERKEHRE'};
 | 
				
			||||||
 | 
						const expected = {
 | 
				
			||||||
 | 
							type: 'line',
 | 
				
			||||||
 | 
							id: 'ruf-9870',
 | 
				
			||||||
 | 
							name: 'RUF 9870',
 | 
				
			||||||
 | 
							fahrtNr: undefined,
 | 
				
			||||||
 | 
							public: true,
 | 
				
			||||||
 | 
							product: 'taxi',
 | 
				
			||||||
 | 
							productName: 'RUF',
 | 
				
			||||||
 | 
							mode: 'taxi',
 | 
				
			||||||
 | 
							operator: null,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						t.same(parse(ctx, input), expected);
 | 
				
			||||||
 | 
						t.end();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tap.test('parses regio guide ruf correctly', (t) => {
 | 
				
			||||||
 | 
						const input = {train: {journeyId: 'foo', category: 'RUF', type: 'SHUTTLE', no: 47403, lineName: '9870'}, category: 'SHUTTLE', administration: {id: 'vrn062', operatorCode: 'DPN', operatorName: 'Nahreisezug'}};
 | 
				
			||||||
 | 
						const expected = {
 | 
				
			||||||
 | 
							type: 'line',
 | 
				
			||||||
 | 
							id: 'ruf-9870-47403',
 | 
				
			||||||
 | 
							name: 'RUF 9870',
 | 
				
			||||||
 | 
							fahrtNr: '47403',
 | 
				
			||||||
 | 
							public: true,
 | 
				
			||||||
 | 
							product: 'taxi',
 | 
				
			||||||
 | 
							productName: 'RUF',
 | 
				
			||||||
 | 
							mode: 'taxi',
 | 
				
			||||||
 | 
							operator: null,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.same(parse(ctx, input), expected);
 | 
				
			||||||
 | 
						t.end();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,3 +37,16 @@ tap.test('parses nothing', (t) => {
 | 
				
			||||||
	t.same(parse(ctx, op), null);
 | 
						t.same(parse(ctx, op), null);
 | 
				
			||||||
	t.end();
 | 
						t.end();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tap.test('parses dbnav operator correctly', (t) => {
 | 
				
			||||||
 | 
						const op = [{text: 'DB Fernverkehr AG', key: 'OP'}];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.same(parse(ctx, op), {
 | 
				
			||||||
 | 
							type: 'operator',
 | 
				
			||||||
 | 
							id: 'db-fernverkehr-ag',
 | 
				
			||||||
 | 
							name: 'DB Fernverkehr AG',
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						t.end();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,3 +190,36 @@ tap.test('parses ris attributes correctly', (t) => {
 | 
				
			||||||
	t.same(parse(ctx, input), expected);
 | 
						t.same(parse(ctx, input), expected);
 | 
				
			||||||
	t.end();
 | 
						t.end();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tap.test('parses dbnav attributes correctly', (t) => {
 | 
				
			||||||
 | 
						const input = {
 | 
				
			||||||
 | 
							echtzeitNotizen: [{text: 'Halt entfällt'}],
 | 
				
			||||||
 | 
							himNotizen: [{text: 'Coach 27 is closed to passengers today.', prio: 'NORMAL', ueberschrift: 'Information.', letzteAktualisierung: '2024-12-16T08:35:53+00:00'}],
 | 
				
			||||||
 | 
							attributNotizen: [{text: 'Komfort Check-in possible (visit bahn.de/kci for more information)', key: 'CK', priority: 200}, {text: 'DB Fernverkehr AG', key: 'OP'}],
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const expected = [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								code: undefined,
 | 
				
			||||||
 | 
								summary: 'Halt entfällt',
 | 
				
			||||||
 | 
								text: 'Halt entfällt',
 | 
				
			||||||
 | 
								type: 'warning',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								code: undefined,
 | 
				
			||||||
 | 
								summary: 'Information.',
 | 
				
			||||||
 | 
								text: 'Coach 27 is closed to passengers today.',
 | 
				
			||||||
 | 
								modified: '2024-12-16T09:35:53+01:00',
 | 
				
			||||||
 | 
								type: 'status',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								code: 'CK',
 | 
				
			||||||
 | 
								summary: 'Komfort Check-in possible (visit bahn.de/kci for more information)',
 | 
				
			||||||
 | 
								text: 'Komfort Check-in possible (visit bahn.de/kci for more information)',
 | 
				
			||||||
 | 
								type: 'hint',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.same(parse(ctx, input), expected);
 | 
				
			||||||
 | 
						t.end();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue