vviinn-widgets 2.7.2 → 2.7.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 (51) hide show
  1. package/dist/cjs/{index-df6896e2.js → cropper-handler_30.cjs.entry.js} +2323 -165
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/vviinn-widgets.cjs.js +1 -1
  4. package/dist/collection/components/vviinn-product-card/vviinn-product-card.js +5 -2
  5. package/dist/esm/{app-globals-865bc7a7.js → app-globals-2f864b5d.js} +1 -1
  6. package/dist/esm/{index-2fdd499d.js → cropper-handler_30.entry.js} +2294 -119
  7. package/dist/esm/{index-443468c7.js → index-040cfca9.js} +2 -2
  8. package/dist/esm/{index-51f71d18.js → index-2d36a726.js} +1 -1
  9. package/dist/esm/loader.js +3 -3
  10. package/dist/esm/vviinn-recommendations-sidebar.entry.js +2 -2
  11. package/dist/esm/vviinn-vpr-button.entry.js +2 -2
  12. package/dist/esm/vviinn-widgets.js +3 -3
  13. package/dist/types/components/vviinn-product-card/vviinn-product-card.d.ts +1 -0
  14. package/dist/vviinn-widgets/{p-3469b71a.js → p-334db07e.js} +1 -1
  15. package/dist/vviinn-widgets/{p-40bea5b5.entry.js → p-a98df480.entry.js} +1 -1
  16. package/dist/vviinn-widgets/p-da99b592.entry.js +1 -0
  17. package/dist/vviinn-widgets/{p-a6e0710f.entry.js → p-dc124f62.entry.js} +1 -1
  18. package/dist/vviinn-widgets/{p-465d043d.js → p-e5a7f685.js} +1 -1
  19. package/dist/vviinn-widgets/{p-166970f3.js → p-fe8dc0b9.js} +1 -1
  20. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  21. package/package.json +1 -1
  22. package/www/build/{p-3469b71a.js → p-334db07e.js} +1 -1
  23. package/www/build/{p-40bea5b5.entry.js → p-a98df480.entry.js} +1 -1
  24. package/www/build/p-c5ef37e7.js +125 -0
  25. package/www/build/p-da99b592.entry.js +1 -0
  26. package/www/build/{p-a6e0710f.entry.js → p-dc124f62.entry.js} +1 -1
  27. package/www/build/p-e0153ae2.css +6 -0
  28. package/www/build/{p-465d043d.js → p-e5a7f685.js} +1 -1
  29. package/www/build/{p-166970f3.js → p-fe8dc0b9.js} +1 -1
  30. package/www/build/vviinn-widgets.esm.js +1 -1
  31. package/www/index.html +2495 -1
  32. package/dist/cjs/cropper-handler_27.cjs.entry.js +0 -1135
  33. package/dist/cjs/customized-slots-06ca4007.js +0 -53
  34. package/dist/cjs/vviinn-carousel_2.cjs.entry.js +0 -1001
  35. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -43
  36. package/dist/esm/cropper-handler_27.entry.js +0 -1105
  37. package/dist/esm/customized-slots-96902edf.js +0 -50
  38. package/dist/esm/vviinn-carousel_2.entry.js +0 -996
  39. package/dist/esm/vviinn-vps-button.entry.js +0 -39
  40. package/dist/vviinn-widgets/p-2dd35f19.entry.js +0 -1
  41. package/dist/vviinn-widgets/p-59bd2a99.js +0 -1
  42. package/dist/vviinn-widgets/p-74ed36af.entry.js +0 -1
  43. package/dist/vviinn-widgets/p-9def6b8b.entry.js +0 -1
  44. package/dist/vviinn-widgets/p-cd995515.js +0 -1
  45. package/www/build/p-2dd35f19.entry.js +0 -1
  46. package/www/build/p-59bd2a99.js +0 -1
  47. package/www/build/p-61933b75.js +0 -1
  48. package/www/build/p-74ed36af.entry.js +0 -1
  49. package/www/build/p-9def6b8b.entry.js +0 -1
  50. package/www/build/p-a67898be.css +0 -1
  51. package/www/build/p-cd995515.js +0 -1
@@ -1,1135 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- const index = require('./index-3c3ab815.js');
6
- const index$1 = require('./index-df6896e2.js');
7
- const index$2 = require('./index-f66cd8d1.js');
8
- const customizedSlots = require('./customized-slots-06ca4007.js');
9
-
10
- 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}";
11
-
12
- let CropperHandler = class {
13
- constructor(hostRef) {
14
- index.registerInstance(this, hostRef);
15
- this.disabled = false;
16
- }
17
- render() {
18
- return (index.h(index.Host, { part: `handle ${index$1.getCursorValue(this.handler.direction)}`, class: {
19
- disabled: this.disabled,
20
- [index$1.getCursorValue(this.handler.direction)]: true,
21
- }, style: {
22
- "--size": "20px",
23
- cursor: index$1.getCursorValue(this.handler.direction),
24
- }, draggable: false }));
25
- }
26
- };
27
- CropperHandler.style = cropperHandlerCss;
28
-
29
- const fromRectangle = (shape, target) => {
30
- const top = `${shape.y}px`;
31
- const left = `${shape.x}px`;
32
- const right = `${target.width - (shape.x + shape.width)}px`;
33
- const bottom = `${target.height - (shape.y + shape.height)}px`;
34
- return {
35
- top,
36
- right,
37
- bottom,
38
- left,
39
- };
40
- };
41
- const printClip = (clip) => `inset(${clip.top} ${clip.right} ${clip.bottom} ${clip.left})`;
42
- const getClipValue = (shape, target) => printClip(fromRectangle(shape, target));
43
-
44
- // -------------------------------------------------------------------------------------
45
- // -------------------------------------------------------------------------------------
46
- // instances
47
- // -------------------------------------------------------------------------------------
48
- /**
49
- * @category instances
50
- * @since 2.10.0
51
- */
52
- var Eq = {
53
- equals: function (first, second) { return first === second; }
54
- };
55
- /**
56
- * @category instances
57
- * @since 2.10.0
58
- */
59
- var Ord = {
60
- equals: Eq.equals,
61
- compare: function (first, second) { return (first < second ? -1 : first > second ? 1 : 0); }
62
- };
63
-
64
- 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)}}";
65
-
66
- let HighlightBox = class {
67
- constructor(hostRef) {
68
- index.registerInstance(this, hostRef);
69
- }
70
- getInsetValue() {
71
- 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(() => ""));
72
- }
73
- renderImage() {
74
- 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(() => ""));
75
- }
76
- render() {
77
- return index.h(index.Host, null, this.renderImage());
78
- }
79
- };
80
- HighlightBox.style = highlightBoxCss;
81
-
82
- const findTarget = (ev) => {
83
- return ev.target;
84
- };
85
-
86
- const imageCropperCss = ":host{display:block;height:100%;left:0;position:absolute;top:0;width:100%}:host(.hidden){visibility:hidden}.crop-area{border:1px solid white;box-sizing:border-box;position:absolute;touch-action:none;transition-property:border-color, opacity;transition-duration:.25s;transition-timing-function:ease-in-out;z-index:2;position:relative;will-change:transform}.crop-area.active{border-color:whitesmoke}.crop-area.disabled{opacity:0.25}";
87
-
88
- const MIN_SEARCHAREA_SIZE = 40;
89
- let ImageCropper = class {
90
- constructor(hostRef) {
91
- index.registerInstance(this, hostRef);
92
- this.cropperChanged = index.createEvent(this, "cropperChanged", 7);
93
- this.disabled = false;
94
- this.handleMove = false;
95
- this.mouseStartPoint = undefined;
96
- this.bounds = undefined;
97
- }
98
- componentDidLoad() {
99
- this.bounds = this.el.getBoundingClientRect();
100
- }
101
- handleHandlerMove(event) {
102
- event.preventDefault();
103
- event.stopPropagation();
104
- const destination = index$1.fromMouseEvent(event);
105
- const distance = index$1.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
106
- const transformedHandler = {
107
- position: distance,
108
- direction: this.handlerMoveDirection,
109
- };
110
- index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((area) => {
111
- const newSearchArea = index$1.transform(area, transformedHandler);
112
- if (this.outOfBounds(newSearchArea))
113
- return;
114
- index$1.imageSearchState.searchArea = index$1.Option.some(newSearchArea);
115
- this.mouseStartPoint = destination;
116
- index$1.imageSearchState.detectedObject = undefined;
117
- }));
118
- }
119
- outOfBounds(area) {
120
- return (area.width < MIN_SEARCHAREA_SIZE ||
121
- area.height < MIN_SEARCHAREA_SIZE ||
122
- area.x < 0 ||
123
- area.y < 0 ||
124
- this.bounds.height - (area.y + area.height) < 0 ||
125
- this.bounds.width - (area.x + area.width) < 0);
126
- }
127
- handleCropperMove(ev) {
128
- ev.preventDefault();
129
- ev.stopPropagation();
130
- const destination = index$1.fromMouseEvent(ev);
131
- const distance = index$1.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
132
- index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((searchArea) => {
133
- const newSearchArea = index$1.move(searchArea, distance);
134
- if (newSearchArea.x < 0 ||
135
- newSearchArea.y < 0 ||
136
- this.bounds.height - (newSearchArea.y + newSearchArea.height) < 0 ||
137
- this.bounds.width - (newSearchArea.x + newSearchArea.width) < 0)
138
- return;
139
- index$1.imageSearchState.detectedObject = undefined;
140
- index$1.imageSearchState.searchArea = index$1.Option.some(newSearchArea);
141
- this.mouseStartPoint = destination;
142
- }));
143
- }
144
- handlePointerDown(event) {
145
- event.stopPropagation();
146
- this.mouseStartPoint = index$1.fromMouseEvent(event);
147
- // should be htmlelement or handler
148
- const target = findTarget(event);
149
- if (target.localName === "cropper-handler") {
150
- this.handlerMoveDirection = target.handler.direction;
151
- this.pointerMoveListener = this.handleHandlerMove.bind(this);
152
- }
153
- else {
154
- this.pointerMoveListener = this.handleCropperMove.bind(this);
155
- }
156
- this.pointerReleaseListener = this.handleSearchAreaRelease.bind(this);
157
- this.el.addEventListener("pointermove", this.pointerMoveListener);
158
- window.addEventListener("pointerup", this.pointerReleaseListener, {
159
- once: true,
160
- });
161
- }
162
- handleSearchAreaRelease() {
163
- this.el.removeEventListener("pointermove", this.pointerMoveListener);
164
- document.removeEventListener("pointerup", this.pointerReleaseListener);
165
- this.mouseStartPoint = undefined;
166
- index$1.makeRectangularSearchRequest();
167
- this.cropperChanged.emit();
168
- }
169
- getStyleMap() {
170
- return index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((rectangle) => {
171
- return {
172
- width: `${rectangle.width}px`,
173
- height: `${rectangle.height}px`,
174
- transform: `translate3d(${rectangle.x}px, ${rectangle.y}px, 0)`,
175
- cursor: this.handleMove ? "move" : "default",
176
- };
177
- }), index$1.Option.getOrElse(() => {
178
- return {};
179
- }));
180
- }
181
- render() {
182
- return (index.h(index.Host, { exportparts: "handle, e-resize, n-resize, ne-resize, nw-resize, s-resize, se-resize, sw-resize, w-resize" }, index.h("div", { class: {
183
- "crop-area": true,
184
- active: this.handleMove,
185
- disabled: this.disabled,
186
- }, 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) }))))));
187
- }
188
- get el() { return index.getElement(this); }
189
- };
190
- ImageCropper.style = imageCropperCss;
191
-
192
- const searchFiltersCss = ":host{display:grid;grid-gap:1rem}.filters{display:flex;flex-direction:row;flex-wrap:wrap;gap:0.5rem}.filter{align-items:center;-webkit-animation-duration:0.25s;animation-duration:0.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:scalein;animation-name:scalein;border:1px solid lightgray;cursor:pointer;display:flex;flex-direction:row;grid-gap:8px;height:-webkit-max-content;height:-moz-max-content;height:max-content;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:0.1rem;transform:scale(0);transition-property:background;transition-duration:0.25s;transition-timing-function:ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:6px 16px}.filter.active{border:1px solid black;padding:6px 8px}.filter:hover{border:1px solid gray}.show-more{display:flex}.show-more.hidden{display:none}.show-more::after{content:url(\"data:image/svg+xml,%3Csvg width='16' height='16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 12.2l-6-6L3.2 5 8 9.8 12.8 5 14 6.2l-6 6z' fill='%23525252'/%3E%3C/svg%3E\");display:block;height:16px;margin-top:1px;margin-left:8px}.show-more.active::after{transform:rotateX(180deg)}@-webkit-keyframes scalein{from{opacity:0;transform:scale(0.5)}to{opacity:1;transform:scale(1)}}@keyframes scalein{from{opacity:0;transform:scale(0.5)}to{opacity:1;transform:scale(1)}}@media (max-width: 415px){.show-more::after{transform:rotate(-90deg)}.show-more.active::after{transform:rotate(90deg)}}@media (max-width: 800px){.filters{flex-wrap:nowrap;overflow-x:scroll;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;grid-gap:unset}.filter{scroll-snap-align:end;margin-right:0.5rem}}";
193
-
194
- const FILTERS_COUNT = 5;
195
- const ACTIVE_FILTER_CLASSNAME = ".filter.active";
196
- const getFilterId = (filter) => filter.href.split("/").reverse()[0];
197
- let SearchFilters = class {
198
- constructor(hostRef) {
199
- index.registerInstance(this, hostRef);
200
- this.filterSelected = index.createEvent(this, "filterSelected", 7);
201
- this.filter = null;
202
- this.selectedCategoryId = null;
203
- this.hideFilters = true;
204
- }
205
- handleFilterSelection(filter) {
206
- return this.isFilterSelected(filter)
207
- ? this.clearSelectedFilter()
208
- : this.selectFilter(filter);
209
- }
210
- selectFilter(filter) {
211
- this.selectedCategoryId = getFilterId(filter);
212
- index$1.imageSearchState.activeIonLink = filter;
213
- this.filterSelected.emit("select");
214
- }
215
- clearSelectedFilter() {
216
- this.selectedCategoryId = null;
217
- index$1.imageSearchState.activeIonLink = undefined;
218
- this.findSelectedFilter().blur();
219
- this.filterSelected.emit("deselect");
220
- }
221
- findSelectedFilter() {
222
- return this.el.shadowRoot.querySelector(ACTIVE_FILTER_CLASSNAME);
223
- }
224
- toggleFilters() {
225
- this.hideFilters = !this.hideFilters;
226
- }
227
- handleEnter(ev, f) {
228
- if (ev.key !== "Enter")
229
- return;
230
- this.handleFilterSelection(f);
231
- }
232
- isFilterSelected(filterLink) {
233
- return this.selectedCategoryId === getFilterId(filterLink);
234
- }
235
- render() {
236
- return (index.h(index.Host, { exportparts: "filter, show-more-filters" }, index.h("div", { class: "filters" }, this.filter.filters
237
- .filter((_, i) => (this.hideFilters ? i < FILTERS_COUNT : true))
238
- .map((f, n) => (index.h("div", { role: "button", tabindex: "0", part: this.isFilterSelected(f) ? "filter active" : "filter", class: {
239
- filter: true,
240
- active: this.selectedCategoryId === getFilterId(f),
241
- }, style: { "animation-delay": `${n * 10}ms` }, onPointerUp: (ev) => {
242
- ev.stopPropagation();
243
- this.handleFilterSelection(f);
244
- }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? index.h(index$2.CheckIcon, null) : null, f.name))), index.h("div", { class: {
245
- filter: true,
246
- "show-more": true,
247
- hidden: this.filter.filters.length <= FILTERS_COUNT,
248
- active: !this.hideFilters,
249
- }, role: "button", tabindex: "0", "aria-role": "button", onClick: () => this.toggleFilters(), onKeyPress: (ev) => {
250
- if (ev.key === "Enter") {
251
- this.toggleFilters();
252
- }
253
- }, part: "show-more-filters" }, this.hideFilters ? "Zeige mehr" : "Zeige weniger"))));
254
- }
255
- get el() { return index.getElement(this); }
256
- };
257
- SearchFilters.style = searchFiltersCss;
258
-
259
- 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}";
260
-
261
- let VviinnDetectedObject = class {
262
- constructor(hostRef) {
263
- index.registerInstance(this, hostRef);
264
- this.detectedObjectClicked = index.createEvent(this, "detectedObjectClicked", 7);
265
- this.position = ["0", "0"];
266
- }
267
- getObjectPosition() {
268
- return index$1._function.pipe(index$1.imageSearchState.imageBounds, index$1.Option.map((bounds) => {
269
- const objectRectangle = index$1.fromAlt(index$1.foldValueObject(this.detectedObject).rectangle);
270
- const { x, y } = index$1._function.pipe(objectRectangle, index$1.scaleWithSized(bounds), index$1.center);
271
- return [`${x}px`, `${y}px`];
272
- }), index$1.Option.getOrElse(() => ["0", "0"]));
273
- }
274
- selectDetectedObject() {
275
- index$1._function.pipe(index$1.imageSearchState.imageBounds, index$1.Option.map((bounds) => {
276
- const rectangle = index$1.foldValueObject(this.detectedObject).rectangle;
277
- const transformedRect = index$1.fromAlt(rectangle);
278
- const scaledRect = index$1.scaleWithSized(bounds)(transformedRect);
279
- index$1.imageSearchState.detectedObject = this.detectedObject;
280
- index$1.imageSearchState.searchArea = index$1.Option.some(scaledRect);
281
- }));
282
- index$1.makeRectangularSearchRequest();
283
- this.detectedObjectClicked.emit();
284
- }
285
- isActive() {
286
- if (!this.detectedObject)
287
- return false;
288
- if (!index$1.imageSearchState.detectedObject)
289
- return false;
290
- const thisObject = index$1.foldValueObject(this.detectedObject);
291
- const savedObject = index$1.foldValueObject(index$1.imageSearchState.detectedObject);
292
- return index$1.detectedObjectEq.equals(thisObject, savedObject);
293
- }
294
- render() {
295
- return (index.h(index.Host, { class: {
296
- active: this.isActive(),
297
- }, onClick: () => this.selectDetectedObject(), style: {
298
- "--x-position": this.getObjectPosition()[0],
299
- "--y-position": this.getObjectPosition()[1],
300
- } }));
301
- }
302
- };
303
- VviinnDetectedObject.style = vviinnDetectedObjectCss;
304
-
305
- const vviinnEmptyResultsCss = ":host{display:grid}vviinn-error{justify-items:center}";
306
-
307
- let VviinnEmptyResults = class {
308
- constructor(hostRef) {
309
- index.registerInstance(this, hostRef);
310
- this.actionClick = index.createEvent(this, "actionClick", 7);
311
- }
312
- render() {
313
- return (index.h(index.Host, null, index.h("vviinn-error", null, index.h("svg", { slot: "icon", class: "icon", width: "32", height: "32", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M16 2a14 14 0 1 0 0 28 14 14 0 0 0 0-28Zm0 26a12 12 0 1 1 0-24 12 12 0 0 1 0 24Z", fill: "#525252" }), index.h("path", { d: "M17 8h-2v11h2V8Zm-1 14a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z", fill: "#525252" })), index.h("h4", { slot: "title" }, "Leider nichts gefunden"), index.h("span", { slot: "text" }, "Leider konnten wir keine passenden Produkte finden. Bitte versuche es mit einem anderen Bildausschnitt noch einmal."))));
314
- }
315
- };
316
- VviinnEmptyResults.style = vviinnEmptyResultsCss;
317
-
318
- 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}";
319
-
320
- let VviinnError = class {
321
- constructor(hostRef) {
322
- index.registerInstance(this, hostRef);
323
- }
324
- render() {
325
- 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" })));
326
- }
327
- };
328
- VviinnError.style = vviinnErrorCss;
329
-
330
- const vviinnExampleImageCss = ":host{display:block;margin-bottom:8px;position:relative}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;pointer-events:none;position:absolute;right:12px;z-index:4}vviinn-preloader{--preloader-size:12px}@media (max-width: 640px){.image-preloader{display:block}}";
331
-
332
- let VviinnExampleImage = class {
333
- constructor(hostRef) {
334
- index.registerInstance(this, hostRef);
335
- this.exampleImageSelected = index.createEvent(this, "exampleImageSelected", 7);
336
- this.exampleImageError = index.createEvent(this, "exampleImageError", 7);
337
- this.src = "";
338
- this.width = 0;
339
- this.height = 0;
340
- this.selected = false;
341
- }
342
- async selectImage(_event) {
343
- this.selected = true;
344
- const file = await index$1.toFile(this.src);
345
- const processResult = await index$1.processSelectedFile(file);
346
- index$1._function.pipe(processResult, index$1.Either.match(() => this.exampleImageError.emit(), () => this.exampleImageSelected.emit()));
347
- this.selected = false;
348
- }
349
- showPreloader() {
350
- return ((index$1.imageSearchState.objectDetectionInProgress ||
351
- index$1.imageSearchState.loading) &&
352
- this.selected);
353
- }
354
- render() {
355
- return (index.h(index.Host, null, this.showPreloader() ? (index.h("div", { class: "image-preloader" }, index.h("vviinn-preloader", null))) : null, index.h("img", { onClick: (ev) => this.selectImage(ev), src: this.src, width: this.width, height: this.height })));
356
- }
357
- };
358
- VviinnExampleImage.style = vviinnExampleImageCss;
359
-
360
- 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}";
361
-
362
- let VviinnExampleImages = class {
363
- constructor(hostRef) {
364
- index.registerInstance(this, hostRef);
365
- this.imageSelected = index.createEvent(this, "imageSelected", 7);
366
- this.imageSelectedError = index.createEvent(this, "imageSelectedError", 7);
367
- }
368
- handleImageSelection() {
369
- this.imageSelected.emit();
370
- }
371
- handleImageSelectionError() {
372
- this.imageSelectedError.emit();
373
- }
374
- componentWillLoad() {
375
- customizedSlots.slotChangeListener(this, this.el);
376
- }
377
- render() {
378
- return (index.h(index.Host, null, index.h("slot", { name: "vviinn-example-images-title" }, index.h("h3", null, "Mit den Beispielbildern die Suche direkt ausprobieren")), index.h("div", { class: "images" }, index.h("slot", { name: "vviinn-example-images-1" }, index.h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDEtTC5qcGc=" })), index.h("slot", { name: "vviinn-example-images-2" }, index.h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDItTS5qcGc=" })), index.h("slot", { name: "vviinn-example-images-3" }, index.h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDMtTS5qcGc=" })), index.h("slot", { name: "vviinn-example-images-4" }, index.h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDQtTC5qcGc=" })))));
379
- }
380
- get el() { return index.getElement(this); }
381
- };
382
- VviinnExampleImages.style = vviinnExampleImagesCss;
383
-
384
- const vviinnImageSelectorCss = ":host{display:block}:host(::hover){background:whitesmoke}.visually-hidden{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}label{cursor:pointer;display:grid;padding:0.5rem;transition:background 0.1s ease-in-out}";
385
-
386
- let VviinnImageSelector = class {
387
- constructor(hostRef) {
388
- index.registerInstance(this, hostRef);
389
- this.imageSelected = index.createEvent(this, "imageSelected", 7);
390
- this.imageSelectedError = index.createEvent(this, "imageSelectedError", 7);
391
- }
392
- async handleInputChange(event) {
393
- const input = event.target;
394
- const processingResult = await index$1.processSelectedFile(input.files[0]);
395
- index$1._function.pipe(processingResult, index$1.match(() => this.imageSelectedError.emit(), () => this.imageSelected.emit()));
396
- input.value = null;
397
- }
398
- isLoading() {
399
- return (index$1.imageSearchState.loading || index$1.imageSearchState.objectDetectionInProgress);
400
- }
401
- render() {
402
- 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) })));
403
- }
404
- };
405
- VviinnImageSelector.style = vviinnImageSelectorCss;
406
-
407
- 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}";
408
-
409
- const getImageSizes = (i) => {
410
- const dimensions = index$1.dimensionsFromImage(i);
411
- const resize = index$1.scaleByLargestSide(288);
412
- const newDimensions = resize(dimensions);
413
- const sizes = newDimensions.map(d => d.size);
414
- return [sizes[0], sizes[1]];
415
- };
416
- let VviinnImageView = class {
417
- constructor(hostRef) {
418
- index.registerInstance(this, hostRef);
419
- }
420
- handleInitialImageLoad(ev) {
421
- const target = ev.target;
422
- const imageBounds = index$1.fromImage(target);
423
- const padding = 12;
424
- const { x, y } = index$1.move(imageBounds, { x: padding, y: padding });
425
- const searchArea = {
426
- x,
427
- y,
428
- width: imageBounds.width - padding * 2,
429
- height: imageBounds.height - padding * 2,
430
- };
431
- index$1.imageSearchState.imageBounds = index$1.Option.some(imageBounds);
432
- index$1.imageSearchState.searchArea = index$1.Option.some(searchArea);
433
- }
434
- renderDetectedObject(object) {
435
- return index.h("vviinn-detected-object", { detectedObject: object });
436
- }
437
- renderImage() {
438
- return index$1._function.pipe(index$1.sequenceToOption(index$1.imageSearchState.imageUrl, index$1.imageSearchState.image), index$1.Option.map(([url, refImage]) => {
439
- const [width, height] = getImageSizes(refImage);
440
- const image = (index.h("img", { decoding: "async", width: width, height: height, src: url, onLoad: (el) => this.handleInitialImageLoad(el), draggable: false }));
441
- return image;
442
- }), index$1.Option.getOrElse(() => null));
443
- }
444
- renderCropper() {
445
- return index$1._function.pipe(index$1.imageSearchState.imageUrl, index$1.Option.map(() => index.h("image-cropper", null)), index$1.Option.getOrElse(() => null));
446
- }
447
- render() {
448
- return (index.h(index.Host, null, index$1.imageSearchState.loading ||
449
- 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))));
450
- }
451
- };
452
- VviinnImageView.style = vviinnImageViewCss;
453
-
454
- const vviinnModalCss = ":host{background:white;border-radius:4px;box-sizing:border-box;display:grid;grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto;max-width:960px}@media (max-width: 415px){:host{-webkit-animation-name:fade-in;animation-name:fade-in;-webkit-animation-duration:0.5s;animation-duration:0.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}:host(.closed){-webkit-animation-name:fade-out;animation-name:fade-out;-webkit-animation-fill-mode:none;animation-fill-mode:none}.body{overflow-y:auto}}@media (max-width: 640px) and (min-width: 415px){:host{max-width:80%}}.head{align-items:center;border-bottom:1px solid #F4F4F4;display:grid;grid-gap:16px;grid-template-columns:-webkit-min-content auto -webkit-min-content;grid-template-columns:min-content auto min-content;justify-items:center;padding:16px}.title{font-weight:600;font-size:18px;line-height:24px}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:grid;padding:unset}@-webkit-keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@-webkit-keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}";
455
-
456
- let VviinnModal = class {
457
- constructor(hostRef) {
458
- index.registerInstance(this, hostRef);
459
- this.modalClosed = index.createEvent(this, "modalClosed", 7);
460
- this.secondaryActionClicked = index.createEvent(this, "secondaryActionClicked", 7);
461
- this.active = false;
462
- this.slider = false;
463
- }
464
- close() {
465
- this.active = false;
466
- setTimeout(() => {
467
- this.modalClosed.emit();
468
- }, this.slider ? 500 : 0);
469
- }
470
- handleAnimationEnd(ev) {
471
- if (ev.animationName !== "fade-in")
472
- return;
473
- this.slider = true;
474
- }
475
- render() {
476
- return (index.h(index.Host, { exportparts: "secondary-action, title, close-button", class: { closed: !this.active }, onAnimationEnd: (ev) => this.handleAnimationEnd(ev) }, index.h("div", { class: "head" }, index.h("button", { part: "secondary-action", onClick: () => this.secondaryActionClicked.emit() }, index.h("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M20.25 12H3.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), index.h("path", { d: "M10.5 5.25L3.75 12L10.5 18.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }))), index.h("div", { class: "title", part: "title" }, "Bildsuche"), index.h("button", { onClick: () => this.close(), class: "close-button", part: "close-button" }, index.h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M16 1.4L14.6 0L8 6.6L1.4 0L0 1.4L6.6 8L0 14.6L1.4 16L8 9.4L14.6 16L16 14.6L9.4 8L16 1.4Z", fill: "#333333" })))), index.h("div", { class: "body" }, index.h("slot", null))));
477
- }
478
- };
479
- VviinnModal.style = vviinnModalCss;
480
-
481
- const vviinnOnboardingCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}::host{display:block}h3{font-size:22px;font-weight:600;line-height:32px;margin:0;margin-bottom:16px;text-align:center}vviinn-slide{background:#f4f4f4;padding:24px}svg{padding:16px 0}.text{display:grid;grid-gap:8px}.text>h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}.text>p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}";
482
-
483
- let VviinnOnboarding = class {
484
- constructor(hostRef) {
485
- index.registerInstance(this, hostRef);
486
- }
487
- componentWillLoad() {
488
- customizedSlots.slotChangeListener(this, this.el);
489
- }
490
- render() {
491
- 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)))));
492
- }
493
- get el() { return index.getElement(this); }
494
- };
495
- VviinnOnboarding.style = vviinnOnboardingCss;
496
-
497
- const onboardingCardCss$2 = ":host{align-items:center;background:#f4f4f4;display:grid;grid-template-rows:repeat(2, 1fr);justify-items:center;padding:24px;width:100%}h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}svg{padding:16px 0}p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}.text{display:grid;grid-gap:8px}";
498
-
499
- let VviinnOnboardingCard1 = class {
500
- constructor(hostRef) {
501
- index.registerInstance(this, hostRef);
502
- }
503
- componentWillLoad() {
504
- customizedSlots.slotChangeListener(this, this.el);
505
- }
506
- render() {
507
- 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.")))));
508
- }
509
- get el() { return index.getElement(this); }
510
- };
511
- VviinnOnboardingCard1.style = onboardingCardCss$2;
512
-
513
- const onboardingCardCss$1 = ":host{align-items:center;background:#f4f4f4;display:grid;grid-template-rows:repeat(2, 1fr);justify-items:center;padding:24px;width:100%}h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}svg{padding:16px 0}p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}.text{display:grid;grid-gap:8px}";
514
-
515
- let VviinnOnboardingCard2 = class {
516
- constructor(hostRef) {
517
- index.registerInstance(this, hostRef);
518
- }
519
- componentWillLoad() {
520
- customizedSlots.slotChangeListener(this, this.el);
521
- }
522
- render() {
523
- 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.")))));
524
- }
525
- get el() { return index.getElement(this); }
526
- };
527
- VviinnOnboardingCard2.style = onboardingCardCss$1;
528
-
529
- const onboardingCardCss = ":host{align-items:center;background:#f4f4f4;display:grid;grid-template-rows:repeat(2, 1fr);justify-items:center;padding:24px;width:100%}h4{color:#161616;font-size:18px;font-weight:600;line-height:24px;margin:unset;text-align:center}svg{padding:16px 0}p{color:#525252;font-size:14px;font-style:normal;font-weight:normal;line-height:20px;margin:unset;text-align:center}.colored{fill:var(--color-icons, var(--color-icons-system))}.text{display:grid;grid-gap:8px}";
530
-
531
- let VviinnOnboardingCard3 = class {
532
- constructor(hostRef) {
533
- index.registerInstance(this, hostRef);
534
- }
535
- componentWillLoad() {
536
- customizedSlots.slotChangeListener(this, this.el);
537
- }
538
- render() {
539
- 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.")))));
540
- }
541
- get el() { return index.getElement(this); }
542
- };
543
- VviinnOnboardingCard3.style = onboardingCardCss;
544
-
545
- const vviinnOverlayCss = ":host{-webkit-animation:fade-in 0.5s ease-in-out;animation:fade-in 0.5s ease-in-out;background:rgba(0, 0, 0, 0.5);display:block;height:100vh;left:0;overflow:hidden;position:fixed;top:0;width:100vw;z-index:9999}@-webkit-keyframes fade-in{from{opacity:0.1}to{opacity:1}}@keyframes fade-in{from{opacity:0.1}to{opacity:1}}";
546
-
547
- let VviinnOverlay = class {
548
- constructor(hostRef) {
549
- index.registerInstance(this, hostRef);
550
- }
551
- render() {
552
- return (index.h(index.Host, null, index.h("slot", null)));
553
- }
554
- };
555
- VviinnOverlay.style = vviinnOverlayCss;
556
-
557
- const vviinnOverlayedModalCss = ":host{display:none}:host(.active){display:block}vviinn-overlay{align-items:center;display:grid;justify-items:center}@media (max-width: 415px){vviinn-modal{border-radius:4px 4px 0 0;height:100vh;margin-top:32px;transform:translateY(100%);width:100vw}vviinn-overlay{align-items:end;display:grid;justify-items:center}}";
558
-
559
- let VviinnOverlayedModal = class {
560
- constructor(hostRef) {
561
- index.registerInstance(this, hostRef);
562
- this.secondaryActionClicked = index.createEvent(this, "secondaryActionClicked", 7);
563
- this.modalClosed = index.createEvent(this, "modalClosed", 7);
564
- this.active = false;
565
- }
566
- render() {
567
- return (index.h(index.Host, { class: { active: this.active } }, index.h("vviinn-overlay", null, index.h("vviinn-modal", { onSecondaryActionClicked: () => this.secondaryActionClicked.emit(), active: this.active }, index.h("slot", null, "CONTENT")))));
568
- }
569
- };
570
- VviinnOverlayedModal.style = vviinnOverlayedModalCss;
571
-
572
- 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)}}";
573
-
574
- let VviinnPreloader = class {
575
- constructor(hostRef) {
576
- index.registerInstance(this, hostRef);
577
- }
578
- isActive() {
579
- return (index$1.imageSearchState.loading || index$1.imageSearchState.objectDetectionInProgress);
580
- }
581
- render() {
582
- return (index.h(index.Host, { class: {
583
- active: this.isActive(),
584
- } }));
585
- }
586
- };
587
- VviinnPreloader.style = vviinnPreloaderCss;
588
-
589
- 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}";
590
-
591
- let VviinnPrivacyBadge = class {
592
- constructor(hostRef) {
593
- index.registerInstance(this, hostRef);
594
- }
595
- componentWillLoad() {
596
- customizedSlots.slotChangeListener(this, this.el);
597
- }
598
- render() {
599
- 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."))))));
600
- }
601
- get el() { return index.getElement(this); }
602
- };
603
- VviinnPrivacyBadge.style = vviinnPrivacyBadgeCss;
604
-
605
- class GtagAnalytics {
606
- sendImpression(product) {
607
- var _a, _b, _c;
608
- gtag('event', 'view_item_list', {
609
- items: [
610
- {
611
- id: product.productId,
612
- name: product.title,
613
- brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
614
- category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
615
- list_name: 'VI VPR View',
616
- price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
617
- }
618
- ]
619
- });
620
- return undefined;
621
- }
622
- sendClick(product) {
623
- var _a, _b, _c;
624
- gtag('event', 'select_content', {
625
- content_type: 'product',
626
- items: [
627
- {
628
- id: product.productId,
629
- name: product.title,
630
- brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
631
- category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
632
- list_name: 'VI VPR View',
633
- price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
634
- }
635
- ]
636
- });
637
- return undefined;
638
- }
639
- }
640
-
641
- class GAnalytics {
642
- constructor() {
643
- ga('require', 'ec');
644
- }
645
- convertProduct(product) {
646
- var _a, _b, _c;
647
- return {
648
- id: product.productId,
649
- name: product.title,
650
- brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
651
- category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
652
- list: 'VI VPR View',
653
- price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
654
- };
655
- }
656
- sendImpression(product) {
657
- ga('ec:addImpression', this.convertProduct(product));
658
- return undefined;
659
- }
660
- sendClick(product) {
661
- var _a, _b, _c;
662
- ga('ec:addProduct', {
663
- id: product.productId,
664
- name: product.title,
665
- brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
666
- category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
667
- price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
668
- });
669
- ga('ec:setAction', 'click', { list: 'VI VPR View' });
670
- return undefined;
671
- }
672
- }
673
-
674
- const getGtagAnalytics = () => index$1._function.pipe(index$1.Option.fromNullable(window.gtag), index$1.Option.map(() => new GtagAnalytics()));
675
- const getCommonAnalytics = () => index$1._function.pipe(index$1.Option.fromNullable(window.ga), index$1.Option.map(() => new GAnalytics()));
676
- const analyticsMonoid = index$1.Option.getMonoid(index$1.Semigroup.first());
677
- const getAnalyticsModule = analyticsMonoid.concat(getGtagAnalytics(), getCommonAnalytics());
678
-
679
- const FIT_EXPR = /fit\/\d+\//;
680
- const containsFit = (url) => {
681
- return index$1._function.pipe(url.match(FIT_EXPR), index$1.Either.fromNullable(url), index$1.Either.map(() => url));
682
- };
683
- const processWidth = (url, size) => {
684
- return index$1._function.pipe(containsFit(url), index$1.Either.map((url) => url.replace(FIT_EXPR, `fit/${size}/`)), index$1.Either.getOrElse(() => url));
685
- };
686
- const Linked = (props, child) => props.deeplink ? (index.h("a", { class: props.part, part: props.part, href: props.deeplink }, child)) : (child);
687
- const FormattedPrice = (props) => {
688
- var _a;
689
- const locale = props.locale;
690
- const formattedPrice = new Intl.NumberFormat(locale, {
691
- minimumFractionDigits: 2,
692
- }).format(props.price);
693
- const fullPrice = `${(_a = props.prefix) !== null && _a !== void 0 ? _a : ""} ${formattedPrice} ${props.currency}`;
694
- return (index.h("span", { class: "price-amount", part: "price-amount" }, fullPrice));
695
- };
696
- const Price = (props) => {
697
- const priceEl = (index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale }));
698
- return (index.h("span", { class: "price-container", part: "price-container" }, props.salePrice ? ([
699
- index.h("span", { class: "price-sale", part: "price-sale" },
700
- index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.salePrice, locale: props.locale })),
701
- index.h("span", { class: "price-outdated", part: "price-outdated" }, priceEl),
702
- ]) : (index.h("span", { class: "price-regular", part: "price-regular" }, priceEl))));
703
- };
704
- const Image = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
705
- 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 })));
706
- const ResponsiveImage = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
707
- index.h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image responsive", src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
708
-
709
- 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}";
710
-
711
- let VviinnProductCard = class {
712
- constructor(hostRef) {
713
- index.registerInstance(this, hostRef);
714
- this.recommendationLoad = index.createEvent(this, "recommendationLoad", 7);
715
- this.recommendationView = index.createEvent(this, "recommendationView", 7);
716
- this.recommendationClick = index.createEvent(this, "recommendationClick", 7);
717
- this.productImageLoaded = index.createEvent(this, "productImageLoaded", 7);
718
- this.currency = undefined;
719
- this.imageRatio = 1;
720
- this.imageWidth = 200;
721
- this.locale = undefined;
722
- this.pricePrefix = undefined;
723
- this.responsive = false;
724
- this.dimmedBackground = false;
725
- /** @internal */
726
- this.index = 0;
727
- this.imageLoaded = false;
728
- this.productData = null;
729
- this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { threshold: 1.0 });
730
- }
731
- connectedCallback() {
732
- this.productData = {
733
- product: this.productId,
734
- rank: this.index,
735
- };
736
- }
737
- intersectionCallback(data) {
738
- if (data.some((entry) => entry.isIntersecting)) {
739
- index$1._function.pipe(getAnalyticsModule, index$1.Option.map((analytics) => analytics.sendImpression(this.getProduct())));
740
- this.recommendationView.emit(this.productData);
741
- this.intersectionObserver.disconnect();
742
- }
743
- }
744
- componentDidLoad() {
745
- this.recommendationLoad.emit(this.productData);
746
- this.intersectionObserver.observe(this.el);
747
- const links = this.el.shadowRoot.querySelectorAll("a");
748
- links.forEach((link) => link.addEventListener("click", (event) => {
749
- event.preventDefault();
750
- event.stopImmediatePropagation();
751
- this.recommendationClick.emit(this.productData);
752
- index$1._function.pipe(getAnalyticsModule, index$1.Option.match(() => null, (analytics) => analytics.sendClick(this.getProduct())));
753
- }));
754
- }
755
- getProduct() {
756
- return index$1.imageSearchState.results.find((r) => r.productId === this.productId);
757
- }
758
- renderImage() {
759
- const props = {
760
- width: this.imageWidth,
761
- height: this.imageWidth * this.imageRatio,
762
- src: this.image,
763
- title: this.productTitle,
764
- lazy: false,
765
- };
766
- return this.responsive
767
- ? ResponsiveImage(props, () => this.kek())
768
- : Image(props, () => this.kek());
769
- }
770
- kek() {
771
- this.productImageLoaded.emit(this.productId);
772
- }
773
- render() {
774
- var _a, _b, _c;
775
- 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 })));
776
- }
777
- get el() { return index.getElement(this); }
778
- };
779
- VviinnProductCard.style = vviinnProductCardCss;
780
-
781
- const vviinnServerErrorCss = ":host{display:block}";
782
-
783
- let VviinnServerError = class {
784
- constructor(hostRef) {
785
- index.registerInstance(this, hostRef);
786
- this.actionClick = index.createEvent(this, "actionClick", 7);
787
- }
788
- render() {
789
- return (index.h(index.Host, null, index.h("vviinn-error", null, index.h("h4", { slot: "title" }, "Keine Verbindung"), index.h("span", { slot: "text" }, "Etwas hat leider nicht funktioniert. Bitte pr\u00FCfen Sie Ihre Internetverbindung und laden Sie das Bild noch einmal hoch."), index.h("button", { slot: "action", onClick: () => this.actionClick.emit() }, "Erneut versuchen"))));
790
- }
791
- };
792
- VviinnServerError.style = vviinnServerErrorCss;
793
-
794
- const vviinnSlideCss = ":host{display:grid;justify-items:center}";
795
-
796
- let VviinnSlide = class {
797
- constructor(hostRef) {
798
- index.registerInstance(this, hostRef);
799
- }
800
- render() {
801
- return (index.h(index.Host, null, index.h("slot", null)));
802
- }
803
- };
804
- VviinnSlide.style = vviinnSlideCss;
805
-
806
- const getStyleMap = (data) => {
807
- return {
808
- "arrow-wrapper": true,
809
- [data.kind]: true,
810
- disabled: data.disabled,
811
- };
812
- };
813
- const Arrow = ({ kind, tabindex, disabled, onClick, onKeyDown, }) => (index.h("div", { class: getStyleMap({ kind, disabled }), onClick: onClick, tabindex: tabindex, onKeyDown: onKeyDown },
814
- index.h(index$2.ArrowIcon, null)));
815
-
816
- 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}";
817
-
818
- let VviinnSlider = class {
819
- constructor(hostRef) {
820
- index.registerInstance(this, hostRef);
821
- this.elementsCount = 0;
822
- this.internalPosition = 0;
823
- this.swipeStartPosition = index$1.Option.none;
824
- this.showBullets = true;
825
- this.position = 0;
826
- this.showArrows = false;
827
- }
828
- positionWatchHandler(newValue) {
829
- this.internalPosition = newValue;
830
- this.el.style.setProperty("--position", `${newValue}`);
831
- this.setActiveCssClassToSlide(newValue);
832
- }
833
- connectedCallback() {
834
- this.handleDomContentChanges();
835
- }
836
- handleDomContentChanges() {
837
- const items = this.el.querySelectorAll("vviinn-slide");
838
- this.elementsCount = items.length;
839
- this.el.style.setProperty("--num-items", `${this.elementsCount}`);
840
- this.setActiveCssClassToSlide(0);
841
- }
842
- setActiveCssClassToSlide(index) {
843
- const items = this.el.querySelectorAll("vviinn-slide");
844
- items.forEach((i) => i.classList.remove("active"));
845
- items[index].classList.add("active");
846
- }
847
- goToSlide(index) {
848
- this.internalPosition = index;
849
- this.el.style.setProperty("--position", `${index}`);
850
- this.setActiveCssClassToSlide(index);
851
- }
852
- renderBullets() {
853
- return this.showBullets ? (index.h("div", { class: "controls" }, index$1.NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (index.h("div", { class: {
854
- bullet: true,
855
- active: i == this.internalPosition % this.elementsCount,
856
- }, onClick: () => this.goToSlide(i) }))))) : null;
857
- }
858
- nextSlide() {
859
- this.internalPosition++;
860
- this.renderSlidePosition();
861
- }
862
- prevSlide() {
863
- const nextPostion = this.internalPosition - 1;
864
- this.internalPosition =
865
- nextPostion > -1 ? nextPostion : this.elementsCount - 1;
866
- this.renderSlidePosition();
867
- }
868
- renderSlidePosition() {
869
- requestAnimationFrame(() => {
870
- this.el.style.setProperty("--position", `${this.internalPosition % this.elementsCount}`);
871
- });
872
- }
873
- handleKeyDown(event) {
874
- if (event.key !== "Space" && event.key !== "Enter")
875
- return;
876
- const target = event.target;
877
- const direction = target.className.includes("prev") ? "prev" : "next";
878
- switch (direction) {
879
- case "prev":
880
- this.prevSlide();
881
- break;
882
- case "next":
883
- this.nextSlide();
884
- break;
885
- }
886
- }
887
- handleTouchStart(event) {
888
- if (!this.showBullets)
889
- return;
890
- this.swipeStartPosition = index$1._function.pipe(event.touches[0], index$1.Option.fromNullable, index$1.Option.map((t) => t.clientX));
891
- }
892
- handleTouchEnd(event) {
893
- if (!this.showBullets)
894
- return;
895
- const swipeEndPosition = index$1._function.pipe(event.changedTouches[0], index$1.Option.fromNullable, index$1.Option.map((t) => t.clientX));
896
- 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) => {
897
- switch (swipeDirection) {
898
- case 1:
899
- return this.nextSlide();
900
- case -1:
901
- return this.prevSlide();
902
- }
903
- }));
904
- }
905
- render() {
906
- return (index.h(index.Host, null, index.h("div", { class: "items-wrapper" }, index.h("div", { class: "items", onTouchStart: (e) => this.handleTouchStart(e), onTouchEnd: (e) => this.handleTouchEnd(e) }, index.h("slot", null))), this.showArrows
907
- ? [
908
- index.h(Arrow, { kind: "prev", onClick: () => this.prevSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 1, disabled: false }),
909
- index.h(Arrow, { kind: "next", onClick: () => this.nextSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 0, disabled: false }),
910
- ]
911
- : null, this.renderBullets()));
912
- }
913
- get el() { return index.getElement(this); }
914
- static get watchers() { return {
915
- "position": ["positionWatchHandler"]
916
- }; }
917
- };
918
- VviinnSlider.style = vviinnSliderCss;
919
-
920
- const vviinnTeaserCss = ":host{align-items:center;display:grid;justify-items:center;grid-gap:16px}.vviinn-teaser-text{font-size:28px;font-weight:600;line-height:40px;size:28px;text-align:center}";
921
-
922
- let VviinnTeaser = class {
923
- constructor(hostRef) {
924
- index.registerInstance(this, hostRef);
925
- }
926
- componentWillLoad() {
927
- customizedSlots.slotChangeListener(this, this.el);
928
- }
929
- render() {
930
- 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")))));
931
- }
932
- get el() { return index.getElement(this); }
933
- };
934
- VviinnTeaser.style = vviinnTeaserCss;
935
-
936
- 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}";
937
-
938
- const filterInt = (value) => /^[-+]?(\d+|Infinity)$/.test(value) ? Number(value) : NaN;
939
- const notEmptyString = (s) => !index$1.isEmpty(s);
940
- const notNan = (n) => !isNaN(n);
941
- let VviinnVpsWidget = class {
942
- constructor(hostRef) {
943
- index.registerInstance(this, hostRef);
944
- /** @internal */
945
- this.apiPath = "https://api.vviinn.com";
946
- /** When true modal window with widget will be shown */
947
- this.active = false;
948
- /** Currency sign will shown after price */
949
- this.currencySign = "€";
950
- /** Locale for currency formatting */
951
- this.locale = "de-DE";
952
- this.slidePosition = 0;
953
- this.width = 0;
954
- this.wrongImageFormat = false;
955
- this.imageSource = null;
956
- }
957
- activeWatcher(value) {
958
- if (value) {
959
- this.overflow = document.body.style.overflow;
960
- document.body.style.overflow = "hidden";
961
- this.trackOpenEvent();
962
- }
963
- else {
964
- document.body.style.overflow = this.overflow;
965
- }
966
- }
967
- trackRecommendationView({ detail }) {
968
- const recommendationViewEvent = index$1.createProductViewVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
969
- this.trackingApi.trackEvent(recommendationViewEvent);
970
- }
971
- trackRecommendationClick({ detail }) {
972
- const recommendationClickEvent = index$1.createProductClickVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
973
- this.trackingApi.trackEvent(recommendationClickEvent).finally(() => {
974
- const product = index$1.imageSearchState.results.find((r) => r.productId === detail.product);
975
- if (!product || !product.deeplink)
976
- return;
977
- window.location.href = product.deeplink;
978
- });
979
- }
980
- trachSearchAreaChanges() {
981
- const searchEvent = index$1.createSearchEvent({
982
- session_id: this.uiSessionId,
983
- source: this.imageSource,
984
- search_area: "manual-selection",
985
- });
986
- this.trackingApi.trackEvent(searchEvent);
987
- }
988
- trackDetectedObject() {
989
- const searchEvent = index$1.createSearchEvent({
990
- session_id: this.uiSessionId,
991
- source: this.imageSource,
992
- search_area: "attention-point",
993
- });
994
- this.trackingApi.trackEvent(searchEvent);
995
- }
996
- trackFilter({ detail }) {
997
- const searchEvent = index$1.createFilterEvent({
998
- session_id: this.uiSessionId,
999
- source: this.imageSource,
1000
- kind: "category",
1001
- action: detail,
1002
- });
1003
- this.trackingApi.trackEvent(searchEvent);
1004
- }
1005
- componentWillLoad() {
1006
- customizedSlots.slotChangeListener(this, this.el);
1007
- }
1008
- connectedCallback() {
1009
- index$1.state.apiPath = this.apiPath;
1010
- index$1.state.currencySign = this.currencySign;
1011
- index$1.state.locale = this.locale;
1012
- index$1.imageSearchState.token = this.token;
1013
- 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}`));
1014
- this.uiSessionId = index$1.v4();
1015
- this.trackingApi = index$1.createTrackingApi(this.apiPath, this.token);
1016
- }
1017
- trackOpenEvent() {
1018
- const widgetOpenEvent = index$1.createWidgetVpsEvent({
1019
- action: "open",
1020
- session_id: this.uiSessionId,
1021
- });
1022
- this.trackingApi.trackEvent(widgetOpenEvent);
1023
- }
1024
- handleImageSelection(source) {
1025
- this.imageSource = source;
1026
- this.slidePosition = 1;
1027
- const root = this.el.shadowRoot.querySelector("vviinn-overlayed-modal");
1028
- const overlay = root.shadowRoot.querySelector("vviinn-overlay");
1029
- const modal = overlay.querySelector("vviinn-modal");
1030
- const modalBody = modal.shadowRoot.querySelector(".body");
1031
- modalBody.scrollTop = 0;
1032
- this.trackInitialSearch();
1033
- }
1034
- trackInitialSearch() {
1035
- const searchEvent = index$1.createSearchEvent({
1036
- session_id: this.uiSessionId,
1037
- source: this.imageSource,
1038
- search_area: "full",
1039
- });
1040
- this.trackingApi.trackEvent(searchEvent);
1041
- }
1042
- resetState() {
1043
- this.resetScroll("onboarding-block");
1044
- this.slidePosition = 0;
1045
- index$1.imageSearchState.image = index$1.Option.none;
1046
- index$1.imageSearchState.imageUrl = index$1.Option.none;
1047
- index$1.imageSearchState.imageBounds = index$1.Option.none;
1048
- index$1.imageSearchState.searchArea = index$1.Option.none;
1049
- index$1.imageSearchState.results = [];
1050
- index$1.imageSearchState.filters = [];
1051
- index$1.imageSearchState.detectedObjects = [];
1052
- index$1.imageSearchState.activeIonLink = undefined;
1053
- index$1.imageSearchState.rectangleSearchForm = undefined;
1054
- this.resetScroll("results-block");
1055
- }
1056
- haveErrors() {
1057
- return this.wrongImageFormat || index$1.imageSearchState.serverError;
1058
- }
1059
- resetScroll(elementId, behavior = "auto") {
1060
- const element = this.el.shadowRoot.getElementById(elementId);
1061
- element.scroll({ top: 0, left: 0, behavior });
1062
- }
1063
- handleModalClose() {
1064
- this.active = false;
1065
- this.resetState();
1066
- const elementsToReset = ["onboarding-block", "results-block"];
1067
- elementsToReset.forEach((name) => this.resetScroll(name));
1068
- const widgetOpenEvent = index$1.createWidgetVpsEvent({
1069
- action: "close",
1070
- session_id: this.uiSessionId,
1071
- });
1072
- this.trackingApi.trackEvent(widgetOpenEvent);
1073
- }
1074
- render() {
1075
- 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: {
1076
- error: this.haveErrors(),
1077
- "start-page_block": true,
1078
- } }, 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", { 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: {
1079
- "nothing-found": true,
1080
- hidden: index$1.imageSearchState.results.length > 0,
1081
- } }, index.h("vviinn-empty-results", null), index.h("vviinn-onboarding", null)), index.h("div", { class: {
1082
- hidden: index$1.imageSearchState.results.length <= 0,
1083
- products: true,
1084
- } }, index$1.imageSearchState.results.map((p, i) => {
1085
- var _a;
1086
- 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 }));
1087
- }))))))));
1088
- }
1089
- get el() { return index.getElement(this); }
1090
- static get watchers() { return {
1091
- "active": ["activeWatcher"]
1092
- }; }
1093
- };
1094
- VviinnVpsWidget.style = vviinnVpsWidgetCss;
1095
-
1096
- const vviinnWrongFormatCss = ":host{display:block}";
1097
-
1098
- let VviinnWrongFormat = class {
1099
- constructor(hostRef) {
1100
- index.registerInstance(this, hostRef);
1101
- this.actionClick = index.createEvent(this, "actionClick", 7);
1102
- }
1103
- render() {
1104
- return (index.h(index.Host, null, index.h("vviinn-error", null, index.h("h4", { slot: "title" }, "Dateityp wird nicht unterst\u00FCtzt"), index.h("span", { slot: "text" }, "Leider unterst\u00FCtzen wir dieses Format nicht. Bitte laden Sie eine .jpg, .png oder .webp Bilddatei hoch."), index.h("button", { slot: "action", onClick: () => this.actionClick.emit() }, "Neues Bild hochladen"))));
1105
- }
1106
- };
1107
- VviinnWrongFormat.style = vviinnWrongFormatCss;
1108
-
1109
- exports.cropper_handler = CropperHandler;
1110
- exports.highlight_box = HighlightBox;
1111
- exports.image_cropper = ImageCropper;
1112
- exports.search_filters = SearchFilters;
1113
- exports.vviinn_detected_object = VviinnDetectedObject;
1114
- exports.vviinn_empty_results = VviinnEmptyResults;
1115
- exports.vviinn_error = VviinnError;
1116
- exports.vviinn_example_image = VviinnExampleImage;
1117
- exports.vviinn_example_images = VviinnExampleImages;
1118
- exports.vviinn_image_selector = VviinnImageSelector;
1119
- exports.vviinn_image_view = VviinnImageView;
1120
- exports.vviinn_modal = VviinnModal;
1121
- exports.vviinn_onboarding = VviinnOnboarding;
1122
- exports.vviinn_onboarding_card_1 = VviinnOnboardingCard1;
1123
- exports.vviinn_onboarding_card_2 = VviinnOnboardingCard2;
1124
- exports.vviinn_onboarding_card_3 = VviinnOnboardingCard3;
1125
- exports.vviinn_overlay = VviinnOverlay;
1126
- exports.vviinn_overlayed_modal = VviinnOverlayedModal;
1127
- exports.vviinn_preloader = VviinnPreloader;
1128
- exports.vviinn_privacy_badge = VviinnPrivacyBadge;
1129
- exports.vviinn_product_card = VviinnProductCard;
1130
- exports.vviinn_server_error = VviinnServerError;
1131
- exports.vviinn_slide = VviinnSlide;
1132
- exports.vviinn_slider = VviinnSlider;
1133
- exports.vviinn_teaser = VviinnTeaser;
1134
- exports.vviinn_vps_widget = VviinnVpsWidget;
1135
- exports.vviinn_wrong_format = VviinnWrongFormat;