@gomusdev/web-components 4.13.1 → 4.14.1

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.
@@ -15399,13 +15399,15 @@ function createDisplayCart(baseCart, apiItems) {
15399
15399
  }
15400
15400
  function createDisplayCartItem(cartItem, attrs) {
15401
15401
  const quantity = isUITour(cartItem.product) ? 1 : resolveApiQuantity(attrs);
15402
- const originalPrice = cartItem.product.price_cents;
15403
- const displayPrice = originalPrice === 0 ? 0 : attrs.price_cents ?? originalPrice;
15402
+ const originalPrice = cartItem.price_cents;
15403
+ const displayPrice = cartItem.product.price_cents === 0 ? 0 : attrs.price_cents ?? originalPrice;
15404
15404
  const discounted = displayPrice < originalPrice;
15405
- return createCartItem({
15405
+ const product = {
15406
15406
  ...cartItem.product,
15407
15407
  price_cents: displayPrice
15408
- }, {
15408
+ };
15409
+ if ("dynamic_prices" in product) product.dynamic_prices = null;
15410
+ return createCartItem(product, {
15409
15411
  quantity,
15410
15412
  time: cartItem.time,
15411
15413
  voucher: cartItem.voucher,
@@ -35490,12 +35492,32 @@ var FILTER_NAMES = [
35490
35492
  "events:admission:day",
35491
35493
  "events:admission:timeslot",
35492
35494
  "events:price",
35493
- "coupon"
35495
+ "coupon",
35496
+ "tour"
35494
35497
  ];
35495
35498
  //#endregion
35496
35499
  //#region src/components/ticketSelection/filters/_helpers.ts
35497
35500
  var TWO_HOURS_MS = 7200 * 1e3;
35498
35501
  /**
35502
+ * The common tail of every ticket filter's `addToCart`: given the ticket
35503
+ * its loader resolved, build the cart line, reject if the ticket is unavailable
35504
+ * (sold out / unknown → the loader yielded nothing) or the quantity exceeds the
35505
+ * remaining capacity, add the line, and return its uuid. Subtype-agnostic — the
35506
+ * per-filter loader is the only thing that differs.
35507
+ */
35508
+ function addResolvedTicketToCart(ticket, { id, quantity, time }) {
35509
+ if (!(quantity > 0)) throw new Error(`(go.cart.addItem) 'quantity' must be a positive number`);
35510
+ if (!ticket) throw new Error(`(go.cart.addItem) ticket ${id} not available (sold out or unknown)`);
35511
+ const item = createCartItem(ticket, {
35512
+ quantity,
35513
+ time: time ?? ticket.selectedTime
35514
+ });
35515
+ const { max } = shop.capacityManager.capacity(shop.cart, item, createCart());
35516
+ if (quantity > max) throw new Error(`(go.cart.addItem) only ${max} left for ticket ${id}`);
35517
+ shop.cart.addItem(item);
35518
+ return item.uuid;
35519
+ }
35520
+ /**
35499
35521
  * When a segment opts into content attributes (with-content), batch-fetch
35500
35522
  * tickets/content for the given tickets and merge each entry's `content` onto
35501
35523
  * the matching ticket by id (mirrors the legacy `ticket.content = item.content`).
@@ -35555,433 +35577,566 @@ async function loadEventsTimeslots(tsd) {
35555
35577
  loadPickerQuotas(tsd, quotas);
35556
35578
  }
35557
35579
  //#endregion
35558
- //#region src/components/ticketSelection/filters/registry.ts
35559
- var REGISTRY = {
35560
- "ticket:timeslot": {
35561
- name: "ticket:timeslot",
35562
- calendarEndpoint: "tickets",
35563
- apiToken: "time_slot",
35564
- requires: [{
35565
- kind: "tsd",
35566
- field: "selectedDate"
35567
- }, {
35568
- kind: "tsd",
35569
- field: "selectedTimeslot"
35570
- }],
35571
- isCalendarVisible: () => true,
35572
- isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
35573
- isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
35574
- async loadTimeslots(tsd) {
35575
- if (!tsd?.selectedDate) return;
35576
- const { quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35577
- by_bookable: true,
35578
- valid_at: tsd.selectedDate.toString(),
35579
- by_ticket_type: "time_slot",
35580
- "by_museum_ids[]": tsd.museumIds,
35581
- "by_exhibition_ids[]": tsd.exhibitionIds,
35582
- "by_ticket_ids[]": tsd.ticketIds,
35583
- "by_ticket_group_ids[]": tsd.ticketGroupIds
35584
- }));
35585
- loadPickerQuotas(tsd, quotas);
35586
- },
35587
- async loadProducts(segment) {
35588
- const tsd = segment.ticketSelectionDetails;
35589
- if (!tsd?.selectedDate || !tsd.selectedTimeslot) return;
35590
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35591
- by_bookable: true,
35592
- valid_at: tsd.selectedDate.toString(),
35593
- by_ticket_type: "time_slot",
35594
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35595
- "by_exhibition_ids[]": tsd.exhibitionIds,
35596
- "by_ticket_ids[]": tsd.ticketIds,
35597
- "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35598
- }));
35599
- shop.capacityManager.addQuotas(quotas);
35600
- const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, tsd.selectedTime), tsd.selectedTime);
35601
- await enrichTicketsWithContent(segment, uiTickets);
35602
- for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
35603
- }
35580
+ //#region src/components/ticketSelection/filters/ticket/timeslot.ts
35581
+ async function loadTimeslotTickets(filters, selectedTime) {
35582
+ const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35583
+ by_bookable: true,
35584
+ by_ticket_type: "time_slot",
35585
+ ...filters
35586
+ }));
35587
+ shop.capacityManager.addQuotas(quotas);
35588
+ return initUITimeslotTickets(filterAvailabletickets(tickets, selectedTime), selectedTime);
35589
+ }
35590
+ var filter$12 = {
35591
+ name: "ticket:timeslot",
35592
+ calendarEndpoint: "tickets",
35593
+ apiToken: "time_slot",
35594
+ requires: [{
35595
+ kind: "tsd",
35596
+ field: "selectedDate"
35597
+ }, {
35598
+ kind: "tsd",
35599
+ field: "selectedTimeslot"
35600
+ }],
35601
+ isCalendarVisible: () => true,
35602
+ isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
35603
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
35604
+ async addToCart(options) {
35605
+ const { id, quantity, time } = options;
35606
+ if (!time) throw new Error(`(go.cart.addItem) ticket:timeslot requires a 'time'`);
35607
+ const ticket = (await loadTimeslotTickets({
35608
+ valid_at: time.slice(0, 10),
35609
+ "by_ticket_ids[]": [id]
35610
+ }, time))[0];
35611
+ return addResolvedTicketToCart(ticket, {
35612
+ id,
35613
+ quantity,
35614
+ time
35615
+ });
35604
35616
  },
35605
- "ticket:day": {
35606
- name: "ticket:day",
35607
- calendarEndpoint: "tickets",
35608
- apiToken: "normal",
35609
- requires: [{
35610
- kind: "tsd",
35611
- field: "selectedDate"
35612
- }],
35613
- isCalendarVisible: () => true,
35614
- isTimeslotsVisible: () => false,
35615
- isTicketsVisible: (tsd) => Boolean(tsd.selectedDate),
35616
- async loadTimeslots() {},
35617
- async loadProducts(segment) {
35618
- const tsd = segment.ticketSelectionDetails;
35619
- if (!tsd?.selectedDate) return;
35620
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35621
- by_bookable: true,
35622
- valid_at: tsd.selectedDate.toString(),
35623
- "by_ticket_types[]": ["normal"],
35624
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35625
- "by_exhibition_ids[]": tsd.exhibitionIds,
35626
- "by_ticket_ids[]": tsd.ticketIds,
35627
- "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35628
- }));
35629
- shop.capacityManager.addQuotas(quotas);
35630
- const uiTickets = initUIDayTickets(tickets);
35631
- await enrichTicketsWithContent(segment, uiTickets);
35632
- for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: ticket.selectedTime }));
35633
- }
35617
+ async loadTimeslots(tsd) {
35618
+ if (!tsd?.selectedDate) return;
35619
+ const { quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35620
+ by_bookable: true,
35621
+ valid_at: tsd.selectedDate.toString(),
35622
+ by_ticket_type: "time_slot",
35623
+ "by_museum_ids[]": tsd.museumIds,
35624
+ "by_exhibition_ids[]": tsd.exhibitionIds,
35625
+ "by_ticket_ids[]": tsd.ticketIds,
35626
+ "by_ticket_group_ids[]": tsd.ticketGroupIds
35627
+ }));
35628
+ loadPickerQuotas(tsd, quotas);
35634
35629
  },
35635
- "ticket:annual": {
35636
- name: "ticket:annual",
35637
- calendarEndpoint: null,
35638
- apiToken: "annual",
35639
- requires: [],
35640
- isCalendarVisible: () => false,
35641
- isTimeslotsVisible: () => false,
35642
- isTicketsVisible: () => true,
35643
- async loadTimeslots() {},
35644
- async loadProducts(segment) {
35645
- const tsd = segment.ticketSelectionDetails;
35646
- if (!tsd) return;
35647
- const tickets = await shop.asyncFetch(() => shop.tickets({
35648
- by_bookable: true,
35649
- "by_ticket_types[]": ["annual"],
35650
- "by_ticket_ids[]": tsd.ticketIds,
35651
- "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35652
- }));
35653
- const uiTickets = Object.values(tickets).map((t) => createUITicket(t));
35654
- await enrichTicketsWithContent(segment, uiTickets);
35655
- for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket));
35656
- }
35630
+ async loadProducts(segment) {
35631
+ const tsd = segment.ticketSelectionDetails;
35632
+ if (!tsd?.selectedDate || !tsd.selectedTimeslot) return;
35633
+ const uiTickets = await loadTimeslotTickets({
35634
+ valid_at: tsd.selectedDate.toString(),
35635
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35636
+ "by_exhibition_ids[]": tsd.exhibitionIds,
35637
+ "by_ticket_ids[]": tsd.ticketIds,
35638
+ "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35639
+ }, tsd.selectedTimeslot);
35640
+ await enrichTicketsWithContent(segment, uiTickets);
35641
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
35642
+ }
35643
+ };
35644
+ //#endregion
35645
+ //#region src/components/ticketSelection/filters/ticket/day.ts
35646
+ async function loadDayTickets(filters) {
35647
+ const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35648
+ by_bookable: true,
35649
+ "by_ticket_types[]": ["normal"],
35650
+ ...filters
35651
+ }));
35652
+ shop.capacityManager.addQuotas(quotas);
35653
+ return initUIDayTickets(tickets);
35654
+ }
35655
+ var filter$11 = {
35656
+ name: "ticket:day",
35657
+ calendarEndpoint: "tickets",
35658
+ apiToken: "normal",
35659
+ requires: [{
35660
+ kind: "tsd",
35661
+ field: "selectedDate"
35662
+ }],
35663
+ isCalendarVisible: () => true,
35664
+ isTimeslotsVisible: () => false,
35665
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate),
35666
+ async loadTimeslots() {},
35667
+ async addToCart(options) {
35668
+ const { id, quantity, date } = options;
35669
+ if (!date) throw new Error(`(go.cart.addItem) ticket:day requires a 'date'`);
35670
+ const ticket = (await loadDayTickets({
35671
+ valid_at: date,
35672
+ "by_ticket_ids[]": [id]
35673
+ }))[0];
35674
+ return addResolvedTicketToCart(ticket, {
35675
+ id,
35676
+ quantity
35677
+ });
35657
35678
  },
35658
- "event:admission": {
35659
- name: "event:admission",
35660
- calendarEndpoint: "events",
35661
- requires: [{
35679
+ async loadProducts(segment) {
35680
+ const tsd = segment.ticketSelectionDetails;
35681
+ if (!tsd?.selectedDate) return;
35682
+ const uiTickets = await loadDayTickets({
35683
+ valid_at: tsd.selectedDate.toString(),
35684
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35685
+ "by_exhibition_ids[]": tsd.exhibitionIds,
35686
+ "by_ticket_ids[]": tsd.ticketIds,
35687
+ "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35688
+ });
35689
+ await enrichTicketsWithContent(segment, uiTickets);
35690
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: ticket.selectedTime }));
35691
+ }
35692
+ };
35693
+ //#endregion
35694
+ //#region src/components/ticketSelection/filters/ticket/annual.ts
35695
+ async function loadAnnualTickets(filters) {
35696
+ const tickets = await shop.asyncFetch(() => shop.tickets({
35697
+ by_bookable: true,
35698
+ "by_ticket_types[]": ["annual"],
35699
+ ...filters
35700
+ }));
35701
+ return Object.values(tickets).map((t) => createUITicket(t));
35702
+ }
35703
+ var filter$10 = {
35704
+ name: "ticket:annual",
35705
+ calendarEndpoint: null,
35706
+ apiToken: "annual",
35707
+ requires: [],
35708
+ isCalendarVisible: () => false,
35709
+ isTimeslotsVisible: () => false,
35710
+ isTicketsVisible: () => true,
35711
+ async loadTimeslots() {},
35712
+ async addToCart(options) {
35713
+ const { id, quantity } = options;
35714
+ const ticket = (await loadAnnualTickets({ "by_ticket_ids[]": [id] }))[0];
35715
+ return addResolvedTicketToCart(ticket, {
35716
+ id,
35717
+ quantity
35718
+ });
35719
+ },
35720
+ async loadProducts(segment) {
35721
+ const tsd = segment.ticketSelectionDetails;
35722
+ if (!tsd) return;
35723
+ const uiTickets = await loadAnnualTickets({
35724
+ "by_ticket_ids[]": tsd.ticketIds,
35725
+ "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35726
+ });
35727
+ await enrichTicketsWithContent(segment, uiTickets);
35728
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket));
35729
+ }
35730
+ };
35731
+ //#endregion
35732
+ //#region src/components/ticketSelection/filters/event/admission.ts
35733
+ var filter$9 = {
35734
+ name: "event:admission",
35735
+ calendarEndpoint: "events",
35736
+ requires: [{
35737
+ kind: "tsd",
35738
+ field: "eventIds"
35739
+ }, {
35740
+ kind: "tsd",
35741
+ field: "selectedDate"
35742
+ }],
35743
+ isCalendarVisible: () => true,
35744
+ isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
35745
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
35746
+ async loadTimeslots(tsd) {
35747
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35748
+ const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35749
+ if (!event.tickets?.length) return;
35750
+ const { quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35751
+ "by_ticket_ids[]": event.tickets,
35752
+ by_bookable: true,
35753
+ valid_at: tsd.selectedDate.toString()
35754
+ }));
35755
+ loadPickerQuotas(tsd, quotas);
35756
+ },
35757
+ async loadProducts(segment) {
35758
+ const tsd = segment.ticketSelectionDetails;
35759
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35760
+ const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35761
+ if (!event.tickets?.length) return;
35762
+ const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35763
+ "by_ticket_ids[]": event.tickets,
35764
+ by_bookable: true,
35765
+ valid_at: tsd.selectedDate.toString()
35766
+ }));
35767
+ shop.capacityManager.addQuotas(quotas);
35768
+ const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, tsd.selectedTime), tsd.selectedTime);
35769
+ await enrichTicketsWithContent(segment, uiTickets);
35770
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
35771
+ }
35772
+ };
35773
+ //#endregion
35774
+ //#region src/components/ticketSelection/filters/event/admission-day.ts
35775
+ var filter$8 = {
35776
+ name: "event:admission:day",
35777
+ calendarEndpoint: "events",
35778
+ requires: [{
35779
+ kind: "tsd",
35780
+ field: "eventIds"
35781
+ }, {
35782
+ kind: "tsd",
35783
+ field: "selectedDate"
35784
+ }],
35785
+ isCalendarVisible: () => true,
35786
+ isTimeslotsVisible: () => false,
35787
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate),
35788
+ async loadTimeslots() {},
35789
+ async loadProducts(segment) {
35790
+ const tsd = segment.ticketSelectionDetails;
35791
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35792
+ const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35793
+ if (!event.tickets?.length) return;
35794
+ const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35795
+ "by_ticket_ids[]": event.tickets,
35796
+ "by_ticket_types[]": ["normal"],
35797
+ by_bookable: true,
35798
+ valid_at: tsd.selectedDate.toString()
35799
+ }));
35800
+ shop.capacityManager.addQuotas(quotas);
35801
+ const uiTickets = initUIDayTickets(tickets);
35802
+ await enrichTicketsWithContent(segment, uiTickets);
35803
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: t.selectedTime }));
35804
+ }
35805
+ };
35806
+ //#endregion
35807
+ //#region src/components/ticketSelection/filters/event/admission-timeslot.ts
35808
+ var filter$7 = {
35809
+ name: "event:admission:timeslot",
35810
+ calendarEndpoint: "events",
35811
+ requires: [
35812
+ {
35662
35813
  kind: "tsd",
35663
35814
  field: "eventIds"
35664
- }, {
35815
+ },
35816
+ {
35665
35817
  kind: "tsd",
35666
35818
  field: "selectedDate"
35667
- }],
35668
- isCalendarVisible: () => true,
35669
- isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
35670
- isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
35671
- async loadTimeslots(tsd) {
35672
- if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35673
- const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35674
- if (!event.tickets?.length) return;
35675
- const { quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35676
- "by_ticket_ids[]": event.tickets,
35677
- by_bookable: true,
35678
- valid_at: tsd.selectedDate.toString()
35679
- }));
35680
- loadPickerQuotas(tsd, quotas);
35681
35819
  },
35682
- async loadProducts(segment) {
35683
- const tsd = segment.ticketSelectionDetails;
35684
- if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35685
- const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35686
- if (!event.tickets?.length) return;
35820
+ {
35821
+ kind: "tsd",
35822
+ field: "selectedTimeslot"
35823
+ }
35824
+ ],
35825
+ isCalendarVisible: () => true,
35826
+ isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
35827
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
35828
+ async loadTimeslots(tsd) {
35829
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35830
+ const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35831
+ if (!event.tickets?.length) return;
35832
+ const { quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35833
+ "by_ticket_ids[]": event.tickets,
35834
+ by_ticket_type: "time_slot",
35835
+ by_bookable: true,
35836
+ valid_at: tsd.selectedDate.toString()
35837
+ }));
35838
+ loadPickerQuotas(tsd, quotas);
35839
+ },
35840
+ async loadProducts(segment) {
35841
+ const tsd = segment.ticketSelectionDetails;
35842
+ if (!tsd?.eventIds?.length || !tsd.selectedDate || !tsd.selectedTimeslot) return;
35843
+ const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35844
+ if (!event.tickets?.length) return;
35845
+ const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35846
+ "by_ticket_ids[]": event.tickets,
35847
+ by_ticket_type: "time_slot",
35848
+ by_bookable: true,
35849
+ valid_at: tsd.selectedDate.toString()
35850
+ }));
35851
+ shop.capacityManager.addQuotas(quotas);
35852
+ const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, tsd.selectedTime), tsd.selectedTime);
35853
+ await enrichTicketsWithContent(segment, uiTickets);
35854
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: tsd.selectedTime }));
35855
+ }
35856
+ };
35857
+ //#endregion
35858
+ //#region src/components/ticketSelection/filters/event/price.ts
35859
+ var filter$6 = {
35860
+ name: "event:price",
35861
+ calendarEndpoint: "events",
35862
+ requires: [{
35863
+ kind: "tsd",
35864
+ field: "eventIds"
35865
+ }, {
35866
+ kind: "segment",
35867
+ field: "dateId"
35868
+ }],
35869
+ isCalendarVisible: () => false,
35870
+ isTimeslotsVisible: () => false,
35871
+ isTicketsVisible: (tsd) => Boolean(tsd.eventIds?.length),
35872
+ loadTimeslots: async () => {},
35873
+ async loadProducts(segment) {
35874
+ const tsd = segment.ticketSelectionDetails;
35875
+ if (!tsd?.eventIds?.length || segment.dateId === void 0) return;
35876
+ const date = await shop.asyncFetch(() => shop.getEventDetailsOnDate(tsd.eventIds[0], segment.dateId));
35877
+ if (!date.prices?.length) return;
35878
+ for (const price of date.prices) {
35879
+ const ticket = createUIEventTicket(price, date.id, { event_title: date.event_title });
35880
+ segment.preCart.addItem(createCartItem(ticket, { time: date.start_time }));
35881
+ }
35882
+ if (date.seats) shop.capacityManager.addSeats(date.id, date.seats);
35883
+ }
35884
+ };
35885
+ //#endregion
35886
+ //#region src/components/ticketSelection/filters/events/admission.ts
35887
+ var filter$5 = {
35888
+ name: "events:admission",
35889
+ calendarEndpoint: "events",
35890
+ requires: [{
35891
+ kind: "tsd",
35892
+ field: "selectedDate"
35893
+ }, {
35894
+ kind: "tsd",
35895
+ field: "selectedTimeslot"
35896
+ }],
35897
+ isCalendarVisible: () => true,
35898
+ isTimeslotsVisible: () => true,
35899
+ isTicketsVisible: () => true,
35900
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35901
+ async loadProducts(segment) {
35902
+ const tsd = segment.ticketSelectionDetails;
35903
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
35904
+ const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35905
+ by_bookable: true,
35906
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35907
+ "by_exhibition_ids[]": tsd.exhibitionIds,
35908
+ "by_event_ids[]": tsd.eventIds,
35909
+ "by_language_ids[]": segment.languageIds,
35910
+ "by_catch_word_ids[]": segment.catchWordIds,
35911
+ start_at: tsd.selectedDate.toString(),
35912
+ per_page: segment.limit || 30
35913
+ })), tsd.selectedDate.toString(), tsd.selectedTime);
35914
+ for (const date of dates) {
35915
+ if (!date.event_id || !date.start_time) continue;
35916
+ const event = await shop.asyncFetch(() => shop.getEvent(date.event_id));
35917
+ if (!event?.tickets?.length) continue;
35687
35918
  const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35688
35919
  "by_ticket_ids[]": event.tickets,
35689
35920
  by_bookable: true,
35690
- valid_at: tsd.selectedDate.toString()
35921
+ valid_at: date.start_time.slice(0, 10)
35691
35922
  }));
35692
35923
  shop.capacityManager.addQuotas(quotas);
35693
- const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, tsd.selectedTime), tsd.selectedTime);
35924
+ const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, date.start_time), date.start_time);
35694
35925
  await enrichTicketsWithContent(segment, uiTickets);
35695
- for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
35926
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: date.start_time }));
35696
35927
  }
35697
- },
35698
- "event:admission:day": {
35699
- name: "event:admission:day",
35700
- calendarEndpoint: "events",
35701
- requires: [{
35702
- kind: "tsd",
35703
- field: "eventIds"
35704
- }, {
35705
- kind: "tsd",
35706
- field: "selectedDate"
35707
- }],
35708
- isCalendarVisible: () => true,
35709
- isTimeslotsVisible: () => false,
35710
- isTicketsVisible: (tsd) => Boolean(tsd.selectedDate),
35711
- async loadTimeslots() {},
35712
- async loadProducts(segment) {
35713
- const tsd = segment.ticketSelectionDetails;
35714
- if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35715
- const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35716
- if (!event.tickets?.length) return;
35928
+ }
35929
+ };
35930
+ //#endregion
35931
+ //#region src/components/ticketSelection/filters/events/admission-day.ts
35932
+ var filter$4 = {
35933
+ name: "events:admission:day",
35934
+ calendarEndpoint: "events",
35935
+ requires: [{
35936
+ kind: "tsd",
35937
+ field: "selectedDate"
35938
+ }, {
35939
+ kind: "tsd",
35940
+ field: "selectedTimeslot"
35941
+ }],
35942
+ isCalendarVisible: () => true,
35943
+ isTimeslotsVisible: () => true,
35944
+ isTicketsVisible: () => true,
35945
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35946
+ async loadProducts(segment) {
35947
+ const tsd = segment.ticketSelectionDetails;
35948
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
35949
+ const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35950
+ by_bookable: true,
35951
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35952
+ "by_exhibition_ids[]": tsd.exhibitionIds,
35953
+ "by_event_ids[]": tsd.eventIds,
35954
+ "by_language_ids[]": segment.languageIds,
35955
+ "by_catch_word_ids[]": segment.catchWordIds,
35956
+ start_at: tsd.selectedDate.toString(),
35957
+ per_page: segment.limit || 30
35958
+ })), tsd.selectedDate.toString(), tsd.selectedTime);
35959
+ for (const date of dates) {
35960
+ if (!date.event_id || !date.start_time) continue;
35961
+ const event = await shop.asyncFetch(() => shop.getEvent(date.event_id));
35962
+ if (!event?.tickets?.length) continue;
35717
35963
  const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35718
35964
  "by_ticket_ids[]": event.tickets,
35719
35965
  "by_ticket_types[]": ["normal"],
35720
35966
  by_bookable: true,
35721
- valid_at: tsd.selectedDate.toString()
35967
+ valid_at: date.start_time.slice(0, 10)
35722
35968
  }));
35723
35969
  shop.capacityManager.addQuotas(quotas);
35724
- const uiTickets = initUIDayTickets(tickets);
35970
+ const uiTickets = initUIDayTickets(tickets, date.start_time);
35725
35971
  await enrichTicketsWithContent(segment, uiTickets);
35726
35972
  for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: t.selectedTime }));
35727
35973
  }
35728
- },
35729
- "event:admission:timeslot": {
35730
- name: "event:admission:timeslot",
35731
- calendarEndpoint: "events",
35732
- requires: [
35733
- {
35734
- kind: "tsd",
35735
- field: "eventIds"
35736
- },
35737
- {
35738
- kind: "tsd",
35739
- field: "selectedDate"
35740
- },
35741
- {
35742
- kind: "tsd",
35743
- field: "selectedTimeslot"
35744
- }
35745
- ],
35746
- isCalendarVisible: () => true,
35747
- isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
35748
- isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
35749
- async loadTimeslots(tsd) {
35750
- if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
35751
- const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35752
- if (!event.tickets?.length) return;
35753
- const { quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35754
- "by_ticket_ids[]": event.tickets,
35755
- by_ticket_type: "time_slot",
35756
- by_bookable: true,
35757
- valid_at: tsd.selectedDate.toString()
35758
- }));
35759
- loadPickerQuotas(tsd, quotas);
35760
- },
35761
- async loadProducts(segment) {
35762
- const tsd = segment.ticketSelectionDetails;
35763
- if (!tsd?.eventIds?.length || !tsd.selectedDate || !tsd.selectedTimeslot) return;
35764
- const event = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
35765
- if (!event.tickets?.length) return;
35974
+ }
35975
+ };
35976
+ //#endregion
35977
+ //#region src/components/ticketSelection/filters/events/admission-timeslot.ts
35978
+ var filter$3 = {
35979
+ name: "events:admission:timeslot",
35980
+ calendarEndpoint: "events",
35981
+ requires: [{
35982
+ kind: "tsd",
35983
+ field: "selectedDate"
35984
+ }, {
35985
+ kind: "tsd",
35986
+ field: "selectedTimeslot"
35987
+ }],
35988
+ isCalendarVisible: () => true,
35989
+ isTimeslotsVisible: () => true,
35990
+ isTicketsVisible: () => true,
35991
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35992
+ async loadProducts(segment) {
35993
+ const tsd = segment.ticketSelectionDetails;
35994
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
35995
+ const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35996
+ by_bookable: true,
35997
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35998
+ "by_exhibition_ids[]": tsd.exhibitionIds,
35999
+ "by_event_ids[]": tsd.eventIds,
36000
+ "by_language_ids[]": segment.languageIds,
36001
+ "by_catch_word_ids[]": segment.catchWordIds,
36002
+ start_at: tsd.selectedDate.toString(),
36003
+ per_page: segment.limit || 30
36004
+ })), tsd.selectedDate.toString(), tsd.selectedTime);
36005
+ for (const date of dates) {
36006
+ if (!date.event_id || !date.start_time) continue;
36007
+ const event = await shop.asyncFetch(() => shop.getEvent(date.event_id));
36008
+ if (!event?.tickets?.length) continue;
35766
36009
  const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35767
36010
  "by_ticket_ids[]": event.tickets,
35768
36011
  by_ticket_type: "time_slot",
35769
36012
  by_bookable: true,
35770
- valid_at: tsd.selectedDate.toString()
36013
+ valid_at: date.start_time.slice(0, 10)
35771
36014
  }));
35772
36015
  shop.capacityManager.addQuotas(quotas);
35773
- const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, tsd.selectedTime), tsd.selectedTime);
36016
+ const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, date.start_time), date.start_time);
35774
36017
  await enrichTicketsWithContent(segment, uiTickets);
35775
- for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: tsd.selectedTime }));
36018
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: date.start_time }));
35776
36019
  }
35777
- },
35778
- "event:price": {
35779
- name: "event:price",
35780
- calendarEndpoint: "events",
35781
- requires: [{
35782
- kind: "tsd",
35783
- field: "eventIds"
35784
- }, {
35785
- kind: "segment",
35786
- field: "dateId"
35787
- }],
35788
- isCalendarVisible: () => false,
35789
- isTimeslotsVisible: () => false,
35790
- isTicketsVisible: (tsd) => Boolean(tsd.eventIds?.length),
35791
- loadTimeslots: async () => {},
35792
- async loadProducts(segment) {
35793
- const tsd = segment.ticketSelectionDetails;
35794
- if (!tsd?.eventIds?.length || segment.dateId === void 0) return;
35795
- const date = await shop.asyncFetch(() => shop.getEventDetailsOnDate(tsd.eventIds[0], segment.dateId));
35796
- if (!date.prices?.length) return;
35797
- for (const price of date.prices) {
36020
+ }
36021
+ };
36022
+ //#endregion
36023
+ //#region src/components/ticketSelection/filters/events/price.ts
36024
+ var filter$2 = {
36025
+ name: "events:price",
36026
+ calendarEndpoint: "events",
36027
+ requires: [{
36028
+ kind: "tsd",
36029
+ field: "selectedDate"
36030
+ }, {
36031
+ kind: "tsd",
36032
+ field: "selectedTimeslot"
36033
+ }],
36034
+ isCalendarVisible: () => true,
36035
+ isTimeslotsVisible: () => true,
36036
+ isTicketsVisible: () => true,
36037
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
36038
+ async loadProducts(segment) {
36039
+ const tsd = segment.ticketSelectionDetails;
36040
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
36041
+ const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
36042
+ by_bookable: true,
36043
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
36044
+ "by_exhibition_ids[]": tsd.exhibitionIds,
36045
+ "by_event_ids[]": tsd.eventIds,
36046
+ "by_language_ids[]": segment.languageIds,
36047
+ "by_catch_word_ids[]": segment.catchWordIds,
36048
+ start_at: tsd.selectedDate.toString(),
36049
+ per_page: segment.limit || 30
36050
+ })), tsd.selectedDate.toString(), tsd.selectedTime);
36051
+ const query = segment.query;
36052
+ for (const date of dates) {
36053
+ if (!date.prices?.length) continue;
36054
+ const prices = query ? date.prices.filter((p) => p.title?.includes(query)) : date.prices;
36055
+ for (const price of prices) {
35798
36056
  const ticket = createUIEventTicket(price, date.id, { event_title: date.event_title });
35799
36057
  segment.preCart.addItem(createCartItem(ticket, { time: date.start_time }));
35800
36058
  }
35801
36059
  if (date.seats) shop.capacityManager.addSeats(date.id, date.seats);
35802
36060
  }
35803
- },
35804
- "events:admission": {
35805
- name: "events:admission",
35806
- calendarEndpoint: "events",
35807
- requires: [{
35808
- kind: "tsd",
35809
- field: "selectedDate"
35810
- }, {
35811
- kind: "tsd",
35812
- field: "selectedTimeslot"
35813
- }],
35814
- isCalendarVisible: () => true,
35815
- isTimeslotsVisible: () => true,
35816
- isTicketsVisible: () => true,
35817
- loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35818
- async loadProducts(segment) {
35819
- const tsd = segment.ticketSelectionDetails;
35820
- if (!tsd?.selectedDate || !tsd.selectedTime) return;
35821
- const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35822
- by_bookable: true,
35823
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35824
- "by_exhibition_ids[]": tsd.exhibitionIds,
35825
- "by_event_ids[]": tsd.eventIds,
35826
- "by_language_ids[]": segment.languageIds,
35827
- "by_catch_word_ids[]": segment.catchWordIds,
35828
- start_at: tsd.selectedDate.toString(),
35829
- per_page: segment.limit || 30
35830
- })), tsd.selectedDate.toString(), tsd.selectedTime);
35831
- for (const date of dates) {
35832
- if (!date.event_id || !date.start_time) continue;
35833
- const event = await shop.asyncFetch(() => shop.getEvent(date.event_id));
35834
- if (!event?.tickets?.length) continue;
35835
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35836
- "by_ticket_ids[]": event.tickets,
35837
- by_bookable: true,
35838
- valid_at: date.start_time.slice(0, 10)
35839
- }));
35840
- shop.capacityManager.addQuotas(quotas);
35841
- const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, date.start_time), date.start_time);
35842
- await enrichTicketsWithContent(segment, uiTickets);
35843
- for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: date.start_time }));
35844
- }
35845
- }
35846
- },
35847
- "events:admission:day": {
35848
- name: "events:admission:day",
35849
- calendarEndpoint: "events",
35850
- requires: [{
35851
- kind: "tsd",
35852
- field: "selectedDate"
35853
- }, {
35854
- kind: "tsd",
35855
- field: "selectedTimeslot"
35856
- }],
35857
- isCalendarVisible: () => true,
35858
- isTimeslotsVisible: () => true,
35859
- isTicketsVisible: () => true,
35860
- loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35861
- async loadProducts(segment) {
35862
- const tsd = segment.ticketSelectionDetails;
35863
- if (!tsd?.selectedDate || !tsd.selectedTime) return;
35864
- const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35865
- by_bookable: true,
35866
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35867
- "by_exhibition_ids[]": tsd.exhibitionIds,
35868
- "by_event_ids[]": tsd.eventIds,
35869
- "by_language_ids[]": segment.languageIds,
35870
- "by_catch_word_ids[]": segment.catchWordIds,
35871
- start_at: tsd.selectedDate.toString(),
35872
- per_page: segment.limit || 30
35873
- })), tsd.selectedDate.toString(), tsd.selectedTime);
35874
- for (const date of dates) {
35875
- if (!date.event_id || !date.start_time) continue;
35876
- const event = await shop.asyncFetch(() => shop.getEvent(date.event_id));
35877
- if (!event?.tickets?.length) continue;
35878
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35879
- "by_ticket_ids[]": event.tickets,
35880
- "by_ticket_types[]": ["normal"],
35881
- by_bookable: true,
35882
- valid_at: date.start_time.slice(0, 10)
35883
- }));
35884
- shop.capacityManager.addQuotas(quotas);
35885
- const uiTickets = initUIDayTickets(tickets, date.start_time);
35886
- await enrichTicketsWithContent(segment, uiTickets);
35887
- for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: t.selectedTime }));
35888
- }
35889
- }
35890
- },
35891
- "events:admission:timeslot": {
35892
- name: "events:admission:timeslot",
35893
- calendarEndpoint: "events",
35894
- requires: [{
35895
- kind: "tsd",
35896
- field: "selectedDate"
35897
- }, {
35898
- kind: "tsd",
35899
- field: "selectedTimeslot"
35900
- }],
35901
- isCalendarVisible: () => true,
35902
- isTimeslotsVisible: () => true,
35903
- isTicketsVisible: () => true,
35904
- loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35905
- async loadProducts(segment) {
35906
- const tsd = segment.ticketSelectionDetails;
35907
- if (!tsd?.selectedDate || !tsd.selectedTime) return;
35908
- const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35909
- by_bookable: true,
35910
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35911
- "by_exhibition_ids[]": tsd.exhibitionIds,
35912
- "by_event_ids[]": tsd.eventIds,
35913
- "by_language_ids[]": segment.languageIds,
35914
- "by_catch_word_ids[]": segment.catchWordIds,
35915
- start_at: tsd.selectedDate.toString(),
35916
- per_page: segment.limit || 30
35917
- })), tsd.selectedDate.toString(), tsd.selectedTime);
35918
- for (const date of dates) {
35919
- if (!date.event_id || !date.start_time) continue;
35920
- const event = await shop.asyncFetch(() => shop.getEvent(date.event_id));
35921
- if (!event?.tickets?.length) continue;
35922
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35923
- "by_ticket_ids[]": event.tickets,
35924
- by_ticket_type: "time_slot",
35925
- by_bookable: true,
35926
- valid_at: date.start_time.slice(0, 10)
35927
- }));
35928
- shop.capacityManager.addQuotas(quotas);
35929
- const uiTickets = initUITimeslotTickets(filterAvailabletickets(tickets, date.start_time), date.start_time);
35930
- await enrichTicketsWithContent(segment, uiTickets);
35931
- for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: date.start_time }));
35932
- }
35933
- }
35934
- },
35935
- "events:price": {
35936
- name: "events:price",
35937
- calendarEndpoint: "events",
35938
- requires: [{
35939
- kind: "tsd",
35940
- field: "selectedDate"
35941
- }, {
35942
- kind: "tsd",
35943
- field: "selectedTimeslot"
35944
- }],
35945
- isCalendarVisible: () => true,
35946
- isTimeslotsVisible: () => true,
35947
- isTicketsVisible: () => true,
35948
- loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
35949
- async loadProducts(segment) {
35950
- const tsd = segment.ticketSelectionDetails;
35951
- if (!tsd?.selectedDate || !tsd.selectedTime) return;
35952
- const dates = filterDatesInWindow(await shop.asyncFetch(() => shop.getDates({
35953
- by_bookable: true,
35954
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35955
- "by_exhibition_ids[]": tsd.exhibitionIds,
35956
- "by_event_ids[]": tsd.eventIds,
35957
- "by_language_ids[]": segment.languageIds,
35958
- "by_catch_word_ids[]": segment.catchWordIds,
35959
- start_at: tsd.selectedDate.toString(),
35960
- per_page: segment.limit || 30
35961
- })), tsd.selectedDate.toString(), tsd.selectedTime);
35962
- const query = segment.query;
35963
- for (const date of dates) {
35964
- if (!date.prices?.length) continue;
35965
- const prices = query ? date.prices.filter((p) => p.title?.includes(query)) : date.prices;
35966
- for (const price of prices) {
35967
- const ticket = createUIEventTicket(price, date.id, { event_title: date.event_title });
35968
- segment.preCart.addItem(createCartItem(ticket, { time: date.start_time }));
35969
- }
35970
- if (date.seats) shop.capacityManager.addSeats(date.id, date.seats);
35971
- }
35972
- }
35973
- },
35974
- coupon: {
35975
- name: "coupon",
36061
+ }
36062
+ };
36063
+ //#endregion
36064
+ //#region src/components/ticketSelection/filters/coupon.ts
36065
+ /**
36066
+ * `coupon` — sells the shop's purchasable coupons (German "Wertgutschein" /
36067
+ * gift card). Coupons are fixed-value, standalone products:
36068
+ * no calendar, no timeslots, no capacity. They are always listed, like a
36069
+ * shelf of products.
36070
+ */
36071
+ var filter$1 = {
36072
+ name: "coupon",
36073
+ calendarEndpoint: null,
36074
+ requires: [],
36075
+ isCalendarVisible: () => false,
36076
+ isTimeslotsVisible: () => false,
36077
+ isTicketsVisible: () => true,
36078
+ loadTimeslots: async () => {},
36079
+ async loadProducts(segment) {
36080
+ const coupons = await shop.asyncFetch(() => shop.getCoupons());
36081
+ for (const coupon of coupons ?? []) segment.preCart.addItem(createCartItem(createUICoupon(coupon)));
36082
+ }
36083
+ };
36084
+ //#endregion
36085
+ //#region src/components/ticketSelection/filters/tour.ts
36086
+ var REQUIRED = [
36087
+ "id",
36088
+ "time",
36089
+ "participants",
36090
+ "languageId",
36091
+ "totalPriceCents",
36092
+ "title"
36093
+ ];
36094
+ //#endregion
36095
+ //#region src/components/ticketSelection/filters/registry.ts
36096
+ var REGISTRY = {
36097
+ "ticket:timeslot": filter$12,
36098
+ "ticket:day": filter$11,
36099
+ "ticket:annual": filter$10,
36100
+ "event:admission": filter$9,
36101
+ "event:admission:day": filter$8,
36102
+ "event:admission:timeslot": filter$7,
36103
+ "event:price": filter$6,
36104
+ "events:admission": filter$5,
36105
+ "events:admission:day": filter$4,
36106
+ "events:admission:timeslot": filter$3,
36107
+ "events:price": filter$2,
36108
+ coupon: filter$1,
36109
+ tour: {
36110
+ name: "tour",
35976
36111
  calendarEndpoint: null,
35977
36112
  requires: [],
35978
36113
  isCalendarVisible: () => false,
35979
36114
  isTimeslotsVisible: () => false,
35980
36115
  isTicketsVisible: () => true,
35981
- loadTimeslots: async () => {},
35982
- async loadProducts(segment) {
35983
- const coupons = await shop.asyncFetch(() => shop.getCoupons());
35984
- for (const coupon of coupons ?? []) segment.preCart.addItem(createCartItem(createUICoupon(coupon)));
36116
+ async loadTimeslots() {},
36117
+ async loadProducts() {},
36118
+ /**
36119
+ * Adds a group-tour booking and returns the cart line's uuid. Every call
36120
+ * appends a NEW line — identical bookings coexist; use the uuid to dedupe or
36121
+ * remove. Tours are not priced by the shop API: `totalPriceCents` is the
36122
+ * integrator-supplied total (incl. mandatory surcharges), verified by the
36123
+ * backend only at checkout.
36124
+ */
36125
+ async addToCart(options) {
36126
+ const o = options;
36127
+ for (const key of REQUIRED) if (o[key] == null || o[key] === "") throw new Error(`(go.cart.addItem) tour '${key}' is required`);
36128
+ if (!(o.participants > 0)) throw new Error(`(go.cart.addItem) tour 'participants' must be a positive number`);
36129
+ if (o.quantities) {
36130
+ const quantitiesSum = sum(Object.values(o.quantities));
36131
+ if (quantitiesSum !== o.participants) throw new Error(`(go.cart.addItem) tour 'quantities' must sum to 'participants' (${quantitiesSum} !== ${o.participants})`);
36132
+ }
36133
+ const { time, ...attributes } = o;
36134
+ const item = createCartItem(createUITour(attributes), {
36135
+ quantity: 1,
36136
+ time
36137
+ });
36138
+ shop.cart.addItem(item);
36139
+ return item.uuid;
35985
36140
  }
35986
36141
  }
35987
36142
  };
@@ -38504,41 +38659,13 @@ customElements.define("go-withdrawal-form", create_custom_element(Withdrawal, {
38504
38659
  } }, [], []));
38505
38660
  //#endregion
38506
38661
  //#region src/go/cart.ts
38507
- var REQUIRED = [
38508
- "id",
38509
- "time",
38510
- "participants",
38511
- "languageId",
38512
- "totalPriceCents",
38513
- "title"
38514
- ];
38515
- function validate(options) {
38516
- for (const key of REQUIRED) if (options[key] == null || options[key] === "") throw new Error(`(go.cart.addTour) '${key}' is required`);
38517
- if (!(options.participants > 0)) throw new Error(`(go.cart.addTour) 'participants' must be a positive number`);
38518
- if (options.quantities) {
38519
- const quantitiesSum = sum(Object.values(options.quantities));
38520
- if (quantitiesSum !== options.participants) throw new Error(`(go.cart.addTour) 'quantities' must sum to 'participants' (${quantitiesSum} !== ${options.participants})`);
38521
- }
38522
- }
38523
- /**
38524
- * Adds a group-tour booking to the cart and resolves with the cart line's
38525
- * uuid. Every call appends a NEW line — identical bookings coexist; use the
38526
- * returned uuid to deduplicate or remove.
38527
- *
38528
- * Tours are not priced by the shop API: `totalPriceCents` is the
38529
- * integrator-supplied booking total (incl. mandatory surcharges) and is
38530
- * verified by the backend only at checkout.
38531
- */
38532
- async function addTour(options) {
38533
- validate(options);
38534
- if (!shop.cart) throw new Error("(go.cart.addTour) shop not initialized — call go.init first");
38535
- const { time, ...attributes } = options;
38536
- const item = createCartItem(createUITour(attributes), {
38537
- quantity: 1,
38538
- time
38539
- });
38540
- shop.cart.addItem(item);
38541
- return item.uuid;
38662
+ /** Resolves with the new cart line's uuid. Throws if the filter can't add to
38663
+ * the cart, or on the filter's own validation / availability errors. */
38664
+ async function addItem({ filter, ...options }) {
38665
+ if (!shop.cart) throw new Error("(go.cart.addItem) shop not initialized — call go.init first");
38666
+ const module = getFilter(filter);
38667
+ if (!module?.addToCart) throw new Error(`(go.cart.addItem) filter '${filter}' cannot add to the cart`);
38668
+ return module.addToCart(options);
38542
38669
  }
38543
38670
  //#endregion
38544
38671
  //#region src/go/go.ts
@@ -38597,9 +38724,9 @@ var go = {
38597
38724
  return shop.asyncFetch(() => shop.getCustomerMemberships());
38598
38725
  }
38599
38726
  },
38600
- cart: { addTour: async (options) => {
38727
+ cart: { addItem: async (options) => {
38601
38728
  await ensureShopReady();
38602
- return addTour(options);
38729
+ return addItem(options);
38603
38730
  } }
38604
38731
  };
38605
38732
  (async () => {