@useinsider/guido 3.17.0-beta.e23d5cd → 3.17.0-beta.e324492

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 (50) hide show
  1. package/dist/components/Guido.vue.js +7 -7
  2. package/dist/components/Guido.vue2.js +59 -57
  3. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
  4. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
  5. package/dist/composables/useStripo.js +14 -14
  6. package/dist/config/i18n/en/labels.json.js +1 -1
  7. package/dist/config/migrator/index.js +9 -8
  8. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  9. package/dist/config/migrator/recommendation/extractors.js +29 -24
  10. package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
  11. package/dist/config/migrator/recommendationMigrator.js +30 -25
  12. package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
  13. package/dist/extensions/Blocks/Recommendation/block.js +12 -11
  14. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  15. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  16. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +24 -22
  17. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +35 -28
  18. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +329 -257
  19. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +127 -113
  20. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +1 -1
  21. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
  22. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
  23. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  24. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
  25. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +37 -26
  26. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  27. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
  28. package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
  29. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
  30. package/dist/guido.css +1 -1
  31. package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
  32. package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
  33. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +5 -0
  34. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
  35. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
  36. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
  37. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  38. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +12 -0
  39. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +11 -0
  40. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  41. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +8 -4
  42. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
  43. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
  44. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +38 -0
  45. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
  46. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
  47. package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
  48. package/dist/static/styles/customEditorStyle.css.js +3 -1
  49. package/dist/utils/templatePreparation.js +37 -36
  50. package/package.json +1 -1
@@ -1,17 +1,17 @@
1
- import { getRecommendationFeedSourceMaps as I, getOperatorOptions as G, PriceAttributes as D } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
1
+ import { getRecommendationFeedSourceMaps as b, getOperatorOptions as G, PriceAttributes as v } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as D } from "../../../../services/recommendationApi.js";
3
3
  import { useConfigStore as F } from "../../../../stores/config.js";
4
- import { defineStore as v } from "pinia";
4
+ import { defineStore as P } from "pinia";
5
5
  import "../constants/selectors.js";
6
6
  import { DEFAULT_MOBILE_CARDS_IN_ROW as _, DEFAULT_CARDS_IN_ROW as U } from "../constants/layout.js";
7
7
  import { DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as L } from "../constants/defaultConfig.js";
8
- import { getDefaultProducts as k } from "../templates/utils.js";
9
- import { generateCompleteFilterQuery as R } from "../utils/filterUtil.js";
8
+ import { getDefaultProducts as R } from "../templates/utils.js";
9
+ import { generateCompleteFilterQuery as k } from "../utils/filterUtil.js";
10
10
  import { getPartnerRecommendationParams as x } from "../utils/partnerCustomizations.js";
11
11
  import { sanitizeProductIds as A } from "../utils/productIds.js";
12
12
  import { isFilterValid as B } from "../validation/filterSchema.js";
13
- import { isConfigValid as z } from "../validation/requiredFields.js";
14
- const m = P();
13
+ import { isConfigValid as M } from "../validation/requiredFields.js";
14
+ const u = D();
15
15
  let f = null, g = null, h = null, S = null;
16
16
  const p = /* @__PURE__ */ new Map();
17
17
  function w() {
@@ -53,12 +53,14 @@ function C() {
53
53
  filterStatus: !1,
54
54
  filterSelectionDrawerStatus: !1,
55
55
  assignStrategyDrawerStatus: !1,
56
+ removeStrategyModalStatus: !1,
56
57
  filterGroup: 1,
57
58
  isInitialized: !1,
58
- filterSnapshot: null
59
+ filterSnapshot: null,
60
+ syncedConfigFingerprint: null
59
61
  };
60
62
  }
61
- const O = () => ({
63
+ const z = () => ({
62
64
  recommendationCampaignUrls: {},
63
65
  activePredictiveAlgorithms: [],
64
66
  languages: {},
@@ -70,8 +72,8 @@ const O = () => ({
70
72
  blockStates: {},
71
73
  currentRecommendationId: null,
72
74
  configVersion: 0
73
- }), Y = v("guidoRecommendationExtension", {
74
- state: () => O(),
75
+ }), Y = P("guidoRecommendationExtension", {
76
+ state: () => z(),
75
77
  getters: {
76
78
  // ====================================================================
77
79
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -98,6 +100,9 @@ const O = () => ({
98
100
  assignStrategyDrawerStatus(t) {
99
101
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
100
102
  },
103
+ removeStrategyModalStatus(t) {
104
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
105
+ },
101
106
  assignedStrategy(t) {
102
107
  const { strategyId: e } = this.recommendationConfigs;
103
108
  return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
@@ -133,7 +138,7 @@ const O = () => ({
133
138
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
134
139
  },
135
140
  getActivePredictiveAlgorithms: (t) => {
136
- const e = I(), r = [];
141
+ const e = b(), r = [];
137
142
  return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
138
143
  r.push(...e.filter((s) => s.id === n));
139
144
  }), r.map((n) => ({
@@ -152,7 +157,7 @@ const O = () => ({
152
157
  getFilterList() {
153
158
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
154
159
  let e;
155
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : D.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
160
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
156
161
  text: t.displayName,
157
162
  value: e,
158
163
  type: t.attributeType
@@ -237,7 +242,7 @@ const O = () => ({
237
242
  const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
238
243
  name: e.currencyCode,
239
244
  value: e.currencyCode,
240
- symbol: e.currencyCode,
245
+ symbol: e.currencySymbol,
241
246
  alignment: e.currencyAlignment === "before" ? "0" : "1",
242
247
  decimalCount: String(e.currencyDecimalCount),
243
248
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
@@ -334,6 +339,12 @@ const O = () => ({
334
339
  closeAssignStrategyDrawer() {
335
340
  this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
336
341
  },
342
+ openRemoveStrategyModal() {
343
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !0);
344
+ },
345
+ closeRemoveStrategyModal() {
346
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
347
+ },
337
348
  async fetchStrategies() {
338
349
  if (S) {
339
350
  await S;
@@ -342,7 +353,7 @@ const O = () => ({
342
353
  S = (async () => {
343
354
  this.strategiesLoading = !0;
344
355
  try {
345
- this.strategies = await m.fetchRecommendationStrategies();
356
+ this.strategies = await u.fetchRecommendationStrategies();
346
357
  } finally {
347
358
  this.strategiesLoading = !1;
348
359
  }
@@ -357,7 +368,7 @@ const O = () => ({
357
368
  const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
358
369
  if (s)
359
370
  return s;
360
- const { full_path: i = "" } = await m.generateStrategyEndpoint(t, e) ?? {};
371
+ const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
361
372
  return n && i && (this.strategyUrlTemplates = {
362
373
  ...this.strategyUrlTemplates,
363
374
  [n]: i
@@ -386,7 +397,7 @@ const O = () => ({
386
397
  activePredictiveAlgorithms: t,
387
398
  languages: e,
388
399
  currencies: r
389
- } = await m.fetchRecommendationCreateData();
400
+ } = await u.fetchRecommendationCreateData();
390
401
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
391
402
  const n = this.blockStates[this.currentRecommendationId];
392
403
  n.filterStatus = !!n.recommendationConfigs.filters.length;
@@ -407,7 +418,7 @@ const O = () => ({
407
418
  return;
408
419
  }
409
420
  g = (async () => {
410
- const t = await m.fetchRecommendationFilters();
421
+ const t = await u.fetchRecommendationFilters();
411
422
  this.filterList = t;
412
423
  })();
413
424
  try {
@@ -480,7 +491,7 @@ const O = () => ({
480
491
  }), e.recommendationConfigs.filters = r;
481
492
  },
482
493
  generateFilterQuery() {
483
- return R(this.recommendationConfigs.filters);
494
+ return k(this.recommendationConfigs.filters);
484
495
  },
485
496
  /**
486
497
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -488,7 +499,7 @@ const O = () => ({
488
499
  * every block's recommendationConfigs across user edits.
489
500
  */
490
501
  hasInvalidBlock() {
491
- return Object.values(this.blockStates).some((t) => !z(t.recommendationConfigs, this));
502
+ return Object.values(this.blockStates).some((t) => !M(t.recommendationConfigs, this));
492
503
  },
493
504
  // ====================================================================
494
505
  // Per-Block Product Fetching
@@ -514,7 +525,7 @@ const O = () => ({
514
525
  await this._doFetchStrategyProducts(t);
515
526
  return;
516
527
  }
517
- const s = r.filters.filter((u) => u.isValid), i = R(s), o = ((d = I().find((u) => u.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
528
+ const s = r.filters.filter((m) => m.isValid), i = k(s), o = ((d = b().find((m) => m.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
518
529
  locale: r.language,
519
530
  currency: r.currencySettings.value,
520
531
  partnerName: n.partnerName,
@@ -528,7 +539,7 @@ const O = () => ({
528
539
  );
529
540
  let l;
530
541
  try {
531
- l = await m.fetchRecommendationProducts(o, a);
542
+ l = await u.fetchRecommendationProducts(o, a);
532
543
  } catch {
533
544
  l = [];
534
545
  }
@@ -546,8 +557,8 @@ const O = () => ({
546
557
  );
547
558
  if (i) {
548
559
  s = parseInt(String(i.size ?? "")) || s;
549
- const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), u = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((b) => b && !b.startsWith("user_id=")), y = u.length ? `${d}?${u.join("&")}` : d;
550
- y && (n = await m.fetchRecommendationProductsByUrl(y));
560
+ const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), m = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((I) => I && !I.startsWith("user_id=")), y = m.length ? `${d}?${m.join("&")}` : d;
561
+ y && (n = await u.fetchRecommendationProductsByUrl(y));
551
562
  }
552
563
  } catch {
553
564
  n = [];
@@ -557,10 +568,10 @@ const O = () => ({
557
568
  _setBlockProducts(t, e, r) {
558
569
  if (!this.blockStates[t])
559
570
  return;
560
- const n = e.length > 0 ? e : k(r);
571
+ const n = e.length > 0 ? e : R(r);
561
572
  this.blockStates[t].recommendationProducts = [
562
573
  ...n.slice(0, r),
563
- ...k(Math.max(0, r - n.length))
574
+ ...R(Math.max(0, r - n.length))
564
575
  ];
565
576
  }
566
577
  }
@@ -1,6 +1,6 @@
1
1
  import { ATTR_PRODUCT_PRICE as f, ATTR_PRODUCT_OLD_PRICE as O } from "../../constants/selectors.js";
2
2
  import { DEFAULT_PRODUCTS_PER_ROW as w } from "../../constants/layout.js";
3
- import { getDefaultProducts as A, DEFAULTS as g, createBlockTemplate as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
3
+ import { createBlockTemplate as A, getDefaultProducts as g, DEFAULTS as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
4
4
  import { DEFAULT_CELL_PADDING as k, renderInlineGridPriceCell as H, buildFillerCell as x, gridElementRenderer as y } from "./elementRenderer.js";
5
5
  const G = `
6
6
  <tr class="recommendation-product-row">
@@ -69,8 +69,8 @@ function M(t, r, o, e = {}, c = {}) {
69
69
  );
70
70
  }
71
71
  function Q(t) {
72
- const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = U("grid", r), e = A(), c = M(e, w);
73
- return o.replace("{-{-TITLE-}-}", g.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
72
+ const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = A("grid", r), e = g(), c = M(e, w);
73
+ return o.replace("{-{-TITLE-}-}", U.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
74
74
  }
75
75
  export {
76
76
  Q as getDefaultTemplate,
@@ -0,0 +1,33 @@
1
+ import { RecommendationBlockId as r } from "../constants/blockIds.js";
2
+ import { DEFAULT_ROW_SPACING as l } from "../constants/layout.js";
3
+ import { CSS_CLASS_ATTRIBUTE_ROW as d, ATTR_RECOMMENDATION_TITLE as n, ATTR_DATA_VISIBILITY as A, CSS_CLASS_TITLE_CELL as _, CSS_CLASS_SPACER as c } from "../constants/selectors.js";
4
+ const a = "You May Also Like!", i = '<p style="font-size: 28px; color: #333333;"><strong>{-{-TITLE-}-}</strong></p>';
5
+ function E(s = i, t = !0, T = l) {
6
+ const e = `class="${d}" data-attribute-type="${n}" ${A}="${t ? "1" : "0"}"`, o = t ? "" : ' style="display: none;"';
7
+ return `
8
+ <tr ${e}${o}>
9
+ <td>
10
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
11
+ <tbody>
12
+ <tr>
13
+ <td
14
+ class="esd-block-text ${_} es-p10t es-p10b es-p20l es-p20r"
15
+ align="center"
16
+ esd-extension-block-id="${r.TITLE}">
17
+ ${s}
18
+ </td>
19
+ </tr>
20
+ </tbody>
21
+ </table>
22
+ </td>
23
+ </tr>
24
+ <tr ${e}${o}>
25
+ <td class="${c}" style="height: ${T}px;"></td>
26
+ </tr>
27
+ `;
28
+ }
29
+ export {
30
+ i as DEFAULT_TITLE_PARAGRAPH,
31
+ a as DEFAULT_TITLE_TEXT,
32
+ E as buildTitleRows
33
+ };
@@ -1,8 +1,9 @@
1
- import { ATTR_PRODUCT_PRICE as l, ATTR_PRODUCT_OLD_PRICE as a, ATTR_CUSTOM_PREFIX as T, ATTR_PRODUCT_IMAGE as m, ATTR_PRODUCT_NAME as C, ATTR_PRODUCT_OMNIBUS_PRICE as _, ATTR_PRODUCT_OMNIBUS_DISCOUNT as p, ATTR_PRODUCT_BUTTON as y, PRODUCT_ATTRIBUTE_PREFIX as I } from "../constants/selectors.js";
1
+ import { ATTR_PRODUCT_PRICE as l, ATTR_PRODUCT_OLD_PRICE as a, ATTR_CUSTOM_PREFIX as T, ATTR_PRODUCT_IMAGE as b, ATTR_PRODUCT_NAME as _, ATTR_PRODUCT_OMNIBUS_PRICE as C, ATTR_PRODUCT_OMNIBUS_DISCOUNT as A, ATTR_PRODUCT_BUTTON as p, PRODUCT_ATTRIBUTE_PREFIX as I } from "../constants/selectors.js";
2
2
  import { useRecommendationExtensionStore as L } from "../store/recommendation.js";
3
- import { compositionKeyToProductAttr as A, isDefaultProductAttr as b, bareAttributeName as S, findFilterByBareName as $, productAttrToCompositionKey as h } from "../utils/compositionKeys.js";
3
+ import { compositionKeyToProductAttr as y, isDefaultProductAttr as f, bareAttributeName as S, findFilterByBareName as $, productAttrToCompositionKey as P } from "../utils/compositionKeys.js";
4
4
  import { formatPrice as B } from "../utils/priceFormatter.js";
5
- function k() {
5
+ import { buildTitleRows as k } from "./titleRows.js";
6
+ function x() {
6
7
  const t = L(), { currencySettings: e } = t.recommendationConfigs;
7
8
  return {
8
9
  code: e.value,
@@ -13,17 +14,17 @@ function k() {
13
14
  thousandSeparator: e.thousandSeparator
14
15
  };
15
16
  }
16
- function f(t, e = "price") {
17
- const o = k(), n = t[e], c = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
17
+ function m(t, e = "price") {
18
+ const o = x(), n = t[e], c = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
18
19
  return B({
19
20
  price: c,
20
21
  currency: o
21
22
  });
22
23
  }
23
24
  function q(t) {
24
- return f(t, "price") === f(t, "original_price");
25
+ return m(t, "price") === m(t, "original_price");
25
26
  }
26
- function x(t) {
27
+ function N(t) {
27
28
  return t.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
28
29
  }
29
30
  function J(t) {
@@ -34,115 +35,114 @@ function J(t) {
34
35
  skip: n ? l : a
35
36
  };
36
37
  }
37
- function N(t) {
38
+ function F(t) {
38
39
  const e = Array.isArray(t) ? t[t.length - 1] : t;
39
40
  if (typeof e == "string")
40
41
  return e;
41
42
  if (typeof e == "number")
42
43
  return String(e);
43
44
  }
44
- function w(t, e) {
45
+ function v(t, e) {
45
46
  var o;
46
47
  return ((o = $(t, e)) == null ? void 0 : o.type) === "defaultAttribute";
47
48
  }
48
- function F(t, e) {
49
- return w(t, e) ? t : `${I}${t}`;
49
+ function w(t, e) {
50
+ return v(t, e) ? t : `${I}${t}`;
50
51
  }
51
52
  function Q(t) {
52
- return h(t);
53
+ return P(t);
53
54
  }
54
- const v = Symbol("customCellHtml");
55
+ const M = Symbol("customCellHtml");
55
56
  function Z(t, e, o = {}) {
56
- const n = t[v];
57
+ const n = t[M];
57
58
  if (!n)
58
59
  return { ...t };
59
60
  const c = { ...t };
60
- return e.filter((s) => s.startsWith(T) && !c[s]).forEach((s) => {
61
- const i = A(s), r = b(i) ? F(i, o) : i, u = S(r), R = x(u), D = b(r);
62
- c[s] = (d, U) => {
61
+ return e.filter((i) => i.startsWith(T) && !c[i]).forEach((i) => {
62
+ const s = y(i), r = f(s) ? w(s, o) : s, u = S(r), h = N(u), D = f(r);
63
+ c[i] = (d, U) => {
63
64
  var g;
64
- const E = D ? d[u] : (g = d.product_attributes) == null ? void 0 : g[u], O = N(E) ?? R;
65
- return n(r, O, U);
65
+ const O = D ? d[u] : (g = d.product_attributes) == null ? void 0 : g[u], E = F(O) ?? h;
66
+ return n(r, E, U);
66
67
  };
67
68
  }), c;
68
69
  }
69
70
  function tt(t, e, o = []) {
70
- const n = t.startsWith(T) ? h(S(A(t))) : t, s = n !== t && !o.includes(n) ? n : t, i = (r) => (r == null ? void 0 : r[t]) ?? (r == null ? void 0 : r[s]);
71
+ const n = t.startsWith(T) ? P(S(y(t))) : t, i = n !== t && !o.includes(n) ? n : t, s = (r) => (r == null ? void 0 : r[t]) ?? (r == null ? void 0 : r[i]);
71
72
  return {
72
73
  cellPadding: e.cellPadding,
73
74
  cardBackgroundColor: e.cardBackgroundColor,
74
- cellBackgroundColor: i(e.cellBackgroundColors),
75
- cellAlignment: i(e.cellAlignments),
76
- cellClasses: i(e.cellClasses),
77
- omnibusText: i(e.omnibusTexts),
78
- styleTemplate: i(e.styleTemplates)
75
+ cellBackgroundColor: s(e.cellBackgroundColors),
76
+ cellAlignment: s(e.cellAlignments),
77
+ cellClasses: s(e.cellClasses),
78
+ omnibusText: s(e.omnibusTexts),
79
+ styleTemplate: s(e.styleTemplates)
79
80
  };
80
81
  }
81
82
  const et = {
82
83
  TITLE: "You May Also Like!"
83
84
  }, ot = [
84
- m,
85
- C,
85
+ b,
86
+ _,
86
87
  a,
87
88
  l,
88
- _,
89
- p,
90
- y
89
+ C,
90
+ A,
91
+ p
91
92
  ], nt = {
92
- [m]: !0,
93
- [C]: !0,
93
+ [b]: !0,
94
+ [_]: !0,
94
95
  [l]: !0,
95
96
  [a]: !0,
96
- [_]: !1,
97
- [p]: !1,
98
- [y]: !0
99
- }, M = 10;
100
- function W(t = M) {
97
+ [C]: !1,
98
+ [A]: !1,
99
+ [p]: !0
100
+ }, W = 10;
101
+ function rt(t = W) {
101
102
  return `
102
103
  <tr>
103
104
  <td class="spacer" style="height: ${t}px;"></td>
104
105
  </tr>
105
106
  `;
106
107
  }
107
- const H = W();
108
- function V(t, e) {
108
+ function H(t, e) {
109
109
  return e ? e.pStyle ?? "" : t;
110
110
  }
111
- function rt(t, e, o) {
112
- const n = V(e.pStyle, o), c = o ? o.openTags ?? "" : e.openTags, s = o ? o.closeTags ?? "" : e.closeTags;
113
- return `<p contenteditable="false" style="${n}">${c}${t}${s}</p>`;
111
+ function it(t, e, o) {
112
+ const n = H(e.pStyle, o), c = o ? o.openTags ?? "" : e.openTags, i = o ? o.closeTags ?? "" : e.closeTags;
113
+ return `<p contenteditable="false" style="${n}">${c}${t}${i}</p>`;
114
114
  }
115
115
  function st(t, e) {
116
116
  const o = [];
117
117
  return t && o.push(t), e && o.push(`background-color: ${e};`), o.join(" ");
118
118
  }
119
- function Y(t) {
119
+ function V(t) {
120
120
  return t ? ` background-color: ${t};` : "";
121
121
  }
122
- function it(t) {
123
- const e = Y(t);
122
+ function ct(t) {
123
+ const e = V(t);
124
124
  return e ? ` style="${e.trim()}"` : "";
125
125
  }
126
- function ct(t, e = "") {
126
+ function lt(t, e = "") {
127
127
  return {
128
128
  before: (t == null ? void 0 : t.before) ?? e,
129
129
  after: (t == null ? void 0 : t.after) ?? ""
130
130
  };
131
131
  }
132
- function lt(t, e) {
132
+ function at(t, e) {
133
133
  return `${(e == null ? void 0 : e.openTags) ?? ""}${t}${(e == null ? void 0 : e.closeTags) ?? ""}`;
134
134
  }
135
- function at(t) {
135
+ function ut(t) {
136
136
  return t != null && t.buttonFitToContainer ? "es-button-border es-fw" : "es-button-border";
137
137
  }
138
- const ut = "display: block; max-width: 100%; height: auto;", dt = "border-width: 1px; background: rgb(217, 234, 211); border-color: rgb(106, 168, 79);", gt = "color: rgb(56, 118, 29); background: rgb(217, 234, 211); font-family: arial, 'helvetica neue', helvetica, sans-serif; font-size: 16px; font-weight: normal; line-height: 120%; mso-border-alt: 10px solid rgb(217, 234, 211); mso-padding-alt: 0;", P = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
139
- function bt(t) {
140
- return !t || typeof t != "string" || t.trim() === "" ? P : t.startsWith("http://") ? t.replace("http://", "https://") : t;
138
+ const dt = "display: block; max-width: 100%; height: auto;", gt = "border-width: 1px; background: rgb(217, 234, 211); border-color: rgb(106, 168, 79);", ft = "color: rgb(56, 118, 29); background: rgb(217, 234, 211); font-family: arial, 'helvetica neue', helvetica, sans-serif; font-size: 16px; font-weight: normal; line-height: 120%; mso-border-alt: 10px solid rgb(217, 234, 211); mso-padding-alt: 0;", R = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
139
+ function mt(t) {
140
+ return !t || typeof t != "string" || t.trim() === "" ? R : t.startsWith("http://") ? t.replace("http://", "https://") : t;
141
141
  }
142
- function G(t) {
142
+ function Y(t) {
143
143
  return {
144
144
  name: "Product Name",
145
- image_url: P,
145
+ image_url: R,
146
146
  price: { USD: 18 },
147
147
  original_price: { USD: 20 },
148
148
  discount: { USD: 2 },
@@ -154,19 +154,20 @@ function G(t) {
154
154
  category: []
155
155
  };
156
156
  }
157
- function ft(t = 6) {
157
+ function Tt(t = 6) {
158
158
  return Array.from(
159
159
  { length: t },
160
- (e, o) => G(String(o + 1))
160
+ (e, o) => Y(String(o + 1))
161
161
  );
162
162
  }
163
- function Tt(t = "grid", e) {
163
+ function bt(t = "grid", e) {
164
164
  const o = t === "list" ? `
165
- data-layout="list"` : "", n = e ? ` ${e}` : "";
165
+ data-layout="list"` : "", n = e ? ` ${e}` : "", i = `recommendation-block-v2 esd-block-recommendation-v3-block es-p20${t === "list" ? " es-m-p0 ins-recommendation-list-layout" : ""}${n}`, s = t === "list" ? "" : `
166
+ {-{-MOBILE_PRODUCT_ROWS-}-}`, r = t === "list" ? ' style="display: none;"' : "";
166
167
  return `
167
168
  <td
168
169
  align="left"
169
- class="${`recommendation-block-v2 esd-block-recommendation-v3-block es-p20${t === "list" ? " es-m-p0 ins-recommendation-list-layout" : ""}${n}`}"${o}>
170
+ class="${i}"${o}>
170
171
  <table width="100%" cellpadding="0" cellspacing="0" border="0">
171
172
  <tr>
172
173
  <td align="center">
@@ -177,28 +178,7 @@ function Tt(t = "grid", e) {
177
178
  cellspacing="0"
178
179
  border="0">
179
180
  <tbody>
180
- <tr>
181
- <td>
182
- <table
183
- width="100%"
184
- cellpadding="0"
185
- cellspacing="0"
186
- border="0">
187
- <tbody>
188
- <tr>
189
- <td
190
- class="esd-block-text es-p10t es-p10b es-p20l es-p20r"
191
- align="center">
192
- <p style="font-size: 28px; color: #333333;">
193
- <strong>{-{-TITLE-}-}</strong>
194
- </p>
195
- </td>
196
- </tr>
197
- </tbody>
198
- </table>
199
- </td>
200
- </tr>
201
- ${H}
181
+ ${k()}
202
182
  <tr>
203
183
  <td>
204
184
  <table
@@ -213,7 +193,7 @@ function Tt(t = "grid", e) {
213
193
  </table>
214
194
  </td>
215
195
  </tr>
216
- <tr class="ins-recommendation-mobile-row"${t === "list" ? ' style="display: none;"' : ""}>
196
+ <tr class="ins-recommendation-mobile-row"${r}>
217
197
  <td>
218
198
  <table
219
199
  class="ins-recommendation-product-container
@@ -223,8 +203,7 @@ function Tt(t = "grid", e) {
223
203
  cellspacing="0"
224
204
  border="0"
225
205
  style="display: none;"
226
- >${t === "list" ? "" : `
227
- {-{-MOBILE_PRODUCT_ROWS-}-}`}
206
+ >${s}
228
207
  </table>
229
208
  </td>
230
209
  </tr>
@@ -237,37 +216,36 @@ function Tt(t = "grid", e) {
237
216
  `;
238
217
  }
239
218
  export {
240
- v as CUSTOM_CELL_HTML,
219
+ M as CUSTOM_CELL_HTML,
241
220
  et as DEFAULTS,
242
- gt as DEFAULT_BUTTON_ANCHOR_STYLE,
243
- dt as DEFAULT_BUTTON_BORDER_STYLE,
221
+ ft as DEFAULT_BUTTON_ANCHOR_STYLE,
222
+ gt as DEFAULT_BUTTON_BORDER_STYLE,
244
223
  ot as DEFAULT_CARD_COMPOSITION,
245
224
  nt as DEFAULT_CARD_VISIBILITY,
246
- ut as DEFAULT_IMG_STYLE,
247
- M as DEFAULT_ROW_SPACING_PX,
248
- P as PLACEHOLDER_IMAGE,
249
- Y as bgColorFragment,
225
+ dt as DEFAULT_IMG_STYLE,
226
+ W as DEFAULT_ROW_SPACING_PX,
227
+ R as PLACEHOLDER_IMAGE,
228
+ V as bgColorFragment,
250
229
  tt as buildCellOptions,
251
230
  Z as buildElementRenderer,
252
- W as buildSpacer,
253
- it as cellBgStyleAttr,
254
- Tt as createBlockTemplate,
255
- f as formatProductPrice,
256
- k as getCurrentCurrencyConfig,
257
- ft as getDefaultProducts,
258
- w as isDefaultAttribute,
231
+ rt as buildSpacer,
232
+ ct as cellBgStyleAttr,
233
+ bt as createBlockTemplate,
234
+ m as formatProductPrice,
235
+ x as getCurrentCurrencyConfig,
236
+ Tt as getDefaultProducts,
237
+ v as isDefaultAttribute,
259
238
  q as isSamePrice,
260
- lt as renderButtonLabel,
261
- rt as renderStyledParagraph,
262
- at as resolveButtonBorderClass,
239
+ at as renderButtonLabel,
240
+ it as renderStyledParagraph,
241
+ ut as resolveButtonBorderClass,
263
242
  J as resolveInlinePriceOrder,
264
- ct as resolveOmnibusText,
265
- V as resolvePStyle,
266
- F as resolveProductAttrValue,
243
+ lt as resolveOmnibusText,
244
+ H as resolvePStyle,
245
+ w as resolveProductAttrValue,
267
246
  st as resolveSegmentBgStyle,
268
- bt as sanitizeImageUrl,
269
- H as spacer,
247
+ mt as sanitizeImageUrl,
270
248
  Q as toCustomCompositionKey,
271
- x as toDisplayName,
272
- N as toDisplayableAttributeValue
249
+ N as toDisplayName,
250
+ F as toDisplayableAttributeValue
273
251
  };
@@ -0,0 +1,22 @@
1
+ import { ModificationDescription as f } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { RECOMMENDATION_ID_ATTR as m } from "../constants/selectors.js";
3
+ import { isPartnerManagedBlock as a, updateProductContentInPlace as d, regenerateProductRowsWithStyles as l } from "../controls/main/utils.js";
4
+ import { RecommendationConfigService as s } from "../services/configService.js";
5
+ let e = null;
6
+ function N(r) {
7
+ e = r;
8
+ }
9
+ function D(r, c, i, u) {
10
+ const n = e == null ? void 0 : e.getDocumentRootHtmlNode();
11
+ if (!e || !n || !("querySelector" in n))
12
+ return !1;
13
+ const t = n.querySelector(`[${m}="${r}"]`);
14
+ if (!t)
15
+ return !1;
16
+ const o = e.getDocumentModifier();
17
+ return s.stageConfig(o, t, c), a(t) ? (o.apply(new f(u)), !0) : (d({ currentNode: t, documentModifier: o, products: i }) || l({ currentNode: t, documentModifier: o, products: i }), !0);
18
+ }
19
+ export {
20
+ D as commitBlockChangeOutsidePanel,
21
+ N as registerNodeConfigWriter
22
+ };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-e6f99d29]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-e6f99d29]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-e6f99d29]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}
1
+ @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-5c588dc5]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-5c588dc5]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-5c588dc5]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2
+ export default _default;
@@ -1,4 +1,12 @@
1
1
  export declare function extractTitleText(block: Element): string;
2
+ /**
3
+ * Fallback for legacy configs that carry no `p_recommendation_title` variable:
4
+ * the rendered HTML decides. A missing or `display: none` title container means
5
+ * the user never saw a title, so the migrated block keeps it toggled off.
6
+ * @param block - The legacy recommendation block element
7
+ * @returns True when the legacy block renders a visible title
8
+ */
9
+ export declare function hasVisibleTitle(block: Element): boolean;
2
10
  /**
3
11
  * Card background lives on either the block (`bgcolor`/`style`) or per-card
4
12
  * cells (`.product-card`). Returns empty string when no background is set —