vviinn-widgets 2.13.0 → 2.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/cjs/{highlight-box_22.cjs.entry.js → cropper-handler_29.cjs.entry.js} +579 -91
  2. package/dist/cjs/{imageSearch.store-8987ae77.js → index-4ea3a37f.js} +14723 -11183
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{vviinn-button_6.cjs.entry.js → vviinn-carousel_2.cjs.entry.js} +26 -323
  5. package/dist/cjs/vviinn-recommendations-sidebar.cjs.entry.js +65 -0
  6. package/dist/cjs/vviinn-vpr-button.cjs.entry.js +50 -0
  7. package/dist/cjs/vviinn-widgets.cjs.js +1 -1
  8. package/dist/collection/components/vviinn-vpr-button/vviinn-vpr-button.js +4 -1
  9. package/dist/collection/components/vviinn-vps-button/vviinn-vps-button.js +2 -1
  10. package/dist/esm/{highlight-box_22.entry.js → cropper-handler_29.entry.js} +501 -20
  11. package/dist/esm/{imageSearch.store-7be7e733.js → index-492f97b7.js} +14983 -11455
  12. package/dist/esm/{index-6f22c68e.js → index-84a46578.js} +1 -1
  13. package/dist/esm/loader.js +1 -1
  14. package/dist/esm/{vviinn-button_6.entry.js → vviinn-carousel_2.entry.js} +3 -296
  15. package/dist/esm/vviinn-recommendations-sidebar.entry.js +61 -0
  16. package/dist/esm/vviinn-vpr-button.entry.js +46 -0
  17. package/dist/esm/vviinn-widgets.js +1 -1
  18. package/dist/vviinn-widgets/p-1a046662.entry.js +1 -0
  19. package/dist/vviinn-widgets/p-2573d0c3.js +1 -0
  20. package/dist/vviinn-widgets/p-4c916bb9.entry.js +1 -0
  21. package/dist/vviinn-widgets/p-4ce65bdb.entry.js +1 -0
  22. package/dist/vviinn-widgets/{p-b1a3c4c6.js → p-90742d1c.js} +1 -1
  23. package/dist/vviinn-widgets/p-c29c3636.entry.js +1 -0
  24. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  25. package/package.json +1 -1
  26. package/www/build/p-1a046662.entry.js +1 -0
  27. package/www/build/p-2573d0c3.js +1 -0
  28. package/www/build/p-4c916bb9.entry.js +1 -0
  29. package/www/build/p-4ce65bdb.entry.js +1 -0
  30. package/www/build/{p-b1a3c4c6.js → p-90742d1c.js} +1 -1
  31. package/www/build/p-c29c3636.entry.js +1 -0
  32. package/www/build/{p-fadf8e72.js → p-dc60c197.js} +1 -1
  33. package/www/build/vviinn-widgets.esm.js +1 -1
  34. package/www/index.html +257 -1
  35. package/dist/cjs/Handler-176539c8.js +0 -331
  36. package/dist/cjs/cropper-handler.cjs.entry.js +0 -27
  37. package/dist/cjs/customized-slots-84e1c444.js +0 -53
  38. package/dist/cjs/index-cf5f9c72.js +0 -3235
  39. package/dist/cjs/vviinn-error.cjs.entry.js +0 -19
  40. package/dist/cjs/vviinn-preloader.cjs.entry.js +0 -26
  41. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -45
  42. package/dist/cjs/vviinn-vps-widget.cjs.entry.js +0 -171
  43. package/dist/esm/Handler-f9b8735c.js +0 -309
  44. package/dist/esm/cropper-handler.entry.js +0 -23
  45. package/dist/esm/customized-slots-01387ced.js +0 -50
  46. package/dist/esm/index-18ec919d.js +0 -3224
  47. package/dist/esm/vviinn-error.entry.js +0 -15
  48. package/dist/esm/vviinn-preloader.entry.js +0 -22
  49. package/dist/esm/vviinn-vps-button.entry.js +0 -41
  50. package/dist/esm/vviinn-vps-widget.entry.js +0 -167
  51. package/dist/vviinn-widgets/p-0f37e35e.js +0 -1
  52. package/dist/vviinn-widgets/p-11f61564.js +0 -1
  53. package/dist/vviinn-widgets/p-6766e68d.entry.js +0 -1
  54. package/dist/vviinn-widgets/p-88d472cc.entry.js +0 -1
  55. package/dist/vviinn-widgets/p-9194527e.js +0 -1
  56. package/dist/vviinn-widgets/p-be862b02.entry.js +0 -1
  57. package/dist/vviinn-widgets/p-c59a3856.entry.js +0 -1
  58. package/dist/vviinn-widgets/p-c8622fab.entry.js +0 -1
  59. package/dist/vviinn-widgets/p-cfd1a0f7.entry.js +0 -1
  60. package/dist/vviinn-widgets/p-d8a8cca5.entry.js +0 -1
  61. package/dist/vviinn-widgets/p-fb95aa1e.js +0 -1
  62. package/www/build/p-0f37e35e.js +0 -1
  63. package/www/build/p-11f61564.js +0 -1
  64. package/www/build/p-6766e68d.entry.js +0 -1
  65. package/www/build/p-88d472cc.entry.js +0 -1
  66. package/www/build/p-9194527e.js +0 -1
  67. package/www/build/p-be862b02.entry.js +0 -1
  68. package/www/build/p-c59a3856.entry.js +0 -1
  69. package/www/build/p-c8622fab.entry.js +0 -1
  70. package/www/build/p-cfd1a0f7.entry.js +0 -1
  71. package/www/build/p-d8a8cca5.entry.js +0 -1
  72. package/www/build/p-fb95aa1e.js +0 -1
@@ -3,10 +3,42 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-1077e27c.js');
6
- const imageSearch_store = require('./imageSearch.store-8987ae77.js');
7
- const Handler = require('./Handler-176539c8.js');
8
- const index$1 = require('./index-b2b8f092.js');
9
- const customizedSlots = require('./customized-slots-84e1c444.js');
6
+ const index$1 = require('./index-4ea3a37f.js');
7
+ const index$2 = require('./index-b2b8f092.js');
8
+
9
+ const cropperHandlerCss = ":host{--size:20px;background:transparent;border:4px solid white;box-sizing:content-box;display:block;height:var(--size);touch-action:none;position:absolute;width:var(--size);z-index:4;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.disabled){opacity:0.25}:host(.nw-resize){border-bottom:none;border-right:none;top:0;left:0}:host(.ne-resize){border-left:none;border-bottom:none;right:0;top:0}:host(.sw-resize){border-right:none;border-top:none;left:0;bottom:0}:host(.se-resize){border-left:none;border-top:none;bottom:0;right:0}";
10
+
11
+ let CropperHandler = class {
12
+ constructor(hostRef) {
13
+ index.registerInstance(this, hostRef);
14
+ this.disabled = false;
15
+ }
16
+ render() {
17
+ return (index.h(index.Host, { part: `handle ${index$1.getCursorValue(this.handler.direction)}`, class: {
18
+ disabled: this.disabled,
19
+ [index$1.getCursorValue(this.handler.direction)]: true,
20
+ }, style: {
21
+ "--size": "20px",
22
+ cursor: index$1.getCursorValue(this.handler.direction),
23
+ }, draggable: false }));
24
+ }
25
+ };
26
+ CropperHandler.style = cropperHandlerCss;
27
+
28
+ const fromRectangle = (shape, target) => {
29
+ const top = `${shape.y}px`;
30
+ const left = `${shape.x}px`;
31
+ const right = `${target.width - (shape.x + shape.width)}px`;
32
+ const bottom = `${target.height - (shape.y + shape.height)}px`;
33
+ return {
34
+ top,
35
+ right,
36
+ bottom,
37
+ left,
38
+ };
39
+ };
40
+ const printClip = (clip) => `inset(${clip.top} ${clip.right} ${clip.bottom} ${clip.left})`;
41
+ const getClipValue = (shape, target) => printClip(fromRectangle(shape, target));
10
42
 
11
43
  // -------------------------------------------------------------------------------------
12
44
  // -------------------------------------------------------------------------------------
@@ -28,21 +60,6 @@ var Ord = {
28
60
  compare: function (first, second) { return (first < second ? -1 : first > second ? 1 : 0); }
29
61
  };
30
62
 
31
- const fromRectangle = (shape, target) => {
32
- const top = `${shape.y}px`;
33
- const left = `${shape.x}px`;
34
- const right = `${target.width - (shape.x + shape.width)}px`;
35
- const bottom = `${target.height - (shape.y + shape.height)}px`;
36
- return {
37
- top,
38
- right,
39
- bottom,
40
- left,
41
- };
42
- };
43
- const printClip = (clip) => `inset(${clip.top} ${clip.right} ${clip.bottom} ${clip.left})`;
44
- const getClipValue = (shape, target) => printClip(fromRectangle(shape, target));
45
-
46
63
  const highlightBoxCss = ":host{display:grid;position:absolute;box-sizing:border-box;border:none;width:100%;height:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;--size:10px;--x-position:0;--y-position:0}img{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pointer{position:absolute;width:var(--size);height:var(--size);background:black;border-radius:50%;z-index:2;cursor:pointer;transform:translate(var(--x-position), var(--y-position)) scale(0);-webkit-animation:0.25s linear fadein;animation:0.25s linear fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.pointer::after{content:\"\";cursor:pointer;border:5px solid black;border-radius:50%;width:var(--size);height:var(--size);display:block;transform:translate(calc(-50% + var(--size) * 0.5), calc(-50% + var(--size) * 0.5));padding:calc(var(--size) * 0.5);opacity:.75}@-webkit-keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}@keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}";
47
64
 
48
65
  let HighlightBox = class {
@@ -50,10 +67,10 @@ let HighlightBox = class {
50
67
  index.registerInstance(this, hostRef);
51
68
  }
52
69
  getInsetValue() {
53
- return Handler.pipe(imageSearch_store.sequenceToOption(imageSearch_store.imageSearchState.searchArea, imageSearch_store.imageSearchState.imageBounds), imageSearch_store.Option.map(([selection, image]) => getClipValue(selection, image)), imageSearch_store.Option.getOrElse(() => ""));
70
+ return index$1.pipe(index$1.sequenceToOption(index$1.imageSearchState.searchArea, index$1.imageSearchState.imageBounds), index$1.Option.map(([selection, image]) => getClipValue(selection, image)), index$1.Option.getOrElse(() => ""));
54
71
  }
55
72
  renderImage() {
56
- return Handler.pipe(imageSearch_store.sequenceToOption(imageSearch_store.imageSearchState.imageUrl, imageSearch_store.imageSearchState.imageBounds), imageSearch_store.Option.map(([url, bounds]) => (index.h("img", { src: url, width: bounds.width, height: bounds.height, style: { "clip-path": `${this.getInsetValue()}` } }))), imageSearch_store.Option.getOrElse(() => ""));
73
+ return index$1.pipe(index$1.sequenceToOption(index$1.imageSearchState.imageUrl, index$1.imageSearchState.imageBounds), index$1.Option.map(([url, bounds]) => (index.h("img", { src: url, width: bounds.width, height: bounds.height, style: { "clip-path": `${this.getInsetValue()}` } }))), index$1.Option.getOrElse(() => ""));
57
74
  }
58
75
  render() {
59
76
  return index.h(index.Host, null, this.renderImage());
@@ -89,19 +106,19 @@ let ImageCropper = class {
89
106
  handleHandlerMove(event) {
90
107
  event.preventDefault();
91
108
  event.stopPropagation();
92
- const destination = Handler.fromMouseEvent(event);
93
- const distance = Handler.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
109
+ const destination = index$1.fromMouseEvent(event);
110
+ const distance = index$1.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
94
111
  const transformedHandler = {
95
112
  position: distance,
96
113
  direction: this.handlerMoveDirection,
97
114
  };
98
- imageSearch_store._function.pipe(imageSearch_store.imageSearchState.searchArea, imageSearch_store.Option.map((area) => {
99
- const newSearchArea = imageSearch_store.transform(area, transformedHandler);
115
+ index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((area) => {
116
+ const newSearchArea = index$1.transform(area, transformedHandler);
100
117
  if (this.outOfBounds(newSearchArea))
101
118
  return;
102
- imageSearch_store.imageSearchState.searchArea = imageSearch_store.Option.some(newSearchArea);
119
+ index$1.imageSearchState.searchArea = index$1.Option.some(newSearchArea);
103
120
  this.mouseStartPoint = destination;
104
- imageSearch_store.imageSearchState.detectedObject = undefined;
121
+ index$1.imageSearchState.detectedObject = undefined;
105
122
  }));
106
123
  }
107
124
  outOfBounds(area) {
@@ -115,23 +132,23 @@ let ImageCropper = class {
115
132
  handleCropperMove(ev) {
116
133
  ev.preventDefault();
117
134
  ev.stopPropagation();
118
- const destination = Handler.fromMouseEvent(ev);
119
- const distance = Handler.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
120
- imageSearch_store._function.pipe(imageSearch_store.imageSearchState.searchArea, imageSearch_store.Option.map((searchArea) => {
121
- const newSearchArea = imageSearch_store.move(searchArea, distance);
135
+ const destination = index$1.fromMouseEvent(ev);
136
+ const distance = index$1.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
137
+ index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((searchArea) => {
138
+ const newSearchArea = index$1.move(searchArea, distance);
122
139
  if (newSearchArea.x < 0 ||
123
140
  newSearchArea.y < 0 ||
124
141
  this.bounds.height - (newSearchArea.y + newSearchArea.height) < 0 ||
125
142
  this.bounds.width - (newSearchArea.x + newSearchArea.width) < 0)
126
143
  return;
127
- imageSearch_store.imageSearchState.detectedObject = undefined;
128
- imageSearch_store.imageSearchState.searchArea = imageSearch_store.Option.some(newSearchArea);
144
+ index$1.imageSearchState.detectedObject = undefined;
145
+ index$1.imageSearchState.searchArea = index$1.Option.some(newSearchArea);
129
146
  this.mouseStartPoint = destination;
130
147
  }));
131
148
  }
132
149
  handlePointerDown(event) {
133
150
  event.stopPropagation();
134
- this.mouseStartPoint = Handler.fromMouseEvent(event);
151
+ this.mouseStartPoint = index$1.fromMouseEvent(event);
135
152
  // should be htmlelement or handler
136
153
  const target = findTarget(event);
137
154
  if (target.localName === "cropper-handler") {
@@ -151,18 +168,18 @@ let ImageCropper = class {
151
168
  this.el.removeEventListener("pointermove", this.pointerMoveListener);
152
169
  document.removeEventListener("pointerup", this.pointerReleaseListener);
153
170
  this.mouseStartPoint = undefined;
154
- imageSearch_store.makeRectangularSearchRequest();
171
+ index$1.makeRectangularSearchRequest();
155
172
  this.cropperChanged.emit();
156
173
  }
157
174
  getStyleMap() {
158
- return imageSearch_store._function.pipe(imageSearch_store.imageSearchState.searchArea, imageSearch_store.Option.map((rectangle) => {
175
+ return index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((rectangle) => {
159
176
  return {
160
177
  width: `${rectangle.width}px`,
161
178
  height: `${rectangle.height}px`,
162
179
  transform: `translate3d(${rectangle.x}px, ${rectangle.y}px, 0)`,
163
180
  cursor: this.handleMove ? "move" : "default",
164
181
  };
165
- }), imageSearch_store.Option.getOrElse(() => {
182
+ }), index$1.Option.getOrElse(() => {
166
183
  return {};
167
184
  }));
168
185
  }
@@ -171,7 +188,7 @@ let ImageCropper = class {
171
188
  "crop-area": true,
172
189
  active: this.handleMove,
173
190
  disabled: this.disabled,
174
- }, draggable: false, style: this.getStyleMap(), onContextMenu: () => false, onPointerDown: (ev) => this.handlePointerDown(ev) }, imageSearch_store.imageSearchState.cropperHandlers.map((handler) => (index.h("cropper-handler", { disabled: this.disabled, handler: handler, onPointerDown: (ev) => this.handlePointerDown(ev) }))))));
191
+ }, draggable: false, style: this.getStyleMap(), onContextMenu: () => false, onPointerDown: (ev) => this.handlePointerDown(ev) }, index$1.imageSearchState.cropperHandlers.map((handler) => (index.h("cropper-handler", { disabled: this.disabled, handler: handler, onPointerDown: (ev) => this.handlePointerDown(ev) }))))));
175
192
  }
176
193
  get el() { return index.getElement(this); }
177
194
  };
@@ -197,12 +214,12 @@ let SearchFilters = class {
197
214
  }
198
215
  selectFilter(filter) {
199
216
  this.selectedCategoryId = getFilterId(filter);
200
- imageSearch_store.imageSearchState.activeIonLink = filter;
217
+ index$1.imageSearchState.activeIonLink = filter;
201
218
  this.filterSelected.emit("select");
202
219
  }
203
220
  clearSelectedFilter() {
204
221
  this.selectedCategoryId = null;
205
- imageSearch_store.imageSearchState.activeIonLink = undefined;
222
+ index$1.imageSearchState.activeIonLink = undefined;
206
223
  this.findSelectedFilter().blur();
207
224
  this.filterSelected.emit("deselect");
208
225
  }
@@ -229,7 +246,7 @@ let SearchFilters = class {
229
246
  }, style: { "animation-delay": `${n * 10}ms` }, onPointerUp: (ev) => {
230
247
  ev.stopPropagation();
231
248
  this.handleFilterSelection(f);
232
- }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? index.h(index$1.CheckIcon, null) : null, f.name))), index.h("div", { class: {
249
+ }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? index.h(index$2.CheckIcon, null) : null, f.name))), index.h("div", { class: {
233
250
  filter: true,
234
251
  "show-more": true,
235
252
  hidden: this.filter.filters.length <= FILTERS_COUNT,
@@ -244,6 +261,19 @@ let SearchFilters = class {
244
261
  };
245
262
  SearchFilters.style = searchFiltersCss;
246
263
 
264
+ const vviinnButtonCss = ":host{display:block}.open-button{align-items:center;background:rgba(255, 255, 255, 0.8);border-radius:50%;border:none;box-shadow:0px 2px 6px rgba(0, 0, 0, 0.15);box-sizing:border-box;cursor:pointer;display:grid;height:40px;justify-items:center;padding:0;width:40px;transition:all 0.25s ease-in-out}.raw-open-button{background:none;border:none;cursor:pointer}.open-button:hover{box-shadow:0px 2px 6px rgba(0, 0, 0, 0.25)}.open-button:focus{border:2px solid rgba(15, 98, 254, 0.5);outline:none}.open-button:active{background:#F4F4F4;outline:none}";
265
+
266
+ let VviinnButton = class {
267
+ constructor(hostRef) {
268
+ index.registerInstance(this, hostRef);
269
+ this.addStyle = true;
270
+ }
271
+ render() {
272
+ return (index.h(index.Host, null, index.h("button", { class: this.addStyle ? "open-button" : "raw-open-button", part: "button" }, index.h("slot", null, index.h(index$2.VisualSearchIcon, null)))));
273
+ }
274
+ };
275
+ VviinnButton.style = vviinnButtonCss;
276
+
247
277
  const vviinnDetectedObjectCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{--size:32px;--x-position:0;--y-position:0;background:rgba(22, 22, 22, 0.5);border-radius:50%;border:none;cursor:pointer;display:block;height:var(--size);position:absolute;transition:opacity 0.25s;width:var(--size);z-index:2;transform:translate(calc(var(--x-position) - (var(--size) * 0.5)), calc(var(--y-position) - (var(--size) * 0.5)));transition:background 0.1 ease-in-out}:host(:hover){background:rgba(22, 22, 22, 0.75)}:host(.active){background:var(--color-primary, var(--color-primary-system))!important;border:2px solid white}:host::after{--size:32px;border-radius:50%;content:\"\";cursor:pointer;display:block;height:calc(var(--size) * 0.25);transform:translate(calc(-50% + var(--size) * 0.5), calc(-50% + var(--size) * 0.5));width:calc(var(--size) * 0.25);background:white}";
248
278
 
249
279
  let VviinnDetectedObject = class {
@@ -253,31 +283,31 @@ let VviinnDetectedObject = class {
253
283
  this.position = ["0", "0"];
254
284
  }
255
285
  getObjectPosition() {
256
- return imageSearch_store._function.pipe(imageSearch_store.imageSearchState.imageBounds, imageSearch_store.Option.map((bounds) => {
257
- const objectRectangle = imageSearch_store.fromAlt(imageSearch_store.foldValueObject(this.detectedObject).rectangle);
258
- const { x, y } = imageSearch_store._function.pipe(objectRectangle, imageSearch_store.scaleWithSized(bounds), imageSearch_store.center);
286
+ return index$1._function.pipe(index$1.imageSearchState.imageBounds, index$1.Option.map((bounds) => {
287
+ const objectRectangle = index$1.fromAlt(index$1.foldValueObject(this.detectedObject).rectangle);
288
+ const { x, y } = index$1._function.pipe(objectRectangle, index$1.scaleWithSized(bounds), index$1.center);
259
289
  return [`${x}px`, `${y}px`];
260
- }), imageSearch_store.Option.getOrElse(() => ["0", "0"]));
290
+ }), index$1.Option.getOrElse(() => ["0", "0"]));
261
291
  }
262
292
  selectDetectedObject() {
263
- imageSearch_store._function.pipe(imageSearch_store.imageSearchState.imageBounds, imageSearch_store.Option.map((bounds) => {
264
- const rectangle = imageSearch_store.foldValueObject(this.detectedObject).rectangle;
265
- const transformedRect = imageSearch_store.fromAlt(rectangle);
266
- const scaledRect = imageSearch_store.scaleWithSized(bounds)(transformedRect);
267
- imageSearch_store.imageSearchState.detectedObject = this.detectedObject;
268
- imageSearch_store.imageSearchState.searchArea = imageSearch_store.Option.some(scaledRect);
293
+ index$1._function.pipe(index$1.imageSearchState.imageBounds, index$1.Option.map((bounds) => {
294
+ const rectangle = index$1.foldValueObject(this.detectedObject).rectangle;
295
+ const transformedRect = index$1.fromAlt(rectangle);
296
+ const scaledRect = index$1.scaleWithSized(bounds)(transformedRect);
297
+ index$1.imageSearchState.detectedObject = this.detectedObject;
298
+ index$1.imageSearchState.searchArea = index$1.Option.some(scaledRect);
269
299
  }));
270
- imageSearch_store.makeRectangularSearchRequest();
300
+ index$1.makeRectangularSearchRequest();
271
301
  this.detectedObjectClicked.emit();
272
302
  }
273
303
  isActive() {
274
304
  if (!this.detectedObject)
275
305
  return false;
276
- if (!imageSearch_store.imageSearchState.detectedObject)
306
+ if (!index$1.imageSearchState.detectedObject)
277
307
  return false;
278
- const thisObject = imageSearch_store.foldValueObject(this.detectedObject);
279
- const savedObject = imageSearch_store.foldValueObject(imageSearch_store.imageSearchState.detectedObject);
280
- return imageSearch_store.detectedObjectEq.equals(thisObject, savedObject);
308
+ const thisObject = index$1.foldValueObject(this.detectedObject);
309
+ const savedObject = index$1.foldValueObject(index$1.imageSearchState.detectedObject);
310
+ return index$1.detectedObjectEq.equals(thisObject, savedObject);
281
311
  }
282
312
  render() {
283
313
  return (index.h(index.Host, { class: {
@@ -303,6 +333,18 @@ let VviinnEmptyResults = class {
303
333
  };
304
334
  VviinnEmptyResults.style = vviinnEmptyResultsCss;
305
335
 
336
+ const vviinnErrorCss = ":host{background:#F4F4F4;border-radius:8px;display:grid;grid-gap:20px;padding:24px;text-align:center}::slotted(svg){display:grid;align-self:center}::slotted(h4){margin:unset;font-weight:600;font-size:18px;line-height:24px}::slotted(span){font-size:14px;line-height:20px}::slotted(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background:transparent;color:var(--color-primary, var(--color-primary-system));font-weight:600;font-size:16px;line-height:20px;cursor:pointer}";
337
+
338
+ let VviinnError = class {
339
+ constructor(hostRef) {
340
+ index.registerInstance(this, hostRef);
341
+ }
342
+ render() {
343
+ return (index.h(index.Host, null, index.h("slot", { name: "icon" }), index.h("slot", { name: "title" }), index.h("slot", { name: "text" }), index.h("slot", { name: "action" })));
344
+ }
345
+ };
346
+ VviinnError.style = vviinnErrorCss;
347
+
306
348
  const vviinnExampleImageCss = ":host{display:block;margin-bottom:8px;position:relative}:host(:focus){border:2px solid var(--color-primary)}img{width:100%;height:auto;cursor:pointer}.image-preloader{background:rgba(0, 0, 0, 0.25);border-radius:4px;bottom:12px;display:none;padding:4px 6px;position:absolute;right:12px;z-index:4}vviinn-preloader{--preloader-size:12px}@media (max-width: 640px){.image-preloader{display:block}}";
307
349
 
308
350
  let VviinnExampleImage = class {
@@ -318,9 +360,9 @@ let VviinnExampleImage = class {
318
360
  }
319
361
  async selectImage() {
320
362
  this.selected = true;
321
- const file = await imageSearch_store.toFile(this.src);
322
- const processResult = await imageSearch_store.processSelectedFile(file);
323
- imageSearch_store._function.pipe(processResult, imageSearch_store.Either.match(() => this.exampleImageError.emit(), () => this.exampleImageSelected.emit()));
363
+ const file = await index$1.toFile(this.src);
364
+ const processResult = await index$1.processSelectedFile(file);
365
+ index$1._function.pipe(processResult, index$1.Either.match(() => this.exampleImageError.emit(), () => this.exampleImageSelected.emit()));
324
366
  this.selected = false;
325
367
  }
326
368
  handleKeyPress({ key }) {
@@ -329,8 +371,8 @@ let VviinnExampleImage = class {
329
371
  this.selectImage();
330
372
  }
331
373
  showPreloader() {
332
- return ((imageSearch_store.imageSearchState.objectDetectionInProgress ||
333
- imageSearch_store.imageSearchState.loading) &&
374
+ return ((index$1.imageSearchState.objectDetectionInProgress ||
375
+ index$1.imageSearchState.loading) &&
334
376
  this.selected);
335
377
  }
336
378
  render() {
@@ -339,6 +381,53 @@ let VviinnExampleImage = class {
339
381
  };
340
382
  VviinnExampleImage.style = vviinnExampleImageCss;
341
383
 
384
+ const defaultSlotsNames = [
385
+ "vviinn-onboarding-title",
386
+ "vviinn-onboarding-card-1-icon",
387
+ "vviinn-onboarding-card-1-text",
388
+ "vviinn-onboarding-card-2-icon",
389
+ "vviinn-onboarding-card-2-text",
390
+ "vviinn-onboarding-card-3-icon",
391
+ "vviinn-onboarding-card-3-text",
392
+ "vviinn-example-images-title",
393
+ "vviinn-example-images-1",
394
+ "vviinn-example-images-2",
395
+ "vviinn-example-images-3",
396
+ "vviinn-example-images-4",
397
+ "vviinn-teaser-text",
398
+ "vviinn-image-upload-button-text",
399
+ "vviinn-privacy-badge-text"
400
+ ];
401
+ const renderNamedSlot = (name) => index.h("slot", { name: name });
402
+ const SlotSkeleton = () => defaultSlotsNames.map(renderNamedSlot);
403
+ const getSlots = (element) => Array.from(element.shadowRoot.querySelectorAll("slot"));
404
+ const getNameAttribute = (element) => element.getAttribute("name");
405
+ const getSlotAttribute = (element) => element.getAttribute("slot");
406
+ const elementContainSlot = (slot) => (container) => {
407
+ const name1 = getNameAttribute(slot);
408
+ const name2 = getSlotAttribute(container);
409
+ return name1 === name2;
410
+ };
411
+ const getContentToReplace = (targets) => (acc, content) => {
412
+ const replaceCandidate = targets.find(elementContainSlot(content));
413
+ if (replaceCandidate) {
414
+ acc.set(content, replaceCandidate);
415
+ }
416
+ return acc;
417
+ };
418
+ const replaceSlotContent = (content, target) => {
419
+ target.innerHTML = content.outerHTML;
420
+ };
421
+ const slotChangeListener = (component, element) => {
422
+ component.connectedCallback = function () {
423
+ document.addEventListener("globalSlotsChanged", ({ detail }) => {
424
+ const slotsToReplace = getSlots(element).reduce(getContentToReplace(detail), new Map());
425
+ slotsToReplace.forEach(replaceSlotContent);
426
+ }, true);
427
+ };
428
+ component.connectedCallback.call(component);
429
+ };
430
+
342
431
  const vviinnExampleImagesCss = "h3{font-size:22px;font-weight:600;line-height:32px;margin:0;margin-bottom:16px;text-align:center}.images{display:block;-moz-column-count:2;column-count:2;-moz-column-gap:16px;column-gap:16px}";
343
432
 
344
433
  let VviinnExampleImages = class {
@@ -354,7 +443,7 @@ let VviinnExampleImages = class {
354
443
  this.imageSelectedError.emit();
355
444
  }
356
445
  componentWillLoad() {
357
- customizedSlots.slotChangeListener(this, this.el);
446
+ slotChangeListener(this, this.el);
358
447
  }
359
448
  delegateFocus() {
360
449
  const firstSlot = this.imagesBlock.childNodes[0];
@@ -378,12 +467,12 @@ let VviinnImageSelector = class {
378
467
  }
379
468
  async handleInputChange(event) {
380
469
  const input = event.target;
381
- const processingResult = await imageSearch_store.processSelectedFile(input.files[0]);
382
- imageSearch_store._function.pipe(processingResult, imageSearch_store.match$1(() => this.imageSelectedError.emit(), () => this.imageSelected.emit()));
470
+ const processingResult = await index$1.processSelectedFile(input.files[0]);
471
+ index$1._function.pipe(processingResult, index$1.match(() => this.imageSelectedError.emit(), () => this.imageSelected.emit()));
383
472
  input.value = null;
384
473
  }
385
474
  isLoading() {
386
- return (imageSearch_store.imageSearchState.loading || imageSearch_store.imageSearchState.objectDetectionInProgress);
475
+ return (index$1.imageSearchState.loading || index$1.imageSearchState.objectDetectionInProgress);
387
476
  }
388
477
  render() {
389
478
  return (index.h(index.Host, { exportparts: "button" }, this.isLoading() ? index.h("vviinn-preloader", null) : null, this.isLoading() ? null : (index.h("label", { htmlFor: "fileInput", part: "button" }, index.h("slot", { name: "upload-button-text" }, "Upload image"))), index.h("input", { id: "fileInput", class: "visually-hidden", type: "file", accept: "image/*", onChange: (event) => this.handleInputChange(event) })));
@@ -394,8 +483,8 @@ VviinnImageSelector.style = vviinnImageSelectorCss;
394
483
  const vviinnImageViewCss = ":host{display:grid;position:relative;justify-self:center}img{box-sizing:border-box;filter:brightness(60%);position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:-1}.image-preloader{background:rgba(0, 0, 0, 0.25);border-radius:4px;bottom:18px;padding:4px 6px;pointer-events:none;position:absolute;right:18px;z-index:4}vviinn-preloader{--preloader-size:12px}";
395
484
 
396
485
  const getImageSizes = (i) => {
397
- const dimensions = imageSearch_store.dimensionsFromImage(i);
398
- const resize = imageSearch_store.scaleByLargestSide(288);
486
+ const dimensions = index$1.dimensionsFromImage(i);
487
+ const resize = index$1.scaleByLargestSide(288);
399
488
  const newDimensions = resize(dimensions);
400
489
  const sizes = newDimensions.map((d) => d.size);
401
490
  return [sizes[0], sizes[1]];
@@ -406,34 +495,34 @@ let VviinnImageView = class {
406
495
  }
407
496
  handleInitialImageLoad(ev) {
408
497
  const target = ev.target;
409
- const imageBounds = imageSearch_store.fromImage(target);
498
+ const imageBounds = index$1.fromImage(target);
410
499
  const padding = 12;
411
- const { x, y } = imageSearch_store.move(imageBounds, { x: padding, y: padding });
500
+ const { x, y } = index$1.move(imageBounds, { x: padding, y: padding });
412
501
  const searchArea = {
413
502
  x,
414
503
  y,
415
504
  width: imageBounds.width - padding * 2,
416
505
  height: imageBounds.height - padding * 2,
417
506
  };
418
- imageSearch_store.imageSearchState.imageBounds = imageSearch_store.Option.some(imageBounds);
419
- imageSearch_store.imageSearchState.searchArea = imageSearch_store.Option.some(searchArea);
507
+ index$1.imageSearchState.imageBounds = index$1.Option.some(imageBounds);
508
+ index$1.imageSearchState.searchArea = index$1.Option.some(searchArea);
420
509
  }
421
510
  renderDetectedObject(object) {
422
511
  return index.h("vviinn-detected-object", { detectedObject: object });
423
512
  }
424
513
  renderImage() {
425
- return imageSearch_store._function.pipe(imageSearch_store.sequenceToOption(imageSearch_store.imageSearchState.imageUrl, imageSearch_store.imageSearchState.image), imageSearch_store.Option.map(([url, refImage]) => {
514
+ return index$1._function.pipe(index$1.sequenceToOption(index$1.imageSearchState.imageUrl, index$1.imageSearchState.image), index$1.Option.map(([url, refImage]) => {
426
515
  const [width, height] = getImageSizes(refImage);
427
516
  const image = (index.h("img", { decoding: "async", width: width, height: height, src: url, onLoad: (el) => this.handleInitialImageLoad(el), draggable: false }));
428
517
  return image;
429
- }), imageSearch_store.Option.getOrElse(() => null));
518
+ }), index$1.Option.getOrElse(() => null));
430
519
  }
431
520
  renderCropper() {
432
- return imageSearch_store._function.pipe(imageSearch_store.imageSearchState.imageUrl, imageSearch_store.Option.map(() => index.h("image-cropper", null)), imageSearch_store.Option.getOrElse(() => null));
521
+ return index$1._function.pipe(index$1.imageSearchState.imageUrl, index$1.Option.map(() => index.h("image-cropper", null)), index$1.Option.getOrElse(() => null));
433
522
  }
434
523
  render() {
435
- return (index.h(index.Host, null, imageSearch_store.imageSearchState.loading ||
436
- imageSearch_store.imageSearchState.objectDetectionInProgress ? (index.h("div", { class: "image-preloader" }, index.h("vviinn-preloader", null))) : null, index.h("highlight-box", null), this.renderImage(), this.renderCropper(), imageSearch_store.imageSearchState.detectedObjects.map((o) => this.renderDetectedObject(o))));
524
+ return (index.h(index.Host, null, index$1.imageSearchState.loading ||
525
+ index$1.imageSearchState.objectDetectionInProgress ? (index.h("div", { class: "image-preloader" }, index.h("vviinn-preloader", null))) : null, index.h("highlight-box", null), this.renderImage(), this.renderCropper(), index$1.imageSearchState.detectedObjects.map((o) => this.renderDetectedObject(o))));
437
526
  }
438
527
  };
439
528
  VviinnImageView.style = vviinnImageViewCss;
@@ -472,7 +561,7 @@ let VviinnOnboarding = class {
472
561
  index.registerInstance(this, hostRef);
473
562
  }
474
563
  componentWillLoad() {
475
- customizedSlots.slotChangeListener(this, this.el);
564
+ slotChangeListener(this, this.el);
476
565
  }
477
566
  render() {
478
567
  return (index.h(index.Host, null, index.h("slot", { name: "vviinn-onboarding-title" }, index.h("h3", null, "So funktioniert es")), index.h("vviinn-slider", { showArrows: true }, index.h("vviinn-slide", null, index.h("vviinn-onboarding-card-1", null)), index.h("vviinn-slide", null, index.h("vviinn-onboarding-card-2", null)), index.h("vviinn-slide", null, index.h("vviinn-onboarding-card-3", null)))));
@@ -488,10 +577,10 @@ let VviinnOnboardingCard1 = class {
488
577
  index.registerInstance(this, hostRef);
489
578
  }
490
579
  componentWillLoad() {
491
- customizedSlots.slotChangeListener(this, this.el);
580
+ slotChangeListener(this, this.el);
492
581
  }
493
582
  render() {
494
- return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-1-icon" }, index.h(index$1.OnboardingCard1Icon, null)), index.h("slot", { name: "onboarding-card-1-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Starte die Bildsuche"), index.h("p", null, "Lade ein Bild aus Deiner Galerie hoch oder fotografiere ein Produkt mit Deiner Kamera.")))));
583
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-1-icon" }, index.h(index$2.OnboardingCard1Icon, null)), index.h("slot", { name: "onboarding-card-1-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Starte die Bildsuche"), index.h("p", null, "Lade ein Bild aus Deiner Galerie hoch oder fotografiere ein Produkt mit Deiner Kamera.")))));
495
584
  }
496
585
  get el() { return index.getElement(this); }
497
586
  };
@@ -504,10 +593,10 @@ let VviinnOnboardingCard2 = class {
504
593
  index.registerInstance(this, hostRef);
505
594
  }
506
595
  componentWillLoad() {
507
- customizedSlots.slotChangeListener(this, this.el);
596
+ slotChangeListener(this, this.el);
508
597
  }
509
598
  render() {
510
- return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-2-icon" }, index.h(index$1.OnboardingCard2Icon, null)), index.h("slot", { name: "onboarding-card-2-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Verfeiner deine Suche"), index.h("p", null, "Du kannst den Bildrahmen selber festlegen und so die Produkte genau ausw\u00E4hlen.")))));
599
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-2-icon" }, index.h(index$2.OnboardingCard2Icon, null)), index.h("slot", { name: "onboarding-card-2-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Verfeiner deine Suche"), index.h("p", null, "Du kannst den Bildrahmen selber festlegen und so die Produkte genau ausw\u00E4hlen.")))));
511
600
  }
512
601
  get el() { return index.getElement(this); }
513
602
  };
@@ -520,10 +609,10 @@ let VviinnOnboardingCard3 = class {
520
609
  index.registerInstance(this, hostRef);
521
610
  }
522
611
  componentWillLoad() {
523
- customizedSlots.slotChangeListener(this, this.el);
612
+ slotChangeListener(this, this.el);
524
613
  }
525
614
  render() {
526
- return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-3-icon" }, index.h(index$1.OnboardingCard3Icon, null)), index.h("slot", { name: "onboarding-card-3-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Ohne Hintergrund"), index.h("p", null, "Die besten Ergebnisse erh\u00E4ltst Du, wenn das gesuchte Objekt mit einfarbigem und hellem Hintergrund zu sehen ist.")))));
615
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-3-icon" }, index.h(index$2.OnboardingCard3Icon, null)), index.h("slot", { name: "onboarding-card-3-text" }, index.h("div", { class: "text" }, index.h("h4", null, "Ohne Hintergrund"), index.h("p", null, "Die besten Ergebnisse erh\u00E4ltst Du, wenn das gesuchte Objekt mit einfarbigem und hellem Hintergrund zu sehen ist.")))));
527
616
  }
528
617
  get el() { return index.getElement(this); }
529
618
  };
@@ -556,6 +645,23 @@ let VviinnOverlayedModal = class {
556
645
  };
557
646
  VviinnOverlayedModal.style = vviinnOverlayedModalCss;
558
647
 
648
+ const vviinnPreloaderCss = ":host{--preloader-size:24px;--preloader-width:calc(var(--preloader-size) / 6);transform-origin:center;-webkit-animation:rotate 3s linear infinite;animation:rotate 3s linear infinite;border:var(--preloader-width) solid white;border-radius:50%;border-top-color:transparent;display:none;outline:0;width:var(--preloader-size);height:var(--preloader-size);box-sizing:border-box}:host(.active){display:flex}@-webkit-keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}@keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}";
649
+
650
+ let VviinnPreloader = class {
651
+ constructor(hostRef) {
652
+ index.registerInstance(this, hostRef);
653
+ }
654
+ isActive() {
655
+ return (index$1.imageSearchState.loading || index$1.imageSearchState.objectDetectionInProgress);
656
+ }
657
+ render() {
658
+ return (index.h(index.Host, { class: {
659
+ active: this.isActive(),
660
+ } }));
661
+ }
662
+ };
663
+ VviinnPreloader.style = vviinnPreloaderCss;
664
+
559
665
  const vviinnPrivacyBadgeCss = ":host{display:block;background:#F4F4F4;padding:17px}.content{display:grid;grid-template-columns:-webkit-min-content auto;grid-template-columns:min-content auto;grid-gap:9px}.content p{color:#525252;font-size:12px;line-height:16px;margin:unset}";
560
666
 
561
667
  let VviinnPrivacyBadge = class {
@@ -563,7 +669,7 @@ let VviinnPrivacyBadge = class {
563
669
  index.registerInstance(this, hostRef);
564
670
  }
565
671
  componentWillLoad() {
566
- customizedSlots.slotChangeListener(this, this.el);
672
+ slotChangeListener(this, this.el);
567
673
  }
568
674
  render() {
569
675
  return (index.h(index.Host, null, index.h("slot", null, index.h("div", { class: "content" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none" }, index.h("defs", null), index.h("path", { fill: "#525252", d: "M8.5 11V7h-2v1h1v3H6v1h4v-1H8.5zM8 4a.75.75 0 100 1.5A.75.75 0 008 4z" }), index.h("path", { fill: "#525252", d: "M8 15A7 7 0 118 1a7 7 0 010 14zM8 2a6 6 0 100 12A6 6 0 008 2z" })), index.h("slot", { name: "vviinn-privacy-badge-text" }, index.h("p", null, "Wir gehen sorgf\u00E4ltig mit Deinen Daten um. Deine Bilder werden nur zum Zweck der Bildsuche gespeichert."))))));
@@ -572,6 +678,185 @@ let VviinnPrivacyBadge = class {
572
678
  };
573
679
  VviinnPrivacyBadge.style = vviinnPrivacyBadgeCss;
574
680
 
681
+ class GtagAnalytics {
682
+ sendImpression(product) {
683
+ var _a, _b, _c;
684
+ gtag('event', 'view_item_list', {
685
+ items: [
686
+ {
687
+ id: product.productId,
688
+ name: product.title,
689
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
690
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
691
+ list_name: 'VI VPR View',
692
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
693
+ }
694
+ ]
695
+ });
696
+ return undefined;
697
+ }
698
+ sendClick(product) {
699
+ var _a, _b, _c;
700
+ gtag('event', 'select_content', {
701
+ content_type: 'product',
702
+ items: [
703
+ {
704
+ id: product.productId,
705
+ name: product.title,
706
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
707
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
708
+ list_name: 'VI VPR View',
709
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
710
+ }
711
+ ]
712
+ });
713
+ return undefined;
714
+ }
715
+ }
716
+
717
+ class GAnalytics {
718
+ constructor() {
719
+ ga('require', 'ec');
720
+ }
721
+ convertProduct(product) {
722
+ var _a, _b, _c;
723
+ return {
724
+ id: product.productId,
725
+ name: product.title,
726
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
727
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
728
+ list: 'VI VPR View',
729
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
730
+ };
731
+ }
732
+ sendImpression(product) {
733
+ ga('ec:addImpression', this.convertProduct(product));
734
+ return undefined;
735
+ }
736
+ sendClick(product) {
737
+ var _a, _b, _c;
738
+ ga('ec:addProduct', {
739
+ id: product.productId,
740
+ name: product.title,
741
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
742
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
743
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
744
+ });
745
+ ga('ec:setAction', 'click', { list: 'VI VPR View' });
746
+ return undefined;
747
+ }
748
+ }
749
+
750
+ const getGtagAnalytics = () => index$1._function.pipe(index$1.Option.fromNullable(window.gtag), index$1.Option.map(() => new GtagAnalytics()));
751
+ const getCommonAnalytics = () => index$1._function.pipe(index$1.Option.fromNullable(window.ga), index$1.Option.map(() => new GAnalytics()));
752
+ const analyticsMonoid = index$1.Option.getMonoid(index$1.Semigroup.first());
753
+ const getAnalyticsModule = analyticsMonoid.concat(getGtagAnalytics(), getCommonAnalytics());
754
+
755
+ const FIT_EXPR = /fit\/\d+\//;
756
+ const containsFit = (url) => {
757
+ return index$1._function.pipe(url.match(FIT_EXPR), index$1.Either.fromNullable(url), index$1.Either.map(() => url));
758
+ };
759
+ const processWidth = (url, size) => {
760
+ return index$1._function.pipe(containsFit(url), index$1.Either.map((url) => url.replace(FIT_EXPR, `fit/${size}/`)), index$1.Either.getOrElse(() => url));
761
+ };
762
+ const Linked = (props, child) => props.deeplink ? (index.h("a", { class: props.part, part: props.part, href: props.deeplink }, child)) : (child);
763
+ const FormattedPrice = (props) => {
764
+ var _a;
765
+ const locale = props.locale;
766
+ const formattedPrice = new Intl.NumberFormat(locale, {
767
+ minimumFractionDigits: 2,
768
+ }).format(props.price);
769
+ const fullPrice = `${(_a = props.prefix) !== null && _a !== void 0 ? _a : ""} ${formattedPrice} ${props.currency}`;
770
+ return (index.h("span", { class: "price-amount", part: "price-amount" }, fullPrice));
771
+ };
772
+ const Price = (props) => {
773
+ const priceEl = (index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale }));
774
+ return (index.h("span", { class: "price-container", part: "price-container" }, props.salePrice ? ([
775
+ index.h("span", { class: "price-sale", part: "price-sale" },
776
+ index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.salePrice, locale: props.locale })),
777
+ index.h("span", { class: "price-outdated", part: "price-outdated" }, priceEl),
778
+ ]) : (index.h("span", { class: "price-regular", part: "price-regular" }, priceEl))));
779
+ };
780
+ const Image = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
781
+ index.h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image", width: props.width, height: props.height, src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
782
+ const ResponsiveImage = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
783
+ index.h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image responsive", src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
784
+
785
+ const vviinnProductCardCss = ":host{align-items:center;display:flex;flex-direction:column;gap:8px;height:100%}.price-container{display:flex;flex-direction:column}.price-sale,.price-regular{font-style:normal;font-weight:normal;font-size:16px;line-height:24px;color:#161616}.price-outdated{font-style:normal;font-weight:normal;font-size:16px;line-height:24px;color:#757575;text-decoration:line-through}.product-type{word-wrap:anywhere}.image{display:grid;align-content:center;-o-object-position:50% 50%;object-position:50% 50%;-o-object-fit:contain;object-fit:contain;text-align:center;box-sizing:border-box}img.responsive{width:100%;height:auto;aspect-ratio:1}.brand,.type{display:none}.title{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:#161616;display:-webkit-box;font-size:16px;font-style:normal;font-weight:500;line-height:24px;margin-bottom:8px;overflow:hidden}.deeplink{text-decoration:none}.image-link{display:contents}picture{position:relative;width:100%}:host(.dimmed) picture::before{content:\"\";width:100%;height:100%;box-sizing:border-box;background:#f7f7f7;display:block;top:0;left:0;position:absolute;mix-blend-mode:multiply}";
786
+
787
+ let VviinnProductCard = class {
788
+ constructor(hostRef) {
789
+ index.registerInstance(this, hostRef);
790
+ this.recommendationLoad = index.createEvent(this, "recommendationLoad", 7);
791
+ this.recommendationView = index.createEvent(this, "recommendationView", 7);
792
+ this.recommendationClick = index.createEvent(this, "recommendationClick", 7);
793
+ this.productImageLoaded = index.createEvent(this, "productImageLoaded", 7);
794
+ this.currency = undefined;
795
+ this.imageRatio = 1;
796
+ this.imageWidth = 200;
797
+ this.locale = undefined;
798
+ this.pricePrefix = undefined;
799
+ this.responsive = false;
800
+ this.dimmedBackground = false;
801
+ /** @internal */
802
+ this.index = 0;
803
+ this.imageLoaded = false;
804
+ this.productData = null;
805
+ this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { threshold: 1.0 });
806
+ }
807
+ connectedCallback() {
808
+ this.productData = this.getProductData();
809
+ }
810
+ getProductData() {
811
+ return {
812
+ product: this.productId,
813
+ rank: this.index,
814
+ };
815
+ }
816
+ intersectionCallback(data) {
817
+ if (data.some((entry) => entry.isIntersecting)) {
818
+ index$1._function.pipe(getAnalyticsModule, index$1.Option.map((analytics) => analytics.sendImpression(this.getProduct())));
819
+ this.recommendationView.emit(this.productData);
820
+ this.intersectionObserver.disconnect();
821
+ }
822
+ }
823
+ componentDidLoad() {
824
+ this.recommendationLoad.emit(this.productData);
825
+ this.intersectionObserver.observe(this.el);
826
+ const links = this.el.shadowRoot.querySelectorAll("a");
827
+ links.forEach((link) => link.addEventListener("click", (event) => {
828
+ event.preventDefault();
829
+ event.stopImmediatePropagation();
830
+ this.recommendationClick.emit(this.getProductData());
831
+ index$1._function.pipe(getAnalyticsModule, index$1.Option.match(() => null, (analytics) => analytics.sendClick(this.getProduct())));
832
+ }));
833
+ }
834
+ getProduct() {
835
+ return index$1.imageSearchState.results.find((r) => r.productId === this.productId);
836
+ }
837
+ renderImage() {
838
+ const props = {
839
+ width: this.imageWidth,
840
+ height: this.imageWidth * this.imageRatio,
841
+ src: this.image,
842
+ title: this.productTitle,
843
+ lazy: false,
844
+ };
845
+ return this.responsive
846
+ ? ResponsiveImage(props, () => this.kek())
847
+ : Image(props, () => this.kek());
848
+ }
849
+ kek() {
850
+ this.productImageLoaded.emit(this.productId);
851
+ }
852
+ render() {
853
+ var _a, _b, _c;
854
+ return (index.h(index.Host, { part: "product-card", class: { dimmed: this.dimmedBackground }, exportparts: "brand, currency, deeplink, image, image-link, price-amount, price-container, price-outdated, price-prefix, price-regular, price-sale, title" }, index.h(Linked, { deeplink: this.deeplink, part: "image-link" }, this.renderImage()), index.h(Linked, { deeplink: this.deeplink, part: "deeplink" }, index.h("span", { class: "title", part: "title" }, this.productTitle)), index.h("span", { class: "brand", part: "brand" }, this.brand), index.h("span", { class: "type", part: "type" }, this.productType), index.h(Price, { prefix: (_a = this.pricePrefix) !== null && _a !== void 0 ? _a : index$1.state.pricePrefix, currency: (_b = this.currency) !== null && _b !== void 0 ? _b : index$1.state.currencySign, price: this.price, salePrice: this.salePrice, locale: (_c = this.locale) !== null && _c !== void 0 ? _c : index$1.state.locale })));
855
+ }
856
+ get el() { return index.getElement(this); }
857
+ };
858
+ VviinnProductCard.style = vviinnProductCardCss;
859
+
575
860
  const vviinnServerErrorCss = ":host{display:block}";
576
861
 
577
862
  let VviinnServerError = class {
@@ -605,7 +890,7 @@ const getStyleMap = (data) => {
605
890
  };
606
891
  };
607
892
  const Arrow = ({ kind, tabindex, disabled, onClick, onKeyDown, }) => (index.h("div", { class: getStyleMap({ kind, disabled }), onClick: onClick, tabindex: tabindex, onKeyDown: onKeyDown },
608
- index.h(index$1.ArrowIcon, null)));
893
+ index.h(index$2.ArrowIcon, null)));
609
894
 
610
895
  const vviinnSliderCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{--num-items:0;--position:0;display:grid;grid-gap:20px;justify-items:center;position:relative}.items-wrapper{overflow:hidden;width:100%}.items{box-sizing:border-box;display:grid;grid-auto-flow:column;grid-template-columns:repeat(var(--num-items), 100%);transform:translateX(calc(-100% * var(--position)));transition:transform 0.33s ease-in-out}.controls{display:grid;grid-gap:16px;grid-template-columns:repeat(var(--num-items), -webkit-min-content);grid-template-columns:repeat(var(--num-items), min-content)}.bullet{background:#E0E0E0;border-radius:50%;box-sizing:border-box;cursor:pointer;height:8px;width:8px;transition:background 0.1s ease-in-out}.bullet:hover{background:#C6C6C6}.bullet.active{background:var(--color-primary, var(--color-primary-system))}.bullet:active{background:transparent;border:2px solid var(--color-primary, var(--color-primary-system))}.arrow-wrapper{align-items:center;background:white;border:2px solid white;bottom:0;box-sizing:border-box;display:grid;height:calc(var(--spacer) * 6);justify-items:center;margin:auto;position:absolute;top:0;transform:translate3d(0, -50%, 0);transition:border 0.25ms ease-in-out;width:calc(var(--spacer) * 4)}.arrow-wrapper:active{border-color:var(--color-primary, var(--color-primary-system));opacity:0.75}.arrow-wrapper:focus{border-color:var(--color-primary, var(--color-primary-system));opacity:0.5;outline:none}.prev{left:0}.next{right:0}.next>svg{transform:rotate3d(0, 1, 0, 180deg)}.arrow-wrapper>svg{transition:fill 0.25ms ease-in-out;fill:#A8A8A8}.arrow-wrapper:hover>svg{fill:#8D8D8D}";
611
896
 
@@ -614,7 +899,7 @@ let VviinnSlider = class {
614
899
  index.registerInstance(this, hostRef);
615
900
  this.elementsCount = 0;
616
901
  this.internalPosition = 0;
617
- this.swipeStartPosition = imageSearch_store.Option.none;
902
+ this.swipeStartPosition = index$1.Option.none;
618
903
  this.showBullets = true;
619
904
  this.position = 0;
620
905
  this.showArrows = false;
@@ -644,7 +929,7 @@ let VviinnSlider = class {
644
929
  this.setActiveCssClassToSlide(index);
645
930
  }
646
931
  renderBullets() {
647
- return this.showBullets ? (index.h("div", { class: "controls" }, imageSearch_store.NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (index.h("div", { class: {
932
+ return this.showBullets ? (index.h("div", { class: "controls" }, index$1.NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (index.h("div", { class: {
648
933
  bullet: true,
649
934
  active: i == this.internalPosition % this.elementsCount,
650
935
  }, onClick: () => this.goToSlide(i) }))))) : null;
@@ -681,13 +966,13 @@ let VviinnSlider = class {
681
966
  handleTouchStart(event) {
682
967
  if (!this.showBullets)
683
968
  return;
684
- this.swipeStartPosition = imageSearch_store._function.pipe(event.touches[0], imageSearch_store.Option.fromNullable, imageSearch_store.Option.map((t) => t.clientX));
969
+ this.swipeStartPosition = index$1._function.pipe(event.touches[0], index$1.Option.fromNullable, index$1.Option.map((t) => t.clientX));
685
970
  }
686
971
  handleTouchEnd(event) {
687
972
  if (!this.showBullets)
688
973
  return;
689
- const swipeEndPosition = imageSearch_store._function.pipe(event.changedTouches[0], imageSearch_store.Option.fromNullable, imageSearch_store.Option.map((t) => t.clientX));
690
- imageSearch_store._function.pipe(imageSearch_store.sequenceToOption(this.swipeStartPosition, swipeEndPosition), imageSearch_store.Option.map(([start, end]) => Ord.compare(start, end)), imageSearch_store.Option.map((swipeDirection) => {
974
+ const swipeEndPosition = index$1._function.pipe(event.changedTouches[0], index$1.Option.fromNullable, index$1.Option.map((t) => t.clientX));
975
+ index$1._function.pipe(index$1.sequenceToOption(this.swipeStartPosition, swipeEndPosition), index$1.Option.map(([start, end]) => Ord.compare(start, end)), index$1.Option.map((swipeDirection) => {
691
976
  switch (swipeDirection) {
692
977
  case 1:
693
978
  return this.nextSlide();
@@ -718,7 +1003,7 @@ let VviinnTeaser = class {
718
1003
  index.registerInstance(this, hostRef);
719
1004
  }
720
1005
  componentWillLoad() {
721
- customizedSlots.slotChangeListener(this, this.el);
1006
+ slotChangeListener(this, this.el);
722
1007
  }
723
1008
  render() {
724
1009
  return (index.h(index.Host, null, index.h("slot", null, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "64", height: "64", fill: "none" }, index.h("defs", null), index.h("path", { fill: "#C6C6C6", d: "M48 28a11.98 11.98 0 00-9.77 18.942L28 57.172 30.828 60l10.23-10.23A11.994 11.994 0 1048 28zm0 20a8 8 0 118-8 8.009 8.009 0 01-8 8zM34 24a6 6 0 10-6-6 6.006 6.006 0 006 6zm0-8a2 2 0 110 4 2 2 0 010-4z" }), index.h("path", { fill: "#C6C6C6", d: "M24 48H8V35.993L18 26l11.172 11.172L32 34.336 20.828 23.165a4 4 0 00-5.656 0L8 30.336V8h40v12h4V8a4.004 4.004 0 00-4-4H8a4.004 4.004 0 00-4 4v40a4.005 4.005 0 004 4h16v-4z" })), index.h("span", { class: "vviinn-teaser-text" }, index.h("slot", { name: "vviinn-teaser-text" }, "Finde Produkte auf ", index.h("br", null), " einem Foto")))));
@@ -727,6 +1012,202 @@ let VviinnTeaser = class {
727
1012
  };
728
1013
  VviinnTeaser.style = vviinnTeaserCss;
729
1014
 
1015
+ const vviinnVpsButtonCss = ":host{display:block}";
1016
+
1017
+ let VviinnVpsButton = class {
1018
+ constructor(hostRef) {
1019
+ index.registerInstance(this, hostRef);
1020
+ this.globalSlotsChanged = index.createEvent(this, "globalSlotsChanged", 7);
1021
+ /** Currency sign will shown after price */
1022
+ this.currencySign = "€";
1023
+ /** Locale for currency formatting */
1024
+ this.locale = "de-DE";
1025
+ /** Add style to the button */
1026
+ this.addStyle = false;
1027
+ this.pressed = false;
1028
+ }
1029
+ handleModalClosed() {
1030
+ this.pressed = false;
1031
+ }
1032
+ componentDidLoad() {
1033
+ const slots = this.el.querySelectorAll("[slot]");
1034
+ this.globalSlotsChanged.emit(Array.from(slots));
1035
+ }
1036
+ handleKeyDown(ev) {
1037
+ if (ev.code !== "Enter" && ev.code !== "Space")
1038
+ return;
1039
+ this.pressed = true;
1040
+ }
1041
+ handleClick() {
1042
+ this.pressed = true;
1043
+ }
1044
+ render() {
1045
+ return (index.h(index.Host, { tabindex: "0", role: "button", pressed: this.pressed, onKeyDown: (ev) => this.handleKeyDown(ev) }, index.h("vviinn-button", { onClick: () => this.handleClick(), addStyle: this.addStyle }, index.h("slot", null, index.h(index$2.CameraIcon, null))), index.h(SlotSkeleton, null), index.h("vviinn-vps-widget", { active: this.pressed, "currency-sign": "\u20AC", token: this.token, locale: this.locale, apiPath: this.apiPath, exportparts: "brand, currency, deeplink, image, image-link, price-amount, price-container, price-outdated, price-prefix, price-regular, price-sale, title, product-card, example-images", campaignId: this.campaignId })));
1046
+ }
1047
+ get el() { return index.getElement(this); }
1048
+ };
1049
+ VviinnVpsButton.style = vviinnVpsButtonCss;
1050
+
1051
+ const vviinnVpsWidgetCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{display:block}.hidden{visibility:hidden;height:1px}vviinn-overlayed-modal.first-screen::part(title),vviinn-overlayed-modal.first-screen::part(secondary-action){visibility:hidden}.start-page{display:grid;grid-template-columns:repeat(2, 1fr);min-height:580px}.start-page_block{align-content:start;border-right:1px solid #F4F4F4;display:grid;padding:48px}.start-page_block.error{align-content:center}#onboarding-block{border-right:unset;box-sizing:border-box;grid-gap:24px;overflow-y:auto;position:relative;width:100%}vviinn-teaser{margin-bottom:32px;margin-top:-24px}vviinn-image-selector{align-items:center;background:var(--color-primary, var(--color-primary-system));border-color:var(--color-primary, var(--color-primary-system));border-radius:2px;color:white;display:grid;font-size:16px;font-weight:600;height:56px;justify-items:center;margin-bottom:16px;transition:background 0.1s ease-in-out}vviinn-image-selector:hover{background:var(--color-primary-hover, var(--color-primary-hover-system));border-color:var(--color-primary-hover, var(--color-primary-hover-system))}vviinn-image-selector:active{border-color:black}.upload-button-content{display:grid;align-items:center;justify-items:start;justify-content:center;grid-template-columns:-webkit-max-content auto;grid-template-columns:max-content auto;grid-gap:16px}.results-page{display:grid;grid-template-columns:336px auto;box-sizing:border-box}.results-page>*{padding:24px;box-sizing:border-box}.products{align-content:center;align-items:start;box-sizing:border-box;display:grid;grid-gap:32px 16px;grid-template-columns:repeat(auto-fill, minmax(152px, 1fr));justify-items:center;padding:24px;padding-right:0;position:absolute;width:calc(100% - 16px)}.products.hidden{display:none}vviinn-empty-results{width:280px;align-self:center;justify-self:center}.products-wrapper{display:grid;overflow-y:auto;overflow-x:hidden;padding:unset;position:relative;width:100%}.image-wrapper{border-right:1px solid #F4F4F4;display:grid;grid-template-rows:-webkit-min-content 170px;grid-template-rows:min-content 170px;grid-gap:24px;min-width:100%}.onboarding-wrapper{position:absolute;width:100%;padding:48px;box-sizing:border-box;display:grid;grid-gap:64px;padding-bottom:24px}vviinn-product-card{gap:0;width:100%}vviinn-product-card::part(image){border:1px solid #eaeaea;margin-bottom:8px}vviinn-product-card::part(price-container),vviinn-product-card::part(deeplink),vviinn-product-card::part(title){align-self:start}search-filters span{display:none}search-filters::part(filter){background:#F4F4F4;border-radius:4px;border:1px solid #F4F4F4;box-sizing:border-box;color:#161616;font-size:14px;font-weight:600;line-height:20px}search-filters::part(show-more-filters){border:1px solid #f4f4f4;border-radius:4px;box-sizing:border-box;color:#161616;font-size:14px;font-weight:600;line-height:20px;padding:6px 16px}search-filters::part(show-more-filters):hover{background:#EAEAEA}search-filters::part(filter):hover{background:#EAEAEA}search-filters::part(filter):focus{outline:none;border:1px solid var(--color-primary, var(--color-primary-system))}search-filters::part(filter active){background:rgba(15, 98, 254, 0.15);color:var(--color-primary, var(--color-primary-system))}.filters-wrapper{overflow:auto}.results-page:not(.active){display:none}.nothing-found{display:grid;grid-gap:64px;justify-self:center;padding-top:64px;padding-bottom:16px;position:absolute;width:60%}@media (max-width: 768px){.start-page_block{padding:24px}.onboarding-wrapper{padding:24px}}@media (max-width: 640px){.start-page{grid-template-rows:-webkit-min-content;grid-template-rows:min-content;grid-template-columns:unset;grid-gap:48px;padding:24px 0 48px 0}}@media (max-width: 640px) and (min-width: 415px){.onboarding-wrapper{position:unset}#onboarding-block{overflow:unset}.start-page.active{height:1px;overflow:auto}}@media (max-width: 415px){.results-page>*{box-sizing:border-box;padding:24px}vviinn-slide{padding-bottom:48px}.start-page_block:last-of-type{border-right:unset;overflow-y:unset;position:static;box-sizing:border-box;width:unset}.start-page_block{padding:0 24px}vviinn-teaser{margin-top:24px}.onboarding-wrapper{position:static;width:unset;padding:unset;box-sizing:border-box}.results-page{grid-template-columns:unset;grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto}.image{margin-bottom:8px}.image-wrapper{grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto;width:100%}.products-wrapper{align-content:start;position:static;overflow-y:unset;width:100%;padding-top:0}.products{position:static;padding:0;width:unset;grid-gap:32px 16px;justify-content:center}.nothing-found{position:static;grid-gap:64px;padding:unset;align-content:start;width:unset}}@media (max-width: 320px){.products{grid-template-columns:unset}}vviinn-wrong-format,vviinn-server-error{width:280px;align-self:center;justify-self:center}";
1052
+
1053
+ const filterInt = (value) => /^[-+]?(\d+|Infinity)$/.test(value) ? Number(value) : NaN;
1054
+ const notEmptyString = (s) => !index$1.isEmpty(s);
1055
+ const notNan = (n) => !isNaN(n);
1056
+ let VviinnVpsWidget = class {
1057
+ constructor(hostRef) {
1058
+ index.registerInstance(this, hostRef);
1059
+ /** @internal */
1060
+ this.apiPath = "https://api.vviinn.com";
1061
+ /** When true modal window with widget will be shown */
1062
+ this.active = false;
1063
+ /** Currency sign will shown after price */
1064
+ this.currencySign = "€";
1065
+ /** Locale for currency formatting */
1066
+ this.locale = "de-DE";
1067
+ this.slidePosition = 0;
1068
+ this.width = 0;
1069
+ this.wrongImageFormat = false;
1070
+ this.imageSource = null;
1071
+ }
1072
+ activeWatcher(value) {
1073
+ if (value) {
1074
+ this.overflow = document.body.style.overflow;
1075
+ document.body.style.overflow = "hidden";
1076
+ this.trackOpenEvent();
1077
+ }
1078
+ else {
1079
+ document.body.style.overflow = this.overflow;
1080
+ }
1081
+ }
1082
+ trackRecommendationView({ detail }) {
1083
+ const recommendationViewEvent = index$1.createProductViewVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
1084
+ this.trackingApi.trackEvent(recommendationViewEvent);
1085
+ }
1086
+ trackRecommendationClick({ detail }) {
1087
+ const recommendationClickEvent = index$1.createProductClickVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
1088
+ this.trackingApi.trackEvent(recommendationClickEvent).finally(() => {
1089
+ const product = index$1.imageSearchState.results.find((r) => r.productId === detail.product);
1090
+ if (!product || !product.deeplink)
1091
+ return;
1092
+ window.location.href = product.deeplink;
1093
+ });
1094
+ }
1095
+ trachSearchAreaChanges() {
1096
+ const searchEvent = index$1.createSearchEvent({
1097
+ session_id: this.uiSessionId,
1098
+ source: this.imageSource,
1099
+ search_area: "manual-selection",
1100
+ });
1101
+ this.trackingApi.trackEvent(searchEvent);
1102
+ }
1103
+ trackDetectedObject() {
1104
+ const searchEvent = index$1.createSearchEvent({
1105
+ session_id: this.uiSessionId,
1106
+ source: this.imageSource,
1107
+ search_area: "attention-point",
1108
+ });
1109
+ this.trackingApi.trackEvent(searchEvent);
1110
+ }
1111
+ trackFilter({ detail }) {
1112
+ const searchEvent = index$1.createFilterEvent({
1113
+ session_id: this.uiSessionId,
1114
+ source: this.imageSource,
1115
+ kind: "category",
1116
+ action: detail,
1117
+ });
1118
+ this.trackingApi.trackEvent(searchEvent);
1119
+ }
1120
+ componentWillLoad() {
1121
+ slotChangeListener(this, this.el);
1122
+ }
1123
+ connectedCallback() {
1124
+ index$1.state.apiPath = this.apiPath;
1125
+ index$1.state.currencySign = this.currencySign;
1126
+ index$1.state.locale = this.locale;
1127
+ index$1.imageSearchState.token = this.token;
1128
+ index$1.imageSearchState.campaignId = index$1._function.pipe(this.campaignId, index$1.Option.fromNullable, index$1.Option.chain(index$1.Option.fromPredicate(notEmptyString)), index$1.Option.map(filterInt), index$1.Option.chain(index$1.Option.fromPredicate(notNan)), index$1.Option.map((s) => `${s}`));
1129
+ this.uiSessionId = index$1.v4();
1130
+ this.trackingApi = index$1.createTrackingApi(this.apiPath, this.token);
1131
+ }
1132
+ trackOpenEvent() {
1133
+ const widgetOpenEvent = index$1.createWidgetVpsEvent({
1134
+ action: "open",
1135
+ session_id: this.uiSessionId,
1136
+ });
1137
+ this.trackingApi.trackEvent(widgetOpenEvent);
1138
+ }
1139
+ handleImageSelection(source) {
1140
+ this.imageSource = source;
1141
+ this.slidePosition = 1;
1142
+ const root = this.el.shadowRoot.querySelector("vviinn-overlayed-modal");
1143
+ const overlay = root.shadowRoot.querySelector("vviinn-overlay");
1144
+ const modal = overlay.querySelector("vviinn-modal");
1145
+ const modalBody = modal.shadowRoot.querySelector(".body");
1146
+ modalBody.scrollTop = 0;
1147
+ this.trackInitialSearch();
1148
+ }
1149
+ trackInitialSearch() {
1150
+ const searchEvent = index$1.createSearchEvent({
1151
+ session_id: this.uiSessionId,
1152
+ source: this.imageSource,
1153
+ search_area: "full",
1154
+ });
1155
+ this.trackingApi.trackEvent(searchEvent);
1156
+ }
1157
+ resetState() {
1158
+ this.resetScroll("onboarding-block");
1159
+ this.slidePosition = 0;
1160
+ index$1.imageSearchState.image = index$1.Option.none;
1161
+ index$1.imageSearchState.imageUrl = index$1.Option.none;
1162
+ index$1.imageSearchState.imageBounds = index$1.Option.none;
1163
+ index$1.imageSearchState.searchArea = index$1.Option.none;
1164
+ index$1.imageSearchState.results = [];
1165
+ index$1.imageSearchState.filters = [];
1166
+ index$1.imageSearchState.detectedObjects = [];
1167
+ index$1.imageSearchState.activeIonLink = undefined;
1168
+ index$1.imageSearchState.rectangleSearchForm = undefined;
1169
+ this.resetScroll("results-block");
1170
+ }
1171
+ haveErrors() {
1172
+ return this.wrongImageFormat || index$1.imageSearchState.serverError;
1173
+ }
1174
+ resetScroll(elementId, behavior = "auto") {
1175
+ const element = this.el.shadowRoot.getElementById(elementId);
1176
+ element.scroll({ top: 0, left: 0, behavior });
1177
+ }
1178
+ handleModalClose() {
1179
+ this.active = false;
1180
+ this.resetState();
1181
+ const elementsToReset = ["onboarding-block", "results-block"];
1182
+ elementsToReset.forEach((name) => this.resetScroll(name));
1183
+ const widgetOpenEvent = index$1.createWidgetVpsEvent({
1184
+ action: "close",
1185
+ session_id: this.uiSessionId,
1186
+ });
1187
+ this.trackingApi.trackEvent(widgetOpenEvent);
1188
+ }
1189
+ render() {
1190
+ return (index.h(index.Host, null, index.h("vviinn-overlayed-modal", { class: { "first-screen": this.slidePosition === 0 }, active: this.active, onSecondaryActionClicked: () => this.resetState(), onModalClosed: () => this.handleModalClose(), exportparts: "secondary-action, title, close-button, example-images" }, index.h("vviinn-slider", { showBullets: false, position: this.slidePosition }, index.h("vviinn-slide", { class: { "start-page": true } }, index.h("div", { class: {
1191
+ error: this.haveErrors(),
1192
+ "start-page_block": true,
1193
+ } }, index.h("vviinn-wrong-format", { class: { hidden: !this.wrongImageFormat }, onActionClick: () => (this.wrongImageFormat = false) }), index.h("vviinn-server-error", { class: { hidden: !index$1.imageSearchState.serverError }, onActionClick: () => (index$1.imageSearchState.serverError = false) }), index.h("vviinn-teaser", { class: { hidden: this.haveErrors() } }), index.h("vviinn-image-selector", { class: { hidden: this.haveErrors() }, onImageSelected: () => this.handleImageSelection("upload"), onImageSelectedError: () => (this.wrongImageFormat = true), part: "select-image_button" }, index.h("span", { slot: "upload-button-text", class: "upload-button-content" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "29", height: "28", fill: "none" }, index.h("defs", null), index.h("path", { fill: "#fff", "fill-rule": "evenodd", d: "M10.271 3.89A.875.875 0 0111 3.5h7c.293 0 .566.146.728.39l1.49 2.235h3.033a2.625 2.625 0 012.625 2.625V21a2.625 2.625 0 01-2.625 2.625H5.75A2.625 2.625 0 013.125 21V8.75A2.625 2.625 0 015.75 6.125h3.031l1.49-2.235zm1.197 1.36l-1.49 2.235a.875.875 0 01-.729.39H5.75a.875.875 0 00-.875.875V21a.875.875 0 00.875.875h17.5a.875.875 0 00.875-.875V8.75a.875.875 0 00-.875-.875h-3.5a.875.875 0 01-.729-.39l-1.49-2.235h-6.063z", "clip-rule": "evenodd" }), index.h("path", { fill: "#fff", "fill-rule": "evenodd", d: "M14.5 11.375a3.062 3.062 0 100 6.125 3.062 3.062 0 000-6.125zm-4.813 3.063a4.812 4.812 0 119.625 0 4.812 4.812 0 01-9.625 0z", "clip-rule": "evenodd" })), index.h("slot", { name: "vviinn-image-upload-button-text" }, index.h("span", null, "Kamera oder Bild ausw\u00E4hlen")))), index.h("vviinn-privacy-badge", { class: { hidden: this.haveErrors() } })), index.h("div", { id: "onboarding-block", class: "start-page_block" }, index.h("div", { class: "onboarding-wrapper" }, index.h("vviinn-onboarding", null), index.h("vviinn-example-images", { tabindex: 0, part: "example-images", onImageSelected: () => this.handleImageSelection("example"), onImageSelectedError: () => this.resetScroll("onboarding-block", "smooth") })))), index.h("vviinn-slide", { class: { "results-page": true, active: this.slidePosition == 1 } }, index.h("div", { class: "image-wrapper" }, index.h("vviinn-image-view", null), index.h("div", { class: "filters-wrapper" }, index.h("div", { class: "filters" }, index$1.imageSearchState.filters.map((filter) => (index.h("search-filters", { filter: filter })))))), index.h("div", { id: "results-block", class: "products-wrapper" }, index.h("div", { class: {
1194
+ "nothing-found": true,
1195
+ hidden: index$1.imageSearchState.results.length > 0,
1196
+ } }, index.h("vviinn-empty-results", null), index.h("vviinn-onboarding", null)), index.h("div", { class: {
1197
+ hidden: index$1.imageSearchState.results.length <= 0,
1198
+ products: true,
1199
+ } }, index$1.imageSearchState.results.map((p, i) => {
1200
+ var _a;
1201
+ return (index.h("vviinn-product-card", { hidden: true, productTitle: p.title, productId: p.productId, brand: p.brand, deeplink: p.deeplink, price: p.price.actual, salePrice: p.price.sale, imageWidth: 160, image: (_a = p.image.thumbnail) !== null && _a !== void 0 ? _a : p.image.original, part: "product-card", index: i }));
1202
+ }))))))));
1203
+ }
1204
+ get el() { return index.getElement(this); }
1205
+ static get watchers() { return {
1206
+ "active": ["activeWatcher"]
1207
+ }; }
1208
+ };
1209
+ VviinnVpsWidget.style = vviinnVpsWidgetCss;
1210
+
730
1211
  const vviinnWrongFormatCss = ":host{display:block}";
731
1212
 
732
1213
  let VviinnWrongFormat = class {
@@ -740,11 +1221,14 @@ let VviinnWrongFormat = class {
740
1221
  };
741
1222
  VviinnWrongFormat.style = vviinnWrongFormatCss;
742
1223
 
1224
+ exports.cropper_handler = CropperHandler;
743
1225
  exports.highlight_box = HighlightBox;
744
1226
  exports.image_cropper = ImageCropper;
745
1227
  exports.search_filters = SearchFilters;
1228
+ exports.vviinn_button = VviinnButton;
746
1229
  exports.vviinn_detected_object = VviinnDetectedObject;
747
1230
  exports.vviinn_empty_results = VviinnEmptyResults;
1231
+ exports.vviinn_error = VviinnError;
748
1232
  exports.vviinn_example_image = VviinnExampleImage;
749
1233
  exports.vviinn_example_images = VviinnExampleImages;
750
1234
  exports.vviinn_image_selector = VviinnImageSelector;
@@ -756,9 +1240,13 @@ exports.vviinn_onboarding_card_2 = VviinnOnboardingCard2;
756
1240
  exports.vviinn_onboarding_card_3 = VviinnOnboardingCard3;
757
1241
  exports.vviinn_overlay = VviinnOverlay;
758
1242
  exports.vviinn_overlayed_modal = VviinnOverlayedModal;
1243
+ exports.vviinn_preloader = VviinnPreloader;
759
1244
  exports.vviinn_privacy_badge = VviinnPrivacyBadge;
1245
+ exports.vviinn_product_card = VviinnProductCard;
760
1246
  exports.vviinn_server_error = VviinnServerError;
761
1247
  exports.vviinn_slide = VviinnSlide;
762
1248
  exports.vviinn_slider = VviinnSlider;
763
1249
  exports.vviinn_teaser = VviinnTeaser;
1250
+ exports.vviinn_vps_button = VviinnVpsButton;
1251
+ exports.vviinn_vps_widget = VviinnVpsWidget;
764
1252
  exports.vviinn_wrong_format = VviinnWrongFormat;