@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.
- package/dist/index.cjs +1192 -407
- package/dist/index.esm.js +1193 -408
- package/dist/types/common/helpers/utils.helper.d.ts +50 -0
- package/dist/types/enums.d.ts +6 -1
- package/dist/types/modules/element/element.interface.d.ts +5 -2
- package/dist/types/modules/event/event.interface.d.ts +6 -32
- package/dist/types/modules/event/event.service.d.ts +7 -22
- package/dist/types/modules/event/index.d.ts +0 -1
- package/dist/types/modules/{event/helpers → helper-service}/index.d.ts +1 -0
- package/dist/types/modules/{event/helpers → helper-service}/intersection.service.d.ts +1 -1
- package/dist/types/modules/helper-service/localstorage.service.d.ts +56 -0
- package/dist/types/modules/{event/pubsub.d.ts → helper-service/pubsub.service.d.ts} +8 -8
- package/dist/types/modules/{event/helpers → helper-service}/resize.service.d.ts +1 -1
- package/dist/types/modules/monitor/index.d.ts +2 -0
- package/dist/types/modules/monitor/monitor.enums.d.ts +4 -0
- package/dist/types/modules/monitor/monitor.interface.d.ts +11 -0
- package/dist/types/modules/monitor/monitor.service.d.ts +12 -0
- package/dist/types/modules/monitor/monitors/datalayer.monitor.d.ts +12 -0
- package/dist/types/modules/selection/selection.interface.d.ts +3 -1
- package/dist/types/rmn-client.d.ts +1 -1
- package/dist/types/types.d.ts +5 -4
- package/package.json +1 -1
- package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
- package/dist/types/modules/element/component/utils.d.ts +0 -1
- package/dist/types/modules/event/helpers/localstorage.service.d.ts +0 -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15162
|
-
|
|
15163
|
-
|
|
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
|
-
|
|
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 (!
|
|
15216
|
-
|
|
15940
|
+
if (!LocalStorageService.instance) {
|
|
15941
|
+
LocalStorageService.instance = new LocalStorageService();
|
|
15217
15942
|
}
|
|
15218
|
-
return
|
|
15943
|
+
return LocalStorageService.instance;
|
|
15219
15944
|
}
|
|
15220
15945
|
syncLocalStorage() {
|
|
15221
|
-
const localStorageData = localStorage.getItem(
|
|
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
|
|
15949
|
+
const decryptedData = this.decryptData(localStorageData);
|
|
15950
|
+
const parsedData = JSON.parse(decryptedData);
|
|
15226
15951
|
if (parsedData && typeof parsedData === 'object') {
|
|
15227
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15253
|
-
|
|
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(
|
|
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) >
|
|
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
|
-
|
|
16019
|
+
mapToObject(map) {
|
|
15269
16020
|
return Object.fromEntries(map);
|
|
15270
16021
|
}
|
|
15271
|
-
|
|
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
|
-
|
|
15276
|
-
|
|
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
|
-
|
|
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
|
|
16533
|
+
this.slides.forEach((slide) => {
|
|
15700
16534
|
const slideElement = document.createElement('div');
|
|
15701
|
-
slideElement.className =
|
|
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
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
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
|
-
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
17549
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
|
|
17969
|
-
|
|
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
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
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 (!
|
|
17978
|
-
|
|
18870
|
+
if (!MonitorService.instance) {
|
|
18871
|
+
MonitorService.instance = new MonitorService();
|
|
17979
18872
|
}
|
|
17980
|
-
return
|
|
18873
|
+
return MonitorService.instance;
|
|
17981
18874
|
}
|
|
17982
|
-
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
|
|
17986
|
-
|
|
17987
|
-
|
|
17988
|
-
|
|
17989
|
-
|
|
17990
|
-
|
|
17991
|
-
|
|
17992
|
-
|
|
17993
|
-
|
|
17994
|
-
|
|
17995
|
-
|
|
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
|
-
|
|
18005
|
-
|
|
18006
|
-
|
|
18007
|
-
|
|
18008
|
-
|
|
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
|
-
|
|
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.
|
|
18048
|
-
this.
|
|
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.
|
|
18993
|
+
return this.pubSubService.subscribe(eventType, callback);
|
|
18061
18994
|
}
|
|
18062
18995
|
publish(eventType, data) {
|
|
18063
|
-
this.
|
|
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
|
|
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.
|
|
19077
|
+
const merged = this.deepMerge(currentState, updates);
|
|
19078
|
+
this.spotStates.set(placementId, merged);
|
|
18145
19079
|
if (publish) {
|
|
18146
|
-
this.
|
|
19080
|
+
this.pubSubService.publish(RMN_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
|
|
18147
19081
|
}
|
|
18148
19082
|
}
|
|
18149
|
-
|
|
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
|
-
|
|
18152
|
-
|
|
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
|
-
|
|
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.
|
|
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 : [
|
|
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
|
|
18183
|
-
this.
|
|
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
|
|
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: '
|
|
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
|
-
}
|
|
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
|
-
}
|
|
18648
|
-
|
|
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 };
|