@gomusdev/web-components 1.56.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist-js/gomus-webcomponents.iife.js +865 -504
  2. package/dist-js/gomus-webcomponents.js +865 -504
  3. package/dist-js/src/components/forms/lib/Field.svelte.d.ts +2 -2
  4. package/dist-js/src/components/forms/ui/generic/FormDetails.svelte.d.ts +1 -1
  5. package/dist-js/src/components/ticketSelection/TicketSelectionDetails.svelte.d.ts +6 -6
  6. package/dist-js/src/components/ticketSelection/filters/_helpers.d.ts +4 -0
  7. package/dist-js/src/components/ticketSelection/filters/event/admission-day.d.ts +3 -0
  8. package/dist-js/src/components/ticketSelection/filters/event/admission-timeslot.d.ts +3 -0
  9. package/dist-js/src/components/ticketSelection/filters/event/admission.d.ts +3 -0
  10. package/dist-js/src/components/ticketSelection/filters/event/price.d.ts +3 -0
  11. package/dist-js/src/components/ticketSelection/filters/event/spec/admission.spec.d.ts +1 -0
  12. package/dist-js/src/components/ticketSelection/filters/event/spec/price.spec.d.ts +1 -0
  13. package/dist-js/src/components/ticketSelection/filters/events/admission-day.d.ts +3 -0
  14. package/dist-js/src/components/ticketSelection/filters/events/admission-timeslot.d.ts +3 -0
  15. package/dist-js/src/components/ticketSelection/filters/events/admission.d.ts +3 -0
  16. package/dist-js/src/components/ticketSelection/filters/events/price.d.ts +3 -0
  17. package/dist-js/src/components/ticketSelection/filters/events/spec/admission-day.spec.d.ts +1 -0
  18. package/dist-js/src/components/ticketSelection/filters/events/spec/admission-timeslot.spec.d.ts +1 -0
  19. package/dist-js/src/components/ticketSelection/filters/events/spec/admission.spec.d.ts +1 -0
  20. package/dist-js/src/components/ticketSelection/filters/events/spec/price.spec.d.ts +1 -0
  21. package/dist-js/src/components/ticketSelection/filters/registry.d.ts +4 -0
  22. package/dist-js/src/components/ticketSelection/filters/ticket/annual.d.ts +3 -0
  23. package/dist-js/src/components/ticketSelection/filters/ticket/day.d.ts +3 -0
  24. package/dist-js/src/components/ticketSelection/filters/ticket/spec/annual.spec.d.ts +1 -0
  25. package/dist-js/src/components/ticketSelection/filters/ticket/spec/day.spec.d.ts +1 -0
  26. package/dist-js/src/components/ticketSelection/filters/ticket/spec/timeslot.spec.d.ts +1 -0
  27. package/dist-js/src/components/ticketSelection/filters/ticket/timeslot.d.ts +3 -0
  28. package/dist-js/src/components/ticketSelection/filters/types.d.ts +23 -0
  29. package/dist-js/src/components/ticketSelection/subcomponents/calendar/lib/calendar.svelte.d.ts +2 -1
  30. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/SegmentDetails.svelte.d.ts +6 -4
  31. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/spec/SegmentDetails.spec.d.ts +1 -0
  32. package/dist-js/src/components/ticketSelection/subcomponents/timeslots/lib/lib.svelte.d.ts +2 -1
  33. package/dist-js/src/lib/stores/shop.svelte.d.ts +6 -1
  34. package/dist-js/src/mocks/MSWMocks.d.ts +3 -0
  35. package/package.json +1 -1
  36. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/lib/annualTickets.svelte.d.ts +0 -2
  37. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/lib/dayTickets.svelte.d.ts +0 -2
  38. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/lib/event/event_ScaledPriceTickets.svelte.d.ts +0 -2
  39. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/lib/event/event_Tickets.svelte.d.ts +0 -2
  40. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/lib/events/events_ScaledPriceTickets.svelte.d.ts +0 -2
  41. package/dist-js/src/components/ticketSelection/subcomponents/tickets/subcomponents/segment/lib/timeslotTickets.svelte.d.ts +0 -2
  42. /package/dist-js/src/components/{ticketSelection/subcomponents/tickets/subcomponents/segment/TicketSegment.spec.d.ts → annualTicketPersonalization/specs/AnnualTicketPersonalizationFormPhoto.spec.d.ts} +0 -0
  43. /package/dist-js/src/components/{ticketSelection/subcomponents/tickets/subcomponents/segment/lib/event/event_ScaledPriceTickets.spec.d.ts → forms/ui/generic/FileField.spec.d.ts} +0 -0
  44. /package/dist-js/src/components/ticketSelection/{subcomponents/tickets/subcomponents/segment/lib/event/event_Tickets.svelte.spec.d.ts → filters/event/spec/admission-day.spec.d.ts} +0 -0
  45. /package/dist-js/src/components/ticketSelection/{subcomponents/tickets/subcomponents/segment/lib/events/events_ScaledPriceTickets.spec.d.ts → filters/event/spec/admission-timeslot.spec.d.ts} +0 -0
@@ -12635,6 +12635,14 @@ class Shop {
12635
12635
  finalizePersonalizations(token, params) {
12636
12636
  return this.apiPost("/api/v4/annual/personalization/finalize", { body: params, params: { query: { token } } });
12637
12637
  }
12638
+ uploadPersonalizationPhoto(token, personalizationId, file) {
12639
+ const fd = new FormData();
12640
+ fd.append("file", file);
12641
+ return this.apiUpload("/api/v4/annual/personalizations/{id}/upload", {
12642
+ body: fd,
12643
+ params: { path: { id: personalizationId }, query: { token } }
12644
+ });
12645
+ }
12638
12646
  /**
12639
12647
  * Returns a reactive value that will contain the fetched data, no need to await.
12640
12648
  *
@@ -12742,6 +12750,16 @@ class Shop {
12742
12750
  async apiDELETE(path, options) {
12743
12751
  return this.apiCall(path, { method: "DELETE", ...options });
12744
12752
  }
12753
+ async apiUpload(path, options) {
12754
+ this.#ensureApi();
12755
+ const { body, params = {} } = options;
12756
+ const ret = await this.client.POST(path, {
12757
+ body,
12758
+ params: assign(this.#defaultApiParams, { params }).params,
12759
+ bodySerializer: (b) => b
12760
+ });
12761
+ return ret;
12762
+ }
12745
12763
  async apiCall(path, options) {
12746
12764
  this.#ensureApi();
12747
12765
  const { body, params = {}, requiredFields } = options;
@@ -16023,6 +16041,28 @@ function refine(fn, _params = {}) {
16023
16041
  function superRefine(fn) {
16024
16042
  return /* @__PURE__ */ _superRefine(fn);
16025
16043
  }
16044
+ function _instanceof(cls, params = {}) {
16045
+ const inst = new ZodCustom({
16046
+ type: "custom",
16047
+ check: "custom",
16048
+ fn: (data) => data instanceof cls,
16049
+ abort: true,
16050
+ ...normalizeParams(params)
16051
+ });
16052
+ inst._zod.bag.Class = cls;
16053
+ inst._zod.check = (payload) => {
16054
+ if (!(payload.value instanceof cls)) {
16055
+ payload.issues.push({
16056
+ code: "invalid_type",
16057
+ expected: cls.name,
16058
+ input: payload.value,
16059
+ inst,
16060
+ path: [...inst._zod.def.path ?? []]
16061
+ });
16062
+ }
16063
+ };
16064
+ return inst;
16065
+ }
16026
16066
  var allFields = {
16027
16067
  salutation: {
16028
16068
  key: "salutation",
@@ -16209,6 +16249,16 @@ var allFields = {
16209
16249
  description: "",
16210
16250
  autocomplete: "off"
16211
16251
  },
16252
+ photo: {
16253
+ key: "photo",
16254
+ apiKey: "file",
16255
+ type: "file",
16256
+ label: "ticket.annual.personalization.form.photo",
16257
+ placeholder: "",
16258
+ description: "",
16259
+ autocomplete: "off",
16260
+ validator: _instanceof(File)
16261
+ },
16212
16262
  paymentMode: {
16213
16263
  key: "paymentMode",
16214
16264
  apiKey: "payment_mode_id",
@@ -16244,6 +16294,8 @@ function createField(data, required) {
16244
16294
  function defaultValue(fieldType) {
16245
16295
  if (fieldType === "checkbox") {
16246
16296
  return false;
16297
+ } else if (fieldType === "file") {
16298
+ return null;
16247
16299
  } else {
16248
16300
  return "";
16249
16301
  }
@@ -16252,7 +16304,8 @@ function validateField(field) {
16252
16304
  field.errors = [];
16253
16305
  if (!field.validator) {
16254
16306
  if (field.required) {
16255
- if (field.value === false || field.value === "") field.errors = field.value ? [] : [`common.fieldErrors.required`];
16307
+ const empty2 = field.value === false || field.value === "" || field.value === null || field.value === void 0;
16308
+ if (empty2) field.errors = [`common.fieldErrors.required`];
16256
16309
  }
16257
16310
  return;
16258
16311
  }
@@ -16359,6 +16412,33 @@ function AnnualTicketPersonalizationForm($$anchor, $$props) {
16359
16412
  if (!isValid2) {
16360
16413
  return;
16361
16414
  }
16415
+ if (details.ticketSale?.photo_mandatory === "mandatory") {
16416
+ const uploads = personalizationForms.map(async (detail, index2) => {
16417
+ const personalizationId = details.ticketSale.personalizations[index2].id;
16418
+ const photoField = detail.fields.find((f) => f.key === "photo");
16419
+ const file = photoField?.value;
16420
+ if (!(file instanceof File)) {
16421
+ return {
16422
+ ok: false,
16423
+ error: "ticket.annual.personalization.photo.missing"
16424
+ };
16425
+ }
16426
+ const result2 = await shop.uploadPersonalizationPhoto(token(), personalizationId, file);
16427
+ if (result2.error) {
16428
+ return {
16429
+ ok: false,
16430
+ error: result2.error.error ?? "ticket.annual.personalization.photo.upload_failed"
16431
+ };
16432
+ }
16433
+ return { ok: true, error: "" };
16434
+ });
16435
+ const results = await Promise.all(uploads);
16436
+ const firstFailure = results.find((r2) => !r2.ok);
16437
+ if (firstFailure) {
16438
+ form.details.apiErrors = [firstFailure.error];
16439
+ return;
16440
+ }
16441
+ }
16362
16442
  const body = {
16363
16443
  personalization: {
16364
16444
  ticket_sale_id: details.ticketSaleId,
@@ -16495,7 +16575,7 @@ class FormDetails {
16495
16575
  if (!Number.isNaN(+x) && x.trim() !== "") return +x;
16496
16576
  return x;
16497
16577
  }
16498
- const validFields = this.fields.filter((f) => f !== void 0).filter((f) => f.value !== "");
16578
+ const validFields = this.fields.filter((f) => f !== void 0).filter((f) => f.type !== "file").filter((f) => f.value !== "");
16499
16579
  const ret = Object.fromEntries(validFields.map((f) => [f.apiKey, coerce2(f.value)]));
16500
16580
  return ret;
16501
16581
  }
@@ -16955,8 +17035,8 @@ var root_5$2 = /* @__PURE__ */ from_html(`<s class="go-cart-item-price-original"
16955
17035
  var root_6$3 = /* @__PURE__ */ from_html(`<span class="go-cart-item-price-discounted"> </span>`);
16956
17036
  var root_7$4 = /* @__PURE__ */ from_html(`<span> </span>`);
16957
17037
  var root_9$4 = /* @__PURE__ */ from_html(`<option> </option>`);
16958
- var root_8$2 = /* @__PURE__ */ from_html(`<select class="go-cart-item-select"></select>`);
16959
- var root_10$2 = /* @__PURE__ */ from_html(`<li class="go-cart-item-remove"><button>⨉</button></li>`);
17038
+ var root_8$3 = /* @__PURE__ */ from_html(`<select class="go-cart-item-select"></select>`);
17039
+ var root_10$1 = /* @__PURE__ */ from_html(`<li class="go-cart-item-remove"><button>⨉</button></li>`);
16960
17040
  var root_1$i = /* @__PURE__ */ from_html(`<article class="go-cart-item-content"><ul><li class="go-cart-item-title-container"><!></li> <li class="go-cart-item-price"><!></li> <li class="go-cart-item-count"><!></li> <!> <li class="go-cart-item-sum"> </li></ul></article>`);
16961
17041
  function Item$1($$anchor, $$props) {
16962
17042
  push($$props, true);
@@ -17111,7 +17191,7 @@ function Item$1($$anchor, $$props) {
17111
17191
  append($$anchor3, span_2);
17112
17192
  };
17113
17193
  var alternate_2 = ($$anchor3) => {
17114
- var select = root_8$2();
17194
+ var select = root_8$3();
17115
17195
  select.__change = (e) => update(e.target);
17116
17196
  each(select, 21, () => generateQuantityOptions(get$2(capacity).min, get$2(capacity).max, { floor: 1 }), (q) => q.value, ($$anchor4, q) => {
17117
17197
  var option2 = root_9$4();
@@ -17140,7 +17220,7 @@ function Item$1($$anchor, $$props) {
17140
17220
  var node_5 = sibling(li_2, 2);
17141
17221
  {
17142
17222
  var consequent_4 = ($$anchor3) => {
17143
- var li_3 = root_10$2();
17223
+ var li_3 = root_10$1();
17144
17224
  var button = child(li_3);
17145
17225
  button.__click = del;
17146
17226
  reset(li_3);
@@ -17679,18 +17759,6 @@ function parseIds(ids) {
17679
17759
  const parsed = ids.split(",").map((id) => id.trim()).map(Number).filter((num) => !isNaN(num) && num > 0);
17680
17760
  return parsed.length > 0 ? parsed : void 0;
17681
17761
  }
17682
- function parseTokens(tokens, possibleTokens) {
17683
- if (!tokens) {
17684
- return void 0;
17685
- }
17686
- const parsed = tokens.split(",").map((token) => token.trim()).map(String).filter((token) => token.length > 0);
17687
- parsed.forEach((token) => {
17688
- if (!possibleTokens.includes(token)) {
17689
- throw new Error("(parseTokens) Invalid token: " + token);
17690
- }
17691
- });
17692
- return parsed.length > 0 ? parsed : void 0;
17693
- }
17694
17762
  var root_1$f = /* @__PURE__ */ from_html(`<button> </button>`);
17695
17763
  var root_2$o = /* @__PURE__ */ from_html(`<form id="donationForm" action="" novalidate=""><div class="donation-custom form-group"><label for="donation-custom-amount"> </label> <input class="form-control" id="donation-custom-amount" type="number" min="1"/></div></form>`);
17696
17764
  var root$8 = /* @__PURE__ */ from_html(`<div class="donation-selection"><h3> </h3> <div class="donation-options"></div> <!></div>`);
@@ -19166,7 +19234,7 @@ var isContentEditable = function isContentEditable2(node) {
19166
19234
  var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable");
19167
19235
  return attValue === "" || attValue === "true";
19168
19236
  };
19169
- var getCandidates = function getCandidates2(el, includeContainer, filter) {
19237
+ var getCandidates = function getCandidates2(el, includeContainer, filter2) {
19170
19238
  if (_isInert(el)) {
19171
19239
  return [];
19172
19240
  }
@@ -19174,7 +19242,7 @@ var getCandidates = function getCandidates2(el, includeContainer, filter) {
19174
19242
  if (includeContainer && matches.call(el, candidateSelector)) {
19175
19243
  candidates.unshift(el);
19176
19244
  }
19177
- candidates = candidates.filter(filter);
19245
+ candidates = candidates.filter(filter2);
19178
19246
  return candidates;
19179
19247
  };
19180
19248
  var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
@@ -31150,7 +31218,7 @@ create_custom_element(Date_picker_trigger, { ref: {}, onkeydown: {} }, [], [], {
31150
31218
  var root_4$4 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
31151
31219
  var root_9$2 = /* @__PURE__ */ from_html(`<!> <!> <!>`, 1);
31152
31220
  var root_11$3 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
31153
- var root_8$1 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
31221
+ var root_8$2 = /* @__PURE__ */ from_html(`<!> <!>`, 1);
31154
31222
  var root_1$b = /* @__PURE__ */ from_html(`<!> <!> <!>`, 1);
31155
31223
  function DatePicker_1($$anchor, $$props) {
31156
31224
  push($$props, true);
@@ -31295,7 +31363,7 @@ function DatePicker_1($$anchor, $$props) {
31295
31363
  const children = ($$anchor6, $$arg0) => {
31296
31364
  let months = () => $$arg0?.().months;
31297
31365
  let weekdays = () => $$arg0?.().weekdays;
31298
- var fragment_8 = root_8$1();
31366
+ var fragment_8 = root_8$2();
31299
31367
  var node_10 = first_child(fragment_8);
31300
31368
  component(node_10, () => Calendar_header, ($$anchor7, DatePicker_Header) => {
31301
31369
  DatePicker_Header($$anchor7, {
@@ -31455,17 +31523,19 @@ create_custom_element(
31455
31523
  var root_2$6 = /* @__PURE__ */ from_html(`<span class="go-field-star" aria-hidden="true">*</span>`);
31456
31524
  var root_1$a = /* @__PURE__ */ from_html(` <!>`, 1);
31457
31525
  var root_3$6 = /* @__PURE__ */ from_html(`<label><!></label> <input/>`, 1);
31458
- var root_4$3 = /* @__PURE__ */ from_html(`<label><input/> <span class="go-checkbox-label"><!></span></label>`);
31459
- var root_7$2 = /* @__PURE__ */ from_html(`<img src="" alt=""/> <option> </option>`, 1);
31460
- var root_6$1 = /* @__PURE__ */ from_html(`<option disabled hidden="" selected> </option> <!>`, 1);
31526
+ var root_5 = /* @__PURE__ */ from_html(`<figure role="status" aria-live="polite"><img class="go-file-preview"/> <figcaption class="go-file-preview-caption"> </figcaption></figure>`);
31527
+ var root_4$3 = /* @__PURE__ */ from_html(`<label><!></label> <input/> <!>`, 1);
31528
+ var root_6$1 = /* @__PURE__ */ from_html(`<label><input/> <span class="go-checkbox-label"><!></span></label>`);
31529
+ var root_9$1 = /* @__PURE__ */ from_html(`<img src="" alt=""/> <option> </option>`, 1);
31530
+ var root_8$1 = /* @__PURE__ */ from_html(`<option disabled hidden="" selected> </option> <!>`, 1);
31461
31531
  var select_content = /* @__PURE__ */ from_html(`<!>`, 1);
31462
- var root_5 = /* @__PURE__ */ from_html(`<label><!></label> <select><!></select>`, 1);
31463
- var root_12$1 = /* @__PURE__ */ from_html(`<img style="width: 60px" aria-hidden="true"/>`);
31464
- var root_11$2 = /* @__PURE__ */ from_html(`<span class="go-payment-mode-icons"></span>`);
31465
- var root_10$1 = /* @__PURE__ */ from_html(`<label><input type="radio"/> <!></label>`);
31466
- var root_9$1 = /* @__PURE__ */ from_html(`<fieldset role="radiogroup"><legend><!></legend> <!></fieldset>`);
31467
- var root_15 = /* @__PURE__ */ from_html(`<label> <input/></label>`);
31468
- var root_13 = /* @__PURE__ */ from_html(`<fieldset><legend><!></legend> <!></fieldset>`);
31532
+ var root_7$2 = /* @__PURE__ */ from_html(`<label><!></label> <select><!></select>`, 1);
31533
+ var root_14 = /* @__PURE__ */ from_html(`<img style="width: 60px" aria-hidden="true"/>`);
31534
+ var root_13 = /* @__PURE__ */ from_html(`<span class="go-payment-mode-icons"></span>`);
31535
+ var root_12$1 = /* @__PURE__ */ from_html(`<label><input type="radio"/> <!></label>`);
31536
+ var root_11$2 = /* @__PURE__ */ from_html(`<fieldset role="radiogroup"><legend><!></legend> <!></fieldset>`);
31537
+ var root_17 = /* @__PURE__ */ from_html(`<label> <input/></label>`);
31538
+ var root_15 = /* @__PURE__ */ from_html(`<fieldset><legend><!></legend> <!></fieldset>`);
31469
31539
  function InputAndLabel($$anchor, $$props) {
31470
31540
  push($$props, true);
31471
31541
  const labelText = ($$anchor2) => {
@@ -31515,11 +31585,73 @@ function InputAndLabel($$anchor, $$props) {
31515
31585
  bind_value(input_1, () => field().value, ($$value) => field(field().value = $$value, true));
31516
31586
  append($$anchor2, fragment_1);
31517
31587
  };
31518
- const checkbox = ($$anchor2) => {
31519
- var label_2 = root_4$3();
31520
- var input_2 = child(label_2);
31588
+ const file = ($$anchor2) => {
31589
+ var fragment_2 = root_4$3();
31590
+ var label_2 = first_child(fragment_2);
31591
+ var node_2 = child(label_2);
31592
+ labelText(node_2);
31593
+ reset(label_2);
31594
+ var input_2 = sibling(label_2, 2);
31595
+ var event_handler = (e) => {
31596
+ const files = e.currentTarget.files;
31597
+ field(field().value = files && files[0] ? files[0] : null, true);
31598
+ if (get$2(details)) get$2(details).validateField(field());
31599
+ else field().validate();
31600
+ };
31521
31601
  attribute_effect(
31522
31602
  input_2,
31603
+ () => ({
31604
+ ...get$2(fieldAttributes),
31605
+ ...restProps,
31606
+ class: inputClass(),
31607
+ type: "file",
31608
+ accept: "image/*",
31609
+ name: field().key,
31610
+ onchange: event_handler
31611
+ }),
31612
+ void 0,
31613
+ void 0,
31614
+ void 0,
31615
+ void 0,
31616
+ true
31617
+ );
31618
+ var node_3 = sibling(input_2, 2);
31619
+ {
31620
+ var consequent_1 = ($$anchor3) => {
31621
+ var figure = root_5();
31622
+ var img = child(figure);
31623
+ var figcaption = sibling(img, 2);
31624
+ var text_1 = child(figcaption, true);
31625
+ reset(figcaption);
31626
+ reset(figure);
31627
+ template_effect(
31628
+ ($0) => {
31629
+ set_attribute(figure, "data-field-preview", field().key);
31630
+ set_attribute(img, "src", get$2(filePreviewUrl));
31631
+ set_attribute(img, "alt", $0);
31632
+ set_text(text_1, field().value.name);
31633
+ },
31634
+ [
31635
+ () => shop.t("forms.file.preview_alt") || "User uploaded photo"
31636
+ ]
31637
+ );
31638
+ append($$anchor3, figure);
31639
+ };
31640
+ if_block(node_3, ($$render) => {
31641
+ if (get$2(filePreviewUrl) && field().value instanceof File) $$render(consequent_1);
31642
+ });
31643
+ }
31644
+ template_effect(() => {
31645
+ set_class(label_2, 1, clsx(labelClass()));
31646
+ set_attribute(label_2, "for", get$2(inputId));
31647
+ });
31648
+ append($$anchor2, fragment_2);
31649
+ };
31650
+ const checkbox = ($$anchor2) => {
31651
+ var label_3 = root_6$1();
31652
+ var input_3 = child(label_3);
31653
+ attribute_effect(
31654
+ input_3,
31523
31655
  () => ({
31524
31656
  ...get$2(fieldAttributes),
31525
31657
  ...restProps,
@@ -31533,17 +31665,17 @@ function InputAndLabel($$anchor, $$props) {
31533
31665
  void 0,
31534
31666
  true
31535
31667
  );
31536
- var span_1 = sibling(input_2, 2);
31537
- var node_2 = child(span_1);
31538
- labelText(node_2);
31668
+ var span_1 = sibling(input_3, 2);
31669
+ var node_4 = child(span_1);
31670
+ labelText(node_4);
31539
31671
  reset(span_1);
31540
- reset(label_2);
31672
+ reset(label_3);
31541
31673
  template_effect(() => {
31542
- set_class(label_2, 1, clsx(labelClass()));
31543
- set_attribute(label_2, "for", get$2(inputId));
31674
+ set_class(label_3, 1, clsx(labelClass()));
31675
+ set_attribute(label_3, "for", get$2(inputId));
31544
31676
  });
31545
31677
  bind_checked(
31546
- input_2,
31678
+ input_3,
31547
31679
  () => {
31548
31680
  return field().value === true;
31549
31681
  },
@@ -31551,15 +31683,15 @@ function InputAndLabel($$anchor, $$props) {
31551
31683
  field(field().value = value, true);
31552
31684
  }
31553
31685
  );
31554
- append($$anchor2, label_2);
31686
+ append($$anchor2, label_3);
31555
31687
  };
31556
31688
  const select = ($$anchor2) => {
31557
- var fragment_2 = root_5();
31558
- var label_3 = first_child(fragment_2);
31559
- var node_3 = child(label_3);
31560
- labelText(node_3);
31561
- reset(label_3);
31562
- var select_1 = sibling(label_3, 2);
31689
+ var fragment_3 = root_7$2();
31690
+ var label_4 = first_child(fragment_3);
31691
+ var node_5 = child(label_4);
31692
+ labelText(node_5);
31693
+ reset(label_4);
31694
+ var select_1 = sibling(label_4, 2);
31563
31695
  attribute_effect(select_1, () => ({
31564
31696
  ...get$2(fieldAttributes),
31565
31697
  ...restProps,
@@ -31568,45 +31700,45 @@ function InputAndLabel($$anchor, $$props) {
31568
31700
  }));
31569
31701
  customizable_select(select_1, () => {
31570
31702
  var anchor = child(select_1);
31571
- var fragment_3 = select_content();
31572
- var node_4 = first_child(fragment_3);
31703
+ var fragment_4 = select_content();
31704
+ var node_6 = first_child(fragment_4);
31573
31705
  {
31574
- var consequent_1 = ($$anchor3) => {
31575
- var fragment_4 = root_6$1();
31576
- var option_1 = first_child(fragment_4);
31577
- var text_1 = child(option_1, true);
31706
+ var consequent_2 = ($$anchor3) => {
31707
+ var fragment_5 = root_8$1();
31708
+ var option_1 = first_child(fragment_5);
31709
+ var text_2 = child(option_1, true);
31578
31710
  reset(option_1);
31579
31711
  option_1.value = option_1.__value = "";
31580
- var node_5 = sibling(option_1, 2);
31581
- each(node_5, 17, () => field().options(), (option2) => option2.value, ($$anchor4, option2) => {
31582
- var fragment_5 = root_7$2();
31583
- var option_2 = sibling(first_child(fragment_5), 2);
31584
- var text_2 = child(option_2, true);
31712
+ var node_7 = sibling(option_1, 2);
31713
+ each(node_7, 17, () => field().options(), (option2) => option2.value, ($$anchor4, option2) => {
31714
+ var fragment_6 = root_9$1();
31715
+ var option_2 = sibling(first_child(fragment_6), 2);
31716
+ var text_3 = child(option_2, true);
31585
31717
  reset(option_2);
31586
31718
  var option_2_value = {};
31587
31719
  template_effect(() => {
31588
- set_text(text_2, get$2(option2).label);
31720
+ set_text(text_3, get$2(option2).label);
31589
31721
  if (option_2_value !== (option_2_value = get$2(option2).value)) {
31590
31722
  option_2.value = (option_2.__value = get$2(option2).value) ?? "";
31591
31723
  }
31592
31724
  });
31593
- append($$anchor4, fragment_5);
31725
+ append($$anchor4, fragment_6);
31594
31726
  });
31595
- template_effect(($0) => set_text(text_1, $0), [() => shop.t("common.choose")]);
31596
- append($$anchor3, fragment_4);
31727
+ template_effect(($0) => set_text(text_2, $0), [() => shop.t("common.choose")]);
31728
+ append($$anchor3, fragment_5);
31597
31729
  };
31598
- if_block(node_4, ($$render) => {
31599
- if (field().options) $$render(consequent_1);
31730
+ if_block(node_6, ($$render) => {
31731
+ if (field().options) $$render(consequent_2);
31600
31732
  });
31601
31733
  }
31602
- append(anchor, fragment_3);
31734
+ append(anchor, fragment_4);
31603
31735
  });
31604
31736
  template_effect(() => {
31605
- set_class(label_3, 1, clsx(labelClass()));
31606
- set_attribute(label_3, "for", get$2(inputId));
31737
+ set_class(label_4, 1, clsx(labelClass()));
31738
+ set_attribute(label_4, "for", get$2(inputId));
31607
31739
  });
31608
31740
  bind_select_value(select_1, () => field().value, ($$value) => field(field().value = $$value, true));
31609
- append($$anchor2, fragment_2);
31741
+ append($$anchor2, fragment_3);
31610
31742
  };
31611
31743
  const date2 = ($$anchor2) => {
31612
31744
  DatePicker_1($$anchor2, {
@@ -31629,48 +31761,48 @@ function InputAndLabel($$anchor, $$props) {
31629
31761
  };
31630
31762
  const paymentMode = ($$anchor2) => {
31631
31763
  const modes = /* @__PURE__ */ user_derived(() => shop.payment_modes ? Object.values(shop.payment_modes) : []);
31632
- var fieldset = root_9$1();
31764
+ var fieldset = root_11$2();
31633
31765
  var legend = child(fieldset);
31634
- var node_6 = child(legend);
31635
- labelText(node_6);
31766
+ var node_8 = child(legend);
31767
+ labelText(node_8);
31636
31768
  reset(legend);
31637
- var node_7 = sibling(legend, 2);
31638
- each(node_7, 17, () => get$2(modes), (mode) => mode.id, ($$anchor3, mode) => {
31639
- var label_4 = root_10$1();
31640
- var input_3 = child(label_4);
31641
- remove_input_defaults(input_3);
31642
- input_3.__change = () => {
31769
+ var node_9 = sibling(legend, 2);
31770
+ each(node_9, 17, () => get$2(modes), (mode) => mode.id, ($$anchor3, mode) => {
31771
+ var label_5 = root_12$1();
31772
+ var input_4 = child(label_5);
31773
+ remove_input_defaults(input_4);
31774
+ input_4.__change = () => {
31643
31775
  field(field().value = String(get$2(mode).id), true);
31644
31776
  };
31645
- var node_8 = sibling(input_3, 2);
31777
+ var node_10 = sibling(input_4, 2);
31646
31778
  {
31647
- var consequent_2 = ($$anchor4) => {
31648
- var span_2 = root_11$2();
31779
+ var consequent_3 = ($$anchor4) => {
31780
+ var span_2 = root_13();
31649
31781
  each(span_2, 20, () => get$2(mode).icons, (icon) => icon, ($$anchor5, icon) => {
31650
31782
  const url = /* @__PURE__ */ user_derived(() => CDN_PATH + icon + ".svg");
31651
- var img = root_12$1();
31783
+ var img_1 = root_14();
31652
31784
  template_effect(() => {
31653
- set_class(img, 1, clsx(icon));
31654
- set_attribute(img, "src", get$2(url));
31655
- set_attribute(img, "alt", icon + " icon");
31785
+ set_class(img_1, 1, clsx(icon));
31786
+ set_attribute(img_1, "src", get$2(url));
31787
+ set_attribute(img_1, "alt", icon + " icon");
31656
31788
  });
31657
- append($$anchor5, img);
31789
+ append($$anchor5, img_1);
31658
31790
  });
31659
31791
  reset(span_2);
31660
31792
  append($$anchor4, span_2);
31661
31793
  };
31662
- if_block(node_8, ($$render) => {
31663
- if (get$2(mode).icons.length > 0) $$render(consequent_2);
31794
+ if_block(node_10, ($$render) => {
31795
+ if (get$2(mode).icons.length > 0) $$render(consequent_3);
31664
31796
  });
31665
31797
  }
31666
- reset(label_4);
31798
+ reset(label_5);
31667
31799
  template_effect(
31668
31800
  ($0, $1, $2) => {
31669
- set_attribute(input_3, "name", field().key);
31670
- set_value(input_3, $0);
31671
- set_checked(input_3, $1);
31672
- set_attribute(input_3, "hidden", get$2(modes).length === 1);
31673
- set_attribute(input_3, "aria-label", $2);
31801
+ set_attribute(input_4, "name", field().key);
31802
+ set_value(input_4, $0);
31803
+ set_checked(input_4, $1);
31804
+ set_attribute(input_4, "hidden", get$2(modes).length === 1);
31805
+ set_attribute(input_4, "aria-label", $2);
31674
31806
  },
31675
31807
  [
31676
31808
  () => String(get$2(mode).id),
@@ -31678,7 +31810,7 @@ function InputAndLabel($$anchor, $$props) {
31678
31810
  () => shop.t(`cart.paymentMode.ariaLabel.${get$2(mode).name.toLowerCase()}`)
31679
31811
  ]
31680
31812
  );
31681
- append($$anchor3, label_4);
31813
+ append($$anchor3, label_5);
31682
31814
  });
31683
31815
  reset(fieldset);
31684
31816
  template_effect(() => {
@@ -31688,22 +31820,22 @@ function InputAndLabel($$anchor, $$props) {
31688
31820
  append($$anchor2, fieldset);
31689
31821
  };
31690
31822
  const radio = ($$anchor2) => {
31691
- var fieldset_1 = root_13();
31823
+ var fieldset_1 = root_15();
31692
31824
  var legend_1 = child(fieldset_1);
31693
- var node_9 = child(legend_1);
31694
- labelText(node_9);
31825
+ var node_11 = child(legend_1);
31826
+ labelText(node_11);
31695
31827
  reset(legend_1);
31696
- var node_10 = sibling(legend_1, 2);
31828
+ var node_12 = sibling(legend_1, 2);
31697
31829
  {
31698
- var consequent_3 = ($$anchor3) => {
31699
- var fragment_7 = comment();
31700
- var node_11 = first_child(fragment_7);
31701
- each(node_11, 17, () => field().options, index$1, ($$anchor4, option2) => {
31702
- var label_5 = root_15();
31703
- var text_3 = child(label_5);
31704
- var input_4 = sibling(text_3);
31830
+ var consequent_4 = ($$anchor3) => {
31831
+ var fragment_8 = comment();
31832
+ var node_13 = first_child(fragment_8);
31833
+ each(node_13, 17, () => field().options, index$1, ($$anchor4, option2) => {
31834
+ var label_6 = root_17();
31835
+ var text_4 = child(label_6);
31836
+ var input_5 = sibling(text_4);
31705
31837
  attribute_effect(
31706
- input_4,
31838
+ input_5,
31707
31839
  () => ({
31708
31840
  ...get$2(fieldAttributes),
31709
31841
  ...restProps,
@@ -31716,19 +31848,19 @@ function InputAndLabel($$anchor, $$props) {
31716
31848
  void 0,
31717
31849
  true
31718
31850
  );
31719
- reset(label_5);
31851
+ reset(label_6);
31720
31852
  template_effect(() => {
31721
- set_class(label_5, 1, clsx(labelClass()));
31722
- set_attribute(label_5, "for", get$2(inputId) + get$2(option2));
31723
- set_text(text_3, `${get$2(option2) ?? ""} `);
31853
+ set_class(label_6, 1, clsx(labelClass()));
31854
+ set_attribute(label_6, "for", get$2(inputId) + get$2(option2));
31855
+ set_text(text_4, `${get$2(option2) ?? ""} `);
31724
31856
  });
31725
- bind_value(input_4, () => field().value, ($$value) => field(field().value = $$value, true));
31726
- append($$anchor4, label_5);
31857
+ bind_value(input_5, () => field().value, ($$value) => field(field().value = $$value, true));
31858
+ append($$anchor4, label_6);
31727
31859
  });
31728
- append($$anchor3, fragment_7);
31860
+ append($$anchor3, fragment_8);
31729
31861
  };
31730
- if_block(node_10, ($$render) => {
31731
- if (field().options) $$render(consequent_3);
31862
+ if_block(node_12, ($$render) => {
31863
+ if (field().options) $$render(consequent_4);
31732
31864
  });
31733
31865
  }
31734
31866
  reset(fieldset_1);
@@ -31760,6 +31892,7 @@ function InputAndLabel($$anchor, $$props) {
31760
31892
  select,
31761
31893
  radio,
31762
31894
  date: date2,
31895
+ file,
31763
31896
  textarea: null,
31764
31897
  paymentMode
31765
31898
  };
@@ -31781,6 +31914,19 @@ function InputAndLabel($$anchor, $$props) {
31781
31914
  }));
31782
31915
  let label = /* @__PURE__ */ user_derived(() => shop.t(field().label) || field().label);
31783
31916
  const CDN_PATH = `https://cdn.shop.platform.gomus.de/`;
31917
+ let filePreviewUrl = /* @__PURE__ */ state(null);
31918
+ user_effect(() => {
31919
+ const value = field().value;
31920
+ if (value instanceof File && value.type.startsWith("image/")) {
31921
+ const url = URL.createObjectURL(value);
31922
+ set(filePreviewUrl, url, true);
31923
+ return () => {
31924
+ URL.revokeObjectURL(url);
31925
+ set(filePreviewUrl, null);
31926
+ };
31927
+ }
31928
+ set(filePreviewUrl, null);
31929
+ });
31784
31930
  var $$exports = {
31785
31931
  get field() {
31786
31932
  return field();
@@ -31818,20 +31964,20 @@ function InputAndLabel($$anchor, $$props) {
31818
31964
  flushSync();
31819
31965
  }
31820
31966
  };
31821
- var fragment_8 = comment();
31822
- var node_12 = first_child(fragment_8);
31967
+ var fragment_9 = comment();
31968
+ var node_14 = first_child(fragment_9);
31823
31969
  {
31824
- var consequent_4 = ($$anchor2) => {
31825
- var fragment_9 = comment();
31826
- var node_13 = first_child(fragment_9);
31827
- snippet(node_13, () => get$2(snippet$1));
31828
- append($$anchor2, fragment_9);
31970
+ var consequent_5 = ($$anchor2) => {
31971
+ var fragment_10 = comment();
31972
+ var node_15 = first_child(fragment_10);
31973
+ snippet(node_15, () => get$2(snippet$1));
31974
+ append($$anchor2, fragment_10);
31829
31975
  };
31830
- if_block(node_12, ($$render) => {
31831
- if (get$2(snippet$1)) $$render(consequent_4);
31976
+ if_block(node_14, ($$render) => {
31977
+ if (get$2(snippet$1)) $$render(consequent_5);
31832
31978
  });
31833
31979
  }
31834
- append($$anchor, fragment_8);
31980
+ append($$anchor, fragment_9);
31835
31981
  return pop($$exports);
31836
31982
  }
31837
31983
  delegate(["change"]);
@@ -33826,24 +33972,507 @@ function evaluateExpression(expression, data) {
33826
33972
  console.error(`Error while evaluating when (${expression}) in go-if: ${error.message}`);
33827
33973
  }
33828
33974
  }
33829
- const validTicketSelectionFilters = [
33830
- "timeslot",
33831
- "day",
33832
- "annual",
33833
- "event:scaled-price",
33834
- "event:ticket",
33835
- "events:scaled-price"
33975
+ const FILTER_NAMES = [
33976
+ "ticket:timeslot",
33977
+ "ticket:day",
33978
+ "ticket:annual",
33979
+ "event:admission",
33980
+ "event:admission:day",
33981
+ "event:admission:timeslot",
33982
+ "event:price",
33983
+ "events:admission",
33984
+ "events:admission:day",
33985
+ "events:admission:timeslot",
33986
+ "events:price"
33836
33987
  ];
33988
+ const filter$a = {
33989
+ name: "ticket:timeslot",
33990
+ calendarEndpoint: "tickets",
33991
+ apiToken: "time_slot",
33992
+ requires: [
33993
+ { kind: "tsd", field: "selectedDate" },
33994
+ { kind: "tsd", field: "selectedTimeslot" }
33995
+ ],
33996
+ isCalendarVisible: () => true,
33997
+ isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
33998
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
33999
+ async loadTimeslots(tsd) {
34000
+ if (!tsd?.selectedDate) return;
34001
+ const { quotas } = await shop.asyncFetch(
34002
+ () => shop.ticketsAndQuotas({
34003
+ by_bookable: true,
34004
+ valid_at: tsd.selectedDate.toString(),
34005
+ // @ts-ignore
34006
+ by_ticket_type: "time_slot",
34007
+ "by_museum_ids[]": tsd.museumIds,
34008
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34009
+ "by_ticket_ids[]": tsd.ticketIds,
34010
+ "by_ticket_group_ids[]": tsd.ticketGroupIds
34011
+ })
34012
+ );
34013
+ shop.capacityManager.addQuotas(quotas);
34014
+ },
34015
+ async loadProducts(segment) {
34016
+ const tsd = segment.ticketSelectionDetails;
34017
+ if (!tsd?.selectedDate || !tsd.selectedTimeslot) return;
34018
+ const { tickets, quotas } = await shop.asyncFetch(
34019
+ () => shop.ticketsAndQuotas({
34020
+ by_bookable: true,
34021
+ valid_at: tsd.selectedDate.toString(),
34022
+ // @ts-ignore
34023
+ by_ticket_type: "time_slot",
34024
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
34025
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34026
+ "by_ticket_ids[]": tsd.ticketIds,
34027
+ "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
34028
+ })
34029
+ );
34030
+ shop.capacityManager.addQuotas(quotas);
34031
+ const available = filterAvailabletickets(tickets, tsd.selectedTime);
34032
+ const uiTickets = initUITimeslotTickets(available, tsd.selectedTime);
34033
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
34034
+ }
34035
+ };
34036
+ const filter$9 = {
34037
+ name: "ticket:day",
34038
+ calendarEndpoint: "tickets",
34039
+ apiToken: "normal",
34040
+ requires: [{ kind: "tsd", field: "selectedDate" }],
34041
+ isCalendarVisible: () => true,
34042
+ isTimeslotsVisible: () => false,
34043
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate),
34044
+ async loadTimeslots() {
34045
+ },
34046
+ async loadProducts(segment) {
34047
+ const tsd = segment.ticketSelectionDetails;
34048
+ if (!tsd?.selectedDate) return;
34049
+ const { tickets, quotas } = await shop.asyncFetch(
34050
+ () => shop.ticketsAndQuotas({
34051
+ by_bookable: true,
34052
+ valid_at: tsd.selectedDate.toString(),
34053
+ // @ts-ignore
34054
+ "by_ticket_types[]": ["normal"],
34055
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
34056
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34057
+ "by_ticket_ids[]": tsd.ticketIds,
34058
+ "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
34059
+ })
34060
+ );
34061
+ shop.capacityManager.addQuotas(quotas);
34062
+ const firstQuota = Object.values(quotas)[0];
34063
+ const timeslot = firstQuota ? Object.keys(firstQuota.capacities)[0] : void 0;
34064
+ const available = filterAvailabletickets(tickets, timeslot);
34065
+ const uiTickets = initUITimeslotTickets(available, timeslot);
34066
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: timeslot }));
34067
+ }
34068
+ };
34069
+ const filter$8 = {
34070
+ name: "ticket:annual",
34071
+ calendarEndpoint: null,
34072
+ apiToken: "annual",
34073
+ requires: [],
34074
+ isCalendarVisible: () => false,
34075
+ isTimeslotsVisible: () => false,
34076
+ isTicketsVisible: () => true,
34077
+ async loadTimeslots() {
34078
+ },
34079
+ async loadProducts(segment) {
34080
+ const tsd = segment.ticketSelectionDetails;
34081
+ if (!tsd) return;
34082
+ const tickets = await shop.asyncFetch(
34083
+ () => shop.tickets({
34084
+ by_bookable: true,
34085
+ // @ts-ignore
34086
+ "by_ticket_types[]": ["annual"],
34087
+ "by_ticket_ids[]": tsd.ticketIds,
34088
+ "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
34089
+ })
34090
+ );
34091
+ for (const t of Object.values(tickets)) {
34092
+ segment.preCart.addItem(createCartItem(createUITicket(t)));
34093
+ }
34094
+ }
34095
+ };
34096
+ const filter$7 = {
34097
+ name: "event:admission",
34098
+ calendarEndpoint: "events",
34099
+ requires: [
34100
+ { kind: "tsd", field: "eventIds" },
34101
+ { kind: "tsd", field: "selectedDate" }
34102
+ ],
34103
+ isCalendarVisible: () => true,
34104
+ isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
34105
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
34106
+ async loadTimeslots(tsd) {
34107
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
34108
+ const event2 = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
34109
+ if (!event2.tickets?.length) return;
34110
+ const { quotas } = await shop.asyncFetch(
34111
+ () => shop.ticketsAndQuotas({
34112
+ "by_ticket_ids[]": event2.tickets,
34113
+ by_bookable: true,
34114
+ valid_at: tsd.selectedDate.toString()
34115
+ })
34116
+ );
34117
+ shop.capacityManager.addQuotas(quotas);
34118
+ },
34119
+ async loadProducts(segment) {
34120
+ const tsd = segment.ticketSelectionDetails;
34121
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
34122
+ const event2 = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
34123
+ if (!event2.tickets?.length) return;
34124
+ const { tickets, quotas } = await shop.asyncFetch(
34125
+ () => shop.ticketsAndQuotas({
34126
+ by_bookable: true,
34127
+ valid_at: tsd.selectedDate.toString(),
34128
+ date_id: segment.dateId
34129
+ })
34130
+ );
34131
+ shop.capacityManager.addQuotas(quotas);
34132
+ const available = filterAvailabletickets(tickets, tsd.selectedTime);
34133
+ const uiTickets = initUITimeslotTickets(available, tsd.selectedTime);
34134
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
34135
+ }
34136
+ };
34137
+ const filter$6 = {
34138
+ name: "event:admission:day",
34139
+ calendarEndpoint: "events",
34140
+ requires: [
34141
+ { kind: "tsd", field: "eventIds" },
34142
+ { kind: "tsd", field: "selectedDate" }
34143
+ ],
34144
+ isCalendarVisible: () => true,
34145
+ isTimeslotsVisible: () => false,
34146
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate),
34147
+ async loadTimeslots() {
34148
+ },
34149
+ async loadProducts(segment) {
34150
+ const tsd = segment.ticketSelectionDetails;
34151
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
34152
+ const event2 = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
34153
+ if (!event2.tickets?.length) return;
34154
+ const { tickets, quotas } = await shop.asyncFetch(
34155
+ () => shop.ticketsAndQuotas({
34156
+ "by_ticket_ids[]": event2.tickets,
34157
+ // @ts-ignore — backend has_scope :by_ticket_types accepts ('normal' | 'time_slot' | 'annual')[]
34158
+ "by_ticket_types[]": ["normal"],
34159
+ by_bookable: true,
34160
+ valid_at: tsd.selectedDate.toString()
34161
+ })
34162
+ );
34163
+ shop.capacityManager.addQuotas(quotas);
34164
+ const firstQuota = Object.values(quotas)[0];
34165
+ const time2 = firstQuota ? Object.keys(firstQuota.capacities)[0] : void 0;
34166
+ const available = filterAvailabletickets(tickets, time2);
34167
+ const uiTickets = initUITimeslotTickets(available, time2);
34168
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: time2 }));
34169
+ }
34170
+ };
34171
+ const filter$5 = {
34172
+ name: "event:admission:timeslot",
34173
+ calendarEndpoint: "events",
34174
+ requires: [
34175
+ { kind: "tsd", field: "eventIds" },
34176
+ { kind: "tsd", field: "selectedDate" },
34177
+ { kind: "tsd", field: "selectedTimeslot" }
34178
+ ],
34179
+ isCalendarVisible: () => true,
34180
+ isTimeslotsVisible: (tsd) => Boolean(tsd.selectedDate),
34181
+ isTicketsVisible: (tsd) => Boolean(tsd.selectedDate && tsd.selectedTimeslot),
34182
+ async loadTimeslots(tsd) {
34183
+ if (!tsd?.eventIds?.length || !tsd.selectedDate) return;
34184
+ const event2 = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
34185
+ if (!event2.tickets?.length) return;
34186
+ const { quotas } = await shop.asyncFetch(
34187
+ () => shop.ticketsAndQuotas({
34188
+ "by_ticket_ids[]": event2.tickets,
34189
+ // @ts-ignore — backend has_scope :by_ticket_type accepts 'time_slot' | 'normal' | 'annual'
34190
+ by_ticket_type: "time_slot",
34191
+ by_bookable: true,
34192
+ valid_at: tsd.selectedDate.toString()
34193
+ })
34194
+ );
34195
+ shop.capacityManager.addQuotas(quotas);
34196
+ },
34197
+ async loadProducts(segment) {
34198
+ const tsd = segment.ticketSelectionDetails;
34199
+ if (!tsd?.eventIds?.length || !tsd.selectedDate || !tsd.selectedTimeslot) return;
34200
+ const event2 = await shop.asyncFetch(() => shop.getEvent(tsd.eventIds[0]));
34201
+ if (!event2.tickets?.length) return;
34202
+ const { tickets, quotas } = await shop.asyncFetch(
34203
+ () => shop.ticketsAndQuotas({
34204
+ "by_ticket_ids[]": event2.tickets,
34205
+ // @ts-ignore
34206
+ by_ticket_type: "time_slot",
34207
+ by_bookable: true,
34208
+ valid_at: tsd.selectedDate.toString()
34209
+ })
34210
+ );
34211
+ shop.capacityManager.addQuotas(quotas);
34212
+ const available = filterAvailabletickets(tickets, tsd.selectedTime);
34213
+ const uiTickets = initUITimeslotTickets(available, tsd.selectedTime);
34214
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: tsd.selectedTime }));
34215
+ }
34216
+ };
34217
+ const filter$4 = {
34218
+ name: "event:price",
34219
+ calendarEndpoint: "events",
34220
+ requires: [
34221
+ { kind: "tsd", field: "eventIds" },
34222
+ { kind: "segment", field: "dateId" }
34223
+ ],
34224
+ isCalendarVisible: () => false,
34225
+ isTimeslotsVisible: () => false,
34226
+ isTicketsVisible: (tsd) => Boolean(tsd.eventIds?.length),
34227
+ loadTimeslots: async () => {
34228
+ },
34229
+ async loadProducts(segment) {
34230
+ const tsd = segment.ticketSelectionDetails;
34231
+ if (!tsd?.eventIds?.length || segment.dateId === void 0) return;
34232
+ const date2 = await shop.asyncFetch(() => shop.getEventDetailsOnDate(tsd.eventIds[0], segment.dateId));
34233
+ if (!date2.prices?.length) return;
34234
+ for (const price of date2.prices) {
34235
+ const ticket = createUIEventTicket(price, date2.id, { event_title: date2.event_title });
34236
+ segment.preCart.addItem(createCartItem(ticket, { time: date2.start_time }));
34237
+ }
34238
+ if (date2.seats) shop.capacityManager.addSeats(date2.id, date2.seats);
34239
+ }
34240
+ };
34241
+ const TWO_HOURS_MS = 2 * 60 * 60 * 1e3;
34242
+ function filterDatesInWindow(dates, selectedDate, selectedTime) {
34243
+ const selectedMs = Date.parse(selectedTime);
34244
+ return dates.filter((d) => {
34245
+ const datePart = d.start_time.slice(0, 10);
34246
+ const startMs = Date.parse(d.start_time);
34247
+ return datePart === selectedDate && startMs >= selectedMs && startMs <= selectedMs + TWO_HOURS_MS && (d.seats?.available ?? 0) > 0;
34248
+ });
34249
+ }
34250
+ async function loadEventsTimeslots(tsd) {
34251
+ if (!tsd?.selectedDate) return;
34252
+ const { quotas } = await shop.asyncFetch(
34253
+ () => shop.ticketsAndQuotas({
34254
+ by_bookable: true,
34255
+ valid_at: tsd.selectedDate.toString(),
34256
+ // @ts-ignore
34257
+ "by_ticket_types[]": ["time_slot"],
34258
+ "by_museum_ids[]": tsd.museumIds,
34259
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34260
+ "by_ticket_ids[]": tsd.ticketIds,
34261
+ "by_ticket_group_ids[]": tsd.ticketGroupIds
34262
+ })
34263
+ );
34264
+ shop.capacityManager.addQuotas(quotas);
34265
+ }
34266
+ const filter$3 = {
34267
+ name: "events:admission",
34268
+ calendarEndpoint: "events",
34269
+ requires: [
34270
+ { kind: "tsd", field: "selectedDate" },
34271
+ { kind: "tsd", field: "selectedTimeslot" }
34272
+ ],
34273
+ isCalendarVisible: () => true,
34274
+ isTimeslotsVisible: () => true,
34275
+ isTicketsVisible: () => true,
34276
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
34277
+ async loadProducts(segment) {
34278
+ const tsd = segment.ticketSelectionDetails;
34279
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
34280
+ const all = await shop.asyncFetch(
34281
+ () => shop.getDates({
34282
+ by_bookable: true,
34283
+ // @ts-ignore — bracketed array params are accepted by API
34284
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
34285
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34286
+ "by_event_ids[]": tsd.eventIds,
34287
+ "by_language_ids[]": segment.languageIds,
34288
+ "by_catch_word_ids[]": segment.catchWordIds,
34289
+ start_at: tsd.selectedDate.toString(),
34290
+ per_page: segment.limit || 30
34291
+ })
34292
+ );
34293
+ const dates = filterDatesInWindow(all, tsd.selectedDate.toString(), tsd.selectedTime);
34294
+ for (const date2 of dates) {
34295
+ if (!date2.event_id || !date2.start_time) continue;
34296
+ const event2 = await shop.asyncFetch(() => shop.getEvent(date2.event_id));
34297
+ if (!event2?.tickets?.length) continue;
34298
+ const { tickets, quotas } = await shop.asyncFetch(
34299
+ () => shop.ticketsAndQuotas({
34300
+ "by_ticket_ids[]": event2.tickets,
34301
+ by_bookable: true,
34302
+ valid_at: date2.start_time.slice(0, 10)
34303
+ })
34304
+ );
34305
+ shop.capacityManager.addQuotas(quotas);
34306
+ const available = filterAvailabletickets(tickets, date2.start_time);
34307
+ const uiTickets = initUITimeslotTickets(available, date2.start_time);
34308
+ for (const ticket of uiTickets) segment.preCart.addItem(createCartItem(ticket, { time: date2.start_time }));
34309
+ }
34310
+ }
34311
+ };
34312
+ const filter$2 = {
34313
+ name: "events:admission:day",
34314
+ calendarEndpoint: "events",
34315
+ requires: [
34316
+ { kind: "tsd", field: "selectedDate" },
34317
+ { kind: "tsd", field: "selectedTimeslot" }
34318
+ ],
34319
+ isCalendarVisible: () => true,
34320
+ isTimeslotsVisible: () => true,
34321
+ isTicketsVisible: () => true,
34322
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
34323
+ async loadProducts(segment) {
34324
+ const tsd = segment.ticketSelectionDetails;
34325
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
34326
+ const all = await shop.asyncFetch(
34327
+ () => shop.getDates({
34328
+ by_bookable: true,
34329
+ // @ts-ignore — bracketed array params are accepted by API
34330
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
34331
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34332
+ "by_event_ids[]": tsd.eventIds,
34333
+ "by_language_ids[]": segment.languageIds,
34334
+ "by_catch_word_ids[]": segment.catchWordIds,
34335
+ start_at: tsd.selectedDate.toString(),
34336
+ per_page: segment.limit || 30
34337
+ })
34338
+ );
34339
+ const dates = filterDatesInWindow(all, tsd.selectedDate.toString(), tsd.selectedTime);
34340
+ for (const date2 of dates) {
34341
+ if (!date2.event_id || !date2.start_time) continue;
34342
+ const event2 = await shop.asyncFetch(() => shop.getEvent(date2.event_id));
34343
+ if (!event2?.tickets?.length) continue;
34344
+ const { tickets, quotas } = await shop.asyncFetch(
34345
+ () => shop.ticketsAndQuotas({
34346
+ "by_ticket_ids[]": event2.tickets,
34347
+ // @ts-ignore
34348
+ "by_ticket_types[]": ["normal"],
34349
+ by_bookable: true,
34350
+ valid_at: date2.start_time.slice(0, 10)
34351
+ })
34352
+ );
34353
+ shop.capacityManager.addQuotas(quotas);
34354
+ const firstQuota = Object.values(quotas)[0];
34355
+ const time2 = firstQuota ? Object.keys(firstQuota.capacities)[0] : date2.start_time;
34356
+ const available = filterAvailabletickets(tickets, time2);
34357
+ const uiTickets = initUITimeslotTickets(available, time2);
34358
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: time2 }));
34359
+ }
34360
+ }
34361
+ };
34362
+ const filter$1 = {
34363
+ name: "events:admission:timeslot",
34364
+ calendarEndpoint: "events",
34365
+ requires: [
34366
+ { kind: "tsd", field: "selectedDate" },
34367
+ { kind: "tsd", field: "selectedTimeslot" }
34368
+ ],
34369
+ isCalendarVisible: () => true,
34370
+ isTimeslotsVisible: () => true,
34371
+ isTicketsVisible: () => true,
34372
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
34373
+ async loadProducts(segment) {
34374
+ const tsd = segment.ticketSelectionDetails;
34375
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
34376
+ const all = await shop.asyncFetch(
34377
+ () => shop.getDates({
34378
+ by_bookable: true,
34379
+ // @ts-ignore — bracketed array params are accepted by API
34380
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
34381
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34382
+ "by_event_ids[]": tsd.eventIds,
34383
+ "by_language_ids[]": segment.languageIds,
34384
+ "by_catch_word_ids[]": segment.catchWordIds,
34385
+ start_at: tsd.selectedDate.toString(),
34386
+ per_page: segment.limit || 30
34387
+ })
34388
+ );
34389
+ const dates = filterDatesInWindow(all, tsd.selectedDate.toString(), tsd.selectedTime);
34390
+ for (const date2 of dates) {
34391
+ if (!date2.event_id || !date2.start_time) continue;
34392
+ const event2 = await shop.asyncFetch(() => shop.getEvent(date2.event_id));
34393
+ if (!event2?.tickets?.length) continue;
34394
+ const { tickets, quotas } = await shop.asyncFetch(
34395
+ () => shop.ticketsAndQuotas({
34396
+ "by_ticket_ids[]": event2.tickets,
34397
+ // @ts-ignore
34398
+ by_ticket_type: "time_slot",
34399
+ by_bookable: true,
34400
+ valid_at: date2.start_time.slice(0, 10)
34401
+ })
34402
+ );
34403
+ shop.capacityManager.addQuotas(quotas);
34404
+ const available = filterAvailabletickets(tickets, date2.start_time);
34405
+ const uiTickets = initUITimeslotTickets(available, date2.start_time);
34406
+ for (const t of uiTickets) segment.preCart.addItem(createCartItem(t, { time: date2.start_time }));
34407
+ }
34408
+ }
34409
+ };
34410
+ const filter = {
34411
+ name: "events:price",
34412
+ calendarEndpoint: "events",
34413
+ requires: [
34414
+ { kind: "tsd", field: "selectedDate" },
34415
+ { kind: "tsd", field: "selectedTimeslot" }
34416
+ ],
34417
+ isCalendarVisible: () => true,
34418
+ isTimeslotsVisible: () => true,
34419
+ isTicketsVisible: () => true,
34420
+ loadTimeslots: (tsd) => loadEventsTimeslots(tsd),
34421
+ async loadProducts(segment) {
34422
+ const tsd = segment.ticketSelectionDetails;
34423
+ if (!tsd?.selectedDate || !tsd.selectedTime) return;
34424
+ const all = await shop.asyncFetch(
34425
+ () => shop.getDates({
34426
+ by_bookable: true,
34427
+ // @ts-ignore — bracketed array params are accepted by API
34428
+ "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
34429
+ "by_exhibition_ids[]": tsd.exhibitionIds,
34430
+ "by_event_ids[]": tsd.eventIds,
34431
+ "by_language_ids[]": segment.languageIds,
34432
+ "by_catch_word_ids[]": segment.catchWordIds,
34433
+ start_at: tsd.selectedDate.toString(),
34434
+ per_page: segment.limit || 30
34435
+ })
34436
+ );
34437
+ const dates = filterDatesInWindow(all, tsd.selectedDate.toString(), tsd.selectedTime);
34438
+ const query = segment.query;
34439
+ for (const date2 of dates) {
34440
+ if (!date2.prices?.length) continue;
34441
+ const prices = query ? date2.prices.filter((p2) => p2.title?.includes(query)) : date2.prices;
34442
+ for (const price of prices) {
34443
+ const ticket = createUIEventTicket(price, date2.id, { event_title: date2.event_title });
34444
+ segment.preCart.addItem(createCartItem(ticket, { time: date2.start_time }));
34445
+ }
34446
+ if (date2.seats) shop.capacityManager.addSeats(date2.id, date2.seats);
34447
+ }
34448
+ }
34449
+ };
34450
+ const REGISTRY = {
34451
+ "ticket:timeslot": filter$a,
34452
+ "ticket:day": filter$9,
34453
+ "ticket:annual": filter$8,
34454
+ "event:admission": filter$7,
34455
+ "event:admission:day": filter$6,
34456
+ "event:admission:timeslot": filter$5,
34457
+ "event:price": filter$4,
34458
+ "events:admission": filter$3,
34459
+ "events:admission:day": filter$2,
34460
+ "events:admission:timeslot": filter$1,
34461
+ "events:price": filter
34462
+ };
34463
+ function getFilter(name) {
34464
+ const filter2 = REGISTRY[name];
34465
+ if (!filter2) {
34466
+ console.warn(
34467
+ `[ticket-selection] Unknown filter "${name}". Valid filters: ${FILTER_NAMES.join(", ")}`
34468
+ );
34469
+ }
34470
+ return filter2;
34471
+ }
34472
+ const validFilterNames = FILTER_NAMES;
33837
34473
  let lastUId = 0;
33838
34474
  class TicketSelectionDetails {
33839
34475
  uid = lastUId++;
33840
- #mode = /* @__PURE__ */ state();
33841
- get mode() {
33842
- return get$2(this.#mode);
33843
- }
33844
- set mode(value) {
33845
- set(this.#mode, value, true);
33846
- }
33847
34476
  #filters = /* @__PURE__ */ state();
33848
34477
  get filters() {
33849
34478
  return get$2(this.#filters);
@@ -33931,48 +34560,14 @@ class TicketSelectionDetails {
33931
34560
  addTicketSegment(ticketGroup) {
33932
34561
  this.ticketSegments.push(ticketGroup);
33933
34562
  }
34563
+ get isCalendarVisible() {
34564
+ return Boolean(this.filters?.some((f) => getFilter(f).isCalendarVisible(this)));
34565
+ }
33934
34566
  get isTimeslotsVisible() {
33935
- if (this.filters?.includes("events:scaled-price")) return true;
33936
- if (this.mode === "event") return false;
33937
- return Boolean(this.filters?.includes("timeslot") && this.selectedDate);
34567
+ return Boolean(this.filters?.some((f) => getFilter(f).isTimeslotsVisible(this)));
33938
34568
  }
33939
34569
  get isTicketsVisible() {
33940
- const byFilter = (filter) => {
33941
- switch (filter) {
33942
- case "day":
33943
- return Boolean(this.selectedDate);
33944
- case "annual":
33945
- return true;
33946
- case "event:scaled-price":
33947
- return Boolean(this.selectedDate);
33948
- case "events:scaled-price":
33949
- return true;
33950
- case "event:ticket":
33951
- return Boolean(this.selectedDate);
33952
- case "timeslot":
33953
- switch (this.mode) {
33954
- case "event":
33955
- return Boolean(this.selectedDate);
33956
- case "ticket":
33957
- return Boolean(this.selectedDate && this.selectedTimeslot);
33958
- case "tour":
33959
- return true;
33960
- case void 0:
33961
- return false;
33962
- default:
33963
- const exhaustedChecking2 = this.mode;
33964
- throw new Error(`(isTicketsVisible) Unhandled case: ${exhaustedChecking2}`);
33965
- }
33966
- default:
33967
- const exhaustedChecking = filter;
33968
- throw new Error(`(isTicketsVisible) Unhandled case: ${exhaustedChecking}`);
33969
- }
33970
- };
33971
- return this.filters?.some(byFilter);
33972
- }
33973
- get isCalendarVisible() {
33974
- if (this.filters?.includes("events:scaled-price")) return true;
33975
- return Boolean(this.filters?.includes("timeslot") || this.filters?.includes("day"));
34570
+ return Boolean(this.filters?.some((f) => getFilter(f).isTicketsVisible(this)));
33976
34571
  }
33977
34572
  }
33978
34573
  const KEY$2 = "go-ticket-selection";
@@ -34839,11 +35434,29 @@ function Overview($$anchor, $$props) {
34839
35434
  customElements.define("go-profile-overview", create_custom_element(Overview, {}, [], []));
34840
35435
  function TicketSelection($$anchor, $$props) {
34841
35436
  push($$props, true);
34842
- let mode = prop($$props, "mode", 7), filters = prop($$props, "filters", 7), eventIds = prop($$props, "eventIds", 7), museumIds = prop($$props, "museumIds", 7), exhibitionIds = prop($$props, "exhibitionIds", 7), selectedDate = prop($$props, "selectedDate", 7), selectedTimeslot = prop($$props, "selectedTimeslot", 7), ticketIds = prop($$props, "ticketIds", 7), ticketGroupIds = prop($$props, "ticketGroupIds", 7);
35437
+ function parseFilters(value) {
35438
+ if (!value) return void 0;
35439
+ const out = [];
35440
+ for (const raw of value.split(",")) {
35441
+ const t = raw.trim();
35442
+ if (!t) continue;
35443
+ if (validFilterNames.includes(t)) {
35444
+ out.push(t);
35445
+ } else {
35446
+ console.warn(`[go-ticket-selection] Unknown filter "${t}". Valid filters: ${validFilterNames.join(", ")}`);
35447
+ }
35448
+ }
35449
+ return out.length ? out : void 0;
35450
+ }
35451
+ let filters = prop($$props, "filters", 7), eventIds = prop($$props, "eventIds", 7), museumIds = prop($$props, "museumIds", 7), exhibitionIds = prop($$props, "exhibitionIds", 7), selectedDate = prop($$props, "selectedDate", 7), selectedTimeslot = prop($$props, "selectedTimeslot", 7), ticketIds = prop($$props, "ticketIds", 7), ticketGroupIds = prop($$props, "ticketGroupIds", 7);
34843
35452
  const details = new TicketSelectionDetails();
34844
35453
  user_effect(() => {
34845
- details.mode = mode();
34846
- details.filters = parseTokens(filters(), validTicketSelectionFilters);
35454
+ if ($$props.$$host.hasAttribute("mode")) {
35455
+ console.warn('[go-ticket-selection] `mode` attribute is deprecated and ignored. Use `filters` instead, e.g. filters="ticket:timeslot".');
35456
+ }
35457
+ });
35458
+ user_effect(() => {
35459
+ details.filters = parseFilters(filters());
34847
35460
  details.eventIds = parseIds(eventIds());
34848
35461
  details.museumIds = parseIds(museumIds());
34849
35462
  details.exhibitionIds = parseIds(exhibitionIds());
@@ -34862,13 +35475,6 @@ function TicketSelection($$anchor, $$props) {
34862
35475
  setTicketSelectionDetails($$props.$$host, details);
34863
35476
  var $$exports = {
34864
35477
  details,
34865
- get mode() {
34866
- return mode();
34867
- },
34868
- set mode($$value) {
34869
- mode($$value);
34870
- flushSync();
34871
- },
34872
35478
  get filters() {
34873
35479
  return filters();
34874
35480
  },
@@ -34931,7 +35537,6 @@ function TicketSelection($$anchor, $$props) {
34931
35537
  customElements.define("go-ticket-selection", create_custom_element(
34932
35538
  TicketSelection,
34933
35539
  {
34934
- mode: { attribute: "mode", reflect: true, type: "String" },
34935
35540
  filters: { attribute: "filters", reflect: true, type: "String" },
34936
35541
  eventIds: { attribute: "event-ids", reflect: true, type: "String" },
34937
35542
  ticketIds: { attribute: "ticket-ids", reflect: true, type: "String" },
@@ -34986,232 +35591,6 @@ function TicketsSum($$anchor, $$props) {
34986
35591
  pop();
34987
35592
  }
34988
35593
  customElements.define("go-tickets-sum", create_custom_element(TicketsSum, {}, [], []));
34989
- async function loadAnnualTickets(segment) {
34990
- const tsd = segment.ticketSelectionDetails;
34991
- if (!tsd || !tsd.filters?.includes("annual")) {
34992
- segment.clear();
34993
- return;
34994
- }
34995
- const tickets = await shop.asyncFetch(() => shop.tickets({
34996
- by_bookable: true,
34997
- // @ts-ignore
34998
- "by_ticket_types[]": ["annual"],
34999
- "by_ticket_ids[]": tsd.ticketIds,
35000
- "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35001
- }));
35002
- const uiTickets = Object.values(tickets).map((t) => createUITicket(t));
35003
- segment.preCart = createCart(uiTickets);
35004
- }
35005
- async function loadDayTickets(segment) {
35006
- const tsd = segment.ticketSelectionDetails;
35007
- if (!tsd) {
35008
- console.warn("(loadDayTickets) tsd is undefined");
35009
- segment.clear();
35010
- return;
35011
- }
35012
- if (!tsd.selectedDate) {
35013
- console.warn("(loadDayTickets) selected-date is not given to the go-ticket-selection");
35014
- segment.clear();
35015
- return;
35016
- }
35017
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35018
- by_bookable: true,
35019
- valid_at: tsd.selectedDate?.toString(),
35020
- // @ts-ignore
35021
- "by_ticket_types[]": ["normal"],
35022
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35023
- "by_exhibition_ids[]": tsd.exhibitionIds,
35024
- "by_ticket_ids[]": tsd.ticketIds,
35025
- "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35026
- }));
35027
- let timeslot;
35028
- if (quotas && Object.values(quotas).length > 0 && Object.keys(Object.values(quotas)[0].capacities).length > 0) {
35029
- timeslot = Object.keys(Object.values(quotas)[0].capacities)[0];
35030
- }
35031
- shop.capacityManager.addQuotas(quotas);
35032
- const available = filterAvailabletickets(tickets, timeslot);
35033
- const uiTickets = initUITimeslotTickets(available, timeslot);
35034
- segment.preCart = createCart();
35035
- for (const ticket of uiTickets) {
35036
- segment.preCart.addItem(createCartItem(ticket, { time: timeslot }));
35037
- }
35038
- }
35039
- async function load_Event_ScaledPricesTickets(segment) {
35040
- const tsd = segment.ticketSelectionDetails;
35041
- if (!tsd) {
35042
- console.warn("(loadEventScaledPricesTickets) tsd is undefined");
35043
- segment.clear();
35044
- return;
35045
- }
35046
- if (!tsd.eventIds?.length) {
35047
- console.warn("(loadEventScaledPricesTickets) eventIds is undefined");
35048
- segment.clear();
35049
- return;
35050
- }
35051
- if (!segment.filters?.includes("event:scaled-price")) {
35052
- console.warn("(loadEventScaledPricesTickets) filters should include event:scaled-price");
35053
- segment.clear();
35054
- return;
35055
- }
35056
- if (segment.dateId === void 0) {
35057
- console.warn("(loadEventScaledPricesTickets) date-id is not given to the go-ticket-segment");
35058
- segment.clear();
35059
- return;
35060
- }
35061
- if (tsd.eventIds.length > 1) throw new Error("(loadEventScaledPricesTickets) currently we support only one eventId in go-ticket-selection");
35062
- const eid = tsd.eventIds[0];
35063
- const eventDate = await shop.asyncFetch(() => shop.getEventDetailsOnDate(eid, segment.dateId));
35064
- if (eventDate.prices) {
35065
- segment.preCart = createCart();
35066
- for (const price of eventDate.prices) {
35067
- const ticket = createUIEventTicket(price, segment.dateId, { event_title: eventDate.event_title });
35068
- segment.preCart.addItem(createCartItem(ticket, { time: eventDate.start_time }));
35069
- }
35070
- } else console.warn("(loadEventScaledPricesTickets) event.prices is undefined");
35071
- if (eventDate.seats) shop.capacityManager.addSeats(segment.dateId, eventDate.seats);
35072
- else console.warn("(loadEventScaledPricesTickets) event.seats is undefined");
35073
- }
35074
- async function loadEventTickets(segment) {
35075
- const tsd = segment.ticketSelectionDetails;
35076
- if (!tsd) {
35077
- console.warn("(loadEventTickets) tsd is undefined");
35078
- segment.clear();
35079
- return;
35080
- }
35081
- if (!tsd.eventIds?.length) {
35082
- console.warn("(loadEventTickets) eventIds is undefined");
35083
- segment.clear();
35084
- return;
35085
- }
35086
- if (!segment.filters?.includes("event:ticket")) {
35087
- console.warn("(loadEventTickets) filters should include event:tickets");
35088
- segment.clear();
35089
- return;
35090
- }
35091
- if (!tsd.selectedDate) {
35092
- console.warn("(loadEventTickets) selected-date is not given to the go-ticket-selection");
35093
- segment.clear();
35094
- return;
35095
- }
35096
- if (tsd.eventIds.length > 1) throw new Error("(loadEventTickets) currently we support only one eventId in go-ticket-selection");
35097
- const eid = tsd.eventIds[0];
35098
- const event2 = await shop.asyncFetch(() => shop.getEvent(eid));
35099
- const ticketIds = event2.tickets;
35100
- if (ticketIds.length === 0) {
35101
- segment.clear();
35102
- return;
35103
- }
35104
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35105
- "by_ticket_ids[]": ticketIds,
35106
- by_bookable: true,
35107
- valid_at: tsd.selectedDate?.toString(),
35108
- date_id: segment.dateId
35109
- }));
35110
- shop.capacityManager.addQuotas(quotas);
35111
- const available = filterAvailabletickets(tickets, tsd.selectedTime);
35112
- const uiTickets = initUITimeslotTickets(available, tsd.selectedTime);
35113
- segment.preCart = createCart();
35114
- for (const ticket of uiTickets) {
35115
- segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
35116
- }
35117
- }
35118
- const TWO_HOURS_IN_MILLISECONDS = 2 * 60 * 60 * 1e3;
35119
- async function load_Events_ScaledPricesTickets(segment) {
35120
- const tsd = segment.ticketSelectionDetails;
35121
- if (!tsd) {
35122
- console.warn("(load_Events_ScaledPricesTickets) tsd is undefined");
35123
- segment.clear();
35124
- return;
35125
- }
35126
- if (!segment.filters?.includes("events:scaled-price")) {
35127
- console.warn("(load_Events_ScaledPricesTickets) filters should include events:scaled-price");
35128
- segment.clear();
35129
- return;
35130
- }
35131
- if (!tsd.selectedDate) {
35132
- console.warn("(load_Events_ScaledPricesTickets) go-ticket-selection does not have a selected date");
35133
- segment.clear();
35134
- return;
35135
- }
35136
- if (!tsd.selectedTime) {
35137
- console.warn("(load_Events_ScaledPricesTickets) go-ticket-selection does not have a selected time");
35138
- segment.clear();
35139
- return;
35140
- }
35141
- let dates = await shop.asyncFetch(() => shop.getDates({
35142
- // q?: string
35143
- by_bookable: true,
35144
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35145
- "by_exhibition_ids[]": tsd.exhibitionIds,
35146
- "by_event_ids[]": tsd.eventIds,
35147
- "by_language_ids[]": segment.languageIds,
35148
- "by_catch_word_ids[]": segment.catchWordIds,
35149
- // by_category_ids?: number[]
35150
- start_at: tsd.selectedDate?.toString(),
35151
- //YYYY-MM-DD format
35152
- // end_at?: string // YYYY-MM-DD format
35153
- per_page: segment.limit || 30
35154
- // page?: number
35155
- }));
35156
- segment.preCart = createCart();
35157
- dates = dates.filter((d) => {
35158
- const datePart = d.start_time.slice(0, 10);
35159
- const sameDay = tsd.selectedDate?.toString() == datePart;
35160
- const selectedMs = Date.parse(tsd.selectedTime);
35161
- const startMs = Date.parse(d.start_time);
35162
- const after = startMs >= selectedMs && startMs <= selectedMs + TWO_HOURS_IN_MILLISECONDS;
35163
- const availableSeats = (d.seats?.available ?? 0) > 0;
35164
- return sameDay && after && availableSeats;
35165
- });
35166
- for (const date2 of dates) {
35167
- if (date2.prices) {
35168
- let prices = date2.prices;
35169
- if (segment.query) prices = prices.filter((p2) => p2.title.includes(segment.query));
35170
- for (const price of prices) {
35171
- const ticket = createUIEventTicket(price, date2.id, { event_title: date2.event_title });
35172
- segment.preCart.addItem(createCartItem(ticket, { time: date2.start_time }));
35173
- }
35174
- } else console.warn("(load_Events_ScaledPricesTickets) event.prices is undefined");
35175
- if (date2.seats) {
35176
- shop.capacityManager.addSeats(date2.id, date2.seats);
35177
- } else console.warn("(load_Events_ScaledPricesTickets) event.seats is undefined");
35178
- }
35179
- }
35180
- async function loadTimeslotTickets(segment) {
35181
- const tsd = segment.ticketSelectionDetails;
35182
- if (!tsd) {
35183
- console.warn("(loadTimeslotTickets) tsd is undefined");
35184
- segment.clear();
35185
- return;
35186
- }
35187
- if (!tsd.selectedDate) {
35188
- console.warn("(loadTimeslotTickets) selectedDate is not given to the go-ticket-selection");
35189
- segment.clear();
35190
- return;
35191
- }
35192
- if (!tsd.selectedTimeslot) {
35193
- console.warn("(loadTimeslotTickets) selectedTimeslot is not given to the go-ticket-selection");
35194
- segment.clear();
35195
- return;
35196
- }
35197
- const { tickets, quotas } = await shop.asyncFetch(() => shop.ticketsAndQuotas({
35198
- by_bookable: true,
35199
- valid_at: tsd.selectedDate?.toString(),
35200
- // @ts-ignore
35201
- by_ticket_type: "time_slot",
35202
- "by_museum_ids[]": segment.museumIds ?? tsd.museumIds,
35203
- "by_exhibition_ids[]": tsd.exhibitionIds,
35204
- "by_ticket_ids[]": tsd.ticketIds,
35205
- "by_ticket_group_ids[]": segment.ticketGroupIds ?? tsd.ticketGroupIds
35206
- }));
35207
- shop.capacityManager.addQuotas(quotas);
35208
- const available = filterAvailabletickets(tickets, tsd.selectedTime);
35209
- const uiTickets = initUITimeslotTickets(available, tsd.selectedTime);
35210
- segment.preCart = createCart();
35211
- for (const ticket of uiTickets) {
35212
- segment.preCart.addItem(createCartItem(ticket, { time: tsd.selectedTime }));
35213
- }
35214
- }
35215
35594
  class SegmentDetails {
35216
35595
  #ticketSelectionDetails;
35217
35596
  get ticketSelectionDetails() {
@@ -35227,7 +35606,7 @@ class SegmentDetails {
35227
35606
  set preCart(value) {
35228
35607
  set(this.#preCart, value, true);
35229
35608
  }
35230
- #filters = /* @__PURE__ */ state("timeslot");
35609
+ #filters = /* @__PURE__ */ state();
35231
35610
  get filters() {
35232
35611
  return get$2(this.#filters);
35233
35612
  }
@@ -35283,28 +35662,27 @@ class SegmentDetails {
35283
35662
  set museumIds(value) {
35284
35663
  set(this.#museumIds, value, true);
35285
35664
  }
35286
- constructor(type, tsdWrapper) {
35287
- this.filters = type;
35665
+ constructor(filters, tsdWrapper) {
35666
+ this.filters = filters === void 0 ? void 0 : Array.isArray(filters) ? filters : [filters];
35288
35667
  this.#ticketSelectionDetails = /* @__PURE__ */ user_derived(() => tsdWrapper.value);
35289
35668
  }
35669
+ get effectiveFilters() {
35670
+ if (this.filters?.length) return this.filters;
35671
+ return this.ticketSelectionDetails?.filters ?? [];
35672
+ }
35290
35673
  clear() {
35291
35674
  this.preCart = createCart([]);
35292
35675
  }
35293
35676
  toString() {
35294
- return JSON.stringify({ filters: this.filters, preCart: this.preCart.toString() });
35295
- }
35296
- loadTickets() {
35297
- const method = {
35298
- timeslot: loadTimeslotTickets,
35299
- annual: loadAnnualTickets,
35300
- day: loadDayTickets,
35301
- custom: () => {
35302
- },
35303
- "event:scaled-price": load_Event_ScaledPricesTickets,
35304
- "events:scaled-price": load_Events_ScaledPricesTickets,
35305
- "event:ticket": loadEventTickets
35306
- }[this.filters];
35307
- method(this);
35677
+ return JSON.stringify({
35678
+ filters: this.effectiveFilters,
35679
+ preCart: this.preCart.toString()
35680
+ });
35681
+ }
35682
+ async loadTickets() {
35683
+ this.preCart = createCart();
35684
+ const filters = this.effectiveFilters.filter((f) => f !== "custom");
35685
+ await Promise.all(filters.map((f) => getFilter(f).loadProducts(this)));
35308
35686
  }
35309
35687
  }
35310
35688
  const KEY = "go-ticket-segment";
@@ -35313,13 +35691,17 @@ const getSegmentDetails = createGetDetails(KEY);
35313
35691
  function TicketSegment($$anchor, $$props) {
35314
35692
  push($$props, true);
35315
35693
  const filters = prop($$props, "filters", 7), dateId = prop($$props, "dateId", 7), query = prop($$props, "query", 7), limit = prop($$props, "limit", 7), ticketGroupIds = prop($$props, "ticketGroupIds", 7), languageIds = prop($$props, "languageIds", 7), catchWordIds = prop($$props, "catchWordIds", 7), museumIds = prop($$props, "museumIds", 7);
35316
- if (!filters()) throw new Error("filters is required");
35694
+ function parseFilters(value) {
35695
+ if (!value) return void 0;
35696
+ const out = value.split(",").map((s) => s.trim()).filter(Boolean);
35697
+ return out.length ? out : void 0;
35698
+ }
35317
35699
  const tsdWrapper = getTicketSelectionDetails($$props.$$host);
35318
35700
  const tsd = tsdWrapper.value;
35319
- const details = new SegmentDetails(filters(), tsdWrapper);
35701
+ const details = new SegmentDetails(parseFilters(filters()), tsdWrapper);
35320
35702
  setSegmentDetails($$props.$$host, details);
35321
35703
  user_effect(() => {
35322
- details.filters = filters();
35704
+ details.filters = parseFilters(filters());
35323
35705
  details.dateId = dateId();
35324
35706
  details.query = query();
35325
35707
  details.limit = limit();
@@ -35331,13 +35713,13 @@ function TicketSegment($$anchor, $$props) {
35331
35713
  user_effect(() => {
35332
35714
  details.dateId;
35333
35715
  details.filters;
35334
- details.dateId;
35335
35716
  details.ticketGroupIds;
35336
35717
  details.museumIds;
35337
35718
  details.languageIds;
35338
35719
  details.catchWordIds;
35339
35720
  details.query;
35340
35721
  details.limit;
35722
+ tsd?.filters;
35341
35723
  tsd?.selectedTimeslot;
35342
35724
  tsd?.selectedTime;
35343
35725
  tsd?.selectedDate;
@@ -35649,6 +36031,13 @@ let Details$1 = class Details {
35649
36031
  set tsd(value) {
35650
36032
  set(this.#tsd, value);
35651
36033
  }
36034
+ #timeslots = /* @__PURE__ */ state(proxy([]));
36035
+ get timeslots() {
36036
+ return get$2(this.#timeslots);
36037
+ }
36038
+ set timeslots(value) {
36039
+ set(this.#timeslots, value, true);
36040
+ }
35652
36041
  constructor(tsdWrapper) {
35653
36042
  if (!tsdWrapper) return;
35654
36043
  this.#tsd = /* @__PURE__ */ user_derived(() => tsdWrapper.value);
@@ -35657,33 +36046,18 @@ let Details$1 = class Details {
35657
36046
  get boockedOutCount() {
35658
36047
  return this.timeslots.filter((t) => t.capacity == 0).length;
35659
36048
  }
35660
- get timeslots() {
35661
- const tsd = this.tsd;
35662
- if (!tsd) return [];
35663
- const date2 = tsd.selectedDate;
35664
- if (!date2) return [];
35665
- const result = snapshot(shop.ticketsAndQuotas({
35666
- by_bookable: true,
35667
- valid_at: date2.toString(),
35668
- // @ts-ignore
35669
- "by_ticket_types[]": ["time_slot"],
35670
- "by_museum_ids[]": tsd.museumIds,
35671
- "by_exhibition_ids[]": tsd.exhibitionIds,
35672
- "by_ticket_ids[]": tsd.ticketIds,
35673
- "by_ticket_group_ids[]": tsd.ticketGroupIds
36049
+ recalculateCapacities() {
36050
+ const date2 = this.tsd?.selectedDate;
36051
+ if (!date2) {
36052
+ this.timeslots = [];
36053
+ return;
36054
+ }
36055
+ this.timeslots = shop.capacityManager.quotaManager.timeslotsOn(date2).map((x) => ({
36056
+ ...x,
36057
+ startAt: x.timeSlot,
36058
+ timeFormatted: x.timeSlot.substring(11, 16),
36059
+ available: x.capacity > 0
35674
36060
  }));
35675
- if (!result) return [];
35676
- let ret = [];
35677
- untrack(() => {
35678
- shop.capacityManager.addQuotas(result.quotas);
35679
- ret = shop.capacityManager.quotaManager.timeslotsOn(tsd.selectedDate).map((x) => ({
35680
- ...x,
35681
- startAt: x.timeSlot,
35682
- timeFormatted: x.timeSlot.substring(11, 16),
35683
- available: x.capacity > 0
35684
- }));
35685
- });
35686
- return ret;
35687
36061
  }
35688
36062
  };
35689
36063
  var root_2$1 = /* @__PURE__ */ from_html(`<li><label> <input type="radio" name="timeslot"/></label></li>`);
@@ -35693,6 +36067,18 @@ function Timeslots($$anchor, $$props) {
35693
36067
  const binding_group = [];
35694
36068
  const _tsd = getTicketSelectionDetails($$props.$$host);
35695
36069
  const details = new Details$1(_tsd);
36070
+ user_effect(() => {
36071
+ const tsd = details.tsd;
36072
+ if (!tsd) return;
36073
+ const filters = tsd.filters;
36074
+ const date2 = tsd.selectedDate;
36075
+ untrack(async () => {
36076
+ if (filters?.length && date2) {
36077
+ await Promise.all(filters.map((f) => getFilter(f).loadTimeslots(tsd)));
36078
+ }
36079
+ details.recalculateCapacities();
36080
+ });
36081
+ });
35696
36082
  const dispatchTimeslotSelect = (target, selected) => {
35697
36083
  if (!target || !("dispatchEvent" in target)) return;
35698
36084
  target.dispatchEvent(new CustomEvent("go-timeslot-select", { detail: { selected }, bubbles: true, composed: true }));
@@ -35760,7 +36146,7 @@ function Timeslots($$anchor, $$props) {
35760
36146
  append($$anchor2, ul);
35761
36147
  };
35762
36148
  if_block(node, ($$render) => {
35763
- if (details.tsd && details.tsd.filters?.includes("timeslot")) $$render(consequent);
36149
+ if (details.tsd?.isTimeslotsVisible) $$render(consequent);
35764
36150
  });
35765
36151
  }
35766
36152
  append($$anchor, fragment);
@@ -35790,55 +36176,37 @@ class Calendar {
35790
36176
  set selected(value) {
35791
36177
  set(this.#selected, value, true);
35792
36178
  }
36179
+ get endpoint() {
36180
+ const endpoints = this.details?.filters?.map((f) => getFilter(f).calendarEndpoint).filter(Boolean) ?? [];
36181
+ return endpoints[0] ?? null;
36182
+ }
35793
36183
  get dates() {
35794
- if (!this.details) {
35795
- return void 0;
35796
- }
35797
- switch (this.details.mode) {
35798
- case "ticket":
36184
+ if (!this.details) return void 0;
36185
+ switch (this.endpoint) {
36186
+ case "tickets":
35799
36187
  return this.ticketsDates();
35800
- case "event":
36188
+ case "events":
35801
36189
  return this.eventsDates();
35802
- case "tour":
35803
- throw new Error("(Calendar) Tour mode not supported");
35804
- case void 0:
35805
- console.error("(Calendar) Mode is undefined");
35806
- return void 0;
35807
36190
  default:
35808
- const exhaustedChecking = this.details.mode;
35809
- throw new Error(`(Calendar) Unhandled case: ${exhaustedChecking}`);
36191
+ return void 0;
35810
36192
  }
35811
36193
  }
35812
36194
  isDateDisabled(date2) {
35813
36195
  if (this.dates) {
35814
36196
  return date2.compare($ad063034c8620db8$export$d0bdf45af03a6ea3($ad063034c8620db8$export$aa8b41735afcabd2())) < 0 || this.dates[date2.toString()] == "unavailable";
35815
- } else {
35816
- return date2.compare($ad063034c8620db8$export$d0bdf45af03a6ea3($ad063034c8620db8$export$aa8b41735afcabd2())) < 0;
35817
36197
  }
36198
+ return date2.compare($ad063034c8620db8$export$d0bdf45af03a6ea3($ad063034c8620db8$export$aa8b41735afcabd2())) < 0;
35818
36199
  }
35819
36200
  isDateUnavailable(date2) {
35820
- if (this.dates) {
35821
- return this.dates[date2.toString()] == "fully_booked";
35822
- }
35823
- return false;
36201
+ return this.dates?.[date2.toString()] == "fully_booked";
35824
36202
  }
35825
- // @ts-ignore
35826
36203
  get apiFilters() {
35827
- return this.details?.filters?.map((f) => ({
35828
- day: "normal",
35829
- timeslot: "time_slot",
35830
- annual: "annual",
35831
- "event:scaled-price": "scaled_price",
35832
- "events:scaled-price": "not implemented",
35833
- "event:ticket": "not implemented"
35834
- })[f]);
36204
+ return this.details?.filters?.map((f) => getFilter(f).apiToken).filter(Boolean);
35835
36205
  }
35836
36206
  params(startAt) {
35837
36207
  if (!this.details) return {};
35838
36208
  const params = {
35839
36209
  by_bookable: true,
35840
- // This should give a type error, but it doesn't because we are using by_ticket_types[] which the type doesn't know
35841
- // we filter out undefined values
35842
36210
  //@ts-ignore
35843
36211
  "by_ticket_types[]": this.apiFilters,
35844
36212
  "by_ticket_ids[]": this.details.ticketIds,
@@ -35847,7 +36215,6 @@ class Calendar {
35847
36215
  "by_exhibition_ids[]": this.details.exhibitionIds,
35848
36216
  "by_event_ids[]": this.details.eventIds,
35849
36217
  depth: "availability_status",
35850
- // these logic are there to minimize fetches
35851
36218
  start_at: startAt.toString(),
35852
36219
  end_at: startAt.add({ months: 1 }).toString()
35853
36220
  };
@@ -35864,13 +36231,11 @@ class Calendar {
35864
36231
  }
35865
36232
  eventsDates() {
35866
36233
  const method = shop.calendar.bind(shop);
35867
- const ret = this.fetchPeriod().reduce((prev, startAt) => assign(prev, method(this.params(startAt))), {});
35868
- return ret;
36234
+ return this.fetchPeriod().reduce((prev, startAt) => assign(prev, method(this.params(startAt))), {});
35869
36235
  }
35870
36236
  ticketsDates() {
35871
36237
  const method = shop.ticketsCalendar.bind(shop);
35872
- const ret = this.fetchPeriod().reduce((prev, startAt) => assign(prev, method(this.params(startAt))), {});
35873
- return ret;
36238
+ return this.fetchPeriod().reduce((prev, startAt) => assign(prev, method(this.params(startAt))), {});
35874
36239
  }
35875
36240
  }
35876
36241
  var root_3 = /* @__PURE__ */ from_html(`<!> <!> <!>`, 1);
@@ -36118,10 +36483,6 @@ function Calendar_1($$anchor, $$props) {
36118
36483
  const ticketSelectionDetails = /* @__PURE__ */ user_derived(() => _ticketSelectionDetails.value);
36119
36484
  user_effect(() => {
36120
36485
  ticketsCalendar.details = get$2(ticketSelectionDetails);
36121
- if (get$2(ticketSelectionDetails)) {
36122
- get$2(ticketSelectionDetails).mode;
36123
- get$2(ticketSelectionDetails).selectedDate = void 0;
36124
- }
36125
36486
  });
36126
36487
  $$props.$$host.addEventListener("go-date-select", (e) => {
36127
36488
  if (get$2(ticketSelectionDetails)) {