@qite/tide-components 1.0.1 → 1.0.3

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.
Files changed (28) hide show
  1. package/README.md +392 -421
  2. package/build/build-cjs/index.js +1031 -133
  3. package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +5 -5
  4. package/build/build-cjs/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +1 -0
  5. package/build/build-cjs/src/booking-wizard/features/travelers-form/validate-form.d.ts +1 -1
  6. package/build/build-cjs/src/booking-wizard/types.d.ts +15 -0
  7. package/build/build-cjs/src/search-results/components/traject/traject-node-card.d.ts +14 -0
  8. package/build/build-cjs/src/search-results/components/traject/traject-results.d.ts +6 -0
  9. package/build/build-cjs/src/search-results/hooks/use-traject-availability.d.ts +2 -0
  10. package/build/build-cjs/src/search-results/store/search-results-slice.d.ts +21 -2
  11. package/build/build-cjs/src/search-results/types.d.ts +2 -1
  12. package/build/build-cjs/src/search-results/utils/flight-booking-params.d.ts +18 -0
  13. package/build/build-cjs/src/search-results/utils/traject-utils.d.ts +33 -0
  14. package/build/build-cjs/src/shared/booking/travelers-form.d.ts +3 -2
  15. package/build/build-esm/index.js +1032 -134
  16. package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +5 -5
  17. package/build/build-esm/src/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +1 -0
  18. package/build/build-esm/src/booking-wizard/features/travelers-form/validate-form.d.ts +1 -1
  19. package/build/build-esm/src/booking-wizard/types.d.ts +15 -0
  20. package/build/build-esm/src/search-results/components/traject/traject-node-card.d.ts +14 -0
  21. package/build/build-esm/src/search-results/components/traject/traject-results.d.ts +6 -0
  22. package/build/build-esm/src/search-results/hooks/use-traject-availability.d.ts +2 -0
  23. package/build/build-esm/src/search-results/store/search-results-slice.d.ts +21 -2
  24. package/build/build-esm/src/search-results/types.d.ts +2 -1
  25. package/build/build-esm/src/search-results/utils/flight-booking-params.d.ts +18 -0
  26. package/build/build-esm/src/search-results/utils/traject-utils.d.ts +33 -0
  27. package/build/build-esm/src/shared/booking/travelers-form.d.ts +3 -2
  28. package/package.json +2 -2
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import React__default, { useLayoutEffect as useLayoutEffect$1, useEffect, useContext, useState, useRef, useCallback, useMemo } from 'react';
4
4
  import JsonURL from '@jsonurl/jsonurl';
5
5
  import { format as format$2, isToday, getDate, startOfWeek, startOfMonth, endOfWeek, addWeeks, endOfMonth, eachDayOfInterval, getYear, getMonth, getISOWeek, getISODay, isSameMonth, startOfDay, isAfter, isEqual, isWithinInterval, endOfDay, isBefore, isSameDay, differenceInCalendarDays, addMonths, addDays, formatISO, addYears, differenceInYears, parseISO, differenceInMinutes, parse, startOfToday, isValid } from 'date-fns';
6
- import { merge, cloneDeep, isNil, isArray as isArray$1, compact, isEmpty as isEmpty$1, range, chunk, isFunction as isFunction$1, clamp, now, omit, first, orderBy, uniq, uniqBy, sortBy, sum, last, findIndex as findIndex$1, set, get, isEqual as isEqual$1, groupBy, minBy, concat, flatMap } from 'lodash';
6
+ import { merge, cloneDeep, isNil, isArray as isArray$1, compact, isEmpty as isEmpty$1, range, chunk, isFunction as isFunction$1, clamp, now, omit, isPlainObject as isPlainObject$1, mapValues, pickBy, first, orderBy, uniq, uniqBy, sortBy, sum, last, findIndex as findIndex$1, set, get, isEqual as isEqual$1, groupBy, minBy, concat, flatMap } from 'lodash';
7
7
  import { arSA, da, de, enGB, es, fr, is, it, nl, nb, pl, pt, sv, ja, enUS } from 'date-fns/locale';
8
8
  import { usePopper } from 'react-popper';
9
9
  import { useSelector, useDispatch, Provider } from 'react-redux';
@@ -170,6 +170,7 @@ var TRAVELERS_FORM$f = {
170
170
  ADULTS: "بالغون",
171
171
  CHILD: "طفل",
172
172
  CHILDREN: "أطفال",
173
+ BABY: "رضيع",
173
174
  GENDER: "اللقب",
174
175
  GENDER_ID: "الجنس حسب جواز السفر/بطاقة الهوية",
175
176
  MALE: "السيد",
@@ -214,6 +215,8 @@ var TRAVELERS_FORM$f = {
214
215
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "المسافر {0}: ليس بالغًا",
215
216
  TRAVELER_X_IS_NO_CHILD: "الغرفة {0} - المسافر {1}: ليس طفلًا",
216
217
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "المسافر {0}: ليس طفلًا",
218
+ TRAVELER_X_IS_NO_BABY: "الغرفة {0} - المسافر {1}: ليس رضيعًا (يجب أن يكون عمره أقل من {2} سنة في تاريخ المغادرة)",
219
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "المسافر {0}: ليس رضيعًا (يجب أن يكون عمره أقل من {1} سنة في تاريخ المغادرة)",
217
220
  NO_MAIN_BOOKER_SELECTED: "لم يتم اختيار حاجز رئيسي",
218
221
  MAIN_BOOKER_FIELD: "الحاجز الرئيسي: {0}",
219
222
  MAIN_BOOKER_EMAIL_IS_INVALID: "الحاجز الرئيسي: البريد الإلكتروني غير صالح",
@@ -606,6 +609,7 @@ var TRAVELERS_FORM$e = {
606
609
  ADULTS: "voksne",
607
610
  CHILD: "barn",
608
611
  CHILDREN: "børn",
612
+ BABY: "baby",
609
613
  GENDER: "Tiltaleform",
610
614
  GENDER_ID: "Køn ifølge pas/ID-kort",
611
615
  MALE: "Hr.",
@@ -650,6 +654,8 @@ var TRAVELERS_FORM$e = {
650
654
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Rejsende {0}: er ikke voksen",
651
655
  TRAVELER_X_IS_NO_CHILD: "Værelse {0} - Rejsende {1}: er ikke barn",
652
656
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Rejsende {0}: er ikke barn",
657
+ TRAVELER_X_IS_NO_BABY: "Værelse {0} - Rejsende {1}: er ikke baby (skal være under {2} år på afrejsedatoen)",
658
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Rejsende {0}: er ikke baby (skal være under {1} år på afrejsedatoen)",
653
659
  NO_MAIN_BOOKER_SELECTED: "Ingen hovedbooker valgt",
654
660
  MAIN_BOOKER_FIELD: "Hovedbooker: {0}",
655
661
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hovedbooker: email er ugyldig",
@@ -1042,6 +1048,7 @@ var TRAVELERS_FORM$d = {
1042
1048
  ADULTS: "Erwachsene",
1043
1049
  CHILD: "Kind",
1044
1050
  CHILDREN: "Kinder",
1051
+ BABY: "Baby",
1045
1052
  GENDER: "Anrede",
1046
1053
  GENDER_ID: "Geschlecht laut Reisepass/Personalausweis",
1047
1054
  MALE: "Herr",
@@ -1086,6 +1093,8 @@ var TRAVELERS_FORM$d = {
1086
1093
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reisender {0}: ist kein Erwachsener",
1087
1094
  TRAVELER_X_IS_NO_CHILD: "Zimmer {0} - Reisender {1}: ist kein Kind",
1088
1095
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reisender {0}: ist kein Kind",
1096
+ TRAVELER_X_IS_NO_BABY: "Zimmer {0} - Reisender {1}: ist kein Baby (muss am Abreisedatum jünger als {2} Jahre sein)",
1097
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reisender {0}: ist kein Baby (muss am Abreisedatum jünger als {1} Jahre sein)",
1089
1098
  NO_MAIN_BOOKER_SELECTED: "Kein Hauptbucher ausgewählt",
1090
1099
  MAIN_BOOKER_FIELD: "Hauptbucher: {0}",
1091
1100
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hauptbucher: E-Mail ist ungültig",
@@ -1479,6 +1488,7 @@ var TRAVELERS_FORM$c = {
1479
1488
  ADULTS: "adults",
1480
1489
  CHILD: "child",
1481
1490
  CHILDREN: "children",
1491
+ BABY: "baby",
1482
1492
  GENDER: "Salutation",
1483
1493
  GENDER_ID: "Gender according to passport/ID card",
1484
1494
  MALE: "Mr.",
@@ -1526,6 +1536,8 @@ var TRAVELERS_FORM$c = {
1526
1536
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Traveler {0}: is not an adult",
1527
1537
  TRAVELER_X_IS_NO_CHILD: "Room {0} - Traveler {1}: is not a child",
1528
1538
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Traveler {0}: is not a child",
1539
+ TRAVELER_X_IS_NO_BABY: "Room {0} - Traveler {1}: is not a baby (must be under {2} years old on the departure date)",
1540
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Traveler {0}: is not a baby (must be under {1} years old on the departure date)",
1529
1541
  NO_MAIN_BOOKER_SELECTED: "No main booker has been selected",
1530
1542
  MAIN_BOOKER_FIELD: "Main booker: {0}",
1531
1543
  MAIN_BOOKER_EMAIL_IS_INVALID: "Main booker: email is invalid",
@@ -1918,6 +1930,7 @@ var TRAVELERS_FORM$b = {
1918
1930
  ADULTS: "adultos",
1919
1931
  CHILD: "niño",
1920
1932
  CHILDREN: "niños",
1933
+ BABY: "bebé",
1921
1934
  GENDER: "Tratamiento",
1922
1935
  GENDER_ID: "Sexo según pasaporte/documento de identidad",
1923
1936
  MALE: "Sr.",
@@ -1962,6 +1975,8 @@ var TRAVELERS_FORM$b = {
1962
1975
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Viajero {0}: no es adulto",
1963
1976
  TRAVELER_X_IS_NO_CHILD: "Habitación {0} - Viajero {1}: no es niño",
1964
1977
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Viajero {0}: no es niño",
1978
+ TRAVELER_X_IS_NO_BABY: "Habitación {0} - Viajero {1}: no es bebé (debe tener menos de {2} años en la fecha de salida)",
1979
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Viajero {0}: no es bebé (debe tener menos de {1} años en la fecha de salida)",
1965
1980
  NO_MAIN_BOOKER_SELECTED: "No se ha seleccionado titular de la reserva",
1966
1981
  MAIN_BOOKER_FIELD: "Titular de la reserva: {0}",
1967
1982
  MAIN_BOOKER_EMAIL_IS_INVALID: "Titular de la reserva: correo electrónico inválido",
@@ -2355,6 +2370,7 @@ var TRAVELERS_FORM$a = {
2355
2370
  ADULTS: "adultes",
2356
2371
  CHILD: "enfant",
2357
2372
  CHILDREN: "enfants",
2373
+ BABY: "bébé",
2358
2374
  GENDER: "Civilité",
2359
2375
  GENDER_ID: "Sexe selon passeport/carte d'identité",
2360
2376
  MALE: "Monsieur",
@@ -2402,6 +2418,8 @@ var TRAVELERS_FORM$a = {
2402
2418
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Voyageur {0} : n'est pas un adulte",
2403
2419
  TRAVELER_X_IS_NO_CHILD: "Chambre {0} - Voyageur {1} : n'est pas un enfant",
2404
2420
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Voyageur {0} : n'est pas un enfant",
2421
+ TRAVELER_X_IS_NO_BABY: "Chambre {0} - Voyageur {1} : n'est pas un bébé (doit avoir moins de {2} ans à la date de départ)",
2422
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Voyageur {0} : n'est pas un bébé (doit avoir moins de {1} ans à la date de départ)",
2405
2423
  NO_MAIN_BOOKER_SELECTED: "Aucun réservant principal n'a été sélectionné",
2406
2424
  MAIN_BOOKER_FIELD: "Principal réservant : {0}",
2407
2425
  MAIN_BOOKER_EMAIL_IS_INVALID: "Principal réservant : e-mail invalide",
@@ -2794,6 +2812,7 @@ var TRAVELERS_FORM$9 = {
2794
2812
  ADULTS: "adultes",
2795
2813
  CHILD: "enfant",
2796
2814
  CHILDREN: "enfants",
2815
+ BABY: "bébé",
2797
2816
  GENDER: "Civilité",
2798
2817
  GENDER_ID: "Sexe selon passeport/carte d'identité",
2799
2818
  MALE: "M.",
@@ -2838,6 +2857,8 @@ var TRAVELERS_FORM$9 = {
2838
2857
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Voyageur {0} : n'est pas un adulte",
2839
2858
  TRAVELER_X_IS_NO_CHILD: "Chambre {0} - Voyageur {1} : n'est pas un enfant",
2840
2859
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Voyageur {0} : n'est pas un enfant",
2860
+ TRAVELER_X_IS_NO_BABY: "Chambre {0} - Voyageur {1} : n'est pas un bébé (doit avoir moins de {2} ans à la date de départ)",
2861
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Voyageur {0} : n'est pas un bébé (doit avoir moins de {1} ans à la date de départ)",
2841
2862
  NO_MAIN_BOOKER_SELECTED: "Aucun titulaire de réservation sélectionné",
2842
2863
  MAIN_BOOKER_FIELD: "Titulaire de la réservation : {0}",
2843
2864
  MAIN_BOOKER_EMAIL_IS_INVALID: "Titulaire de la réservation : email invalide",
@@ -3230,6 +3251,7 @@ var TRAVELERS_FORM$8 = {
3230
3251
  ADULTS: "fullorðnir",
3231
3252
  CHILD: "barn",
3232
3253
  CHILDREN: "börn",
3254
+ BABY: "ungabarn",
3233
3255
  GENDER: "Ávarp",
3234
3256
  GENDER_ID: "Kyn samkvæmt vegabréfi/skilríki",
3235
3257
  MALE: "Herra",
@@ -3274,6 +3296,8 @@ var TRAVELERS_FORM$8 = {
3274
3296
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Farþegi {0}: er ekki fullorðinn",
3275
3297
  TRAVELER_X_IS_NO_CHILD: "Herbergi {0} - Farþegi {1}: er ekki barn",
3276
3298
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Farþegi {0}: er ekki barn",
3299
+ TRAVELER_X_IS_NO_BABY: "Herbergi {0} - Farþegi {1}: er ekki ungabarn (verður að vera undir {2} ára á brottfarardegi)",
3300
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Farþegi {0}: er ekki ungabarn (verður að vera undir {1} ára á brottfarardegi)",
3277
3301
  NO_MAIN_BOOKER_SELECTED: "Enginn aðal bókari valinn",
3278
3302
  MAIN_BOOKER_FIELD: "Aðal bókari: {0}",
3279
3303
  MAIN_BOOKER_EMAIL_IS_INVALID: "Aðal bókari: netfang ógilt",
@@ -3666,6 +3690,7 @@ var TRAVELERS_FORM$7 = {
3666
3690
  ADULTS: "adulti",
3667
3691
  CHILD: "bambino",
3668
3692
  CHILDREN: "bambini",
3693
+ BABY: "neonato",
3669
3694
  GENDER: "Titolo",
3670
3695
  GENDER_ID: "Sesso secondo passaporto/carta d'identità",
3671
3696
  MALE: "Sig.",
@@ -3710,6 +3735,8 @@ var TRAVELERS_FORM$7 = {
3710
3735
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Viaggiatore {0}: non è un adulto",
3711
3736
  TRAVELER_X_IS_NO_CHILD: "Camera {0} - Viaggiatore {1}: non è un bambino",
3712
3737
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Viaggiatore {0}: non è un bambino",
3738
+ TRAVELER_X_IS_NO_BABY: "Camera {0} - Viaggiatore {1}: non è un neonato (deve avere meno di {2} anni alla data di partenza)",
3739
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Viaggiatore {0}: non è un neonato (deve avere meno di {1} anni alla data di partenza)",
3713
3740
  NO_MAIN_BOOKER_SELECTED: "Nessun intestatario della prenotazione selezionato",
3714
3741
  MAIN_BOOKER_FIELD: "Intestatario della prenotazione: {0}",
3715
3742
  MAIN_BOOKER_EMAIL_IS_INVALID: "Intestatario della prenotazione: email non valida",
@@ -4103,6 +4130,7 @@ var TRAVELERS_FORM$6 = {
4103
4130
  ADULTS: "volwassenen",
4104
4131
  CHILD: "kind",
4105
4132
  CHILDREN: "kinderen",
4133
+ BABY: "baby",
4106
4134
  GENDER: "Aanspreking",
4107
4135
  GENDER_ID: "Geslacht volgens paspoort/identiteitskaart",
4108
4136
  MALE: "Meneer",
@@ -4150,6 +4178,8 @@ var TRAVELERS_FORM$6 = {
4150
4178
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reiziger {0}: is geen volwassene",
4151
4179
  TRAVELER_X_IS_NO_CHILD: "Kamer {0} - Reiziger {1}: is geen kind",
4152
4180
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reiziger {0}: is geen kind",
4181
+ TRAVELER_X_IS_NO_BABY: "Kamer {0} - Reiziger {1}: is geen baby (moet jonger zijn dan {2} jaar op de heendatum)",
4182
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reiziger {0}: is geen baby (moet jonger zijn dan {1} jaar op de heendatum)",
4153
4183
  NO_MAIN_BOOKER_SELECTED: "Er werd geen hoofdboeker geselecteerd",
4154
4184
  MAIN_BOOKER_FIELD: "Hoofdboeker: {0}",
4155
4185
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hoofdboeker: e-mail is ongeldig",
@@ -4542,6 +4572,7 @@ var TRAVELERS_FORM$5 = {
4542
4572
  ADULTS: "volwassenen",
4543
4573
  CHILD: "kind",
4544
4574
  CHILDREN: "kinderen",
4575
+ BABY: "baby",
4545
4576
  GENDER: "Aanhef",
4546
4577
  GENDER_ID: "Geslacht volgens paspoort/identiteitskaart",
4547
4578
  MALE: "Dhr.",
@@ -4586,6 +4617,8 @@ var TRAVELERS_FORM$5 = {
4586
4617
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reiziger {0}: is geen volwassene",
4587
4618
  TRAVELER_X_IS_NO_CHILD: "Kamer {0} - Reiziger {1}: is geen kind",
4588
4619
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reiziger {0}: is geen kind",
4620
+ TRAVELER_X_IS_NO_BABY: "Kamer {0} - Reiziger {1}: is geen baby (moet jonger zijn dan {2} jaar op de heendatum)",
4621
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reiziger {0}: is geen baby (moet jonger zijn dan {1} jaar op de heendatum)",
4589
4622
  NO_MAIN_BOOKER_SELECTED: "Geen hoofdboeker geselecteerd",
4590
4623
  MAIN_BOOKER_FIELD: "Hoofdboeker: {0}",
4591
4624
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hoofdboeker: e-mailadres is ongeldig",
@@ -4978,6 +5011,7 @@ var TRAVELERS_FORM$4 = {
4978
5011
  ADULTS: "voksne",
4979
5012
  CHILD: "barn",
4980
5013
  CHILDREN: "barn",
5014
+ BABY: "baby",
4981
5015
  GENDER: "Tiltaleform",
4982
5016
  GENDER_ID: "Kjønn ifølge pass/ID-kort",
4983
5017
  MALE: "Herr",
@@ -5022,6 +5056,8 @@ var TRAVELERS_FORM$4 = {
5022
5056
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Reisende {0}: er ikke voksen",
5023
5057
  TRAVELER_X_IS_NO_CHILD: "Rom {0} – Reisende {1}: er ikke barn",
5024
5058
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Reisende {0}: er ikke barn",
5059
+ TRAVELER_X_IS_NO_BABY: "Rom {0} – Reisende {1}: er ikke baby (må være under {2} år på avreisedatoen)",
5060
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Reisende {0}: er ikke baby (må være under {1} år på avreisedatoen)",
5025
5061
  NO_MAIN_BOOKER_SELECTED: "Ingen hovedbestiller valgt",
5026
5062
  MAIN_BOOKER_FIELD: "Hovedbestiller: {0}",
5027
5063
  MAIN_BOOKER_EMAIL_IS_INVALID: "Hovedbestiller: e-post er ugyldig",
@@ -5414,6 +5450,7 @@ var TRAVELERS_FORM$3 = {
5414
5450
  ADULTS: "dorośli",
5415
5451
  CHILD: "dziecko",
5416
5452
  CHILDREN: "dzieci",
5453
+ BABY: "niemowlę",
5417
5454
  GENDER: "Forma grzecznościowa",
5418
5455
  GENDER_ID: "Płeć według paszportu/dowodu osobistego",
5419
5456
  MALE: "Pan",
@@ -5458,6 +5495,8 @@ var TRAVELERS_FORM$3 = {
5458
5495
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Podróżny {0}: nie jest dorosły",
5459
5496
  TRAVELER_X_IS_NO_CHILD: "Pokój {0} – Podróżny {1}: nie jest dzieckiem",
5460
5497
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Podróżny {0}: nie jest dzieckiem",
5498
+ TRAVELER_X_IS_NO_BABY: "Pokój {0} – Podróżny {1}: nie jest niemowlęciem (musi mieć mniej niż {2} lata w dniu wyjazdu)",
5499
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Podróżny {0}: nie jest niemowlęciem (musi mieć mniej niż {1} lata w dniu wyjazdu)",
5461
5500
  NO_MAIN_BOOKER_SELECTED: "Nie wybrano głównego rezerwującego",
5462
5501
  MAIN_BOOKER_FIELD: "Główny rezerwujący: {0}",
5463
5502
  MAIN_BOOKER_EMAIL_IS_INVALID: "Główny rezerwujący: nieprawidłowy adres e-mail",
@@ -5850,6 +5889,7 @@ var TRAVELERS_FORM$2 = {
5850
5889
  ADULTS: "adultos",
5851
5890
  CHILD: "criança",
5852
5891
  CHILDREN: "crianças",
5892
+ BABY: "bebé",
5853
5893
  GENDER: "Tratamento",
5854
5894
  GENDER_ID: "Sexo conforme passaporte/documento de identidade",
5855
5895
  MALE: "Sr.",
@@ -5894,6 +5934,8 @@ var TRAVELERS_FORM$2 = {
5894
5934
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Viajante {0}: não é adulto",
5895
5935
  TRAVELER_X_IS_NO_CHILD: "Quarto {0} – Viajante {1}: não é criança",
5896
5936
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Viajante {0}: não é criança",
5937
+ TRAVELER_X_IS_NO_BABY: "Quarto {0} – Viajante {1}: não é bebé (deve ter menos de {2} anos na data de partida)",
5938
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Viajante {0}: não é bebé (deve ter menos de {1} anos na data de partida)",
5897
5939
  NO_MAIN_BOOKER_SELECTED: "Nenhum titular da reserva foi selecionado",
5898
5940
  MAIN_BOOKER_FIELD: "Titular da reserva: {0}",
5899
5941
  MAIN_BOOKER_EMAIL_IS_INVALID: "Titular da reserva: o e-mail é inválido",
@@ -6286,6 +6328,7 @@ var TRAVELERS_FORM$1 = {
6286
6328
  ADULTS: "vuxna",
6287
6329
  CHILD: "barn",
6288
6330
  CHILDREN: "barn",
6331
+ BABY: "spädbarn",
6289
6332
  GENDER: "Tilltalsform",
6290
6333
  GENDER_ID: "Kön enligt pass/ID-kort",
6291
6334
  MALE: "Herr",
@@ -6330,6 +6373,8 @@ var TRAVELERS_FORM$1 = {
6330
6373
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "Resenär {0}: är inte vuxen",
6331
6374
  TRAVELER_X_IS_NO_CHILD: "Rum {0} – Resenär {1}: är inte barn",
6332
6375
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "Resenär {0}: är inte barn",
6376
+ TRAVELER_X_IS_NO_BABY: "Rum {0} – Resenär {1}: är inte spädbarn (måste vara under {2} år på avresedatumet)",
6377
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "Resenär {0}: är inte spädbarn (måste vara under {1} år på avresedatumet)",
6333
6378
  NO_MAIN_BOOKER_SELECTED: "Ingen huvudbokare har valts",
6334
6379
  MAIN_BOOKER_FIELD: "Huvudbokare: {0}",
6335
6380
  MAIN_BOOKER_EMAIL_IS_INVALID: "Huvudbokare: e-postadressen är ogiltig",
@@ -6722,6 +6767,7 @@ var TRAVELERS_FORM = {
6722
6767
  ADULTS: "大人",
6723
6768
  CHILD: "子供",
6724
6769
  CHILDREN: "子供",
6770
+ BABY: "乳児",
6725
6771
  GENDER: "敬称",
6726
6772
  GENDER_ID: "パスポート/身分証明書上の性別",
6727
6773
  MALE: "男性",
@@ -6766,6 +6812,8 @@ var TRAVELERS_FORM = {
6766
6812
  SINGLE_ROOM_TRAVELER_X_IS_NO_ADULT: "旅行者 {0}: 大人ではありません",
6767
6813
  TRAVELER_X_IS_NO_CHILD: "客室 {0} – 旅行者 {1}: 子供ではありません",
6768
6814
  SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD: "旅行者 {0}: 子供ではありません",
6815
+ TRAVELER_X_IS_NO_BABY: "客室 {0} – 旅行者 {1}: 乳児ではありません(出発日時点で{2}歳未満である必要があります)",
6816
+ SINGLE_ROOM_TRAVELER_X_IS_NO_BABY: "旅行者 {0}: 乳児ではありません(出発日時点で{1}歳未満である必要があります)",
6769
6817
  NO_MAIN_BOOKER_SELECTED: "代表予約者が選択されていません",
6770
6818
  MAIN_BOOKER_FIELD: "代表予約者: {0}",
6771
6819
  MAIN_BOOKER_EMAIL_IS_INVALID: "代表予約者: メールアドレスが無効です",
@@ -7391,12 +7439,6 @@ var DataType = {
7391
7439
  template: "template",
7392
7440
  };
7393
7441
 
7394
- exports.DateAmountType = void 0;
7395
- (function (DateAmountType) {
7396
- DateAmountType[(DateAmountType["days"] = 0)] = "days";
7397
- DateAmountType[(DateAmountType["months"] = 1)] = "months";
7398
- })(exports.DateAmountType || (exports.DateAmountType = {}));
7399
-
7400
7442
  var DossierType = {
7401
7443
  hotelOnly: 0,
7402
7444
  transportOnly: 1,
@@ -7500,6 +7542,16 @@ var MetaDataType = {
7500
7542
  additionalServices: 7,
7501
7543
  };
7502
7544
 
7545
+ exports.NoteType = void 0;
7546
+ (function (NoteType) {
7547
+ NoteType[(NoteType["notification"] = 0)] = "notification";
7548
+ NoteType[(NoteType["task"] = 1)] = "task";
7549
+ NoteType[(NoteType["calendar"] = 2)] = "calendar";
7550
+ NoteType[(NoteType["callLog"] = 3)] = "callLog";
7551
+ NoteType[(NoteType["opportunity"] = 4)] = "opportunity";
7552
+ NoteType[(NoteType["email"] = 5)] = "email";
7553
+ })(exports.NoteType || (exports.NoteType = {}));
7554
+
7503
7555
  var PaymentType = {
7504
7556
  other: 0,
7505
7557
  bancontact: 1,
@@ -7507,22 +7559,6 @@ var PaymentType = {
7507
7559
  cash: 3,
7508
7560
  };
7509
7561
 
7510
- exports.PortalQsmType = void 0;
7511
- (function (PortalQsmType) {
7512
- PortalQsmType[(PortalQsmType["Multidestination"] = 0)] = "Multidestination";
7513
- PortalQsmType[(PortalQsmType["Accommodation"] = 1)] = "Accommodation";
7514
- PortalQsmType[(PortalQsmType["AccommodationAndFlight"] = 2)] =
7515
- "AccommodationAndFlight";
7516
- PortalQsmType[(PortalQsmType["Flight"] = 3)] = "Flight";
7517
- PortalQsmType[(PortalQsmType["RoundTrip"] = 4)] = "RoundTrip";
7518
- PortalQsmType[(PortalQsmType["GroupTour"] = 5)] = "GroupTour";
7519
- PortalQsmType[(PortalQsmType["Package"] = 6)] = "Package";
7520
- PortalQsmType[(PortalQsmType["Ticket"] = 7)] = "Ticket";
7521
- PortalQsmType[(PortalQsmType["Car"] = 8)] = "Car";
7522
- PortalQsmType[(PortalQsmType["Transfer"] = 9)] = "Transfer";
7523
- PortalQsmType[(PortalQsmType["Cruise"] = 10)] = "Cruise";
7524
- })(exports.PortalQsmType || (exports.PortalQsmType = {}));
7525
-
7526
7562
  var PriceChartType = {
7527
7563
  purchasePrices: 0,
7528
7564
  sellingPrices: 1,
@@ -7627,6 +7663,35 @@ var VendorType = {
7627
7663
  sunnyCars: 20,
7628
7664
  };
7629
7665
 
7666
+ exports.DateAmountType = void 0;
7667
+ (function (DateAmountType) {
7668
+ DateAmountType[(DateAmountType["days"] = 0)] = "days";
7669
+ DateAmountType[(DateAmountType["months"] = 1)] = "months";
7670
+ })(exports.DateAmountType || (exports.DateAmountType = {}));
7671
+
7672
+ exports.PortalQsmType = void 0;
7673
+ (function (PortalQsmType) {
7674
+ PortalQsmType[(PortalQsmType["Multidestination"] = 0)] = "Multidestination";
7675
+ PortalQsmType[(PortalQsmType["Accommodation"] = 1)] = "Accommodation";
7676
+ PortalQsmType[(PortalQsmType["AccommodationAndFlight"] = 2)] =
7677
+ "AccommodationAndFlight";
7678
+ PortalQsmType[(PortalQsmType["Flight"] = 3)] = "Flight";
7679
+ PortalQsmType[(PortalQsmType["RoundTrip"] = 4)] = "RoundTrip";
7680
+ PortalQsmType[(PortalQsmType["GroupTour"] = 5)] = "GroupTour";
7681
+ PortalQsmType[(PortalQsmType["Package"] = 6)] = "Package";
7682
+ PortalQsmType[(PortalQsmType["Ticket"] = 7)] = "Ticket";
7683
+ PortalQsmType[(PortalQsmType["Car"] = 8)] = "Car";
7684
+ PortalQsmType[(PortalQsmType["Transfer"] = 9)] = "Transfer";
7685
+ PortalQsmType[(PortalQsmType["Cruise"] = 10)] = "Cruise";
7686
+ })(exports.PortalQsmType || (exports.PortalQsmType = {}));
7687
+
7688
+ var TrajectNodeType = {
7689
+ regular: 0,
7690
+ connectingNode: 1,
7691
+ poi: 2,
7692
+ subroute: 3,
7693
+ };
7694
+
7630
7695
  /******************************************************************************
7631
7696
  Copyright (c) Microsoft Corporation.
7632
7697
 
@@ -13923,58 +13988,73 @@ var get = function (url, apiKey, token, signal, skipReviver, languageCode) {
13923
13988
  });
13924
13989
  };
13925
13990
 
13926
- var ENDPOINT$9 = "/api/web/booking/v2";
13927
- var ENDPOINT_AVAILABLE_FLIGHTS = ENDPOINT$9 + "/available-flights";
13928
- var ENDPOINT_TRANSPORT_DATES = ENDPOINT$9 + "/transport-dates";
13929
- var ENDPOINT_PRICES = ENDPOINT$9 + "/prices";
13930
- var ENDPOINT_AVAILABLE_COUNTRIES = ENDPOINT$9 + "/available-countries";
13931
- var ENDPOINT_SEARCH = ENDPOINT$9 + "/search";
13991
+ var ENDPOINT$a = "/api/web/booking/v2";
13992
+ var ENDPOINT_AVAILABLE_FLIGHTS = ENDPOINT$a + "/available-flights";
13993
+ var ENDPOINT_TRANSPORT_DATES = ENDPOINT$a + "/transport-dates";
13994
+ var ENDPOINT_PRICES = ENDPOINT$a + "/prices";
13995
+ var ENDPOINT_AVAILABLE_COUNTRIES = ENDPOINT$a + "/available-countries";
13996
+ var ENDPOINT_SEARCH = ENDPOINT$a + "/search";
13932
13997
  var ENDPOINT_SEARCH_WITH_ERROR_MAPPING =
13933
- ENDPOINT$9 + "/search-with-error-mapping";
13998
+ ENDPOINT$a + "/search-with-error-mapping";
13934
13999
  // const ENDPOINT_ELASTIC = `${ENDPOINT}/elastic`; // TODO
13935
- var ENDPOINT_DETAILS = ENDPOINT$9 + "/details";
13936
- var ENDPOINT_DETAILS_WL = ENDPOINT$9 + "/details-wl";
14000
+ var ENDPOINT_DETAILS = ENDPOINT$a + "/details";
14001
+ var ENDPOINT_DETAILS_WL = ENDPOINT$a + "/details-wl";
13937
14002
  var ENDPOINT_ENTRYLIGHT = function (code) {
13938
- return ENDPOINT$9 + "/entry-light/" + code;
14003
+ return ENDPOINT$a + "/entry-light/" + code;
13939
14004
  };
13940
- var ENDPOINT_VALIDATE_VOUCHER = ENDPOINT$9 + "/validate-voucher";
14005
+ var ENDPOINT_VALIDATE_VOUCHER = ENDPOINT$a + "/validate-voucher";
13941
14006
  var ENDPOINT_ALTERNATE_HOTELS = function (transactionId, optionId) {
13942
14007
  return (
13943
- ENDPOINT$9 + "/details/" + transactionId + "/alternate-hotels/" + optionId
14008
+ ENDPOINT$a + "/details/" + transactionId + "/alternate-hotels/" + optionId
13944
14009
  );
13945
14010
  };
13946
14011
  var ENDPOINT_ALTERNATE_FLIGHTS = function (transactionId) {
13947
- return ENDPOINT$9 + "/details/" + transactionId + "/alternate-flights";
14012
+ return ENDPOINT$a + "/details/" + transactionId + "/alternate-flights";
13948
14013
  };
13949
- var ENDPOINT_BOOKABLE_DATES = ENDPOINT$9 + "/bookable-dates";
13950
- var ENDPOINT_PRICE_DETAILS$1 = ENDPOINT$9 + "/price-details";
13951
- var ENDPOINT_BOOK$1 = ENDPOINT$9 + "/book";
13952
- var ENDPOINT_UPDATE = ENDPOINT$9 + "/update";
13953
- var ENDPOINT_AGENTS = ENDPOINT$9 + "/agents";
14014
+ var ENDPOINT_BOOKABLE_DATES = ENDPOINT$a + "/bookable-dates";
14015
+ var ENDPOINT_PRICE_DETAILS$1 = ENDPOINT$a + "/price-details";
14016
+ var ENDPOINT_BOOK$1 = ENDPOINT$a + "/book";
14017
+ var ENDPOINT_UPDATE = ENDPOINT$a + "/update";
14018
+ var ENDPOINT_AGENTS = ENDPOINT$a + "/agents";
13954
14019
  var ENDPOINT_AVAILABLE_ALLOTMENTS = function (eventId, productCode) {
13955
14020
  return (
13956
- ENDPOINT$9 + "/get-allotment-availability/" + eventId + "/" + productCode
14021
+ ENDPOINT$a + "/get-allotment-availability/" + eventId + "/" + productCode
13957
14022
  );
13958
14023
  };
13959
- var ENDPOINT_FLIGHT_POOL = ENDPOINT$9 + "/flight-pool";
13960
- var ENDPOINT_TOUR_CODES = ENDPOINT$9 + "/tourcodes";
14024
+ var ENDPOINT_FLIGHT_POOL = ENDPOINT$a + "/flight-pool";
14025
+ var ENDPOINT_TOUR_CODES = ENDPOINT$a + "/tourcodes";
13961
14026
  var ENDPOINT_CUSTOM_ENTRY_STATUS$1 = function (
13962
14027
  dossierNumber,
13963
14028
  customEntryStatusId
13964
14029
  ) {
13965
14030
  return (
13966
- ENDPOINT$9 +
14031
+ ENDPOINT$a +
13967
14032
  "/custom-entry-status/" +
13968
14033
  dossierNumber +
13969
14034
  "/" +
13970
14035
  customEntryStatusId
13971
14036
  );
13972
14037
  };
13973
- var ENDPOINT_ENTRY_STATUS = function (dossierNumber, entryStatus) {
13974
- return ENDPOINT$9 + "/entry-status/" + dossierNumber + "/" + entryStatus;
14038
+ var ENDPOINT_ENTRY_STATUS = function (
14039
+ dossierNumber,
14040
+ entryStatus,
14041
+ customEntryStatusId
14042
+ ) {
14043
+ return (
14044
+ ENDPOINT$a +
14045
+ "/entry-status/" +
14046
+ dossierNumber +
14047
+ "/" +
14048
+ entryStatus +
14049
+ (customEntryStatusId !== undefined
14050
+ ? "?customEntryStatusId=" + customEntryStatusId
14051
+ : "")
14052
+ );
13975
14053
  };
13976
- var ENDPOINT_ELASTIC = ENDPOINT$9 + "/elastic";
13977
- var ENDPOINT_FLIGHT_LINES = ENDPOINT$9 + "/flightlines";
14054
+ var ENDPOINT_ELASTIC = ENDPOINT$a + "/elastic";
14055
+ var ENDPOINT_FLIGHT_LINES = ENDPOINT$a + "/flightlines";
14056
+ var ENDPOINT_REPRICE_AND_ISSUE_TICKET =
14057
+ ENDPOINT$a + "/reprice-and-issue-ticket";
13978
14058
  var availableFlights = function (config, request, signal) {
13979
14059
  var url = "" + config.host + ENDPOINT_AVAILABLE_FLIGHTS;
13980
14060
  var apiKey = config.apiKey;
@@ -14112,12 +14192,27 @@ var setCustomEntryStatus = function (
14112
14192
  var apiKey = config.apiKey;
14113
14193
  return patch(url, apiKey, null, config.token, signal, true);
14114
14194
  };
14115
- var setEntryStatus = function (config, dossierNumber, entryStatus, signal) {
14195
+ var setEntryStatus = function (
14196
+ config,
14197
+ dossierNumber,
14198
+ entryStatus,
14199
+ customEntryStatusId,
14200
+ signal
14201
+ ) {
14116
14202
  var url =
14117
- "" + config.host + ENDPOINT_ENTRY_STATUS(dossierNumber, entryStatus);
14203
+ "" +
14204
+ config.host +
14205
+ ENDPOINT_ENTRY_STATUS(dossierNumber, entryStatus, customEntryStatusId);
14118
14206
  var apiKey = config.apiKey;
14119
14207
  return patch(url, apiKey, null, config.token, signal, true);
14120
14208
  };
14209
+ // PRICING
14210
+ var repriceAndIssueTicket = function (config, request, signal) {
14211
+ var url = "" + config.host + ENDPOINT_REPRICE_AND_ISSUE_TICKET;
14212
+ var apiKey = config.apiKey;
14213
+ var body = JSON.stringify(request);
14214
+ return post(url, apiKey, body, config.token, signal, true);
14215
+ };
14121
14216
  var flightLines = function (config, request, signal) {
14122
14217
  var url = "" + config.host + ENDPOINT_FLIGHT_LINES;
14123
14218
  var apiKey = config.apiKey;
@@ -14125,12 +14220,12 @@ var flightLines = function (config, request, signal) {
14125
14220
  return post(url, apiKey, body, config.token, signal, true);
14126
14221
  };
14127
14222
 
14128
- var ENDPOINT$8 = "/api/member";
14129
- var ENDPOINT_LOGIN = ENDPOINT$8 + "/login";
14130
- var ENDPOINT_LOGOUT = ENDPOINT$8 + "/logout";
14131
- var ENDPOINT_CONFIRM = ENDPOINT$8 + "/confirm";
14132
- var ENDPOINT_FORGOT_PASSWORD = ENDPOINT$8 + "/forgot-password";
14133
- var ENDPOINT_RESET_PASSWORD = ENDPOINT$8 + "/reset-password";
14223
+ var ENDPOINT$9 = "/api/member";
14224
+ var ENDPOINT_LOGIN = ENDPOINT$9 + "/login";
14225
+ var ENDPOINT_LOGOUT = ENDPOINT$9 + "/logout";
14226
+ var ENDPOINT_CONFIRM = ENDPOINT$9 + "/confirm";
14227
+ var ENDPOINT_FORGOT_PASSWORD = ENDPOINT$9 + "/forgot-password";
14228
+ var ENDPOINT_RESET_PASSWORD = ENDPOINT$9 + "/reset-password";
14134
14229
  var login = function (config, request, signal) {
14135
14230
  var url = "" + config.host + ENDPOINT_LOGIN;
14136
14231
  var apiKey = config.apiKey;
@@ -14162,8 +14257,8 @@ var resetPassword = function (config, request, signal) {
14162
14257
  return post$1(url, apiKey, body, config.token, signal);
14163
14258
  };
14164
14259
 
14165
- var ENDPOINT$7 = "/api/mollie";
14166
- var ENDPOINT_CREATE_PAYMENTS = ENDPOINT$7 + "/create-payment";
14260
+ var ENDPOINT$8 = "/api/mollie";
14261
+ var ENDPOINT_CREATE_PAYMENTS = ENDPOINT$8 + "/create-payment";
14167
14262
  /**
14168
14263
  * api/mollie/create-payment
14169
14264
  * @param request
@@ -14176,13 +14271,14 @@ var getMolliePayment = function (config, request, signal) {
14176
14271
  return post(url, apiKey, body, config.token, signal);
14177
14272
  };
14178
14273
 
14179
- var ENDPOINT$6 = "/api/web/search";
14180
- var ENDPOINT_COUNTRIES = ENDPOINT$6 + "/countries";
14181
- var ENDPOINT_REGIONS = ENDPOINT$6 + "/regions";
14182
- var ENDPOINT_OORDS = ENDPOINT$6 + "/oords";
14183
- var ENDPOINT_LOCATIONS$1 = ENDPOINT$6 + "/locations";
14274
+ var ENDPOINT$7 = "/api/web/search";
14275
+ var ENDPOINT_COUNTRIES = ENDPOINT$7 + "/countries";
14276
+ var ENDPOINT_REGIONS = ENDPOINT$7 + "/regions";
14277
+ var ENDPOINT_OORDS = ENDPOINT$7 + "/oords";
14278
+ var ENDPOINT_LOCATIONS$1 = ENDPOINT$7 + "/locations";
14279
+ var ENDPOINT_GEOGRAPHICAL_REGIONS = ENDPOINT$7 + "/geographicalregions";
14184
14280
  var ENDPOINT_PORTAL = function (portalId) {
14185
- return ENDPOINT$6 + "/portal/" + portalId;
14281
+ return ENDPOINT$7 + "/portal/" + portalId;
14186
14282
  };
14187
14283
  var ENDPOINT_AIRPORT = "/api/web/entity/airport";
14188
14284
  /**
@@ -14237,6 +14333,18 @@ var searchLocations = function (config, searchTerm, signal) {
14237
14333
  var url = "" + config.host + ENDPOINT_LOCATIONS$1 + "?" + filter;
14238
14334
  return get(url, apiKey, config.token, signal, true);
14239
14335
  };
14336
+ /**
14337
+ * api/web/search/geographicalregions
14338
+ * Gets all available Geographical Regions
14339
+ * @param config
14340
+ * @param signal
14341
+ * @returns OK if succeeded.
14342
+ */
14343
+ var getAvailableGeographicalRegions = function (config, signal) {
14344
+ var url = "" + config.host + ENDPOINT_GEOGRAPHICAL_REGIONS;
14345
+ var apiKey = config.apiKey;
14346
+ return get(url, apiKey, config.token, signal, true);
14347
+ };
14240
14348
  var getPortal = function (config, portalId, signal) {
14241
14349
  var url = "" + config.host + ENDPOINT_PORTAL(portalId);
14242
14350
  var apiKey = config.apiKey;
@@ -14405,13 +14513,13 @@ var isValidDate = function (d) {
14405
14513
  return d instanceof Date && !isNaN(d.getTime());
14406
14514
  };
14407
14515
 
14408
- var ENDPOINT$5 = "/api/web/agent";
14409
- var ENDPOINT_GET_PRINT_ACTIONS = ENDPOINT$5 + "/print-action";
14410
- var ENDPOINT_PRINT = ENDPOINT$5 + "/print-action";
14411
- var ENDPOINT_CUSTOM_ENTRY_STATUS = ENDPOINT$5 + "/custom-entry-status";
14412
- var ENDPOINT_ENUM_ENTRY_STATUS = ENDPOINT$5 + "/enum/entry-status";
14516
+ var ENDPOINT$6 = "/api/web/agent";
14517
+ var ENDPOINT_GET_PRINT_ACTIONS = ENDPOINT$6 + "/print-action";
14518
+ var ENDPOINT_PRINT = ENDPOINT$6 + "/print-action";
14519
+ var ENDPOINT_CUSTOM_ENTRY_STATUS = ENDPOINT$6 + "/custom-entry-status";
14520
+ var ENDPOINT_ENUM_ENTRY_STATUS = ENDPOINT$6 + "/enum/entry-status";
14413
14521
  var ENDPOINT_CHANGE_ENTRY_AGENT_SURCHARGE =
14414
- ENDPOINT$5 + "/entry/change-agent-surcharge";
14522
+ ENDPOINT$6 + "/entry/change-agent-surcharge";
14415
14523
  /**
14416
14524
  * api/web/agent/print-action/{print-action-group}
14417
14525
  * @param config
@@ -14445,7 +14553,7 @@ var getEntryList = function (config, filterItem, gridColumns, signal) {
14445
14553
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14446
14554
  })
14447
14555
  .join("&");
14448
- var url = "" + config.host + ENDPOINT$5 + "/entry/list?" + queryString;
14556
+ var url = "" + config.host + ENDPOINT$6 + "/entry/list?" + queryString;
14449
14557
  var apiKey = config.apiKey;
14450
14558
  return get(url, apiKey, config.token, signal, true);
14451
14559
  };
@@ -14456,7 +14564,7 @@ var getEntryListv2 = function (config, filterItem, gridColumns, signal) {
14456
14564
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14457
14565
  })
14458
14566
  .join("&");
14459
- var url = "" + config.host + ENDPOINT$5 + "/v2/entry/list?" + queryString;
14567
+ var url = "" + config.host + ENDPOINT$6 + "/v2/entry/list?" + queryString;
14460
14568
  var apiKey = config.apiKey;
14461
14569
  return get(url, apiKey, config.token, signal, true);
14462
14570
  };
@@ -14467,12 +14575,12 @@ var getEntryTotals = function (config, filterItem, gridColumns, signal) {
14467
14575
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14468
14576
  })
14469
14577
  .join("&");
14470
- var url = "" + config.host + ENDPOINT$5 + "/entry/total?" + queryString;
14578
+ var url = "" + config.host + ENDPOINT$6 + "/entry/total?" + queryString;
14471
14579
  var apiKey = config.apiKey;
14472
14580
  return get(url, apiKey, config.token, signal, true);
14473
14581
  };
14474
14582
  var getEntryDetailv2 = function (config, entryId, signal) {
14475
- var url = "" + config.host + ENDPOINT$5 + "/v2/entry/detail/" + entryId;
14583
+ var url = "" + config.host + ENDPOINT$6 + "/v2/entry/detail/" + entryId;
14476
14584
  var apiKey = config.apiKey;
14477
14585
  return get(url, apiKey, config.token, signal, true);
14478
14586
  };
@@ -14483,7 +14591,7 @@ var getInvoiceList = function (config, filterItem, gridColumns, signal) {
14483
14591
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14484
14592
  })
14485
14593
  .join("&");
14486
- var url = "" + config.host + ENDPOINT$5 + "/invoice/list?" + queryString;
14594
+ var url = "" + config.host + ENDPOINT$6 + "/invoice/list?" + queryString;
14487
14595
  var apiKey = config.apiKey;
14488
14596
  return get(url, apiKey, config.token, signal, true);
14489
14597
  };
@@ -14510,28 +14618,48 @@ var getAllotmentList = function (config, filterItem, gridColumns, signal) {
14510
14618
  return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
14511
14619
  })
14512
14620
  .join("&");
14513
- var url = "" + config.host + ENDPOINT$5 + "/allotment/list?" + queryString;
14621
+ var url = "" + config.host + ENDPOINT$6 + "/allotment/list?" + queryString;
14514
14622
  var apiKey = config.apiKey;
14515
14623
  return get(url, apiKey, config.token, signal, true);
14516
14624
  };
14517
14625
  var getAllotment = function (config, allotmentId, signal) {
14518
- var url = "" + config.host + ENDPOINT$5 + "/allotment/" + allotmentId;
14626
+ var url = "" + config.host + ENDPOINT$6 + "/allotment/" + allotmentId;
14519
14627
  var apiKey = config.apiKey;
14520
14628
  return get(url, apiKey, config.token, signal, true);
14521
14629
  };
14522
14630
 
14523
- var ENDPOINT$4 = "/api/web";
14524
- var ENDPOINT_CREATE_CRM_CONTACT = ENDPOINT$4 + "/crmcontact";
14525
- var ENDPOINT_CONTACT_FORM$1 = ENDPOINT$4 + "/contactform";
14526
- var ENDPOINT_CREATE_AFFILIATES = ENDPOINT$4 + "/affiliates";
14527
- var ENDPOINT_TRANSLATION_DICTIONARY = ENDPOINT$4 + "/translation-dictionary";
14528
- var ENDPOINT_BOOKING_ACCOMMODATION = ENDPOINT$4 + "/booking-accommodation";
14529
- var ENDPOINT_LOCATIONS = ENDPOINT$4 + "/entity/locations";
14631
+ var ENDPOINT$5 = "/api/web";
14632
+ var ENDPOINT_MAIL = ENDPOINT$5 + "/mail";
14633
+ var ENDPOINT_CREATE_CRM_CONTACT = ENDPOINT$5 + "/crmcontact";
14634
+ var ENDPOINT_CONTACT_FORM$1 = ENDPOINT$5 + "/contactform";
14635
+ var ENDPOINT_TRAVEL_AGENTS = ENDPOINT$5 + "/travelagents";
14636
+ var ENDPOINT_CREATE_AFFILIATES = ENDPOINT$5 + "/affiliates";
14637
+ var ENDPOINT_TRANSLATION_DICTIONARY = ENDPOINT$5 + "/translation-dictionary";
14638
+ var ENDPOINT_BOOKING_ACCOMMODATION = ENDPOINT$5 + "/booking-accommodation";
14639
+ var ENDPOINT_OPPORTUNITY = ENDPOINT$5 + "/opportunity";
14640
+ var ENDPOINT_CALCULATE_DEPOSIT = function (entryId) {
14641
+ return ENDPOINT$5 + "/entry/" + entryId + "/calculate-deposit";
14642
+ };
14643
+ var ENDPOINT_LOCATIONS = ENDPOINT$5 + "/entity/locations";
14530
14644
  var ENDPOINT_WEBSITE_CONFIGURATION = function (portalId) {
14531
- return ENDPOINT$4 + "/website/" + portalId + "/configuration";
14645
+ return ENDPOINT$5 + "/website/" + portalId + "/configuration";
14532
14646
  };
14533
14647
  var ENDPOINT_WEBSITE_STYLESHEET = function (styleSheetId) {
14534
- return ENDPOINT$4 + "/style-sheet/" + styleSheetId;
14648
+ return ENDPOINT$5 + "/style-sheet/" + styleSheetId;
14649
+ };
14650
+ /**
14651
+ * api/web/mail
14652
+ * Adds the sender as a person and sends a mail.
14653
+ * @param config
14654
+ * @param request
14655
+ * @param signal
14656
+ * @returns OK if succeeded.
14657
+ */
14658
+ var sendMail = function (config, request, signal) {
14659
+ var url = "" + config.host + ENDPOINT_MAIL;
14660
+ var apiKey = config.apiKey;
14661
+ var body = JSON.stringify(request);
14662
+ return post(url, apiKey, body, config.token, signal);
14535
14663
  };
14536
14664
  /**
14537
14665
  * api/web/crmcontact
@@ -14555,12 +14683,27 @@ var createCrmContact = function (config, request, signal) {
14555
14683
  * @param signal
14556
14684
  * @returns OK if succeeded.
14557
14685
  */
14558
- var ContactForm = function (config, request, signal) {
14686
+ var sendContactForm = function (config, request, signal) {
14559
14687
  var url = "" + config.host + ENDPOINT_CONTACT_FORM$1;
14560
14688
  var apiKey = config.apiKey;
14561
14689
  var body = JSON.stringify(request);
14562
14690
  return post(url, apiKey, body, config.token, signal, true);
14563
14691
  };
14692
+ /**
14693
+ * api/web/travelagents
14694
+ * Searches travel agents (addresses of type Agent). Optionally pass a raw OData
14695
+ * query string (without leading '?'), e.g. "$top=20&$filter=contains(name,'foo')".
14696
+ * @param config
14697
+ * @param odataQuery
14698
+ * @param signal
14699
+ * @returns OK if succeeded.
14700
+ */
14701
+ var getTravelAgents = function (config, odataQuery, signal) {
14702
+ var query = odataQuery ? "?" + odataQuery : "";
14703
+ var url = "" + config.host + ENDPOINT_TRAVEL_AGENTS + query;
14704
+ var apiKey = config.apiKey;
14705
+ return get(url, apiKey, config.token, signal, true);
14706
+ };
14564
14707
  /**
14565
14708
  * api/web/affiliates
14566
14709
  * Gets all Affiliates
@@ -14585,6 +14728,33 @@ var generateBookingAccommodations = function (config, request, signal) {
14585
14728
  var body = JSON.stringify(request);
14586
14729
  return post(url, apiKey, body, config.token, signal);
14587
14730
  };
14731
+ /**
14732
+ * api/web/opportunity
14733
+ * Creates a CRM opportunity from a web contact.
14734
+ * @param config
14735
+ * @param request
14736
+ * @param signal
14737
+ * @returns OK if succeeded.
14738
+ */
14739
+ var createOpportunity = function (config, request, signal) {
14740
+ var url = "" + config.host + ENDPOINT_OPPORTUNITY;
14741
+ var apiKey = config.apiKey;
14742
+ var body = JSON.stringify(request);
14743
+ return post(url, apiKey, body, config.token, signal);
14744
+ };
14745
+ /**
14746
+ * api/web/entry/{entryId}/calculate-deposit
14747
+ * Calculates the deposit amount for an entry.
14748
+ * @param config
14749
+ * @param entryId
14750
+ * @param signal
14751
+ * @returns The deposit amount.
14752
+ */
14753
+ var calculateDeposit = function (config, entryId, signal) {
14754
+ var url = "" + config.host + ENDPOINT_CALCULATE_DEPOSIT(entryId);
14755
+ var apiKey = config.apiKey;
14756
+ return get(url, apiKey, config.token, signal, true);
14757
+ };
14588
14758
  var getLocations = function (config, request, signal) {
14589
14759
  var url = "" + config.host + ENDPOINT_LOCATIONS;
14590
14760
  var apiKey = config.apiKey;
@@ -14602,9 +14772,9 @@ var getStyleSheet = function (config, id, signal) {
14602
14772
  return get(url, apiKey, config.token, signal, true);
14603
14773
  };
14604
14774
 
14605
- var ENDPOINT$3 = "/api/web/contact";
14606
- var ENDPOINT_CONTACT_FORM = ENDPOINT$3 + "/contact-form";
14607
- var ENDPOINT_CONTACT_HAS_TAG = ENDPOINT$3 + "/has-tag";
14775
+ var ENDPOINT$4 = "/api/web/contact";
14776
+ var ENDPOINT_CONTACT_FORM = ENDPOINT$4 + "/contact-form";
14777
+ var ENDPOINT_CONTACT_HAS_TAG = ENDPOINT$4 + "/has-tag";
14608
14778
  /**
14609
14779
  * api/web/contact/contact-form
14610
14780
  * Processes a contact form.
@@ -14626,6 +14796,118 @@ var contactHasTag = function (config, request, signal) {
14626
14796
  return post$1(url, apiKey, body, config.token, signal);
14627
14797
  };
14628
14798
 
14799
+ var ENDPOINT$3 = "/api/web/content";
14800
+ var ENDPOINT_LIVE = ENDPOINT$3 + "/live";
14801
+ var ENDPOINT_DRAFT = ENDPOINT$3 + "/draft";
14802
+ /**
14803
+ * api/web/content/live
14804
+ * Gets all Live content
14805
+ * @param config
14806
+ * @param signal
14807
+ * @returns OK if succeeded.
14808
+ */
14809
+ var getContentLive = function (config, signal) {
14810
+ var url = "" + config.host + ENDPOINT_LIVE;
14811
+ var apiKey = config.apiKey;
14812
+ return get(url, apiKey, config.token, signal, true);
14813
+ };
14814
+ /**
14815
+ * api/web/content/draft
14816
+ * Gets all Draft (Internal) content
14817
+ * @param config
14818
+ * @param signal
14819
+ * @returns OK if succeeded.
14820
+ */
14821
+ var getContentDraft = function (config, signal) {
14822
+ var url = "" + config.host + ENDPOINT_DRAFT;
14823
+ var apiKey = config.apiKey;
14824
+ return get(url, apiKey, config.token, signal, true);
14825
+ };
14826
+ /**
14827
+ * api/web/content/live/by-property
14828
+ * Gets Live content matching a property value (or values).
14829
+ * @param config
14830
+ * @param request
14831
+ * @param signal
14832
+ * @returns OK if succeeded.
14833
+ */
14834
+ var getContentLiveByProperty = function (config, request, signal) {
14835
+ var url = "" + config.host + ENDPOINT_LIVE + "/by-property";
14836
+ var apiKey = config.apiKey;
14837
+ var body = JSON.stringify(request);
14838
+ return post(url, apiKey, body, config.token, signal, true);
14839
+ };
14840
+ /**
14841
+ * api/web/content/draft/by-property
14842
+ * Gets Draft (Internal) content matching a property value (or values).
14843
+ * @param config
14844
+ * @param request
14845
+ * @param signal
14846
+ * @returns OK if succeeded.
14847
+ */
14848
+ var getContentDraftByProperty = function (config, request, signal) {
14849
+ var url = "" + config.host + ENDPOINT_DRAFT + "/by-property";
14850
+ var apiKey = config.apiKey;
14851
+ var body = JSON.stringify(request);
14852
+ return post(url, apiKey, body, config.token, signal, true);
14853
+ };
14854
+ /**
14855
+ * api/web/content/live/by-template
14856
+ * Gets Live content of a given template.
14857
+ * @param config
14858
+ * @param request
14859
+ * @param signal
14860
+ * @returns OK if succeeded.
14861
+ */
14862
+ var getContentLiveByTemplate = function (config, request, signal) {
14863
+ var url = "" + config.host + ENDPOINT_LIVE + "/by-template";
14864
+ var apiKey = config.apiKey;
14865
+ var body = JSON.stringify(request);
14866
+ return post(url, apiKey, body, config.token, signal, true);
14867
+ };
14868
+ /**
14869
+ * api/web/content/draft/by-template
14870
+ * Gets Draft (Internal) content of a given template.
14871
+ * @param config
14872
+ * @param request
14873
+ * @param signal
14874
+ * @returns OK if succeeded.
14875
+ */
14876
+ var getContentDraftByTemplate = function (config, request, signal) {
14877
+ var url = "" + config.host + ENDPOINT_DRAFT + "/by-template";
14878
+ var apiKey = config.apiKey;
14879
+ var body = JSON.stringify(request);
14880
+ return post(url, apiKey, body, config.token, signal, true);
14881
+ };
14882
+ /**
14883
+ * api/web/content/live/children
14884
+ * Gets the Live children of a parent item.
14885
+ * @param config
14886
+ * @param request
14887
+ * @param signal
14888
+ * @returns OK if succeeded.
14889
+ */
14890
+ var getContentLiveChildren = function (config, request, signal) {
14891
+ var url = "" + config.host + ENDPOINT_LIVE + "/children";
14892
+ var apiKey = config.apiKey;
14893
+ var body = JSON.stringify(request);
14894
+ return post(url, apiKey, body, config.token, signal, true);
14895
+ };
14896
+ /**
14897
+ * api/web/content/draft/children
14898
+ * Gets the Draft (Internal) children of a parent item.
14899
+ * @param config
14900
+ * @param request
14901
+ * @param signal
14902
+ * @returns OK if succeeded.
14903
+ */
14904
+ var getContentDraftChildren = function (config, request, signal) {
14905
+ var url = "" + config.host + ENDPOINT_DRAFT + "/children";
14906
+ var apiKey = config.apiKey;
14907
+ var body = JSON.stringify(request);
14908
+ return post(url, apiKey, body, config.token, signal, true);
14909
+ };
14910
+
14629
14911
  var ENDPOINT$2 = "/api/web/file";
14630
14912
  var ENDPOINT_FEED = ENDPOINT$2 + "/feed";
14631
14913
  /**
@@ -14664,6 +14946,7 @@ var ENDPOINT_FLIGHTS = ENDPOINT$1 + "/flights";
14664
14946
  var ENDPOINT_PRICE_DETAILS = ENDPOINT$1 + "/price-details";
14665
14947
  var ENDPOINT_BOOK = ENDPOINT$1 + "/book";
14666
14948
  var ENDPOINT_ITINERARY = ENDPOINT$1 + "/itinerary";
14949
+ var ENDPOINT_TRAJECT = ENDPOINT$1 + "/traject";
14667
14950
  var ENDPOINT_ENTRY = function (magicLinkCode) {
14668
14951
  return ENDPOINT$1 + "/entry/" + magicLinkCode;
14669
14952
  };
@@ -14695,6 +14978,12 @@ var getEntry = function (config, magicLinkCode, signal) {
14695
14978
  var url = "" + config.host + ENDPOINT_ENTRY(magicLinkCode);
14696
14979
  return get(url, apiKey, config.token, signal, true);
14697
14980
  };
14981
+ var getTrajectEntry = function (config, request, signal) {
14982
+ var url = "" + config.host + ENDPOINT_TRAJECT;
14983
+ var apiKey = config.apiKey;
14984
+ var body = JSON.stringify(request);
14985
+ return post(url, apiKey, body, config.token, signal, true);
14986
+ };
14698
14987
  var getPriceDetails = function (config, request, signal) {
14699
14988
  var url = "" + config.host + ENDPOINT_PRICE_DETAILS;
14700
14989
  var apiKey = config.apiKey;
@@ -14752,7 +15041,6 @@ var submitForm = function (config, id, request, signal) {
14752
15041
  };
14753
15042
 
14754
15043
  exports.AllotmentType = AllotmentType;
14755
- exports.ContactForm = ContactForm;
14756
15044
  exports.DataType = DataType;
14757
15045
  exports.DossierType = DossierType;
14758
15046
  exports.EntryLineFlag = EntryLineFlag;
@@ -14770,6 +15058,7 @@ exports.RoomType = RoomType;
14770
15058
  exports.SaleType = SaleType;
14771
15059
  exports.ServiceTokenError = ServiceTokenError;
14772
15060
  exports.ServiceType = ServiceType;
15061
+ exports.TrajectNodeType = TrajectNodeType;
14773
15062
  exports.VendorType = VendorType;
14774
15063
  exports.agents = agents;
14775
15064
  exports.alternateFlights = alternateFlights;
@@ -14779,12 +15068,14 @@ exports.availableFlights = availableFlights;
14779
15068
  exports.book = book;
14780
15069
  exports.bookPackagingEntry = bookPackagingEntry;
14781
15070
  exports.bookableDates = bookableDates;
15071
+ exports.calculateDeposit = calculateDeposit;
14782
15072
  exports.changeEntryAgentSurcharge = changeEntryAgentSurcharge;
14783
15073
  exports.clearServiceTokenCache = clearServiceTokenCache;
14784
15074
  exports.confirm = confirm;
14785
15075
  exports.contactForm = contactForm;
14786
15076
  exports.contactHasTag = contactHasTag;
14787
15077
  exports.createCrmContact = createCrmContact;
15078
+ exports.createOpportunity = createOpportunity;
14788
15079
  exports.createParams = createParams;
14789
15080
  exports.details = details;
14790
15081
  exports.detailsWL = detailsWL;
@@ -14798,6 +15089,15 @@ exports.getAirports = getAirports;
14798
15089
  exports.getAllotment = getAllotment;
14799
15090
  exports.getAllotmentAvailability = getAllotmentAvailability;
14800
15091
  exports.getAllotmentList = getAllotmentList;
15092
+ exports.getAvailableGeographicalRegions = getAvailableGeographicalRegions;
15093
+ exports.getContentDraft = getContentDraft;
15094
+ exports.getContentDraftByProperty = getContentDraftByProperty;
15095
+ exports.getContentDraftByTemplate = getContentDraftByTemplate;
15096
+ exports.getContentDraftChildren = getContentDraftChildren;
15097
+ exports.getContentLive = getContentLive;
15098
+ exports.getContentLiveByProperty = getContentLiveByProperty;
15099
+ exports.getContentLiveByTemplate = getContentLiveByTemplate;
15100
+ exports.getContentLiveChildren = getContentLiveChildren;
14801
15101
  exports.getCountries = getCountries;
14802
15102
  exports.getCustomEntryStatus = getCustomEntryStatus;
14803
15103
  exports.getEntry = getEntry;
@@ -14815,7 +15115,9 @@ exports.getPortal = getPortal;
14815
15115
  exports.getPriceDetails = getPriceDetails;
14816
15116
  exports.getPrintActions = getPrintActions;
14817
15117
  exports.getStyleSheet = getStyleSheet;
15118
+ exports.getTrajectEntry = getTrajectEntry;
14818
15119
  exports.getTranslationDictionary = getTranslationDictionary;
15120
+ exports.getTravelAgents = getTravelAgents;
14819
15121
  exports.getWebsiteConfiguration = getWebsiteConfiguration;
14820
15122
  exports.login = login;
14821
15123
  exports.logout = logout;
@@ -14823,6 +15125,7 @@ exports.priceDetails = priceDetails;
14823
15125
  exports.prices = prices;
14824
15126
  exports.print = print;
14825
15127
  exports.readForm = readForm;
15128
+ exports.repriceAndIssueTicket = repriceAndIssueTicket;
14826
15129
  exports.resetPassword = resetPassword;
14827
15130
  exports.search = search;
14828
15131
  exports.searchCountries = searchCountries;
@@ -14835,6 +15138,8 @@ exports.searchPackagingExcursions = searchPackagingExcursions;
14835
15138
  exports.searchPackagingFlights = searchPackagingFlights;
14836
15139
  exports.searchRegions = searchRegions;
14837
15140
  exports.searchWithErrorMapping = searchWithErrorMapping;
15141
+ exports.sendContactForm = sendContactForm;
15142
+ exports.sendMail = sendMail;
14838
15143
  exports.setCustomEntryStatus = setCustomEntryStatus;
14839
15144
  exports.setEntryStatus = setEntryStatus;
14840
15145
  exports.startTransaction = startTransaction;
@@ -18044,6 +18349,9 @@ function useViewTransitionState(to, opts) {
18044
18349
  }
18045
18350
 
18046
18351
  const CHILD_MAX_AGE = 17;
18352
+ // Maximum age (inclusive) at which a child still counts as a baby. Overridable
18353
+ // through settings.maxBabyAge (see TIDE-3269).
18354
+ const BABY_MAX_AGE = 1;
18047
18355
  const initialState$6 = {
18048
18356
  formValues: undefined
18049
18357
  };
@@ -18074,20 +18382,16 @@ const makeSelectFormRooms = (maxChildAge = CHILD_MAX_AGE) => createSelector(sele
18074
18382
  children: []
18075
18383
  };
18076
18384
  x.pax.forEach((p) => {
18077
- if (p.age && p.age > maxChildAge) {
18385
+ // typeof, not truthiness: a baby booked as age 0 has to be classified instead of
18386
+ // being dropped from the form altogether (TIDE-3269).
18387
+ const age = typeof p.age === 'number' ? p.age : p.dateOfBirth ? differenceInYears(new Date(), new Date(p.dateOfBirth)) : undefined;
18388
+ if (age === undefined)
18389
+ return;
18390
+ if (age > maxChildAge) {
18078
18391
  formRoom.adults.push({ id: p.id, age: 30 });
18079
18392
  }
18080
- else if (p.age && p.age <= maxChildAge) {
18081
- formRoom.children.push({ id: p.id, age: p.age });
18082
- }
18083
- else if (p.dateOfBirth) {
18084
- const age = differenceInYears(new Date(), new Date(p.dateOfBirth));
18085
- if (age > maxChildAge) {
18086
- formRoom.adults.push({ id: p.id, age: 30 });
18087
- }
18088
- else {
18089
- formRoom.children.push({ id: p.id, age: age });
18090
- }
18393
+ else {
18394
+ formRoom.children.push({ id: p.id, age });
18091
18395
  }
18092
18396
  });
18093
18397
  formRooms.push(formRoom);
@@ -18332,22 +18636,22 @@ const selectRequestRooms = (state) => state.booking.package?.options.find((x) =>
18332
18636
  const selectOfficeId = (state) => state.booking.officeId;
18333
18637
  const selectLanguageCode = (state) => state.booking.languageCode;
18334
18638
  const selectCurrencyCode = (state) => state.booking.package?.currencyCode ?? 'EUR';
18335
- const selectDefaultStaticTranslations = (state) => getTranslations(state.booking.languageCode);
18336
18639
  const selectLanguage = (state) => state.booking.languageCode;
18337
18640
  const selectAllDynamicTranslations = (state) => state.booking.translations;
18338
18641
  const selectDynamicTranslations = createSelector([selectAllDynamicTranslations, selectLanguage], (allDynamicTranslations, language) => {
18339
18642
  return allDynamicTranslations?.find((x) => x.language == language)?.value ?? {};
18340
18643
  });
18341
- const selectTranslations = createSelector([selectDefaultStaticTranslations, selectDynamicTranslations], (defaultStaticTranslations, dynamicTranslations) => {
18342
- const merged = {};
18343
- for (const key of Array.from(new Set([...Object.keys(defaultStaticTranslations), ...Object.keys(dynamicTranslations)]))) {
18344
- merged[key] = {
18345
- ...(defaultStaticTranslations[key] || {}),
18346
- ...(dynamicTranslations[key] || {})
18347
- };
18348
- }
18349
- return merged;
18350
- });
18644
+ // Host override files are hand-maintained, and a null only ever blanks a key the component
18645
+ // then reads, so treat it like a missing key (lodash merge already skips undefined).
18646
+ const withoutNulls = (value) => isPlainObject$1(value)
18647
+ ? mapValues(pickBy(value, (x) => x !== null), withoutNulls)
18648
+ : value;
18649
+ // getTranslations deep-merges the overrides over a clone of the built-in translations, so a
18650
+ // host override of a nested group (TRAVELERS_FORM.VALIDATION, TRAVELERS_FORM.COUNTRIES)
18651
+ // only replaces the keys it actually contains. Merging per section one level deep dropped
18652
+ // every other built-in key of such a group, which made those keys resolve to undefined and
18653
+ // crash format() in the consuming component.
18654
+ const selectTranslations = createSelector([selectLanguage, selectDynamicTranslations], (language, dynamicTranslations) => getTranslations(language, isEmpty$1(dynamicTranslations) ? undefined : withoutNulls(dynamicTranslations)));
18351
18655
  const selectBookingOptions = (state) => state.booking.bookingOptions;
18352
18656
  const selectBookingType = (state) => state.booking.bookingType;
18353
18657
  const selectTagIds = (state) => state.booking.tagIds;
@@ -22567,7 +22871,7 @@ function getAge(birthDateText, startDateText) {
22567
22871
  }
22568
22872
  return age;
22569
22873
  }
22570
- const validateForm$1 = (values, agentRequired, bookingType, translations, formFields, mainBookerFormFields, maxChildAge = CHILD_MAX_AGE) => {
22874
+ const validateForm$1 = (values, agentRequired, bookingType, translations, formFields, mainBookerFormFields, maxChildAge = CHILD_MAX_AGE, maxBabyAge = BABY_MAX_AGE) => {
22571
22875
  const errors = {};
22572
22876
  const isFormFieldPresent = (type) => {
22573
22877
  return formFields?.some((f) => f.type === type) ?? true;
@@ -22590,6 +22894,14 @@ const validateForm$1 = (values, agentRequired, bookingType, translations, formFi
22590
22894
  ? format$1(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_CHILD, [room, pax])
22591
22895
  : format$1(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_IS_NO_CHILD, [pax]);
22592
22896
  };
22897
+ const formatTravelerIsNoBaby = (room, pax) => {
22898
+ // The message states the boundary the traveler has to stay under, so we pass
22899
+ // the first age that is too old rather than the inclusive maxBabyAge.
22900
+ const tooOldAge = maxBabyAge + 1;
22901
+ return values.rooms.length > 1
22902
+ ? format$1(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_IS_NO_BABY, [room, pax, tooOldAge])
22903
+ : format$1(translations.TRAVELERS_FORM.VALIDATION.SINGLE_ROOM_TRAVELER_X_IS_NO_BABY, [pax, tooOldAge]);
22904
+ };
22593
22905
  const formatTravelerFieldInvalidCharacters = (room, pax, field) => {
22594
22906
  return values.rooms.length > 1
22595
22907
  ? format$1(translations.TRAVELERS_FORM.VALIDATION.TRAVELER_X_FIELD_INVALID_CHARACTERS, [room, pax, field])
@@ -22634,10 +22946,10 @@ const validateForm$1 = (values, agentRequired, bookingType, translations, formFi
22634
22946
  }
22635
22947
  if (isFormFieldPresent('firstName')) {
22636
22948
  if (isEmpty$1(child.firstName)) {
22637
- set(errors, `children[${index}].firstName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22949
+ set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22638
22950
  }
22639
22951
  else if (hasInvalidNameCharacters(child.firstName)) {
22640
- set(errors, `children[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22952
+ set(errors, `rooms[${rIndex}].children[${index}].firstName`, formatTravelerFieldInvalidCharacters(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.FIRST_NAME));
22641
22953
  }
22642
22954
  }
22643
22955
  if (isFormFieldPresent('lastName')) {
@@ -22652,8 +22964,16 @@ const validateForm$1 = (values, agentRequired, bookingType, translations, formFi
22652
22964
  if (isEmpty$1(child.birthDate)) {
22653
22965
  set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerField(rIndex + 1, r.adults.length + index + 1, translations.TRAVELERS_FORM.BIRTHDATE));
22654
22966
  }
22967
+ else if (child.isBaby && values.startDate) {
22968
+ // A baby only has to be under the maxBabyAge on departure, so we check the startDate here instead of the endDate (TIDE-3269)
22969
+ const age = getAge(child.birthDate, values.startDate);
22970
+ if (age > maxBabyAge) {
22971
+ set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerIsNoBaby(rIndex + 1, r.adults.length + index + 1));
22972
+ }
22973
+ }
22655
22974
  else if (values.endDate) {
22656
- // You need to be under the maxChildAge until the end of the trip, so we check the endDate here instead of the startDate
22975
+ // You need to be under the maxChildAge until the end of the trip, so we check the endDate here instead of the startDate.
22976
+ // Babies land here too when there is no startDate to check them against, so they keep at least the child age check.
22657
22977
  const age = getAge(child.birthDate, values.endDate);
22658
22978
  if (age > maxChildAge) {
22659
22979
  set(errors, `rooms[${rIndex}].children[${index}].birthDate`, formatTravelerIsNoChild(rIndex + 1, r.adults.length + index + 1));
@@ -22859,7 +23179,14 @@ const TypeAheadInput = ({ name, value, placeholder, options, onChange, onSelect,
22859
23179
  })))));
22860
23180
  };
22861
23181
 
22862
- function createTraveler(traveler, followNumber, personTranslation, isCompact) {
23182
+ // A traveler is a baby when the age they were booked with is at or below the baby
23183
+ // boundary. Babies get their own label and birth date validation (TIDE-3269). Only
23184
+ // meaningful for the regular form: the compact form asks for an age instead of a birth
23185
+ // date, so it has nothing to validate and its own age input already states the age.
23186
+ function isBabyAge(age, maxBabyAge = BABY_MAX_AGE) {
23187
+ return typeof age === 'number' && age <= maxBabyAge;
23188
+ }
23189
+ function createTraveler(traveler, followNumber, personTranslation, isCompact, maxBabyAge) {
22863
23190
  if (isCompact) {
22864
23191
  return {
22865
23192
  id: traveler.id,
@@ -22867,7 +23194,13 @@ function createTraveler(traveler, followNumber, personTranslation, isCompact) {
22867
23194
  lastName: `${followNumber.number++}`,
22868
23195
  birthDate: '',
22869
23196
  gender: '',
22870
- age: traveler.age || 30
23197
+ // Keep a booked age of 0 instead of submitting and pricing the traveler as a 30 year
23198
+ // old, while still falling back for a missing or unusable age. `??` alone would let a
23199
+ // NaN (unparseable date of birth upstream) reach the age input and the booked pax.
23200
+ // See TIDE-3269.
23201
+ age: Number.isFinite(traveler.age) ? traveler.age : 30
23202
+ // No isBaby here on purpose: the age below is editable and nothing revalidates it
23203
+ // in compact mode, so a stored flag would end up contradicting the entered age.
22871
23204
  };
22872
23205
  }
22873
23206
  return {
@@ -22875,17 +23208,18 @@ function createTraveler(traveler, followNumber, personTranslation, isCompact) {
22875
23208
  firstName: '',
22876
23209
  lastName: '',
22877
23210
  birthDate: '',
22878
- gender: ''
23211
+ gender: '',
23212
+ isBaby: isBabyAge(traveler.age, maxBabyAge)
22879
23213
  };
22880
23214
  }
22881
- function createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, personTranslation, isCompact) {
23215
+ function createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, personTranslation, isCompact, maxBabyAge) {
22882
23216
  const followNumber = { number: 1 };
22883
23217
  const initialValues = {
22884
23218
  startDate,
22885
23219
  endDate,
22886
23220
  rooms: formRooms.map((room) => ({
22887
- adults: room.adults.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact)),
22888
- children: room.children.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact))
23221
+ adults: room.adults.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact, maxBabyAge)),
23222
+ children: room.children.map((traveler) => createTraveler(traveler, followNumber, personTranslation, isCompact, maxBabyAge))
22889
23223
  })),
22890
23224
  mainBookerId: -1,
22891
23225
  street: '',
@@ -22927,7 +23261,8 @@ function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry, a
22927
23261
  firstName: roomTraveler.firstName ?? '',
22928
23262
  lastName: roomTraveler.lastName ?? '',
22929
23263
  birthDate: roomTraveler.dateOfBirth ? format$2(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
22930
- gender: ''
23264
+ gender: '',
23265
+ isBaby: isBabyAge(roomTraveler.age)
22931
23266
  };
22932
23267
  })
22933
23268
  };
@@ -23151,7 +23486,7 @@ const SharedTravelersForm = ({ formik, translations, travellersSettings, countri
23151
23486
  translations.TRAVELERS_FORM.TRAVELER,
23152
23487
  " ",
23153
23488
  room.adults.length + index + 1),
23154
- React__default.createElement("p", { className: "form__region-label" }, translations.TRAVELERS_FORM.CHILD)),
23489
+ React__default.createElement("p", { className: "form__region-label" }, travelerValues.isBaby ? translations.TRAVELERS_FORM.BABY : translations.TRAVELERS_FORM.CHILD)),
23155
23490
  renderTravelerFields(travelerValues, `rooms[${roomIndex}].children[${index}]`, false, roomIndex, index)))),
23156
23491
  !useCompactForm && travelersFirstStep && (React__default.createElement("div", { className: "form__region" },
23157
23492
  React__default.createElement("button", { type: "button", className: "cta cta--select", onClick: () => handleAddTraveler(roomIndex) }, translations.TRAVELERS_FORM.ADD_TRAVELER)))))),
@@ -23227,13 +23562,17 @@ const TravelersForm = () => {
23227
23562
  const useCompactForm = !!settings.travellers.compactForm && !!settings.agentAdressId;
23228
23563
  const showAllCountries = !!settings.travellers.showAllCountries;
23229
23564
  const initialValues = useSelector(selectTravelersFormValues) ??
23230
- createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, translations.TRAVELERS_FORM.PERSON, useCompactForm);
23565
+ createInitialValuesFromRooms(formRooms, startDate, endDate, agentAdressId, translations.TRAVELERS_FORM.PERSON, useCompactForm, settings.maxBabyAge);
23231
23566
  const [showAgentSelection, setShowAgentSelection] = useState(!settings.agentAdressId && !settings.hideAgentSelection);
23232
23567
  const formik = useFormik({
23233
23568
  initialValues,
23234
23569
  validate: useCompactForm
23235
23570
  ? () => { }
23236
- : (values) => validateForm$1(values, settings.agentRequired, bookingType, translations, settings.travellers.formFields, settings.travellers.mainBookerFormFields, settings.maxChildAge),
23571
+ : (values) => validateForm$1(
23572
+ // The travel dates are captured into initialValues once and then persisted in
23573
+ // redux, so validating against the values would use the dates of whichever
23574
+ // package option was selected first. Age checks need the current ones.
23575
+ { ...values, startDate, endDate }, settings.agentRequired, bookingType, translations, settings.travellers.formFields, settings.travellers.mainBookerFormFields, settings.maxChildAge, settings.maxBabyAge),
23237
23576
  onSubmit: (values) => {
23238
23577
  dispatch(setFormValues(values));
23239
23578
  if (useCompactForm) {
@@ -27000,7 +27339,9 @@ const initialState$1 = {
27000
27339
  confirmedExcursionsByDay: {},
27001
27340
  bookPackagingEntry: false,
27002
27341
  currentStep: 0,
27003
- bookingNumber: undefined
27342
+ bookingNumber: undefined,
27343
+ trajectNodeAvailability: {},
27344
+ trajectFlightsResolved: false
27004
27345
  };
27005
27346
  const searchResultsSlice = createSlice({
27006
27347
  name: 'searchResults',
@@ -27179,10 +27520,59 @@ const searchResultsSlice = createSlice({
27179
27520
  },
27180
27521
  setBookingNumber(state, action) {
27181
27522
  state.bookingNumber = action.payload;
27523
+ },
27524
+ setTrajectNodeLoading(state, action) {
27525
+ const lineGuid = action.payload;
27526
+ state.trajectNodeAvailability[lineGuid] = {
27527
+ lineGuid,
27528
+ status: 'loading',
27529
+ results: state.trajectNodeAvailability[lineGuid]?.results ?? [],
27530
+ selectedCode: state.trajectNodeAvailability[lineGuid]?.selectedCode ?? null,
27531
+ preferredUnavailable: false
27532
+ };
27533
+ },
27534
+ setTrajectNodeAvailability(state, action) {
27535
+ const { lineGuid, results, selectedCode, preferredUnavailable } = action.payload;
27536
+ state.trajectNodeAvailability[lineGuid] = {
27537
+ lineGuid,
27538
+ status: selectedCode ? 'resolved' : 'unavailable',
27539
+ results,
27540
+ selectedCode,
27541
+ preferredUnavailable
27542
+ };
27543
+ },
27544
+ setTrajectNodeSelection(state, action) {
27545
+ const { lineGuid, code } = action.payload;
27546
+ const node = state.trajectNodeAvailability[lineGuid];
27547
+ if (!node)
27548
+ return;
27549
+ node.selectedCode = code;
27550
+ node.status = 'resolved';
27551
+ },
27552
+ updateEditableEntryLine(state, action) {
27553
+ if (!state.editablePackagingEntry)
27554
+ return;
27555
+ const index = (state.editablePackagingEntry.lines ?? []).findIndex((x) => x.guid === action.payload.guid);
27556
+ if (index === -1)
27557
+ return;
27558
+ state.editablePackagingEntry.lines[index] = action.payload;
27559
+ },
27560
+ removeEditableEntryLines(state, action) {
27561
+ if (!state.editablePackagingEntry)
27562
+ return;
27563
+ const guids = new Set(action.payload);
27564
+ state.editablePackagingEntry.lines = (state.editablePackagingEntry.lines ?? []).filter((x) => !guids.has(x.guid));
27565
+ },
27566
+ setTrajectFlightsResolved(state, action) {
27567
+ state.trajectFlightsResolved = action.payload;
27568
+ },
27569
+ resetTrajectAvailability(state) {
27570
+ state.trajectNodeAvailability = {};
27571
+ state.trajectFlightsResolved = false;
27182
27572
  }
27183
27573
  }
27184
27574
  });
27185
- const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber } = searchResultsSlice.actions;
27575
+ const { setResults, setFilteredResults, setSelectedSearchResult, setPackagingAccoResults, setFilteredPackagingAccoResults, setFilteredPackagingFlightResults, setPackagingAccoSearchDetails, setSelectedPackagingAccoResult, setPackagingFlightResults, setSelectedPackagingFlight, setSelectedFlight, setSelectedFlightDetails, setBookingPackageDetails, selectFlight, setIsLoading, setFlightsLoading, setInitialFilters, setFilters, resetFilters, setInitialFlightFilters, setFlightFilters, resetFlightFilters, setSortType, setFlightSortType, setActiveTab, setCurrentPage, resetSearchState, setFlyInIsOpen, setEditablePackagingEntry, setTransactionId, setFlyInType, setPriceDetails, setItinerary, setSelectedOutwardKey, setSelectedReturnKey, resetFlightSelection, setExcursionSearchParams, setSelectedExcursionSearchResult, confirmExcursionForDay, removeConfirmedExcursionForDay, clearConfirmedExcursionsForDay, setBookPackagingEntry, setCurrentStep, setBookingNumber, setTrajectNodeLoading, setTrajectNodeAvailability, setTrajectNodeSelection, setTrajectFlightsResolved, resetTrajectAvailability, updateEditableEntryLine, removeEditableEntryLines } = searchResultsSlice.actions;
27186
27576
  var searchResultsReducer = searchResultsSlice.reducer;
27187
27577
 
27188
27578
  const ItemPicker = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
@@ -29345,7 +29735,7 @@ const HotelCard = ({ result, translations }) => {
29345
29735
  React__default.createElement("button", { type: "button", className: `cta ${selectedPackagingAccoResultCode === result.code ? 'cta--selected' : 'cta--select'}`, onClick: () => handleChange(result.code) }, selectedPackagingAccoResultCode === result.code ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT)))));
29346
29736
  };
29347
29737
 
29348
- const getLocation = (locationName, regionName, countryName, fallback) => {
29738
+ const getLocation$1 = (locationName, regionName, countryName, fallback) => {
29349
29739
  if (locationName || regionName) {
29350
29740
  return `${locationName || regionName}${countryName ? `, ${countryName}` : ''}`;
29351
29741
  }
@@ -29357,7 +29747,7 @@ const getBaseHotelResult = (searchResult, cmsItem, languageCode, translations) =
29357
29747
  title: cmsItem?.content?.general?.title || searchResult.name,
29358
29748
  image: cmsItem?.content?.images?.thumbnailPicture?.url,
29359
29749
  description: cmsItem?.content?.descriptions?.introductionTitle || '',
29360
- location: getLocation(searchResult.locationName, searchResult.regionName, searchResult.countryName, cmsItem?.parentItem?.name),
29750
+ location: getLocation$1(searchResult.locationName, searchResult.regionName, searchResult.countryName, cmsItem?.parentItem?.name),
29361
29751
  price: formatPrice$3(searchResult.price, searchResult.currencyCode, languageCode),
29362
29752
  ctaText: translations?.SRP.VIEW_DETAILS
29363
29753
  });
@@ -32529,6 +32919,504 @@ const BookPackagingEntry = ({ activeSearchSeed, isLoading, isConfirmationPage })
32529
32919
  React__default.createElement(WLSidebar, { activeSearchSeed: activeSearchSeed, packagingAccoResult: selectedPackagingAccoResult }))));
32530
32920
  };
32531
32921
 
32922
+ const REGULAR_TRAJECT_NODE_TYPE = 0;
32923
+ const isSearchableTrajectNode = (node) => node.serviceType === ACCOMMODATION_SERVICE_TYPE || node.serviceType === EXCURSION_SERVICE_TYPE;
32924
+ const isTrajectFlightNode = (node) => node.serviceType === FLIGHT_SERVICE_TYPE;
32925
+ const getTrajectNodesWithLines = (trajectEntry) => {
32926
+ const linesByGuid = new Map((trajectEntry.entry.lines ?? []).map((line) => [line.guid, line]));
32927
+ return [...(trajectEntry.nodes ?? [])]
32928
+ .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
32929
+ .map((node) => ({ node, line: linesByGuid.get(node.lineGuid) }))
32930
+ .filter((x) => !!x.line);
32931
+ };
32932
+ const buildDestination = (line) => {
32933
+ if (line.location?.id)
32934
+ return { id: line.location.id, isLocation: true };
32935
+ if (line.oord?.id)
32936
+ return { id: line.oord.id, isOord: true };
32937
+ if (line.region?.id)
32938
+ return { id: line.region.id, isRegion: true };
32939
+ if (line.country?.id)
32940
+ return { id: line.country.id, isCountry: true };
32941
+ if (line.latitude && line.longitude)
32942
+ return { latitude: line.latitude, longitude: line.longitude };
32943
+ return { id: 0 };
32944
+ };
32945
+ const buildTrajectNodeRequest = ({ node, line }, context, productCode) => ({
32946
+ transactionId: context.transactionId,
32947
+ officeId: context.officeId,
32948
+ agentId: context.agentId ?? null,
32949
+ catalogueId: context.catalogueId,
32950
+ searchConfigurationId: context.searchConfigurationId,
32951
+ portalId: context.portalId ?? null,
32952
+ vendorConfigurationId: node.externalVendorId ?? null,
32953
+ language: context.language,
32954
+ serviceType: node.serviceType,
32955
+ fromDate: toDateOnlyString(line.from),
32956
+ toDate: toDateOnlyString(line.to),
32957
+ destination: buildDestination(line),
32958
+ productCode,
32959
+ rooms: context.rooms,
32960
+ tagIds: []
32961
+ });
32962
+ const getNodeCandidates = (node) => {
32963
+ const configured = (node.alternatives ?? []).filter((x) => !!x.code && x.code.trim().length > 0);
32964
+ if (configured.length)
32965
+ return configured;
32966
+ const fallbackCode = node.code ?? node.preferredAccommodationCode;
32967
+ if (!fallbackCode || !fallbackCode.trim().length)
32968
+ return [];
32969
+ return [
32970
+ {
32971
+ code: fallbackCode,
32972
+ name: node.name,
32973
+ description: node.description,
32974
+ imageUrl: node.imageUrl,
32975
+ contentSource: node.contentSource,
32976
+ vendor: node.vendor,
32977
+ externalVendorId: node.externalVendorId,
32978
+ isPreferred: true
32979
+ }
32980
+ ];
32981
+ };
32982
+ const findCandidateForResult = (node, result) => getNodeCandidates(node).find((candidate) => matchesCode(result, candidate.code)) ?? null;
32983
+ const matchesCode = (result, code) => {
32984
+ if (result.code === code)
32985
+ return true;
32986
+ return (result.rooms ?? []).some((room) => (room.options ?? []).some((option) => option.accommodationCode === code));
32987
+ };
32988
+ const getPackagingRoomsFromEntry = (entry) => {
32989
+ const paxById = new Map((entry.pax ?? []).map((p) => [p.id, p]));
32990
+ const rooms = (entry.rooms ?? []).map((room) => ({
32991
+ travellers: (room.paxIds ?? []).map((paxId) => {
32992
+ const pax = paxById.get(paxId);
32993
+ return {
32994
+ id: paxId,
32995
+ age: pax?.age ?? null,
32996
+ dateOfBirth: pax?.dateOfBirth ?? null
32997
+ };
32998
+ })
32999
+ }));
33000
+ return rooms.filter((room) => room.travellers.length > 0);
33001
+ };
33002
+ const pickCheapest = (results) => [...results].sort((a, b) => a.price - b.price)[0] ?? null;
33003
+ const applyResultToLine = (line, result) => {
33004
+ const option = (result.rooms ?? []).flatMap((room) => room.options ?? []).find((x) => x.isSelected) ?? (result.rooms ?? [])[0]?.options?.[0];
33005
+ return {
33006
+ ...line,
33007
+ productName: result.name ?? line.productName,
33008
+ productCode: result.code ?? line.productCode,
33009
+ accommodationCode: option?.accommodationCode ?? line.accommodationCode,
33010
+ accommodationName: option?.accommodationName ?? line.accommodationName,
33011
+ regimeCode: option?.regimeCode ?? line.regimeCode,
33012
+ regimeName: option?.regimeName ?? line.regimeName,
33013
+ latitude: result.latitude ?? line.latitude,
33014
+ longitude: result.longitude ?? line.longitude,
33015
+ isChanged: true
33016
+ };
33017
+ };
33018
+ const toDateOnlyUtcString = (value) => {
33019
+ const date = new Date(value);
33020
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())).toISOString();
33021
+ };
33022
+ const toTimeOnlyString = (value) => {
33023
+ const date = new Date(value);
33024
+ const hh = String(date.getUTCHours()).padStart(2, '0');
33025
+ const mm = String(date.getUTCMinutes()).padStart(2, '0');
33026
+ const ss = String(date.getUTCSeconds()).padStart(2, '0');
33027
+ return `${hh}:${mm}:${ss}`;
33028
+ };
33029
+ const mapFlightSegmentsToFlightLines = (segments) => segments.map((segment) => ({
33030
+ airlineCode: segment.marketingAirlineCode,
33031
+ airlineDescription: segment.marketingAirlineName,
33032
+ operatingAirlineCode: segment.operatingAirlineCode,
33033
+ operatingAirlineDescription: segment.operatingAirlineName,
33034
+ flightNumber: segment.flightNumber,
33035
+ operatingFlightNumber: segment.operatingFlightNumber ?? null,
33036
+ departureDate: toDateOnlyUtcString(segment.departureDateTime),
33037
+ departureTime: toTimeOnlyString(segment.departureDateTime),
33038
+ departureAirportCode: segment.departureAirportCode,
33039
+ departureAirportDescription: segment.departureAirportName,
33040
+ arrivalDate: toDateOnlyUtcString(segment.arrivalDateTime),
33041
+ arrivalTime: toTimeOnlyString(segment.arrivalDateTime),
33042
+ arrivalAirportCode: segment.arrivalAirportCode,
33043
+ arrivalAirportDescription: segment.arrivalAirportName,
33044
+ durationInTicks: segment.durationInTicks
33045
+ }));
33046
+ const applyFlightToLine = (line, flight, isOutbound) => {
33047
+ const segments = (isOutbound ? flight.outward?.segments : flight.return?.segments) ?? [];
33048
+ if (!segments.length)
33049
+ return line;
33050
+ const firstSegment = segments[0];
33051
+ const lastSegment = segments[segments.length - 1];
33052
+ return {
33053
+ ...line,
33054
+ from: new Date(firstSegment.departureDateTime).toISOString(),
33055
+ to: new Date(lastSegment.arrivalDateTime).toISOString(),
33056
+ productName: `${firstSegment.departureAirportName} - ${lastSegment.arrivalAirportName} (${firstSegment.marketingAirlineName})`,
33057
+ productCode: `${firstSegment.departureAirportCode} ${lastSegment.arrivalAirportCode}/${firstSegment.marketingAirlineCode}`,
33058
+ accommodationName: firstSegment.metaData?.farePriceClassName ?? line.accommodationName,
33059
+ accommodationCode: firstSegment.metaData?.fareCode ?? line.accommodationCode,
33060
+ flightInformation: {
33061
+ pnr: '',
33062
+ flightLines: mapFlightSegmentsToFlightLines(segments)
33063
+ },
33064
+ isChanged: true
33065
+ };
33066
+ };
33067
+ const pairTrajectFlights = (nodes) => {
33068
+ const flights = nodes.filter((x) => isTrajectFlightNode(x.node));
33069
+ return {
33070
+ outbound: flights[0] ?? null,
33071
+ inbound: flights.length > 1 ? flights[flights.length - 1] : null,
33072
+ unsupported: flights.slice(1, Math.max(flights.length - 1, 1))
33073
+ };
33074
+ };
33075
+
33076
+ const getLocation = (result) => {
33077
+ const place = result.locationName || result.regionName || result.oordName;
33078
+ if (!place)
33079
+ return result.countryName ?? '';
33080
+ return result.countryName ? `${place}, ${result.countryName}` : place;
33081
+ };
33082
+ const toPlainText = (value) => {
33083
+ if (!value)
33084
+ return '';
33085
+ return he
33086
+ .decode(value.replace(/<[^>]*>/g, ' '))
33087
+ .replace(/\s+/g, ' ')
33088
+ .trim();
33089
+ };
33090
+ const TrajectNodeCard = ({ item, result, isSelected, languageCode, translations, onSelect, showNights }) => {
33091
+ const { node } = item;
33092
+ const selectedOption = first(result.rooms)?.options?.find((x) => x.isSelected) ?? first(result.rooms)?.options?.[0];
33093
+ const price = formatPrice$3(result.price, result.currencyCode, languageCode);
33094
+ const nights = calculateNights(new Date(result.fromDate), new Date(result.toDate));
33095
+ const candidate = findCandidateForResult(node, result);
33096
+ const image = candidate?.imageUrl ?? null;
33097
+ const description = toPlainText(candidate?.description);
33098
+ const title = candidate?.name ?? result.name;
33099
+ const priceBlock = (React__default.createElement("div", { className: "search__result-card__price__wrapper" },
33100
+ React__default.createElement("span", { className: "search__result-card__price__label" }, translations?.SHARED.TOTAL_PRICE),
33101
+ React__default.createElement("span", { className: "search__result-card__price" }, price)));
33102
+ const selectButton = (React__default.createElement("button", { type: "button", className: `cta ${isSelected ? 'cta--selected' : 'cta--select'}`, onClick: onSelect }, isSelected ? translations?.SHARED.SELECTED : translations?.SHARED.SELECT));
33103
+ if (result.contents?.length) {
33104
+ return (React__default.createElement("div", { className: `search__result-card__wrapper search__result-card__wrapper--custom ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
33105
+ React__default.createElement("div", { className: "search__result-card__top", dangerouslySetInnerHTML: { __html: he.decode(result.contents) } }),
33106
+ React__default.createElement("div", { className: "search__result-card__footer" }, selectButton)));
33107
+ }
33108
+ return (React__default.createElement("div", { className: `search__result-card__wrapper ${isSelected ? 'search__result-card__wrapper--selected' : ''}` },
33109
+ image && (React__default.createElement("div", { className: "search__result-card__img-wrapper" },
33110
+ React__default.createElement("img", { src: image, alt: title, className: "search__result-card__img" }),
33111
+ priceBlock)),
33112
+ React__default.createElement("div", { className: "search__result-card__content" },
33113
+ React__default.createElement("div", { className: "search__result-card__content__wrapper" },
33114
+ React__default.createElement("div", { className: "search__result-card__header" },
33115
+ React__default.createElement("div", { className: "search__result-card__header__wrapper" },
33116
+ !!result.stars && (React__default.createElement("div", { className: "rating" }, [...Array(result.stars)].map((_, index) => (React__default.createElement(Icon, { name: "ui-star", key: `rating-star-${index + 1}`, width: 14, height: 14 }))))),
33117
+ React__default.createElement("h3", { className: "search__result-card__title" }, title)),
33118
+ !image && priceBlock),
33119
+ React__default.createElement("span", { className: "search__result-card__location" },
33120
+ React__default.createElement(Icon, { name: "ui-location", height: 16 }),
33121
+ getLocation(result)),
33122
+ React__default.createElement("div", { className: "search__result-card__options" },
33123
+ showNights && nights > 0 && (React__default.createElement("div", { className: "search__result-card__option" },
33124
+ React__default.createElement(Icon, { name: "ui-moon", height: 16 }),
33125
+ nights,
33126
+ " ",
33127
+ translations?.SRP.NIGHTS)),
33128
+ selectedOption?.accommodationName && (React__default.createElement("div", { className: "search__result-card__option" },
33129
+ React__default.createElement(Icon, { name: "ui-bed", height: 16 }),
33130
+ selectedOption.accommodationName)),
33131
+ selectedOption?.regimeName && (React__default.createElement("div", { className: "search__result-card__option" },
33132
+ React__default.createElement(Icon, { name: "ui-utensils", height: 16 }),
33133
+ selectedOption.regimeName))),
33134
+ description && React__default.createElement("p", { className: "search__result-card__description" }, description)),
33135
+ React__default.createElement("div", { className: "search__result-card__footer" }, selectButton))));
33136
+ };
33137
+
33138
+ const getNodeIcon = (node) => {
33139
+ if (isTrajectFlightNode(node))
33140
+ return 'ui-flight';
33141
+ if (node.serviceType === EXCURSION_SERVICE_TYPE)
33142
+ return 'ui-excursion';
33143
+ if (node.serviceType === ACCOMMODATION_SERVICE_TYPE)
33144
+ return 'ui-bed';
33145
+ return 'ui-location';
33146
+ };
33147
+ const TrajectResults = ({ isLoading }) => {
33148
+ const context = useContext(SearchResultsConfigurationContext);
33149
+ const dispatch = useDispatch();
33150
+ const translations = getTranslations(context?.languageCode ?? 'en-GB');
33151
+ const locale = getLocale(context?.languageCode ?? 'en-GB');
33152
+ const { trajectNodeAvailability, flightsLoading, trajectFlightsResolved, selectedOutwardKey, selectedReturnKey } = useSelector((state) => state.searchResults);
33153
+ const uniqueOutwardFlights = useSelector(selectUniqueOutwardFlights);
33154
+ const uniqueReturnFlights = useSelector(selectUniqueReturnFlights);
33155
+ const selectedOutward = useSelector(selectSelectedOutward);
33156
+ const selectedReturn = useSelector(selectSelectedReturn);
33157
+ const [expandedNodes, setExpandedNodes] = useState({});
33158
+ const trajectEntry = context?.trajectEntry;
33159
+ const nodesWithLines = useMemo(() => (trajectEntry ? getTrajectNodesWithLines(trajectEntry) : []), [trajectEntry]);
33160
+ const flightPairing = useMemo(() => pairTrajectFlights(nodesWithLines), [nodesWithLines]);
33161
+ const lineByNodeId = useMemo(() => new Map(nodesWithLines.map((x) => [x.node.nodeId, x])), [nodesWithLines]);
33162
+ const nodesByDay = useMemo(() => {
33163
+ const map = new Map();
33164
+ [...(trajectEntry?.nodes ?? [])]
33165
+ .sort((a, b) => a.dayOrder - b.dayOrder || a.order - b.order)
33166
+ .forEach((node) => {
33167
+ if (!map.has(node.dayOrder))
33168
+ map.set(node.dayOrder, []);
33169
+ map.get(node.dayOrder).push(node);
33170
+ });
33171
+ return map;
33172
+ }, [trajectEntry]);
33173
+ if (!context || !trajectEntry)
33174
+ return null;
33175
+ const toggleExpanded = (lineGuid) => setExpandedNodes((prev) => ({ ...prev, [lineGuid]: !prev[lineGuid] }));
33176
+ const handleSelect = (item, code) => {
33177
+ const availability = trajectNodeAvailability[item.line.guid];
33178
+ const result = availability?.results.find((x) => x.code === code);
33179
+ if (!result)
33180
+ return;
33181
+ dispatch(setTrajectNodeSelection({ lineGuid: item.line.guid, code }));
33182
+ dispatch(updateEditableEntryLine(applyResultToLine(item.line, result)));
33183
+ };
33184
+ const renderServiceNode = (item) => {
33185
+ const { node, line } = item;
33186
+ const availability = trajectNodeAvailability[line.guid];
33187
+ const isExpanded = !!expandedNodes[line.guid];
33188
+ const results = availability?.results ?? [];
33189
+ const selected = results.find((x) => x.code === availability?.selectedCode) ?? null;
33190
+ const configured = results.filter((x) => x.code !== selected?.code && !!findCandidateForResult(node, x));
33191
+ const others = results.filter((x) => x.code !== selected?.code && !findCandidateForResult(node, x));
33192
+ // No entry yet means the node's search has been queued but not dispatched — still loading.
33193
+ const status = availability?.status ?? 'loading';
33194
+ return (React__default.createElement(React__default.Fragment, { key: line.guid },
33195
+ React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33196
+ React__default.createElement("div", { className: "search__results__label__date" },
33197
+ React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(line.from), 'd', { locale })),
33198
+ React__default.createElement("p", null, format$2(new Date(line.from), 'MMM', { locale }))),
33199
+ React__default.createElement("div", { className: "search__results__label__text" },
33200
+ React__default.createElement(Icon, { name: getNodeIcon(node), height: 16 }))),
33201
+ status === 'loading' && (React__default.createElement(Spinner, { label: node.serviceType === EXCURSION_SERVICE_TYPE ? translations.SRP.LOADING_EXCURSIONS : translations.SRP.LOADING_ACCOMMODATIONS })),
33202
+ status === 'unavailable' && React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS),
33203
+ status === 'resolved' && selected && (React__default.createElement(React__default.Fragment, null,
33204
+ availability.preferredUnavailable && node.preferredAccommodationName && (React__default.createElement("div", { className: "search__results__cards__actions" },
33205
+ React__default.createElement("span", null,
33206
+ node.preferredAccommodationName,
33207
+ " \u2014 ",
33208
+ translations.SRP.NO_RESULTS))),
33209
+ React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" }, [selected, ...configured, ...(isExpanded ? others : [])].map((result) => (React__default.createElement(TrajectNodeCard, { key: result.code, item: item, result: result, isSelected: result.code === selected.code, languageCode: context.languageCode, translations: translations, onSelect: () => handleSelect(item, result.code), showNights: node.serviceType === ACCOMMODATION_SERVICE_TYPE })))),
33210
+ others.length > 0 && (React__default.createElement("div", { className: "search__results__cards__actions" },
33211
+ React__default.createElement("button", { type: "button", className: "cta cta--secondary", onClick: () => toggleExpanded(line.guid) }, isExpanded ? translations.SRP.SHOW_LESS : `${translations.SRP.SHOW_MORE} (${others.length})`)))))));
33212
+ };
33213
+ const renderFlightNode = (item) => {
33214
+ const { node, line } = item;
33215
+ const isOutbound = flightPairing.outbound?.node.nodeId === node.nodeId;
33216
+ const isInbound = flightPairing.inbound?.node.nodeId === node.nodeId;
33217
+ // A middle leg of a multi-flight traject: the round-trip flight search cannot express it.
33218
+ if (!isOutbound && !isInbound) {
33219
+ return (React__default.createElement(React__default.Fragment, { key: line.guid },
33220
+ React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33221
+ React__default.createElement("div", { className: "search__results__label__date" },
33222
+ React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(line.from), 'd', { locale })),
33223
+ React__default.createElement("p", null, format$2(new Date(line.from), 'MMM', { locale }))),
33224
+ React__default.createElement("div", { className: "search__results__label__text" },
33225
+ React__default.createElement(Icon, { name: "ui-flight", height: 16 }),
33226
+ React__default.createElement("h3", null,
33227
+ React__default.createElement("strong", null, node.name)))),
33228
+ React__default.createElement("div", { className: "no-results" },
33229
+ node.departureAirportCode,
33230
+ " \u2192 ",
33231
+ node.arrivalAirportCode)));
33232
+ }
33233
+ const flights = isOutbound ? uniqueOutwardFlights : uniqueReturnFlights;
33234
+ const selectedFlight = isOutbound ? selectedOutward : selectedReturn;
33235
+ const selectedKey = isOutbound ? selectedOutwardKey : selectedReturnKey;
33236
+ const visible = flights.filter((x) => getFlightKey(isOutbound ? x.outward.segments : x.return.segments) !== selectedKey);
33237
+ return (React__default.createElement(React__default.Fragment, { key: line.guid },
33238
+ React__default.createElement("div", { className: "search__results__label search__results__label--secondary" },
33239
+ React__default.createElement("div", { className: "search__results__label__date" },
33240
+ React__default.createElement("p", { className: "search__results__label__date-date" }, format$2(new Date(line.from), 'd', { locale })),
33241
+ React__default.createElement("p", null, format$2(new Date(line.from), 'MMM', { locale }))),
33242
+ React__default.createElement("div", { className: "search__results__label__text" },
33243
+ React__default.createElement(Icon, { name: "ui-flight", height: 16 }),
33244
+ React__default.createElement("h3", null,
33245
+ translations.SRP.SELECT,
33246
+ " ",
33247
+ React__default.createElement("strong", null, isOutbound ? translations.SRP.DEPARTURE : translations.SRP.RETURN)))),
33248
+ flightsLoading || !trajectFlightsResolved ? (React__default.createElement(Spinner, { label: translations.SRP.LOADING_FLIGHTS })) : flights.length === 0 ? (React__default.createElement("div", { className: "no-results" }, translations.SRP.NO_RESULTS)) : (React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" },
33249
+ selectedFlight && (React__default.createElement(IndependentFlightOption, { key: `flight-${selectedKey}`, item: isOutbound ? selectedFlight.outward : selectedFlight.return, guid: selectedFlight.outwardGuid, selectedGuid: selectedFlight.outwardGuid, isOutward: isOutbound, showSelectedState: true, price: selectedFlight.price, onSelect: isOutbound ? () => dispatch(setSelectedOutwardKey(null)) : undefined })),
33250
+ visible.map((result) => (React__default.createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: isOutbound ? result.outward : result.return, guid: result.outwardGuid, isOutward: isOutbound, price: result.price, currentSelectedPrice: selectedFlight?.price, onSelect: () => dispatch(isOutbound ? setSelectedOutwardKey(getFlightKey(result.outward.segments)) : setSelectedReturnKey(getFlightKey(result.return.segments))) })))))));
33251
+ };
33252
+ if (isLoading)
33253
+ return React__default.createElement(Spinner, { label: translations.SRP.LOADING_ITINERARY });
33254
+ return (React__default.createElement(React__default.Fragment, null, trajectEntry.traject.days.map((day) => {
33255
+ const dayNodes = nodesByDay.get(day.order) ?? [];
33256
+ if (!dayNodes.length)
33257
+ return null;
33258
+ return (React__default.createElement(React__default.Fragment, { key: `day-${day.order}` }, dayNodes.map((node) => {
33259
+ // if (node.trajectNodeType === CONNECTING_TRAJECT_NODE_TYPE) return null;
33260
+ // if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE) return renderContextNode(node);
33261
+ if (node.trajectNodeType !== REGULAR_TRAJECT_NODE_TYPE)
33262
+ return null;
33263
+ const item = lineByNodeId.get(node.nodeId);
33264
+ // if (!item) return renderContextNode(node);
33265
+ if (!item)
33266
+ return null;
33267
+ return isTrajectFlightNode(node) ? renderFlightNode(item) : renderServiceNode(item);
33268
+ })));
33269
+ })));
33270
+ };
33271
+
33272
+ const useTrajectAvailability = () => {
33273
+ const context = useContext(SearchResultsConfigurationContext);
33274
+ const dispatch = useDispatch();
33275
+ const trajectEntry = context?.trajectEntry;
33276
+ const selectedCombinationFlight = useSelector(selectSelectedCombinationFlight);
33277
+ useEffect(() => {
33278
+ if (!context || !trajectEntry)
33279
+ return;
33280
+ const controller = new AbortController();
33281
+ dispatch(resetTrajectAvailability());
33282
+ const config = {
33283
+ host: context.tideConnection.host,
33284
+ apiKey: context.tideConnection.apiKey
33285
+ };
33286
+ const searchContext = {
33287
+ transactionId: trajectEntry.entry.transactionId,
33288
+ officeId: context.tideConnection.officeId ?? 1,
33289
+ catalogueId: context.searchConfiguration.defaultCatalogueId ?? first(context.tideConnection.catalogueIds) ?? 1,
33290
+ searchConfigurationId: context.searchConfiguration.id,
33291
+ portalId: context.portalId ?? null,
33292
+ agentId: context.agentId ?? null,
33293
+ language: context.languageCode ?? 'en-GB',
33294
+ rooms: getPackagingRoomsFromEntry(trajectEntry.entry)
33295
+ };
33296
+ const nodesWithLines = getTrajectNodesWithLines(trajectEntry);
33297
+ const resolveNode = async (item) => {
33298
+ const lineGuid = item.line.guid;
33299
+ const search = item.node.serviceType === EXCURSION_SERVICE_TYPE ? build.searchPackagingExcursions : build.searchPackagingAccommodations;
33300
+ dispatch(setTrajectNodeLoading(lineGuid));
33301
+ try {
33302
+ const candidates = getNodeCandidates(item.node);
33303
+ const attempts = await Promise.all(candidates.map(async (candidate) => {
33304
+ try {
33305
+ const attempt = await search(config, buildTrajectNodeRequest(item, searchContext, candidate.code), controller.signal);
33306
+ return (attempt ?? []).find((result) => matchesCode(result, candidate.code)) ?? null;
33307
+ }
33308
+ catch (error) {
33309
+ if (!controller.signal.aborted)
33310
+ console.error('Traject hotel unavailable', candidate.code, error);
33311
+ return null;
33312
+ }
33313
+ }));
33314
+ let results = attempts.filter((x) => !!x).filter((x, i, all) => all.findIndex((y) => y.code === x.code) === i);
33315
+ let picked = results[0] ?? null;
33316
+ const preferredCandidate = candidates.find((x) => x.isPreferred) ?? candidates[0];
33317
+ let preferredUnavailable = !!preferredCandidate && !results.some((x) => matchesCode(x, preferredCandidate.code));
33318
+ // Nothing configured was available — fall back to the cheapest result in the destination.
33319
+ if (!picked) {
33320
+ results = (await search(config, buildTrajectNodeRequest(item, searchContext, ''), controller.signal)) ?? [];
33321
+ picked = pickCheapest(results);
33322
+ preferredUnavailable = candidates.length > 0;
33323
+ }
33324
+ if (controller.signal.aborted)
33325
+ return null;
33326
+ dispatch(setTrajectNodeAvailability({
33327
+ lineGuid,
33328
+ results,
33329
+ selectedCode: picked?.code ?? null,
33330
+ preferredUnavailable
33331
+ }));
33332
+ if (!picked)
33333
+ return lineGuid;
33334
+ dispatch(updateEditableEntryLine(applyResultToLine(item.line, picked)));
33335
+ return null;
33336
+ }
33337
+ catch (error) {
33338
+ if (controller.signal.aborted)
33339
+ return null;
33340
+ console.error('Failed to resolve traject node availability', item.node.name, error);
33341
+ dispatch(setTrajectNodeAvailability({ lineGuid, results: [], selectedCode: null, preferredUnavailable: false }));
33342
+ return lineGuid;
33343
+ }
33344
+ };
33345
+ const resolveFlights = async () => {
33346
+ const { outbound, inbound } = pairTrajectFlights(nodesWithLines);
33347
+ if (!outbound) {
33348
+ dispatch(setTrajectFlightsResolved(true));
33349
+ return;
33350
+ }
33351
+ dispatch(setFlightsLoading(true));
33352
+ try {
33353
+ const pax = trajectEntry.entry.pax ?? [];
33354
+ const ageOf = (p) => p.age ?? 30;
33355
+ const adults = pax.filter((p) => ageOf(p) >= 12).length;
33356
+ const kids = pax.filter((p) => ageOf(p) >= 2 && ageOf(p) < 12).length;
33357
+ const babies = pax.filter((p) => ageOf(p) < 2).length;
33358
+ const request = {
33359
+ transactionId: trajectEntry.entry.transactionId,
33360
+ officeId: searchContext.officeId,
33361
+ catalogueId: searchContext.catalogueId,
33362
+ agentId: searchContext.agentId,
33363
+ language: searchContext.language,
33364
+ departureAirportCode: outbound.node.departureAirportCode ?? '',
33365
+ arrivalAirportCode: outbound.node.arrivalAirportCode ?? '',
33366
+ returnAirportCode: inbound?.node.arrivalAirportCode ?? outbound.node.departureAirportCode ?? null,
33367
+ luggageIncluded: null,
33368
+ maxStops: null,
33369
+ travelClass: null,
33370
+ pax: concat(Array.from({ length: adults }, (_, index) => ({ id: index, age: 31 })), Array.from({ length: kids }, (_, index) => ({ id: index + adults, age: 8 })), Array.from({ length: babies }, (_, index) => ({ id: index + adults + kids, age: 1 }))),
33371
+ outward: { date: dateToDateStruct(new Date(outbound.line.from)) },
33372
+ return: { date: dateToDateStruct(new Date((inbound ?? outbound).line.from)) }
33373
+ };
33374
+ const flights = (await build.searchPackagingFlights(config, request, controller.signal)) ?? [];
33375
+ if (controller.signal.aborted)
33376
+ return;
33377
+ dispatch(setPackagingFlightResults(flights));
33378
+ const firstFlight = first(flights);
33379
+ if (firstFlight) {
33380
+ dispatch(setSelectedOutwardKey(getFlightKey(firstFlight.outward.segments)));
33381
+ dispatch(setSelectedReturnKey(getFlightKey(firstFlight.return.segments)));
33382
+ }
33383
+ }
33384
+ catch (error) {
33385
+ if (!controller.signal.aborted)
33386
+ console.error('Failed to resolve traject flights', error);
33387
+ }
33388
+ finally {
33389
+ if (!controller.signal.aborted) {
33390
+ dispatch(setFlightsLoading(false));
33391
+ dispatch(setTrajectFlightsResolved(true));
33392
+ }
33393
+ }
33394
+ };
33395
+ (async () => {
33396
+ const searchable = nodesWithLines.filter((x) => isSearchableTrajectNode(x.node));
33397
+ const [unresolved] = await Promise.all([Promise.all(searchable.map(resolveNode)), resolveFlights()]);
33398
+ if (controller.signal.aborted)
33399
+ return;
33400
+ // A node with no availability anywhere cannot be priced or booked, so its line comes off
33401
+ // the entry. The card stays visible and reports the gap.
33402
+ const emptyLineGuids = unresolved.filter((guid) => !!guid);
33403
+ if (emptyLineGuids.length)
33404
+ dispatch(removeEditableEntryLines(emptyLineGuids));
33405
+ })();
33406
+ return () => controller.abort();
33407
+ }, [trajectEntry]);
33408
+ // Keep the traject's own flight lines in step with whatever outward/return the user picks.
33409
+ useEffect(() => {
33410
+ if (!trajectEntry || !selectedCombinationFlight)
33411
+ return;
33412
+ const { outbound, inbound } = pairTrajectFlights(getTrajectNodesWithLines(trajectEntry));
33413
+ if (outbound)
33414
+ dispatch(updateEditableEntryLine(applyFlightToLine(outbound.line, selectedCombinationFlight, true)));
33415
+ if (inbound)
33416
+ dispatch(updateEditableEntryLine(applyFlightToLine(inbound.line, selectedCombinationFlight, false)));
33417
+ }, [trajectEntry, selectedCombinationFlight]);
33418
+ };
33419
+
32532
33420
  const SearchResultsContainer = ({ onBookingStarted }) => {
32533
33421
  const currentSearch = typeof window !== 'undefined' ? window.location.search : '';
32534
33422
  const dispatch = useDispatch();
@@ -32536,6 +33424,8 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
32536
33424
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
32537
33425
  const { results, filteredResults, packagingAccoResults, filteredPackagingAccoResults, isLoading, flightsLoading, initialFilters, filters, flightFilters, selectedSortType, selectedFlightSortType, selectedSearchResult, selectedPackagingAccoResultCode, flyInIsOpen, packagingAccoSearchDetails, editablePackagingEntry, transactionId, flyInType, packagingFlightResults, confirmedExcursionsByDay, bookPackagingEntry } = useSelector((state) => state.searchResults);
32538
33426
  const isMobile = useMediaQuery('(max-width: 1200px)');
33427
+ // Resolves live availability per traject node; no-op unless a traject entry is configured.
33428
+ useTrajectAvailability();
32539
33429
  const [initialFiltersSet, setInitialFiltersSet] = useState(false);
32540
33430
  const [initialFlightFiltersSet, setInitialFlightFiltersSet] = useState(false);
32541
33431
  const [filtersOpen, setFiltersOpen] = useState(false);
@@ -33309,6 +34199,9 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
33309
34199
  const fetchItinerary = async () => {
33310
34200
  if (!context || !context.packagingEntry || !editablePackagingEntry || isEmpty$1(editablePackagingEntry.lines))
33311
34201
  return;
34202
+ // The traject view renders its own day-by-day column, so the generated itinerary is unused.
34203
+ if (context.trajectEntry)
34204
+ return;
33312
34205
  setItineraryIsLoading(true);
33313
34206
  try {
33314
34207
  const config = {
@@ -33379,6 +34272,10 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
33379
34272
  useEffect(() => {
33380
34273
  if (!context)
33381
34274
  return;
34275
+ // A traject entry already has its lines; they are updated per node rather than rebuilt from
34276
+ // a single hotel/flight selection, which would discard the node-to-line mapping.
34277
+ if (context.trajectEntry)
34278
+ return;
33382
34279
  const seed = activeSearchSeed;
33383
34280
  if (!seed)
33384
34281
  return;
@@ -33767,7 +34664,8 @@ const SearchResultsContainer = ({ onBookingStarted }) => {
33767
34664
  React__default.createElement("div", { className: "search__results__cards search__results__cards--extended" },
33768
34665
  selectedReturnKey && selectedReturn && (React__default.createElement(IndependentFlightOption, { key: `flight-${selectedReturnKey}`, item: selectedReturn.return, guid: selectedReturn.outwardGuid, selectedGuid: selectedReturn.outwardGuid, isOutward: false, showSelectedState: true, price: selectedReturn.price })),
33769
34666
  uniqueReturnFlights.map((result) => (React__default.createElement(IndependentFlightOption, { key: `flight-${result.outwardGuid}`, item: result.return, onSelect: () => dispatch(setSelectedReturnKey(getFlightKey(result.return.segments))), guid: result.outwardGuid, isOutward: false, currentSelectedPrice: selectedReturn?.price, price: result.price })))))),
33770
- context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.packagingEntry && (React__default.createElement(FullItinerary, { isLoading: itineraryIsLoading })))),
34667
+ context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.trajectEntry && (React__default.createElement(TrajectResults, { isLoading: isLoading })),
34668
+ context.searchConfiguration.qsmType === build.PortalQsmType.AccommodationAndFlight && context.packagingEntry && !context.trajectEntry && (React__default.createElement(FullItinerary, { isLoading: itineraryIsLoading })))),
33771
34669
  React__default.createElement(FlyIn, { srpType: context.searchConfiguration.qsmType, isOpen: flyInIsOpen, setIsOpen: handleFlyInToggle, handleConfirm: () => handleConfirmHotelSwap(), onPanelRef: (el) => (panelRef.current = el), detailsLoading: detailsIsLoading, flyInType: flyInType, isPackageEditFlow: !!context.packagingEntry, sortByTypes: sortByTypes, activeSearchSeed: activeSearchSeed, toggleFilters: () => setFiltersOpen(!filtersOpen), filtersOpen: filtersOpen })))))))));
33772
34670
  };
33773
34671