@useinsider/guido 3.7.0-beta.830822b → 3.7.0-beta.9fddd7d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/@types/config/schemas.js +70 -66
  2. package/dist/composables/usePreviewMode.js +15 -14
  3. package/dist/composables/useRecommendationPreview.js +100 -0
  4. package/dist/config/compiler/utils/recommendationCompilerUtils.js +90 -82
  5. package/dist/config/migrator/recommendation/htmlBuilder.js +59 -58
  6. package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
  7. package/dist/enums/extensions/recommendationBlock.js +1 -3
  8. package/dist/extensions/Blocks/Recommendation/block.js +58 -39
  9. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
  10. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +369 -288
  11. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +84 -72
  12. package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
  13. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +68 -66
  14. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
  15. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
  16. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +12 -10
  17. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +101 -72
  18. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +31 -30
  19. package/dist/extensions/Blocks/Recommendation/templates/index.js +9 -7
  20. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +74 -59
  21. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
  22. package/dist/extensions/Blocks/Recommendation/templates/utils.js +88 -57
  23. package/dist/services/recommendationApi.js +19 -31
  24. package/dist/src/@types/config/schemas.d.ts +16 -0
  25. package/dist/src/composables/useConfig.d.ts +4 -0
  26. package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
  27. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
  28. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -1
  29. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  30. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +29 -3
  31. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
  32. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
  33. package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
  34. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
  35. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +16 -0
  36. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  37. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +13 -0
  38. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -2
  39. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +33 -1
  40. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
  41. package/dist/src/stores/config.d.ts +36 -0
  42. package/package.json +1 -1
@@ -1,70 +1,75 @@
1
1
  import { CURRENT_CONFIG_VERSION as s, DEFAULT_CURRENCY as i } from "../../../extensions/Blocks/Recommendation/constants/defaultConfig.js";
2
- import { DEFAULT_CARDS_IN_ROW as m, DEFAULT_MOBILE_ROW_SPACING as p, DEFAULT_MOBILE_COLUMN_SPACING as f, DEFAULT_ROW_SPACING as S, DEFAULT_COLUMN_SPACING as d, DEFAULT_MOBILE_CARDS_IN_ROW as u } from "../../../extensions/Blocks/Recommendation/constants/layout.js";
3
- import { mapLegacyStrategy as c } from "../../../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
4
- function l(t) {
2
+ import { DEFAULT_CARDS_IN_ROW as m, DEFAULT_MOBILE_ROW_SPACING as p, DEFAULT_MOBILE_COLUMN_SPACING as d, DEFAULT_ROW_SPACING as f, DEFAULT_COLUMN_SPACING as S, DEFAULT_MOBILE_CARDS_IN_ROW as a } from "../../../extensions/Blocks/Recommendation/constants/layout.js";
3
+ import { mapLegacyStrategy as l } from "../../../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
4
+ function c(t) {
5
5
  return t === "0" || t === 0 ? "before" : "after";
6
6
  }
7
- function _(t) {
7
+ function I(t) {
8
8
  if (typeof t == "number" && Number.isFinite(t))
9
9
  return t;
10
10
  if (typeof t == "string") {
11
- const n = parseInt(t);
12
- if (!Number.isNaN(n))
13
- return n;
11
+ const o = parseInt(t);
12
+ if (!Number.isNaN(o))
13
+ return o;
14
14
  }
15
15
  return i.decimalCount;
16
16
  }
17
- function I(t) {
17
+ function _(t) {
18
18
  return t === "." || t === "," || t === " " || t === "" ? t : ",";
19
19
  }
20
- function A(t) {
20
+ function N(t) {
21
21
  return t === "." || t === "," || t === " " ? t : ".";
22
22
  }
23
- function N(t) {
23
+ function A(t) {
24
24
  if (!t || typeof t != "object")
25
25
  return { ...i };
26
- const n = t, o = n.value ?? n.name ?? i.code, r = n.symbol ?? o;
26
+ const o = t, n = o.value ?? o.name ?? i.code, r = o.symbol ?? n;
27
27
  return {
28
- code: o,
28
+ code: n,
29
29
  symbol: r,
30
- alignment: l(n.alignment),
31
- decimalCount: _(n.decimalCount),
32
- decimalSeparator: A(n.decimalSeparator),
33
- thousandSeparator: I(n.thousandSeparator)
30
+ alignment: c(o.alignment),
31
+ decimalCount: I(o.decimalCount),
32
+ decimalSeparator: N(o.decimalSeparator),
33
+ thousandSeparator: _(o.thousandSeparator)
34
34
  };
35
35
  }
36
- function R(t) {
36
+ function L(t) {
37
37
  return t === "horizontal" || t === "list" ? "list" : "grid";
38
38
  }
39
- function b(t) {
40
- return c(t) || "mostPopular";
39
+ function R(t) {
40
+ return l(t) || "mostPopular";
41
41
  }
42
- function D(t, n, o) {
43
- const r = n.rowCount ?? t.cardsInRow ?? m, a = n.totalCount ?? (typeof t.size == "string" ? parseInt(t.size) : t.size) ?? 6;
42
+ function U(t, o, n) {
43
+ const r = o.rowCount ?? t.cardsInRow ?? m, u = o.totalCount ?? (typeof t.size == "string" ? parseInt(t.size) : t.size) ?? 6;
44
44
  return {
45
- recommendationId: o,
46
- strategy: b(t.strategy),
45
+ recommendationId: n,
46
+ strategy: R(t.strategy),
47
47
  productIds: (t.productIds ?? []).map((e) => String(e)),
48
- size: String(a),
48
+ size: String(u),
49
49
  shuffleProducts: !!t.shuffleProducts,
50
50
  language: t.language ?? "en_US",
51
- currency: N(t.currencySettings),
51
+ currency: A(t.currencySettings),
52
52
  filters: (t.filters ?? []).map((e) => ({ ...e })),
53
- layout: R(t.orientation ?? n.orientation),
53
+ layout: L(t.orientation ?? o.orientation),
54
54
  cardsInRow: r,
55
- mobileCardsInRow: u,
55
+ mobileCardsInRow: a,
56
56
  mobileLayoutEnabled: !1,
57
- previousMobileCardsInRow: u,
58
- columnSpacing: d,
59
- rowSpacing: S,
60
- mobileColumnSpacing: f,
57
+ previousMobileCardsInRow: a,
58
+ columnSpacing: S,
59
+ rowSpacing: f,
60
+ mobileColumnSpacing: d,
61
61
  mobileRowSpacing: p,
62
62
  omnibusPrice: { textBefore: "", textAfter: "" },
63
63
  omnibusDiscount: { textBefore: "", textAfter: "" },
64
+ // Preserve the legacy price-placement toggles. Absent legacy keys map to
65
+ // `false`, matching the legacy default (prices inline, original price not
66
+ // gated). New Guido blocks default differently (see DEFAULT_NODE_CONFIG).
67
+ priceMovedToNextLine: !!t.isPriceMovedToNextLine,
68
+ priceHideIfSameAsDiscounted: !!t.isPriceDeletedForZeroSale,
64
69
  configVersion: s
65
70
  };
66
71
  }
67
72
  export {
68
- N as mapCurrency,
69
- D as mapSettings
73
+ A as mapCurrency,
74
+ U as mapSettings
70
75
  };
@@ -1,8 +1,6 @@
1
1
  import { useTranslations as r } from "../../composables/useTranslations.js";
2
2
  const l = {
3
- RECOMMENDATION_API_URL: "https://recommendationv2.api.useinsider.com",
4
- // Relative path → same-origin as the embedding inone dashboard (Dataforce).
5
- PRODUCT_ATTRIBUTES_PATH: "/product-attributes/get-attributes"
3
+ RECOMMENDATION_API_URL: "https://recommendationv2.api.useinsider.com"
6
4
  }, c = {
7
5
  CLIENT_ID: "clientId"
8
6
  }, d = () => {
@@ -1,24 +1,24 @@
1
- var k = Object.defineProperty;
2
- var y = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
- var d = (a, r, t) => y(a, typeof r != "symbol" ? r + "" : r, t);
1
+ var D = Object.defineProperty;
2
+ var y = (a, c, t) => c in a ? D(a, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[c] = t;
3
+ var h = (a, c, t) => y(a, typeof c != "symbol" ? c + "" : c, t);
4
4
  import { BlockId as B } from "../../../enums/block.js";
5
- import { getMigrationBannerHtml as D } from "../../../utils/migrationBannerHtml.js";
6
- import { Block as R, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
- import { regenerateMobileProductRows as b } from "./controls/main/utils.js";
8
- import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as A } from "./controls/mobileLayout/cssRules.js";
9
- import { RecommendationConfigService as c } from "./services/configService.js";
10
- import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
11
- import { getDefaultTemplate as E } from "./templates/grid/template.js";
12
- const _ = B.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
13
- let I = !1;
14
- class q extends R {
5
+ import { getMigrationBannerHtml as R } from "../../../utils/migrationBannerHtml.js";
6
+ import { Block as b, BlockCompositionType as A, ModificationDescription as g } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
+ import { regenerateMobileProductRows as C } from "./controls/main/utils.js";
8
+ import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as E } from "./controls/mobileLayout/cssRules.js";
9
+ import { RecommendationConfigService as s } from "./services/configService.js";
10
+ import { useRecommendationExtensionStore as d } from "./store/recommendation.js";
11
+ import { getDefaultTemplate as S } from "./templates/grid/template.js";
12
+ const _ = B.Recommendation, m = "recommendation-block-v2", u = "recommendation-id", I = "hide-price";
13
+ let k = !1;
14
+ class q extends b {
15
15
  constructor() {
16
16
  super();
17
17
  /**
18
18
  * Stores the ID generated in getTemplate() so onCreated() can reuse it.
19
19
  * This avoids generating a new (different) ID in onCreated().
20
20
  */
21
- d(this, "_pendingBlockId", null);
21
+ h(this, "_pendingBlockId", null);
22
22
  }
23
23
  getId() {
24
24
  return _;
@@ -27,7 +27,7 @@ class q extends R {
27
27
  return "recommendation-icon";
28
28
  }
29
29
  getBlockCompositionType() {
30
- return C.CONTAINER;
30
+ return A.CONTAINER;
31
31
  }
32
32
  getName() {
33
33
  return this.api.translate("Recommendation Block");
@@ -38,7 +38,7 @@ class q extends R {
38
38
  );
39
39
  }
40
40
  getSettingsPanelTitleHtml() {
41
- return D(
41
+ return R(
42
42
  _,
43
43
  this.api.translate("Recommendation Block"),
44
44
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
@@ -59,7 +59,7 @@ class q extends R {
59
59
  */
60
60
  getTemplate() {
61
61
  const t = this._generateNextId();
62
- return this._pendingBlockId = t, E(t);
62
+ return this._pendingBlockId = t, S(t);
63
63
  }
64
64
  /**
65
65
  * Called when a new block is dropped into the template
@@ -82,20 +82,20 @@ class q extends R {
82
82
  }
83
83
  const i = this._pendingBlockId ?? this._generateNextId();
84
84
  this._pendingBlockId = null, this._assignRecommendationId(t, i);
85
- const { config: n, wasFreshDrop: o } = c.initializeConfig(
85
+ const { config: n, wasFreshDrop: o } = s.initializeConfig(
86
86
  this.api,
87
87
  t,
88
88
  { recommendationId: i }
89
- ), s = g();
90
- if (s.setCurrentBlock(i), o) {
89
+ ), r = d();
90
+ if (r.setCurrentBlock(i), this._stampHidePrice(t, n.priceHideIfSameAsDiscounted), o) {
91
91
  p(this.api);
92
92
  const l = this._getBlockElement(t);
93
- l && (f(this.api, l, !0), b({
93
+ l && (f(this.api, l, !0), C({
94
94
  currentNode: t,
95
95
  documentModifier: this.api.getDocumentModifier()
96
96
  }));
97
97
  }
98
- s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
98
+ r.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
99
99
  }
100
100
  /**
101
101
  * Called when the document changes or template is loaded
@@ -108,20 +108,20 @@ class q extends R {
108
108
  if (!(!t || !("getNodeConfig" in t))) {
109
109
  if (!this._getRecommendationId(t)) {
110
110
  const e = this._generateNextId();
111
- this._assignRecommendationId(t, e), c.hasConfig(t) && c.updateConfig(
111
+ this._assignRecommendationId(t, e), s.hasConfig(t) && s.updateConfig(
112
112
  this.api,
113
113
  t,
114
114
  { recommendationId: e },
115
115
  "Assign recommendation ID to legacy block"
116
116
  );
117
117
  }
118
- this._healLingeringDuplicate(t), c.needsMigration(t) && this._migrateFromLegacy(t);
118
+ this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
119
119
  try {
120
- I || (p(this.api), I = !0);
121
- const e = c.getConfig(t), i = this._getBlockElement(t);
120
+ k || (p(this.api), k = !0);
121
+ const e = s.getConfig(t), i = this._getBlockElement(t);
122
122
  if (i) {
123
123
  const n = !e.mobileLayoutEnabled;
124
- A(i) !== n && f(this.api, i, n);
124
+ E(i) !== n && f(this.api, i, n);
125
125
  }
126
126
  } catch {
127
127
  }
@@ -135,7 +135,7 @@ class q extends R {
135
135
  */
136
136
  onDelete(t) {
137
137
  const e = this._getRecommendationId(t);
138
- e && g().removeBlockState(e);
138
+ e && d().removeBlockState(e);
139
139
  }
140
140
  /**
141
141
  * Generates the next unique recommendation ID by scanning all existing blocks
@@ -147,8 +147,8 @@ class q extends R {
147
147
  const e = this.api.getDocumentRoot();
148
148
  e && "querySelectorAll" in e && e.querySelectorAll(`.${m}`).forEach((n) => {
149
149
  if ("getAttribute" in n) {
150
- const o = n.getAttribute(u), s = o ? parseInt(o) : 0;
151
- s > t && (t = s);
150
+ const o = n.getAttribute(u), r = o ? parseInt(o) : 0;
151
+ r > t && (t = r);
152
152
  }
153
153
  });
154
154
  } catch {
@@ -182,13 +182,13 @@ class q extends R {
182
182
  const o = this._getBlockElement(t);
183
183
  if (!o)
184
184
  return;
185
- let s = -1;
185
+ let r = -1;
186
186
  for (let l = 0; l < n.length; l++)
187
187
  if (n[l] === o) {
188
- s = l;
188
+ r = l;
189
189
  break;
190
190
  }
191
- if (s <= 0)
191
+ if (r <= 0)
192
192
  return;
193
193
  this._reassignDuplicateId(t, e);
194
194
  } catch {
@@ -208,7 +208,7 @@ class q extends R {
208
208
  }
209
209
  /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
210
210
  _handleDuplicate(t, e) {
211
- const i = this._reassignDuplicateId(t, e), n = g();
211
+ const i = this._reassignDuplicateId(t, e), n = d();
212
212
  n.cloneBlockState(e, i), n.setCurrentBlock(i);
213
213
  }
214
214
  /**
@@ -224,7 +224,7 @@ class q extends R {
224
224
  */
225
225
  _reassignDuplicateId(t, e) {
226
226
  const i = this._generateNextId(), n = this._getBlockElement(t);
227
- return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), c.hasConfig(t) && c.updateConfig(
227
+ return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), s.hasConfig(t) && s.updateConfig(
228
228
  this.api,
229
229
  t,
230
230
  { recommendationId: i },
@@ -241,8 +241,8 @@ class q extends R {
241
241
  _reassignInstanceClass(t, e, i) {
242
242
  if (!("getAttribute" in t))
243
243
  return;
244
- const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, s = this.api.getDocumentModifier();
245
- s.modifyHtml(t).removeClass(n).setClass(o), s.apply(new h(
244
+ const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, r = this.api.getDocumentModifier();
245
+ r.modifyHtml(t).removeClass(n).setClass(o), r.apply(new g(
246
246
  `Reassign recommendation instance class ${n} -> ${o}`
247
247
  ));
248
248
  }
@@ -257,7 +257,26 @@ class q extends R {
257
257
  if (!i)
258
258
  return;
259
259
  const n = this.api.getDocumentModifier();
260
- n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new h(`Assign recommendation ID ${e}`));
260
+ n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new g(`Assign recommendation ID ${e}`));
261
+ }
262
+ /**
263
+ * Stamps the `hide-price` attribute (read by email-service at send time) on
264
+ * the block element from the config flag.
265
+ */
266
+ _stampHidePrice(t, e) {
267
+ const i = this._getBlockElement(t);
268
+ i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(I, String(e)).apply(new g("Stamp hide-price"));
269
+ }
270
+ /**
271
+ * Stamps `hide-price` from config only when the block lacks the attribute —
272
+ * heals templates saved before this feature without dirtying current ones.
273
+ */
274
+ _healHidePriceAttr(t) {
275
+ const e = this._getBlockElement(t);
276
+ if (!e || !("getAttribute" in e) || e.getAttribute(I) !== null)
277
+ return;
278
+ const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
279
+ this._stampHidePrice(t, i);
261
280
  }
262
281
  /**
263
282
  * Gets the recommendation-id from a block node
@@ -287,7 +306,7 @@ class q extends R {
287
306
  * Migrate configuration from legacy format
288
307
  */
289
308
  _migrateFromLegacy(t) {
290
- c.migrateFromDataAttributes(this.api, t);
309
+ s.migrateFromDataAttributes(this.api, t);
291
310
  }
292
311
  }
293
312
  export {
@@ -1,34 +1,34 @@
1
- import { DEFAULT_COLUMN_SPACING as R, DEFAULT_ROW_SPACING as U, DEFAULT_MOBILE_ROW_SPACING as i, DEFAULT_MOBILE_COLUMN_SPACING as s, DEFAULT_MOBILE_CARDS_IN_ROW as o, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
2
- import { ATTR_PRODUCT_IMAGE as _, ATTR_PRODUCT_NAME as e, ATTR_PRODUCT_OLD_PRICE as t, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as I, ATTR_PRODUCT_BUTTON as n } from "./selectors.js";
3
- const O = {
1
+ import { DEFAULT_COLUMN_SPACING as n, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as R, DEFAULT_MOBILE_COLUMN_SPACING as U, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
2
+ import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as t, ATTR_PRODUCT_OLD_PRICE as _, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as i, ATTR_PRODUCT_BUTTON as I } from "./selectors.js";
3
+ const D = {
4
4
  code: "USD",
5
5
  symbol: "USD",
6
6
  alignment: "after",
7
7
  decimalCount: 2,
8
8
  decimalSeparator: ".",
9
9
  thousandSeparator: ","
10
- }, D = {
10
+ }, O = {
11
11
  textBefore: "",
12
12
  textAfter: ""
13
- }, A = {
13
+ }, a = {
14
14
  textBefore: "",
15
15
  textAfter: ""
16
- }, a = [
17
- _,
18
- e,
16
+ }, A = [
17
+ o,
19
18
  t,
19
+ _,
20
20
  T,
21
21
  r,
22
- I,
23
- n
24
- ], E = {
25
- [_]: !0,
26
- [e]: !0,
27
- [T]: !0,
22
+ i,
23
+ I
24
+ ], c = {
25
+ [o]: !0,
28
26
  [t]: !0,
27
+ [T]: !0,
28
+ [_]: !0,
29
29
  [r]: !1,
30
- [I]: !1,
31
- [n]: !0
30
+ [i]: !1,
31
+ [I]: !0
32
32
  }, l = {
33
33
  // Settings
34
34
  strategy: "mostPopular",
@@ -36,36 +36,45 @@ const O = {
36
36
  size: "6",
37
37
  shuffleProducts: !1,
38
38
  language: "en_US",
39
- currency: O,
39
+ currency: D,
40
40
  filters: [],
41
41
  // Layout
42
42
  layout: "grid",
43
43
  cardsInRow: C,
44
- mobileCardsInRow: o,
44
+ mobileCardsInRow: e,
45
45
  mobileLayoutEnabled: !1,
46
- previousMobileCardsInRow: o,
47
- columnSpacing: R,
48
- rowSpacing: U,
49
- mobileColumnSpacing: s,
50
- mobileRowSpacing: i,
46
+ previousMobileCardsInRow: e,
47
+ columnSpacing: n,
48
+ rowSpacing: s,
49
+ mobileColumnSpacing: U,
50
+ mobileRowSpacing: R,
51
51
  // Composition
52
- composition: a,
53
- visibility: E,
52
+ composition: A,
53
+ visibility: c,
54
54
  // Element settings
55
- omnibusPrice: D,
56
- omnibusDiscount: A,
55
+ omnibusPrice: O,
56
+ omnibusDiscount: a,
57
57
  textTrimming: !1,
58
+ // Price placement (block-level, affects all cards)
59
+ // Default ON = current stacked look, so existing templates are unaffected.
60
+ priceMovedToNextLine: !0,
61
+ // Default OFF: the original price always shows; the user opts in to hide it
62
+ // when it equals the sale price. Mirrors email-service's `hide-price` default
63
+ // of "false" (the actual hiding happens server-side at send).
64
+ priceHideIfSameAsDiscounted: !1,
58
65
  // Meta
66
+ // Version NOT bumped: mergeWithDefaults() backfills the two new fields from
67
+ // defaults, so no data transform (and no needsMigration trigger) is required.
59
68
  configVersion: 1,
60
69
  recommendationId: 0
61
70
  }, N = [11, 12], m = 1;
62
71
  export {
63
72
  m as CURRENT_CONFIG_VERSION,
64
- a as DEFAULT_COMPOSITION,
65
- O as DEFAULT_CURRENCY,
73
+ A as DEFAULT_COMPOSITION,
74
+ D as DEFAULT_CURRENCY,
66
75
  l as DEFAULT_NODE_CONFIG,
67
- A as DEFAULT_OMNIBUS_DISCOUNT,
68
- D as DEFAULT_OMNIBUS_PRICE,
69
- E as DEFAULT_VISIBILITY,
76
+ a as DEFAULT_OMNIBUS_DISCOUNT,
77
+ O as DEFAULT_OMNIBUS_PRICE,
78
+ c as DEFAULT_VISIBILITY,
70
79
  N as EXCLUDED_ALGORITHM_IDS
71
80
  };