/* Help4 Builder Suite 1.3.316 | build e0bf22c8bac2c863f033078c97ae2049d42f0eab2d66bf4421fc207d92da6717 */
(function () {
  'use strict';

  var storageKey = 'h4bsProductCompare';
  var config = window.h4bsCommerceConfig || {};
  var labels = config.labels || {};
  var maxItems = parseInt(config.maxCompareItems, 10);

  if (!Number.isFinite(maxItems) || maxItems < 1) {
    maxItems = 4;
  }

  function label(key, fallback) {
    return labels[key] || fallback;
  }

  function readItems() {
    try {
      var parsed = JSON.parse(window.localStorage.getItem(storageKey) || '[]');
      return Array.isArray(parsed) ? parsed : [];
    } catch (error) {
      return [];
    }
  }

  function writeItems(items) {
    try {
      window.localStorage.setItem(storageKey, JSON.stringify(items.slice(0, maxItems)));
    } catch (error) {
      return;
    }
  }

  function escapeText(value) {
    return String(value || '').replace(/[&<>"']/g, function (character) {
      return {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;',
      }[character];
    });
  }

  function announce(message) {
    var status = document.querySelector('[data-h4bs-compare-status]');

    if (status) {
      status.textContent = message;
    }
  }

  function createCheckoutKey() {
    if (window.crypto && typeof window.crypto.randomUUID === 'function') {
      return window.crypto.randomUUID();
    }

    return 'h4bs-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 14);
  }

  function checkoutField(data, name) {
    return String(data.get(name) || '').trim();
  }

  function customerFieldValue(form, key) {
    var controls = Array.from(form.querySelectorAll('[data-h4bs-customer-field="' + key + '"]'));
    if (!controls.length) {
      var calculated = form.querySelector('[data-h4bs-calculated-field="' + key + '"]');
      return calculated ? String(calculated.dataset.calculationValue || '') : '';
    }
    var first = controls[0];
    if (first.type === 'radio') {
      var selectedRadio = controls.find(function (control) { return control.checked; });
      return selectedRadio ? String(selectedRadio.value || '') : '';
    }
    if (first.type === 'checkbox') {
      return first.checked ? '1' : '';
    }
    if (first.multiple) {
      return Array.from(first.selectedOptions).map(function (option) { return String(option.value || ''); });
    }
    return String(first.value || '').trim();
  }

  function collectCustomerFields(form) {
    var values = {};
    form.querySelectorAll('[data-h4bs-customer-field]').forEach(function (control) {
      var wrapper = control.closest('[data-h4bs-customer-field-wrap]');
      var key = String(control.getAttribute('data-h4bs-customer-field') || '');
      if (!key || (wrapper && wrapper.hidden) || Object.prototype.hasOwnProperty.call(values, key)) {
        return;
      }
      var value = customerFieldValue(form, key);
      values[key] = value;
    });
    return values;
  }

  function calculateCustomerFormula(formula, values) {
    var source = String(formula || '').trim();
    var offset = 0;
    var tokens = 0;

    function fail(code) {
      var error = new Error(code);
      error.code = code;
      throw error;
    }
    function skipWhitespace() {
      while (offset < source.length && /\s/.test(source.charAt(offset))) {
        offset += 1;
      }
    }
    function operator(operators) {
      skipWhitespace();
      var character = source.charAt(offset);
      return operators.indexOf(character) !== -1 ? character : '';
    }
    function primary(depth) {
      if (depth > 24 || ++tokens > 200) fail('complex');
      skipWhitespace();
      var character = source.charAt(offset);
      if (character === '(') {
        offset += 1;
        var grouped = expression(depth + 1);
        skipWhitespace();
        if (source.charAt(offset) !== ')') fail('syntax');
        offset += 1;
        return grouped;
      }
      if (character === '{') {
        var closing = source.indexOf('}', offset + 1);
        if (closing === -1) fail('syntax');
        var key = source.slice(offset + 1, closing);
        if (!/^[a-z0-9_]+$/.test(key)) fail('syntax');
        offset = closing + 1;
        if (!Object.prototype.hasOwnProperty.call(values, key)) fail('missing');
        var raw = values[key];
        if (raw === '' || raw === null || raw === false) return 0;
        if (raw === true) return 1;
        var referenced = Number(raw);
        if (!Number.isFinite(referenced)) fail('nonnumeric');
        return referenced;
      }
      var numberMatch = source.slice(offset).match(/^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/);
      if (numberMatch) {
        offset += numberMatch[0].length;
        var number = Number(numberMatch[0]);
        if (!Number.isFinite(number)) fail('finite');
        return number;
      }
      var functionMatch = source.slice(offset).match(/^([a-z][a-z0-9_]*)/);
      if (functionMatch) {
        var functionName = functionMatch[1];
        if (['abs', 'ceil', 'floor', 'round', 'min', 'max'].indexOf(functionName) === -1) fail('function');
        offset += functionMatch[0].length;
        skipWhitespace();
        if (source.charAt(offset) !== '(') fail('syntax');
        offset += 1;
        var args = [];
        while (true) {
          args.push(expression(depth + 1));
          skipWhitespace();
          if (source.charAt(offset) === ',') {
            offset += 1;
            continue;
          }
          if (source.charAt(offset) !== ')') fail('syntax');
          offset += 1;
          break;
        }
        if ((functionName === 'round' && (args.length < 1 || args.length > 2))
          || (['abs', 'ceil', 'floor'].indexOf(functionName) !== -1 && args.length !== 1)
          || (['min', 'max'].indexOf(functionName) !== -1 && args.length !== 2)) fail('arguments');
        if (functionName === 'abs') return Math.abs(args[0]);
        if (functionName === 'ceil') return Math.ceil(args[0]);
        if (functionName === 'floor') return Math.floor(args[0]);
        if (functionName === 'min') return Math.min(args[0], args[1]);
        if (functionName === 'max') return Math.max(args[0], args[1]);
        var precision = Math.max(-6, Math.min(6, Math.trunc(args[1] || 0)));
        var factor = Math.pow(10, precision);
        var scaled = args[0] * factor;
        var rounded = scaled < 0
          ? -Math.round(-scaled + Number.EPSILON)
          : Math.round(scaled + Number.EPSILON);
        return rounded / factor;
      }
      fail('syntax');
    }
    function unary(depth) {
      if (depth > 24) fail('complex');
      var unaryOperator = operator(['+', '-']);
      if (!unaryOperator) return primary(depth + 1);
      offset += 1;
      var result = unary(depth + 1);
      return unaryOperator === '-' ? -result : result;
    }
    function term(depth) {
      var left = unary(depth + 1);
      while (true) {
        var termOperator = operator(['*', '/']);
        if (!termOperator) return left;
        offset += 1;
        var right = unary(depth + 1);
        if (termOperator === '/' && Math.abs(right) < 0.000000000001) fail('division');
        left = termOperator === '*' ? left * right : left / right;
        if (!Number.isFinite(left)) fail('finite');
      }
    }
    function expression(depth) {
      var left = term(depth + 1);
      while (true) {
        var expressionOperator = operator(['+', '-']);
        if (!expressionOperator) return left;
        offset += 1;
        var right = term(depth + 1);
        left = expressionOperator === '+' ? left + right : left - right;
        if (!Number.isFinite(left)) fail('finite');
      }
    }

    if (!source || source.length > 500) fail('syntax');
    var result = expression(0);
    skipWhitespace();
    if (offset !== source.length || !Number.isFinite(result)) fail('syntax');
    return result;
  }

  function updateCustomerFieldCalculations(form) {
    var available = collectCustomerFields(form);
    var pending = Array.from(form.querySelectorAll('[data-h4bs-calculated-field]')).filter(function (output) {
      return output.dataset.calculationSensitive !== '1';
    });
    while (pending.length) {
      var progress = false;
      pending = pending.filter(function (output) {
        var key = String(output.getAttribute('data-h4bs-calculated-field') || '');
        try {
          var result = calculateCustomerFormula(String(output.dataset.calculationFormula || ''), available);
          var precision = Math.max(0, Math.min(6, parseInt(output.dataset.calculationPrecision || '2', 10)));
          result = Number(result.toFixed(precision));
          available[key] = result;
          output.dataset.calculationValue = String(result);
          output.textContent = String(output.dataset.calculationPrefix || '') + result.toFixed(precision) + String(output.dataset.calculationSuffix || '');
          progress = true;
          return false;
        } catch (error) {
          if (error && error.code === 'missing') return true;
          output.dataset.calculationValue = '';
          output.textContent = label('fieldCalculationUnavailable', 'Calculation unavailable');
          return false;
        }
      });
      if (!progress && pending.length) {
        pending.forEach(function (output) {
          output.dataset.calculationValue = '';
          output.textContent = label('fieldCalculationWaiting', 'Waiting for numeric values');
        });
        break;
      }
    }
  }

  function customerFieldConditionExpected(form, expected) {
    var token = String(expected || '').trim().match(/^\{([a-z0-9_]{1,64})\}$/);
    return token ? customerFieldValue(form, token[1]) : expected;
  }

  function customerFieldConditionMatches(actual, operator, expected) {
    var actualText = Array.isArray(actual) ? actual.join('|') : String(actual || '');
    var expectedText = Array.isArray(expected) ? expected.join('|') : String(expected || '');
    var expectedOptions = expectedText.split(/[|,]+/).map(function (value) { return value.trim(); }).filter(Boolean);
    if (operator === 'not_equals') {
      return actualText !== expectedText;
    }
    if (operator === 'contains') {
      return actualText.indexOf(expectedText) !== -1;
    }
    if (operator === 'not_contains') {
      return actualText.indexOf(expectedText) === -1;
    }
    if (operator === 'empty') {
      return actualText === '';
    }
    if (operator === 'not_empty') {
      return actualText !== '';
    }
    if (operator === 'greater_than') {
      return actualText !== '' && Number.isFinite(Number(actualText)) && Number(actualText) > Number(expectedText);
    }
    if (operator === 'less_than') {
      return actualText !== '' && Number.isFinite(Number(actualText)) && Number(actualText) < Number(expectedText);
    }
    if (operator === 'one_of') {
      return expectedOptions.indexOf(actualText) !== -1;
    }
    if (operator === 'not_one_of') {
      return expectedOptions.indexOf(actualText) === -1;
    }
    return actualText === expectedText;
  }

  function customerFieldConditions(wrapper) {
    try {
      var parsed = JSON.parse(String(wrapper.dataset.conditions || '[]'));
      return Array.isArray(parsed) ? parsed.filter(function (condition) {
        return condition && typeof condition === 'object' && String(condition.field || '');
      }) : [];
    } catch (error) {
      return [];
    }
  }

  function customerFieldAudienceMatches(form, wrapper) {
    var countries = String(wrapper.dataset.targetCountries || '').split(',').map(function (country) { return country.trim().toUpperCase(); }).filter(Boolean);
    var countryControl = form.elements.namedItem('country');
    if (countries.length && countryControl && countries.indexOf(String(countryControl.value || '').toUpperCase()) === -1) {
      return false;
    }
    var quantityControl = form.elements.namedItem('quantity');
    var unitPrice = Number(form.dataset.unitPrice || 0);
    var subtotal = unitPrice * Number(quantityControl ? quantityControl.value : 1);
    var minimum = wrapper.dataset.minSubtotal === '' ? null : Number(wrapper.dataset.minSubtotal);
    var maximum = wrapper.dataset.maxSubtotal === '' ? null : Number(wrapper.dataset.maxSubtotal);
    if (Number.isFinite(subtotal) && ((minimum !== null && subtotal < minimum) || (maximum !== null && subtotal > maximum))) {
      return false;
    }
    return true;
  }

  function updateCustomerFieldSelectionValidity(form) {
    form.querySelectorAll('select[data-h4bs-customer-field][multiple]').forEach(function (control) {
      var count = control.selectedOptions.length;
      var minimum = parseInt(control.dataset.minSelections || '0', 10);
      var maximum = parseInt(control.dataset.maxSelections || '0', 10);
      var message = '';
      if (minimum > 0 && count < minimum) {
        message = label('fieldSelectionMinimum', 'Choose at least %d options.').replace('%d', String(minimum));
      } else if (maximum > 0 && count > maximum) {
        message = label('fieldSelectionMaximum', 'Choose no more than %d options.').replace('%d', String(maximum));
      }
      control.setCustomValidity(message);
    });
  }

  function updateCustomerFieldRangeOutputs(form) {
    form.querySelectorAll('[data-h4bs-range-input]').forEach(function (control) {
      var output = control.parentElement ? control.parentElement.querySelector('[data-h4bs-range-output]') : null;
      if (output) {
        output.value = String(control.value || '');
        output.textContent = String(control.value || '');
      }
    });
  }

  function updateCustomerFieldConditions(form) {
    updateCustomerFieldCalculations(form);
    form.querySelectorAll('[data-h4bs-customer-field-wrap]').forEach(function (wrapper) {
      var conditions = customerFieldConditions(wrapper);
      var matches = conditions.map(function (condition) {
        return customerFieldConditionMatches(
          customerFieldValue(form, String(condition.field || '')),
          String(condition.operator || 'equals'),
          customerFieldConditionExpected(form, condition.value)
        );
      });
      var visible = !conditions.length || (String(wrapper.dataset.conditionMatch || 'all') === 'any'
        ? matches.indexOf(true) !== -1
        : matches.indexOf(false) === -1);
      visible = visible && customerFieldAudienceMatches(form, wrapper);
      wrapper.hidden = !visible;
      wrapper.querySelectorAll('input, select, textarea').forEach(function (control) {
        control.disabled = !visible;
        if (wrapper.dataset.required === '1' && control.hasAttribute('data-h4bs-customer-field')) {
          control.required = visible;
        }
      });
    });
    updateCustomerFieldSelectionValidity(form);
    updateCustomerFieldRangeOutputs(form);
    updateCustomerFieldCalculations(form);
  }

  function initializeCustomerFields() {
    document.querySelectorAll('[data-h4bs-checkout], [data-h4bs-customer-fields-form]').forEach(function (form) {
      updateCustomerFieldConditions(form);
      form.addEventListener('change', function () {
        updateCustomerFieldConditions(form);
      });
      form.addEventListener('input', function () {
        updateCustomerFieldConditions(form);
      });
    });
  }

  function formatMoney(value, currency) {
    var amount = Number(value || 0);
    try {
      return new Intl.NumberFormat(undefined, {
        style: 'currency',
        currency: currency || 'USD',
      }).format(amount);
    } catch (error) {
      return (currency || 'USD') + ' ' + amount.toFixed(2);
    }
  }

  function appendCheckoutSummaryRow(summary, name, value, className) {
    var term = document.createElement('dt');
    var detail = document.createElement('dd');
    term.textContent = name;
    detail.textContent = value;
    if (className) {
      term.className = className;
      detail.className = className;
    }
    summary.appendChild(term);
    summary.appendChild(detail);
  }

  function renderCheckoutSummary(summary, response) {
    var currency = String(response.currency || 'USD');
    var discount = Number(response.discount_total || 0);
    summary.replaceChildren();
    appendCheckoutSummaryRow(summary, label('subtotal', 'Subtotal'), formatMoney(response.subtotal, currency));
    if (discount > 0) {
      appendCheckoutSummaryRow(summary, label('discount', 'Discount'), '-' + formatMoney(discount, currency), 'h4bs-checkout-summary-discount');
    }
    appendCheckoutSummaryRow(summary, label('shipping', 'Shipping'), formatMoney(response.shipping_total, currency));
    appendCheckoutSummaryRow(summary, label('tax', 'Tax'), formatMoney(response.tax_total, currency));
    appendCheckoutSummaryRow(summary, label('total', 'Total'), formatMoney(response.total, currency), 'h4bs-checkout-summary-total');
    if (response.order_number) {
      appendCheckoutSummaryRow(summary, label('order', 'Order'), String(response.order_number));
    }
    summary.hidden = false;
  }

  function checkoutRedirectUrl(response) {
    var router = response && typeof response.processor_router === 'object' ? response.processor_router : {};
    var candidate = String(router.checkout_url || router.redirect_url || response.checkout_url || response.redirect_url || '');
    if (!candidate) {
      return '';
    }
    try {
      var url = new URL(candidate, window.location.href);
      return url.protocol === 'https:' || url.protocol === 'http:' ? url.href : '';
    } catch (error) {
      return '';
    }
  }

  function submitCheckout(form) {
    var endpoint = String(config.checkoutEndpoint || '');
    var status = form.querySelector('[data-h4bs-checkout-status]');
    var summary = form.querySelector('[data-h4bs-checkout-summary]');
    var submit = form.querySelector('[type="submit"]');
    if (!endpoint || !status || !summary || !submit) {
      return;
    }

    var data = new FormData(form);
    var quantityEnabled = String(form.dataset.quantityEnabled || '1') !== '0';
    var quantity = quantityEnabled ? Number(data.get('quantity') || 1) : 1;
    if (!Number.isFinite(quantity) || quantity <= 0) {
      status.textContent = label('checkoutQuantityInvalid', 'Enter a valid quantity.');
      return;
    }

    if (!form.dataset.checkoutKey) {
      form.dataset.checkoutKey = createCheckoutKey();
    }
    if (!form.dataset.lineKey) {
      form.dataset.lineKey = createCheckoutKey();
    }
    var shipping = {
      first_name: checkoutField(data, 'first_name'),
      last_name: checkoutField(data, 'last_name'),
      address_1: checkoutField(data, 'address_1'),
      address_2: checkoutField(data, 'address_2'),
      city: checkoutField(data, 'city'),
      state: checkoutField(data, 'state'),
      postcode: checkoutField(data, 'postcode'),
      country: checkoutField(data, 'country').toUpperCase(),
      phone: checkoutField(data, 'phone'),
    };
    var request = {
      checkout_key: form.dataset.checkoutKey,
      customer_email: checkoutField(data, 'email'),
      customer_first_name: shipping.first_name,
      customer_last_name: shipping.last_name,
      currency: String(form.dataset.currency || 'USD').toUpperCase(),
      gateway: checkoutField(data, 'gateway'),
      promotion_code: checkoutField(data, 'promotion_code').toUpperCase(),
      customer_fields: collectCustomerFields(form),
      shipping: shipping,
      billing: shipping,
      items: [{
        line_key: String(form.dataset.lineKey),
        product_id: Number(form.dataset.productId || 0),
        variant_id: Number(form.dataset.variantId || 0),
        qty: quantity,
      }],
    };
    var headers = {'Content-Type': 'application/json'};
    if (config.restNonce) {
      headers['X-WP-Nonce'] = String(config.restNonce);
    }

    submit.disabled = true;
    form.setAttribute('aria-busy', 'true');
    status.classList.remove('is-error', 'is-success');
    status.textContent = label('checkoutWorking', 'Processing checkout...');

    window.fetch(endpoint, {
      method: 'POST',
      credentials: 'same-origin',
      headers: headers,
      body: JSON.stringify(request),
    }).then(function (httpResponse) {
      return httpResponse.json().catch(function () {
        return {};
      }).then(function (body) {
        if (!httpResponse.ok) {
          var failure = new Error(String(body.message || label('checkoutFailed', 'Checkout could not be completed.')));
          failure.checkoutResponse = body;
          throw failure;
        }
        return body;
      });
    }).then(function (response) {
      renderCheckoutSummary(summary, response);
      if (String(response.status || '') === 'payment_failed') {
        status.classList.add('is-error');
        status.textContent = label('checkoutPaymentFailed', 'Payment could not be started. No inventory or promotion was held.');
        form.dataset.checkoutKey = '';
        return;
      }

      status.classList.add('is-success');
      status.textContent = response.order_number
        ? label('checkoutAccepted', 'Checkout accepted for order') + ' ' + String(response.order_number) + '.'
        : label('checkoutAcceptedGeneric', 'Checkout accepted.');
      var redirectUrl = checkoutRedirectUrl(response);
      if (redirectUrl) {
        window.location.assign(redirectUrl);
      }
    }).catch(function (error) {
      status.classList.add('is-error');
      status.textContent = String(error && error.message ? error.message : label('checkoutFailed', 'Checkout could not be completed.'));
      if (!error.checkoutResponse || error.checkoutResponse.code !== 'h4bs_checkout_replay') {
        form.dataset.checkoutKey = '';
      }
    }).finally(function () {
      submit.disabled = false;
      form.removeAttribute('aria-busy');
    });
  }

  function updateTray() {
    var items = readItems();
    var tray = document.querySelector('[data-h4bs-compare-tray]');
    var list = document.querySelector('[data-h4bs-compare-list]');
    var countNodes = document.querySelectorAll('[data-h4bs-compare-count]');

    countNodes.forEach(function (node) {
      node.textContent = String(items.length);
    });
    document.dispatchEvent(new CustomEvent('h4bs:commerce-count', {
      detail: {
        source: 'compare',
        count: items.length,
      },
    }));

    if (!tray || !list) {
      return;
    }

    tray.hidden = items.length === 0;
    list.innerHTML = items.map(function (item) {
      return '<article class="h4bs-product-compare-item">'
        + '<strong>' + escapeText(item.name) + '</strong>'
        + '<span>' + escapeText(item.price) + '</span>'
        + '<small>' + escapeText(item.type) + '</small>'
        + '<button type="button" data-h4bs-compare-remove="' + escapeText(item.id) + '">'
        + escapeText(label('remove', 'Remove'))
        + '</button>'
        + '</article>';
    }).join('');

    document.querySelectorAll('[data-h4bs-compare-product]').forEach(function (button) {
      var productId = button.getAttribute('data-h4bs-compare-product') || '';
      var selected = items.some(function (item) {
        return item.id === productId;
      });
      button.classList.toggle('is-selected', selected);
      button.setAttribute('aria-pressed', selected ? 'true' : 'false');
      button.textContent = selected ? label('compared', 'Compared') : label('compare', 'Compare');
    });
  }

  document.addEventListener('click', function (event) {
    var compareButton = event.target.closest('[data-h4bs-compare-product]');
    if (compareButton) {
      var productId = compareButton.getAttribute('data-h4bs-compare-product') || '';
      if (!productId) {
        return;
      }
      var items = readItems();
      var existingIndex = items.findIndex(function (item) {
        return item.id === productId;
      });
      if (existingIndex >= 0) {
        items.splice(existingIndex, 1);
      } else {
        items.unshift({
          id: productId,
          name: compareButton.getAttribute('data-h4bs-compare-name') || '',
          price: compareButton.getAttribute('data-h4bs-compare-price') || '',
          type: compareButton.getAttribute('data-h4bs-compare-type') || '',
        });
      }
      writeItems(items);
      updateTray();
      announce(label('compareListUpdated', 'Compare list updated.'));
      return;
    }

    var removeButton = event.target.closest('[data-h4bs-compare-remove]');
    if (removeButton) {
      var removeId = removeButton.getAttribute('data-h4bs-compare-remove') || '';
      writeItems(readItems().filter(function (item) {
        return item.id !== removeId;
      }));
      updateTray();
      announce(label('compareListUpdated', 'Compare list updated.'));
      return;
    }

    if (event.target.closest('[data-h4bs-compare-clear]')) {
      writeItems([]);
      updateTray();
      announce(label('compareListCleared', 'Compare list cleared.'));
      return;
    }

    if (event.target.closest('[data-h4bs-compare-open]')) {
      var tray = document.querySelector('[data-h4bs-compare-tray]');
      if (tray) {
        tray.hidden = false;
        tray.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        tray.focus({ preventScroll: true });
        announce(label('compareTrayOpened', 'Compare tray opened.'));
      }
    }
  });

  document.addEventListener('submit', function (event) {
    var form = event.target.closest ? event.target.closest('[data-h4bs-checkout]') : null;
    if (!form) {
      return;
    }
    event.preventDefault();
    if (typeof form.reportValidity === 'function' && !form.reportValidity()) {
      return;
    }
    submitCheckout(form);
  });

  function initializeCommerce() {
    updateTray();
    initializeCustomerFields();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initializeCommerce);
  } else {
    initializeCommerce();
  }
}());
