zet-api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,561 @@
1
+ /** Auth tokens returned by login and refresh endpoints. */
2
+ interface ZETAuthTokens {
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ }
6
+ /** Payload used to authenticate a user. */
7
+ interface ZETLoginRequest {
8
+ username: string;
9
+ password: string;
10
+ revokeOtherTokens?: boolean;
11
+ fcmToken?: string;
12
+ }
13
+ /** Account details for the currently authenticated user. */
14
+ interface ZETAccount {
15
+ id: number;
16
+ uid: string;
17
+ email: string;
18
+ firstName: string;
19
+ lastName: string;
20
+ ePurseAmount: number;
21
+ clientId: string | null;
22
+ language: number;
23
+ isFullProfileActivationInProgress: boolean;
24
+ messages: unknown[];
25
+ processes: unknown | null;
26
+ }
27
+ /** Traffic news item from `/NewsProxyService.Api/api/newsfeed`. */
28
+ interface ZETNewsItem {
29
+ title: string;
30
+ description: string;
31
+ link: string;
32
+ datePublished: string;
33
+ type: number;
34
+ lines: number[];
35
+ stations: unknown[];
36
+ validFrom: string;
37
+ validTo: string;
38
+ }
39
+ /** Wallet top-up/order record. */
40
+ interface ZETOrder {
41
+ orderId: number;
42
+ accountId: number;
43
+ documentContentToken: string;
44
+ dateTimeCreated: string;
45
+ caption: string;
46
+ period: unknown | null;
47
+ orderNumber: string | null;
48
+ orderStatus: number;
49
+ orderType: number;
50
+ source: number;
51
+ language: number;
52
+ amount: number;
53
+ invoiceNumber: string;
54
+ installmentNumber: number;
55
+ paymentType: number;
56
+ authorizationCode: string;
57
+ cardName: string;
58
+ bankName: string;
59
+ isCorvusCompleted: boolean | null;
60
+ isCardUpdateNeeded: boolean | null;
61
+ }
62
+ /** Query parameters for order history. */
63
+ interface ZETOrdersParams {
64
+ completedOnly?: boolean;
65
+ pageSize?: number;
66
+ pageNumber?: number;
67
+ }
68
+ /** Zone representation used in multiple responses. */
69
+ interface ZETZoneInfo {
70
+ value: number;
71
+ caption: string;
72
+ }
73
+ /**
74
+ * Ticket validation data.
75
+ * Fields beyond `id`, `vehicleNumber`, and `wkt` are optional because
76
+ * some responses include a lighter validation object.
77
+ */
78
+ interface ZETValidation {
79
+ id: number;
80
+ vehicleNumber: string;
81
+ wkt: unknown | null;
82
+ precision?: number | null;
83
+ validationDateTime?: string;
84
+ validated?: boolean;
85
+ ticketStations?: unknown[];
86
+ }
87
+ /** Item from paginated ticket purchase history. */
88
+ interface ZETTicketSummary {
89
+ ticketId: number;
90
+ created: string;
91
+ caption: string;
92
+ vehicleNumber: string;
93
+ zones: string;
94
+ mPurseState: number;
95
+ transactionAmount: number;
96
+ totalCount: number;
97
+ }
98
+ /** Full ticket model returned by active ticket and purchase endpoints. */
99
+ interface ZETTicket {
100
+ id: number;
101
+ ticketType: number;
102
+ passengers: number;
103
+ accountId: number;
104
+ clientId: string | null;
105
+ caption: string;
106
+ description: string | null;
107
+ barcode: string | null;
108
+ validFrom: string;
109
+ validTo: string;
110
+ articleId: number;
111
+ trafficZone: number;
112
+ couponId: unknown | null;
113
+ trafficAreas: unknown[];
114
+ progress: number;
115
+ statusType: ZETTicketStatus;
116
+ currentTime: string;
117
+ validInZones: ZETZoneInfo[];
118
+ validations: ZETValidation[];
119
+ relation: unknown | null;
120
+ subsidyType: unknown | null;
121
+ hzStamp: unknown | null;
122
+ }
123
+ /** Ticket status values observed in API responses. */
124
+ declare enum ZETTicketStatus {
125
+ Pending = 0,
126
+ Active = 1
127
+ }
128
+ /** Query parameters for paginated ticket history. */
129
+ interface ZETTicketsParams {
130
+ pageSize?: number;
131
+ pageNumber?: number;
132
+ }
133
+ /** Query parameters for active/filtered tickets. */
134
+ interface ZETActiveTicketsParams {
135
+ isControlTicket?: boolean;
136
+ validOnly?: boolean;
137
+ includeValidations?: boolean;
138
+ }
139
+ /** Ticket article returned by `/tickets/article`. */
140
+ interface ZETArticle {
141
+ articleId: number;
142
+ articleCaption: string;
143
+ validInZones: ZETZoneInfo[];
144
+ availableInZones: ZETZoneInfo[];
145
+ validOnlyInZoneOfAcquisition: boolean;
146
+ price: number;
147
+ }
148
+ /** Response model for article lookup endpoint. */
149
+ interface ZETArticlesResponse {
150
+ foundArticles: ZETArticle[];
151
+ foundInTheVicinityOfStationsIds: unknown | null;
152
+ extractedZone: ZETZoneInfo;
153
+ }
154
+ /** Query parameters for article lookup endpoint. */
155
+ interface ZETArticlesParams {
156
+ lat?: number;
157
+ lng?: number;
158
+ precision?: number;
159
+ }
160
+ /** Payload used to purchase a ticket. */
161
+ interface ZETBuyTicketRequest {
162
+ trafficZone: number;
163
+ ticketType?: number;
164
+ passengers?: number;
165
+ articleId: number;
166
+ vehicleNumber: string;
167
+ wkt?: string | null;
168
+ precision?: number | null;
169
+ ticketStations?: unknown[];
170
+ }
171
+ /** Payload used by `PUT /tickets/ticket` to update vehicle validation. */
172
+ interface ZETChangeVehicleRequest {
173
+ accountId: number;
174
+ vehicleNumber: string;
175
+ precision?: number | null;
176
+ wkt?: string | null;
177
+ }
178
+ /** Response payload for `PUT /tickets/ticket`. */
179
+ interface ZETChangeVehicleResponse {
180
+ validatedTickets: ZETTicket[];
181
+ numberOfValidatedTickets?: number;
182
+ }
183
+ /** Query parameters for opening the mPurse top-up flow. */
184
+ interface ZETPaymentRedirectParams {
185
+ mPurse?: number;
186
+ }
187
+ /** Parsed Corvus payment form returned by order redirect endpoint. */
188
+ interface ZETPaymentForm {
189
+ action: string;
190
+ method: string;
191
+ inputs: Record<string, string>;
192
+ html: string;
193
+ }
194
+ /** Minimal top-up payment payload needed by mobile clients. */
195
+ interface ZETTopUpPaymentInfo {
196
+ url: string;
197
+ orderNumber: string | null;
198
+ }
199
+ /** Payload used by `OrderService.MVC/Order/Cancel`. */
200
+ interface ZETOrderCancelRequest {
201
+ orderNumber: string;
202
+ language?: string;
203
+ }
204
+ /** Public transport route (tram or bus line). */
205
+ interface ZETRoute {
206
+ id: number;
207
+ shortName: string;
208
+ longName: string;
209
+ routeType: ZETRouteType;
210
+ departureHeadsign: string;
211
+ destinationHeadsign: string;
212
+ normalizedSearchName: string;
213
+ }
214
+ /** Vehicle position embedded in trip data. */
215
+ interface ZETVehiclePosition {
216
+ id: string;
217
+ isForDisabledPeople: boolean | null;
218
+ vehicleTypeId: unknown | null;
219
+ position: {
220
+ latitude: number;
221
+ longitude: number;
222
+ };
223
+ }
224
+ /** Trip/departure model for a route. */
225
+ interface ZETTrip {
226
+ id: string;
227
+ direction: 0 | 1;
228
+ headsign: string;
229
+ departureDateTime: string;
230
+ arrivalDateTime: string;
231
+ hasLiveTracking: boolean;
232
+ tripStatus: ZETTripStatus;
233
+ vehicles: ZETVehiclePosition[];
234
+ shapeId: string;
235
+ }
236
+ /** Trip status values observed in API responses. */
237
+ declare enum ZETTripStatus {
238
+ Running = 0,
239
+ Scheduled = 3
240
+ }
241
+ /** Stop-time row with live arrival state for one stop in a trip. */
242
+ interface ZETStopTime {
243
+ id: string;
244
+ stopName: string;
245
+ stopSequence: number;
246
+ expectedArrivalDateTime: string;
247
+ isArrived: boolean;
248
+ isArrivedPrediction: boolean;
249
+ stopLat: number;
250
+ stopLong: number;
251
+ trip: ZETTrip;
252
+ }
253
+ /** Incoming departures for a specific stop. */
254
+ interface ZETIncomingTrip {
255
+ tripId: string;
256
+ routeShortName: string;
257
+ headsign: string;
258
+ expectedArrivalDateTime: string;
259
+ hasLiveTracking: boolean;
260
+ daysFromToday: number;
261
+ shapeId: string;
262
+ vehicles: ZETVehiclePosition[];
263
+ }
264
+ /** Query parameters used by route/trip timetable endpoints. */
265
+ interface ZETRouteTripParams {
266
+ daysFromToday?: number;
267
+ }
268
+ /** Route type values used across route, stop, and shape models. */
269
+ type ZETRouteType = 0 | 3;
270
+ /** Stop route-headsign helper object from `/gtfs/stops`. */
271
+ interface ZETStopTripHeadsign {
272
+ routeCode: string;
273
+ tripHeadsigns: string[];
274
+ }
275
+ /** Stop model from `/TimetableService.Api/api/gtfs/stops`. */
276
+ interface ZETStop {
277
+ id: string;
278
+ name: string;
279
+ routeType: ZETRouteType;
280
+ trips: ZETStopTripHeadsign[];
281
+ stopLat: number;
282
+ stopLong: number;
283
+ parentStopId: string;
284
+ normalizedSearchName: string;
285
+ isForDisabledPeople: boolean;
286
+ projectNo: string;
287
+ }
288
+ /** One coordinate point in a GTFS shape. */
289
+ interface ZETShapePoint {
290
+ latitude: number;
291
+ longitude: number;
292
+ sequence: number;
293
+ }
294
+ /** Polyline shape model from `/TimetableService.Api/api/gtfs/shapes`. */
295
+ interface ZETShape {
296
+ id: string;
297
+ points: ZETShapePoint[];
298
+ routeType?: ZETRouteType;
299
+ }
300
+ /** Optional controls for fuzzy route search. */
301
+ interface ZETRouteSearchOptions {
302
+ routeType?: ZETRouteType;
303
+ limit?: number;
304
+ }
305
+ /** Optional controls for fuzzy stop search. */
306
+ interface ZETStopSearchOptions {
307
+ routeType?: ZETRouteType;
308
+ limit?: number;
309
+ }
310
+
311
+ declare class ZETApiError extends Error {
312
+ readonly status: number;
313
+ readonly endpoint: string;
314
+ constructor(message: string, status: number, endpoint: string);
315
+ }
316
+ declare class ZETAuthError extends ZETApiError {
317
+ constructor(endpoint: string);
318
+ }
319
+
320
+ /** Storage adapter used by `ZETClient` for auth tokens. */
321
+ interface ZETTokenStorage {
322
+ get(key: string): Promise<string | null> | string | null;
323
+ set(key: string, value: string): Promise<void> | void;
324
+ delete(key: string): Promise<void> | void;
325
+ }
326
+ /** In-memory token storage. Tokens are lost when the process exits. */
327
+ declare class MemoryStorage implements ZETTokenStorage {
328
+ private readonly store;
329
+ get(key: string): string | null;
330
+ set(key: string, value: string): void;
331
+ delete(key: string): void;
332
+ }
333
+
334
+ /** App keys required by ticket and order services. */
335
+ interface ZETAppKeys {
336
+ ticket: string;
337
+ order: string;
338
+ }
339
+ /** Configuration options for `ZETClient`. */
340
+ interface ZETClientOptions {
341
+ appKeys: ZETAppKeys;
342
+ storage?: ZETTokenStorage;
343
+ onTokenRefresh?: (tokens: ZETAuthTokens) => void;
344
+ onAuthFailure?: () => void;
345
+ timeout?: number;
346
+ baseUrl?: string;
347
+ cacheTTL?: number;
348
+ }
349
+ /** HTTP client for ZET auth, ticketing, timetable, news, and payment APIs. */
350
+ declare class ZETClient {
351
+ private readonly baseUrl;
352
+ private readonly appKeys;
353
+ private readonly storage;
354
+ private readonly cacheTTL;
355
+ private readonly newsCacheTTL;
356
+ private isRefreshing;
357
+ private refreshQueue;
358
+ private readonly opts;
359
+ private cachedRoutes;
360
+ private cachedStops;
361
+ private cachedShapes;
362
+ private cachedNews;
363
+ private routesCachedAt;
364
+ private stopsCachedAt;
365
+ private shapesCachedAt;
366
+ private newsCachedAt;
367
+ private routesLoading;
368
+ private stopsLoading;
369
+ private shapesLoading;
370
+ private newsLoading;
371
+ private shapeToRouteTypeMapLoading;
372
+ private shapeToRouteTypeMap;
373
+ constructor(options: ZETClientOptions);
374
+ private resolveNewsCacheTTL;
375
+ private createBaseHeaders;
376
+ private createHeaders;
377
+ private buildUrl;
378
+ private fetchWithTimeout;
379
+ private readErrorMessage;
380
+ private toApiError;
381
+ private sendRequest;
382
+ private requestJson;
383
+ private requestText;
384
+ private saveTokens;
385
+ private refreshTokens;
386
+ private resolveRefreshQueue;
387
+ private rejectRefreshQueue;
388
+ private handleUnauthorized;
389
+ private ticketHeaders;
390
+ private orderHeaders;
391
+ private isExpired;
392
+ private fetchRoutesAndCache;
393
+ private fetchStopsAndCache;
394
+ private fetchShapesAndCache;
395
+ private fetchNewsAndCache;
396
+ private getRoutesCached;
397
+ private getStopsCached;
398
+ private getShapesCached;
399
+ private getNewsCached;
400
+ private ensureShapeToRouteTypeMap;
401
+ private invalidateShapeToRouteTypeMap;
402
+ private extractHtmlAttribute;
403
+ private parsePaymentForm;
404
+ /** Logs in and stores returned tokens. */
405
+ login(credentials: ZETLoginRequest): Promise<ZETAuthTokens>;
406
+ /** Stores externally obtained access and refresh tokens. */
407
+ setTokens(tokens: ZETAuthTokens): Promise<void>;
408
+ /** Clears locally stored tokens. */
409
+ clearTokens(): Promise<void>;
410
+ /** Returns currently stored access token or `null`. */
411
+ getAccessToken(): Promise<string | null>;
412
+ /** Fetches current account details. */
413
+ getAccount(): Promise<ZETAccount>;
414
+ /** Fetches traffic/service news feed with internal cache. */
415
+ getNewsFeed(): Promise<ZETNewsItem[]>;
416
+ /** Backward-compatible alias of `getNewsFeed`. */
417
+ getNewsfeed(): Promise<ZETNewsItem[]>;
418
+ /** Fetches news filtered by route line id. */
419
+ getNewsByRoute(routeId: number): Promise<ZETNewsItem[]>;
420
+ /** Fetches top-up/order history. */
421
+ getOrders(params?: ZETOrdersParams): Promise<ZETOrder[]>;
422
+ /**
423
+ * Opens mPurse top-up redirect and returns raw HTML that auto-submits to CorvusPay.
424
+ */
425
+ getTopUpPaymentHtml(params?: ZETPaymentRedirectParams): Promise<string>;
426
+ /**
427
+ * Opens mPurse top-up redirect and parses the generated CorvusPay form.
428
+ * The returned `action` URL is where the user should be redirected.
429
+ */
430
+ getTopUpPaymentForm(params?: ZETPaymentRedirectParams): Promise<ZETPaymentForm>;
431
+ /** Returns only top-up payment URL and order number for cancel flow. */
432
+ getTopUpPaymentInfo(params?: ZETPaymentRedirectParams): Promise<ZETTopUpPaymentInfo>;
433
+ /**
434
+ * Calls `OrderService.MVC/Order/Cancel` with the Corvus order number.
435
+ * This is the same endpoint the WebView flow calls when payment is canceled.
436
+ */
437
+ cancelTopUpPayment(request: ZETOrderCancelRequest): Promise<string>;
438
+ /** Returns cached routes, optionally filtered by route type. */
439
+ getRoutes(routeType?: ZETRouteType): Promise<ZETRoute[]>;
440
+ /** Returns one route by route id using cached routes. */
441
+ getRouteById(routeId: number): Promise<ZETRoute | null>;
442
+ /** Fuzzy-search routes by normalized name and short route code. */
443
+ searchRoutes(query: string, options?: ZETRouteSearchOptions): Promise<ZETRoute[]>;
444
+ /** Returns cached stops, optionally filtered by route type. */
445
+ getStops(routeType?: ZETRouteType): Promise<ZETStop[]>;
446
+ /** Returns one stop by id from cached stops. */
447
+ getStopById(stopId: string): Promise<ZETStop | null>;
448
+ /** Fuzzy-search stops by normalized stop name. */
449
+ searchStops(query: string, options?: ZETStopSearchOptions): Promise<ZETStop[]>;
450
+ /** Returns cached shapes. */
451
+ getShapes(): Promise<ZETShape[]>;
452
+ /** Returns shapes used by trips of the specified route id. */
453
+ getShapesByRouteId(routeId: number): Promise<ZETShape[]>;
454
+ /** Fetches paginated ticket purchase history. */
455
+ getTicketHistory(params?: ZETTicketsParams): Promise<ZETTicketSummary[]>;
456
+ /** Fetches filtered/active tickets. */
457
+ getActiveTickets(params?: ZETActiveTicketsParams): Promise<ZETTicket[]>;
458
+ /**
459
+ * Fetches ticket articles.
460
+ * If `lat` and `lng` are provided, zone-specific data is requested.
461
+ */
462
+ getArticles(params?: ZETArticlesParams): Promise<ZETArticlesResponse>;
463
+ /** Purchases a ticket. */
464
+ buyTicket(request: ZETBuyTicketRequest): Promise<ZETTicket[]>;
465
+ /**
466
+ * Updates active ticket validation by changing the vehicle number.
467
+ * Mirrors `PUT /TicketService.Api/api/v1/open/tickets/ticket` in `zet.txt`.
468
+ */
469
+ changeTicketVehicle(request: ZETChangeVehicleRequest): Promise<ZETChangeVehicleResponse>;
470
+ /** Fetches all trips for one route and relative day offset. */
471
+ getRouteTrips(routeId: number, params?: ZETRouteTripParams): Promise<ZETTrip[]>;
472
+ /** Fetches stop times and live state for one trip. */
473
+ getTripStopTimes(tripId: string, params?: ZETRouteTripParams): Promise<ZETStopTime[]>;
474
+ /** Fetches upcoming trips for one stop. */
475
+ getStopIncomingTrips(stopId: string): Promise<ZETIncomingTrip[]>;
476
+ }
477
+
478
+ /** Vehicle position extracted from the GTFS-RT feed. */
479
+ interface GtfsRtVehicle {
480
+ vehicleId: string;
481
+ routeId: string;
482
+ latitude: number;
483
+ longitude: number;
484
+ timestamp: number;
485
+ }
486
+ /** Vehicle plus computed distance and basic type classification. */
487
+ interface NearbyVehicle extends GtfsRtVehicle {
488
+ distanceMeters: number;
489
+ vehicleType: 'tram' | 'bus' | 'unknown';
490
+ }
491
+ /**
492
+ * Fetches and parses the ZET GTFS-RT protobuf feed.
493
+ *
494
+ * `gtfs-realtime-bindings` is statically imported and always bundled.
495
+ */
496
+ declare function fetchGtfsRtVehicles(url?: string, fetchFn?: typeof fetch): Promise<GtfsRtVehicle[]>;
497
+ /** Calculates Haversine distance in meters between two WGS84 coordinates. */
498
+ declare function haversineMeters(lat1: number, lng1: number, lat2: number, lng2: number): number;
499
+ /**
500
+ * Returns vehicles within `radiusMeters` from user coordinates, sorted by distance.
501
+ */
502
+ declare function getNearbyVehicles(vehicles: GtfsRtVehicle[], userLat: number, userLng: number, radiusMeters?: number): NearbyVehicle[];
503
+
504
+ /**
505
+ * Async generator for paginated ZET endpoints.
506
+ * The `fetcher` callback must return one page of results for a given page number.
507
+ */
508
+ declare function paginate<T>(fetcher: (pageNumber: number) => Promise<T[]>, pageSize?: number): AsyncGenerator<T[]>;
509
+ /**
510
+ * Collects all pages into one array.
511
+ * Use `paginate` directly if you need streaming behavior.
512
+ */
513
+ declare function collectAll<T>(fetcher: (pageNumber: number) => Promise<T[]>, pageSize?: number): Promise<T[]>;
514
+
515
+ /** Returns `true` when a trip is currently running and has live tracking. */
516
+ declare function isTripLive(trip: ZETTrip): boolean;
517
+ /** Returns the first not-yet-arrived stop index, or `-1` if there is none. */
518
+ declare function getCurrentStopIndex(stops: ZETStopTime[]): number;
519
+ /** Returns the last arrived stop, or `null` if no stop is marked as arrived. */
520
+ declare function getLastArrivedStop(stops: ZETStopTime[]): ZETStopTime | null;
521
+ /** Returns the next not-yet-arrived stop, or `null` if all stops are arrived. */
522
+ declare function getNextStop(stops: ZETStopTime[]): ZETStopTime | null;
523
+ /** Returns `true` when the route type is tram (`0`). */
524
+ declare function isTram(route: ZETRoute): boolean;
525
+ /** Returns `true` when the route type is bus (`3`). */
526
+ declare function isBus(route: ZETRoute): boolean;
527
+ /** Normalized trip item returned by `buildTimetable`. */
528
+ interface TimetableEntry {
529
+ trip: ZETTrip;
530
+ departureTime: Date;
531
+ arrivalTime: Date;
532
+ isPast: boolean;
533
+ isLive: boolean;
534
+ isNext: boolean;
535
+ }
536
+ /**
537
+ * Filters trips by direction, sorts by departure time, and annotates timeline state.
538
+ */
539
+ declare function buildTimetable(trips: ZETTrip[], direction: 0 | 1): TimetableEntry[];
540
+ /**
541
+ * Returns a short label for a ticket article caption.
542
+ * Falls back to the original caption when no known pattern is found.
543
+ */
544
+ declare function getArticleLabel(article: ZETArticle): string;
545
+ /** Keeps only standard zone 1/2 products and removes funicular-only articles. */
546
+ declare function getStandardArticles(articles: ZETArticle[]): ZETArticle[];
547
+ /** Returns `true` when ticket is active and its validity end is in the future. */
548
+ declare function isTicketActive(ticket: ZETTicket): boolean;
549
+ /** Returns remaining ticket validity in whole seconds. Can be negative if expired. */
550
+ declare function getTicketRemainingSeconds(ticket: ZETTicket): number;
551
+ /** Formats a second count as `M:SS`. */
552
+ declare function formatCountdown(seconds: number): string;
553
+ /**
554
+ * Normalizes strings for fuzzy matching.
555
+ * Croatian diacritics are reduced to base ASCII letters.
556
+ */
557
+ declare function normalizeString(value: string): string;
558
+ /** Returns the validated vehicle number if available. */
559
+ declare function getTicketVehicleNumber(ticket: ZETTicket): string | null;
560
+
561
+ export { type GtfsRtVehicle, MemoryStorage, type NearbyVehicle, type TimetableEntry, type ZETAccount, type ZETActiveTicketsParams, ZETApiError, type ZETAppKeys, type ZETArticle, type ZETArticlesParams, type ZETArticlesResponse, ZETAuthError, type ZETAuthTokens, type ZETBuyTicketRequest, type ZETChangeVehicleRequest, type ZETChangeVehicleResponse, ZETClient, type ZETClientOptions, type ZETIncomingTrip, type ZETLoginRequest, type ZETNewsItem, type ZETOrder, type ZETOrderCancelRequest, type ZETOrdersParams, type ZETPaymentForm, type ZETPaymentRedirectParams, type ZETRoute, type ZETRouteSearchOptions, type ZETRouteTripParams, type ZETRouteType, type ZETShape, type ZETShapePoint, type ZETStop, type ZETStopSearchOptions, type ZETStopTime, type ZETStopTripHeadsign, type ZETTicket, ZETTicketStatus, type ZETTicketSummary, type ZETTicketsParams, type ZETTokenStorage, type ZETTopUpPaymentInfo, type ZETTrip, ZETTripStatus, type ZETValidation, type ZETVehiclePosition, type ZETZoneInfo, buildTimetable, collectAll, fetchGtfsRtVehicles, formatCountdown, getArticleLabel, getCurrentStopIndex, getLastArrivedStop, getNearbyVehicles, getNextStop, getStandardArticles, getTicketRemainingSeconds, getTicketVehicleNumber, haversineMeters, isBus, isTicketActive, isTram, isTripLive, normalizeString, paginate };