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