PageSourceSearch

https://www.quiltersfancy.com/1789392363/c/js/website-facets/webSiteFacetsComponent.js

js quiltersfancy.com collected 2026-09-25 20:59:19 UTC 27,816 bytes, 756 lines download raw bytes

1"use strict";
2
3angular.module('rainApp').directive("webSiteFacets", function () {
4
5    var controller = function ($scope, $window, $timeout, $httpParamSerializer) {
6
7        $scope.facetsViewLimit = 6;
8
9        $scope.isStonesFacetsEnable = function () {
10            return window.isJewelry && !!window.knobby && window.knobby.module_stone_management && window.knobby.module_stones_facets;
11        };
12
13        $scope.DYNAMIC_FACETS_META = {
14            __type__: {
15                sorder: 2,
16                title: 'Item Type',
17                hideIfOne: true,
18            },
19            class_category: {
20                sorder: 1,
21                title: 'Class Categories',
22                normalizer: function (item) {
23                    return $scope.classGroups[item] || item.key;
24                },
25                filter: function (value, index, allValues) {
26                    if (+value.key === -1 && allValues.length <= 2) {
27                        // we don't need to show root All Classes category if there is only one class category
28                        return false;
29                    }
30
31                    return true;
32                },
33                no_checkbox: true
34            },
35            custom_field: {
36                normalizer: function(item) {
37                    if (item.custom_field_type === 'currency' && $scope.currencySymbol) {
38                        return $scope.currencySymbol + item.key;
39                    }
40
41                    if (item.custom_field_type === 'dropdown') {
42                        return item.value;
43                    }
44
45                    return item.key;
46                },
47            },
48            mfg_name: {
49                sorder: 3,
50                title: 'Brand',
51                capitalizeValue: false
52            },
53            instructor: {
54                sorder: 4,
55                title: 'Instructor'
56            },
57            skill_level: {
58                sorder: 5,
59                title: 'Skill Level',
60                sort: (function () {
61                    var order = ['beginner', 'intermediate', 'advanced'];
62                    return function (a, b) {
63                        return order.indexOf(a.key) - order.indexOf(b.key)
64                    }
65                })(),
66            },
67        };
68
69        $scope.viewAllDynamicFacets = {};
70        $scope.viewAllVariationsFacets = {};
71
72        $scope.init = function () {
73            $scope.classGroups = $window.classGroups;
74
75            $scope.showFacetsNumbers = $window.showFacetsNumbers;
76            $scope.currencySymbol = $window.currencySymbol;
77            $scope.decodedCurencySymbol = $window.currencySymbol;
78            $scope.search_keyword = $window.search_keyword;
79            $scope.category = $window.facetsCategory;
80            $scope.dynamicFacets = $window.facetsDynamicFacets;
81            $scope.dynamicFacetsNormalized = prepareDynamicFacets($window.facetsDynamicFacets);
82
83            $scope.dynamicFilters = $window.facetsDynamicFilters;
84            $scope.variationsFilters = $window.facetsVariationsFilters;
85            $scope.minFilterPrice = $window.minFilterPrice || 0;
86            $scope.maxFilterPrice = $window.maxFilterPrice || 2000000;
87            $scope.priceFilter = {
88                min: null,
89                max: null,
90            };
91
92            if ($scope.isStonesFacetsEnable()) {
93                $scope.stoneOptionsFilter = {
94                    carat: {
95                        min: $window.stoneMinCaratFilter || 0.01,
96                        max: $window.stoneMaxCaratFilter || 100,
97                        filterMin: 0.01,
98                        filterMax: 100,
99                    },
100                    colors: $window.stoneColorsFilters || [],
101                    types: $window.stoneTypesFilter || [],
102                    clarities: $window.stoneClaritiesFilter || [],
103                    cuts: $window.stoneCutsFilter || [],
104                    shapes: $window.stoneShapesFilter || [],
105                };
106            }
107
108            $scope.variationsFacets = {};
109            angular.forEach($window.facetsVariationsFacets, function (values, key) {
110                $scope.variationsFacets[key] = [];
111                angular.forEach(values, function (value) {
112                    $scope.variationsFacets[key].push(value);
113                })
114            });
115
116            $scope.hasClasses = $window.facetsHasClasses;
117
118            $scope.classDateFilter = $window.facetsClassDateFilter;
119
120            $scope.isJewelry = $window.isJewelry;
121
122            $scope.visibleColorGroups = {};
123            $scope.getStoneFacets = [];
124
125            if ($scope.isStonesFacetsEnable()) {
126                $scope.getStoneFacets = [
127                    $scope.createStoneFilter('Type', window.stoneTypesFacets, 'types'),
128                    $scope.createStoneFilter('Clarity', window.stoneClaritiesFacets, 'clarities'),
129                    $scope.createStoneFilter('Cut', window.stoneCutsFacets, 'cuts'),
130                ];
131            }
132
133            if ($scope.isStonesFacetsEnable()) {
134                $scope.visibleColorGroups = JSON.parse(localStorage.getItem('visible-color-groups')) || {};
135            }
136
137            if ($scope.isExpandCollapseWebFiltersFlagEnabled()) {
138                if (localStorage.getItem('expand-collapse-state')) {
139                    $scope.expandCollapseState = JSON.parse(localStorage.getItem('expand-collapse-state'));
140                } else {
141                    if ($scope.collapseFiltersOnInit()) {
142                        $scope.expandCollapseState = $scope.getExpandCollapseState(false);
143                    } else {
144                        $scope.expandCollapseState = $scope.getExpandCollapseState(true);
145                    }
146                }
147            }
148
149            $timeout(initDatePicker);
150
151            $timeout(initPriceFilter)
152        };
153
154        $scope.createStoneFilter = function(filterName, options, arrayName) {
155            return {
156                filterName: filterName,
157                filterOptions: Array.isArray(options) ? options : [],
158                isOptionChecked: function (value) {
159                    return $scope.stoneOptionsFilter[arrayName].includes(value);
160                },
161                toggleAction: function (value) {
162                    $scope.toggleStoneFilterAction(arrayName, value);
163                },
164            };
165        }
166
167        $scope.toggleStoneFilterAction = function (filterName, value) {
168            var index = $scope.stoneOptionsFilter[filterName].indexOf(value);
169
170            if (index === -1) {
171                $scope.stoneOptionsFilter[filterName].push(value);
172            } else {
173                $scope.stoneOptionsFilter[filterName].splice(index, 1);
174            }
175
176            $scope.applyFilters();
177        };
178
179        // The editor frame keeps an 'editing' class on the preview document's root element while
180        // in edit mode; navigating away then would tear down the page being edited.
181        var isEditorEditMode = function () {
182            return !!($window.knobby && $window.knobby.module_web_editor_2026 && $window.__onyxPreview)
183                && $window.document.documentElement.classList.contains('editing');
184        };
185
186        var isWebsiteEditorEnabled = function () {
187            return !!($window.knobby && $window.knobby.module_web_editor_2026);
188        };
189
190        var uuidRegex = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/;
191
192        // Under an admin domain the storefront is served beneath /{uuid}/, which window.storeUrl
193        // carries as a relative path whenever an editor is on the page; a root-absolute /iishop
194        // would leave the store.
195        var shopUrl = function () {
196            if (!isWebsiteEditorEnabled()) {
197                return '/iishop';
198            }
199
200            if (/^\/.*\/$/.test($window.storeUrl || '')) {
201                return $window.storeUrl + 'iishop';
202            }
203
204            var match = $window.location.pathname.match(uuidRegex);
205
206            return (match ? '/' + match[0] : '') + '/iishop';
207        };
208
209        $scope.shopUrl = shopUrl;
210
211        $scope.handleCategoryClick = function (category) {
212            if (isEditorEditMode()) {
213                return;
214            }
215
216            var location = category.url,
217                filtersString = $scope.getFiltersString();
218
219            if (filtersString) {
220                location += '?';
221            }
222
223            var match = window.location.href.match(uuidRegex);
224
225            if (!isWebsiteEditorEnabled() && '/iishop' === location && match) {
226                location = '/' + match[0];
227            }
228
229            $window.location = location + filtersString;
230        };
231
232        $scope.applyFilters = function (url) {
233            if (isEditorEditMode()) {
234                return;
235            }
236
237            $timeout(function () {
238                var location = url || $window.location.pathname;
239
240                var filtersString = $scope.getFiltersString();
241
242                if (filtersString) {
243                    location += '?';
244                }
245
246                $window.location = location + filtersString;
247            });
248        };
249
250        $scope.priceDynamicRanges = [
251            {min: 0, max: 30, increment: 2},
252            {min: 30, max: 100, increment: 5},
253            {min: 100, max: 500, increment: 10},
254            {min: 500, max: 3000, increment: 20},
255            {min: 3000, max: 5000, increment: 100},
256            {min: 5000, max: 10000, increment: 200},
257            {min: 10000, max: 20000, increment: 2000},
258            {min: 20000, max: 50000, increment: 10000},
259            {min: 50000, max: Infinity, increment: 20000},
260        ];
261
262        $scope.caratDynamicRanges = [
263            {min: 0, max: 2, increment: 0.01},
264            {min: 2, max: 3, increment: 0.05},
265            {min: 3, max: 5, increment: 0.1},
266            {min: 5, max: 10, increment: 0.5},
267            {min: 10, max: Infinity, increment: 10},
268        ];
269
270        $scope.getFiltersString = function () {
271            var dataToSerialize = {};
272
273            if ($scope.search_keyword) {
274                dataToSerialize.search_keyword = $scope.search_keyword;
275            }
276
277            if (!angular.equals({}, $scope.dynamicFilters)) {
278                dataToSerialize.dynamicFilters = $scope.dynamicFilters;
279            }
280
281            if (!angular.equals({}, $scope.variationsFilters)) {
282                dataToSerialize.variationsFilters = $scope.variationsFilters;
283            }
284
285            if ($scope.priceFilter.min !== null && $scope.priceFilter.min !== $scope.minFilterPrice) {
286                dataToSerialize.minPrice = $scope.priceFilter.min;
287            }
288
289            if ($scope.priceFilter.max !== null &&  $scope.priceFilter.max !== $scope.maxFilterPrice) {
290                dataToSerialize.maxPrice = $scope.priceFilter.max;
291            }
292
293            if ($scope.classDateFilter !== null) {
294                dataToSerialize.classDateFilter = $scope.classDateFilter;
295            }
296
297            if ($scope.isStonesFacetsEnable()) {
298                if ($scope.stoneOptionsFilter.shapes?.length) {
299                    dataToSerialize.stnshps = $scope.stoneOptionsFilter.shapes.join('|');
300                }
301
302                if ($scope.stoneOptionsFilter.colors?.length) {
303                    dataToSerialize.stnclrs = $scope.stoneOptionsFilter.colors.join('|');
304                }
305
306                if ($scope.stoneOptionsFilter.clarities?.length) {
307                    dataToSerialize.stnclrt = $scope.stoneOptionsFilter.clarities.join('|');
308                }
309
310                if ($scope.stoneOptionsFilter.types?.length) {
311                    dataToSerialize.stntps = $scope.stoneOptionsFilter.types.join('|');
312                }
313
314                if ($scope.stoneOptionsFilter.cuts?.length) {
315                    dataToSerialize.stncuts = $scope.stoneOptionsFilter.cuts.join('|');
316                }
317
318                if ($scope.stoneOptionsFilter.carat.min !== $scope.stoneOptionsFilter.carat.filterMin || $scope.stoneOptionsFilter.carat.max !== $scope.stoneOptionsFilter.carat.filterMax) {
319                    dataToSerialize.stncrtmn = $scope.stoneOptionsFilter.carat.min;
320                    dataToSerialize.stncrtmx = $scope.stoneOptionsFilter.carat.max;
321                }
322            }
323
324            var urlParams= $scope.getQueryParams();
325            if (urlParams['sort']) {
326                dataToSerialize.sort = urlParams['sort'];
327            }
328            if (urlParams['order']) {
329                dataToSerialize.order = urlParams['order'];
330            }
331
332            if ($window.knobby && $window.knobby.module_web_editor_2026 && $window.__onyxPreview) {
333                dataToSerialize.embedded = 1;
334            }
335
336            return $httpParamSerializer(dataToSerialize);
337        };
338
339        $scope.getQueryParams = function () {
340            var params = {};
341            var queryString = $window.location.search.substring(1);
342            var pairs = queryString.split("&");
343            for (var i = 0; i < pairs.length; i++) {
344                var pair = pairs[i].split("=");
345                var key = decodeURIComponent(pair[0]);
346                var value = decodeURIComponent(pair[1] || "");
347                if (key) {
348                    params[key] = value;
349                }
350            }
351            return params;
352        };
353
354        $scope.handleAllCategoriesClick = function () {
355            $scope.clearAllFilters(false);
356            $timeout(function () {
357                $scope.handleCategoryClick({url: shopUrl()})
358            });
359        };
360
361        $scope.clearAllFilters = function (apply) {
362            angular.forEach($scope.variationsFilters, function (filter, key) {
363                $scope.clearVariationFilter(key, false);
364            });
365            angular.forEach($scope.dynamicFilters, function (filter, key) {
366                $scope.clearDynamicFacetFilter(key, false);
367            });
368            $scope.clearPriceFilters(false);
369            $scope.clearClassDateFilter(false);
370
371            if ($scope.isExpandCollapseWebFiltersFlagEnabled()) {
372                $scope.clearSearchFilter();
373                if ($scope.isStonesFacetsEnable()) {
374                    $scope.clearStonesFilters();
375                }
376                $timeout(function () {
377                    $scope.handleCategoryClick({url: shopUrl()})
378                });
379            }
380
381            if (apply) {
382                $scope.applyFilters();
383            }
384        };
385
386        $scope.clearSearchFilter = function () {
387            $scope.search_keyword = '';
388        }
389
390        $scope.clearStonesFilters = function () {
391            $scope.stoneOptionsFilter = {
392                carat: {},
393                colors: [],
394                types: [],
395                clarities: [],
396                cuts: [],
397                shapes: [],
398            };
399        }
400
401        $scope.clearDynamicFacetFilter = function (key, apply) {
402            $scope.dynamicFilters[key] = {};
403
404            if (apply) {
405                $scope.applyFilters();
406            }
407        };
408
409        $scope.clearPriceFilters = function (apply) {
410            $scope.priceFilter.min = $scope.minFilterPrice;
411            $scope.priceFilter.max = $scope.maxFilterPrice;
412
413            if (apply) {
414                $scope.applyFilters();
415            }
416        };
417
418        $scope.clearVariationFilter = function (key, apply) {
419            $scope.variationsFilters[key] = {};
420
421            if (apply) {
422                $scope.applyFilters();
423            }
424        };
425
426        $scope.clearClassDateFilter = function (apply) {
427            $scope.classDateFilter = null;
428            if (apply) {
429                $scope.applyFilters();
430            }
431        };
432
433        $scope.isDynamicFacetVisible = function (key, item) {
434            if ($scope.viewAllDynamicFacets[key]) {
435                return true;
436            }
437
438            var index = $scope.dynamicFacets[key].map(function (v) {
439                return v.key;
440            }).indexOf(item.key);
441
442            if (index < $scope.facetsViewLimit) {
443                return true;
444            }
445
446            if ($scope.dynamicFilters[key] !== undefined && $scope.dynamicFilters[key][item.key] !== undefined) {
447                return $scope.dynamicFilters[key][item.key];
448            }
449
450            return false;
451        };
452
453        $scope.isVariationFacetVisible = function (key, item) {
454            if ($scope.viewAllVariationsFacets[key]) {
455                return true;
456            }
457
458            var index = $scope.variationsFacets[key].map(function (v) {
459                return v.key;
460            }).indexOf(item.key);
461
462            if (index < $scope.facetsViewLimit) {
463                return true;
464            }
465
466            if ($scope.variationsFilters[key] !== undefined && $scope.variationsFilters[key][item.key] !== undefined) {
467                return $scope.variationsFilters[key][item.key];
468            }
469
470            return false;
471        };
472
473        $scope.allVariationsFacetsVisible = function (key) {
474            if ($scope.viewAllVariationsFacets[key]) {
475                return true;
476            }
477
478            return $scope.variationsFacets[key].every(function (item) {
479                return $scope.isVariationFacetVisible(key, item)
480            });
481        };
482
483        $scope.allDynamicFacetsVisible = function (key) {
484            if ($scope.viewAllDynamicFacets[key]) {
485                return true;
486            }
487
488            return $scope.dynamicFacets[key].every(function (item) {
489                return $scope.isDynamicFacetVisible(key, item)
490            });
491        };
492
493        $scope.$watch('dynamicFilters', function () {
494            clearEmpty($scope.dynamicFilters);
495        }, true);
496
497        $scope.$watch('variationsFilters', function () {
498            clearEmpty($scope.variationsFilters);
499        }, true);
500
501        var clearEmpty = function (object) {
502            angular.forEach(object, function (values) {
503                for (var key in values) {
504                    if (values.hasOwnProperty(key) && !values[key]) {
505                        delete values[key];
506                    }
507                }
508            });
509
510            for (var key in object) {
511                if (object.hasOwnProperty(key)
512                    && (!object[key] || Object.keys(object[key]).length <= 0)) {
513                    delete object[key];
514                }
515            }
516        };
517
518        $scope.toggleColorGroup = function (event, colorGroup) {
519            event.preventDefault();
520
521            var cgKey = $scope.generateStoneColorGroupKey(colorGroup);
522
523            $scope.visibleColorGroups[cgKey] = !$scope.visibleColorGroups[cgKey];
524            localStorage.setItem('visible-color-groups', JSON.stringify($scope.visibleColorGroups));
525        };
526
527        $scope.generateStoneColorGroupKey = function (colorGroup) {
528            return colorGroup.replace(/[^a-zA-Z0-9]/g, '');
529        };
530
531        $scope.getStoneColorsFacets = function () {
532            return window.stoneColorsFacets || [];
533        };
534
535        $scope.getStoneShapesFacets = function () {
536            return window.stoneShapesFacets || [];
537        };
538
539        var prepareDynamicFacets = function (facets) {
540            var result = [];
541
542            angular.forEach(facets, function (facet, key) {
543                var meta = $scope.DYNAMIC_FACETS_META[key] || {};
544
545                if (meta.sort) {
546                    facet.sort(meta.sort);
547                }
548
549                if (meta.filter) {
550                    facet = facet.filter(meta.filter);
551                }
552
553                if (facet.length > 0 && facet[0].custom_field) {
554                    meta = $scope.DYNAMIC_FACETS_META['custom_field'];
555
556                    if (facet[0].title) {
557                        meta.title = facet[0].title;
558                    }
559                }
560
561                result.push({
562                    sorder: meta.sorder || Infinity,
563                    values: facet,
564                    key: key,
565                    title: meta.title || key,
566                    capitalizeValue: meta.capitalizeValue = true,
567                    meta: meta
568                });
569            });
570
571            if (window.knobby && window.knobby.module_facet_fields_order_web_fix) {
572                result.sort(function (a, b) {
573                    var keyA = (a.key && a.key.includes('::') && a.key.split('::')[1]) ? a.key.split('::')[1] : '';
574                    var keyB = (b.key && b.key.includes('::') && b.key.split('::')[1]) ? b.key.split('::')[1] : '';
575
576                    return keyA.localeCompare(keyB);
577                });
578            } else {
579                result.sort(function (a,b) {
580                    return a.sorder - b.sorder;
581                });
582            }
583
584            return result;
585        };
586
587        var initPriceFilter = function () {
588            $scope.priceFilter = {
589                min: $window.facetsMinPriceFilter
590                && $window.facetsMinPriceFilter > $scope.minFilterPrice
591                && $window.facetsMinPriceFilter < $scope.maxFilterPrice
592                    ? $window.facetsMinPriceFilter
593                    : $scope.minFilterPrice,
594                max: $window.facetsMaxPriceFilter
595                && $window.facetsMaxPriceFilter < $scope.maxFilterPrice
596                && $window.facetsMaxPriceFilter > $scope.minFilterPrice
597                    ? $window.facetsMaxPriceFilter
598                    : $scope.maxFilterPrice,
599            };
600        };
601
602        var initDatePicker = function() {
603            var datePickerOptions = {
604                linkedCalendars: false,
605                minDate: moment(),
606                startDate: moment(),
607                endDate: moment(),
608                locale: {
609                    format: 'MMM D, YYYY',
610                    cancelLabel: 'Clear'
611                },
612                drops: 'up',
613                autoApply: true,
614                autoUpdateInput: false,
615                opens: 'right',
616                ranges: {
617                    'Today': [moment(), moment()],
618                    'Tomorrow': [moment().add(1, 'days'), moment().add(1, 'days')],
619                    'Next 7 Days': [moment(), moment().add(6, 'days')],
620                    'This Month': [moment().startOf('month'), moment().endOf('month')],
621                }
622            };
623
624            if ($scope.$element.find('#filterDateRange').length > 0) {
625                $scope.$element.find('#filterDateRange').daterangepicker(datePickerOptions);
626
627                $scope.$element.find('#filterDateRange').on('apply.daterangepicker', function(ev, picker) {
628                    $(this).val(picker.startDate.format('MM/DD/YYYY') + ' - ' + picker.endDate.format('MM/DD/YYYY'));
629
630                    $scope.classDateFilter = picker.startDate.format('YYYY-MM-DD HH:mm:ss')+'|'+picker.endDate.format('YYYY-MM-DD HH:mm:ss');
631                    $scope.applyFilters();
632                });
633
634                if ($scope.classDateFilter !== null) {
635                    var parts = $scope.classDateFilter.split('|');
636                    $scope.$element.find('#filterDateRange').val(
637                        moment(parts[0]).format('MM/DD/YYYY') + ' - ' + moment(parts[1]).format('MM/DD/YYYY')
638                    );
639                }
640            }
641        };
642
643        $scope.toggleFilters = function (event) {
644            var element = document.getElementById('fn_filter_wrapper');
645            if (element.style.display === "block") {
646                element.style.display = "none";
647            } else {
648                element.style.display = "block";
649            }
650            if (event.target.innerText === event.target.dataset.show) {
651                event.target.innerText = event.target.dataset.hide;
652            } else {
653                event.target.innerText = event.target.dataset.show;
654            }
655        }
656
657        $scope.handleExpandCollapse = function (parent, key) {
658            if (!$scope.isExpandCollapseWebFiltersFlagEnabled()) {
659                return;
660            }
661
662            if ($scope.expandCollapseState[parent] !== undefined) {
663                $scope.expandCollapseState[parent][key] = !$scope.expandCollapseState[parent][key];
664            } else {
665                $scope.expandCollapseState[parent] = {[key]: true};
666            }
667
668            localStorage.setItem('expand-collapse-state', JSON.stringify($scope.expandCollapseState));
669        }
670
671        $scope.isExpandCollapseWebFiltersFlagEnabled = function () {
672            return !!window.knobby && window.knobby.module_expand_collapse_web_filters;
673        };
674
675        $scope.getButtonExpandCollapseAllTitle = function () {
676            const isCollapseAll = Object.values($scope.expandCollapseState).every(child =>
677                Object.values(child).every(value => value === true)
678            );
679
680            return isCollapseAll ? 'Collapse All' : 'Expand All';
681        };
682
683        $scope.handleExpandCollapseAll = function (action) {
684            if (action === 'Collapse All') {
685                $scope.expandCollapseState = $scope.getExpandCollapseState(false);
686            } else {
687                $scope.expandCollapseState = $scope.getExpandCollapseState(true);
688            }
689
690            localStorage.setItem('expand-collapse-state', JSON.stringify($scope.expandCollapseState));
691        };
692
693        $scope.collapseFiltersOnInit = function () {
694            return $scope.isStonesFacetsEnable() || ($scope.dynamicFacetsNormalized.length + Object.keys($scope.variationsFacets).length) > 3;
695        };
696
697        $scope.getExpandCollapseState = function (value) {
698            return {
699                static: {
700                    search: value,
701                    categories: value,
702                    price: value,
703                },
704                dynamic: Object.fromEntries(
705                    $scope.dynamicFacetsNormalized.map(facet => [facet.key, value])
706                ),
707                variations: Object.fromEntries(
708                    Object.keys($scope.variationsFacets).map(key => [key, value])
709                ),
710                ...($scope.isStonesFacetsEnable() ? {
711                    stones: {
712                        Clarity: value,
713                        Cut: value,
714                        Type: value,
715                        carat: value,
716                        color: value,
717                        shapes: value,
718                    }
719                } : {})
720            };
721        };
722
723        $scope.isAnyFilterSelected = function () {
724            return !!(Object.keys($scope.dynamicFilters).length || Object.keys($scope.variationsFilters).length || $scope.search_keyword || (!$scope.priceFilter.min && $scope.priceFilter.max !== 50000) || ($scope.isStonesFacetsEnable() && !$scope.isStoneOptionsFiltersEmpty()) || $scope.category.current);
725        }
726
727        $scope.isStoneOptionsFiltersEmpty = function () {
728            var stoneOptionsFilter = $scope.stoneOptionsFilter;
729            var arraysAreEmpty = ['clarities', 'colors', 'cuts', 'shapes', 'types'].every(function (key) {
730                return !stoneOptionsFilter[key].length;
731            });
732            var caratFilterIsDefault = stoneOptionsFilter.carat?.filterMin === 0.01 &&
733                stoneOptionsFilter.carat?.filterMax === 100;
734
735            return arraysAreEmpty && caratFilterIsDefault;
736        };
737    };
738
739    return {
740        restrict: 'E',
741        scope: {},
742        controller: controller,
743        templateUrl: '/c/js/website-facets/webSiteFacetsTemplate.html?v=1.0.4',
744        link: function ($scope, $element) {
745            $scope.$element = $element;
746            $scope.init();
747        }
748    };
749});
750
751angular.module('rainApp').filter('reverse', function() {
752    return function(items) {
753        return items.slice().reverse();
754    };
755});
756

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.