vviinn-widgets 2.224.4 → 2.224.6

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 (53) hide show
  1. package/dist/cjs/{index-D8doLTd3.js → index-ClRBW1Hb.js} +1 -1
  2. package/dist/cjs/{search.store-CbH-X7eB.js → search.store-vismGe4F.js} +7 -11
  3. package/dist/cjs/vviinn-button_6.cjs.entry.js +1 -1
  4. package/dist/cjs/vviinn-camera_12.cjs.entry.js +39 -37
  5. package/dist/cjs/vviinn-carousel_10.cjs.entry.js +2 -2
  6. package/dist/cjs/vviinn-shop-the-look.cjs.entry.js +6 -3
  7. package/dist/cjs/vviinn-text-search.cjs.entry.js +1 -1
  8. package/dist/collection/components/vviinn-camera/vviinn-camera.js +5 -3
  9. package/dist/collection/components/vviinn-filters/vviinn-selected-filters.js +29 -29
  10. package/dist/collection/components/vviinn-image-selector/vviinn-image-selector.js +3 -3
  11. package/dist/collection/components/vviinn-shop-the-look/helpers.js +5 -2
  12. package/dist/collection/favicon.svg +4 -0
  13. package/dist/collection/filters/testFixtures.js +24 -0
  14. package/dist/collection/store/search.store.js +6 -10
  15. package/dist/esm/{index-fmWj9vF1.js → index-DCw3hZJZ.js} +1 -1
  16. package/dist/esm/{search.store-DOwsr2Al.js → search.store-X9fVl6Qr.js} +7 -11
  17. package/dist/esm/vviinn-button_6.entry.js +1 -1
  18. package/dist/esm/vviinn-camera_12.entry.js +39 -37
  19. package/dist/esm/vviinn-carousel_10.entry.js +2 -2
  20. package/dist/esm/vviinn-shop-the-look.entry.js +6 -3
  21. package/dist/esm/vviinn-text-search.entry.js +1 -1
  22. package/dist/types/components/vviinn-filters/vviinn-selected-filters.d.ts +3 -4
  23. package/dist/types/components/vviinn-shop-the-look/helpers.d.ts +4 -9
  24. package/dist/types/filters/testFixtures.d.ts +8 -0
  25. package/dist/types/store/search.store.d.ts +10 -6
  26. package/dist/vviinn-widgets/{p-dda93c85.entry.js → p-16472259.entry.js} +1 -1
  27. package/dist/vviinn-widgets/p-2add5235.entry.js +1 -0
  28. package/dist/vviinn-widgets/{p-a3e1cc3c.entry.js → p-8e879b54.entry.js} +1 -1
  29. package/dist/vviinn-widgets/{p-Y1Lq5OJz.js → p-D3l4RrWR.js} +1 -1
  30. package/dist/vviinn-widgets/{p-f9a7e87e.entry.js → p-abf5d279.entry.js} +1 -1
  31. package/dist/vviinn-widgets/p-c18dd576.entry.js +1 -0
  32. package/dist/vviinn-widgets/{p-DA0yi42k.js → p-ncpJa8gY.js} +1 -1
  33. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  34. package/package.json +2 -1
  35. package/readme.md +15 -0
  36. package/www/apple-touch-icon.png +0 -0
  37. package/www/build/{p-dda93c85.entry.js → p-16472259.entry.js} +1 -1
  38. package/www/build/p-2add5235.entry.js +1 -0
  39. package/www/build/{p-a3e1cc3c.entry.js → p-8e879b54.entry.js} +1 -1
  40. package/www/build/{p-6b33c29f.js → p-8f1bb7c5.js} +1 -1
  41. package/www/build/{p-Y1Lq5OJz.js → p-D3l4RrWR.js} +1 -1
  42. package/www/build/{p-f9a7e87e.entry.js → p-abf5d279.entry.js} +1 -1
  43. package/www/build/p-c18dd576.entry.js +1 -0
  44. package/www/build/{p-DA0yi42k.js → p-ncpJa8gY.js} +1 -1
  45. package/www/build/vviinn-widgets.esm.js +1 -1
  46. package/www/favicon.ico +0 -0
  47. package/www/favicon.svg +4 -0
  48. package/www/index.html +1 -1
  49. package/dist/vviinn-widgets/p-1d871785.entry.js +0 -1
  50. package/dist/vviinn-widgets/p-29ac785e.entry.js +0 -1
  51. package/www/assets/VI_logo_dark.png +0 -0
  52. package/www/build/p-1d871785.entry.js +0 -1
  53. package/www/build/p-29ac785e.entry.js +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-BU8FMTXn.js');
4
- var search_store = require('./search.store-CbH-X7eB.js');
4
+ var search_store = require('./search.store-vismGe4F.js');
5
5
  var store = require('./store-jPZ4ROqV.js');
6
6
 
7
7
  const PlusIcon = () => (index.h("svg", { width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", class: "plus-icon", "aria-hidden": "true" },
@@ -8630,7 +8630,7 @@ const startSearch = (store) => {
8630
8630
  return () => latestSearch.get(store) !== sequence;
8631
8631
  };
8632
8632
 
8633
- const version = "2.224.4";
8633
+ const version = "2.224.6";
8634
8634
 
8635
8635
  const appStateGlobalDefaults = {
8636
8636
  excluded: null,
@@ -8689,6 +8689,7 @@ const resetResultEvents = (store) => {
8689
8689
  state.resultLoaded = false;
8690
8690
  state.resultViewed = false;
8691
8691
  };
8692
+ /** `excludedFields` names the fields the reset leaves alone. */
8692
8693
  const resetStore = (store, mode = "appStateAndReceivedData", excludedFields = []) => {
8693
8694
  const state = useStore(store);
8694
8695
  let resetPayload = {};
@@ -8705,11 +8706,6 @@ const resetStore = (store, mode = "appStateAndReceivedData", excludedFields = []
8705
8706
  case "all":
8706
8707
  resetPayload = Object.assign({}, storeDefaults);
8707
8708
  break;
8708
- case "manual":
8709
- for (const key of excludedFields) {
8710
- delete state[key];
8711
- }
8712
- return;
8713
8709
  }
8714
8710
  for (const key of excludedFields) {
8715
8711
  delete resetPayload[key];
@@ -8773,7 +8769,7 @@ const processVisualSearch = (store, body, token, apiPath, isHiResUpdate = false)
8773
8769
  return sessionResponse;
8774
8770
  }), Rectangle.mapLeft(handleSearchError(store, isStale)));
8775
8771
  };
8776
- const uploadImageFile = (store, token, imageType = "image", searchId, apiPath, campaignId, isHiResUpdate = false) => (file) => {
8772
+ const uploadImageFile = (store, token, { apiPath, campaignId, imageType = "image", searchId, isHiResUpdate = false, } = {}) => (file) => {
8777
8773
  const state = useStore(store);
8778
8774
  return Rectangle.pipe(Rectangle.fromEither(checkFileWithExtention(file)), Rectangle.chainTaskK(resizeFileTo(imageType)), Rectangle.chain$1((resizedFile) => updateImageState(store)(resizedFile)), Rectangle.chain$1((resizedFile) => Rectangle.pipe(Rectangle.tryCatch(async () => (Object.assign(Object.assign(Object.assign({ query: {
8779
8775
  [imageType]: (await fileToB64(resizedFile)).split(",")[1],
@@ -8784,7 +8780,7 @@ const uploadImageFile = (store, token, imageType = "image", searchId, apiPath, c
8784
8780
  inner: error,
8785
8781
  })), Rectangle.chain$1((body) => processVisualSearch(store, body, token, apiPath, isHiResUpdate)))));
8786
8782
  };
8787
- const makeVisualSearchByUrlRequest = async (store, imageUrl, token, apiPath, campaignId) => {
8783
+ const makeVisualSearchByUrlRequest = async (store, imageUrl, token, { apiPath, campaignId } = {}) => {
8788
8784
  const state = useStore(store);
8789
8785
  const body = Object.assign(Object.assign({ query: {
8790
8786
  url: imageUrl,
@@ -8793,7 +8789,7 @@ const makeVisualSearchByUrlRequest = async (store, imageUrl, token, apiPath, cam
8793
8789
  } }, addNestedIfNotEmpty("staticFilters", Object.assign({}, addIfNotEmpty("excluded", state.excluded)))), addIfNotEmpty("campaign", campaignId || state.campaignIdVisualSearch || state.campaignId));
8794
8790
  return processVisualSearch(store, body, token, apiPath)();
8795
8791
  };
8796
- const makeUploadFileRequest = (store, token, apiPath, campaignId) => async (file) => {
8792
+ const makeUploadFileRequest = (store, token, options = {}) => async (file) => {
8797
8793
  var _a;
8798
8794
  const state = useStore(store);
8799
8795
  if (store !== "shopTheLook") {
@@ -8806,13 +8802,13 @@ const makeUploadFileRequest = (store, token, apiPath, campaignId) => async (file
8806
8802
  visualSearchStarted: true,
8807
8803
  });
8808
8804
  }
8809
- const session = await Rectangle.pipe(uploadImageFile(store, token, "image", undefined, apiPath, campaignId)(file))();
8805
+ const session = await uploadImageFile(store, token, options)(file)();
8810
8806
  if (!((_a = state.visualSearchId) === null || _a === void 0 ? void 0 : _a.length))
8811
8807
  return session;
8812
8808
  const shouldProcessHiRes = await Rectangle.pipe(Rectangle.fromTask(imageFromFileTask(file)), Rectangle.map((img) => shouldResize(img, "highResolutionImage")), Rectangle.getOrElse(() => Rectangle.of(false)))();
8813
8809
  if (!shouldProcessHiRes)
8814
8810
  return session;
8815
- Rectangle.pipe(uploadImageFile(store, token, "highResolutionImage", state.visualSearchId, apiPath, campaignId, true)(file), Rectangle.getOrElseW((error) => {
8811
+ Rectangle.pipe(uploadImageFile(store, token, Object.assign(Object.assign({}, options), { imageType: "highResolutionImage", searchId: state.visualSearchId, isHiResUpdate: true }))(file), Rectangle.getOrElseW((error) => {
8816
8812
  console.error("Failed to upload hi-res image:", error);
8817
8813
  return Rectangle.of(session);
8818
8814
  }))();
@@ -2,7 +2,7 @@
2
2
 
3
3
  var index = require('./index-BU8FMTXn.js');
4
4
  var store = require('./store-jPZ4ROqV.js');
5
- var search_store = require('./search.store-CbH-X7eB.js');
5
+ var search_store = require('./search.store-vismGe4F.js');
6
6
  var index$1 = require('./index-CP1QUrJT.js');
7
7
  var SecondaryActionIcon = require('./SecondaryActionIcon-CuNEBTWD.js');
8
8
  var index$2 = require('./index-BF9aENF8.js');
@@ -2,9 +2,9 @@
2
2
 
3
3
  var index = require('./index-BU8FMTXn.js');
4
4
  var Rectangle = require('./Rectangle-7dF6_xf3.js');
5
- var search_store = require('./search.store-CbH-X7eB.js');
5
+ var search_store = require('./search.store-vismGe4F.js');
6
6
  var index$2 = require('./index-CP1QUrJT.js');
7
- var index$1 = require('./index-D8doLTd3.js');
7
+ var index$1 = require('./index-ClRBW1Hb.js');
8
8
  var store = require('./store-jPZ4ROqV.js');
9
9
  var cropperUtils = require('./cropperUtils-s4RL8x1I.js');
10
10
  var cssUrlHelper = require('./cssUrlHelper-B5A2BBm7.js');
@@ -177,7 +177,9 @@ const VviinnExampleImage = class {
177
177
  ctx.drawImage(video, dx, dy, cropDimension, cropDimension, 0, 0, canvas.width, canvas.height);
178
178
  const dataURI = canvas.toDataURL("image/jpeg");
179
179
  file = search_store.toFile(dataURI);
180
- Rectangle._functionExports.pipe(await search_store.makeUploadFileRequest(this.storeName, this.token, this.apiPath)(file), Rectangle.EitherExports.match(() => {
180
+ Rectangle._functionExports.pipe(await search_store.makeUploadFileRequest(this.storeName, this.token, {
181
+ apiPath: this.apiPath,
182
+ })(file), Rectangle.EitherExports.match(() => {
181
183
  this.vviinnNoResult.emit(this.basicEventData);
182
184
  }, (response) => {
183
185
  var _a;
@@ -211,9 +213,9 @@ const VviinnExampleImage = class {
211
213
  };
212
214
  }
213
215
  render() {
214
- return (index.h(index.Host, { key: '86700ba180e1ae7d957e5fa14e1a261a2602a5a2', onKeyUp: (ev) => this.handleKeyPress(ev), class: { "video-expanded": this.cameraButtonClicked } }, index.h("video", { key: 'f4de85ab700fe1ba81812de608627e9c57686311', id: "camera-preview", class: {
216
+ return (index.h(index.Host, { key: '6010f6cb4b3387b640c988d8d28426b5d265e7a5', onKeyUp: (ev) => this.handleKeyPress(ev), class: { "video-expanded": this.cameraButtonClicked } }, index.h("video", { key: '477a619c739162628c3d0a3fcbbb3b698892c62b', id: "camera-preview", class: {
215
217
  hidden: !this.videoInitialized || this.selected,
216
- }, autoplay: true, playsinline: true, muted: true }), index.h("img", { key: '22cc3ba84282941cb6a4d41364cb4a04f3b3b0f3', src: this.exampleImageSource, alt: store.instance.t("a11y.cameraExampleImage"), width: this.width, height: this.height, class: { hidden: this.videoInitialized || this.selected } }), index.h("img", { key: '799ecac4e9fe6006126fa0017b7bb51e2838fdf5', id: "captured-image-placeholder", alt: store.instance.t("a11y.capturedImage"), class: { hidden: !this.selected } }), index.h("div", { key: '2309b225a7b2c3d02e96f7477d395b1698b61877', class: { container: true, hidden: !this.videoInitialized } }, index.h("div", { key: 'e207a1517570cc676a4cb441a1acd60af2340a96', class: "photo-frame-container" }, index.h("div", { key: '7589da472a9e02456274de41640ae3c9b9de6fe8', id: "photo-frame" }, index.h(PhotoFrameCorner, { key: '140f0552a4d52c565c6fa690c404b9d4467ea8ee', className: "photo-frame-corner top-left" }), index.h(PhotoFrameCorner, { key: 'c3262b110cd7ecae4a7a45f750779e6857131d85', className: "photo-frame-corner top-right" }), index.h(PhotoFrameCorner, { key: '19ba8d3a4fcd78099d051fc3eb3ca35277388d4c', className: "photo-frame-corner bottom-left" }), index.h(PhotoFrameCorner, { key: '03988144b8abb8d65c976fde23f3d0b0e3ef8ea7', className: "photo-frame-corner bottom-right" })), index.h("div", { key: '68d87a529d40e7d654fd578059941f6caa0918ed', class: { "zoom-buttons": true, hidden: !this.zoomCapabilities } }, index.h("button", { key: '37edae86c3402a1f2913e5cf3f08f0e93c793e2e', "aria-label": store.instance.t("a11y.zoomOut"), onClick: () => this.onZoom("out") }, index.h(MinusIcon, { key: '3b10f8ff52ce4da97ba224357f18fc0c9af2f4d1' })), index.h("button", { key: '916a7d7e66e8899b3e20b52309a6356b53dfec90', "aria-label": store.instance.t("a11y.zoomIn"), onClick: () => this.onZoom("in") }, index.h(index$1.PlusIcon, { key: '2d7ca2ae82636298c14067d0b8f6cc9be5f0af39' })))), index.h("div", { key: '7fd64daa8eeceb60ec14f39847a3d01a22a9347c', class: "photo-button-container" }, index.h("button", { key: 'e05aedeb1c6c80781afc89a5f81bb77d768e8e32', class: "photo-button", "aria-label": store.instance.t("a11y.takePicture"), onClick: () => this.selectImage() }, index.h(RoundCameraIcon, { key: '68df03db0496f1cfdaf1b10dbecf69b1053057f5' }))))));
218
+ }, autoplay: true, playsinline: true, muted: true }), index.h("img", { key: 'e445fb47faba8f923164c3183b9c75d6c506cca0', src: this.exampleImageSource, alt: store.instance.t("a11y.cameraExampleImage"), width: this.width, height: this.height, class: { hidden: this.videoInitialized || this.selected } }), index.h("img", { key: '72303fbd8da8e846a0770410968e4e72e95fdb11', id: "captured-image-placeholder", alt: store.instance.t("a11y.capturedImage"), class: { hidden: !this.selected } }), index.h("div", { key: 'c2eb69a7d53be148d0163f9c08236bb713540752', class: { container: true, hidden: !this.videoInitialized } }, index.h("div", { key: '8aacaf120ee4b955a69d98faf705e8db85a94671', class: "photo-frame-container" }, index.h("div", { key: '9c231f5b4ab8c677991a309d1bb37352ae16f937', id: "photo-frame" }, index.h(PhotoFrameCorner, { key: '9dc75012a6c2f228ba37258b3b706a30e999cf9b', className: "photo-frame-corner top-left" }), index.h(PhotoFrameCorner, { key: '8c3e0fe5d07c51d6834fa3cc3d7e15e6fbde2734', className: "photo-frame-corner top-right" }), index.h(PhotoFrameCorner, { key: 'af3510e60b36392cf66a41d31704778011715a30', className: "photo-frame-corner bottom-left" }), index.h(PhotoFrameCorner, { key: 'd8a52a9dbe422a849f412e28b4e515936eb63522', className: "photo-frame-corner bottom-right" })), index.h("div", { key: 'e8d881d9fac1bcc4ee128c8155cd7bfdb73601ca', class: { "zoom-buttons": true, hidden: !this.zoomCapabilities } }, index.h("button", { key: 'd0bf4d2bafb181a0f129e81c5cb0b800d4cad82e', "aria-label": store.instance.t("a11y.zoomOut"), onClick: () => this.onZoom("out") }, index.h(MinusIcon, { key: 'df8e0a0c66e02a9f2e1f5dc3289e386867475417' })), index.h("button", { key: '3c3fa371b91b5db25dce2a90852fe5f3370dcb4d', "aria-label": store.instance.t("a11y.zoomIn"), onClick: () => this.onZoom("in") }, index.h(index$1.PlusIcon, { key: 'f0a95ba1f95d81831c75541c0dd4486815976071' })))), index.h("div", { key: 'b1e7d0fd0e7e18f6b4adb0a1e711e9277234dde1', class: "photo-button-container" }, index.h("button", { key: 'd6b86de54bde91c0cccfbebd67a2f4a2433ad6aa', class: "photo-button", "aria-label": store.instance.t("a11y.takePicture"), onClick: () => this.selectImage() }, index.h(RoundCameraIcon, { key: 'e565d8e5ca591736d9b851a3590c35d70ae94281' }))))));
217
219
  }
218
220
  get el() { return index.getElement(this); }
219
221
  static get watchers() { return {
@@ -654,7 +656,7 @@ const VviinnImageSelector = class {
654
656
  this.vviinnImageUploadStarted.emit(Object.assign(Object.assign({}, this.basicEventData), { isTriggeredByVpsWidget: this.storeName === "widget" }));
655
657
  this.isProcessing = true;
656
658
  try {
657
- const processingResult = await search_store.makeUploadFileRequest(this.storeName, this.token, this.apiPath)(file);
659
+ const processingResult = await search_store.makeUploadFileRequest(this.storeName, this.token, { apiPath: this.apiPath })(file);
658
660
  Rectangle._functionExports.pipe(processingResult, Rectangle.match(({ kind, code }) => {
659
661
  this.vviinnNoResult.emit(Object.assign(Object.assign({}, this.basicEventData), { reason: kind, errorCode: code }));
660
662
  }, (response) => {
@@ -723,13 +725,13 @@ const VviinnImageSelector = class {
723
725
  }
724
726
  }
725
727
  render() {
726
- return (index.h(index.Host, { key: '616c751da82243f02d9d9cbc4f908702c49b3889', exportparts: this.useDragAndDrop ? "button:upload-photo_button" : "button", class: { "drag-over": this.isDragOver } }, this.useDragAndDrop && (index.h("div", { key: 'b02ad9a11981be6f13bd1347279fe4dad3046887', class: "drop-zone__hint", "aria-hidden": "true" }, index.h("span", { key: '9f5ed13a34f05cd9dd13aeddf3bfe166b84ee6f6', class: "drop-zone__icon" }, index.h("slot", { key: 'ccbadd5393155b7e2222d89afad490f43e93b0bc', name: "drop-zone-icon" })), index.h("span", { key: '0cd1cbaaadb326ef8d53bd8c895c9d72af8571a0', class: "drop-zone__text" }, index.h("slot", { key: '659b6e91869f7fbb1d73df37d6e25a54ebd200a1', name: "drop-zone-text" })))), index.h("label", { key: '3684c5e7afefa0403b8d760db89390530834d16d', htmlFor: "fileInput", part: "button", class: { loading: this.loading }, tabindex: this.loading ? -1 : 0, onKeyDown: (e) => {
728
+ return (index.h(index.Host, { key: '798b8ccc61af60c6a0794d52d5c86bd323aacf11', exportparts: this.useDragAndDrop ? "button:upload-photo_button" : "button", class: { "drag-over": this.isDragOver } }, this.useDragAndDrop && (index.h("div", { key: '0a0e5e4177265c0e7e4f691ccdbeb7769d8e060c', class: "drop-zone__hint", "aria-hidden": "true" }, index.h("span", { key: 'b1dbcbf92ce61c46587fe94857c59f9dea17c1b3', class: "drop-zone__icon" }, index.h("slot", { key: '156abf857a51a6843401b130043fa4c1fe5b5bfb', name: "drop-zone-icon" })), index.h("span", { key: '17a11fb8b274200b8436028b3295ea0f9b0b95ee', class: "drop-zone__text" }, index.h("slot", { key: 'f2226fbef3df72fd0f6f0d0974531a022fed1e31', name: "drop-zone-text" })))), index.h("label", { key: '235d62c02f871a85c90848ecc14dd8251feee7e9', htmlFor: "fileInput", part: "button", class: { loading: this.loading }, tabindex: this.loading ? -1 : 0, onKeyDown: (e) => {
727
729
  var _a;
728
730
  if (!this.loading && (e.key === "Enter" || e.key === " ")) {
729
731
  e.preventDefault();
730
732
  (_a = this.fileInput) === null || _a === void 0 ? void 0 : _a.click();
731
733
  }
732
- } }, this.loading ? (index.h("vviinn-preloader", null)) : (index.h("slot", { name: "upload-button-text" }, "Upload image"))), index.h("input", { key: '7d9cfd89c2d64cdf3c262e89f652da500dcc80ba', id: "fileInput", class: "visually-hidden", type: "file", tabindex: "-1", accept: search_store.getAcceptableFileFormats(), onChange: (event) => this.handleInputChange(event), ref: (el) => (this.fileInput = el) })));
734
+ } }, this.loading ? (index.h("vviinn-preloader", null)) : (index.h("slot", { name: "upload-button-text" }, "Upload image"))), index.h("input", { key: 'aeb6562fca0a11ea3da456813e61ddabb2cce708', id: "fileInput", class: "visually-hidden", type: "file", tabindex: "-1", accept: search_store.getAcceptableFileFormats(), onChange: (event) => this.handleInputChange(event), ref: (el) => (this.fileInput = el) })));
733
735
  }
734
736
  static get watchers() { return {
735
737
  "startUpload": ["startUploadWatcher"]
@@ -1236,10 +1238,6 @@ const VviinnSelectedFilters = class {
1236
1238
  this.requestFilters = [];
1237
1239
  this.textSearchCustomFilter = null;
1238
1240
  this.imageSrc = null;
1239
- // Rebuilt in componentWillRender and consumed by the render after it, so plain fields.
1240
- // The local requestFilters drive that rebuild — reads there register no subscription.
1241
- this.selectedFilterButtons = [];
1242
- this.intervalFilterButtons = [];
1243
1241
  this.handleSubFilterSelection = (filterValue, selectedFilter) => {
1244
1242
  this.requestFilters = index$1.triggerFilter({
1245
1243
  filterValue,
@@ -1355,44 +1353,47 @@ const VviinnSelectedFilters = class {
1355
1353
  (_a = this.eventAbortController) === null || _a === void 0 ? void 0 : _a.abort();
1356
1354
  (_b = this.disposeStoreListener) === null || _b === void 0 ? void 0 : _b.call(this);
1357
1355
  }
1358
- componentWillRender() {
1359
- var _a;
1360
- this.selectedFilterButtons = [];
1361
- this.intervalFilterButtons = [];
1362
- const filters = ((_a = this.state) === null || _a === void 0 ? void 0 : _a.dynamicFilters) || [];
1363
- filters.forEach((filter) => {
1356
+ /** Built here so the dynamicFilters read happens under render() and registers a subscription. */
1357
+ buildChips() {
1358
+ var _a, _b;
1359
+ const intervalChips = [];
1360
+ const selectedChips = [];
1361
+ ((_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.dynamicFilters) !== null && _b !== void 0 ? _b : []).forEach((filter) => {
1364
1362
  if (filter.type === "interval") {
1365
- this.collectIntervalButton(filter);
1363
+ const chip = this.renderIntervalChip(filter);
1364
+ if (chip)
1365
+ intervalChips.push(chip);
1366
1366
  return;
1367
1367
  }
1368
1368
  if (!("values" in filter))
1369
1369
  return;
1370
1370
  filter.values.forEach(({ value, label, active }) => {
1371
- if (index$1.isSubFilterActive(this.requestFilters, value, filter)) {
1372
- this.selectedFilterButtons.push(index$1.RenderFilterButton({
1373
- handleSubFilterSelection: this.handleSubFilterSelection,
1374
- selectedFilter: filter,
1375
- value,
1376
- label,
1377
- active,
1378
- isSelected: true,
1379
- showClose: true,
1380
- }));
1381
- }
1371
+ if (!index$1.isSubFilterActive(this.requestFilters, value, filter))
1372
+ return;
1373
+ selectedChips.push(index$1.RenderFilterButton({
1374
+ handleSubFilterSelection: this.handleSubFilterSelection,
1375
+ selectedFilter: filter,
1376
+ value,
1377
+ label,
1378
+ active,
1379
+ isSelected: true,
1380
+ showClose: true,
1381
+ }));
1382
1382
  });
1383
1383
  });
1384
+ return { intervalChips, selectedChips };
1384
1385
  }
1385
1386
  /** A chip exists only while the column has an applied interval to show. */
1386
- collectIntervalButton(filter) {
1387
+ renderIntervalChip(filter) {
1387
1388
  var _a;
1388
1389
  const applied = index$1.getSelectedInterval(this.requestFilters, filter.column);
1389
1390
  if (!applied)
1390
- return;
1391
+ return null;
1391
1392
  const label = index$1.getIntervalLabel(filter, applied, (_a = this.currencySign) !== null && _a !== void 0 ? _a : store.defaultConfig.currencySign, true);
1392
1393
  if (!label)
1393
- return;
1394
+ return null;
1394
1395
  const { column } = filter;
1395
- this.intervalFilterButtons.push(index.h("div", { key: column }, RenderCustomButton({
1396
+ return (index.h("div", { key: column }, RenderCustomButton({
1396
1397
  label,
1397
1398
  buttonType: "range",
1398
1399
  onClick: () => this.handleIntervalButtonClick(column),
@@ -1400,10 +1401,11 @@ const VviinnSelectedFilters = class {
1400
1401
  }
1401
1402
  render() {
1402
1403
  var _a, _b;
1404
+ const { intervalChips, selectedChips } = this.buildChips();
1403
1405
  if (this.showInWidget &&
1404
- !this.selectedFilterButtons.length &&
1406
+ !selectedChips.length &&
1405
1407
  !this.state.croppedImageUrl &&
1406
- !this.intervalFilterButtons.length)
1408
+ !intervalChips.length)
1407
1409
  return null;
1408
1410
  return (index.h(index.Host, { class: {
1409
1411
  "show-in-widget": this.showInWidget,
@@ -1425,7 +1427,7 @@ const VviinnSelectedFilters = class {
1425
1427
  imageSrc: this.state.croppedImageUrl,
1426
1428
  onClick: this.handleCropButtonClick,
1427
1429
  hidden: !this.state.searchArea,
1428
- }), this.intervalFilterButtons, this.selectedFilterButtons))));
1430
+ }), intervalChips, selectedChips))));
1429
1431
  }
1430
1432
  get el() { return index.getElement(this); }
1431
1433
  };
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-BU8FMTXn.js');
4
- var search_store = require('./search.store-CbH-X7eB.js');
4
+ var search_store = require('./search.store-vismGe4F.js');
5
5
  var Rectangle = require('./Rectangle-7dF6_xf3.js');
6
6
  var store = require('./store-jPZ4ROqV.js');
7
- var index$1 = require('./index-D8doLTd3.js');
7
+ var index$1 = require('./index-ClRBW1Hb.js');
8
8
  var constants = require('./constants-BlwqMvns.js');
9
9
  var index$2 = require('./index-CP1QUrJT.js');
10
10
  var index$3 = require('./index-BF9aENF8.js');
@@ -4,7 +4,7 @@ var index = require('./index-BU8FMTXn.js');
4
4
  var Rectangle = require('./Rectangle-7dF6_xf3.js');
5
5
  var cropperUtils = require('./cropperUtils-s4RL8x1I.js');
6
6
  var swiperElement = require('./swiper-element-DjtzojCR.js');
7
- var search_store = require('./search.store-CbH-X7eB.js');
7
+ var search_store = require('./search.store-vismGe4F.js');
8
8
  var SecondaryActionIcon = require('./SecondaryActionIcon-CuNEBTWD.js');
9
9
  var index$1 = require('./index-BF9aENF8.js');
10
10
  var store = require('./store-jPZ4ROqV.js');
@@ -220,7 +220,7 @@ const calculateModalPosition = (imageElement, detectedObject, containerElement,
220
220
  };
221
221
  const performVisualSearch = async (params) => {
222
222
  try {
223
- const result = await search_store.makeVisualSearchByUrlRequest("shopTheLook", params.imageUrl, params.token, params.apiPath, params.campaignId);
223
+ const result = await search_store.makeVisualSearchByUrlRequest("shopTheLook", params.imageUrl, params.token, { apiPath: params.apiPath, campaignId: params.campaignId });
224
224
  return Rectangle.EitherExports.fold((error) => Rectangle.EitherExports.left(`Visual search failed: ${error.inner}`), (response) => {
225
225
  var _a, _b;
226
226
  const detectedObjects = ((_b = (_a = response.interactions) === null || _a === void 0 ? void 0 : _a.suggestedSearchAreas) === null || _b === void 0 ? void 0 : _b.map((area) => area.rectangle)) || [];
@@ -278,7 +278,10 @@ const processFileUpload = async (params) => {
278
278
  try {
279
279
  const imageElement = await search_store.imageFromFileTask(file)();
280
280
  const imageUrl = imageElement.src;
281
- const uploadResult = await search_store.makeUploadFileRequest("shopTheLook", token, apiPath, campaignId)(file);
281
+ const uploadResult = await search_store.makeUploadFileRequest("shopTheLook", token, {
282
+ apiPath,
283
+ campaignId,
284
+ })(file);
282
285
  return Rectangle.EitherExports.fold((error) => Rectangle.EitherExports.left(`Upload failed: ${error.inner}`), (response) => {
283
286
  var _a, _b;
284
287
  const detectedObjects = ((_b = (_a = response.interactions) === null || _a === void 0 ? void 0 : _a.suggestedSearchAreas) === null || _b === void 0 ? void 0 : _b.map((area) => area.rectangle)) || [];
@@ -2,7 +2,7 @@
2
2
 
3
3
  var index = require('./index-BU8FMTXn.js');
4
4
  var Rectangle = require('./Rectangle-7dF6_xf3.js');
5
- var search_store = require('./search.store-CbH-X7eB.js');
5
+ var search_store = require('./search.store-vismGe4F.js');
6
6
  var index$2 = require('./index-CP1QUrJT.js');
7
7
  var store = require('./store-jPZ4ROqV.js');
8
8
  var index$1 = require('./index-BF9aENF8.js');
@@ -101,7 +101,9 @@ export class VviinnExampleImage {
101
101
  ctx.drawImage(video, dx, dy, cropDimension, cropDimension, 0, 0, canvas.width, canvas.height);
102
102
  const dataURI = canvas.toDataURL("image/jpeg");
103
103
  file = toFile(dataURI);
104
- pipe(await makeUploadFileRequest(this.storeName, this.token, this.apiPath)(file), E.match(() => {
104
+ pipe(await makeUploadFileRequest(this.storeName, this.token, {
105
+ apiPath: this.apiPath,
106
+ })(file), E.match(() => {
105
107
  this.vviinnNoResult.emit(this.basicEventData);
106
108
  }, (response) => {
107
109
  var _a;
@@ -135,9 +137,9 @@ export class VviinnExampleImage {
135
137
  };
136
138
  }
137
139
  render() {
138
- return (h(Host, { key: '86700ba180e1ae7d957e5fa14e1a261a2602a5a2', onKeyUp: (ev) => this.handleKeyPress(ev), class: { "video-expanded": this.cameraButtonClicked } }, h("video", { key: 'f4de85ab700fe1ba81812de608627e9c57686311', id: "camera-preview", class: {
140
+ return (h(Host, { key: '6010f6cb4b3387b640c988d8d28426b5d265e7a5', onKeyUp: (ev) => this.handleKeyPress(ev), class: { "video-expanded": this.cameraButtonClicked } }, h("video", { key: '477a619c739162628c3d0a3fcbbb3b698892c62b', id: "camera-preview", class: {
139
141
  hidden: !this.videoInitialized || this.selected,
140
- }, autoplay: true, playsinline: true, muted: true }), h("img", { key: '22cc3ba84282941cb6a4d41364cb4a04f3b3b0f3', src: this.exampleImageSource, alt: i18next.t("a11y.cameraExampleImage"), width: this.width, height: this.height, class: { hidden: this.videoInitialized || this.selected } }), h("img", { key: '799ecac4e9fe6006126fa0017b7bb51e2838fdf5', id: "captured-image-placeholder", alt: i18next.t("a11y.capturedImage"), class: { hidden: !this.selected } }), h("div", { key: '2309b225a7b2c3d02e96f7477d395b1698b61877', class: { container: true, hidden: !this.videoInitialized } }, h("div", { key: 'e207a1517570cc676a4cb441a1acd60af2340a96', class: "photo-frame-container" }, h("div", { key: '7589da472a9e02456274de41640ae3c9b9de6fe8', id: "photo-frame" }, h(PhotoFrameCorner, { key: '140f0552a4d52c565c6fa690c404b9d4467ea8ee', className: "photo-frame-corner top-left" }), h(PhotoFrameCorner, { key: 'c3262b110cd7ecae4a7a45f750779e6857131d85', className: "photo-frame-corner top-right" }), h(PhotoFrameCorner, { key: '19ba8d3a4fcd78099d051fc3eb3ca35277388d4c', className: "photo-frame-corner bottom-left" }), h(PhotoFrameCorner, { key: '03988144b8abb8d65c976fde23f3d0b0e3ef8ea7', className: "photo-frame-corner bottom-right" })), h("div", { key: '68d87a529d40e7d654fd578059941f6caa0918ed', class: { "zoom-buttons": true, hidden: !this.zoomCapabilities } }, h("button", { key: '37edae86c3402a1f2913e5cf3f08f0e93c793e2e', "aria-label": i18next.t("a11y.zoomOut"), onClick: () => this.onZoom("out") }, h(MinusIcon, { key: '3b10f8ff52ce4da97ba224357f18fc0c9af2f4d1' })), h("button", { key: '916a7d7e66e8899b3e20b52309a6356b53dfec90', "aria-label": i18next.t("a11y.zoomIn"), onClick: () => this.onZoom("in") }, h(PlusIcon, { key: '2d7ca2ae82636298c14067d0b8f6cc9be5f0af39' })))), h("div", { key: '7fd64daa8eeceb60ec14f39847a3d01a22a9347c', class: "photo-button-container" }, h("button", { key: 'e05aedeb1c6c80781afc89a5f81bb77d768e8e32', class: "photo-button", "aria-label": i18next.t("a11y.takePicture"), onClick: () => this.selectImage() }, h(RoundCameraIcon, { key: '68df03db0496f1cfdaf1b10dbecf69b1053057f5' }))))));
142
+ }, autoplay: true, playsinline: true, muted: true }), h("img", { key: 'e445fb47faba8f923164c3183b9c75d6c506cca0', src: this.exampleImageSource, alt: i18next.t("a11y.cameraExampleImage"), width: this.width, height: this.height, class: { hidden: this.videoInitialized || this.selected } }), h("img", { key: '72303fbd8da8e846a0770410968e4e72e95fdb11', id: "captured-image-placeholder", alt: i18next.t("a11y.capturedImage"), class: { hidden: !this.selected } }), h("div", { key: 'c2eb69a7d53be148d0163f9c08236bb713540752', class: { container: true, hidden: !this.videoInitialized } }, h("div", { key: '8aacaf120ee4b955a69d98faf705e8db85a94671', class: "photo-frame-container" }, h("div", { key: '9c231f5b4ab8c677991a309d1bb37352ae16f937', id: "photo-frame" }, h(PhotoFrameCorner, { key: '9dc75012a6c2f228ba37258b3b706a30e999cf9b', className: "photo-frame-corner top-left" }), h(PhotoFrameCorner, { key: '8c3e0fe5d07c51d6834fa3cc3d7e15e6fbde2734', className: "photo-frame-corner top-right" }), h(PhotoFrameCorner, { key: 'af3510e60b36392cf66a41d31704778011715a30', className: "photo-frame-corner bottom-left" }), h(PhotoFrameCorner, { key: 'd8a52a9dbe422a849f412e28b4e515936eb63522', className: "photo-frame-corner bottom-right" })), h("div", { key: 'e8d881d9fac1bcc4ee128c8155cd7bfdb73601ca', class: { "zoom-buttons": true, hidden: !this.zoomCapabilities } }, h("button", { key: 'd0bf4d2bafb181a0f129e81c5cb0b800d4cad82e', "aria-label": i18next.t("a11y.zoomOut"), onClick: () => this.onZoom("out") }, h(MinusIcon, { key: 'df8e0a0c66e02a9f2e1f5dc3289e386867475417' })), h("button", { key: '3c3fa371b91b5db25dce2a90852fe5f3370dcb4d', "aria-label": i18next.t("a11y.zoomIn"), onClick: () => this.onZoom("in") }, h(PlusIcon, { key: 'f0a95ba1f95d81831c75541c0dd4486815976071' })))), h("div", { key: 'b1e7d0fd0e7e18f6b4adb0a1e711e9277234dde1', class: "photo-button-container" }, h("button", { key: 'd6b86de54bde91c0cccfbebd67a2f4a2433ad6aa', class: "photo-button", "aria-label": i18next.t("a11y.takePicture"), onClick: () => this.selectImage() }, h(RoundCameraIcon, { key: 'e565d8e5ca591736d9b851a3590c35d70ae94281' }))))));
141
143
  }
142
144
  static get is() { return "vviinn-camera"; }
143
145
  static get encapsulation() { return "shadow"; }
@@ -26,10 +26,6 @@ export class VviinnSelectedFilters {
26
26
  this.requestFilters = [];
27
27
  this.textSearchCustomFilter = null;
28
28
  this.imageSrc = null;
29
- // Rebuilt in componentWillRender and consumed by the render after it, so plain fields.
30
- // The local requestFilters drive that rebuild — reads there register no subscription.
31
- this.selectedFilterButtons = [];
32
- this.intervalFilterButtons = [];
33
29
  this.handleSubFilterSelection = (filterValue, selectedFilter) => {
34
30
  this.requestFilters = triggerFilter({
35
31
  filterValue,
@@ -145,44 +141,47 @@ export class VviinnSelectedFilters {
145
141
  (_a = this.eventAbortController) === null || _a === void 0 ? void 0 : _a.abort();
146
142
  (_b = this.disposeStoreListener) === null || _b === void 0 ? void 0 : _b.call(this);
147
143
  }
148
- componentWillRender() {
149
- var _a;
150
- this.selectedFilterButtons = [];
151
- this.intervalFilterButtons = [];
152
- const filters = ((_a = this.state) === null || _a === void 0 ? void 0 : _a.dynamicFilters) || [];
153
- filters.forEach((filter) => {
144
+ /** Built here so the dynamicFilters read happens under render() and registers a subscription. */
145
+ buildChips() {
146
+ var _a, _b;
147
+ const intervalChips = [];
148
+ const selectedChips = [];
149
+ ((_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.dynamicFilters) !== null && _b !== void 0 ? _b : []).forEach((filter) => {
154
150
  if (filter.type === "interval") {
155
- this.collectIntervalButton(filter);
151
+ const chip = this.renderIntervalChip(filter);
152
+ if (chip)
153
+ intervalChips.push(chip);
156
154
  return;
157
155
  }
158
156
  if (!("values" in filter))
159
157
  return;
160
158
  filter.values.forEach(({ value, label, active }) => {
161
- if (isSubFilterActive(this.requestFilters, value, filter)) {
162
- this.selectedFilterButtons.push(RenderFilterButton({
163
- handleSubFilterSelection: this.handleSubFilterSelection,
164
- selectedFilter: filter,
165
- value,
166
- label,
167
- active,
168
- isSelected: true,
169
- showClose: true,
170
- }));
171
- }
159
+ if (!isSubFilterActive(this.requestFilters, value, filter))
160
+ return;
161
+ selectedChips.push(RenderFilterButton({
162
+ handleSubFilterSelection: this.handleSubFilterSelection,
163
+ selectedFilter: filter,
164
+ value,
165
+ label,
166
+ active,
167
+ isSelected: true,
168
+ showClose: true,
169
+ }));
172
170
  });
173
171
  });
172
+ return { intervalChips, selectedChips };
174
173
  }
175
174
  /** A chip exists only while the column has an applied interval to show. */
176
- collectIntervalButton(filter) {
175
+ renderIntervalChip(filter) {
177
176
  var _a;
178
177
  const applied = getSelectedInterval(this.requestFilters, filter.column);
179
178
  if (!applied)
180
- return;
179
+ return null;
181
180
  const label = getIntervalLabel(filter, applied, (_a = this.currencySign) !== null && _a !== void 0 ? _a : defaultConfig.currencySign, true);
182
181
  if (!label)
183
- return;
182
+ return null;
184
183
  const { column } = filter;
185
- this.intervalFilterButtons.push(h("div", { key: column }, RenderCustomButton({
184
+ return (h("div", { key: column }, RenderCustomButton({
186
185
  label,
187
186
  buttonType: "range",
188
187
  onClick: () => this.handleIntervalButtonClick(column),
@@ -190,10 +189,11 @@ export class VviinnSelectedFilters {
190
189
  }
191
190
  render() {
192
191
  var _a, _b;
192
+ const { intervalChips, selectedChips } = this.buildChips();
193
193
  if (this.showInWidget &&
194
- !this.selectedFilterButtons.length &&
194
+ !selectedChips.length &&
195
195
  !this.state.croppedImageUrl &&
196
- !this.intervalFilterButtons.length)
196
+ !intervalChips.length)
197
197
  return null;
198
198
  return (h(Host, { class: {
199
199
  "show-in-widget": this.showInWidget,
@@ -215,7 +215,7 @@ export class VviinnSelectedFilters {
215
215
  imageSrc: this.state.croppedImageUrl,
216
216
  onClick: this.handleCropButtonClick,
217
217
  hidden: !this.state.searchArea,
218
- }), this.intervalFilterButtons, this.selectedFilterButtons))));
218
+ }), intervalChips, selectedChips))));
219
219
  }
220
220
  static get is() { return "vviinn-selected-filters"; }
221
221
  static get encapsulation() { return "shadow"; }
@@ -29,7 +29,7 @@ export class VviinnImageSelector {
29
29
  this.vviinnImageUploadStarted.emit(Object.assign(Object.assign({}, this.basicEventData), { isTriggeredByVpsWidget: this.storeName === "widget" }));
30
30
  this.isProcessing = true;
31
31
  try {
32
- const processingResult = await makeUploadFileRequest(this.storeName, this.token, this.apiPath)(file);
32
+ const processingResult = await makeUploadFileRequest(this.storeName, this.token, { apiPath: this.apiPath })(file);
33
33
  pipe(processingResult, E.match(({ kind, code }) => {
34
34
  this.vviinnNoResult.emit(Object.assign(Object.assign({}, this.basicEventData), { reason: kind, errorCode: code }));
35
35
  }, (response) => {
@@ -98,13 +98,13 @@ export class VviinnImageSelector {
98
98
  }
99
99
  }
100
100
  render() {
101
- return (h(Host, { key: '616c751da82243f02d9d9cbc4f908702c49b3889', exportparts: this.useDragAndDrop ? "button:upload-photo_button" : "button", class: { "drag-over": this.isDragOver } }, this.useDragAndDrop && (h("div", { key: 'b02ad9a11981be6f13bd1347279fe4dad3046887', class: "drop-zone__hint", "aria-hidden": "true" }, h("span", { key: '9f5ed13a34f05cd9dd13aeddf3bfe166b84ee6f6', class: "drop-zone__icon" }, h("slot", { key: 'ccbadd5393155b7e2222d89afad490f43e93b0bc', name: "drop-zone-icon" })), h("span", { key: '0cd1cbaaadb326ef8d53bd8c895c9d72af8571a0', class: "drop-zone__text" }, h("slot", { key: '659b6e91869f7fbb1d73df37d6e25a54ebd200a1', name: "drop-zone-text" })))), h("label", { key: '3684c5e7afefa0403b8d760db89390530834d16d', htmlFor: "fileInput", part: "button", class: { loading: this.loading }, tabindex: this.loading ? -1 : 0, onKeyDown: (e) => {
101
+ return (h(Host, { key: '798b8ccc61af60c6a0794d52d5c86bd323aacf11', exportparts: this.useDragAndDrop ? "button:upload-photo_button" : "button", class: { "drag-over": this.isDragOver } }, this.useDragAndDrop && (h("div", { key: '0a0e5e4177265c0e7e4f691ccdbeb7769d8e060c', class: "drop-zone__hint", "aria-hidden": "true" }, h("span", { key: 'b1dbcbf92ce61c46587fe94857c59f9dea17c1b3', class: "drop-zone__icon" }, h("slot", { key: '156abf857a51a6843401b130043fa4c1fe5b5bfb', name: "drop-zone-icon" })), h("span", { key: '17a11fb8b274200b8436028b3295ea0f9b0b95ee', class: "drop-zone__text" }, h("slot", { key: 'f2226fbef3df72fd0f6f0d0974531a022fed1e31', name: "drop-zone-text" })))), h("label", { key: '235d62c02f871a85c90848ecc14dd8251feee7e9', htmlFor: "fileInput", part: "button", class: { loading: this.loading }, tabindex: this.loading ? -1 : 0, onKeyDown: (e) => {
102
102
  var _a;
103
103
  if (!this.loading && (e.key === "Enter" || e.key === " ")) {
104
104
  e.preventDefault();
105
105
  (_a = this.fileInput) === null || _a === void 0 ? void 0 : _a.click();
106
106
  }
107
- } }, this.loading ? (h("vviinn-preloader", null)) : (h("slot", { name: "upload-button-text" }, "Upload image"))), h("input", { key: '7d9cfd89c2d64cdf3c262e89f652da500dcc80ba', id: "fileInput", class: "visually-hidden", type: "file", tabindex: "-1", accept: getAcceptableFileFormats(), onChange: (event) => this.handleInputChange(event), ref: (el) => (this.fileInput = el) })));
107
+ } }, this.loading ? (h("vviinn-preloader", null)) : (h("slot", { name: "upload-button-text" }, "Upload image"))), h("input", { key: 'aeb6562fca0a11ea3da456813e61ddabb2cce708', id: "fileInput", class: "visually-hidden", type: "file", tabindex: "-1", accept: getAcceptableFileFormats(), onChange: (event) => this.handleInputChange(event), ref: (el) => (this.fileInput = el) })));
108
108
  }
109
109
  static get is() { return "vviinn-image-selector"; }
110
110
  static get encapsulation() { return "shadow"; }
@@ -93,7 +93,7 @@ export const resetSearchState = () => ({
93
93
  });
94
94
  export const performVisualSearch = async (params) => {
95
95
  try {
96
- const result = await makeVisualSearchByUrlRequest("shopTheLook", params.imageUrl, params.token, params.apiPath, params.campaignId);
96
+ const result = await makeVisualSearchByUrlRequest("shopTheLook", params.imageUrl, params.token, { apiPath: params.apiPath, campaignId: params.campaignId });
97
97
  return E.fold((error) => E.left(`Visual search failed: ${error.inner}`), (response) => {
98
98
  var _a, _b;
99
99
  const detectedObjects = ((_b = (_a = response.interactions) === null || _a === void 0 ? void 0 : _a.suggestedSearchAreas) === null || _b === void 0 ? void 0 : _b.map((area) => area.rectangle)) || [];
@@ -158,7 +158,10 @@ export const processFileUpload = async (params) => {
158
158
  try {
159
159
  const imageElement = await imageFromFileTask(file)();
160
160
  const imageUrl = imageElement.src;
161
- const uploadResult = await makeUploadFileRequest("shopTheLook", token, apiPath, campaignId)(file);
161
+ const uploadResult = await makeUploadFileRequest("shopTheLook", token, {
162
+ apiPath,
163
+ campaignId,
164
+ })(file);
162
165
  return E.fold((error) => E.left(`Upload failed: ${error.inner}`), (response) => {
163
166
  var _a, _b;
164
167
  const detectedObjects = ((_b = (_a = response.interactions) === null || _a === void 0 ? void 0 : _a.suggestedSearchAreas) === null || _b === void 0 ? void 0 : _b.map((area) => area.rectangle)) || [];
@@ -0,0 +1,4 @@
1
+ <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="128" height="128" fill="#E0EA0C"/>
3
+ <path d="M111 24L64.0328 110L17 24H39.8932L63.9672 69.6567L88.238 24H111Z" fill="#141413"/>
4
+ </svg>
@@ -0,0 +1,24 @@
1
+ /** Response- and request-shaped filters for specs, built against the generated types. */
2
+ export const categoricalFilter = (column, values) => ({
3
+ type: "categorical",
4
+ column,
5
+ label: column,
6
+ isPrimary: false,
7
+ values: values.map(({ value, selected }) => ({
8
+ value,
9
+ label: value,
10
+ active: true,
11
+ selected,
12
+ })),
13
+ });
14
+ export const intervalFilter = (column, selectedValues, full = { start: 0, end: 100 }) => ({
15
+ type: "interval",
16
+ column,
17
+ label: column,
18
+ isPrimary: false,
19
+ full,
20
+ selectedValues,
21
+ suggestions: [],
22
+ histogram: [],
23
+ });
24
+ export const appliedFilter = (column, values) => ({ column, values });
@@ -74,6 +74,7 @@ export const resetResultEvents = (store) => {
74
74
  state.resultLoaded = false;
75
75
  state.resultViewed = false;
76
76
  };
77
+ /** `excludedFields` names the fields the reset leaves alone. */
77
78
  export const resetStore = (store, mode = "appStateAndReceivedData", excludedFields = []) => {
78
79
  const state = useStore(store);
79
80
  let resetPayload = {};
@@ -90,11 +91,6 @@ export const resetStore = (store, mode = "appStateAndReceivedData", excludedFiel
90
91
  case "all":
91
92
  resetPayload = Object.assign({}, storeDefaults);
92
93
  break;
93
- case "manual":
94
- for (const key of excludedFields) {
95
- delete state[key];
96
- }
97
- return;
98
94
  }
99
95
  for (const key of excludedFields) {
100
96
  delete resetPayload[key];
@@ -158,7 +154,7 @@ const processVisualSearch = (store, body, token, apiPath, isHiResUpdate = false)
158
154
  return sessionResponse;
159
155
  }), TE.mapLeft(handleSearchError(store, isStale)));
160
156
  };
161
- const uploadImageFile = (store, token, imageType = "image", searchId, apiPath, campaignId, isHiResUpdate = false) => (file) => {
157
+ const uploadImageFile = (store, token, { apiPath, campaignId, imageType = "image", searchId, isHiResUpdate = false, } = {}) => (file) => {
162
158
  const state = useStore(store);
163
159
  return pipe(TE.fromEither(checkFileWithExtention(file)), TE.chainTaskK(resizeFileTo(imageType)), TE.chain((resizedFile) => updateImageState(store)(resizedFile)), TE.chain((resizedFile) => pipe(TE.tryCatch(async () => (Object.assign(Object.assign(Object.assign({ query: {
164
160
  [imageType]: (await fileToB64(resizedFile)).split(",")[1],
@@ -169,7 +165,7 @@ const uploadImageFile = (store, token, imageType = "image", searchId, apiPath, c
169
165
  inner: error,
170
166
  })), TE.chain((body) => processVisualSearch(store, body, token, apiPath, isHiResUpdate)))));
171
167
  };
172
- export const makeVisualSearchByUrlRequest = async (store, imageUrl, token, apiPath, campaignId) => {
168
+ export const makeVisualSearchByUrlRequest = async (store, imageUrl, token, { apiPath, campaignId } = {}) => {
173
169
  const state = useStore(store);
174
170
  const body = Object.assign(Object.assign({ query: {
175
171
  url: imageUrl,
@@ -178,7 +174,7 @@ export const makeVisualSearchByUrlRequest = async (store, imageUrl, token, apiPa
178
174
  } }, addNestedIfNotEmpty("staticFilters", Object.assign({}, addIfNotEmpty("excluded", state.excluded)))), addIfNotEmpty("campaign", campaignId || state.campaignIdVisualSearch || state.campaignId));
179
175
  return processVisualSearch(store, body, token, apiPath)();
180
176
  };
181
- export const makeUploadFileRequest = (store, token, apiPath, campaignId) => async (file) => {
177
+ export const makeUploadFileRequest = (store, token, options = {}) => async (file) => {
182
178
  var _a;
183
179
  const state = useStore(store);
184
180
  if (store !== "shopTheLook") {
@@ -191,13 +187,13 @@ export const makeUploadFileRequest = (store, token, apiPath, campaignId) => asyn
191
187
  visualSearchStarted: true,
192
188
  });
193
189
  }
194
- const session = await pipe(uploadImageFile(store, token, "image", undefined, apiPath, campaignId)(file))();
190
+ const session = await uploadImageFile(store, token, options)(file)();
195
191
  if (!((_a = state.visualSearchId) === null || _a === void 0 ? void 0 : _a.length))
196
192
  return session;
197
193
  const shouldProcessHiRes = await pipe(TE.fromTask(imageFromFileTask(file)), TE.map((img) => shouldResize(img, "highResolutionImage")), TE.getOrElse(() => T.of(false)))();
198
194
  if (!shouldProcessHiRes)
199
195
  return session;
200
- pipe(uploadImageFile(store, token, "highResolutionImage", state.visualSearchId, apiPath, campaignId, true)(file), TE.getOrElseW((error) => {
196
+ pipe(uploadImageFile(store, token, Object.assign(Object.assign({}, options), { imageType: "highResolutionImage", searchId: state.visualSearchId, isHiResUpdate: true }))(file), TE.getOrElseW((error) => {
201
197
  console.error("Failed to upload hi-res image:", error);
202
198
  return T.of(session);
203
199
  }))();
@@ -1,5 +1,5 @@
1
1
  import { h } from './index-B89nCb_F.js';
2
- import { h as addIfNotEmpty, p as parseStringToExcluded, n as isValueMatch, o as isIntervalMatch, q as valueToString, r as extractFilterValue } from './search.store-DOwsr2Al.js';
2
+ import { h as addIfNotEmpty, p as parseStringToExcluded, n as isValueMatch, o as isIntervalMatch, q as valueToString, r as extractFilterValue } from './search.store-X9fVl6Qr.js';
3
3
  import { i as instance } from './store-BJxQCbNV.js';
4
4
 
5
5
  const PlusIcon = () => (h("svg", { width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", class: "plus-icon", "aria-hidden": "true" },