vviinn-widgets 2.7.2 → 2.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cjs/{index-df6896e2.js → cropper-handler_30.cjs.entry.js} +2323 -165
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/vviinn-widgets.cjs.js +1 -1
  4. package/dist/collection/components/vviinn-product-card/vviinn-product-card.js +5 -2
  5. package/dist/esm/{app-globals-865bc7a7.js → app-globals-2f864b5d.js} +1 -1
  6. package/dist/esm/{index-2fdd499d.js → cropper-handler_30.entry.js} +2294 -119
  7. package/dist/esm/{index-443468c7.js → index-040cfca9.js} +2 -2
  8. package/dist/esm/{index-51f71d18.js → index-2d36a726.js} +1 -1
  9. package/dist/esm/loader.js +3 -3
  10. package/dist/esm/vviinn-recommendations-sidebar.entry.js +2 -2
  11. package/dist/esm/vviinn-vpr-button.entry.js +2 -2
  12. package/dist/esm/vviinn-widgets.js +3 -3
  13. package/dist/types/components/vviinn-product-card/vviinn-product-card.d.ts +1 -0
  14. package/dist/vviinn-widgets/{p-3469b71a.js → p-334db07e.js} +1 -1
  15. package/dist/vviinn-widgets/{p-40bea5b5.entry.js → p-a98df480.entry.js} +1 -1
  16. package/dist/vviinn-widgets/p-da99b592.entry.js +1 -0
  17. package/dist/vviinn-widgets/{p-a6e0710f.entry.js → p-dc124f62.entry.js} +1 -1
  18. package/dist/vviinn-widgets/{p-465d043d.js → p-e5a7f685.js} +1 -1
  19. package/dist/vviinn-widgets/{p-166970f3.js → p-fe8dc0b9.js} +1 -1
  20. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  21. package/package.json +1 -1
  22. package/www/build/{p-3469b71a.js → p-334db07e.js} +1 -1
  23. package/www/build/{p-40bea5b5.entry.js → p-a98df480.entry.js} +1 -1
  24. package/www/build/p-c5ef37e7.js +125 -0
  25. package/www/build/p-da99b592.entry.js +1 -0
  26. package/www/build/{p-a6e0710f.entry.js → p-dc124f62.entry.js} +1 -1
  27. package/www/build/p-e0153ae2.css +6 -0
  28. package/www/build/{p-465d043d.js → p-e5a7f685.js} +1 -1
  29. package/www/build/{p-166970f3.js → p-fe8dc0b9.js} +1 -1
  30. package/www/build/vviinn-widgets.esm.js +1 -1
  31. package/www/index.html +2495 -1
  32. package/dist/cjs/cropper-handler_27.cjs.entry.js +0 -1135
  33. package/dist/cjs/customized-slots-06ca4007.js +0 -53
  34. package/dist/cjs/vviinn-carousel_2.cjs.entry.js +0 -1001
  35. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -43
  36. package/dist/esm/cropper-handler_27.entry.js +0 -1105
  37. package/dist/esm/customized-slots-96902edf.js +0 -50
  38. package/dist/esm/vviinn-carousel_2.entry.js +0 -996
  39. package/dist/esm/vviinn-vps-button.entry.js +0 -39
  40. package/dist/vviinn-widgets/p-2dd35f19.entry.js +0 -1
  41. package/dist/vviinn-widgets/p-59bd2a99.js +0 -1
  42. package/dist/vviinn-widgets/p-74ed36af.entry.js +0 -1
  43. package/dist/vviinn-widgets/p-9def6b8b.entry.js +0 -1
  44. package/dist/vviinn-widgets/p-cd995515.js +0 -1
  45. package/www/build/p-2dd35f19.entry.js +0 -1
  46. package/www/build/p-59bd2a99.js +0 -1
  47. package/www/build/p-61933b75.js +0 -1
  48. package/www/build/p-74ed36af.entry.js +0 -1
  49. package/www/build/p-9def6b8b.entry.js +0 -1
  50. package/www/build/p-a67898be.css +0 -1
  51. package/www/build/p-cd995515.js +0 -1
@@ -1,10 +1,11 @@
1
- import { a as getRenderingRef, f as forceUpdate } from './index-51f71d18.js';
1
+ import { r as registerInstance, h, H as Host, g as getRenderingRef, f as forceUpdate, c as createEvent, a as getElement } from './index-2d36a726.js';
2
+ import { C as CheckIcon, a as ChevronIcon, O as OnboardingCard1Icon, b as OnboardingCard2Icon, c as OnboardingCard3Icon, A as ArrowIcon, d as CameraIcon } from './index-040cfca9.js';
2
3
 
3
4
  // -------------------------------------------------------------------------------------
4
5
  /**
5
6
  * @since 2.0.0
6
7
  */
7
- function identity(a) {
8
+ function identity$1(a) {
8
9
  return a;
9
10
  }
10
11
  function flow(ab, bc, cd, de, ef, fg, gh, hi, ij) {
@@ -198,7 +199,7 @@ var struct = function (semigroups) { return ({
198
199
  * @category instances
199
200
  * @since 2.10.0
200
201
  */
201
- var first = function () { return ({ concat: identity }); };
202
+ var first = function () { return ({ concat: identity$1 }); };
202
203
  /**
203
204
  * Always return the last argument.
204
205
  *
@@ -226,7 +227,7 @@ const semigroupDiff = {
226
227
  concat: (x, y) => x - y,
227
228
  };
228
229
 
229
- const fromRectangle$1 = ({ x, y }) => {
230
+ const fromRectangle$2 = ({ x, y }) => {
230
231
  return {
231
232
  x,
232
233
  y,
@@ -280,27 +281,27 @@ const getCursorValue = (direction) => {
280
281
  return "pointer";
281
282
  }
282
283
  };
283
- const fromRectangle = (r) => [
284
+ const fromRectangle$1 = (r) => [
284
285
  {
285
- position: fromRectangle$1(r),
286
+ position: fromRectangle$2(r),
286
287
  direction: HandlerDirection.NorthWest,
287
288
  },
288
289
  {
289
- position: pointSumSemigroup.concat(fromRectangle$1(r), {
290
+ position: pointSumSemigroup.concat(fromRectangle$2(r), {
290
291
  x: r.width,
291
292
  y: 0,
292
293
  }),
293
294
  direction: HandlerDirection.NorthEast,
294
295
  },
295
296
  {
296
- position: pointSumSemigroup.concat(fromRectangle$1(r), {
297
+ position: pointSumSemigroup.concat(fromRectangle$2(r), {
297
298
  x: 0,
298
299
  y: r.height,
299
300
  }),
300
301
  direction: HandlerDirection.SouthWest,
301
302
  },
302
303
  {
303
- position: pointSumSemigroup.concat(fromRectangle$1(r), {
304
+ position: pointSumSemigroup.concat(fromRectangle$2(r), {
304
305
  x: r.width,
305
306
  y: r.height,
306
307
  }),
@@ -308,6 +309,40 @@ const fromRectangle = (r) => [
308
309
  },
309
310
  ];
310
311
 
312
+ const cropperHandlerCss = ":host{--size:20px;background:transparent;border:4px solid white;box-sizing:content-box;display:block;height:var(--size);touch-action:none;position:absolute;width:var(--size);z-index:4;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.disabled){opacity:0.25}:host(.nw-resize){border-bottom:none;border-right:none;top:0;left:0}:host(.ne-resize){border-left:none;border-bottom:none;right:0;top:0}:host(.sw-resize){border-right:none;border-top:none;left:0;bottom:0}:host(.se-resize){border-left:none;border-top:none;bottom:0;right:0}";
313
+
314
+ let CropperHandler = class {
315
+ constructor(hostRef) {
316
+ registerInstance(this, hostRef);
317
+ this.disabled = false;
318
+ }
319
+ render() {
320
+ return (h(Host, { part: `handle ${getCursorValue(this.handler.direction)}`, class: {
321
+ disabled: this.disabled,
322
+ [getCursorValue(this.handler.direction)]: true,
323
+ }, style: {
324
+ "--size": "20px",
325
+ cursor: getCursorValue(this.handler.direction),
326
+ }, draggable: false }));
327
+ }
328
+ };
329
+ CropperHandler.style = cropperHandlerCss;
330
+
331
+ const fromRectangle = (shape, target) => {
332
+ const top = `${shape.y}px`;
333
+ const left = `${shape.x}px`;
334
+ const right = `${target.width - (shape.x + shape.width)}px`;
335
+ const bottom = `${target.height - (shape.y + shape.height)}px`;
336
+ return {
337
+ top,
338
+ right,
339
+ bottom,
340
+ left,
341
+ };
342
+ };
343
+ const printClip = (clip) => `inset(${clip.top} ${clip.right} ${clip.bottom} ${clip.left})`;
344
+ const getClipValue = (shape, target) => printClip(fromRectangle(shape, target));
345
+
311
346
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
312
347
 
313
348
  function createCommonjsModule(fn, basedir, module) {
@@ -1255,7 +1290,7 @@ var concatAll = function (M) { return function (startWith) { return function (as
1255
1290
  exports.concatAll = concatAll;
1256
1291
  });
1257
1292
 
1258
- var Eq = createCommonjsModule(function (module, exports) {
1293
+ var Eq$1 = createCommonjsModule(function (module, exports) {
1259
1294
  Object.defineProperty(exports, "__esModule", { value: true });
1260
1295
  exports.eqDate = exports.eqNumber = exports.eqString = exports.eqBoolean = exports.eq = exports.strictEqual = exports.getStructEq = exports.getTupleEq = exports.Contravariant = exports.getMonoid = exports.getSemigroup = exports.eqStrict = exports.URI = exports.contramap = exports.tuple = exports.struct = exports.fromEquals = void 0;
1261
1296
 
@@ -1445,7 +1480,7 @@ exports.eqDate = {
1445
1480
  };
1446
1481
  });
1447
1482
 
1448
- var Ord = createCommonjsModule(function (module, exports) {
1483
+ var Ord$1 = createCommonjsModule(function (module, exports) {
1449
1484
  Object.defineProperty(exports, "__esModule", { value: true });
1450
1485
  exports.ordDate = exports.ordNumber = exports.ordString = exports.ordBoolean = exports.ord = exports.getDualOrd = exports.getTupleOrd = exports.between = exports.clamp = exports.max = exports.min = exports.geq = exports.leq = exports.gt = exports.lt = exports.equals = exports.trivial = exports.Contravariant = exports.getMonoid = exports.getSemigroup = exports.URI = exports.contramap = exports.reverse = exports.tuple = exports.fromCompare = exports.equalsDefault = void 0;
1451
1486
 
@@ -1756,7 +1791,7 @@ function compare(first, second) {
1756
1791
  return first < second ? -1 : first > second ? 1 : 0;
1757
1792
  }
1758
1793
  var strictOrd = {
1759
- equals: Eq.eqStrict.equals,
1794
+ equals: Eq$1.eqStrict.equals,
1760
1795
  compare: compare
1761
1796
  };
1762
1797
  /**
@@ -1863,7 +1898,7 @@ exports.semigroupProduct = exports.semigroupSum = exports.semigroupString = expo
1863
1898
 
1864
1899
  var _ = __importStar(internal);
1865
1900
  var M = __importStar(Magma);
1866
- var Or = __importStar(Ord);
1901
+ var Or = __importStar(Ord$1);
1867
1902
  // -------------------------------------------------------------------------------------
1868
1903
  // constructors
1869
1904
  // -------------------------------------------------------------------------------------
@@ -3962,7 +3997,7 @@ var mapLeft$2 = function (f) { return function (fa) {
3962
3997
  */
3963
3998
  var FromEither$1 = {
3964
3999
  URI: URI$2,
3965
- fromEither: identity
4000
+ fromEither: identity$1
3966
4001
  };
3967
4002
  // -------------------------------------------------------------------------------------
3968
4003
  // natural transformations
@@ -4191,7 +4226,7 @@ var match = matchW;
4191
4226
  * @category destructors
4192
4227
  * @since 2.0.0
4193
4228
  */
4194
- var fold = match;
4229
+ var fold$1 = match;
4195
4230
  /**
4196
4231
  * Less strict version of [`getOrElse`](#getorelse).
4197
4232
  *
@@ -8019,7 +8054,7 @@ const createBearerHeaders = (token) => new Headers({
8019
8054
  const checkToken = (token) => pipe(token, existAndNotEmpty, Either.mapLeft(() => invalidTokenError));
8020
8055
  const processBearerToken = (token) => pipe(token, checkToken, Either.map(createBearerHeaders));
8021
8056
 
8022
- const sequenceToEither = Apply$1.sequenceT(Either.Apply);
8057
+ const sequenceToEither$1 = Apply$1.sequenceT(Either.Apply);
8023
8058
 
8024
8059
  const imageFormFromFile = (file) => {
8025
8060
  const body = new FormData();
@@ -8040,8 +8075,8 @@ const detectedObjectEq = {
8040
8075
  };
8041
8076
  const searchSessionClient = (initialData, campaignId = none) => {
8042
8077
  const searchUrl = "search/session";
8043
- const requestUrl = _function.pipe(campaignId, fold(() => searchUrl, (campaignId) => `${searchUrl}?campaign-id=${campaignId}`));
8044
- return _function.pipe(sequenceToEither(getApiPath(), createInitPostRequest), fromEither, chainW(makeRequest(requestUrl, initialData)));
8078
+ const requestUrl = _function.pipe(campaignId, fold$1(() => searchUrl, (campaignId) => `${searchUrl}?campaign-id=${campaignId}`));
8079
+ return _function.pipe(sequenceToEither$1(getApiPath(), createInitPostRequest), fromEither, chainW(makeRequest(requestUrl, initialData)));
8045
8080
  };
8046
8081
 
8047
8082
  var ObjectMemberName;
@@ -8069,29 +8104,29 @@ const foldValueObject = (i) => {
8069
8104
  };
8070
8105
 
8071
8106
  const getLink = (item, path) => pipe(item.links, fromNullable, chain$3((linksObject) => fromNullable(linksObject[path])));
8072
- const linkRequest = (link) => (data) => pipe(sequenceToEither(getApiPath(), createRequestFromMethod(link.method)), fromEither, chainW(makeRequest(link.href, data)));
8107
+ const linkRequest = (link) => (data) => pipe(sequenceToEither$1(getApiPath(), createRequestFromMethod(link.method)), fromEither, chainW(makeRequest(link.href, data)));
8073
8108
 
8074
8109
  const move = (origin, position) => {
8075
- const originPosition = fromRectangle$1(origin);
8110
+ const originPosition = fromRectangle$2(origin);
8076
8111
  const newPosition = pointSumSemigroup.concat(originPosition, position);
8077
8112
  return Object.assign(Object.assign({}, newPosition), { width: origin.width, height: origin.height });
8078
8113
  };
8079
8114
  const transformNorthEast = (origin, handler) => {
8080
- const newPosition = pointSumSemigroup.concat(fromRectangle$1(origin), {
8115
+ const newPosition = pointSumSemigroup.concat(fromRectangle$2(origin), {
8081
8116
  x: 0,
8082
8117
  y: handler.position.y,
8083
8118
  });
8084
8119
  return Object.assign(Object.assign({}, newPosition), { width: origin.width + handler.position.x, height: origin.height - handler.position.y });
8085
8120
  };
8086
8121
  const transformNorthWest = (origin, handler) => {
8087
- const newPosition = pointSumSemigroup.concat(fromRectangle$1(origin), handler.position);
8122
+ const newPosition = pointSumSemigroup.concat(fromRectangle$2(origin), handler.position);
8088
8123
  return Object.assign(Object.assign({}, newPosition), { width: origin.width - handler.position.x, height: origin.height - handler.position.y });
8089
8124
  };
8090
8125
  const transformSouthEast = (origin, handler) => {
8091
8126
  return Object.assign(Object.assign({}, origin), { width: origin.width + handler.position.x, height: origin.height + handler.position.y });
8092
8127
  };
8093
8128
  const transformSouthWest = (origin, handler) => {
8094
- const newPosition = pointSumSemigroup.concat(fromRectangle$1(origin), {
8129
+ const newPosition = pointSumSemigroup.concat(fromRectangle$2(origin), {
8095
8130
  x: handler.position.x,
8096
8131
  y: 0,
8097
8132
  });
@@ -8194,7 +8229,7 @@ const transformSendForm = (form, data) => [
8194
8229
  }),
8195
8230
  },
8196
8231
  ];
8197
- const formRequest = (form, data = {}) => (payload) => _function.pipe(sequenceToEither(getApiPath(), _function.pipe(requestFromForm(form, data), mapLeft$2((error) => {
8232
+ const formRequest = (form, data = {}) => (payload) => _function.pipe(sequenceToEither$1(getApiPath(), _function.pipe(requestFromForm(form, data), mapLeft$2((error) => {
8198
8233
  return { kind: "app", inner: error };
8199
8234
  }))), fromEither, chainW((initialData) => {
8200
8235
  const apiPath = initialData[0];
@@ -8220,6 +8255,26 @@ const fromFile = async (f) => {
8220
8255
  const sequenceToOption = Apply$1.sequenceT(Option.Apply);
8221
8256
  const checkEmpryString = (x) => x.length > 0 ? Option.some(x) : Option.none;
8222
8257
 
8258
+ // -------------------------------------------------------------------------------------
8259
+ // -------------------------------------------------------------------------------------
8260
+ // instances
8261
+ // -------------------------------------------------------------------------------------
8262
+ /**
8263
+ * @category instances
8264
+ * @since 2.10.0
8265
+ */
8266
+ var Eq = {
8267
+ equals: function (first, second) { return first === second; }
8268
+ };
8269
+ /**
8270
+ * @category instances
8271
+ * @since 2.10.0
8272
+ */
8273
+ var Ord = {
8274
+ equals: Eq.equals,
8275
+ compare: function (first, second) { return (first < second ? -1 : first > second ? 1 : 0); }
8276
+ };
8277
+
8223
8278
  /**
8224
8279
  * Find the first element returned by an option based selector function
8225
8280
  *
@@ -8960,7 +9015,7 @@ exports.uniq = uniq;
8960
9015
  */
8961
9016
  var sortBy = function (ords) {
8962
9017
  if ((0, exports.isNonEmpty)(ords)) {
8963
- var M = (0, Ord.getMonoid)();
9018
+ var M = (0, Ord$1.getMonoid)();
8964
9019
  return (0, exports.sort)(ords.reduce(M.concat, M.empty));
8965
9020
  }
8966
9021
  return _function.identity;
@@ -9574,7 +9629,7 @@ exports.getSemigroup = getSemigroup;
9574
9629
  * @since 2.5.0
9575
9630
  */
9576
9631
  var getEq = function (E) {
9577
- return (0, Eq.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
9632
+ return (0, Eq$1.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
9578
9633
  };
9579
9634
  exports.getEq = getEq;
9580
9635
  /**
@@ -10175,7 +10230,7 @@ exports.uniq = uniq;
10175
10230
  */
10176
10231
  var sortBy = function (ords) {
10177
10232
  if ((0, exports.isNonEmpty)(ords)) {
10178
- var M = (0, Ord.getMonoid)();
10233
+ var M = (0, Ord$1.getMonoid)();
10179
10234
  return (0, exports.sort)(ords.reduce(M.concat, M.empty));
10180
10235
  }
10181
10236
  return exports.copy;
@@ -12685,7 +12740,7 @@ exports.getMonoid = getMonoid;
12685
12740
  * @since 2.5.0
12686
12741
  */
12687
12742
  var getEq = function (E) {
12688
- return (0, Eq.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
12743
+ return (0, Eq$1.fromEquals)(function (xs, ys) { return xs.length === ys.length && xs.every(function (x, i) { return E.equals(x, ys[i]); }); });
12689
12744
  };
12690
12745
  exports.getEq = getEq;
12691
12746
  /**
@@ -12708,7 +12763,7 @@ exports.getEq = getEq;
12708
12763
  * @since 2.5.0
12709
12764
  */
12710
12765
  var getOrd = function (O) {
12711
- return (0, Ord.fromCompare)(function (a, b) {
12766
+ return (0, Ord$1.fromCompare)(function (a, b) {
12712
12767
  var aLen = a.length;
12713
12768
  var bLen = b.length;
12714
12769
  var len = Math.min(aLen, bLen);
@@ -15918,7 +15973,7 @@ const makeHeight = (size) => {
15918
15973
  size,
15919
15974
  };
15920
15975
  };
15921
- const ordBySize = Ord.contramap((s) => s.size)(number.Ord);
15976
+ const ordBySize = Ord$1.contramap((s) => s.size)(number.Ord);
15922
15977
  const ordByKind = {
15923
15978
  equals: (x, y) => x.kind === y.kind,
15924
15979
  compare: (x, y) => {
@@ -16068,7 +16123,7 @@ const makeRectangularSearchRequest = async () => {
16068
16123
  const uploadFile = (file) => {
16069
16124
  state.loading = true;
16070
16125
  const fileForm = imageFormFromFile(file);
16071
- const tokenWithFile = sequenceToEither(processBearerToken(state.token), right(fileForm));
16126
+ const tokenWithFile = sequenceToEither$1(processBearerToken(state.token), right(fileForm));
16072
16127
  return pipe(tokenWithFile, map$4(([headers, body]) => {
16073
16128
  return {
16074
16129
  headers,
@@ -16098,7 +16153,7 @@ onChange("activeIonLink", async (newLink) => {
16098
16153
  });
16099
16154
  onChange("searchArea", (newSearchArea) => {
16100
16155
  pipe(newSearchArea, Option.map((area) => {
16101
- state.cropperHandlers = fromRectangle(area);
16156
+ state.cropperHandlers = fromRectangle$1(area);
16102
16157
  }));
16103
16158
  });
16104
16159
  onChange("serverError", () => {
@@ -16113,128 +16168,1896 @@ const processSelectedFile = async (file) => {
16113
16168
  const fileResizer = resizeFileTo(RESIZED_IMAGE_WIDTH);
16114
16169
  const resizeFileTask = pipe(originFile, fromEither, chainTaskK(fileResizer));
16115
16170
  const session = await pipe(resizeFileTask, chain(uploadFile))();
16116
- pipe(sequenceToEither(session, originFile), map$4(([sessionObject, file]) => uploadHiresFile(sessionObject, file)));
16171
+ pipe(sequenceToEither$1(session, originFile), map$4(([sessionObject, file]) => uploadHiresFile(sessionObject, file)));
16117
16172
  await pipe(resizeFileTask, chainTaskK(imageFromFileTask), map(setSelectedImage))();
16118
16173
  return session;
16119
16174
  };
16120
16175
 
16121
- // Unique ID creation requires a high quality random # generator. In the browser we therefore
16122
- // require the crypto API and do not support built-in fallback to lower quality random number
16123
- // generators (like Math.random()).
16124
- var getRandomValues;
16125
- var rnds8 = new Uint8Array(16);
16126
- function rng() {
16127
- // lazy load so that environments that need to polyfill have a chance to do so
16128
- if (!getRandomValues) {
16129
- // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
16130
- // find the complete implementation of crypto (msCrypto) on IE11.
16131
- getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
16176
+ const highlightBoxCss = ":host{display:grid;position:absolute;box-sizing:border-box;border:none;width:100%;height:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;--size:10px;--x-position:0;--y-position:0}img{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pointer{position:absolute;width:var(--size);height:var(--size);background:black;border-radius:50%;z-index:2;cursor:pointer;transform:translate(var(--x-position), var(--y-position)) scale(0);-webkit-animation:0.25s linear fadein;animation:0.25s linear fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.pointer::after{content:\"\";cursor:pointer;border:5px solid black;border-radius:50%;width:var(--size);height:var(--size);display:block;transform:translate(calc(-50% + var(--size) * 0.5), calc(-50% + var(--size) * 0.5));padding:calc(var(--size) * 0.5);opacity:.75}@-webkit-keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}@keyframes fadein{from{transform:translate(var(--x-position), var(--y-position)) scale(0)}to{transform:translate(var(--x-position), var(--y-position)) scale(1)}}";
16132
16177
 
16133
- if (!getRandomValues) {
16134
- throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
16178
+ let HighlightBox = class {
16179
+ constructor(hostRef) {
16180
+ registerInstance(this, hostRef);
16181
+ }
16182
+ getInsetValue() {
16183
+ return pipe(sequenceToOption(imageSearchState.searchArea, imageSearchState.imageBounds), Option.map(([selection, image]) => getClipValue(selection, image)), Option.getOrElse(() => ""));
16184
+ }
16185
+ renderImage() {
16186
+ return pipe(sequenceToOption(imageSearchState.imageUrl, imageSearchState.imageBounds), Option.map(([url, bounds]) => (h("img", { src: url, width: bounds.width, height: bounds.height, style: { "clip-path": `${this.getInsetValue()}` } }))), Option.getOrElse(() => ""));
16187
+ }
16188
+ render() {
16189
+ return h(Host, null, this.renderImage());
16190
+ }
16191
+ };
16192
+ HighlightBox.style = highlightBoxCss;
16193
+
16194
+ const findTarget = (ev) => {
16195
+ return ev.target;
16196
+ };
16197
+
16198
+ 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}";
16199
+
16200
+ const MIN_SEARCHAREA_SIZE = 40;
16201
+ let ImageCropper = class {
16202
+ constructor(hostRef) {
16203
+ registerInstance(this, hostRef);
16204
+ this.cropperChanged = createEvent(this, "cropperChanged", 7);
16205
+ this.disabled = false;
16206
+ this.handleMove = false;
16207
+ this.mouseStartPoint = undefined;
16208
+ this.bounds = undefined;
16209
+ }
16210
+ componentDidLoad() {
16211
+ this.bounds = this.el.getBoundingClientRect();
16212
+ }
16213
+ handleHandlerMove(event) {
16214
+ event.preventDefault();
16215
+ event.stopPropagation();
16216
+ const destination = fromMouseEvent(event);
16217
+ const distance = pointDiffSemigroup.concat(destination, this.mouseStartPoint);
16218
+ const transformedHandler = {
16219
+ position: distance,
16220
+ direction: this.handlerMoveDirection,
16221
+ };
16222
+ _function.pipe(imageSearchState.searchArea, Option.map((area) => {
16223
+ const newSearchArea = transform(area, transformedHandler);
16224
+ if (this.outOfBounds(newSearchArea))
16225
+ return;
16226
+ imageSearchState.searchArea = Option.some(newSearchArea);
16227
+ this.mouseStartPoint = destination;
16228
+ imageSearchState.detectedObject = undefined;
16229
+ }));
16230
+ }
16231
+ outOfBounds(area) {
16232
+ return (area.width < MIN_SEARCHAREA_SIZE ||
16233
+ area.height < MIN_SEARCHAREA_SIZE ||
16234
+ area.x < 0 ||
16235
+ area.y < 0 ||
16236
+ this.bounds.height - (area.y + area.height) < 0 ||
16237
+ this.bounds.width - (area.x + area.width) < 0);
16238
+ }
16239
+ handleCropperMove(ev) {
16240
+ ev.preventDefault();
16241
+ ev.stopPropagation();
16242
+ const destination = fromMouseEvent(ev);
16243
+ const distance = pointDiffSemigroup.concat(destination, this.mouseStartPoint);
16244
+ _function.pipe(imageSearchState.searchArea, Option.map((searchArea) => {
16245
+ const newSearchArea = move(searchArea, distance);
16246
+ if (newSearchArea.x < 0 ||
16247
+ newSearchArea.y < 0 ||
16248
+ this.bounds.height - (newSearchArea.y + newSearchArea.height) < 0 ||
16249
+ this.bounds.width - (newSearchArea.x + newSearchArea.width) < 0)
16250
+ return;
16251
+ imageSearchState.detectedObject = undefined;
16252
+ imageSearchState.searchArea = Option.some(newSearchArea);
16253
+ this.mouseStartPoint = destination;
16254
+ }));
16255
+ }
16256
+ handlePointerDown(event) {
16257
+ event.stopPropagation();
16258
+ this.mouseStartPoint = fromMouseEvent(event);
16259
+ // should be htmlelement or handler
16260
+ const target = findTarget(event);
16261
+ if (target.localName === "cropper-handler") {
16262
+ this.handlerMoveDirection = target.handler.direction;
16263
+ this.pointerMoveListener = this.handleHandlerMove.bind(this);
16264
+ }
16265
+ else {
16266
+ this.pointerMoveListener = this.handleCropperMove.bind(this);
16267
+ }
16268
+ this.pointerReleaseListener = this.handleSearchAreaRelease.bind(this);
16269
+ this.el.addEventListener("pointermove", this.pointerMoveListener);
16270
+ window.addEventListener("pointerup", this.pointerReleaseListener, {
16271
+ once: true,
16272
+ });
16273
+ }
16274
+ handleSearchAreaRelease() {
16275
+ this.el.removeEventListener("pointermove", this.pointerMoveListener);
16276
+ document.removeEventListener("pointerup", this.pointerReleaseListener);
16277
+ this.mouseStartPoint = undefined;
16278
+ makeRectangularSearchRequest();
16279
+ this.cropperChanged.emit();
16280
+ }
16281
+ getStyleMap() {
16282
+ return _function.pipe(imageSearchState.searchArea, Option.map((rectangle) => {
16283
+ return {
16284
+ width: `${rectangle.width}px`,
16285
+ height: `${rectangle.height}px`,
16286
+ transform: `translate3d(${rectangle.x}px, ${rectangle.y}px, 0)`,
16287
+ cursor: this.handleMove ? "move" : "default",
16288
+ };
16289
+ }), Option.getOrElse(() => {
16290
+ return {};
16291
+ }));
16292
+ }
16293
+ render() {
16294
+ return (h(Host, { exportparts: "handle, e-resize, n-resize, ne-resize, nw-resize, s-resize, se-resize, sw-resize, w-resize" }, h("div", { class: {
16295
+ "crop-area": true,
16296
+ active: this.handleMove,
16297
+ disabled: this.disabled,
16298
+ }, draggable: false, style: this.getStyleMap(), onContextMenu: () => false, onPointerDown: (ev) => this.handlePointerDown(ev) }, imageSearchState.cropperHandlers.map((handler) => (h("cropper-handler", { disabled: this.disabled, handler: handler, onPointerDown: (ev) => this.handlePointerDown(ev) }))))));
16299
+ }
16300
+ get el() { return getElement(this); }
16301
+ };
16302
+ ImageCropper.style = imageCropperCss;
16303
+
16304
+ const searchFiltersCss = ":host{display:grid;grid-gap:1rem}.filters{display:flex;flex-direction:row;flex-wrap:wrap;gap:0.5rem}.filter{align-items:center;-webkit-animation-duration:0.25s;animation-duration:0.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:scalein;animation-name:scalein;border:1px solid lightgray;cursor:pointer;display:flex;flex-direction:row;grid-gap:8px;height:-webkit-max-content;height:-moz-max-content;height:max-content;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:0.1rem;transform:scale(0);transition-property:background;transition-duration:0.25s;transition-timing-function:ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:6px 16px}.filter.active{border:1px solid black;padding:6px 8px}.filter:hover{border:1px solid gray}.show-more{display:flex}.show-more.hidden{display:none}.show-more::after{content:url(\"data:image/svg+xml,%3Csvg width='16' height='16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 12.2l-6-6L3.2 5 8 9.8 12.8 5 14 6.2l-6 6z' fill='%23525252'/%3E%3C/svg%3E\");display:block;height:16px;margin-top:1px;margin-left:8px}.show-more.active::after{transform:rotateX(180deg)}@-webkit-keyframes scalein{from{opacity:0;transform:scale(0.5)}to{opacity:1;transform:scale(1)}}@keyframes scalein{from{opacity:0;transform:scale(0.5)}to{opacity:1;transform:scale(1)}}@media (max-width: 415px){.show-more::after{transform:rotate(-90deg)}.show-more.active::after{transform:rotate(90deg)}}@media (max-width: 800px){.filters{flex-wrap:nowrap;overflow-x:scroll;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;grid-gap:unset}.filter{scroll-snap-align:end;margin-right:0.5rem}}";
16305
+
16306
+ const FILTERS_COUNT = 5;
16307
+ const ACTIVE_FILTER_CLASSNAME = ".filter.active";
16308
+ const getFilterId = (filter) => filter.href.split("/").reverse()[0];
16309
+ let SearchFilters = class {
16310
+ constructor(hostRef) {
16311
+ registerInstance(this, hostRef);
16312
+ this.filterSelected = createEvent(this, "filterSelected", 7);
16313
+ this.filter = null;
16314
+ this.selectedCategoryId = null;
16315
+ this.hideFilters = true;
16316
+ }
16317
+ handleFilterSelection(filter) {
16318
+ return this.isFilterSelected(filter)
16319
+ ? this.clearSelectedFilter()
16320
+ : this.selectFilter(filter);
16321
+ }
16322
+ selectFilter(filter) {
16323
+ this.selectedCategoryId = getFilterId(filter);
16324
+ imageSearchState.activeIonLink = filter;
16325
+ this.filterSelected.emit("select");
16326
+ }
16327
+ clearSelectedFilter() {
16328
+ this.selectedCategoryId = null;
16329
+ imageSearchState.activeIonLink = undefined;
16330
+ this.findSelectedFilter().blur();
16331
+ this.filterSelected.emit("deselect");
16332
+ }
16333
+ findSelectedFilter() {
16334
+ return this.el.shadowRoot.querySelector(ACTIVE_FILTER_CLASSNAME);
16335
+ }
16336
+ toggleFilters() {
16337
+ this.hideFilters = !this.hideFilters;
16338
+ }
16339
+ handleEnter(ev, f) {
16340
+ if (ev.key !== "Enter")
16341
+ return;
16342
+ this.handleFilterSelection(f);
16343
+ }
16344
+ isFilterSelected(filterLink) {
16345
+ return this.selectedCategoryId === getFilterId(filterLink);
16346
+ }
16347
+ render() {
16348
+ return (h(Host, { exportparts: "filter, show-more-filters" }, h("div", { class: "filters" }, this.filter.filters
16349
+ .filter((_, i) => (this.hideFilters ? i < FILTERS_COUNT : true))
16350
+ .map((f, n) => (h("div", { role: "button", tabindex: "0", part: this.isFilterSelected(f) ? "filter active" : "filter", class: {
16351
+ filter: true,
16352
+ active: this.selectedCategoryId === getFilterId(f),
16353
+ }, style: { "animation-delay": `${n * 10}ms` }, onPointerUp: (ev) => {
16354
+ ev.stopPropagation();
16355
+ this.handleFilterSelection(f);
16356
+ }, onKeyPress: (ev) => this.handleEnter(ev, f) }, this.isFilterSelected(f) ? h(CheckIcon, null) : null, f.name))), h("div", { class: {
16357
+ filter: true,
16358
+ "show-more": true,
16359
+ hidden: this.filter.filters.length <= FILTERS_COUNT,
16360
+ active: !this.hideFilters,
16361
+ }, role: "button", tabindex: "0", "aria-role": "button", onClick: () => this.toggleFilters(), onKeyPress: (ev) => {
16362
+ if (ev.key === "Enter") {
16363
+ this.toggleFilters();
16364
+ }
16365
+ }, part: "show-more-filters" }, this.hideFilters ? "Zeige mehr" : "Zeige weniger"))));
16366
+ }
16367
+ get el() { return getElement(this); }
16368
+ };
16369
+ SearchFilters.style = searchFiltersCss;
16370
+
16371
+ const vviinnCarouselCss = ":host{--vviinn-progressbar-width:0;--vviinn-carousel-item-width:150px;--vviinn-carousel-columns-internal:var(--vviinn-carousel-columns, 4);--vviinn-carousel-image-width-system:140px}.body{display:flex;position:relative;width:var(--vviinn-carousel-content-width);flex-direction:column}.content-wrapper *{box-sizing:border-box}.content-wrapper{overflow-y:hidden;overflow-x:auto;flex-grow:1}.bullets{margin-top:16px;display:flex;flex-direction:row;grid-gap:24px;justify-content:center}.bullet{width:10px;height:10px;background:#E0E0E0;border-radius:50%;cursor:pointer}.bullet.active{background:#161616}.content:not(.show-scrollbar),.content.grid{scrollbar-color:#fff0 #fff0}.content:not(.show-scrollbar)::-webkit-scrollbar,.content.grid::-webkit-scrollbar{opacity:0}.content{display:flex;flex-direction:row;grid-gap:8px;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;overflow-y:hidden;overflow-x:auto;flex-grow:1;padding-bottom:16px}.content.left>*{scroll-snap-align:start}.content.right>*{scroll-snap-align:end}:host(.continuity) button{border-radius:2px}:host(.grid) button{border-radius:50%}button{align-items:center;background-color:white;border:none;box-shadow:0px 2px 6px rgba(0, 0, 0, 0.15);cursor:pointer;display:grid;height:40px;justify-items:center;position:absolute;top:calc(50% - 20px);width:40px;z-index:1;padding:0;margin:0}button{fill:#525252}button.prev svg{transform:rotate(180deg);margin-left:-5px}.prev{left:0}.next{right:0}.items-group{display:grid;grid-gap:16px;grid-template-columns:repeat(var(--vviinn-carousel-columns-internal), 1fr);min-width:100%}vviinn-product-card::part(price-container){text-align:center}:host(.classic) vviinn-product-card::part(title),:host(.classic) vviinn-product-card::part(brand),:host(.classic) vviinn-product-card::part(type){text-align:center}@media (max-width: 480px){:host(.modern) button{display:none}.items-group{grid-template-columns:repeat(2, 1fr)}}";
16372
+
16373
+ const COLUMNS_NUMBER_CSS_VAR = "--vviinn-carousel-columns-internal";
16374
+ const CAROUSEL_WIDTH_CSS_VAR = "--vviinn-carousel-content-width";
16375
+ const CAROUSEL_IMAGE_WIDTH_CSS_VAR = "--vviinn-carousel-image-width";
16376
+ const CONTENT_GROUP_CSS_CLASS = "items-group";
16377
+ let VviinnCarousel = class {
16378
+ constructor(hostRef) {
16379
+ registerInstance(this, hostRef);
16380
+ this.moveDirection = "right";
16381
+ this.contentGroups = [];
16382
+ this.activeContentGroup = 0;
16383
+ this.mode = "continuity";
16384
+ this.imageWidth = 140;
16385
+ this.showScroll = true;
16386
+ this.recommendations = [];
16387
+ this.columns = 0;
16388
+ this.resizeObserver = new ResizeObserver(() => this.handleResize());
16389
+ this.mutationObserver = new MutationObserver(() => this.cloneSlottedContent());
16390
+ }
16391
+ connectedCallback() {
16392
+ this.setItemWidth();
16393
+ }
16394
+ disconnectedCallback() {
16395
+ this.resizeObserver.disconnect();
16396
+ }
16397
+ componentDidLoad() {
16398
+ this.setWidth();
16399
+ this.processScrollbarWidth();
16400
+ this.columns = this.getColumnsNumber();
16401
+ const slot = this.el.querySelector(".content");
16402
+ this.mutationObserver.observe(slot, { subtree: true, childList: true });
16403
+ this.resizeObserver.observe(this.getHostParent());
16404
+ }
16405
+ getItemWidthFromDocument() {
16406
+ return parseInt(getComputedStyle(document.body).getPropertyValue(CAROUSEL_IMAGE_WIDTH_CSS_VAR));
16407
+ }
16408
+ setItemWidth() {
16409
+ const widthInDocument = this.getItemWidthFromDocument();
16410
+ const itemWidth = isNaN(widthInDocument)
16411
+ ? this.imageWidth
16412
+ : widthInDocument;
16413
+ this.el.style.setProperty(CAROUSEL_IMAGE_WIDTH_CSS_VAR, `${itemWidth}px`);
16414
+ }
16415
+ getContentClassMap() {
16416
+ return {
16417
+ content: true,
16418
+ [this.moveDirection]: true,
16419
+ [this.mode]: true,
16420
+ "show-scrollbar": this.showScroll,
16421
+ };
16422
+ }
16423
+ handleResize() {
16424
+ this.setWidth();
16425
+ this.processScrollbarWidth();
16426
+ this.setItemWidth();
16427
+ const newColumns = this.getColumnsNumber();
16428
+ if (newColumns !== this.columns) {
16429
+ this.columns = newColumns;
16135
16430
  }
16136
16431
  }
16432
+ calculateMoveStep() {
16433
+ const contentWidths = this.getContent().map((el) => el.getBoundingClientRect().width);
16434
+ const sum = contentWidths.reduce((acc, val) => acc + val, 0);
16435
+ return sum / contentWidths.length;
16436
+ }
16437
+ getHostParent() {
16438
+ const parent = this.el.parentNode;
16439
+ return parent.host.parentElement;
16440
+ }
16441
+ setWidth() {
16442
+ const parent = this.getHostParent();
16443
+ if (!parent)
16444
+ return;
16445
+ const parentStyles = getComputedStyle(parent);
16446
+ const parentWidth = parent.getBoundingClientRect().width;
16447
+ const width = parentWidth -
16448
+ (parseInt(parentStyles["padding-right"]) +
16449
+ parseInt(parentStyles["padding-left"]));
16450
+ this.el.style.setProperty(CAROUSEL_WIDTH_CSS_VAR, `${width}px`);
16451
+ }
16452
+ getParent() {
16453
+ const parentNode = this.el.parentNode;
16454
+ const host = parentNode.host;
16455
+ return host.parentElement;
16456
+ }
16457
+ cloneSlottedContent() {
16458
+ this.setWidth();
16459
+ }
16460
+ getActiveGroupIndex() {
16461
+ var _a, _b;
16462
+ const contentNodeLeft = (_b = (_a = this.getContentNode()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) === null || _b === void 0 ? void 0 : _b.left;
16463
+ if (!contentNodeLeft)
16464
+ return 0;
16465
+ const groups = this.getContentGroups();
16466
+ const groupsPositions = groups.map((g) => g.getBoundingClientRect().left);
16467
+ const indexedPositions = groupsPositions
16468
+ .map((value, index) => [value, index])
16469
+ .filter((x) => x[0] >= 0);
16470
+ return indexedPositions.length > 0 ? indexedPositions[0][1] : 0;
16471
+ }
16472
+ getContentNode() {
16473
+ return this.el.querySelector(".content");
16474
+ }
16475
+ getContent() {
16476
+ const children = this.getContentNode().children;
16477
+ return Array.from(children).map((c) => c);
16478
+ }
16479
+ getColumnsNumber() {
16480
+ const styleSheet = getComputedStyle(this.el);
16481
+ const columnsInCss = styleSheet.getPropertyValue(COLUMNS_NUMBER_CSS_VAR);
16482
+ return parseInt(columnsInCss);
16483
+ }
16484
+ getContentGroups() {
16485
+ return Array.from(this.el.querySelectorAll(`.${CONTENT_GROUP_CSS_CLASS}`));
16486
+ }
16487
+ showNext() {
16488
+ this.moveDirection = "right";
16489
+ const contentContainer = this.getContentNode();
16490
+ requestAnimationFrame(() => {
16491
+ contentContainer.scrollTo({
16492
+ top: 0,
16493
+ left: contentContainer.scrollLeft + this.calculateMoveStep(),
16494
+ behavior: "smooth",
16495
+ });
16496
+ });
16497
+ }
16498
+ showPrev() {
16499
+ this.moveDirection = "left";
16500
+ const contentContainer = this.getContentNode();
16501
+ requestAnimationFrame(() => {
16502
+ contentContainer.scrollTo({
16503
+ top: 0,
16504
+ left: contentContainer.scrollLeft - this.calculateMoveStep(),
16505
+ behavior: "smooth",
16506
+ });
16507
+ });
16508
+ }
16509
+ scroll(index) {
16510
+ const contentContainer = this.getContentNode();
16511
+ requestAnimationFrame(() => {
16512
+ contentContainer.scrollTo({
16513
+ top: 0,
16514
+ left: this.calculateMoveStep() * index,
16515
+ behavior: "smooth",
16516
+ });
16517
+ });
16518
+ }
16519
+ processScrollbarWidth() {
16520
+ const target = this.getContentNode();
16521
+ const scrollRatio = (target.scrollLeft + target.clientWidth) / target.scrollWidth;
16522
+ const scrolledWidth = target.clientWidth * scrollRatio;
16523
+ this.el.style.setProperty("--vviinn-progressbar-width", `${scrolledWidth}px`);
16524
+ this.activeContentGroup = this.getActiveGroupIndex();
16525
+ }
16526
+ showBullets() {
16527
+ return this.mode === "grid" && this.showScroll;
16528
+ }
16529
+ showScrollbar() {
16530
+ return this.mode === "continuity" && this.showScroll;
16531
+ }
16532
+ getClassMap() {
16533
+ return {
16534
+ [this.mode]: true,
16535
+ "show-scrollbar": this.showScrollbar(),
16536
+ };
16537
+ }
16538
+ renderRecommendation(recommendation, rank) {
16539
+ return (h("vviinn-product-card", { part: "product-part", productId: recommendation.productId, productTitle: recommendation.title, deeplink: recommendation.deeplink, image: recommendation.image.thumbnail, brand: recommendation.brand, imageWidth: this.imageWidth, imageRatio: 1, price: recommendation.price.actual, salePrice: recommendation.price.sale, responsive: this.mode === "grid", dimmedBackground: this.mode === "continuity", index: rank }));
16540
+ }
16541
+ renderRecommendationGroup(elements) {
16542
+ return h("div", { class: CONTENT_GROUP_CSS_CLASS }, elements);
16543
+ }
16544
+ renderRecommendationGroups(elements) {
16545
+ return elements.map((el) => this.renderRecommendationGroup(el));
16546
+ }
16547
+ renderRecommendations() {
16548
+ return this.mode === "grid"
16549
+ ? this.renderGrid()
16550
+ : this.renderRecommendationsElements();
16551
+ }
16552
+ renderRecommendationsElements() {
16553
+ return this.recommendations.map((r, i) => this.renderRecommendation(r, i));
16554
+ }
16555
+ renderGrid() {
16556
+ const recommendations = this.renderRecommendationsElements();
16557
+ const grouppedContent = _Array.chunksOf(this.getColumnsNumber())(recommendations);
16558
+ return this.renderRecommendationGroups(grouppedContent);
16559
+ }
16560
+ renderBullets() {
16561
+ const numberOfBullets = Math.ceil(this.recommendations.length / this.getColumnsNumber());
16562
+ const bulletsArray = Array.from(Array(numberOfBullets).keys());
16563
+ return bulletsArray.map((index) => (h("div", { class: {
16564
+ bullet: true,
16565
+ active: this.activeContentGroup === index,
16566
+ }, onClick: () => this.scroll(index) })));
16567
+ }
16568
+ render() {
16569
+ return (h(Host, { class: this.getClassMap() }, h("div", { class: Object.assign({ body: true }, this.getClassMap()) }, h("button", { class: "prev", onClick: () => this.showPrev(), part: "carousel-button" }, h(ChevronIcon, null)), h("div", { class: this.getContentClassMap(), onScroll: () => this.processScrollbarWidth() }, this.renderRecommendations()), h("button", { class: "next", onClick: () => this.showNext(), part: "carousel-button" }, h(ChevronIcon, null))), this.showBullets() ? (h("div", { class: "bullets" }, this.renderBullets())) : ("")));
16570
+ }
16571
+ get el() { return getElement(this); }
16572
+ };
16573
+ VviinnCarousel.style = vviinnCarouselCss;
16137
16574
 
16138
- return getRandomValues(rnds8);
16139
- }
16575
+ 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}";
16140
16576
 
16141
- const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
16577
+ let VviinnDetectedObject = class {
16578
+ constructor(hostRef) {
16579
+ registerInstance(this, hostRef);
16580
+ this.detectedObjectClicked = createEvent(this, "detectedObjectClicked", 7);
16581
+ this.position = ["0", "0"];
16582
+ }
16583
+ getObjectPosition() {
16584
+ return _function.pipe(imageSearchState.imageBounds, Option.map((bounds) => {
16585
+ const objectRectangle = fromAlt(foldValueObject(this.detectedObject).rectangle);
16586
+ const { x, y } = _function.pipe(objectRectangle, scaleWithSized(bounds), center);
16587
+ return [`${x}px`, `${y}px`];
16588
+ }), Option.getOrElse(() => ["0", "0"]));
16589
+ }
16590
+ selectDetectedObject() {
16591
+ _function.pipe(imageSearchState.imageBounds, Option.map((bounds) => {
16592
+ const rectangle = foldValueObject(this.detectedObject).rectangle;
16593
+ const transformedRect = fromAlt(rectangle);
16594
+ const scaledRect = scaleWithSized(bounds)(transformedRect);
16595
+ imageSearchState.detectedObject = this.detectedObject;
16596
+ imageSearchState.searchArea = Option.some(scaledRect);
16597
+ }));
16598
+ makeRectangularSearchRequest();
16599
+ this.detectedObjectClicked.emit();
16600
+ }
16601
+ isActive() {
16602
+ if (!this.detectedObject)
16603
+ return false;
16604
+ if (!imageSearchState.detectedObject)
16605
+ return false;
16606
+ const thisObject = foldValueObject(this.detectedObject);
16607
+ const savedObject = foldValueObject(imageSearchState.detectedObject);
16608
+ return detectedObjectEq.equals(thisObject, savedObject);
16609
+ }
16610
+ render() {
16611
+ return (h(Host, { class: {
16612
+ active: this.isActive(),
16613
+ }, onClick: () => this.selectDetectedObject(), style: {
16614
+ "--x-position": this.getObjectPosition()[0],
16615
+ "--y-position": this.getObjectPosition()[1],
16616
+ } }));
16617
+ }
16618
+ };
16619
+ VviinnDetectedObject.style = vviinnDetectedObjectCss;
16142
16620
 
16143
- function validate(uuid) {
16144
- return typeof uuid === 'string' && REGEX.test(uuid);
16145
- }
16621
+ const vviinnEmptyResultsCss = ":host{display:grid}vviinn-error{justify-items:center}";
16146
16622
 
16147
- /**
16148
- * Convert array of 16 byte values to UUID string format of the form:
16149
- * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
16150
- */
16623
+ let VviinnEmptyResults = class {
16624
+ constructor(hostRef) {
16625
+ registerInstance(this, hostRef);
16626
+ this.actionClick = createEvent(this, "actionClick", 7);
16627
+ }
16628
+ render() {
16629
+ return (h(Host, null, h("vviinn-error", null, h("svg", { slot: "icon", class: "icon", width: "32", height: "32", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, 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" }), 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" })), h("h4", { slot: "title" }, "Leider nichts gefunden"), h("span", { slot: "text" }, "Leider konnten wir keine passenden Produkte finden. Bitte versuche es mit einem anderen Bildausschnitt noch einmal."))));
16630
+ }
16631
+ };
16632
+ VviinnEmptyResults.style = vviinnEmptyResultsCss;
16151
16633
 
16152
- var byteToHex = [];
16634
+ 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}";
16153
16635
 
16154
- for (var i = 0; i < 256; ++i) {
16155
- byteToHex.push((i + 0x100).toString(16).substr(1));
16156
- }
16636
+ let VviinnError = class {
16637
+ constructor(hostRef) {
16638
+ registerInstance(this, hostRef);
16639
+ }
16640
+ render() {
16641
+ return (h(Host, null, h("slot", { name: "icon" }), h("slot", { name: "title" }), h("slot", { name: "text" }), h("slot", { name: "action" })));
16642
+ }
16643
+ };
16644
+ VviinnError.style = vviinnErrorCss;
16157
16645
 
16158
- function stringify$1(arr) {
16159
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
16160
- // Note: Be careful editing this code! It's been tuned for performance
16161
- // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
16162
- var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
16163
- // of the following:
16164
- // - One or more input array values don't map to a hex octet (leading to
16165
- // "undefined" in the uuid)
16166
- // - Invalid input values for the RFC `version` or `variant` fields
16646
+ const vviinnExampleImageCss = ":host{display:block;margin-bottom:8px;position:relative}img{width:100%;height:auto;cursor:pointer}.image-preloader{background:rgba(0, 0, 0, 0.25);border-radius:4px;bottom:12px;display:none;padding:4px 6px;pointer-events:none;position:absolute;right:12px;z-index:4}vviinn-preloader{--preloader-size:12px}@media (max-width: 640px){.image-preloader{display:block}}";
16167
16647
 
16168
- if (!validate(uuid)) {
16169
- throw TypeError('Stringified UUID is invalid');
16648
+ let VviinnExampleImage = class {
16649
+ constructor(hostRef) {
16650
+ registerInstance(this, hostRef);
16651
+ this.exampleImageSelected = createEvent(this, "exampleImageSelected", 7);
16652
+ this.exampleImageError = createEvent(this, "exampleImageError", 7);
16653
+ this.src = "";
16654
+ this.width = 0;
16655
+ this.height = 0;
16656
+ this.selected = false;
16170
16657
  }
16658
+ async selectImage(_event) {
16659
+ this.selected = true;
16660
+ const file = await toFile(this.src);
16661
+ const processResult = await processSelectedFile(file);
16662
+ _function.pipe(processResult, Either.match(() => this.exampleImageError.emit(), () => this.exampleImageSelected.emit()));
16663
+ this.selected = false;
16664
+ }
16665
+ showPreloader() {
16666
+ return ((imageSearchState.objectDetectionInProgress ||
16667
+ imageSearchState.loading) &&
16668
+ this.selected);
16669
+ }
16670
+ render() {
16671
+ return (h(Host, null, this.showPreloader() ? (h("div", { class: "image-preloader" }, h("vviinn-preloader", null))) : null, h("img", { onClick: (ev) => this.selectImage(ev), src: this.src, width: this.width, height: this.height })));
16672
+ }
16673
+ };
16674
+ VviinnExampleImage.style = vviinnExampleImageCss;
16675
+
16676
+ const defaultSlotsNames = [
16677
+ "vviinn-onboarding-title",
16678
+ "vviinn-onboarding-card-1-icon",
16679
+ "vviinn-onboarding-card-1-text",
16680
+ "vviinn-onboarding-card-2-icon",
16681
+ "vviinn-onboarding-card-2-text",
16682
+ "vviinn-onboarding-card-3-icon",
16683
+ "vviinn-onboarding-card-3-text",
16684
+ "vviinn-example-images-title",
16685
+ "vviinn-example-images-1",
16686
+ "vviinn-example-images-2",
16687
+ "vviinn-example-images-3",
16688
+ "vviinn-example-images-4",
16689
+ "vviinn-teaser-text",
16690
+ "vviinn-image-upload-button-text",
16691
+ "vviinn-privacy-badge-text"
16692
+ ];
16693
+ const renderNamedSlot = (name) => h("slot", { name: name });
16694
+ const SlotSkeleton = () => defaultSlotsNames.map(renderNamedSlot);
16695
+ const getSlots = (element) => Array.from(element.shadowRoot.querySelectorAll("slot"));
16696
+ const getNameAttribute = (element) => element.getAttribute("name");
16697
+ const getSlotAttribute = (element) => element.getAttribute("slot");
16698
+ const elementContainSlot = (slot) => (container) => {
16699
+ const name1 = getNameAttribute(slot);
16700
+ const name2 = getSlotAttribute(container);
16701
+ return name1 === name2;
16702
+ };
16703
+ const getContentToReplace = (targets) => (acc, content) => {
16704
+ const replaceCandidate = targets.find(elementContainSlot(content));
16705
+ if (replaceCandidate) {
16706
+ acc.set(content, replaceCandidate);
16707
+ }
16708
+ return acc;
16709
+ };
16710
+ const replaceSlotContent = (content, target) => {
16711
+ target.innerHTML = content.outerHTML;
16712
+ };
16713
+ const slotChangeListener = (component, element) => {
16714
+ component.connectedCallback = function () {
16715
+ document.addEventListener("globalSlotsChanged", ({ detail }) => {
16716
+ const slotsToReplace = getSlots(element).reduce(getContentToReplace(detail), new Map());
16717
+ slotsToReplace.forEach(replaceSlotContent);
16718
+ }, true);
16719
+ };
16720
+ component.connectedCallback.call(component);
16721
+ };
16171
16722
 
16172
- return uuid;
16173
- }
16723
+ 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}";
16174
16724
 
16175
- function v4(options, buf, offset) {
16176
- options = options || {};
16177
- var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
16725
+ let VviinnExampleImages = class {
16726
+ constructor(hostRef) {
16727
+ registerInstance(this, hostRef);
16728
+ this.imageSelected = createEvent(this, "imageSelected", 7);
16729
+ this.imageSelectedError = createEvent(this, "imageSelectedError", 7);
16730
+ }
16731
+ handleImageSelection() {
16732
+ this.imageSelected.emit();
16733
+ }
16734
+ handleImageSelectionError() {
16735
+ this.imageSelectedError.emit();
16736
+ }
16737
+ componentWillLoad() {
16738
+ slotChangeListener(this, this.el);
16739
+ }
16740
+ render() {
16741
+ return (h(Host, null, h("slot", { name: "vviinn-example-images-title" }, h("h3", null, "Mit den Beispielbildern die Suche direkt ausprobieren")), h("div", { class: "images" }, h("slot", { name: "vviinn-example-images-1" }, h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDEtTC5qcGc=" })), h("slot", { name: "vviinn-example-images-2" }, h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDItTS5qcGc=" })), h("slot", { name: "vviinn-example-images-3" }, h("vviinn-example-image", { width: 280, height: 480, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDMtTS5qcGc=" })), h("slot", { name: "vviinn-example-images-4" }, h("vviinn-example-image", { width: 480, height: 640, src: "https://cdn.vviinn.com/0/fit/480/0/ce/0/Z3M6Ly9haWFhcy1pbWdwcm94eS9leGFtcGxlcy9pbWctaW5zcGlyYXRpb24tMDQtTC5qcGc=" })))));
16742
+ }
16743
+ get el() { return getElement(this); }
16744
+ };
16745
+ VviinnExampleImages.style = vviinnExampleImagesCss;
16178
16746
 
16179
- rnds[6] = rnds[6] & 0x0f | 0x40;
16180
- rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
16747
+ const vviinnImageSelectorCss = ":host{display:block}:host(::hover){background:whitesmoke}.visually-hidden{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}label{cursor:pointer;display:grid;padding:0.5rem;transition:background 0.1s ease-in-out}";
16181
16748
 
16182
- if (buf) {
16183
- offset = offset || 0;
16749
+ let VviinnImageSelector = class {
16750
+ constructor(hostRef) {
16751
+ registerInstance(this, hostRef);
16752
+ this.imageSelected = createEvent(this, "imageSelected", 7);
16753
+ this.imageSelectedError = createEvent(this, "imageSelectedError", 7);
16754
+ }
16755
+ async handleInputChange(event) {
16756
+ const input = event.target;
16757
+ const processingResult = await processSelectedFile(input.files[0]);
16758
+ _function.pipe(processingResult, match$1(() => this.imageSelectedError.emit(), () => this.imageSelected.emit()));
16759
+ input.value = null;
16760
+ }
16761
+ isLoading() {
16762
+ return (imageSearchState.loading || imageSearchState.objectDetectionInProgress);
16763
+ }
16764
+ render() {
16765
+ return (h(Host, { exportparts: "button" }, this.isLoading() ? h("vviinn-preloader", null) : null, this.isLoading() ? null : (h("label", { htmlFor: "fileInput", part: "button" }, h("slot", { name: "upload-button-text" }, "Upload image"))), h("input", { id: "fileInput", class: "visually-hidden", type: "file", accept: "image/*", onChange: (event) => this.handleInputChange(event) })));
16766
+ }
16767
+ };
16768
+ VviinnImageSelector.style = vviinnImageSelectorCss;
16184
16769
 
16185
- for (var i = 0; i < 16; ++i) {
16186
- buf[offset + i] = rnds[i];
16187
- }
16770
+ const vviinnImageViewCss = ":host{display:grid;position:relative;justify-self:center}img{box-sizing:border-box;filter:brightness(60%);position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:-1}.image-preloader{background:rgba(0, 0, 0, 0.25);border-radius:4px;bottom:18px;padding:4px 6px;pointer-events:none;position:absolute;right:18px;z-index:4}vviinn-preloader{--preloader-size:12px}";
16188
16771
 
16189
- return buf;
16772
+ const getImageSizes = (i) => {
16773
+ const dimensions = dimensionsFromImage(i);
16774
+ const resize = scaleByLargestSide(288);
16775
+ const newDimensions = resize(dimensions);
16776
+ const sizes = newDimensions.map(d => d.size);
16777
+ return [sizes[0], sizes[1]];
16778
+ };
16779
+ let VviinnImageView = class {
16780
+ constructor(hostRef) {
16781
+ registerInstance(this, hostRef);
16782
+ }
16783
+ handleInitialImageLoad(ev) {
16784
+ const target = ev.target;
16785
+ const imageBounds = fromImage(target);
16786
+ const padding = 12;
16787
+ const { x, y } = move(imageBounds, { x: padding, y: padding });
16788
+ const searchArea = {
16789
+ x,
16790
+ y,
16791
+ width: imageBounds.width - padding * 2,
16792
+ height: imageBounds.height - padding * 2,
16793
+ };
16794
+ imageSearchState.imageBounds = Option.some(imageBounds);
16795
+ imageSearchState.searchArea = Option.some(searchArea);
16796
+ }
16797
+ renderDetectedObject(object) {
16798
+ return h("vviinn-detected-object", { detectedObject: object });
16799
+ }
16800
+ renderImage() {
16801
+ return _function.pipe(sequenceToOption(imageSearchState.imageUrl, imageSearchState.image), Option.map(([url, refImage]) => {
16802
+ const [width, height] = getImageSizes(refImage);
16803
+ const image = (h("img", { decoding: "async", width: width, height: height, src: url, onLoad: (el) => this.handleInitialImageLoad(el), draggable: false }));
16804
+ return image;
16805
+ }), Option.getOrElse(() => null));
16806
+ }
16807
+ renderCropper() {
16808
+ return _function.pipe(imageSearchState.imageUrl, Option.map(() => h("image-cropper", null)), Option.getOrElse(() => null));
16190
16809
  }
16810
+ render() {
16811
+ return (h(Host, null, imageSearchState.loading ||
16812
+ imageSearchState.objectDetectionInProgress ? (h("div", { class: "image-preloader" }, h("vviinn-preloader", null))) : null, h("highlight-box", null), this.renderImage(), this.renderCropper(), imageSearchState.detectedObjects.map((o) => this.renderDetectedObject(o))));
16813
+ }
16814
+ };
16815
+ VviinnImageView.style = vviinnImageViewCss;
16191
16816
 
16192
- return stringify$1(rnds);
16193
- }
16817
+ const vviinnModalCss = ":host{background:white;border-radius:4px;box-sizing:border-box;display:grid;grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto;max-width:960px}@media (max-width: 415px){:host{-webkit-animation-name:fade-in;animation-name:fade-in;-webkit-animation-duration:0.5s;animation-duration:0.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}:host(.closed){-webkit-animation-name:fade-out;animation-name:fade-out;-webkit-animation-fill-mode:none;animation-fill-mode:none}.body{overflow-y:auto}}@media (max-width: 640px) and (min-width: 415px){:host{max-width:80%}}.head{align-items:center;border-bottom:1px solid #F4F4F4;display:grid;grid-gap:16px;grid-template-columns:-webkit-min-content auto -webkit-min-content;grid-template-columns:min-content auto min-content;justify-items:center;padding:16px}.title{font-weight:600;font-size:18px;line-height:24px}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:grid;padding:unset}@-webkit-keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes fade-in{from{transform:translateY(100%)}to{transform:translateY(0)}}@-webkit-keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes fade-out{from{transform:translateY(0)}to{transform:translateY(100%)}}";
16194
16818
 
16195
- /**
16196
- * Check if we're required to add a port number.
16197
- *
16198
- * @see https://url.spec.whatwg.org/#default-port
16199
- * @param {Number|String} port Port number we need to check
16200
- * @param {String} protocol Protocol we need to check against.
16201
- * @returns {Boolean} Is it a default port for the given protocol
16202
- * @api private
16203
- */
16204
- var requiresPort = function required(port, protocol) {
16205
- protocol = protocol.split(':')[0];
16206
- port = +port;
16819
+ let VviinnModal = class {
16820
+ constructor(hostRef) {
16821
+ registerInstance(this, hostRef);
16822
+ this.modalClosed = createEvent(this, "modalClosed", 7);
16823
+ this.secondaryActionClicked = createEvent(this, "secondaryActionClicked", 7);
16824
+ this.active = false;
16825
+ this.slider = false;
16826
+ }
16827
+ close() {
16828
+ this.active = false;
16829
+ setTimeout(() => {
16830
+ this.modalClosed.emit();
16831
+ }, this.slider ? 500 : 0);
16832
+ }
16833
+ handleAnimationEnd(ev) {
16834
+ if (ev.animationName !== "fade-in")
16835
+ return;
16836
+ this.slider = true;
16837
+ }
16838
+ render() {
16839
+ return (h(Host, { exportparts: "secondary-action, title, close-button", class: { closed: !this.active }, onAnimationEnd: (ev) => this.handleAnimationEnd(ev) }, h("div", { class: "head" }, h("button", { part: "secondary-action", onClick: () => this.secondaryActionClicked.emit() }, h("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M20.25 12H3.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { d: "M10.5 5.25L3.75 12L10.5 18.75", stroke: "#161616", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }))), h("div", { class: "title", part: "title" }, "Bildsuche"), h("button", { onClick: () => this.close(), class: "close-button", part: "close-button" }, h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, 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" })))), h("div", { class: "body" }, h("slot", null))));
16840
+ }
16841
+ };
16842
+ VviinnModal.style = vviinnModalCss;
16207
16843
 
16208
- if (!port) return false;
16844
+ 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))}";
16209
16845
 
16210
- switch (protocol) {
16211
- case 'http':
16212
- case 'ws':
16213
- return port !== 80;
16846
+ let VviinnOnboarding = class {
16847
+ constructor(hostRef) {
16848
+ registerInstance(this, hostRef);
16849
+ }
16850
+ componentWillLoad() {
16851
+ slotChangeListener(this, this.el);
16852
+ }
16853
+ render() {
16854
+ return (h(Host, null, h("slot", { name: "vviinn-onboarding-title" }, h("h3", null, "So funktioniert es")), h("vviinn-slider", { showArrows: true }, h("vviinn-slide", null, h("vviinn-onboarding-card-1", null)), h("vviinn-slide", null, h("vviinn-onboarding-card-2", null)), h("vviinn-slide", null, h("vviinn-onboarding-card-3", null)))));
16855
+ }
16856
+ get el() { return getElement(this); }
16857
+ };
16858
+ VviinnOnboarding.style = vviinnOnboardingCss;
16214
16859
 
16215
- case 'https':
16216
- case 'wss':
16217
- return port !== 443;
16860
+ 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}";
16218
16861
 
16219
- case 'ftp':
16220
- return port !== 21;
16862
+ let VviinnOnboardingCard1 = class {
16863
+ constructor(hostRef) {
16864
+ registerInstance(this, hostRef);
16865
+ }
16866
+ componentWillLoad() {
16867
+ slotChangeListener(this, this.el);
16868
+ }
16869
+ render() {
16870
+ return (h(Host, null, h("slot", { name: "onboarding-card-1-icon" }, h(OnboardingCard1Icon, null)), h("slot", { name: "onboarding-card-1-text" }, h("div", { class: "text" }, h("h4", null, "Starte die Bildsuche"), h("p", null, "Lade ein Bild aus Deiner Galerie hoch oder fotografiere ein Produkt mit Deiner Kamera.")))));
16871
+ }
16872
+ get el() { return getElement(this); }
16873
+ };
16874
+ VviinnOnboardingCard1.style = onboardingCardCss$2;
16221
16875
 
16222
- case 'gopher':
16223
- return port !== 70;
16876
+ 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}";
16224
16877
 
16225
- case 'file':
16226
- return false;
16878
+ let VviinnOnboardingCard2 = class {
16879
+ constructor(hostRef) {
16880
+ registerInstance(this, hostRef);
16881
+ }
16882
+ componentWillLoad() {
16883
+ slotChangeListener(this, this.el);
16227
16884
  }
16885
+ render() {
16886
+ return (h(Host, null, h("slot", { name: "onboarding-card-2-icon" }, h(OnboardingCard2Icon, null)), h("slot", { name: "onboarding-card-2-text" }, h("div", { class: "text" }, h("h4", null, "Verfeiner deine Suche"), h("p", null, "Du kannst den Bildrahmen selber festlegen und so die Produkte genau ausw\u00E4hlen.")))));
16887
+ }
16888
+ get el() { return getElement(this); }
16889
+ };
16890
+ VviinnOnboardingCard2.style = onboardingCardCss$1;
16228
16891
 
16229
- return port !== 0;
16892
+ 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}";
16893
+
16894
+ let VviinnOnboardingCard3 = class {
16895
+ constructor(hostRef) {
16896
+ registerInstance(this, hostRef);
16897
+ }
16898
+ componentWillLoad() {
16899
+ slotChangeListener(this, this.el);
16900
+ }
16901
+ render() {
16902
+ return (h(Host, null, h("slot", { name: "onboarding-card-3-icon" }, h(OnboardingCard3Icon, null)), h("slot", { name: "onboarding-card-3-text" }, h("div", { class: "text" }, h("h4", null, "Ohne Hintergrund"), h("p", null, "Die besten Ergebnisse erh\u00E4ltst Du, wenn das gesuchte Objekt mit einfarbigem und hellem Hintergrund zu sehen ist.")))));
16903
+ }
16904
+ get el() { return getElement(this); }
16230
16905
  };
16906
+ VviinnOnboardingCard3.style = onboardingCardCss;
16231
16907
 
16232
- var has = Object.prototype.hasOwnProperty
16233
- , undef;
16908
+ const vviinnOverlayCss = ":host{-webkit-animation:fade-in 0.5s ease-in-out;animation:fade-in 0.5s ease-in-out;background:rgba(0, 0, 0, 0.5);display:block;height:100vh;left:0;overflow:hidden;position:fixed;top:0;width:100vw;z-index:9999}@-webkit-keyframes fade-in{from{opacity:0.1}to{opacity:1}}@keyframes fade-in{from{opacity:0.1}to{opacity:1}}";
16234
16909
 
16235
- /**
16236
- * Decode a URI encoded string.
16237
- *
16910
+ let VviinnOverlay = class {
16911
+ constructor(hostRef) {
16912
+ registerInstance(this, hostRef);
16913
+ }
16914
+ render() {
16915
+ return (h(Host, null, h("slot", null)));
16916
+ }
16917
+ };
16918
+ VviinnOverlay.style = vviinnOverlayCss;
16919
+
16920
+ const vviinnOverlayedModalCss = ":host{display:none}:host(.active){display:block}vviinn-overlay{align-items:center;display:grid;justify-items:center}@media (max-width: 415px){vviinn-modal{border-radius:4px 4px 0 0;height:100vh;margin-top:32px;transform:translateY(100%);width:100vw}vviinn-overlay{align-items:end;display:grid;justify-items:center}}";
16921
+
16922
+ let VviinnOverlayedModal = class {
16923
+ constructor(hostRef) {
16924
+ registerInstance(this, hostRef);
16925
+ this.secondaryActionClicked = createEvent(this, "secondaryActionClicked", 7);
16926
+ this.modalClosed = createEvent(this, "modalClosed", 7);
16927
+ this.active = false;
16928
+ }
16929
+ render() {
16930
+ return (h(Host, { class: { active: this.active } }, h("vviinn-overlay", null, h("vviinn-modal", { onSecondaryActionClicked: () => this.secondaryActionClicked.emit(), active: this.active }, h("slot", null, "CONTENT")))));
16931
+ }
16932
+ };
16933
+ VviinnOverlayedModal.style = vviinnOverlayedModalCss;
16934
+
16935
+ const vviinnPreloaderCss = ":host{--preloader-size:24px;--preloader-width:calc(var(--preloader-size) / 6);transform-origin:center;-webkit-animation:rotate 3s linear infinite;animation:rotate 3s linear infinite;border:var(--preloader-width) solid white;border-radius:50%;border-top-color:transparent;display:none;outline:0;width:var(--preloader-size);height:var(--preloader-size);box-sizing:border-box}:host(.active){display:flex}@-webkit-keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}@keyframes rotate{from{transform:rotate(-360deg)}to{transform:rotate(360deg)}}";
16936
+
16937
+ let VviinnPreloader = class {
16938
+ constructor(hostRef) {
16939
+ registerInstance(this, hostRef);
16940
+ }
16941
+ isActive() {
16942
+ return (imageSearchState.loading || imageSearchState.objectDetectionInProgress);
16943
+ }
16944
+ render() {
16945
+ return (h(Host, { class: {
16946
+ active: this.isActive(),
16947
+ } }));
16948
+ }
16949
+ };
16950
+ VviinnPreloader.style = vviinnPreloaderCss;
16951
+
16952
+ const vviinnPrivacyBadgeCss = ":host{display:block;background:#F4F4F4;padding:17px}.content{display:grid;grid-template-columns:-webkit-min-content auto;grid-template-columns:min-content auto;grid-gap:9px}.content p{color:#525252;font-size:12px;line-height:16px;margin:unset}";
16953
+
16954
+ let VviinnPrivacyBadge = class {
16955
+ constructor(hostRef) {
16956
+ registerInstance(this, hostRef);
16957
+ }
16958
+ componentWillLoad() {
16959
+ slotChangeListener(this, this.el);
16960
+ }
16961
+ render() {
16962
+ return (h(Host, null, h("slot", null, h("div", { class: "content" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none" }, h("defs", null), h("path", { fill: "#525252", d: "M8.5 11V7h-2v1h1v3H6v1h4v-1H8.5zM8 4a.75.75 0 100 1.5A.75.75 0 008 4z" }), h("path", { fill: "#525252", d: "M8 15A7 7 0 118 1a7 7 0 010 14zM8 2a6 6 0 100 12A6 6 0 008 2z" })), h("slot", { name: "vviinn-privacy-badge-text" }, h("p", null, "Wir gehen sorgf\u00E4ltig mit Deinen Daten um. Deine Bilder werden nur zum Zweck der Bildsuche gespeichert."))))));
16963
+ }
16964
+ get el() { return getElement(this); }
16965
+ };
16966
+ VviinnPrivacyBadge.style = vviinnPrivacyBadgeCss;
16967
+
16968
+ class GtagAnalytics {
16969
+ sendImpression(product) {
16970
+ var _a, _b, _c;
16971
+ gtag('event', 'view_item_list', {
16972
+ items: [
16973
+ {
16974
+ id: product.productId,
16975
+ name: product.title,
16976
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
16977
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
16978
+ list_name: 'VI VPR View',
16979
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
16980
+ }
16981
+ ]
16982
+ });
16983
+ return undefined;
16984
+ }
16985
+ sendClick(product) {
16986
+ var _a, _b, _c;
16987
+ gtag('event', 'select_content', {
16988
+ content_type: 'product',
16989
+ items: [
16990
+ {
16991
+ id: product.productId,
16992
+ name: product.title,
16993
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
16994
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
16995
+ list_name: 'VI VPR View',
16996
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
16997
+ }
16998
+ ]
16999
+ });
17000
+ return undefined;
17001
+ }
17002
+ }
17003
+
17004
+ class GAnalytics {
17005
+ constructor() {
17006
+ ga('require', 'ec');
17007
+ }
17008
+ convertProduct(product) {
17009
+ var _a, _b, _c;
17010
+ return {
17011
+ id: product.productId,
17012
+ name: product.title,
17013
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
17014
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
17015
+ list: 'VI VPR View',
17016
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
17017
+ };
17018
+ }
17019
+ sendImpression(product) {
17020
+ ga('ec:addImpression', this.convertProduct(product));
17021
+ return undefined;
17022
+ }
17023
+ sendClick(product) {
17024
+ var _a, _b, _c;
17025
+ ga('ec:addProduct', {
17026
+ id: product.productId,
17027
+ name: product.title,
17028
+ brand: (_a = product.brand) !== null && _a !== void 0 ? _a : '',
17029
+ category: (_b = product.productType) !== null && _b !== void 0 ? _b : '',
17030
+ price: Math.min(...[product.price.actual, (_c = product.price.sale) !== null && _c !== void 0 ? _c : Infinity])
17031
+ });
17032
+ ga('ec:setAction', 'click', { list: 'VI VPR View' });
17033
+ return undefined;
17034
+ }
17035
+ }
17036
+
17037
+ const getGtagAnalytics = () => _function.pipe(Option.fromNullable(window.gtag), Option.map(() => new GtagAnalytics()));
17038
+ const getCommonAnalytics = () => _function.pipe(Option.fromNullable(window.ga), Option.map(() => new GAnalytics()));
17039
+ const analyticsMonoid = Option.getMonoid(Semigroup$1.first());
17040
+ const getAnalyticsModule = analyticsMonoid.concat(getGtagAnalytics(), getCommonAnalytics());
17041
+
17042
+ const FIT_EXPR = /fit\/\d+\//;
17043
+ const containsFit = (url) => {
17044
+ return _function.pipe(url.match(FIT_EXPR), Either.fromNullable(url), Either.map(() => url));
17045
+ };
17046
+ const processWidth = (url, size) => {
17047
+ return _function.pipe(containsFit(url), Either.map((url) => url.replace(FIT_EXPR, `fit/${size}/`)), Either.getOrElse(() => url));
17048
+ };
17049
+ const Linked = (props, child) => props.deeplink ? (h("a", { class: props.part, part: props.part, href: props.deeplink }, child)) : (child);
17050
+ const FormattedPrice = (props) => {
17051
+ var _a;
17052
+ const locale = props.locale;
17053
+ const formattedPrice = new Intl.NumberFormat(locale, {
17054
+ minimumFractionDigits: 2,
17055
+ }).format(props.price);
17056
+ const fullPrice = `${(_a = props.prefix) !== null && _a !== void 0 ? _a : ""} ${formattedPrice} ${props.currency}`;
17057
+ return (h("span", { class: "price-amount", part: "price-amount" }, fullPrice));
17058
+ };
17059
+ const Price = (props) => {
17060
+ const priceEl = (h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.price, locale: props.locale }));
17061
+ return (h("span", { class: "price-container", part: "price-container" }, props.salePrice ? ([
17062
+ h("span", { class: "price-sale", part: "price-sale" },
17063
+ h(FormattedPrice, { prefix: props.prefix, currency: props.currency, price: props.salePrice, locale: props.locale })),
17064
+ h("span", { class: "price-outdated", part: "price-outdated" }, priceEl),
17065
+ ]) : (h("span", { class: "price-regular", part: "price-regular" }, priceEl))));
17066
+ };
17067
+ const Image$1 = (props, onLoadEnd = () => undefined) => (h("picture", null,
17068
+ 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 })));
17069
+ const ResponsiveImage = (props, onLoadEnd = () => undefined) => (h("picture", null,
17070
+ h("img", { loading: props.lazy ? "lazy" : "eager", part: "image", class: "image responsive", src: processWidth(props.src, props.width), alt: props.title, onLoad: onLoadEnd })));
17071
+
17072
+ 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}";
17073
+
17074
+ let VviinnProductCard = class {
17075
+ constructor(hostRef) {
17076
+ registerInstance(this, hostRef);
17077
+ this.recommendationLoad = createEvent(this, "recommendationLoad", 7);
17078
+ this.recommendationView = createEvent(this, "recommendationView", 7);
17079
+ this.recommendationClick = createEvent(this, "recommendationClick", 7);
17080
+ this.productImageLoaded = createEvent(this, "productImageLoaded", 7);
17081
+ this.currency = undefined;
17082
+ this.imageRatio = 1;
17083
+ this.imageWidth = 200;
17084
+ this.locale = undefined;
17085
+ this.pricePrefix = undefined;
17086
+ this.responsive = false;
17087
+ this.dimmedBackground = false;
17088
+ /** @internal */
17089
+ this.index = 0;
17090
+ this.imageLoaded = false;
17091
+ this.productData = null;
17092
+ this.intersectionObserver = new IntersectionObserver(this.intersectionCallback.bind(this), { threshold: 1.0 });
17093
+ }
17094
+ connectedCallback() {
17095
+ this.productData = this.getProductData();
17096
+ }
17097
+ getProductData() {
17098
+ return {
17099
+ product: this.productId,
17100
+ rank: this.index,
17101
+ };
17102
+ }
17103
+ intersectionCallback(data) {
17104
+ if (data.some((entry) => entry.isIntersecting)) {
17105
+ _function.pipe(getAnalyticsModule, Option.map((analytics) => analytics.sendImpression(this.getProduct())));
17106
+ this.recommendationView.emit(this.productData);
17107
+ this.intersectionObserver.disconnect();
17108
+ }
17109
+ }
17110
+ componentDidLoad() {
17111
+ this.recommendationLoad.emit(this.productData);
17112
+ this.intersectionObserver.observe(this.el);
17113
+ const links = this.el.shadowRoot.querySelectorAll("a");
17114
+ links.forEach((link) => link.addEventListener("click", (event) => {
17115
+ event.preventDefault();
17116
+ event.stopImmediatePropagation();
17117
+ this.recommendationClick.emit(this.getProductData());
17118
+ _function.pipe(getAnalyticsModule, Option.match(() => null, (analytics) => analytics.sendClick(this.getProduct())));
17119
+ }));
17120
+ }
17121
+ getProduct() {
17122
+ return imageSearchState.results.find((r) => r.productId === this.productId);
17123
+ }
17124
+ renderImage() {
17125
+ const props = {
17126
+ width: this.imageWidth,
17127
+ height: this.imageWidth * this.imageRatio,
17128
+ src: this.image,
17129
+ title: this.productTitle,
17130
+ lazy: false,
17131
+ };
17132
+ return this.responsive
17133
+ ? ResponsiveImage(props, () => this.kek())
17134
+ : Image$1(props, () => this.kek());
17135
+ }
17136
+ kek() {
17137
+ this.productImageLoaded.emit(this.productId);
17138
+ }
17139
+ render() {
17140
+ var _a, _b, _c;
17141
+ return (h(Host, { part: "product-card", class: { dimmed: this.dimmedBackground }, exportparts: "brand, currency, deeplink, image, image-link, price-amount, price-container, price-outdated, price-prefix, price-regular, price-sale, title" }, h(Linked, { deeplink: this.deeplink, part: "image-link" }, this.renderImage()), h(Linked, { deeplink: this.deeplink, part: "deeplink" }, h("span", { class: "title", part: "title" }, this.productTitle)), h("span", { class: "brand", part: "brand" }, this.brand), h("span", { class: "type", part: "type" }, this.productType), h(Price, { prefix: (_a = this.pricePrefix) !== null && _a !== void 0 ? _a : state$1.pricePrefix, currency: (_b = this.currency) !== null && _b !== void 0 ? _b : state$1.currencySign, price: this.price, salePrice: this.salePrice, locale: (_c = this.locale) !== null && _c !== void 0 ? _c : state$1.locale })));
17142
+ }
17143
+ get el() { return getElement(this); }
17144
+ };
17145
+ VviinnProductCard.style = vviinnProductCardCss;
17146
+
17147
+ const vviinnServerErrorCss = ":host{display:block}";
17148
+
17149
+ let VviinnServerError = class {
17150
+ constructor(hostRef) {
17151
+ registerInstance(this, hostRef);
17152
+ this.actionClick = createEvent(this, "actionClick", 7);
17153
+ }
17154
+ render() {
17155
+ return (h(Host, null, h("vviinn-error", null, h("h4", { slot: "title" }, "Keine Verbindung"), h("span", { slot: "text" }, "Etwas hat leider nicht funktioniert. Bitte pr\u00FCfen Sie Ihre Internetverbindung und laden Sie das Bild noch einmal hoch."), h("button", { slot: "action", onClick: () => this.actionClick.emit() }, "Erneut versuchen"))));
17156
+ }
17157
+ };
17158
+ VviinnServerError.style = vviinnServerErrorCss;
17159
+
17160
+ const vviinnSlideCss = ":host{display:grid;justify-items:center}";
17161
+
17162
+ let VviinnSlide = class {
17163
+ constructor(hostRef) {
17164
+ registerInstance(this, hostRef);
17165
+ }
17166
+ render() {
17167
+ return (h(Host, null, h("slot", null)));
17168
+ }
17169
+ };
17170
+ VviinnSlide.style = vviinnSlideCss;
17171
+
17172
+ const getStyleMap = (data) => {
17173
+ return {
17174
+ "arrow-wrapper": true,
17175
+ [data.kind]: true,
17176
+ disabled: data.disabled,
17177
+ };
17178
+ };
17179
+ const Arrow = ({ kind, tabindex, disabled, onClick, onKeyDown, }) => (h("div", { class: getStyleMap({ kind, disabled }), onClick: onClick, tabindex: tabindex, onKeyDown: onKeyDown },
17180
+ h(ArrowIcon, null)));
17181
+
17182
+ const vviinnSliderCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{--num-items:0;--position:0;display:grid;grid-gap:20px;justify-items:center;position:relative}.items-wrapper{overflow:hidden;width:100%}.items{box-sizing:border-box;display:grid;grid-auto-flow:column;grid-template-columns:repeat(var(--num-items), 100%);transform:translateX(calc(-100% * var(--position)));transition:transform 0.33s ease-in-out}.controls{display:grid;grid-gap:16px;grid-template-columns:repeat(var(--num-items), -webkit-min-content);grid-template-columns:repeat(var(--num-items), min-content)}.bullet{background:#E0E0E0;border-radius:50%;box-sizing:border-box;cursor:pointer;height:8px;width:8px;transition:background 0.1s ease-in-out}.bullet:hover{background:#C6C6C6}.bullet.active{background:var(--color-primary, var(--color-primary-system))}.bullet:active{background:transparent;border:2px solid var(--color-primary, var(--color-primary-system))}.arrow-wrapper{align-items:center;background:white;border:2px solid white;bottom:0;box-sizing:border-box;display:grid;height:calc(var(--spacer) * 6);justify-items:center;margin:auto;position:absolute;top:0;transform:translate3d(0, -50%, 0);transition:border 0.25ms ease-in-out;width:calc(var(--spacer) * 4)}.arrow-wrapper:active{border-color:var(--color-primary, var(--color-primary-system));opacity:0.75}.arrow-wrapper:focus{border-color:var(--color-primary, var(--color-primary-system));opacity:0.5;outline:none}.prev{left:0}.next{right:0}.next>svg{transform:rotate3d(0, 1, 0, 180deg)}.arrow-wrapper>svg{transition:fill 0.25ms ease-in-out;fill:#A8A8A8}.arrow-wrapper:hover>svg{fill:#8D8D8D}";
17183
+
17184
+ let VviinnSlider = class {
17185
+ constructor(hostRef) {
17186
+ registerInstance(this, hostRef);
17187
+ this.elementsCount = 0;
17188
+ this.internalPosition = 0;
17189
+ this.swipeStartPosition = Option.none;
17190
+ this.showBullets = true;
17191
+ this.position = 0;
17192
+ this.showArrows = false;
17193
+ }
17194
+ positionWatchHandler(newValue) {
17195
+ this.internalPosition = newValue;
17196
+ this.el.style.setProperty("--position", `${newValue}`);
17197
+ this.setActiveCssClassToSlide(newValue);
17198
+ }
17199
+ connectedCallback() {
17200
+ this.handleDomContentChanges();
17201
+ }
17202
+ handleDomContentChanges() {
17203
+ const items = this.el.querySelectorAll("vviinn-slide");
17204
+ this.elementsCount = items.length;
17205
+ this.el.style.setProperty("--num-items", `${this.elementsCount}`);
17206
+ this.setActiveCssClassToSlide(0);
17207
+ }
17208
+ setActiveCssClassToSlide(index) {
17209
+ const items = this.el.querySelectorAll("vviinn-slide");
17210
+ items.forEach((i) => i.classList.remove("active"));
17211
+ items[index].classList.add("active");
17212
+ }
17213
+ goToSlide(index) {
17214
+ this.internalPosition = index;
17215
+ this.el.style.setProperty("--position", `${index}`);
17216
+ this.setActiveCssClassToSlide(index);
17217
+ }
17218
+ renderBullets() {
17219
+ return this.showBullets ? (h("div", { class: "controls" }, NonEmptyArray.range(0, this.elementsCount - 1).map((i) => (h("div", { class: {
17220
+ bullet: true,
17221
+ active: i == this.internalPosition % this.elementsCount,
17222
+ }, onClick: () => this.goToSlide(i) }))))) : null;
17223
+ }
17224
+ nextSlide() {
17225
+ this.internalPosition++;
17226
+ this.renderSlidePosition();
17227
+ }
17228
+ prevSlide() {
17229
+ const nextPostion = this.internalPosition - 1;
17230
+ this.internalPosition =
17231
+ nextPostion > -1 ? nextPostion : this.elementsCount - 1;
17232
+ this.renderSlidePosition();
17233
+ }
17234
+ renderSlidePosition() {
17235
+ requestAnimationFrame(() => {
17236
+ this.el.style.setProperty("--position", `${this.internalPosition % this.elementsCount}`);
17237
+ });
17238
+ }
17239
+ handleKeyDown(event) {
17240
+ if (event.key !== "Space" && event.key !== "Enter")
17241
+ return;
17242
+ const target = event.target;
17243
+ const direction = target.className.includes("prev") ? "prev" : "next";
17244
+ switch (direction) {
17245
+ case "prev":
17246
+ this.prevSlide();
17247
+ break;
17248
+ case "next":
17249
+ this.nextSlide();
17250
+ break;
17251
+ }
17252
+ }
17253
+ handleTouchStart(event) {
17254
+ if (!this.showBullets)
17255
+ return;
17256
+ this.swipeStartPosition = _function.pipe(event.touches[0], Option.fromNullable, Option.map((t) => t.clientX));
17257
+ }
17258
+ handleTouchEnd(event) {
17259
+ if (!this.showBullets)
17260
+ return;
17261
+ const swipeEndPosition = _function.pipe(event.changedTouches[0], Option.fromNullable, Option.map((t) => t.clientX));
17262
+ _function.pipe(sequenceToOption(this.swipeStartPosition, swipeEndPosition), Option.map(([start, end]) => Ord.compare(start, end)), Option.map((swipeDirection) => {
17263
+ switch (swipeDirection) {
17264
+ case 1:
17265
+ return this.nextSlide();
17266
+ case -1:
17267
+ return this.prevSlide();
17268
+ }
17269
+ }));
17270
+ }
17271
+ render() {
17272
+ return (h(Host, null, h("div", { class: "items-wrapper" }, h("div", { class: "items", onTouchStart: (e) => this.handleTouchStart(e), onTouchEnd: (e) => this.handleTouchEnd(e) }, h("slot", null))), this.showArrows
17273
+ ? [
17274
+ h(Arrow, { kind: "prev", onClick: () => this.prevSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 1, disabled: false }),
17275
+ h(Arrow, { kind: "next", onClick: () => this.nextSlide(), onKeyDown: (ev) => this.handleKeyDown(ev), tabindex: 0, disabled: false }),
17276
+ ]
17277
+ : null, this.renderBullets()));
17278
+ }
17279
+ get el() { return getElement(this); }
17280
+ static get watchers() { return {
17281
+ "position": ["positionWatchHandler"]
17282
+ }; }
17283
+ };
17284
+ VviinnSlider.style = vviinnSliderCss;
17285
+
17286
+ 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}";
17287
+
17288
+ let VviinnTeaser = class {
17289
+ constructor(hostRef) {
17290
+ registerInstance(this, hostRef);
17291
+ }
17292
+ componentWillLoad() {
17293
+ slotChangeListener(this, this.el);
17294
+ }
17295
+ render() {
17296
+ return (h(Host, null, h("slot", null, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "64", height: "64", fill: "none" }, h("defs", null), 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" }), 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" })), h("span", { class: "vviinn-teaser-text" }, h("slot", { name: "vviinn-teaser-text" }, "Finde Produkte auf ", h("br", null), " einem Foto")))));
17297
+ }
17298
+ get el() { return getElement(this); }
17299
+ };
17300
+ VviinnTeaser.style = vviinnTeaserCss;
17301
+
17302
+ const createBearerString = (x) => `Bearer ${x}`;
17303
+ const createAuthedHeader = (x) => new Headers({
17304
+ Authorization: x,
17305
+ });
17306
+ const createFetchAuthOptions = (x) => {
17307
+ return {
17308
+ headers: x,
17309
+ };
17310
+ };
17311
+ const createBearAuthedHeader = _function.flow(createBearerString, createAuthedHeader, createFetchAuthOptions);
17312
+
17313
+ const isVPR = (c) => c._tag === "VPR";
17314
+ function fold(onVPR, onVCS) {
17315
+ return (c) => (isVPR(c) ? onVPR() : onVCS());
17316
+ }
17317
+ function fromString(s) {
17318
+ return s === "VPR" ? { _tag: "VPR" } : { _tag: "VCS" };
17319
+ }
17320
+
17321
+ const sequenceToEither = sequenceT(Apply);
17322
+ const apiGet = (path, data = {}) => pipe(sequenceToEither(getApiPath(), createInitGetRequest), fromEither, chainW(makeRequest(path, data)));
17323
+
17324
+ const getVPRRecommendations = (productId) => (campaigns) => (options) => {
17325
+ const url = _function.pipe(campaigns, map$3(encodeURIComponent), match(() => `product/${productId}/similar-products`, (encodedCampaignsIds) => `product/${productId}/similar-products?campaigns=${encodedCampaignsIds}`));
17326
+ return apiGet(url, options);
17327
+ };
17328
+
17329
+ const getVCSRecommendations = (productId) => (campaigns) => (options) => {
17330
+ const url = _function.pipe(campaigns, map$3(encodeURIComponent), match(() => `product/${productId}/cross-selling-products`, (encodedCampaignsIds) => `product/${productId}/cross-selling-products?campaigns=${encodedCampaignsIds}`));
17331
+ return apiGet(url, options);
17332
+ };
17333
+
17334
+ const getRecommendationsService = (campaignType) => _function.pipe(fromString(campaignType), fold(() => getVPRRecommendations, () => getVCSRecommendations));
17335
+
17336
+ function isFunction(value) {
17337
+ return typeof value === 'function';
17338
+ }
17339
+
17340
+ function createErrorClass(createImpl) {
17341
+ const _super = (instance) => {
17342
+ Error.call(instance);
17343
+ instance.stack = new Error().stack;
17344
+ };
17345
+ const ctorFunc = createImpl(_super);
17346
+ ctorFunc.prototype = Object.create(Error.prototype);
17347
+ ctorFunc.prototype.constructor = ctorFunc;
17348
+ return ctorFunc;
17349
+ }
17350
+
17351
+ const UnsubscriptionError = createErrorClass((_super) => function UnsubscriptionErrorImpl(errors) {
17352
+ _super(this);
17353
+ this.message = errors
17354
+ ? `${errors.length} errors occurred during unsubscription:
17355
+ ${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\n ')}`
17356
+ : '';
17357
+ this.name = 'UnsubscriptionError';
17358
+ this.errors = errors;
17359
+ });
17360
+
17361
+ function arrRemove(arr, item) {
17362
+ if (arr) {
17363
+ const index = arr.indexOf(item);
17364
+ 0 <= index && arr.splice(index, 1);
17365
+ }
17366
+ }
17367
+
17368
+ class Subscription {
17369
+ constructor(initialTeardown) {
17370
+ this.initialTeardown = initialTeardown;
17371
+ this.closed = false;
17372
+ this._parentage = null;
17373
+ this._finalizers = null;
17374
+ }
17375
+ unsubscribe() {
17376
+ let errors;
17377
+ if (!this.closed) {
17378
+ this.closed = true;
17379
+ const { _parentage } = this;
17380
+ if (_parentage) {
17381
+ this._parentage = null;
17382
+ if (Array.isArray(_parentage)) {
17383
+ for (const parent of _parentage) {
17384
+ parent.remove(this);
17385
+ }
17386
+ }
17387
+ else {
17388
+ _parentage.remove(this);
17389
+ }
17390
+ }
17391
+ const { initialTeardown: initialFinalizer } = this;
17392
+ if (isFunction(initialFinalizer)) {
17393
+ try {
17394
+ initialFinalizer();
17395
+ }
17396
+ catch (e) {
17397
+ errors = e instanceof UnsubscriptionError ? e.errors : [e];
17398
+ }
17399
+ }
17400
+ const { _finalizers } = this;
17401
+ if (_finalizers) {
17402
+ this._finalizers = null;
17403
+ for (const finalizer of _finalizers) {
17404
+ try {
17405
+ execFinalizer(finalizer);
17406
+ }
17407
+ catch (err) {
17408
+ errors = errors !== null && errors !== void 0 ? errors : [];
17409
+ if (err instanceof UnsubscriptionError) {
17410
+ errors = [...errors, ...err.errors];
17411
+ }
17412
+ else {
17413
+ errors.push(err);
17414
+ }
17415
+ }
17416
+ }
17417
+ }
17418
+ if (errors) {
17419
+ throw new UnsubscriptionError(errors);
17420
+ }
17421
+ }
17422
+ }
17423
+ add(teardown) {
17424
+ var _a;
17425
+ if (teardown && teardown !== this) {
17426
+ if (this.closed) {
17427
+ execFinalizer(teardown);
17428
+ }
17429
+ else {
17430
+ if (teardown instanceof Subscription) {
17431
+ if (teardown.closed || teardown._hasParent(this)) {
17432
+ return;
17433
+ }
17434
+ teardown._addParent(this);
17435
+ }
17436
+ (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
17437
+ }
17438
+ }
17439
+ }
17440
+ _hasParent(parent) {
17441
+ const { _parentage } = this;
17442
+ return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));
17443
+ }
17444
+ _addParent(parent) {
17445
+ const { _parentage } = this;
17446
+ this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;
17447
+ }
17448
+ _removeParent(parent) {
17449
+ const { _parentage } = this;
17450
+ if (_parentage === parent) {
17451
+ this._parentage = null;
17452
+ }
17453
+ else if (Array.isArray(_parentage)) {
17454
+ arrRemove(_parentage, parent);
17455
+ }
17456
+ }
17457
+ remove(teardown) {
17458
+ const { _finalizers } = this;
17459
+ _finalizers && arrRemove(_finalizers, teardown);
17460
+ if (teardown instanceof Subscription) {
17461
+ teardown._removeParent(this);
17462
+ }
17463
+ }
17464
+ }
17465
+ Subscription.EMPTY = (() => {
17466
+ const empty = new Subscription();
17467
+ empty.closed = true;
17468
+ return empty;
17469
+ })();
17470
+ const EMPTY_SUBSCRIPTION = Subscription.EMPTY;
17471
+ function isSubscription(value) {
17472
+ return (value instanceof Subscription ||
17473
+ (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe)));
17474
+ }
17475
+ function execFinalizer(finalizer) {
17476
+ if (isFunction(finalizer)) {
17477
+ finalizer();
17478
+ }
17479
+ else {
17480
+ finalizer.unsubscribe();
17481
+ }
17482
+ }
17483
+
17484
+ const config = {
17485
+ onUnhandledError: null,
17486
+ onStoppedNotification: null,
17487
+ Promise: undefined,
17488
+ useDeprecatedSynchronousErrorHandling: false,
17489
+ useDeprecatedNextContext: false,
17490
+ };
17491
+
17492
+ const timeoutProvider = {
17493
+ setTimeout(handler, timeout, ...args) {
17494
+ const { delegate } = timeoutProvider;
17495
+ if (delegate === null || delegate === void 0 ? void 0 : delegate.setTimeout) {
17496
+ return delegate.setTimeout(handler, timeout, ...args);
17497
+ }
17498
+ return setTimeout(handler, timeout, ...args);
17499
+ },
17500
+ clearTimeout(handle) {
17501
+ const { delegate } = timeoutProvider;
17502
+ return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearTimeout) || clearTimeout)(handle);
17503
+ },
17504
+ delegate: undefined,
17505
+ };
17506
+
17507
+ function reportUnhandledError(err) {
17508
+ timeoutProvider.setTimeout(() => {
17509
+ const { onUnhandledError } = config;
17510
+ if (onUnhandledError) {
17511
+ onUnhandledError(err);
17512
+ }
17513
+ else {
17514
+ throw err;
17515
+ }
17516
+ });
17517
+ }
17518
+
17519
+ function noop() { }
17520
+
17521
+ const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined))();
17522
+ function errorNotification(error) {
17523
+ return createNotification('E', undefined, error);
17524
+ }
17525
+ function nextNotification(value) {
17526
+ return createNotification('N', value, undefined);
17527
+ }
17528
+ function createNotification(kind, value, error) {
17529
+ return {
17530
+ kind,
17531
+ value,
17532
+ error,
17533
+ };
17534
+ }
17535
+
17536
+ function errorContext(cb) {
17537
+ {
17538
+ cb();
17539
+ }
17540
+ }
17541
+
17542
+ class Subscriber extends Subscription {
17543
+ constructor(destination) {
17544
+ super();
17545
+ this.isStopped = false;
17546
+ if (destination) {
17547
+ this.destination = destination;
17548
+ if (isSubscription(destination)) {
17549
+ destination.add(this);
17550
+ }
17551
+ }
17552
+ else {
17553
+ this.destination = EMPTY_OBSERVER;
17554
+ }
17555
+ }
17556
+ static create(next, error, complete) {
17557
+ return new SafeSubscriber(next, error, complete);
17558
+ }
17559
+ next(value) {
17560
+ if (this.isStopped) {
17561
+ handleStoppedNotification(nextNotification(value), this);
17562
+ }
17563
+ else {
17564
+ this._next(value);
17565
+ }
17566
+ }
17567
+ error(err) {
17568
+ if (this.isStopped) {
17569
+ handleStoppedNotification(errorNotification(err), this);
17570
+ }
17571
+ else {
17572
+ this.isStopped = true;
17573
+ this._error(err);
17574
+ }
17575
+ }
17576
+ complete() {
17577
+ if (this.isStopped) {
17578
+ handleStoppedNotification(COMPLETE_NOTIFICATION, this);
17579
+ }
17580
+ else {
17581
+ this.isStopped = true;
17582
+ this._complete();
17583
+ }
17584
+ }
17585
+ unsubscribe() {
17586
+ if (!this.closed) {
17587
+ this.isStopped = true;
17588
+ super.unsubscribe();
17589
+ this.destination = null;
17590
+ }
17591
+ }
17592
+ _next(value) {
17593
+ this.destination.next(value);
17594
+ }
17595
+ _error(err) {
17596
+ try {
17597
+ this.destination.error(err);
17598
+ }
17599
+ finally {
17600
+ this.unsubscribe();
17601
+ }
17602
+ }
17603
+ _complete() {
17604
+ try {
17605
+ this.destination.complete();
17606
+ }
17607
+ finally {
17608
+ this.unsubscribe();
17609
+ }
17610
+ }
17611
+ }
17612
+ const _bind = Function.prototype.bind;
17613
+ function bind(fn, thisArg) {
17614
+ return _bind.call(fn, thisArg);
17615
+ }
17616
+ class ConsumerObserver {
17617
+ constructor(partialObserver) {
17618
+ this.partialObserver = partialObserver;
17619
+ }
17620
+ next(value) {
17621
+ const { partialObserver } = this;
17622
+ if (partialObserver.next) {
17623
+ try {
17624
+ partialObserver.next(value);
17625
+ }
17626
+ catch (error) {
17627
+ handleUnhandledError(error);
17628
+ }
17629
+ }
17630
+ }
17631
+ error(err) {
17632
+ const { partialObserver } = this;
17633
+ if (partialObserver.error) {
17634
+ try {
17635
+ partialObserver.error(err);
17636
+ }
17637
+ catch (error) {
17638
+ handleUnhandledError(error);
17639
+ }
17640
+ }
17641
+ else {
17642
+ handleUnhandledError(err);
17643
+ }
17644
+ }
17645
+ complete() {
17646
+ const { partialObserver } = this;
17647
+ if (partialObserver.complete) {
17648
+ try {
17649
+ partialObserver.complete();
17650
+ }
17651
+ catch (error) {
17652
+ handleUnhandledError(error);
17653
+ }
17654
+ }
17655
+ }
17656
+ }
17657
+ class SafeSubscriber extends Subscriber {
17658
+ constructor(observerOrNext, error, complete) {
17659
+ super();
17660
+ let partialObserver;
17661
+ if (isFunction(observerOrNext) || !observerOrNext) {
17662
+ partialObserver = {
17663
+ next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined,
17664
+ error: error !== null && error !== void 0 ? error : undefined,
17665
+ complete: complete !== null && complete !== void 0 ? complete : undefined,
17666
+ };
17667
+ }
17668
+ else {
17669
+ let context;
17670
+ if (this && config.useDeprecatedNextContext) {
17671
+ context = Object.create(observerOrNext);
17672
+ context.unsubscribe = () => this.unsubscribe();
17673
+ partialObserver = {
17674
+ next: observerOrNext.next && bind(observerOrNext.next, context),
17675
+ error: observerOrNext.error && bind(observerOrNext.error, context),
17676
+ complete: observerOrNext.complete && bind(observerOrNext.complete, context),
17677
+ };
17678
+ }
17679
+ else {
17680
+ partialObserver = observerOrNext;
17681
+ }
17682
+ }
17683
+ this.destination = new ConsumerObserver(partialObserver);
17684
+ }
17685
+ }
17686
+ function handleUnhandledError(error) {
17687
+ {
17688
+ reportUnhandledError(error);
17689
+ }
17690
+ }
17691
+ function defaultErrorHandler(err) {
17692
+ throw err;
17693
+ }
17694
+ function handleStoppedNotification(notification, subscriber) {
17695
+ const { onStoppedNotification } = config;
17696
+ onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));
17697
+ }
17698
+ const EMPTY_OBSERVER = {
17699
+ closed: true,
17700
+ next: noop,
17701
+ error: defaultErrorHandler,
17702
+ complete: noop,
17703
+ };
17704
+
17705
+ const observable = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();
17706
+
17707
+ function identity(x) {
17708
+ return x;
17709
+ }
17710
+
17711
+ function pipeFromArray(fns) {
17712
+ if (fns.length === 0) {
17713
+ return identity;
17714
+ }
17715
+ if (fns.length === 1) {
17716
+ return fns[0];
17717
+ }
17718
+ return function piped(input) {
17719
+ return fns.reduce((prev, fn) => fn(prev), input);
17720
+ };
17721
+ }
17722
+
17723
+ class Observable {
17724
+ constructor(subscribe) {
17725
+ if (subscribe) {
17726
+ this._subscribe = subscribe;
17727
+ }
17728
+ }
17729
+ lift(operator) {
17730
+ const observable = new Observable();
17731
+ observable.source = this;
17732
+ observable.operator = operator;
17733
+ return observable;
17734
+ }
17735
+ subscribe(observerOrNext, error, complete) {
17736
+ const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);
17737
+ errorContext(() => {
17738
+ const { operator, source } = this;
17739
+ subscriber.add(operator
17740
+ ?
17741
+ operator.call(subscriber, source)
17742
+ : source
17743
+ ?
17744
+ this._subscribe(subscriber)
17745
+ :
17746
+ this._trySubscribe(subscriber));
17747
+ });
17748
+ return subscriber;
17749
+ }
17750
+ _trySubscribe(sink) {
17751
+ try {
17752
+ return this._subscribe(sink);
17753
+ }
17754
+ catch (err) {
17755
+ sink.error(err);
17756
+ }
17757
+ }
17758
+ forEach(next, promiseCtor) {
17759
+ promiseCtor = getPromiseCtor(promiseCtor);
17760
+ return new promiseCtor((resolve, reject) => {
17761
+ const subscriber = new SafeSubscriber({
17762
+ next: (value) => {
17763
+ try {
17764
+ next(value);
17765
+ }
17766
+ catch (err) {
17767
+ reject(err);
17768
+ subscriber.unsubscribe();
17769
+ }
17770
+ },
17771
+ error: reject,
17772
+ complete: resolve,
17773
+ });
17774
+ this.subscribe(subscriber);
17775
+ });
17776
+ }
17777
+ _subscribe(subscriber) {
17778
+ var _a;
17779
+ return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
17780
+ }
17781
+ [observable]() {
17782
+ return this;
17783
+ }
17784
+ pipe(...operations) {
17785
+ return pipeFromArray(operations)(this);
17786
+ }
17787
+ toPromise(promiseCtor) {
17788
+ promiseCtor = getPromiseCtor(promiseCtor);
17789
+ return new promiseCtor((resolve, reject) => {
17790
+ let value;
17791
+ this.subscribe((x) => (value = x), (err) => reject(err), () => resolve(value));
17792
+ });
17793
+ }
17794
+ }
17795
+ Observable.create = (subscribe) => {
17796
+ return new Observable(subscribe);
17797
+ };
17798
+ function getPromiseCtor(promiseCtor) {
17799
+ var _a;
17800
+ return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;
17801
+ }
17802
+ function isObserver(value) {
17803
+ return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);
17804
+ }
17805
+ function isSubscriber(value) {
17806
+ return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));
17807
+ }
17808
+
17809
+ const ObjectUnsubscribedError = createErrorClass((_super) => function ObjectUnsubscribedErrorImpl() {
17810
+ _super(this);
17811
+ this.name = 'ObjectUnsubscribedError';
17812
+ this.message = 'object unsubscribed';
17813
+ });
17814
+
17815
+ class Subject extends Observable {
17816
+ constructor() {
17817
+ super();
17818
+ this.closed = false;
17819
+ this.currentObservers = null;
17820
+ this.observers = [];
17821
+ this.isStopped = false;
17822
+ this.hasError = false;
17823
+ this.thrownError = null;
17824
+ }
17825
+ lift(operator) {
17826
+ const subject = new AnonymousSubject(this, this);
17827
+ subject.operator = operator;
17828
+ return subject;
17829
+ }
17830
+ _throwIfClosed() {
17831
+ if (this.closed) {
17832
+ throw new ObjectUnsubscribedError();
17833
+ }
17834
+ }
17835
+ next(value) {
17836
+ errorContext(() => {
17837
+ this._throwIfClosed();
17838
+ if (!this.isStopped) {
17839
+ if (!this.currentObservers) {
17840
+ this.currentObservers = Array.from(this.observers);
17841
+ }
17842
+ for (const observer of this.currentObservers) {
17843
+ observer.next(value);
17844
+ }
17845
+ }
17846
+ });
17847
+ }
17848
+ error(err) {
17849
+ errorContext(() => {
17850
+ this._throwIfClosed();
17851
+ if (!this.isStopped) {
17852
+ this.hasError = this.isStopped = true;
17853
+ this.thrownError = err;
17854
+ const { observers } = this;
17855
+ while (observers.length) {
17856
+ observers.shift().error(err);
17857
+ }
17858
+ }
17859
+ });
17860
+ }
17861
+ complete() {
17862
+ errorContext(() => {
17863
+ this._throwIfClosed();
17864
+ if (!this.isStopped) {
17865
+ this.isStopped = true;
17866
+ const { observers } = this;
17867
+ while (observers.length) {
17868
+ observers.shift().complete();
17869
+ }
17870
+ }
17871
+ });
17872
+ }
17873
+ unsubscribe() {
17874
+ this.isStopped = this.closed = true;
17875
+ this.observers = this.currentObservers = null;
17876
+ }
17877
+ get observed() {
17878
+ var _a;
17879
+ return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
17880
+ }
17881
+ _trySubscribe(subscriber) {
17882
+ this._throwIfClosed();
17883
+ return super._trySubscribe(subscriber);
17884
+ }
17885
+ _subscribe(subscriber) {
17886
+ this._throwIfClosed();
17887
+ this._checkFinalizedStatuses(subscriber);
17888
+ return this._innerSubscribe(subscriber);
17889
+ }
17890
+ _innerSubscribe(subscriber) {
17891
+ const { hasError, isStopped, observers } = this;
17892
+ if (hasError || isStopped) {
17893
+ return EMPTY_SUBSCRIPTION;
17894
+ }
17895
+ this.currentObservers = null;
17896
+ observers.push(subscriber);
17897
+ return new Subscription(() => {
17898
+ this.currentObservers = null;
17899
+ arrRemove(observers, subscriber);
17900
+ });
17901
+ }
17902
+ _checkFinalizedStatuses(subscriber) {
17903
+ const { hasError, thrownError, isStopped } = this;
17904
+ if (hasError) {
17905
+ subscriber.error(thrownError);
17906
+ }
17907
+ else if (isStopped) {
17908
+ subscriber.complete();
17909
+ }
17910
+ }
17911
+ asObservable() {
17912
+ const observable = new Observable();
17913
+ observable.source = this;
17914
+ return observable;
17915
+ }
17916
+ }
17917
+ Subject.create = (destination, source) => {
17918
+ return new AnonymousSubject(destination, source);
17919
+ };
17920
+ class AnonymousSubject extends Subject {
17921
+ constructor(destination, source) {
17922
+ super();
17923
+ this.destination = destination;
17924
+ this.source = source;
17925
+ }
17926
+ next(value) {
17927
+ var _a, _b;
17928
+ (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
17929
+ }
17930
+ error(err) {
17931
+ var _a, _b;
17932
+ (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
17933
+ }
17934
+ complete() {
17935
+ var _a, _b;
17936
+ (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
17937
+ }
17938
+ _subscribe(subscriber) {
17939
+ var _a, _b;
17940
+ return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;
17941
+ }
17942
+ }
17943
+
17944
+ // Unique ID creation requires a high quality random # generator. In the browser we therefore
17945
+ // require the crypto API and do not support built-in fallback to lower quality random number
17946
+ // generators (like Math.random()).
17947
+ var getRandomValues;
17948
+ var rnds8 = new Uint8Array(16);
17949
+ function rng() {
17950
+ // lazy load so that environments that need to polyfill have a chance to do so
17951
+ if (!getRandomValues) {
17952
+ // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
17953
+ // find the complete implementation of crypto (msCrypto) on IE11.
17954
+ getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
17955
+
17956
+ if (!getRandomValues) {
17957
+ throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
17958
+ }
17959
+ }
17960
+
17961
+ return getRandomValues(rnds8);
17962
+ }
17963
+
17964
+ const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
17965
+
17966
+ function validate(uuid) {
17967
+ return typeof uuid === 'string' && REGEX.test(uuid);
17968
+ }
17969
+
17970
+ /**
17971
+ * Convert array of 16 byte values to UUID string format of the form:
17972
+ * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
17973
+ */
17974
+
17975
+ var byteToHex = [];
17976
+
17977
+ for (var i = 0; i < 256; ++i) {
17978
+ byteToHex.push((i + 0x100).toString(16).substr(1));
17979
+ }
17980
+
17981
+ function stringify$1(arr) {
17982
+ var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
17983
+ // Note: Be careful editing this code! It's been tuned for performance
17984
+ // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
17985
+ var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
17986
+ // of the following:
17987
+ // - One or more input array values don't map to a hex octet (leading to
17988
+ // "undefined" in the uuid)
17989
+ // - Invalid input values for the RFC `version` or `variant` fields
17990
+
17991
+ if (!validate(uuid)) {
17992
+ throw TypeError('Stringified UUID is invalid');
17993
+ }
17994
+
17995
+ return uuid;
17996
+ }
17997
+
17998
+ function v4(options, buf, offset) {
17999
+ options = options || {};
18000
+ var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
18001
+
18002
+ rnds[6] = rnds[6] & 0x0f | 0x40;
18003
+ rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
18004
+
18005
+ if (buf) {
18006
+ offset = offset || 0;
18007
+
18008
+ for (var i = 0; i < 16; ++i) {
18009
+ buf[offset + i] = rnds[i];
18010
+ }
18011
+
18012
+ return buf;
18013
+ }
18014
+
18015
+ return stringify$1(rnds);
18016
+ }
18017
+
18018
+ /**
18019
+ * Check if we're required to add a port number.
18020
+ *
18021
+ * @see https://url.spec.whatwg.org/#default-port
18022
+ * @param {Number|String} port Port number we need to check
18023
+ * @param {String} protocol Protocol we need to check against.
18024
+ * @returns {Boolean} Is it a default port for the given protocol
18025
+ * @api private
18026
+ */
18027
+ var requiresPort = function required(port, protocol) {
18028
+ protocol = protocol.split(':')[0];
18029
+ port = +port;
18030
+
18031
+ if (!port) return false;
18032
+
18033
+ switch (protocol) {
18034
+ case 'http':
18035
+ case 'ws':
18036
+ return port !== 80;
18037
+
18038
+ case 'https':
18039
+ case 'wss':
18040
+ return port !== 443;
18041
+
18042
+ case 'ftp':
18043
+ return port !== 21;
18044
+
18045
+ case 'gopher':
18046
+ return port !== 70;
18047
+
18048
+ case 'file':
18049
+ return false;
18050
+ }
18051
+
18052
+ return port !== 0;
18053
+ };
18054
+
18055
+ var has = Object.prototype.hasOwnProperty
18056
+ , undef;
18057
+
18058
+ /**
18059
+ * Decode a URI encoded string.
18060
+ *
16238
18061
  * @param {String} input The URI encoded string.
16239
18062
  * @returns {String|Null} The decoded string.
16240
18063
  * @api private
@@ -19339,4 +21162,356 @@ const createWidgetVpsEvent = createTrackingEvent(vpsWidget);
19339
21162
  const createSearchEvent = createTrackingEvent(searchEvent);
19340
21163
  const createFilterEvent = createTrackingEvent(filterEvent);
19341
21164
 
19342
- export { createTrackingApi as A, createWidgetVpsEvent as B, isEmpty$1 as C, _Array as D, Either as E, chainW as F, makeRequest as G, fromEither as H, getApiPath as I, createInitGetRequest as J, sequenceT as K, Apply as L, map$3 as M, NonEmptyArray as N, Option as O, match as P, createProductViewVprEvent as Q, createProductClickVprEvent as R, Semigroup$1 as S, createWidgetVprEvent as T, TaskEither as U, checkEmpryString as V, _function as _, pointDiffSemigroup as a, makeRectangularSearchRequest as b, fromAlt as c, foldValueObject as d, scaleWithSized as e, fromMouseEvent as f, getCursorValue as g, center as h, imageSearchState as i, detectedObjectEq as j, toFile as k, processSelectedFile as l, move as m, match$1 as n, fromImage as o, pipe as p, dimensionsFromImage as q, scaleByLargestSide as r, sequenceToOption as s, transform as t, state$1 as u, createProductViewVpsEvent as v, createProductClickVpsEvent as w, createSearchEvent as x, createFilterEvent as y, v4 as z };
21165
+ const vviinnVprWidgetCss = ":host{display:grid;grid-gap:1rem;width:100%}:host(:not(.loaded)){position:absolute;visibility:hidden}:host(.grid) vviinn-product-card::part(image){border:1px solid #DDDDDD;width:100%}h2{margin:0}vviinn-product-card::part(price-container){align-self:flex-start;text-align:left;display:flex}.results{display:grid;grid-gap:1rem}.visually-hidden{position:absolute;top:0;left:0;z-index:-1;height:0;width:0}h2{margin:0}:host(.grid) h2{justify-content:center}:host(.grid) vviinn-product-card::part(image){min-width:100%}:host(.grid) vviinn-product-card::part(image-link){width:100%}:host(.grid) vviinn-product-card::part(title),:host(.grid) vviinn-product-card::part(brand),:host(.grid) vviinn-product-card::part(type){text-align:center}:host(.grid) vviinn-product-card::part(price-container){align-self:center}:host(.continuity) vviinn-product-card::part(title),:host(.continuity) vviinn-product-card::part(brand),:host(.continuity) vviinn-product-card::part(type),:host(.continuity) vviinn-product-card::part(deeplink){text-align:left;max-width:unset;align-self:start}";
21166
+
21167
+ let VviinnVprWidget = class {
21168
+ constructor(hostRef) {
21169
+ registerInstance(this, hostRef);
21170
+ this.recommendationsLoaded = createEvent(this, "recommendationsLoaded", 7);
21171
+ /** Title for recommendations widget */
21172
+ this.blockTitle = "Recommended products";
21173
+ /** Ratio of each recommended product image */
21174
+ this.imageRatio = 1;
21175
+ /** Width of each recommended product image */
21176
+ this.imageWidth = 300;
21177
+ /** Currency sign will shown after price */
21178
+ this.currencySign = "€";
21179
+ /** Use slider or grid view */
21180
+ this.mode = "continuity";
21181
+ /** Campaign type */
21182
+ this.campaignType = "VPR";
21183
+ /** Locale for currency formatting */
21184
+ this.locale = "de-DE";
21185
+ /** comma-separated list of campaign-ids */
21186
+ this.campaigns = "";
21187
+ /** @internal */
21188
+ this.apiPath = "https://api.vviinn.com";
21189
+ /** @internal */
21190
+ this.useCarousel = true;
21191
+ this.showScroll = true;
21192
+ this.cssUrl = null;
21193
+ this.recommendations = [];
21194
+ this.loaded = false;
21195
+ this.productImageLoadedSubject = new Subject();
21196
+ }
21197
+ handleProductIdChange() {
21198
+ this.getRecommendations();
21199
+ }
21200
+ handleCampaignTypeChange() {
21201
+ this.getRecommendations();
21202
+ }
21203
+ handleCampaignsChange() {
21204
+ this.getRecommendations();
21205
+ }
21206
+ handleApiPathChange(newPath) {
21207
+ state$1.apiPath = newPath;
21208
+ this.getRecommendations();
21209
+ }
21210
+ handleImageLoading({ detail }) {
21211
+ this.productImageLoadedSubject.next(detail);
21212
+ }
21213
+ trackRecommendationView({ detail }) {
21214
+ const recommendationViewEvent = createProductViewVprEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21215
+ this.trackingApi.trackEvent(recommendationViewEvent);
21216
+ }
21217
+ trackRecommendationClick({ detail }) {
21218
+ const recommendationClickEvent = createProductClickVprEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21219
+ this.trackingApi.trackEvent(recommendationClickEvent).finally(() => {
21220
+ const product = this.recommendations.find((r) => r.productId === detail.product);
21221
+ if (!product || !product.deeplink)
21222
+ return;
21223
+ window.location.href = product.deeplink;
21224
+ });
21225
+ }
21226
+ connectedCallback() {
21227
+ state$1.apiPath = this.apiPath;
21228
+ state$1.currencySign = this.currencySign;
21229
+ state$1.locale = this.locale;
21230
+ this.uiSessionId = v4();
21231
+ this.trackingApi = createTrackingApi(this.apiPath, this.token);
21232
+ const widgetOpenEvent = createWidgetVprEvent({
21233
+ action: "open",
21234
+ session_id: this.uiSessionId,
21235
+ });
21236
+ this.trackingApi.trackEvent(widgetOpenEvent);
21237
+ }
21238
+ disconnectedCallback() {
21239
+ const widgetCloseEvent = createWidgetVprEvent({
21240
+ action: "close",
21241
+ session_id: this.uiSessionId,
21242
+ });
21243
+ this.trackingApi.trackEvent(widgetCloseEvent);
21244
+ }
21245
+ async componentWillLoad() {
21246
+ state$1.pricePrefix = this.pricePrefix;
21247
+ state$1.currencySign = this.currencySign;
21248
+ this.getRecommendations();
21249
+ }
21250
+ async getRecommendations() {
21251
+ if (this.productId === undefined || this.token === undefined)
21252
+ return;
21253
+ const campaignType = this.campaignType.length > 0 ? this.campaignType : "VPR";
21254
+ const headers = createBearAuthedHeader(this.token);
21255
+ const request = _function.pipe(TaskEither.of(getRecommendationsService(campaignType)), TaskEither.ap(TaskEither.of(this.productId)), TaskEither.ap(TaskEither.of(checkEmpryString(this.campaigns))), TaskEither.ap(TaskEither.of(headers)), TaskEither.flatten);
21256
+ const runRequest = await request();
21257
+ _function.pipe(runRequest, Either.fold((error) => this.handleError(error), (data) => this.handleRecommendationsSucces(data)));
21258
+ }
21259
+ handleError(error) {
21260
+ console.log("ERROR:", error);
21261
+ }
21262
+ handleRecommendationsSucces(data) {
21263
+ var _a;
21264
+ this.recommendations = (_a = data === null || data === void 0 ? void 0 : data.extended) !== null && _a !== void 0 ? _a : data;
21265
+ imageSearchState.results = this.recommendations;
21266
+ this.loaded = true;
21267
+ this.productIds = this.recommendations.map((r) => r.productId);
21268
+ this.productImageLoadedSubject.subscribe((id) => {
21269
+ this.productIds = this.productIds.filter((x) => x !== id);
21270
+ if (this.productIds.length === 0) {
21271
+ this.recommendationsLoaded.emit();
21272
+ }
21273
+ });
21274
+ }
21275
+ isExternalCSS() {
21276
+ return this.cssUrl && this.cssUrl.length > 0;
21277
+ }
21278
+ renderExternalCSS() {
21279
+ return this.isExternalCSS() ? (h("link", { href: this.cssUrl, rel: "stylesheet" })) : ("");
21280
+ }
21281
+ render() {
21282
+ return (h(Host, { class: {
21283
+ loaded: this.loaded,
21284
+ empty: this.recommendations.length == 0,
21285
+ [this.mode]: true,
21286
+ }, "aria-hidden": this.loaded ? "false" : "true" }, this.renderExternalCSS(), h("style", null, state$1.fallbackStyles), h("h2", { part: "recommendations-title" }, this.blockTitle), this.useCarousel ? this.renderCarousel() : this.renderResults()));
21287
+ }
21288
+ renderRecommendation(recommendation, index) {
21289
+ return (h("vviinn-product-card", { part: "product-part", productId: recommendation.productId, productTitle: recommendation.title, deeplink: recommendation.deeplink, image: recommendation.image.thumbnail, brand: recommendation.brand, imageWidth: this.imageWidth, imageRatio: 1, price: recommendation.price.actual, salePrice: recommendation.price.sale, responsive: this.mode === "grid", dimmedBackground: this.useDimmedBackgroundInCard(), index: index }));
21290
+ }
21291
+ useDimmedBackgroundInCard() {
21292
+ return this.mode === "continuity" || !this.useCarousel;
21293
+ }
21294
+ renderResults() {
21295
+ return (h("div", { class: "recommendations-grid", part: "recommendations-grid" }, this.recommendations.map((r, i) => this.renderRecommendation(r, i))));
21296
+ }
21297
+ renderCarousel() {
21298
+ return (h("vviinn-carousel", { mode: this.mode, imageWidth: this.imageWidth, showScroll: this.showScroll, recommendations: this.recommendations }));
21299
+ }
21300
+ get el() { return getElement(this); }
21301
+ static get watchers() { return {
21302
+ "productId": ["handleProductIdChange"],
21303
+ "campaignType": ["handleCampaignTypeChange"],
21304
+ "campaigns": ["handleCampaignsChange"],
21305
+ "apiPath": ["handleApiPathChange"]
21306
+ }; }
21307
+ };
21308
+ VviinnVprWidget.style = vviinnVprWidgetCss;
21309
+
21310
+ const vviinnVpsButtonCss = ":host{cursor:pointer}";
21311
+
21312
+ let VviinnVpsButton = class {
21313
+ constructor(hostRef) {
21314
+ registerInstance(this, hostRef);
21315
+ this.globalSlotsChanged = createEvent(this, "globalSlotsChanged", 7);
21316
+ /** Currency sign will shown after price */
21317
+ this.currencySign = "€";
21318
+ /** Locale for currency formatting */
21319
+ this.locale = "de-DE";
21320
+ this.pressed = false;
21321
+ }
21322
+ handleModalClosed() {
21323
+ this.pressed = false;
21324
+ }
21325
+ componentDidLoad() {
21326
+ const slots = this.el.querySelectorAll("[slot]");
21327
+ this.globalSlotsChanged.emit(Array.from(slots));
21328
+ }
21329
+ handleKeyDown(ev) {
21330
+ if (ev.code !== "Enter" && ev.code !== "Space")
21331
+ return;
21332
+ this.pressed = true;
21333
+ }
21334
+ handleClick() {
21335
+ this.pressed = true;
21336
+ }
21337
+ render() {
21338
+ return (h(Host, { tabindex: "0", role: "button", pressed: this.pressed, onClick: () => this.handleClick(), onKeyDown: (ev) => this.handleKeyDown(ev) }, h("slot", null, h(CameraIcon, null)), h(SlotSkeleton, null), h("vviinn-vps-widget", { active: this.pressed, "currency-sign": "\u20AC", token: this.token, locale: this.locale, apiPath: this.apiPath, exportparts: "brand, currency, deeplink, image, image-link, price-amount, price-container, price-outdated, price-prefix, price-regular, price-sale, title, product-card, example-images", campaignId: this.campaignId })));
21339
+ }
21340
+ get el() { return getElement(this); }
21341
+ };
21342
+ VviinnVpsButton.style = vviinnVpsButtonCss;
21343
+
21344
+ const vviinnVpsWidgetCss = ":host{--color-primary-system:#0F62FE;--color-primary-hover-system:#014CDA;--color-icons-system:#2F8EDF;--spacer:8px}:host{display:block}.hidden{visibility:hidden;height:1px}vviinn-overlayed-modal.first-screen::part(title),vviinn-overlayed-modal.first-screen::part(secondary-action){visibility:hidden}.start-page{display:grid;grid-template-columns:repeat(2, 1fr);min-height:580px}.start-page_block{align-content:start;border-right:1px solid #F4F4F4;display:grid;padding:48px}.start-page_block.error{align-content:center}#onboarding-block{border-right:unset;box-sizing:border-box;grid-gap:24px;overflow-y:auto;position:relative;width:100%}vviinn-teaser{margin-bottom:32px;margin-top:-24px}vviinn-image-selector{align-items:center;background:var(--color-primary, var(--color-primary-system));border-color:var(--color-primary, var(--color-primary-system));border-radius:2px;color:white;display:grid;font-size:16px;font-weight:600;height:56px;justify-items:center;margin-bottom:16px;transition:background 0.1s ease-in-out}vviinn-image-selector:hover{background:var(--color-primary-hover, var(--color-primary-hover-system));border-color:var(--color-primary-hover, var(--color-primary-hover-system))}vviinn-image-selector:active{border-color:black}.upload-button-content{display:grid;align-items:center;justify-items:start;justify-content:center;grid-template-columns:-webkit-max-content auto;grid-template-columns:max-content auto;grid-gap:16px}.results-page{display:grid;grid-template-columns:336px auto;box-sizing:border-box}.results-page>*{padding:24px;box-sizing:border-box}.products{align-content:center;align-items:start;box-sizing:border-box;display:grid;grid-gap:32px 16px;grid-template-columns:repeat(auto-fill, minmax(152px, 1fr));justify-items:center;padding:24px;padding-right:0;position:absolute;width:calc(100% - 16px)}.products.hidden{display:none}vviinn-empty-results{width:280px;align-self:center;justify-self:center}.products-wrapper{display:grid;overflow-y:auto;overflow-x:hidden;padding:unset;position:relative;width:100%}.image-wrapper{border-right:1px solid #F4F4F4;display:grid;grid-template-rows:-webkit-min-content 170px;grid-template-rows:min-content 170px;grid-gap:24px;min-width:100%}.onboarding-wrapper{position:absolute;width:100%;padding:48px;box-sizing:border-box;display:grid;grid-gap:64px;padding-bottom:24px}vviinn-product-card{gap:0;width:100%}vviinn-product-card::part(image){border:1px solid #eaeaea;margin-bottom:8px}vviinn-product-card::part(price-container),vviinn-product-card::part(deeplink),vviinn-product-card::part(title){align-self:start}search-filters span{display:none}search-filters::part(filter){background:#F4F4F4;border-radius:4px;border:1px solid #F4F4F4;box-sizing:border-box;color:#161616;font-size:14px;font-weight:600;line-height:20px}search-filters::part(show-more-filters){border:1px solid #f4f4f4;border-radius:4px;box-sizing:border-box;color:#161616;font-size:14px;font-weight:600;line-height:20px;padding:6px 16px}search-filters::part(show-more-filters):hover{background:#EAEAEA}search-filters::part(filter):hover{background:#EAEAEA}search-filters::part(filter):focus{outline:none;border:1px solid var(--color-primary, var(--color-primary-system))}search-filters::part(filter active){background:rgba(15, 98, 254, 0.15);color:var(--color-primary, var(--color-primary-system))}.filters-wrapper{overflow:auto}.results-page:not(.active){display:none}.nothing-found{display:grid;grid-gap:64px;justify-self:center;padding-top:64px;padding-bottom:16px;position:absolute;width:60%}@media (max-width: 768px){.start-page_block{padding:24px}.onboarding-wrapper{padding:24px}}@media (max-width: 640px){.start-page{grid-template-rows:-webkit-min-content;grid-template-rows:min-content;grid-template-columns:unset;grid-gap:48px;padding:24px 0 48px 0}}@media (max-width: 640px) and (min-width: 415px){.onboarding-wrapper{position:unset}#onboarding-block{overflow:unset}.start-page.active{height:1px;overflow:auto}}@media (max-width: 415px){.results-page>*{box-sizing:border-box;padding:24px}vviinn-slide{padding-bottom:48px}.start-page_block:last-of-type{border-right:unset;overflow-y:unset;position:static;box-sizing:border-box;width:unset}.start-page_block{padding:0 24px}vviinn-teaser{margin-top:24px}.onboarding-wrapper{position:static;width:unset;padding:unset;box-sizing:border-box}.results-page{grid-template-columns:unset;grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto}.image{margin-bottom:8px}.image-wrapper{grid-template-rows:-webkit-min-content auto;grid-template-rows:min-content auto;width:100%}.products-wrapper{align-content:start;position:static;overflow-y:unset;width:100%;padding-top:0}.products{position:static;padding:0;width:unset;grid-gap:32px 16px;justify-content:center}.nothing-found{position:static;grid-gap:64px;padding:unset;align-content:start;width:unset}}@media (max-width: 320px){.products{grid-template-columns:unset}}vviinn-wrong-format,vviinn-server-error{width:280px;align-self:center;justify-self:center}";
21345
+
21346
+ const filterInt = (value) => /^[-+]?(\d+|Infinity)$/.test(value) ? Number(value) : NaN;
21347
+ const notEmptyString = (s) => !isEmpty$1(s);
21348
+ const notNan = (n) => !isNaN(n);
21349
+ let VviinnVpsWidget = class {
21350
+ constructor(hostRef) {
21351
+ registerInstance(this, hostRef);
21352
+ /** @internal */
21353
+ this.apiPath = "https://api.vviinn.com";
21354
+ /** When true modal window with widget will be shown */
21355
+ this.active = false;
21356
+ /** Currency sign will shown after price */
21357
+ this.currencySign = "€";
21358
+ /** Locale for currency formatting */
21359
+ this.locale = "de-DE";
21360
+ this.slidePosition = 0;
21361
+ this.width = 0;
21362
+ this.wrongImageFormat = false;
21363
+ this.imageSource = null;
21364
+ }
21365
+ activeWatcher(value) {
21366
+ if (value) {
21367
+ this.overflow = document.body.style.overflow;
21368
+ document.body.style.overflow = "hidden";
21369
+ this.trackOpenEvent();
21370
+ }
21371
+ else {
21372
+ document.body.style.overflow = this.overflow;
21373
+ }
21374
+ }
21375
+ trackRecommendationView({ detail }) {
21376
+ const recommendationViewEvent = createProductViewVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21377
+ this.trackingApi.trackEvent(recommendationViewEvent);
21378
+ }
21379
+ trackRecommendationClick({ detail }) {
21380
+ const recommendationClickEvent = createProductClickVpsEvent(Object.assign({ session_id: this.uiSessionId }, detail));
21381
+ this.trackingApi.trackEvent(recommendationClickEvent).finally(() => {
21382
+ const product = imageSearchState.results.find((r) => r.productId === detail.product);
21383
+ if (!product || !product.deeplink)
21384
+ return;
21385
+ window.location.href = product.deeplink;
21386
+ });
21387
+ }
21388
+ trachSearchAreaChanges() {
21389
+ const searchEvent = createSearchEvent({
21390
+ session_id: this.uiSessionId,
21391
+ source: this.imageSource,
21392
+ search_area: "manual-selection",
21393
+ });
21394
+ this.trackingApi.trackEvent(searchEvent);
21395
+ }
21396
+ trackDetectedObject() {
21397
+ const searchEvent = createSearchEvent({
21398
+ session_id: this.uiSessionId,
21399
+ source: this.imageSource,
21400
+ search_area: "attention-point",
21401
+ });
21402
+ this.trackingApi.trackEvent(searchEvent);
21403
+ }
21404
+ trackFilter({ detail }) {
21405
+ const searchEvent = createFilterEvent({
21406
+ session_id: this.uiSessionId,
21407
+ source: this.imageSource,
21408
+ kind: "category",
21409
+ action: detail,
21410
+ });
21411
+ this.trackingApi.trackEvent(searchEvent);
21412
+ }
21413
+ componentWillLoad() {
21414
+ slotChangeListener(this, this.el);
21415
+ }
21416
+ connectedCallback() {
21417
+ state$1.apiPath = this.apiPath;
21418
+ state$1.currencySign = this.currencySign;
21419
+ state$1.locale = this.locale;
21420
+ imageSearchState.token = this.token;
21421
+ imageSearchState.campaignId = _function.pipe(this.campaignId, Option.fromNullable, Option.chain(Option.fromPredicate(notEmptyString)), Option.map(filterInt), Option.chain(Option.fromPredicate(notNan)), Option.map((s) => `${s}`));
21422
+ this.uiSessionId = v4();
21423
+ this.trackingApi = createTrackingApi(this.apiPath, this.token);
21424
+ }
21425
+ trackOpenEvent() {
21426
+ const widgetOpenEvent = createWidgetVpsEvent({
21427
+ action: "open",
21428
+ session_id: this.uiSessionId,
21429
+ });
21430
+ this.trackingApi.trackEvent(widgetOpenEvent);
21431
+ }
21432
+ handleImageSelection(source) {
21433
+ this.imageSource = source;
21434
+ this.slidePosition = 1;
21435
+ const root = this.el.shadowRoot.querySelector("vviinn-overlayed-modal");
21436
+ const overlay = root.shadowRoot.querySelector("vviinn-overlay");
21437
+ const modal = overlay.querySelector("vviinn-modal");
21438
+ const modalBody = modal.shadowRoot.querySelector(".body");
21439
+ modalBody.scrollTop = 0;
21440
+ this.trackInitialSearch();
21441
+ }
21442
+ trackInitialSearch() {
21443
+ const searchEvent = createSearchEvent({
21444
+ session_id: this.uiSessionId,
21445
+ source: this.imageSource,
21446
+ search_area: "full",
21447
+ });
21448
+ this.trackingApi.trackEvent(searchEvent);
21449
+ }
21450
+ resetState() {
21451
+ this.resetScroll("onboarding-block");
21452
+ this.slidePosition = 0;
21453
+ imageSearchState.image = Option.none;
21454
+ imageSearchState.imageUrl = Option.none;
21455
+ imageSearchState.imageBounds = Option.none;
21456
+ imageSearchState.searchArea = Option.none;
21457
+ imageSearchState.results = [];
21458
+ imageSearchState.filters = [];
21459
+ imageSearchState.detectedObjects = [];
21460
+ imageSearchState.activeIonLink = undefined;
21461
+ imageSearchState.rectangleSearchForm = undefined;
21462
+ this.resetScroll("results-block");
21463
+ }
21464
+ haveErrors() {
21465
+ return this.wrongImageFormat || imageSearchState.serverError;
21466
+ }
21467
+ resetScroll(elementId, behavior = "auto") {
21468
+ const element = this.el.shadowRoot.getElementById(elementId);
21469
+ element.scroll({ top: 0, left: 0, behavior });
21470
+ }
21471
+ handleModalClose() {
21472
+ this.active = false;
21473
+ this.resetState();
21474
+ const elementsToReset = ["onboarding-block", "results-block"];
21475
+ elementsToReset.forEach((name) => this.resetScroll(name));
21476
+ const widgetOpenEvent = createWidgetVpsEvent({
21477
+ action: "close",
21478
+ session_id: this.uiSessionId,
21479
+ });
21480
+ this.trackingApi.trackEvent(widgetOpenEvent);
21481
+ }
21482
+ render() {
21483
+ return (h(Host, null, h("vviinn-overlayed-modal", { class: { "first-screen": this.slidePosition === 0 }, active: this.active, onSecondaryActionClicked: () => this.resetState(), onModalClosed: () => this.handleModalClose(), exportparts: "secondary-action, title, close-button, example-images" }, h("vviinn-slider", { showBullets: false, position: this.slidePosition }, h("vviinn-slide", { class: { "start-page": true } }, h("div", { class: {
21484
+ error: this.haveErrors(),
21485
+ "start-page_block": true,
21486
+ } }, h("vviinn-wrong-format", { class: { hidden: !this.wrongImageFormat }, onActionClick: () => (this.wrongImageFormat = false) }), h("vviinn-server-error", { class: { hidden: !imageSearchState.serverError }, onActionClick: () => (imageSearchState.serverError = false) }), h("vviinn-teaser", { class: { hidden: this.haveErrors() } }), h("vviinn-image-selector", { class: { hidden: this.haveErrors() }, onImageSelected: () => this.handleImageSelection("upload"), onImageSelectedError: () => (this.wrongImageFormat = true), part: "select-image_button" }, h("span", { slot: "upload-button-text", class: "upload-button-content" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "29", height: "28", fill: "none" }, h("defs", null), 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" }), 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" })), h("slot", { name: "vviinn-image-upload-button-text" }, h("span", null, "Kamera oder Bild ausw\u00E4hlen")))), h("vviinn-privacy-badge", { class: { hidden: this.haveErrors() } })), h("div", { id: "onboarding-block", class: "start-page_block" }, h("div", { class: "onboarding-wrapper" }, h("vviinn-onboarding", null), h("vviinn-example-images", { part: "example-images", onImageSelected: () => this.handleImageSelection("example"), onImageSelectedError: () => this.resetScroll("onboarding-block", "smooth") })))), h("vviinn-slide", { class: { "results-page": true, active: this.slidePosition == 1 } }, h("div", { class: "image-wrapper" }, h("vviinn-image-view", null), h("div", { class: "filters-wrapper" }, h("div", { class: "filters" }, imageSearchState.filters.map((filter) => (h("search-filters", { filter: filter })))))), h("div", { id: "results-block", class: "products-wrapper" }, h("div", { class: {
21487
+ "nothing-found": true,
21488
+ hidden: imageSearchState.results.length > 0,
21489
+ } }, h("vviinn-empty-results", null), h("vviinn-onboarding", null)), h("div", { class: {
21490
+ hidden: imageSearchState.results.length <= 0,
21491
+ products: true,
21492
+ } }, imageSearchState.results.map((p, i) => {
21493
+ var _a;
21494
+ return (h("vviinn-product-card", { hidden: true, productTitle: p.title, productId: p.productId, brand: p.brand, deeplink: p.deeplink, price: p.price.actual, salePrice: p.price.sale, imageWidth: 160, image: (_a = p.image.thumbnail) !== null && _a !== void 0 ? _a : p.image.original, part: "product-card", index: i }));
21495
+ }))))))));
21496
+ }
21497
+ get el() { return getElement(this); }
21498
+ static get watchers() { return {
21499
+ "active": ["activeWatcher"]
21500
+ }; }
21501
+ };
21502
+ VviinnVpsWidget.style = vviinnVpsWidgetCss;
21503
+
21504
+ const vviinnWrongFormatCss = ":host{display:block}";
21505
+
21506
+ let VviinnWrongFormat = class {
21507
+ constructor(hostRef) {
21508
+ registerInstance(this, hostRef);
21509
+ this.actionClick = createEvent(this, "actionClick", 7);
21510
+ }
21511
+ render() {
21512
+ return (h(Host, null, h("vviinn-error", null, h("h4", { slot: "title" }, "Dateityp wird nicht unterst\u00FCtzt"), h("span", { slot: "text" }, "Leider unterst\u00FCtzen wir dieses Format nicht. Bitte laden Sie eine .jpg, .png oder .webp Bilddatei hoch."), h("button", { slot: "action", onClick: () => this.actionClick.emit() }, "Neues Bild hochladen"))));
21513
+ }
21514
+ };
21515
+ VviinnWrongFormat.style = vviinnWrongFormatCss;
21516
+
21517
+ export { CropperHandler as cropper_handler, HighlightBox as highlight_box, ImageCropper as image_cropper, SearchFilters as search_filters, VviinnCarousel as vviinn_carousel, VviinnDetectedObject as vviinn_detected_object, VviinnEmptyResults as vviinn_empty_results, VviinnError as vviinn_error, VviinnExampleImage as vviinn_example_image, VviinnExampleImages as vviinn_example_images, VviinnImageSelector as vviinn_image_selector, VviinnImageView as vviinn_image_view, VviinnModal as vviinn_modal, VviinnOnboarding as vviinn_onboarding, VviinnOnboardingCard1 as vviinn_onboarding_card_1, VviinnOnboardingCard2 as vviinn_onboarding_card_2, VviinnOnboardingCard3 as vviinn_onboarding_card_3, VviinnOverlay as vviinn_overlay, VviinnOverlayedModal as vviinn_overlayed_modal, VviinnPreloader as vviinn_preloader, VviinnPrivacyBadge as vviinn_privacy_badge, VviinnProductCard as vviinn_product_card, VviinnServerError as vviinn_server_error, VviinnSlide as vviinn_slide, VviinnSlider as vviinn_slider, VviinnTeaser as vviinn_teaser, VviinnVprWidget as vviinn_vpr_widget, VviinnVpsButton as vviinn_vps_button, VviinnVpsWidget as vviinn_vps_widget, VviinnWrongFormat as vviinn_wrong_format };