{"version":3,"sources":["webpack:///./ClientApp/services/Localizer.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/svg/PlusThinSVG.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/svg/MinusThinSVG.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/Facet.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ConfigProvider.tsx","webpack:///./ClientApp/shared/polyfills/customEvent.js","webpack:///./ClientApp/features/search/RocHawkConfig.ts","webpack:///./ClientApp/features/tracking/trackers/commerce/hawksearch/tracking-commerce.ts","webpack:///./ClientApp/shared/components/svg/QuestionMarkCircleSVG.tsx","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Request.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Category.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Product.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Content.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Popular.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Response.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Pagination.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Result.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Sorting.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Selections.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Facets/Value.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Facets/Swatch.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Facets/Range.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Facets/Facet.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Rule.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Trigger.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Merchandising.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/PageContent.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/Response.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/ClientData.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Search/ContentType.ts","webpack:///./ClientApp/shared/components/hawksearch/store/HawkState.ts","webpack:///./ClientApp/shared/components/hawksearch/util/SearchTracking.ts","webpack:///./ClientApp/shared/components/hawksearch/util/MergableState.ts","webpack:///./ClientApp/shared/components/Spinner.tsx","webpack:///./ClientApp/shared/components/hawksearch/net/HawkClient.ts","webpack:///./ClientApp/shared/components/svg/MagnifyingGlassSVG.tsx","webpack:///./ClientApp/services/AxiosHelper.ts","webpack:///./ClientApp/shared/components/hawksearch/components/svg/CheckmarkSVG.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/svg/PlusCircleSVG.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/Checkbox.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/Search.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/Link.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/SliderNumericInputs.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/Slider.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/SwatchItem.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/Swatch.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/NestedItem.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/Nested.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/FacetTypes/OpenRange.tsx","webpack:///./ClientApp/shared/components/hawksearch/models/Facets/FacetType.ts","webpack:///./ClientApp/shared/components/hawksearch/components/ui/Facets/Overrides.ts","webpack:///./ClientApp/shared/components/hawksearch/components/ui/SearchBox/SearchSuggestionsList.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/SearchBox/SearchSuggestions.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/SearchBox/SearchBoxBase.tsx","webpack:///./ClientApp/shared/components/hawksearch/components/ui/SearchBox/GlobalSearchBox.tsx","webpack:///./ClientApp/shared/edit/InlineAlert.tsx","webpack:///./ClientApp/shared/components/svg/XSVG.tsx","webpack:///./ClientApp/services/UserData.ts","webpack:///./ClientApp/shared/components/hawksearch/styles/app.scss?a7f7","webpack:///./ClientApp/styles/node-modules/@reach/tooltip/styles.css?c65c","webpack:///./ClientApp/styles/node-modules/@reach/tooltip/styles.css","webpack:///./ClientApp/shared/util/AccountUrls.ts","webpack:///./ClientApp/shared/hooks/useRocEventHandler.tsx","webpack:///./ClientApp/shared/util/ErrorBoundary.tsx","webpack:///./ClientApp/shared/polyfills/getAttributeNames.js","webpack:///./ClientApp/shared/util/ApplicationInit.tsx","webpack:///./ClientApp/shared/hooks/useDelayedDisplay.tsx","webpack:///./ClientApp/features/tracking/trackers/hawksearch/tracking.ts","webpack:///./ClientApp/features/search/Search.tsx","webpack:///./ClientApp/shared/util/events/rocEventUtils.ts","webpack:///./ClientApp/shared/components/hawksearch/components/svg/DashCircleSVG.tsx","webpack:///./ClientApp/shared/components/hawksearch/helpers/Cookies.ts","webpack:///./ClientApp/shared/components/hawksearch/components/StoreProvider.tsx","webpack:///./ClientApp/services/ServerData.ts","webpack:///./ClientApp/util/StringUtil.ts","webpack:///./ClientApp/shared/components/hawksearch/util/Constants.ts","webpack:///./ClientApp/shared/components/hawksearch/store/Store.ts","webpack:///./ClientApp/shared/components/hawksearch/models/Autocomplete/Suggestion.ts"],"names":["LocalizerResources","isAlreadyLogged","initializeLocalizerResources","windowWithResources","window","__ROC_LOCALIZER_RESOURCES__","Array","isArray","forEach","obj","Object","keys","key","Localizer","replaceStrings","length","console","warn","resource","replace","match","index","LocalizedSpan","props","resourceKey","args","localizedString","data-testid","toKebabCase","dangerouslySetInnerHTML","__html","PlusThinSVG","viewBox","className","class","focusable","aria-hidden","d","MinusThinSVG","LazyTooltip","React","lazy","FacetContext","createContext","useFacet","useContext","Facet","facet","children","onFacetChange","searchActor","useHawkSearch","actor","wrapperRef","useRef","useState","filter","setFilter","shouldTruncate","isTruncated","setTruncated","IsCollapsible","IsCollapsedDefault","isCollapsed","setCollapsed","t","useTranslation","hasTooltip","Tooltip","facetValues","Values","shouldSearch","val","Label","toLowerCase","indexOf","remainingFacets","valuesBeforeTrunc","slice","TruncateThreshold","selectFacet","facetValue","toggleFacetValue","negateFacet","setFacets","values","setFacetValues","state","decimalPrecision","renderer","renderTruncation","onClick","Suspense","fallback","Spinner","Provider","value","classnames","type","event","current","contains","target","toggleCollapsible","aria-expanded","aria-describedby","Name","label","as","aria-label","QuestionMarkCircleSVG","id","style","DisplayType","ScrollHeight","height","overflowY","facetStyle","onChange","e","currentTarget","placeholder","ConfigContext","useHawkConfig","context","config","Error","ConfigProvider","assetPath","path","startsWith","endsWith","__webpack_public_path__","CustomEvent","params","bubbles","cancelable","detail","undefined","evt","document","createEvent","initCustomEvent","prototype","Event","searchState","__ROC_SEARCH_STATE__","RocHawkConfig","apiUrl","searchEndpoint","clientGuid","trackingKey","searchPageUrl","dashboardUrl","Constants","searchBoxPlaceholder","trackingUrl","recommendationUrl","recommendationEndpoint","organizationId","CommerceEventTrackingType","CommercePageType","CommerceSuggestType","trackCommerce","eventName","toLocaleLowerCase","orderNo","itemList","total","subTotal","tax","currency","payload","EventType","sale","EventData","preparePayload","OrderNo","ItemList","Total","Tax","SubTotal","Currency","makeRequest","uniqueId","price","quantity","addToCart","UniqueId","Quantity","Price","trackAddToCart","itemsList","add2CartMultiple","ItemsList","TrackAddToCartMultiple","rate","Value","trackRate","rest","stroke","strokeWidth","fill","fillRule","transform","Category","init","SuggestionType","assign","Suggestion","CategoryStrategy","item","downshift","location","Url","Product","Results","Result","ProductStrategy","ProductName","Content","ContentStrategy","Popular","PopularStrategy","Response","this","Categories","map","r","Products","Pagination","Items","i","PaginationItem","field","Document","Sorting","SortingItem","Selections","selFacet","SelectionFacet","SelectionFacetValue","Swatch","Range","SwatchData","s","Ranges","v","IsSearch","SearchThreshold","ParamName","Field","RuleType","RuleOperatorType","Rule","Parent","Rules","BannerTrigger","FeaturedItems","FeaturedItem","Merchandising","MerchandisingItem","PageContentItem","Trigger","PageContent","Facets","f","p","ContentType","CompareValueType","setSearchTracking","request","response","isLandingPage","CustomUrl","searchType","FacetSelections","MaxPerPage","PageNo","SearchType","Refinement","Initial","dispatchRocEvent","trackingId","TrackingId","useHawkState","initialSearch","initialValue","typeConstructor","setState","client","HawkClient","pendingSearch","Keyword","SearchStore","isLoading","itemsToCompare","comparedResults","itemsToCompareIds","prevState","newState","store","setStore","cancellationToken","getComparedItems","search","searchResults","searchParams","IsInPreview","isInPreview","ClientGuid","indexName","IndexName","keyword","query","Query","Success","axios","isCancel","error","requestError","setSearch","doHistory","setSearchSelections","selections","searchWithin","SearchWithin","useEffect","cts","CancelToken","source","token","cancel","negate","facetName","facetField","selectionField","valueValue","valueLabel","facetSelections","isFacetSelected","selState","selectionIndex","FacetSelectionState","Selected","Negated","splice","push","clearFacet","clearFacetValue","NotSelected","clearAllFacets","setItemsToCompare","resultItem","isCheck","itemsArray","DocId","setComparedResults","data","clearItemsToCompare","getCompareFieldValue","compareItem","fieldName","compareType","find","MultipleValueDecimal","parsedValues","rawValue","parseFloat","toFixed","toString","join","SingleValueString","MultipleValueString","light","waitMs","align","block","parentCentered","useDelayedDisplay","spinner","baseUrl","searchUrl","autocompleteUrl","recommendationWidgetUrl","compareItemsURL","post","URL","href","cancelToken","result","MagnifyingGlassSVG","AxiosHelper","create","defaults","headers","common","interceptors","use","method","getCsrfToken","csrfToken","RequestVerificationToken","addUnauthorizedAccessInterceptor","history","status","AccountUrls","Login","encodeURIComponent","pathname","Promise","reject","CheckmarkSVG","PlusCircleSVG","Checkbox","renderCheckMark","isSelected","renderFacetActions","isNegated","DashCircleSVG","FieldType","correspondingRange","c","rangeValueAssetUrl","AssetFullUrl","selectionState","aria-pressed","title","src","alt","textDecoration","Count","Search","hawkActor","input","setInput","searchInputRef","labelFor","FacetId","htmlFor","onKeyDown","ref","name","Link","LazyNumberFormat","SliderNumericInputs","sliderProps","minValue","setMinValue","maxValue","setMaxValue","reloadFacets","onValueChange","Number","thousandSeparator","isCurrency","prefix","currencySymbol","min","max","newMinValue","isNaN","onBlur","decimalScale","newMaxValue","Rheostat","Slider","range","Math","floor","RangeMin","rangeMin","setMinRange","ceil","RangeMax","rangeMax","setMaxRange","RangeStart","rangeStart","setStartRange","RangeEnd","rangeEnd","setEndRange","IsCurrency","setIsCurrency","CurrencySymbol","setCurrencySymbol","paramName","items","selectedValues","split","newRange","minVal","maxVal","selection","currentMinValue","currentMaxValue","SwatchItem","swatchValue","swatchUrl","suffix","facetSwatch","AssetUrl","AssetName","test","substring","getSwatchUrl","colorSwatchStyle","backgroundColor","Color","listItemClassNames","onSwatchSelected","isColor","NestedItem","isExpanded","setIsExpanded","setIsTruncated","hierarchyValue","hierarchyChildren","Children","remainingValues","shouldTruncateChildren","onValueSelected","Path","Nested","OpenRange","FacetType","setStartValue","setEndValue","startVal","endVal","data-type","defaultFacetComponents","facetType","component","DefaultCheckbox","NestedCheckbox","DefaultNestedCheckbox","DefaultSearch","DefaultLink","DefaultSlider","DefaultSwatch","DefaultOpenRange","defaultAutocompleteStrategies","strategy","getFacetComponents","overridedComponents","facetComponents","fType","fComponent","getAutocompleteStrategies","overridedStrategies","suggestionStrategies","sType","autocompleteStrategy","strategyMatch","SearchSuggestionsList","onViewMatches","popular","categories","products","content","PopularHeading","CategoryHeading","ProductHeading","ContentHeading","getItemProps","getMenuProps","highlightedIndex","isRecordEmpty","hasPopular","hasCategories","hasProducts","hasContent","hasAllEmpty","isAtleastOneExist","getAtleastOneExist","dynamicIndex","suggestType","TopProductMatches","itemName","url","Thumb","ViewAll","SearchSuggestions","results","setResults","setIsLoading","autocomplete","DisplayFullResponse","then","o","debounceMs","autocompleteDebounce","timeout","setTimeout","doAutocomplete","clearTimeout","Downshift","SearchBoxBase","onSubmit","strategies","autocompleteStrategies","stateReducer","changes","inputValue","itemToString","matchedStrategy","handleToString","handleItemChange","initialInputValue","options","isOpen","getInputProps","openMenu","showSuggestions","getLabelProps","onFocus","GlobalSearchBox","redirectToSearchPage","keywords","redirect","InlineAlert","defaultProps","theme","isTitleOnOwnRow","onCollapse","message","axiosError","isAxiosError","XSVG","userDataPromise","getUserData","get","getUserDataNoCache","userData","requestToken","api","__esModule","default","module","exports","locals","___CSS_LOADER_API_IMPORT___","BaseUrl","ServerData","ACCOUNT_URL_BASE","ACCOUNT_LOGIN_URL","Login2fa","ACCOUNT_LOGIN_WITH_2FA_URL","Register","ACCOUNT_REGISTER_URL","ForgotPassword","ACCOUNT_FORGOT_PASSWORD_URL","LoginWithRecoveryCode","ACCOUNT_LOGIN_WITH_RECOVERY_CODE_URL","Logout","ACCOUNT_LOGOUT_URL","OrganizationReview","ACCOUNT_ORGANIZATION_REVIEW_URL","OrganizationSelector","ACCOUNT_ORGANIZATION_SELECTOR_URL","eventType","dispatchEvent","useRocEventHandler","eventHandler","deps","removeHandlerCallback","addRocEventHandler","ErrorBoundary","renderError","Component","renderProps","Element","getAttributeNames","attributes","getDataPropsFromAttributes","element","attributeName","toCamelCase","getAttribute","initReactApp","getReactElement","elementId","getElementById","ReactDOM","render","initReactAppByAttribute","attribute","elements","querySelectorAll","display","setDisplay","EventTrackingType","PageType","SuggestType","createGuid","substr","random","btoa","JSON","stringify","HawkSearch","TrackingUrl","visitId","getCookie","visitorId","isNewVisitor","setCookie","Date","setTime","getTime","toUTCString","getVisitorExpiry","VisitId","VisitorId","TrackingProperties","Context","CustomDictionary","CustomContext","catch","initCustomEvents","readyState","addEventListener","ContextDictionary","remove","hasOwnProperty","existingValue","add","Tracking","track","pageType","documentElement","clientHeight","clientWidth","pageLoad","PageTypeId","RequestPath","Qs","ViewportHeight","ViewportWidth","typeId","queryId","QueryId","TypeId","trackSearchTracking","click","trackClick","bannerId","campaignId","bannerClick","CampaignId","BannerId","bannerImpression","trackBannerImpression","autoCompleteClick","widgetGuid","itemIndex","requestId","recommendationClick","ItemIndex","RequestId","WidgetGuid","trackRecommendationClick","hawkConfig","handler","removeEventListener","getVisitExpiry","nameEQ","ca","cookie","charAt","expiry","expires","HawkContext","StoreProvider","windowWithServerData","__ROC_SERVER_DATA__","initializeServerData","trim","word","toUpperCase","stripHtml","html","tmp","createElement","innerHTML","textContent","innerText","trimString","defaultApiUrl","defaultDashboardUrl","defaultSearchUrl","defaultAutocompleteUrl","defaultSearchPageUrl","defaultCompareItemsURL","defaultRecommendationUrl","initial","selectionIdx","negationIdx","selectedValue","selectionValue","matchingValue","findMatchingValue","clientSelections","facets","selectionValues","matchingVal","suggestionType"],"mappings":"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","file":"search.js","sourcesContent":["import { AddressResourceKeys } from 'features/address-book/resources';\r\nimport { ContactFormResourceKeys } from 'features/contact-form/resources';\r\nimport { CreatePasswordResourceKeys } from 'features/create-password/resources';\r\nimport { LoginWith2faResourceKeys } from 'features/login-with-2fa/resources';\r\nimport { LoginWithRecoveryCodeResourceKeys } from 'features/login-with-recovery-code/resources';\r\nimport { LoginResourceKeys } from 'features/login/resources';\r\nimport { MyAccountResourceKeys } from 'features/my-account/resources';\r\nimport { ResetPasswordResourceKeys } from 'features/reset-password/resources';\r\nimport { SubmitQuestionResourceKeys } from 'features/submit-question/resources';\r\nimport * as React from 'react';\r\nimport { toKebabCase } from 'util/StringUtil';\r\n\r\n// #region Commerce\r\nimport { CommerceResourceKeys } from 'features/commerce/CommerceResourceKeys';\r\n// #endregion\r\n\r\n// #region TapeCase Customization\r\nimport { SubmitQuoteResourceKeys } from 'features/submit-quote/resources';\r\nimport { TapeCaseRegistrationResourceKeys } from 'features/register-tapecase/resources';\r\nimport { CareersFormResourceKeys } from 'features/careers-form/resources';\r\nimport { FileUploadResourceKeys } from 'features/file-upload/resources';\r\n// #endregion\r\n\r\n/**\r\n * Type that will hold all the global localization keys\r\n */\r\ntype LocalizerGlobalResourceKeys =\r\n\t| 'Success'\r\n\t| 'OfTotalPages'\r\n\t| 'Cancel'\r\n\t| 'Confirm'\r\n\t| 'FirstName'\r\n\t| 'LastName'\r\n\t| 'Email'\r\n\t| 'Username'\r\n\t| 'Amount'\r\n\t| 'NameOnCard'\r\n\t| 'CardNumber'\r\n\t| 'ExpDate'\r\n\t| 'ExpMonth'\r\n\t| 'ExpYear'\r\n\t| 'Expires'\r\n\t| 'Expired'\r\n\t| 'SecurityCode'\r\n\t| 'Submit'\r\n\t| 'Save'\r\n\t| 'ZipCode'\r\n\t| 'Remove'\r\n\t| 'Removed'\r\n\t| 'Update'\r\n\t| 'Undo'\r\n\t| 'Cancel'\r\n\t| 'Enter'\r\n\t| 'Close'\r\n\t| 'SortBy'\r\n\t| 'PleaseWait'\r\n\t| 'Unknown'\r\n\t| 'Yes'\r\n\t| 'No'\r\n\t| 'Delete'\r\n\t| 'Update'\r\n\t| 'SaveAndContinueButtonText'\r\n\t| 'SaveAndContinue'\r\n\t| 'Continue'\r\n\t| 'SaveErrorMessage'\r\n\t| 'Edit'\r\n\t| 'ErrorMessageGenericTitle'\r\n\t| 'CheckEnteredValues'\r\n\t| 'ErrorMessageForbidden'\r\n\t| 'ErrorMessageNetwork'\r\n\t| 'ErrorOccurredSubmittingTheForm'\r\n\t| 'UnexpectedErrorOccurred'\r\n\t| 'Login'\r\n\t| 'ReturnToShipping'\r\n\t| 'BreadcrumbsLabel'\r\n\t| 'Other'\r\n\t| 'RememberMe'\r\n\t| 'ForgotYourPassword'\r\n\t| 'RegisterNewUserLinkText'\r\n\t| 'LoginPageTitleText'\r\n\t| 'ForgotPasswordPageTitle'\r\n\t| 'ForgotPasswordConfirmationPageTitle'\r\n\t| 'ForgotPasswordConfirmation'\r\n\t| 'Optional'\r\n\t| 'SearchBoxPlaceholder'\r\n\t| 'XOutOfYStars'\r\n\t| 'XToYOfZ'\r\n\t| 'ModalLabel'\r\n\t| 'RequiredFields'\r\n\t| 'Status'\r\n\t| 'Version'\r\n\t| 'CreatedOn'\r\n\t| 'CreatedBy'\r\n\t| 'ModifiedOn'\r\n\t| 'ModifiedBy'\r\n\t| 'OpenStatusInformation'\r\n\t| 'CloseStatusInformation'\r\n\t| 'SearchFilter'\r\n\t| 'Pagination'\r\n\t| 'Previous'\r\n\t| 'Next'\r\n\t| 'ClearFilter';\r\n\r\n/**\r\n * Type that will hold all the localization keys\r\n */\r\nexport type LocalizerResourceKey =\r\n\t| LocalizerGlobalResourceKeys\r\n\t| LoginResourceKeys\r\n\t| ContactFormResourceKeys\r\n\t// #region Commerce\r\n\t| CommerceResourceKeys\r\n\t// #endregion\r\n\t| ResetPasswordResourceKeys\r\n\t| CreatePasswordResourceKeys\r\n\t| SubmitQuestionResourceKeys\r\n\t| ResetPasswordResourceKeys\r\n\t| CreatePasswordResourceKeys\r\n\t| MyAccountResourceKeys\r\n\t| LoginWith2faResourceKeys\r\n\t| LoginWithRecoveryCodeResourceKeys\r\n\t| AddressResourceKeys\r\n\t// #region TapeCase Customization\r\n\t| SubmitQuoteResourceKeys\r\n\t| TapeCaseRegistrationResourceKeys\r\n\t| CareersFormResourceKeys\r\n\t| FileUploadResourceKeys;\r\n// #endregion\r\n\r\n/**\r\n * Interface for the resources\r\n *\r\n * @export\r\n * @interface LocalizerResource\r\n */\r\ninterface LocalizerResource {\r\n\t[id: string]: string;\r\n}\r\n\r\n/**\r\n * Extends Window with a property that will hold the localizer resources\r\n *\r\n * @interface WindowWithResources\r\n * @extends {Window}\r\n */\r\nexport interface WindowWithResources extends Window {\r\n\t__ROC_LOCALIZER_RESOURCES__?: LocalizerResource[];\r\n}\r\n\r\n/**\r\n * Main object that will hold all the localized resources\r\n */\r\nconst LocalizerResources: LocalizerResource = {};\r\n\r\n/**\r\n * To prevent redundant logging\r\n */\r\nconst isAlreadyLogged: Record = {};\r\n\r\n/**\r\n * Initializer function that will populate the main localized resources object\r\n */\r\nfunction initializeLocalizerResources() {\r\n\tconst windowWithResources = window as WindowWithResources;\r\n\r\n\tif (\r\n\t\twindowWithResources &&\r\n\t\twindowWithResources.__ROC_LOCALIZER_RESOURCES__ &&\r\n\t\tArray.isArray(windowWithResources.__ROC_LOCALIZER_RESOURCES__)\r\n\t) {\r\n\t\twindowWithResources.__ROC_LOCALIZER_RESOURCES__.forEach((obj) => {\r\n\t\t\tfor (const key of Object.keys(obj)) {\r\n\t\t\t\tLocalizerResources[key] = obj[key];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}\r\n\r\n/**\r\n * Function that can be used to load the localized strings with support to parameter replacements\r\n *\r\n * @export\r\n * @param {string} key\r\n * @param {...string[]} replaceStrings\r\n * @returns\r\n */\r\nexport function Localizer(\r\n\tkey: TResourceKey,\r\n\t...replaceStrings: string[]\r\n) {\r\n\tif (Object.keys(LocalizerResources).length === 0) {\r\n\t\tinitializeLocalizerResources();\r\n\t}\r\n\r\n\tif (!LocalizerResources || !LocalizerResources[key]) {\r\n\t\t// if running in a test environment, just skip any warnings.\r\n\t\tif (process.env.NODE_ENV !== 'test') {\r\n\t\t\tif (!isAlreadyLogged[key]) {\r\n\t\t\t\tconsole.warn(key, 'Localizer Resource not found. Key will be used instead.');\r\n\t\t\t\tisAlreadyLogged[key] = true;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn key;\r\n\t}\r\n\r\n\tconst resource = LocalizerResources[key];\r\n\r\n\tif (!replaceStrings) {\r\n\t\treturn resource;\r\n\t}\r\n\r\n\treturn resource.replace(/{(\\d+)}/g, (match: string, index: number) => {\r\n\t\treturn replaceStrings[index] ? replaceStrings[index] : '';\r\n\t});\r\n}\r\n\r\n/**\r\n * Interface for the LocalizedSpan component\r\n *\r\n * @interface LocalizedSpanProps\r\n */\r\ninterface LocalizedSpanProps {\r\n\tresourceKey: LocalizerResourceKey;\r\n\targs?: string[];\r\n}\r\n\r\n/**\r\n * Component responsible for the initialization of the react app\r\n */\r\nexport function LocalizedSpan(props: LocalizedSpanProps) {\r\n\tconst { resourceKey, args = [] } = props;\r\n\tconst localizedString = Localizer(resourceKey, ...args);\r\n\r\n\treturn (\r\n\t\t\r\n\t);\r\n}\r\n","import * as React from 'react';\r\n\r\ninterface PlusSVGProps {\r\n\tclass?: string;\r\n}\r\n\r\n/**\r\n * Plus SVG\r\n *\r\n * @returns\r\n */\r\nfunction PlusThinSVG(props: PlusSVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default PlusThinSVG;\r\n","import * as React from 'react';\r\n\r\ninterface MinusSVGProps {\r\n\tclass?: string;\r\n}\r\n\r\n/**\r\n * Minus SVG\r\n *\r\n * @returns\r\n */\r\nfunction MinusThinSVG(props: MinusSVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default MinusThinSVG;\r\n","import React, { useContext, useState, useRef, MouseEvent } from 'react';\r\nimport { Facet as FacetModel, Value } from 'models/Facets';\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport PlusThinSVG from 'components/svg/PlusThinSVG';\r\nimport MinusThinSVG from 'components/svg/MinusThinSVG';\r\nimport { useTranslation } from 'react-i18next';\r\nimport type Tooltip from '@reach/tooltip';\r\nimport 'styles/node-modules/@reach/tooltip/styles.css';\r\nimport QuestionMarkCircleSVG from 'shared/components/svg/QuestionMarkCircleSVG';\r\nimport Spinner from 'shared/components/Spinner';\r\nimport classnames from 'classnames';\r\nconst LazyTooltip = React.lazy(() => import('@reach/tooltip'));\r\nconst FacetContext = React.createContext({} as FacetContextValue);\r\n\r\nexport interface FacetProps {\r\n\tfacet: FacetModel;\r\n\tchildren: React.ReactNode;\r\n\tonFacetChange: () => void;\r\n}\r\n\r\ninterface FacetContextValue {\r\n\t/** The facet model returned from the server for this facet. */\r\n\tfacet: FacetModel;\r\n\r\n\t/** Returns the state of the parent facet container. */\r\n\tstate: FacetState;\r\n\r\n\t/** An actor interface to perform actions for this facet. */\r\n\tactor: FacetActor;\r\n\r\n\trenderer: FacetRenderer;\r\n}\r\n\r\nexport interface FacetState {\r\n\t/**\r\n\t * An array of facet values for this facet. If this facet has a quick lookup search bar, this list\r\n\t * will be filtered by this quick lookup.\r\n\t */\r\n\tfacetValues: Value[];\r\n\r\n\t/**\r\n\t * If the facet is configured for filtering, this is the user's entered filter value. Updated on\r\n\t * immediately when the user types.\r\n\t */\r\n\tfilter: string;\r\n\r\n\t/** Whether or not this facet has its values truncated. */\r\n\tisTruncated: boolean;\r\n\r\n\t/** Whether or not this facet is collapsed. */\r\n\tisCollapsed: boolean;\r\n\r\n\t/** If filter is enabled, contains the number of facets that are truncated. */\r\n\tremainingFacets: number;\r\n\r\n\t/** The number of digits displayed after the decimal points for numeric facet values. */\r\n\tdecimalPrecision: number;\r\n}\r\n\r\nexport interface FacetActor {\r\n\t/** Select the given facet value. */\r\n\tselectFacet(facetValue: Value | string): void;\r\n\r\n\t/** Selects and negates the given facet value. */\r\n\tnegateFacet(facetValue: Value | string): void;\r\n\r\n\t/** Sets the selected facet values by replacing existing selections for this facet. */\r\n\tsetFacets(facetValues: Value[] | string[]): void;\r\n\r\n\t/** Sets the filter for this facet container. */\r\n\tsetFilter(filter: string): void;\r\n\r\n\t/** Sets whether or not this facet is currently being truncated. */\r\n\tsetTruncated(truncated: boolean): void;\r\n\r\n\t/** Sets whether or not this facet is currently collapsed. */\r\n\tsetCollapsed(collapsed: boolean): void;\r\n}\r\n\r\nexport interface FacetRenderer {\r\n\t/**\r\n\t * Conditionally renders the default truncation UI (the \"Show More\"/\"Show Less\" buttons). Nothing will render\r\n\t * if the facet is configured to not be truncated.\r\n\t */\r\n\trenderTruncation();\r\n}\r\n\r\nfunction Facet({ facet, children, onFacetChange }: FacetProps) {\r\n\tconst { actor: searchActor } = useHawkSearch();\r\n\tconst wrapperRef = useRef(null);\r\n\tconst [filter, setFilter] = useState('');\r\n\tconst [isTruncated, setTruncated] = useState(facet.shouldTruncate);\r\n\tconst [isCollapsed, setCollapsed] = useState(facet.IsCollapsible && facet.IsCollapsedDefault);\r\n\tconst { t } = useTranslation();\r\n\r\n\tconst hasTooltip = !!facet.Tooltip;\r\n\r\n\tfunction selectFacet(facetValue: Value | string): void {\r\n\t\tsetFilter('');\r\n\t\tsearchActor.toggleFacetValue(facet, facetValue);\r\n\t\tonFacetChange();\r\n\t}\r\n\r\n\tfunction setFacets(values: Value[] | string[]): void {\r\n\t\tsetFilter('');\r\n\t\tsearchActor.setFacetValues(facet, values);\r\n\t\tonFacetChange();\r\n\t}\r\n\r\n\tfunction negateFacet(facetValue: Value | string): void {\r\n\t\tsetFilter('');\r\n\t\tsearchActor.toggleFacetValue(facet, facetValue, /* negate */ true);\r\n\t\tonFacetChange();\r\n\t}\r\n\r\n\tfunction renderTruncation() {\r\n\t\t// only show the toggle button if the facet is configured for truncation and we're not filtering\r\n\r\n\t\treturn (\r\n\t\t\t<>\r\n\t\t\t\t{facet.shouldTruncate && !filter && (\r\n\t\t\t\t\t\r\n\t\t\t\t)}\r\n\t\t\t\r\n\t\t);\r\n\t}\r\n\r\n\t// TODO: sort facet values\r\n\tlet facetValues = facet.Values;\r\n\r\n\t// first, perform any filtering if enabled and a filter has been typed in\r\n\tif (facet.shouldSearch && filter) {\r\n\t\tfacetValues = facet.Values.filter((val) => {\r\n\t\t\tif (!val.Label) {\r\n\t\t\t\t// if a facet value doesn't have a label, we can't really filter down to it\r\n\t\t\t\t// so exclude it\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\r\n\t\t\treturn val.Label.toLowerCase().indexOf(filter.toLowerCase()) !== -1;\r\n\t\t});\r\n\t}\r\n\r\n\t// next, handle truncation\r\n\tlet remainingFacets = 0;\r\n\r\n\tif (facet.shouldTruncate && isTruncated) {\r\n\t\tconst valuesBeforeTrunc = facetValues.length;\r\n\r\n\t\tfacetValues = facetValues.slice(0, facet.TruncateThreshold);\r\n\r\n\t\tremainingFacets = valuesBeforeTrunc - facet.TruncateThreshold;\r\n\t}\r\n\r\n\tconst actor: FacetActor = {\r\n\t\tselectFacet,\r\n\t\tnegateFacet,\r\n\t\tsetFacets,\r\n\t\tsetFilter,\r\n\t\tsetTruncated,\r\n\t\tsetCollapsed,\r\n\t};\r\n\r\n\tconst state: FacetState = {\r\n\t\tfacetValues,\r\n\t\tfilter,\r\n\t\tisTruncated,\r\n\t\tisCollapsed,\r\n\t\tremainingFacets,\r\n\t\tdecimalPrecision: 2,\r\n\t};\r\n\r\n\tconst renderer: FacetRenderer = {\r\n\t\trenderTruncation,\r\n\t};\r\n\r\n\tfunction toggleCollapsible(event: MouseEvent) {\r\n\t\tif (wrapperRef.current && wrapperRef.current.contains(event.target as Node)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tsetCollapsed(!isCollapsed);\r\n\t}\r\n\r\n\tfunction facetStyle(facet: FacetModel) {\r\n\t\tif (facet.DisplayType === 'scrolling' && facet.ScrollHeight) {\r\n\t\t\treturn {\r\n\t\t\t\theight: facet.ScrollHeight,\r\n\t\t\t\toverflowY: 'auto',\r\n\t\t\t} as React.CSSProperties;\r\n\t\t}\r\n\t\treturn {};\r\n\t}\r\n\r\n\treturn (\r\n\t\t}>\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\t toggleCollapsible(event)}\r\n\t\t\t\t\t\t\taria-expanded={!isCollapsed}\r\n\t\t\t\t\t\t\taria-describedby={'hawk-facet-rail-facet-heading-' + facet.Name}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t

{facet.Name}

\r\n\r\n\t\t\t\t\t\t\t{isCollapsed ? (\r\n\t\t\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\t\t{' '}\r\n\t\t\t\t\t\t\t\t\tExpand facet category{' '}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t) : (\r\n\t\t\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\t\t{' '}\r\n\t\t\t\t\t\t\t\t\tCollapse facet category\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t{facet.Tooltip ? (\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t) : null}\r\n\t\t\t\t\t
\r\n\r\n\t\t\t\t\t
\r\n\t\t\t\t\t\tClicking this button will display a list of tabbable {facet.Name} values below. Tab down to\r\n\t\t\t\t\t\tinteract with them.\r\n\t\t\t\t\t
\r\n\r\n\t\t\t\t\t{!isCollapsed && (\r\n\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t{facet.shouldSearch && (\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t\t setFilter(e.currentTarget.value)}\r\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\r\n\t\t\t\t\t\t\t\t\t\tplaceholder={t('Quick Lookup')}\r\n\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t)}\r\n\r\n\t\t\t\t\t\t\t{/* render listing component */}\r\n\t\t\t\t\t\t\t{children}\r\n\t\t\t\t\t\t
\r\n\t\t\t\t\t)}\r\n\t\t\t\t\r\n\t\t\t
\r\n\t\t
\r\n\t);\r\n}\r\n\r\nexport function useFacet() {\r\n\treturn useContext(FacetContext);\r\n}\r\n\r\nexport default Facet;\r\n","/*eslint camelcase: \"off\"*/\r\nimport React, { useContext } from 'react';\r\n\r\nimport { HawkSearchConfig } from 'types/HawkSearchConfig';\r\n\r\nconst ConfigContext = React.createContext({} as ConfigContextValue);\r\n\r\ndeclare global {\r\n\tinterface Window {\r\n\t\t__webpack_public_path__: string;\r\n\t}\r\n}\r\n\r\nexport interface ConfigContextValue {\r\n\t/** Global configuration. */\r\n\tconfig: HawkSearchConfig;\r\n}\r\n\r\nexport interface ConfigProviderProps {\r\n\tconfig: HawkSearchConfig;\r\n\tchildren: React.ReactNode;\r\n}\r\n\r\nfunction ConfigProvider({ config, children }: ConfigProviderProps) {\r\n\tif (config.assetPath) {\r\n\t\tlet path = config.assetPath;\r\n\r\n\t\t// ensure the provided path both starts and ends with a slash\r\n\t\tif (!path.startsWith('/')) {\r\n\t\t\tpath = '/' + path;\r\n\t\t}\r\n\t\tif (!path.endsWith('/')) {\r\n\t\t\tpath = path + '/';\r\n\t\t}\r\n\r\n\t\t// allow consumers to tell webpack where to load code split/lazy loaded files from, as they may not be\r\n\t\t// hosting our JS from /assets/ (the default path)\r\n\t\t// eslint-disable-next-line\r\n\t\twindow.__webpack_public_path__ = path;\r\n\t}\r\n\r\n\treturn {children};\r\n}\r\n\r\nexport function useHawkConfig() {\r\n\tconst context = useContext(ConfigContext);\r\n\r\n\tif (!context.config) {\r\n\t\tthrow new Error(\r\n\t\t\t'No HawkSearchConfig is available, did you forget to wrap your components in a ConfigProvider component?',\r\n\t\t);\r\n\t}\r\n\r\n\treturn context;\r\n}\r\n\r\nexport default ConfigProvider;\r\n","// source: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent\r\n(function () {\r\n\tif (typeof window.CustomEvent === 'function') {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tfunction CustomEvent(event, params) {\r\n\t\tparams = params || { bubbles: false, cancelable: false, detail: undefined };\r\n\t\t// eslint-disable-next-line\r\n\t\tvar evt = document.createEvent('CustomEvent');\r\n\t\tevt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\r\n\t\treturn evt;\r\n\t}\r\n\r\n\tCustomEvent.prototype = window.Event.prototype;\r\n\r\n\twindow.CustomEvent = CustomEvent;\r\n})();\r\n","import { HawkSearchConfig } from 'shared/components/hawksearch/types/HawkSearchConfig';\r\nimport * as Constants from 'util/Constants';\r\nimport { Localizer } from 'services/Localizer';\r\n\r\nconst searchState = (window as any).__ROC_SEARCH_STATE__;\r\n\r\nconst RocHawkConfig: HawkSearchConfig = {\r\n\tapiUrl: searchState.searchEndpoint as string,\r\n\tclientGuid: searchState.trackingKey as string,\r\n\tsearchPageUrl: (searchState.searchPageUrl as string) || '/search',\r\n\tdashboardUrl: (searchState.dashboardUrl as string) || Constants.defaultDashboardUrl,\r\n\tsearchBoxPlaceholder: Localizer('SearchBoxPlaceholder'),\r\n\ttrackingUrl: searchState.trackingUrl as string,\r\n\t/* #region Commerce */\r\n\trecommendationUrl: searchState.recommendationEndpoint as string,\r\n\t/* #endregion */\r\n\t/* #region TapeCase */\r\n\torganizationId: searchState.organizationId as string,\r\n\t/* #endregion */\r\n};\r\n\r\nexport default RocHawkConfig;\r\n","import { ExtractEventParameters } from 'shared/events';\r\nimport { makeRequest, preparePayload } from '../../hawksearch/tracking';\r\n\r\nexport enum CommerceEventTrackingType {\r\n\taddToCart = 4,\r\n\trate = 5,\r\n\tsale = 6,\r\n\tadd2CartMultiple = 14,\r\n}\r\n\r\n/**\r\n * The page type\r\n */\r\nexport enum CommercePageType {\r\n\t/**\r\n\t * Item detail page (i.e. PDP)\r\n\t */\r\n\titem = 1,\r\n\t/**\r\n\t * Shopping Cart Page\r\n\t */\r\n\tcart = 3,\r\n\t/**\r\n\t * Order Confirmation Page\r\n\t */\r\n\torder = 4,\r\n}\r\n\r\nexport enum CommerceSuggestType {\r\n\tTopCategories = 2,\r\n\tTopProductMatches = 3,\r\n}\r\n\r\ntype CommerceHawkEvents =\r\n\t| ({ name: 'sale' } & TrackSaleArgs)\r\n\t| ({ name: 'add2cart' } & TrackAddToCartArgs)\r\n\t| ({ name: 'add2cartmultiple' } & TrackAddToCartMultipleArgs)\r\n\t| ({ name: 'rate' } & TrackRateArgs);\r\n\r\nexport type CommerceHawkEventType = CommerceHawkEvents['name'];\r\n\r\nexport function trackCommerce(\r\n\teventName: T,\r\n\targs: ExtractEventParameters,\r\n) {\r\n\tswitch (eventName.toLocaleLowerCase()) {\r\n\t\tcase 'sale':\r\n\t\t\t//HawkSearch.Tracking.track('sale', {orderNo: 'order_123',itemList: [{uniqueid: '123456789', itemPrice: 12.99, quantity: 2}], total: 25.98, subTotal: 22, tax: 3.98, currency: 'USD'});\r\n\t\t\treturn trackSale((args as unknown) as TrackSaleArgs);\r\n\t\tcase 'add2cart':\r\n\t\t\t//HawkSearch.Tracking.track('add2cart',{uniqueId: '123456789', price: 19.99, quantity: 3, currency: 'USD'});\r\n\t\t\treturn trackAddToCart((args as unknown) as TrackAddToCartArgs);\r\n\t\tcase 'add2cartmultiple':\r\n\t\t\t//HawkSearch.Tracking.track('add2cartmultiple', [{uniqueId: '123456789',price: 15.97,quantity: 1,currency: 'USD'},{uniqueId: '987465321', price: 18.00, quantity: 1, currency: 'USD'}]);\r\n\t\t\treturn TrackAddToCartMultiple((args as unknown) as TrackAddToCartMultipleArgs);\r\n\t\tcase 'rate':\r\n\t\t\t//HawkSearch.Tracking.track('rate', {uniqueId: '123456789',value: 3.00});\r\n\t\t\treturn trackRate((args as unknown) as TrackRateArgs);\r\n\t}\r\n}\r\n\r\nexport type TrackSaleItemArgs = {\r\n\t/**\r\n\t * Represents the unique identifier of a product. This should correspond to the value of the field set up as the primary key in the fields section of Hawksearch dashboard\r\n\t */\r\n\tuniqueId: string;\r\n\t/**\r\n\t * Represents a single item price\r\n\t */\r\n\titemPrice: number;\r\n\t/**\r\n\t * The number of items being added to the cart\r\n\t */\r\n\tquantity: number;\r\n};\r\n\r\ntype TrackSaleArgs = {\r\n\t/**\r\n\t * The alphanumeric value representing the order number\r\n\t */\r\n\torderNo: string;\r\n\t/**\r\n\t * Is an array of objects that stores information about items. To see object properties check Sale Item Info Model below.\r\n\t */\r\n\titemList: TrackSaleItemArgs[];\r\n\t/**\r\n\t * The actual order total amount\r\n\t */\r\n\ttotal?: number;\r\n\t/**\r\n\t * The order the sub total amoun\r\n\t */\r\n\tsubTotal?: number;\r\n\t/**\r\n\t * The tax value\r\n\t */\r\n\ttax?: number;\r\n\t/**\r\n\t * The actual currency in ISO format\r\n\t */\r\n\tcurrency?: string;\r\n};\r\n\r\nfunction trackSale({ orderNo, itemList, total, subTotal, tax, currency }: TrackSaleArgs) {\r\n\tconst payload = {\r\n\t\tEventType: CommerceEventTrackingType.sale,\r\n\t\tEventData: preparePayload({\r\n\t\t\tOrderNo: orderNo,\r\n\t\t\tItemList: itemList,\r\n\t\t\tTotal: total,\r\n\t\t\tTax: tax,\r\n\t\t\tSubTotal: subTotal,\r\n\t\t\tCurrency: currency,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\nexport type TrackAddToCartArgs = {\r\n\t/**\r\n\t * Represents the unique identifier of a product. This should correspond to the value of the field set up as the primary key in the fields section of Hawksearch dashboard\r\n\t */\r\n\tuniqueId: string;\r\n\t/**\r\n\t * Represents a single item price\r\n\t */\r\n\tprice: number;\r\n\t/**\r\n\t * The number of items being added to the cart\r\n\t */\r\n\tquantity: number;\r\n\t/**\r\n\t * Actual currency in ISO format\r\n\t */\r\n\tcurrency: string;\r\n};\r\n\r\nfunction trackAddToCart({ uniqueId, price, quantity, currency }: TrackAddToCartArgs) {\r\n\tconst payload = {\r\n\t\tEventType: CommerceEventTrackingType.addToCart,\r\n\t\tEventData: preparePayload({\r\n\t\t\tUniqueId: uniqueId,\r\n\t\t\tQuantity: quantity,\r\n\t\t\tPrice: price,\r\n\t\t\tCurrency: currency,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackAddToCartMultipleArgs = {\r\n\t/**\r\n\t * Is an array of objects that stores information about items\r\n\t */\r\n\titemsList: TrackAddToCartArgs[];\r\n};\r\n\r\nfunction TrackAddToCartMultiple({ itemsList }: TrackAddToCartMultipleArgs) {\r\n\tconst payload = {\r\n\t\tEventType: CommerceEventTrackingType.add2CartMultiple,\r\n\t\tEventData: preparePayload({\r\n\t\t\tItemsList: itemsList,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackRateArgs = {\r\n\t/**\r\n\t * The unique identifier of an item. In many cases the uniqueId is different than SKU.\r\n\t */\r\n\tuniqueId: string;\r\n\t/**\r\n\t * Represents a user’s rating for an item. The decimal value must be between 1 and 5.\r\n\t */\r\n\tvalue: number;\r\n};\r\n\r\nfunction trackRate({ uniqueId, value }: TrackRateArgs) {\r\n\tconst payload = {\r\n\t\tEventType: CommerceEventTrackingType.rate,\r\n\t\tEventData: preparePayload({\r\n\t\t\tUniqueId: uniqueId,\r\n\t\t\tValue: value,\r\n\t\t}),\r\n\t};\r\n\tmakeRequest(payload);\r\n}\r\n","import React from 'react';\r\nimport { SVGProps } from './SVGProps';\r\nimport classnames from 'classnames';\r\n\r\n/**\r\n * Question Mark within a Circle SVG\r\n */\r\nfunction QuestionMarkCircleSVG({ className, ...rest }: SVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default QuestionMarkCircleSVG;\r\n","import { ClientData } from 'models/Search';\r\n\r\nexport class Request {\r\n\t/**\r\n\t * API Client Guid. Usually comes from the \"Tracking Key\" in the \"Account Info\" section of the hawk dashboard.\r\n\t */\r\n\tpublic ClientGuid: string;\r\n\r\n\t/**\r\n\t * Search term entered by a user. If keyword is not included, all items configured to be returned will be\r\n\t * returned. When this parameter is populated, the results will be matched against this term by the search\r\n\t * engine.\r\n\t */\r\n\tpublic Keyword?: string;\r\n\r\n\t/**\r\n\t * This is used by the Hawksearch Preview to set to true will display elements in a preview mode.\r\n\t *\r\n\t * You can use this if you desire additional score information returned.\r\n\t */\r\n\tpublic IsInPreview?: boolean;\r\n\r\n\tpublic Type?: 'Category' | 'Product' | 'Content' | 'Popular';\r\n\r\n\t/** The maximum number of results to return for selected @see Type */\r\n\tpublic ProductCount?: number;\r\n\r\n\t/** Flag set to true will display also full Document object from Elastic for Products and Content suggestions. */\r\n\tpublic DisplayFullResponse?: boolean;\r\n\r\n\t/**\r\n\t * An array of field names that will be returned in the response. If provided, only the fields listed will\r\n\t * be returned. If no FieldOverride value is sent, the Workbench configuration will be used.\r\n\t *\r\n\t * If the Skip from Custom flag is turned “on” for a field, it will not be returned in the response, even if\r\n\t * set in the FieldOverride parameter.\r\n\t */\r\n\tpublic FieldOverride?: string[];\r\n\r\n\t/** Client data. */\r\n\tpublic ClientData?: ClientData;\r\n\tpublic IndexName?: string;\r\n}\r\n","import { Suggestion, SuggestionType, SuggestionStrategy } from './Suggestion';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\n\r\nexport class Category extends Suggestion {\r\n\t/** Display name of category (example: Men » Jackets). */\r\n\tpublic Value: string;\r\n\t/**\r\n\t * URL for displaying contents of the category, ex:\r\n\t * http://hawk-dev.americaneagle.com/sites/elasticdemo?department_nest=Jackets_4\r\n\t */\r\n\tpublic Url: string;\r\n\r\n\tpublic constructor(init: Category) {\r\n\t\tsuper(SuggestionType.Category);\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n\r\nexport class CategoryStrategy implements SuggestionStrategy {\r\n\t// eslint-disable-next-line no-unused-vars\r\n\tpublic handleItemChange(item: Category, downshift: ControllerStateAndHelpers): void {\r\n\t\tlocation.assign(item.Url);\r\n\t}\r\n\r\n\tpublic toString(item: Category): string {\r\n\t\treturn item.Value;\r\n\t}\r\n}\r\n","import { Result } from 'models/Search';\r\nimport { Suggestion, SuggestionStrategy, SuggestionType } from './Suggestion';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\n\r\nexport class Product extends Suggestion {\r\n\t/** Name of the item (if applicable). */\r\n\tpublic ProductName: string;\r\n\r\n\t/* Sku of the item (if applicable). */\r\n\tpublic Sku: string;\r\n\r\n\t/** URL of image of the item (if applicable). */\r\n\tpublic Thumb: string;\r\n\r\n\t/** URL of product page (if applicable). */\r\n\tpublic Url: string;\r\n\r\n\t/** HTML to display the item in autocomplete. */\r\n\tpublic Html: string;\r\n\r\n\t/**\r\n\t * This will only be populated if the request parameter @see Request.DisplayFullResponse is sent\r\n\t * as `true`.\r\n\t */\r\n\tpublic Results: Result;\r\n\r\n\tpublic constructor(init: Product) {\r\n\t\tsuper(SuggestionType.Product);\r\n\t\tObject.assign(this, init);\r\n\t\tthis.Results = new Result(init.Results);\r\n\t}\r\n}\r\n\r\nexport class ProductStrategy implements SuggestionStrategy {\r\n\t// eslint-disable-next-line no-unused-vars\r\n\tpublic handleItemChange(item: Product, downshift: ControllerStateAndHelpers): void {\r\n\t\tlocation.assign(item.Url);\r\n\t}\r\n\r\n\tpublic toString(item: Product): string {\r\n\t\treturn item.ProductName;\r\n\t}\r\n}\r\n","import { Result } from 'models/Search';\r\nimport { SuggestionType, Suggestion, SuggestionStrategy } from './Suggestion';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\n\r\nexport class Content extends Suggestion {\r\n\t/** Display label for the content item in Autocomplete. */\r\n\tpublic Value: string;\r\n\r\n\t/** The URL for the link created. */\r\n\tpublic Url: string;\r\n\r\n\t/** The display label in HTML format, if applicable. */\r\n\tpublic Html: string;\r\n\r\n\tpublic Results: Result;\r\n\r\n\tpublic constructor(init: Content) {\r\n\t\tsuper(SuggestionType.Content);\r\n\t\tObject.assign(this, init);\r\n\t\tthis.Results = new Result(init.Results);\r\n\t}\r\n}\r\n\r\nexport class ContentStrategy implements SuggestionStrategy {\r\n\t// eslint-disable-next-line no-unused-vars\r\n\tpublic handleItemChange(item: Content, downshift: ControllerStateAndHelpers): void {\r\n\t\tlocation.assign(item.Url);\r\n\t}\r\n\r\n\tpublic toString(item: Content): string {\r\n\t\treturn item.Value;\r\n\t}\r\n}\r\n","import { SuggestionType, Suggestion, SuggestionStrategy } from './Suggestion';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\n\r\nexport class Popular extends Suggestion {\r\n\t/** Display label for the popular search term. */\r\n\tpublic Value: string;\r\n\r\n\t/** The URL for the link created. */\r\n\tpublic Url: string;\r\n\r\n\tpublic constructor(init: Popular) {\r\n\t\tsuper(SuggestionType.Popular);\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n\r\nexport class PopularStrategy implements SuggestionStrategy {\r\n\t// eslint-disable-next-line no-unused-vars\r\n\tpublic handleItemChange(item: Popular, downshift: ControllerStateAndHelpers): void {\r\n\t\tlocation.assign(item.Url);\r\n\t}\r\n\r\n\tpublic toString(item: Popular): string {\r\n\t\treturn item.Value;\r\n\t}\r\n}\r\n","import { Category } from './Category';\r\nimport { Product } from './Product';\r\nimport { Content } from './Content';\r\nimport { Popular } from './Popular';\r\n\r\nexport class Response {\r\n\t/** Number of products that would be in search results if search was executed. */\r\n\tpublic Count: number;\r\n\t/** Number of content items that would be in search results if search was executed. */\r\n\tpublic ContentCount: number;\r\n\r\n\t/**\r\n\t * Pairs of display values and URLs for matching category names. The number of categories returned\r\n\t * is configured in the Hawksearch Workbench unless overridden by the request parameters.\r\n\t */\r\n\tpublic Categories: Category[];\r\n\r\n\tpublic Products: Product[];\r\n\r\n\t/**\r\n\t * A set of objects for each content item returned. The number returned is configured in the\r\n\t * Hawksearch Workbench > Keyword Search > Auto-complete > Update Top Content.\r\n\t */\r\n\tpublic Content: Content[];\r\n\r\n\t/**\r\n\t * A set of Value and Url for each popular search term. The definition of Popular can be defined in\r\n\t * the Hawksearch Workbench > Keyword Search > Auto-complete > Update Popular Searches.\r\n\t */\r\n\tpublic Popular: Popular[];\r\n\r\n\t/** Search website URL to be used to complete links. */\r\n\tpublic SearchWebsiteUrl: string;\r\n\r\n\t/** The name of the parameter used to pass the keyword entered by user. */\r\n\tpublic KeywordField: string;\r\n\r\n\t/**\r\n\t * Will be included in the response if there are results to display. The `CategoryHeading` contains\r\n\t * the text to display above the list of categories to display in Autocomplete.\r\n\t */\r\n\tpublic CategoryHeading?: string;\r\n\r\n\t/**\r\n\t * Will be included in the response if there are results to display. The `ContentHeading` contains\r\n\t * the text to display above the list of content items to display in Autocomplete.\r\n\t */\r\n\tpublic ContentHeading?: string;\r\n\r\n\t/**\r\n\t * Will be included in the response if there are results to display. The `ProductHeading` contains\r\n\t * the text to display above the list of products to display in Autocomplete.\r\n\t */\r\n\tpublic ProductHeading?: string;\r\n\r\n\t/**\r\n\t * Will be included in the response if there are results to display. The `PopularHeading` contains\r\n\t * the text to display above the list of popular search terms to display in Autocomplete.\r\n\t */\r\n\tpublic PopularHeading?: string;\r\n\r\n\t/**\r\n\t * Will be included in the response if there are results to display. The `ViewAllButtonLabel` contains\r\n\t * the text to display for the link to return all results from searching with the term entered.\r\n\t */\r\n\tpublic ViewAllButtonLabel?: string;\r\n\r\n\tpublic constructor(init: Response) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.Categories = init.Categories.map((r) => new Category(r));\r\n\t\tthis.Products = init.Products.map((r) => new Product(r));\r\n\t\tthis.Popular = init.Popular.map((r) => new Popular(r));\r\n\t\tthis.Content = init.Content.map((r) => new Content(r));\r\n\t}\r\n}\r\n","export class Pagination {\r\n\t/** Number of total items in the result set. */\r\n\tpublic NofResults: number;\r\n\r\n\t/** The page number returned. */\r\n\tpublic CurrentPage: number;\r\n\r\n\t/** The number of items returned for the page. */\r\n\tpublic MaxPerPage: number;\r\n\r\n\t/** The total number of pages for the result set - with the current @see MaxPerPage. */\r\n\tpublic NofPages: number;\r\n\r\n\t/** Set of pagination options */\r\n\tpublic Items: PaginationItem[];\r\n\r\n\tpublic constructor(init: Pagination) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.Items = init.Items.map((i) => new PaginationItem(i));\r\n\t}\r\n}\r\n\r\nexport class PaginationItem {\r\n\t/** Display label for user's pagination option (i.e. 24 per page). */\r\n\tpublic Label: string;\r\n\r\n\t/** The maximum number of items that will be returned per page when this option is selected. */\r\n\tpublic PageSize: number;\r\n\r\n\t/** Indicates if this is the option selected. Only one pagination item will have this set to `true`. */\r\n\tpublic Selected: boolean;\r\n\r\n\t/** Indicates if this is the default option. Only one pagination item will have this set to `true`. */\r\n\tpublic Default: boolean;\r\n\r\n\tpublic constructor(init: PaginationItem) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","import { Explain } from './Explain';\r\n\r\nexport class Result {\r\n\t/** Unique identifier for this search result item. */\r\n\tpublic DocId: string;\r\n\r\n\t/** Calculated relevancy score. */\r\n\tpublic Score: number;\r\n\r\n\t/**\r\n\t * Contains the fields for the search result item, as an object of string keys to an array\r\n\t * of string values. The keys correspond to the name of the field within the hawk dashboard,\r\n\t * and the value of the map is an array of strings for each of the values for that field.\r\n\t */\r\n\tpublic Document?: { [field: string]: string[] };\r\n\r\n\tpublic Explain?: Explain;\r\n\r\n\tpublic IsPin: boolean;\r\n\r\n\tpublic BestFragment: string;\r\n\r\n\t/**\r\n\t * Returns a single document value, by the given field name. If the field does not exist in\r\n\t * the document, or has no values, then `undefined` is returned instead.\r\n\t * @param field The field within the result document to retrieve the value of.\r\n\t */\r\n\tpublic getDocumentValue(field: string): string | undefined {\r\n\t\tif (this.Document) {\r\n\t\t\tconst values = this.Document[field];\r\n\r\n\t\t\tif (values && values.length > 0) {\r\n\t\t\t\treturn values[0];\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tpublic constructor(init: Result) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","export class Sorting {\r\n\t/** The sorting items. */\r\n\tpublic Items: SortingItem[];\r\n\r\n\tpublic constructor(init: Sorting) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.Items = init.Items.map((i) => new SortingItem(i));\r\n\t}\r\n}\r\n\r\nexport class SortingItem {\r\n\t/** Name of the sorting option. This is the label to display to users. */\r\n\tpublic Label: string;\r\n\r\n\t/**\r\n\t * The value to be used to specify the sort order once user selects it. This value is passed in the @see Request.SortBy\r\n\t * field in the @see Request object.\r\n\t */\r\n\tpublic Value: string;\r\n\r\n\t/** Indicates if this sorting option was configured to be the default. */\r\n\tpublic IsDefault: boolean;\r\n\r\n\t/** Indicates if this sorting option is currently being used for the current result set. */\r\n\tpublic Selected: boolean;\r\n\r\n\tpublic constructor(init: SortingItem) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","export class Selections {\r\n\t// You may get build errors if you are using react hot loader because of this indexer. If this file is listed as a culprit and you don't know why, this is likely the reason.\r\n\t[field: string]: SelectionFacet;\r\n\r\n\tpublic constructor(init: Selections) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tObject.keys(init).forEach((key) => {\r\n\t\t\tconst selFacet = init[key];\r\n\r\n\t\t\tthis[key] = new SelectionFacet(selFacet);\r\n\t\t});\r\n\t}\r\n}\r\n\r\nexport class SelectionFacet {\r\n\t/** Display name for facet. */\r\n\tpublic Label: string;\r\n\r\n\t/** Will contain an entry for each selection made within the facet. */\r\n\tpublic Items: SelectionFacetValue[];\r\n\r\n\tpublic constructor(init: SelectionFacet) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.Items = init.Items.map((i) => new SelectionFacetValue(i));\r\n\t}\r\n}\r\n\r\nexport class SelectionFacetValue {\r\n\t/** Display label for facet value. */\r\n\tpublic Label: string;\r\n\r\n\t/** Value for facet value. */\r\n\tpublic Value: string;\r\n\r\n\tpublic constructor(init: SelectionFacetValue) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","export class Value {\r\n\t/** Label of the value to display. */\r\n\tpublic Label?: string;\r\n\t/** Value to use when setting the facet value selection. */\r\n\tpublic Value?: string;\r\n\r\n\t/** Number of results in current set that have this facet value. */\r\n\tpublic Count: number;\r\n\t/** Indicates if this facet value has been selected. */\r\n\tpublic Selected: boolean;\r\n\r\n\t/**\r\n\t * Used for displaying the slider facet. @see RangeStart indicates what the starting point of the range\r\n\t * to display, either on basis of what the user selected by sliding the slider, or if they have no\r\n\t * selection it reflects the lowest price product.\r\n\t */\r\n\tpublic RangeStart?: string;\r\n\t/**\r\n\t * Used for displaying the slider facet. @see RangeEnd indicates what the end point of the range to\r\n\t * display is, either on basis of what the user selected by sliding the slider, or if they have no\r\n\t * selection, it reflects the highest price product.\r\n\t */\r\n\tpublic RangeEnd?: string;\r\n\r\n\t/**\r\n\t * Used for displaying the slider facet. @see RangeMin indicates lowest value for the range in the list\r\n\t * of products displayed.\r\n\t */\r\n\tpublic RangeMin?: string;\r\n\t/**\r\n\t * Used for displaying the slider facet. @see RangeMax indicates highest value for the range in the list\r\n\t * of products displayed.\r\n\t */\r\n\tpublic RangeMax?: string;\r\n\r\n\t/** Used for nested facets. */\r\n\tpublic Path?: string;\r\n\r\n\t/** Set of pagination options */\r\n\tpublic Children: Value[];\r\n\r\n\tpublic Level: number;\r\n\r\n\tpublic constructor(init: Value) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","export class Swatch {\r\n\t/** Match this value to the @see Value object in the @see Values array of @see Facet. */\r\n\tpublic Value: string;\r\n\r\n\t/** Name of the asset. */\r\n\tpublic AssetName: string;\r\n\t/** URL of the asset. */\r\n\tpublic AssetUrl: string;\r\n\r\n\t/** Indicates if value is the default. */\r\n\tpublic IsDefault: boolean;\r\n\r\n\t/** Color of the asset. */\r\n\tpublic Color: string;\r\n\r\n\tpublic constructor(init: Swatch) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","export class Range {\r\n\t/** Label of the value to display. */\r\n\tpublic Label: string;\r\n\t/** Value to use when setting the facet value selection. */\r\n\tpublic Value: string;\r\n\r\n\t/** Indicates if the values are numeric. */\r\n\tpublic IsNumeric: boolean;\r\n\r\n\t/** Lower value of the range. */\r\n\tpublic LBound: string;\r\n\t/** Upper value of the range. */\r\n\tpublic UBound: string;\r\n\t/** Asset Url */\r\n\tpublic AssetFullUrl: string;\r\n\r\n\tpublic constructor(init: Range) {\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","import { Value } from './Value';\r\nimport { Swatch } from './Swatch';\r\nimport { Range } from './Range';\r\nimport { FacetType } from 'models/Facets/FacetType';\r\n\r\nexport class Facet {\r\n\t/** Unique identifier of the facet. */\r\n\tpublic FacetId: number;\r\n\r\n\t/** Display name of the facet. */\r\n\tpublic Name: string;\r\n\r\n\t/** The name of the field that is linked to this facet. */\r\n\tpublic Field: string;\r\n\r\n\t/** The name of the field that is linked to this facet. */\r\n\tpublic FieldType: 'string' | 'range' | 'numeric' | 'search' | 'tab';\r\n\r\n\t/** The type of facet. This dictates the appearance and behavior of this instance and is partially restricted by @see FieldType */\r\n\tpublic FacetType: FacetType;\r\n\r\n\t/** The Display Type controls how many options your users can see when they search and how they are able to access them. */\r\n\tpublic DisplayType: 'default' | 'scrolling' | 'truncating';\r\n\r\n\t/** Indicates the maximum number of facet values that are returned. */\r\n\tpublic MaxCount: number;\r\n\r\n\t/** Indicates the minimum number of results each facet value needs to have in order to be returned. */\r\n\tpublic MinHitCount: number;\r\n\r\n\t/**\r\n\t * If this is set, it is to be used as the facet name if passed in the `FacetSelections`. If not set,\r\n\t * the value of the Field object would be used. (This is only applicable when a slider and range\r\n\t * facets are both configured for the same field.)\r\n\t */\r\n\tpublic ParamName?: string;\r\n\r\n\t/**\r\n\t * Indicates the sorting logic that is used for this facet’s values. The possible values for this\r\n\t * are the parameters for sorting set options that are configured in \"Workbench > Data Configuration\r\n\t * > Sorting/Pagination\".\r\n\t */\r\n\tpublic SortBy: string;\r\n\r\n\t/** Indicates if the user should be able to apply more than one filter value from this facet. */\r\n\tpublic ExpandSelection: boolean;\r\n\r\n\t/** Indicates if facet values are numeric. */\r\n\tpublic IsNumeric: boolean;\r\n\r\n\t/** Indicates if facet values are currency (and should be displayed appropriately). */\r\n\tpublic IsCurrency: boolean;\r\n\r\n\t/** Indicates currency symbol in case of currency type facets */\r\n\tpublic CurrencySymbol: string;\r\n\r\n\t/** Indicates if the facet can be collapsed and expanded by the user. */\r\n\tpublic IsCollapsible: boolean;\r\n\r\n\t/** If @see IsCollapsible is `true`, this indicates if the facet should initially be collapsed or expanded. */\r\n\tpublic IsCollapsedDefault: boolean;\r\n\r\n\t/** Indicates if the facet is set to be visible. */\r\n\tpublic IsVisible: boolean;\r\n\r\n\t/**\r\n\t * Indicates if search is enabled for this facet. If it is enabled, a search box should be available for\r\n\t * users to filter the facet values by typing in the search box.\r\n\t */\r\n\tpublic IsSearch: boolean;\r\n\r\n\t/**\r\n\t * If facet display type is Scrolling, this value is the height in pixels for the window inside scroll box.\r\n\t * Only to be used if @see DisplayType is `\"scrolling\"`.\r\n\t */\r\n\tpublic ScrollHeight: number;\r\n\r\n\t/**\r\n\t * If the number of facet values exceeds this number and @see DisplayType is `\"scrolling\"`, then the facet\r\n\t * should be displayed as scrolling list; if not, display as `\"default\"`.\r\n\t */\r\n\tpublic ScrollThreshold: number;\r\n\r\n\t/**\r\n\t * If the number of facet values exceeds this number and @see DisplayType is `\"truncate\"`, then the facet\r\n\t * should be displayed as truncated list; if not, display as `\"default\"`.\r\n\t */\r\n\tpublic TruncateThreshold: number;\r\n\r\n\t/**\r\n\t * To be used if @see IsSearch is `true`. The number of facet values must be this number or higher for the\r\n\t * facet search box to display.\r\n\t */\r\n\tpublic SearchThreshold: number;\r\n\r\n\t/** Text to display when user hovers over a help icon. */\r\n\tpublic Tooltip?: string;\r\n\r\n\t/**\r\n\t * If `false`, indicates that sometimes this facet will not be returned. The conditions that trigger its\r\n\t * display are maintained in the Workbench.\r\n\t */\r\n\tpublic AlwaysVisible: boolean;\r\n\r\n\t/**\r\n\t * The display order of the facet in the facet list.\r\n\t */\r\n\tpublic SortOrder: number;\r\n\r\n\t/** This is maximum number of values that could be returned for the facet. */\r\n\tpublic NofVisible: number;\r\n\r\n\t/** Will be included if @see FacetType is `\"swatch\"`. */\r\n\tpublic SwatchData?: Swatch[];\r\n\r\n\t/** Indicates type of facet range display. */\r\n\tpublic FacetRangeDisplayType: number;\r\n\r\n\t/** Indicates if setting in Workbench is set to On or Off. */\r\n\tpublic PreloadChildren: boolean;\r\n\r\n\t/**\r\n\t * To be used if @see FacetType is `\"slider\"`. If @see ShowSliderInputs is `true`, input boxes should be\r\n\t * available for user to enter values.\r\n\t */\r\n\tpublic ShowSliderInputs: boolean;\r\n\r\n\t/** Always present, but will only be populated if the facet is numeric and not a slider. */\r\n\tpublic Ranges: Range[];\r\n\r\n\t/** The values for this facet. */\r\n\tpublic Values: Value[];\r\n\r\n\t/** Whether or not the facet should be rendered as truncated. */\r\n\tpublic get shouldTruncate() {\r\n\t\t// the facet does truncated listing of values if configured for truncating and we have too many facets\r\n\t\treturn this.DisplayType === 'truncating' && this.Values.length > this.TruncateThreshold;\r\n\t}\r\n\r\n\t/** Whether or not the facet should have a quick lookup search input. */\r\n\tpublic get shouldSearch() {\r\n\t\t// the facet should have a search box if configured to do so, and the number of facet values is greater\r\n\t\t// than the threshold\r\n\t\treturn this.IsSearch && this.Values.length > this.SearchThreshold;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the name of the key when using this facet for a selection. This will take into consideration\r\n\t * @see ParamName and @see Field in determining which value should be returned.\r\n\t */\r\n\tpublic get selectionField() {\r\n\t\treturn this.ParamName ? this.ParamName : this.Field;\r\n\t}\r\n\r\n\tpublic constructor(init: Facet) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.SwatchData = init.SwatchData ? init.SwatchData.map((s) => new Swatch(s)) : [];\r\n\t\tthis.Ranges = init.Ranges.map((r) => new Range(r));\r\n\t\tthis.Values = init.Values.map((v) => new Value(v));\r\n\t}\r\n}\r\n","export class Rule {\r\n\tpublic RuleType: RuleType;\r\n\tpublic Field: string;\r\n\tpublic Condition: string;\r\n\tpublic Value: string;\r\n\tpublic Operator: RuleOperatorType;\r\n\r\n\tpublic Rules: Rule[];\r\n\tpublic Parent: Rule;\r\n\tpublic constructor(init: Rule) {\r\n\t\tObject.assign(this, init);\r\n\t\tif (init.Parent) {\r\n\t\t\tthis.Parent = new Rule(init.Parent);\r\n\t\t}\r\n\t\tthis.Rules = init.Rules ? init.Rules.map((i) => new Rule(i)) : [];\r\n\t}\r\n}\r\n\r\nexport enum RuleType {\r\n\tGroup = 0,\r\n\tEval = 1,\r\n}\r\n\r\nexport enum RuleOperatorType {\r\n\tAll = 0,\r\n\tAny = 1,\r\n\tNone = 2,\r\n}\r\n","import { Rule } from './Rule';\r\n\r\nexport class BannerTrigger {\r\n\tpublic BannerGroupId: number;\r\n\tpublic Name: string;\r\n\tpublic SortOrder: number;\r\n\tpublic Rule: Rule;\r\n\r\n\tpublic constructor(init: BannerTrigger) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.Rule = new Rule(this.Rule);\r\n\t}\r\n}\r\n","import { ContentType } from './ContentType';\r\nimport { Result } from './Result';\r\nimport { BannerTrigger } from './Trigger';\r\n\r\nexport class FeaturedItems {\r\n\tpublic Items: FeaturedItem[];\r\n\r\n\tpublic constructor(init: FeaturedItems) {\r\n\t\tObject.assign(this, init);\r\n\t\tif (init && init.Items) {\r\n\t\t\tthis.Items = init.Items.map((i) => new FeaturedItem(i));\r\n\t\t}\r\n\t}\r\n}\r\n\r\nexport class Merchandising {\r\n\tpublic Items: MerchandisingItem[];\r\n\r\n\tpublic constructor(init: Merchandising) {\r\n\t\tObject.assign(this, init);\r\n\t\tif (init && init.Items) {\r\n\t\t\tthis.Items = init.Items.map((i) => new MerchandisingItem(i));\r\n\t\t}\r\n\t}\r\n}\r\n\r\nexport class PageContentItem {\r\n\tpublic Zone: string;\r\n\tpublic ContentType: ContentType;\r\n\tpublic ImageUrl: string;\r\n\tpublic AltTag: string;\r\n\tpublic ForwardUrl: string;\r\n\tpublic Output: any;\r\n\tpublic WidgetArgs: string;\r\n\tpublic Title: string;\r\n\tpublic Name: string;\r\n\tpublic DateFrom: string;\r\n\tpublic DateTo: string;\r\n\tpublic IsMobile: boolean;\r\n\tpublic MobileContentType: string;\r\n\tpublic MobileImageUrl: string;\r\n\tpublic MobileOutput: string;\r\n\tpublic MobileWidgetArgs: string;\r\n\tpublic IsTrackingEnabled: boolean;\r\n\tpublic MobileIsTrackingEnabled?: boolean;\r\n\tpublic FeaturedItems: Result[];\r\n\tpublic Items: Result[];\r\n\tpublic Target: string;\r\n\tpublic MobileTarget: string;\r\n\tpublic MobileAltTag: string;\r\n\tpublic MobileForwardUrl: string;\r\n\tpublic MobileWidth: string;\r\n\tpublic MobileHeight: string;\r\n\tpublic Trigger: BannerTrigger;\r\n\r\n\tpublic constructor(init: PageContentItem) {\r\n\t\tObject.assign(this, init);\r\n\t\tif (init.FeaturedItems) {\r\n\t\t\tthis.FeaturedItems = init.FeaturedItems.map((i) => new Result(i));\r\n\t\t}\r\n\t\tif (init.Trigger) {\r\n\t\t\tthis.Trigger = new BannerTrigger(init.Trigger);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nexport class FeaturedItem extends PageContentItem {\r\n\tpublic Items: Result[];\r\n\r\n\tpublic constructor(init: FeaturedItem) {\r\n\t\tsuper(init);\r\n\t\tObject.assign(this, init);\r\n\t\tthis.Items = init.Items.map((i) => new Result(i));\r\n\t}\r\n}\r\n\r\nexport class MerchandisingItem extends PageContentItem {\r\n\tpublic constructor(init: MerchandisingItem) {\r\n\t\tsuper(init);\r\n\t\tObject.assign(this, init);\r\n\t}\r\n}\r\n","import { PageContentItem } from './Merchandising';\r\n\r\nexport class PageContent {\r\n\tpublic ZoneName: string;\r\n\r\n\tpublic Items: PageContentItem[];\r\n\r\n\tpublic constructor(init: PageContent) {\r\n\t\tObject.assign(this, init);\r\n\t\tthis.Items = init.Items.map((i) => new PageContentItem(i));\r\n\t}\r\n}\r\n","import { Pagination } from './Pagination';\r\nimport { Result } from './Result';\r\nimport { Sorting } from './Sorting';\r\nimport { Selections } from './Selections';\r\nimport { Facet } from 'models/Facets';\r\nimport { Merchandising, FeaturedItems } from './Merchandising';\r\nimport { PageContent } from './PageContent';\r\n\r\nexport class Response {\r\n\t/** Indicates if request was successful. */\r\n\tpublic Success: boolean;\r\n\r\n\t/** Summary of pagination details and a set of pagination options. */\r\n\tpublic Pagination: Pagination;\r\n\r\n\t/**\r\n\t * The Keyword value that was sent to Hawksearch in the request. If no Keyword was set in the\r\n\t * request, the value will be empty.\r\n\t */\r\n\tpublic Keyword: string;\r\n\r\n\t/**\r\n\t * If this is populated, it indicates that the Keyword value returned 0 results, but the results\r\n\t * in this response are from this AdjustedKeyword. A message should be displayed to the user\r\n\t * informing them that their search was corrected to this string.\r\n\t *\r\n\t * This is the result of Auto Correct, which is configured in the Workbench > Keyword Search >\r\n\t * Did You Mean.\r\n\t */\r\n\tpublic AdjustedKeyword?: string;\r\n\r\n\t/** An entry in the array for each item returned in search results. */\r\n\tpublic Results: Result[];\r\n\r\n\tpublic Facets: Facet[];\r\n\r\n\t/**\r\n\t * Will contain an entry for each facet that has one or more selections. Will be empty if no facet\r\n\t * selections have been made.\r\n\t */\r\n\tpublic Selections: Selections;\r\n\r\n\tpublic Sorting: Sorting;\r\n\r\n\t/**\r\n\t * If any strings are returned in the array, they should be displayed to the user as suggested\r\n\t * search terms.\r\n\t *\r\n\t * This is the result of Did You Mean, which is configured in the Workbench > Keyword Search >\r\n\t * Did You Mean.\r\n\t */\r\n\tpublic DidYouMean: string[];\r\n\r\n\t/**\r\n\t * Merchandising can be placed by using Campaigns in the Hawksearch Workbench. The Campaign will\r\n\t * determine if the content should appear and in what zone.\r\n\t */\r\n\tpublic Merchandising: Merchandising;\r\n\tpublic FeaturedItems: FeaturedItems;\r\n\r\n\tpublic SearchDuration: number;\r\n\r\n\tpublic DocExplain?: string;\r\n\r\n\t/**\r\n\t * Properties that gets populated when user requests landing page related results\r\n\t *\r\n\t */\r\n\r\n\tpublic Breadcrumb: string;\r\n\r\n\tpublic CustomHtml: string;\r\n\r\n\tpublic HeaderTitle: string;\r\n\r\n\tpublic MetaDescription: string;\r\n\r\n\tpublic MetaKeywords: string;\r\n\tpublic MetaRobots: string;\r\n\tpublic Name: string;\r\n\tpublic Next: string;\r\n\tpublic Prev: string;\r\n\tpublic PageHeading: string;\r\n\tpublic PageContent: PageContent[];\r\n\tpublic RelCanonical: string;\r\n\tpublic PageLayoutId: number;\r\n\tpublic TrackingId: string;\r\n\t// end of landing page related fields\r\n\r\n\tpublic constructor(init: Response) {\r\n\t\tObject.assign(this, init);\r\n\r\n\t\tthis.Pagination = new Pagination(init.Pagination);\r\n\t\tthis.Merchandising = new Merchandising(init.Merchandising);\r\n\t\tthis.FeaturedItems = new FeaturedItems(init.FeaturedItems);\r\n\t\tthis.Results = init.Results.map((r) => new Result(r));\r\n\t\tthis.Facets = init.Facets.map((f) => new Facet(f));\r\n\t\tthis.PageContent = init.PageContent ? init.PageContent.map((p) => new PageContent(p)) : [];\r\n\t\tthis.Selections = new Selections(init.Selections);\r\n\t\tthis.Sorting = new Sorting(init.Sorting);\r\n\t}\r\n}\r\n","/** An object that contains the data related to the client making search or autosuggest requests. */\r\nexport class ClientData {\r\n\t/** Unique identifier used for tracking visitors. */\r\n\tpublic VisitorId: string;\r\n\r\n\t/** Custom information used for evaluating Visitor Targets. */\r\n\tpublic Custom?: string;\r\n\r\n\t/** Client IP used for evaluating Visitor Targets. */\r\n\tpublic HttpTrueClientIp?: string;\r\n\r\n\t/** Browser user agent used for evaluating Visitor Targets. */\r\n\tpublic UserAgent?: string;\r\n\r\n\tpublic PreviewBuckets?: number[];\r\n\r\n\t/**\r\n\t * The source used for evaluating Visitor Targets. This was previously called 'hawksource' and can\r\n\t * be used to track the source the user came from (i.e. email, instagram, etc).\r\n\t */\r\n\tpublic Source?: string;\r\n}\r\n","export enum ContentType {\r\n\tImage = 'image',\r\n\tWidget = 'widget',\r\n\tFeatured = 'featured',\r\n\tCustom = 'custom',\r\n\tLandingPage = 'landingPage',\r\n}\r\n","import { useEffect } from 'react';\r\nimport axios, { CancelToken } from 'axios';\r\nimport { SearchStore, FacetSelectionState } from './Store';\r\nimport HawkClient from 'net/HawkClient';\r\nimport { Response, Request, FacetSelections, Result } from 'models/Search';\r\nimport { useMergableState } from 'util/MergableState';\r\nimport { useHawkConfig } from 'components/ConfigProvider';\r\nimport { Facet, Value } from 'models/Facets';\r\nimport { Response as CompareDataResponse, Request as CompareItemRequest } from 'models/CompareItems';\r\nimport { CompareResultObject } from '../models/CompareResultObject';\r\nimport { setSearchTracking } from '../util/SearchTracking';\r\n\r\nexport interface SearchActor {\r\n\t/**\r\n\t * Performs a search with the currently configured pending search request. The search request can be\r\n\t * configured via the `setSearch` method. This method usually doesn't need to be called directly, as\r\n\t * the `StoreProvider` component will usually trigger searches directly in response to calls to\r\n\t * `setSearch`.\r\n\t * @returns A promise that resolves when the search request has been completed.\r\n\t */\r\n\tsearch(cancellationToken?: CancelToken): Promise;\r\n\r\n\t/**\r\n\t * Configures the next search request that will be executed. This will also execute a search in response to\r\n\t * the next search request changing.\r\n\t * @param search The partial search request object. This will be merged with previous calls to `setSearch`.\r\n\t * @param doHistory Whether or not this search request will push a history entry into the browser. If\r\n\t * \t\t\t\t\tnot specified, the default is `true`.\r\n\t */\r\n\tsetSearch(search: Partial, doHistory?: boolean): void;\r\n\r\n\t/**\r\n\t * Toggles a facet value for the next search request that will be executed. If the given facet had previously\r\n\t * been selected, it will be unselected. If the negation state of a selected facet is changed, the selection\r\n\t * will have its negation state changed. Internally, this will call `setSearch` to configure the next search\r\n\t * with this selected facet.\r\n\t * @param facet The facet for which the value is being selected.\r\n\t * @param facetValue The facet value being selected.\r\n\t * @param negate Whether or not this selection is considered a negation.\r\n\t */\r\n\ttoggleFacetValue(facet: Facet | string, facetValue: Value | string, negate?: boolean): void;\r\n\r\n\tsetFacetValues(facet: Facet | string, facetValues: Value[] | string[]): void;\r\n\r\n\t/**\r\n\t * Entirely clears all the values of the given facet from the current selection.\r\n\t * @param facet The facet to clear.\r\n\t */\r\n\tclearFacet(facet: Facet | string): void;\r\n\r\n\t/**\r\n\t * Clears a given facet value of the given facet from the current selection.\r\n\t * @param facet The facet to clear.\r\n\t * @param facetValue The facet value to clear.\r\n\t */\r\n\tclearFacetValue(facet: Facet | string, facetValue?: Value | string): void;\r\n\r\n\t/**\r\n\t * Clears all selected facets from the current selection.\r\n\t */\r\n\tclearAllFacets(): void;\r\n\r\n\t// Store items to make comparision via request\r\n\tsetItemsToCompare(resultItem: Result, isCheck: boolean): void;\r\n\r\n\t// To store items after getting the results from compare request\r\n\tsetComparedResults(comparedResults: CompareResultObject[]): void;\r\n\r\n\t// Clear stored compared items\r\n\tclearItemsToCompare(): void;\r\n\r\n\t// Get comparision of items from request\r\n\tgetComparedItems(request: CompareItemRequest, cancellationToken?: CancelToken): Promise;\r\n\r\n\t/** Gets the value for a given field of a compared item */\r\n\tgetCompareFieldValue(\r\n\t\tcompareItem: CompareResultObject,\r\n\t\tfieldName: string,\r\n\t\tcompareType: CompareValueType,\r\n\t): string | undefined;\r\n}\r\n\r\n/** The format expected for a compare value */\r\nexport enum CompareValueType {\r\n\tSingleValueString = 0,\r\n\tMultipleValueString = 1,\r\n\tMultipleValueDecimal = 2,\r\n}\r\n\r\nexport function useHawkState(initialSearch?: Partial): [SearchStore, SearchActor] {\r\n\tconst { config } = useHawkConfig();\r\n\r\n\tconst client = new HawkClient(config);\r\n\r\n\tconst pendingSearch: Partial = initialSearch || { Keyword: '', FacetSelections: {} };\r\n\r\n\tconst [store, setStore] = useMergableState(\r\n\t\tnew SearchStore({\r\n\t\t\tpendingSearch,\r\n\t\t\tisLoading: true,\r\n\t\t\titemsToCompare: [],\r\n\t\t\tcomparedResults: [],\r\n\t\t\titemsToCompareIds: [],\r\n\t\t}),\r\n\t\tSearchStore,\r\n\t);\r\n\r\n\tuseEffect(() => {\r\n\t\t// when the pending search changes, trigger a search\r\n\r\n\t\tconst cts = axios.CancelToken.source();\r\n\t\tsearch(cts.token);\r\n\r\n\t\treturn () => {\r\n\t\t\tcts.cancel();\r\n\t\t};\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t}, [store.pendingSearch]);\r\n\r\n\t/**\r\n\t * Performs a comparision between two or more than two products based on ID\r\n\t * user can use this method from view application.\r\n\t * @returns A promise that resolves when the compare request has been completed.\r\n\t */\r\n\tasync function getComparedItems(\r\n\t\trequest: CompareItemRequest,\r\n\t\tcancellationToken?: CancelToken,\r\n\t): Promise {\r\n\t\treturn await client.getComparedItems(request, cancellationToken);\r\n\t}\r\n\r\n\t/**\r\n\t * Performs a search with the currently configured pending search request. The search request can be\r\n\t * configured via the `setSearch` method. This method usually doesn't need to be called directly, as\r\n\t * the `StoreProvider` component will usually trigger searches directly in response to calls to\r\n\t * `setSearch`.\r\n\t * @returns A promise that resolves when the search request has been completed.\r\n\t */\r\n\tasync function search(cancellationToken?: CancelToken): Promise {\r\n\t\tsetStore({ isLoading: true });\r\n\r\n\t\tlet searchResults: Response | null = null;\r\n\r\n\t\tconst searchParams = {\r\n\t\t\t// the search request being executed is spread from the pendingSearch\r\n\t\t\t...store.pendingSearch,\r\n\t\t\t// pass parameter for extended response\r\n\t\t\tIsInPreview: config.isInPreview,\r\n\t\t\t// and override some of the request fields with config values\r\n\t\t\tClientGuid: config.clientGuid,\r\n\t\t};\r\n\r\n\t\t// The index name in the configuration takes priority over the one supplied from the URL\r\n\t\tif (config.indexName) {\r\n\t\t\tsearchParams.IndexName = config.indexName;\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\t//#region TapeCase - search by CPN/Keyword\r\n\t\t\tconst keyword = searchParams.Keyword;\r\n\t\t\tconst query = searchParams.Query;\r\n\r\n\t\t\tif (config.organizationId) {\r\n\t\t\t\t// perform search by CPN\r\n\t\t\t\tsearchParams.Query =\r\n\t\t\t\t\t'organization_id_part_no: \"' + config.organizationId + '||' + searchParams.Keyword + '\"';\r\n\t\t\t\tsearchParams.Keyword = undefined;\r\n\t\t\t\tsearchResults = await client.search(searchParams, cancellationToken);\r\n\t\t\t}\r\n\r\n\t\t\tif (\r\n\t\t\t\t!config.organizationId ||\r\n\t\t\t\t(searchResults && searchResults.Success && searchResults.Results.length == 0)\r\n\t\t\t) {\r\n\t\t\t\t// perform search by keyword\r\n\t\t\t\tsearchParams.Keyword = keyword;\r\n\t\t\t\tsearchParams.Query = query;\r\n\t\t\t\tsearchResults = await client.search(searchParams, cancellationToken);\r\n\t\t\t}\r\n\t\t\t//#endregion\r\n\t\t} catch (error) {\r\n\t\t\tif (axios.isCancel(error)) {\r\n\t\t\t\t// if the request was cancelled, it's because this component was updated\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconsole.error('Search request error:', error);\r\n\t\t\tsetStore({ requestError: true });\r\n\t\t}\r\n\r\n\t\tsetStore({ isLoading: false });\r\n\r\n\t\tif (searchResults) {\r\n\t\t\tif (!searchResults.Success) {\r\n\t\t\t\tconsole.error('Search result error:', searchResults);\r\n\t\t\t\tsetStore({ requestError: true });\r\n\t\t\t} else {\r\n\t\t\t\tsetStore({\r\n\t\t\t\t\tsearchResults: new Response(searchResults),\r\n\t\t\t\t\trequestError: false,\r\n\t\t\t\t});\r\n\t\t\t\t// tracking search event changes\r\n\t\t\t\tsetSearchTracking(pendingSearch, searchResults);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Configures the next search request that will be executed. This will also execute a search in response to\r\n\t * the next search request changing.\r\n\t * @param search The partial search request object. This will be merged with previous calls to `setSearch`.\r\n\t * @param doHistory Whether or not this search request will push a history entry into the browser. If\r\n\t * \t\t\t\t\tnot specified, the default is `true`.\r\n\t */\r\n\tfunction setSearch(pendingSearch: Partial, doHistory?: boolean): void {\r\n\t\tif (doHistory === undefined) {\r\n\t\t\tdoHistory = true;\r\n\t\t}\r\n\r\n\t\tsetStore((prevState) => {\r\n\t\t\tconst newState = {\r\n\t\t\t\tpendingSearch: { ...prevState.pendingSearch, ...pendingSearch },\r\n\t\t\t\tdoHistory,\r\n\t\t\t};\r\n\t\t\tif (newState.pendingSearch.Keyword === '') {\r\n\t\t\t\tnewState.pendingSearch.Keyword = undefined;\r\n\t\t\t}\r\n\r\n\t\t\treturn newState;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the facet selections and search within configuration for the next search request. This will also\r\n\t * clear the page number of the next request to display the first page of results.\r\n\t * @param selections The facet selections to set.\r\n\t * @param searchWithin The search within value to set.\r\n\t */\r\n\tfunction setSearchSelections(selections?: FacetSelections, searchWithin?: string) {\r\n\t\tsetSearch({\r\n\t\t\tFacetSelections: selections,\r\n\t\t\tSearchWithin: searchWithin,\r\n\r\n\t\t\t// when we change facet selections, also clear the current page so that we navigate\r\n\t\t\t// back to the first page of results\r\n\t\t\tPageNo: undefined,\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Toggles a facet value for the next search request that will be executed. Internally, this will call\r\n\t * `setSearch` to configure the next search with this selected facet.\r\n\t * @param facet The facet for which the value is being selected.\r\n\t * @param facetValue The facet value being selected.\r\n\t * @param negate Whether or not this selection is considered a negation.\r\n\t */\r\n\tfunction toggleFacetValue(facet: Facet | string, facetValue: Value | string, negate?: boolean): void {\r\n\t\tif (negate === undefined) {\r\n\t\t\tnegate = false;\r\n\t\t}\r\n\r\n\t\tconst facetName: string = typeof facet === 'string' ? facet : facet.Name;\r\n\t\tconst facetField = typeof facet === 'string' ? facet : facet.selectionField;\r\n\r\n\t\tconst valueValue = typeof facetValue === 'string' ? facetValue : facetValue.Value;\r\n\t\tconst valueLabel = typeof facetValue === 'string' ? facetValue : facetValue.Label;\r\n\r\n\t\tif (!valueValue) {\r\n\t\t\tconsole.error(`Facet ${facetName} (${facetField}) has no facet value for ${valueLabel}`);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet facetSelections = store.pendingSearch.FacetSelections;\r\n\r\n\t\t// handle `searchWithin` facet, which isn't a facet selection but is instead a field on the\r\n\t\t// search request.\r\n\t\tif (facetField === 'searchWithin') {\r\n\t\t\t// set the search within to the facet value provided\r\n\t\t\tsetSearchSelections(facetSelections, /* searchWithin */ valueValue);\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!facetSelections) {\r\n\t\t\tfacetSelections = {};\r\n\t\t}\r\n\r\n\t\tif (!facetSelections[facetField]) {\r\n\t\t\tfacetSelections[facetField] = [];\r\n\t\t}\r\n\r\n\t\tconst { state: selState, selectionIndex } = store.isFacetSelected(facet, facetValue);\r\n\r\n\t\tif (selState === FacetSelectionState.Selected || selState === FacetSelectionState.Negated) {\r\n\t\t\t// we're selecting this facet, and it's already selected\r\n\r\n\t\t\t// first, remove it from our selections\r\n\t\t\tfacetSelections[facetField]!.splice(selectionIndex!, 1);\r\n\r\n\t\t\tif (\r\n\t\t\t\t(selState === FacetSelectionState.Selected && negate) ||\r\n\t\t\t\t(selState === FacetSelectionState.Negated && !negate)\r\n\t\t\t) {\r\n\t\t\t\t// if we're toggling from negation to non-negation or vice versa, then push the new selection\r\n\t\t\t\tfacetSelections[facetField]!.push(negate ? `-${valueValue}` : valueValue);\r\n\t\t\t} else {\r\n\t\t\t\t// if we're not toggling the negation, nothing to do because we already removed the selection above\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// not selected, so we want to select it\r\n\t\t\tfacetSelections[facetField]!.push(negate ? `-${valueValue}` : valueValue);\r\n\t\t}\r\n\r\n\t\tif (facetSelections[facetField]!.length === 0) {\r\n\t\t\t// clean up any facets that no longer have any selected facet values\r\n\t\t\tdelete facetSelections[facetField];\r\n\t\t}\r\n\r\n\t\tsetSearchSelections(facetSelections, store.pendingSearch.SearchWithin);\r\n\t}\r\n\r\n\tfunction setFacetValues(facet: Facet | string, facetValues: Value[] | string[]): void {\r\n\t\tconst facetName = typeof facet === 'string' ? facet : facet.Name;\r\n\t\tconst facetField = typeof facet === 'string' ? facet : facet.selectionField;\r\n\r\n\t\tlet facetSelections = store.pendingSearch.FacetSelections;\r\n\r\n\t\tif (!facetSelections) {\r\n\t\t\tfacetSelections = {};\r\n\t\t}\r\n\r\n\t\tfacetSelections[facetField] = [];\r\n\r\n\t\tfor (const facetValue of facetValues) {\r\n\t\t\tconst valueValue = typeof facetValue === 'string' ? facetValue : facetValue.Value;\r\n\t\t\tconst valueLabel = typeof facetValue === 'string' ? facetValue : facetValue.Label;\r\n\r\n\t\t\tif (!valueValue) {\r\n\t\t\t\tconsole.error(`Facet ${facetName} (${facetField}) has no facet value for ${valueLabel}`);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tfacetSelections[facetField]!.push(valueValue);\r\n\t\t}\r\n\r\n\t\tsetSearchSelections(facetSelections, store.pendingSearch.SearchWithin);\r\n\t}\r\n\r\n\t/**\r\n\t * Entirely clears all the values of the given facet from the current selection.\r\n\t * @param facet The facet to clear.\r\n\t */\r\n\tfunction clearFacet(facet: Facet | string) {\r\n\t\tconst facetField = typeof facet === 'string' ? facet : facet.selectionField;\r\n\r\n\t\tconst facetSelections = store.pendingSearch.FacetSelections;\r\n\r\n\t\t// handle `searchWithin` facet, which isn't a facet selection but is instead a field on the\r\n\t\t// search request.\r\n\t\tif (facetField === 'searchWithin') {\r\n\t\t\t// set searchWithin to undefined to clear it\r\n\t\t\tsetSearchSelections(facetSelections, /* searchWithin */ undefined);\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!facetSelections || !facetSelections[facetField]) {\r\n\t\t\t// if there are no facet selections or the facet isn't selected at all, there's nothing to clear\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tdelete facetSelections[facetField];\r\n\r\n\t\tsetSearchSelections(facetSelections, store.pendingSearch.SearchWithin);\r\n\t}\r\n\r\n\t/**\r\n\t * Clears a given facet value of the given facet from the current selection.\r\n\t * @param facet The facet to clear.\r\n\t * @param facetValue The facet value to clear.\r\n\t */\r\n\tfunction clearFacetValue(facet: Facet | string, facetValue: Value | string) {\r\n\t\tconst facetName = typeof facet === 'string' ? facet : facet.Name;\r\n\t\tconst facetField = typeof facet === 'string' ? facet : facet.selectionField;\r\n\r\n\t\tconst valueValue = typeof facetValue === 'string' ? facetValue : facetValue.Value;\r\n\t\tconst valueLabel = typeof facetValue === 'string' ? facetValue : facetValue.Label;\r\n\r\n\t\tif (!valueValue) {\r\n\t\t\tconsole.error(`Facet ${facetName} (${facetField}) has no facet value for ${valueLabel}`);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// handle `searchWithin` facet, which isn't a facet selection but is instead a field on the\r\n\t\t// search request.\r\n\t\tif (facetField === 'searchWithin') {\r\n\t\t\t// set searchWithin to undefined to clear it\r\n\t\t\tsetSearchSelections(store.pendingSearch.FacetSelections, /* searchWithin */ undefined);\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst { state: selState, selectionIndex } = store.isFacetSelected(facet, facetValue);\r\n\r\n\t\tif (selState === FacetSelectionState.NotSelected) {\r\n\t\t\t// if there are no facet selections or the facet isn't selected at all, there's nothing to clear\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst facetSelections = store.pendingSearch.FacetSelections!;\r\n\r\n\t\t// remove it from the selections\r\n\t\tfacetSelections[facetField]!.splice(selectionIndex!, 1);\r\n\r\n\t\tif (facetSelections[facetField]!.length === 0) {\r\n\t\t\t// clean up any facets that no longer have any selected facet values\r\n\t\t\tdelete facetSelections[facetField];\r\n\t\t}\r\n\r\n\t\tsetSearchSelections(facetSelections, store.pendingSearch.SearchWithin);\r\n\t}\r\n\r\n\t/**\r\n\t * Clears all selected facets from the current selection.\r\n\t */\r\n\tfunction clearAllFacets(): void {\r\n\t\tsetSearchSelections();\r\n\t}\r\n\r\n\tfunction setItemsToCompare(resultItem: Result, isCheck: boolean): void {\r\n\t\tlet itemsArray = [...store.itemsToCompare];\r\n\t\tif (isCheck) {\r\n\t\t\t// append\r\n\t\t\titemsArray = [...itemsArray, ...[resultItem]];\r\n\t\t} else {\r\n\t\t\t// filter out\r\n\t\t\titemsArray = itemsArray.filter((item) => item.DocId !== resultItem.DocId);\r\n\t\t}\r\n\t\t// setStore({ itemsToCompare: itemsArray });\r\n\t\tsetStore({\r\n\t\t\titemsToCompare: itemsArray,\r\n\t\t\titemsToCompareIds: itemsArray.map((item) => item.DocId),\r\n\t\t});\r\n\t}\r\n\r\n\tfunction setComparedResults(data: CompareResultObject[]): void {\r\n\t\tsetStore({\r\n\t\t\tcomparedResults: data,\r\n\t\t});\r\n\t}\r\n\r\n\tfunction clearItemsToCompare() {\r\n\t\tsetStore({\r\n\t\t\titemsToCompare: [],\r\n\t\t\titemsToCompareIds: [],\r\n\t\t});\r\n\t}\r\n\r\n\t/** Gets the value for a given field of a compared item */\r\n\tfunction getCompareFieldValue(compareItem: CompareResultObject, fieldName: string, compareType: CompareValueType) {\r\n\t\tconst field = compareItem.Document.find((item) => item.Field === fieldName);\r\n\r\n\t\tif (field == null || field.Value.length === 0) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tswitch (compareType) {\r\n\t\t\tcase CompareValueType.MultipleValueDecimal:\r\n\t\t\t\t// Parse decimal values and then join them together into a comma-separated list\r\n\t\t\t\tconst parsedValues: string[] = [];\r\n\t\t\t\tfor (const rawValue of field.Value) {\r\n\t\t\t\t\tparsedValues.push(parseFloat(rawValue).toFixed(1).toString());\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn parsedValues.join(', ');\r\n\t\t\tcase CompareValueType.SingleValueString:\r\n\t\t\t\treturn field.Value[0];\r\n\t\t\tcase CompareValueType.MultipleValueString:\r\n\t\t\tdefault:\r\n\t\t\t\treturn field.Value.join(', ');\r\n\t\t}\r\n\t}\r\n\r\n\tconst actor: SearchActor = {\r\n\t\tsearch,\r\n\t\tsetSearch,\r\n\t\ttoggleFacetValue,\r\n\t\tsetFacetValues,\r\n\t\tclearFacet,\r\n\t\tclearFacetValue,\r\n\t\tclearAllFacets,\r\n\t\tsetItemsToCompare,\r\n\t\tsetComparedResults,\r\n\t\tclearItemsToCompare,\r\n\t\tgetComparedItems,\r\n\t\tgetCompareFieldValue,\r\n\t};\r\n\r\n\treturn [store, actor];\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\n/* eslint-disable no-unused-vars */\r\nimport { SearchType } from 'features/tracking/trackers/hawksearch/tracking';\r\nimport { Response, Request } from 'models/Search';\r\nimport { dispatchRocEvent } from 'shared/hooks/useRocEventHandler';\r\n\r\n/**\r\n * Dispatches hawk search page tracking events based on search request\r\n */\r\nexport function setSearchTracking(request: Partial, response: Response) {\r\n\tconst isLandingPage: boolean = !!request.CustomUrl;\r\n\tconst hasFacetSelections: boolean =\r\n\t\trequest.FacetSelections && Object.keys(request.FacetSelections).length > 0 ? true : false;\r\n\r\n\tconst searchType: SearchType =\r\n\t\t!hasFacetSelections && !request.MaxPerPage && !request.PageNo ? SearchType.Initial : SearchType.Refinement;\r\n\r\n\tif (isLandingPage) {\r\n\t\tdispatchRocEvent('hawk-landing-page-viewed', {});\r\n\t} else {\r\n\t\tdispatchRocEvent('hawk-search-tracking', { trackingId: response.TrackingId, searchType: searchType });\r\n\t}\r\n}\r\n","import { useState, Dispatch } from 'react';\r\n\r\ntype SetStateAction = Partial | ((prevState: T) => Partial);\r\n\r\nexport function useMergableState(\r\n\tinitialValue: T,\r\n\ttypeConstructor: new (init: Partial) => T,\r\n): [T, Dispatch>] {\r\n\tconst [state, setState] = useState(new typeConstructor(initialValue));\r\n\r\n\tfunction setStateAndMerge(value: SetStateAction) {\r\n\t\tif (typeof value === 'function') {\r\n\t\t\t// if we're being passed a function, we're setting state in the form of setState(prevState => ...).\r\n\r\n\t\t\tsetState((prevState) => {\r\n\t\t\t\t// so we derive the new state from the previous state\r\n\t\t\t\tconst newState = value(prevState);\r\n\r\n\t\t\t\t// and then set the new merged state\r\n\t\t\t\treturn new typeConstructor({ ...prevState, ...newState });\r\n\t\t\t});\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// otherwise, the new state was simply passed in\r\n\t\tsetState((prevState) => {\r\n\t\t\t// merge state together and set it\r\n\t\t\treturn new typeConstructor({ ...prevState, ...value });\r\n\t\t});\r\n\t}\r\n\r\n\treturn [state, setStateAndMerge];\r\n}\r\n","import React from 'react';\r\nimport useDelayedDisplay from 'shared/hooks/useDelayedDisplay';\r\nimport classnames from 'classnames';\r\n\r\ntype SpinnerAlignment = 'left' | 'right' | 'none';\r\n\r\ninterface SpinnerProps {\r\n\tlight?: boolean;\r\n\twaitMs?: number;\r\n\talign?: SpinnerAlignment;\r\n\tblock?: boolean;\r\n\tparentCentered?: boolean;\r\n}\r\n\r\n/**\r\n * Reusable roc-spinner component with color, alignment and wait time props.\r\n *\r\n * @export\r\n * @param {SpinnerProps} { light = false, waitMs = 200, align = 'right', block }\r\n * @returns\r\n */\r\nexport default function Spinner({\r\n\tlight = false,\r\n\twaitMs = 200,\r\n\talign = 'right',\r\n\tblock,\r\n\tparentCentered = false,\r\n}: SpinnerProps) {\r\n\tconst display = useDelayedDisplay(waitMs);\r\n\r\n\tif (!display) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst spinner = (\r\n\t\t\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t
\r\n\t);\r\n\r\n\tif (parentCentered) {\r\n\t\treturn
{spinner}
;\r\n\t}\r\n\r\n\treturn spinner;\r\n}\r\n","import axios, { CancelToken } from 'axios';\r\nimport { Request as AutocompleteRequest, Response as AutocompleteResponse } from 'models/Autocomplete';\r\nimport { Request as CompareItemRequest, Response as CompareDataResponse } from 'models/CompareItems';\r\nimport { Request as SearchRequest, Response as SearchResponse } from 'models/Search';\r\nimport { HawkSearchConfig } from 'types/HawkSearchConfig';\r\nimport * as Constants from 'util/Constants';\r\nimport { Request as RecommendationRequest, Response as RecommendationResponse } from '../models/Recommendation';\r\n\r\nclass HawkClient {\r\n\tprivate baseUrl: string;\r\n\tprivate searchUrl: string;\r\n\tprivate dashboardUrl: string;\r\n\tprivate autocompleteUrl: string;\r\n\tprivate compareItemsURL: string;\r\n\tprivate recommendationUrl: string;\r\n\tprivate recommendationWidgetUrl: string;\r\n\r\n\tconstructor(config: HawkSearchConfig) {\r\n\t\tthis.baseUrl = config.apiUrl || Constants.defaultApiUrl;\r\n\t\tthis.dashboardUrl = config.dashboardUrl || Constants.defaultDashboardUrl;\r\n\t\tthis.searchUrl = config.searchUrl || Constants.defaultSearchUrl;\r\n\t\tthis.autocompleteUrl = config.autocompleteUrl || Constants.defaultAutocompleteUrl;\r\n\t\tthis.recommendationUrl = config.recommendationUrl || Constants.defaultRecommendationUrl;\r\n\t\tthis.recommendationWidgetUrl = config.recommendationWidgetUrl || Constants.recommendationWidgetUrl;\r\n\t\t/* #region Commerce */\r\n\t\tthis.compareItemsURL = config.compareItemsURL || Constants.defaultCompareItemsURL;\r\n\t\t/* #endregion */\r\n\t}\r\n\r\n\tpublic async search(request: SearchRequest, cancellationToken?: CancelToken): Promise {\r\n\t\tconst result = await axios.post(new URL(this.searchUrl, this.baseUrl).href, request, {\r\n\t\t\tcancelToken: cancellationToken,\r\n\t\t});\r\n\t\treturn result.data;\r\n\t}\r\n\r\n\tpublic async autocomplete(\r\n\t\trequest: AutocompleteRequest,\r\n\t\tcancellationToken?: CancelToken,\r\n\t): Promise {\r\n\t\tconst result = await axios.post(\r\n\t\t\tnew URL(this.autocompleteUrl, this.baseUrl).href,\r\n\t\t\trequest,\r\n\t\t\t{\r\n\t\t\t\tcancelToken: cancellationToken,\r\n\t\t\t},\r\n\t\t);\r\n\r\n\t\treturn result.data;\r\n\t}\r\n\r\n\t/**\r\n\t * Request the compared items from hawk.\r\n\t *\r\n\t * @param {CompareItemRequest} request\r\n\t * @param {CancelToken} [cancellationToken]\r\n\t * @returns {Promise}\r\n\t * @memberof HawkClient\r\n\t */\r\n\tpublic async getComparedItems(\r\n\t\trequest: CompareItemRequest,\r\n\t\tcancellationToken?: CancelToken,\r\n\t): Promise {\r\n\t\tconst result = await axios.post(\r\n\t\t\tnew URL(this.compareItemsURL, this.baseUrl).href,\r\n\t\t\trequest,\r\n\t\t\t{\r\n\t\t\t\tcancelToken: cancellationToken,\r\n\t\t\t},\r\n\t\t);\r\n\r\n\t\treturn result.data;\r\n\t}\r\n\r\n\tpublic async getRecommendationWidgetItems(\r\n\t\trequest: RecommendationRequest,\r\n\t\tcancellationToken?: CancelToken,\r\n\t): Promise {\r\n\t\tconst result = await axios.post(\r\n\t\t\tnew URL(this.recommendationWidgetUrl, this.recommendationUrl).href,\r\n\t\t\trequest,\r\n\t\t\t{\r\n\t\t\t\tcancelToken: cancellationToken,\r\n\t\t\t},\r\n\t\t);\r\n\t\treturn result.data;\r\n\t}\r\n}\r\n\r\nexport default HawkClient;\r\n","import React from 'react';\r\nimport { SVGProps } from './SVGProps';\r\nimport classnames from 'classnames';\r\n\r\n/**\r\n * Spinner SVG for loading purposes\r\n *\r\n * @returns\r\n */\r\nfunction MagnifyingGlassSVG({ className, ...rest }: SVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default MagnifyingGlassSVG;\r\n","import axios, { AxiosInstance, AxiosResponse, AxiosError } from 'axios';\r\nimport AccountUrls from 'shared/util/AccountUrls';\r\nimport { getCsrfToken } from './UserData';\r\n\r\n/**\r\n * Helper that creates an instance of Axios to be used throughout the client application\r\n * and adds a default X-Requested-With header to all requests.\r\n *\r\n */\r\nconst AxiosHelper: AxiosInstance = axios.create();\r\nAxiosHelper.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';\r\n\r\n// Add CSRF tokens to all commands that are not GET, HEAD, or OPTIONS\r\nAxiosHelper.interceptors.request.use(async (config) => {\r\n\tif (\r\n\t\tconfig.method?.toLowerCase() !== 'get' &&\r\n\t\tconfig.method?.toLowerCase() !== 'head' &&\r\n\t\tconfig.method?.toLowerCase() !== 'options'\r\n\t) {\r\n\t\tconst csrfToken = await getCsrfToken();\r\n\t\tconfig.headers = { RequestVerificationToken: csrfToken, ...config.headers };\r\n\t}\r\n\treturn config;\r\n});\r\n\r\nexport default AxiosHelper;\r\n\r\n// eslint-disable-next-line no-unused-vars\r\nexport const addUnauthorizedAccessInterceptor = (history) => {\r\n\t// this allows us to act when any request going through axios succeeds or fails.\r\n\tAxiosHelper.interceptors.response.use(\r\n\t\t(response: AxiosResponse) => {\r\n\t\t\treturn response;\r\n\t\t},\r\n\t\t(error: AxiosError) => {\r\n\t\t\tif (error.response && error.response.status === 401) {\r\n\t\t\t\twindow.location.replace(\r\n\t\t\t\t\t`${AccountUrls.Login}?ReturnUrl=${encodeURIComponent(window.location.pathname)}`,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\treturn Promise.reject(error);\r\n\t\t},\r\n\t);\r\n};\r\n","import * as React from 'react';\r\n\r\ninterface CheckmarkSVGProps {\r\n\tclass?: string;\r\n}\r\n\r\n/**\r\n * Checkmark SVG\r\n *\r\n * @returns\r\n */\r\nfunction CheckmarkSVG(props: CheckmarkSVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default CheckmarkSVG;\r\n","import * as React from 'react';\r\n\r\ninterface PlusCircleSVGProps {\r\n\tclass: string;\r\n}\r\n\r\n/**\r\n * Plus SVG\r\n *\r\n * @returns\r\n */\r\nfunction PlusCircleSVG(props: PlusCircleSVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default PlusCircleSVG;\r\n","import React from 'react';\r\n\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport { FacetSelectionState } from 'store/Store';\r\nimport DashCircleSVG from 'components/svg/DashCircleSVG';\r\nimport CheckmarkSVG from 'components/svg/CheckmarkSVG';\r\nimport PlusCircleSVG from 'components/svg/PlusCircleSVG';\r\nimport { useHawkConfig } from 'components/ConfigProvider';\r\n\r\nfunction Checkbox() {\r\n\tconst { store } = useHawkSearch();\r\n\tconst { config } = useHawkConfig();\r\n\r\n\tconst {\r\n\t\tfacet,\r\n\t\tstate: { facetValues },\r\n\t\tactor,\r\n\t\trenderer,\r\n\t} = useFacet();\r\n\r\n\tfunction renderOptions() {\r\n\t\tif (facet.FieldType === 'range') {\r\n\t\t\treturn facetValues.map((value) => {\r\n\t\t\t\tconst correspondingRange = facet.Ranges.find((c) => c.Value === value.Value);\r\n\t\t\t\tconst rangeValueAssetUrl = correspondingRange\r\n\t\t\t\t\t? config.dashboardUrl + correspondingRange.AssetFullUrl\r\n\t\t\t\t\t: '';\r\n\r\n\t\t\t\t// facets can be selected or negated, so explicitly check that the facet is not selected\r\n\t\t\t\tconst selectionState = store.isFacetSelected(facet, value).state;\r\n\r\n\t\t\t\tconst isSelected = selectionState !== FacetSelectionState.NotSelected;\r\n\t\t\t\tconst isNegated = selectionState === FacetSelectionState.Negated;\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t
  • \r\n\t\t\t\t\t\t actor.selectFacet(value)}\r\n\t\t\t\t\t\t\tclassName=\"hawk-facet-rail__facet-btn\"\r\n\t\t\t\t\t\t\taria-pressed={isSelected}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{renderCheckMark(isSelected)}\r\n\t\t\t\t\t\t\t{rangeValueAssetUrl !== '' ? (\r\n\t\t\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t\t\t\t\t{value.Label}\r\n\t\t\t\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t{value.Label} ({value.Count})\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t) : (\r\n\t\t\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t{value.Label} ({value.Count})\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t{renderFacetActions(value.Value || '', isNegated)}\r\n\t\t\t\t\t
  • \r\n\t\t\t\t);\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\treturn facetValues.map((value) => {\r\n\t\t\t\t// facets can be selected or negated, so explicitly check that the facet is not selected\r\n\t\t\t\tconst selectionState = store.isFacetSelected(facet, value).state;\r\n\r\n\t\t\t\tconst isSelected = selectionState !== FacetSelectionState.NotSelected;\r\n\t\t\t\tconst isNegated = selectionState === FacetSelectionState.Negated;\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t
  • \r\n\t\t\t\t\t\t actor.selectFacet(value)}\r\n\t\t\t\t\t\t\tclassName=\"hawk-facet-rail__facet-btn\"\r\n\t\t\t\t\t\t\taria-pressed={isSelected}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{renderCheckMark(isSelected)}\r\n\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t{value.Label} ({value.Count})\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t{renderFacetActions(value.Value || '', isNegated)}\r\n\t\t\t\t\t
  • \r\n\t\t\t\t);\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tfunction renderCheckMark(isSelected: boolean) {\r\n\t\treturn (\r\n\t\t\t\r\n\t\t\t\t{isSelected ? : null}\r\n\t\t\t\r\n\t\t);\r\n\t}\r\n\tfunction renderFacetActions(value: string, isNegated: boolean) {\r\n\t\treturn (\r\n\t\t\t\r\n\t\t);\r\n\t}\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t{facetValues.length > 0 ? (\r\n\t\t\t\t
    \r\n\t\t\t\t\t
      {renderOptions()}
    \r\n\t\t\t\t
    \r\n\t\t\t) : null}\r\n\r\n\t\t\t{/* render the default truncation control as we don't need to customize this */}\r\n\t\t\t{renderer.renderTruncation()}\r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default Checkbox;\r\n","import React, { useState, useRef } from 'react';\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport { useTranslation } from 'react-i18next';\r\nimport MagnifyingGlassSVG from 'shared/components/svg/MagnifyingGlassSVG';\r\n\r\nfunction Search() {\r\n\tconst { store, actor: hawkActor } = useHawkSearch();\r\n\tconst { facet, actor } = useFacet();\r\n\r\n\tconst [input, setInput] = useState(undefined);\r\n\r\n\tconst searchInputRef = useRef(null);\r\n\tconst { t } = useTranslation();\r\n\r\n\tfunction onKeyDown(event: React.KeyboardEvent) {\r\n\t\tif (event.key === 'Enter') {\r\n\t\t\tsetInput(undefined); // clear the user's entered value as we want to be driven by the store again\r\n\r\n\t\t\tactor.selectFacet(event.currentTarget.value);\r\n\t\t}\r\n\t}\r\n\r\n\tfunction clearFacet() {\r\n\t\tsetInput(undefined); // clear the user's entered value as we want to be driven by the store again\r\n\r\n\t\thawkActor.clearFacet(facet);\r\n\t}\r\n\r\n\tfunction getInputValue() {\r\n\t\tif (input !== undefined) {\r\n\t\t\t// if the user type an input, that's the value for the input\r\n\t\t\treturn input;\r\n\t\t}\r\n\r\n\t\t// otherwise, use the value from the store\r\n\t\treturn store.pendingSearch.SearchWithin ?? '';\r\n\t}\r\n\r\n\tconst labelFor = `search-within-${facet.FacetId.toString()}`;\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t
    \r\n\t\t\t\t\r\n\r\n\t\t\t\t {\r\n\t\t\t\t\t\tif (searchInputRef && searchInputRef.current) {\r\n\t\t\t\t\t\t\tsetInput(undefined);\r\n\r\n\t\t\t\t\t\t\tactor.selectFacet(searchInputRef.current.value);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}}\r\n\t\t\t\t\taria-label={facet.Name}\r\n\t\t\t\t>\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t
    \r\n\r\n\t\t\t{store.pendingSearch.SearchWithin ? (\r\n\t\t\t\t
    \r\n\t\t\t\t\t\r\n\t\t\t\t
    \r\n\t\t\t) : null}\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default Search;\r\n","import React from 'react';\r\n\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport { FacetSelectionState } from 'store/Store';\r\n\r\nfunction Link() {\r\n\tconst { store } = useHawkSearch();\r\n\tconst {\r\n\t\tfacet,\r\n\t\tstate: { facetValues },\r\n\t\tactor,\r\n\t\trenderer,\r\n\t} = useFacet();\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t
    \r\n\t\t\t\t
      \r\n\t\t\t\t\t{facetValues.map((value) => {\r\n\t\t\t\t\t\t// facets can be selected or negated, so explicitly check that the facet is not selected\r\n\t\t\t\t\t\tconst selectionState = store.isFacetSelected(facet, value).state;\r\n\r\n\t\t\t\t\t\tconst isSelected = selectionState !== FacetSelectionState.NotSelected;\r\n\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t
    • \r\n\t\t\t\t\t\t\t\t actor.selectFacet(value)}\r\n\t\t\t\t\t\t\t\t\tclassName=\"hawk-facet-rail__facet-btn\"\r\n\t\t\t\t\t\t\t\t\taria-pressed={isSelected}\r\n\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t{value.Label} ({value.Count})\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t
    • \r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t})}\r\n\t\t\t\t
    \r\n\t\t\t
    \r\n\r\n\t\t\t{/* render the default truncation control as we don't need to customize this */}\r\n\t\t\t{renderer.renderTruncation()}\r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default Link;\r\n","import React, { useState, useEffect } from 'react';\r\nimport type NumberFormat from 'react-number-format';\r\nimport Spinner from 'shared/components/Spinner';\r\nconst LazyNumberFormat = React.lazy(() => import('react-number-format'));\r\n\r\nexport interface SliderNumericInputsProps {\r\n\tmin: number;\r\n\tmax: number;\r\n\tvalues: number[];\r\n\tisCurrency: boolean;\r\n\tcurrencySymbol: string;\r\n\tdecimalPrecision: number;\r\n\tonValueChange(minValue: number, maxValue: number): void;\r\n}\r\n\r\nfunction SliderNumericInputs(sliderProps: SliderNumericInputsProps) {\r\n\tconst [minValue, setMinValue] = useState('' as string);\r\n\tconst [maxValue, setMaxValue] = useState('' as string);\r\n\r\n\tfunction onMinUpdate(values: any) {\r\n\t\tconst { value } = values;\r\n\r\n\t\tconst newMinValue = Number(value);\r\n\t\tif (isNaN(newMinValue) || minValue === value) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tsetMinValue(value);\r\n\t}\r\n\r\n\tfunction onMaxUpdate(values: any) {\r\n\t\tconst { value } = values;\r\n\r\n\t\tconst newMaxValue = Number(value);\r\n\t\tif (isNaN(newMaxValue) || maxValue === value) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tsetMaxValue(value);\r\n\t}\r\n\r\n\t// eslint-disable-next-line no-unused-vars\r\n\tfunction reloadFacets(event: React.FormEvent) {\r\n\t\tsliderProps.onValueChange(Number(minValue), Number(maxValue));\r\n\t}\r\n\r\n\tuseEffect(() => {\r\n\t\tsetMinValue(sliderProps.values[0].toString());\r\n\t\tsetMaxValue(sliderProps.values[1].toString());\r\n\t}, [sliderProps]);\r\n\r\n\treturn (\r\n\t\t}>\r\n\t\t\t
    \r\n\t\t\t\t\r\n\r\n\t\t\t\t\r\n\t\t\t
    \r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default SliderNumericInputs;\r\n","import React, { useState, useEffect } from 'react';\r\nimport { PublicState } from 'rheostat';\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport SliderNumericInputs from 'components/ui/Facets/SliderNumericInputs';\r\n\r\nconst Rheostat = React.lazy(() => import(/* webpackChunkName: \"rheostat\" */ 'rheostat'));\r\n\r\nfunction Slider() {\r\n\tconst {\r\n\t\tstore: { facetSelections },\r\n\t} = useHawkSearch();\r\n\r\n\tconst {\r\n\t\tstate: { facetValues, decimalPrecision },\r\n\t\tfacet,\r\n\t\tactor,\r\n\t} = useFacet();\r\n\r\n\t// the range of the slider is defined by the first facet value. or null if there is no first value\r\n\tconst range = facetValues.length > 0 ? facetValues[0] : null;\r\n\r\n\tconst [rangeMin, setMinRange] = useState(range && Math.floor(parseFloat(range.RangeMin || '')));\r\n\tconst [rangeMax, setMaxRange] = useState(range && Math.ceil(parseFloat(range.RangeMax || '')));\r\n\tconst [rangeStart, setStartRange] = useState(range && Math.floor(parseFloat(range.RangeStart || '')));\r\n\tconst [rangeEnd, setEndRange] = useState(range && Math.ceil(parseFloat(range.RangeEnd || '')));\r\n\r\n\t// if there's no range, initialize to zeros\r\n\tconst [minValue, setMinValue] = useState();\r\n\tconst [maxValue, setMaxValue] = useState();\r\n\r\n\tconst [isCurrency, setIsCurrency] = useState(facet.IsCurrency);\r\n\tconst [currencySymbol, setCurrencySymbol] = useState(facet.CurrencySymbol);\r\n\r\n\tuseEffect(() => {\r\n\t\tsetCurrencySymbol(facet.CurrencySymbol ?? '$');\r\n\t\tsetIsCurrency(facet.IsCurrency);\r\n\t}, [facet]);\r\n\r\n\tuseEffect(() => {\r\n\t\tconst paramName = facet.ParamName || facet.Field;\r\n\r\n\t\t// clear min and max value if these were cleared\r\n\t\tif (!paramName || !(paramName in facetSelections)) {\r\n\t\t\tsetMinValue(undefined);\r\n\t\t\tsetMaxValue(undefined);\r\n\t\t} else if (\r\n\t\t\tparamName in facetSelections &&\r\n\t\t\tfacetSelections[paramName].items &&\r\n\t\t\tfacetSelections[paramName].items.length > 0\r\n\t\t) {\r\n\t\t\tconst selectedValues = facetSelections[paramName].items[0].value.split(',');\r\n\t\t\tsetMinValue(Number(selectedValues[0]));\r\n\t\t\tsetMaxValue(Number(selectedValues[1]));\r\n\t\t}\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t}, [facetSelections]);\r\n\r\n\tuseEffect(() => {\r\n\t\tconst newRange = facetValues.length > 0 ? facetValues[0] : null;\r\n\t\tsetMinRange(newRange && Math.floor(parseFloat(newRange.RangeMin || '')));\r\n\t\tsetMaxRange(newRange && Math.ceil(parseFloat(newRange.RangeMax || '')));\r\n\t\tsetStartRange(newRange && Math.floor(parseFloat(newRange.RangeStart || '')));\r\n\t\tsetEndRange(newRange && Math.ceil(parseFloat(newRange.RangeEnd || '')));\r\n\t}, [facetValues]);\r\n\r\n\tif (\r\n\t\trangeMin === null ||\r\n\t\tisNaN(rangeMin) ||\r\n\t\trangeMax === null ||\r\n\t\tisNaN(rangeMax) ||\r\n\t\trangeStart === null ||\r\n\t\tisNaN(rangeStart) ||\r\n\t\trangeEnd === null ||\r\n\t\tisNaN(rangeEnd)\r\n\t) {\r\n\t\t// this facet is somehow misconfigured so don't render\r\n\t\treturn null;\r\n\t}\r\n\r\n\tfunction onSliderValueChange(state: PublicState) {\r\n\t\tconst [newMin, newMax] = state.values;\r\n\r\n\t\tsetFacetValues(newMin, newMax);\r\n\t}\r\n\r\n\tfunction onValueChange(newMinValue: number, newMaxValue: number) {\r\n\t\tlet currentMinValue = minValue;\r\n\t\tlet currentMaxValue = maxValue;\r\n\t\t// if min value wasn't yet selected use range start\r\n\t\tif (minValue === undefined && rangeStart !== null) {\r\n\t\t\tcurrentMinValue = rangeStart; // setMinValue(rangeStart);\r\n\t\t}\r\n\r\n\t\t// if max value wasn't yet selected use range end\r\n\t\tif (maxValue === undefined && rangeEnd !== null) {\r\n\t\t\tcurrentMaxValue = rangeEnd;\r\n\t\t}\r\n\r\n\t\tif (currentMinValue === undefined || currentMaxValue === undefined) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (currentMinValue !== newMinValue && newMinValue <= currentMaxValue) {\r\n\t\t\tcurrentMinValue = newMinValue;\r\n\t\t}\r\n\r\n\t\tif (currentMaxValue !== newMaxValue && newMaxValue >= currentMinValue) {\r\n\t\t\tcurrentMaxValue = newMaxValue;\r\n\t\t}\r\n\t\tsetMinValue(currentMinValue);\r\n\t\tsetMaxValue(currentMaxValue);\r\n\t\tsetFacetValues(currentMinValue, currentMaxValue);\r\n\t}\r\n\r\n\tfunction setFacetValues(minVal: number | undefined, maxVal: number | undefined) {\r\n\t\tif (minVal === undefined || maxVal === undefined || isNaN(minVal) || isNaN(maxVal)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tsetMinValue(minVal);\r\n\t\tsetMaxValue(maxVal);\r\n\r\n\t\t// this selection is sent to hawk separated by commas, so build the value here\r\n\t\tconst selection = `${minVal},${maxVal}`;\r\n\r\n\t\tactor.setFacets([selection]);\r\n\t}\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t
    \r\n\t\t\t\tLoading...
    }>\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t
    \r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default Slider;\r\n","import React from 'react';\r\n\r\nimport { Value } from 'models/Facets/Value';\r\nimport { Swatch } from 'models/Facets';\r\nimport { useHawkConfig } from 'components/ConfigProvider';\r\nimport * as Constants from 'util/Constants';\r\n\r\nexport interface SwatchItemProps {\r\n\tswatchValue: Value;\r\n\tfacetSwatch: Swatch;\r\n\tisNegated: boolean;\r\n\tisSelected: boolean;\r\n\tisColor: boolean;\r\n\tonSwatchSelected(facetValue: string, isNegated: boolean): void;\r\n}\r\n\r\n/**\r\n * Gets the absolute URL of the swatch's image resource.\r\n */\r\nfunction getSwatchUrl(item: SwatchItemProps) {\r\n\t// eslint-disable-next-line\r\n\tconst { config } = useHawkConfig();\r\n\r\n\tlet suffix = !item.facetSwatch.AssetUrl ? item.facetSwatch.AssetName : item.facetSwatch.AssetUrl;\r\n\r\n\tif (suffix.length === 0 || /^https?:\\/\\//.test(suffix)) {\r\n\t\t// If our \"suffix\" is an absolute url or empty it isn't meaningful to prepend anything to it.\r\n\t\treturn suffix;\r\n\t}\r\n\r\n\t// Suffix must have a prepended slash\r\n\tif (suffix[0] !== '/') {\r\n\t\tsuffix = '/' + suffix;\r\n\t}\r\n\r\n\t// Prefix shoudn't have an appended slash\r\n\t// Technically speaking this is legal eg \"https://www.example.com/test//assets/1232/red.gif\" but it is more likely than not, an error.\r\n\tconst dashboardUrl = config.dashboardUrl || Constants.defaultDashboardUrl;\r\n\tconst prefix =\r\n\t\tdashboardUrl[dashboardUrl.length - 1] === '/'\r\n\t\t\t? dashboardUrl.substring(0, dashboardUrl.length - 1)\r\n\t\t\t: dashboardUrl;\r\n\r\n\treturn prefix + suffix;\r\n}\r\n\r\nfunction SwatchItem(item: SwatchItemProps) {\r\n\tconst facetValue = item.swatchValue.Value || '';\r\n\r\n\t// facets can be selected or negated, so explicitly check that the facet is not selected\r\n\tconst swatchUrl = getSwatchUrl(item);\r\n\r\n\tconst colorSwatchStyle = {\r\n\t\tbackgroundColor: item.facetSwatch.Color,\r\n\t};\r\n\r\n\tconst listItemClassNames =\r\n\t\t'hawk-facet-rail__swatch-list-item' +\r\n\t\t(item.isSelected ? ' hawkFacet-active' : '') +\r\n\t\t(item.isNegated ? ' hawkFacet-negative' : '');\r\n\r\n\treturn (\r\n\t\t
  • \r\n\t\t\t item.onSwatchSelected(facetValue, false)}\r\n\t\t\t\tclassName=\"hawk-styleSwatch\"\r\n\t\t\t\taria-pressed={item.isSelected}\r\n\t\t\t>\r\n\t\t\t\t\r\n\t\t\t\t\t{item.isColor ? (\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t{item.facetSwatch.Value}\r\n\t\t\t\t\t)}\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t
  • \r\n\t);\r\n}\r\n\r\nexport default SwatchItem;\r\n","import React from 'react';\r\n\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport { FacetSelectionState } from 'store/Store';\r\nimport SwatchItem from './SwatchItem';\r\n\r\nfunction Swatch() {\r\n\tconst { store } = useHawkSearch();\r\n\tconst {\r\n\t\tfacet,\r\n\t\tactor,\r\n\t\tstate: { facetValues },\r\n\t\trenderer,\r\n\t} = useFacet();\r\n\r\n\tfunction onSwatchSelected(facetValue: string, isNegated: boolean) {\r\n\t\tisNegated ? actor.negateFacet(facetValue) : actor.selectFacet(facetValue);\r\n\t}\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t
    \r\n\t\t\t\t
      \r\n\t\t\t\t\t{facet.SwatchData &&\r\n\t\t\t\t\t\tfacetValues.map((value) => {\r\n\t\t\t\t\t\t\tconst facetValue = value.Value || '';\r\n\t\t\t\t\t\t\t// find swatch that is corresponding with value\r\n\t\t\t\t\t\t\tconst facetSwatch =\r\n\t\t\t\t\t\t\t\tfacet.SwatchData &&\r\n\t\t\t\t\t\t\t\tfacet.SwatchData.find((s) => s.Value.toLowerCase() === facetValue.toLowerCase());\r\n\t\t\t\t\t\t\tif (!facetSwatch) {\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst selectionState = store.isFacetSelected(facet, value).state;\r\n\t\t\t\t\t\t\tconst isNegated = selectionState === FacetSelectionState.Negated;\r\n\t\t\t\t\t\t\tconst isSelected = selectionState !== FacetSelectionState.NotSelected;\r\n\r\n\t\t\t\t\t\t\tconst isColor = !!facetSwatch.Color;\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t
    \r\n\t\t\t
    \r\n\r\n\t\t\t{/* render the default truncation control as we don't need to customize this */}\r\n\t\t\t{renderer.renderTruncation()}\r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default Swatch;\r\n","import React, { useState } from 'react';\r\n\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { FacetSelectionState } from 'store/Store';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport CheckmarkSVG from 'components/svg/CheckmarkSVG';\r\nimport { Value } from 'models/Facets';\r\nimport PlusCircleSVG from 'components/svg/PlusCircleSVG';\r\nimport DashCircleSVG from 'components/svg/DashCircleSVG';\r\n\r\nexport interface NestedItemProps {\r\n\thierarchyValue: Value;\r\n\tisNegated: boolean;\r\n\tisSelected: boolean;\r\n\tonValueSelected(facetValue: Value, isNegated: boolean): void;\r\n}\r\n\r\nfunction NestedItem(item: NestedItemProps) {\r\n\tconst { store } = useHawkSearch();\r\n\tconst { facet } = useFacet();\r\n\r\n\tconst [isExpanded, setIsExpanded] = useState(false);\r\n\tconst [isTruncated, setIsTruncated] = useState(facet.shouldTruncate);\r\n\r\n\tconst hierarchyValue = item.hierarchyValue || '';\r\n\tlet hierarchyChildren = item.hierarchyValue.Children || [];\r\n\r\n\tlet remainingValues = 0;\r\n\r\n\tconst shouldTruncateChildren =\r\n\t\tfacet.DisplayType === 'truncating' && hierarchyChildren.length > facet.TruncateThreshold;\r\n\r\n\tif (shouldTruncateChildren && isTruncated) {\r\n\t\tconst valuesBeforeTrunc = hierarchyChildren.length;\r\n\r\n\t\thierarchyChildren = hierarchyChildren.slice(0, facet.TruncateThreshold);\r\n\r\n\t\tremainingValues = valuesBeforeTrunc - facet.TruncateThreshold;\r\n\t}\r\n\r\n\tfunction renderChildTruncation() {\r\n\t\treturn (\r\n\t\t\t<>\r\n\t\t\t\t{shouldTruncateChildren && (\r\n\t\t\t\t\t
  • \r\n\t\t\t\t\t\t\r\n\t\t\t\t\t
  • \r\n\t\t\t\t)}\r\n\t\t\t\r\n\t\t);\r\n\t}\r\n\r\n\treturn (\r\n\t\t
  • \r\n\t\t\t
    \r\n\t\t\t\t item.onValueSelected(hierarchyValue, false)}\r\n\t\t\t\t\tclassName=\"hawk-facet-rail__facet-btn\"\r\n\t\t\t\t\taria-pressed={item.isSelected}\r\n\t\t\t\t>\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t{item.isSelected ? : null}\r\n\t\t\t\t\t\r\n\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t{item.hierarchyValue.Label} ({item.hierarchyValue.Count})\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\r\n\t\t\t\t item.onValueSelected(hierarchyValue, true)}\r\n\t\t\t\t\tclassName=\"hawk-facet-rail__facet-btn-exclude\"\r\n\t\t\t\t>\r\n\t\t\t\t\t{item.isNegated ? (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tInclude facet\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tExclude facet\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t)}\r\n\t\t\t\t\r\n\t\t\t
    \r\n\r\n\t\t\t{hierarchyChildren.length > 0 ? (\r\n\t\t\t\t setIsExpanded(!isExpanded)}\r\n\t\t\t\t>\r\n\t\t\t\t\t{isExpanded ? (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\tCollapse child facets\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\tExpand child facets\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t)}\r\n\t\t\t\t\r\n\t\t\t) : null}\r\n\r\n\t\t\t{isExpanded && hierarchyChildren ? (\r\n\t\t\t\t
    \r\n\t\t\t\t\t
      \r\n\t\t\t\t\t\t{hierarchyChildren.map((value) => {\r\n\t\t\t\t\t\t\tconst selectionState = store.isFacetSelected(facet, value).state;\r\n\t\t\t\t\t\t\tconst isNegated = selectionState === FacetSelectionState.Negated;\r\n\t\t\t\t\t\t\tconst isSelected = selectionState !== FacetSelectionState.NotSelected;\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t\t{renderChildTruncation()}\r\n\t\t\t\t\t
    \r\n\t\t\t\t
    \r\n\t\t\t) : (\r\n\t\t\t\t<>\r\n\t\t\t)}\r\n\t\t
  • \r\n\t);\r\n}\r\n\r\nexport default NestedItem;\r\n","import React from 'react';\r\n\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { FacetSelectionState } from 'store/Store';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\nimport NestedItem from './NestedItem';\r\nimport { Value } from 'models/Facets/Value';\r\n\r\nfunction Nested() {\r\n\tconst { store } = useHawkSearch();\r\n\tconst {\r\n\t\tfacet,\r\n\t\tstate: { facetValues },\r\n\t\tactor,\r\n\t\trenderer,\r\n\t} = useFacet();\r\n\r\n\tfunction onValueSelected(facetValue: Value, isNegated: boolean) {\r\n\t\tisNegated ? actor.negateFacet(facetValue) : actor.selectFacet(facetValue);\r\n\t}\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t{facetValues.length > 0 ? (\r\n\t\t\t\t
    \r\n\t\t\t\t\t
      \r\n\t\t\t\t\t\t{facetValues.map((value) => {\r\n\t\t\t\t\t\t\t// facets can be selected or negated, so explicitly check that the facet is not selected\r\n\t\t\t\t\t\t\tconst selectionState = store.isFacetSelected(facet, value).state;\r\n\r\n\t\t\t\t\t\t\tconst isSelected = selectionState !== FacetSelectionState.NotSelected;\r\n\t\t\t\t\t\t\tconst isNegated = selectionState === FacetSelectionState.Negated;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t
    \r\n\t\t\t\t
    \r\n\t\t\t) : null}\r\n\r\n\t\t\t{/* render the default truncation control as we don't need to customize this */}\r\n\t\t\t{renderer.renderTruncation()}\r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default Nested;\r\n","import React, { useState } from 'react';\r\nimport { useHawkSearch } from 'components/StoreProvider';\r\nimport { useFacet } from 'components/ui/Facets/Facet';\r\n\r\nfunction OpenRange() {\r\n\tconst { actor: hawkActor } = useHawkSearch();\r\n\r\n\tconst {\r\n\t\tstate: { facetValues },\r\n\t\tfacet,\r\n\t\tactor,\r\n\t} = useFacet();\r\n\r\n\t// the open range boundary values are defined by the first facet value. or null if there is no first value\r\n\r\n\tconst range = facetValues.length > 0 ? facetValues[0] : null;\r\n\r\n\tconst rangeStart = (range && range.RangeStart) || '';\r\n\tconst rangeEnd = (range && range.RangeEnd) || '';\r\n\r\n\t// if there's no range, initialize to empty strings\r\n\tconst [minValue, setStartValue] = useState(rangeStart || '');\r\n\tconst [maxValue, setEndValue] = useState(rangeEnd || '');\r\n\r\n\tif (rangeStart === null || rangeEnd === null) {\r\n\t\t// this facet is somehow misconfigured so don't render\r\n\t\treturn null;\r\n\t}\r\n\r\n\tfunction onRangeStartChange(event: React.FormEvent) {\r\n\t\tsetFacetValues(event.currentTarget.value, maxValue);\r\n\t}\r\n\r\n\tfunction onRangeEndChange(event: React.FormEvent) {\r\n\t\tsetFacetValues(minValue, event.currentTarget.value);\r\n\t}\r\n\r\n\tfunction setFacetValues(startVal: string, endVal: string) {\r\n\t\tsetStartValue(startVal);\r\n\t\tsetEndValue(endVal);\r\n\r\n\t\t// this selection is sent to hawk separated by commas, so build the value here\r\n\r\n\t\tif (startVal === '' && endVal === '') {\r\n\t\t\thawkActor.clearFacet(facet);\r\n\t\t} else {\r\n\t\t\tconst selection = `${startVal},${endVal}`;\r\n\t\t\tactor.setFacets([selection]);\r\n\t\t}\r\n\t}\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t
    \r\n\t\t\t\t
    \r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t
    \r\n\t\t\t
    \r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default OpenRange;\r\n","export enum FacetType {\r\n\tCheckbox = 'checkbox',\r\n\tNestedCheckbox = 'nestedcheckbox',\r\n\tLink = 'link',\r\n\tNestedlink = 'nestedlink',\r\n\tSlider = 'slider',\r\n\tSwatch = 'swatch',\r\n\tRating = 'rating',\r\n\tSize = 'size',\r\n\tSearchWithin = 'search',\r\n\tRecentSearches = 'recentsearches',\r\n\tRelatedSearches = 'relatedsearches',\r\n\tOpenRange = 'openRange',\r\n}\r\n","import {\r\n\tCheckbox as DefaultCheckbox,\r\n\tNestedCheckbox as DefaultNestedCheckbox,\r\n\tSearch as DefaultSearch,\r\n\tLink as DefaultLink,\r\n\tSlider as DefaultSlider,\r\n\tSwatch as DefaultSwatch,\r\n\tOpenRange as DefaultOpenRange,\r\n} from 'components/ui/Facets/FacetTypes';\r\nimport { FacetComponent } from 'types/FacetComponent';\r\nimport { FacetType } from 'models/Facets/FacetType';\r\nimport { SuggestionStrategyMatch, SuggestionType } from 'models/Autocomplete/Suggestion';\r\nimport { ProductStrategy, CategoryStrategy, PopularStrategy, ContentStrategy } from 'models/Autocomplete';\r\n\r\n// the default set of facet components that we support\r\nconst defaultFacetComponents: FacetComponent[] = [\r\n\t{ facetType: FacetType.Checkbox, component: DefaultCheckbox },\r\n\t{ facetType: FacetType.NestedCheckbox, component: DefaultNestedCheckbox },\r\n\t{ facetType: FacetType.SearchWithin, component: DefaultSearch },\r\n\t{ facetType: FacetType.Link, component: DefaultLink },\r\n\t{ facetType: FacetType.Slider, component: DefaultSlider },\r\n\t{ facetType: FacetType.Swatch, component: DefaultSwatch },\r\n\t{ facetType: FacetType.OpenRange, component: DefaultOpenRange },\r\n];\r\n\r\nconst defaultAutocompleteStrategies: SuggestionStrategyMatch[] = [\r\n\t{ type: SuggestionType.Product, strategy: new ProductStrategy() },\r\n\t{ type: SuggestionType.Category, strategy: new CategoryStrategy() },\r\n\t{ type: SuggestionType.Popular, strategy: new PopularStrategy() },\r\n\t{ type: SuggestionType.Content, strategy: new ContentStrategy() },\r\n];\r\n\r\n/**\r\n * Builds a list of all supported facet components by also taking into consideration overridden components.\r\n */\r\nexport function getFacetComponents(overridedComponents: FacetComponent[]) {\r\n\tconst facetComponents: FacetComponent[] = [];\r\n\r\n\tfor (const key in FacetType) {\r\n\t\tconst fType = FacetType[key];\r\n\r\n\t\tconst fComponent =\r\n\t\t\t// check to see if the facet is overridden\r\n\t\t\toverridedComponents.find((component) => component.facetType === fType) ||\r\n\t\t\t// otherwise, pull from defaults\r\n\t\t\tdefaultFacetComponents.find((component) => component.facetType === fType);\r\n\r\n\t\tif (fComponent) {\r\n\t\t\tfacetComponents.push(fComponent);\r\n\t\t}\r\n\t}\r\n\r\n\treturn facetComponents;\r\n}\r\n\r\n/**\r\n * Builds a list of all supported autocomplete suggestion strategiesby also taking into consideration overridden strategies.\r\n */\r\nexport function getAutocompleteStrategies(overridedStrategies: SuggestionStrategyMatch[]): SuggestionStrategyMatch[] {\r\n\tconst suggestionStrategies: SuggestionStrategyMatch[] = [];\r\n\r\n\t// tslint:disable-next-line:forin\r\n\tfor (const key in SuggestionType) {\r\n\t\tconst sType = SuggestionType[key];\r\n\r\n\t\tconst autocompleteStrategy =\r\n\t\t\t// check to see if the facet is overridden\r\n\t\t\toverridedStrategies.find((strategyMatch) => strategyMatch.type === sType) ||\r\n\t\t\t// otherwise, pull from defaults\r\n\t\t\tdefaultAutocompleteStrategies.find((strategyMatch) => strategyMatch.type === sType);\r\n\r\n\t\tif (autocompleteStrategy) {\r\n\t\t\tsuggestionStrategies.push(autocompleteStrategy);\r\n\t\t}\r\n\t}\r\n\treturn suggestionStrategies;\r\n}\r\n","/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */\r\nimport React from 'react';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\nimport { Response, Product, Popular, Category, Content } from 'models/Autocomplete';\r\nimport { Suggestion, SuggestionType } from '../../../models/Autocomplete/Suggestion';\r\nimport { useTranslation } from 'react-i18next';\r\nimport classnames from 'classnames';\r\n/* #region Commerce */\r\nimport { dispatchRocEvent } from 'shared/hooks/useRocEventHandler';\r\nimport { CommerceSuggestType } from 'features/tracking/trackers/commerce/hawksearch/tracking-commerce';\r\n/* #endregion */\r\n\r\nexport interface SearchSuggestionsListProps {\r\n\tisLoading: boolean;\r\n\tsearchResults: Response;\r\n\tdownshift: ControllerStateAndHelpers;\r\n\tquery: string;\r\n\tonViewMatches: (downshift: ControllerStateAndHelpers) => void;\r\n}\r\n\r\nfunction hasAllEmpty(\r\n\tpopular: Popular[] | undefined,\r\n\tcategories: Category[] | undefined,\r\n\tproducts: Product[] | undefined,\r\n\tcontent: Content[] | undefined,\r\n) {\r\n\tconst hasPopular = popular && popular.length === 0;\r\n\tconst hasCategories = categories && categories.length === 0;\r\n\tconst hasProducts = products && products.length === 0;\r\n\tconst hasContent = content && content.length === 0;\r\n\treturn hasPopular && hasCategories && hasProducts && hasContent;\r\n}\r\n\r\nfunction getAtleastOneExist(\r\n\tpopular: Popular[] | undefined,\r\n\tcategories: Category[] | undefined,\r\n\tproducts: Product[] | undefined,\r\n\tcontent: Content[] | undefined,\r\n) {\r\n\tconst hasPopular = popular && popular.length > 0;\r\n\tconst hasCategories = categories && categories.length > 0;\r\n\tconst hasProducts = products && products.length > 0;\r\n\tconst hasContent = content && content.length > 0;\r\n\treturn hasPopular || hasCategories || hasProducts || hasContent;\r\n}\r\n\r\nfunction SearchSuggestionsList({\r\n\tisLoading,\r\n\tsearchResults,\r\n\tdownshift,\r\n\tquery,\r\n\tonViewMatches,\r\n}: SearchSuggestionsListProps) {\r\n\tconst {\r\n\t\tPopular: popular,\r\n\t\tCategories: categories,\r\n\t\tProducts: products,\r\n\t\tContent: content,\r\n\t\tPopularHeading,\r\n\t\tCategoryHeading,\r\n\t\tProductHeading,\r\n\t\tContentHeading,\r\n\t} = searchResults;\r\n\r\n\tconst { getItemProps, getMenuProps, highlightedIndex } = downshift;\r\n\tconst isRecordEmpty = hasAllEmpty(popular, categories, products, content);\r\n\tconst isAtleastOneExist = getAtleastOneExist(popular, categories, products, content);\r\n\tconst { t } = useTranslation();\r\n\r\n\tlet dynamicIndex = 0;\r\n\r\n\treturn (\r\n\t\t
      \r\n\t\t\t{isLoading &&
    • Loading...
    • }\r\n\t\t\t{products && products.length ? (\r\n\t\t\t\t<>\r\n\t\t\t\t\t{ProductHeading ?

      {ProductHeading}

      : ''}\r\n\t\t\t\t\t{products.map((item) => {\r\n\t\t\t\t\t\tdynamicIndex++;\r\n\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t {\r\n\t\t\t\t\t\t\t\t\t\tdispatchRocEvent('hawk-autocomplete-click', {\r\n\t\t\t\t\t\t\t\t\t\t\tkeyword: query,\r\n\t\t\t\t\t\t\t\t\t\t\tsuggestType: CommerceSuggestType.TopProductMatches,\r\n\t\t\t\t\t\t\t\t\t\t\titemName: item.ProductName,\r\n\t\t\t\t\t\t\t\t\t\t\turl: item.Url,\r\n\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\t/* #endregion */\r\n\t\t\t\t\t\t\t\t})}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t
      \r\n\t\t\t\t\t\t\t\t{item.ProductName}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t})}\r\n\t\t\t\t\r\n\t\t\t) : null}\r\n\t\t\t
      \r\n\t\t\t\t{categories && categories.length ? (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t

      {CategoryHeading}

      \r\n\t\t\t\t\t\t{categories.map((item) => {\r\n\t\t\t\t\t\t\tdynamicIndex++;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t
      \r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t\r\n\t\t\t\t) : null}\r\n\t\t\t\t{popular && popular.length ? (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t

      {PopularHeading}

      \r\n\t\t\t\t\t\t{popular.map((item) => {\r\n\t\t\t\t\t\t\tdynamicIndex++;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t
      \r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t\r\n\t\t\t\t) : null}\r\n\t\t\t\t{content && content.length ? (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t

      {ContentHeading}

      \r\n\t\t\t\t\t\t{content.map((item) => {\r\n\t\t\t\t\t\t\tdynamicIndex++;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t{item.Value}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t\r\n\t\t\t\t) : null}\r\n\t\t\t
      \r\n\t\t\t{isAtleastOneExist && (\r\n\t\t\t\t// eslint-disable-next-line jsx-a11y/click-events-have-key-events\r\n\t\t\t\t onViewMatches(downshift)}\r\n\t\t\t\t>\r\n\t\t\t\t\tView all matches\r\n\t\t\t\t\r\n\t\t\t)}\r\n\t\t\t{!isLoading && isRecordEmpty &&
    • {t('No results.')}
    • }\r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default SearchSuggestionsList;\r\n","import React, { useState, useEffect } from 'react';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\nimport axios, { CancelToken } from 'axios';\r\nimport HawkClient from 'net/HawkClient';\r\nimport { Response } from 'models/Autocomplete';\r\nimport { useHawkConfig } from 'components/ConfigProvider';\r\nimport SearchSuggestionsList from './SearchSuggestionsList';\r\nimport { Suggestion } from 'models/Autocomplete/Suggestion';\r\n\r\nexport interface SearchSuggestionsProps {\r\n\t/** The user entered search string in the autocomplete text input. */\r\n\tquery: string;\r\n\r\n\t/** Downshift's render prop parameter. */\r\n\tdownshift: ControllerStateAndHelpers;\r\n\r\n\tonViewMatches: (downshift: ControllerStateAndHelpers) => void;\r\n}\r\n\r\nfunction SearchSuggestions({ query, downshift, onViewMatches }: SearchSuggestionsProps) {\r\n\tconst { config } = useHawkConfig();\r\n\r\n\tconst client = new HawkClient(config);\r\n\r\n\tconst [results, setResults] = useState({} as Response);\r\n\tconst [isLoading, setIsLoading] = useState(false);\r\n\r\n\t// debounce the input search string so that we only do an autocomplete query every so often\r\n\tuseEffect(() => {\r\n\t\t// default to 200ms if not specified\r\n\t\tconst debounceMs = config.autocompleteDebounce || 200;\r\n\r\n\t\tconst cts = axios.CancelToken.source();\r\n\t\tconst timeout = setTimeout(() => doAutocomplete(query, cts.token), debounceMs);\r\n\r\n\t\treturn () => {\r\n\t\t\tcts.cancel();\r\n\t\t\tclearTimeout(timeout);\r\n\t\t};\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t}, [query, config.autocompleteDebounce]);\r\n\r\n\t/**\r\n\t * Performs an autocomplete request to the Hawk API and populates the result set of this component.\r\n\t * @param input The user entered search string that results will be autocompleted for.\r\n\t */\r\n\tasync function doAutocomplete(input: string, cancellationToken?: CancelToken) {\r\n\t\tsetIsLoading(true);\r\n\r\n\t\tlet response: Response | null = null;\r\n\r\n\t\ttry {\r\n\t\t\tresponse = await client\r\n\t\t\t\t.autocomplete(\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tClientGuid: config.clientGuid,\r\n\r\n\t\t\t\t\t\tKeyword: input,\r\n\t\t\t\t\t\tIndexName: config.indexName,\r\n\t\t\t\t\t\tDisplayFullResponse: true,\r\n\t\t\t\t\t},\r\n\t\t\t\t\tcancellationToken,\r\n\t\t\t\t)\r\n\t\t\t\t.then((o) => {\r\n\t\t\t\t\t// ensure, returned object will return response\r\n\t\t\t\t\t// since by default, axios uses JSON.parse to parse an object,\r\n\t\t\t\t\t// it doesn't recognize it as Response type - this line is to prevent it\r\n\t\t\t\t\treturn new Response(o);\r\n\t\t\t\t});\r\n\t\t} catch (error) {\r\n\t\t\tif (axios.isCancel(error)) {\r\n\t\t\t\t// if the request was cancelled, it's because this component was updated\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconsole.error('Autocomplete request error:', error);\r\n\t\t}\r\n\r\n\t\tsetIsLoading(false);\r\n\r\n\t\tif (response) {\r\n\t\t\tsetResults(response);\r\n\t\t}\r\n\t}\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t\r\n\t\t
    \r\n\t);\r\n}\r\n\r\nexport default SearchSuggestions;\r\n","import React from 'react';\r\nimport { DownshiftState, StateChangeOptions, ControllerStateAndHelpers } from 'downshift';\r\nimport SearchSuggestions from 'components/ui/SearchBox/SearchSuggestions';\r\nimport MagnifyingGlassSVG from 'shared/components/svg/MagnifyingGlassSVG'; // ERRONEOUS: Referencing stuff outside of Hawk from within Hawk. This should be inverted.\r\nimport { Suggestion } from 'models/Autocomplete/Suggestion';\r\nimport { getAutocompleteStrategies } from '../Facets/Overrides';\r\nimport { useHawkConfig } from 'components/ConfigProvider';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\nconst Downshift = React.lazy(() => import(/* webpackChunkName: \"downshift\" */ 'downshift'));\r\n\r\nexport interface SearchBoxBaseProps {\r\n\tinitialValue?: string;\r\n\tonSubmit: (keywords: string) => void;\r\n\tonViewMatches: (downshift: ControllerStateAndHelpers) => void;\r\n}\r\n\r\nfunction SearchBoxBase({ initialValue, onSubmit, onViewMatches }: SearchBoxBaseProps) {\r\n\tconst { config } = useHawkConfig();\r\n\tconst strategies = getAutocompleteStrategies(config.autocompleteStrategies || []);\r\n\tconst { t } = useTranslation();\r\n\r\n\t/** Called when the internal state of downshift changes - we're handling a couple custom behaviors here */\r\n\tfunction handleStateChange(\r\n\t\tstate: DownshiftState,\r\n\t\tchanges: StateChangeOptions,\r\n\t): Partial> {\r\n\t\tif (\r\n\t\t\t// NOTE: these strings are hardcoded to support code splitting downshift.\r\n\t\t\t// using the constants from the package will prevent code splitting from operating correctly\r\n\t\t\tchanges.type === '__autocomplete_mouseup__' ||\r\n\t\t\tchanges.type === '__autocomplete_keydown_enter__' ||\r\n\t\t\tchanges.type === '__autocomplete_click_item__'\r\n\t\t) {\r\n\t\t\t// when:\r\n\t\t\t//\r\n\t\t\t// 1. the mouse the clicked outside of downshift\r\n\t\t\t// 2. enter is pressed on the keyboard\r\n\t\t\t// 3. an item is selected from the dropdown\r\n\t\t\t//\r\n\t\t\t// then we want to retain the input value that was originally typed in. by default downshift\r\n\t\t\t// will clear the input value, so we're overriding this behavior here.\r\n\t\t\treturn { ...changes, inputValue: state.inputValue };\r\n\t\t}\r\n\r\n\t\treturn changes;\r\n\t}\r\n\r\n\t/** Called when an item has been selected from the autocomplete results. */\r\n\tfunction handleItemChange(item: Suggestion, downshift: ControllerStateAndHelpers) {\r\n\t\tif (!item) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst matchedStrategy = strategies.find((strategy) => strategy.type === item.SuggestionType);\r\n\t\tif (!matchedStrategy) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmatchedStrategy.strategy.handleItemChange(item, downshift);\r\n\t}\r\n\r\n\tfunction handleToString(item: Suggestion): string {\r\n\t\tif (!item) {\r\n\t\t\treturn '';\r\n\t\t}\r\n\t\tconst matchedStrategy = strategies.find((strategy) => strategy.type === item.SuggestionType);\r\n\t\tif (!matchedStrategy) {\r\n\t\t\treturn '';\r\n\t\t}\r\n\r\n\t\treturn matchedStrategy.strategy.toString(item);\r\n\t}\r\n\r\n\treturn (\r\n\t\t
    \r\n\t\t\t{t('Loading')}...
    }>\r\n\t\t\t\t handleToString(item)}\r\n\t\t\t\t\tonChange={handleItemChange}\r\n\t\t\t\t\tinitialInputValue={initialValue || ''}\r\n\t\t\t\t>\r\n\t\t\t\t\t{(options: ControllerStateAndHelpers) => {\r\n\t\t\t\t\t\tconst { isOpen, inputValue, getInputProps, openMenu } = options;\r\n\t\t\t\t\t\tconst showSuggestions = isOpen && inputValue && inputValue.length > 0;\r\n\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t
    \r\n\t\t\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t\t\t {\r\n\t\t\t\t\t\t\t\t\t\tif (onSubmit) {\r\n\t\t\t\t\t\t\t\t\t\t\tonSubmit(inputValue ?? '');\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\t\tdata-testid=\"global-search-button\"\r\n\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tSearch\r\n\t\t\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t\t\t{showSuggestions ? (\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t) : null}\r\n\t\t\t\t\t\t\t
    \r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}}\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default SearchBoxBase;\r\n","import React from 'react';\r\nimport { ControllerStateAndHelpers } from 'downshift';\r\nimport { useHawkConfig } from 'components/ConfigProvider';\r\nimport { Product } from 'models/Autocomplete';\r\nimport SearchBoxBase from 'components/ui/SearchBox/SearchBoxBase';\r\nimport * as Constants from 'util/Constants';\r\n\r\n/**\r\n * This component is a simple search input box (with autosuggest) that can be placed globally throughout the site.\r\n * This search box is intended to be used on non-search pages. On search pages, the `SearchBox` component should be\r\n * used instead.\r\n */\r\nfunction GlobalSearchBox() {\r\n\tconst { config } = useHawkConfig();\r\n\tconst searchUrl = config.searchPageUrl || Constants.defaultSearchPageUrl;\r\n\r\n\tfunction redirectToSearchPage(keywords: string | null) {\r\n\t\tlet redirect = `${searchUrl}?keyword=${encodeURIComponent(keywords ?? '')}`;\r\n\t\tif (config.indexName) {\r\n\t\t\tredirect += '&indexName=' + config.indexName;\r\n\t\t}\r\n\r\n\t\tlocation.assign(redirect);\r\n\t}\r\n\r\n\tfunction handleSubmit(keywords: string) {\r\n\t\tredirectToSearchPage(keywords);\r\n\t}\r\n\r\n\t// On select view all matches from suggestions list\r\n\tfunction handleViewAllMatches(downshift: ControllerStateAndHelpers) {\r\n\t\tconst { inputValue } = downshift;\r\n\t\tredirectToSearchPage(inputValue);\r\n\t}\r\n\r\n\treturn ;\r\n}\r\n\r\nexport default GlobalSearchBox;\r\n","import React from 'react';\r\nimport classnames from 'classnames';\r\nimport { Localizer } from 'services/Localizer';\r\nimport { AxiosError } from 'axios';\r\nimport XSVG from 'shared/components/svg/XSVG';\r\n\r\ntype Theme = 'danger' | 'warning' | 'info' | 'success';\r\n\r\nexport interface ErrorAlertProps {\r\n\t/**\r\n\t * The title of the error message such as \"Uh Oh!\" or \"An Unexpected Error has Occurred!\"\r\n\t */\r\n\ttitle: string;\r\n\r\n\t/**\r\n\t * The error message to display if an error object doesn't have a more appropriate message.\r\n\t */\r\n\tmessage: React.ReactNode | string;\r\n\r\n\tchildren?: any;\r\n\r\n\ttheme?: Theme;\r\n\r\n\tisTitleOnOwnRow?: boolean;\r\n\r\n\t/** The error responsible for this message. */\r\n\terror: AxiosError | Error | null;\r\n\r\n\t/**\r\n\t * Method from parent that handles collapse state.\r\n\t */\r\n\tonCollapse?: (collased: boolean) => void;\r\n\r\n\t/**\r\n\t * Controlled collapse state from parent.\r\n\t */\r\n\tisCollapsed?: boolean;\r\n}\r\n\r\n/**\r\n * Reusable Error Alert Component.\r\n */\r\nexport default function InlineAlert(props: ErrorAlertProps) {\r\n\tconst {\r\n\t\ttitle = InlineAlert.defaultProps.title,\r\n\t\tchildren,\r\n\t\ttheme = 'danger',\r\n\t\tisTitleOnOwnRow = false,\r\n\t\terror = InlineAlert.defaultProps.error,\r\n\t\tisCollapsed = false,\r\n\t\tonCollapse,\r\n\t} = props;\r\n\r\n\tlet { message = InlineAlert.defaultProps.message } = props;\r\n\r\n\tconst axiosError = error as AxiosError | null;\r\n\tif (axiosError?.isAxiosError && axiosError != null && axiosError.response == null && axiosError.request != null) {\r\n\t\tmessage = Localizer('ErrorMessageNetwork');\r\n\t}\r\n\r\n\tif (axiosError?.isAxiosError && (axiosError?.response?.status === 401 || axiosError?.response?.status === 403)) {\r\n\t\tmessage = Localizer('ErrorMessageForbidden');\r\n\t}\r\n\r\n\tif (axiosError?.response?.data?.message) {\r\n\t\tmessage = axiosError.response.data.message;\r\n\t}\r\n\r\n\tif (isCollapsed) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t{onCollapse ? (\r\n\t\t\t\t\r\n\t\t\t) : null}\r\n\r\n\t\t\t{title ? (\r\n\t\t\t\t\r\n\t\t\t\t\t{title}\r\n\t\t\t\t\r\n\t\t\t) : null}\r\n\r\n\t\t\t{message ? {message} : null}\r\n\r\n\t\t\t{children ? <> {children} : null}\r\n\t\t\r\n\t);\r\n}\r\n\r\n/**\r\n * Error Alert Default Props\r\n */\r\nInlineAlert.defaultProps = {\r\n\ttitle: Localizer('ErrorMessageGenericTitle'),\r\n\tmessage: Localizer('UnexpectedErrorOccurred'),\r\n\terror: null,\r\n};\r\n","import React from 'react';\r\nimport { SVGProps } from './SVGProps';\r\nimport classnames from 'classnames';\r\n\r\n/**\r\n * X SVG\r\n *\r\n * @returns\r\n */\r\nfunction XSVG({ className, ...rest }: SVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default XSVG;\r\n","import AxiosHelper from 'services/AxiosHelper';\r\nimport { AxiosResponse } from 'axios';\r\n\r\nexport interface UserSummary {\r\n\tisSignedIn: boolean;\r\n\tuserName: string | null;\r\n\tfirstName: string | null;\r\n\tlastName: string | null;\r\n\temail: string | null;\r\n\tphoneNumber: string | null;\r\n\ttwoFactorEnabled: boolean;\r\n\thasRecoveryCodes: boolean;\r\n\tisMachineRemembered: boolean;\r\n\tannouncements: UserAnnouncement[];\r\n\tisExternalLoginUser: boolean;\r\n\r\n\t// #region TapeCase\r\n\tisOptedInForMarketingEmails: boolean;\r\n\t// #endregion\r\n}\r\n\r\n/** Represents the details about an admin impersonation session of the logged in user. */\r\nexport interface Impersonation {\r\n\t/** The id of the admin impersonating the front end user. */\r\n\timpersonatorId: string;\r\n\r\n\t/** The name of the admin impersonating the front end user. */\r\n\timpersonatorName: string;\r\n\r\n\t/** The id of the active user impersonation session. */\r\n\tsessionId: string;\r\n}\r\n\r\nexport interface UserData {\r\n\t/**\r\n\t * Summary of user-specific details\r\n\t */\r\n\tsummary?: UserSummary;\r\n\r\n\t/**\r\n\t * CSRF validation token generated by the server\r\n\t */\r\n\trequestToken?: string;\r\n\r\n\t/**\r\n\t * The information on an impersonation session if one is active.\r\n\t * If an impersonation session isn't active this field will be undefined.\r\n\t */\r\n\timpersonation?: Impersonation;\r\n}\r\n\r\nexport interface UserAnnouncement {\r\n\t/** The id used as the primary key for the announcement in the database */\r\n\tid: string;\r\n\r\n\t/** An announcement to be displayed to the user */\r\n\tmessage: string;\r\n\r\n\t/** A list of pages where the announcement will be displayed. This will be an empty array if it is to be displayed on all pages. */\r\n\tpages: string[];\r\n}\r\n\r\nlet userDataPromise: Promise> | null = null;\r\n\r\n/**\r\n * Returns details related to the current user. By default, this is primarily their first/last name\r\n * and whether they are logged in or not. This can customized to include more details if necessary.\r\n */\r\nexport const getUserData = () => {\r\n\tif (userDataPromise === null) {\r\n\t\tuserDataPromise = AxiosHelper.get('/ajax/user');\r\n\t}\r\n\r\n\treturn userDataPromise;\r\n};\r\n\r\n/**\r\n * Returns non-cached details related to the current user. By default, this is primarily their first/last name\r\n * and whether they are logged in or not. This can customized to include more details if necessary.\r\n */\r\nexport const getUserDataNoCache = () => {\r\n\treturn AxiosHelper.get('/ajax/user');\r\n};\r\n\r\n/**\r\n * Returns a promise that will contain the CSRF token generated on the server to be used to validate\r\n * forms being posted via AJAX.\r\n */\r\nexport async function getCsrfToken() {\r\n\ttry {\r\n\t\tconst userData = await getUserData();\r\n\t\treturn userData.data.requestToken;\r\n\t} catch (error) {\r\n\t\tconsole.warn('Unable to load CSRF token.');\r\n\t\treturn '';\r\n\t}\r\n}\r\n\r\n// #region Commerce\r\nimport { CartSummary } from './UserData.Commerce';\r\nimport { LocationDto } from 'features/commerce/store-locator/types';\r\nimport { OrganizationInvite, OrganizationShipTo } from 'shared-client/types/commerce/organization';\r\nimport { AutoSuggestOption } from '../../../Roc.SharedClientApp/types/fields';\r\n\r\n// Commerce extensions to the UserData interface\r\nexport interface UserData {\r\n\tcartSummary?: CartSummary;\r\n\r\n\t/***\r\n\t * The customer's default store location or null if not set\r\n\t */\r\n\tdefaultStoreLocation?: LocationDto | null;\r\n\r\n\t/**\r\n\t * If store is enabled for this site\r\n\t */\r\n\tenableStoreLocation?: boolean;\r\n}\r\n\r\n/***\r\n * Organization data and permissions\r\n */\r\nexport interface Organization {\r\n\tid: string;\r\n\tpurchaseOrderNumberRequired: boolean;\r\n\tcreditCardAllowed: boolean;\r\n\tgiftCardAllowed: boolean;\r\n\torganizationName: string;\r\n\tcorpAccountAllowed: boolean;\r\n\t//#region TapeCase Customization\r\n\tisApprovedDistributor: boolean;\r\n\tpurchaseOrderAllowed: boolean;\r\n\t//#endregion\r\n}\r\n\r\n/***\r\n * Organization dto data\r\n */\r\nexport interface OrganizationDto extends AutoSuggestOption {}\r\n\r\n/***\r\n * User's organization and permissions data\r\n */\r\nexport interface UserSummary {\r\n\t/***\r\n\t * User's current default organization\r\n\t */\r\n\torganization: Organization | null;\r\n\r\n\t/***\r\n\t * The list of organizations the user is part of\r\n\t */\r\n\tuserOrganizations?: OrganizationDto[] | null;\r\n\r\n\t/***\r\n\t * The selected organization ship to\r\n\t */\r\n\tselectedShipTo: OrganizationShipTo | null;\r\n\r\n\t/***\r\n\t * Defines if the user has multiple shiptos to select from\r\n\t */\r\n\thasMultipleShipTos: boolean | null;\r\n\r\n\t/***\r\n\t * Defines if the user has saved payment methods\r\n\t */\r\n\thasSavedPaymentMethods: boolean | null;\r\n\r\n\t/***\r\n\t * The list of user permissions\r\n\t */\r\n\tpermissions?: UserPermissions;\r\n\r\n\t/***\r\n\t * The list of organizations the user is invited to join\r\n\t */\r\n\torganizationInvites?: OrganizationInvite[];\r\n\r\n\t/***\r\n\t * The user organization removal notification\r\n\t * Used to notify the user if he is no more part of his default organization\r\n\t */\r\n\tuserOrganizationRemovalNotification?: string;\r\n}\r\n\r\n/***\r\n * User's permissions\r\n */\r\nexport interface UserPermissions {\r\n\t/***\r\n\t * Defines if the current user can see organization users\r\n\t */\r\n\tcanSeeOrganizationUsers?: boolean;\r\n\r\n\t/***\r\n\t * Defines if the current user can assign roles to organization users\r\n\t */\r\n\tcanAssignRolesToOrganizationUsers?: boolean;\r\n\r\n\t/***\r\n\t * Defines if the current user can remove users from an organization\r\n\t */\r\n\tremoveUserFromOrganization?: boolean;\r\n\r\n\t/***\r\n\t * Defines if the current user can create organization users\r\n\t */\r\n\tcreateOrganizationUser?: boolean;\r\n\r\n\t/***\r\n\t * Defines if the current user can enable/disable ShipTos for organization users\r\n\t */\r\n\tmanageShipTosAssociation?: boolean;\r\n\r\n\t/***\r\n\t * Defines if the current user can see status of the organization users\r\n\t */\r\n\tcanSeePendingOrganizationUsers?: boolean;\r\n}\r\n// #endregion\r\n","var api = require(\"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n var content = require(\"!!../../../../../node_modules/mini-css-extract-plugin/dist/loader.js!../../../../../node_modules/css-loader/dist/cjs.js!../../../../../node_modules/postcss-loader/src/index.js!../../../../../node_modules/sass-loader/dist/cjs.js!./app.scss\");\n\n content = content.__esModule ? content.default : content;\n\n if (typeof content === 'string') {\n content = [[module.id, content, '']];\n }\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\n\nmodule.exports = content.locals || {};","var api = require(\"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n var content = require(\"!!../../../../../node_modules/css-loader/dist/cjs.js!./styles.css\");\n\n content = content.__esModule ? content.default : content;\n\n if (typeof content === 'string') {\n content = [[module.id, content, '']];\n }\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\n\nmodule.exports = content.locals || {};","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../../../../../node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.id, \":root {\\n --reach-tooltip: 1;\\n}\\n\\n[data-reach-tooltip] {\\n z-index: 1;\\n pointer-events: none;\\n position: absolute;\\n padding: 0.25em 0.5em;\\n box-shadow: 2px 2px 10px hsla(0, 0%, 0%, 0.1);\\n white-space: nowrap;\\n font-size: 85%;\\n background: #f0f0f0;\\n color: #444;\\n border: solid 1px #ccc;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n","import { ServerData } from 'services/ServerData';\r\n\r\nexport default {\r\n\tBaseUrl: ServerData.ACCOUNT_URL_BASE ?? '/my-account',\r\n\tLogin: ServerData.ACCOUNT_LOGIN_URL ?? '/my-account/login',\r\n\tLogin2fa: ServerData.ACCOUNT_LOGIN_WITH_2FA_URL ?? '/my-account/login-with-2fa',\r\n\tRegister: ServerData.ACCOUNT_REGISTER_URL ?? '/my-account/register',\r\n\tForgotPassword: ServerData.ACCOUNT_FORGOT_PASSWORD_URL ?? '/my-account/forgot-password',\r\n\tLoginWithRecoveryCode: ServerData.ACCOUNT_LOGIN_WITH_RECOVERY_CODE_URL ?? '/my-account/login-with-recovery-code',\r\n\tLogout: ServerData.ACCOUNT_LOGOUT_URL ?? '/my-account/logout',\r\n\t// #region Commerce\r\n\tOrganizationReview: ServerData.ACCOUNT_ORGANIZATION_REVIEW_URL ?? '/my-account/organization-review',\r\n\tOrganizationSelector: ServerData.ACCOUNT_ORGANIZATION_SELECTOR_URL ?? '/my-account/organization-selector',\r\n\t// #endregion\r\n};\r\n","import { useEffect } from 'react';\r\nimport 'shared/polyfills/customEvent';\r\nimport { RocEventType, ExtractEventParameters, RocEvent } from 'shared/events';\r\nimport addRocEventHandler from 'shared/util/events/rocEventUtils';\r\n\r\n/**\r\n * Helper function for dispatching ROC events.\r\n *\r\n * @param eventType The event type for the dispatcher\r\n */\r\nexport function dispatchRocEvent(eventType: T, data: ExtractEventParameters) {\r\n\tconst event = new CustomEvent(eventType, {\r\n\t\tdetail: data,\r\n\t});\r\n\tdocument.dispatchEvent(event);\r\n}\r\n\r\n/**\r\n * Reusable hook for handling ROC events\r\n *\r\n * @param eventType The type of event to handle\r\n * @param eventHandler The event handler\r\n * @param deps List of dependencies\r\n */\r\nexport default function useRocEventHandler(\r\n\teventType: T,\r\n\teventHandler: (data: ExtractEventParameters) => void,\r\n\tdeps?: any[],\r\n) {\r\n\tuseEffect(() => {\r\n\t\tconst removeHandlerCallback = addRocEventHandler(eventType, eventHandler);\r\n\r\n\t\treturn () => {\r\n\t\t\tremoveHandlerCallback();\r\n\t\t};\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t}, deps);\r\n}\r\n","import React from 'react';\r\nimport InlineAlert from 'shared/edit/InlineAlert';\r\n\r\n// eslint-disable-next-line\r\n// tslint:disable-next-line\r\nexport interface ErrorBoundaryRenderProps extends ErrorBoundaryState {}\r\n\r\nexport interface ErrorBoundaryProps {\r\n\tchildren: React.ReactNode;\r\n\trenderError?: (renderProps: ErrorBoundaryRenderProps) => React.ReactNode;\r\n}\r\n\r\nexport interface ErrorBoundaryState {\r\n\terror?: Error;\r\n}\r\n\r\n/**\r\n * Default Error Boundary component for frontend components, so that in case a JS error occurs, we show\r\n * something instead of nothing.\r\n */\r\nexport default class ErrorBoundary extends React.Component {\r\n\tpublic static defaultProps = {\r\n\t\trenderError: (renderProps: ErrorBoundaryRenderProps) => ,\r\n\t};\r\n\r\n\tpublic state: ErrorBoundaryState = {};\r\n\r\n\tpublic componentDidCatch(error: Error) {\r\n\t\tthis.setState({\r\n\t\t\terror,\r\n\t\t});\r\n\t}\r\n\r\n\tpublic render() {\r\n\t\tif (this.state.error) {\r\n\t\t\treturn this.props.renderError!(this.state);\r\n\t\t}\r\n\r\n\t\treturn this.props.children;\r\n\t}\r\n}\r\n","// source: https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNames\r\n/* eslint-disable no-var */\r\n(function () {\r\n\tif (Element.prototype.getAttributeNames == undefined) {\r\n\t\tElement.prototype.getAttributeNames = function () {\r\n\t\t\tvar attributes = this.attributes;\r\n\t\t\tvar length = attributes.length;\r\n\t\t\tvar result = new Array(length);\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\tresult[i] = attributes[i].name;\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t};\r\n\t}\r\n})();\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport ErrorBoundary from './ErrorBoundary';\r\nimport { toCamelCase } from 'util/StringUtil';\r\nimport 'shared/polyfills/getAttributeNames';\r\nimport Spinner from 'shared/components/Spinner';\r\n\r\ninterface AttributeProps {\r\n\t[index: string]: string;\r\n}\r\n\r\nfunction getDataPropsFromAttributes(element: Element): AttributeProps {\r\n\tconst props: AttributeProps = {};\r\n\r\n\tconst dataAttributePrefix = 'data-';\r\n\r\n\tconst attributeNames = element.getAttributeNames().filter((s) => s.startsWith(dataAttributePrefix));\r\n\tfor (const attributeName of attributeNames) {\r\n\t\tconst strippedName = toCamelCase(attributeName.substring(dataAttributePrefix.length));\r\n\t\tprops[strippedName] = element.getAttribute(attributeName) ?? '';\r\n\t}\r\n\r\n\treturn props;\r\n}\r\n\r\n/**\r\n * A helper function to facilitate initializing react applications on top of server-side rendered elements.\r\n * @param getReactElement Function that returns the react component to render.\r\n * @param elementId The ID of the DOM element being targeted.\r\n */\r\nexport const initReactApp = (getReactElement: (props: unknown) => React.ReactElement, elementId: string) => {\r\n\tif (typeof getReactElement !== 'function' || !elementId) {\r\n\t\treturn () => {\r\n\t\t\tconsole.warn('A react element generator function and element ID are required.');\r\n\t\t};\r\n\t}\r\n\r\n\tconst element = document.getElementById(elementId);\r\n\r\n\tif (!element) {\r\n\t\treturn () => {\r\n\t\t\tconsole.warn(\r\n\t\t\t\t`Element with ID '${elementId}' was not found. Did you forget to render it on the server or is this entry point not supposed to run?`,\r\n\t\t\t);\r\n\t\t};\r\n\t}\r\n\r\n\treturn () => {\r\n\t\tconst props = getDataPropsFromAttributes(element);\r\n\t\tconsole.debug(`Rendering application inside element with ID ${elementId}.`);\r\n\t\tReactDOM.render(\r\n\t\t\t}>\r\n\t\t\t\t{getReactElement(props)}\r\n\t\t\t,\r\n\t\t\telement,\r\n\t\t);\r\n\t};\r\n};\r\n\r\nexport const initReactAppByAttribute = (\r\n\tgetReactElement: (props: unknown, domElement: Element) => React.ReactElement,\r\n\tattribute: string,\r\n) => {\r\n\tif (typeof getReactElement !== 'function' || !attribute) {\r\n\t\treturn () => {\r\n\t\t\tconsole.warn('A react element generator function and element ID are required.');\r\n\t\t};\r\n\t}\r\n\r\n\tconst elements = document.querySelectorAll(`[${attribute}]`);\r\n\r\n\tif (!elements || elements.length == 0) {\r\n\t\treturn () => {\r\n\t\t\tconsole.warn(\r\n\t\t\t\t`No elements with data attribute '${attribute}' were found. Did you forget to render it on the server or is this entry point not supposed to run?`,\r\n\t\t\t);\r\n\t\t};\r\n\t}\r\n\r\n\treturn () => {\r\n\t\tfor (let i = 0; i < elements.length; ++i) {\r\n\t\t\tconst element = elements[i];\r\n\t\t\tconst props = getDataPropsFromAttributes(element);\r\n\t\t\tconsole.debug(`Rendering application inside element with attribute ${attribute}.`);\r\n\t\t\tReactDOM.render(\r\n\t\t\t\t}>\r\n\t\t\t\t\t{getReactElement(props, element)}\r\n\t\t\t\t,\r\n\t\t\t\telement,\r\n\t\t\t);\r\n\t\t}\r\n\t};\r\n};\r\n","import { useState, useEffect } from 'react';\r\n\r\n/**\r\n * Reusable hook that returns true after a certain amount of time has passed. Useful to delay\r\n * displaying components in render functions.\r\n *\r\n * @export\r\n * @param {number} [waitMs=200]\r\n * @returns\r\n */\r\nexport default function useDelayedDisplay(waitMs: number = 200) {\r\n\tconst [display, setDisplay] = useState(false);\r\n\r\n\tuseEffect(() => {\r\n\t\t// after a set amount of time, show the spinner\r\n\t\tconst timeout = setTimeout(() => {\r\n\t\t\tsetDisplay(true);\r\n\t\t}, waitMs);\r\n\r\n\t\treturn () => {\r\n\t\t\tclearTimeout(timeout);\r\n\t\t};\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t}, []);\r\n\r\n\treturn display;\r\n}\r\n","import { AxiosError } from 'axios';\r\nimport RocHawkConfig from 'features/search/RocHawkConfig';\r\nimport AxiosHelper from 'services/AxiosHelper';\r\nimport { getCookie, setCookie } from 'shared/components/hawksearch/helpers/Cookies';\r\nimport { ExtractEventParameters } from 'shared/events';\r\n//#region Commerce\r\nimport { CommercePageType, CommerceSuggestType, trackCommerce } from '../commerce/hawksearch/tracking-commerce';\r\n//#endregion\r\n\r\nexport interface HawkSearch {\r\n\tClientGuid: string;\r\n\tContext: ContextDictionary;\r\n\tCustomContext: ContextDictionary;\r\n\tTrackingUrl: string | null;\r\n\tinitCustomEvents?: () => void;\r\n}\r\n\r\ndeclare global {\r\n\tinterface Window {\r\n\t\tHawkSearch: HawkSearch;\r\n\t}\r\n}\r\n\r\nexport enum EventTrackingType {\r\n\tpageLoad = 1,\r\n\tsearch = 2,\r\n\tclick = 3,\r\n\tbannerClick = 7,\r\n\tbannerImpression = 8,\r\n\trecommendationClick = 10,\r\n\tautoCompleteClick = 11,\r\n}\r\n\r\n/**\r\n * The page type\r\n */\r\nexport enum PageType {\r\n\t/**\r\n\t * Landing Page\r\n\t */\r\n\tlanding = 2,\r\n\t/**\r\n\t * All other Page Types\r\n\t */\r\n\tcustom = 5,\r\n}\r\n\r\nexport enum SuggestType {\r\n\tPopularSearches = 1,\r\n\tTopContentMatches = 4,\r\n}\r\n\r\nexport enum SearchType {\r\n\tInitial = 1,\r\n\tRefinement = 2,\r\n}\r\n\r\ntype HawkEvents =\r\n\t| ({ name: 'pageload' } & TrackPageLoadArgs)\r\n\t| ({ name: 'searchtracking' } & TrackSearchTrackingArgs)\r\n\t| ({ name: 'click' } & TrackClickArgs)\r\n\t| ({ name: 'bannerclick' } & TrackBannerClickArgs)\r\n\t| ({ name: 'bannerimpression' } & TrackBannerImpressionArgs)\r\n\t| ({ name: 'autocompleteclick' } & TrackAutoCompleteClickArgs)\r\n\t| ({ name: 'recommendationclick' } & TrackRecommendationClickArgs);\r\n\r\nexport type HawkEventType = HawkEvents['name'];\r\n\r\nfunction track(eventName: T, args: ExtractEventParameters) {\r\n\tswitch (eventName.toLocaleLowerCase()) {\r\n\t\tcase 'pageload':\r\n\t\t\t//HawkSearch.Context.add(\"uniqueid\", \"123456789\");\r\n\t\t\t//HawkSearch.Tracking.track('pageload',{pageType: \"item\"});\r\n\t\t\treturn trackPageLoad((args as unknown) as TrackPageLoadArgs);\r\n\t\tcase 'searchtracking':\r\n\t\t\t//HawkSearch.Tracking.track(\"searchtracking\", {trackingId:\"a9bd6e50-e434-45b9-9f66-489eca07ad0a\", typeId: HawkSearch.Tracking.SearchType.Initial});\r\n\t\t\t//HawkSearch.Tracking.track(\"searchtracking\", {trackingId:\"a9bd6e50-e434-45b9-9f66-489eca07ad0a\", typeId: HawkSearch.Tracking.SearchType.Refinement});\r\n\t\t\treturn trackSearchTracking((args as unknown) as TrackSearchTrackingArgs);\r\n\t\tcase 'click':\r\n\t\t\t//HawkSearch.Tracking.track('click',{event: e, uniqueId: \"33333\", trackingId: \"75a0801a-a93c-4bcb-81f1-f4b011f616e3\"});\r\n\t\t\treturn trackClick((args as unknown) as TrackClickArgs);\r\n\t\tcase 'bannerclick':\r\n\t\t\t//HawkSearch.Tracking.track('bannerclick',{bannerId: 1, campaignId: 2, trackingId:\"2d652a1e-2e05-4414-9d76-51979109f724\"});\r\n\t\t\treturn trackBannerClick((args as unknown) as TrackBannerClickArgs);\r\n\t\tcase 'bannerimpression':\r\n\t\t\t//HawkSearch.Tracking.track('bannerimpression',{bannerId: \"2\", campaignId: \"2\", trackingId:\"2d652a1e-2e05-4414-9d76-51979109f724\"});\r\n\t\t\treturn trackBannerImpression((args as unknown) as TrackBannerImpressionArgs);\r\n\t\tcase 'autocompleteclick':\r\n\t\t\t//HawkSearch.Tracking.track('autocompleteclick',{keyword: \"test\", suggestType: HawkSearch.Tracking.SuggestType.PopularSearches, name:\"tester\", url:\"/test\"});\r\n\t\t\treturn trackAutoCompleteClick((args as unknown) as TrackAutoCompleteClickArgs);\r\n\t\tcase 'recommendationclick':\r\n\t\t\t//HawkSearch.Tracking.track('recommendationclick',{uniqueId: \"223222\", itemIndex: \"222\", widgetGuid:\"2d652a1e-2e05-4414-9d76-51979109f724\", requestId:\"2d652a1e-2e05-4414-9d76-51979109f724\"});\r\n\t\t\treturn trackRecommendationClick((args as unknown) as TrackRecommendationClickArgs);\r\n\t}\r\n}\r\n\r\nfunction getVisitorExpiry() {\r\n\tconst d = new Date();\r\n\t// 1 year\r\n\td.setTime(d.getTime() + 360 * 24 * 60 * 60 * 1000);\r\n\treturn d.toUTCString();\r\n}\r\n\r\nfunction getVisitExpiry() {\r\n\tconst d = new Date();\r\n\t// 4 hours\r\n\td.setTime(d.getTime() + 4 * 60 * 60 * 1000);\r\n\treturn d.toUTCString();\r\n}\r\n\r\nfunction createGuid() {\r\n\tconst s: string[] = [];\r\n\tconst hexDigits = '0123456789abcdef';\r\n\tfor (let i = 0; i < 36; i++) {\r\n\t\ts[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);\r\n\t}\r\n\ts[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010\r\n\ts[19] = hexDigits.substr(((s[19] as any) & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01\r\n\ts[8] = s[13] = s[18] = s[23] = '-';\r\n\r\n\treturn s.join('');\r\n}\r\n\r\ntype TrackPageLoadArgs = {\r\n\t/**\r\n\t * The page type\r\n\t */\r\n\tpageType:\r\n\t\t| PageType\r\n\t\t// #region Commerce\r\n\t\t| CommercePageType;\r\n\t// #endregion\r\n\r\n\t/**\r\n\t * Unique identifier of item that was clicked\r\n\t */\r\n\tuniqueId?: string;\r\n};\r\n\r\nfunction trackPageLoad({ pageType, uniqueId }: TrackPageLoadArgs) {\r\n\tconst { clientHeight, clientWidth } = document.documentElement;\r\n\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.pageLoad,\r\n\t\tEventData: preparePayload({\r\n\t\t\tPageTypeId: pageType,\r\n\t\t\tRequestPath: window.location.pathname,\r\n\t\t\tQs: window.location.search,\r\n\t\t\tViewportHeight: clientHeight,\r\n\t\t\tViewportWidth: clientWidth,\r\n\t\t\tUniqueId: uniqueId,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackSearchTrackingArgs = {\r\n\t/**\r\n\t * The ‘TrackingId’ object that is passed in this function is returned in the Hawksearch response\r\n\t */\r\n\ttrackingId: string;\r\n\t/**\r\n\t * The type of search that is performed\r\n\t */\r\n\ttypeId: SearchType;\r\n};\r\n\r\nfunction trackSearchTracking({ trackingId, typeId }: TrackSearchTrackingArgs) {\r\n\tif (typeId == SearchType.Initial) {\r\n\t\tsetCookie('hawk_query_id', createGuid());\r\n\t}\r\n\r\n\tconst queryId = getCookie('hawk_query_id');\r\n\tconst { clientHeight, clientWidth } = document.documentElement;\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.search,\r\n\t\tEventData: preparePayload({\r\n\t\t\tQueryId: queryId,\r\n\t\t\tTrackingId: trackingId,\r\n\t\t\tTypeId: typeId,\r\n\t\t\tViewportHeight: clientHeight,\r\n\t\t\tViewportWidth: clientWidth,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackClickArgs = {\r\n\t/**\r\n\t * Unique identifier of item that was clicked\r\n\t */\r\n\tuniqueId: string;\r\n\t/**\r\n\t * This is the TrackingId that was passed back in the search response\r\n\t */\r\n\ttrackingId: string;\r\n\t/**\r\n\t * Target URL that clicked element points to\r\n\t */\r\n\turl: string;\r\n};\r\n\r\nfunction trackClick({ uniqueId, trackingId, url }: TrackClickArgs) {\r\n\tconst { clientHeight, clientWidth } = document.documentElement;\r\n\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.click,\r\n\t\tEventData: preparePayload({\r\n\t\t\tUrl: url,\r\n\t\t\tQs: window.location.search,\r\n\t\t\tRequestPath: window.location.pathname,\r\n\t\t\tTrackingId: trackingId,\r\n\t\t\tUniqueId: uniqueId,\r\n\t\t\tViewportHeight: clientHeight,\r\n\t\t\tViewportWidth: clientWidth,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackBannerClickArgs = {\r\n\t/**\r\n\t * The identifier of corresponding banner\r\n\t */\r\n\tbannerId: string;\r\n\t/**\r\n\t * The identifier of corresponding campaign (optional)\r\n\t */\r\n\tcampaignId: string;\r\n\t/**\r\n\t * The ‘TrackingId’ object that is passed in this function is returned in the Hawksearch response\r\n\t */\r\n\ttrackingId: string;\r\n};\r\n\r\nfunction trackBannerClick({ bannerId, trackingId, campaignId }: TrackBannerClickArgs) {\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.bannerClick,\r\n\t\tEventData: preparePayload({\r\n\t\t\tCampaignId: campaignId,\r\n\t\t\tBannerId: bannerId,\r\n\t\t\tTrackingId: trackingId,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackBannerImpressionArgs = TrackBannerClickArgs;\r\n\r\nfunction trackBannerImpression({ bannerId, campaignId, trackingId }: TrackBannerImpressionArgs) {\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.bannerImpression,\r\n\t\tEventData: preparePayload({\r\n\t\t\tCampaignId: campaignId,\r\n\t\t\tBannerId: bannerId,\r\n\t\t\tTrackingId: trackingId,\r\n\t\t}),\r\n\t};\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackAutoCompleteClickArgs = {\r\n\t/**\r\n\t * Selected keyword used as a autocomplete query\r\n\t */\r\n\tkeyword: string;\r\n\t/**\r\n\t * The type of autocomplete results type\r\n\t */\r\n\tsuggestType?: SuggestType | CommerceSuggestType;\r\n\t/**\r\n\t * Text value associated with the autocomplete item clicked\r\n\t */\r\n\titemName: string;\r\n\t/**\r\n\t * The target URL of clicked autocomplete item\r\n\t */\r\n\turl: string;\r\n};\r\n\r\nfunction trackAutoCompleteClick({ keyword, suggestType, itemName, url }: TrackAutoCompleteClickArgs) {\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.autoCompleteClick,\r\n\t\tEventData: preparePayload({\r\n\t\t\tKeyword: keyword,\r\n\t\t\tName: itemName,\r\n\t\t\tSuggestType: suggestType,\r\n\t\t\tUrl: url,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\ntype TrackRecommendationClickArgs = {\r\n\t/**\r\n\t * The unique identifier of the recommendation widget that displayed clicked item. This should correspond to the widget GUID generated for each widget individually in Hawksearch dashboard\r\n\t */\r\n\twidgetGuid: string;\r\n\t/**\r\n\t * Represents the unique identifier of a product. This should correspond to the value of the field set up as the primary key in the fields section of Hawksearch dashboard.\r\n\t */\r\n\tuniqueId: string;\r\n\t/**\r\n\t * The number of the clicked recommendation item on the displayed widget.\r\n\t */\r\n\titemIndex: number;\r\n\t/**\r\n\t * The ‘RequestId’ object that is passed in this function is returned in the recommendation widget response\r\n\t */\r\n\trequestId: string;\r\n};\r\n\r\nfunction trackRecommendationClick({ widgetGuid, uniqueId, itemIndex, requestId }: TrackRecommendationClickArgs) {\r\n\tconst payload = {\r\n\t\tEventType: EventTrackingType.recommendationClick,\r\n\t\tEventData: preparePayload({\r\n\t\t\tItemIndex: itemIndex,\r\n\t\t\tRequestId: requestId,\r\n\t\t\tUniqueId: uniqueId,\r\n\t\t\tWidgetGuid: widgetGuid,\r\n\t\t}),\r\n\t};\r\n\r\n\tmakeRequest(payload);\r\n}\r\n\r\nexport function preparePayload(payload: any) {\r\n\treturn btoa(JSON.stringify(payload));\r\n}\r\n\r\nexport function makeRequest(data) {\r\n\tif (!HawkSearch.TrackingUrl) {\r\n\t\tconsole.warn(\r\n\t\t\t\"Unable to send tracking event to HawkSearch because site's configuration is missing tracking URL.\",\r\n\t\t);\r\n\t\treturn;\r\n\t}\r\n\r\n\tlet visitId = getCookie('hawk_visit_id');\r\n\tlet visitorId = getCookie('hawk_visitor_id');\r\n\tconst isNewVisitor = !visitId || !visitorId;\r\n\r\n\tif (!visitId) {\r\n\t\tsetCookie('hawk_visit_id', createGuid(), getVisitExpiry());\r\n\t\tvisitId = getCookie('hawk_visit_id');\r\n\t}\r\n\r\n\tif (!visitorId) {\r\n\t\tsetCookie('hawk_visitor_id', createGuid(), getVisitorExpiry());\r\n\t\tvisitorId = getCookie('hawk_visitor_id');\r\n\t}\r\n\r\n\tif (isNewVisitor) {\r\n\t\tAxiosHelper.post('/ajax/hawksearch/identify', {\r\n\t\t\tvisitId: visitId,\r\n\t\t\tvisitorId: visitorId,\r\n\t\t});\r\n\t}\r\n\r\n\tconst payload = Object.assign(\r\n\t\t{\r\n\t\t\tClientGuid: HawkSearch.ClientGuid,\r\n\t\t\tVisitId: visitId,\r\n\t\t\tVisitorId: visitorId,\r\n\t\t\tTrackingProperties: HawkSearch.Context,\r\n\t\t\tCustomDictionary: HawkSearch.CustomContext,\r\n\t\t},\r\n\t\tdata,\r\n\t);\r\n\r\n\tAxiosHelper.post(HawkSearch.TrackingUrl + '/api/trackevent', payload)\r\n\t\t.then((response) => {\r\n\t\t\tconsole.log('Success:', response.statusText);\r\n\t\t})\r\n\t\t.catch((error: AxiosError) => {\r\n\t\t\tconsole.error('Error:', error);\r\n\t\t});\r\n}\r\n\r\n// TODO: add comments about what this is for? i think it has to do with timing between hawksearch.js and this script?\r\nfunction init() {\r\n\tif (window.HawkSearch && typeof window.HawkSearch.initCustomEvents === 'function') {\r\n\t\twindow.HawkSearch.initCustomEvents();\r\n\t}\r\n}\r\n\r\nif (document.readyState === 'complete' || document.readyState === 'interactive') {\r\n\tsetTimeout(init);\r\n} else {\r\n\tdocument.addEventListener('DOMContentLoaded', init);\r\n}\r\n\r\nclass ContextDictionary {\r\n\tadd(key: string, value: any) {\r\n\t\tthis[key] = value;\r\n\t}\r\n\r\n\tclear() {\r\n\t\tfor (const key in this) {\r\n\t\t\tthis.remove(key);\r\n\t\t}\r\n\t}\r\n\r\n\tremove(key: string) {\r\n\t\tif (this.hasOwnProperty(key)) {\r\n\t\t\tdelete this[key];\r\n\t\t}\r\n\t}\r\n\r\n\tpush(key: string, value: any) {\r\n\t\tif (this.hasOwnProperty(key)) {\r\n\t\t\tconst existingValue = this[key];\r\n\t\t\tthis[key] = `${existingValue},${value}`;\r\n\t\t} else {\r\n\t\t\tthis.add(key, value);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst Context = new ContextDictionary();\r\nconst CustomContext = new ContextDictionary();\r\n\r\n// initialize HawkSearch with values from RocHawkConfig\r\nif (!window.HawkSearch) {\r\n\twindow.HawkSearch = {\r\n\t\tClientGuid: RocHawkConfig.clientGuid,\r\n\t\tTrackingUrl: RocHawkConfig.trackingUrl,\r\n\t\tContext: Context,\r\n\t\tCustomContext: CustomContext,\r\n\t};\r\n}\r\n\r\nconst HawkSearch = window.HawkSearch;\r\n\r\nexport default {\r\n\tTracking: {\r\n\t\ttrack,\r\n\t\t// #region Commerce\r\n\t\ttrackCommerce,\r\n\t\t// #endregion\r\n\t},\r\n\tContext,\r\n\tCustomContext,\r\n};\r\n","import React from 'react';\r\n\r\nimport 'shared/components/hawksearch/styles/app.scss';\r\n\r\nimport ConfigProvider from 'shared/components/hawksearch/components/ConfigProvider';\r\nimport GlobalSearchBox from 'shared/components/hawksearch/components/ui/SearchBox/GlobalSearchBox';\r\nimport hawkConfig from './RocHawkConfig';\r\nimport { initReactApp } from 'shared/util/ApplicationInit';\r\n\r\nconst render = initReactApp(\r\n\t() => (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t),\r\n\t'searchbox',\r\n);\r\n\r\nrender();\r\n","import { RocEventType, RocEvent, ExtractEventParameters } from 'shared/events';\r\n\r\n/**\r\n * Helper function for handling ROC events from non React functions.\r\n * @param eventType The type of event to handle\r\n * @param eventHandler The event handler\r\n * @returns The callback function to remove this handler\r\n */\r\nexport default function addRocEventHandler(\r\n\teventType: T,\r\n\teventHandler: (data: ExtractEventParameters) => void,\r\n): () => void {\r\n\tconst handler = (evt: CustomEvent): void => {\r\n\t\teventHandler(evt.detail);\r\n\t};\r\n\r\n\tdocument.addEventListener(eventType, handler);\r\n\r\n\treturn () => document.removeEventListener(eventType, handler);\r\n}\r\n","import * as React from 'react';\r\n\r\ninterface DashCircleSVGProps {\r\n\tclass?: string;\r\n}\r\n\r\n/**\r\n * Dash circle SVG\r\n *\r\n * @returns\r\n */\r\nfunction DashCircleSVG(props: DashCircleSVGProps) {\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t);\r\n}\r\n\r\nexport default DashCircleSVG;\r\n","/**\r\n * Returns visitor expiry date for hawksearch visitor id stored in the cookie for the user.\r\n */\r\nexport function getVisitorExpiry() {\r\n\tconst d = new Date();\r\n\t// 1 year\r\n\td.setTime(d.getTime() + 360 * 24 * 60 * 60 * 1000);\r\n\treturn d.toUTCString();\r\n}\r\n\r\n/**\r\n * Returns visitor expiry date for hawksearch visit id stored in the cookie for the user.\r\n */\r\nexport function getVisitExpiry() {\r\n\tconst d = new Date();\r\n\t// 4 hours\r\n\td.setTime(d.getTime() + 4 * 60 * 60 * 1000);\r\n\treturn d.toUTCString();\r\n}\r\n\r\n/**\r\n * Creates GUID.\r\n */\r\nexport function createGuid() {\r\n\tconst s: string[] = [];\r\n\tconst hexDigits = '0123456789abcdef';\r\n\tfor (let i = 0; i < 36; i++) {\r\n\t\ts[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);\r\n\t}\r\n\ts[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010\r\n\ts[19] = hexDigits.substr(((s[19] as any) & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01\r\n\ts[8] = s[13] = s[18] = s[23] = '-';\r\n\r\n\treturn s.join('');\r\n}\r\n\r\n/**\r\n * Returns the cookie.\r\n */\r\nexport function getCookie(name) {\r\n\tconst nameEQ = name + '=';\r\n\tconst ca = document.cookie.split(';');\r\n\r\n\tfor (let i = 0; i < ca.length; i++) {\r\n\t\tlet cookie = ca[i];\r\n\r\n\t\twhile (cookie.charAt(0) == ' ') {\r\n\t\t\tcookie = cookie.substring(1, cookie.length);\r\n\t\t}\r\n\r\n\t\tif (cookie.indexOf(nameEQ) == 0) {\r\n\t\t\treturn cookie.substring(nameEQ.length, cookie.length);\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n}\r\n\r\n/**\r\n * Sets the cookie.\r\n */\r\nexport function setCookie(name: string, value: string, expiry?: string) {\r\n\tlet expires = '';\r\n\r\n\tif (expiry) {\r\n\t\texpires = '; expires=' + expiry;\r\n\t}\r\n\r\n\tdocument.cookie = name + '=' + value + expires + '; path=/';\r\n}\r\n","import React, { useContext } from 'react';\r\n\r\nimport { SearchStore } from 'store/Store';\r\nimport { useHawkState, SearchActor } from 'store/HawkState';\r\nimport { Request } from 'models/Search';\r\n\r\nconst HawkContext = React.createContext({} as HawkContextValue);\r\n\r\nexport interface HawkContextValue {\r\n\t/** The store of data used throughout the application. */\r\n\tstore: SearchStore;\r\n\r\n\t/**\r\n\t * An interface that allows actions to be performed on the store (such as executing searches,\r\n\t * changing pages, etc).\r\n\t */\r\n\tactor: SearchActor;\r\n}\r\n\r\nexport interface HawkStoreProviderProps {\r\n\t/** The initial search to perform when initializing the search components. */\r\n\tinitialSearch?: Partial;\r\n\tchildren: React.ReactNode;\r\n}\r\n\r\n/**\r\n * This component acts as the global store for the hawksearch application state. Only one instance of this component\r\n * should exist, and it should be the root level component.\r\n */\r\nfunction StoreProvider({ initialSearch, children }: HawkStoreProviderProps) {\r\n\tconst [store, actor] = useHawkState(initialSearch);\r\n\r\n\treturn {children};\r\n}\r\n\r\n/**\r\n * Retrieves the global hawk store for use within a component.\r\n */\r\nexport function useHawkSearch() {\r\n\treturn useContext(HawkContext);\r\n}\r\n\r\nexport default StoreProvider;\r\n","import { ExternalLoginProvider } from 'features/login/ExternalLogins';\r\n\r\n/**\r\n * Extends Window with a property that will hold the client data\r\n *\r\n * @interface WindowWithClientData\r\n * @extends {Window}\r\n */\r\ninterface WindowWithServerData extends Window {\r\n\t__ROC_SERVER_DATA__?: Array<{\r\n\t\t[name: string]: string;\r\n\t}>;\r\n}\r\n\r\n/**\r\n * This type will hold all the keys that are used by ServerData\r\n */\r\ninterface ServerData {\r\n\tIsReCaptchaEnabled?: boolean;\r\n\tReCaptchaV3Key?: string;\r\n\tTimeZone?: string;\r\n\tUSE_EMAIL_AS_USERNAME?: boolean;\r\n\tRegistrationThankYouTitle?: string;\r\n\tRegistrationThankYouMessage?: string;\r\n\tForgotPasswordConfirmationTitle?: string;\r\n\tForgotPasswordConfirmationMessage?: string;\r\n\tPageTitleSuffix?: string;\r\n\tRequireConfirmEmail?: boolean;\r\n\tACCOUNT_URL_BASE?: string;\r\n\tACCOUNT_LOGIN_URL?: string;\r\n\tACCOUNT_LOGOUT_URL?: string;\r\n\tACCOUNT_REGISTER_URL?: string;\r\n\tACCOUNT_LOGIN_WITH_2FA_URL?: string;\r\n\tACCOUNT_FORGOT_PASSWORD_URL?: string;\r\n\tACCOUNT_LOGIN_WITH_RECOVERY_CODE_URL?: string;\r\n\tEXTERNAL_LOGIN_PROVIDERS?: ExternalLoginProvider[];\r\n\t// #region Commerce\r\n\tACCOUNT_ORGANIZATION_REVIEW_URL?: string;\r\n\tACCOUNT_ORGANIZATION_SELECTOR_URL?: string;\r\n\tGoogleMapsApiKey?: string; // used in Store Locator\r\n\tMinimumTimeBeforeRecentlyViewedProductsAreValidated?: number;\r\n\tQuickOrderItemMinumumSearchCharacters?: number;\r\n\tMaxAllowedQuickOrderItems?: number;\r\n\tMaxNumberForQuantityDropdown?: number;\r\n\tOrderDetailsUIComponent?: string;\r\n\tGuestCheckoutEnabled?: boolean;\r\n\t// #endregion\r\n\t// #region TapeCase Customizations\r\n\tListPriceMessagingForNotApprovedDistributors?: string;\r\n\tMaxNumberOfDaysToCancelOrders?: number;\r\n\tMaxNumberOfDaysToCancelOrdersMessage?: string;\r\n\t// #endregion\r\n}\r\n\r\n/**\r\n * Main object that will hold all the client data\r\n */\r\nexport const ServerData: ServerData = {};\r\n\r\n/**\r\n * Initializer function that will populate the main settings object\r\n */\r\nfunction initializeServerData() {\r\n\tconst windowWithServerData = window as WindowWithServerData;\r\n\r\n\tif (\r\n\t\twindowWithServerData &&\r\n\t\twindowWithServerData.__ROC_SERVER_DATA__ &&\r\n\t\tArray.isArray(windowWithServerData.__ROC_SERVER_DATA__)\r\n\t) {\r\n\t\tfor (const obj of windowWithServerData.__ROC_SERVER_DATA__) {\r\n\t\t\tfor (const key of Object.keys(obj)) {\r\n\t\t\t\tServerData[key] = obj[key];\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\ninitializeServerData();\r\n","// These functions may be potentially innaccurate in certain locales that use differing amounts of characters in different cases\r\n\r\n/**\r\n * Tests if a string includes another if casing is ignored\r\n * @param thisString The string to test\r\n * @param otherString The potentially included string being tested for\r\n */\r\nexport function stringWeaklyIncludes(thisString: string, otherString: string) {\r\n\treturn thisString.toLocaleLowerCase().includes(otherString.toLocaleLowerCase());\r\n}\r\n\r\n/**\r\n * Tests if a string starts with another if casing is ignored\r\n * @param thisString The string to test\r\n * @param otherString The potentially included string being tested for\r\n */\r\nexport function stringWeaklyStartsWith(thisString: string, otherString: string) {\r\n\treturn thisString.toLocaleLowerCase().startsWith(otherString.toLocaleLowerCase());\r\n}\r\n\r\n/**\r\n * Tests if a string ends with another if casing is ignored\r\n * @param thisString The string to test\r\n * @param otherString The potentially included string being tested for\r\n */\r\nexport function stringWeaklyEndsWith(thisString: string, otherString: string) {\r\n\treturn thisString.toLocaleLowerCase().endsWith(otherString.toLocaleLowerCase());\r\n}\r\n\r\n/**\r\n * Converts the first character in a string to upper-case. Will not work for all languages (for example Dutch).\r\n *\r\n * @export\r\n * @param {string} thisString\r\n * @returns\r\n */\r\nexport function firstCharacterToUpper(thisString: string) {\r\n\tif (!thisString) {\r\n\t\treturn '';\r\n\t}\r\n\r\n\tlet newString = thisString.substring(0, 1).toLocaleUpperCase();\r\n\r\n\tif (thisString.length > 1) {\r\n\t\tnewString += thisString.substring(1);\r\n\t}\r\n\r\n\treturn newString;\r\n}\r\n\r\n/**\r\n * Converts the first character in a string to upper-case. Will not work for all languages (for example Dutch).\r\n *\r\n * @export\r\n * @param {string} thisString\r\n * @returns\r\n */\r\nexport function firstCharacterToLower(thisString: string) {\r\n\tif (!thisString) {\r\n\t\treturn '';\r\n\t}\r\n\r\n\tlet newString = thisString.substring(0, 1).toLocaleLowerCase();\r\n\r\n\tif (thisString.length > 1) {\r\n\t\tnewString += thisString.substring(1);\r\n\t}\r\n\r\n\treturn newString;\r\n}\r\n\r\n// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart\r\nexport function padStart(value, targetLength, padString) {\r\n\t// tslint:disable-next-line:no-bitwise\r\n\ttargetLength = targetLength >> 0; // truncate if number, or convert non-number to 0;\r\n\tpadString = String(typeof padString !== 'undefined' ? padString : ' ');\r\n\tif (value.length >= targetLength) {\r\n\t\treturn String(value);\r\n\t} else {\r\n\t\ttargetLength = targetLength - value.length;\r\n\t\tif (targetLength > padString.length) {\r\n\t\t\tpadString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed\r\n\t\t}\r\n\t\treturn padString.slice(0, targetLength) + String(value);\r\n\t}\r\n}\r\n\r\n/**\r\n * Converts a string from \" Something Like This\" to \"something-like-this\"\r\n * @param value The string to convert\r\n */\r\nexport function toKebabCase(value: string) {\r\n\tif (!value || !value.trim()) {\r\n\t\treturn '';\r\n\t}\r\n\r\n\treturn value\r\n\t\t.trim()\r\n\t\t.replace(/[^a-zA-Z0-9]+/g, '-')\r\n\t\t.replace(/([a-z0-9])([A-Z])/g, '$1-$2')\r\n\t\t.replace(/([A-Z])([A-Z])(?=[a-z])/g, '$1-$2')\r\n\t\t.replace(/-$/, '')\r\n\t\t.toLocaleLowerCase();\r\n}\r\n\r\n/**\r\n * Converts a string from PascalCase, camelCase, snake_case, or space separated to camelCase. Beginning and trailing whitespace are trimmed.\r\n * @param value The string to convert\r\n */\r\nexport function toCamelCase(value: string) {\r\n\treturn value\r\n\t\t.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, function (word, index) {\r\n\t\t\treturn index === 0 ? word.toLowerCase() : word.toUpperCase();\r\n\t\t})\r\n\t\t.replace(/(?:\\s+|[-_])/g, '');\r\n}\r\n\r\n/**\r\n * Removes html characters\r\n *\r\n * @export\r\n * @param {*} html\r\n * @returns\r\n */\r\nexport function stripHtml(html) {\r\n\tconst tmp = document.createElement('div');\r\n\ttmp.innerHTML = html;\r\n\treturn tmp.textContent || tmp.innerText || '';\r\n}\r\n\r\n/**\r\n * Cuts of text and adds ellipsis (...) after a certain number of characters\r\n * @param text The text to format\r\n * @param cutoff The number of characters to add the ellipsis after\r\n */\r\nexport function addEllipsis(text: string, cutoff: number = 20) {\r\n\tif (!text || text.length < cutoff) {\r\n\t\treturn text;\r\n\t}\r\n\r\n\treturn text.substring(0, cutoff) + '...';\r\n}\r\n\r\n/**\r\n * Trims a string value\r\n */\r\nexport function trimString(value: string) {\r\n\treturn value ? value.trim() : '';\r\n}\r\n","/**\r\n * @see HawkSearchConfig.apiUrl\r\n */\r\nexport const defaultApiUrl = 'https://searchapi-dev.americaneagle.com';\r\n\r\n/**\r\n * @see HawkSearchConfig.dashboardUrl\r\n */\r\nexport const defaultDashboardUrl = 'https://hawk-dev.americaneagle.com';\r\n\r\n/**\r\n * @see HawkSearchConfig.searchUrl\r\n */\r\nexport const defaultSearchUrl = '/api/v2/search';\r\n\r\n/**\r\n * @see HawkSearchConfig.autocompleteUrl\r\n */\r\nexport const defaultAutocompleteUrl = '/api/autocomplete';\r\n\r\n/**\r\n * @see HawkSearchConfig.searchPageUrl\r\n */\r\nexport const defaultSearchPageUrl = '/search';\r\n\r\n/**\r\n * Endpoint for hawksearch's compare api\r\n */\r\nexport const defaultCompareItemsURL = '/api/v2/compare';\r\n\r\n/**\r\n * @see HawkSearchConfig.recommendationUrl\r\n */\r\nexport const defaultRecommendationUrl = 'https://recs-dev.americaneagle.com';\r\n\r\n/**\r\n * @see HawkSearchConfig.recommendationWidgetUrl\r\n */\r\nexport const recommendationWidgetUrl = '/api/recommendation/v2/getwidgetitems';\r\n","import { Response, Request, Result } from 'models/Search';\r\nimport { Value, Facet } from 'models/Facets';\r\nimport { ClientSelections, ClientSelectionValue } from 'store/ClientSelections';\r\nimport { CompareResultObject } from '../models/CompareResultObject';\r\n\r\nexport enum FacetSelectionState {\r\n\t/** The facet value is not selected. */\r\n\tNotSelected,\r\n\t/** The facet value is selected. */\r\n\tSelected,\r\n\t/** The facet value is selected, but negated. */\r\n\tNegated,\r\n}\r\n\r\nexport interface SelectionInfo {\r\n\t/** The facet value selection state. */\r\n\tstate: FacetSelectionState;\r\n\r\n\t/**\r\n\t * If the facet value is `FacetSelectionState.Selected` or `FacetSelectionState.Negated`, this is the value of\r\n\t * the facet value. For negated facet values this will be prefixed with the negation character `'-'`.\r\n\t */\r\n\tselectedValue?: string;\r\n\r\n\t/**\r\n\t * If the facet value is `FacetSelectionState.Selected` or `FacetSelectionState.Negated`, this is the index\r\n\t * into the `pendingSearch.FacetSelections[facetName]` array for this facet value.\r\n\t */\r\n\tselectionIndex?: number;\r\n}\r\n\r\nexport class SearchStore {\r\n\t/** This represents the next search request that will be executed. */\r\n\tpublic pendingSearch: Partial;\r\n\r\n\t/**\r\n\t * Whether or not the next search request will perform history actions (pushing the search into browser\r\n\t * history).\r\n\t */\r\n\tpublic doHistory: boolean;\r\n\r\n\t/** Whether or not a search request is waiting for completion. */\r\n\tpublic isLoading: boolean;\r\n\r\n\tpublic itemsToCompare: Result[];\r\n\tpublic itemsToCompareIds: string[];\r\n\tpublic comparedResults: CompareResultObject[];\r\n\r\n\t/** The results of the last search request, if one has been performed. Otherwise, `undefined`. */\r\n\tpublic searchResults?: Response;\r\n\r\n\tpublic requestError: boolean;\r\n\r\n\tpublic constructor(initial?: Partial) {\r\n\t\tObject.assign(this, initial);\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not this is the initial load of the search results.\r\n\t */\r\n\tpublic get isInitialLoad() {\r\n\t\treturn this.isLoading && !this.searchResults;\r\n\t}\r\n\r\n\t/**\r\n\t * Determines whether or not the given facet and facet value is selected, and returns info regarding the selection.\r\n\t * @param facet The facet for which the facet value will be checked for selection.\r\n\t * @param facetValue The facet value that will be checked for selection.\r\n\t */\r\n\tpublic isFacetSelected(facet: Facet | string, facetValue: Value | string): SelectionInfo {\r\n\t\tconst facetName = typeof facet === 'string' ? facet : facet.Name;\r\n\t\tconst facetField = typeof facet === 'string' ? facet : facet.selectionField;\r\n\r\n\t\tconst valueValue = typeof facetValue === 'string' ? facetValue : facetValue.Value;\r\n\t\tconst valueLabel = typeof facetValue === 'string' ? facetValue : facetValue.Label;\r\n\r\n\t\tif (!valueValue) {\r\n\t\t\tconsole.error(`Facet ${facetName} (${facetField}) has no facet value for ${valueLabel}`);\r\n\t\t\treturn { state: FacetSelectionState.NotSelected };\r\n\t\t}\r\n\r\n\t\tconst facetSelections = this.pendingSearch.FacetSelections;\r\n\r\n\t\tif (!facetSelections || !facetSelections[facetField]) {\r\n\t\t\treturn { state: FacetSelectionState.NotSelected };\r\n\t\t}\r\n\r\n\t\tconst selectionIdx = facetSelections[facetField]!.indexOf(valueValue);\r\n\t\tconst negationIdx = facetSelections[facetField]!.indexOf(`-${valueValue}`);\r\n\r\n\t\tif (selectionIdx !== -1) {\r\n\t\t\t// if the exact facet value exists, then we're normally selected\r\n\t\t\treturn {\r\n\t\t\t\tstate: FacetSelectionState.Selected,\r\n\t\t\t\tselectedValue: valueValue,\r\n\t\t\t\tselectionIndex: selectionIdx,\r\n\t\t\t};\r\n\t\t} else if (negationIdx !== -1) {\r\n\t\t\t// if the facet value is selected but prefixed with a -, then we're negated\r\n\t\t\treturn {\r\n\t\t\t\tstate: FacetSelectionState.Negated,\r\n\t\t\t\tselectedValue: `-${valueValue}`,\r\n\t\t\t\tselectionIndex: negationIdx,\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\treturn { state: FacetSelectionState.NotSelected };\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an object containing the selections that have been made in both the next search request and also\r\n\t * in the previous search request. This should be used when iterating selections instead of pulling the values\r\n\t * out from the search result or pending search - as this will merge the values together and provide an accurate\r\n\t * view of all facet selections.\r\n\t */\r\n\tpublic get facetSelections(): ClientSelections {\r\n\t\tconst {\r\n\t\t\tpendingSearch: { FacetSelections: clientSelections, SearchWithin },\r\n\t\t\tsearchResults,\r\n\t\t} = this;\r\n\r\n\t\tconst selections: ClientSelections = {};\r\n\r\n\t\tif (!clientSelections && !SearchWithin) {\r\n\t\t\treturn selections;\r\n\t\t}\r\n\r\n\t\t// if we've made selections on the client, transform these into more detailed selections.\r\n\t\t// the client-side selections are just facet fields and values without any labels - so we\r\n\t\t// need to combine this information with the list of facets received from the server in the\r\n\t\t// previous search in order to return a rich list of selections\r\n\r\n\t\tconst facets = searchResults ? searchResults.Facets : null;\r\n\r\n\t\tif (!facets) {\r\n\t\t\t// but we can only do this if we've received facet information from the server. without this\r\n\t\t\t// info we can't determine what labels should be used\r\n\t\t\treturn selections;\r\n\t\t}\r\n\r\n\t\t// manually handle the `searchWithin` selection, as this doesn't usually behave like a normal facet selection\r\n\t\t// but instead a field on the search request\r\n\t\tif (SearchWithin) {\r\n\t\t\tconst facet = facets.find((f) => f.selectionField === 'searchWithin');\r\n\r\n\t\t\tif (facet) {\r\n\t\t\t\tselections.searchWithin = {\r\n\t\t\t\t\tfacet,\r\n\t\t\t\t\tlabel: facet.Name,\r\n\t\t\t\t\titems: [\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tlabel: SearchWithin,\r\n\t\t\t\t\t\t\tvalue: SearchWithin,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t],\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!clientSelections) {\r\n\t\t\treturn selections;\r\n\t\t}\r\n\r\n\t\tObject.keys(clientSelections).forEach((fieldName) => {\r\n\t\t\tconst selectionValues = clientSelections[fieldName];\r\n\r\n\t\t\tif (!selectionValues) {\r\n\t\t\t\t// if this selection has no values, it's not really selected\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconst facet = facets.find((f) => f.selectionField === fieldName);\r\n\r\n\t\t\tif (!facet) {\r\n\t\t\t\t// if there's no matching facet from the server, we can't show this since we'll have no labels\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconst items: ClientSelectionValue[] = [];\r\n\r\n\t\t\tif (facet.FieldType === 'range') {\r\n\t\t\t\t// if the facet this selection is for is a range, there won't be a matching value and thus there won't be a label.\r\n\t\t\t\t// so because of this we'll just use the selection value as the label\r\n\r\n\t\t\t\tselectionValues.forEach((selectionValue) => {\r\n\t\t\t\t\titems.push({\r\n\t\t\t\t\t\tlabel: selectionValue,\r\n\t\t\t\t\t\tvalue: selectionValue,\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t} else if (facet.FieldType === 'tab') {\r\n\t\t\t\t// do not return the selection value for tab facet\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\t// for other types of facets, try to find a matching value\r\n\r\n\t\t\t\tselectionValues.forEach((selectionValue) => {\r\n\t\t\t\t\tconst matchingVal = this.findMatchingValue(selectionValue, facet.Values);\r\n\r\n\t\t\t\t\tif (!matchingVal || !matchingVal.Label) {\r\n\t\t\t\t\t\t// if there's no matching value from the server, we cannot display because there would\r\n\t\t\t\t\t\t// be no label - same if there's no label at all\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\titems.push({\r\n\t\t\t\t\t\tlabel: matchingVal.Label,\r\n\t\t\t\t\t\tvalue: selectionValue,\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\tselections[fieldName] = {\r\n\t\t\t\tfacet,\r\n\t\t\t\tlabel: facet.Name,\r\n\t\t\t\titems,\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\treturn selections;\r\n\t}\r\n\r\n\tprivate findMatchingValue(selectionValue: string, facetValues: Value[]): Value | null {\r\n\t\tlet matchingValue: Value | null = null;\r\n\t\tif (!facetValues || facetValues.length === 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tfor (const facetValue of facetValues) {\r\n\t\t\tconst isMatchingVal = facetValue.Value === selectionValue || `-${facetValue.Value}` === selectionValue;\r\n\t\t\t// loop through children\r\n\t\t\tif (!isMatchingVal) {\r\n\t\t\t\tmatchingValue = this.findMatchingValue(selectionValue, facetValue.Children);\r\n\t\t\t} else {\r\n\t\t\t\tmatchingValue = facetValue;\r\n\t\t\t}\r\n\r\n\t\t\tif (matchingValue) {\r\n\t\t\t\treturn matchingValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn matchingValue;\r\n\t}\r\n}\r\n","import { ControllerStateAndHelpers } from 'downshift';\r\n\r\nexport enum SuggestionType {\r\n\tProduct = 'product',\r\n\tCategory = 'category',\r\n\tContent = 'content',\r\n\tPopular = 'popular',\r\n\tViewAll = 'viewall',\r\n}\r\nexport abstract class Suggestion {\r\n\tpublic SuggestionType: SuggestionType;\r\n\tpublic constructor(suggestionType: SuggestionType) {\r\n\t\tthis.SuggestionType = suggestionType;\r\n\t}\r\n}\r\n\r\nexport interface SuggestionStrategy {\r\n\thandleItemChange(item: Suggestion, downshift: ControllerStateAndHelpers): void;\r\n\ttoString(item: Suggestion): string;\r\n}\r\n\r\nexport interface SuggestionStrategyMatch {\r\n\ttype: SuggestionType;\r\n\tstrategy: SuggestionStrategy;\r\n}\r\n"],"sourceRoot":""}