-
- {rideText(row.carrier, row.seg)}
+ {ride.title}
+
+
+
+
+
+
-
-
+ {(ride.from.placeLine || ride.to.placeLine) && (
+
+ {ride.from.placeLine}
+ {ride.to.placeLine}
+
+ )}
+ {(ride.checkIn || ride.duration) && (
+
+ {ride.checkIn && }
+ {ride.duration && }>{ride.duration}}
+
+ )}
>
)
- const cls = 'my-1 flex min-w-0 flex-col gap-[7px] rounded-[16px] bg-[color:var(--m-ic)] px-[12px] py-[9px] text-start'
+ const cls = `my-1 flex min-w-0 flex-col gap-[7px] rounded-[16px] border bg-[color:var(--m-ic)] px-[11px] py-[8px] text-start ${
+ ride.checkIn?.state === 'missed' ? 'border-[color:var(--m-st-pending)]' : 'border-transparent'
+ }`
return (
diff --git a/client/src/mobile/screens/trip/sheets/MTransportFormSheet.tsx b/client/src/mobile/screens/trip/sheets/MTransportFormSheet.tsx
index 9dd067cf5..20e44c98f 100644
--- a/client/src/mobile/screens/trip/sheets/MTransportFormSheet.tsx
+++ b/client/src/mobile/screens/trip/sheets/MTransportFormSheet.tsx
@@ -4,7 +4,7 @@ import MSheet from '../../../components/MSheet'
import { useAddonStore } from '../../../../store/addonStore'
import { useTranslation } from '../../../../i18n'
import { formatDate, resolveDayId, splitReservationDateTime } from '../../../../utils/formatters'
-import { orderedEndpoints, parseReservationMetadata } from '../../../../utils/flightLegs'
+import { orderedEndpoints, parseReservationMetadata, stripAirportCode } from '../../../../utils/flightLegs'
import { typeToCostCategory } from '@trek/shared'
import CustomSelect from '../../../../components/shared/CustomSelect'
import CustomTimePicker from '../../../../components/shared/CustomTimePicker'
@@ -56,13 +56,6 @@ function endpointFromAirport(a: Airport, role: 'from' | 'to' | 'stop', sequence:
function endpointFromLocation(l: LocationPoint, role: 'from' | 'to' | 'stop', sequence: number, date: string | null, time: string | null): Omit {
return { role, sequence, name: l.name, code: null, lat: l.lat, lng: l.lng, timezone: null, local_date: date, local_time: time }
}
-// "Paris Charles de Gaulle (CDG)" → "Paris Charles de Gaulle", the same trim-plus-
-// anchored-test the desktop TransportModal uses instead of /\s*\([A-Z]{3}\)\s*$/,
-// because that leading \s* backtracks over every space in a long name.
-function stripAirportCode(name: string): string {
- const trimmed = name.trimEnd()
- return /\([A-Z]{3}\)$/.test(trimmed) ? trimmed.slice(0, -5).trimEnd() : name
-}
function airportFromEndpoint(e: ReservationEndpoint | undefined): Airport | null {
if (!e || !e.code) return null
return { iata: e.code, icao: null, name: e.name, city: stripAirportCode(e.name), country: '', lat: e.lat, lng: e.lng, tz: e.timezone || '' }
diff --git a/client/src/utils/flightLegs.test.ts b/client/src/utils/flightLegs.test.ts
index 33d6e7bd8..a9363b6e4 100644
--- a/client/src/utils/flightLegs.test.ts
+++ b/client/src/utils/flightLegs.test.ts
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest'
-import { getFlightLegs, getTrainLegs, isMultiLegTrain } from './flightLegs'
+import { getFlightLegs, getTrainLegs, isMultiLegTrain, stripAirportCode } from './flightLegs'
import type { Reservation } from '../types'
function res(partial: Partial): Reservation {
@@ -96,3 +96,14 @@ describe('per-segment booking references (#1943)', () => {
expect(getTrainLegs(train)[0].confirmation_number).toBe('BOOK2')
})
})
+
+describe('stripAirportCode', () => {
+ it('drops the code the forms and the airport backfill append, and nothing else', () => {
+ expect(stripAirportCode('Paris Charles de Gaulle (CDG)')).toBe('Paris Charles de Gaulle')
+ expect(stripAirportCode('Hamburg (HAM) ')).toBe('Hamburg')
+ // A station has no such suffix, and a bracket that is not a code stays.
+ expect(stripAirportCode('Hamburg Hbf')).toBe('Hamburg Hbf')
+ expect(stripAirportCode('Frankfurt (Main)')).toBe('Frankfurt (Main)')
+ expect(stripAirportCode('Munich (muc)')).toBe('Munich (muc)')
+ })
+})
diff --git a/client/src/utils/flightLegs.ts b/client/src/utils/flightLegs.ts
index fa7179db0..2333a243a 100644
--- a/client/src/utils/flightLegs.ts
+++ b/client/src/utils/flightLegs.ts
@@ -48,6 +48,17 @@ export function orderedEndpoints(r: Pick): Reservation
return (r.endpoints || []).slice().sort((a, b) => (a.sequence ?? 0) - (b.sequence ?? 0))
}
+/**
+ * An airport endpoint's name without the code every writer appends to it:
+ * "Paris Charles de Gaulle (CDG)" → "Paris Charles de Gaulle". Done as a trim plus an
+ * anchored test instead of /\s*\([A-Z]{3}\)\s*$/, because the leading \s* backtracks over
+ * every space in a long name for a quadratic worst case.
+ */
+export function stripAirportCode(name: string): string {
+ const trimmed = name.trimEnd()
+ return /\([A-Z]{3}\)$/.test(trimmed) ? trimmed.slice(0, -5).trimEnd() : name
+}
+
/**
* Ordered legs of a flight. `metadata.legs` is preferred; otherwise a single leg
* is derived from the endpoints (and finally the flat metadata) so that legacy
diff --git a/client/tests/unit/mobile/trip/MRoadtripRows.test.tsx b/client/tests/unit/mobile/trip/MRoadtripRows.test.tsx
index a417e8d22..383ef9e4d 100644
--- a/client/tests/unit/mobile/trip/MRoadtripRows.test.tsx
+++ b/client/tests/unit/mobile/trip/MRoadtripRows.test.tsx
@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from 'vitest'
-import { fireEvent, render, screen } from '../../../helpers/render'
+import { fireEvent, render, screen, within } from '../../../helpers/render'
import {
RtAutoRow, RtBookendRow, RtBookingChips, RtDryRow, RtLegRow, RtRideRow, RtSpillRow, RtStopRow, type RowChrome,
} from '../../../../src/mobile/screens/trip/roadtrip/MRoadtripRows'
@@ -9,7 +9,7 @@ import type { Reservation, TranslationFn } from '../../../../src/types'
import type { RefuelSearch } from '../../../../src/components/Roadtrip/useRefuelSearch'
import type { RefuelCandidate } from '../../../../src/components/Roadtrip/refuelSuggestion'
-// FE-MOB-RTROW-001 to FE-MOB-RTROW-059
+// FE-MOB-RTROW-001 to FE-MOB-RTROW-065
// Same echo strategy as tests/helpers/mobileTrip: assertions stay on keys, not copy.
const t: TranslationFn = (key, params) =>
@@ -46,6 +46,16 @@ const SEG: RouteSegment = {
}
describe('RtStopRow', () => {
+ it('FE-MOB-RTROW-065: the own stop of a stay on its check-in day carries the check-in hour, other stops do not', () => {
+ const hotel = { ...stopRow().stop, name: 'Gasthof Post', stopType: 'hotel', night: true, checkInTime: '15:00' }
+ const first = render()
+ expect(screen.getByText('roadtrip.bookend.checkIn').parentElement).toHaveTextContent('15:00')
+ first.unmount()
+
+ render()
+ expect(screen.queryByText('roadtrip.bookend.checkIn')).toBeNull()
+ })
+
it('FE-MOB-RTROW-001: gives a destination its number and no kind icon', () => {
const { container } = render()
@@ -230,6 +240,18 @@ describe('RtStopRow', () => {
expect(screen.getByText('14:05')).toBeInTheDocument()
})
+ it('FE-MOB-RTROW-064: lateness reads in hours and minutes, and leaving after the time set is marked the same way', () => {
+ const late = render()
+ expect(screen.getByText('+9 h 39 min')).toBeInTheDocument()
+ late.unmount()
+
+ const { container } = render()
+ expect(screen.getByText('+20 min')).toBeInTheDocument()
+ expect(container.querySelector('.lucide-alert-triangle')).not.toBeNull()
+ // It used to fall through to the night's word.
+ expect(screen.queryByText('roadtrip.warn.overnight')).toBeNull()
+ })
+
it('FE-MOB-RTROW-013: writes an overnight warning as a word, since it has no figure', () => {
const warning: ScheduleWarning = { index: 1, code: 'overnight' }
const { container } = render()
@@ -248,7 +270,10 @@ describe('RtStopRow', () => {
const { container } = render()
expect(screen.getByText('Sixt Hauptbahnhof')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.ride.pickup:09:00')).toBeInTheDocument()
+ // Which desk it is under the name, and the booking's clock once, on the right.
+ expect(screen.getByText('reservations.span.pickup')).toBeInTheDocument()
+ expect(screen.getAllByText('09:00')).toHaveLength(1)
+ expect(screen.getByText('roadtrip.ride.pickup:09:00')).toHaveClass('sr-only')
expect(screen.queryByText('2')).toBeNull()
// The booking's own icon on the disc, and the disc is not a control even for an
// editor: nobody turns a rental desk into a petrol station.
@@ -275,35 +300,49 @@ function carrier(role: CarrierTerminal['role'], over: Partial =
const FLIGHT_SEG = { ...SEG, distance: 0, duration: 4200, distanceText: '', durationText: '1 h 10 min' }
-function rideRow(over: Partial> = {}): Extract {
- const end = (role: 'departure' | 'arrival'): StopRow => stopRow({
- number: null,
+/**
+ * One end of LH 2020 as its row carries it: the departure pinned an hour ahead of the
+ * timetable for the check-in, and `late` minutes past that pin when the drive gets there late.
+ */
+const rideEnd = (role: 'departure' | 'arrival', late?: number): StopRow => stopRow({
+ number: null,
+ time: role === 'departure' ? '12:20' : '14:30',
+ pinned: true,
+ warning: late ? { index: 1, code: 'late', minutes: late } : null,
+ stop: {
+ ...stopRow().stop,
+ assignmentId: role === 'departure' ? -3000000140 : -3000000141,
+ placeId: -70,
+ name: role === 'departure' ? 'Hamburg Airport' : 'Munich Airport',
time: role === 'departure' ? '12:20' : '14:30',
- pinned: true,
- stop: {
- ...stopRow().stop,
- assignmentId: role === 'departure' ? -3000000140 : -3000000141,
- placeId: -70,
- name: role === 'departure' ? 'Hamburg Airport' : 'Munich Airport',
- carrier: carrier(role),
- },
- })
- return { kind: 'ride', index: 1, carrier: carrier('departure'), seg: FLIGHT_SEG, departure: end('departure'), arrival: end('arrival'), ...over }
+ carrier: carrier(role),
+ },
+})
+
+function rideRow(over: Partial> = {}, late?: number): Extract {
+ return { kind: 'ride', index: 1, carrier: carrier('departure'), seg: FLIGHT_SEG, departure: rideEnd('departure', late), arrival: rideEnd('arrival'), ...over }
}
describe('RtRideRow', () => {
- it('FE-MOB-RTROW-051: a ride is one block: the booking and its minutes over both terminals, each with its code, its timetable line and its clock', () => {
+ it('FE-MOB-RTROW-051: a ride is one block in four lines: the booking and its minutes, both codes with their timetable, the places, the check-in', () => {
render()
- expect(screen.getByText('LH 2020 · 1 h 10 min')).toBeInTheDocument()
+ expect(screen.getByText('LH 2020')).toBeInTheDocument()
+ expect(screen.getByText('1 h 10 min')).toBeInTheDocument()
+ expect(screen.queryByText(/·/)).toBeNull()
+ // Each code and each timetable clock once, the words for the clocks for a screen reader only.
+ expect(screen.getAllByText('HAM')).toHaveLength(1)
+ expect(screen.getAllByText('MUC')).toHaveLength(1)
+ expect(screen.getAllByText('13:20')).toHaveLength(1)
+ expect(screen.getAllByText('14:30')).toHaveLength(1)
+ expect(screen.getByText('roadtrip.ride.departureFlight:13:20')).toHaveClass('sr-only')
+ expect(screen.getByText('roadtrip.ride.arrival:14:30')).toHaveClass('sr-only')
expect(screen.getByText('Hamburg Airport')).toBeInTheDocument()
- expect(screen.getByText('HAM')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.ride.departure:13:20')).toBeInTheDocument()
- expect(screen.getByText('12:20')).toBeInTheDocument()
expect(screen.getByText('Munich Airport')).toBeInTheDocument()
- expect(screen.getByText('MUC')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.ride.arrival:14:30')).toBeInTheDocument()
- expect(screen.getByText('14:30')).toBeInTheDocument()
+ // The check-in, with its hour in the pill inside it and its sentence for a screen reader.
+ const checkIn = screen.getByRole('img', { name: 'roadtrip.ride.hintFlight:LH 2020,13:20,12:20' })
+ expect(checkIn).toHaveTextContent('roadtrip.ride.checkIn')
+ expect(within(checkIn).getByText('12:20')).toBeInTheDocument()
// The terminals take no number: Hamburg is 1 and Munich is 2 either side of them.
expect(screen.queryByText('2')).toBeNull()
})
@@ -315,7 +354,7 @@ describe('RtRideRow', () => {
// One control for the whole ride, not one per terminal.
expect(screen.getAllByRole('button')).toHaveLength(1)
fireEvent.click(screen.getByText('Hamburg Airport'))
- fireEvent.click(screen.getByText('LH 2020 · 1 h 10 min'))
+ fireEvent.click(screen.getByText('LH 2020'))
expect(onOpen).toHaveBeenCalledTimes(2)
opens.unmount()
@@ -328,11 +367,50 @@ describe('RtRideRow', () => {
render()
expect(screen.getByText('LH 2020')).toBeInTheDocument()
- expect(screen.queryByText(/LH 2020 ·/)).toBeNull()
- expect(screen.getByText('roadtrip.ride.departure:1:20 PM')).toBeInTheDocument()
+ expect(screen.queryByText('1 h 10 min')).toBeNull()
+ expect(screen.getByText('1:20 PM')).toBeInTheDocument()
+ expect(screen.getByText('roadtrip.ride.departureFlight:1:20 PM')).toBeInTheDocument()
expect(screen.getByText('12:20 PM')).toBeInTheDocument()
expect(screen.queryByText('13:20')).toBeNull()
})
+
+ it('FE-MOB-RTROW-060: a flight the drive reaches after take-off is missed, says when the drive gets there, and edges the block', () => {
+ render()
+
+ const mark = screen.getByRole('img', { name: 'roadtrip.ride.lateHintFlight:LH 2020,13:20,12:20,Hamburg Airport,21:59' })
+ expect(mark).toHaveTextContent('roadtrip.ride.missed')
+ expect(within(mark).getByText('roadtrip.ride.reachedAt:21:59')).toBeInTheDocument()
+ expect(mark.querySelector('.lucide-alert-triangle')).not.toBeNull()
+ expect(screen.getByRole('button').className).toContain('border-[color:var(--m-st-pending)]')
+ })
+
+ it('FE-MOB-RTROW-061: late for the check-in but in time for the flight says by how much, on the check-in word', () => {
+ const { container } = render()
+
+ const mark = screen.getByRole('img', { name: /^roadtrip\.ride\.lateHintFlight:/ })
+ expect(mark).toHaveTextContent('roadtrip.ride.checkIn')
+ expect(within(mark).getByText('roadtrip.ride.lateBy:25 min')).toBeInTheDocument()
+ expect(container.querySelector('.border-transparent')).not.toBeNull()
+ })
+
+ it('FE-MOB-RTROW-062: a departure on a row of its own reads the block\'s pieces, and its lateness once, on the check-in', () => {
+ const row = stopRow({
+ number: null,
+ time: '12:20',
+ pinned: true,
+ warning: { index: 1, code: 'late', minutes: 579 },
+ stop: { ...stopRow().stop, assignmentId: -3000000140, placeId: -70, name: 'Hamburg (HAM)', time: '12:20', carrier: carrier('departure') },
+ })
+ render()
+
+ expect(screen.getByText('HAM')).toBeInTheDocument()
+ expect(screen.getByText('Hamburg')).toBeInTheDocument()
+ // The timetable on the right, not the pin with a glyph calling it a time somebody set.
+ expect(screen.getByText('13:20')).toBeInTheDocument()
+ expect(screen.queryByLabelText('roadtrip.stop.pinned')).toBeNull()
+ expect(screen.getByRole('img', { name: /^roadtrip\.ride\.lateHintFlight:/ })).toHaveTextContent('roadtrip.ride.missed')
+ expect(screen.queryByText('+9 h 39 min')).toBeNull()
+ })
})
describe('RtBookingChips', () => {
@@ -808,6 +886,7 @@ describe('RtBookendRow', () => {
variant: 'checkOut',
name: 'Hotel Alpenblick',
until: '10:00',
+ from: null,
reservationId: 41,
accommodationId: 5,
placeId: 900,
@@ -820,8 +899,10 @@ describe('RtBookendRow', () => {
const onOpen = vi.fn()
const { container } = render()
- expect(screen.getByText('roadtrip.bookend.checkOut:Hotel Alpenblick')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.stay.until:10:00')).toBeInTheDocument()
+ // The hotel is the name; the edge of the stay and its hour sit in one badge under it.
+ expect(screen.getByText('Hotel Alpenblick')).toBeInTheDocument()
+ expect(screen.getByText('roadtrip.bookend.checkOut').parentElement).toHaveTextContent('10:00')
+ expect(screen.queryByText(/·/)).toBeNull()
expect(screen.getByText('08:40')).toBeInTheDocument()
expect(container.querySelector('.lucide-bed-double')).not.toBeNull()
expect(screen.queryByText('2')).toBeNull()
@@ -833,8 +914,9 @@ describe('RtBookendRow', () => {
it('FE-MOB-RTROW-058: an evening says nothing under its name but what the drive into it ran over', () => {
const warning: ScheduleWarning = { index: 3, code: 'leg', overMinutes: 30 }
const quiet = render()
- expect(screen.getByText('roadtrip.bookend.back:Hotel Alpenblick')).toBeInTheDocument()
- expect(screen.queryByText(/roadtrip\.stay\.until/)).toBeNull()
+ expect(screen.getByText('Hotel Alpenblick')).toBeInTheDocument()
+ expect(screen.getByText('roadtrip.bookend.back')).toBeInTheDocument()
+ expect(screen.queryByText('10:00')).toBeNull()
expect(screen.queryByText('08:40')).toBeNull()
quiet.unmount()
@@ -843,14 +925,30 @@ describe('RtBookendRow', () => {
expect(screen.getByText('7:10 PM')).toBeInTheDocument()
})
+ it('FE-MOB-RTROW-063: the hotel wears the hotel stop\'s own disc, not a terminal\'s', () => {
+ const edge = render()
+ const bookendDisc = edge.container.querySelector('.lucide-bed-double')!.parentElement as HTMLElement
+ const bookendFace = [bookendDisc.style.background, bookendDisc.style.color]
+ edge.unmount()
+
+ const stay = render()
+ const stopDisc = stay.container.querySelector('.lucide-bed-double')!.parentElement as HTMLElement
+ expect(bookendFace[0]).not.toBe('')
+ expect(bookendFace[0]).toBe(stopDisc.style.background)
+ // White on it, as the stop's bed is.
+ expect(bookendFace[1]).toBe('rgb(255, 255, 255)')
+ expect(stopDisc).toHaveClass('text-white')
+ })
+
it('FE-MOB-RTROW-059: a check-out morning the drive leaves after the room is handed back is marked', () => {
const entry = (arrival: string) => ({ arrival, departure: arrival, anchored: false, dayOffset: 0 })
const late = render()
- expect(screen.getByText('roadtrip.stay.until:10:00')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.bookend.afterCheckOut')).toBeInTheDocument()
+ // The check-out badge itself turns and says why, instead of a second mark beside it.
+ expect(screen.getByLabelText('roadtrip.bookend.checkOut 10:00 roadtrip.bookend.afterCheckOut')).toBeInTheDocument()
late.unmount()
render()
- expect(screen.queryByText('roadtrip.bookend.afterCheckOut')).toBeNull()
+ expect(screen.queryByLabelText(/roadtrip\.bookend\.afterCheckOut/)).toBeNull()
+ expect(screen.getByText('roadtrip.bookend.checkOut')).toBeInTheDocument()
})
})
diff --git a/client/tests/unit/mobile/trip/MRoadtripTab.test.tsx b/client/tests/unit/mobile/trip/MRoadtripTab.test.tsx
index 960a340f4..f623c887d 100644
--- a/client/tests/unit/mobile/trip/MRoadtripTab.test.tsx
+++ b/client/tests/unit/mobile/trip/MRoadtripTab.test.tsx
@@ -10,7 +10,7 @@ import type { CarrierTerminal, RoadtripDay, RoadtripRoutes, RoadtripStop, RouteS
import type { LegAlternatives } from '../../../../src/components/Roadtrip/useRouteAlternatives'
import { openLeg } from '../../../helpers/legAlternatives'
-// FE-MOB-RTTAB-001 to FE-MOB-RTTAB-065
+// FE-MOB-RTTAB-001 to FE-MOB-RTTAB-066
//
// The stage bar pictures the place its day ends at. It reads that place out of the trip
// store rather than the planner, the unfiltered list, so the picture tests seed the store.
@@ -108,13 +108,13 @@ function stage(over: Partial = {}): RoadtripDay {
{ arrival: '12:40', departure: null, anchored: false, dayOffset: 0 },
{ arrival: '22:00', departure: null, anchored: false, dayOffset: 0 },
],
- warnings: [],
+ warnings: [{ index: 2, code: 'late', minutes: 25 }],
},
legVias: [[], [], []],
geometry: [],
distance: 412_000,
duration: 18_000,
- driveWarnings: [{ index: 2, code: 'late', minutes: 25 }],
+ driveWarnings: [],
dayWarning: null,
spills: [{ at: 0, count: 1, fromDayNumber: 1, departure: '23:10', leg: undefined }],
dryPoints: [{ legIndex: 1, intoLegKm: 82, drivenMeters: 82_000, sinceKm: 520, lat: 35.2, lng: 137.5 }],
@@ -843,15 +843,17 @@ describe('MRoadtripTab', () => {
// The desk is unnumbered and its disc is no control: only the two real stops
// offer to become a stop on the way, and the count says two.
expect(screen.getAllByRole('button', { name: 'roadtrip.stop.makeService' })).toHaveLength(2)
- expect(screen.getByText('roadtrip.ride.pickup:09:00')).toBeInTheDocument()
+ expect(screen.getByText('reservations.span.pickup')).toBeInTheDocument()
+ expect(screen.getByText('roadtrip.ride.pickup:09:00')).toHaveClass('sr-only')
expect(screen.getByText('roadtrip.day.stopCount:2')).toBeInTheDocument()
})
it('FE-MOB-RTTAB-055: a ride is one block that opens its booking, between the two stops it joins', () => {
const { shell } = renderTab(planner({ roadtripRoutes: routes({ days: [flightStage()] }) }))
- expect(screen.getByText('LH 2020 · 1 h 10 min')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.ride.departure:13:20')).toBeInTheDocument()
+ expect(screen.getByText('LH 2020')).toBeInTheDocument()
+ expect(screen.getByText('1 h 10 min')).toBeInTheDocument()
+ expect(screen.getByText('roadtrip.ride.departureFlight:13:20')).toBeInTheDocument()
expect(screen.getByText('roadtrip.ride.arrival:14:30')).toBeInTheDocument()
// Kyoto is 1 and Munich is 2: the terminals between them take no number.
expect(screen.getByText('1')).toBeInTheDocument()
@@ -864,6 +866,21 @@ describe('MRoadtripTab', () => {
expect(shell.openSheet).toHaveBeenCalledTimes(1)
})
+ it('FE-MOB-RTTAB-066: a flight the drive reaches after take-off is said on the ride, where the stage only ever showed it on time', () => {
+ const pinned = flightStage()
+ const late = stage({
+ ...pinned,
+ // The departure pinned an hour ahead for the check-in, the drive to it ten hours late.
+ stops: pinned.stops.map((s, i) => (i === 1 ? { ...s, time: '12:20' } : s)),
+ schedule: { ...pinned.schedule, warnings: [{ index: 1, code: 'late', minutes: 600 }] },
+ })
+ renderTab(planner({ roadtripRoutes: routes({ days: [late] }) }))
+
+ const mark = screen.getByRole('img', { name: /^roadtrip\.ride\.lateHintFlight:LH 2020,13:20,12:20,Hamburg Airport,22:20/ })
+ expect(mark).toHaveTextContent('roadtrip.ride.missed')
+ expect(within(mark).getByText('roadtrip.ride.reachedAt:22:20')).toBeInTheDocument()
+ })
+
it('FE-MOB-RTTAB-056: a table hangs under its stop as a chip, one booked for no stop is listed under the day, and the night is neither', () => {
const reservations = [
booking({ id: 11, title: 'Tisch Bullerei', reservation_time: '2026-05-02T19:30', assignment_id: 503 }),
@@ -962,9 +979,9 @@ describe('MRoadtripTab', () => {
it('FE-MOB-RTTAB-062: the stage leaves from the hotel and comes back to one, with no number and no kind on either', () => {
renderTab(planner({ roadtripRoutes: routes({ days: [hotelStage()] }) }))
- expect(screen.getByText('roadtrip.bookend.checkOut:Hotel Alpenblick')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.stay.until:10:00')).toBeInTheDocument()
- expect(screen.getByText('roadtrip.bookend.back:Hotel Alpenblick')).toBeInTheDocument()
+ expect(screen.getAllByText('Hotel Alpenblick')).toHaveLength(2)
+ expect(screen.getByText('roadtrip.bookend.checkOut').parentElement).toHaveTextContent('10:00')
+ expect(screen.getByText('roadtrip.bookend.back')).toBeInTheDocument()
// Only the two places offer to become a stop on the way, and the count says two.
expect(screen.getAllByRole('button', { name: 'roadtrip.stop.makeService' })).toHaveLength(2)
expect(screen.getByText('roadtrip.day.stopCount:2')).toBeInTheDocument()
@@ -978,7 +995,7 @@ describe('MRoadtripTab', () => {
it('FE-MOB-RTTAB-063: a tap opens the booking behind the night, or the stay for somebody who may not edit bookings', () => {
const editor = planner({ roadtripRoutes: routes({ days: [hotelStage()] }), reservations: [hotelBooking] })
const first = renderTab(editor)
- fireEvent.click(screen.getByText('roadtrip.bookend.back:Hotel Alpenblick'))
+ fireEvent.click(screen.getByText('roadtrip.bookend.back'))
expect(editor.setEditingReservation).toHaveBeenCalledWith(hotelBooking)
expect(editor.setShowReservationModal).toHaveBeenCalledWith(true)
expect(first.shell.openSheet).not.toHaveBeenCalled()
@@ -990,7 +1007,7 @@ describe('MRoadtripTab', () => {
can: (action: string) => action !== 'reservation_edit',
})
const { shell } = renderTab(dayEditor)
- fireEvent.click(screen.getByText('roadtrip.bookend.checkOut:Hotel Alpenblick'))
+ fireEvent.click(screen.getByText('roadtrip.bookend.checkOut'))
expect(shell.openSheet).toHaveBeenCalledWith('accommodation', { dayId: 2, accId: 5 })
expect(dayEditor.setEditingReservation).not.toHaveBeenCalled()
})
@@ -1003,7 +1020,7 @@ describe('MRoadtripTab', () => {
const { shell } = renderTab(reader)
expect(screen.queryByText('roadtrip.window.resume')).toBeNull()
- fireEvent.click(screen.getByText('roadtrip.bookend.checkOut:Hotel Alpenblick'))
+ fireEvent.click(screen.getByText('roadtrip.bookend.checkOut'))
expect(reader.handlePlaceClick).toHaveBeenCalledWith(900)
expect(shell.openSheet).not.toHaveBeenCalled()
})
@@ -1017,7 +1034,8 @@ describe('MRoadtripTab', () => {
})
renderTab(planner({ roadtripRoutes: routes({ days: [transfer] }) }))
- expect(screen.getByText('roadtrip.bookend.back:Wallinga')).toBeInTheDocument()
+ expect(screen.getByText('Wallinga')).toBeInTheDocument()
+ expect(screen.getByText('roadtrip.bookend.back')).toBeInTheDocument()
expect(screen.queryByText(/roadtrip\.day\.stopCount/)).toBeNull()
})
})
diff --git a/shared/src/i18n/ar/roadtrip.ts b/shared/src/i18n/ar/roadtrip.ts
index 79c26eb35..b2a5a6f57 100644
--- a/shared/src/i18n/ar/roadtrip.ts
+++ b/shared/src/i18n/ar/roadtrip.ts
@@ -286,10 +286,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'فتح الحجز',
'roadtrip.ride.undated': 'الحجز {title} لا يقع في أي يوم من أيام هذه الرحلة، لذلك لا يستخدمه المسار.',
'roadtrip.bookings.loose': 'محجوز أيضًا في هذا اليوم',
- 'roadtrip.bookend.checkOut': 'تسجيل المغادرة · {name}',
- 'roadtrip.bookend.from': 'من {name}',
- 'roadtrip.bookend.back': 'العودة إلى {name}',
- 'roadtrip.bookend.checkIn': 'تسجيل الوصول · {name}',
+ 'roadtrip.ride.departureFlight': 'الإقلاع {time}',
+ 'roadtrip.ride.duration': 'المدة حسب الحجز',
+ 'roadtrip.ride.checkIn': 'تسجيل الوصول',
+ 'roadtrip.ride.boarding': 'الصعود',
+ 'roadtrip.ride.missed': 'فاتتك',
+ 'roadtrip.ride.lateBy': 'متأخر {time}',
+ 'roadtrip.ride.reachedAt': 'الوصول {time}',
+ 'roadtrip.ride.hintFlight': '{title} تُقلع في {departs}، وتسجيل الوصول حتى {pin}.',
+ 'roadtrip.ride.hintShip': '{title} تُبحر في {departs}، وتسجيل الوصول حتى {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} تغادر في {departs}، والصعود حتى {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'لا تصل الرحلة إلى {place} قبل {time}. {title} تُقلع في {departs}، وتسجيل الوصول حتى {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'لا تصل الرحلة إلى {place} قبل {time}. {title} تُبحر في {departs}، وتسجيل الوصول حتى {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'لا تصل الرحلة إلى {place} قبل {time}. {title} تغادر في {departs}، والصعود حتى {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'فاتتك الرحلة الجوية',
+ 'roadtrip.day.rideMissed.train': 'فاتك القطار',
+ 'roadtrip.day.rideMissed.ferry': 'فاتتك العبّارة',
+ 'roadtrip.day.rideMissed.cruise': 'فاتتك الرحلة البحرية',
+ 'roadtrip.day.rideMissed.bus': 'فاتتك الحافلة',
+ 'roadtrip.bookend.checkOut': 'تسجيل المغادرة',
+ 'roadtrip.bookend.from': 'بداية اليوم',
+ 'roadtrip.bookend.back': 'مبيت',
+ 'roadtrip.bookend.checkIn': 'تسجيل الوصول',
'roadtrip.bookend.afterCheckOut': 'الانطلاق بعد موعد تسجيل المغادرة',
'roadtrip.bookend.noVia': 'لا يمكن وضع نقطة عبور على الطريق من مكان إقامتك أو إليه. أضف توقفاً هناك بدلاً من ذلك.',
};
diff --git a/shared/src/i18n/br/roadtrip.ts b/shared/src/i18n/br/roadtrip.ts
index a2b3bac25..a488f6eb1 100644
--- a/shared/src/i18n/br/roadtrip.ts
+++ b/shared/src/i18n/br/roadtrip.ts
@@ -292,10 +292,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'A reserva {title} não está em nenhum dia desta viagem, por isso o percurso não a considera.',
'roadtrip.bookings.loose': 'Também reservado neste dia',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'Saindo de {name}',
- 'roadtrip.bookend.back': 'Volta para {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Partida {time}',
+ 'roadtrip.ride.duration': 'Duração segundo a reserva',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Embarque',
+ 'roadtrip.ride.missed': 'Perdido',
+ 'roadtrip.ride.lateBy': '{time} de atraso',
+ 'roadtrip.ride.reachedAt': 'chega às {time}',
+ 'roadtrip.ride.hintFlight': '{title} decola às {departs}, check-in até {pin}.',
+ 'roadtrip.ride.hintShip': '{title} zarpa às {departs}, check-in até {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} parte às {departs}, embarque até {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'O trajeto só chega a {place} às {time}. {title} decola às {departs}, check-in até {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'O trajeto só chega a {place} às {time}. {title} zarpa às {departs}, check-in até {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'O trajeto só chega a {place} às {time}. {title} parte às {departs}, embarque até {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Voo perdido',
+ 'roadtrip.day.rideMissed.train': 'Trem perdido',
+ 'roadtrip.day.rideMissed.ferry': 'Balsa perdida',
+ 'roadtrip.day.rideMissed.cruise': 'Cruzeiro perdido',
+ 'roadtrip.day.rideMissed.bus': 'Ônibus perdido',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Início do dia',
+ 'roadtrip.bookend.back': 'Pernoite',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Saída depois do check-out',
'roadtrip.bookend.noVia':
'Não dá para colocar um ponto de passagem no trajeto de ida ou volta da sua hospedagem. Adicione uma parada ali.',
diff --git a/shared/src/i18n/ca/roadtrip.ts b/shared/src/i18n/ca/roadtrip.ts
index 690a4da6d..26c2d97b4 100644
--- a/shared/src/i18n/ca/roadtrip.ts
+++ b/shared/src/i18n/ca/roadtrip.ts
@@ -295,10 +295,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'La reserva {title} no és a cap dia d’aquest viatge, així que el trajecte no la té en compte.',
'roadtrip.bookings.loose': 'També reservat aquest dia',
- 'roadtrip.bookend.checkOut': 'Sortida · {name}',
- 'roadtrip.bookend.from': 'Des de {name}',
- 'roadtrip.bookend.back': 'Tornada a {name}',
- 'roadtrip.bookend.checkIn': 'Entrada · {name}',
+ 'roadtrip.ride.departureFlight': 'Sortida {time}',
+ 'roadtrip.ride.duration': 'Durada segons la reserva',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Embarcament',
+ 'roadtrip.ride.missed': 'Perdut',
+ 'roadtrip.ride.lateBy': '{time} de retard',
+ 'roadtrip.ride.reachedAt': 'arriba a les {time}',
+ 'roadtrip.ride.hintFlight': '{title} s’enlaira a les {departs}, check-in fins a les {pin}.',
+ 'roadtrip.ride.hintShip': '{title} salpa a les {departs}, check-in fins a les {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} surt a les {departs}, embarcament fins a les {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'El trajecte no arriba a {place} fins a les {time}. {title} s’enlaira a les {departs}, check-in fins a les {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'El trajecte no arriba a {place} fins a les {time}. {title} salpa a les {departs}, check-in fins a les {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'El trajecte no arriba a {place} fins a les {time}. {title} surt a les {departs}, embarcament fins a les {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Vol perdut',
+ 'roadtrip.day.rideMissed.train': 'Tren perdut',
+ 'roadtrip.day.rideMissed.ferry': 'Ferri perdut',
+ 'roadtrip.day.rideMissed.cruise': 'Creuer perdut',
+ 'roadtrip.day.rideMissed.bus': 'Autobús perdut',
+ 'roadtrip.bookend.checkOut': 'Sortida',
+ 'roadtrip.bookend.from': 'Inici del dia',
+ 'roadtrip.bookend.back': 'Pernoctació',
+ 'roadtrip.bookend.checkIn': 'Entrada',
'roadtrip.bookend.afterCheckOut': 'Marxa després de l’hora de sortida',
'roadtrip.bookend.noVia':
'No es pot posar cap punt de pas al trajecte fins al teu allotjament o des d’ell. Afegeix-hi una parada.',
diff --git a/shared/src/i18n/cs/roadtrip.ts b/shared/src/i18n/cs/roadtrip.ts
index cabe54e0b..49f471b7a 100644
--- a/shared/src/i18n/cs/roadtrip.ts
+++ b/shared/src/i18n/cs/roadtrip.ts
@@ -289,10 +289,28 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Otevřít rezervaci',
'roadtrip.ride.undated': 'Rezervace {title} nepatří k žádnému dni této cesty, proto s ní jízda nepočítá.',
'roadtrip.bookings.loose': 'Také rezervováno na tento den',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'Z ubytování {name}',
- 'roadtrip.bookend.back': 'Zpět do ubytování {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Odlet {time}',
+ 'roadtrip.ride.duration': 'Doba podle rezervace',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Nástup',
+ 'roadtrip.ride.missed': 'Zmeškáno',
+ 'roadtrip.ride.lateBy': 'zpoždění {time}',
+ 'roadtrip.ride.reachedAt': 'až v {time}',
+ 'roadtrip.ride.hintFlight': '{title} odlétá v {departs}, check-in do {pin}.',
+ 'roadtrip.ride.hintShip': '{title} vyplouvá v {departs}, check-in do {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} odjíždí v {departs}, nástup do {pin}.',
+ 'roadtrip.ride.lateHintFlight': '{place}: příjezd až v {time}. {title} odlétá v {departs}, check-in do {pin}.',
+ 'roadtrip.ride.lateHintShip': '{place}: příjezd až v {time}. {title} vyplouvá v {departs}, check-in do {pin}.',
+ 'roadtrip.ride.lateHintBoarding': '{place}: příjezd až v {time}. {title} odjíždí v {departs}, nástup do {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Zmeškaný let',
+ 'roadtrip.day.rideMissed.train': 'Zmeškaný vlak',
+ 'roadtrip.day.rideMissed.ferry': 'Zmeškaný trajekt',
+ 'roadtrip.day.rideMissed.cruise': 'Zmeškaná plavba',
+ 'roadtrip.day.rideMissed.bus': 'Zmeškaný autobus',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Začátek dne',
+ 'roadtrip.bookend.back': 'Nocleh',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Odjezd až po check-outu',
'roadtrip.bookend.noVia':
'Na trasu do ubytování ani z něj nelze přidat průjezdní bod. Přidejte tam místo toho zastávku.',
diff --git a/shared/src/i18n/de/roadtrip.ts b/shared/src/i18n/de/roadtrip.ts
index 2129de69a..87431155f 100644
--- a/shared/src/i18n/de/roadtrip.ts
+++ b/shared/src/i18n/de/roadtrip.ts
@@ -289,10 +289,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'Die Buchung {title} liegt auf keinem Tag dieser Reise, deshalb plant die Fahrt nicht mit ihr.',
'roadtrip.bookings.loose': 'Außerdem an diesem Tag gebucht',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'Ab {name}',
- 'roadtrip.bookend.back': 'Zurück zu {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Abflug {time}',
+ 'roadtrip.ride.duration': 'Dauer laut Buchung',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Einstieg',
+ 'roadtrip.ride.missed': 'Verpasst',
+ 'roadtrip.ride.lateBy': '{time} zu spät',
+ 'roadtrip.ride.reachedAt': 'erst {time} da',
+ 'roadtrip.ride.hintFlight': '{title} fliegt um {departs} ab, Check-in bis {pin}.',
+ 'roadtrip.ride.hintShip': '{title} legt um {departs} ab, Check-in bis {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} fährt um {departs} ab, Einstieg bis {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'Die Fahrt erreicht {place} erst um {time}. {title} fliegt um {departs} ab, Check-in bis {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'Die Fahrt erreicht {place} erst um {time}. {title} legt um {departs} ab, Check-in bis {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'Die Fahrt erreicht {place} erst um {time}. {title} fährt um {departs} ab, Einstieg bis {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Flug verpasst',
+ 'roadtrip.day.rideMissed.train': 'Zug verpasst',
+ 'roadtrip.day.rideMissed.ferry': 'Fähre verpasst',
+ 'roadtrip.day.rideMissed.cruise': 'Kreuzfahrt verpasst',
+ 'roadtrip.day.rideMissed.bus': 'Bus verpasst',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Tagesstart',
+ 'roadtrip.bookend.back': 'Übernachtung',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Abfahrt nach dem Check-out',
'roadtrip.bookend.noVia':
'Auf der Fahrt zur oder von der Unterkunft geht kein Zwischenpunkt. Füge dort stattdessen einen Stopp hinzu.',
diff --git a/shared/src/i18n/en/roadtrip.ts b/shared/src/i18n/en/roadtrip.ts
index 3e4161945..e65a5c55e 100644
--- a/shared/src/i18n/en/roadtrip.ts
+++ b/shared/src/i18n/en/roadtrip.ts
@@ -286,10 +286,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Open booking',
'roadtrip.ride.undated': '{title} is on none of this trip’s days, so the drive does not use it.',
'roadtrip.bookings.loose': 'Also booked this day',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'From {name}',
- 'roadtrip.bookend.back': 'Back to {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Departure {time}',
+ 'roadtrip.ride.duration': 'Duration per the booking',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Boarding',
+ 'roadtrip.ride.missed': 'Missed',
+ 'roadtrip.ride.lateBy': '{time} late',
+ 'roadtrip.ride.reachedAt': 'there at {time}',
+ 'roadtrip.ride.hintFlight': '{title} departs at {departs}, check-in closes at {pin}.',
+ 'roadtrip.ride.hintShip': '{title} sails at {departs}, check-in closes at {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} departs at {departs}, boarding by {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'The drive reaches {place} at {time}. {title} departs at {departs}, check-in closes at {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'The drive reaches {place} at {time}. {title} sails at {departs}, check-in closes at {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'The drive reaches {place} at {time}. {title} departs at {departs}, boarding by {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Flight missed',
+ 'roadtrip.day.rideMissed.train': 'Train missed',
+ 'roadtrip.day.rideMissed.ferry': 'Ferry missed',
+ 'roadtrip.day.rideMissed.cruise': 'Cruise missed',
+ 'roadtrip.day.rideMissed.bus': 'Bus missed',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Day start',
+ 'roadtrip.bookend.back': 'Overnight',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Leaves after check-out',
'roadtrip.bookend.noVia': 'No via point on the drive to or from your stay. Add a stop there instead.',
};
diff --git a/shared/src/i18n/es/roadtrip.ts b/shared/src/i18n/es/roadtrip.ts
index 7a2819cec..427210984 100644
--- a/shared/src/i18n/es/roadtrip.ts
+++ b/shared/src/i18n/es/roadtrip.ts
@@ -293,10 +293,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'La reserva {title} no está en ningún día de este viaje, así que el trayecto no la tiene en cuenta.',
'roadtrip.bookings.loose': 'También reservado este día',
- 'roadtrip.bookend.checkOut': 'Salida · {name}',
- 'roadtrip.bookend.from': 'Desde {name}',
- 'roadtrip.bookend.back': 'Vuelta a {name}',
- 'roadtrip.bookend.checkIn': 'Entrada · {name}',
+ 'roadtrip.ride.departureFlight': 'Salida {time}',
+ 'roadtrip.ride.duration': 'Duración según la reserva',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Embarque',
+ 'roadtrip.ride.missed': 'Perdido',
+ 'roadtrip.ride.lateBy': '{time} de retraso',
+ 'roadtrip.ride.reachedAt': 'llega a las {time}',
+ 'roadtrip.ride.hintFlight': '{title} despega a las {departs}, check-in hasta las {pin}.',
+ 'roadtrip.ride.hintShip': '{title} zarpa a las {departs}, check-in hasta las {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} sale a las {departs}, embarque hasta las {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'El trayecto no llega a {place} hasta las {time}. {title} despega a las {departs}, check-in hasta las {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'El trayecto no llega a {place} hasta las {time}. {title} zarpa a las {departs}, check-in hasta las {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'El trayecto no llega a {place} hasta las {time}. {title} sale a las {departs}, embarque hasta las {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Vuelo perdido',
+ 'roadtrip.day.rideMissed.train': 'Tren perdido',
+ 'roadtrip.day.rideMissed.ferry': 'Ferry perdido',
+ 'roadtrip.day.rideMissed.cruise': 'Crucero perdido',
+ 'roadtrip.day.rideMissed.bus': 'Autobús perdido',
+ 'roadtrip.bookend.checkOut': 'Salida',
+ 'roadtrip.bookend.from': 'Inicio del día',
+ 'roadtrip.bookend.back': 'Pernoctación',
+ 'roadtrip.bookend.checkIn': 'Entrada',
'roadtrip.bookend.afterCheckOut': 'Parte después de la hora de salida',
'roadtrip.bookend.noVia':
'No se puede poner un punto de paso en el trayecto hacia tu alojamiento o desde él. Añade una parada allí.',
diff --git a/shared/src/i18n/fr/roadtrip.ts b/shared/src/i18n/fr/roadtrip.ts
index 11d967a5e..27deed816 100644
--- a/shared/src/i18n/fr/roadtrip.ts
+++ b/shared/src/i18n/fr/roadtrip.ts
@@ -295,10 +295,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'La réservation {title} n’est sur aucun jour de ce voyage, le trajet n’en tient donc pas compte.',
'roadtrip.bookings.loose': 'Également réservé ce jour',
- 'roadtrip.bookend.checkOut': 'Départ · {name}',
- 'roadtrip.bookend.from': 'Depuis {name}',
- 'roadtrip.bookend.back': 'Retour à {name}',
- 'roadtrip.bookend.checkIn': 'Arrivée · {name}',
+ 'roadtrip.ride.departureFlight': 'Départ {time}',
+ 'roadtrip.ride.duration': 'Durée selon la réservation',
+ 'roadtrip.ride.checkIn': 'Enregistrement',
+ 'roadtrip.ride.boarding': 'Embarquement',
+ 'roadtrip.ride.missed': 'Manqué',
+ 'roadtrip.ride.lateBy': '{time} de retard',
+ 'roadtrip.ride.reachedAt': 'arrivée à {time}',
+ 'roadtrip.ride.hintFlight': '{title} décolle à {departs}, enregistrement jusqu’à {pin}.',
+ 'roadtrip.ride.hintShip': '{title} appareille à {departs}, enregistrement jusqu’à {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} part à {departs}, embarquement jusqu’à {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'Le trajet n’atteint {place} qu’à {time}. {title} décolle à {departs}, enregistrement jusqu’à {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'Le trajet n’atteint {place} qu’à {time}. {title} appareille à {departs}, enregistrement jusqu’à {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'Le trajet n’atteint {place} qu’à {time}. {title} part à {departs}, embarquement jusqu’à {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Vol manqué',
+ 'roadtrip.day.rideMissed.train': 'Train manqué',
+ 'roadtrip.day.rideMissed.ferry': 'Ferry manqué',
+ 'roadtrip.day.rideMissed.cruise': 'Croisière manquée',
+ 'roadtrip.day.rideMissed.bus': 'Bus manqué',
+ 'roadtrip.bookend.checkOut': 'Départ',
+ 'roadtrip.bookend.from': 'Début de journée',
+ 'roadtrip.bookend.back': 'Nuitée',
+ 'roadtrip.bookend.checkIn': 'Arrivée',
'roadtrip.bookend.afterCheckOut': 'Part après l’heure limite de départ',
'roadtrip.bookend.noVia':
'Pas de point de passage sur le trajet vers ou depuis votre hébergement. Ajoutez plutôt un arrêt à cet endroit.',
diff --git a/shared/src/i18n/gr/roadtrip.ts b/shared/src/i18n/gr/roadtrip.ts
index 4cfafc6c4..6d945a48f 100644
--- a/shared/src/i18n/gr/roadtrip.ts
+++ b/shared/src/i18n/gr/roadtrip.ts
@@ -297,10 +297,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'Η κράτηση {title} δεν βρίσκεται σε καμία μέρα αυτού του ταξιδιού, οπότε η διαδρομή δεν τη λαμβάνει υπόψη.',
'roadtrip.bookings.loose': 'Επίσης κρατημένο αυτή τη μέρα',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'Από {name}',
- 'roadtrip.bookend.back': 'Επιστροφή: {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Αναχώρηση {time}',
+ 'roadtrip.ride.duration': 'Διάρκεια σύμφωνα με την κράτηση',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Επιβίβαση',
+ 'roadtrip.ride.missed': 'Χάθηκε',
+ 'roadtrip.ride.lateBy': '{time} καθυστέρηση',
+ 'roadtrip.ride.reachedAt': 'άφιξη {time}',
+ 'roadtrip.ride.hintFlight': '{title}: αναχώρηση στις {departs}, check-in έως τις {pin}.',
+ 'roadtrip.ride.hintShip': '{title}: απόπλους στις {departs}, check-in έως τις {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title}: αναχώρηση στις {departs}, επιβίβαση έως τις {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ '{place}: άφιξη μόλις στις {time}. {title}: αναχώρηση στις {departs}, check-in έως τις {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ '{place}: άφιξη μόλις στις {time}. {title}: απόπλους στις {departs}, check-in έως τις {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ '{place}: άφιξη μόλις στις {time}. {title}: αναχώρηση στις {departs}, επιβίβαση έως τις {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Χαμένη πτήση',
+ 'roadtrip.day.rideMissed.train': 'Χαμένο τρένο',
+ 'roadtrip.day.rideMissed.ferry': 'Χαμένο φέρι',
+ 'roadtrip.day.rideMissed.cruise': 'Χαμένη κρουαζιέρα',
+ 'roadtrip.day.rideMissed.bus': 'Χαμένο λεωφορείο',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Έναρξη ημέρας',
+ 'roadtrip.bookend.back': 'Διανυκτέρευση',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Αναχώρηση μετά το check-out',
'roadtrip.bookend.noVia':
'Δεν μπαίνει ενδιάμεσο σημείο στη διαδρομή προς ή από το κατάλυμα. Προσθέστε εκεί μια στάση.',
diff --git a/shared/src/i18n/hu/roadtrip.ts b/shared/src/i18n/hu/roadtrip.ts
index 19874898f..aaaf0273b 100644
--- a/shared/src/i18n/hu/roadtrip.ts
+++ b/shared/src/i18n/hu/roadtrip.ts
@@ -291,10 +291,28 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Foglalás megnyitása',
'roadtrip.ride.undated': '{title}: a foglalás az utazás egyik napjára sem esik, ezért az útvonal nem számol vele.',
'roadtrip.bookings.loose': 'Erre a napra még lefoglalva',
- 'roadtrip.bookend.checkOut': 'Kijelentkezés · {name}',
- 'roadtrip.bookend.from': 'Indulás: {name}',
- 'roadtrip.bookend.back': 'Vissza: {name}',
- 'roadtrip.bookend.checkIn': 'Bejelentkezés · {name}',
+ 'roadtrip.ride.departureFlight': 'Indulás {time}',
+ 'roadtrip.ride.duration': 'Időtartam a foglalás szerint',
+ 'roadtrip.ride.checkIn': 'Utasfelvétel',
+ 'roadtrip.ride.boarding': 'Beszállás',
+ 'roadtrip.ride.missed': 'Lekésve',
+ 'roadtrip.ride.lateBy': '{time} késés',
+ 'roadtrip.ride.reachedAt': 'érkezés csak {time}',
+ 'roadtrip.ride.hintFlight': '{title}: indulás {departs}, utasfelvétel {pin}-ig.',
+ 'roadtrip.ride.hintShip': '{title}: kifutás {departs}, utasfelvétel {pin}-ig.',
+ 'roadtrip.ride.hintBoarding': '{title}: indulás {departs}, beszállás {pin}-ig.',
+ 'roadtrip.ride.lateHintFlight': '{place}: érkezés csak {time}. {title}: indulás {departs}, utasfelvétel {pin}-ig.',
+ 'roadtrip.ride.lateHintShip': '{place}: érkezés csak {time}. {title}: kifutás {departs}, utasfelvétel {pin}-ig.',
+ 'roadtrip.ride.lateHintBoarding': '{place}: érkezés csak {time}. {title}: indulás {departs}, beszállás {pin}-ig.',
+ 'roadtrip.day.rideMissed.flight': 'Lekésett járat',
+ 'roadtrip.day.rideMissed.train': 'Lekésett vonat',
+ 'roadtrip.day.rideMissed.ferry': 'Lekésett komp',
+ 'roadtrip.day.rideMissed.cruise': 'Lekésett hajóút',
+ 'roadtrip.day.rideMissed.bus': 'Lekésett busz',
+ 'roadtrip.bookend.checkOut': 'Kijelentkezés',
+ 'roadtrip.bookend.from': 'Napkezdés',
+ 'roadtrip.bookend.back': 'Éjszakázás',
+ 'roadtrip.bookend.checkIn': 'Bejelentkezés',
'roadtrip.bookend.afterCheckOut': 'Indulás kijelentkezés után',
'roadtrip.bookend.noVia':
'A szálláshoz vezető vagy onnan induló útra nem kerülhet köztes pont. Adj hozzá inkább egy megállót ott.',
diff --git a/shared/src/i18n/id/roadtrip.ts b/shared/src/i18n/id/roadtrip.ts
index 776715171..a482586a0 100644
--- a/shared/src/i18n/id/roadtrip.ts
+++ b/shared/src/i18n/id/roadtrip.ts
@@ -294,10 +294,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'Pemesanan {title} tidak berada di hari mana pun dalam perjalanan ini, jadi perjalanan tidak memperhitungkannya.',
'roadtrip.bookings.loose': 'Juga dipesan hari ini',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'Dari {name}',
- 'roadtrip.bookend.back': 'Kembali ke {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Berangkat {time}',
+ 'roadtrip.ride.duration': 'Durasi sesuai pemesanan',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Boarding',
+ 'roadtrip.ride.missed': 'Terlewat',
+ 'roadtrip.ride.lateBy': 'terlambat {time}',
+ 'roadtrip.ride.reachedAt': 'baru tiba {time}',
+ 'roadtrip.ride.hintFlight': '{title} berangkat pukul {departs}, check-in sampai {pin}.',
+ 'roadtrip.ride.hintShip': '{title} berlayar pukul {departs}, check-in sampai {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} berangkat pukul {departs}, boarding sampai {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'Perjalanan baru tiba di {place} pukul {time}. {title} berangkat pukul {departs}, check-in sampai {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'Perjalanan baru tiba di {place} pukul {time}. {title} berlayar pukul {departs}, check-in sampai {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'Perjalanan baru tiba di {place} pukul {time}. {title} berangkat pukul {departs}, boarding sampai {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Penerbangan terlewat',
+ 'roadtrip.day.rideMissed.train': 'Kereta terlewat',
+ 'roadtrip.day.rideMissed.ferry': 'Feri terlewat',
+ 'roadtrip.day.rideMissed.cruise': 'Kapal pesiar terlewat',
+ 'roadtrip.day.rideMissed.bus': 'Bus terlewat',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Awal hari',
+ 'roadtrip.bookend.back': 'Menginap',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Berangkat setelah check-out',
'roadtrip.bookend.noVia':
'Titik lintas tidak bisa ditaruh di perjalanan ke atau dari penginapan Anda. Tambahkan perhentian di sana.',
diff --git a/shared/src/i18n/it/roadtrip.ts b/shared/src/i18n/it/roadtrip.ts
index 92b1bb559..9bd0565e4 100644
--- a/shared/src/i18n/it/roadtrip.ts
+++ b/shared/src/i18n/it/roadtrip.ts
@@ -294,10 +294,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'La prenotazione {title} non cade in nessun giorno di questo viaggio, quindi il percorso non la considera.',
'roadtrip.bookings.loose': 'Prenotato anche questo giorno',
- 'roadtrip.bookend.checkOut': 'Check-out · {name}',
- 'roadtrip.bookend.from': 'Da {name}',
- 'roadtrip.bookend.back': 'Ritorno a {name}',
- 'roadtrip.bookend.checkIn': 'Check-in · {name}',
+ 'roadtrip.ride.departureFlight': 'Partenza {time}',
+ 'roadtrip.ride.duration': 'Durata secondo la prenotazione',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Imbarco',
+ 'roadtrip.ride.missed': 'Perso',
+ 'roadtrip.ride.lateBy': '{time} di ritardo',
+ 'roadtrip.ride.reachedAt': 'arrivo alle {time}',
+ 'roadtrip.ride.hintFlight': '{title} decolla alle {departs}, check-in entro le {pin}.',
+ 'roadtrip.ride.hintShip': '{title} salpa alle {departs}, check-in entro le {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} parte alle {departs}, imbarco entro le {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'Il viaggio arriva a {place} solo alle {time}. {title} decolla alle {departs}, check-in entro le {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'Il viaggio arriva a {place} solo alle {time}. {title} salpa alle {departs}, check-in entro le {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'Il viaggio arriva a {place} solo alle {time}. {title} parte alle {departs}, imbarco entro le {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Volo perso',
+ 'roadtrip.day.rideMissed.train': 'Treno perso',
+ 'roadtrip.day.rideMissed.ferry': 'Traghetto perso',
+ 'roadtrip.day.rideMissed.cruise': 'Crociera persa',
+ 'roadtrip.day.rideMissed.bus': 'Autobus perso',
+ 'roadtrip.bookend.checkOut': 'Check-out',
+ 'roadtrip.bookend.from': 'Inizio giornata',
+ 'roadtrip.bookend.back': 'Pernottamento',
+ 'roadtrip.bookend.checkIn': 'Check-in',
'roadtrip.bookend.afterCheckOut': 'Partenza dopo il check-out',
'roadtrip.bookend.noVia':
'Nessun punto di passaggio sul tragitto verso o dal tuo alloggio. Aggiungi invece una sosta in quel punto.',
diff --git a/shared/src/i18n/ja/roadtrip.ts b/shared/src/i18n/ja/roadtrip.ts
index 73c2ee04b..08a84c8e7 100644
--- a/shared/src/i18n/ja/roadtrip.ts
+++ b/shared/src/i18n/ja/roadtrip.ts
@@ -288,10 +288,30 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': '予約を開く',
'roadtrip.ride.undated': '{title} はこの旅行のどの日にも入っていないため、走行では使われません。',
'roadtrip.bookings.loose': 'この日のその他の予約',
- 'roadtrip.bookend.checkOut': 'チェックアウト · {name}',
- 'roadtrip.bookend.from': '{name}から',
- 'roadtrip.bookend.back': '{name}へ戻る',
- 'roadtrip.bookend.checkIn': 'チェックイン · {name}',
+ 'roadtrip.ride.departureFlight': '出発 {time}',
+ 'roadtrip.ride.duration': '予約上の所要時間',
+ 'roadtrip.ride.checkIn': 'チェックイン',
+ 'roadtrip.ride.boarding': '乗車',
+ 'roadtrip.ride.missed': '乗り遅れ',
+ 'roadtrip.ride.lateBy': '{time}遅れ',
+ 'roadtrip.ride.reachedAt': '{time}着',
+ 'roadtrip.ride.hintFlight': '{title} は {departs} 発、チェックインは {pin} まで。',
+ 'roadtrip.ride.hintShip': '{title} は {departs} 出港、チェックインは {pin} まで。',
+ 'roadtrip.ride.hintBoarding': '{title} は {departs} 発、乗車は {pin} まで。',
+ 'roadtrip.ride.lateHintFlight':
+ '{place} に着くのは {time} です。{title} は {departs} 発、チェックインは {pin} まで。',
+ 'roadtrip.ride.lateHintShip':
+ '{place} に着くのは {time} です。{title} は {departs} 出港、チェックインは {pin} まで。',
+ 'roadtrip.ride.lateHintBoarding': '{place} に着くのは {time} です。{title} は {departs} 発、乗車は {pin} まで。',
+ 'roadtrip.day.rideMissed.flight': '飛行機に乗り遅れ',
+ 'roadtrip.day.rideMissed.train': '列車に乗り遅れ',
+ 'roadtrip.day.rideMissed.ferry': 'フェリーに乗り遅れ',
+ 'roadtrip.day.rideMissed.cruise': 'クルーズに乗り遅れ',
+ 'roadtrip.day.rideMissed.bus': 'バスに乗り遅れ',
+ 'roadtrip.bookend.checkOut': 'チェックアウト',
+ 'roadtrip.bookend.from': '出発',
+ 'roadtrip.bookend.back': '宿泊',
+ 'roadtrip.bookend.checkIn': 'チェックイン',
'roadtrip.bookend.afterCheckOut': 'チェックアウト後に出発',
'roadtrip.bookend.noVia': '宿泊先との間の区間には経由地を置けません。代わりにそこへ立ち寄り先を追加してください。',
};
diff --git a/shared/src/i18n/ko/roadtrip.ts b/shared/src/i18n/ko/roadtrip.ts
index fa188f1b5..f4556b3fa 100644
--- a/shared/src/i18n/ko/roadtrip.ts
+++ b/shared/src/i18n/ko/roadtrip.ts
@@ -285,10 +285,28 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': '예약 열기',
'roadtrip.ride.undated': '{title}은(는) 이 여행의 어느 날에도 속하지 않아 주행에 반영되지 않습니다.',
'roadtrip.bookings.loose': '이날의 다른 예약',
- 'roadtrip.bookend.checkOut': '체크아웃 · {name}',
- 'roadtrip.bookend.from': '{name}에서 출발',
- 'roadtrip.bookend.back': '{name}(으)로 돌아가기',
- 'roadtrip.bookend.checkIn': '체크인 · {name}',
+ 'roadtrip.ride.departureFlight': '출발 {time}',
+ 'roadtrip.ride.duration': '예약 기준 소요 시간',
+ 'roadtrip.ride.checkIn': '체크인',
+ 'roadtrip.ride.boarding': '탑승',
+ 'roadtrip.ride.missed': '놓침',
+ 'roadtrip.ride.lateBy': '{time} 늦음',
+ 'roadtrip.ride.reachedAt': '{time} 도착',
+ 'roadtrip.ride.hintFlight': '{title} {departs} 출발, 체크인 마감 {pin}.',
+ 'roadtrip.ride.hintShip': '{title} {departs} 출항, 체크인 마감 {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} {departs} 출발, 탑승 마감 {pin}.',
+ 'roadtrip.ride.lateHintFlight': '{place}에 {time}에야 도착합니다. {title} {departs} 출발, 체크인 마감 {pin}.',
+ 'roadtrip.ride.lateHintShip': '{place}에 {time}에야 도착합니다. {title} {departs} 출항, 체크인 마감 {pin}.',
+ 'roadtrip.ride.lateHintBoarding': '{place}에 {time}에야 도착합니다. {title} {departs} 출발, 탑승 마감 {pin}.',
+ 'roadtrip.day.rideMissed.flight': '항공편 놓침',
+ 'roadtrip.day.rideMissed.train': '기차 놓침',
+ 'roadtrip.day.rideMissed.ferry': '페리 놓침',
+ 'roadtrip.day.rideMissed.cruise': '크루즈 놓침',
+ 'roadtrip.day.rideMissed.bus': '버스 놓침',
+ 'roadtrip.bookend.checkOut': '체크아웃',
+ 'roadtrip.bookend.from': '하루 시작',
+ 'roadtrip.bookend.back': '숙박',
+ 'roadtrip.bookend.checkIn': '체크인',
'roadtrip.bookend.afterCheckOut': '체크아웃 후 출발',
'roadtrip.bookend.noVia': '숙소를 오가는 구간에는 경유지를 둘 수 없습니다. 대신 그곳에 정차 지점을 추가하세요.',
};
diff --git a/shared/src/i18n/nl/roadtrip.ts b/shared/src/i18n/nl/roadtrip.ts
index f9caad8ba..94f4edcbb 100644
--- a/shared/src/i18n/nl/roadtrip.ts
+++ b/shared/src/i18n/nl/roadtrip.ts
@@ -293,10 +293,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'De boeking {title} valt op geen enkele dag van deze reis, dus de rit houdt er geen rekening mee.',
'roadtrip.bookings.loose': 'Ook geboekt op deze dag',
- 'roadtrip.bookend.checkOut': 'Uitchecken · {name}',
- 'roadtrip.bookend.from': 'Vanaf {name}',
- 'roadtrip.bookend.back': 'Terug naar {name}',
- 'roadtrip.bookend.checkIn': 'Inchecken · {name}',
+ 'roadtrip.ride.departureFlight': 'Vertrek {time}',
+ 'roadtrip.ride.duration': 'Duur volgens de boeking',
+ 'roadtrip.ride.checkIn': 'Inchecken',
+ 'roadtrip.ride.boarding': 'Instappen',
+ 'roadtrip.ride.missed': 'Gemist',
+ 'roadtrip.ride.lateBy': '{time} te laat',
+ 'roadtrip.ride.reachedAt': 'pas om {time}',
+ 'roadtrip.ride.hintFlight': '{title} vertrekt om {departs}, inchecken tot {pin}.',
+ 'roadtrip.ride.hintShip': '{title} vaart af om {departs}, inchecken tot {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} vertrekt om {departs}, instappen tot {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'De rit bereikt {place} pas om {time}. {title} vertrekt om {departs}, inchecken tot {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'De rit bereikt {place} pas om {time}. {title} vaart af om {departs}, inchecken tot {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'De rit bereikt {place} pas om {time}. {title} vertrekt om {departs}, instappen tot {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Vlucht gemist',
+ 'roadtrip.day.rideMissed.train': 'Trein gemist',
+ 'roadtrip.day.rideMissed.ferry': 'Veerboot gemist',
+ 'roadtrip.day.rideMissed.cruise': 'Cruise gemist',
+ 'roadtrip.day.rideMissed.bus': 'Bus gemist',
+ 'roadtrip.bookend.checkOut': 'Uitchecken',
+ 'roadtrip.bookend.from': 'Dagstart',
+ 'roadtrip.bookend.back': 'Overnachting',
+ 'roadtrip.bookend.checkIn': 'Inchecken',
'roadtrip.bookend.afterCheckOut': 'Vertrek na het uitchecken',
'roadtrip.bookend.noVia':
'Geen tussenpunt op de rit naar of van je verblijf. Voeg daar in plaats daarvan een stop toe.',
diff --git a/shared/src/i18n/pl/roadtrip.ts b/shared/src/i18n/pl/roadtrip.ts
index 16fbd684a..6ace8c25f 100644
--- a/shared/src/i18n/pl/roadtrip.ts
+++ b/shared/src/i18n/pl/roadtrip.ts
@@ -290,10 +290,29 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Otwórz rezerwację',
'roadtrip.ride.undated': 'Rezerwacja {title} nie przypada na żaden dzień tej podróży, więc trasa jej nie uwzględnia.',
'roadtrip.bookings.loose': 'Zarezerwowane też tego dnia',
- 'roadtrip.bookend.checkOut': 'Wymeldowanie · {name}',
- 'roadtrip.bookend.from': 'Wyjazd: {name}',
- 'roadtrip.bookend.back': 'Powrót: {name}',
- 'roadtrip.bookend.checkIn': 'Zameldowanie · {name}',
+ 'roadtrip.ride.departureFlight': 'Wylot {time}',
+ 'roadtrip.ride.duration': 'Czas trwania według rezerwacji',
+ 'roadtrip.ride.checkIn': 'Odprawa',
+ 'roadtrip.ride.boarding': 'Wsiadanie',
+ 'roadtrip.ride.missed': 'Spóźnienie',
+ 'roadtrip.ride.lateBy': '{time} spóźnienia',
+ 'roadtrip.ride.reachedAt': 'dopiero o {time}',
+ 'roadtrip.ride.hintFlight': '{title} odlatuje o {departs}, odprawa do {pin}.',
+ 'roadtrip.ride.hintShip': '{title} wypływa o {departs}, odprawa do {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} odjeżdża o {departs}, wsiadanie do {pin}.',
+ 'roadtrip.ride.lateHintFlight': '{place}: przyjazd dopiero o {time}. {title} odlatuje o {departs}, odprawa do {pin}.',
+ 'roadtrip.ride.lateHintShip': '{place}: przyjazd dopiero o {time}. {title} wypływa o {departs}, odprawa do {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ '{place}: przyjazd dopiero o {time}. {title} odjeżdża o {departs}, wsiadanie do {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Spóźnienie na lot',
+ 'roadtrip.day.rideMissed.train': 'Spóźnienie na pociąg',
+ 'roadtrip.day.rideMissed.ferry': 'Spóźnienie na prom',
+ 'roadtrip.day.rideMissed.cruise': 'Spóźnienie na rejs',
+ 'roadtrip.day.rideMissed.bus': 'Spóźnienie na autobus',
+ 'roadtrip.bookend.checkOut': 'Wymeldowanie',
+ 'roadtrip.bookend.from': 'Początek dnia',
+ 'roadtrip.bookend.back': 'Nocleg',
+ 'roadtrip.bookend.checkIn': 'Zameldowanie',
'roadtrip.bookend.afterCheckOut': 'Wyjazd po godzinie wymeldowania',
'roadtrip.bookend.noVia':
'Na trasie do noclegu ani z niego nie można dodać punktu pośredniego. Dodaj tam zamiast tego postój.',
diff --git a/shared/src/i18n/ru/roadtrip.ts b/shared/src/i18n/ru/roadtrip.ts
index a6c3b61bf..284101e33 100644
--- a/shared/src/i18n/ru/roadtrip.ts
+++ b/shared/src/i18n/ru/roadtrip.ts
@@ -294,10 +294,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'Бронирование {title} не относится ни к одному дню этой поездки, поэтому маршрут его не учитывает.',
'roadtrip.bookings.loose': 'Также забронировано в этот день',
- 'roadtrip.bookend.checkOut': 'Выезд · {name}',
- 'roadtrip.bookend.from': 'Отправление: {name}',
- 'roadtrip.bookend.back': 'Возвращение: {name}',
- 'roadtrip.bookend.checkIn': 'Заезд · {name}',
+ 'roadtrip.ride.departureFlight': 'Вылет {time}',
+ 'roadtrip.ride.duration': 'Длительность по бронированию',
+ 'roadtrip.ride.checkIn': 'Регистрация',
+ 'roadtrip.ride.boarding': 'Посадка',
+ 'roadtrip.ride.missed': 'Опоздание',
+ 'roadtrip.ride.lateBy': 'опоздание {time}',
+ 'roadtrip.ride.reachedAt': 'только в {time}',
+ 'roadtrip.ride.hintFlight': '{title} вылетает в {departs}, регистрация до {pin}.',
+ 'roadtrip.ride.hintShip': '{title} отплывает в {departs}, регистрация до {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} отправляется в {departs}, посадка до {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ '{place}: прибытие только в {time}. {title} вылетает в {departs}, регистрация до {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ '{place}: прибытие только в {time}. {title} отплывает в {departs}, регистрация до {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ '{place}: прибытие только в {time}. {title} отправляется в {departs}, посадка до {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Опоздание на рейс',
+ 'roadtrip.day.rideMissed.train': 'Опоздание на поезд',
+ 'roadtrip.day.rideMissed.ferry': 'Опоздание на паром',
+ 'roadtrip.day.rideMissed.cruise': 'Опоздание на круиз',
+ 'roadtrip.day.rideMissed.bus': 'Опоздание на автобус',
+ 'roadtrip.bookend.checkOut': 'Выезд',
+ 'roadtrip.bookend.from': 'Начало дня',
+ 'roadtrip.bookend.back': 'Ночёвка',
+ 'roadtrip.bookend.checkIn': 'Заезд',
'roadtrip.bookend.afterCheckOut': 'Отъезд позже расчётного часа',
'roadtrip.bookend.noVia':
'На маршрут до места проживания или от него нельзя поставить промежуточную точку. Добавьте там остановку.',
diff --git a/shared/src/i18n/sv/roadtrip.ts b/shared/src/i18n/sv/roadtrip.ts
index 8177d1e7e..3d999f59d 100644
--- a/shared/src/i18n/sv/roadtrip.ts
+++ b/shared/src/i18n/sv/roadtrip.ts
@@ -289,10 +289,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Öppna bokning',
'roadtrip.ride.undated': 'Bokningen {title} ligger inte på någon av resans dagar, så körningen tar inte med den.',
'roadtrip.bookings.loose': 'Även bokat denna dag',
- 'roadtrip.bookend.checkOut': 'Utcheckning · {name}',
- 'roadtrip.bookend.from': 'Från {name}',
- 'roadtrip.bookend.back': 'Tillbaka till {name}',
- 'roadtrip.bookend.checkIn': 'Incheckning · {name}',
+ 'roadtrip.ride.departureFlight': 'Avgång {time}',
+ 'roadtrip.ride.duration': 'Längd enligt bokningen',
+ 'roadtrip.ride.checkIn': 'Incheckning',
+ 'roadtrip.ride.boarding': 'Påstigning',
+ 'roadtrip.ride.missed': 'Missad',
+ 'roadtrip.ride.lateBy': '{time} sent',
+ 'roadtrip.ride.reachedAt': 'framme {time}',
+ 'roadtrip.ride.hintFlight': '{title} avgår {departs}, incheckningen stänger {pin}.',
+ 'roadtrip.ride.hintShip': '{title} lägger ut {departs}, incheckningen stänger {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} avgår {departs}, påstigning senast {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'Körningen når {place} först {time}. {title} avgår {departs}, incheckningen stänger {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'Körningen når {place} först {time}. {title} lägger ut {departs}, incheckningen stänger {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'Körningen når {place} först {time}. {title} avgår {departs}, påstigning senast {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Missat flyg',
+ 'roadtrip.day.rideMissed.train': 'Missat tåg',
+ 'roadtrip.day.rideMissed.ferry': 'Missad färja',
+ 'roadtrip.day.rideMissed.cruise': 'Missad kryssning',
+ 'roadtrip.day.rideMissed.bus': 'Missad buss',
+ 'roadtrip.bookend.checkOut': 'Utcheckning',
+ 'roadtrip.bookend.from': 'Dagens start',
+ 'roadtrip.bookend.back': 'Övernattning',
+ 'roadtrip.bookend.checkIn': 'Incheckning',
'roadtrip.bookend.afterCheckOut': 'Avresa efter utcheckning',
'roadtrip.bookend.noVia':
'Ingen mellanpunkt på resan till eller från ditt boende. Lägg till ett stopp där i stället.',
diff --git a/shared/src/i18n/tr/roadtrip.ts b/shared/src/i18n/tr/roadtrip.ts
index 459aa92c4..c2ebee609 100644
--- a/shared/src/i18n/tr/roadtrip.ts
+++ b/shared/src/i18n/tr/roadtrip.ts
@@ -292,10 +292,28 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.undated':
'{title} rezervasyonu bu yolculuğun hiçbir gününde değil, bu yüzden sürüş onu hesaba katmıyor.',
'roadtrip.bookings.loose': 'Bu gün için ayrıca rezerve edildi',
- 'roadtrip.bookend.checkOut': 'Çıkış · {name}',
- 'roadtrip.bookend.from': 'Başlangıç: {name}',
- 'roadtrip.bookend.back': 'Dönüş: {name}',
- 'roadtrip.bookend.checkIn': 'Giriş · {name}',
+ 'roadtrip.ride.departureFlight': 'Kalkış {time}',
+ 'roadtrip.ride.duration': 'Rezervasyona göre süre',
+ 'roadtrip.ride.checkIn': 'Check-in',
+ 'roadtrip.ride.boarding': 'Biniş',
+ 'roadtrip.ride.missed': 'Kaçırıldı',
+ 'roadtrip.ride.lateBy': '{time} geç',
+ 'roadtrip.ride.reachedAt': 'varış {time}',
+ 'roadtrip.ride.hintFlight': '{title}: kalkış {departs}, check-in en geç {pin}.',
+ 'roadtrip.ride.hintShip': '{title}: hareket {departs}, check-in en geç {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title}: kalkış {departs}, biniş en geç {pin}.',
+ 'roadtrip.ride.lateHintFlight': '{place}: varış ancak {time}. {title}: kalkış {departs}, check-in en geç {pin}.',
+ 'roadtrip.ride.lateHintShip': '{place}: varış ancak {time}. {title}: hareket {departs}, check-in en geç {pin}.',
+ 'roadtrip.ride.lateHintBoarding': '{place}: varış ancak {time}. {title}: kalkış {departs}, biniş en geç {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Uçuş kaçırıldı',
+ 'roadtrip.day.rideMissed.train': 'Tren kaçırıldı',
+ 'roadtrip.day.rideMissed.ferry': 'Feribot kaçırıldı',
+ 'roadtrip.day.rideMissed.cruise': 'Gemi turu kaçırıldı',
+ 'roadtrip.day.rideMissed.bus': 'Otobüs kaçırıldı',
+ 'roadtrip.bookend.checkOut': 'Çıkış',
+ 'roadtrip.bookend.from': 'Gün başlangıcı',
+ 'roadtrip.bookend.back': 'Konaklama',
+ 'roadtrip.bookend.checkIn': 'Giriş',
'roadtrip.bookend.afterCheckOut': 'Çıkış saatinden sonra hareket',
'roadtrip.bookend.noVia':
'Konaklama yerinize giden ya da oradan çıkan yola ara nokta konamaz. Bunun yerine oraya bir mola ekleyin.',
diff --git a/shared/src/i18n/uk/roadtrip.ts b/shared/src/i18n/uk/roadtrip.ts
index 5f1b1f204..49ffdc665 100644
--- a/shared/src/i18n/uk/roadtrip.ts
+++ b/shared/src/i18n/uk/roadtrip.ts
@@ -291,10 +291,29 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Відкрити бронювання',
'roadtrip.ride.undated': 'Бронювання {title} не припадає на жоден день цієї подорожі, тому маршрут його не враховує.',
'roadtrip.bookings.loose': 'Також заброньовано цього дня',
- 'roadtrip.bookend.checkOut': 'Виїзд · {name}',
- 'roadtrip.bookend.from': 'Відправлення: {name}',
- 'roadtrip.bookend.back': 'Повернення: {name}',
- 'roadtrip.bookend.checkIn': 'Заїзд · {name}',
+ 'roadtrip.ride.departureFlight': 'Виліт {time}',
+ 'roadtrip.ride.duration': 'Тривалість за бронюванням',
+ 'roadtrip.ride.checkIn': 'Реєстрація',
+ 'roadtrip.ride.boarding': 'Посадка',
+ 'roadtrip.ride.missed': 'Запізнення',
+ 'roadtrip.ride.lateBy': 'запізнення {time}',
+ 'roadtrip.ride.reachedAt': 'лише о {time}',
+ 'roadtrip.ride.hintFlight': '{title} вилітає о {departs}, реєстрація до {pin}.',
+ 'roadtrip.ride.hintShip': '{title} відпливає о {departs}, реєстрація до {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} відправляється о {departs}, посадка до {pin}.',
+ 'roadtrip.ride.lateHintFlight': '{place}: прибуття лише о {time}. {title} вилітає о {departs}, реєстрація до {pin}.',
+ 'roadtrip.ride.lateHintShip': '{place}: прибуття лише о {time}. {title} відпливає о {departs}, реєстрація до {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ '{place}: прибуття лише о {time}. {title} відправляється о {departs}, посадка до {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Запізнення на рейс',
+ 'roadtrip.day.rideMissed.train': 'Запізнення на поїзд',
+ 'roadtrip.day.rideMissed.ferry': 'Запізнення на пором',
+ 'roadtrip.day.rideMissed.cruise': 'Запізнення на круїз',
+ 'roadtrip.day.rideMissed.bus': 'Запізнення на автобус',
+ 'roadtrip.bookend.checkOut': 'Виїзд',
+ 'roadtrip.bookend.from': 'Початок дня',
+ 'roadtrip.bookend.back': 'Ночівля',
+ 'roadtrip.bookend.checkIn': 'Заїзд',
'roadtrip.bookend.afterCheckOut': 'Від’їзд пізніше розрахункової години',
'roadtrip.bookend.noVia':
'На маршрут до місця проживання чи від нього не можна поставити проміжну точку. Додайте там зупинку.',
diff --git a/shared/src/i18n/vi/roadtrip.ts b/shared/src/i18n/vi/roadtrip.ts
index f843ed6f7..a11f19c7f 100644
--- a/shared/src/i18n/vi/roadtrip.ts
+++ b/shared/src/i18n/vi/roadtrip.ts
@@ -290,10 +290,31 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': 'Mở đặt chỗ',
'roadtrip.ride.undated': 'Đặt chỗ {title} không thuộc ngày nào của chuyến đi này, nên hành trình không tính đến nó.',
'roadtrip.bookings.loose': 'Cũng đã đặt trong ngày này',
- 'roadtrip.bookend.checkOut': 'Trả phòng · {name}',
- 'roadtrip.bookend.from': 'Từ {name}',
- 'roadtrip.bookend.back': 'Về lại {name}',
- 'roadtrip.bookend.checkIn': 'Nhận phòng · {name}',
+ 'roadtrip.ride.departureFlight': 'Cất cánh {time}',
+ 'roadtrip.ride.duration': 'Thời lượng theo đặt chỗ',
+ 'roadtrip.ride.checkIn': 'Làm thủ tục',
+ 'roadtrip.ride.boarding': 'Lên tàu',
+ 'roadtrip.ride.missed': 'Lỡ chuyến',
+ 'roadtrip.ride.lateBy': 'trễ {time}',
+ 'roadtrip.ride.reachedAt': 'đến lúc {time}',
+ 'roadtrip.ride.hintFlight': '{title} cất cánh lúc {departs}, làm thủ tục đến {pin}.',
+ 'roadtrip.ride.hintShip': '{title} khởi hành lúc {departs}, làm thủ tục đến {pin}.',
+ 'roadtrip.ride.hintBoarding': '{title} khởi hành lúc {departs}, lên tàu đến {pin}.',
+ 'roadtrip.ride.lateHintFlight':
+ 'Chuyến đi chỉ tới {place} lúc {time}. {title} cất cánh lúc {departs}, làm thủ tục đến {pin}.',
+ 'roadtrip.ride.lateHintShip':
+ 'Chuyến đi chỉ tới {place} lúc {time}. {title} khởi hành lúc {departs}, làm thủ tục đến {pin}.',
+ 'roadtrip.ride.lateHintBoarding':
+ 'Chuyến đi chỉ tới {place} lúc {time}. {title} khởi hành lúc {departs}, lên tàu đến {pin}.',
+ 'roadtrip.day.rideMissed.flight': 'Lỡ chuyến bay',
+ 'roadtrip.day.rideMissed.train': 'Lỡ chuyến tàu',
+ 'roadtrip.day.rideMissed.ferry': 'Lỡ chuyến phà',
+ 'roadtrip.day.rideMissed.cruise': 'Lỡ chuyến du thuyền',
+ 'roadtrip.day.rideMissed.bus': 'Lỡ chuyến xe buýt',
+ 'roadtrip.bookend.checkOut': 'Trả phòng',
+ 'roadtrip.bookend.from': 'Bắt đầu ngày',
+ 'roadtrip.bookend.back': 'Nghỉ đêm',
+ 'roadtrip.bookend.checkIn': 'Nhận phòng',
'roadtrip.bookend.afterCheckOut': 'Khởi hành sau giờ trả phòng',
'roadtrip.bookend.noVia':
'Không thể đặt điểm trung gian trên chặng đi hoặc về nơi lưu trú. Hãy thêm một điểm dừng ở đó.',
diff --git a/shared/src/i18n/zh-TW/roadtrip.ts b/shared/src/i18n/zh-TW/roadtrip.ts
index e3ca1e8da..376d4724d 100644
--- a/shared/src/i18n/zh-TW/roadtrip.ts
+++ b/shared/src/i18n/zh-TW/roadtrip.ts
@@ -274,10 +274,28 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': '開啟預訂',
'roadtrip.ride.undated': '{title} 不在本次旅行的任何一天,因此行程不會用到它。',
'roadtrip.bookings.loose': '當天的其他預訂',
- 'roadtrip.bookend.checkOut': '退房 · {name}',
- 'roadtrip.bookend.from': '從 {name} 出發',
- 'roadtrip.bookend.back': '返回 {name}',
- 'roadtrip.bookend.checkIn': '入住 · {name}',
+ 'roadtrip.ride.departureFlight': '起飛 {time}',
+ 'roadtrip.ride.duration': '預訂時長',
+ 'roadtrip.ride.checkIn': '辦理登記',
+ 'roadtrip.ride.boarding': '上車',
+ 'roadtrip.ride.missed': '錯過',
+ 'roadtrip.ride.lateBy': '晚到 {time}',
+ 'roadtrip.ride.reachedAt': '{time} 才到',
+ 'roadtrip.ride.hintFlight': '{title} {departs} 起飛,{pin} 前辦理登記。',
+ 'roadtrip.ride.hintShip': '{title} {departs} 開船,{pin} 前辦理登記。',
+ 'roadtrip.ride.hintBoarding': '{title} {departs} 發車,{pin} 前上車。',
+ 'roadtrip.ride.lateHintFlight': '行程 {time} 才抵達 {place}。{title} {departs} 起飛,{pin} 前辦理登記。',
+ 'roadtrip.ride.lateHintShip': '行程 {time} 才抵達 {place}。{title} {departs} 開船,{pin} 前辦理登記。',
+ 'roadtrip.ride.lateHintBoarding': '行程 {time} 才抵達 {place}。{title} {departs} 發車,{pin} 前上車。',
+ 'roadtrip.day.rideMissed.flight': '錯過航班',
+ 'roadtrip.day.rideMissed.train': '錯過火車',
+ 'roadtrip.day.rideMissed.ferry': '錯過渡輪',
+ 'roadtrip.day.rideMissed.cruise': '錯過郵輪',
+ 'roadtrip.day.rideMissed.bus': '錯過巴士',
+ 'roadtrip.bookend.checkOut': '退房',
+ 'roadtrip.bookend.from': '出發',
+ 'roadtrip.bookend.back': '住宿',
+ 'roadtrip.bookend.checkIn': '入住',
'roadtrip.bookend.afterCheckOut': '退房後才出發',
'roadtrip.bookend.noVia': '往返住宿地點的路段無法加入途經點。請改在那裡新增一個停靠點。',
};
diff --git a/shared/src/i18n/zh/roadtrip.ts b/shared/src/i18n/zh/roadtrip.ts
index 9a77567ef..2cf19c942 100644
--- a/shared/src/i18n/zh/roadtrip.ts
+++ b/shared/src/i18n/zh/roadtrip.ts
@@ -275,10 +275,28 @@ const roadtrip: TranslationStrings = {
'roadtrip.ride.open': '打开预订',
'roadtrip.ride.undated': '{title} 不在本次旅行的任何一天,因此行程不会用到它。',
'roadtrip.bookings.loose': '当天的其他预订',
- 'roadtrip.bookend.checkOut': '退房 · {name}',
- 'roadtrip.bookend.from': '从 {name} 出发',
- 'roadtrip.bookend.back': '返回 {name}',
- 'roadtrip.bookend.checkIn': '入住 · {name}',
+ 'roadtrip.ride.departureFlight': '起飞 {time}',
+ 'roadtrip.ride.duration': '预订时长',
+ 'roadtrip.ride.checkIn': '办理登记',
+ 'roadtrip.ride.boarding': '上车',
+ 'roadtrip.ride.missed': '错过',
+ 'roadtrip.ride.lateBy': '晚到 {time}',
+ 'roadtrip.ride.reachedAt': '{time} 才到',
+ 'roadtrip.ride.hintFlight': '{title} {departs} 起飞,{pin} 前办理登记。',
+ 'roadtrip.ride.hintShip': '{title} {departs} 开船,{pin} 前办理登记。',
+ 'roadtrip.ride.hintBoarding': '{title} {departs} 发车,{pin} 前上车。',
+ 'roadtrip.ride.lateHintFlight': '行程 {time} 才到达 {place}。{title} {departs} 起飞,{pin} 前办理登记。',
+ 'roadtrip.ride.lateHintShip': '行程 {time} 才到达 {place}。{title} {departs} 开船,{pin} 前办理登记。',
+ 'roadtrip.ride.lateHintBoarding': '行程 {time} 才到达 {place}。{title} {departs} 发车,{pin} 前上车。',
+ 'roadtrip.day.rideMissed.flight': '错过航班',
+ 'roadtrip.day.rideMissed.train': '错过火车',
+ 'roadtrip.day.rideMissed.ferry': '错过渡轮',
+ 'roadtrip.day.rideMissed.cruise': '错过邮轮',
+ 'roadtrip.day.rideMissed.bus': '错过巴士',
+ 'roadtrip.bookend.checkOut': '退房',
+ 'roadtrip.bookend.from': '出发',
+ 'roadtrip.bookend.back': '住宿',
+ 'roadtrip.bookend.checkIn': '入住',
'roadtrip.bookend.afterCheckOut': '退房后才出发',
'roadtrip.bookend.noVia': '往返住处的路段不能添加途经点。请改为在那里添加一个停靠点。',
};