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

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