@liquidcommercedev/rmn-sdk 1.5.0-beta.1 → 1.5.0-beta.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. package/dist/index.cjs +1192 -407
  2. package/dist/index.esm.js +1193 -408
  3. package/dist/types/common/helpers/utils.helper.d.ts +50 -0
  4. package/dist/types/enums.d.ts +6 -1
  5. package/dist/types/modules/element/element.interface.d.ts +5 -2
  6. package/dist/types/modules/event/event.interface.d.ts +6 -32
  7. package/dist/types/modules/event/event.service.d.ts +7 -22
  8. package/dist/types/modules/event/index.d.ts +0 -1
  9. package/dist/types/modules/{event/helpers → helper-service}/index.d.ts +1 -0
  10. package/dist/types/modules/{event/helpers → helper-service}/intersection.service.d.ts +1 -1
  11. package/dist/types/modules/helper-service/localstorage.service.d.ts +56 -0
  12. package/dist/types/modules/{event/pubsub.d.ts → helper-service/pubsub.service.d.ts} +8 -8
  13. package/dist/types/modules/{event/helpers → helper-service}/resize.service.d.ts +1 -1
  14. package/dist/types/modules/monitor/index.d.ts +2 -0
  15. package/dist/types/modules/monitor/monitor.enums.d.ts +4 -0
  16. package/dist/types/modules/monitor/monitor.interface.d.ts +11 -0
  17. package/dist/types/modules/monitor/monitor.service.d.ts +12 -0
  18. package/dist/types/modules/monitor/monitors/datalayer.monitor.d.ts +12 -0
  19. package/dist/types/modules/selection/selection.interface.d.ts +3 -1
  20. package/dist/types/rmn-client.d.ts +1 -1
  21. package/dist/types/types.d.ts +5 -4
  22. package/package.json +1 -1
  23. package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
  24. package/dist/types/modules/element/component/utils.d.ts +0 -1
  25. package/dist/types/modules/event/helpers/localstorage.service.d.ts +0 -26
  26. /package/dist/types/{static.constant.d.ts → example.constant.d.ts} +0 -0
package/dist/index.cjs CHANGED
@@ -3,6 +3,7 @@
3
3
  exports.RMN_SPOT_TYPE = void 0;
4
4
  (function (RMN_SPOT_TYPE) {
5
5
  // Reserve Bar Spot Types
6
+ RMN_SPOT_TYPE["RB_HOMEPAGE_HERO"] = "rbHomepageHero";
6
7
  RMN_SPOT_TYPE["RB_HOMEPAGE_HERO_THREE_TILE"] = "rbHomepageHeroThreeTile";
7
8
  RMN_SPOT_TYPE["RB_HOMEPAGE_HERO_TWO_TILE"] = "rbHomepageHeroTwoTile";
8
9
  RMN_SPOT_TYPE["RB_HOMEPAGE_HERO_FULL_IMAGE"] = "rbHomepageHeroFullImage";
@@ -54,13 +55,18 @@ exports.RMN_FILTER_PROPERTIES = void 0;
54
55
  RMN_FILTER_PROPERTIES["PUBLISHERS"] = "publishers";
55
56
  RMN_FILTER_PROPERTIES["SECTION"] = "section";
56
57
  })(exports.RMN_FILTER_PROPERTIES || (exports.RMN_FILTER_PROPERTIES = {}));
58
+ exports.RMN_EVENT = void 0;
59
+ (function (RMN_EVENT) {
60
+ RMN_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
61
+ RMN_EVENT["SPOT_EVENT"] = "SPOT_EVENT";
62
+ })(exports.RMN_EVENT || (exports.RMN_EVENT = {}));
57
63
  exports.RMN_SPOT_EVENT = void 0;
58
64
  (function (RMN_SPOT_EVENT) {
59
- RMN_SPOT_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
60
65
  RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
61
66
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
62
67
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
63
68
  RMN_SPOT_EVENT["ADD_TO_CART"] = "ADD_TO_CART";
69
+ RMN_SPOT_EVENT["REMOVE_FROM_CART"] = "REMOVE_FROM_CART";
64
70
  RMN_SPOT_EVENT["ADD_TO_WISHLIST"] = "ADD_TO_WISHLIST";
65
71
  RMN_SPOT_EVENT["BUY_NOW"] = "BUY_NOW";
66
72
  })(exports.RMN_SPOT_EVENT || (exports.RMN_SPOT_EVENT = {}));
@@ -72,6 +78,511 @@ exports.RMN_ENV = void 0;
72
78
  RMN_ENV["PRODUCTION"] = "production";
73
79
  })(exports.RMN_ENV || (exports.RMN_ENV = {}));
74
80
 
81
+ const SPOT_EVENTS_EXAMPLE = [
82
+ {
83
+ event: exports.RMN_SPOT_EVENT.CLICK,
84
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwidXIiOm51bGx9&s=hWz37kbxi_u95EVNn2aoQhc5Aas',
85
+ },
86
+ {
87
+ event: exports.RMN_SPOT_EVENT.IMPRESSION,
88
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiYmEiOjEsImZxIjowfQ&s=djoysjCimurf-5T11AlNAwwLSS8',
89
+ },
90
+ {
91
+ event: exports.RMN_SPOT_EVENT.PURCHASE,
92
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjU5fQ&s=AAPAw-3SfZ0JMzjEGFSwt9L-2S4',
93
+ },
94
+ {
95
+ event: exports.RMN_SPOT_EVENT.ADD_TO_CART,
96
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYwfQ&s=uzQFcjgL7m9XqUG8FvTPVN5YkZY',
97
+ },
98
+ {
99
+ event: exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST,
100
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYzfQ&s=m3ISU_iIy-OFtXrTKpI6cJAEC0k',
101
+ },
102
+ {
103
+ event: exports.RMN_SPOT_EVENT.BUY_NOW,
104
+ url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjY5fQ&s=l6MOscQC-q-FkC2Ksd7w6jjySCQ',
105
+ },
106
+ ];
107
+ const RB_SPOTS_SELECTION_EXAMPLE = {
108
+ rbHomepageHero: [
109
+ {
110
+ id: 'abc123',
111
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
112
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
113
+ width: 1140,
114
+ height: 640,
115
+ header: 'Premium Wine Collection',
116
+ description: 'Discover our exclusive selection of vintage wines',
117
+ ctaText: 'Shop Wines',
118
+ textColor: '#ffffff',
119
+ ctaTextColor: '#ffffff',
120
+ primaryImage: 'https://placehold.co/1140x640/png?text=Wine+Collection',
121
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Wine',
122
+ events: SPOT_EVENTS_EXAMPLE,
123
+ productIds: [1, 2, 3],
124
+ },
125
+ {
126
+ id: 'jkl012',
127
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
128
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
129
+ width: 1140,
130
+ height: 640,
131
+ header: 'Whiskey Collection',
132
+ description: 'Premium whiskeys from around the world',
133
+ ctaText: 'Shop Whiskeys',
134
+ textColor: '#ffffff',
135
+ backgroundColor: '#2c1810',
136
+ ctaTextColor: '#2c1810',
137
+ primaryImage: 'https://placehold.co/1140x640/png?text=Whiskey',
138
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Whiskey',
139
+ events: SPOT_EVENTS_EXAMPLE,
140
+ productIds: [10, 11],
141
+ },
142
+ {
143
+ id: 'stu901',
144
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
145
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
146
+ width: 1140,
147
+ height: 640,
148
+ header: 'Summer Cocktails',
149
+ description: 'Essential spirits for summer mixing',
150
+ ctaText: 'Mix It Up',
151
+ textColor: '#ffffff',
152
+ backgroundColor: '#4d3a0a',
153
+ ctaTextColor: '#4d3a0a',
154
+ primaryImage: 'https://placehold.co/1140x640/png?text=Cocktails',
155
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Mixers',
156
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Cocktails',
157
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Mixers',
158
+ events: SPOT_EVENTS_EXAMPLE,
159
+ productIds: [16, 17, 18],
160
+ },
161
+ {
162
+ id: 'def456',
163
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
164
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
165
+ width: 1140,
166
+ height: 640,
167
+ header: 'Craft Beer Festival',
168
+ description: 'Local breweries and exclusive releases',
169
+ ctaText: 'Explore Beers',
170
+ textColor: '#ffffff',
171
+ ctaTextColor: '#ffffff',
172
+ primaryImage: 'https://placehold.co/1140x640/png?text=Beer+Festival',
173
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Beer',
174
+ events: SPOT_EVENTS_EXAMPLE,
175
+ productIds: [4, 5, 6],
176
+ },
177
+ {
178
+ id: 'mno345',
179
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
180
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
181
+ width: 1140,
182
+ height: 640,
183
+ header: 'Champagne Selection',
184
+ description: 'Finest champagnes for every occasion',
185
+ ctaText: 'View Champagnes',
186
+ textColor: '#ffffff',
187
+ backgroundColor: '#1a1a1a',
188
+ ctaTextColor: '#1a1a1a',
189
+ primaryImage: 'https://placehold.co/1140x640/png?text=Champagne',
190
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Champagne',
191
+ events: SPOT_EVENTS_EXAMPLE,
192
+ productIds: [12, 13],
193
+ },
194
+ {
195
+ id: 'vwx234',
196
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
197
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
198
+ width: 1140,
199
+ height: 640,
200
+ header: 'Wine Regions',
201
+ description: 'Explore wines from top regions',
202
+ ctaText: 'Tour Regions',
203
+ textColor: '#ffffff',
204
+ backgroundColor: '#4d0a0a',
205
+ ctaTextColor: '#4d0a0a',
206
+ primaryImage: 'https://placehold.co/1140x640/png?text=Wine+Regions',
207
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Vineyards',
208
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Regions',
209
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Vineyards',
210
+ events: SPOT_EVENTS_EXAMPLE,
211
+ productIds: [19, 20, 21],
212
+ },
213
+ {
214
+ id: 'ghi789',
215
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
216
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
217
+ width: 1140,
218
+ height: 640,
219
+ header: 'Rare Spirits',
220
+ description: 'Limited edition spirits collection',
221
+ ctaText: 'View Collection',
222
+ textColor: '#ffffff',
223
+ ctaTextColor: '#ffffff',
224
+ primaryImage: 'https://placehold.co/1140x640/png?text=Rare+Spirits',
225
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Spirits',
226
+ events: SPOT_EVENTS_EXAMPLE,
227
+ productIds: [7, 8, 9],
228
+ },
229
+ {
230
+ id: 'pqr678',
231
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
232
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
233
+ width: 1140,
234
+ height: 640,
235
+ header: 'Gin Collection',
236
+ description: 'Artisanal gins and botanicals',
237
+ ctaText: 'Explore Gins',
238
+ textColor: '#ffffff',
239
+ backgroundColor: '#0a4d4d',
240
+ ctaTextColor: '#0a4d4d',
241
+ primaryImage: 'https://placehold.co/1140x640/png?text=Gin',
242
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Gin',
243
+ events: SPOT_EVENTS_EXAMPLE,
244
+ productIds: [14, 15],
245
+ },
246
+ {
247
+ id: 'yz5678',
248
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
249
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
250
+ width: 1140,
251
+ height: 640,
252
+ header: 'Tequila Collection',
253
+ description: 'Premium tequilas and mezcals',
254
+ ctaText: 'Shop Tequila',
255
+ textColor: '#ffffff',
256
+ backgroundColor: '#0a4d2b',
257
+ ctaTextColor: '#0a4d2b',
258
+ primaryImage: 'https://placehold.co/1140x640/png?text=Tequila',
259
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Mezcal',
260
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Tequila',
261
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Mezcal',
262
+ events: SPOT_EVENTS_EXAMPLE,
263
+ productIds: [22, 23, 24],
264
+ },
265
+ ],
266
+ rbHomepageHeroFullImage: [
267
+ {
268
+ id: 'hjk567',
269
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
270
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
271
+ width: 1140,
272
+ height: 640,
273
+ header: 'Holiday Gift Guide',
274
+ description: 'Perfect spirits for every occasion',
275
+ ctaText: 'Shop Gifts',
276
+ textColor: '#ffffff',
277
+ ctaTextColor: '#ffffff',
278
+ primaryImage: 'https://placehold.co/1140x640/png?text=Gift+Guide',
279
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Gifts',
280
+ events: SPOT_EVENTS_EXAMPLE,
281
+ productIds: [25, 26],
282
+ },
283
+ {
284
+ id: 'qwe890',
285
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
286
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
287
+ width: 1140,
288
+ height: 640,
289
+ header: 'Summer Wine Festival',
290
+ description: 'Refreshing wines for summer',
291
+ ctaText: 'Shop Festival',
292
+ textColor: '#ffffff',
293
+ ctaTextColor: '#ffffff',
294
+ primaryImage: 'https://placehold.co/1140x640/png?text=Wine+Festival',
295
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Festival',
296
+ events: SPOT_EVENTS_EXAMPLE,
297
+ productIds: [27, 28],
298
+ },
299
+ ],
300
+ rbHomepageHeroTwoTile: [
301
+ {
302
+ id: 'iop987',
303
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
304
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
305
+ width: 1140,
306
+ height: 640,
307
+ header: 'Bourbon Selection',
308
+ description: "Kentucky's finest bourbons",
309
+ ctaText: 'Shop Bourbon',
310
+ textColor: '#ffffff',
311
+ backgroundColor: '#2c1810',
312
+ ctaTextColor: '#2c1810',
313
+ primaryImage: 'https://placehold.co/1140x640/png?text=Bourbon',
314
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Bourbon',
315
+ events: SPOT_EVENTS_EXAMPLE,
316
+ productIds: [29, 30],
317
+ },
318
+ {
319
+ id: 'lkj012',
320
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
321
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
322
+ width: 1140,
323
+ height: 640,
324
+ header: 'Vodka Collection',
325
+ description: 'Premium vodkas from around the world',
326
+ ctaText: 'Shop Vodka',
327
+ textColor: '#ffffff',
328
+ backgroundColor: '#1a1a1a',
329
+ ctaTextColor: '#1a1a1a',
330
+ primaryImage: 'https://placehold.co/1140x640/png?text=Vodka',
331
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Vodka',
332
+ events: SPOT_EVENTS_EXAMPLE,
333
+ productIds: [31, 32],
334
+ },
335
+ ],
336
+ rbHomepageHeroThreeTile: [
337
+ {
338
+ id: 'bnm345',
339
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
340
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
341
+ width: 1140,
342
+ height: 640,
343
+ header: 'Rum Collection',
344
+ description: 'Caribbean and craft rums',
345
+ ctaText: 'Shop Rum',
346
+ textColor: '#ffffff',
347
+ backgroundColor: '#4d3a0a',
348
+ ctaTextColor: '#4d3a0a',
349
+ primaryImage: 'https://placehold.co/1140x640/png?text=Rum',
350
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Craft+Rum',
351
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Rum',
352
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Craft',
353
+ events: SPOT_EVENTS_EXAMPLE,
354
+ productIds: [33, 34],
355
+ },
356
+ {
357
+ id: 'fgh678',
358
+ spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
359
+ variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
360
+ width: 1140,
361
+ height: 640,
362
+ header: 'Scotch Selection',
363
+ description: 'Single malts and blends',
364
+ ctaText: 'Shop Scotch',
365
+ textColor: '#ffffff',
366
+ backgroundColor: '#4d0a0a',
367
+ ctaTextColor: '#4d0a0a',
368
+ primaryImage: 'https://placehold.co/1140x640/png?text=Scotch',
369
+ secondaryImage: 'https://placehold.co/1140x640/png?text=Single+Malts',
370
+ mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Scotch',
371
+ mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Malts',
372
+ events: SPOT_EVENTS_EXAMPLE,
373
+ productIds: [35, 36],
374
+ },
375
+ ],
376
+ rbLargeCategoryImageTout: [
377
+ {
378
+ id: 'cde567',
379
+ spot: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
380
+ variant: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
381
+ width: 468,
382
+ height: 410,
383
+ header: 'Rare & Limited Edition',
384
+ description: 'Discover our collection of hard-to-find and limited release spirits.',
385
+ textColor: '#ffffff',
386
+ ctaTextColor: '#ffffff',
387
+ primaryImage: 'https://placehold.co/468x410/png?text=Rare+Spirits',
388
+ mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Rare+Spirits',
389
+ ctaText: 'Shop Rare Spirits',
390
+ events: SPOT_EVENTS_EXAMPLE,
391
+ productIds: [37, 38, 39, 40, 41],
392
+ },
393
+ {
394
+ id: 'efg789',
395
+ spot: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
396
+ variant: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
397
+ width: 468,
398
+ height: 410,
399
+ header: 'Vintage Champagnes',
400
+ description: 'Explore our prestigious collection of aged champagnes.',
401
+ textColor: '#ffffff',
402
+ ctaTextColor: '#ffffff',
403
+ primaryImage: 'https://placehold.co/468x410/png?text=Vintage+Champagne',
404
+ mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Champagne',
405
+ ctaText: 'View Collection',
406
+ events: SPOT_EVENTS_EXAMPLE,
407
+ productIds: [42, 43, 44, 45, 46],
408
+ },
409
+ {
410
+ id: 'ghi012',
411
+ spot: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
412
+ variant: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
413
+ width: 468,
414
+ height: 410,
415
+ header: 'Small Batch Bourbon',
416
+ description: 'Hand-selected premium bourbon from craft distilleries.',
417
+ textColor: '#ffffff',
418
+ ctaTextColor: '#ffffff',
419
+ primaryImage: 'https://placehold.co/468x410/png?text=Craft+Bourbon',
420
+ mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Bourbon',
421
+ ctaText: 'Explore Bourbon',
422
+ events: SPOT_EVENTS_EXAMPLE,
423
+ productIds: [47, 48, 49, 50, 51],
424
+ },
425
+ ],
426
+ rbSmallDiscoverTout: [
427
+ {
428
+ id: 'jkl345',
429
+ spot: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
430
+ variant: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
431
+ width: 224,
432
+ height: 378,
433
+ header: 'Château Margaux 2015 Bordeaux',
434
+ textColor: '#ffffff',
435
+ primaryImage: 'https://placehold.co/224x378/png?text=Château+Margaux',
436
+ mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Château+Margaux',
437
+ events: SPOT_EVENTS_EXAMPLE,
438
+ productIds: [52, 53, 54, 55, 56],
439
+ },
440
+ {
441
+ id: 'lmn678',
442
+ spot: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
443
+ variant: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
444
+ width: 224,
445
+ height: 378,
446
+ header: 'Macallan 25 Year',
447
+ textColor: '#ffffff',
448
+ primaryImage: 'https://placehold.co/224x378/png?text=Macallan+25',
449
+ mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Macallan',
450
+ events: SPOT_EVENTS_EXAMPLE,
451
+ productIds: [57, 58, 59, 60, 61],
452
+ },
453
+ {
454
+ id: 'nop901',
455
+ spot: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
456
+ variant: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
457
+ width: 224,
458
+ height: 378,
459
+ header: 'Louis XIII Cognac',
460
+ textColor: '#ffffff',
461
+ primaryImage: 'https://placehold.co/224x378/png?text=Louis+XIII',
462
+ mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Louis+XIII',
463
+ events: SPOT_EVENTS_EXAMPLE,
464
+ productIds: [62, 63, 64, 65, 66],
465
+ },
466
+ ],
467
+ rbSmallCategoryImageTout: [
468
+ {
469
+ id: 'qrs234',
470
+ spot: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
471
+ variant: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
472
+ width: 224,
473
+ height: 410,
474
+ header: 'Japanese Sake',
475
+ textColor: '#ffffff',
476
+ primaryImage: 'https://placehold.co/224x410/png?text=Japanese+Sake',
477
+ mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Japanese+Sake',
478
+ events: SPOT_EVENTS_EXAMPLE,
479
+ productIds: [67, 68, 69, 70, 71],
480
+ },
481
+ {
482
+ id: 'stu567',
483
+ spot: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
484
+ variant: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
485
+ width: 224,
486
+ height: 410,
487
+ header: 'Craft Vermouth',
488
+ textColor: '#ffffff',
489
+ primaryImage: 'https://placehold.co/224x410/png?text=Craft+Vermouth',
490
+ mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Vermouth',
491
+ events: SPOT_EVENTS_EXAMPLE,
492
+ productIds: [72, 73, 74, 75, 76],
493
+ },
494
+ {
495
+ id: 'vwx890',
496
+ spot: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
497
+ variant: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
498
+ width: 224,
499
+ height: 410,
500
+ header: 'Premium Mezcal',
501
+ textColor: '#ffffff',
502
+ primaryImage: 'https://placehold.co/224x410/png?text=Premium+Mezcal',
503
+ mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Mezcal',
504
+ events: SPOT_EVENTS_EXAMPLE,
505
+ productIds: [77, 78, 79, 80, 81],
506
+ },
507
+ ],
508
+ rbCollectionBannerWithoutTextBlock: [
509
+ {
510
+ id: 'yz1234',
511
+ spot: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
512
+ variant: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
513
+ width: 887,
514
+ height: 344,
515
+ primaryImage: 'https://placehold.co/887x344/png?text=Summer+Cocktails',
516
+ mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Summer+Cocktails',
517
+ events: SPOT_EVENTS_EXAMPLE,
518
+ productIds: [82, 83, 84, 85, 86],
519
+ },
520
+ {
521
+ id: 'abc567',
522
+ spot: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
523
+ variant: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
524
+ width: 887,
525
+ height: 344,
526
+ primaryImage: 'https://placehold.co/887x344/png?text=Holiday+Spirits',
527
+ mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Holiday+Spirits',
528
+ events: SPOT_EVENTS_EXAMPLE,
529
+ productIds: [87, 88, 89, 90, 91],
530
+ },
531
+ {
532
+ id: 'def901',
533
+ spot: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
534
+ variant: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
535
+ width: 887,
536
+ height: 344,
537
+ primaryImage: 'https://placehold.co/887x344/png?text=Wine+Essentials',
538
+ mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Wine+Essentials',
539
+ events: SPOT_EVENTS_EXAMPLE,
540
+ productIds: [92, 93, 94, 95, 96],
541
+ },
542
+ ],
543
+ rbNavigationBanner: [
544
+ {
545
+ id: 'ghi234',
546
+ spot: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
547
+ variant: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
548
+ width: 440,
549
+ height: 220,
550
+ header: 'Explore Tequilas',
551
+ textColor: '#ffffff',
552
+ primaryImage: 'https://placehold.co/440x220/png?text=Tequila+Collection',
553
+ mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Tequila+Collection',
554
+ events: SPOT_EVENTS_EXAMPLE,
555
+ productIds: [97, 98, 99, 100, 101],
556
+ },
557
+ {
558
+ id: 'jkl678',
559
+ spot: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
560
+ variant: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
561
+ width: 440,
562
+ height: 220,
563
+ header: 'Craft Gin Selection',
564
+ textColor: '#ffffff',
565
+ primaryImage: 'https://placehold.co/440x220/png?text=Gin+Selection',
566
+ mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Gin+Selection',
567
+ events: SPOT_EVENTS_EXAMPLE,
568
+ productIds: [102, 103, 104, 105, 106],
569
+ },
570
+ {
571
+ id: 'mno012',
572
+ spot: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
573
+ variant: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
574
+ width: 440,
575
+ height: 220,
576
+ header: 'Premium Vodka',
577
+ textColor: '#ffffff',
578
+ primaryImage: 'https://placehold.co/440x220/png?text=Vodka+Premium',
579
+ mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Vodka+Premium',
580
+ events: SPOT_EVENTS_EXAMPLE,
581
+ productIds: [107, 108, 109, 110, 111],
582
+ },
583
+ ],
584
+ };
585
+
75
586
  const REQUEST_CLOUD_PARTNER_SITE = 'X-Liquid-Partner-Site';
76
587
  const REQUEST_CLOUD_PROTECTED_KEY = 'X-Liquid-Protected';
77
588
  const REQUEST_CLOUD_PROTECTED_TIMESTAMP = 'X-Liquid-Timestamp';
@@ -15141,29 +15652,230 @@ class AuthService extends BaseApi {
15141
15652
  if (isErr) {
15142
15653
  throw new Error(`There was an error during authentication: (${isErr === null || isErr === void 0 ? void 0 : isErr.errorMessage})`);
15143
15654
  }
15144
- if (isOk && (val === null || val === void 0 ? void 0 : val.data.token)) {
15145
- this.authInfo.token = val.data.token;
15146
- this.authInfo.authenticated = true;
15655
+ if (isOk && (val === null || val === void 0 ? void 0 : val.data.token)) {
15656
+ this.authInfo.token = val.data.token;
15657
+ this.authInfo.authenticated = true;
15658
+ }
15659
+ else {
15660
+ throw new Error('Auth response was not successful');
15661
+ }
15662
+ return this.authInfo;
15663
+ }
15664
+ }
15665
+
15666
+ const SPOT_ELEMENT_TAG = 'spot-element';
15667
+ const CAROUSEL_ELEMENT_TAG = 'spot-carousel-element';
15668
+ const GFONT_PRECONNECT = `
15669
+ <link rel="preconnect" href="https://fonts.googleapis.com">
15670
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15671
+ `;
15672
+ const GFONT_SOURCE_SANS_3 = `
15673
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15674
+ `;
15675
+ const GFONT_CORMORANT = `
15676
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15677
+ `;
15678
+
15679
+ /**
15680
+ * Determines the event type from a raw event string.
15681
+ *
15682
+ * @param {string} [event] - The raw event string to evaluate.
15683
+ * @returns {RMN_SPOT_EVENT | null} - The corresponding RMN_SPOT_EVENT or null if no match is found.
15684
+ */
15685
+ function getEventTypeFromRawEvent(event) {
15686
+ if (!event) {
15687
+ return null;
15688
+ }
15689
+ if (event.includes('cart')) {
15690
+ if (event.includes('add')) {
15691
+ return exports.RMN_SPOT_EVENT.ADD_TO_CART;
15692
+ }
15693
+ if (event.includes('remove')) {
15694
+ return exports.RMN_SPOT_EVENT.REMOVE_FROM_CART;
15695
+ }
15696
+ }
15697
+ if (event.includes('purchase')) {
15698
+ return exports.RMN_SPOT_EVENT.PURCHASE;
15699
+ }
15700
+ // if(event.includes('refund')) {
15701
+ // return RMN_SPOT_EVENT.REFUND;
15702
+ // }
15703
+ if (event.includes('wishlist') && event.includes('add')) {
15704
+ return exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST;
15705
+ }
15706
+ return null;
15707
+ }
15708
+ /**
15709
+ * Recursively extracts ID values from a nested data structure.
15710
+ * Searches for specified property names and collects their primitive values (strings/numbers).
15711
+ *
15712
+ * @param data - The data structure to search through (can be nested objects/arrays)
15713
+ * @param propertyNames - Array of property names to look for
15714
+ * @returns Array of extracted ID values (strings/numbers only)
15715
+ *
15716
+ * @example
15717
+ * const data = {
15718
+ * id: [1, 2, 3],
15719
+ * nested: { id: 'abc' },
15720
+ * items: [{ id: 456 }]
15721
+ * };
15722
+ * extractDeepIds(data); // Returns [1, 2, 3, 'abc', 456]
15723
+ */
15724
+ function extractDeepIds(data, propertyNames) {
15725
+ const ids = [];
15726
+ const defaulPropertyNames = [
15727
+ 'id',
15728
+ 'upc',
15729
+ 'groupingId',
15730
+ 'sku',
15731
+ 'productId',
15732
+ 'item_id',
15733
+ 'isbn',
15734
+ 'asin',
15735
+ 'mpn',
15736
+ 'model_number',
15737
+ 'article_number',
15738
+ 'variant_id',
15739
+ 'item_number',
15740
+ 'catalog_id',
15741
+ 'reference_id',
15742
+ ];
15743
+ // Set for faster property name lookups
15744
+ const propertySet = new Set(defaulPropertyNames);
15745
+ /**
15746
+ * Processes a value and extracts IDs if it matches criteria
15747
+ * @param value - The value to process
15748
+ * @param currentKey - The property name of the current value
15749
+ */
15750
+ const processValue = (value, currentKey) => {
15751
+ // Early exit for null/undefined values
15752
+ if (value == null)
15753
+ return;
15754
+ // If current key matches our target properties
15755
+ if (currentKey && propertySet.has(currentKey)) {
15756
+ if (Array.isArray(value)) {
15757
+ // Filter and push valid array values in one pass
15758
+ ids.push(...value.filter((item) => typeof item === 'string' || typeof item === 'number'));
15759
+ }
15760
+ else if (typeof value === 'string' || typeof value === 'number') {
15761
+ ids.push(value);
15762
+ }
15763
+ return; // Stop processing this branch after handling the ID
15764
+ }
15765
+ // Recursively process nested structures
15766
+ if (Array.isArray(value)) {
15767
+ value.forEach((item) => processValue(item));
15147
15768
  }
15148
- else {
15149
- throw new Error('Auth response was not successful');
15769
+ else if (typeof value === 'object') {
15770
+ // Process all enumerable properties
15771
+ for (const [key, val] of Object.entries(value)) {
15772
+ processValue(val, key);
15773
+ }
15150
15774
  }
15151
- return this.authInfo;
15775
+ };
15776
+ processValue(data);
15777
+ return ids; // No need to filter nulls as we handle that during collection
15778
+ }
15779
+ // Fallback method using fetch if sendBeacon isn't available
15780
+ async function fallbackEventFire(url) {
15781
+ try {
15782
+ const racePromise = Promise.race([
15783
+ // Promise #1: The fetch request
15784
+ fetch(url, {
15785
+ method: 'POST',
15786
+ keepalive: true,
15787
+ }),
15788
+ // Promise #2: The timeout
15789
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Request timeout')), 2000)),
15790
+ ]);
15791
+ /**
15792
+ * Prevent requests from hanging indefinitely
15793
+ * Improve user experience by failing fast
15794
+ * Handle slow network conditions gracefully
15795
+ * Ensure resources are freed up in a timely manner
15796
+ */
15797
+ const response = await racePromise;
15798
+ return response.ok;
15799
+ }
15800
+ catch (_a) {
15801
+ return false;
15152
15802
  }
15153
15803
  }
15154
-
15155
- const SPOT_ELEMENT_TAG = 'spot-element';
15156
- const CAROUSEL_ELEMENT_TAG = 'spot-carousel-element';
15157
- const GFONT_PRECONNECT = `
15158
- <link rel="preconnect" href="https://fonts.googleapis.com">
15159
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15160
- `;
15161
- const GFONT_SOURCE_SANS_3 = `
15162
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15163
- `;
15164
- const GFONT_CORMORANT = `
15165
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15166
- `;
15804
+ /**
15805
+ * Extracts and decodes a URL from a base64-encoded query parameter.
15806
+ *
15807
+ * @param {string} url - The URL containing the base64-encoded query parameter.
15808
+ * @returns {string | null} - The decoded URL or null if not found or invalid.
15809
+ */
15810
+ function getRedirectUrlFromPayload(url) {
15811
+ try {
15812
+ const base64String = new URL(url).searchParams.get('e');
15813
+ if (!base64String) {
15814
+ return null;
15815
+ }
15816
+ const data = JSON.parse(atob(base64String));
15817
+ return data.ur || null;
15818
+ }
15819
+ catch (_a) {
15820
+ return null;
15821
+ }
15822
+ }
15823
+ /**
15824
+ * Fires an event using the navigator.sendBeacon method or a fallback method if sendBeacon is not available.
15825
+ * If the event is a click event and a redirect URL is found, it redirects the user to that URL.
15826
+ *
15827
+ * @param {IFireEventParams} params - The parameters for firing the event.
15828
+ * @param {RMN_SPOT_EVENT} params.event - The event type.
15829
+ * @param {string} params.eventUrl - The URL to which the event is sent.
15830
+ * @returns {Promise<void>} - A promise that resolves when the event is fired.
15831
+ */
15832
+ async function fireEvent({ event, eventUrl }) {
15833
+ var _a;
15834
+ try {
15835
+ const didFireEvent = ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.sendBeacon) === null || _a === void 0 ? void 0 : _a.call(navigator, eventUrl)) || (await fallbackEventFire(eventUrl));
15836
+ if (!didFireEvent) {
15837
+ return;
15838
+ }
15839
+ if (event === exports.RMN_SPOT_EVENT.CLICK) {
15840
+ const redirectUrl = getRedirectUrlFromPayload(eventUrl);
15841
+ if (redirectUrl) {
15842
+ window.location.href = redirectUrl;
15843
+ }
15844
+ }
15845
+ }
15846
+ catch (_b) {
15847
+ // Handle errors silently
15848
+ }
15849
+ }
15850
+ function calculateScaleFactor(elementScale) {
15851
+ // Step 1: Apply square root for non-linear scaling
15852
+ // This creates a more gradual scaling effect, especially for larger changes
15853
+ // For example:
15854
+ // - elementScale of 0.25 (1/4 size) becomes 0.5
15855
+ // - elementScale of 1 (unchanged) remains 1
15856
+ // - elementScale of 4 (4x size) becomes 2
15857
+ const baseFactor = Math.sqrt(elementScale);
15858
+ // Step 2: Apply additional dampening to further soften the scaling effect
15859
+ // The dampening factor (0.5) can be adjusted:
15860
+ // - Lower values (closer to 0) make scaling more subtle
15861
+ // - Higher values (closer to 1) make scaling more pronounced
15862
+ const dampening = 0.35;
15863
+ // Calculate the scaleFactor:
15864
+ // 1. (baseFactor - 1) represents the change from the original size
15865
+ // 2. Multiply by dampening to reduce the effect
15866
+ // 3. Add 1 to center the scaling around the original size
15867
+ // For example, if baseFactor is 2:
15868
+ // scaleFactor = 1 + (2 - 1) * 0.5 = 1.5
15869
+ const scaleFactor = 1 + (baseFactor - 1) * dampening;
15870
+ // Step 3: Define the allowed range for the scale factor
15871
+ // This ensures that the font size never changes too drastically
15872
+ const minScale = 0.35; // Font will never be smaller than 50% of original
15873
+ const maxScale = 1.5; // Font will never be larger than 150% of original
15874
+ // Step 4: Clamp the scale factor to the defined range
15875
+ // Math.min ensures the value doesn't exceed maxScale
15876
+ // Math.max ensures the value isn't less than minScale
15877
+ return Math.max(minScale, Math.min(maxScale, scaleFactor));
15878
+ }
15167
15879
 
15168
15880
  class IntersectionObserverService {
15169
15881
  constructor(defaultOptions = {}) {
@@ -15205,8 +15917,21 @@ class IntersectionObserverService {
15205
15917
  }
15206
15918
  }
15207
15919
 
15208
- class LocalStorage {
15920
+ var ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX;
15921
+ (function (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX) {
15922
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PLACEMENT_ID"] = 0] = "PLACEMENT_ID";
15923
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_ID"] = 1] = "SPOT_ID";
15924
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_TYPE"] = 2] = "SPOT_TYPE";
15925
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["EVENTS"] = 3] = "EVENTS";
15926
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 4] = "PRODUCT_IDS";
15927
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 5] = "CREATED_AT";
15928
+ })(ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX || (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX = {}));
15929
+ class LocalStorageService {
15209
15930
  constructor() {
15931
+ if (typeof window.localStorage === 'undefined') {
15932
+ console.warn('Local storage is not supported in this environment');
15933
+ return;
15934
+ }
15210
15935
  this.spots = new Map();
15211
15936
  // Sync local storage with the current state
15212
15937
  this.syncLocalStorage();
@@ -15214,19 +15939,23 @@ class LocalStorage {
15214
15939
  this.removeExpiredSpots();
15215
15940
  }
15216
15941
  static getInstance() {
15217
- if (!LocalStorage.instance) {
15218
- LocalStorage.instance = new LocalStorage();
15942
+ if (!LocalStorageService.instance) {
15943
+ LocalStorageService.instance = new LocalStorageService();
15219
15944
  }
15220
- return LocalStorage.instance;
15945
+ return LocalStorageService.instance;
15221
15946
  }
15222
15947
  syncLocalStorage() {
15223
- const localStorageData = localStorage.getItem(LocalStorage.localStorageKey);
15224
- // TODO: Encrypt the data before storing it in the local storage
15948
+ const localStorageData = window.localStorage.getItem(LocalStorageService.localStorageKey);
15225
15949
  if (localStorageData) {
15226
15950
  try {
15227
- const parsedData = JSON.parse(localStorageData);
15951
+ const decryptedData = this.decryptData(localStorageData);
15952
+ const parsedData = JSON.parse(decryptedData);
15228
15953
  if (parsedData && typeof parsedData === 'object') {
15229
- this.spots = this.objToMap(parsedData);
15954
+ const data = {};
15955
+ for (const [key, value] of Object.entries(parsedData)) {
15956
+ data[key] = this.arrayToObject(value);
15957
+ }
15958
+ this.spots = this.objectToMap(data);
15230
15959
  }
15231
15960
  else {
15232
15961
  this.clearLocalStorage();
@@ -15239,43 +15968,176 @@ class LocalStorage {
15239
15968
  }
15240
15969
  }
15241
15970
  setSpot(spotId, data) {
15971
+ var _a;
15242
15972
  data.createdAt = Date.now();
15243
- this.spots.set(spotId, data);
15973
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.set(spotId, data);
15244
15974
  this.updateLocalStorage();
15245
15975
  }
15246
- getSpot(spotId) {
15247
- return this.spots.get(spotId);
15248
- }
15249
15976
  removeSpot(spotId) {
15250
- this.spots.delete(spotId);
15977
+ var _a;
15978
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.delete(spotId);
15251
15979
  this.updateLocalStorage();
15252
15980
  }
15981
+ getSpot(spotId) {
15982
+ var _a;
15983
+ return (_a = this.spots) === null || _a === void 0 ? void 0 : _a.get(spotId);
15984
+ }
15985
+ getSpots() {
15986
+ if (!this.spots)
15987
+ return undefined;
15988
+ return this.mapToObject(this.spots);
15989
+ }
15253
15990
  updateLocalStorage() {
15254
- const data = this.mapToObj(this.spots);
15255
- localStorage.setItem(LocalStorage.localStorageKey, JSON.stringify(data));
15991
+ if (!this.spots)
15992
+ return undefined;
15993
+ const data = this.mapToObject(this.spots);
15994
+ const dataArray = {};
15995
+ for (const [key, value] of Object.entries(data)) {
15996
+ dataArray[key] = this.objectToArray(value);
15997
+ }
15998
+ try {
15999
+ const encryptedData = this.encryptData(JSON.stringify(dataArray));
16000
+ window.localStorage.setItem(LocalStorageService.localStorageKey, encryptedData);
16001
+ }
16002
+ catch (_a) {
16003
+ // If there is an error parsing the data, clear the local storage to prevent any issues
16004
+ this.clearLocalStorage();
16005
+ }
15256
16006
  }
15257
16007
  clearLocalStorage() {
15258
- localStorage.removeItem(LocalStorage.localStorageKey);
16008
+ window.localStorage.removeItem(LocalStorageService.localStorageKey);
15259
16009
  }
15260
16010
  removeExpiredSpots() {
16011
+ var _a;
15261
16012
  const currentTime = Date.now();
15262
- this.spots.forEach((spot, spotId) => {
15263
- var _a;
15264
- if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorage.spotExpirationTime) {
15265
- this.spots.delete(spotId);
16013
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.forEach((spot, spotId) => {
16014
+ var _a, _b;
16015
+ if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorageService.spotExpirationTime) {
16016
+ (_b = this.spots) === null || _b === void 0 ? void 0 : _b.delete(spotId);
15266
16017
  }
15267
16018
  });
15268
16019
  this.updateLocalStorage();
15269
16020
  }
15270
- mapToObj(map) {
16021
+ mapToObject(map) {
15271
16022
  return Object.fromEntries(map);
15272
16023
  }
15273
- objToMap(obj) {
16024
+ objectToMap(obj) {
15274
16025
  return new Map(Object.entries(obj));
15275
16026
  }
16027
+ objectToArray(obj) {
16028
+ return [obj.placementId, obj.spotId, obj.spotType, obj.events, obj.productIds, obj.createdAt];
16029
+ }
16030
+ arrayToObject(arr) {
16031
+ return {
16032
+ placementId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PLACEMENT_ID],
16033
+ spotId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_ID],
16034
+ spotType: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_TYPE],
16035
+ events: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.EVENTS],
16036
+ productIds: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PRODUCT_IDS],
16037
+ createdAt: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.CREATED_AT],
16038
+ };
16039
+ }
16040
+ encryptData(data) {
16041
+ if (!LocalStorageService.encryptData)
16042
+ return data;
16043
+ // For now, we are using base64 encoding to encrypt the data
16044
+ // Later we will use Jose encryption
16045
+ const encryptedData = btoa(data);
16046
+ return encryptedData;
16047
+ }
16048
+ decryptData(data) {
16049
+ if (!LocalStorageService.encryptData)
16050
+ return data;
16051
+ // For now, we are using base64 encoding to encrypt
16052
+ // Later we will use Jose encryption
16053
+ const decryptedData = atob(data);
16054
+ return decryptedData;
16055
+ }
16056
+ }
16057
+ LocalStorageService.localStorageKey = 'lc_rmn';
16058
+ LocalStorageService.spotExpirationTime = 1000 * 60 * 60 * 24 * 7; // 7 days
16059
+ LocalStorageService.encryptData = true;
16060
+
16061
+ /**
16062
+ * PubsubService class
16063
+ * Manages event subscriptions and publications
16064
+ * @template IRmnEventMap A record type defining the structure of events and their data
16065
+ */
16066
+ class PubsubService {
16067
+ constructor() {
16068
+ /**
16069
+ * Object to store subscribers for each event type
16070
+ */
16071
+ this.subscribers = {};
16072
+ }
16073
+ static getInstance() {
16074
+ if (!PubsubService.instance) {
16075
+ PubsubService.instance = new PubsubService();
16076
+ }
16077
+ return PubsubService.instance;
16078
+ }
16079
+ /**
16080
+ * Subscribe to an event
16081
+ * @param eventType - The type of event to subscribe to
16082
+ * @param callback - The function to be called when the event is published
16083
+ * @returns A function to unsubscribe from the event
16084
+ *
16085
+ * @Example:
16086
+ * const unsubscribe = pubSub.subscribe('userLogin', (data) => {
16087
+ * console.log(`User ${data.username} logged in`);
16088
+ * });
16089
+ */
16090
+ subscribe(eventType, callback) {
16091
+ if (!this.subscribers[eventType]) {
16092
+ this.subscribers[eventType] = [];
16093
+ }
16094
+ this.subscribers[eventType].push(callback);
16095
+ // Return an unsubscribe function
16096
+ return () => {
16097
+ this.subscribers[eventType] = this.subscribers[eventType].filter((cb) => cb !== callback);
16098
+ };
16099
+ }
16100
+ /**
16101
+ * Publish an event
16102
+ * @param eventType - The type of event to publish
16103
+ * @param data - The data to be passed to the event subscribers
16104
+ *
16105
+ * @Example:
16106
+ * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
16107
+ */
16108
+ publish(eventType, data) {
16109
+ if (!this.subscribers[eventType]) {
16110
+ return;
16111
+ }
16112
+ this.subscribers[eventType].forEach((callback) => callback(data));
16113
+ }
15276
16114
  }
15277
- LocalStorage.localStorageKey = 'lc_rmn';
15278
- LocalStorage.spotExpirationTime = 1000 * 60 * 60 * 24 * 7; // 7 days
16115
+ /**
16116
+ * Usage Example:
16117
+ *
16118
+ * interface IRmnEventMap {
16119
+ * userLogin: { username: string; timestamp: number };
16120
+ * pageView: { url: string; timestamp: number };
16121
+ * }
16122
+ *
16123
+ * const pubSub = new PubsubService<IRmnEventMap>();
16124
+ *
16125
+ * // Subscribe to events
16126
+ * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
16127
+ * console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
16128
+ * });
16129
+ *
16130
+ * pubSub.subscribe('pageView', (data) => {
16131
+ * console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
16132
+ * });
16133
+ *
16134
+ * // Publish events
16135
+ * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
16136
+ * pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
16137
+ *
16138
+ * // Unsubscribe from an event
16139
+ * unsubscribeLogin();
16140
+ */
15279
16141
 
15280
16142
  class ResizeObserverService {
15281
16143
  constructor({ element, maxSize, minScale }) {
@@ -15345,36 +16207,6 @@ class ResizeObserverService {
15345
16207
  }
15346
16208
  }
15347
16209
 
15348
- function calculateScaleFactor(elementScale) {
15349
- // Step 1: Apply square root for non-linear scaling
15350
- // This creates a more gradual scaling effect, especially for larger changes
15351
- // For example:
15352
- // - elementScale of 0.25 (1/4 size) becomes 0.5
15353
- // - elementScale of 1 (unchanged) remains 1
15354
- // - elementScale of 4 (4x size) becomes 2
15355
- const baseFactor = Math.sqrt(elementScale);
15356
- // Step 2: Apply additional dampening to further soften the scaling effect
15357
- // The dampening factor (0.5) can be adjusted:
15358
- // - Lower values (closer to 0) make scaling more subtle
15359
- // - Higher values (closer to 1) make scaling more pronounced
15360
- const dampening = 0.35;
15361
- // Calculate the scaleFactor:
15362
- // 1. (baseFactor - 1) represents the change from the original size
15363
- // 2. Multiply by dampening to reduce the effect
15364
- // 3. Add 1 to center the scaling around the original size
15365
- // For example, if baseFactor is 2:
15366
- // scaleFactor = 1 + (2 - 1) * 0.5 = 1.5
15367
- const scaleFactor = 1 + (baseFactor - 1) * dampening;
15368
- // Step 3: Define the allowed range for the scale factor
15369
- // This ensures that the font size never changes too drastically
15370
- const minScale = 0.35; // Font will never be smaller than 50% of original
15371
- const maxScale = 1.5; // Font will never be larger than 150% of original
15372
- // Step 4: Clamp the scale factor to the defined range
15373
- // Math.min ensures the value doesn't exceed maxScale
15374
- // Math.max ensures the value isn't less than minScale
15375
- return Math.max(minScale, Math.min(maxScale, scaleFactor));
15376
- }
15377
-
15378
16210
  const CAROUSEL_COMPONENT_STYLE = ({ width, height, fluid }) => `
15379
16211
  :host {
15380
16212
  position: relative;
@@ -15389,11 +16221,13 @@ const CAROUSEL_COMPONENT_STYLE = ({ width, height, fluid }) => `
15389
16221
  position: relative;
15390
16222
  height: 100%;
15391
16223
  width: 100%;
16224
+ display: flex;
16225
+ transition: transform 0.5s ease-in-out;
15392
16226
  }
15393
16227
 
15394
16228
  .slide {
15395
- display: none;
15396
-
16229
+ flex: 0 0 100%;
16230
+ display: flex;
15397
16231
  justify-content: center;
15398
16232
  align-items: center;
15399
16233
  height: 100%;
@@ -15698,9 +16532,9 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
15698
16532
  renderSlides() {
15699
16533
  const slidesContainer = document.createElement('div');
15700
16534
  slidesContainer.className = 'slides';
15701
- this.slides.forEach((slide, index) => {
16535
+ this.slides.forEach((slide) => {
15702
16536
  const slideElement = document.createElement('div');
15703
- slideElement.className = `slide ${index === this.currentSlide ? 'active' : ''}`;
16537
+ slideElement.className = 'slide';
15704
16538
  if (slide instanceof HTMLElement) {
15705
16539
  slideElement.appendChild(slide);
15706
16540
  }
@@ -15779,10 +16613,9 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
15779
16613
  updateCarousel() {
15780
16614
  if (!this.slidesContainer)
15781
16615
  return;
15782
- const slides = Array.from(this.slidesContainer.children);
15783
- slides.forEach((slide, index) => {
15784
- slide.classList.toggle('active', index === this.currentSlide);
15785
- });
16616
+ // Calculate the translation distance based on current slide
16617
+ const translateX = -this.currentSlide * 100;
16618
+ this.slidesContainer.style.transform = `translateX(${translateX}%)`;
15786
16619
  this.updateDots();
15787
16620
  }
15788
16621
  updateDots() {
@@ -16206,12 +17039,13 @@ function spotHtmlStringToElement(htmlString) {
16206
17039
  spot.className = 'spot';
16207
17040
  spot.innerHTML = htmlString;
16208
17041
  Object.assign(spot.style, {
16209
- position: 'relative',
16210
17042
  display: 'block',
16211
17043
  width: '100%',
16212
17044
  height: '100%',
16213
17045
  margin: '0',
16214
17046
  padding: '0',
17047
+ containerType: 'inline-size',
17048
+ position: 'relative',
16215
17049
  });
16216
17050
  return spot;
16217
17051
  }
@@ -17081,7 +17915,6 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17081
17915
  box-sizing: border-box;
17082
17916
  color: ${textColor};
17083
17917
  cursor: pointer;
17084
- container-type: inline-size;
17085
17918
  }
17086
17919
 
17087
17920
  .${prefix}__text {
@@ -17097,7 +17930,7 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17097
17930
  .${prefix}__header {
17098
17931
  font-size: 24px;
17099
17932
  margin: 0;
17100
- font-family: "Cormorant";
17933
+ font-family: "Cormorant", system-ui;
17101
17934
  font-style: normal;
17102
17935
  font-weight: 300;
17103
17936
  line-height: normal;
@@ -17216,7 +18049,6 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17216
18049
  height: 100%;
17217
18050
  display: block;
17218
18051
  position: relative;
17219
- container-type: inline-size;
17220
18052
  }
17221
18053
 
17222
18054
  .${prefix}__content {
@@ -17407,15 +18239,20 @@ function rbHomepageHeroThreeTileTemplate(spot, config) {
17407
18239
  const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextColor = textColor, primaryImage, mobilePrimaryImage = primaryImage, }, { prefix }) => `
17408
18240
  <style>
17409
18241
  .${prefix} {
18242
+ width: 100%;
18243
+ height: 100%;
18244
+ background-color: transparent;
18245
+ cursor: pointer;
18246
+ position: relative;
18247
+ }
18248
+
18249
+ .${prefix}__content {
17410
18250
  width: 100%;
17411
18251
  height: 100%;
17412
18252
  display: flex;
17413
18253
  flex-direction: column-reverse;
17414
18254
  background-color: transparent;
17415
18255
  gap: 6px;
17416
- cursor: pointer;
17417
- container-type: inline-size;
17418
- position: relative;
17419
18256
  }
17420
18257
 
17421
18258
  .${prefix}__image {
@@ -17446,7 +18283,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17446
18283
  font-size: 18px;
17447
18284
  margin: 0;
17448
18285
  color: inherit;
17449
- font-family: "Cormorant";
18286
+ font-family: "Cormorant", system-ui;
17450
18287
  font-style: normal;
17451
18288
  font-weight: 700;
17452
18289
  line-height: normal;
@@ -17488,7 +18325,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17488
18325
  }
17489
18326
 
17490
18327
  @container (min-width: 768px) {
17491
- .${prefix} {
18328
+ .${prefix}__content {
17492
18329
  flex-direction: row;
17493
18330
  }
17494
18331
  .${prefix}__image {
@@ -17543,12 +18380,14 @@ function rbHomepageHeroTwoTileTemplate(spot, config) {
17543
18380
  ${GFONT_CORMORANT}
17544
18381
  ${STYLES$4(spot, config)}
17545
18382
  <div class="${prefix}">
17546
- <div class="${prefix}__text">
17547
- ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17548
- ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
17549
- ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
17550
- </div>
17551
- <div class="${prefix}__image"></div>
18383
+ <div class="${prefix}__content">
18384
+ <div class="${prefix}__text">
18385
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
18386
+ ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
18387
+ ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
18388
+ </div>
18389
+ <div class="${prefix}__image"></div>
18390
+ </div>
17552
18391
  </div>
17553
18392
  `;
17554
18393
  }
@@ -17571,12 +18410,10 @@ const STYLES$3 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17571
18410
  overflow: hidden;
17572
18411
  cursor: pointer;
17573
18412
  color: ${textColor};
17574
- container-type: inline-size;
17575
18413
  }
17576
18414
 
17577
18415
  .${prefix}__text {
17578
18416
  padding: 20px;
17579
- width: 70%;
17580
18417
  display: flex;
17581
18418
  flex-direction: column;
17582
18419
  justify-content: center;
@@ -17588,7 +18425,7 @@ const STYLES$3 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
17588
18425
  color: inherit;
17589
18426
  margin: 0;
17590
18427
  font-size: 20px;
17591
- font-family: "Cormorant";
18428
+ font-family: "Cormorant", system-ui;
17592
18429
  font-style: normal;
17593
18430
  font-weight: 300;
17594
18431
  line-height: normal;
@@ -17707,7 +18544,6 @@ const STYLES$2 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
17707
18544
  background-size: cover;
17708
18545
  background-position: center;
17709
18546
  background-repeat: no-repeat;
17710
- container-type: inline-size;
17711
18547
  position: relative;
17712
18548
  }
17713
18549
 
@@ -17777,12 +18613,7 @@ const STYLES$1 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
17777
18613
  border-radius: 5px;
17778
18614
  overflow: hidden;
17779
18615
  cursor: pointer;
17780
- container-type: inline-size;
17781
- }
17782
-
17783
- .${prefix}__text {
17784
- padding: 10px;
17785
- width: 70%;
18616
+ position: relative;
17786
18617
  }
17787
18618
 
17788
18619
  .${prefix}__header {
@@ -17793,6 +18624,7 @@ const STYLES$1 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
17793
18624
  font-style: normal;
17794
18625
  font-weight: 400;
17795
18626
  margin: 0;
18627
+ padding: 10px;
17796
18628
  }
17797
18629
 
17798
18630
  @container (min-width: 640px) {
@@ -17810,9 +18642,7 @@ function rbSmallCategoryImageToutTemplate(spot, config) {
17810
18642
  ${GFONT_CORMORANT}
17811
18643
  ${STYLES$1(spot, config)}
17812
18644
  <div class="${prefix}">
17813
- <div class="${prefix}__text">
17814
- ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17815
- </div>
18645
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17816
18646
  </div>
17817
18647
  `;
17818
18648
  }
@@ -17827,7 +18657,6 @@ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primar
17827
18657
  display: flex;
17828
18658
  flex-direction: column;
17829
18659
  border-radius: 5px;
17830
- container-type: inline-size;
17831
18660
  }
17832
18661
 
17833
18662
  .${prefix}__image {
@@ -17963,94 +18792,198 @@ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
17963
18792
  return spotHtmlStringToElement(spotHtmlString);
17964
18793
  };
17965
18794
 
17966
- /**
17967
- * PubSub class
17968
- * Manages event subscriptions and publications
17969
- * @template IEventMap A record type defining the structure of events and their data
17970
- */
17971
- class PubSub {
18795
+ // For the moment, we will only focus on sites that use Google Analytics,
18796
+ // but we will add support for other analytics tools in the future.
18797
+ var AnalyticsTool;
18798
+ (function (AnalyticsTool) {
18799
+ AnalyticsTool["GoogleAnalytics"] = "google-analytics";
18800
+ AnalyticsTool["Other"] = "Other";
18801
+ })(AnalyticsTool || (AnalyticsTool = {}));
18802
+
18803
+ class DataLayerMonitor {
18804
+ constructor() {
18805
+ if (!window.dataLayer) {
18806
+ return;
18807
+ }
18808
+ this.originalPush = window.dataLayer.push;
18809
+ }
18810
+ static getInstance() {
18811
+ if (!DataLayerMonitor.instance) {
18812
+ DataLayerMonitor.instance = new DataLayerMonitor();
18813
+ }
18814
+ return DataLayerMonitor.instance;
18815
+ }
18816
+ setListener(listener) {
18817
+ this.listener = listener;
18818
+ }
18819
+ start() {
18820
+ window.dataLayer.push = (...args) => {
18821
+ const result = this.originalPush.apply(window.dataLayer, args);
18822
+ const pushedEvent = args[0];
18823
+ if (this.listener) {
18824
+ const normalizedData = this.cleanEventData(pushedEvent);
18825
+ if (normalizedData) {
18826
+ this.listener(normalizedData);
18827
+ }
18828
+ }
18829
+ return result;
18830
+ };
18831
+ }
18832
+ cleanEventData(data) {
18833
+ const eventName = getEventTypeFromRawEvent(data.event);
18834
+ if (!eventName) {
18835
+ return null;
18836
+ }
18837
+ const productIds = extractDeepIds(data.value);
18838
+ return {
18839
+ event: eventName,
18840
+ productIds,
18841
+ };
18842
+ }
18843
+ stop() {
18844
+ if (this.originalPush) {
18845
+ window.dataLayer.push = this.originalPush;
18846
+ }
18847
+ this.listener = undefined;
18848
+ }
18849
+ }
18850
+
18851
+ // @TODO: Add support for user to push events to our own data layer, if they don't use any analytics tool.
18852
+ // window.rmnDataLayer = window.rmnDataLayer || [];
18853
+ class MonitorService {
17972
18854
  constructor() {
17973
- /**
17974
- * Object to store subscribers for each event type
17975
- */
17976
- this.subscribers = {};
18855
+ const analyticsTool = this.detectAnalyticsTool();
18856
+ switch (analyticsTool) {
18857
+ case AnalyticsTool.GoogleAnalytics:
18858
+ this.implementedMonitor = DataLayerMonitor.getInstance();
18859
+ break;
18860
+ case AnalyticsTool.Other:
18861
+ default:
18862
+ console.warn('This site uses an unsupported analytics tool.');
18863
+ break;
18864
+ }
18865
+ if (analyticsTool === AnalyticsTool.Other) {
18866
+ return;
18867
+ }
18868
+ this.pubSubService = PubsubService.getInstance();
18869
+ this.localStorageService = LocalStorageService.getInstance();
17977
18870
  }
17978
18871
  static getInstance() {
17979
- if (!PubSub.instance) {
17980
- PubSub.instance = new PubSub();
18872
+ if (!MonitorService.instance) {
18873
+ MonitorService.instance = new MonitorService();
17981
18874
  }
17982
- return PubSub.instance;
18875
+ return MonitorService.instance;
17983
18876
  }
17984
- /**
17985
- * Subscribe to an event
17986
- * @param eventType - The type of event to subscribe to
17987
- * @param callback - The function to be called when the event is published
17988
- * @returns A function to unsubscribe from the event
17989
- *
17990
- * @Example:
17991
- * const unsubscribe = pubSub.subscribe('userLogin', (data) => {
17992
- * console.log(`User ${data.username} logged in`);
17993
- * });
17994
- */
17995
- subscribe(eventType, callback) {
17996
- if (!this.subscribers[eventType]) {
17997
- this.subscribers[eventType] = [];
18877
+ start() {
18878
+ if (!this.implementedMonitor)
18879
+ return;
18880
+ this.implementedMonitor.setListener(async (eventData) => {
18881
+ var _a;
18882
+ await this.matchAndFireEvent(eventData, (_a = this.localStorageService) === null || _a === void 0 ? void 0 : _a.getSpots());
18883
+ });
18884
+ this.implementedMonitor.start();
18885
+ }
18886
+ async matchAndFireEvent(eventData, spots) {
18887
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
18888
+ if (!spots)
18889
+ return;
18890
+ const eventProductIds = new Set(eventData.productIds);
18891
+ for (const spot of Object.values(spots)) {
18892
+ if (!spot.productIds.length)
18893
+ continue;
18894
+ const hasCommonProductIds = spot.productIds.find((productId) => eventProductIds.has(productId));
18895
+ if (hasCommonProductIds) {
18896
+ switch (eventData.event) {
18897
+ case exports.RMN_SPOT_EVENT.ADD_TO_CART:
18898
+ await this.fireAndPublishSpotEvent({
18899
+ spotEvent: exports.RMN_SPOT_EVENT.ADD_TO_CART,
18900
+ eventUrl: (_b = (_a = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.ADD_TO_CART)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
18901
+ placementId: spot.placementId,
18902
+ spotId: spot.spotId,
18903
+ });
18904
+ break;
18905
+ case exports.RMN_SPOT_EVENT.REMOVE_FROM_CART:
18906
+ await this.fireAndPublishSpotEvent({
18907
+ spotEvent: exports.RMN_SPOT_EVENT.REMOVE_FROM_CART,
18908
+ eventUrl: (_d = (_c = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.REMOVE_FROM_CART)) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : '',
18909
+ placementId: spot.placementId,
18910
+ spotId: spot.spotId,
18911
+ });
18912
+ break;
18913
+ case exports.RMN_SPOT_EVENT.PURCHASE:
18914
+ await this.fireAndPublishSpotEvent({
18915
+ spotEvent: exports.RMN_SPOT_EVENT.PURCHASE,
18916
+ eventUrl: (_f = (_e = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.PURCHASE)) === null || _e === void 0 ? void 0 : _e.url) !== null && _f !== void 0 ? _f : '',
18917
+ placementId: spot.placementId,
18918
+ spotId: spot.spotId,
18919
+ });
18920
+ break;
18921
+ case exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST:
18922
+ await this.fireAndPublishSpotEvent({
18923
+ spotEvent: exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST,
18924
+ eventUrl: (_h = (_g = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST)) === null || _g === void 0 ? void 0 : _g.url) !== null && _h !== void 0 ? _h : '',
18925
+ placementId: spot.placementId,
18926
+ spotId: spot.spotId,
18927
+ });
18928
+ break;
18929
+ case exports.RMN_SPOT_EVENT.BUY_NOW:
18930
+ await this.fireAndPublishSpotEvent({
18931
+ spotEvent: exports.RMN_SPOT_EVENT.BUY_NOW,
18932
+ eventUrl: (_k = (_j = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.BUY_NOW)) === null || _j === void 0 ? void 0 : _j.url) !== null && _k !== void 0 ? _k : '',
18933
+ placementId: spot.placementId,
18934
+ spotId: spot.spotId,
18935
+ });
18936
+ break;
18937
+ }
18938
+ }
17998
18939
  }
17999
- this.subscribers[eventType].push(callback);
18000
- // Return an unsubscribe function
18001
- return () => {
18002
- this.subscribers[eventType] = this.subscribers[eventType].filter((cb) => cb !== callback);
18003
- };
18004
18940
  }
18005
- /**
18006
- * Publish an event
18007
- * @param eventType - The type of event to publish
18008
- * @param data - The data to be passed to the event subscribers
18009
- *
18010
- * @Example:
18011
- * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
18012
- */
18013
- publish(eventType, data) {
18014
- if (!this.subscribers[eventType]) {
18941
+ async fireAndPublishSpotEvent({ spotEvent, eventUrl, placementId, spotId, }) {
18942
+ await fireEvent({
18943
+ event: spotEvent,
18944
+ eventUrl,
18945
+ });
18946
+ if (!this.pubSubService)
18015
18947
  return;
18948
+ this.pubSubService.publish(exports.RMN_EVENT.SPOT_EVENT, {
18949
+ eventType: spotEvent,
18950
+ placementId,
18951
+ spotId,
18952
+ });
18953
+ }
18954
+ detectAnalyticsTool() {
18955
+ let analyticsTool = AnalyticsTool.Other;
18956
+ // Check for Google Analytics
18957
+ if (typeof window.ga !== 'undefined') {
18958
+ analyticsTool = AnalyticsTool.GoogleAnalytics;
18016
18959
  }
18017
- this.subscribers[eventType].forEach((callback) => callback(data));
18960
+ // Check for Google Analytics 4
18961
+ if (typeof window.gtag !== 'undefined') {
18962
+ analyticsTool = AnalyticsTool.GoogleAnalytics;
18963
+ }
18964
+ // Check for Google Tag Manager
18965
+ if (typeof window.google_tag_manager !== 'undefined') {
18966
+ analyticsTool = AnalyticsTool.GoogleAnalytics;
18967
+ }
18968
+ // @TODO: Add support for other analytics tools
18969
+ // Check for Heap Analytics
18970
+ // Check for Mixpanel
18971
+ // Check for Woopra
18972
+ // Check for Segment
18973
+ // Check for Amplitude
18974
+ return analyticsTool;
18018
18975
  }
18019
18976
  }
18020
- /**
18021
- * Usage Example:
18022
- *
18023
- * interface IEventMap {
18024
- * userLogin: { username: string; timestamp: number };
18025
- * pageView: { url: string; timestamp: number };
18026
- * }
18027
- *
18028
- * const pubSub = new PubSub<IEventMap>();
18029
- *
18030
- * // Subscribe to events
18031
- * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
18032
- * console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
18033
- * });
18034
- *
18035
- * pubSub.subscribe('pageView', (data) => {
18036
- * console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
18037
- * });
18038
- *
18039
- * // Publish events
18040
- * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
18041
- * pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
18042
- *
18043
- * // Unsubscribe from an event
18044
- * unsubscribeLogin();
18045
- */
18046
18977
 
18047
18978
  class EventService {
18048
18979
  constructor() {
18049
- this.pubSub = PubSub.getInstance();
18050
- this.localStorage = LocalStorage.getInstance();
18980
+ this.pubSubService = PubsubService.getInstance();
18981
+ this.localStorageService = LocalStorageService.getInstance();
18051
18982
  this.activeSpots = new Map();
18052
18983
  this.spotStates = new Map();
18053
18984
  this.intersectionObserver = new IntersectionObserverService();
18985
+ // Start the user monitor, which will track and check user interactions
18986
+ MonitorService.getInstance().start();
18054
18987
  }
18055
18988
  static getInstance() {
18056
18989
  if (!EventService.instance) {
@@ -18059,16 +18992,16 @@ class EventService {
18059
18992
  return EventService.instance;
18060
18993
  }
18061
18994
  subscribe(eventType, callback) {
18062
- return this.pubSub.subscribe(eventType, callback);
18995
+ return this.pubSubService.subscribe(eventType, callback);
18063
18996
  }
18064
18997
  publish(eventType, data) {
18065
- this.pubSub.publish(eventType, data);
18998
+ this.pubSubService.publish(eventType, data);
18066
18999
  }
18067
19000
  registerSpot(params) {
18068
19001
  const { placementId, spot, spotElement } = params;
18069
19002
  this.activeSpots.set(placementId, { spotElement });
18070
19003
  // Fire impression event
18071
- this.fireImpressionEvent(placementId, spot, spotElement);
19004
+ this.fireImpressionEvent(placementId, spot);
18072
19005
  // Handle intersection observer
18073
19006
  this.handleIntersectionObserver(placementId, spot, spotElement);
18074
19007
  // Attach click event listener
@@ -18143,30 +19076,42 @@ class EventService {
18143
19076
  },
18144
19077
  };
18145
19078
  }
18146
- this.spotStates.set(placementId, { ...currentState, ...updates });
19079
+ const merged = this.deepMerge(currentState, updates);
19080
+ this.spotStates.set(placementId, merged);
18147
19081
  if (publish) {
18148
- this.pubSub.publish(exports.RMN_SPOT_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
19082
+ this.pubSubService.publish(exports.RMN_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
18149
19083
  }
18150
19084
  }
18151
- async handleClick({ placementId, spot, spotElement, }) {
19085
+ deepMerge(current, updates) {
19086
+ return {
19087
+ identifier: updates.identifier
19088
+ ? { ...current.identifier, ...updates.identifier }
19089
+ : current.identifier,
19090
+ dom: updates.dom ? { ...current.dom, ...updates.dom } : current.dom,
19091
+ state: updates.state ? { ...current.state, ...updates.state } : current.state,
19092
+ displayConfig: updates.displayConfig
19093
+ ? { ...current.displayConfig, ...updates.displayConfig }
19094
+ : current.displayConfig,
19095
+ };
19096
+ }
19097
+ async handleClick({ placementId, spot }) {
18152
19098
  var _a, _b, _c;
18153
- // Publish click event
18154
- this.pubSub.publish(exports.RMN_SPOT_EVENT.CLICK, {
19099
+ this.pubSubService.publish(exports.RMN_EVENT.SPOT_EVENT, {
19100
+ eventType: exports.RMN_SPOT_EVENT.CLICK,
18155
19101
  placementId,
18156
19102
  spotId: spot.id,
18157
- spotElement,
18158
19103
  });
18159
- // Fire click event
18160
- await this.fireEvent({
19104
+ await fireEvent({
18161
19105
  event: exports.RMN_SPOT_EVENT.CLICK,
18162
19106
  eventUrl: (_b = (_a = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.CLICK)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
18163
19107
  });
18164
19108
  // Save spot to local storage for event tracking
18165
- this.localStorage.setSpot(spot.id, {
19109
+ this.localStorageService.setSpot(spot.id, {
19110
+ placementId,
18166
19111
  spotId: spot.id,
18167
19112
  spotType: spot.spot,
18168
19113
  events: spot.events,
18169
- productIds: (_c = spot.productIds) !== null && _c !== void 0 ? _c : [1, 'GROUPING-12345', 'DAN-12345', 131398103],
19114
+ productIds: (_c = spot.productIds) !== null && _c !== void 0 ? _c : [],
18170
19115
  });
18171
19116
  }
18172
19117
  handleIntersectionObserver(placementId, _spot, spotElement) {
@@ -18181,51 +19126,20 @@ class EventService {
18181
19126
  };
18182
19127
  this.intersectionObserver.observe(spotElement, spotIsVisibleCallback);
18183
19128
  }
18184
- fireImpressionEvent(placementId, spot, spotElement) {
18185
- this.pubSub.publish(exports.RMN_SPOT_EVENT.IMPRESSION, {
19129
+ fireImpressionEvent(placementId, spot) {
19130
+ this.pubSubService.publish(exports.RMN_EVENT.SPOT_EVENT, {
19131
+ eventType: exports.RMN_SPOT_EVENT.IMPRESSION,
18186
19132
  placementId,
18187
19133
  spotId: spot.id,
18188
- spotElement,
18189
19134
  });
18190
19135
  (async () => {
18191
19136
  var _a, _b;
18192
- await this.fireEvent({
19137
+ await fireEvent({
18193
19138
  event: exports.RMN_SPOT_EVENT.IMPRESSION,
18194
19139
  eventUrl: (_b = (_a = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.IMPRESSION)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
18195
19140
  });
18196
19141
  })();
18197
19142
  }
18198
- /**
18199
- * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
18200
- *
18201
- * @param {IFireEventParams} params - The parameters for firing the event.
18202
- * @param {RMN_SPOT_EVENT} params.event - The event type.
18203
- * @param {string} params.eventUrl - The URL to which the event is sent.
18204
- * @returns {Promise<void>} - A promise that resolves when the event is fired.
18205
- */
18206
- async fireEvent({ event, eventUrl }) {
18207
- const didFireEvent = navigator.sendBeacon(eventUrl);
18208
- if (didFireEvent && event === exports.RMN_SPOT_EVENT.CLICK) {
18209
- window.location.href = this.getRedirectUrlFromPayload(eventUrl);
18210
- }
18211
- }
18212
- /**
18213
- * Extracts and decodes a URL from a base64-encoded query parameter.
18214
- *
18215
- * @param {string} url - The URL containing the base64-encoded query parameter.
18216
- * @returns {string} - The decoded URL or an empty string if decoding fails.
18217
- */
18218
- getRedirectUrlFromPayload(url) {
18219
- var _a, _b;
18220
- const base64String = (_a = new URL(url).searchParams.get('e')) !== null && _a !== void 0 ? _a : '';
18221
- try {
18222
- const data = JSON.parse(atob(base64String));
18223
- return (_b = data.ur) !== null && _b !== void 0 ? _b : '';
18224
- }
18225
- catch (_c) {
18226
- return '';
18227
- }
18228
- }
18229
19143
  }
18230
19144
 
18231
19145
  const SELECTION_API_PATH = '/spots/selection';
@@ -18258,176 +19172,6 @@ class SelectionService extends BaseApi {
18258
19172
  }
18259
19173
  }
18260
19174
 
18261
- const SPOT_EVENTS_EXAMPLE = [
18262
- {
18263
- event: exports.RMN_SPOT_EVENT.CLICK,
18264
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwidXIiOm51bGx9&s=hWz37kbxi_u95EVNn2aoQhc5Aas',
18265
- },
18266
- {
18267
- event: exports.RMN_SPOT_EVENT.IMPRESSION,
18268
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiYmEiOjEsImZxIjowfQ&s=djoysjCimurf-5T11AlNAwwLSS8',
18269
- },
18270
- {
18271
- event: exports.RMN_SPOT_EVENT.PURCHASE,
18272
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjU5fQ&s=AAPAw-3SfZ0JMzjEGFSwt9L-2S4',
18273
- },
18274
- {
18275
- event: exports.RMN_SPOT_EVENT.ADD_TO_CART,
18276
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYwfQ&s=uzQFcjgL7m9XqUG8FvTPVN5YkZY',
18277
- },
18278
- {
18279
- event: exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST,
18280
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjYzfQ&s=m3ISU_iIy-OFtXrTKpI6cJAEC0k',
18281
- },
18282
- {
18283
- event: exports.RMN_SPOT_EVENT.BUY_NOW,
18284
- url: 'https://dev.rmn.liquidcommerce.cloud/api/spots/event?e=eyJ2IjoiMS4xMiIsImF2IjozMDY1NzgzLCJhdCI6MTYzLCJidCI6MCwiY20iOjQ0MDE5MjQxOCwiY2giOjYzMTg0LCJjayI6e30sImNyIjo0ODE4NTUzNzUsImRpIjoiOWMxNGFhMGI3NWY4NDMxNTllMTAwYWQzNzA1NzQyYzMiLCJkaiI6MCwiaWkiOiIxZjU0MGM5NmQ1N2M0YmZjODFlZjRkNjhkMzFjNDVkOSIsImRtIjozLCJmYyI6NjU2NjgyNTQ5LCJmbCI6NjQzOTMxODIxLCJpcCI6IjM1LjIyMy4xOTguOTUiLCJudyI6MTE1MDAsInBjIjo1MDAwLCJvcCI6NTAwMCwibXAiOjUwMDAsImVjIjowLCJnbSI6MCwiZXAiOm51bGwsInByIjoyNDkzMTYsInJ0IjoxLCJycyI6NTAwLCJzYSI6IjU1Iiwic2IiOiJpLTA0MDI0ODg4ZDlkMWRjZWQ3Iiwic3AiOjI3MjI3Miwic3QiOjEyODcyOTYsInRyIjp0cnVlLCJ1ayI6IjNhZWRhMWMxLTZhYjItNDUwNy04Mzg5LTEwZTJmNDMxYjM5MSIsInRzIjoxNzI5MzU5MDU0OTI3LCJiZiI6dHJ1ZSwicG4iOiJyYlByb2R1Y3RVcGNzIiwiZ2MiOnRydWUsImdDIjp0cnVlLCJncyI6Im5vbmUiLCJkYyI6MSwidHoiOiJBbWVyaWNhL05ld19Zb3JrIiwiZXQiOjY5fQ&s=l6MOscQC-q-FkC2Ksd7w6jjySCQ',
18285
- },
18286
- ];
18287
- const RB_SPOTS_SELECTION_EXAMPLE = {
18288
- rbHomepageHeroFullImage: [
18289
- {
18290
- id: '111111_111111',
18291
- spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18292
- variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18293
- width: 1140,
18294
- height: 640,
18295
- header: 'Artisanal Craft Beer Collection',
18296
- description: 'Discover our curated selection of small-batch, flavor-packed craft beers.',
18297
- ctaText: 'Explore the Collection',
18298
- textColor: '#ffffff',
18299
- ctaTextColor: '#ffffff',
18300
- primaryImage: 'https://placehold.co/1140x640/png?text=Craft+Beer+Collection',
18301
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Craft+Beer',
18302
- events: SPOT_EVENTS_EXAMPLE,
18303
- },
18304
- {
18305
- id: '222222_222222',
18306
- spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18307
- variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_FULL_IMAGE,
18308
- width: 1140,
18309
- height: 640,
18310
- header: 'Summer Wine Spectacular',
18311
- description: 'Refresh your palate with our handpicked selection of crisp, summer wines.',
18312
- ctaText: 'Shop Summer Wines',
18313
- textColor: '#000000',
18314
- ctaTextColor: '#ffffff',
18315
- primaryImage: 'https://placehold.co/1140x640/png?text=Summer+Wines',
18316
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Summer+Wines',
18317
- events: SPOT_EVENTS_EXAMPLE,
18318
- },
18319
- ],
18320
- rbHomepageHeroTwoTile: [
18321
- {
18322
- id: '333333_333333',
18323
- spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
18324
- variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_TWO_TILE,
18325
- width: 1140,
18326
- height: 640,
18327
- header: 'Whiskey Wonderland',
18328
- description: 'Embark on a journey through our premium whiskey selection.',
18329
- ctaText: 'Discover Whiskeys',
18330
- textColor: '#ffffff',
18331
- backgroundColor: '#2c1a05',
18332
- ctaTextColor: '#2c1a05',
18333
- primaryImage: 'https://placehold.co/1140x640/png?text=Whiskey+Collection',
18334
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Whiskey',
18335
- events: SPOT_EVENTS_EXAMPLE,
18336
- },
18337
- ],
18338
- rbHomepageHeroThreeTile: [
18339
- {
18340
- id: '444444_444444',
18341
- spot: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
18342
- variant: exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE,
18343
- width: 1140,
18344
- height: 640,
18345
- header: 'Cocktail Essentials',
18346
- description: 'Stock your bar with premium spirits and mixers for the perfect cocktail.',
18347
- ctaText: 'Build Your Bar',
18348
- textColor: '#ffffff',
18349
- backgroundColor: '#1a3c4d',
18350
- ctaTextColor: '#1a3c4d',
18351
- primaryImage: 'https://placehold.co/1140x640/png?text=Cocktail+Spirits',
18352
- secondaryImage: 'https://placehold.co/1140x640/png?text=Cocktail+Mixers',
18353
- mobilePrimaryImage: 'https://placehold.co/640x640/png?text=Mobile+Cocktail+Kit',
18354
- mobileSecondaryImage: 'https://placehold.co/640x320/png?text=Mobile+Cocktail+Mixers',
18355
- events: SPOT_EVENTS_EXAMPLE,
18356
- },
18357
- ],
18358
- rbLargeCategoryImageTout: [
18359
- {
18360
- id: '555555_555555',
18361
- spot: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
18362
- variant: exports.RMN_SPOT_TYPE.RB_LARGE_CATEGORY_IMAGE_TOUT,
18363
- width: 468,
18364
- height: 410,
18365
- header: 'Rare & Limited Edition',
18366
- description: 'Discover our collection of hard-to-find and limited release spirits.',
18367
- textColor: '#ffffff',
18368
- ctaTextColor: '#ffffff',
18369
- primaryImage: 'https://placehold.co/468x410/png?text=Rare+Spirits',
18370
- mobilePrimaryImage: 'https://placehold.co/468x410/png?text=Mobile+Rare+Spirits',
18371
- ctaText: 'Shop Rare Spirits',
18372
- events: SPOT_EVENTS_EXAMPLE,
18373
- },
18374
- ],
18375
- rbSmallDiscoverTout: [
18376
- {
18377
- id: '666666_666666',
18378
- spot: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
18379
- variant: exports.RMN_SPOT_TYPE.RB_SMALL_DISCOVER_TOUT,
18380
- width: 224,
18381
- height: 378,
18382
- header: 'Château Margaux 2015 Bordeaux',
18383
- textColor: '#ffffff',
18384
- primaryImage: 'https://placehold.co/224x378/png?text=Château+Margaux',
18385
- mobilePrimaryImage: 'https://placehold.co/224x378/png?text=Mobile+Château+Margaux',
18386
- events: SPOT_EVENTS_EXAMPLE,
18387
- },
18388
- ],
18389
- rbSmallCategoryImageTout: [
18390
- {
18391
- id: '777777_777777',
18392
- spot: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
18393
- variant: exports.RMN_SPOT_TYPE.RB_SMALL_CATEGORY_IMAGE_TOUT,
18394
- width: 224,
18395
- height: 410,
18396
- header: 'Japanese Sake',
18397
- textColor: '#ffffff',
18398
- primaryImage: 'https://placehold.co/224x410/png?text=Japanese+Sake',
18399
- mobilePrimaryImage: 'https://placehold.co/224x410/png?text=Mobile+Japanese+Sake',
18400
- events: SPOT_EVENTS_EXAMPLE,
18401
- },
18402
- ],
18403
- rbCollectionBannerWithoutTextBlock: [
18404
- {
18405
- id: '888888_888888',
18406
- spot: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
18407
- variant: exports.RMN_SPOT_TYPE.RB_COLLECTION_BANNER_WITHOUT_TEXT_BLOCK,
18408
- width: 887,
18409
- height: 344,
18410
- primaryImage: 'https://placehold.co/887x344/png?text=Summer+Cocktails',
18411
- mobilePrimaryImage: 'https://placehold.co/887x344/png?text=Mobile+Summer+Cocktails',
18412
- events: SPOT_EVENTS_EXAMPLE,
18413
- },
18414
- ],
18415
- rbNavigationBanner: [
18416
- {
18417
- id: '999999_999999',
18418
- spot: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
18419
- variant: exports.RMN_SPOT_TYPE.RB_NAVIGATION_BANNER,
18420
- width: 440,
18421
- height: 220,
18422
- header: 'Explore Tequilas',
18423
- textColor: '#ffffff',
18424
- primaryImage: 'https://placehold.co/440x220/png?text=Tequila+Collection',
18425
- mobilePrimaryImage: 'https://placehold.co/440x220/png?text=Mobile+Tequila+Collection',
18426
- events: SPOT_EVENTS_EXAMPLE,
18427
- },
18428
- ],
18429
- };
18430
-
18431
19175
  class LiquidCommerceRmnClient {
18432
19176
  constructor(auth) {
18433
19177
  this.selectionService = SelectionService.getInstance(auth);
@@ -18441,7 +19185,7 @@ class LiquidCommerceRmnClient {
18441
19185
  *
18442
19186
  * @param {ISpotSelectionParams} params - Spots selection parameters.
18443
19187
  *
18444
- * @return {Promise<ISpots | {error : string}>} - The spots response object.
19188
+ * @return {Promise<ISpots | { error : string }>} - The spots response object.
18445
19189
  */
18446
19190
  async spotSelection(params) {
18447
19191
  return this.selectionService.spotSelection(params);
@@ -18455,13 +19199,19 @@ class LiquidCommerceRmnClient {
18455
19199
  */
18456
19200
  async injectSpotElement(params) {
18457
19201
  var _a;
19202
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
19203
+ console.warn('LiquidCommerce Rmn Sdk: Methods which create elements are only available in browser environments.');
19204
+ return;
19205
+ }
18458
19206
  const config = params.config;
18459
19207
  let inject = params.inject;
18460
19208
  if (!inject.length) {
19209
+ // Handle no spots error state
18461
19210
  this.eventService.handleSpotState('all', {
18462
19211
  state: {
18463
19212
  error: 'No spot elements provided for injection.',
18464
19213
  loading: false,
19214
+ mounted: false,
18465
19215
  },
18466
19216
  });
18467
19217
  return;
@@ -18480,9 +19230,12 @@ class LiquidCommerceRmnClient {
18480
19230
  // const response = await this.useSpotSelectionExample(inject);
18481
19231
  // Handle the response
18482
19232
  if (typeof response === 'object' && 'error' in response) {
19233
+ // Handle request error state
18483
19234
  this.eventService.handleSpotState('all', {
18484
19235
  state: {
18485
19236
  error: response.error,
19237
+ mounted: false,
19238
+ loading: false,
18486
19239
  },
18487
19240
  });
18488
19241
  return;
@@ -18491,9 +19244,11 @@ class LiquidCommerceRmnClient {
18491
19244
  const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
18492
19245
  const spots = response[item.placementId];
18493
19246
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
19247
+ // Handle no spots found error state
18494
19248
  this.eventService.handleSpotState(item.placementId, {
18495
19249
  state: {
18496
19250
  error: `No spots found for type "${item.spotType}".`,
19251
+ mounted: false,
18497
19252
  loading: false,
18498
19253
  },
18499
19254
  });
@@ -18502,9 +19257,11 @@ class LiquidCommerceRmnClient {
18502
19257
  const placementId = item.placementId.replace('#', '');
18503
19258
  const placement = document.getElementById(placementId);
18504
19259
  if (!placement) {
19260
+ // Handle placement not found error state
18505
19261
  this.eventService.handleSpotState(item.placementId, {
18506
19262
  state: {
18507
19263
  error: `Placement not found for id "${placementId}".`,
19264
+ mounted: false,
18508
19265
  loading: false,
18509
19266
  },
18510
19267
  });
@@ -18515,16 +19272,18 @@ class LiquidCommerceRmnClient {
18515
19272
  placement.removeAttribute('class');
18516
19273
  Object.assign(placement.style, {
18517
19274
  width: '100%',
18518
- height: 'auto',
19275
+ height: '100%',
18519
19276
  display: 'flex',
18520
19277
  justifyContent: 'center',
18521
19278
  });
19279
+ // Handle single spot
18522
19280
  if (spots.length === 1) {
18523
19281
  const isInjected = this.injectOneSpotElement(item, placement, spots[0], itemConfig);
18524
19282
  if (!isInjected) {
18525
19283
  continue;
18526
19284
  }
18527
19285
  }
19286
+ // Handle multiple spots (carousel)
18528
19287
  if (spots.length > 1) {
18529
19288
  const isInjected = this.injectCarouselSpotElement(placement, spots, itemConfig);
18530
19289
  if (!isInjected) {
@@ -18568,18 +19327,24 @@ class LiquidCommerceRmnClient {
18568
19327
  const carouselSlides = [];
18569
19328
  for (const spotItem of spots) {
18570
19329
  this.eventService.handleSpotState(placement.id, {
19330
+ identifier: {
19331
+ placementId: placement.id,
19332
+ spotType: spotItem.spot,
19333
+ spotId: spotItem.id,
19334
+ },
18571
19335
  displayConfig: {
19336
+ isSingleItem: false,
18572
19337
  isCarousel: true,
18573
19338
  isCarouselItem: true,
18574
- isSingleItem: false,
18575
19339
  },
18576
- }, false);
19340
+ });
18577
19341
  const spot = this.elementService.overrideSpotColors(spotItem, config === null || config === void 0 ? void 0 : config.colors);
18578
19342
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spot, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18579
19343
  if (!content) {
18580
19344
  this.eventService.handleSpotState(placement.id, {
18581
19345
  state: {
18582
19346
  error: `Failed to inject carousel spot item element. Could not create element for type "${spot.spot}".`,
19347
+ mounted: false,
18583
19348
  loading: false,
18584
19349
  },
18585
19350
  });
@@ -18612,6 +19377,7 @@ class LiquidCommerceRmnClient {
18612
19377
  this.eventService.handleSpotState(placement.id, {
18613
19378
  state: {
18614
19379
  error: `Failed to inject spot carousel element. Could not create spot carousel element.`,
19380
+ mounted: false,
18615
19381
  loading: false,
18616
19382
  },
18617
19383
  });
@@ -18621,10 +19387,12 @@ class LiquidCommerceRmnClient {
18621
19387
  this.eventService.handleSpotState(placement.id, {
18622
19388
  dom: {
18623
19389
  spotElement: carouselElement,
19390
+ visibleOnViewport: false,
18624
19391
  },
18625
19392
  state: {
18626
19393
  mounted: true,
18627
19394
  loading: false,
19395
+ error: undefined,
18628
19396
  },
18629
19397
  });
18630
19398
  return true;
@@ -18641,18 +19409,25 @@ class LiquidCommerceRmnClient {
18641
19409
  */
18642
19410
  injectOneSpotElement(injectItem, placement, spot, config) {
18643
19411
  var _a;
18644
- const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
18645
19412
  this.eventService.handleSpotState(injectItem.placementId, {
19413
+ identifier: {
19414
+ placementId: injectItem.placementId,
19415
+ spotType: injectItem.spotType,
19416
+ spotId: spot.id,
19417
+ },
18646
19418
  displayConfig: {
18647
19419
  isSingleItem: true,
19420
+ isCarousel: false,
19421
+ isCarouselItem: false,
18648
19422
  },
18649
- }, false);
18650
- // Create the spot template element
19423
+ });
19424
+ const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
18651
19425
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18652
19426
  if (!content) {
18653
19427
  this.eventService.handleSpotState(injectItem.placementId, {
18654
19428
  state: {
18655
19429
  error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
19430
+ mounted: false,
18656
19431
  loading: false,
18657
19432
  },
18658
19433
  });
@@ -18673,6 +19448,7 @@ class LiquidCommerceRmnClient {
18673
19448
  this.eventService.handleSpotState(injectItem.placementId, {
18674
19449
  state: {
18675
19450
  error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
19451
+ mounted: false,
18676
19452
  loading: false,
18677
19453
  },
18678
19454
  });
@@ -18687,10 +19463,12 @@ class LiquidCommerceRmnClient {
18687
19463
  this.eventService.handleSpotState(injectItem.placementId, {
18688
19464
  dom: {
18689
19465
  spotElement,
19466
+ visibleOnViewport: false,
18690
19467
  },
18691
19468
  state: {
18692
19469
  mounted: true,
18693
19470
  loading: false,
19471
+ error: undefined,
18694
19472
  },
18695
19473
  });
18696
19474
  return true;
@@ -18711,6 +19489,8 @@ class LiquidCommerceRmnClient {
18711
19489
  this.eventService.handleSpotState(item.placementId, {
18712
19490
  state: {
18713
19491
  error: `Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`,
19492
+ mounted: false,
19493
+ loading: false,
18714
19494
  },
18715
19495
  });
18716
19496
  return false;
@@ -18726,6 +19506,8 @@ class LiquidCommerceRmnClient {
18726
19506
  this.eventService.handleSpotState(item.placementId, {
18727
19507
  state: {
18728
19508
  error: `Invalid spot type (${item.spotType}) found. Please provide a valid spot type for each spot element.`,
19509
+ mounted: false,
19510
+ loading: false,
18729
19511
  },
18730
19512
  });
18731
19513
  continue;
@@ -18734,6 +19516,7 @@ class LiquidCommerceRmnClient {
18734
19516
  }
18735
19517
  return newInject;
18736
19518
  }
19519
+ // Initialize spots with loading state and identifiers
18737
19520
  updateSpotsState(inject) {
18738
19521
  for (const item of inject) {
18739
19522
  this.eventService.handleSpotState(item.placementId, {
@@ -18743,6 +19526,8 @@ class LiquidCommerceRmnClient {
18743
19526
  },
18744
19527
  state: {
18745
19528
  loading: true,
19529
+ mounted: false,
19530
+ error: undefined,
18746
19531
  },
18747
19532
  });
18748
19533
  }