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