vviinn-widgets 2.18.21 → 2.19.1

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 (183) hide show
  1. package/dist/cjs/{index-cb410762.js → Campaign-a94a827a.js} +17 -1
  2. package/dist/cjs/cropper-handler_29.cjs.entry.js +1418 -0
  3. package/dist/cjs/{imageSearch.store-98824653.js → index-48c94264.js} +16016 -11171
  4. package/dist/cjs/{index-7f1325a7.js → index-a4becaff.js} +683 -303
  5. package/dist/cjs/loader.cjs.js +4 -3
  6. package/dist/cjs/{vviinn-carousel_3.cjs.entry.js → vviinn-carousel_2.cjs.entry.js} +150 -270
  7. package/dist/cjs/vviinn-recommendations-sidebar.cjs.entry.js +14 -8
  8. package/dist/cjs/vviinn-vpr-button.cjs.entry.js +12 -14
  9. package/dist/cjs/vviinn-widgets.cjs.js +10 -3
  10. package/dist/collection/Image/sizing.spec.js +66 -0
  11. package/dist/collection/collection-manifest.json +2 -2
  12. package/dist/collection/components/image-search/image-view/highlight-box/highlight-box.css +2 -16
  13. package/dist/collection/components/image-search/image-view/highlight-box/highlight-box.js +11 -7
  14. package/dist/collection/components/image-search/image-view/image-cropper/cropper-handler/cropper-handler.css +0 -1
  15. package/dist/collection/components/image-search/image-view/image-cropper/cropper-handler/cropper-handler.js +40 -37
  16. package/dist/collection/components/image-search/image-view/image-cropper/image-cropper.js +73 -67
  17. package/dist/collection/components/image-search/search-filters/search-filters.css +4 -23
  18. package/dist/collection/components/image-search/search-filters/search-filters.js +97 -91
  19. package/dist/collection/components/vviinn-button/vviinn-button.js +34 -31
  20. package/dist/collection/components/vviinn-carousel/vviinn-carousel.css +1 -2
  21. package/dist/collection/components/vviinn-carousel/vviinn-carousel.js +161 -156
  22. package/dist/collection/components/vviinn-error/vviinn-empty-results/vviinn-empty-results.js +12 -14
  23. package/dist/collection/components/vviinn-error/vviinn-error.js +12 -12
  24. package/dist/collection/components/vviinn-error/vviinn-server-error/vviinn-server-error.js +35 -30
  25. package/dist/collection/components/vviinn-error/vviinn-wrong-format/vviinn-wrong-format.js +35 -30
  26. package/dist/collection/components/vviinn-example-images/vviinn-example-image/vviinn-example-image.js +129 -121
  27. package/dist/collection/components/vviinn-example-images/vviinn-example-images.js +75 -75
  28. package/dist/collection/components/vviinn-icons/index.js +10 -27
  29. package/dist/collection/components/vviinn-image-selector/vviinn-image-selector.js +120 -67
  30. package/dist/collection/components/vviinn-image-view/vviinn-detected-object/vviinn-detected-object.js +81 -69
  31. package/dist/collection/components/vviinn-image-view/vviinn-image-view.css +0 -1
  32. package/dist/collection/components/vviinn-image-view/vviinn-image-view.js +27 -28
  33. package/dist/collection/components/vviinn-modal/vviinn-modal.css +7 -36
  34. package/dist/collection/components/vviinn-modal/vviinn-modal.js +115 -93
  35. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-1/vviinn-onboarding-card-1.js +12 -14
  36. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-2/vviinn-onboarding-card-2.js +12 -14
  37. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-3/vviinn-onboarding-card-3.js +12 -14
  38. package/dist/collection/components/vviinn-onboarding/vviinn-onboarding.js +12 -17
  39. package/dist/collection/components/vviinn-overlay/vviinn-overlay.css +1 -12
  40. package/dist/collection/components/vviinn-overlay/vviinn-overlay.js +12 -9
  41. package/dist/collection/components/vviinn-overlayed-modal/vviinn-overlayed-modal.js +107 -78
  42. package/dist/collection/components/vviinn-preloader/vviinn-preloader.css +1 -11
  43. package/dist/collection/components/vviinn-preloader/vviinn-preloader.js +11 -7
  44. package/dist/collection/components/vviinn-privacy-badge/vviinn-privacy-badge.css +0 -1
  45. package/dist/collection/components/vviinn-privacy-badge/vviinn-privacy-badge.js +12 -16
  46. package/dist/collection/components/vviinn-product-card/render-helpers.js +6 -14
  47. package/dist/collection/components/vviinn-product-card/vviinn-product-card.js +425 -415
  48. package/dist/collection/components/vviinn-slider/arrow.js +1 -2
  49. package/dist/collection/components/vviinn-slider/vviinn-slide/vviinn-slide.js +12 -9
  50. package/dist/collection/components/vviinn-slider/vviinn-slider.css +0 -1
  51. package/dist/collection/components/vviinn-slider/vviinn-slider.js +87 -82
  52. package/dist/collection/components/vviinn-teaser/vviinn-teaser.js +12 -18
  53. package/dist/collection/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.css +12 -64
  54. package/dist/collection/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.js +371 -360
  55. package/dist/collection/components/vviinn-vpr-button/vviinn-vpr-button.js +448 -444
  56. package/dist/collection/components/vviinn-vpr-widget/vviinn-vpr-vidget.js +545 -542
  57. package/dist/collection/components/vviinn-vps-button/stories/vviinn-vps-button.stories.js +2 -0
  58. package/dist/collection/components/vviinn-vps-button/vviinn-vps-button.js +368 -332
  59. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.css +0 -5
  60. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.e2e.js +26 -0
  61. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.js +502 -425
  62. package/dist/collection/geometry/Clip.spec.js +16 -0
  63. package/dist/collection/geometry/Rectangle.spec.js +66 -0
  64. package/dist/collection/geometry/Sized.spec.js +16 -0
  65. package/dist/collection/interfaces/generated.js +0 -4
  66. package/dist/collection/network/ion/Form.spec.js +43 -0
  67. package/dist/esm/{index-b31d86ce.js → Campaign-4aa53f29.js} +15 -2
  68. package/dist/esm/cropper-handler_29.entry.js +1386 -0
  69. package/dist/esm/{index-590cb67e.js → index-48ef9564.js} +683 -304
  70. package/dist/esm/{imageSearch.store-9dde5360.js → index-976acf7e.js} +16124 -11292
  71. package/dist/esm/loader.js +4 -3
  72. package/dist/esm/polyfills/css-shim.js +1 -1
  73. package/dist/esm/{vviinn-carousel_3.entry.js → vviinn-carousel_2.entry.js} +106 -225
  74. package/dist/esm/vviinn-recommendations-sidebar.entry.js +13 -7
  75. package/dist/esm/vviinn-vpr-button.entry.js +11 -13
  76. package/dist/esm/vviinn-widgets.js +7 -3
  77. package/dist/loader/index.d.ts +9 -0
  78. package/dist/loader/package.json +1 -0
  79. package/dist/types/Image/sizing.d.ts +4 -4
  80. package/dist/types/campaign/Campaign.d.ts +5 -5
  81. package/dist/types/campaign/VCSCampaignResponse.d.ts +1 -1
  82. package/dist/types/components/vviinn-carousel/vviinn-carousel.d.ts +2 -2
  83. package/dist/types/components/vviinn-image-selector/vviinn-image-selector.d.ts +4 -0
  84. package/dist/types/components/vviinn-modal/vviinn-modal.d.ts +2 -0
  85. package/dist/types/components/vviinn-overlayed-modal/vviinn-overlayed-modal.d.ts +2 -0
  86. package/dist/types/components/vviinn-product-card/render-helpers.d.ts +3 -3
  87. package/dist/types/components/vviinn-slider/arrow.d.ts +2 -2
  88. package/dist/types/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.d.ts +2 -2
  89. package/dist/types/components/vviinn-vps-button/vviinn-vps-button.d.ts +9 -4
  90. package/dist/types/components/vviinn-vps-widget/vviinn-vps-widget.d.ts +8 -0
  91. package/dist/types/components.d.ts +154 -54
  92. package/dist/types/error.d.ts +1 -1
  93. package/dist/types/geometry/Point.d.ts +1 -1
  94. package/dist/types/geometry/Rectangle.d.ts +1 -1
  95. package/dist/types/geometry/Sized.d.ts +1 -1
  96. package/dist/types/interfaces/generated.d.ts +192 -371
  97. package/dist/types/network/ion/File.d.ts +2 -2
  98. package/dist/types/network/ion/Form.d.ts +5 -5
  99. package/dist/types/network/ion/Link.d.ts +1 -1
  100. package/dist/types/network/ion/ValueObject.d.ts +4 -4
  101. package/dist/types/network/utils.d.ts +3 -3
  102. package/dist/types/recommendation/events.d.ts +5 -5
  103. package/dist/types/recommendation/recommendation.d.ts +1 -1
  104. package/dist/types/searchSession/searchSession.d.ts +7 -7
  105. package/dist/types/slider/GridMode.d.ts +1 -1
  106. package/dist/types/stencil-public-runtime.d.ts +98 -23
  107. package/dist/types/store/imageSearch.store.d.ts +1 -1
  108. package/dist/types/tracking/models.d.ts +2 -2
  109. package/dist/types/utils/event/Events.d.ts +1 -1
  110. package/dist/vviinn-widgets/p-312b0eb7.entry.js +1 -0
  111. package/dist/vviinn-widgets/p-414b2291.js +1 -0
  112. package/dist/vviinn-widgets/p-5b50c7e5.entry.js +1 -0
  113. package/dist/vviinn-widgets/p-8deaa5da.entry.js +1 -0
  114. package/dist/vviinn-widgets/p-c6209bc1.entry.js +1 -0
  115. package/{www/build/p-2f9ee951.js → dist/vviinn-widgets/p-d08ce429.js} +1 -1
  116. package/dist/vviinn-widgets/p-fa17e81f.js +2 -0
  117. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  118. package/package.json +12 -12
  119. package/www/build/p-312b0eb7.entry.js +1 -0
  120. package/www/build/p-414b2291.js +1 -0
  121. package/www/build/p-5b50c7e5.entry.js +1 -0
  122. package/www/build/p-8deaa5da.entry.js +1 -0
  123. package/www/build/p-c6209bc1.entry.js +1 -0
  124. package/{dist/vviinn-widgets/p-2f9ee951.js → www/build/p-d08ce429.js} +1 -1
  125. package/www/build/p-d39b7d70.js +161 -0
  126. package/www/build/p-fa17e81f.js +2 -0
  127. package/www/build/vviinn-widgets.esm.js +1 -1
  128. package/www/index.html +2 -2
  129. package/dist/cjs/Campaign-13258569.js +0 -18
  130. package/dist/cjs/Handler-176539c8.js +0 -331
  131. package/dist/cjs/cropper-handler.cjs.entry.js +0 -27
  132. package/dist/cjs/customized-slots-6e56c354.js +0 -54
  133. package/dist/cjs/highlight-box_22.cjs.entry.js +0 -770
  134. package/dist/cjs/index-a99edb90.js +0 -3235
  135. package/dist/cjs/vviinn-button.cjs.entry.js +0 -21
  136. package/dist/cjs/vviinn-error.cjs.entry.js +0 -19
  137. package/dist/cjs/vviinn-preloader.cjs.entry.js +0 -26
  138. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -65
  139. package/dist/cjs/vviinn-vps-widget.cjs.entry.js +0 -251
  140. package/dist/esm/Campaign-90ba7e06.js +0 -14
  141. package/dist/esm/Handler-f9b8735c.js +0 -309
  142. package/dist/esm/cropper-handler.entry.js +0 -23
  143. package/dist/esm/customized-slots-00afe247.js +0 -51
  144. package/dist/esm/highlight-box_22.entry.js +0 -745
  145. package/dist/esm/index-4d5b52ba.js +0 -3224
  146. package/dist/esm/vviinn-button.entry.js +0 -17
  147. package/dist/esm/vviinn-error.entry.js +0 -15
  148. package/dist/esm/vviinn-preloader.entry.js +0 -22
  149. package/dist/esm/vviinn-vps-button.entry.js +0 -61
  150. package/dist/esm/vviinn-vps-widget.entry.js +0 -247
  151. package/dist/vviinn-widgets/p-11f61564.js +0 -1
  152. package/dist/vviinn-widgets/p-12851e97.entry.js +0 -1
  153. package/dist/vviinn-widgets/p-18fd769b.js +0 -1
  154. package/dist/vviinn-widgets/p-339c6838.js +0 -1
  155. package/dist/vviinn-widgets/p-3b2c91c0.entry.js +0 -1
  156. package/dist/vviinn-widgets/p-45df9f28.entry.js +0 -1
  157. package/dist/vviinn-widgets/p-57ed5303.entry.js +0 -1
  158. package/dist/vviinn-widgets/p-69850e5b.js +0 -1
  159. package/dist/vviinn-widgets/p-7c2f762a.entry.js +0 -1
  160. package/dist/vviinn-widgets/p-7c3b7388.entry.js +0 -1
  161. package/dist/vviinn-widgets/p-85006f41.entry.js +0 -1
  162. package/dist/vviinn-widgets/p-8a3dd76d.entry.js +0 -1
  163. package/dist/vviinn-widgets/p-99e58be7.entry.js +0 -1
  164. package/dist/vviinn-widgets/p-a2b450b6.entry.js +0 -1
  165. package/dist/vviinn-widgets/p-bcc1ccf0.js +0 -1
  166. package/dist/vviinn-widgets/p-e6fee8d2.js +0 -1
  167. package/www/build/p-11f61564.js +0 -1
  168. package/www/build/p-12851e97.entry.js +0 -1
  169. package/www/build/p-18fd769b.js +0 -1
  170. package/www/build/p-339c6838.js +0 -1
  171. package/www/build/p-3b2c91c0.entry.js +0 -1
  172. package/www/build/p-45df9f28.entry.js +0 -1
  173. package/www/build/p-57ed5303.entry.js +0 -1
  174. package/www/build/p-69850e5b.js +0 -1
  175. package/www/build/p-7c2f762a.entry.js +0 -1
  176. package/www/build/p-7c3b7388.entry.js +0 -1
  177. package/www/build/p-85006f41.entry.js +0 -1
  178. package/www/build/p-8a3dd76d.entry.js +0 -1
  179. package/www/build/p-99e58be7.entry.js +0 -1
  180. package/www/build/p-9e2c131a.js +0 -125
  181. package/www/build/p-a2b450b6.entry.js +0 -1
  182. package/www/build/p-bcc1ccf0.js +0 -1
  183. package/www/build/p-e6fee8d2.js +0 -1
@@ -0,0 +1,1418 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-a4becaff.js');
6
+ const index$1 = require('./index-48c94264.js');
7
+ const Campaign = require('./Campaign-a94a827a.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;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
+ const CropperHandler = class {
12
+ constructor(hostRef) {
13
+ index.registerInstance(this, hostRef);
14
+ this.handler = undefined;
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;user-select:none;--size:10px;--x-position:0;--y-position:0}img{-webkit-user-select:none;-moz-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);animation:0.25s linear fadein;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}@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
+ const 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
+ const ImageCropper = class {
90
+ constructor(hostRef) {
91
+ index.registerInstance(this, hostRef);
92
+ this.vviinnImageCrop = index.createEvent(this, "vviinnImageCrop", 7);
93
+ this.mouseStartPoint = undefined;
94
+ this.bounds = undefined;
95
+ this.resizeObserver = new ResizeObserver(() => {
96
+ this.bounds = this.el.getBoundingClientRect();
97
+ });
98
+ this.disabled = false;
99
+ this.basicEventData = undefined;
100
+ this.handleMove = false;
101
+ }
102
+ componentDidLoad() {
103
+ this.resizeObserver.observe(this.el);
104
+ }
105
+ disconnectedCallback() {
106
+ this.resizeObserver.disconnect();
107
+ }
108
+ handleHandlerMove(event) {
109
+ event.preventDefault();
110
+ event.stopPropagation();
111
+ const destination = index$1.fromMouseEvent(event);
112
+ const distance = index$1.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
113
+ const transformedHandler = {
114
+ position: distance,
115
+ direction: this.handlerMoveDirection,
116
+ };
117
+ index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((area) => {
118
+ const newSearchArea = index$1.transform(area, transformedHandler);
119
+ if (this.outOfBounds(newSearchArea))
120
+ return;
121
+ index$1.imageSearchState.searchArea = index$1.Option.some(newSearchArea);
122
+ this.mouseStartPoint = destination;
123
+ index$1.imageSearchState.detectedObject = undefined;
124
+ }));
125
+ }
126
+ outOfBounds(area) {
127
+ return (area.width < MIN_SEARCHAREA_SIZE ||
128
+ area.height < MIN_SEARCHAREA_SIZE ||
129
+ area.x < 0 ||
130
+ area.y < 0 ||
131
+ this.bounds.height - (area.y + area.height) < 0 ||
132
+ this.bounds.width - (area.x + area.width) < 0);
133
+ }
134
+ handleCropperMove(ev) {
135
+ ev.preventDefault();
136
+ ev.stopPropagation();
137
+ const destination = index$1.fromMouseEvent(ev);
138
+ const distance = index$1.pointDiffSemigroup.concat(destination, this.mouseStartPoint);
139
+ index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((searchArea) => {
140
+ const newSearchArea = index$1.move(searchArea, distance);
141
+ if (newSearchArea.x < 0 ||
142
+ newSearchArea.y < 0 ||
143
+ this.bounds.height - (newSearchArea.y + newSearchArea.height) < 0 ||
144
+ this.bounds.width - (newSearchArea.x + newSearchArea.width) < 0)
145
+ return;
146
+ index$1.imageSearchState.detectedObject = undefined;
147
+ index$1.imageSearchState.searchArea = index$1.Option.some(newSearchArea);
148
+ this.mouseStartPoint = destination;
149
+ }));
150
+ }
151
+ handlePointerDown(event) {
152
+ event.stopPropagation();
153
+ this.mouseStartPoint = index$1.fromMouseEvent(event);
154
+ // should be htmlelement or handler
155
+ const target = findTarget(event);
156
+ if (target.localName === "cropper-handler") {
157
+ this.handlerMoveDirection = target.handler.direction;
158
+ this.pointerMoveListener = this.handleHandlerMove.bind(this);
159
+ }
160
+ else {
161
+ this.pointerMoveListener = this.handleCropperMove.bind(this);
162
+ }
163
+ this.pointerReleaseListener = this.handleSearchAreaRelease.bind(this);
164
+ this.el.addEventListener("pointermove", this.pointerMoveListener);
165
+ window.addEventListener("pointerup", this.pointerReleaseListener, {
166
+ once: true,
167
+ });
168
+ }
169
+ handleSearchAreaRelease() {
170
+ this.el.removeEventListener("pointermove", this.pointerMoveListener);
171
+ document.removeEventListener("pointerup", this.pointerReleaseListener);
172
+ this.mouseStartPoint = undefined;
173
+ index$1.makeRectangularSearchRequest();
174
+ this.vviinnImageCrop.emit(this.basicEventData);
175
+ }
176
+ getStyleMap() {
177
+ return index$1._function.pipe(index$1.imageSearchState.searchArea, index$1.Option.map((rectangle) => {
178
+ return {
179
+ width: `${rectangle.width}px`,
180
+ height: `${rectangle.height}px`,
181
+ transform: `translate3d(${rectangle.x}px, ${rectangle.y}px, 0)`,
182
+ cursor: this.handleMove ? "move" : "default",
183
+ };
184
+ }), index$1.Option.getOrElse(() => {
185
+ return {};
186
+ }));
187
+ }
188
+ render() {
189
+ 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: {
190
+ "crop-area": true,
191
+ active: this.handleMove,
192
+ disabled: this.disabled,
193
+ }, 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) }))))));
194
+ }
195
+ get el() { return index.getElement(this); }
196
+ };
197
+ ImageCropper.style = imageCropperCss;
198
+
199
+ const searchFiltersCss = ":host{display:grid;grid-gap:1rem}.filters{display:flex;flex-direction:row;flex-wrap:wrap;gap:0.5rem}.filter{align-items:center;animation-duration:0.25s;animation-fill-mode:forwards;animation-name:scalein;border:1px solid lightgray;cursor:pointer;display:flex;flex-direction:row;grid-gap:8px;height:-moz-max-content;height: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;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)}@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;scroll-snap-type:x mandatory;grid-gap:unset}.filter{scroll-snap-align:end;margin-right:0.5rem}}";
200
+
201
+ const FILTERS_COUNT = 5;
202
+ const ACTIVE_FILTER_CLASSNAME = ".filter.active";
203
+ const getFilterId = (filter) => filter.href.split("/").reverse()[0];
204
+ const SearchFilters = class {
205
+ constructor(hostRef) {
206
+ index.registerInstance(this, hostRef);
207
+ this.vviinnSelectFilter = index.createEvent(this, "vviinnSelectFilter", 7);
208
+ this.filter = null;
209
+ this.basicEventData = undefined;
210
+ this.selectedCategoryId = null;
211
+ this.hideFilters = true;
212
+ }
213
+ handleFilterSelection(filter) {
214
+ return this.isFilterSelected(filter)
215
+ ? this.clearSelectedFilter()
216
+ : this.selectFilter(filter);
217
+ }
218
+ selectFilter(filter) {
219
+ this.selectedCategoryId = getFilterId(filter);
220
+ index$1.imageSearchState.activeIonLink = filter;
221
+ this.vviinnSelectFilter.emit(Object.assign(Object.assign({}, this.basicEventData), { action: "select", filterName: filter.name }));
222
+ }
223
+ clearSelectedFilter() {
224
+ this.selectedCategoryId = null;
225
+ index$1.imageSearchState.activeIonLink = undefined;
226
+ this.findSelectedFilter().blur();
227
+ this.vviinnSelectFilter.emit(Object.assign(Object.assign({}, this.basicEventData), { action: "deselect" }));
228
+ }
229
+ findSelectedFilter() {
230
+ return this.el.shadowRoot.querySelector(ACTIVE_FILTER_CLASSNAME);
231
+ }
232
+ toggleFilters() {
233
+ this.hideFilters = !this.hideFilters;
234
+ }
235
+ handleEnter(ev, f) {
236
+ if (ev.key !== "Enter")
237
+ return;
238
+ this.handleFilterSelection(f);
239
+ }
240
+ isFilterSelected(filterLink) {
241
+ return this.selectedCategoryId === getFilterId(filterLink);
242
+ }
243
+ render() {
244
+ return (index.h(index.Host, { exportparts: "filter, show-more-filters" }, index.h("div", { class: "filters" }, this.filter.filters
245
+ .filter((_, i) => (this.hideFilters ? i < FILTERS_COUNT : true))
246
+ .map((f, n) => (index.h("div", { role: "button", tabindex: "0", part: this.isFilterSelected(f) ? "filter active" : "filter", class: {
247
+ filter: true,
248
+ active: this.selectedCategoryId === getFilterId(f),
249
+ }, style: { "animation-delay": `${n * 10}ms` }, onPointerUp: (ev) => {
250
+ ev.stopPropagation();
251
+ this.handleFilterSelection(f);
252
+ }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? index.h(Campaign.CheckIcon, null) : null, f.name))), index.h("div", { class: {
253
+ filter: true,
254
+ "show-more": true,
255
+ hidden: this.filter.filters.length <= FILTERS_COUNT,
256
+ active: !this.hideFilters,
257
+ }, role: "button", tabindex: "0", "aria-role": "button", onClick: () => this.toggleFilters(), onKeyPress: (ev) => {
258
+ if (ev.key === "Enter") {
259
+ this.toggleFilters();
260
+ }
261
+ }, part: "show-more-filters" }, this.hideFilters ? "Zeige mehr" : "Zeige weniger"))));
262
+ }
263
+ get el() { return index.getElement(this); }
264
+ };
265
+ SearchFilters.style = searchFiltersCss;
266
+
267
+ 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}";
268
+
269
+ const VviinnButton = class {
270
+ constructor(hostRef) {
271
+ index.registerInstance(this, hostRef);
272
+ this.addStyle = true;
273
+ }
274
+ render() {
275
+ return (index.h(index.Host, { exportparts: "button" }, index.h("button", { class: this.addStyle ? "open-button" : "raw-open-button", part: "button" }, index.h("slot", null, index.h(Campaign.VisualSearchIcon, null)))));
276
+ }
277
+ };
278
+ VviinnButton.style = vviinnButtonCss;
279
+
280
+ 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}";
281
+
282
+ const VviinnDetectedObject = class {
283
+ constructor(hostRef) {
284
+ index.registerInstance(this, hostRef);
285
+ this.vviinnSelectObject = index.createEvent(this, "vviinnSelectObject", 7);
286
+ this.detectedObject = undefined;
287
+ this.basicEventData = undefined;
288
+ this.position = ["0", "0"];
289
+ }
290
+ getObjectPosition() {
291
+ return index$1._function.pipe(index$1.imageSearchState.imageBounds, index$1.Option.map((bounds) => {
292
+ const objectRectangle = index$1.fromAlt(index$1.foldValueObject(this.detectedObject).rectangle);
293
+ const { x, y } = index$1._function.pipe(objectRectangle, index$1.scaleWithSized(bounds), index$1.center);
294
+ return [`${x}px`, `${y}px`];
295
+ }), index$1.Option.getOrElse(() => ["0", "0"]));
296
+ }
297
+ selectDetectedObject() {
298
+ index$1._function.pipe(index$1.imageSearchState.imageBounds, index$1.Option.map((bounds) => {
299
+ const rectangle = index$1.foldValueObject(this.detectedObject).rectangle;
300
+ const transformedRect = index$1.fromAlt(rectangle);
301
+ const scaledRect = index$1.scaleWithSized(bounds)(transformedRect);
302
+ index$1.imageSearchState.detectedObject = this.detectedObject;
303
+ index$1.imageSearchState.searchArea = index$1.Option.some(scaledRect);
304
+ }));
305
+ index$1.makeRectangularSearchRequest();
306
+ this.vviinnSelectObject.emit(Object.assign(Object.assign({}, this.basicEventData), { detectedObject: this.detectedObject }));
307
+ }
308
+ isActive() {
309
+ if (!this.detectedObject)
310
+ return false;
311
+ if (!index$1.imageSearchState.detectedObject)
312
+ return false;
313
+ const thisObject = index$1.foldValueObject(this.detectedObject);
314
+ const savedObject = index$1.foldValueObject(index$1.imageSearchState.detectedObject);
315
+ return index$1.detectedObjectEq.equals(thisObject, savedObject);
316
+ }
317
+ render() {
318
+ return (index.h(index.Host, { class: {
319
+ active: this.isActive(),
320
+ }, onClick: () => this.selectDetectedObject(), style: {
321
+ "--x-position": this.getObjectPosition()[0],
322
+ "--y-position": this.getObjectPosition()[1],
323
+ } }));
324
+ }
325
+ };
326
+ VviinnDetectedObject.style = vviinnDetectedObjectCss;
327
+
328
+ const vviinnEmptyResultsCss = ":host{display:grid}vviinn-error{justify-items:center}";
329
+
330
+ const VviinnEmptyResults = class {
331
+ constructor(hostRef) {
332
+ index.registerInstance(this, hostRef);
333
+ }
334
+ render() {
335
+ 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."))));
336
+ }
337
+ };
338
+ VviinnEmptyResults.style = vviinnEmptyResultsCss;
339
+
340
+ 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}";
341
+
342
+ const VviinnError = class {
343
+ constructor(hostRef) {
344
+ index.registerInstance(this, hostRef);
345
+ }
346
+ render() {
347
+ 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" })));
348
+ }
349
+ };
350
+ VviinnError.style = vviinnErrorCss;
351
+
352
+ 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}}";
353
+
354
+ const VviinnExampleImage = class {
355
+ constructor(hostRef) {
356
+ index.registerInstance(this, hostRef);
357
+ this.vviinnImageUpload = index.createEvent(this, "vviinnImageUpload", 7);
358
+ this.vviinnNoResult = index.createEvent(this, "vviinnNoResult", 7);
359
+ this.src = "";
360
+ this.width = 0;
361
+ this.height = 0;
362
+ this.basicEventData = undefined;
363
+ this.selected = false;
364
+ }
365
+ async selectImage() {
366
+ this.selected = true;
367
+ const file = await index$1.toFile(this.src);
368
+ const processResult = await index$1.processSelectedFile(file);
369
+ index$1._function.pipe(processResult, index$1.Either.match(() => this.vviinnNoResult.emit(this.basicEventData), () => this.vviinnImageUpload.emit(this.basicEventData)));
370
+ this.selected = false;
371
+ }
372
+ handleKeyPress({ key }) {
373
+ if (key !== "Enter" && key !== " ")
374
+ return;
375
+ this.selectImage();
376
+ }
377
+ showPreloader() {
378
+ return ((index$1.imageSearchState.objectDetectionInProgress ||
379
+ index$1.imageSearchState.loading) &&
380
+ this.selected);
381
+ }
382
+ render() {
383
+ return (index.h(index.Host, { onClick: () => this.selectImage(), onKeyUp: (ev) => this.handleKeyPress(ev) }, this.showPreloader() ? (index.h("div", { class: "image-preloader" }, index.h("vviinn-preloader", null))) : null, index.h("img", { src: this.src, width: this.width, height: this.height, tabindex: 1 })));
384
+ }
385
+ };
386
+ VviinnExampleImage.style = vviinnExampleImageCss;
387
+
388
+ const defaultSlotsNames = [
389
+ "vviinn-onboarding-title",
390
+ "onboarding-card-1-icon",
391
+ "onboarding-card-1-text",
392
+ "onboarding-card-2-icon",
393
+ "onboarding-card-2-text",
394
+ "onboarding-card-3-icon",
395
+ "onboarding-card-3-text",
396
+ "vviinn-example-images-title",
397
+ "vviinn-example-images-1",
398
+ "vviinn-example-images-2",
399
+ "vviinn-example-images-3",
400
+ "vviinn-example-images-4",
401
+ "vviinn-teaser-text",
402
+ "vviinn-image-upload-button-text",
403
+ "vviinn-privacy-badge-text",
404
+ "vviinn-image-search-modal-title",
405
+ ];
406
+ const renderNamedSlot = (name) => index.h("slot", { name: name });
407
+ const SlotSkeleton = () => defaultSlotsNames.map(renderNamedSlot);
408
+ const getSlots = (element) => Array.from(element.shadowRoot.querySelectorAll("slot"));
409
+ const getNameAttribute = (element) => element.getAttribute("name");
410
+ const getSlotAttribute = (element) => element.getAttribute("slot");
411
+ const elementContainSlot = (slot) => (container) => {
412
+ const name1 = getNameAttribute(slot);
413
+ const name2 = getSlotAttribute(container);
414
+ return name1 === name2;
415
+ };
416
+ const getContentToReplace = (targets) => (acc, content) => {
417
+ const replaceCandidate = targets.find(elementContainSlot(content));
418
+ if (replaceCandidate) {
419
+ acc.set(content, replaceCandidate);
420
+ }
421
+ return acc;
422
+ };
423
+ const replaceSlotContent = (content, target) => {
424
+ target.innerHTML = content.outerHTML;
425
+ };
426
+ const slotChangeListener = (component, element) => {
427
+ component.connectedCallback = function () {
428
+ document.addEventListener("globalSlotsChanged", ({ detail }) => {
429
+ const slotsToReplace = getSlots(element).reduce(getContentToReplace(detail), new Map());
430
+ slotsToReplace.forEach(replaceSlotContent);
431
+ }, true);
432
+ };
433
+ component.connectedCallback.call(component);
434
+ };
435
+
436
+ 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}";
437
+
438
+ const VviinnExampleImages = class {
439
+ constructor(hostRef) {
440
+ index.registerInstance(this, hostRef);
441
+ this.vviinnImageUpload = index.createEvent(this, "vviinnImageUpload", 7);
442
+ this.vviinnNoResult = index.createEvent(this, "vviinnNoResult", 7);
443
+ this.basicEventData = undefined;
444
+ }
445
+ componentWillLoad() {
446
+ slotChangeListener(this, this.el);
447
+ }
448
+ delegateFocus() {
449
+ const firstSlot = this.imagesBlock.childNodes[0];
450
+ const firstExampleImage = firstSlot.childNodes[0];
451
+ firstExampleImage.focus();
452
+ }
453
+ render() {
454
+ return (index.h(index.Host, { onFocus: () => this.delegateFocus() }, index.h("slot", { name: "vviinn-example-images-title" }, index.h("h3", null, "Mit den Beispielbildern die Suche direkt ausprobieren")), index.h("div", { class: "images", ref: (el) => (this.imagesBlock = el) }, 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=", basicEventData: this.basicEventData })), 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=", basicEventData: this.basicEventData })), 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=", basicEventData: this.basicEventData })), 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=", basicEventData: this.basicEventData })))));
455
+ }
456
+ get el() { return index.getElement(this); }
457
+ };
458
+ VviinnExampleImages.style = vviinnExampleImagesCss;
459
+
460
+ 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;width:100%;height:100%;transition:background 0.1s ease-in-out}";
461
+
462
+ const VviinnImageSelector = class {
463
+ constructor(hostRef) {
464
+ index.registerInstance(this, hostRef);
465
+ this.vviinnImageUpload = index.createEvent(this, "vviinnImageUpload", 7);
466
+ this.vviinnNoResult = index.createEvent(this, "vviinnNoResult", 7);
467
+ this.basicEventData = undefined;
468
+ this.startUpload = undefined;
469
+ this.resetVpsButton = undefined;
470
+ }
471
+ async handleInputChange(event) {
472
+ const input = event.target;
473
+ const processingResult = await index$1.processSelectedFile(input.files[0]);
474
+ index$1._function.pipe(processingResult, index$1.match(() => this.vviinnNoResult.emit(this.basicEventData), () => this.vviinnImageUpload.emit(this.basicEventData)));
475
+ input.value = null;
476
+ }
477
+ isLoading() {
478
+ return index$1.imageSearchState.loading;
479
+ }
480
+ startUploadWatcher(upload) {
481
+ if (upload) {
482
+ this.fileInput.click();
483
+ this.resetVpsButton();
484
+ }
485
+ }
486
+ render() {
487
+ 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), ref: (el) => (this.fileInput = el) })));
488
+ }
489
+ static get watchers() { return {
490
+ "startUpload": ["startUploadWatcher"]
491
+ }; }
492
+ };
493
+ VviinnImageSelector.style = vviinnImageSelectorCss;
494
+
495
+ const vviinnImageViewCss = ":host{display:grid;position:relative;justify-self:center;direction:ltr}img{box-sizing:border-box;filter:brightness(60%);position:relative;-webkit-user-select:none;-moz-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}";
496
+
497
+ const getImageSizes = (i) => {
498
+ const dimensions = index$1.dimensionsFromImage(i);
499
+ const resize = index$1.scaleByLargestSide(288);
500
+ const newDimensions = resize(dimensions);
501
+ const sizes = newDimensions.map((d) => d.size);
502
+ return [sizes[0], sizes[1]];
503
+ };
504
+ const VviinnImageView = class {
505
+ constructor(hostRef) {
506
+ index.registerInstance(this, hostRef);
507
+ this.basicEventData = undefined;
508
+ }
509
+ handleInitialImageLoad(ev) {
510
+ const target = ev.target;
511
+ const imageBounds = index$1.fromImage(target);
512
+ const padding = 12;
513
+ const { x, y } = index$1.move(imageBounds, { x: padding, y: padding });
514
+ const searchArea = {
515
+ x,
516
+ y,
517
+ width: imageBounds.width - padding * 2,
518
+ height: imageBounds.height - padding * 2,
519
+ };
520
+ index$1.imageSearchState.imageBounds = index$1.Option.some(imageBounds);
521
+ index$1.imageSearchState.searchArea = index$1.Option.some(searchArea);
522
+ }
523
+ renderDetectedObject(object) {
524
+ return (index.h("vviinn-detected-object", { detectedObject: object, basicEventData: this.basicEventData }));
525
+ }
526
+ renderImage() {
527
+ return index$1._function.pipe(index$1.sequenceToOption(index$1.imageSearchState.imageUrl, index$1.imageSearchState.image), index$1.Option.map(([url, refImage]) => {
528
+ const [width, height] = getImageSizes(refImage);
529
+ const image = (index.h("img", { decoding: "async", width: width, height: height, src: url, onLoad: (el) => this.handleInitialImageLoad(el), draggable: false }));
530
+ return image;
531
+ }), index$1.Option.getOrElse(() => null));
532
+ }
533
+ renderCropper() {
534
+ return index$1._function.pipe(index$1.imageSearchState.imageUrl, index$1.Option.map(() => index.h("image-cropper", { basicEventData: this.basicEventData })), index$1.Option.getOrElse(() => null));
535
+ }
536
+ render() {
537
+ return (index.h(index.Host, null, index$1.imageSearchState.loading ||
538
+ 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))));
539
+ }
540
+ };
541
+ VviinnImageView.style = vviinnImageViewCss;
542
+
543
+ const vviinnModalCss = ":host{background:white;border-radius:4px;box-sizing:border-box;display:grid;grid-template-rows:min-content auto;max-width:960px;overflow:auto}@media (max-width: 415px){:host{animation-name:fade-in;animation-duration:0.5s;animation-fill-mode:forwards}:host(.closed){animation-name:fade-out;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:flex;padding:16px}.title{font-weight:600;font-size:18px;line-height:24px;margin:0 auto}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:grid;padding:unset}@keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}";
544
+
545
+ const VviinnModal = class {
546
+ constructor(hostRef) {
547
+ index.registerInstance(this, hostRef);
548
+ this.vviinnWidgetClose = index.createEvent(this, "vviinnWidgetClose", 7);
549
+ this.active = false;
550
+ this.resetState = undefined;
551
+ this.buttonElementId = undefined;
552
+ this.hideBackButton = false;
553
+ this.slider = false;
554
+ }
555
+ componentWillLoad() {
556
+ slotChangeListener(this, this.el);
557
+ }
558
+ close() {
559
+ this.active = false;
560
+ setTimeout(() => {
561
+ this.vviinnWidgetClose.emit({
562
+ widgetType: "VPS",
563
+ campaignTypeId: "VPS",
564
+ campaignTypeName: Campaign.campaignTypeNames["VPS"],
565
+ widgetId: this.buttonElementId,
566
+ });
567
+ }, this.slider ? 500 : 0);
568
+ }
569
+ handleAnimationEnd(ev) {
570
+ if (ev.animationName !== "fade-in")
571
+ return;
572
+ this.slider = true;
573
+ }
574
+ render() {
575
+ 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" }, !this.hideBackButton && (index.h("button", { part: "secondary-action", onClick: () => this.resetState() }, 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" }, index.h("slot", { name: "vviinn-image-search-modal-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))));
576
+ }
577
+ get el() { return index.getElement(this); }
578
+ };
579
+ VviinnModal.style = vviinnModalCss;
580
+
581
+ 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))}";
582
+
583
+ const VviinnOnboarding = class {
584
+ constructor(hostRef) {
585
+ index.registerInstance(this, hostRef);
586
+ }
587
+ componentWillLoad() {
588
+ slotChangeListener(this, this.el);
589
+ }
590
+ render() {
591
+ 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)))));
592
+ }
593
+ get el() { return index.getElement(this); }
594
+ };
595
+ VviinnOnboarding.style = vviinnOnboardingCss;
596
+
597
+ 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}";
598
+
599
+ const VviinnOnboardingCard1 = class {
600
+ constructor(hostRef) {
601
+ index.registerInstance(this, hostRef);
602
+ }
603
+ componentWillLoad() {
604
+ slotChangeListener(this, this.el);
605
+ }
606
+ render() {
607
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-1-icon" }, index.h(Campaign.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.")))));
608
+ }
609
+ get el() { return index.getElement(this); }
610
+ };
611
+ VviinnOnboardingCard1.style = onboardingCardCss$2;
612
+
613
+ 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}";
614
+
615
+ const VviinnOnboardingCard2 = class {
616
+ constructor(hostRef) {
617
+ index.registerInstance(this, hostRef);
618
+ }
619
+ componentWillLoad() {
620
+ slotChangeListener(this, this.el);
621
+ }
622
+ render() {
623
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-2-icon" }, index.h(Campaign.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.")))));
624
+ }
625
+ get el() { return index.getElement(this); }
626
+ };
627
+ VviinnOnboardingCard2.style = onboardingCardCss$1;
628
+
629
+ 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}";
630
+
631
+ const VviinnOnboardingCard3 = class {
632
+ constructor(hostRef) {
633
+ index.registerInstance(this, hostRef);
634
+ }
635
+ componentWillLoad() {
636
+ slotChangeListener(this, this.el);
637
+ }
638
+ render() {
639
+ return (index.h(index.Host, null, index.h("slot", { name: "onboarding-card-3-icon" }, index.h(Campaign.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.")))));
640
+ }
641
+ get el() { return index.getElement(this); }
642
+ };
643
+ VviinnOnboardingCard3.style = onboardingCardCss;
644
+
645
+ const vviinnOverlayCss = ":host{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}@keyframes fade-in{from{opacity:0.1}to{opacity:1}}";
646
+
647
+ const VviinnOverlay = class {
648
+ constructor(hostRef) {
649
+ index.registerInstance(this, hostRef);
650
+ }
651
+ render() {
652
+ return (index.h(index.Host, null, index.h("slot", null)));
653
+ }
654
+ };
655
+ VviinnOverlay.style = vviinnOverlayCss;
656
+
657
+ const vviinnOverlayedModalCss = ":host{display:none}:host(.active){display:block}vviinn-overlay{align-items:center;display:grid;justify-items:center;cursor:default}@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}}";
658
+
659
+ const VviinnOverlayedModal = class {
660
+ constructor(hostRef) {
661
+ index.registerInstance(this, hostRef);
662
+ this.vviinnWidgetClose = index.createEvent(this, "vviinnWidgetClose", 7);
663
+ this.active = false;
664
+ this.resetState = undefined;
665
+ this.buttonElementId = undefined;
666
+ this.hideBackButton = false;
667
+ }
668
+ render() {
669
+ return (index.h(index.Host, { class: { active: this.active } }, index.h("vviinn-overlay", null, index.h("vviinn-modal", { resetState: this.resetState, active: this.active, buttonElementId: this.buttonElementId, hideBackButton: this.hideBackButton }, index.h("slot", null, "CONTENT")))));
670
+ }
671
+ };
672
+ VviinnOverlayedModal.style = vviinnOverlayedModalCss;
673
+
674
+ const vviinnPreloaderCss = ":host{--preloader-size:24px;--preloader-width:calc(var(--preloader-size) / 6);transform-origin:center;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}@keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}";
675
+
676
+ const VviinnPreloader = class {
677
+ constructor(hostRef) {
678
+ index.registerInstance(this, hostRef);
679
+ }
680
+ isActive() {
681
+ return (index$1.imageSearchState.loading || index$1.imageSearchState.objectDetectionInProgress);
682
+ }
683
+ render() {
684
+ return (index.h(index.Host, { class: {
685
+ active: this.isActive(),
686
+ } }));
687
+ }
688
+ };
689
+ VviinnPreloader.style = vviinnPreloaderCss;
690
+
691
+ const vviinnPrivacyBadgeCss = ":host{display:block;background:#F4F4F4;padding:17px}.content{display:grid;grid-template-columns:min-content auto;grid-gap:9px}.content p{color:#525252;font-size:12px;line-height:16px;margin:unset}";
692
+
693
+ const VviinnPrivacyBadge = class {
694
+ constructor(hostRef) {
695
+ index.registerInstance(this, hostRef);
696
+ }
697
+ componentWillLoad() {
698
+ slotChangeListener(this, this.el);
699
+ }
700
+ render() {
701
+ 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, "Durch das Hochladen eines Bildes willigen Sie in die Verarbeitung durch unseren Partner Vviinn ein. Das Bild wird nach einer Stunde Inaktivit\u00E4t gel\u00F6scht."))))));
702
+ }
703
+ get el() { return index.getElement(this); }
704
+ };
705
+ VviinnPrivacyBadge.style = vviinnPrivacyBadgeCss;
706
+
707
+ class GtagAnalytics {
708
+ sendImpression(product) {
709
+ var _a, _b, _c;
710
+ gtag('event', 'view_item_list', {
711
+ items: [
712
+ {
713
+ id: product.productId,
714
+ name: product.title,
715
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
716
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
717
+ list_name: 'VI VPR View',
718
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
719
+ }
720
+ ]
721
+ });
722
+ return undefined;
723
+ }
724
+ sendClick(product) {
725
+ var _a, _b, _c;
726
+ gtag('event', 'select_content', {
727
+ content_type: 'product',
728
+ items: [
729
+ {
730
+ id: product.productId,
731
+ name: product.title,
732
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
733
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
734
+ list_name: 'VI VPR View',
735
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
736
+ }
737
+ ]
738
+ });
739
+ return undefined;
740
+ }
741
+ }
742
+
743
+ class GAnalytics {
744
+ constructor() {
745
+ ga('require', 'ec');
746
+ }
747
+ convertProduct(product) {
748
+ var _a, _b, _c;
749
+ return {
750
+ id: product.productId,
751
+ name: product.title,
752
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
753
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
754
+ list: 'VI VPR View',
755
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
756
+ };
757
+ }
758
+ sendImpression(product) {
759
+ ga('ec:addImpression', this.convertProduct(product));
760
+ return undefined;
761
+ }
762
+ sendClick(product) {
763
+ var _a, _b, _c;
764
+ ga('ec:addProduct', {
765
+ id: product.productId,
766
+ name: product.title,
767
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
768
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
769
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
770
+ });
771
+ ga('ec:setAction', 'click', { list: 'VI VPR View' });
772
+ return undefined;
773
+ }
774
+ }
775
+
776
+ const getGtagAnalytics = () => index$1._function.pipe(index$1.Option.fromNullable(window.gtag), index$1.Option.map(() => new GtagAnalytics()));
777
+ const getCommonAnalytics = () => index$1._function.pipe(index$1.Option.fromNullable(window.ga), index$1.Option.map(() => new GAnalytics()));
778
+ const analyticsMonoid = index$1.Option.getMonoid(index$1.Semigroup.first());
779
+ const getAnalyticsModule = analyticsMonoid.concat(getGtagAnalytics(), getCommonAnalytics());
780
+
781
+ const FIT_EXPR = /fit\/\d+\//;
782
+ const containsFit = (url) => {
783
+ return index$1._function.pipe(url.match(FIT_EXPR), index$1.Either.fromNullable(url), index$1.Either.map(() => url));
784
+ };
785
+ const processWidth = (url, size) => {
786
+ return index$1._function.pipe(containsFit(url), index$1.Either.map((url) => url.replace(FIT_EXPR, `fit/${size}/`)), index$1.Either.getOrElse(() => url));
787
+ };
788
+ const Linked = (props, child) => props.deeplink ? (index.h("a", { class: props.part, part: props.part, href: props.deeplink }, child)) : (child);
789
+ const FormattedPrice = (props) => {
790
+ const locale = props.locale;
791
+ const priceType = props.priceType;
792
+ const formattedPrice = new Intl.NumberFormat(locale, {
793
+ minimumFractionDigits: 2,
794
+ }).format(props.price);
795
+ const prefixElement = props.prefix ? (index.h("span", { part: "price-prefix" }, props.prefix + " ")) : null;
796
+ const currencyElement = props.currency ? (index.h("span", { part: "currency" }, " " + props.currency)) : null;
797
+ return (index.h("span", { class: "price-amount", part: `price-amount${priceType ? "-" + priceType : ""}` },
798
+ prefixElement,
799
+ formattedPrice,
800
+ currencyElement));
801
+ };
802
+ const Price = (props) => {
803
+ return (index.h("span", { class: "price-container", part: "price-container" }, props.salePrice ? ([
804
+ index.h("span", { class: "price-sale", part: "price-sale" },
805
+ index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.salePrice, locale: props.locale, priceType: "sale" })),
806
+ index.h("span", { class: "price-outdated", part: "price-outdated" },
807
+ index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale, priceType: "outdated" })),
808
+ ]) : (index.h("span", { class: "price-regular", part: "price-regular" },
809
+ index.h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale, priceType: "regular" })))));
810
+ };
811
+ const Image = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
812
+ 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 })));
813
+ const ResponsiveImage = (props, onLoadEnd = () => undefined) => (index.h("picture", null,
814
+ index.h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image responsive", src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
815
+
816
+ 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}";
817
+
818
+ const VviinnProductCard = class {
819
+ constructor(hostRef) {
820
+ index.registerInstance(this, hostRef);
821
+ this.vviinnProductLoad = index.createEvent(this, "vviinnProductLoad", 7);
822
+ this.vviinnProductView = index.createEvent(this, "vviinnProductView", 7);
823
+ this.vviinnProductClick = index.createEvent(this, "vviinnProductClick", 7);
824
+ this.productData = null;
825
+ this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { threshold: 1.0 });
826
+ this.brand = undefined;
827
+ this.currency = undefined;
828
+ this.deeplink = undefined;
829
+ this.image = undefined;
830
+ this.imageRatio = 1;
831
+ this.imageWidth = 200;
832
+ this.locale = undefined;
833
+ this.price = undefined;
834
+ this.pricePrefix = undefined;
835
+ this.productId = undefined;
836
+ this.productTitle = undefined;
837
+ this.productType = undefined;
838
+ this.salePrice = undefined;
839
+ this.responsive = false;
840
+ this.campaignTypeId = undefined;
841
+ this.dimmedBackground = false;
842
+ this.widgetElementId = undefined;
843
+ this.buttonElementId = undefined;
844
+ this.index = 0;
845
+ this.imageLoaded = false;
846
+ }
847
+ connectedCallback() {
848
+ this.productData = this.getProductData();
849
+ }
850
+ getWidgetType() {
851
+ return this.campaignTypeId === "VPR" || this.campaignTypeId === "VCS"
852
+ ? "VPR"
853
+ : "VPS";
854
+ }
855
+ getProductData() {
856
+ var _a;
857
+ return {
858
+ productId: this.productId,
859
+ productRank: this.index,
860
+ productName: this.productTitle,
861
+ widgetType: this.getWidgetType(),
862
+ campaignTypeId: this.campaignTypeId,
863
+ campaignTypeName: Campaign.campaignTypeNames[this.campaignTypeId],
864
+ widgetId: (_a = this.buttonElementId) !== null && _a !== void 0 ? _a : this.widgetElementId,
865
+ };
866
+ }
867
+ intersectionCallback(data) {
868
+ if (data.some((entry) => entry.isIntersecting)) {
869
+ index$1._function.pipe(getAnalyticsModule, index$1.Option.map((analytics) => analytics.sendImpression(this.getProduct())));
870
+ this.vviinnProductView.emit(this.productData);
871
+ this.intersectionObserver.disconnect();
872
+ }
873
+ }
874
+ componentDidLoad() {
875
+ this.vviinnProductLoad.emit(this.productData);
876
+ this.intersectionObserver.observe(this.el);
877
+ const links = this.el.shadowRoot.querySelectorAll("a");
878
+ links.forEach((link) => link.addEventListener("click", (event) => {
879
+ event.preventDefault();
880
+ event.stopImmediatePropagation();
881
+ this.vviinnProductClick.emit(this.productData);
882
+ index$1._function.pipe(getAnalyticsModule, index$1.Option.match(() => null, (analytics) => analytics.sendClick(this.getProduct())));
883
+ }));
884
+ }
885
+ getProduct() {
886
+ return index$1.imageSearchState.results.find((r) => r.productId === this.productId);
887
+ }
888
+ renderImage() {
889
+ const props = {
890
+ width: this.imageWidth,
891
+ height: this.imageWidth * this.imageRatio,
892
+ src: this.image,
893
+ title: this.productTitle,
894
+ lazy: false,
895
+ };
896
+ return this.responsive ? ResponsiveImage(props) : Image(props);
897
+ }
898
+ render() {
899
+ var _a, _b, _c;
900
+ return (index.h(index.Host, { part: "product-card", class: { dimmed: this.dimmedBackground }, exportparts: "brand, currency, deeplink, image, image-link, price-amount-sale, price-amount-outdated, price-amount-regular, price-container, price-outdated, price-regular, price-sale, price-prefix, 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 })));
901
+ }
902
+ get el() { return index.getElement(this); }
903
+ };
904
+ VviinnProductCard.style = vviinnProductCardCss;
905
+
906
+ const vviinnServerErrorCss = ":host{display:block}";
907
+
908
+ const VviinnServerError = class {
909
+ constructor(hostRef) {
910
+ index.registerInstance(this, hostRef);
911
+ this.handler = undefined;
912
+ }
913
+ render() {
914
+ 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.handler }, "Erneut versuchen"))));
915
+ }
916
+ };
917
+ VviinnServerError.style = vviinnServerErrorCss;
918
+
919
+ const vviinnSlideCss = ":host{display:grid;justify-items:center}";
920
+
921
+ const VviinnSlide = class {
922
+ constructor(hostRef) {
923
+ index.registerInstance(this, hostRef);
924
+ }
925
+ render() {
926
+ return (index.h(index.Host, null, index.h("slot", null)));
927
+ }
928
+ };
929
+ VviinnSlide.style = vviinnSlideCss;
930
+
931
+ const getStyleMap = (data) => {
932
+ return {
933
+ "arrow-wrapper": true,
934
+ [data.kind]: true,
935
+ disabled: data.disabled,
936
+ };
937
+ };
938
+ const Arrow = ({ kind, tabindex, disabled, onClick, onKeyDown, }) => (index.h("div", { class: getStyleMap({ kind, disabled }), onClick: onClick, tabindex: tabindex, onKeyDown: onKeyDown },
939
+ index.h(Campaign.ArrowIcon, null)));
940
+
941
+ 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), 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;cursor:pointer;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}";
942
+
943
+ const VviinnSlider = class {
944
+ constructor(hostRef) {
945
+ index.registerInstance(this, hostRef);
946
+ this.elementsCount = 0;
947
+ this.internalPosition = 0;
948
+ this.swipeStartPosition = index$1.Option.none;
949
+ this.isRTL = false;
950
+ this.showBullets = true;
951
+ this.position = 0;
952
+ this.showArrows = false;
953
+ }
954
+ positionWatchHandler(newValue) {
955
+ this.internalPosition = newValue;
956
+ this.el.style.setProperty("--position", `${this.calculatePosition(newValue)}`);
957
+ this.setActiveCssClassToSlide(newValue);
958
+ }
959
+ componentWillLoad() {
960
+ this.isRTL = document.dir === "rtl";
961
+ }
962
+ connectedCallback() {
963
+ this.handleDomContentChanges();
964
+ }
965
+ handleDomContentChanges() {
966
+ const items = this.el.querySelectorAll("vviinn-slide");
967
+ this.elementsCount = items.length;
968
+ this.el.style.setProperty("--num-items", `${this.elementsCount}`);
969
+ this.setActiveCssClassToSlide(0);
970
+ }
971
+ setActiveCssClassToSlide(index) {
972
+ const items = this.el.querySelectorAll("vviinn-slide");
973
+ items.forEach((i) => i.classList.remove("active"));
974
+ items[index].classList.add("active");
975
+ }
976
+ goToSlide(index) {
977
+ this.internalPosition = index;
978
+ this.el.style.setProperty("--position", `${index}`);
979
+ this.setActiveCssClassToSlide(index);
980
+ }
981
+ renderBullets() {
982
+ return this.showBullets ? (index.h("div", { class: "controls" }, index$1.NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (index.h("div", { class: {
983
+ bullet: true,
984
+ active: i == Math.abs(this.internalPosition) % this.elementsCount,
985
+ }, onClick: () => this.goToSlide(i) }))))) : null;
986
+ }
987
+ nextSlide() {
988
+ this.internalPosition++;
989
+ this.renderSlidePosition();
990
+ }
991
+ prevSlide() {
992
+ const nextPostion = this.internalPosition - 1;
993
+ this.internalPosition =
994
+ nextPostion > -1 ? nextPostion : this.elementsCount - 1;
995
+ this.renderSlidePosition();
996
+ }
997
+ renderSlidePosition() {
998
+ const position = this.internalPosition % this.elementsCount;
999
+ requestAnimationFrame(() => {
1000
+ this.el.style.setProperty("--position", `${this.calculatePosition(position)}`);
1001
+ });
1002
+ }
1003
+ calculatePosition(position) {
1004
+ return this.isRTL ? position * -1 : position;
1005
+ }
1006
+ handleKeyDown(event) {
1007
+ if (event.key !== "Space" && event.key !== "Enter")
1008
+ return;
1009
+ const target = event.target;
1010
+ const direction = target.className.includes("prev") ? "prev" : "next";
1011
+ switch (direction) {
1012
+ case "prev":
1013
+ this.prevSlide();
1014
+ break;
1015
+ case "next":
1016
+ this.nextSlide();
1017
+ break;
1018
+ }
1019
+ }
1020
+ handleTouchStart(event) {
1021
+ if (!this.showBullets)
1022
+ return;
1023
+ this.swipeStartPosition = index$1._function.pipe(event.touches[0], index$1.Option.fromNullable, index$1.Option.map((t) => t.clientX));
1024
+ }
1025
+ handleTouchEnd(event) {
1026
+ if (!this.showBullets)
1027
+ return;
1028
+ const swipeEndPosition = index$1._function.pipe(event.changedTouches[0], index$1.Option.fromNullable, index$1.Option.map((t) => t.clientX));
1029
+ 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) => {
1030
+ switch (swipeDirection) {
1031
+ case 1:
1032
+ return this.nextSlide();
1033
+ case -1:
1034
+ return this.prevSlide();
1035
+ }
1036
+ }));
1037
+ }
1038
+ render() {
1039
+ 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
1040
+ ? [
1041
+ index.h(Arrow, { kind: "prev", onClick: () => this.isRTL ? this.nextSlide() : this.prevSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 1, disabled: false }),
1042
+ index.h(Arrow, { kind: "next", onClick: () => this.isRTL ? this.prevSlide() : this.nextSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 0, disabled: false }),
1043
+ ]
1044
+ : null, this.renderBullets()));
1045
+ }
1046
+ get el() { return index.getElement(this); }
1047
+ static get watchers() { return {
1048
+ "position": ["positionWatchHandler"]
1049
+ }; }
1050
+ };
1051
+ VviinnSlider.style = vviinnSliderCss;
1052
+
1053
+ 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}";
1054
+
1055
+ const VviinnTeaser = class {
1056
+ constructor(hostRef) {
1057
+ index.registerInstance(this, hostRef);
1058
+ }
1059
+ componentWillLoad() {
1060
+ slotChangeListener(this, this.el);
1061
+ }
1062
+ render() {
1063
+ 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")))));
1064
+ }
1065
+ get el() { return index.getElement(this); }
1066
+ };
1067
+ VviinnTeaser.style = vviinnTeaserCss;
1068
+
1069
+ const vviinnVpsButtonCss = ":host{display:block}";
1070
+
1071
+ const VviinnVpsButton = class {
1072
+ constructor(hostRef) {
1073
+ index.registerInstance(this, hostRef);
1074
+ this.globalSlotsChanged = index.createEvent(this, "globalSlotsChanged", 7);
1075
+ this.vviinnWidgetOpen = index.createEvent(this, "vviinnWidgetOpen", 7);
1076
+ this.vviinnImageUpload = index.createEvent(this, "vviinnImageUpload", 7);
1077
+ this.vviinnNoResult = index.createEvent(this, "vviinnNoResult", 7);
1078
+ this.vviinnWidgetLoad = index.createEvent(this, "vviinnWidgetLoad", 7);
1079
+ this.vviinnWidgetClose = index.createEvent(this, "vviinnWidgetClose", 7);
1080
+ this.vviinnProductClick = index.createEvent(this, "vviinnProductClick", 7);
1081
+ this.vviinnProductView = index.createEvent(this, "vviinnProductView", 7);
1082
+ this.vviinnProductLoad = index.createEvent(this, "vviinnProductLoad", 7);
1083
+ this.vviinnImageCrop = index.createEvent(this, "vviinnImageCrop", 7);
1084
+ this.vviinnSelectObject = index.createEvent(this, "vviinnSelectObject", 7);
1085
+ this.vviinnSelectFilter = index.createEvent(this, "vviinnSelectFilter", 7);
1086
+ this.getBasicEventData = () => {
1087
+ return {
1088
+ widgetType: "VPS",
1089
+ campaignTypeId: "VPS",
1090
+ campaignTypeName: Campaign.campaignTypeNames["VPS"],
1091
+ widgetId: this.el.id,
1092
+ };
1093
+ };
1094
+ this.token = undefined;
1095
+ this.currencySign = "€";
1096
+ this.locale = "de-DE";
1097
+ this.campaignId = undefined;
1098
+ this.addStyle = false;
1099
+ this.mode = "modal";
1100
+ this.apiPath = undefined;
1101
+ this.buttonPressed = false;
1102
+ }
1103
+ handleModalClosed() {
1104
+ this.buttonPressed = false;
1105
+ }
1106
+ componentDidLoad() {
1107
+ const slots = this.el.querySelectorAll("[slot]");
1108
+ this.globalSlotsChanged.emit(Array.from(slots));
1109
+ }
1110
+ handleClick() {
1111
+ this.buttonPressed = true;
1112
+ }
1113
+ resetButton() {
1114
+ this.buttonPressed = false;
1115
+ }
1116
+ render() {
1117
+ return (index.h(index.Host, { tabindex: "0", role: "button" }, index.h("vviinn-button", { onClick: () => {
1118
+ this.handleClick();
1119
+ }, addStyle: this.addStyle, part: "vviinn-button" }, index.h("slot", null, index.h(Campaign.CameraIcon, null))), index.h(SlotSkeleton, null), index.h("vviinn-vps-widget", { mode: this.mode, "currency-sign": this.currencySign, token: this.token, locale: this.locale, apiPath: this.apiPath, exportparts: "brand, deeplink, currency, image, image-link, price-amount-sale, price-amount-outdated, price-amount-regular, price-container, price-outdated, price-regular, price-sale, price-prefix, title, product-card, example-images", campaignId: this.campaignId, showingInButton: true, buttonPressed: this.buttonPressed, resetVpsButton: this.resetButton.bind(this), buttonElementId: this.el.id })));
1120
+ }
1121
+ get el() { return index.getElement(this); }
1122
+ };
1123
+ VviinnVpsButton.style = vviinnVpsButtonCss;
1124
+
1125
+ 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: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: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: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:min-content auto}.image{margin-bottom:8px}.image-wrapper{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}";
1126
+
1127
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
1128
+ var t = {};
1129
+ for (var p in s)
1130
+ if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
1131
+ t[p] = s[p];
1132
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
1133
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
1134
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
1135
+ t[p[i]] = s[p[i]];
1136
+ }
1137
+ return t;
1138
+ };
1139
+ const filterInt = (value) => /^[-+]?(\d+|Infinity)$/.test(value) ? Number(value) : NaN;
1140
+ const notEmptyString = (s) => !index$1.isEmpty(s);
1141
+ const notNan = (n) => !isNaN(n);
1142
+ const VviinnVpsWidget = class {
1143
+ constructor(hostRef) {
1144
+ index.registerInstance(this, hostRef);
1145
+ this.globalSlotsChanged = index.createEvent(this, "globalSlotsChanged", 7);
1146
+ this.vviinnWidgetLoad = index.createEvent(this, "vviinnWidgetLoad", 7);
1147
+ this.vviinnWidgetOpen = index.createEvent(this, "vviinnWidgetOpen", 7);
1148
+ this.vviinnWidgetClose = index.createEvent(this, "vviinnWidgetClose", 7);
1149
+ this.vviinnProductClick = index.createEvent(this, "vviinnProductClick", 7);
1150
+ this.vviinnProductView = index.createEvent(this, "vviinnProductView", 7);
1151
+ this.vviinnProductLoad = index.createEvent(this, "vviinnProductLoad", 7);
1152
+ this.vviinnImageUpload = index.createEvent(this, "vviinnImageUpload", 7);
1153
+ this.vviinnImageCrop = index.createEvent(this, "vviinnImageCrop", 7);
1154
+ this.vviinnSelectObject = index.createEvent(this, "vviinnSelectObject", 7);
1155
+ this.vviinnSelectFilter = index.createEvent(this, "vviinnSelectFilter", 7);
1156
+ this.vviinnNoResult = index.createEvent(this, "vviinnNoResult", 7);
1157
+ this.imageSource = null;
1158
+ this.setTrackingDeactivated = (result) => {
1159
+ if (result.status === "rejected") {
1160
+ this.trackingDeactivated = true;
1161
+ }
1162
+ };
1163
+ this.getBasicEventData = () => {
1164
+ var _a;
1165
+ return {
1166
+ widgetType: "VPS",
1167
+ campaignTypeId: "VPS",
1168
+ campaignTypeName: Campaign.campaignTypeNames["VPS"],
1169
+ widgetId: (_a = this.buttonElementId) !== null && _a !== void 0 ? _a : this.id,
1170
+ };
1171
+ };
1172
+ this.token = undefined;
1173
+ this.apiPath = "https://api.vviinn.com";
1174
+ this.active = false;
1175
+ this.currencySign = "€";
1176
+ this.locale = "de-DE";
1177
+ this.campaignId = undefined;
1178
+ this.showingInButton = false;
1179
+ this.buttonElementId = undefined;
1180
+ this.buttonPressed = undefined;
1181
+ this.mode = "modal";
1182
+ this.resetVpsButton = undefined;
1183
+ this.slidePosition = 0;
1184
+ this.width = 0;
1185
+ this.wrongImageFormat = false;
1186
+ this.trackingDeactivated = false;
1187
+ }
1188
+ componentDidLoad() {
1189
+ const slots = this.el.querySelectorAll("[slot]");
1190
+ this.globalSlotsChanged.emit(Array.from(slots));
1191
+ }
1192
+ activeWatcher(value) {
1193
+ if (value) {
1194
+ this.overflow = document.body.style.overflow;
1195
+ document.body.style.overflow = "hidden";
1196
+ this.trackOpenEvent();
1197
+ }
1198
+ else {
1199
+ document.body.style.overflow = this.overflow;
1200
+ }
1201
+ }
1202
+ buttonPressedWatcher(pressed) {
1203
+ if (!pressed)
1204
+ return;
1205
+ if (this.mode === "modal") {
1206
+ this.active = true;
1207
+ this.vviinnWidgetOpen.emit(this.getBasicEventData());
1208
+ }
1209
+ }
1210
+ trackProductView({ detail }) {
1211
+ if (this.trackingDeactivated)
1212
+ return;
1213
+ const { productRank, productId, productName, widgetType, widgetId, campaignTypeId, campaignTypeName } = detail, rest = __rest(detail, ["productRank", "productId", "productName", "widgetType", "widgetId", "campaignTypeId", "campaignTypeName"]);
1214
+ const productViewEvent = index$1.createProductViewVpsEvent(Object.assign({ session_id: this.uiSessionId, rank: productRank, product: productId }, rest));
1215
+ this.trackingApi
1216
+ .trackEvent(productViewEvent)
1217
+ .then(this.setTrackingDeactivated);
1218
+ }
1219
+ async trackProductClick({ detail }) {
1220
+ const { productRank, productId, productName, widgetType, widgetId, campaignTypeId, campaignTypeName } = detail, rest = __rest(detail, ["productRank", "productId", "productName", "widgetType", "widgetId", "campaignTypeId", "campaignTypeName"]);
1221
+ const productClickEvent = index$1.createProductClickVpsEvent(Object.assign({ session_id: this.uiSessionId, rank: productRank, product: productId }, rest));
1222
+ if (!this.trackingDeactivated) {
1223
+ await this.trackingApi
1224
+ .trackEvent(this.trackingDeactivated ? null : productClickEvent)
1225
+ .then(this.setTrackingDeactivated);
1226
+ }
1227
+ const product = index$1.imageSearchState.results.find((r) => r.productId === detail.productId);
1228
+ if (!product || !product.deeplink)
1229
+ return;
1230
+ window.location.href = product.deeplink;
1231
+ }
1232
+ trachSearchAreaChanges() {
1233
+ if (this.trackingDeactivated)
1234
+ return;
1235
+ const searchEvent = index$1.createSearchEvent({
1236
+ session_id: this.uiSessionId,
1237
+ source: this.imageSource,
1238
+ search_area: "manual-selection",
1239
+ });
1240
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1241
+ }
1242
+ trackDetectedObject() {
1243
+ if (this.trackingDeactivated)
1244
+ return;
1245
+ const searchEvent = index$1.createSearchEvent({
1246
+ session_id: this.uiSessionId,
1247
+ source: this.imageSource,
1248
+ search_area: "attention-point",
1249
+ });
1250
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1251
+ }
1252
+ trackFilter({ detail }) {
1253
+ if (this.trackingDeactivated)
1254
+ return;
1255
+ const searchEvent = index$1.createFilterEvent({
1256
+ session_id: this.uiSessionId,
1257
+ source: this.imageSource,
1258
+ kind: "category",
1259
+ action: detail.action,
1260
+ });
1261
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1262
+ }
1263
+ connectedCallback() {
1264
+ index$1.state.apiPath = this.apiPath;
1265
+ index$1.state.currencySign = this.currencySign;
1266
+ index$1.state.locale = this.locale;
1267
+ index$1.imageSearchState.token = this.token;
1268
+ 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}`));
1269
+ this.uiSessionId = index$1.v4();
1270
+ this.trackingApi = index$1.createTrackingApi(this.apiPath, this.token);
1271
+ this.id = this.el.id;
1272
+ }
1273
+ componentWillLoad() {
1274
+ slotChangeListener(this, this.el);
1275
+ this.vviinnWidgetLoad.emit(this.getBasicEventData());
1276
+ }
1277
+ trackOpenEvent() {
1278
+ if (this.trackingDeactivated)
1279
+ return;
1280
+ const widgetOpenEvent = index$1.createWidgetVpsEvent({
1281
+ action: "open",
1282
+ session_id: this.uiSessionId,
1283
+ });
1284
+ this.trackingApi
1285
+ .trackEvent(widgetOpenEvent)
1286
+ .then(this.setTrackingDeactivated);
1287
+ }
1288
+ handleImageSelection(source) {
1289
+ this.imageSource = source;
1290
+ this.slidePosition = 1;
1291
+ const root = this.el.shadowRoot.querySelector("vviinn-overlayed-modal");
1292
+ const overlay = root.shadowRoot.querySelector("vviinn-overlay");
1293
+ const modal = overlay.querySelector("vviinn-modal");
1294
+ const modalBody = modal.shadowRoot.querySelector(".body");
1295
+ modalBody.scrollTop = 0;
1296
+ this.trackInitialSearch();
1297
+ }
1298
+ trackInitialSearch() {
1299
+ if (this.trackingDeactivated)
1300
+ return;
1301
+ const searchEvent = index$1.createSearchEvent({
1302
+ session_id: this.uiSessionId,
1303
+ source: this.imageSource,
1304
+ search_area: "full",
1305
+ });
1306
+ this.trackingApi.trackEvent(searchEvent).then(this.setTrackingDeactivated);
1307
+ }
1308
+ resetState() {
1309
+ this.resetScroll("onboarding-block");
1310
+ this.slidePosition = 0;
1311
+ index$1.imageSearchState.image = index$1.Option.none;
1312
+ index$1.imageSearchState.imageUrl = index$1.Option.none;
1313
+ index$1.imageSearchState.imageBounds = index$1.Option.none;
1314
+ index$1.imageSearchState.searchArea = index$1.Option.none;
1315
+ index$1.imageSearchState.results = [];
1316
+ index$1.imageSearchState.filters = [];
1317
+ index$1.imageSearchState.detectedObjects = [];
1318
+ index$1.imageSearchState.activeIonLink = undefined;
1319
+ index$1.imageSearchState.rectangleSearchForm = undefined;
1320
+ index$1.imageSearchState.loading = false;
1321
+ this.resetScroll("results-block");
1322
+ }
1323
+ haveErrors() {
1324
+ return this.wrongImageFormat || index$1.imageSearchState.serverError;
1325
+ }
1326
+ resetScroll(elementId, behavior = "auto") {
1327
+ const element = this.el.shadowRoot.getElementById(elementId);
1328
+ element.scroll({ top: 0, left: 0, behavior });
1329
+ }
1330
+ handleModalClose() {
1331
+ this.active = false;
1332
+ this.resetState();
1333
+ const elementsToReset = ["onboarding-block", "results-block"];
1334
+ elementsToReset.forEach((name) => this.resetScroll(name));
1335
+ if (this.trackingDeactivated)
1336
+ return;
1337
+ const widgetCloseEvent = index$1.createWidgetVpsEvent({
1338
+ action: "close",
1339
+ session_id: this.uiSessionId,
1340
+ });
1341
+ this.trackingApi
1342
+ .trackEvent(widgetCloseEvent)
1343
+ .then(this.setTrackingDeactivated);
1344
+ }
1345
+ render() {
1346
+ var _a;
1347
+ return (index.h(index.Host, null, !this.showingInButton && index.h(SlotSkeleton, null), index.h("vviinn-overlayed-modal", { class: { "first-screen": this.slidePosition === 0 }, active: this.active, resetState: this.resetState.bind(this), onVviinnWidgetClose: () => this.handleModalClose(), buttonElementId: (_a = this.buttonElementId) !== null && _a !== void 0 ? _a : this.id, hideBackButton: this.mode === "upload", 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: {
1348
+ error: this.haveErrors(),
1349
+ "start-page_block": true,
1350
+ } }, index.h("vviinn-wrong-format", { class: { hidden: !this.wrongImageFormat }, handler: () => (this.wrongImageFormat = false) }), index.h("vviinn-server-error", { class: { hidden: !index$1.imageSearchState.serverError }, handler: () => (index$1.imageSearchState.serverError = false) }), index.h("vviinn-teaser", { class: { hidden: this.haveErrors() } }), index.h("vviinn-image-selector", { class: { hidden: this.haveErrors() }, onVviinnImageUpload: () => {
1351
+ this.active = true;
1352
+ this.handleImageSelection("upload");
1353
+ if (this.mode === "upload") {
1354
+ this.vviinnWidgetOpen.emit(this.getBasicEventData());
1355
+ }
1356
+ }, onVviinnNoResult: () => (this.wrongImageFormat = true), resetVpsButton: this.resetVpsButton, basicEventData: this.getBasicEventData(), part: "select-image_button", startUpload: this.buttonPressed &&
1357
+ this.showingInButton &&
1358
+ this.mode === "upload" }, 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", onVviinnImageUpload: () => this.handleImageSelection("example"), onVviinnNoResult: () => this.resetScroll("onboarding-block", "smooth"), basicEventData: this.getBasicEventData() })))), index.h("vviinn-slide", { class: { "results-page": true, active: this.slidePosition == 1 } }, index.h("div", { class: "image-wrapper" }, index.h("vviinn-image-view", { basicEventData: this.getBasicEventData() }), index.h("div", { class: "filters-wrapper" }, index.h("div", { class: "filters" }, index$1.imageSearchState.filters.map((filter) => (index.h("search-filters", { filter: filter, basicEventData: this.getBasicEventData() })))))), index.h("div", { id: "results-block", class: "products-wrapper" }, index.h("div", { class: {
1359
+ "nothing-found": true,
1360
+ hidden: index$1.imageSearchState.results.length > 0,
1361
+ } }, index.h("vviinn-empty-results", null), index.h("vviinn-onboarding", null)), index.h("div", { class: {
1362
+ hidden: index$1.imageSearchState.results.length <= 0,
1363
+ products: true,
1364
+ } }, index$1.imageSearchState.results.map((p, i) => {
1365
+ var _a;
1366
+ return (index.h("vviinn-product-card", { key: p.productId, 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", campaignTypeId: "VPS", index: i, widgetElementId: this.id, buttonElementId: this.buttonElementId }));
1367
+ }))))))));
1368
+ }
1369
+ get el() { return index.getElement(this); }
1370
+ static get watchers() { return {
1371
+ "active": ["activeWatcher"],
1372
+ "buttonPressed": ["buttonPressedWatcher"]
1373
+ }; }
1374
+ };
1375
+ VviinnVpsWidget.style = vviinnVpsWidgetCss;
1376
+
1377
+ const vviinnWrongFormatCss = ":host{display:block}";
1378
+
1379
+ const VviinnWrongFormat = class {
1380
+ constructor(hostRef) {
1381
+ index.registerInstance(this, hostRef);
1382
+ this.handler = undefined;
1383
+ }
1384
+ render() {
1385
+ 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.handler }, "Neues Bild hochladen"))));
1386
+ }
1387
+ };
1388
+ VviinnWrongFormat.style = vviinnWrongFormatCss;
1389
+
1390
+ exports.cropper_handler = CropperHandler;
1391
+ exports.highlight_box = HighlightBox;
1392
+ exports.image_cropper = ImageCropper;
1393
+ exports.search_filters = SearchFilters;
1394
+ exports.vviinn_button = VviinnButton;
1395
+ exports.vviinn_detected_object = VviinnDetectedObject;
1396
+ exports.vviinn_empty_results = VviinnEmptyResults;
1397
+ exports.vviinn_error = VviinnError;
1398
+ exports.vviinn_example_image = VviinnExampleImage;
1399
+ exports.vviinn_example_images = VviinnExampleImages;
1400
+ exports.vviinn_image_selector = VviinnImageSelector;
1401
+ exports.vviinn_image_view = VviinnImageView;
1402
+ exports.vviinn_modal = VviinnModal;
1403
+ exports.vviinn_onboarding = VviinnOnboarding;
1404
+ exports.vviinn_onboarding_card_1 = VviinnOnboardingCard1;
1405
+ exports.vviinn_onboarding_card_2 = VviinnOnboardingCard2;
1406
+ exports.vviinn_onboarding_card_3 = VviinnOnboardingCard3;
1407
+ exports.vviinn_overlay = VviinnOverlay;
1408
+ exports.vviinn_overlayed_modal = VviinnOverlayedModal;
1409
+ exports.vviinn_preloader = VviinnPreloader;
1410
+ exports.vviinn_privacy_badge = VviinnPrivacyBadge;
1411
+ exports.vviinn_product_card = VviinnProductCard;
1412
+ exports.vviinn_server_error = VviinnServerError;
1413
+ exports.vviinn_slide = VviinnSlide;
1414
+ exports.vviinn_slider = VviinnSlider;
1415
+ exports.vviinn_teaser = VviinnTeaser;
1416
+ exports.vviinn_vps_button = VviinnVpsButton;
1417
+ exports.vviinn_vps_widget = VviinnVpsWidget;
1418
+ exports.vviinn_wrong_format = VviinnWrongFormat;