PageSourceSearch

https://www.kraftedlabs.com/assets/projects/user_pages/rebilly-checkout-FZAQEHSF.js

js kraftedlabs.com collected 2026-09-30 06:39:33 UTC 195,326 bytes, 4,842 lines download raw bytes

1import {
2  init_select_box_v2
3} from "./chunk-R4YB6JIA.js";
4import {
5  AVAILABLE_KLARNA_COUNTRIES,
6  CheckoutCriticalError,
7  CheckoutExistingOrders,
8  CheckoutSubmit,
9  ERROR_CODES,
10  ErrorTypes,
11  PaypalStates,
12  addressToString,
13  backfillAddressesId,
14  buildComputed,
15  collectLeads,
16  create,
17  decodeVirtualInstallmentId,
18  displayAndLogCriticalError,
19  encodeVirtualInstallmentId,
20  fieldsForCountry,
21  hasPhysicalProducts,
22  initializeUtilities,
23  isSavedAddress,
24  makeCurrentPageFetcher,
25  numberOfStepsInCheckout,
26  parseAddressByFields,
27  resolveInitialPaymentType,
28  scrollToFirstVisibleError,
29  setupOrderSummaries
30} from "./chunk-SYANC6RH.js";
31import "./chunk-W3RKY5WP.js";
32import {
33  CFFetch,
34  CFFetcherError,
35  CFFetcherErrorTypes,
36  Fetcher,
37  MANUALLY_ABORTED,
38  init_fetcher,
39  isBackendError,
40  isFetcherError,
41  isResponseError
42} from "./chunk-YSVSPNWW.js";
43import "./chunk-372FPXG6.js";
44import {
45  atom,
46  batched,
47  computed,
48  deepEqual,
49  formatNumberToCurrency,
50  init_general,
51  init_nanostores,
52  isElementVisibleOnViewport,
53  map,
54  onMount
55} from "./chunk-BY72GGKB.js";
56import {
57  addError,
58  resetInputErrors
59} from "./chunk-4AIF3XZW.js";
60import {
61  init_radio_v1
62} from "./chunk-TLMSI2UF.js";
63import {
64  init_checkbox_v1,
65  init_input_v1
66} from "./chunk-FQR6BHZQ.js";
67import {
68  IntlTel_initPhoneInput,
69  init_cf_utils,
70  uuidv4
71} from "./chunk-KIZY5IRN.js";
72import {
73  init_modal_v1
74} from "./chunk-5NUE6T5P.js";
75import {
76  CF2Component,
77  init_runtime,
78  registerComponent
79} from "./chunk-NQUHJ6NR.js";
80import {
81  __privateAdd,
82  __privateGet,
83  __privateMethod,
84  __privateSet,
85  __publicField,
86  init_define_process
87} from "./chunk-RFSPGZ3L.js";
88
89// projects/lib/packages/yggdrasil-blueprints/__generated__/packs/rebilly-checkout.ts
90init_define_process();
91
92// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-saved-multiple-payments-preview-v1.ts
93init_define_process();
94init_runtime();
95var CheckoutSavedMultiplePaymentsPreviewV1 = class extends CF2Component {
96  constructor(el, runtimeSel) {
97    super(el, runtimeSel);
98  }
99  mount() {
100    Checkout.computed.paymentMethod.subscribe((payment_method) => {
101      this.current_payment_method = payment_method || { type: "new-payment" };
102      this.render();
103    });
104  }
105  remove() {
106    this.element.innerHTML = "";
107  }
108  render(initializeChildrenInstances = false) {
109    const is_server = true;
110    const current_payment_method = this.current_payment_method ?? null;
111    const checkoutSavedMultiplePaymentsTexts = this.checkoutSavedMultiplePaymentsTexts ?? null;
112    let html = "";
113    {
114      if (current_payment_method?.type == "new-payment") {
115        html += `<div class="elSelectText">${checkoutSavedMultiplePaymentsTexts?.addNewPaymentMethod}</div>`;
116      } else if (current_payment_method?.type == "payment-card") {
117        html += `<div class="elSelectText"><i class="fab fa-cc-${current_payment_method?.icon}"></i><span class="elSelectTextMaskedNumber"> ${current_payment_method?.details}</span></div>`;
118      } else if (current_payment_method?.type == "paypal") {
119        html += `<div class="elSelectText"><i class="fab fa-paypal"></i>${current_payment_method?.details}</div>`;
120      } else if (current_payment_method?.type == "Klarna") {
121        html += `<div class="elSelectText"><svg xmlns="http://www.w3.org/2000/svg" width="78" viewBox="-67.935 -25.275 588.77 151.65"><path d="M79.7 0H57.4c0 18.3-8.4 35-23 46l-8.8 6.6 34.2 46.6h28.1L56.4 56.3C71.3 41.5 79.7 21.5 79.7 0zM0 0h22.8v99.2H0zm94.5 0H116v99.2H94.5zm210.1 28.7c-8.2 0-16 2.5-21.2 9.6v-7.7H263v68.6h20.7v-36c0-10.4 7-15.5 15.4-15.5 9 0 14.2 5.4 14.2 15.4v36.2h20.5V55.6c0-16-12.7-26.9-29.2-26.9zM181 30.6V35c-5.8-4-12.8-6.3-20.4-6.3-20 0-36.2 16.2-36.2 36.2 0 20 16.2 36.2 36.2 36.2 7.6 0 14.6-2.3 20.4-6.3v4.4h20.5V30.6zm-18.7 51.9c-10.3 0-18.6-7.9-18.6-17.6 0-9.7 8.3-17.6 18.6-17.6s18.6 7.9 18.6 17.6c0 9.7-8.3 17.6-18.6 17.6zm71-43v-8.9h-21v68.6h21.1v-32c0-10.8 11.7-16.6 19.8-16.6h.2v-20c-8.3 0-16 3.6-20.1 8.9zm164.3-8.9V35c-5.8-4-12.8-6.3-20.4-6.3-20 0-36.2 16.2-36.2 36.2 0 20 16.2 36.2 36.2 36.2 7.6 0 14.6-2.3 20.4-6.3v4.4h20.5V30.6zm-18.7 51.9c-10.3 0-18.6-7.9-18.6-17.6 0-9.7 8.3-17.6 18.6-17.6s18.6 7.9 18.6 17.6c.1 9.7-8.3 17.6-18.6 17.6zM434 32.6c0-1-.7-1.6-1.8-1.6h-1.9v5.2h.9v-1.9h1l.8 1.9h1l-.9-2.1c.6-.3.9-.8.9-1.5zm-1.8.8h-1v-1.6h1c.6 0 .9.3.9.8s-.2.8-.9.8z"></path><path d="M431.9 28.8c-2.7 0-4.9 2.2-4.9 4.9.1 2.7 2.2 4.9 4.9 4.9s4.9-2.2 4.9-4.9-2.2-4.9-4.9-4.9zm0 8.9c-2.2 0-3.9-1.8-3.9-4s1.8-4 3.9-4c2.2 0 3.9 1.8 3.9 4s-1.8 4-3.9 4zm8.1 37.2c-7.1 0-12.9 5.8-12.9 12.9 0 7.1 5.8 12.9 12.9 12.9 7.1 0 12.9-5.8 12.9-12.9 0-7.2-5.8-12.9-12.9-12.9z"></path></svg></div>`;
122      }
123    }
124    this.replaceContent(html);
125    if (initializeChildrenInstances) {
126      const scopeToYggRender = this.element.querySelectorAll("[ygg-render]").length > 0;
127      const options = { scopeToYggRender };
128      CF2Component.hydrateTree(this.element, options);
129    }
130  }
131};
132registerComponent("CheckoutSavedMultiplePaymentsPreview/V1", CheckoutSavedMultiplePaymentsPreviewV1);
133window["CheckoutSavedMultiplePaymentsPreviewV1"] = CheckoutSavedMultiplePaymentsPreviewV1;
134
135// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-threeds-frame-v1.ts
136init_define_process();
137init_runtime();
138var CheckoutThreedsFrameV1 = class extends CF2Component {
139  constructor(el, runtimeSel) {
140    super(el, runtimeSel);
141  }
142  mount() {
143    Checkout.store.threeds.listen((threeds) => {
144      if (threeds.show) {
145        const approvalUrl = threeds.approvalUrl;
146        const iframe = document.createElement("iframe");
147        const orderStautsIframe = "/cf_order_status?disable-dispatch=true";
148        iframe.onload = (evt) => {
149          if (evt.target.src.includes(orderStautsIframe)) {
150            this.element.classList.remove("elHide");
151            iframe.src = approvalUrl;
152          }
153        };
154        this.element.innerHTML = "";
155        this.element.appendChild(iframe);
156        iframe.src = orderStautsIframe;
157      } else {
158        this.element.classList.add("elHide");
159        this.element.innerHTML = "";
160      }
161    });
162  }
163};
164registerComponent("CheckoutThreedsFrame/V1", CheckoutThreedsFrameV1);
165window["CheckoutThreedsFrameV1"] = CheckoutThreedsFrameV1;
166
167// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-address-form-v1.ts
168init_define_process();
169init_nanostores();
170init_input_v1();
171init_select_box_v2();
172
173// projects/lib/packages/yggdrasil-blueprints/src/Elements/Utils/address-autocomplete.ts
174init_define_process();
175init_cf_utils();
176init_fetcher();
177var CFAddressAutocomplete = class {
178  constructor(input, options) {
179    __publicField(this, "input");
180    __publicField(this, "addressForm");
181    __publicField(this, "options");
182    __publicField(this, "sessionToken");
183    __publicField(this, "resultsContainer");
184    __publicField(this, "debounceTimer");
185    __publicField(this, "currentIndex", -1);
186    __publicField(this, "predictionsFetcher", null);
187    __publicField(this, "placeDetailsFetcher", null);
188    this.input = input;
189    this.addressForm = input.closest('[data-page-element="CheckoutAddressForm/V1"]');
190    this.options = {
191      types: ["address"],
192      debounceMs: 400,
193      ...options
194    };
195    this.sessionToken = uuidv4();
196    this.createResultsContainer();
197    this.attachListeners();
198  }
199  createResultsContainer() {
200    this.resultsContainer = document.createElement("div");
201    this.resultsContainer.className = "cf-autocomplete-results";
202    const parentStyle = window.getComputedStyle(this.input.parentElement);
203    if (parentStyle.position === "static") {
204      this.input.parentElement.style.position = "relative";
205    }
206    this.input.parentElement.appendChild(this.resultsContainer);
207  }
208  attachListeners() {
209    this.input.addEventListener("input", () => this.handleInput());
210    this.input.addEventListener("keydown", (e) => this.handleKeydown(e));
211    this.input.addEventListener("blur", () => {
212      clearTimeout(this.debounceTimer);
213      if (this.predictionsFetcher) {
214        this.predictionsFetcher.abort();
215      }
216      setTimeout(() => this.hideResults(), 300);
217    });
218    this.input.addEventListener("focus", () => {
219      if (this.resultsContainer.children.length > 0) {
220        this.showResults();
221      }
222    });
223  }
224  handleInput() {
225    clearTimeout(this.debounceTimer);
226    const value = this.input.value.trim();
227    if (value.length < 3) {
228      this.resultsContainer.innerHTML = "";
229      this.hideResults();
230      return;
231    }
232    this.debounceTimer = setTimeout(() => {
233      this.fetchPredictions(value);
234    }, this.options.debounceMs);
235  }
236  handleKeydown(e) {
237    const items = this.resultsContainer.children;
238    if (items.length === 0) return;
239    switch (e.key) {
240      case "ArrowDown":
241        e.preventDefault();
242        this.currentIndex = Math.min(this.currentIndex + 1, items.length - 1);
243        this.updateSelection();
244        break;
245      case "ArrowUp":
246        e.preventDefault();
247        this.currentIndex = Math.max(this.currentIndex - 1, -1);
248        this.updateSelection();
249        break;
250      case "Enter":
251        e.preventDefault();
252        e.stopPropagation();
253        if (this.currentIndex >= 0) {
254          ;
255          items[this.currentIndex].click();
256        }
257        break;
258      case "Escape":
259        this.hideResults();
260        break;
261    }
262  }
263  updateSelection() {
264    const items = this.resultsContainer.children;
265    Array.from(items).forEach((item, index) => {
266      if (index === this.currentIndex) {
267        item.classList.add("cf-autocomplete-selected");
268      } else {
269        item.classList.remove("cf-autocomplete-selected");
270      }
271    });
272  }
273  async fetchPredictions(input) {
274    if (!this.predictionsFetcher) this.predictionsFetcher = new Fetcher();
275    const params = new URLSearchParams({
276      input,
277      types: this.options.types.join(","),
278      session_token: this.sessionToken
279    });
280    this.predictionsFetcher.fetch(
281      `/user_pages/api/v1/address_autocomplete/predictions?${params}`,
282      {
283        headers: { "Content-Type": "application/json" }
284      },
285      { retries: 3, shouldCaptureServerError: true, onlyOneInflightRequest: true }
286    ).then((res) => {
287      if (res instanceof Response && res.ok) {
288        return res.json();
289      }
290      throw new Error("Address autocomplete error");
291    }).then((data) => {
292      if (data.predictions && data.predictions.length > 0) {
293        this.renderPredictions(data.predictions);
294      } else {
295        this.hideResults();
296      }
297    }).catch((error) => {
298      if (error === MANUALLY_ABORTED) {
299        return;
300      }
301      console.error("Address autocomplete error:", error);
302      this.hideResults();
303    });
304  }
305  async fetchPlaceDetails(placeId) {
306    if (!this.placeDetailsFetcher) this.placeDetailsFetcher = new Fetcher();
307    const params = new URLSearchParams({
308      place_id: placeId,
309      session_token: this.sessionToken
310    });
311    return this.placeDetailsFetcher.fetch(
312      `/user_pages/api/v1/address_autocomplete/place_details?${params}`,
313      {
314        headers: { "Content-Type": "application/json" }
315      },
316      { retries: 3, shouldCaptureServerError: true, onlyOneInflightRequest: true }
317    ).then((res) => {
318      if (res instanceof Response && res.ok) {
319        return res.json();
320      }
321      throw new Error("Place details request failed");
322    }).then((data) => {
323      return data.place_details;
324    }).catch((error) => {
325      if (error === MANUALLY_ABORTED) {
326        return null;
327      }
328      console.error("Place details fetch error:", error);
329    });
330  }
331  renderPredictions(predictions) {
332    this.resultsContainer.innerHTML = "";
333    this.currentIndex = -1;
334    predictions.forEach((prediction, index) => {
335      const item = document.createElement("div");
336      item.className = "cf-autocomplete-item";
337      item.dataset.placeId = prediction.place_id;
338      if (prediction.structured_formatting) {
339        const mainText = this.highlightMatches(
340          prediction.structured_formatting.main_text,
341          prediction.structured_formatting.main_text_matched_substrings || []
342        );
343        const secondaryText = prediction.structured_formatting.secondary_text ? this.highlightMatches(
344          prediction.structured_formatting.secondary_text,
345          prediction.structured_formatting.secondary_text_matched_substrings || []
346        ) : "";
347        const mainSpan = document.createElement("span");
348        mainSpan.className = "cf-autocomplete-main";
349        mainSpan.innerHTML = mainText;
350        item.appendChild(mainSpan);
351        if (secondaryText) {
352          const secondarySpan = document.createElement("span");
353          secondarySpan.className = "cf-autocomplete-secondary";
354          secondarySpan.innerHTML = secondaryText;
355          item.appendChild(secondarySpan);
356        }
357      } else {
358        item.textContent = prediction.description;
359      }
360      item.addEventListener("mouseenter", () => {
361        this.currentIndex = index;
362        this.updateSelection();
363      });
364      item.addEventListener("click", () => this.selectPlace(prediction));
365      this.resultsContainer.appendChild(item);
366    });
367    this.showResults();
368  }
369  highlightMatches(text, matches) {
370    if (!matches || matches.length === 0) {
371      return this.escapeHtml(text);
372    }
373    let result = "";
374    let lastIndex = 0;
375    const sortedMatches = matches.sort((a, b) => a.offset - b.offset);
376    sortedMatches.forEach((match) => {
377      const { offset, length } = match;
378      result += this.escapeHtml(text.substring(lastIndex, offset));
379      result += `<strong class="cf-autocomplete-highlight">${this.escapeHtml(
380        text.substring(offset, offset + length)
381      )}</strong>`;
382      lastIndex = offset + length;
383    });
384    result += this.escapeHtml(text.substring(lastIndex));
385    return result;
386  }
387  escapeHtml(text) {
388    const div = document.createElement("div");
389    div.textContent = text;
390    return div.innerHTML;
391  }
392  async selectPlace(prediction) {
393    this.addressForm.querySelector('[data-page-element="Spinner/V1"]').setAttribute("data-loader", "true");
394    const placeDetails = await this.fetchPlaceDetails(prediction.place_id);
395    if (placeDetails) {
396      this.options.onPlaceSelected(placeDetails);
397      this.sessionToken = uuidv4();
398      this.resultsContainer.innerHTML = "";
399      this.currentIndex = -1;
400      this.hideResults();
401    }
402    this.addressForm.querySelector('[data-page-element="Spinner/V1"]').setAttribute("data-loader", "false");
403  }
404  showResults() {
405    this.resultsContainer.classList.add("cf-autocomplete-visible");
406    this.resultsContainer.style.width = `${this.input.offsetWidth}px`;
407  }
408  hideResults() {
409    this.resultsContainer.classList.remove("cf-autocomplete-visible");
410  }
411  destroy() {
412    this.resultsContainer.remove();
413    this.input.removeEventListener("input", () => this.handleInput());
414    this.input.removeEventListener("keydown", (e) => this.handleKeydown(e));
415  }
416};
417
418// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-address-form-v1.ts
419init_runtime();
420var CheckoutAddressFormV1 = class extends CF2Component {
421  constructor(el, runtimeSel) {
422    super(el, runtimeSel);
423  }
424  mount() {
425    if (this.useCheckoutStore) {
426      this.store = Checkout.store[this.type];
427      this.fields = Checkout.store[`${this.type}Fields`];
428      this.showAllErrors = Checkout.store.showAllErrors[this.type];
429      this.formErrors = Checkout.computed[`${this.type}Errors`];
430    } else {
431      this.store = map({});
432      this.fields = atom([...Checkout.store[`${this.type}Fields`].get()]);
433      this.showAllErrors = atom(false);
434      this.formErrors = computed([this.store, this.showAllErrors], (store, showAllErrors) => {
435        const fields = this.fields.get();
436        return Checkout.utils.addressErrors(store, showAllErrors, fields);
437      });
438      const initializeFromSavedContact = () => {
439        const values = this.store.get();
440        const fields = this.fields.get();
441        const fieldsValues = parseAddressByFields(values, fields);
442        this.store.set(fieldsValues);
443        const { country, state } = this.store.get();
444        if (country) {
445          this.setInputValue("country", country);
446        }
447        if (state && this.hasState()) {
448          this.setInputValue("state", state);
449        }
450      };
451      Checkout.store.state.listen((newState) => {
452        if (newState == Checkout.StoreStates.INITIALIZED) {
453          initializeFromSavedContact();
454        }
455      });
456      Checkout.store.checkout.mode.listen((newMode) => {
457        if (newMode === "saved") {
458          initializeFromSavedContact();
459        }
460      });
461      this.store.listen((address) => {
462        const fields = this.fields.get();
463        const addressFields = fieldsForCountry(fields, address.country);
464        this.fields.set(addressFields);
465      });
466    }
467    this.store.listen((fieldValues) => {
468      this.fields.get().forEach((prop) => {
469        this.setInputValue(prop, fieldValues[prop]);
470      });
471    });
472    this.formErrors.subscribe((errors) => {
473      if (!this.disableInputValidationOnBlur) {
474        this.checkErrors(errors);
475      } else {
476        if (this.showAllErrors.get()) this.checkErrors(errors);
477      }
478    });
479    this.setupAutocomplete();
480    this.setupInputListeners();
481  }
482  hasState() {
483    return this.fields.get().includes("state");
484  }
485  hasPostalCode(fields) {
486    return (fields ?? this.fields.get()).includes("zip");
487  }
488  checkErrors(errors) {
489    const errorWrapper = this.element.querySelector(".elCheckoutFormErrors");
490    errorWrapper.classList.add("elHide");
491    this.fields.get().forEach((prop) => {
492      const input = this.getInputFromName(prop);
493      resetInputErrors(input);
494    });
495    if (Checkout.utils.hasErrors(errors)) {
496      const fieldErrors = errors.fields;
497      if (fieldErrors) {
498        const errors2 = [];
499        Object.entries(fieldErrors).forEach(([field, error]) => {
500          const { message } = error;
501          errors2.push(message);
502          const input = this.getInputFromName(field);
503          addError(input);
504        });
505        if (errors2.length) {
506          const listErrors = `<ul>${errors2.map((err) => `<li>${err}</li>`).join("")}</ul>`;
507          errorWrapper.innerHTML = listErrors;
508          errorWrapper.classList.remove("elHide");
509        } else {
510          errorWrapper.classList.add("elHide");
511        }
512      }
513    }
514  }
515  getInputFromName(name) {
516    return this.element.querySelector(`[name='${this.type}_${name}']`);
517  }
518  getWrapperElement(prop) {
519    const input = this.getInputFromName(prop);
520    return input.closest(".elFormItemWrapper");
521  }
522  setInputValue(fieldName, value) {
523    const input = this.getInputFromName(fieldName);
524    value = value?.trim();
525    if (value) {
526      if (fieldName === "country") {
527        !this.populatedCountries && this.populateCountries();
528        this.populatedCountries = true;
529        if (this.hasState()) this.populateStates();
530      }
531      input.value = value;
532      $(input).parents(".elFormItemWrapper").addClass("hasValue");
533    } else {
534      input.value = "";
535      $(input).parents(".elFormItemWrapper").removeClass("hasValue");
536    }
537  }
538  setupAutocomplete() {
539    const addressInput = this.getInputFromName("address");
540    if (!addressInput) return;
541    const autocomplete = new CFAddressAutocomplete(addressInput, {
542      types: ["address"],
543      onPlaceSelected: (place) => {
544        const valueByComponentType = place.address_components.reduce((acc, component) => {
545          const type = component.types;
546          if (type.includes("locality")) {
547            acc["locality"] = component.long_name;
548          } else if (type.includes("administrative_area_level_2")) {
549            acc["administrative_area_level_2"] = component.long_name;
550          } else if (type.includes("administrative_area_level_1")) {
551            acc["administrative_area_level_1"] = component.short_name;
552          } else if (type.includes("country")) {
553            acc["country"] = component.short_name;
554          } else if (type.includes("postal_code")) {
555            acc["postal_code"] = component.long_name;
556          }
557          return acc;
558        }, {});
559        const address = { address: place.name };
560        address.country = valueByComponentType["country"];
561        const stateMap = this.stateMap(address.country);
562        const stateValue = valueByComponentType["administrative_area_level_1"];
563        address.state = stateMap.mapByCode[stateValue] ? stateValue : stateMap.mapByGoogleName[stateValue];
564        if (!address.state) {
565          address.state = this.firstStateFromCountry(address.country);
566        }
567        address.city = valueByComponentType["locality"] || valueByComponentType["administrative_area_level_2"];
568        address.zip = valueByComponentType["postal_code"];
569        this.store.set(address);
570        this.validateFormFields();
571      }
572    });
573  }
574  updateFields(country) {
575    const addressFields = fieldsForCountry(this.fields.get(), country);
576    this.fields.set(addressFields);
577  }
578  setupInputListeners() {
579    this.fields.get().forEach((prop) => {
580      const input = this.getInputFromName(prop);
581      if (input !== null) {
582        if (prop === "state" || prop === "country") {
583          input.addEventListener("input", () => {
584            if (prop === "country") {
585              const firstStateValue = this.firstStateFromCountry(input.value);
586              if (this.hasState()) {
587                this.store.set({
588                  ...this.store.get(),
589                  country: input.value,
590                  state: firstStateValue
591                });
592              } else {
593                this.store.set({
594                  ...this.hasPostalCode() ? this.store.get() : {},
595                  country: input.value
596                });
597              }
598            } else {
599              const value = input.value;
600              setTimeout(() => {
601                this.store.setKey(prop, value);
602              });
603            }
604          });
605        } else {
606          input.addEventListener("blur", () => {
607            this.store.setKey(prop, input.value);
608            if (!this.disableInputValidationOnBlur) {
609              this.checkErrors(this.formErrors.get());
610            } else {
611              if (this.showAllErrors.get()) this.checkErrors(this.formErrors.get());
612            }
613          });
614        }
615      }
616    });
617    this.fields.listen((fields) => {
618      this.updatePostalCode(fields);
619    });
620    this.updatePostalCode();
621  }
622  updatePostalCode(fields) {
623    const hasPostalCode = this.hasPostalCode(fields);
624    const zipInputWrapper = this.getWrapperElement("zip");
625    const countryWrapper = this.getWrapperElement("country");
626    if (this.locale === "ja") {
627      if (hasPostalCode) {
628        zipInputWrapper.classList.remove("elHide");
629        countryWrapper.classList.add("inputNoBorderTop");
630        countryWrapper.classList.remove("elInputOuterTopLeftCorner");
631        countryWrapper.classList.remove("elInputOuterTopRightCorner");
632      } else {
633        zipInputWrapper.classList.add("elHide");
634        countryWrapper.classList.remove("inputNoBorderTop");
635        countryWrapper.classList.add("elInputOuterTopLeftCorner");
636        countryWrapper.classList.add("elInputOuterTopRightCorner");
637      }
638    } else {
639      if (hasPostalCode) {
640        zipInputWrapper.classList.remove("elHide");
641        countryWrapper.classList.remove("elInputOuterBottomLeftCorner");
642        countryWrapper.classList.remove("elInputOuterBottomRightCorner");
643      } else {
644        zipInputWrapper.classList.add("elHide");
645        countryWrapper.classList.add("elInputOuterBottomLeftCorner");
646        countryWrapper.classList.add("elInputOuterBottomRightCorner");
647      }
648    }
649  }
650  validateFormFields() {
651    const address = this.store.get();
652    const errors = Checkout.utils.addressErrors(address, true, this.fields.get());
653    if (Checkout.utils.hasErrors(errors)) {
654      this.showAllErrors.set(true);
655      return false;
656    } else {
657      return true;
658    }
659  }
660  populateCountries() {
661    const topMapping = ["US", "CA", "GB", "IE", "AU", "NZ"];
662    const topHash = topMapping.reduce((acc, val) => {
663      acc[val] = true;
664      return acc;
665    }, {});
666    const topOptions = topMapping.map((iso2) => ({ iso2 }));
667    const remainingOptions = [];
668    Checkout.allCountries.forEach((item) => {
669      if (topHash[item.iso2]) {
670        const option = topOptions.find((option2) => option2.iso2 == item.iso2);
671        option.name = item.name;
672      } else {
673        remainingOptions.push(item);
674      }
675    });
676    let html = "";
677    topOptions.forEach((item) => html += `<option value="${item.iso2}" > ${item.name} </option>`);
678    remainingOptions.forEach((item) => html += `<option value="${item.iso2}" > ${item.name} </option>`);
679    const countrySelect = this.getInputFromName("country");
680    countrySelect.innerHTML = html;
681  }
682  populateStates() {
683    const countryValue = this.store.get().country;
684    const statesSelect = this.getInputFromName("state");
685    let html = "";
686    const countryData = Checkout.allCountries.find((country) => countryValue == country.iso2);
687    countryData.regions.forEach((region, index) => {
688      html += `<option value="${region.state_code}" > ${region.name} </option>`;
689    });
690    const firstStateValue = countryData.regions?.[0]?.state_code;
691    if (firstStateValue) {
692      $(statesSelect).parents(".elFormItemWrapper").show();
693      statesSelect.innerHTML = html;
694    } else {
695      $(statesSelect).parents(".elFormItemWrapper").hide();
696      statesSelect.innerHTML = "";
697    }
698  }
699  stateMap(countryValue) {
700    const stateMap = {
701      mapByCode: {},
702      mapByGoogleName: {}
703    };
704    const countryData = Checkout.allCountries.find((country) => countryValue == country.iso2);
705    countryData.regions.forEach((region, index) => {
706      stateMap.mapByCode[region.state_code] = true;
707      stateMap.mapByGoogleName[region.google_name] = region.state_code;
708    });
709    return stateMap;
710  }
711  firstStateFromCountry(countryValue) {
712    const countryData = Checkout.allCountries.find((country) => country.iso2 == countryValue);
713    return countryData.regions?.[0]?.state_code;
714  }
715};
716registerComponent("CheckoutAddressForm/V1", CheckoutAddressFormV1);
717window["CheckoutAddressFormV1"] = CheckoutAddressFormV1;
718
719// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-billing-address-v1.ts
720init_define_process();
721init_checkbox_v1();
722init_runtime();
723var CheckoutBillingAddressV1 = class extends CF2Component {
724  constructor(el, runtimeSel) {
725    super(el, runtimeSel);
726  }
727  mount() {
728    this.type = "billing";
729    this.getCheckbox().addEventListener("change", (evt) => {
730      evt.stopPropagation();
731      const value = !!evt.target.checked;
732      Checkout.store.billingSameAsShipping.set(value);
733      if (!value) {
734        const shippingData = Checkout.store.shipping.get();
735        const newBillingData = parseAddressByFields(shippingData, this.fields, false);
736        Checkout.store.billing.set(newBillingData);
737      }
738    });
739    Checkout.store.billingSameAsShipping.listen((value) => {
740      this.getCheckbox().checked = value;
741      if (value) {
742        this.hideForm();
743      } else {
744        this.showForm();
745      }
746    });
747    nanostores.computed(
748      [Checkout.computed.hasPhysicalProducts, Checkout.store.billingSameAsShipping],
749      (hasPhysicalProducts2, billingSameAsShipping) => ({ hasPhysicalProducts: hasPhysicalProducts2, billingSameAsShipping })
750    ).subscribe(({ hasPhysicalProducts: hasPhysicalProducts2, billingSameAsShipping }) => {
751      if (hasPhysicalProducts2) {
752        this.showBillingSameAsShipping();
753        if (billingSameAsShipping) {
754          this.hideForm();
755        } else {
756          this.showForm();
757        }
758      } else {
759        this.hideBillingSameAsShipping();
760        this.showForm();
761      }
762    });
763    nanostores.computed([Checkout.store.payment.type], (paymentType) => paymentType != "apple-pay").subscribe((display) => {
764      if (display) {
765        this.show();
766      } else {
767        this.hide();
768      }
769    });
770  }
771  show() {
772    this.element.classList.remove("elHide");
773  }
774  hide() {
775    this.element.classList.add("elHide");
776  }
777  showForm() {
778    this.element.querySelector(".elBillingForm").classList.remove("elHide");
779  }
780  hideForm() {
781    this.element.querySelector(".elBillingForm").classList.add("elHide");
782  }
783  getCheckboxContainer() {
784    return this.element.querySelector(".elShippingSameAsBillingContainer");
785  }
786  getCheckbox() {
787    return this.getCheckboxContainer().querySelector("input");
788  }
789  showBillingSameAsShipping() {
790    this.getCheckboxContainer().classList.remove("elHide");
791  }
792  hideBillingSameAsShipping() {
793    this.getCheckboxContainer().classList.add("elHide");
794  }
795};
796registerComponent("CheckoutBillingAddress/V1", CheckoutBillingAddressV1);
797window["CheckoutBillingAddressV1"] = CheckoutBillingAddressV1;
798
799// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-shipping-address-v1.ts
800init_define_process();
801init_runtime();
802var CheckoutShippingAddressV1 = class extends CF2Component {
803  constructor(el, runtimeSel) {
804    super(el, runtimeSel);
805  }
806  mount() {
807    this.contentEl = this.element.querySelector("div");
808    const shouldDisplay = nanostores.computed([
809      Checkout.computed.isNewDigitalWalletPayment,
810      Checkout.computed.hasPhysicalProducts
811    ], (isNewDigitalWalletPayment, hasPhysicalProducts2) => {
812      return hasPhysicalProducts2 && !isNewDigitalWalletPayment;
813    });
814    shouldDisplay.subscribe((display) => {
815      if (display) {
816        this.show();
817      } else {
818        this.hide();
819      }
820    });
821  }
822  show() {
823    this.element.classList.remove("elHide");
824  }
825  hide() {
826    this.element.classList.add("elHide");
827  }
828};
829registerComponent("CheckoutShippingAddress/V1", CheckoutShippingAddressV1);
830window["CheckoutShippingAddressV1"] = CheckoutShippingAddressV1;
831
832// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-login-v2.ts
833init_define_process();
834init_nanostores();
835init_input_v1();
836init_cf_utils();
837
838// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-auth.ts
839init_define_process();
840init_nanostores();
841var PhoneVerificationOtpStates = /* @__PURE__ */ new Set([
842  13 /* RequestingAnotherPhoneVerificationCode */,
843  16 /* SubmittingPhoneVerificationCode */,
844  17 /* PhoneVerificationSubmitError */,
845  14 /* SentPhoneVerificationOtp */,
846  19 /* FailedPhoneVerification */
847]);
848var PhoneVerificationRequestStates = /* @__PURE__ */ new Set([
849  11 /* SuggestingPhoneVerification */,
850  12 /* RequestingPhoneVerification */,
851  15 /* FailedRequestPhoneVerification */
852]);
853var PhoneVerificationDialogStates = new Set(
854  [18 /* PhoneVerificationSucceeded */].concat([...PhoneVerificationRequestStates]).concat([...PhoneVerificationOtpStates])
855);
856var AuthDialogStates = /* @__PURE__ */ new Set([
857  4 /* AwaitingOtp */,
858  5 /* FetchingOtpValidation */,
859  6 /* InvalidOtp */,
860  8 /* FetchingResendOtp */,
861  9 /* FailedResendOtp */,
862  // AuthMode.TryingAutoPhoneVerification,
863  ...PhoneVerificationDialogStates
864]);
865var AuthFlow = {
866  ["*"]: {
867    submitOtp: 5 /* FetchingOtpValidation */,
868    resendOtp: 8 /* FetchingResendOtp */,
869    changeOtpSource: 8 /* FetchingResendOtp */,
870    continueAsGuest: 21 /* ContinuingAsGuest */
871  },
872  [0 /* Initializing */]: {
873    alreadySaved: 1 /* AlreadySavedMode */,
874    noUser: 2 /* AwaitingEmail */
875  },
876  [2 /* AwaitingEmail */]: {
877    gotEmail: 3 /* FetchingEmailCheck */
878  },
879  [3 /* FetchingEmailCheck */]: {
880    sentOtp: 4 /* AwaitingOtp */,
881    unrecognized: 21 /* ContinuingAsGuest */
882  },
883  [4 /* AwaitingOtp */]: {
884    submitOtp: 5 /* FetchingOtpValidation */,
885    resendOtp: 8 /* FetchingResendOtp */
886  },
887  [5 /* FetchingOtpValidation */]: {
888    validOtp: 7 /* ValidOtp */,
889    invalidOtp: 6 /* InvalidOtp */
890  },
891  [7 /* ValidOtp */]: {
892    continueAsSaved: 20 /* ContinuingAsSaved */,
893    suggestPhoneVerification: 11 /* SuggestingPhoneVerification */
894  },
895  [6 /* InvalidOtp */]: {
896    resendOtp: 8 /* FetchingResendOtp */
897  },
898  [8 /* FetchingResendOtp */]: {
899    sentOtp: 4 /* AwaitingOtp */,
900    resendFailed: 9 /* FailedResendOtp */
901  },
902  [9 /* FailedResendOtp */]: {},
903  // phone verification flow
904  [11 /* SuggestingPhoneVerification */]: {
905    skipPhoneVerification: 20 /* ContinuingAsSaved */,
906    requestPhoneVerification: 12 /* RequestingPhoneVerification */
907  },
908  [12 /* RequestingPhoneVerification */]: {
909    skipPhoneVerification: 20 /* ContinuingAsSaved */,
910    sentPhoneVerificationOtp: 14 /* SentPhoneVerificationOtp */,
911    failStartPhoneVerification: 15 /* FailedRequestPhoneVerification */,
912    requestPhoneVerification: 12 /* RequestingPhoneVerification */
913  },
914  [15 /* FailedRequestPhoneVerification */]: {
915    skipPhoneVerification: 20 /* ContinuingAsSaved */,
916    requestPhoneVerification: 12 /* RequestingPhoneVerification */
917  },
918  [13 /* RequestingAnotherPhoneVerificationCode */]: {
919    skipPhoneVerification: 20 /* ContinuingAsSaved */,
920    sentPhoneVerificationOtp: 14 /* SentPhoneVerificationOtp */,
921    failStartPhoneVerification: 15 /* FailedRequestPhoneVerification */,
922    requestPhoneVerification: 13 /* RequestingAnotherPhoneVerificationCode */
923  },
924  [14 /* SentPhoneVerificationOtp */]: {
925    skipPhoneVerification: 20 /* ContinuingAsSaved */,
926    requestPhoneVerification: 13 /* RequestingAnotherPhoneVerificationCode */,
927    submitPhoneVerificationCode: 16 /* SubmittingPhoneVerificationCode */
928  },
929  [16 /* SubmittingPhoneVerificationCode */]: {
930    skipPhoneVerification: 20 /* ContinuingAsSaved */,
931    verificationSucceeded: 18 /* PhoneVerificationSucceeded */,
932    verificationFailed: 19 /* FailedPhoneVerification */,
933    verificationSubmitError: 17 /* PhoneVerificationSubmitError */
934  },
935  [19 /* FailedPhoneVerification */]: {
936    skipPhoneVerification: 20 /* ContinuingAsSaved */,
937    submitPhoneVerificationCode: 16 /* SubmittingPhoneVerificationCode */,
938    requestPhoneVerification: 13 /* RequestingAnotherPhoneVerificationCode */
939  },
940  [18 /* PhoneVerificationSucceeded */]: {
941    continueAsSaved: 20 /* ContinuingAsSaved */
942  }
943};
944var CheckoutAuth = class {
945  static initializeOneClickCheckoutFlow() {
946    globalThis.Checkout.auth = this;
947    this.store = globalThis.Checkout.store.auth = {
948      flow: map({
949        from: void 0,
950        event: void 0,
951        to: 0 /* Initializing */
952      }),
953      otpRequestFailure: map({
954        time: void 0,
955        retry_in: 0,
956        error: void 0
957      }),
958      otpLoginSource: atom(void 0),
959      phoneVerificationRequest: map({
960        time: void 0,
961        count: 0,
962        rejections: 0,
963        error: void 0
964      }),
965      phoneVerificationOtp: map({
966        time: void 0,
967        count: 0,
968        rejections: 0,
969        error: void 0
970      })
971    };
972    this.store.mode = computed(this.store.flow, (change) => change.to);
973    const requireLogin = computed([this.store.mode], (mode) => AuthDialogStates.has(mode)), otpLoginOptions = computed(globalThis.Checkout.store.contact_pending_auth, (partialContact) => {
974      const options = [];
975      if (partialContact) {
976        if (partialContact.is_phone_verified === true) {
977          options.push("phone_number");
978        }
979        if (partialContact.email) {
980          options.push("email");
981        }
982      }
983      return options;
984    }), suggestingPhoneVerification = computed([this.store.mode], (mode) => PhoneVerificationDialogStates.has(mode)), showingPhoneVerificationRequest = computed([this.store.mode], (mode) => PhoneVerificationRequestStates.has(mode)), showingPhoneOtp = computed([this.store.mode], (mode) => PhoneVerificationOtpStates.has(mode)), validGuestEmail = computed(
985      [
986        globalThis.Checkout.store.checkout.mode,
987        globalThis.Checkout.store.contact,
988        globalThis.Checkout.computed.contactErrors,
989        globalThis.Checkout.computed.hideContactInformationForm
990      ],
991      (mode, { email }, errors, hideContactInformationForm) => mode === "guest" && !errors?.fields?.email && !hideContactInformationForm && email
992    ), submittingPhoneVerification = computed(
993      globalThis.Checkout.store.auth.mode,
994      (mode) => mode === 16 /* SubmittingPhoneVerificationCode */
995    ), RequestingPhoneVerification = computed(
996      globalThis.Checkout.store.auth.mode,
997      (mode) => mode === 12 /* RequestingPhoneVerification */
998    ), phoneVerificationMessages = computed(
999      globalThis.Checkout.store.auth.mode,
1000      (mode) => mode === 12 /* RequestingPhoneVerification */ ? "Requesting a new code..." : (
1001        // // TODO
1002        // mode === AuthMode.SentAnotherPhoneVerificationOtp ?
1003        //   "Resent code. Please check your messages." :
1004        ""
1005      )
1006    ), phoneVerificationRequestErrorMsg = computed(globalThis.Checkout.store.auth.mode, (mode) => {
1007      if ([15 /* FailedRequestPhoneVerification */].includes(mode)) {
1008        const { numberTaken, errors } = globalThis.Checkout.store.auth.flow.get().data;
1009        if (numberTaken) {
1010          return "Sorry, that phone number is already taken";
1011        }
1012        if (errors) {
1013          return `Error: ${errors}`;
1014        }
1015        return "Unknown error. Please check your connection and try again.";
1016      }
1017      return "";
1018    }), phoneVerificationErrorMsg = computed(globalThis.Checkout.store.auth.mode, (mode) => {
1019      if (mode === 19 /* FailedPhoneVerification */) {
1020        return "Invalid code. Please check and try again.";
1021      }
1022      if ([17 /* PhoneVerificationSubmitError */].includes(mode)) {
1023        return "Unknown error. Please check your connection and try again.";
1024      }
1025      return "";
1026    }), submittingOtp = computed(globalThis.Checkout.store.auth.mode, (mode) => mode === 5 /* FetchingOtpValidation */), requestingAnotherOtp = computed(globalThis.Checkout.store.auth.mode, (mode) => {
1027      return mode === 8 /* FetchingResendOtp */;
1028    }), resentOtp = atom(false), otpRequestError = computed(globalThis.Checkout.store.auth.otpRequestFailure, ({ error }) => error);
1029    otpLoginOptions.subscribe((options) => {
1030      if (options && this.store.otpLoginSource.get() === void 0) {
1031        this.store.otpLoginSource.set(options[0]);
1032      }
1033    });
1034    const retrySeconds = atom(0);
1035    onMount(retrySeconds, () => {
1036      let ticking;
1037      const unsub = this.store.otpRequestFailure.subscribe(({ time, retry_in }) => {
1038        stop();
1039        if (!retry_in) return;
1040        const t = /* @__PURE__ */ new Date();
1041        t.setSeconds(t.getSeconds() + retry_in);
1042        const update = () => {
1043          const now = Date.now();
1044          let diff = t.getTime() - now;
1045          if (diff <= 0) {
1046            diff = 0;
1047            stop();
1048          }
1049          retrySeconds.set(Math.ceil(diff / 1e3));
1050        };
1051        update();
1052        ticking = setInterval(update, 1e3);
1053      });
1054      return () => {
1055        unsub();
1056        stop();
1057      };
1058      function stop() {
1059        if (ticking) {
1060          clearInterval(ticking);
1061          ticking = void 0;
1062        }
1063      }
1064    });
1065    this.computed = globalThis.Checkout.computed.auth = {
1066      validGuestEmail,
1067      requireLogin,
1068      otpLoginOptions,
1069      showingPhoneOtp,
1070      submittingOtp,
1071      requestingAnotherOtp,
1072      retrySeconds,
1073      resentOtp,
1074      otpRequestError,
1075      suggestingPhoneVerification,
1076      showingPhoneVerificationRequest,
1077      submittingPhoneVerification,
1078      RequestingPhoneVerification,
1079      phoneVerificationRequestErrorMsg,
1080      phoneVerificationMessages,
1081      phoneVerificationErrorMsg
1082    };
1083    globalThis.Checkout.store.checkout.mode.listen((mode) => {
1084      if (mode === "guest") {
1085        this.continueAsGuest();
1086        this.fetchSignOff().catch((error) => {
1087          console.log("error signing off", error);
1088        });
1089      }
1090    });
1091    this.store.flow.listen((change) => {
1092      this.onFlowChange(change);
1093    });
1094    const uniqueEmailsFound = /* @__PURE__ */ new Set();
1095    this.computed.validGuestEmail.subscribe((email) => {
1096      if (!email || uniqueEmailsFound.has(email)) return;
1097      uniqueEmailsFound.add(email);
1098      this.send("gotEmail");
1099      this.fetchAuthentication(email);
1100    });
1101    if (globalThis.Checkout.store.checkout.mode.get() === "saved") {
1102      this.send("alreadySaved");
1103    } else {
1104      this.send("noUser");
1105    }
1106  }
1107  static onFlowChange({ to, data }) {
1108    if (to === 7 /* ValidOtp */) {
1109      const { source } = data;
1110      const lacksVerifiedPhone = source === "email" && globalThis.Checkout.store.contact_pending_auth.get().is_phone_verified !== true && !sessionStorage.getItem("skipped-phone-verification");
1111      const nextEvent = lacksVerifiedPhone ? "suggestPhoneVerification" : "continueAsSaved";
1112      Promise.resolve().then(() => this.send(nextEvent));
1113    }
1114  }
1115  static send(eventId, data) {
1116    const modeName = this.store.mode.get();
1117    const modeConfig = AuthFlow[modeName];
1118    const nextMode = modeConfig && modeConfig[eventId] || AuthFlow["*"][eventId];
1119    if (nextMode) {
1120      this.store.flow.set({
1121        from: this.store.mode.get(),
1122        event: eventId,
1123        to: nextMode,
1124        data
1125      });
1126    }
1127  }
1128  static requestPhoneVerification() {
1129    const count = globalThis.Checkout.auth.store.phoneVerificationRequest.get().count ?? 0;
1130    globalThis.Checkout.auth.store.phoneVerificationRequest.setKey("count", count + 1);
1131    this.fetchAddVerificationNumber().then((result) => {
1132      if (result.ok) {
1133        globalThis.Checkout.auth.store.phoneVerificationRequest.setKey("error", void 0);
1134        this.send("sentPhoneVerificationOtp");
1135      } else {
1136        const count2 = globalThis.Checkout.auth.store.phoneVerificationRequest.get().rejections ?? 0;
1137        globalThis.Checkout.auth.store.phoneVerificationRequest.setKey("rejections", count2 + 1);
1138        this.send("failStartPhoneVerification", result);
1139      }
1140    }).catch((err) => {
1141      console.log("request phone verification failed", err);
1142      globalThis.Checkout.auth.store.phoneVerificationRequest.setKey("error", err);
1143      this.send("failStartPhoneVerification");
1144    });
1145    this.send("requestPhoneVerification");
1146  }
1147  /*
1148      /user_pages/api/v1/contacts/request_authentication.json
1149      Param: email
1150      Response:
1151      📌 400: {result: false, errors: 'Invalid email'}
1152      📌 404 (contact not found): {result: false}
1153      ✅ 200: {result: true, contact:
1154          {first_name: '', email: '', uuid: '', masked_phone: '', is_verified: '', is_phone_verified: '' }}
1155    */
1156  static fetchAuthentication(email) {
1157    fetch("/user_pages/api/v1/contacts/request_authentication.json?" + new URLSearchParams({ email }), {
1158      method: "GET"
1159    }).then((res) => {
1160      if (res.ok) {
1161        return res.json().then(({ result, contact }) => {
1162          const sentOTP = !!result;
1163          if (sentOTP) {
1164            globalThis.Checkout.store.contact_pending_auth.set({ ...contact ?? {}, authenticated: false });
1165            this.send("sentOtp");
1166          }
1167        });
1168      }
1169    }).catch((err) => {
1170      console.log("fetch exception", err);
1171    });
1172  }
1173  static submitOtp(code) {
1174    this.send("submitOtp");
1175    this.fetchValidateCode(code);
1176  }
1177  static resendCode(optionalSource) {
1178    this.send("resendOtp", { optionalSource });
1179    return this.fetchResendCode(optionalSource);
1180  }
1181  static fetchResendCode(optionalSource) {
1182    const { email } = globalThis.Checkout.store.contact_pending_auth.get();
1183    const source = optionalSource || globalThis.Checkout.auth.store.otpLoginSource.get();
1184    this.store.otpRequestFailure.set({
1185      time: -1,
1186      retry_in: 0
1187    });
1188    return fetch("/user_pages/api/v1/contacts/resend_otp.json", {
1189      method: "POST",
1190      headers: { "Content-Type": "application/json" },
1191      body: JSON.stringify({
1192        source: optionalSource || source,
1193        email
1194      })
1195    }).then((res) => {
1196      if (res.ok) {
1197        globalThis.Checkout.auth.store.otpLoginSource.set(source);
1198      }
1199      return res;
1200    }).then((res) => this.fetchedResendCode(res)).catch((err) => {
1201      this.fetchedResendCode(void 0, err);
1202    });
1203  }
1204  static fetchedResendCode(res, error) {
1205    let sent;
1206    const fail = ({ retry_in, error: error2 } = {}) => {
1207      const time = /* @__PURE__ */ new Date();
1208      this.store.otpRequestFailure.set({
1209        time,
1210        retry_in,
1211        error: error2
1212      });
1213      this.send("resendFailed", { retry_in, time, error: error2 });
1214    };
1215    if (res) {
1216      if (res.ok) {
1217        return res.json().then((props) => {
1218          const { result } = props;
1219          sent = result;
1220          if (sent) {
1221            this.send("sentOtp");
1222          } else {
1223            fail();
1224          }
1225        });
1226      } else {
1227        if (res.status === 400) {
1228          return res.json().then((props) => {
1229            const { retry_in } = props;
1230            fail({ retry_in });
1231          }).catch(fail);
1232        }
1233      }
1234    }
1235    fail({ error });
1236  }
1237  /*
1238      PATCH: /user_pages/api/v1/contacts/validate_and_sign_in.json
1239        2a. Param: {otp: '', email: '', source: 'email' | 'phone_number' }
1240        2b. Response
1241      404 (contact not found): {result: false}
1242      400 (invalid OTP): {result: false}
1243      200: {result: true, contact: {first_name: ‘’, email: ‘’, uuid: ‘’, masked_phone: ‘’,
1244        is_verified: ‘’, is_phone_verified: ‘’, payment_methods: [], shipping_addresses: [], billing_addresses: [] }}
1245    */
1246  static fetchValidateCode(otp) {
1247    const { email } = globalThis.Checkout.store.contact_pending_auth.get();
1248    const source = globalThis.Checkout.auth.store.otpLoginSource.get();
1249    fetch("/user_pages/api/v1/contacts/validate_and_sign_in", {
1250      method: "POST",
1251      credentials: "include",
1252      headers: { "Content-Type": "application/json" },
1253      body: JSON.stringify({
1254        email,
1255        otp,
1256        source
1257      })
1258    }).then((res) => {
1259      if (res.ok) {
1260        return res.json().then((data) => {
1261          const { result, contact } = data;
1262          if (result) {
1263            this.backfillContactFields(contact);
1264            CheckoutExistingOrders.fetch().then(() => {
1265              const isSelectedCartItemUpdatable = globalThis.Checkout.computed.checkoutCart.get().items.some((i) => i.type);
1266              if (isSelectedCartItemUpdatable) {
1267                globalThis.Checkout.store.checkout.lastModeIndependentOfCartItems.set("saved");
1268              } else {
1269                globalThis.Checkout.store.checkout.mode.set("saved");
1270              }
1271              this.send("validOtp", { source });
1272            });
1273          } else {
1274            this.otpFailed();
1275          }
1276        });
1277      } else {
1278        this.otpFailed();
1279      }
1280    }).catch((err) => {
1281      console.log("fetch auth exception", err);
1282      this.otpFailed();
1283    });
1284  }
1285  static fetchAddVerificationNumber() {
1286    console.log("fetchAddVerificationNumber");
1287    const { email, phone_number } = globalThis.Checkout.store.contact.get();
1288    return fetch("/user_pages/api/v1/contacts/request_otp_to_add_new_number", {
1289      method: "POST",
1290      headers: { "Content-Type": "application/json" },
1291      body: JSON.stringify({
1292        email,
1293        phone_number
1294      })
1295    }).then((res) => {
1296      if (res.ok) {
1297        return res;
1298      }
1299      return res.json().then(({ result, errors }) => {
1300        const errorResult = {
1301          ok: false,
1302          errors,
1303          numberTaken: errors === "Phone number already taken"
1304        };
1305        return errorResult;
1306      });
1307    });
1308  }
1309  static submitVerifyPhoneCode(otp) {
1310    const { email, phone_number } = globalThis.Checkout.store.contact.get();
1311    this.send("submitPhoneVerificationCode");
1312    const fail = (err) => {
1313    };
1314    return fetch("/user_pages/api/v1/contacts/validate_and_associate_phone_number", {
1315      method: "POST",
1316      headers: { "Content-Type": "application/json" },
1317      credentials: "same-origin",
1318      body: JSON.stringify({
1319        email,
1320        phone_number,
1321        otp
1322      })
1323    }).then((res) => {
1324      if (res.ok) {
1325        this.send("verificationSucceeded");
1326      } else {
1327        this.send("verificationFailed");
1328      }
1329    }).catch((err) => {
1330      console.log("fetch auth exception", err);
1331      this.send("verificationSubmitError", { error: err });
1332    });
1333  }
1334  static continueAsGuest() {
1335    this.send("continueAsGuest");
1336  }
1337  static fetchSignOff() {
1338    return fetch("/contacts/sign_out", {
1339      method: "DELETE",
1340      headers: { "Content-Type": "application/json" },
1341      credentials: "same-origin"
1342    }).then((res) => {
1343      if (!res.ok) {
1344        console.log("sign_out failed", res);
1345        throw new Error("Sign out failed");
1346      }
1347      return res;
1348    });
1349  }
1350  static otpFailed() {
1351    this.send("invalidOtp");
1352  }
1353  static backfillContactFields(data) {
1354    const {
1355      email,
1356      first_name,
1357      last_name,
1358      phone_number,
1359      uuid,
1360      is_phone_verified,
1361      masked_phone,
1362      payment_methods,
1363      billing_addresses,
1364      shipping_addresses
1365    } = data;
1366    let newBilling = {};
1367    if (billing_addresses && billing_addresses.length > 0) {
1368      const backfilled_billing_addresses = backfillAddressesId(billing_addresses);
1369      newBilling = backfilled_billing_addresses[0];
1370      globalThis.Checkout.store.billing.set(newBilling);
1371      globalThis.Checkout.store.billing_addresses.set(backfilled_billing_addresses);
1372    } else {
1373      globalThis.Checkout.store.billing_addresses.set([]);
1374    }
1375    let newShipping = {};
1376    if (shipping_addresses && shipping_addresses.length > 0) {
1377      const backfilled_shipping_addresses = backfillAddressesId(shipping_addresses);
1378      newShipping = backfilled_shipping_addresses[0];
1379      globalThis.Checkout.store.shipping.set(newShipping);
1380      globalThis.Checkout.store.shipping_addresses.set(backfilled_shipping_addresses);
1381    } else {
1382      globalThis.Checkout.store.shipping_addresses.set([]);
1383    }
1384    globalThis.Checkout.store.billingSameAsShipping.set(Boolean(newBilling.id && newBilling.id == newShipping.id));
1385    if (payment_methods && payment_methods.length > 0) {
1386      globalThis.Checkout.store.paymentMethods.set([
1387        ...globalThis.Checkout.store.paymentMethods.get() || [],
1388        ...payment_methods
1389      ]);
1390      if (!globalThis.Checkout.store.payment.id.get()) {
1391        globalThis.Checkout.store.payment.id.set(payment_methods[0].id);
1392        globalThis.Checkout.store.payment.type.set(
1393          resolveInitialPaymentType(payment_methods[0].type, globalThis.globalResourceData.enabledPayments)
1394        );
1395      }
1396      globalThis.Checkout.store.contact.set({
1397        ...globalThis.Checkout.store.contact.get(),
1398        email,
1399        first_name,
1400        last_name,
1401        phone_number
1402      });
1403      globalThis.Checkout.store.contact_pending_auth.set({
1404        ...globalThis.Checkout.store.contact.get(),
1405        email,
1406        first_name,
1407        last_name,
1408        phone_number,
1409        uuid,
1410        is_phone_verified,
1411        masked_phone,
1412        authenticated: true
1413      });
1414    }
1415  }
1416  static skipPhoneVerification() {
1417    sessionStorage.setItem("skipped-phone-verification", "true");
1418    this.send("skipPhoneVerification");
1419  }
1420  static continueAfterPhoneVerification() {
1421    this.send("continueAsSaved");
1422  }
1423};
1424__publicField(CheckoutAuth, "store");
1425__publicField(CheckoutAuth, "computed");
1426
1427// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-login-v2.ts
1428init_general();
1429init_runtime();
1430var CheckoutLoginV22 = class extends CF2Component {
1431  constructor(el, runtimeSel) {
1432    super(el, runtimeSel);
1433  }
1434  mount() {
1435    CheckoutAuth.initializeOneClickCheckoutFlow();
1436    this.mountPhoneVerificationSubform();
1437    this.firstNameInput = this.element.querySelector(".elCheckoutLogin_FirstName");
1438    this.deviceInfo = this.element.querySelector(".elCheckoutLogin_DeviceInfo");
1439    this.alternateOtp = this.element.querySelector(".elCheckoutLogin_AlternateSource");
1440    this.alternateOtpDeviceInfo = this.element.querySelector(".elCheckoutLogin_AlternateDeviceInfo");
1441    const resendCodeEl = this.element.querySelector(".elResendCode");
1442    const continueAsGuest = this.element.querySelector(".elLinkContinueAsGuest");
1443    const getOtpSourceDescription = (source) => {
1444      const partialContact = Checkout.store.contact_pending_auth.get();
1445      if (!partialContact) return "";
1446      return source === "email" ? this.checkoutLoginTexts.emailAddress : source === "phone_number" ? `${this.checkoutLoginTexts.phoneNumberEndingIn} ${partialContact.masked_phone}` : source;
1447    };
1448    const otpSource = Checkout.auth.store.otpLoginSource;
1449    const alternateOtpSource = computed([
1450      otpSource,
1451      Checkout.auth.computed.otpLoginOptions
1452    ], (otpSource2, otpOptions) => {
1453      return otpOptions.find((option) => option !== otpSource2);
1454    });
1455    this.bindText(this.firstNameInput, computed(Checkout.store.contact, (contact) => contact?.first_name));
1456    this.bindText(this.deviceInfo, otpSource, (otpSource2) => {
1457      return getOtpSourceDescription(otpSource2);
1458    });
1459    this.bindVisibility(this.alternateOtp, computed(alternateOtpSource, (alt) => !!alt));
1460    this.bindText(this.alternateOtpDeviceInfo, alternateOtpSource, getOtpSourceDescription);
1461    this.element.querySelector('[href="#change-otp-source"]').addEventListener("click", (ev) => {
1462      ev.preventDefault();
1463      const source = alternateOtpSource.get();
1464      CheckoutAuth.resendCode(source);
1465    });
1466    this.loginOtpInput = this.bindOtpInput(this.element.querySelector(".elCheckoutLoginInputContent .elOtpInput"), (code) => {
1467      CheckoutAuth.submitOtp(code);
1468    });
1469    this.loginOtpSubmit = this.element.querySelector('.elCheckoutLoginForm [href="#submit-otp-code"]');
1470    this.bindSubmitting(this.loginOtpSubmit.parentElement, CheckoutAuth.computed.submittingOtp);
1471    this.loginOtpSubmit.addEventListener("click", (ev) => {
1472      ev.preventDefault();
1473      this.loginOtpInput.submit();
1474    });
1475    this.checkoutLoginInfo = this.element.querySelector(".elOtpInfo p span");
1476    this.checkoutLoginError = this.element.querySelector(".elOtpError p span");
1477    this.checkoutLoginStatus = this.element.querySelector(".elOtpSendStatus p span");
1478    this.element.querySelector(".elLinkResendCode")?.addEventListener("click", () => {
1479      this.setErrorMessage("");
1480      CheckoutAuth.resendCode();
1481    });
1482    continueAsGuest?.addEventListener("click", () => {
1483      if (Checkout.store.checkout.mode.get() !== "guest") {
1484        Checkout.store.checkout.mode.set("guest");
1485      } else {
1486        CheckoutAuth.continueAsGuest();
1487      }
1488    });
1489    CheckoutAuth.store.flow.listen((change) => {
1490      this.onFlowChange(change);
1491    });
1492    Checkout.store.state.listen((state) => {
1493      if (state === Checkout.StoreStates.INITIALIZED) {
1494        this.initializePhoneNumber();
1495      }
1496    });
1497    Checkout.store.checkout.mode.listen((state) => {
1498      if (state === "saved") {
1499        this.initializePhoneNumber();
1500      }
1501    });
1502    this.bindText(this.checkoutLoginInfo, CheckoutAuth.computed.requestingAnotherOtp, (active) => {
1503      return active ? this.checkoutLoginTexts.requestingNewCode : ``;
1504    });
1505    this.bindText(this.element.querySelector(".elResendOtpWaitTime"), CheckoutAuth.computed.retrySeconds, (seconds) => seconds.toString());
1506    this.bindVisibility(resendCodeEl, CheckoutAuth.computed.retrySeconds, (seconds) => !(seconds > 0));
1507    this.bindVisibility(this.element.querySelector(".elWaitToResendOtp"), CheckoutAuth.computed.retrySeconds, (seconds) => seconds > 0);
1508    CheckoutAuth.store.otpRequestFailure.subscribe(({ error }) => {
1509      if (error) {
1510        this.notifyNetworkError(error);
1511      }
1512    });
1513    this.bindVisibility(this.element.querySelector(".elCheckoutLoginForm"), CheckoutAuth.computed.suggestingPhoneVerification, false);
1514    this.bindVisibility(this.element.querySelector(".elCheckoutPhoneVerificationContainer"), CheckoutAuth.computed.suggestingPhoneVerification);
1515    this.bindVisibility(this.element.querySelector(".elCheckoutPhoneVerificationOtpInputContent"), CheckoutAuth.computed.showingPhoneOtp);
1516  }
1517  mountPhoneVerificationSubform() {
1518    this.phoneVerificationOtpInput = this.bindOtpInput(
1519      this.element.querySelector(".elCheckoutPhoneVerificationOtpInputContent .elOtpInput"),
1520      (code) => CheckoutAuth.submitVerifyPhoneCode(code)
1521    );
1522    this.phoneVerificationOtpSubmit = this.element.querySelector('.elCheckoutPhoneVerificationForm [href="#submit-otp-code"]');
1523    this.bindSubmitting(this.phoneVerificationOtpSubmit.parentElement, CheckoutAuth.computed.submittingPhoneVerification);
1524    this.phoneVerificationOtpSubmit.addEventListener("click", (ev) => {
1525      ev.preventDefault();
1526      this.phoneVerificationOtpInput.submit();
1527    });
1528    this.element.querySelector(".elContinueAfterPhoneVerification").addEventListener("click", (evt) => {
1529      evt.preventDefault();
1530      CheckoutAuth.continueAfterPhoneVerification();
1531    });
1532    Array.from(this.element.querySelectorAll(".elSkipPhoneVerification")).forEac
1532h((el) => {
1533      el.addEventListener("click", (ev) => {
1534        ev.preventDefault();
1535        CheckoutAuth.skipPhoneVerification();
1536      });
1537    });
1538    this.element.querySelector(".elVerifyPhoneButton > a").addEventListener("click", (ev) => {
1539      ev.preventDefault();
1540      CheckoutAuth.requestPhoneVerification();
1541    });
1542    this.bindSubmitting(this.element.querySelector(".elVerifyPhoneButton"), CheckoutAuth.computed.RequestingPhoneVerification);
1543    this.element.querySelector(".elLinkRerequestPhoneVerification").addEventListener("click", (ev) => {
1544      ev.preventDefault();
1545      CheckoutAuth.requestPhoneVerification();
1546    });
1547    CheckoutAuth.computed.phoneVerificationRequestErrorMsg.subscribe((msg) => {
1548      $(this.element.querySelector(".elPhoneVerificationRequestError")).text(msg);
1549    });
1550    CheckoutAuth.computed.phoneVerificationErrorMsg.subscribe((msg) => {
1551      $(this.element.querySelector(".elPhoneVerificationOtpError")).text(msg);
1552      if (msg) {
1553        this.phoneVerificationOtpInput.clear();
1554        this.phoneVerificationOtpInput.focus();
1555      }
1556    });
1557    this.bindText(this.element.querySelector(".elPhoneVerificationMessages"), CheckoutAuth.computed.phoneVerificationMessages);
1558    CheckoutAuth.computed.RequestingPhoneVerification.subscribe((pending) => {
1559      this.element.querySelector(".elLinkRerequestPhoneVerification").href = pending ? "" : "#";
1560      if (pending === false) {
1561        this.phoneVerificationOtpInput.focus();
1562      }
1563    });
1564    this.bindVisibility(this.element.querySelector(".elCheckoutPhoneVerificationForm"), CheckoutAuth.computed.showingPhoneOtp);
1565    this.bindVisibility(this.element.querySelector(".elPhoneVerificationRequest"), CheckoutAuth.computed.showingPhoneVerificationRequest);
1566  }
1567  show() {
1568    const { first_name, masked_phone, is_phone_verified } = Checkout.store.contact_pending_auth.get();
1569    const checkoutElement = this.element.closest(".elCheckout");
1570    this.element.classList.remove("hide");
1571    this.resetLoginOtpInputs();
1572    this.resetMessages();
1573  }
1574  hide() {
1575    this.element.classList.add("hide");
1576  }
1577  setElText(el, text) {
1578    jQuery(el).text(text);
1579  }
1580  bindText(el, store, fn) {
1581    return store.subscribe((value) => {
1582      const text = fn ? fn(value) : value;
1583      this.setElText(el, text?.toString() || "");
1584    });
1585  }
1586  bindVisibility(el, store, test) {
1587    return store.subscribe((value) => {
1588      let visible = test !== void 0 ? typeof test === "function" ? test(value) : test === value : value;
1589      el.hidden = !visible;
1590    });
1591  }
1592  onInvalidOtp() {
1593    this.setErrorMessage(this.checkoutLoginTexts.invalidOtp);
1594    this.resetLoginOtpInputs();
1595  }
1596  onResentCode() {
1597    this.loginOtpInput.focus();
1598  }
1599  notifyNetworkError(error) {
1600    this.setErrorMessage(this.checkoutLoginTexts.networkError);
1601  }
1602  // TODO: factor out depencency on event and state strings
1603  // use computeds and prefer matching states to events
1604  onFlowChange({ event, from, to }) {
1605    if (event === "submitOtp") {
1606      this.onSubmittingOtp();
1607    }
1608    if (event === "resentOtp") {
1609      this.onResentCode();
1610    }
1611    if (event === "invalidOtp") {
1612      this.onInvalidOtp();
1613    }
1614    if (event === "resendFailed") {
1615      const { error, retry_in } = to;
1616      if (error) {
1617        this.notifyNetworkError();
1618      } else if (retry_in) {
1619        this.loginOtpInput.focus();
1620      }
1621    }
1622    if (event === "verificationSucceeded") {
1623      this.element.querySelector(".elCheckoutPhoneVerificationConfirmation").hidden = false;
1624      this.element.querySelector(".elCheckoutPhoneVerificationForm").hidden = true;
1625    }
1626  }
1627  bindOtpInput(input, onSubmit) {
1628    const maxLength = Number(input.getAttribute("maxlength"));
1629    const getCode = () => {
1630      return input.value;
1631    };
1632    const submitIfValid = () => {
1633      const code = getCode();
1634      if (code.length === maxLength) {
1635        onSubmit(code);
1636      }
1637    };
1638    input.addEventListener("keydown", (evt) => {
1639      if (evt.isComposing || evt.keyCode === 229) return;
1640      if (evt.key === "Tab") {
1641        return;
1642      }
1643      if (evt.key === "Enter") {
1644        evt.preventDefault();
1645        evt.stopPropagation();
1646        submitIfValid();
1647        return;
1648      }
1649      if (evt.key === "Backspace" || evt.keycode === 37) {
1650        if (input.value.length === maxLength) {
1651          submitIfValid();
1652        }
1653      }
1654    });
1655    input.addEventListener("input", () => {
1656      input.style.setProperty("--_otp-digit", input.selectionStart);
1657      if (input.value.length === maxLength) {
1658        submitIfValid();
1659      }
1660    });
1661    function setEnabled(enabled) {
1662      input.disabled = !enabled;
1663    }
1664    function focus(index = 0) {
1665      input.style.setProperty("--_otp-digit", index);
1666      input.focus();
1667    }
1668    function clear() {
1669      input.style.setProperty("--_otp-digit", 0);
1670      input.value = "";
1671    }
1672    return { input, getCode, setEnabled, clear, focus, submit: submitIfValid };
1673  }
1674  onSubmittingOtp() {
1675    this.resetMessages();
1676  }
1677  resetLoginOtpInputs() {
1678    this.loginOtpInput.clear();
1679    const checkoutElement = this.element.closest(".elCheckout");
1680    if (isElementVisibleOnViewport(checkoutElement, 20)) this.loginOtpInput.focus();
1681  }
1682  // maybe keep
1683  resetMessages() {
1684    this.setErrorMessage("");
1685  }
1686  setErrorMessage(message) {
1687    this.checkoutLoginError.innerHTML = message;
1688  }
1689  bindLoader(el, store, test) {
1690    return store.subscribe((value) => {
1691      let visible = test !== void 0 ? typeof test === "function" ? test(value) : test === value : value;
1692      if (visible) {
1693        el.dataset.loader = true;
1694      } else {
1695        delete el.dataset.loader;
1696      }
1697    });
1698  }
1699  bindSubmitting(button, store) {
1700    const elButton = button.querySelector(".elButton");
1701    const buttonMain = button.querySelector(".elButtonMain");
1702    const buttonMainText = buttonMain.querySelector(".elButtonMainText");
1703    const spinner = buttonMain.querySelector(".elButtonSpinner");
1704    const buttonText = buttonMainText.innerHTML;
1705    const submittingText = elButton.getAttribute("data-param-submittingtext") || "Submitting...";
1706    store.listen((submitting) => {
1707      if (submitting) {
1708        spinner.style.display = "inline-block";
1709        buttonMainText.innerHTML = submittingText;
1710      } else {
1711        spinner.style.removeProperty("display");
1712        buttonMainText.innerHTML = buttonText;
1713        button.querySelector(".elButtonSub").innerHTML = "";
1714      }
1715    });
1716  }
1717  bindDisabled(el, store, test) {
1718    return store.subscribe((value) => {
1719      let disabled = test !== void 0 ? typeof test === "function" ? test(value) : test === value : value;
1720      el.disabled = disabled;
1721    });
1722  }
1723  // #region phone number form
1724  // ported from contact-form-v1
1725  getInputFromName(name) {
1726    return this.element.querySelector(`[name='${name}']`);
1727  }
1728  // TODO: The intlTelInput setup should be handled by the Input/V1 blueprint
1729  initializePhoneNumber() {
1730    const phoneInput = this.getInputFromName("phone_number");
1731    const initialCountry = Checkout.store.shipping.get().country;
1732    IntlTel_initPhoneInput(phoneInput, { initialCountry });
1733    phoneInput.addEventListener("countrychange", () => {
1734      Checkout.store.contact.setKey("phone_number", phoneInput.iti.getNumber());
1735    });
1736    phoneInput.addEventListener("blur", () => {
1737      const value = phoneInput.iti.getNumber();
1738      Checkout.store.contact.setKey("phone_number", value);
1739    });
1740    const $phoneNumber = computed(Checkout.store.contact, ({ phone_number }) => phone_number);
1741    $phoneNumber.subscribe((phone_number) => {
1742      phoneInput.iti.setNumber(phone_number || "");
1743      if (phone_number) {
1744        $(phoneInput).parents(".elFormItemWrapper").addClass("hasValue");
1745      } else {
1746        $(phoneInput).parents(".elFormItemWrapper").removeClass("hasValue");
1747      }
1748    });
1749    const $phoneError = computed(Checkout.computed.contactErrors, (errors) => {
1750      this.checkForm(Checkout.computed.contactErrors.get());
1751      return errors?.fields?.phone_number;
1752    });
1753    const $disableSubmit = computed([$phoneNumber, $phoneError], (phone_number, error) => {
1754      return !phone_number || error;
1755    });
1756    Checkout.computed.contactErrors.subscribe((contactErrors) => {
1757      this.checkForm(contactErrors);
1758    });
1759    $disableSubmit.subscribe((disable) => {
1760      this.element.querySelector(".elVerifyPhoneButton > a").dataset.disabled = disable;
1761    });
1762  }
1763  checkForm(contactErrors) {
1764    const fields = ["phone_number"];
1765    fields.forEach((prop) => {
1766      const input = this.getInputFromName(prop);
1767      resetInputErrors(input);
1768    });
1769    if (Checkout.utils.hasErrors(contactErrors)) {
1770      const fieldErrors = contactErrors.fields;
1771      if (fieldErrors) {
1772        fields.forEach((field) => {
1773          const error = fieldErrors[field];
1774          if (error) {
1775            const { message } = error;
1776            const input = this.getInputFromName(field);
1777            addError(input, message);
1778          }
1779        });
1780      }
1781    }
1782  }
1783  // #endregion phone number form
1784};
1785registerComponent("CheckoutLogin/V2", CheckoutLoginV22);
1786window["CheckoutLoginV2"] = CheckoutLoginV22;
1787
1788// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-multiple-payments-v2.ts
1789init_define_process();
1790init_general();
1791init_nanostores();
1792init_runtime();
1793var CheckoutMultiplePaymentsV2 = class extends CF2Component {
1794  constructor(el, runtimeSel) {
1795    super(el, runtimeSel);
1796    __publicField(this, "devices", {
1797      "payment-card": void 0,
1798      paypal: void 0,
1799      "apple-pay": void 0,
1800      Klarna: void 0
1801    });
1802    __publicField(this, "CARD_FIELDS", ["number", "cvv", "date"]);
1803    __publicField(this, "selectedPaymentTab", batched(
1804      [Checkout.store.payment.type, Checkout.store.payment.virtualInstallmentId],
1805      (paymentType, virtualInstallmentId) => {
1806        return paymentType === "payment-card" && virtualInstallmentId !== null ? "splitit" : paymentType;
1807      }
1808    ));
1809  }
1810  mount() {
1811    this.cleanupPaymentOption("Klarna", () => !AVAILABLE_KLARNA_COUNTRIES.includes(globalThis.cfVisitorData.country));
1812    this.cleanupPaymentOption("apple-pay", () => !window.ApplePaySession);
1813    const form = document.querySelector("#cfAR");
1814    form.querySelectorAll("input[data-rebilly]").forEach((cfARInput) => {
1815      const dataRebillyAttribute = cfARInput.getAttribute("data-rebilly");
1816      const dataCfFormField = cfARInput.getAttribute("data-cf-form-field");
1817      const pageInputField = document.querySelector(`input[name="${dataCfFormField}"], select[name="${dataCfFormField}"]`);
1818      if (!pageInputField) {
1819        cfARInput?.removeAttribute("data-rebilly");
1820      } else {
1821        pageInputField?.setAttribute("data-rebilly", dataRebillyAttribute);
1822      }
1823    });
1824    Checkout.computed.modeLeaveEnterEvent.subscribe((ev) => {
1825      const { leave, next, enter, previous } = ev;
1826      const paymentState = Checkout.store.payment.state.get();
1827      if (paymentState == Checkout.PaymentStates.INITIALIZED) {
1828        if (leave && leave === this.mode) {
1829          this.unmountAllPaymentMethods();
1830        }
1831        if (enter === this.mode && previous) {
1832          this.mountRebillyElement();
1833        }
1834      }
1835    });
1836    Checkout.store.payment.state.listen((state) => {
1837      const checkoutMode = Checkout.store.checkout.mode.get();
1838      switch (state) {
1839        case Checkout.PaymentStates.LOADING: {
1840          if (this.mode == "guest") this.showLoader();
1841          break;
1842        }
1843        case Checkout.PaymentStates.INITIALIZED: {
1844          if (this.mode == "guest") this.hideLoader();
1845          this.element.setAttribute("data-initialized", "true");
1846          this.unmountAllPaymentMethods();
1847          if (this.mode == Checkout.store.checkout.mode.get()) this.mountRebillyElement();
1848          break;
1849        }
1850      }
1851    });
1852    Checkout.computed.paymentErrors.subscribe((errors) => {
1853      const errorWrapper = this.element.querySelector(".elCheckoutFormErrors");
1854      errorWrapper.classList.add("elHide");
1855      this.element.classList.remove("hasPaymentError");
1856      if (Checkout.utils.hasErrors(errors)) {
1857        const isFocused = this.element.querySelector(".payment-card-fields-container-focus");
1858        const isMobile = this.element.clientWidth <= 770;
1859        if (!isFocused || isMobile) {
1860          this.element.classList.add("hasPaymentError");
1861        }
1862        const fieldsErrors = errors.fields;
1863        if (fieldsErrors) {
1864          const errors2 = [];
1865          Object.entries(fieldsErrors).forEach(([field, error]) => {
1866            const { message } = error;
1867            errors2.push(message);
1868          });
1869          if (errors2.length) {
1870            const listErrors = `<ul>${errors2.map((err) => `<li>${err}</li>`).join("")}</ul>`;
1871            errorWrapper.innerHTML = listErrors;
1872            errorWrapper.classList.remove("elHide");
1873          } else {
1874            errorWrapper.classList.add("elHide");
1875          }
1876        }
1877      }
1878    });
1879    Checkout.store.payment.type.listen((type) => {
1880      const paymentState = Checkout.store.payment.state.get();
1881      this.showPaymentType(type);
1882      this.unmountAllPaymentMethods();
1883      if (type == "paypal" && Checkout.store.payment.paypal.state.get().state == Checkout.PaypalStates.PAYMENT_METHOD_APPROVED) return;
1884      if (this.mode == Checkout.store.checkout.mode.get()) {
1885        if (paymentState === Checkout.PaymentStates.INITIALIZED) {
1886          this.mountRebillyElement();
1887        }
1888      }
1889    });
1890    Checkout.store.submitting.listen((value) => {
1891      const paymentType = Checkout.store.payment.type.get();
1892      const failedSubmit = value.state == Checkout.SubmittingStates.ERROR;
1893      if (failedSubmit && paymentType == "apple-pay" && this.mode == Checkout.store.checkout.mode.get()) {
1894        this.unmountAllPaymentMethods();
1895        this.mountRebillyElement();
1896      }
1897    });
1898    if (this.enabledPayments.includes("paypal")) {
1899      this.addPaypalEventListeners();
1900    }
1901    this.addPaymentEventListeners();
1902    this.initializeInstallments();
1903    this.showPaymentType(this.selectedPaymentTab.get());
1904  }
1905  cleanupPaymentOption(paymentType, cleanupCallback) {
1906    const paymentIndex = this.enabledPayments.findIndex((v) => v == paymentType);
1907    if (cleanupCallback() && paymentIndex >= 0) {
1908      this.enabledPayments.splice(paymentIndex, 1);
1909    }
1910    const paymentElements = this.element.querySelectorAll(`[data-
1910payment-type="${paymentType}"]`);
1911    if (!paymentElements.length) return;
1912    if (cleanupCallback() || !this.enabledPayments.includes(paymentType)) {
1913      paymentElements.forEach((el) => el.remove());
1914      if (this.enabledPayments.length <= 1) {
1915        this.element.querySelector(".pai-payment-methods")?.remove();
1916      }
1917    } else {
1918      paymentElements.forEach((el) => el.classList.remove("elHide"));
1919    }
1920  }
1921  showLoader() {
1922    this.element.querySelector(".elPAILoader").dataset.loader = true;
1923  }
1924  hideLoader() {
1925    this.element.querySelector(".elPAILoader").dataset.loader = false;
1926  }
1927  addPaypalEventListeners() {
1928    Checkout.store.payment.paypal.state.listen((paypalState) => {
1929      switch (paypalState.state) {
1930        case Checkout.PaypalStates.IDLE: {
1931          this.paypalPreventClick();
1932          this.paypalInitializeContent();
1933          break;
1934        }
1935        case Checkout.PaypalStates.INITIALIZED: {
1936          this.paypalAllowClick();
1937          this.paypalInitializeContent();
1938          break;
1939        }
1940        case Checkout.PaypalStates.ERROR: {
1941          this.paypalPreventClick();
1942          switch (paypalState.code) {
1943            case Checkout.ErrorTypes.PAYPAL_DECLINED_ERROR: {
1944              const paypalStatus = this.getPaypalContent().querySelector(".paypal-status");
1945              paypalStatus.setAttribute("data-type", "error");
1946              paypalStatus.innerText = this.checkoutMultiplePaymentsTexts.paypalDeclined;
1947              break;
1948            }
1949            case Checkout.ErrorTypes.PAYPAL_CUSTOM_ERROR: {
1950              const paypalStatus = this.getPaypalContent().querySelector(".paypal-status");
1951              paypalStatus.setAttribute("data-type", "error");
1952              paypalStatus.innerText = paypalState.message;
1953              break;
1954            }
1955          }
1956          break;
1957        }
1958        case Checkout.PaypalStates.PAYMENT_METHOD_APPROVED: {
1959          this.getPaypalContent().querySelector(".paypal-content-button-container").classList.add("elHide");
1960          const paypalStatus = this.getPaypalContent().querySelector(".paypal-status");
1961          paypalStatus.setAttribute("data-type", "success");
1962          paypalStatus.innerHTML = `<i class="fas fa-check"></i> ${this.checkoutMultiplePaymentsTexts.yourPaymentIsConfigured}`;
1963          break;
1964        }
1965      }
1966    });
1967  }
1968  getPaypalContent() {
1969    return this.element.querySelector(".paypal-content");
1970  }
1971  paypalInitializeContent() {
1972    this.getPaypalContent().querySelector(".paypal-status").innerHTML = "";
1973    this.getPaypalContent().querySelector(".paypal-content-button-container").classList.remove("elHide");
1974  }
1975  paypalPreventClick() {
1976    this.getPaypalContent().querySelector(".elSpinnerWrapper").dataset.loader = true;
1977  }
1978  paypalAllowClick() {
1979    this.getPaypalContent().querySelector(".elSpinnerWrapper").dataset.loader = false;
1980  }
1981  showPaymentType(type) {
1982    const paymentFields = this.element.querySelectorAll(".pai-payment-field");
1983    paymentFields.forEach((element) => {
1984      element.dataset.active = element.dataset.paymentType == type;
1985    });
1986    const paymentContents = this.element.querySelectorAll(".pai-payment-content");
1987    paymentContents.forEach((element) => {
1988      element.dataset.active = element.dataset.paymentType == type;
1989    });
1990  }
1991  addPaymentEventListeners() {
1992    const paymentFields = this.element.querySelectorAll(".pai-payment-field");
1993    paymentFields.forEach((element) => {
1994      element.addEventListener("click", (evt) => {
1995        evt.preventDefault();
1996        const paymentType = element.dataset.paymentType;
1997        const actualPaymentType = element.dataset.actualPaymentType;
1998        if (this.selectedPaymentTab.get() === paymentType) {
1999          return;
2000        }
2001        if (Checkout.store.payment.type.get() == "payment-card" && !Object.values(this.devices["payment-card"] ?? {}).every((v) => v?.element?.mounted)) return;
2002        if (this.enabledPayments.includes("paypal") && Checkout.store.payment.paypal.state.get().state != Checkout.PaypalStates.PAYMENT_METHOD_APPROVED) {
2003          Checkout.store.payment.paypal.state.set({ state: Checkout.PaypalStates.IDLE });
2004        }
2005        Checkout.store.payment["payment-card"].events.set({});
2006        Checkout.store.payment.type.set(actualPaymentType ?? paymentType);
2007        if (paymentType === "splitit") {
2008          this.syncInstallments(true);
2009        } else {
2010          Checkout.store.payment.virtualInstallmentId.set(null);
2011        }
2012      });
2013    });
2014  }
2015  unmountPaymentMethod(type) {
2016    switch (type) {
2017      case "apple-pay": {
2018        if (!this.devices["apple-pay"]) break;
2019        this.devices["apple-pay"].unmount();
2020        this.devices["apple-pay"] = void 0;
2021        break;
2022      }
2023      case "paypal": {
2024        if (!this.devices.paypal) break;
2025        this.devices.paypal.unmount();
2026        this.devices.paypal = void 0;
2027        break;
2028      }
2029      case "payment-card": {
2030        if (!this.devices["payment-card"]) break;
2031        ["number", "cvv", "date"].forEach((key) => {
2032          this.devices["payment-card"][key].element.mounted && this.devices["payment-card"][key].destroy();
2033        });
2034        this.devices["payment-card"] = void 0;
2035        break;
2036      }
2037      case "Klarna": {
2038        if (!this.devices.Klarna) break;
2039        this.devices.Klarna.unmount();
2040        this.devices.Klarna = void 0;
2041        break;
2042      }
2043    }
2044  }
2045  unmountPaymentMethods(types) {
2046    types.forEach((type) => {
2047      this.unmountPaymentMethod(type);
2048    });
2049  }
2050  unmountAllPaymentMethods() {
2051    this.unmountPaymentMethods(this.enabledPayments);
2052  }
2053  mountRebillyElement() {
2054    const Rebilly = globalThis.Rebilly;
2055    const paymentType = Checkout.store.payment.type.get();
2056    if (paymentType == "apple-pay" && !this.devices["apple-pay"]) {
2057      this.devices["apple-pay"] = Rebilly.applePay.mount(`[data-wrapper-checkout-state="${this.mode}"] .apple-pay-button`);
2058    }
2059    if (paymentType == "payment-card" && !this.devices["payment-card"]?.number) {
2060      const activeContent = this.element.querySelector(`.pai-payment-content[data-active="true"]`);
2061      const paymentCardWrapper = activeContent?.querySelector(".payment-card-fields-container");
2062      if (!paymentCardWrapper) return;
2063      this.devices["payment-card"] = {};
2064      let lastEvent;
2065      const mountNameMapper = {
2066        number: "cardNumber",
2067        cvv: "cardCvv",
2068        date: "cardExpiration"
2069      };
2070      this.CARD_FIELDS.forEach((key) => {
2071        const mountPoint = paymentCardWrapper.querySelector(`.payment-card-${key}-mount`);
2072        const rebillyField = Rebilly.card.mount(mountPoint, mountNameMapper[key]);
2073        const fieldElement = rebillyField.element.element.querySelector(".rebilly-framepay");
2074        rebillyField.on("focus", (ev) => {
2075          this.element.classList.remove("hasPaymentError");
2076          fieldElement.classList.add(`payment-card-field-focus`);
2077          paymentCardWrapper.classList.add("payment-card-fields-container-focus");
2078          Checkout.store.payment["payment-card"].events.setKey(key, void 0);
2079          lastEvent = null;
2080        });
2081        rebillyField.on("change", (ev) => {
2082          lastEvent = ev;
2083        });
2084        rebillyField.on("blur", (ev) => {
2085          fieldElement.classList.remove(`payment-card-field-focus`);
2086          paymentCardWrapper.classList.remove("payment-card-fields-container-focus");
2087          Checkout.store.payment["payment-card"].events.setKey(key, lastEvent);
2088        });
2089        this.devices["payment-card"][key] = rebillyField;
2090      });
2091    } else if (paymentType == "paypal") {
2092      this.devices.paypal = Rebilly.paypal.mount(`[data-wrapper-checkout-state="${this.mode}
2092"] .paypal-mount`, { extraData: Checkout.PaypalCallbacks });
2093    } else if (paymentType == "Klarna") {
2094      this.devices.Klarna = Rebilly.klarna.mount(`[data-wrapper-checkout-state="${this.mode}"] .klarna-mount`);
2095    }
2096  }
2097  initializeInstallments() {
2098    if (!this.enabledPayments.includes("splitit")) return;
2099    const installmentsContainer = this.element.querySelector(".installments-container");
2100    const installmentsButton = this.element.querySelector(".installments-custom-dropdown-button");
2101    const dropdownOptions = this.element.querySelector(".installments-dropdown-options");
2102    const arrow = this.element.querySelector(".installments-dropdown-arrow");
2103    if (this.mode === Checkout.store.checkout.mode.get()) {
2104      const initialInstallmentsInput = this.element.querySelector('input[name="initial_installments_value"]');
2105      if (initialInstallmentsInput) {
2106        const value = initialInstallmentsInput.value;
2107        Checkout.store.payment.virtualInstallmentId.set(value);
2108        this.syncInstallments();
2109      }
2110    }
2111    Checkout.computed.checkoutCart.listen((cart) => {
2112      if (this.mode !== Checkout.store.checkout.mode.get()) return;
2113      this.syncInstallments();
2114    });
2115    Checkout.store.summary.listen((summaryState) => {
2116      if (this.mode !== Checkout.store.checkout.mode.get()) return;
2117      this.syncInstallments();
2118    });
2119    installmentsButton.addEventListener("click", (evt) => {
2120      evt.preventDefault();
2121      evt.stopPropagation();
2122      const isOpen = dropdownOptions.style.display === "block";
2123      dropdownOptions.style.display = isOpen ? "none" : "block";
2124      arrow.classList.toggle("open", !isOpen);
2125    });
2126    document.addEventListener("click", (evt) => {
2127      const isClickInside = installmentsContainer.contains(evt.target);
2128      if (!isClickInside && dropdownOptions.style.display === "block") {
2129        this.closeinstallmentsDropdown();
2130      }
2131    });
2132    this.selectedPaymentTab.listen((selectedTab, oldSelectedTab) => {
2133      this.showPaymentType(selectedTab);
2134      if (this.mode !== Checkout.store.checkout.mode.get()) return;
2135      const shouldRemount = Checkout.store.payment.state.get() == Checkout.PaymentStates.INITIALIZED && (selectedTab == "splitit" || oldSelectedTab == "payment-card" || (selectedTab == "payment-card" || oldSelectedTab == "splitit"));
2136      if (shouldRemount) {
2137        if (this.devices["payment-card"]) {
2138          this.unmountPaymentMethod("payment-card");
2139        }
2140        this.mountRebillyElement();
2141      }
2142    });
2143  }
2144  syncInstallments(forceSelection = false) {
2145    const installmentsContainer = this.element.querySelector(".installments-container");
2146    const dropdownOptions = this.element.querySelector(".installments-dropdown-options");
2147    const cart = Checkout.computed.checkoutCart.get();
2148    const hasRecurringPrice = cart.items.some(({ price_id }) => {
2149      const price = globalThis.globalResourceData.pricesById[price_id];
2150      return price.is_recurring;
2151    });
2152    const hasFreeTrial = cart.items.some(({ price_id }) => {
2153      const price = globalThis.globalResourceData.pricesById[price_id];
2154      return price.initial_price_cents === 0 || !price.initial_price_cents;
2155    });
2156    const hasNonBumpProducts = cart.items.some(({ product_id }) => {
2157      return !globalThis.Checkout.productsById[product_id]?.bump;
2158    });
2159    if (hasRecurringPrice || hasFreeTrial || cart.items.length === 0 || !hasNonBumpProducts) {
2160      this.disableInstallments();
2161      return;
2162    }
2163    let totalAmount = 0;
2164    let currencySymbol = Checkout.products[0].variants[0].currency;
2165    const summaryState = Checkout.store.summary.get();
2166    if (summaryState?.data?.total?.amount) {
2167      const summaryData = summaryState.data;
2168      totalAmount = summaryData.total.amount;
2169      if (summaryData.currency_symbol) {
2170        currencySymbol = summaryData.currency_symbol;
2171      }
2172    } else {
2173      const cartItems = Checkout.computed.checkoutCart.get().items;
2174      if (!cartItems || cartItems.length === 0) {
2175        this.disableInstallments();
2176        return;
2177      }
2178      Object.values(cartItems).forEach((item) => {
2179        const priceId = item.price_id;
2180        const quantity = item.quantity || 1;
2181        const priceData = globalResourceData.pricesById?.[priceId];
2182        if (priceData?.initial_price_cents) {
2183          totalAmount += priceData.initial_price_cents / 100 * quantity;
2184        }
2185      });
2186    }
2187    if (totalAmount <= 0) {
2188      this.disableInstallments();
2189      return;
2190    }
2191    const currentVirtualId = Checkout.store.payment.virtualInstallmentId.get();
2192    const installmentsTab = this.element.querySelector('[data-payment-type="splitit"]');
2193    const installmentsContent = this.element.querySelector(".installments-content");
2194    installmentsTab.classList.remove("elHide");
2195    installmentsContent.classList.remove("elHide");
2196    const tabSelector = this.element.querySelector(".pai-payment-methods");
2197    tabSelector?.classList.remove("elHide");
2198    if (!currentVirtualId && !forceSelection) {
2199      this.disableInstallments(false);
2200      return;
2201    }
2202    const installmentOptions = globalResourceData.installments.map((inst) => ({
2203      duration: inst.duration,
2204      type: inst.installment_type
2205    }));
2206    let optionsHTML = "";
2207    installmentOptions.forEach(({ duration, type }) => {
2208      if (duration >= 2 && duration <= 12) {
2209        const amountPerInstallment = Math.floor(totalAmount / duration * 100) / 100;
2210        const formattedAmount = formatNumberToCurrency(currencySymbol, amountPerInstallment);
2211        const scheduleText = "every month";
2212        const virtualId = encodeVirtualInstallmentId(duration, type);
2213        optionsHTML += `
2214          <div class="installments-dropdown-option" data-virtual-id="${virtualId}" data-count="${duration}" data-amount="${amountPerInstallment}" data-currency="${currencySymbol}" data-type="${type}">
2215            <div>
2216              <div class="installments-option-text">${duration} payments</div>
2217              <div class="installments-option-schedule">${scheduleText}</div>
2218            </div>
2219            <div class="installments-dropdown-option-amount">${formattedAmount}</div>
2220          </div>
2221        `;
2222      }
2223    });
2224    dropdownOptions.innerHTML = optionsHTML;
2225    dropdownOptions.querySelectorAll(".installments-dropdown-option").forEach((option) => {
2226      option.addEventListener("click", () => {
2227        const count = parseInt(option.getAttribute("data-count"), 10);
2228        const amount = parseFloat(option.getAttribute("data-amount"));
2229        const currency = option.getAttribute("data-currency");
2230        const type = option.getAttribute("data-type");
2231        this.selectInstallmentPlan(count, amount, currency, type);
2232      });
2233    });
2234    const currentVirtualIdParsed = decodeVirtualInstallmentId(currentVirtualId);
2235    if (installmentOptions.length > 0) {
2236      const isCurrentValid = currentVirtualIdParsed && installmentOptions.some(
2237        (opt) => opt.duration === currentVirtualIdParsed.duration && opt.type === currentVirtualIdParsed.type
2238      );
2239      const shouldPreserveSelection = !forceSelection && isCurrentValid;
2240      if (shouldPreserveSelection && currentVirtualIdParsed) {
2241        const currentAmount = Math.floor(totalAmount / currentVirtualIdParsed.duration * 100) / 100;
2242        this.selectInstallmentPlan(currentVirtualIdParsed.duration, currentAmount, currencySymbol, currentVirtualIdParsed.type);
2243      } else {
2244        const first = installmentOptions[0];
2245        const firstAmount = Math.floor(totalAmount / first.duration * 100) / 100;
2246        this.selectInstallmentPlan(first.duration, firstAmount, currencySymbol, first.type);
2247      }
2248    }
2249  }
2250  closeinstallmentsDropdown() {
2251    const dropdownOptions = this.element.querySelector(".installments-dropdown-options");
2252    const arrow = this.element.querySelector(".installments-dropdown-arrow");
2253    dropdownOptions.style.display = "none";
2254    arrow.classList.remove("open");
2255  }
2256  selectInstallmentPlan(count, amount, currencySymbol, type = "monthly") {
2257    const selectedText = this.element.querySelector(".installments-selected-text");
2258    const selectedSchedule = this.element.querySelector(".installments-selected-schedule");
2259    const formattedAmount = formatNumberToCurrency(currencySymbol, amount);
2260    selectedText.textContent = `${count} payments`;
2261    selectedSchedule.textContent = formattedAmount;
2262    const previewAmount = this.element.querySelector(".installments-preview-amount");
2263    const previewSchedule = this.element.querySelector(".installments-preview-schedule");
2264    previewAmount.textContent = formattedAmount;
2265    const scheduleText = "per month";
2266    previewSchedule.textContent = `${scheduleText} \xD7 ${count} payments`;
2267    const scheduleContainer = this.element.querySelector(".installments-payment-schedule");
2268    const today = /* @__PURE__ */ new Date();
2269    const dates = this.getinstallmentsDates(today, count, type);
2270    let html = "";
2271    dates.forEach((date, index) => {
2272      const displayDate = index === 0 ? "Today" : date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
2273      html += `
2274        <div class="installments-schedule-item">
2275          <span>Payment ${index + 1} (${displayDate})</span>
2276          <span class="installments-schedule-amount">${formattedAmount}</span>
2277        </div>
2278      `;
2279    });
2280    scheduleContainer.innerHTML = html;
2281    const virtualId = encodeVirtualInstallmentId(count, type);
2282    Checkout.store.payment.virtualInstallmentId.set(virtualId);
2283    this.closeinstallmentsDropdown();
2284  }
2285  getinstallmentsDates(startDateObj, count, type = "monthly") {
2286    const result = [];
2287    if (type === "monthly") {
2288      const startDay = startDateObj.getDate();
2289      const startMonth = startDateObj.getMonth();
2290      const startYear = startDateObj.getFullYear();
2291      for (let i = 0; i < count; i++) {
2292        const newDate = new Date(startYear, startMonth + i, startDay);
2293        if (newDate.getDate() !== startDay) {
2294          newDate.setDate(0);
2295        }
2296        result.push(newDate);
2297      }
2298    }
2299    return result;
2300  }
2301  disableInstallments(hideTab = true) {
2302    const installmentsTab = this.element.querySelector('[data-payment-type="splitit"]');
2303    const installmentsContent = this.element.querySelector(".installments-content");
2304    installmentsContent.classList.add("elHide");
2305    Checkout.store.payment.virtualInstallmentId.set(null);
2306    if (hideTab) {
2307      installmentsTab.classList.add("elHide");
2308      if (this.enabledPayments.length === 2) {
2309        const tabSelector = this.element.querySelector(".pai-payment-methods");
2310        if (tabSelector) {
2311          tabSelector.classList.add("elHide");
2312        }
2313      }
2314    }
2315  }
2316};
2317registerComponent("CheckoutMultiplePayments/V2", CheckoutMultiplePaymentsV2);
2318window["CheckoutMultiplePaymentsV2"] = CheckoutMultiplePaymentsV2;
2319
2320// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-express-payments-v1.ts
2321init_define_process();
2322init_runtime();
2323var CheckoutExpressPaymentsV1 = class extends CF2Component {
2324  constructor(el, runtimeSel) {
2325    super(el, runtimeSel);
2326    __publicField(this, "devices", {
2327      "apple-pay": void 0
2328    });
2329  }
2330  mount() {
2331    this.enabledPayments = this.enabledPayments ?? [];
2332    this.cleanupApplePayOption();
2333    const form = document.querySelector("#cfAR");
2334    form.querySelectorAll("input[data-rebilly]").forEach((cfARInput) => {
2335      const dataRebillyAttribute = cfARInput.getAttribute("data-rebilly");
2336      const dataCfFormField = cfARInput.getAttribute("data-cf-form-field");
2337      const pageInputField = document.querySelector('input[name="' + dataCfFormField + '"]');
2338      if (!pageInputField) {
2339        cfARInput?.removeAttribute("data-rebilly");
2340      } else {
2341        pageInputField?.setAttribute("data-rebilly", dataRebillyAttribute);
2342      }
2343    });
2344    Checkout.computed.modeLeaveEnterEvent.subscribe((ev) => {
2345      const { leave, next, enter, previous } = ev;
2346      const paymentState = Checkout.store.payment.state.get();
2347      if (paymentState == Checkout.PaymentStates.INITIALIZED) {
2348        if (leave && leave === this.mode) {
2349          this.unmountAllPaymentMethods();
2350        }
2351        if (enter === this.mode && previous) {
2352          this.mountExpressRebillyElements();
2353        }
2354      }
2355    });
2356    Checkout.store.payment.state.listen((state) => {
2357      const checkoutMode = Checkout.store.checkout.mode.get();
2358      switch (state) {
2359        case Checkout.PaymentStates.LOADING: {
2360          if (this.mode == "guest") this.showLoader();
2361          break;
2362        }
2363        case Checkout.PaymentStates.INITIALIZED: {
2364          if (this.mode == "guest") this.hideLoader();
2365          this.element.setAttribute("data-initialized", "true");
2366          this.unmountAllPaymentMethods();
2367          if (this.mode == Checkout.store.checkout.mode.get()) this.mountExpressRebillyElements();
2368          break;
2369        }
2370      }
2371    });
2372  }
2373  cleanupApplePayOption() {
2374    const applePayIndex = this.enabledPayments.findIndex((v) => v == "apple-pay");
2375    if (!window.ApplePaySession && applePayIndex >= 0) {
2376      this.enabledPayments.splice(applePayIndex, 1);
2377    }
2378    const applePayElement = this.element.querySelector(".apple-pay-button-wrapper");
2379    if (!applePayElement) return;
2380    if (!window.ApplePaySession || !this.enabledPayments.includes("apple-pay")) {
2381      const isApplePayActive = applePayElement.getAttribute("data-active") == "true";
2382      applePayElement.remove();
2383      if (this.enabledPayments.length <= 1) {
2384        this.element.querySelector(".pai-express-payment-methods")?.remove();
2385        this.element.querySelector(".elCheckoutExpressPaymentSeperator")?.remove();
2386      }
2387    }
2388  }
2389  showLoader() {
2390    this.element.querySelector(".elPAILoader").dataset.loader = true;
2391  }
2392  hideLoader() {
2393    this.element.querySelector(".elPAILoader").dataset.loader = false;
2394  }
2395  unmountPaymentMethod(type) {
2396    switch (type) {
2397      case "apple-pay": {
2398        if (!this.devices["apple-pay"]) break;
2399        this.devices["apple-pay"].unmount();
2400        this.devices["apple-pay"] = void 0;
2401        break;
2402      }
2403    }
2404  }
2405  unmountPaymentMethods(types) {
2406    types.forEach((type) => {
2407      this.unmountPaymentMethod(type);
2408    });
2409  }
2410  unmountAllPaymentMethods() {
2411    this.unmountPaymentMethods(this.enabledPayments);
2412  }
2413  mountExpressRebillyElements() {
2414    const Rebilly = globalThis.Rebilly;
2415    Object.values(this.enabledPayments).forEach((paymentType) => {
2416      if (paymentType == "apple-pay" && !this.devices["apple-pay"]) {
2417        this.devices["apple-pay"] = Rebilly.applePay.mount(`[data-wrapper-checkout-state="${this.mode}"] .elExpressPaymentMethods .apple-pay-button`);
2418      }
2419    });
2420  }
2421};
2422registerComponent("CheckoutExpressPayments/V1", CheckoutExpressPaymentsV1);
2423window["CheckoutExpressPaymentsV1"] = CheckoutExpressPaymentsV1;
2424
2425// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-contact-form-v1.ts
2426init_define_process();
2427init_input_v1();
2428init_cf_utils();
2429
2430// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-subscription-duplicates.ts
2431init_define_process();
2432init_nanostores();
2433var CheckoutSubscriptionDuplicates = class {
2434  static initialize() {
2435    if (this.initialized) return;
2436    this.store = {
2437      mode: atom(0 /* Idle */),
2438      duplicateInfo: atom(null),
2439      checkedEmails: atom(/* @__PURE__ */ new Set()),
2440      lastError: atom(null)
2441    };
2442    this.computed = {
2443      showingDuplicates: computed(this.store.mode, (mode) => mode === 2 /* FoundDuplicates */),
2444      hasError: computed(this.store.mode, (mode) => mode === 4 /* Error */),
2445      duplicateSubscription: computed(this.store.duplicateInfo, (info) => info?.subscription || null)
2446    };
2447    this.setupEmailMonitoring();
2448    this.initialized = true;
2449  }
2450  static setupEmailMonitoring() {
2451    const validGuestEmail = computed(
2452      [
2453        globalThis.Checkout.store.checkout.mode,
2454        globalThis.Checkout.store.contact,
2455        globalThis.Checkout.computed.contactErrors,
2456        globalThis.Checkout.computed.hideContactInformationForm
2457      ],
2458      (mode, { email }, errors, hideContactInformationForm) => mode === "guest" && !errors?.fields?.email && !hideContactInformationForm && email
2459    );
2460    validGuestEmail.subscribe((email) => {
2461      if (!email) return;
2462      const checkedEmails = this.store.checkedEmails.get();
2463      if (checkedEmails.has(email)) return;
2464      checkedEmails.add(email);
2465      this.store.checkedEmails.set(new Set(checkedEmails));
2466      this.checkForDuplicateSubscriptions(email);
2467    });
2468  }
2469  static async checkForDuplicateSubscriptions(email) {
2470    try {
2471      this.store.mode.set(1 /* CheckingDuplicates */);
2472      this.store.lastError.set(null);
2473      const response = await fetch(
2474        "/user_pages/api/v1/contacts/check_subscription_duplicates.json?" + new URLSearchParams({ email }),
2475        {
2476          method: "GET",
2477          headers: {
2478            "Content-Type": "application/json"
2479          }
2480        }
2481      );
2482      if (!response.ok) {
2483        if (response.status === 404) {
2484          this.store.duplicateInfo.set({
2485            hasMatches: false,
2486            subscription: null
2487          });
2488          this.store.mode.set(3 /* NoDuplicatesFound */);
2489          return;
2490        }
2491        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
2492      }
2493      const data = await response.json();
2494      if (data.result && data.duplicate_subscription) {
2495        this.store.duplicateInfo.set({
2496          hasMatches: true,
2497          subscription: data.duplicate_subscription
2498        });
2499        this.store.mode.set(2 /* FoundDuplicates */);
2500      } else {
2501        this.store.duplicateInfo.set({
2502          hasMatches: false,
2503          subscription: null
2504        });
2505        this.store.mode.set(3 /* NoDuplicatesFound */);
2506      }
2507    } catch (error) {
2508      console.error("Subscription duplicate check failed:", error);
2509      this.store.lastError.set(error.message || "Unknown error occurred");
2510      this.store.mode.set(4 /* Error */);
2511    }
2512  }
2513  static dismissDuplicates() {
2514    this.store.mode.set(0 /* Idle */);
2515    this.store.duplicateInfo.set(null);
2516  }
2517  static reset() {
2518    this.store.mode.set(0 /* Idle */);
2519    this.store.duplicateInfo.set(null);
2520    this.store.checkedEmails.set(/* @__PURE__ */ new Set());
2521    this.store.lastError.set(null);
2522  }
2523};
2524__publicField(CheckoutSubscriptionDuplicates, "store");
2525__publicField(CheckoutSubscriptionDuplicates, "computed");
2526__publicField(CheckoutSubscriptionDuplicates, "initialized", false);
2527
2528// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-contact-form-v1.ts
2529init_runtime();
2530var CheckoutContactFormV1 = class extends CF2Component {
2531  constructor(el, runtimeSel) {
2532    super(el, runtimeSel);
2533  }
2534  mount() {
2535    Checkout.store.contact.listen((contactData) => {
2536      this.fields.forEach((prop) => {
2537        const input = this.getInputFromName(prop);
2538        const inputValue = input.value;
2539        const newValue = contactData[prop];
2540        if (newValue) {
2541          if (prop === "phone_number") {
2542            input.iti.setNumber(newValue);
2543          } else {
2544            input.value = newValue;
2545          }
2546          $(input).parents(".elFormItemWrapper").addClass("hasValue");
2547        } else {
2548          input.value = "";
2549          $(input).parents(".elFormItemWrapper").removeClass("hasValue");
2550        }
2551      });
2552    });
2553    this.fields.forEach((prop) => {
2554      const input = this.getInputFromName(prop);
2555      input.addEventListener("blur", () => {
2556        let value;
2557        if (prop === "phone_number") {
2558          value = input.iti.getNumber();
2559        } else {
2560          value = input.value;
2561        }
2562        Checkout.store.contact.setKey(prop, value);
2563        window.cfGarlicUtils.store(prop, value);
2564        if (!this.disableInputValidationOnBlur) {
2565          this.checkForm(Checkout.computed.contactErrors.get());
2566        } else {
2567          if (Checkout.store.showAllErrors.contact.get()) this.checkForm(Checkout.computed.contactErrors.get());
2568        }
2569      });
2570    });
2571    Checkout.computed.contactErrors.subscribe((contactErrors) => {
2572      if (!this.disableInputValidationOnBlur) {
2573        this.checkForm(contactErrors);
2574      } else {
2575        if (Checkout.store.showAllErrors.contact.get()) this.checkForm(contactErrors);
2576      }
2577    });
2578    Checkout.store.phoneNumberInitialized.listen((phoneNumberInitialized) => {
2579      if (phoneNumberInitialized) {
2580        this.initializePhoneNumber();
2581      }
2582    });
2583    Checkout.computed.hideContactInformationForm.subscribe((hideContactInformationForm) => {
2584      if (hideContactInformationForm) {
2585        this.element.classList.add("elHide");
2586      } else {
2587        this.element.classList.remove("elHide");
2588      }
2589    });
2590    if (this.enableSubscriptionDuplicateDetection) {
2591      CheckoutSubscriptionDuplicates.initialize();
2592      const duplicateRow = this.element.querySelector(".elSubscriptionDuplicateRow");
2593      const manageLink = this.element.querySelector(".elManageSubscriptionLink");
2594      if (CheckoutSubscriptionDuplicates.computed && CheckoutSubscriptionDuplicates.computed.showingDuplicates) {
2595        CheckoutSubscriptionDuplicates.computed.showingDuplicates.subscribe((showingDuplicates) => {
2596          if (duplicateRow) {
2597            if (showingDuplicates) {
2598              duplicateRow.classList.remove("elHide");
2599            } else {
2600              duplicateRow.classList.add("elHide");
2601            }
2602          }
2603        });
2604      }
2605      if (manageLink && CheckoutSubscriptionDuplicates.computed && CheckoutSubscriptionDuplicates.computed.duplicateSubscription) {
2606        manageLink.addEventListener("click", (e) => {
2607          e.preventDefault();
2608          const subscription = CheckoutSubscriptionDuplicates.computed.duplicateSubscription.get();
2609          if (subscription) {
2610            window.open(subscription.customer_center_url, "_blank");
2611          }
2612        });
2613      }
2614      const textElement = this.element.querySelector(".elSubscriptionDuplicateText");
2615      if (textElement && CheckoutSubscriptionDuplicates.computed && CheckoutSubscriptionDuplicates.computed.duplicateSubscription) {
2616        CheckoutSubscriptionDuplicates.computed.duplicateSubscription.subscribe((subscription) => {
2617          if (subscription && subscription.product_name) {
2618            textElement.textContent = `${this.checkoutContactFormTexts.existingSubscriptionFor} '${subscription.product_name}' ${this.checkoutContactFormTexts.thatBelongsToYou}`;
2619          }
2620        });
2621      }
2622    }
2623  }
2624  checkForm(contactErrors) {
2625    const errorWrapper = this.element.querySelector(".elCheckoutFormErrors");
2626    errorWrapper.classList.add("elHide");
2627    this.fields.forEach((prop) => {
2628      const input = this.getInputFromName(prop);
2629      resetInputErrors(input);
2630    });
2631    if (Checkout.utils.hasErrors(contactErrors)) {
2632      const fieldErrors = contactErrors.fields;
2633      if (fieldErrors) {
2634        const errors = [];
2635        Object.entries(fieldErrors).forEach(([field, error]) => {
2636          const { message } = error;
2637          errors.push(message);
2638          const input = this.getInputFromName(field);
2639          addError(input);
2640        });
2641        if (errors.length) {
2642          const listErrors = `<ul>${errors.map((err) => `<li>${err}</li>`).join("")}</ul>`;
2643          errorWrapper.innerHTML = listErrors;
2644          errorWrapper.classList.remove("elHide");
2645        } else {
2646          errorWrapper.classList.add("elHide");
2647        }
2648      }
2649    }
2650  }
2651  getInputFromName(name) {
2652    return this.element.querySelector(`[name='${name}']`);
2653  }
2654  // TODO: The intlTelInput setup should be handled by the Input/V1 blueprint
2655  initializePhoneNumber() {
2656    const phoneInput = this.getInputFromName("phone_number");
2657    if (!phoneInput) return;
2658    const initialCountry = Checkout.store.shipping.get().country;
2659    IntlTel_initPhoneInput(phoneInput, { initialCountry: initialCountry.toLowerCase() });
2660    phoneInput.addEventListener("countrychange", () => {
2661      Checkout.store.contact.setKey("phone_number", phoneInput.iti.getNumber());
2662    });
2663  }
2664};
2665registerComponent("CheckoutContactForm/V1", CheckoutContactFormV1);
2666window["CheckoutContactFormV1"] = CheckoutContactFormV1;
2667
2668// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-saved-address-form-v1.ts
2669init_define_process();
2670init_radio_v1();
2671init_runtime();
2672var CheckoutSavedAddressFormV1 = class extends CF2Component {
2673  constructor(el, runtimeSel) {
2674    super(el, runtimeSel);
2675  }
2676  mount() {
2677    this.bindNewAddressClick();
2678    this.bindAddressClick();
2679    Checkout.store[`${this.type}_addresses`].listen((addresses) => {
2680      this.addresses = addresses;
2681      if (addresses && addresses.length > 0) {
2682        this.addresses = addresses;
2683        this.renderAddresses(addresses);
2684        this.getAddNewAddressButton().classList.remove("elHide");
2685        this.getAddNewAddressElement().classList.remove("elCheckoutStandaloneSavedAddNewAddress");
2686        this.getAddNewAddressElement().classList.add("elHide");
2687      } else {
2688        this.getAddressInputByValue("new-address").checked = true;
2689        this.showAddNewAddressForm();
2690      }
2691    });
2692  }
2693  bindNewAddressClick() {
2694    this.getAddNewAddressButton().addEventListener("click", (evt) => {
2695      evt.preventDefault();
2696      this.getAddressInputByValue("new-address").checked = true;
2697      this.showAddNewAddressForm();
2698    });
2699  }
2700  getAddressFormValues() {
2701    return this.getComponent("CheckoutAddressForm/V1").store.get();
2702  }
2703  validateNewAddressForm() {
2704    return this.getComponent("CheckoutAddressForm/V1").validateFormFields();
2705  }
2706  showAddNewAddressForm() {
2707    this.getAddNewAddressButton().classList.add("elHide");
2708    this.getAddNewAddressElement().classList.remove("elHide");
2709  }
2710  getAddNewAddressElement() {
2711    return this.element.querySelector(".elCheckoutSavedAddNewAddress");
2712  }
2713  getAddNewAddressButton() {
2714    return this.element.querySelector(".elCheckoutSavedAddNewAddressContainer");
2715  }
2716  getAddressInputByValue(value) {
2717    return this.element.querySelector(`input[value="${value}"]`);
2718  }
2719  getSavedAddressById(id) {
2720    return this.addresses.find((addr) => addr.id == id);
2721  }
2722  getSelectedAddressId() {
2723    return this.element.querySelector(`input[name="selected-${this.type}-address"]:checked`).value;
2724  }
2725  isNewAddress() {
2726    return this.getSelectedAddressId() === "new-address";
2727  }
2728  bindAddressClick() {
2729    Array.from(
2730      this.element.querySelector(".elCheckoutAddressList").querySelectorAll(".elCheckoutSavedAddressContainer")
2731    ).forEach((addressContainer) => {
2732      const elRadio = addressContainer.parentElement.querySelector('[type="radio"]');
2733      addressContainer.addEventListener("click", (ev) => {
2734        ev.preventDefault();
2735        elRadio.checked = true;
2736      });
2737    });
2738  }
2739  renderAddresses(addresses = []) {
2740    if (addresses.length === 0) return;
2741    const el = this.element.querySelector(".elCheckoutAddressList");
2742    $(el).html(`
2743      ${addresses.map((address, index) => {
2744      const { id, city, state, zip, country } = address;
2745      const { type } = this;
2746      const checked = index === 0;
2747      const fieldsOrder = this.locale == "ja" ? [zip, country, state, city] : [city, state, zip, country];
2748      const addressGoesFirst = this.locale !== "ja";
2749      const address12Html = address.address ? `<span class="elCheckoutSavedAddressInfo">
2750          ${[address.address, address.address2].filter((x) => x).join(", ")}
2751        </span>` : "";
2752      const fullAddressHtml = `
2753          ${addressGoesFirst ? address12Html : ""}
2754          <span class="elCheckoutSavedAddressDetails">
2755            ${fieldsOrder.filter((x) => x).join(", ")}
2756          </span>
2757          ${addressGoesFirst ? "" : address12Html}
2758        `;
2759      return `
2760          <div class="elCheckoutSavedAddressContainer">
2761            <div data-page-element="Radio/V1" class="elRadioWrapper">
2762              <label class="elRadioLabel">
2763                <input type="radio" value="${address.id}" name="selected-${type}-address" ${checked ? "checked" : ""} class="elRadioInput">
2764                <div class="elRadio">
2765                  <div class="elRadioIcon">
2766                  </div>
2767                </div>
2768                <span class="elRadioText"></span>
2769              </label>
2770            </div>
2771            <div class="elCheckoutSavedAddress"> 
2772              ${fullAddressHtml}
2773            </div>
2774          </div>        
2775        `;
2776    }).join("\n")}
2777    `);
2778    this.bindAddressClick();
2779  }
2780};
2781registerComponent("CheckoutSavedAddressForm/V1", CheckoutSavedAddressFormV1);
2782window["CheckoutSavedAddressFormV1"] = CheckoutSavedAddressFormV1;
2783
2784// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-saved-billing-address-v1.ts
2785init_define_process();
2786init_nanostores();
2787init_modal_v1();
2788init_checkbox_v1();
2789init_runtime();
2790var CheckoutSavedBillingAddressV1 = class extends CF2Component {
2791  constructor(el, runtimeSel) {
2792    super(el, runtimeSel);
2793  }
2794  mount() {
2795    this.currentBillingSameAsShipping = atom(Checkout.store.billingSameAsShipping.get());
2796    this.modalShow = atom(false);
2797    this.getOpenModalButton().addEventListener("click", (evt) => {
2798      evt.preventDefault();
2799      this.modalShow.set(true);
2800    });
2801    this.getCloseButton().addEventListener("click", (evt) => {
2802      evt.preventDefault();
2803      this.modalShow.set(false);
2804    });
2805    this.getModal().onClose = () => {
2806      this.modalShow.set(false);
2807    };
2808    this.getCheckbox().addEventListener("change", (evt) => {
2809      evt.stopPropagation();
2810      this.currentBillingSameAsShipping.set(!!evt.target.checked);
2811    });
2812    this.getUpdateButton().addEventListener("click", (evt) => {
2813      evt.preventDefault();
2814      this.updateAddress();
2815    });
2816    this.modalShow.listen((value) => {
2817      if (value) {
2818        this.showModal();
2819      } else {
2820        this.hideModal();
2821        const storeBillingSameAsShipping = Checkout.store.billingSameAsShipping.get();
2822        if (!storeBillingSameAsShipping) {
2823          const currentAddress = Checkout.store.billing.get();
2824          const id = currentAddress?.id ?? "new-address";
2825          this.getSavedAddressForm().getAddressInputByValue(id).checked = true;
2826        }
2827      }
2828    });
2829    Checkout.store.billingSameAsShipping.listen((value) => {
2830      this.currentBillingSameAsShipping.set(value);
2831    });
2832    this.currentBillingSameAsShipping.listen((value) => {
2833      this.getCheckbox().checked = value;
2834      if (value) {
2835        this.hideSelectAddressForm();
2836      } else {
2837        this.showSelectAddressForm();
2838      }
2839    });
2840    const computedSavedBillingAddress = computed([
2841      Checkout.store.billing,
2842      Checkout.store.shipping,
2843      Checkout.store.billingSameAsShipping
2844    ], (billing, shipping, billingSameAsShipping) => {
2845      return billingSameAsShipping ? shipping : billing;
2846    });
2847    computedSavedBillingAddress.listen((savedAddress) => {
2848      this.refreshDetailsElement(savedAddress);
2849    });
2850    Checkout.computed.hasPhysicalProducts.subscribe((hasPhysicalProducts2) => {
2851      if (hasPhysicalProducts2) {
2852        this.showBillingSameAsShipping();
2853        if (Checkout.store.billingSameAsShipping.get()) {
2854          this.hideSelectAddressForm();
2855        } else {
2856          this.showSelectAddressForm();
2857        }
2858      } else {
2859        this.hideBillingSameAsShipping();
2860        this.showSelectAddressForm();
2861      }
2862    });
2863    this.listenToBillingApiErrors();
2864    Checkout.computed.isNewDigitalWalletPayment.subscribe((isNewDigitalWalletPayment) => {
2865      if (isNewDigitalWalletPayment) {
2866        this.hide();
2867      } else {
2868        this.show();
2869      }
2870    });
2871  }
2872  updateAddress() {
2873    const savedAddrComp = this.getSavedAddressForm();
2874    const cart = Checkout.computed.checkoutCart.get();
2875    if (hasPhysicalProducts(cart) && this.currentBillingSameAsShipping.get()) {
2876      Checkout.store.billingSameAsShipping.set(true);
2877      const shippingData = Checkout.store.shipping.get();
2878      Checkout.store.billing.set(shippingData);
2879      this.modalShow.set(false);
2880    } else {
2881      if (savedAddrComp.isNewAddress()) {
2882        if (savedAddrComp.validateNewAddressForm()) {
2883          Checkout.store.billingSameAsShipping.set(false);
2884          const newAddress = savedAddrComp.getAddressFormValues();
2885          Checkout.store.billing.set(newAddress);
2886          this.modalShow.set(false);
2887        }
2888      } else {
2889        Checkout.store.billingSameAsShipping.set(false);
2890        const selectedAddressId = savedAddrComp.getSelectedAddressId();
2891        const newAddress = savedAddrComp.getSavedAddressById(selectedAddressId);
2892        if (newAddress) {
2893          Checkout.store.billing.set(newAddress);
2894        }
2895        this.modalShow.set(false);
2896      }
2897    }
2898  }
2899  refreshDetailsElement(address) {
2900    const detailsTextElement = this.element.querySelector(".elSavedDetailsText");
2901    const detailsIconElement = this.element.querySelector(".elSavedDetailsIcon");
2902    if (address && Object.keys(address).length) {
2903      const billingSameAsShipping = Checkout.store.billingSameAsShipping.get();
2904      const addressByFields = billingSameAsShipping ? address : parseAddressByFields(address, this.fields, false);
2905      const formattedText = addressToString(address);
2906      detailsTextElement.innerHTML = formattedText;
2907      detailsTextElement.classList.remove("elError");
2908      detailsIconElement.classList.remove("elError");
2909    } else {
2910      detailsTextElement.innerHTML = this.checkoutSavedBillingAddressFormTexts.requiresAddressConfiguration;
2911      detailsTextElement.classList.add("elError");
2912      detailsIconElement.classList.add("elError");
2913    }
2914  }
2915  getModal() {
2916    return this.getComponent("Modal/V1");
2917  }
2918  getOpenModalButton() {
2919    return this.element.querySelector(".elSavedDetailsEdit");
2920  }
2921  showModal() {
2922    this.getModal().element.style.display = "flex";
2923  }
2924  hideModal() {
2925    this.getModal().element.style.display = "none";
2926  }
2927  hideSelectAddressForm() {
2928    this.getSelectAddressForm().classList.add("elHide");
2929  }
2930  showSelectAddressForm() {
2931    this.getSelectAddressForm().classList.remove("elHide");
2932  }
2933  getSelectAddressForm() {
2934    return this.getModal().element.querySelector(".elCheckoutSelectAddressWrapper");
2935  }
2936  getUpdateButton() {
2937    return this.getModal().element.querySelector(".elButton");
2938  }
2939  getCheckbox() {
2940    return this.getBillingSameAsShippingCheckbox().querySelector("input");
2941  }
2942  getCloseButton() {
2943    return this.getModal().element.querySelector(".elCheckoutModalFormClose");
2944  }
2945  getSavedAddressForm() {
2946    return this.getComponent("CheckoutSavedAddressForm/V1");
2947  }
2948  getBillingSameAsShippingCheckbox() {
2949    return this.element.querySelector(".elShippingSameAsBillingContainer");
2950  }
2951  showBillingSameAsShipping() {
2952    return this.getBillingSameAsShippingCheckbox().classList.remove("elHide");
2953  }
2954  hideBillingSameAsShipping() {
2955    return this.getBillingSameAsShippingCheckbox().classList.add("elHide");
2956  }
2957  listenToBillingApiErrors() {
2958    Checkout.store.billingApiErrorsByField.listen((apiErrors) => {
2959      const errorWrapper = this.element.querySelector(".elCheckoutFormErrors");
2960      const savedDetailsContainer = this.element.querySelector(".elSavedDetailsContainer");
2961      errorWrapper.classList.add("elHide");
2962      savedDetailsContainer.classList.remove("errorBillingAddress");
2963      if (apiErrors) {
2964        const errors = [];
2965        Object.entries(apiErrors).forEach(([field, error]) => {
2966          const { message } = error;
2967          errors.push(message);
2968        });
2969        if (errors.length) {
2970          const listErrors = `<ul>${errors.map((err) => `<li>${err}</li>`).join("")}</ul>`;
2971          errorWrapper.innerHTML = listErrors;
2972          errorWrapper.classList.remove("elHide");
2973          savedDetailsContainer.classList.add("errorBillingAddress");
2974        }
2975      }
2976    });
2977  }
2978  show() {
2979    this.element.classList.remove("elHide");
2980  }
2981  hide() {
2982    this.element.classList.add("elHide");
2983  }
2984};
2985registerComponent("CheckoutSavedBillingAddress/V1", CheckoutSavedBillingAddressV1);
2986window["CheckoutSavedBillingAddressV1"] = CheckoutSavedBillingAddressV1;
2987
2988// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-saved-contact-details-v1.ts
2989init_define_process();
2990init_nanostores();
2991init_modal_v1();
2992init_radio_v1();
2993init_runtime();
2994var CheckoutSavedContactDetailsV1 = class extends CF2Component {
2995  constructor(el, runtimeSel) {
2996    super(el, runtimeSel);
2997  }
2998  mount() {
2999    this.modalShow = atom(false);
3000    this.getOpenModalButton().addEventListener("click", (evt) => {
3001      evt.preventDefault();
3002      this.modalShow.set(true);
3003    });
3004    this.getCloseButton().addEventListener("click", (evt) => {
3005      evt.preventDefault();
3006      this.modalShow.set(false);
3007    });
3008    this.getModal().onClose = () => {
3009      this.modalShow.set(false);
3010    };
3011    this.getButtonElement().addEventListener("click", (evt) => {
3012      evt.preventDefault();
3013      this.updateAddress();
3014    });
3015    this.modalShow.listen((value) => {
3016      if (value) {
3017        this.showModal();
3018      } else {
3019        this.hideModal();
3020        const currentAddress = Checkout.store.shipping.get();
3021        const id = currentAddress?.id ?? "new-address";
3022        this.getSavedAddressForm().getAddressInputByValue(id).checked = true;
3023      }
3024    });
3025    Checkout.store.shipping.listen((shipping) => {
3026      const shippingAddressLength = this.getSavedContainerWrapper().getAttribute("data-contact-shipping-addresses-length");
3027      if (!shipping.id == null && (!shippingAddressLength || shippingAddressLength == "0")) {
3028        this.getSavedContainerWrapper().setAttribute("data-contact-shipping-addresses-length", "1");
3029      }
3030      this.refreshAddress(shipping);
3031    });
3032    Checkout.store.contact_pending_auth.listen((contact_pending_auth) => {
3033      const authenticated = contact_pending_auth.authenticated;
3034      this.setShowContactDetails(!authenticated);
3035    });
3036    Checkout.store.contact.listen((contact) => {
3037      const { email, first_name, last_name, phone_number } = contact;
3038      this.element.querySelector(".contact_email").innerHTML = email || "";
3039      this.element.querySelector(".contact_first_name").innerHTML = first_name || "";
3040      this.element.querySelector(".contact_last_name").innerHTML = last_name || "";
3041      this.element.querySelector(".elSavedPhone").innerHTML = phone_number ? `
3042        <i class="fas fa-phone"></i>
3043        <span class="contact_phone_number"> ${contact.phone_number} </span>      
3044      ` : ``;
3045    });
3046    Checkout.store.checkout.mode.subscribe((mode) => {
3047      this.getSavedContainerWrapper().dataset.mode = mode;
3048    });
3049    Checkout.computed.hasPhysicalProducts.subscribe((hasPhysicalProducts2) => {
3050      const defaultLabel = "Shipping Information";
3051      const formDetailsLabel = this.element.querySelector(".elCheckoutFormLabel");
3052      if (!formDetailsLabel) return;
3053      this.getSavedContainerWrapper().dataset["selectedProductType"] = hasPhysicalProducts2 ? "physical" : "digital";
3054      if (hasPhysicalProducts2) {
3055        formDetailsLabel.innerHTML = this.shippingHeadline || defaultLabel;
3056      } else {
3057        formDetailsLabel.innerHTML = this.showContactDetails() ? this.contactHeadline : this.shippingHeadline;
3058      }
3059    });
3060    Checkout.computed.isNewDigitalWalletPayment.subscribe((isNewDigitalWalletPayment) => {
3061      if (isNewDigitalWalletPayment) {
3062        this.hide();
3063      } else {
3064        this.show();
3065      }
3066    });
3067    Checkout.store.shipping_addresses.listen((shippingAddresses) => {
3068      this.getSavedContainerWrapper().setAttribute("data-contact-shipping-addresses-length", shippingAddresses.length);
3069    });
3070  }
3071  hide() {
3072    this.element.classList.add("elHide");
3073  }
3074  show() {
3075    this.element.classList.remove("elHide");
3076  }
3077  updateAddress() {
3078    const savedAddrComp = this.getSavedAddressForm();
3079    if (savedAddrComp.isNewAddress()) {
3080      if (savedAddrComp.validateNewAddressForm()) {
3081        const newAddress = savedAddrComp.getAddressFormValues();
3082        Checkout.store.shipping.set(newAddress);
3083        this.modalShow.set(false);
3084      }
3085    } else {
3086      const selectedAddressId = savedAddrComp.getSelectedAddressId();
3087      const newAddress = savedAddrComp.getSavedAddressById(selectedAddressId);
3088      if (newAddress) {
3089        Checkout.store.shipping.set(newAddress);
3090      }
3091      this.modalShow.set(false);
3092    }
3093  }
3094  refreshAddress(address) {
3095    const detailsTextElement = this.element.querySelector(".elSavedDetailsText");
3096    const detailsIconElement = this.element.querySelector(".elSavedDetailsIcon");
3097    if (address && address.address) {
3098      const formattedText = addressToString(address);
3099      detailsTextElement.innerHTML = formattedText;
3100      detailsTextElement.classList.remove("elError");
3101      detailsIconElement.classList.remove("elError");
3102    }
3103  }
3104  getModal() {
3105    return this.getComponent("Modal/V1");
3106  }
3107  getOpenModalButton() {
3108    return this.element.querySelector(".elSavedDetailsEdit");
3109  }
3110  showModal() {
3111    this.getModal().element.style.display = "flex";
3112  }
3113  hideModal() {
3114    this.getModal().element.style.display = "none";
3115  }
3116  getSavedAddressForm() {
3117    return this.getComponent("CheckoutSavedAddressForm/V1");
3118  }
3119  getButtonElement() {
3120    return this.getModal().element.querySelector(".elButton");
3121  }
3122  getCloseButton() {
3123    return this.getModal().element.querySelector(".elCheckoutModalFormClose");
3124  }
3125  getSavedContainerWrapper() {
3126    return this.element.querySelector(".elCheckoutSavedContactDetailsWrapper");
3127  }
3128  showContactDetails() {
3129    return this.getSavedContainerWrapper().getAttribute("data-show-contact-details");
3130  }
3131  setShowContactDetails(value) {
3132    this.getSavedContainerWrapper().setAttribute("data-show-contact-details", value);
3133  }
3134};
3135registerComponent("CheckoutSavedContactDetails/V1", CheckoutSavedContactDetailsV1);
3136window["CheckoutSavedContactDetailsV1"] = CheckoutSavedContactDetailsV1;
3137
3138// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/checkout-saved-multiple-payments-v1.ts
3139init_define_process();
3140init_modal_v1();
3141init_runtime();
3142var CheckoutSavedMultiplePaymentsV1 = class extends CF2Component {
3143  constructor(el, runtimeSel) {
3144    super(el, runtimeSel);
3145  }
3146  mount() {
3147    this.paymentSelect = this.element.querySelector('[name="payment_method"]');
3148    this.paymentSelect.addEventListener("change", (evt) => {
3149      evt.preventDefault();
3150      const paymentId = evt.target.value == "new-payment" ? null : evt.target.value;
3151      Checkout.store.payment.id.set(paymentId);
3152    });
3153    if (this.paymentSelect.value == "new-payment") {
3154      const multiplePaymentsWrapper = this.element.querySelector(".elCheckoutMultiplePaymentsWrapper");
3155      multiplePaymentsWrapper.classList.remove("elHide");
3156    }
3157    Checkout.computed.paymentMethod.listen((paymentMethod) => {
3158      const multiplePaymentsWrapper = this.element.querySelector(".elCheckoutMultiplePaymentsWrapper");
3159      this.paymentMethod = paymentMethod;
3160      if (paymentMethod) {
3161        multiplePaymentsWrapper.classList.add("elHide");
3162      } else {
3163        multiplePaymentsWrapper.classList.remove("elHide");
3164      }
3165    });
3166    Checkout.store.paymentMethods.listen((payment_methods) => {
3167      this.contact = {
3168        payment_methods
3169      };
3170      this.rerenderSelect();
3171    });
3172    Checkout.store.payment.state.listen((state) => {
3173      if (state == Checkout.PaymentStates.LOADING) {
3174        this.showLoader();
3175      } else if (state == Checkout.PaymentStates.INITIALIZED) {
3176        this.hideLoader();
3177      }
3178    });
3179  }
3180  showLoader() {
3181    this.element.querySelector(".elPAISavedLoader").dataset.loader = true;
3182  }
3183  hideLoader() {
3184    this.element.querySelector(".elPAISavedLoader").dataset.loader = false;
3185  }
3186  rerenderSelect() {
3187    const selectedId = Checkout.store.payment.id.get();
3188    this.paymentSelect.innerHTML = `
3189      ${this.contact.payment_methods.map((payment_method) => {
3190      const checked = payment_method.id === selectedId;
3191      let label = "";
3192      if (payment_method.type === "payment-card") {
3193        label = payment_method.details;
3194      } else if (payment_method.type === "paypal") {
3195        label = `Paypal - ${payment_method.details}`;
3196      } else if (payment_method.type === "Klarna") {
3197        label = `Klarna - ${payment_method.details}`;
3198      }
3199      return `<option value="${payment_method.id}" ${checked ? "checked" : ""}> ${label} </option>`;
3200    })}
3201      <option value="new-payment">${this.checkoutSavedMultiplePaymentsTexts.addNewPaymentMethod}</option>
3202    `;
3203  }
3204};
3205registerComponent("CheckoutSavedMultiplePayments/V1", CheckoutSavedMultiplePaymentsV1);
3206window["CheckoutSavedMultiplePaymentsV1"] = CheckoutSavedMultiplePaymentsV1;
3207
3208// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/rebilly-checkout.ts
3209init_define_process();
3210
3211// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-summary.ts
3212init_define_process();
3213init_general();
3214
3215// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-machine.ts
3216init_define_process();
3217
3218// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-digital-wallet.ts
3219init_define_process();
3220var _CheckoutDigitalWallet_static, updateRebillyWithCallback_fn;
3221var CheckoutDigitalWallet = class {
3222  static initialize() {
3223    globalThis.Rebilly.on("token-ready", (data, extraData) => {
3224      const paymentType = globalThis.Checkout.store.payment.type.get();
3225      const paymentMethod = data.method;
3226      const paymentInstrumentMethod = data.paymentInstrument?.type;
3227      CheckoutSummary.skipOrderSummaryUpdateWithCb(() => {
3228        if (paymentMethod == "digital-wallet" && paymentInstrumentMethod == "Apple Pay") {
3229          let rebillyShippingAddress;
3230          const shippingAddress = extraData?.shippingDetails?.address;
3231          const billingAddress = data.billingAddress;
3232          if (globalThis.Checkout.computed.hasPhysicalProducts.get()) {
3233            rebillyShippingAddress = {
3234              address: shippingAddress.addressLines?.[0],
3235              address_2: shippingAddress.addressLines?.[1],
3236              country: shippingAddress.countryCode.toUpperCase(),
3237              city: shippingAddress.locality,
3238              zip: shippingAddress.postalCode,
3239              state: shippingAddress.administrativeArea
3240            };
3241          }
3242          const rebillyBillingAddress = {
3243            address: billingAddress.address,
3244            address_2: billingAddress.address2,
3245            country: billingAddress.country.toUpperCase(),
3246            city: billingAddress.city,
3247            zip: billingAddress.postalCode,
3248            state: billingAddress.region
3249          };
3250          const payload = CheckoutSubmit.buildPayloadFromStore({
3251            contact: this.getContact(shippingAddress, billingAddress),
3252            turnstileToken: globalThis.Checkout.turnstileToken,
3253            shippingAddress: rebillyShippingAddress,
3254            billingAddress: rebillyBillingAddress,
3255            paymentMethodDetails: {
3256              payment_method_id: null,
3257              payment_method_type: "apple-pay",
3258              rebilly_token: data.id
3259            },
3260            selectedShippingOption: this.transactionShippingOption ?? {},
3261            skipBillingAddress: false
3262          });
3263          CheckoutSubmit.submit(payload);
3264        } else {
3265          globalThis.Checkout.store.payment[paymentType].token.set(data.id);
3266        }
3267      });
3268    });
3269    globalThis.Rebilly.on("shipping-address-changed", (shippingAddress, updateShippingOptions) => {
3270      this.transactionShipping = {
3271        address: shippingAddress.addressLines?.[0],
3272        address_2: shippingAddress.addressLines?.[1],
3273        country: shippingAddress.countryCode.toUpperCase(),
3274        city: shippingAddress.locality,
3275        zip: shippingAddress.postalCode,
3276        state: shippingAddress.administrativeArea
3277      };
3278      __privateMethod(this, _CheckoutDigitalWallet_static, updateRebillyWithCallback_fn).call(this, updateShippingOptions);
3279    });
3280    globalThis.Rebilly.on("shipping-option-changed", (selectedShippingOption, updateTransaction) => {
3281      CheckoutSummary.skipOrderSummaryUpdateWithCb(() => {
3282        this.transactionShippingOption = this.shippingOptions.find(
3283          (s) => CheckoutSubmit.generateShippingOptionId(s) == selectedShippingOption.id
3284        );
3285      });
3286      __privateMethod(this, _CheckoutDigitalWallet_static, updateRebillyWithCallback_fn).call(this, updateTransaction);
3287    });
3288    globalThis.Rebilly.on("billing-address-changed", (billingAddress, updateTransaction) => {
3289      if (billingAddress) {
3290        this.transactionBilling = {
3291          address: billingAddress.addressLines?.[0],
3292          address_2: billingAddress.addressLines?.[1],
3293          country: billingAddress.countryCode.toUpperCase(),
3294          city: billingAddress.locality,
3295          zip: billingAddress.postalCode,
3296          state: billingAddress.administrativeArea
3297        };
3298      }
3299      __privateMethod(this, _CheckoutDigitalWallet_static, updateRebillyWithCallback_fn).call(this, updateTransaction);
3300    });
3301  }
3302  static getContact(shippingAddress, billingAddress) {
3303    if (globalThis.Checkout.store.checkout.mode.get() == "guest" && numberOfStepsInCheckout() == 1) {
3304      const { emailAddress: shippingEmail, familyName: shippingLN, givenName: shippingFN } = shippingAddress ?? {};
3305      const { firstName: billingFN, lastName: billingLN } = billingAddress;
3306      if (globalThis.sessionData.contact.email) {
3307        const { email, first_name, last_name, phone_number } = globalThis.sessionData.contact;
3308        return {
3309          email,
3310          first_name,
3311          last_name,
3312          phone_number
3313        };
3314      } else {
3315        return {
3316          email: shippingEmail,
3317          first_name: [shippingFN, billingFN].find(Boolean),
3318          last_name: [shippingLN, billingLN].find(Boolean),
3319          phone_number: globalThis.Checkout.store.contact.get().phone_number
3320        };
3321      }
3322    }
3323    return globalThis.Checkout.store.contact.get();
3324  }
3325};
3326_CheckoutDigitalWallet_static = new WeakSet();
3327updateRebillyWithCallback_fn = function(updateCallback) {
3328  const cart = globalThis.Checkout.computed.checkoutCart.get();
3329  const shippingEnabled = hasPhysicalProducts(cart);
3330  CheckoutSummary.fetchOrderSummaryForExpress(cart, {
3331    billingAddress: this.transactionBilling ?? {},
3332    shippingAddress: this.transactionShipping ?? (shippingEnabled ? this.transactionBilling : {}) ?? {},
3333    shippingOption: this.transactionShippingOption ?? {},
3334    billingSameAsShipping: false
3335  }).then(({ summary, data }) => {
3336    const { shipping_quotes_response } = summary;
3337    this.shippingOptions = shipping_quotes_response?.options ?? [];
3338    const transactionData = CheckoutSubmit.buildDigitalWalletTransactionData(
3339      data,
3340      cart,
3341      shippingEnabled,
3342      this.shippingOptions
3343    );
3344    updateCallback(transactionData);
3345  }).catch((e) => {
3346    console.error(e);
3347    updateCallback({ status: "fail" });
3348  });
3349};
3350__privateAdd(CheckoutDigitalWallet, _CheckoutDigitalWallet_static);
3351__publicField(CheckoutDigitalWallet, "transactionShipping");
3352__publicField(CheckoutDigitalWallet, "transactionShippingOption");
3353__publicField(CheckoutDigitalWallet, "transactionBilling");
3354__publicField(CheckoutDigitalWallet, "shippingOptions");
3355__publicField(CheckoutDigitalWallet, "totalSteps");
3356
3357// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-paypal.ts
3358init_define_process();
3359var paypalApproved = () => globalThis.Checkout.store.payment.paypal.state.get()?.state == PaypalStates.PAYMENT_METHOD_APPROVED && !!globalThis.Checkout.store.payment.paypal.token.get();
3360var resetPaypalErrorState = () => {
3361  if (paypalApproved()) return;
3362  globalThis.Checkout.store.payment.paypal.state.set({ state: PaypalStates.INITIALIZED });
3363};
3364var buildPaypalCallbacks = () => ({
3365  onInit: () => {
3366    console.log("[PayPal] - onInit called");
3367    if (paypalApproved()) return;
3368    globalThis.Checkout.store.payment.paypal.state.set({ state: PaypalStates.INITIALIZED });
3369  },
3370  onApprove: (data, actions) => {
3371    console.log("[PayPal] - onApprove called", data, actions);
3372    globalThis.Checkout.store.payment.paypal.state.set({
3373      state: PaypalStates.PAYMENT_METHOD_APPROVED
3374    });
3375  },
3376  onError: (data, actions) => {
3377    console.log("[PayPal] - onError called", data, actions);
3378    if (paypalApproved()) return;
3379    globalThis.Checkout.store.payment.paypal.state.set({
3380      state: PaypalStates.ERROR,
3381      code: ErrorTypes.PAYPAL_CUSTOM_ERROR,
3382      message: "Something unexpected happened"
3383    });
3384  },
3385  onCancel: (data, actions) => {
3386    console.log("[PayPal] - onCancel called", data, actions);
3387    if (paypalApproved()) return;
3388    globalThis.Checkout.store.payment.paypal.state.set({
3389      state: PaypalStates.ERROR,
3390      code: ErrorTypes.PAYPAL_DECLINED_ERROR
3391    });
3392  },
3393  onClick: (data, actions) => {
3394    console.log("[PayPal] - onClick called", data, actions);
3395    if (paypalApproved()) return;
3396    globalThis.Checkout.store.payment.paypal.state.set({
3397      state: PaypalStates.ADDING_PAYMENT_METHOD
3398    });
3399  }
3400});
3401
3402// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-machine.ts
3403init_nanostores();
3404init_fetcher();
3405var INITIALIAZE_PAI_TIMEOUT = 6e4;
3406var FRAMEPAY_SCRIPT_URL = "https://framepay.payments.ai/rebilly.js";
3407var FRAMEPAY_CSS_URL = "https://framepay.payments.ai/rebilly.css";
3408var TimeoutError = class extends Error {
3409};
3410var buildPAIContext = (extra = {}) => ({
3411  phase: "pai-init",
3412  visibilityState: typeof document !== "undefined" ? document.visibilityState : null,
3413  pageUrl: typeof location !== "undefined" ? location.href : null,
3414  rebillyLoaded: !!globalThis.Rebilly,
3415  rebillyInitialized: !!globalThis.Rebilly?.initialized,
3416  ...extra
3417});
3418var buildPAIError = (code, cause, extraContext = {}) => {
3419  const error = new CheckoutCriticalError(code, { cause });
3420  error.context = buildPAIContext(extraContext);
3421  return error;
3422};
3423var extractRebillyErrorFields = (e) => ({
3424  rebillyErrorCode: e?.code ?? e?.data?.code ?? null,
3425  rebillyErrorMessage: e?.data?.message ?? e?.message ?? null
3426});
3427var loadPAIDeps = (addLoader = true) => {
3428  if (globalThis.Rebilly?.initialized) return Promise.resolve();
3429  if (globalThis.Checkout.store.payment.state.get() != globalThis.Checkout.PaymentStates.START) return void 0;
3430  const startedAt = performance.now();
3431  globalThis.Checkout.store.payment.state.set(globalThis.Checkout.PaymentStates.INITIALIZING);
3432  if (addLoader) globalThis.Checkout.store.payment.state.set(globalThis.Checkout.PaymentStates.LOADING);
3433  const js = document.createElement("script");
3434  js.src = FRAMEPAY_SCRIPT_URL;
3435  const onFailure = () => {
3436    resetPAIConfigState();
3437    globalThis.Checkout.store.payment.state.set(globalThis.Checkout.PaymentStates.START);
3438  };
3439  const promise = new Promise((resolve, reject) => {
3440    js.onload = () => {
3441      const scriptLoadMs = Math.round(performance.now() - startedAt);
3442      intializePAI().then(() => {
3443        const summary = globalThis.Checkout.store.summary.get();
3444        const cart = globalThis.Checkout.computed.checkoutCart.get();
3445        const summaryData = summary.data?.line_items?.length ? summary.data : CheckoutSummary.lastPreviewedSummary;
3446        return CheckoutSummary.updateRebillyTransactionDataPromise(summaryData, cart).then(() => {
3447          resolve();
3448        });
3449      }).catch((e) => {
3450        const retries = initializePAIConfigRetries;
3451        const isPaiInitFailure = !(e instanceof CheckoutCriticalError) || e.context?.phase === "pai-init";
3452        if (isPaiInitFailure) {
3453          onFailure();
3454        }
3455        const elapsedMs = Math.round(performance.now() - startedAt);
3456        if (e instanceof CheckoutCriticalError) {
3457          if (e.context?.phase === "pai-init") {
3458            e.context = { ...e.context, elapsedMs, scriptLoadMs, retries };
3459          }
3460          reject(e);
3461          return;
3462        }
3463        const errorType = e instanceof TimeoutError ? ERROR_CODES.PAI_INITIALIZATION_TIMEOUT_ERROR : ERROR_CODES.UNEXPECTED_INITIALIZATION_ERROR;
3464        reject(
3465          buildPAIError(errorType, e, {
3466            elapsedMs,
3467            scriptLoadMs,
3468            retries,
3469            ...extractRebillyErrorFields(e)
3470          })
3471        );
3472      });
3473    };
3474    js.onerror = () => {
3475      const retries = initializePAIConfigRetries;
3476      const elapsedMs = Math.round(performance.now() - startedAt);
3477      onFailure();
3478      reject(
3479        buildPAIError(ERROR_CODES.PAI_INITIALIZATION_SCRIPT_ERROR, new Error("framepay JS onError load"), {
3480          elapsedMs,
3481          retries,
3482          scriptSrc: FRAMEPAY_SCRIPT_URL
3483        })
3484      );
3485    };
3486  });
3487  document.head.appendChild(js);
3488  const css = document.createElement("link");
3489  css.href = FRAMEPAY_CSS_URL;
3490  css.rel = "stylesheet";
3491  document.head.appendChild(css);
3492  return promise;
3493};
3494var resetPAIConfigState = () => {
3495  initializePAIConfigPromise = void 0;
3496  if (initializePAIConfigNetworkTimeout) {
3497    clearTimeout(initializePAIConfigNetworkTimeout);
3498    initializePAIConfigNetworkTimeout = void 0;
3499  }
3500  initializePAIConfigRetries = 0;
3501};
3502var initializeTurnstile = () => {
3503  const turnstilejs = document.createElement("script");
3504  turnstilejs.src = "https://challenges.cloudflare.com/turnstile/v0/api.js";
3505  turnstilejs.onload = () => {
3506    const key = window.turnstileSiteKey;
3507    window.turnstile.render("#cf-turnstile", {
3508      sitekey: key,
3509      callback: function(token) {
3510        globalThis.Checkout.turnstileToken = token;
3511      }
3512    });
3513  };
3514  turnstilejs.onerror = (e) => {
3515    console.error("Turnstile error", e);
3516  };
3517  document.head.appendChild(turnstilejs);
3518};
3519function toPascalCase(kebabCase) {
3520  return kebabCase.replace(/(^\w|-\w)/g, (text) => {
3521    return text.replace(/-/, "").toUpperCase();
3522  });
3523}
3524var rebillyErrorClasses = {};
3525var hasGeneratedRebillyErrorClasses;
3526function generateRebillyErrorClasses() {
3527  if (hasGeneratedRebillyErrorClasses) return;
3528  hasGeneratedRebillyErrorClasses = true;
3529  const errorGenerator = (name) => ({
3530    [name]: class extends Error {
3531      constructor(data) {
3532        super();
3533        __publicField(this, "data");
3534        this.data = data;
3535      }
3536    }
3537  })[name];
3538  Object.values(globalThis.Rebilly.errorCodes).forEach((errorCode) => {
3539    const errorClassName = toPascalCase(errorCode);
3540    rebillyErrorClasses[errorClassName] = errorGenerator(errorClassName);
3541  });
3542}
3543var initializePAIConfigPromise;
3544var initializePAIConfigNetworkTimeout;
3545var initializePAIConfigRetries = 0;
3546var initializePAIConfig = (rebillyConfig) => {
3547  if (initializePAIConfigPromise) return initializePAIConfigPromise;
3548  initializePAIConfigPromise = new Promise((resolve, reject) => {
3549    let timeout = null;
3550    const armTimeout = () => {
3551      if (timeout) clearTimeout(timeout);
3552      timeout = setTimeout(() => {
3553        reject(new TimeoutError(`Timeout error: Rebilly took more than ${INITIALIAZE_PAI_TIMEOUT}ms to load`));
3554      }, INITIALIAZE_PAI_TIMEOUT);
3555    };
3556    const cancelTimeout = () => {
3557      if (timeout) clearTimeout(timeout);
3558      timeout = null;
3559    };
3560    armTimeout();
3561    globalThis.Rebilly.on("ready", () => {
3562      if (initializePAIConfigNetworkTimeout) clearTimeout(initializePAIConfigNetworkTimeout);
3563      cancelTimeout();
3564      try {
3565        globalThis.Checkout.store.payment.state.set(globalThis.Checkout.PaymentStates.INITIALIZED);
3566        resolve();
3567      } catch (e) {
3568        reject(e);
3569      }
3570    });
3571    globalThis.Rebilly.on("error", (rebillyError) => {
3572      generateRebillyErrorClasses();
3573      const errorClassName = rebillyError.code && typeof rebillyError.code == "string" ? toPascalCase(rebillyError.code) : null;
3574      if (!errorClassName || !rebillyErrorClasses[errorClassName]) {
3575        cancelTimeout();
3576        reject(rebillyError);
3577        return;
3578      }
3579      const error = new rebillyErrorClasses[errorClassName](rebillyError);
3580      if (rebillyError.code == "network-error") {
3581        if (initializePAIConfigRetries < 5) {
3582          armTimeout();
3583          initializePAIConfigNetworkTimeout = setTimeout(() => {
3584            globalThis.Rebilly.initialize(rebillyConfig);
3585            initializePAIConfigRetries++;
3586          }, 2e3 * initializePAIConfigRetries);
3587        } else {
3588          cancelTimeout();
3589          reject(error);
3590        }
3591      } else if (rebillyError.code == "already-initialized") {
3592        cancelTimeout();
3593        resolve();
3594      } else {
3595        cancelTimeout();
3596        reject(error);
3597      }
3598    });
3599  });
3600  globalThis.Rebilly.initialize(rebillyConfig);
3601  return initializePAIConfigPromise;
3602};
3603var intializePAI = () => {
3604  globalThis.Checkout.PaypalCallbacks = buildPaypalCallbacks();
3605  const checkoutElement = document.querySelector('[data-page-element="Checkout/V2"]');
3606  const checkoutComponent = checkoutElement.cf2_instance;
3607  const inputColor = getComputedStyle(checkoutElement).getPropertyValue("--input-color");
3608  const fontFamily = getComputedStyle(checkoutElement).getPropertyValue("--multiple-payments-font-family");
3609  const fontSize = getComputedStyle(checkoutElement).getPropertyValue("--multiple-payments-font-size");
3610  const rebillyKeys = document.getElementById("payment-gateway-keys");
3611  if (!rebillyKeys) {
3612    return Promise.reject(
3613      buildPAIError(ERROR_CODES.PAI_INITIALIZATION_CONFIG_ERROR, new Error("payment-gateway-keys element not found"))
3614    );
3615  }
3616  const publishableKey = rebillyKeys.getAttribute("data-rebilly-publishable-key");
3617  const organizationId = rebillyKeys.getAttribute("data-rebilly-organization-id");
3618  const websiteId = rebillyKeys.getAttribute("data-rebilly-website-id");
3619  const currency = rebillyKeys.getAttribute("data-rebilly-currency");
3620  if (!publishableKey) {
3621    return Promise.reject(
3622      buildPAIError(ERROR_CODES.PAI_INITIALIZATION_CONFIG_ERROR, new Error("Missing required Rebilly publishable key"), {
3623        hasPublishableKey: !!publishableKey,
3624        hasOrganizationId: !!organizationId,
3625        hasWebsiteId: !!websiteId
3626      })
3627    );
3628  }
3629  const placeholders = checkoutComponent.cardPaymentPlaceholders;
3630  const rebillyConfig = {
3631    publishableKey,
3632    organizationId,
3633    kountAccountId: "700000",
3634    // This is for capturing kount fraud sessions
3635    websiteId,
3636    // NOTE: need to add below otherwise this error happens: transactionData must contain an amount to fetch methods
3637    transactionData: {
3638      currency: currency || "USD",
3639      amount: 1,
3640      label: "Product Purchase"
3641    },
3642    icon: {
3643      color: inputColor
3644    },
3645    style: {
3646      base: {
3647        color: inputColor,
3648        fontFamily,
3649        fontSize,
3650        "::placeholder": {
3651          color: inputColor,
3652          fontFamily,
3653          fontSize
3654        }
3655      }
3656    },
3657    placeholders: {
3658      card: {
3659        number: placeholders.number,
3660        ...placeholders.expiration.includes("/") ? {
3661          expirationSeparator: "/",
3662          expirationMonth: placeholders.expiration.split("/")[0],
3663          expirationYear: placeholders.expiration.split("/")[1]
3664        } : {
3665          expiration: placeholders.expiration
3666        },
3667        cvv: placeholders.cvv
3668      }
3669    }
3670  };
3671  CheckoutDigitalWallet.initialize();
3672  return initializePAIConfig(rebillyConfig);
3673};
3674var initializeCountries = (options) => {
3675  return globalThis.CFFetch(
3676    "/cf_countries_states.json",
3677    {
3678      headers: { "Content-Type": "application/json" }
3679    },
3680    { retries: 3, shouldCaptureServerError: true }
3681  ).then(function(res) {
3682    return res.json();
3683  }).catch((e) => {
3684    throw new CheckoutCriticalError(ERROR_CODES.FETCH_COUNTRIES_STATES_ERROR, {
3685      cause: e
3686    });
3687  }).then((countryStateReqResponse) => {
3688    globalThis.Checkout.allCountries = countryStateReqResponse.result;
3689    const defaultCountryCode = "US";
3690    const countryData = globalThis.Checkout.allCountries.find((c) => c.iso2 == globalThis.cfVisitorData.country) ?? globalThis.Checkout.allCountries.find((c) => c.iso2 == defaultCountryCode);
3691    const stateData = countryData.regions?.find((r) => r.iso2 == globalThis.cfVisitorData.regionCode) ?? countryData.regions?.[0];
3692    const country = countryData.iso2;
3693    const state = stateData?.state_code;
3694    globalThis.Checkout.contactLocale = {
3695      country,
3696      state
3697    };
3698    const initialShipping = globalThis.Checkout.store.shipping.get();
3699    globalThis.Checkout.store.shipping.set({
3700      ...initialShipping ?? {},
3701      country: initialShipping?.country ?? country,
3702      state: initialShipping?.state ?? state
3703    });
3704    let initialBilling = globalThis.Checkout.store.billing.get();
3705    if (globalThis.Checkout.store.checkout.mode.get() == "guest") {
3706      initialBilling = parseAddressByFields(initialBilling, options.billingFields);
3707    }
3708    globalThis.Checkout.store.billing.set(initialBilling);
3709    globalThis.Checkout.store.phoneNumberInitialized.set(true);
3710  });
3711};
3712var checkFeatureFlags = () => {
3713  return CFFetch("/user_pages/api/v1/checkouts/feature_flags.json", {}, { retries: 3, shouldCaptureServerError: true }).then((res) => {
3714    return res.json();
3715  }).then((res) => {
3716    globalThis.Checkout.store.featureFlags.isShippingEnabled.set(res.feature_flags.is_shipping_enabled);
3717  }).catch((e) => {
3718    throw new CheckoutCriticalError(ERROR_CODES.FETCH_FEATURE_FLAGS_ERROR, {
3719      cause: e
3720    });
3721  });
3722};
3723var initializeMachine = (options) => {
3724  globalThis.Checkout.store.state.listen((newState) => {
3725    switch (newState) {
3726      case globalThis.Checkout.StoreStates.INITIALIZING: {
3727        const isGuest = globalThis.Checkout.store.checkout.mode.get() == "guest";
3728        const isSaved = globalThis.Checkout.store.checkout.mode.get() == "saved";
3729        const isOTO = globalThis.Checkout.store.checkout.mode.get() == "oto";
3730        const paymentMethods = globalThis.Checkout.store.paymentMethods.get();
3731        const oneStepCheckout = document.querySelector('[data-page-element="Checkout/V2"][data-total-steps="1"]');
3732        const expressPaymentAvailable = globalThis.globalResourceData.expressEnabledPayments && globalThis.globalResourceData.expressEnabledPayments.length > 0;
3733        const shouldIntializePAI = oneStepCheckout && isGuest || !paymentMethods.length && (isSaved || isOTO) || expressPaymentAvailable && isSaved;
3734        const shouldInitializeTurnstile = window.turnstileSiteKey && window.turnstileSiteKey.length;
3735        if (shouldInitializeTurnstile) initializeTurnstile();
3736        Promise.all(
3737          [
3738            checkFeatureFlags(),
3739            shouldIntializePAI && loadPAIDeps(false),
3740            initializeCountries(options),
3741            !isGuest && Object.keys(globalThis.Checkout.productsById).length > 0 && CheckoutExistingOrders.fetch()
3742          ].filter((v) => !!v)
3743        ).then(() => {
3744          globalThis.Checkout.store.state.set(globalThis.Checkout.StoreStates.INITIALIZED);
3745        }).catch((e) => {
3746          if (e instanceof CheckoutCriticalError) {
3747            displayAndLogCriticalError(e);
3748          } else {
3749            const initializationError = new CheckoutCriticalError(ERROR_CODES.UNEXPECTED_INITIALIZATION_ERROR, {
3750              cause: e
3751            });
3752            displayAndLogCriticalError(initializationError);
3753          }
3754        });
3755        break;
3756      }
3757      case globalThis.Checkout.StoreStates.INITIALIZED: {
3758        CheckoutSummary.sendOrderPreview();
3759        setTimeout(() => {
3760          globalThis.Checkout.store.state.set(globalThis.Checkout.StoreStates.FILLING_FORM);
3761        });
3762        break;
3763      }
3764      case globalThis.Checkout.StoreStates.FILLING_FORM: {
3765        break;
3766      }
3767      case globalThis.Checkout.StoreStates.SUBMITTED: {
3768        break;
3769      }
3770    }
3771  });
3772  globalThis.Checkout.store.submitting.listen((submitting) => {
3773    const state = submitting.state;
3774    switch (state) {
3775      case globalThis.Checkout.SubmittingStates.ERROR: {
3776        globalThis.Checkout.store.state.set(globalThis.Checkout.StoreStates.FILLING_FORM);
3777        break;
3778      }
3779      case globalThis.Checkout.SubmittingStates.DONE: {
3780        globalThis.Checkout.store.state.set(globalThis.Checkout.StoreStates.SUBMITTED);
3781        break;
3782      }
3783    }
3784  });
3785  globalThis.Checkout.store.billing.listen((billing) => {
3786    const fields = globalThis.Checkout.store.billingFields.get();
3787    const addressFields = fieldsForCountry(fields, billing.country);
3788    globalThis.Checkout.store.billingFields.set(addressFields);
3789  });
3790  globalThis.Checkout.store.payment.paypal.state.listen((submitting) => {
3791    const state = submitting.state;
3792    switch (state) {
3793      case globalThis.Checkout.PaypalStates.ERROR: {
3794        setTimeout(resetPaypalErrorState, 3e3);
3795        break;
3796      }
3797    }
3798  });
3799  globalThis.Checkout.store.checkout.mode.listen((mode) => {
3800    if (mode === "guest") {
3801      const cart = globalThis.Checkout.computed.checkoutCart.get();
3802      CheckoutExistingOrders.clearUpdatableOrders(cart.items[0]?.product_id);
3803      globalThis.Checkout.store.contact.set({});
3804      globalThis.Checkout.store.shipping.set({
3805        country: globalThis.Checkout.contactLocale.country,
3806        state: globalThis.Checkout.contactLocale.state
3807      });
3808      const newBillingData = parseAddressByFields(globalThis.Checkout.contactLocale, options.billingFields);
3809      globalThis.Checkout.store.billing.set(newBillingData);
3810      globalThis.Checkout.store.payment.id.set(null);
3811    }
3812  });
3813  globalThis.Checkout.store.payment.id.listen((newPaymentId) => {
3814    if (!newPaymentId) loadPAIDeps()?.catch((e) => displayAndLogCriticalError(e));
3815  });
3816  globalThis.Checkout.computed.isOTORetrialPayment.listen((isOTORetrialPayment) => {
3817    if (isOTORetrialPayment) loadPAIDeps()?.catch((e) => displayAndLogCriticalError(e));
3818  });
3819  const checkoutStatesChangedByCartItems = {
3820    [globalThis.Checkout.CheckoutStates.UPGRADE_DOWNGRADE]: true,
3821    [globalThis.Checkout.CheckoutStates.REACTIVATE]: true
3822  };
3823  computed([globalThis.Checkout.computed.modeLeaveEnterEvent, globalThis.Checkout.store.state], (ev, state) => {
3824    if ([globalThis.Checkout.StoreStates.START, globalThis.Checkout.StoreStates.INITIALIZING].includes(state)) return;
3825    const { enter } = ev;
3826    if (enter && !checkoutStatesChangedByCartItems[enter]) {
3827      globalThis.Checkout.store.checkout.lastModeIndependentOfCartItems.set(enter);
3828    }
3829    const oneStepCheckout = document.querySelector('[data-page-element="Checkout/V2"][data-total-steps="1"]');
3830    if (enter === "guest" && oneStepCheckout) {
3831      loadPAIDeps()?.catch((e) => displayAndLogCriticalError(e));
3832    }
3833    if (enter === "saved") {
3834      const contactPaymentMethod = globalThis.Checkout.store.paymentMethods.get();
3835      if (!contactPaymentMethod?.length) {
3836        loadPAIDeps()?.catch((e) => displayAndLogCriticalError(e));
3837      }
3838    }
3839  }).subscribe(() => {
3840  });
3841  globalThis.Checkout.computed.checkoutCart.listen((cart) => {
3842    const currentMode = globalThis.Checkout.store.checkout.mode.get();
3843    let cartState;
3844    cart.items.forEach(({ type }) => {
3845      if (type) {
3846        if (cartState) {
3847          throw new Error(`Cart has more than one item of type ${type}`);
3848        }
3849        cartState = type;
3850      }
3851    });
3852    if (cartState && cartState != currentMode) {
3853      globalThis.Checkout.store.checkout.mode.set(cartState);
3854    } else if (!cartState && [globalThis.Checkout.CheckoutStates.UPGRADE_DOWNGRADE, globalThis.Checkout.CheckoutStates.REACTIVATE].includes(
3855      currentMode
3856    )) {
3857      const lastModeIndependentOfCartItems = globalThis.Checkout.store.checkout.lastModeIndependentOfCartItems.get();
3858      if (lastModeIndependentOfCartItems && lastModeIndependentOfCartItems != currentMode) {
3859        globalThis.Checkout.store.checkout.mode.set(lastModeIndependentOfCartItems);
3860      }
3861    }
3862  });
3863  let lastBilling;
3864  globalThis.Checkout.store.billing.listen((billing) => {
3865    if (globalThis.Checkout.store.billingApiErrorsByField.get()) globalThis.Checkout.store.billingApiErrorsByField.set();
3866    const backfilledBillingFromApi = options.billingFields.length == 2 && Object.keys(billing).length > 2;
3867    const updatedZipForSameAddress = !billing.id && lastBilling?.zip != billing.zip;
3868    if (backfilledBillingFromApi && updatedZipForSameAddress) {
3869      const newBillingAddress = {
3870        country: billing.country,
3871        zip: billing.zip
3872      };
3873      globalThis.Checkout.store.billing.set(newBillingAddress);
3874    }
3875    lastBilling = billing;
3876  });
3877};
3878
3879// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/Services/checkout-summary.ts
3880init_fetcher();
3881var PreviewError = class extends Error {
3882  constructor(message, details) {
3883    super(message);
3884    __publicField(this, "details");
3885    this.name = this.constructor.name;
3886    this.details = details;
3887    if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
3888  }
3889};
3890var orderPreviewFetcher = makeCurrentPageFetcher();
3891var _sendOrderPreviewTimer, _lastOrderPreviewData, _lastRebillyUpdate, _couponStateBeforeApplying, _skipOrderSummaryUpdate, _previewPending, _lastPreviewedSummary, _CheckoutSummary_static, setLoadingShippingOptions_fn, validAddress_fn, backfillBillingAddress_fn, processOrderPreviewResponseForSummary_fn, buildRecurringSummary_fn, buildCartDetails_fn, buildOrderPreviewPayload_fn, buildAddressParams_fn;
3892var CheckoutSummary = class {
3893  static skipOrderSummaryUpdateWithCb(cb) {
3894    __privateSet(this, _skipOrderSummaryUpdate, true);
3895    cb();
3896    __privateSet(this, _skipOrderSummaryUpdate, false);
3897  }
3898  static sendOrderPreview(options) {
3899    const cart = globalThis.Checkout.computed.checkoutCart.get();
3900    const isCouponValidation = !!options?.isCouponValidation;
3901    const forceRebillyUpdate = !!options?.forceRebillyUpdate;
3902    const revalidateCoupon = !!options?.revalidateCoupon;
3903    if (__privateGet(this, _skipOrderSummaryUpdate)) {
3904      return;
3905    }
3906    if (!cart.items?.length) {
3907      if (globalThis.Checkout.store.coupons.appliedCode.get() || globalThis.Checkout.store.coupons.currentCode.get()) {
3908        globalThis.Checkout.store.coupons.appliedCode.set("");
3909        globalThis.Checkout.store.coupons.currentCode.set("");
3910        globalThis.Checkout.store.coupons.state.set(globalThis.Checkout.CouponStates.READY);
3911      }
3912      if (globalThis.Checkout.store.summary.get().state != globalThis.Checkout.SummaryStates.WAITING) {
3913        globalThis.Checkout.store.summary.set({ state: globalThis.Checkout.SummaryStates.WAITING });
3914      }
3915      __privateSet(this, _lastOrderPreviewData, null);
3916      this.disableIsUpdatingRebilly();
3917      return;
3918    }
3919    const billingFields = globalThis.Checkout.store.billingFields?.get();
3920    const shippingFields = globalThis.Checkout.store.shippingFields?.get();
3921    const checkoutResourcePage = globalThis.globalResourceData.resourceName == "checkout";
3922    const shouldUpdateSummaryData = isCouponValidation || checkoutResourcePage || globalThis.Checkout.utils.hasValidDataForOrderPreview({ billingFields, shippingFields });
3923    const hasDigitalPayment = globalThis.globalResourceData.enabledPayments.includes("apple-pay") || globalThis.globalResourceData.expressEnabledPayments.includes("apple-pay");
3924    const shouldRevalidateAppliedCoupon = revalidateCoupon && !isCouponValidation && !!globalThis.Checkout.store.coupons.appliedCode.get();
3925    if (!shouldUpdateSummaryData && !hasDigitalPayment) {
3926      if (globalThis.Checkout.store.summary.get().state != globalThis.Checkout.SummaryStates.WAITING) {
3927        globalThis.Checkout.store.summary.set({ state: globalThis.Checkout.SummaryStates.WAITING });
3928      }
3929      __privateSet(this, _lastOrderPreviewData, null);
3930      if (!shouldRevalidateAppliedCoupon) return;
3931    }
3932    const dataToPreview = __privateMethod(this, _CheckoutSummary_static, buildOrderPreviewPayload_fn).call(this, cart, {
3933      billingAddress: globalThis.Checkout.store.billing.get(),
3934      shippingAddress: globalThis.Checkout.store.shipping.get(),
3935      shippingOption: globalThis.Checkout.store.shippingOption.get(),
3936      billingSameAsShipping: globalThis.Checkout.store.billingSameAsShipping.get()
3937    }, {
3938      skipBillingAddress: globalThis.Checkout.utils.skipBillingAddress(globalThis.Checkout.store)
3939    });
3940    if (!isCouponValidation && deepEqual(dataToPreview, __privateGet(this, _lastOrderPreviewData))) {
3941      if (forceRebillyUpdate) {
3942        this.updateRebillyTransactionData(globalThis.Checkout.store.summary.get().data, cart, forceRebillyUpdate);
3943      }
3944      return;
3945    }
3946    if (__privateGet(this, _sendOrderPreviewTimer)) clearTimeout(__privateGet(this, _sendOrderPreviewTimer));
3947    if (globalThis.Checkout.store.summary.get().state != globalThis.Checkout.SummaryStates.
3947CALCULATING) {
3948      if (globalThis.Checkout.store.payment.type.get() == "apple-pay") {
3949        globalThis.Checkout.store.isUpdatingRebilly.set(true);
3950      }
3951      if (shouldUpdateSummaryData) {
3952        globalThis.Checkout.store.summary.set({ state: globalThis.Checkout.SummaryStates.CALCULATING });
3953      }
3954    }
3955    const couponStateBeforeApplying = globalThis.Checkout.store.coupons.state.get();
3956    if (isCouponValidation && couponStateBeforeApplying != globalThis.Checkout.CouponStates.APPLYING) {
3957      __privateSet(this, _couponStateBeforeApplying, couponStateBeforeApplying);
3958      globalThis.Checkout.store.coupons.state.set(globalThis.Checkout.CouponStates.APPLYING);
3959    }
3960    const validShippingAddress = !!globalThis.Checkout.utils.hasValidDataForShippingOptions({ shippingFields });
3961    const validBillingAddress = !!globalThis.Checkout.utils.hasValidDataForTaxes({ billingFields });
3962    if (validShippingAddress) {
3963      __privateMethod(this, _CheckoutSummary_static, setLoadingShippingOptions_fn).call(this, dataToPreview);
3964    }
3965    clearTimeout(__privateGet(this, _sendOrderPreviewTimer));
3966    __privateSet(this, _previewPending, true);
3967    __privateSet(this, _sendOrderPreviewTimer, setTimeout(() => {
3968      return this.fetchOrderPreview(cart, {
3969        shouldSetShippingOptions: validShippingAddress,
3970        shouldSetTax: validBillingAddress,
3971        shouldUpdateSummaryData
3972      }).catch((e) => {
3973        this.disableIsUpdatingRebilly();
3974        throw e;
3975      }).finally(() => {
3976        __privateSet(this, _previewPending, false);
3977      });
3978    }, 500));
3979  }
3980  static async fetchOrderPreview(cart, options) {
3981    options = options ?? {};
3982    const shouldUpdateSummaryData = options.shouldUpdateSummaryData ?? true;
3983    const dataToPreview = __privateMethod(this, _CheckoutSummary_static, buildOrderPreviewPayload_fn).call(this, cart, {
3984      billingAddress: globalThis.Checkout.store.billing.get(),
3985      shippingAddress: globalThis.Checkout.store.shipping.get(),
3986      shippingOption: globalThis.Checkout.store.shippingOption.get(),
3987      billingSameAsShipping: globalThis.Checkout.store.billingSameAsShipping.get()
3988    }, {
3989      skipBillingAddress: globalThis.Checkout.utils.skipBillingAddress(globalThis.Checkout.store)
3990    });
3991    __privateSet(this, _lastOrderPreviewData, dataToPreview);
3992    const criticalErrors = globalThis.Checkout.store.criticalErrors.get();
3993    globalThis.Checkout.store.criticalErrors.set([
3994      ...criticalErrors.filter((error) => error.code != ERROR_CODES.ORDER_RECURRING_INTERVAL_MISMATCH)
3995    ]);
3996    const summaryData = await orderPreviewFetcher.post("/order_preview", dataToPreview);
3997    if (isResponseError(summaryData)) {
3998      if (isFetcherError(summaryData)) {
3999        const previewError = summaryData.error;
4000        const timedOut = previewError instanceof CFFetcherError && previewError.type == CFFetcherErrorTypes.TIMEOUT_ERROR;
4001        if (previewError != MANUALLY_ABORTED && !timedOut) {
4002          const errorData = summaryData;
4003          throw new PreviewError(errorData.error);
4004        }
4005        if (timedOut) {
4006          globalThis.Checkout.store.loadingShipping.set(false);
4007          this.disableIsUpdatingRebilly();
4008          __privateSet(this, _lastOrderPreviewData, null);
4009          if (globalThis.Checkout.store.coupons.state.get() == globalThis.Checkout.CouponStates.APPLYING) {
4010            globalThis.Checkout.store.coupons.state.set(__privateGet(this, _couponStateBeforeApplying));
4011          }
4012          if (shouldUpdateSummaryData) {
4013            globalThis.Checkout.store.summary.set({ state: globalThis.Checkout.SummaryStates.WAITING });
4014          }
4015        }
4016      } else if (isBackendError(summaryData)) {
4017        globalThis.Checkout.store.loadingShipping.set(false);
4018        const error = summaryData.error;
4019        const errorDetails = error?.details?.[0];
4020        let newSummaryState;
4021        if (errorDetails?.type == "InvalidPostalCodeError") {
4022          newSummaryState = {
4023            state: globalThis.Checkout.SummaryStates.WAITING
4024          };
4025          globalThis.Checkout.store.showAllErrors.billing.set(true);
4026          globalThis.Checkout.store.billingApiErrorsByField.set({ zip: { message: errorDetails.message } });
4027          this.disableIsUpdatingRebilly();
4028        } else if (errorDetails?.type == "InvalidCouponError") {
4029          globalThis.Checkout.store.coupons.appliedCode.set("");
4030          globalThis.Checkout.store.coupons.currentCode.set("");
4031          globalThis.Checkout.store.coupons.errorMessage.set(errorDetails.message);
4032          globalThis.Checkout.store.coupons.state.set(globalThis.Checkout.CouponStates.ERROR);
4033          const summaryData2 = __privateMethod(this, _CheckoutSummary_static, processOrderPreviewResponseForSummary_fn).c
4033all(this, errorDetails.preview, {
4034            shouldSetShippingOptions: options?.shouldSetShippingOptions,
4035            shouldSetTax: options?.shouldSetTax
4036          });
4037          newSummaryState = {
4038            state: globalThis.Checkout.SummaryStates.OK,
4039            data: summaryData2
4040          };
4041          this.updateRebillyTransactionData(summaryData2, cart);
4042        } else {
4043          globalThis.Checkout.store.coupons.state.set(__privateGet(this, _couponStateBeforeApplying));
4044          newSummaryState = { state: globalThis.Checkout.SummaryStates.ERROR };
4045          if (errorDetails?.type == "RecurringMismatch") {
4046            const criticalErrors2 = globalThis.Checkout.store.criticalErrors.get();
4047            globalThis.Checkout.store.criticalErrors.set([
4048              ...criticalErrors2,
4049              { code: ERROR_CODES.ORDER_RECURRING_INTERVAL_MISMATCH }
4050            ]);
4051          } else if (errorDetails?.message) {
4052            newSummaryState = {
4053              state: globalThis.Checkout.SummaryStates.ERROR,
4054              error: { message: errorDetails?.message }
4055            };
4056          }
4057          this.disableIsUpdatingRebilly();
4058        }
4059        if (shouldUpdateSummaryData && newSummaryState) {
4060          globalThis.Checkout.store.summary.set(newSummaryState);
4061        }
4062      }
4063    } else {
4064      const { shipping_quotes_response, selected_shipping_option } = summaryData;
4065      if (options?.shouldSetShippingOptions) {
4066        this.skipOrderSummaryUpdateWithCb(() => {
4067          globalThis.Checkout.store.shippingOptions.set(shipping_quotes_response?.options ?? []);
4068          globalThis.Checkout.store.shippingOption.set(selected_shipping_option);
4069          globalThis.Checkout.store.loadingShipping.set(false);
4070          __privateMethod(this, _CheckoutSummary_static, backfillBillingAddress_fn).call(this, summaryData);
4071        });
4072      }
4073      const reconciledCode = globalThis.Checkout.store.coupons.currentCode.get() || globalThis.Checkout.store.coupons.appliedCode.get();
4074      const couponCodeApplied = summaryData.discounts?.find(
4075        (discount) => discount.code?.toUpperCase() == reconciledCode?.toUpperCase()
4076      );
4077      if (couponCodeApplied) {
4078        globalThis.Checkout.store.coupons.appliedCode.set(reconciledCode);
4079        globalThis.Checkout.store.coupons.state.set(globalThis.Checkout.CouponStates.APPLIED);
4080      } else {
4081        if (reconciledCode) {
4082          globalThis.Checkout.store.coupons.appliedCode.set("");
4083          globalThis.Checkout.store.coupons.currentCode.set("");
4084        }
4085        globalThis.Checkout.store.coupons.state.set(globalThis.Checkout.CouponStates.READY);
4086      }
4087      const newSummaryState = {
4088        state: globalThis.Checkout.SummaryStates.OK,
4089        data: __privateMethod(this, _CheckoutSummary_static, processOrderPreviewResponseForSummary_fn).call(this, summaryData, {
4090          shouldSetShippingOptions: options?.shouldSetShippingOptions,
4091          shouldSetTax: options?.shouldSetTax
4092        })
4093      };
4094      if (shouldUpdateSummaryData) {
4095        globalThis.Checkout.store.summary.set(newSummaryState);
4096      }
4097      __privateSet(this, _lastPreviewedSummary, newSummaryState.data);
4098      this.updateRebillyTransactionData(newSummaryState.data, cart);
4099    }
4100  }
4101  static async fetchOrderSummaryForExpress(cart, payload) {
4102    const dataToPreview = __privateMethod(this, _CheckoutSummary_static, buildOrderPreviewPayload_fn).call(this, cart, {
4103      billingAddress: payload.billingAddress,
4104      shippingAddress: payload.shippingAddress,
4105      shippingOption: payload.shippingOption,
4106      billingSameAsShipping: payload.billingSameAsShipping
4107    }, {
4108      skipBillingAddress: false
4109    });
4110    const summaryData = await orderPreviewFetcher.post("/order_preview", dataToPreview);
4111    if (isResponseError(summaryData)) {
4112      if (isFetcherError(summaryData)) {
4113        throw new PreviewError(summaryData.error);
4114      } else if (isBackendError(summaryData)) {
4115        throw new PreviewError(summaryData.error.error, summaryData.error.details);
4116      }
4117    } else {
4118      const validShippingAddress = __privateMethod(this, _CheckoutSummary_static, validAddress_fn).call(this, payload.shippingAddress);
4119      const validBillingAddress = __privateMethod(this, _CheckoutSummary_static, validAddress_fn).call(this, payload.billingAddress);
4120      return {
4121        summary: summaryData,
4122        data: __privateMethod(this, _CheckoutSummary_static, processOrderPreviewResponseForSummary_fn).c
4122all(this, summaryData, {
4123          shouldSetShippingOptions: validShippingAddress,
4124          shouldSetTax: validBillingAddress
4125        })
4126      };
4127    }
4128  }
4129  static disableIsUpdatingRebilly() {
4130    globalThis.Checkout.store.isUpdatingRebilly.set(false);
4131  }
4132  static get lastPreviewedSummary() {
4133    return __privateGet(this, _lastPreviewedSummary);
4134  }
4135  static updateRebillyTransactionData(summary, cart, forceRebillyUpdate = false) {
4136    this.updateRebillyTransactionDataPromise(summary, cart, forceRebillyUpdate).catch((e) => {
4137      this.disableIsUpdatingRebilly();
4138      if (e instanceof CheckoutCriticalError) displayAndLogCriticalError(e);
4139    });
4140  }
4141  static updateRebillyTransactionDataPromise(summary, cart, forceRebillyUpdate = false) {
4142    const mode = globalThis.Checkout.store.checkout.mode.get();
4143    const shippingEnabled = globalThis.Checkout.utils.hasPhysicalProducts();
4144    const paymentType = globalThis.Checkout.store.payment.type.get();
4145    const lineItems = summary?.line_items ?? [];
4146    const RebillyFullyInitialized = globalThis.Checkout.store.payment.state.get() == globalThis.Checkout.PaymentStates.INITIALIZED;
4147    if (mode == globalThis.Checkout.CheckoutStates.UPGRADE_DOWNGRADE || !lineItems.length || !RebillyFullyInitialized) {
4148      if (!__privateGet(this, _previewPending)) {
4149        this.disableIsUpdatingRebilly();
4150      }
4151      return Promise.resolve();
4152    }
4153    const transactionData = this.buildTransactionData(summary, cart, shippingEnabled, paymentType);
4154    if (!forceRebillyUpdate && deepEqual(__privateGet(this, _lastRebillyUpdate), transactionData)) {
4155      this.disableIsUpdatingRebilly();
4156      return Promise.resolve();
4157    }
4158    return globalThis.Rebilly.update({ transactionData }).then(() => {
4159      this.disableIsUpdatingRebilly();
4160      __privateSet(this, _lastRebillyUpdate, transactionData);
4161    }).catch((e) => {
4162      const error = new CheckoutCriticalError(ERROR_CODES.READY_TO_PAY_UPDATE_ERROR, { cause: e });
4163      error.context = {
4164        phase: "ready-to-pay-update",
4165        paymentType,
4166        mode,
4167        currency: transactionData.currency,
4168        amount: transactionData.amount,
4169        lineItemCount: transactionData.lineItems.length,
4170        requestShipping: transactionData.requestShipping,
4171        ...extractRebillyErrorFields(e)
4172      };
4173      throw error;
4174    });
4175  }
4176  static buildTransactionData(summaryData, cart, shippingEnabled, paymentType) {
4177    const { currency, line_items } = summaryData;
4178    const lineItems = line_items.map(({ price, description }, index) => {
4179      let label;
4180      if (line_items.length == cart.items.length) {
4181        const variantId = cart.items[index].variant_id;
4182        const variant = globalThis.Checkout.variantsById[variantId];
4183        label = variant.name;
4184      } else {
4185        label = description;
4186      }
4187      return {
4188        label,
4189        amount: price
4190      };
4191    });
4192    let amount = summaryData.subtotal.amount;
4193    if (paymentType === "Klarna") {
4194      amount = summaryData.total.amount;
4195    }
4196    return {
4197      currency,
4198      amount,
4199      label: "Total Purchase",
4200      lineItems,
4201      requestShipping: shippingEnabled
4202    };
4203  }
4204};
4205_sendOrderPreviewTimer = new WeakMap();
4206_lastOrderPreviewData = new WeakMap();
4207_lastRebillyUpdate = new WeakMap();
4208_couponStateBeforeApplying = new WeakMap();
4209_skipOrderSummaryUpdate = new WeakMap();
4210_previewPending = new WeakMap();
4211_lastPreviewedSummary = new WeakMap();
4212_CheckoutSummary_static = new WeakSet();
4213setLoadingShippingOptions_fn = function(dataToPreview) {
4214  const { selected_shipping_option: _tmpShippingOption1, ...dataToPreviewWithoutShippingOption } = dataToPreview?.order ?? {};
4215  const { selected_shipping_option: _tmpShippingOption2, ...lastOrderPreviewDataWithoutShippingOption } = __privateGet(this, _lastOrderPreviewData)?.order ?? {};
4216  if (!deepEqual(dataToPreviewWithoutShippingOption, lastOrderPreviewDataWithoutShippingOption)) {
4217    globalThis.Checkout.store.loadingShipping.set(true);
4218  }
4219};
4220validAddress_fn = function(address) {
4221  return !!address?.zip && !!address?.country;
4222};
4223backfillBillingAddress_fn = function(summaryData) {
4224  const checkoutBilling = globalThis.Checkout.store.billing.get();
4225  if (summaryData.billing_address) {
4226    const { city: summaryCity, region: summaryRegion } = summaryData.billing_address;
4227    if (!checkoutBilling.city || !checkoutBilling.state) {
4228      globalThis.Checkout.store.billing.set({
4229        ...checkoutBilling,
4230        ...!checkoutBilling.city ? { city: summaryCity } : {},
4231        ...!checkoutBilling.state ? { state: summaryRegion } : {}
4232      });
4233    }
4234  }
4235};
4236processOrderPreviewResponseForSummary_fn = function(summaryData, options) {
4237  const recurring = __privateMethod(this, _CheckoutSummary_static, buildRecurringSummary_fn).c
4237all(this, summaryData);
4238  return {
4239    currency: summaryData.currency,
4240    currency_symbol: summaryData.currency_symbol,
4241    line_items: summaryData.line_items,
4242    total: {
4243      amount: parseFloat(summaryData.total_amount?.amount),
4244      formatted: summaryData.total_amount_formatted
4245    },
4246    discount: {
4247      amount: parseFloat(summaryData.discount_amount.amount),
4248      formatted: summaryData.discount_amount_formatted
4249    },
4250    discounts: (summaryData.discounts ?? []).map((discount) => {
4251      return {
4252        name: discount.name,
4253        code: discount.code,
4254        amount_formatted: "-" + formatNumberToCurrency(summaryData.currency_symbol, discount.amount)
4255      };
4256    }),
4257    subtotal: {
4258      amount: parseFloat(summaryData.subtotal_amount.amount),
4259      formatted: summaryData.subtotal_amount_formatted
4260    },
4261    ...options?.shouldSetShippingOptions ? {
4262      shipping: {
4263        amount: parseFloat(summaryData.shipping_amount.amount),
4264        formatted: summaryData.shipping_amount_formatted
4265      }
4266    } : { shipping: {} },
4267    ...options?.shouldSetTax ? {
4268      tax: {
4269        amount: parseFloat(summaryData.tax_amount.amount),
4270        formatted: summaryData.tax_amount_formatted
4271      }
4272    } : { tax: {} },
4273    ...summaryData.upcoming_invoice?.interim_amount ? {
4274      interim: {
4275        amount: parseFloat(summaryData.upcoming_invoice.interim_amount.amount),
4276        formatted: summaryData.upcoming_invoice.interim_amount_formatted
4277      }
4278    } : {},
4279    ...summaryData.upcoming_invoice ? {
4280      upcoming_invoice: {
4281        line_items: summaryData.upcoming_invoice.line_items.filter((i) => i.interim).map((item) => {
4282          return {
4283            variant_name: item.variant_name,
4284            quantity: item.quantity,
4285            amount: parseFloat(item.amount.amount),
4286            formatted: item.amount_formatted
4287          };
4288        })
4289      }
4290    } : {},
4291    ...recurring ? { recurring } : {}
4292  };
4293};
4294buildRecurringSummary_fn = function(summaryData) {
4295  if (!summaryData.recurring_total_amount) return void 0;
4296  const recurringTotal = parseFloat(summaryData.recurring_total_amount.amount);
4297  const recurringDiscount = parseFloat(summaryData.recurring_discount_amount?.amount ?? "0");
4298  const displayedTotal = summaryData.upcoming_invoice?.interim_amount ? parseFloat(summaryData.upcoming_invoice.interim_amount.amount) : parseFloat(summaryData.total_amount?.amount);
4299  return {
4300    showThen: Math.abs(recurringTotal - displayedTotal) > 1e-3,
4301    total: { amount: recurringTotal, formatted: summaryData.recurring_total_amount_formatted },
4302    discount: { amount: recurringDiscount, formatted: summaryData.recurring_discount_amount_formatted },
4303    interval: summaryData.recurring_interval ?? "",
4304    before_formatted: recurringDiscount > 0 ? summaryData.recurring_total_before_discount_formatted ?? "" : ""
4305  };
4306};
4307buildCartDetails_fn = function(cart) {
4308  const orderId = cart.order_id;
4309  const lineItems = cart.items.map(({ price_id, line_item_id, variant_id, quantity }) => {
4310    const data = {
4311      variant_id,
4312      price_id,
4313      ...line_item_id ? { line_item_id } : {},
4314      quantity
4315    };
4316    return data;
4317  });
4318  return { order_id: orderId, line_items: lineItems };
4319};
4320buildOrderPreviewPayload_fn = function(cart, payload, options) {
4321  const couponState = globalThis.Checkout.store.coupons.state.get();
4322  let couponCode;
4323  if (couponState == globalThis.Checkout.CouponStates.APPLYING) {
4324    couponCode = globalThis.Checkout.store.coupons.currentCode.get();
4325  } else {
4326    couponCode = globalThis.Checkout.store.coupons.appliedCode.get();
4327  }
4328  const selected_shipping_option = payload.shippingOption;
4329  return {
4330    order: {
4331      full_preview: true,
4332      should_backfill_billing_address: true,
4333      coupon_codes: couponCode,
4334      ...selected_shipping_option?.amount ? { selected_shipping_option } : {},
4335      ...__privateMethod(this, _CheckoutSummary_static, buildAddressParams_fn).call(this, cart, {
4336        billingAddress: payload.billingAddress,
4337        shippingAddress: payload.shippingAddress,
4338        billingSameAsShipping: payload.billingSameAsShipping
4339      }, options),
4340      ...__privateMethod(this, _CheckoutSummary_static, buildCartDetails_fn).call(this, cart)
4341    }
4342  };
4343};
4344buildAddressParams_fn = function(cart, addressParams, options) {
4345  const billing = addressParams.billingAddress;
4346  const shipping = addressParams.shippingAddress;
4347  const mode = globalThis.Checkout.store.checkout.mode.get();
4348  if (mode === globalThis.Checkout.CheckoutStates.UPGRADE_DOWNGRADE && !hasPhysicalProducts(cart)) {
4349    return;
4350  }
4351  let billingData, shippingData;
4352  if (mode !== globalThis.Checkout.CheckoutStates.UPGRADE_DOWNGRADE) {
4353    if (isSavedAddress(billing)) {
4354      billingData = {
4355        id: billing.id
4356      };
4357    } else {
4358      billingData = {
4359        address_one: billing.address,
4360        address_two: billing.address_2,
4361        city: billing.city,
4362        state: billing.state,
4363        country: billing.country,
4364        postal_code: billing.zip
4365      };
4366    }
4367  }
4368  if (isSavedAddress(shipping)) {
4369    shippingData = {
4370      id: shipping.id,
4371      address_one: shipping.address,
4372      address_two: shipping.address_2,
4373      city: shipping.city,
4374      state: shipping.state,
4375      country: shipping.country,
4376      postal_code: shipping.zip
4377    };
4378  } else {
4379    shippingData = {
4380      address_one: shipping.address,
4381      address_two: shipping.address_2,
4382      city: shipping.city,
4383      state: shipping.state,
4384      country: shipping.country,
4385      postal_code: shipping.zip
4386    };
4387  }
4388  if (hasPhysicalProducts(cart)) {
4389    const billingSameAsShippingData = addressParams.billingSameAsShipping;
4390    if (options.skipBillingAddress) {
4391      return { delivery_address: shippingData };
4392    }
4393    if (mode == globalThis.Checkout.CheckoutStates.OTO) {
4394      return {
4395        delivery_address: shippingData,
4396        billing_address: billingData
4397      };
4398    }
4399    if (billingSameAsShippingData) {
4400      return {
4401        delivery_address: shippingData,
4402        billing_address: shippingData
4403      };
4404    } else {
4405      return {
4406        delivery_address: shippingData,
4407        billing_address: billingData
4408      };
4409    }
4410  } else {
4411    if (options.skipBillingAddress) return;
4412    return { billing_address: billingData };
4413  }
4414};
4415__privateAdd(CheckoutSummary, _CheckoutSummary_static);
4416__privateAdd(CheckoutSummary, _sendOrderPreviewTimer);
4417__privateAdd(CheckoutSummary, _lastOrderPreviewData);
4418__privateAdd(CheckoutSummary, _lastRebillyUpdate);
4419__privateAdd(CheckoutSummary, _couponStateBeforeApplying);
4420__privateAdd(CheckoutSummary, _skipOrderSummaryUpdate);
4421__privateAdd(CheckoutSummary, _previewPending, false);
4422// Last summary a preview actually computed, cached even when the store is not written
4423// (invalid/absent billing on a wallet checkout keeps shouldUpdateSummaryData false). The
4424// post-init wallet update reads this so it can push the real amount instead of the
4425// amount:1 placeholder (ENG-6708 / ENG-6871).
4426__privateAdd(CheckoutSummary, _lastPreviewedSummary);
4427
4428// projects/lib/packages/yggdrasil-blueprints/src/Elements/Checkout/V2/CheckoutMultiStep/V2/checkoutFormUtils.ts
4429init_define_process();
4430function formBySteps(formStructure) {
4431  return Object.entries(formStructure).reduce((acc1, item) => {
4432    const [totalSteps, form] = item;
4433    acc1[totalSteps] = {};
4434    form.reduce((acc2, form2, index) => {
4435      form2.forEach((field) => {
4436        acc2[field] = index;
4437      });
4438      return acc2;
4439    }, acc1[totalSteps]);
4440    return acc1;
4441  }, {});
4442}
4443
4444// projects/lib/packages/yggdrasil-blueprints/__generated__/blueprints/rebilly-checkout.ts
4445init_nanostores();
4446init_runtime();
4447var RebillyCheckout = class extends CF2Component {
4448  constructor(el, runtimeSel) {
4449    super(el, runtimeSel);
4450    __publicField(this, "FORM_STRUCTURE_BY_TOTAL_STEPS", {
4451      2: [["contact", "shipping"], ["products", "shippingOption", "billing", "payment", "tos", "summary"]],
4452      3: [["products"], ["contact", "shipping"], ["shippingOption", "billing", "payment", "tos", "summary"]]
4453    });
4454    __publicField(this, "FORM_BY_STEP", formBySteps(this.FORM_STRUCTURE_BY_TOTAL_STEPS));
4455    __publicField(this, "_lazyInitPending");
4456  }
4457  _initializeStore() {
4458    Checkout.isCheckoutResource = globalThis.globalResourceData.resourceName == "checkout";
4459    globalResourceData.enabledPayments = !window.ApplePaySession ? globalResourceData.enabledPayments.filter((v) => v != "apple-pay") : globalResourceData.enabledPayments;
4460    globalResourceData.enabledPayments = !AVAILABLE_KLARNA_COUNTRIES.includes(globalThis.cfVisitorData.country) ? globalResourceData.enabledPayments.filter((paymentType) => paymentType != "Klarna") : globalResourceData.enabledPayments;
4461    globalResourceData.expressEnabledPayments = !window.ApplePaySession ? globalResourceData.expressEnabledPayments.filter((v) => v != "apple-pay") : globalResourceData.expressEnabledPayments;
4462    if (!globalResourceData.expressEnabledPayments.includes("apple-pay")) {
4463      (this.element.querySelectorAll(".elExpressCheckoutForCart") ?? []).forEach((item) => item.remove());
4464    }
4465    const billingFields = this.billingEnabled ? this.billingFields : [];
4466    Checkout.store = create(billingFields, this.shippingFields, globalResourceData.enabledPayments, globalResourceData.expressEnabledPayments);
4467    Checkout.computed = buildComputed(Checkout.store, this.contactFields, this.shippingFields, this.totalSteps);
4468    if (document.querySelectorAll('[data-page-element="Checkout/V2"]').length > 1) {
4469      const error = new CheckoutCriticalError(ERROR_CODES.MULTIPLE_CHECKOUT_PRESENT);
4470      displayAndLogCriticalError(error);
4471      return;
4472    }
4473    initializeUtilities(Checkout.store, Checkout.computed);
4474  }
4475  _initializeMachine() {
4476    const billingFields = this.billingEnabled ? this.billingFields : [];
4477    initializeMachine({
4478      hasPhoneNumber: this.contactFields.includes("phone_number"),
4479      billingFields,
4480      shippingFields: this.shippingFields
4481    });
4482  }
4483  initialize() {
4484    this._initializeStore();
4485    if (this.lazyLoadCheckout) {
4486      this._lazyInitPending = true;
4487      return;
4488    }
4489    this._initializeMachine();
4490  }
4491  backfillContactDataFromGarlic_Mutable(contactData) {
4492    Object.keys(contactData).reduce((acc, field) => {
4493      if (!contactData[field]) {
4494        const val = window.cfGarlicUtils.retrieve(field);
4495        if (field?.length) acc[field] = val;
4496      }
4497      return acc;
4498    }, contactData);
4499  }
4500  updateCheckoutMode(mode) {
4501    const containerMapping = Object.values(Checkout.CheckoutStates).reduce((acc, item) => {
4502      acc[item] = this.element.querySelector(`[data-wrapper-checkout-state="${item}"]`);
4503      return acc;
4504    }, {});
4505    const currentContainer = containerMapping[mode];
4506    for (let container of Object.values(containerMapping)) {
4507      if (container == currentContainer) {
4508        currentContainer.classList.remove("elHide");
4509      } else {
4510        container.classList.add("elHide");
4511      }
4512    }
4513  }
4514  mount() {
4515    if (this._lazyInitPending) {
4516      return;
4517    }
4518    this._doMount();
4519  }
4520  _performLazyInit() {
4521    this._lazyInitPending = false;
4522    this._initializeMachine();
4523    this._doMount();
4524  }
4525  _doMount() {
4526    const contactData = this.contactFields.reduce((acc, field) => {
4527      acc[field] = Checkout.initialContactData[field];
4528      return acc;
4529    }, {});
4530    this.backfillContactDataFromGarlic_Mutable(contactData);
4531    Checkout.computed.checkoutCart.listen(() => {
4532      CheckoutSummary.sendOrderPreview({ revalidateCoupon: true });
4533    });
4534    [Checkout.store.billing, Checkout.store.shipping, Checkout.store.shippingOption].forEac
4534h((store) => {
4535      store?.listen(() => {
4536        CheckoutSummary.sendOrderPreview();
4537      });
4538    });
4539    [Checkout.store.payment.type].forEach((store) => {
4540      store?.listen((newValue, oldValue) => {
4541        const shouldForceRebillyUpdate = newValue === "Klarna" || oldValue === "Klarna";
4542        CheckoutSummary.sendOrderPreview({ forceRebillyUpdate: shouldForceRebillyUpdate });
4543      });
4544    });
4545    if (!this.disableOTP) {
4546      const checkoutLogin = this.getComponentGroup(CheckoutLoginV2);
4547      Checkout.auth.computed.requireLogin.listen((requireLogin) => {
4548        if (requireLogin) {
4549          this.element.querySelector(`[data-wrapper-checkout-state="${Checkout.store.checkout.mode.get()}"]`).classList.add("elHide");
4550          checkoutLogin.show();
4551        } else {
4552          this.updateCheckoutMode(Checkout.store.checkout.mode.get());
4553          checkoutLogin.hide();
4554        }
4555      });
4556    }
4557    Checkout.store.checkout.mode.listen((mode) => {
4558      this.updateCheckoutMode(mode);
4559    });
4560    this.listenAndUpdateCheckoutErrors();
4561    Checkout.store.tos.present.set(this.showTos);
4562    Checkout.store.state.listen((state) => {
4563      if ([Checkout.StoreStates.START, Checkout.StoreStates.INITIALIZING, Checkout.StoreStates.INITIALIZED].includes(state)) {
4564        this.element.querySelector(".elSpinnerWrapper").dataset.loader = true;
4565        if (state === Checkout.StoreStates.INITIALIZED) {
4566          Checkout.store.contact.set(contactData);
4567        }
4568      } else {
4569        if (this.element.querySelector('[data-page-element="CheckoutConfigurationError/V1"]').querySelector(".elHide")) {
4570          delete this.element.querySelector(".elSpinnerWrapper").dataset.loader;
4571        }
4572      }
4573    });
4574    this.element.querySelectorAll('[href="#!checkout-as-guest"]').forEach((el) => {
4575      el.addEventListener("click", (evt) => {
4576        evt.preventDefault();
4577        Checkout.store.checkout.mode.set("guest");
4578      });
4579    });
4580    Checkout.computed.hasShippingEnabled.subscribe((hasShippingEnabled) => {
4581      if (!hasShippingEnabled && Checkout.store.shippingOption.value) {
4582        Checkout.store.shippingOption.set(null);
4583      }
4584    });
4585    Checkout.computed.hideShipping.subscribe((hideShipping) => {
4586      this.element.querySelector(".elCheckoutWrapper").setAttribute("data-shipping-enabled", hideShipping ? "false" : "true");
4587    });
4588    Checkout.store.state.set(Checkout.StoreStates.INITIALIZING);
4589    setupOrderSummaries(this);
4590    this.element.querySelectorAll("input, select").forEach((el) => {
4591      el.addEventListener("focus", () => {
4592        Checkout.store.submitting.set({ state: Checkout.SubmittingStates.IDLE });
4593      });
4594    });
4595    const trackableStores = [
4596      Checkout.store.contact,
4597      Checkout.store.shipping,
4598      Checkout.store.billing,
4599      Checkout.store.billingSameAsShipping,
4600      Checkout.store.tos.accepted,
4601      Checkout.store.shippingOption,
4602      // Checkout.store.payment.state,
4603      Checkout.store.payment.id,
4604      Checkout.store.payment.type,
4605      Checkout.store.payment["payment-card"].events,
4606      Checkout.store.payment["payment-card"].token,
4607      Checkout.store.payment.paypal.state,
4608      Checkout.store.payment.paypal.token,
4609      Checkout.computed.checkoutCart
4610    ];
4611    trackableStores.forEach((store) => {
4612      store.listen((v) => {
4613        Checkout.store.submitting.set({ state: Checkout.SubmittingStates.IDLE });
4614      });
4615    });
4616    Checkout.computed.isOTORetrialPayment.listen((isOTORetrialPayment) => {
4617      if (isOTORetrialPayment) {
4618        this.element.querySelector(".elCheckoutOtoPayment").classList.remove("elHide");
4619      }
4620    });
4621    this.setHandlers(CheckoutMultiStepV2, {
4622      onValidateStep: (step) => {
4623        const valid = this.validateStep(step);
4624        if (!valid) {
4625          scrollToFirstVisibleError();
4626        }
4627        return valid;
4628      },
4629      onStepChange: (oldStep, currentStep) => {
4630        const currentFormStructure = this.FORM_STRUCTURE_BY_TOTAL_STEPS[this.totalSteps][currentStep];
4631        if (currentFormStructure.includes("payment")) {
4632          loadPAIDeps()?.catch((e) => displayAndLogCriticalError(e));
4633        }
4634        const oldFormStructure = this.FORM_STRUCTURE_BY_TOTAL_STEPS[this.totalSteps][oldStep];
4635        if (oldFormStructure.includes("contact")) {
4636          const contactDetails = Checkout.store.contact.get();
4637          collectLeads(contactDetails);
4638        }
4639      }
4640    });
4641    this.setHandlers(CheckoutSubmitButtonV1, {
4642      // NOTE: returned so the button can tell a finished attempt from one that is
4643      // still running, and unlock itself when we never got as far as the POST.
4644      onSubmit: (element) => CheckoutSubmit.submitFromButtonClick(element, () => scrollToFirstVisibleError())
4645    });
4646    this.setHandlers(CheckoutTosV1, {
4647      onAcceptedChange: (accepted) => {
4648        Checkout.store.tos.accepted.set(accepted);
4649      }
4650    });
4651    window.addEventListener("ON_APPLY_COUPON", (event) => {
4652      CheckoutSummary.sendOrderPreview(event.detail);
4653    });
4654    window.addEventListener("ON_CLEAR_COUPON", (event) => {
4655      CheckoutSummary.sendOrderPreview(event.detail);
4656    });
4657    this.setupShippingProfileSelect();
4658    this.setupSubmittingListeners();
4659  }
4660  setupShippingProfileSelect() {
4661    const shippingProfileSelects = this.getComponentGroup(CheckoutShippingProfileSelectV1, {
4662      onSelectOption: (option) => {
4663        Checkout.store.shippingOption.set(option);
4664      }
4665    });
4666    const renderDeps = computed([
4667      Checkout.store.shippingOptions,
4668      Checkout.computed.hasValidShippingAddress,
4669      Checkout.store.loadingShipping,
4670      Checkout.store.summary
4671    ], (...args) => args);
4672    renderDeps.listen(([shippingOptions, hasValidShippingAddress, loadingShipping, summary]) => {
4673      const shippingOption = Checkout.store.shippingOption.get();
4674      const summaryHasError = summary.state === "error";
4675      shippingProfileSelects.update({ shippingOption, shippingOptions, hasValidShippingAddress, loadingShipping, summaryHasError });
4676    });
4677    Checkout.store.shippingOption.listen((shippingOption) => {
4678      shippingProfileSelects.setOption(shippingOption);
4679    });
4680    Checkout.computed.isNewDigitalWalletPayment.subscribe((isNewDigitalWalletPayment) => {
4681      if (isNewDigitalWalletPayment) {
4682        shippingProfileSelects.hide();
4683      } else {
4684        shippingProfileSelects.show();
4685      }
4686    });
4687  }
4688  setupSubmittingListeners() {
4689    const checkoutLoading = this.getComponentGroup(CheckoutLoadingV1);
4690    const submitButtons = this.getComponentGroup(CheckoutSubmitButtonV1);
4691    const submitNotification = this.getComponentGroup(CheckoutSubmitNotificationV1);
4692    computed([Checkout.store.submitting, Checkout.store.summary, Checkout.store.state], (submitting, summary, machineState) => {
4693      const state = submitting.state;
4694      const attemptOwnsButton = machineState === Checkout.StoreStates.SUBMITTING || machineState === Checkout.StoreStates.SUBMITTED;
4695      switch (state) {
4696        case Checkout.SubmittingStates.IDLE: {
4697          if (attemptOwnsButton) break;
4698          checkoutLoading.hide();
4699          switch (summary.state) {
4700            case Checkout.SummaryStates.CALCULATING: {
4701              submitButtons.setLoading();
4702              break;
4703            }
4704            default: {
4705              submitButtons.setButtonInitialHTML();
4706              submitNotification.setStatus("", "");
4707            }
4708          }
4709          break;
4710        }
4711        case Checkout.SubmittingStates.START: {
4712          checkoutLoading.show();
4713          submitButtons.setSubmittingText();
4714          submitNotification.setStatus("", "");
4715          break;
4716        }
4717        case Checkout.SubmittingStates.WAITING_ON_QUEUE: {
4718          checkoutLoading.show();
4719          checkoutLoading.showWaitingOnQueueText(`${this.rebillyCheckoutTexts.waitingOnQueue} (${this.rebillyCheckoutTexts.retryingIn} ${submitting.remainingSeconds}${this.rebillyCheckoutTexts.seconds})`);
4720          submitNotification.setStatus(`${this.rebillyCheckoutTexts.waitingOnQueue}`, `(${this.rebillyCheckoutTexts.retryingIn} ${submitting.remainingSeconds}${this.rebillyCheckoutTexts.seconds})`);
4721          break;
4722        }
4723        case Checkout.SubmittingStates.ERROR: {
4724          checkoutLoading.hide();
4725          submitButtons.setButtonInitialHTML();
4726          switch (submitting.code) {
4727            case Checkout.ErrorTypes.REBILLY_ERROR:
4728            case Checkout.ErrorTypes.SERVER_ERROR:
4729            case Checkout.ErrorTypes.UNHANDLED_SERVER_RESPONSE:
4730            case Checkout.ErrorTypes.EXCEEDED_MAX_RETRIES: {
4731              submitNotification.setStatus(`${this.rebillyCheckoutTexts.failedToSubmit}`, `${this.rebillyCheckoutTexts.retryAgainInFewSeconds}`, submitting.message ? submitting.message : "");
4732              break;
4733            }
4734            case Checkout.ErrorTypes.THREEDS_DECLINED_ERROR: {
4735              submitNotification.setStatus(`${this.rebillyCheckoutTexts.failedToSubmit}`, `${this.rebillyCheckoutTexts.transactionDeclined}`);
4736              break;
4737            }
4738            case Checkout.ErrorTypes.SERVER_ERROR_WITH_MESSAGE: {
4739              submitNotification.setStatus(`${this.rebillyCheckoutTexts.failedToSubmit}`, submitting.message);
4740              break;
4741            }
4742            case Checkout.ErrorTypes.THREEDS_DECLINED_CUSTOM_ERROR: {
4743              submitNotification.setStatus(`${this.rebillyCheckoutTexts.failedToSubmit}`, submitting.message);
4744              break;
4745            }
4746          }
4747          break;
4748        }
4749      }
4750    }).subscribe(() => {
4751    });
4752  }
4753  validateStep(step) {
4754    const currentStep = Checkout.store.checkout.step.get();
4755    const currentFormStructure = this.FORM_STRUCTURE_BY_TOTAL_STEPS[this.totalSteps][currentStep];
4756    const errors = currentFormStructure.reduce((acc, formName) => {
4757      Checkout.store.showAllErrors[formName].set(true);
4758      const error = Checkout.computed.errorsByName[formName].get();
4759      if (Checkout.utils.hasErrors(error)) {
4760        acc.push(error);
4761      }
4762      return acc;
4763    }, []);
4764    return errors.length == 0;
4765  }
4766  listenAndUpdateCheckoutErrors() {
4767    Object.entries(Checkout.computed.errorsByName).forEach(([name, computed3]) => {
4768      computed3.subscribe((error) => {
4769        Object.values(Checkout.CheckoutStates).forEach((mode) => {
4770          let formStructure = [];
4771          let currentErrorElement = null;
4772          if (mode == "guest" && this.totalSteps != 1) {
4773            const currentStep = Checkout.store.checkout.step.get();
4774            let currentStepWithError = currentStep;
4775            currentErrorElement = this.element.querySelector('.elMultiStepBody[data-step-state="active"]').querySelector(".checkout-general-errors-wrapper");
4776            const stepForField = this.FORM_BY_STEP[this.totalSteps][name];
4777            if (stepForField != void 0) {
4778              if (Checkout.utils.hasErrors(error) && stepForField < currentStep) {
4779                Checkout.store.checkout.step.set(stepForField);
4780                scrollToFirstVisibleError();
4781              }
4782              currentErrorElement = this.element.querySelector(`.elMultiStepBody[data-step-number="${stepForField + 1}"]`).querySelector(".checkout-general-errors-wrapper");
4783              currentStepWithError = stepForField;
4784            }
4785            formStructure = this.FORM_STRUCTURE_BY_TOTAL_STEPS[this.totalSteps][currentStepWithError];
4786          } else {
4787            formStructure = ["shippingOption", "products", "tos", "payment", "billing", "summary"];
4788            currentErrorElement = this.element.querySelector(`[data-wrapper-checkout-state="${mode}"]`).querySelector(".checkout-general-errors-wrapper");
4789          }
4790          const errors = formStructure.reduce((acc, formName) => {
4791            const error2 = Checkout.computed.errorsByName[formName].get();
4792            if (Checkout.utils.hasErrors(error2)) {
4793              acc.push({ name: formName, errors: error2 });
4794            }
4795            return acc;
4796          }, []);
4797          if (!errors || errors?.length == 0) {
4798            currentErrorElement.classList.add("elHide");
4799          } else {
4800            const error2 = errors[0];
4801            if (error2.errors?.globalErrors?.[0]?.message) {
4802              const errorMessage = error2.errors.globalErrors[0].message;
4803              currentErrorElement.querySelector("span").innerHTML = errorMessage;
4804              currentErrorElement.classList.remove("elHide");
4805            } else {
4806              currentErrorElement.classList.add("elHide");
4807            }
4808          }
4809        });
4810      });
4811    });
4812  }
4813  getCart() {
4814    return globalThis.Checkout.computed.checkoutCart.get();
4815  }
4816  submitOTO(redirectOverride) {
4817    return new Promise((resolve) => {
4818      let settled = false;
4819      let unlisten;
4820      const finish = (result) => {
4821        if (settled) return;
4822        settled = true;
4823        unlisten && unlisten();
4824        resolve(result);
4825      };
4826      unlisten = globalThis.Checkout.store.submitting.listen((submitting) => {
4827        if (submitting.state === globalThis.Checkout.SubmittingStates.DONE) {
4828          finish({ ok: true });
4829        } else if (submitting.state === globalThis.Checkout.SubmittingStates.ERROR) {
4830          finish({ ok: false, actionable: submitting.actionable !== false, message: submitting.message });
4831        }
4832      });
4833      CheckoutSubmit.submitFromButtonClick(this.element, () => scrollToFirstVisibleError(), redirectOverride);
4834      if (globalThis.Checkout.store.state.get() !== globalThis.Checkout.StoreStates.SUBMITTING) {
4835        finish({ ok: false, actionable: true });
4836      }
4837    });
4838  }
4839};
4840registerComponent("RebillyCheckout", RebillyCheckout);
4841window["RebillyCheckout"] = RebillyCheckout;
4842//# sourceMappingURL=rebilly-checkout-FZAQEHSF.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.