@sezzle/sezzle-react-widget 3.1.7 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -395,6 +395,19 @@ function getCurrency(priceString) {
395
395
  return currencyMatch ? currencyMatch[0] : defaultCurrency;
396
396
  }
397
397
 
398
+ /**
399
+ * Renders a numeric value with the decimal separator appropriate for the
400
+ * language: a period for English, a comma for French/Spanish. Only the decimal
401
+ * separator is swapped; no grouping is applied.
402
+ * @param value - number or numeric string (e.g. an APR like 9.99)
403
+ * @param lang - Language code (en, fr, es)
404
+ * @return string
405
+ */
406
+ function formatNumberForLocale(value, lang) {
407
+ var str = String(value);
408
+ return lang === 'fr' || lang === 'es' ? str.replace('.', ',') : str;
409
+ }
410
+
398
411
  /**
399
412
  * Returns the translation object for the specified language
400
413
  * @param currentLang - Language code (en, fr, es)
@@ -409,6 +422,218 @@ function getTranslations(currentLang) {
409
422
  return translationsMap[currentLang];
410
423
  }
411
424
 
425
+ function _toConsumableArray$1(r) { return _arrayWithoutHoles$1(r) || _iterableToArray$1(r) || _unsupportedIterableToArray$1(r) || _nonIterableSpread$1(); }
426
+ function _nonIterableSpread$1() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
427
+ function _iterableToArray$1(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
428
+ function _arrayWithoutHoles$1(r) { if (Array.isArray(r)) return _arrayLikeToArray$1(r); }
429
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$1(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
430
+ function _unsupportedIterableToArray$1(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$1(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0; } }
431
+ function _arrayLikeToArray$1(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
432
+ function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
433
+ function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
434
+ function _defineProperty$4(e, r, t) { return (r = _toPropertyKey$4(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
435
+ function _toPropertyKey$4(t) { var i = _toPrimitive$4(t, "string"); return "symbol" == _typeof$4(i) ? i : i + ""; }
436
+ function _toPrimitive$4(t, r) { if ("object" != _typeof$4(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof$4(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
437
+ function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
438
+ // Long-term (LT) product configuration.
439
+ //
440
+ // The widget supports long-term payment options whose defaults differ by
441
+ // lending partner. To make per-partner rollouts easy, each partner's complete
442
+ // set of LT defaults is bundled under a neutral alias ("a", "b", ...). The
443
+ // alias is deliberately non-branded so the lending partner is never exposed to
444
+ // merchants. An account manager guides the merchant on which alias to use based
445
+ // on their enrollment, so the merchant no longer has to set every LT field by
446
+ // hand. "a" is the default fallback preset.
447
+ //
448
+ // Every LT option follows a consistent contract: 0 (or unset) means "not set."
449
+ // To disable LT entirely, omit both `minPriceLT` and `LTgroup`.
450
+ //
451
+ // Units note: unlike the backend LT API (which uses cents), every LT value in
452
+ // this widget is expressed in whole currency units (dollars), matching the rest
453
+ // of this project's config — minPriceLT, maxPriceLT, and the termsToShow
454
+ // thresholds are all dollar amounts.
455
+
456
+ var DEFAULT_LT_GROUP = 'a';
457
+
458
+ // Recursively freeze an object and all nested objects/arrays. The presets below
459
+ // are shared, long-lived references that resolve* helpers hand out directly
460
+ // (e.g. resolveTermsToShow returns the preset's termsToShow, including its term
461
+ // arrays, by reference). Freezing makes any accidental downstream mutation
462
+ // (e.g. config.termsToShow.default.push(12)) throw instead of silently
463
+ // corrupting the preset for the lifetime of the page.
464
+ function deepFreeze(obj) {
465
+ for (var _i = 0, _Object$values = Object.values(obj); _i < _Object$values.length; _i++) {
466
+ var value = _Object$values[_i];
467
+ if (value && _typeof$4(value) === 'object' && !Object.isFrozen(value)) {
468
+ deepFreeze(value);
469
+ }
470
+ }
471
+ return Object.freeze(obj);
472
+ }
473
+
474
+ // Per-partner presets. Each preset is a COMPLETE set of LT defaults:
475
+ // minPriceLT – lowest price (inclusive) eligible for LT
476
+ // maxPriceLT – highest price (inclusive) eligible for LT
477
+ // minAPR – lowest APR offered; lower bound of the disclaimer APR range
478
+ // medianAPR – representative APR; drives per-card monthly payment + per-card APR display
479
+ // maxAPR – highest APR offered; upper bound of the disclaimer APR range
480
+ // termsToShow – price-threshold → term-length map (see termsToShow shape below)
481
+ //
482
+ // termsToShow shape: keys are price thresholds in dollars, values are arrays of
483
+ // term lengths in months. The `default` key handles prices below all
484
+ // thresholds. A price selects the array for the highest threshold it strictly
485
+ // exceeds, mirroring the previously hardcoded tiers.
486
+ var LT_GROUPS = deepFreeze({
487
+ // "a" is seeded from this project's prior production values
488
+ // (APR range 9.99–34.99, median 21.99, maxPriceLT 15000, and the original
489
+ // hardcoded term tiers).
490
+ a: {
491
+ minPriceLT: 150,
492
+ maxPriceLT: 15000,
493
+ minAPR: 9.99,
494
+ medianAPR: 21.99,
495
+ maxAPR: 34.99,
496
+ termsToShow: {
497
+ "default": [3, 6, 9],
498
+ 300: [6, 9, 12],
499
+ 500: [12, 18, 24],
500
+ 1000: [24, 36, 48]
501
+ }
502
+ },
503
+ b: {
504
+ minPriceLT: 400,
505
+ maxPriceLT: 8000,
506
+ minAPR: 24.99,
507
+ medianAPR: 29.99,
508
+ maxAPR: 35.99,
509
+ termsToShow: {
510
+ "default": [3, 6, 9],
511
+ 600: [6, 9, 12],
512
+ 800: [9, 12, 24],
513
+ 1000: [12, 24, 36]
514
+ }
515
+ }
516
+ });
517
+
518
+ // Resolve an LTgroup alias to its canonical (lowercased) preset key, or null
519
+ // when no alias is given. An unrecognized (non-empty) alias warns (listing the
520
+ // accepted values) and resolves to null so callers fall back to the default.
521
+ function normalizeGroup(alias) {
522
+ if (alias === undefined || alias === null || alias === '') return null;
523
+ var key = String(alias).toLowerCase();
524
+ if (LT_GROUPS[key]) return key;
525
+ console.warn("[Sezzle] Unknown LTgroup \"".concat(alias, "\". Accepted values: ").concat(Object.keys(LT_GROUPS).map(function (k) {
526
+ return "\"".concat(k, "\"");
527
+ }).join(', '), ". Falling back to \"").concat(DEFAULT_LT_GROUP, "\"."));
528
+ return null;
529
+ }
530
+
531
+ // True when `value` is a well-formed termsToShow map: an object whose values are
532
+ // non-empty arrays of positive numbers (months).
533
+ function isValidTermsToShow(value) {
534
+ if (!value || _typeof$4(value) !== 'object' || Array.isArray(value)) return false;
535
+ var entries = Object.values(value);
536
+ if (entries.length === 0) return false;
537
+ return entries.every(function (arr) {
538
+ return Array.isArray(arr) && arr.length > 0 && arr.every(function (n) {
539
+ return Number.isFinite(n) && n > 0;
540
+ });
541
+ });
542
+ }
543
+
544
+ // Resolve a merchant-supplied termsToShow against the group preset. Malformed
545
+ // input warns (with the expected shape) and falls back to the preset. A valid
546
+ // map missing the `default` key warns and borrows the preset's default so
547
+ // below-threshold lookups never fall through.
548
+ function resolveTermsToShow(provided, presetTerms) {
549
+ if (provided === undefined || provided === null) return presetTerms;
550
+ if (!isValidTermsToShow(provided)) {
551
+ console.warn('[Sezzle] Malformed termsToShow. Expected an object mapping price ' + 'thresholds (numbers, in dollars) to arrays of term lengths in months, ' + 'plus a "default" key for prices below all thresholds, e.g. ' + '{ default: [3, 6, 9], 500: [12, 18, 24] }. Falling back to the ' + 'LTgroup preset.');
552
+ return presetTerms;
553
+ }
554
+ if (!Array.isArray(provided["default"])) {
555
+ console.warn('[Sezzle] termsToShow is missing a "default" key for prices below all ' + "thresholds. Using the LTgroup preset's default.");
556
+ return _objectSpread$4(_objectSpread$4({}, provided), {}, {
557
+ "default": presetTerms["default"]
558
+ });
559
+ }
560
+ return provided;
561
+ }
562
+
563
+ // Pick an explicit prop when it is "set" (> 0), otherwise the preset value.
564
+ // A value of 0 is never a valid LT setting, so it is treated as "not set."
565
+ function pickPrice(value, fallback) {
566
+ return Number(value) > 0 ? Number(value) : fallback;
567
+ }
568
+
569
+ // Resolve the effective LT config from widget props.
570
+ //
571
+ // Every LT value defaults to a group preset, falling back to group "a" even
572
+ // when LT is off, so maxPriceLT / the APRs / termsToShow are never 0 or null
573
+ // downstream. `minPriceLT` is the sole exception: it is the render trigger
574
+ // (the widget shows LT only when minPriceLT > 0), so it stays 0 when LT is
575
+ // disabled — i.e. when neither LTgroup nor minPriceLT is provided.
576
+ function resolveLTConfig() {
577
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
578
+ var explicitGroup = normalizeGroup(props.LTgroup);
579
+ // Backcompat: pre-LTgroup configs enabled LT via minPriceLT alone. When that's
580
+ // set without an explicit LTgroup, auto-resolve to the default preset so the
581
+ // remaining LT defaults come from the original group "a".
582
+ var minPriceLTSet = Number(props.minPriceLT) > 0;
583
+ var group = explicitGroup || (minPriceLTSet ? DEFAULT_LT_GROUP : null);
584
+ var groupDefaults = LT_GROUPS[group] || LT_GROUPS[DEFAULT_LT_GROUP];
585
+ return {
586
+ minPriceLT: pickPrice(props.minPriceLT, group ? groupDefaults.minPriceLT : 0),
587
+ maxPriceLT: pickPrice(props.maxPriceLT, groupDefaults.maxPriceLT),
588
+ minAPR: pickPrice(props.minAPR, groupDefaults.minAPR),
589
+ medianAPR: pickPrice(props.medianAPR, groupDefaults.medianAPR),
590
+ maxAPR: pickPrice(props.maxAPR, groupDefaults.maxAPR),
591
+ termsToShow: resolveTermsToShow(props.termsToShow, groupDefaults.termsToShow)
592
+ };
593
+ }
594
+
595
+ // Select the term-length array for a price from a termsToShow map. Returns the
596
+ // array for the highest dollar threshold the price strictly exceeds, falling
597
+ // back to the `default` key. Returns undefined only when the map is missing /
598
+ // has no usable default — callers guard against that.
599
+ function selectTermsToShow(price, termsConfig) {
600
+ if (!termsConfig || _typeof$4(termsConfig) !== 'object') return undefined;
601
+ var thresholds = Object.keys(termsConfig).filter(function (k) {
602
+ return k !== 'default';
603
+ }).map(Number).filter(Number.isFinite).sort(function (a, b) {
604
+ return a - b;
605
+ });
606
+ var selected = termsConfig["default"];
607
+ var _iterator = _createForOfIteratorHelper(thresholds),
608
+ _step;
609
+ try {
610
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
611
+ var threshold = _step.value;
612
+ if (price > threshold) selected = termsConfig[threshold];
613
+ }
614
+ } catch (err) {
615
+ _iterator.e(err);
616
+ } finally {
617
+ _iterator.f();
618
+ }
619
+ return selected;
620
+ }
621
+
622
+ // Min and max term-month across the whole termsToShow map (the union of every
623
+ // term array, including `default`). Used for the disclaimer's term-length
624
+ // bounds. Returns null when no usable terms exist.
625
+ function termMonthBounds(termsConfig) {
626
+ if (!termsConfig || _typeof$4(termsConfig) !== 'object') return null;
627
+ var months = Object.values(termsConfig).filter(Array.isArray).flat().filter(function (n) {
628
+ return Number.isFinite(n);
629
+ });
630
+ if (months.length === 0) return null;
631
+ return {
632
+ min: Math.min.apply(Math, _toConsumableArray$1(months)),
633
+ max: Math.max.apply(Math, _toConsumableArray$1(months))
634
+ };
635
+ }
636
+
412
637
  var PI5_MIN_PRICE = 50;
413
638
  function isProductEligibleLT(priceText, minPriceLT, maxPriceLT) {
414
639
  if (!minPriceLT) return false;
@@ -432,18 +657,6 @@ function isInputAmountValid(priceText, minPrice, maxPrice, minPriceLT, maxPriceL
432
657
  var upper = minPriceLT > 0 ? Math.max(maxPrice, maxPriceLT || 0) : maxPrice;
433
658
  return price >= minPrice && price <= upper;
434
659
  }
435
- function termsToShow(price) {
436
- switch (true) {
437
- case price > 1000:
438
- return [24, 36, 48];
439
- case price > 500:
440
- return [12, 18, 24];
441
- case price > 300:
442
- return [6, 9, 12];
443
- default:
444
- return [3, 6, 9];
445
- }
446
- }
447
660
  function addDelimiters(priceString) {
448
661
  var parsedPrice = Number(priceString).toFixed(2);
449
662
  if (parsedPrice.length > 6) {
@@ -463,12 +676,24 @@ function calculateMonthlyWithInterest(priceText, term, APR) {
463
676
  return price / term;
464
677
  }
465
678
  }
466
- function getFormattedPrice(price, numberOfPayments, minPriceLT, maxPriceLT, bestAPR) {
679
+ function getFormattedPrice(price, numberOfPayments, minPriceLT, maxPriceLT, medianAPR, termsConfig) {
467
680
  var priceString = parsePriceString(price);
468
681
  var priceReplacer = parsePrice(price);
469
682
  var formatter = price.replace(priceString, '{price}');
470
- var terms = termsToShow(priceReplacer);
471
- var sezzleInstallmentPrice = isProductEligibleLT(priceString, minPriceLT, maxPriceLT) ? calculateMonthlyWithInterest(priceString, terms[terms.length - 1], bestAPR) : priceReplacer / numberOfPayments;
683
+ var sezzleInstallmentPrice;
684
+ if (isProductEligibleLT(priceString, minPriceLT, maxPriceLT)) {
685
+ var terms = selectTermsToShow(priceReplacer, termsConfig);
686
+ // Defensive guard: when LT-eligible but no terms match (e.g. a malformed
687
+ // termsToShow that slipped past validation), fall back to the bi-weekly
688
+ // installment price rather than producing NaN.
689
+ if (Array.isArray(terms) && terms.length > 0) {
690
+ sezzleInstallmentPrice = calculateMonthlyWithInterest(priceString, terms[terms.length - 1], medianAPR);
691
+ } else {
692
+ sezzleInstallmentPrice = priceReplacer / numberOfPayments;
693
+ }
694
+ } else {
695
+ sezzleInstallmentPrice = priceReplacer / numberOfPayments;
696
+ }
472
697
  var sezzleInstallmentFormattedPrice = formatter.replace('{price}', sezzleInstallmentPrice.toFixed(2));
473
698
  return sezzleInstallmentFormattedPrice;
474
699
  }
@@ -514,10 +739,6 @@ var CAROUSEL_MAX_TAB = 3;
514
739
  var INPUT_DEBOUNCE_DELAY_MS = 150;
515
740
  var CURRENCY_REGEX_GLOBAL = /[$€£₤₹]/g;
516
741
  var SANITIZE_REGEX = /[^0-9,.$€£₤₹]/g;
517
- var LT_APR_MIN = 9.99;
518
- var LT_APR_MAX = 34.99;
519
- var LT_TERM_MIN = 3;
520
- var LT_TERM_MAX = 48;
521
742
  function computeEligibility(priceString, opts) {
522
743
  return {
523
744
  pi4: isProductEligiblePI4(priceString, opts.minPrice, opts.maxPrice),
@@ -528,10 +749,13 @@ function computeEligibility(priceString, opts) {
528
749
  function formatLTAmount(currency, value) {
529
750
  return currency + addDelimiters(value);
530
751
  }
531
- function generateBiweeklyCard(numberOfPayments, currency, priceString, minPriceLT, maxPriceLT, bestAPR, translations) {
752
+ function generateBiweeklyCard(numberOfPayments, currency, priceString, translations) {
532
753
  var classModifier = numberOfPayments === 4 ? 'fourth' : 'fifth';
533
754
  var dashWidth = numberOfPayments === 4 ? 30 : 22;
534
- var installmentPrice = getFormattedPrice(currency + priceString, numberOfPayments, minPriceLT, maxPriceLT, bestAPR);
755
+ // Biweekly cards always show the bi-weekly installment (price / numberOfPayments),
756
+ // never the long-term monthly amount. Passing minPriceLT/maxPriceLT = 0 forces
757
+ // getFormattedPrice down the non-LT branch even for LT-eligible prices.
758
+ var installmentPrice = getFormattedPrice(currency + priceString, numberOfPayments, 0, 0, 0, null);
535
759
  var pillLabel = numberOfPayments === 5 ? "".concat(translations.MultiPlanpayIn, " 5 <sup>TM</sup>") : "".concat(translations.MultiPlanpayIn, " ").concat(numberOfPayments);
536
760
  var installments = [];
537
761
  for (var i = 0; i < numberOfPayments; i++) {
@@ -543,30 +767,31 @@ function generateBiweeklyCard(numberOfPayments, currency, priceString, minPriceL
543
767
  }
544
768
  return "\n <div class='payment-card ".concat(numberOfPayments, "-pay-installment-card'>\n <div class='plan-summary'>\n <div class='purple'>\n <div class='left'>\n <span class='price ").concat(numberOfPayments, "-pay-installment'>").concat(installmentPrice, "</span>\n <span class='due'>").concat(translations.today, "</span>\n </div>\n <div class='right'>\n <span class='pill'>").concat(pillLabel, "</span>\n </div>\n </div>\n <div class='grey'>\n <span class=\"").concat(numberOfPayments, "-pay-installment\">").concat(installmentPrice, "</span> ").concat(translations.MultiPlanevery2Weeks, "\n </div>\n </div>\n <div class='payment-breakdown'>\n ").concat(installments.join(''), "\n </div>\n </div>\n ");
545
769
  }
546
- function generateMonthlyCard(months, currency, priceString, bestAPR, translations) {
547
- var monthly = calculateMonthlyWithInterest(priceString, months, bestAPR);
770
+ function generateMonthlyCard(months, currency, priceString, medianAPR, translations, lang) {
771
+ var monthly = calculateMonthlyWithInterest(priceString, months, medianAPR);
548
772
  var total = monthly * months;
549
773
  var interest = total - Number(priceString);
550
- return "\n <div class='payment-card monthly-installment-card' data-months='".concat(months, "'>\n <div class='plan-summary'>\n <div class='purple'>\n <div class='left'>\n <span class='price monthly-amount' data-months='").concat(months, "'>").concat(formatLTAmount(currency, monthly), "</span>\n <span class='due' aria-label='").concat(translations.LTperMonth, "'>\n <span aria-hidden='true'>").concat(translations.LTmonthlyAmount, "</span>\n </span>\n </div>\n <div class='right'>\n <span class='pill'>").concat(months, " ").concat(translations.LTtermLength, "</span>\n </div>\n </div>\n </div>\n <div class='plan-details monthly-plan-details'>\n <div class='monthly-detail-row' aria-label='").concat(translations.LTreadApr, " ").concat(bestAPR, " ").concat(translations.LTpercent, "'>\n <span class='detail-label' aria-hidden='true'>").concat(translations.LTsampleApr, "</span>\n <span class='detail-value monthly-apr' aria-hidden='true'>").concat(bestAPR, "%</span>\n </div>\n <div class='monthly-detail-row'>\n <span class='detail-label'>").concat(translations.LTinterest, "</span>\n <span class='detail-value monthly-interest' data-months='").concat(months, "'>").concat(formatLTAmount(currency, interest), "</span>\n </div>\n <div class='monthly-detail-row'>\n <span class='detail-label'>").concat(translations.LTadjustedTotal, "</span>\n <span class='detail-value monthly-total' data-months='").concat(months, "'>").concat(formatLTAmount(currency, total), "</span>\n </div>\n </div>\n </div>\n ");
774
+ var aprDisplay = formatNumberForLocale(medianAPR, lang);
775
+ return "\n <div class='payment-card monthly-installment-card' data-months='".concat(months, "'>\n <div class='plan-summary'>\n <div class='purple'>\n <div class='left'>\n <span class='price monthly-amount' data-months='").concat(months, "'>").concat(formatLTAmount(currency, monthly), "</span>\n <span class='due' aria-label='").concat(translations.LTperMonth, "'>\n <span aria-hidden='true'>").concat(translations.LTmonthlyAmount, "</span>\n </span>\n </div>\n <div class='right'>\n <span class='pill'>").concat(months, " ").concat(translations.LTtermLength, "</span>\n </div>\n </div>\n </div>\n <div class='plan-details monthly-plan-details'>\n <div class='monthly-detail-row' aria-label='").concat(translations.LTreadApr, " ").concat(aprDisplay, " ").concat(translations.LTpercent, "'>\n <span class='detail-label' aria-hidden='true'>").concat(translations.LTsampleApr, "</span>\n <span class='detail-value monthly-apr' aria-hidden='true'>").concat(aprDisplay, "%</span>\n </div>\n <div class='monthly-detail-row'>\n <span class='detail-label'>").concat(translations.LTinterest, "</span>\n <span class='detail-value monthly-interest' data-months='").concat(months, "'>").concat(formatLTAmount(currency, interest), "</span>\n </div>\n <div class='monthly-detail-row'>\n <span class='detail-label'>").concat(translations.LTadjustedTotal, "</span>\n <span class='detail-value monthly-total' data-months='").concat(months, "'>").concat(formatLTAmount(currency, total), "</span>\n </div>\n </div>\n </div>\n ");
551
776
  }
552
777
  function featureCheckSvg() {
553
778
  return "<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6.66667 0C2.98667 0 0 2.98667 0 6.66667C0 10.3467 2.98667 13.3333 6.66667 13.3333C10.3467 13.3333 13.3333 10.3467 13.3333 6.66667C13.3333 2.98667 10.3467 0 6.66667 0ZM6.66667 12C3.72667 12 1.33333 9.60667 1.33333 6.66667C1.33333 3.72667 3.72667 1.33333 6.66667 1.33333C9.60667 1.33333 12 3.72667 12 6.66667C12 9.60667 9.60667 12 6.66667 12ZM9.25333 4.19333L5.33333 8.11333L4.08 6.86C3.82 6.6 3.4 6.6 3.14 6.86C2.88 7.12 2.88 7.54 3.14 7.8L4.86667 9.52667C5.12667 9.78667 5.54667 9.78667 5.80667 9.52667L10.2 5.13333C10.46 4.87333 10.46 4.45333 10.2 4.19333C9.94 3.93333 9.51333 3.93333 9.25333 4.19333Z\" fill=\"#8333D4\"/>\n </svg>";
554
779
  }
555
780
  function generateBiweeklyInner(eligibility, currency, priceString, opts, translations) {
556
781
  if (!eligibility.pi4) return '';
557
- return "\n ".concat(generateBiweeklyCard(4, currency, priceString, opts.minPriceLT, opts.maxPriceLT, opts.bestAPR, translations), "\n ").concat(eligibility.pi5 ? generateBiweeklyCard(5, currency, priceString, opts.minPriceLT, opts.maxPriceLT, opts.bestAPR, translations) : '', "\n ");
782
+ return "\n ".concat(generateBiweeklyCard(4, currency, priceString, translations), "\n ").concat(eligibility.pi5 ? generateBiweeklyCard(5, currency, priceString, translations) : '', "\n ");
558
783
  }
559
- function generateMonthlyInner(eligibility, currency, priceString, opts, translations) {
784
+ function generateMonthlyInner(eligibility, currency, priceString, opts, translations, lang) {
560
785
  if (!eligibility.lt) return '';
561
- var terms = termsToShow(parsePrice(priceString));
786
+ var terms = selectTermsToShow(parsePrice(priceString), opts.termsToShow) || [];
562
787
  var cards = terms.map(function (months) {
563
- return generateMonthlyCard(months, currency, priceString, opts.bestAPR, translations);
788
+ return generateMonthlyCard(months, currency, priceString, opts.medianAPR, translations, lang);
564
789
  }).join('');
565
790
  var seeDetails = translations.LTseeDetails;
566
791
  var hideDetails = translations.LThideDetails;
567
792
  return "\n ".concat(cards, "\n <div class=\"features-accordion\">\n <div class=\"accordion-title-bar\">\n <span class=\"accordion-title\" aria-hidden='true'>").concat(seeDetails, "</span>\n <button class=\"accordion-icon accordion-toggle\" aria-expanded=\"false\" aria-controls=\"features-drawer\" aria-label='").concat(seeDetails, "' data-label-expand='").concat(seeDetails, "' data-label-collapse='").concat(hideDetails, "'>\n <svg class=\"accordion-icon-expand\" width=\"12\" height=\"7\" viewBox=\"0 0 12 7\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9.4625 0.2925L5.5825 4.1725L1.7025 0.2925C1.3125 -0.0975 0.6825 -0.0975 0.2925 0.2925C-0.0975 0.6825 -0.0975 1.3125 0.2925 1.7025L4.8825 6.2925C5.2725 6.6825 5.9025 6.6825 6.2925 6.2925L10.8825 1.7025C11.2725 1.3125 11.2725 0.6825 10.8825 0.2925C10.4925 -0.0875 9.8525 -0.0975 9.4625 0.2925Z\" fill=\"#8333D4\"/>\n </svg>\n <svg class=\"accordion-icon-collapse\" style=\"display:none\" width=\"12\" height=\"7\" viewBox=\"0 0 12 7\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4.8825 0.2925L0.2925 4.8825C-0.0975 5.2725 -0.0975 5.9025 0.2925 6.2925C0.6825 6.6825 1.3125 6.6825 1.7025 6.2925L5.5925 2.4125L9.4725 6.2925C9.8625 6.6825 10.4925 6.6825 10.8825 6.2925C11.2725 5.9025 11.2725 5.2725 10.8825 4.8825L6.2925 0.2925C5.9125 -0.0975 5.2725 -0.0975 4.8825 0.2925Z\" fill=\"#8333D4\"/>\n </svg>\n </button>\n </div>\n <div id=\"features-drawer\" class=\"features-drawer\" style=\"display: none;\">\n <div class=\"single-feature\"><div>").concat(featureCheckSvg(), "</div><span>").concat(translations.LTsingleFeatureAffordable, "</span></div>\n <div class=\"single-feature\"><div>").concat(featureCheckSvg(), "</div><span>").concat(translations.LTsingleFeaturePrequalify, "</span></div>\n <div class=\"single-feature\"><div>").concat(featureCheckSvg(), "</div><span>").concat(translations.LTsingleFeatureTrusted, "</span></div>\n </div>\n </div>\n ");
568
793
  }
569
- function generateTermsInner(eligibility, translations) {
794
+ function generateTermsInner(eligibility, translations, opts, lang) {
570
795
  var webBank = '';
571
796
  if (eligibility.pi4) {
572
797
  var productTerms = eligibility.pi5 ? translations.webBankTermsPI5 : translations.webBankTermsPI4;
@@ -574,7 +799,14 @@ function generateTermsInner(eligibility, translations) {
574
799
  }
575
800
  var ltTerms = '';
576
801
  if (eligibility.lt) {
577
- var ltTerms3 = (translations.LTterms3 || '* Subject to credit approval by a third party lender.').replace('{minAPR}', LT_APR_MIN).replace('{maxAPR}', LT_APR_MAX).replace('{minTermMonths}', LT_TERM_MIN).replace('{maxTermMonths}', LT_TERM_MAX);
802
+ // APR range comes from the resolved LT config; term-month bounds derive from
803
+ // the union of every termsToShow array. APR values render with the
804
+ // locale-appropriate decimal separator.
805
+ var bounds = termMonthBounds(opts.termsToShow) || {
806
+ min: '',
807
+ max: ''
808
+ };
809
+ var ltTerms3 = (translations.LTterms3 || '* Subject to credit approval by a third party lender.').replace('{minAPR}', formatNumberForLocale(opts.minAPR, lang)).replace('{maxAPR}', formatNumberForLocale(opts.maxAPR, lang)).replace('{minTermMonths}', bounds.min).replace('{maxTermMonths}', bounds.max);
578
810
  ltTerms = "<p class=\"terms lt-terms\">".concat(ltTerms3, "</p>");
579
811
  }
580
812
  return "\n <p class=\"terms\"><span>".concat(translations.terms1, "</span><br /><span>").concat(translations.termsHiw, "</span></p>\n <p class=\"terms\">").concat(translations.terms2, "</p>\n ").concat(webBank, "\n ").concat(ltTerms, "\n ");
@@ -688,7 +920,7 @@ function attachFeaturesAccordion(modalNode) {
688
920
  }
689
921
 
690
922
  // Swap in re-rendered HTML for the sections that depend on the input amount.
691
- function renderDynamicSections(modalNode, currency, priceString, opts, translations) {
923
+ function renderDynamicSections(modalNode, currency, priceString, opts, translations, lang) {
692
924
  var eligibility = computeEligibility(priceString, opts);
693
925
  var container = modalNode.querySelector('#sezzle-modal-container');
694
926
  if (container) container.classList.toggle('pi4-only', !eligibility.pi5);
@@ -699,12 +931,12 @@ function renderDynamicSections(modalNode, currency, priceString, opts, translati
699
931
  }
700
932
  var monthly = modalNode.querySelector('.payment-cards-monthly');
701
933
  if (monthly) {
702
- monthly.innerHTML = generateMonthlyInner(eligibility, currency, priceString, opts, translations);
934
+ monthly.innerHTML = generateMonthlyInner(eligibility, currency, priceString, opts, translations, lang);
703
935
  monthly.style.display = eligibility.lt ? '' : 'none';
704
936
  if (eligibility.lt) attachFeaturesAccordion(modalNode);
705
937
  }
706
938
  var terms = modalNode.querySelector('.terms-container');
707
- if (terms) terms.innerHTML = generateTermsInner(eligibility, translations);
939
+ if (terms) terms.innerHTML = generateTermsInner(eligibility, translations, opts, lang);
708
940
  }
709
941
  function handleMultiPlanInput(modalNode, opts, initialCurrency) {
710
942
  var input = modalNode.querySelector('.input-amount');
@@ -712,7 +944,8 @@ function handleMultiPlanInput(modalNode, opts, initialCurrency) {
712
944
  if (!input || input.dataset.listenersAdded === 'true') return;
713
945
  var currency = initialCurrency;
714
946
  var debounceTimer = null;
715
- var translations = getTranslations(getLanguage());
947
+ var lang = getLanguage();
948
+ var translations = getTranslations(lang);
716
949
  input.addEventListener('click', function (e) {
717
950
  return e.stopPropagation();
718
951
  });
@@ -734,7 +967,7 @@ function handleMultiPlanInput(modalNode, opts, initialCurrency) {
734
967
  }
735
968
  input.classList.remove('input-error');
736
969
  if (container) container.classList.remove('input-error');
737
- renderDynamicSections(modalNode, currency, priceString, opts, translations);
970
+ renderDynamicSections(modalNode, currency, priceString, opts, translations, lang);
738
971
  }, INPUT_DEBOUNCE_DELAY_MS);
739
972
  });
740
973
  input.dataset.listenersAdded = 'true';
@@ -746,7 +979,8 @@ function handleMultiPlanInput(modalNode, opts, initialCurrency) {
746
979
  // minPrice=0 relaxation as the initial render so PI4 is always visible on open.
747
980
  function resetMultiPlanModal(modalNode, rawPrice, opts) {
748
981
  if (!modalNode) return;
749
- var translations = getTranslations(getLanguage());
982
+ var lang = getLanguage();
983
+ var translations = getTranslations(lang);
750
984
  // Whitelist-sanitize before interpolating into innerHTML downstream, matching
751
985
  // the user-input path in handleMultiPlanInput so all entry points share the
752
986
  // same trust posture regardless of how the caller sourced rawPrice.
@@ -762,7 +996,7 @@ function resetMultiPlanModal(modalNode, rawPrice, opts) {
762
996
  if (container) container.classList.remove('input-error');
763
997
  renderDynamicSections(modalNode, currency, priceString, _objectSpread$3(_objectSpread$3({}, opts), {}, {
764
998
  minPrice: 0
765
- }), translations);
999
+ }), translations, lang);
766
1000
  }
767
1001
  function getMultiPlanModal(modalNode, priceString, opts) {
768
1002
  var currentLang = getLanguage();
@@ -782,7 +1016,7 @@ function getMultiPlanModal(modalNode, priceString, opts) {
782
1016
  minPrice: 0
783
1017
  }));
784
1018
  modalNode.className = 'sezzle-checkout-modal-lightbox sezzle-modal';
785
- var modalContent = "<section class=\"sezzle-checkout-modal-lightbox close-sezzle-modal\" lang=\"".concat(currentLang, "\" aria-label=\"").concat(translations.sezzleInformation, "\" style=\"display: block;\">\n <div id=\"sezzle-modal-container\" role=\"dialog\" aria-label=\"Sezzle Modal\" class=\"sezzle-checkout-modal-hidden sezzle-multi-plan").concat(eligibility.pi5 ? '' : ' pi4-only', "\">\n <div class=\"sezzle-modal\">\n <div><button role=\"button\" aria-label=\"").concat(translations.closeSezzleModal, "\" class=\"close-sezzle-modal\"></button></div>\n <div class=\"sezzle-logo\" title=\"Sezzle\"></div>\n <div id=\"sezzle-modal-core-content\" class=\"sezzle-modal-content\">\n <p class='trusted'>").concat(translations.MultiPlantrusted, "</p>\n <header class='sezzle-header'>").concat(translations.MultiPlanheader, "</header>\n <div class='payment-plan-wrapper'>\n <p class='sample-payments ").concat(currentLang === 'fr' ? 'sezzle-multi-plan-fr' : '', "'>\n <span class=\"sample-payments-title\">").concat(translations.MultiPlanSeePlans, "</span>\n <span class=\"input-amount-container\">\n <label class=\"input-amount-label\" for=\"multi-plan-input-amount\">").concat(translations.MultiPlanAmount, "</label>\n <input class='price input-amount' id=\"multi-plan-input-amount\" maxlength=\"12\" value='").concat(currency + priceString, "'/>\n </span>\n </p>\n <div class='payment-cards payment-cards-biweekly'").concat(eligibility.pi4 ? '' : ' style="display:none"', ">").concat(generateBiweeklyInner(eligibility, currency, priceString, opts, translations), "</div>\n <div class='payment-cards payment-cards-monthly'").concat(eligibility.lt ? '' : ' style="display:none"', ">").concat(generateMonthlyInner(eligibility, currency, priceString, opts, translations), "</div>\n </div>\n <div class='how-to-sezzle'>\n <div class='carousel-header'>\n <div class='how-to-text-wrapper'>\n <span class='how-to-text'>").concat(translations.MultiPlanhowToPay, "</span>\n <div class='how-to-logo'>\n <img class=\"how-to-sezzle-logo szl-light-image\" src=\"https://media.sezzle.com/branding/2.0/Sezzle_Logo_FullColor.svg\" alt=\"Sezzle\" style=\"height: 14px; width: 58px;\">\n </div>\n </div>\n <div class='arrows'>\n <button type='button' class='arrow arrow-left disabled' disabled aria-label='").concat(translations.previousSlide, "'>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14.5 16.4078C14.825 16.0828 14.825 15.5578 14.5 15.2328L11.2667 11.9995L14.5 8.76614C14.825 8.44114 14.825 7.91614 14.5 7.59114C14.175 7.26614 13.65 7.26614 13.325 7.59114L9.5 11.4161C9.175 11.7411 9.175 12.2661 9.5 12.5911L13.325 16.4161C13.6417 16.7328 14.175 16.7328 14.5 16.4078Z\" fill=\"#8333D4\"/></svg>\n </button>\n <button type='button' class='arrow arrow-right' aria-label='").concat(translations.nextSlide, "'>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 7.59219C9.175 7.91719 9.175 8.44219 9.5 8.76719L12.7333 12.0005L9.5 15.2339C9.175 15.5589 9.175 16.0839 9.5 16.4089C9.825 16.7339 10.35 16.7339 10.675 16.4089L14.5 12.5839C14.825 12.2589 14.825 11.7339 14.5 11.4089L10.675 7.58386C10.3583 7.26719 9.825 7.26719 9.5 7.59219Z\" fill=\"#8333D4\"/></svg>\n </button>\n </div>\n </div>\n <div class='carousel position-1'>\n <div class='carousel-item'><div class='carousel-item-content'><div class='step-number'><span class='step-number-content'>1</span></div><div class='step-name'>").concat(translations.MultiPlanStep1, "</div></div></div>\n <div class='carousel-item'><div class='carousel-item-content'><div class='step-number'><span class='step-number-content'>2</span></div><div class='step-name'>").concat(translations.MultiPlanStep2, "</div></div></div>\n <div class='carousel-item'><div class='carousel-item-content'><div class='step-number'><span class='step-number-content'>3</span></div><div class='step-name'>").concat(translations.MultiPlanStep3, "</div></div></div>\n </div>\n <div class='carousel-dots' role=\"tablist\" aria-label=\"").concat(translations.carouselPosition, "\">\n <div class=\"dot active\" role=\"tab\" aria-selected=\"true\" aria-label=\"").concat(translations.slide, " 1\"><svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"6\" height=\"6\" rx=\"3\" fill=\"#8333D4\"/></svg></div>\n <div class=\"dot\" role=\"tab\" aria-selected=\"false\" aria-label=\"").concat(translations.slide, " 2\"><svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"6\" height=\"6\" rx=\"3\" fill=\"#8333D4\"/></svg></div>\n <div class=\"dot\" role=\"tab\" aria-selected=\"false\" aria-label=\"").concat(translations.slide, " 3\"><svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"6\" height=\"6\" rx=\"3\" fill=\"#8333D4\"/></svg></div>\n </div>\n </div>\n <div class=\"terms-container\">").concat(generateTermsInner(eligibility, translations), "</div>\n </div>\n </div>\n </div>\n</section>");
1019
+ var modalContent = "<section class=\"sezzle-checkout-modal-lightbox close-sezzle-modal\" lang=\"".concat(currentLang, "\" aria-label=\"").concat(translations.sezzleInformation, "\" style=\"display: block;\">\n <div id=\"sezzle-modal-container\" role=\"dialog\" aria-label=\"Sezzle Modal\" class=\"sezzle-checkout-modal-hidden sezzle-multi-plan").concat(eligibility.pi5 ? '' : ' pi4-only', "\">\n <div class=\"sezzle-modal\">\n <div><button role=\"button\" aria-label=\"").concat(translations.closeSezzleModal, "\" class=\"close-sezzle-modal\"></button></div>\n <div class=\"sezzle-logo\" title=\"Sezzle\"></div>\n <div id=\"sezzle-modal-core-content\" class=\"sezzle-modal-content\">\n <p class='trusted'>").concat(translations.MultiPlantrusted, "</p>\n <header class='sezzle-header'>").concat(translations.MultiPlanheader, "</header>\n <div class='payment-plan-wrapper'>\n <p class='sample-payments ").concat(currentLang === 'fr' ? 'sezzle-multi-plan-fr' : '', "'>\n <span class=\"sample-payments-title\">").concat(translations.MultiPlanSeePlans, "</span>\n <span class=\"input-amount-container\">\n <label class=\"input-amount-label\" for=\"multi-plan-input-amount\">").concat(translations.MultiPlanAmount, "</label>\n <input class='price input-amount' id=\"multi-plan-input-amount\" maxlength=\"12\" value='").concat(currency + priceString, "'/>\n </span>\n </p>\n <div class='payment-cards payment-cards-biweekly'").concat(eligibility.pi4 ? '' : ' style="display:none"', ">").concat(generateBiweeklyInner(eligibility, currency, priceString, opts, translations), "</div>\n <div class='payment-cards payment-cards-monthly'").concat(eligibility.lt ? '' : ' style="display:none"', ">").concat(generateMonthlyInner(eligibility, currency, priceString, opts, translations, currentLang), "</div>\n </div>\n <div class='how-to-sezzle'>\n <div class='carousel-header'>\n <div class='how-to-text-wrapper'>\n <span class='how-to-text'>").concat(translations.MultiPlanhowToPay, "</span>\n <div class='how-to-logo'>\n <img class=\"how-to-sezzle-logo szl-light-image\" src=\"https://media.sezzle.com/branding/2.0/Sezzle_Logo_FullColor.svg\" alt=\"Sezzle\" style=\"height: 14px; width: 58px;\">\n </div>\n </div>\n <div class='arrows'>\n <button type='button' class='arrow arrow-left disabled' disabled aria-label='").concat(translations.previousSlide, "'>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14.5 16.4078C14.825 16.0828 14.825 15.5578 14.5 15.2328L11.2667 11.9995L14.5 8.76614C14.825 8.44114 14.825 7.91614 14.5 7.59114C14.175 7.26614 13.65 7.26614 13.325 7.59114L9.5 11.4161C9.175 11.7411 9.175 12.2661 9.5 12.5911L13.325 16.4161C13.6417 16.7328 14.175 16.7328 14.5 16.4078Z\" fill=\"#8333D4\"/></svg>\n </button>\n <button type='button' class='arrow arrow-right' aria-label='").concat(translations.nextSlide, "'>\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 7.59219C9.175 7.91719 9.175 8.44219 9.5 8.76719L12.7333 12.0005L9.5 15.2339C9.175 15.5589 9.175 16.0839 9.5 16.4089C9.825 16.7339 10.35 16.7339 10.675 16.4089L14.5 12.5839C14.825 12.2589 14.825 11.7339 14.5 11.4089L10.675 7.58386C10.3583 7.26719 9.825 7.26719 9.5 7.59219Z\" fill=\"#8333D4\"/></svg>\n </button>\n </div>\n </div>\n <div class='carousel position-1'>\n <div class='carousel-item'><div class='carousel-item-content'><div class='step-number'><span class='step-number-content'>1</span></div><div class='step-name'>").concat(translations.MultiPlanStep1, "</div></div></div>\n <div class='carousel-item'><div class='carousel-item-content'><div class='step-number'><span class='step-number-content'>2</span></div><div class='step-name'>").concat(translations.MultiPlanStep2, "</div></div></div>\n <div class='carousel-item'><div class='carousel-item-content'><div class='step-number'><span class='step-number-content'>3</span></div><div class='step-name'>").concat(translations.MultiPlanStep3, "</div></div></div>\n </div>\n <div class='carousel-dots' role=\"tablist\" aria-label=\"").concat(translations.carouselPosition, "\">\n <div class=\"dot active\" role=\"tab\" aria-selected=\"true\" aria-label=\"").concat(translations.slide, " 1\"><svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"6\" height=\"6\" rx=\"3\" fill=\"#8333D4\"/></svg></div>\n <div class=\"dot\" role=\"tab\" aria-selected=\"false\" aria-label=\"").concat(translations.slide, " 2\"><svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"6\" height=\"6\" rx=\"3\" fill=\"#8333D4\"/></svg></div>\n <div class=\"dot\" role=\"tab\" aria-selected=\"false\" aria-label=\"").concat(translations.slide, " 3\"><svg width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\"><rect width=\"6\" height=\"6\" rx=\"3\" fill=\"#8333D4\"/></svg></div>\n </div>\n </div>\n <div class=\"terms-container\">").concat(generateTermsInner(eligibility, translations, opts, currentLang), "</div>\n </div>\n </div>\n </div>\n</section>");
786
1020
  modalNode.innerHTML = modalContent;
787
1021
  handleCarousel(modalNode);
788
1022
  if (eligibility.lt) attachFeaturesAccordion(modalNode);
@@ -834,7 +1068,10 @@ var Modal = /*#__PURE__*/function (_React$Component) {
834
1068
  maxPrice: _this.props.maxPrice,
835
1069
  minPriceLT: _this.props.minPriceLT,
836
1070
  maxPriceLT: _this.props.maxPriceLT,
837
- bestAPR: _this.props.bestAPR,
1071
+ minAPR: _this.props.minAPR,
1072
+ medianAPR: _this.props.medianAPR,
1073
+ maxAPR: _this.props.maxAPR,
1074
+ termsToShow: _this.props.termsToShow,
838
1075
  numberOfPayments: _this.props.numberOfPayments
839
1076
  });
840
1077
  handleCarousel(_this.state.modalElement);
@@ -904,7 +1141,10 @@ var Modal = /*#__PURE__*/function (_React$Component) {
904
1141
  maxPrice: props.maxPrice,
905
1142
  minPriceLT: props.minPriceLT,
906
1143
  maxPriceLT: props.maxPriceLT,
907
- bestAPR: props.bestAPR,
1144
+ minAPR: props.minAPR,
1145
+ medianAPR: props.medianAPR,
1146
+ maxAPR: props.maxAPR,
1147
+ termsToShow: props.termsToShow,
908
1148
  numberOfPayments: props.numberOfPayments
909
1149
  });
910
1150
  }
@@ -927,7 +1167,10 @@ Modal.propTypes = {
927
1167
  maxPrice: PropTypes.number,
928
1168
  minPriceLT: PropTypes.number,
929
1169
  maxPriceLT: PropTypes.number,
930
- bestAPR: PropTypes.number
1170
+ minAPR: PropTypes.number,
1171
+ medianAPR: PropTypes.number,
1172
+ maxAPR: PropTypes.number,
1173
+ termsToShow: PropTypes.object
931
1174
  };
932
1175
 
933
1176
  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
@@ -1006,7 +1249,7 @@ var SezzleWidgetText = /*#__PURE__*/function (_React$Component) {
1006
1249
  var priceElement = /*#__PURE__*/React.createElement("span", {
1007
1250
  className: "sezzle-payment-amount sezzle-button-text",
1008
1251
  key: index
1009
- }, getFormattedPrice(_this2.state.config.price, effectiveNumberOfPayments, _this2.state.config.minPriceLT, _this2.state.config.maxPriceLT, _this2.state.config.bestAPR));
1252
+ }, getFormattedPrice(_this2.state.config.price, effectiveNumberOfPayments, _this2.state.config.minPriceLT, _this2.state.config.maxPriceLT, _this2.state.config.medianAPR, _this2.state.config.termsToShow));
1010
1253
  subtemplates.push(priceElement);
1011
1254
  break;
1012
1255
  case 'logo':
@@ -1131,7 +1374,10 @@ var SezzleWidgetText = /*#__PURE__*/function (_React$Component) {
1131
1374
  maxPrice: _this3.state.config.maxPrice,
1132
1375
  minPriceLT: _this3.state.config.minPriceLT,
1133
1376
  maxPriceLT: _this3.state.config.maxPriceLT,
1134
- bestAPR: _this3.state.config.bestAPR,
1377
+ minAPR: _this3.state.config.minAPR,
1378
+ medianAPR: _this3.state.config.medianAPR,
1379
+ maxAPR: _this3.state.config.maxAPR,
1380
+ termsToShow: _this3.state.config.termsToShow,
1135
1381
  price: _this3.state.config.price,
1136
1382
  numberOfPayments: _this3.state.config.numberOfPayments
1137
1383
  });
@@ -1173,6 +1419,18 @@ var SezzleWidgetWrapper = /*#__PURE__*/function (_React$Component) {
1173
1419
  var _this;
1174
1420
  _classCallCheck(this, SezzleWidgetWrapper);
1175
1421
  _this = _callSuper(this, SezzleWidgetWrapper, [props]);
1422
+ // Resolve LT options from the LTgroup alias preset, overlaid with any
1423
+ // explicitly-set LT props. Returns a fully-disabled config when neither
1424
+ // LTgroup nor minPriceLT is provided.
1425
+ var ltConfig = resolveLTConfig({
1426
+ LTgroup: _this.props.LTgroup,
1427
+ minPriceLT: _this.props.minPriceLT,
1428
+ maxPriceLT: _this.props.maxPriceLT,
1429
+ minAPR: _this.props.minAPR,
1430
+ medianAPR: _this.props.medianAPR,
1431
+ maxAPR: _this.props.maxAPR,
1432
+ termsToShow: _this.props.termsToShow
1433
+ });
1176
1434
  _this.state = {
1177
1435
  sezzleConfig: {
1178
1436
  price: _this.props.price || 0,
@@ -1180,9 +1438,12 @@ var SezzleWidgetWrapper = /*#__PURE__*/function (_React$Component) {
1180
1438
  includeAPModal: _this.props.includeAPModal || false,
1181
1439
  minPrice: _this.props.minPrice || 0,
1182
1440
  maxPrice: _this.props.maxPrice || 2500,
1183
- minPriceLT: _this.props.minPriceLT || 0,
1184
- maxPriceLT: _this.props.maxPriceLT || 15000,
1185
- bestAPR: _this.props.bestAPR || 21.99,
1441
+ minPriceLT: ltConfig.minPriceLT,
1442
+ maxPriceLT: ltConfig.maxPriceLT,
1443
+ minAPR: ltConfig.minAPR,
1444
+ medianAPR: ltConfig.medianAPR,
1445
+ maxAPR: ltConfig.maxAPR,
1446
+ termsToShow: ltConfig.termsToShow,
1186
1447
  theme: _this.props.theme || 'light',
1187
1448
  alignment: _this.props.alignment || 'auto',
1188
1449
  fontWeight: _this.props.fontWeight || 500,
@@ -1232,9 +1493,13 @@ SezzleWidgetWrapper.propTypes = {
1232
1493
  logoSize: PropTypes.number,
1233
1494
  minPrice: PropTypes.number,
1234
1495
  maxPrice: PropTypes.number,
1496
+ LTgroup: PropTypes.string,
1235
1497
  minPriceLT: PropTypes.number,
1236
1498
  maxPriceLT: PropTypes.number,
1237
- bestAPR: PropTypes.number,
1499
+ minAPR: PropTypes.number,
1500
+ medianAPR: PropTypes.number,
1501
+ maxAPR: PropTypes.number,
1502
+ termsToShow: PropTypes.object,
1238
1503
  includeAPModal: PropTypes.bool,
1239
1504
  numberOfPayments: PropTypes.number
1240
1505
  };