@stapel/search-react 0.4.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +1 -1
  3. package/dist/default/DegradationNotice.d.ts +7 -0
  4. package/dist/default/DegradationNotice.d.ts.map +1 -1
  5. package/dist/default/DegradationNotice.js +17 -6
  6. package/dist/default/DegradationNotice.js.map +1 -1
  7. package/dist/default/FacetGroupControl.d.ts +40 -0
  8. package/dist/default/FacetGroupControl.d.ts.map +1 -0
  9. package/dist/default/FacetGroupControl.js +176 -0
  10. package/dist/default/FacetGroupControl.js.map +1 -0
  11. package/dist/default/FacetPanelPane.d.ts +54 -3
  12. package/dist/default/FacetPanelPane.d.ts.map +1 -1
  13. package/dist/default/FacetPanelPane.js +116 -22
  14. package/dist/default/FacetPanelPane.js.map +1 -1
  15. package/dist/default/FilterChips.d.ts +28 -0
  16. package/dist/default/FilterChips.d.ts.map +1 -0
  17. package/dist/default/FilterChips.js +204 -0
  18. package/dist/default/FilterChips.js.map +1 -0
  19. package/dist/default/LanguageSelect.d.ts +9 -0
  20. package/dist/default/LanguageSelect.d.ts.map +1 -0
  21. package/dist/default/LanguageSelect.js +72 -0
  22. package/dist/default/LanguageSelect.js.map +1 -0
  23. package/dist/default/PageSizeSelect.d.ts +29 -0
  24. package/dist/default/PageSizeSelect.d.ts.map +1 -0
  25. package/dist/default/PageSizeSelect.js +25 -0
  26. package/dist/default/PageSizeSelect.js.map +1 -0
  27. package/dist/default/RangeFilterRow.d.ts +12 -0
  28. package/dist/default/RangeFilterRow.d.ts.map +1 -0
  29. package/dist/default/RangeFilterRow.js +75 -0
  30. package/dist/default/RangeFilterRow.js.map +1 -0
  31. package/dist/default/RankingDisclosurePane.d.ts +5 -0
  32. package/dist/default/RankingDisclosurePane.d.ts.map +1 -1
  33. package/dist/default/RankingDisclosurePane.js +15 -15
  34. package/dist/default/RankingDisclosurePane.js.map +1 -1
  35. package/dist/default/SearchBox.d.ts +13 -0
  36. package/dist/default/SearchBox.d.ts.map +1 -0
  37. package/dist/default/SearchBox.js +67 -0
  38. package/dist/default/SearchBox.js.map +1 -0
  39. package/dist/default/SearchPage.d.ts +94 -16
  40. package/dist/default/SearchPage.d.ts.map +1 -1
  41. package/dist/default/SearchPage.js +191 -8
  42. package/dist/default/SearchPage.js.map +1 -1
  43. package/dist/default/SearchResultCard.d.ts +19 -18
  44. package/dist/default/SearchResultCard.d.ts.map +1 -1
  45. package/dist/default/SearchResultCard.js +178 -5
  46. package/dist/default/SearchResultCard.js.map +1 -1
  47. package/dist/default/SearchResultsPane.d.ts +61 -3
  48. package/dist/default/SearchResultsPane.d.ts.map +1 -1
  49. package/dist/default/SearchResultsPane.js +51 -21
  50. package/dist/default/SearchResultsPane.js.map +1 -1
  51. package/dist/default/SortSelect.d.ts +10 -2
  52. package/dist/default/SortSelect.d.ts.map +1 -1
  53. package/dist/default/SortSelect.js +27 -24
  54. package/dist/default/SortSelect.js.map +1 -1
  55. package/dist/default/UrlIssueNotice.d.ts.map +1 -1
  56. package/dist/default/UrlIssueNotice.js +19 -1
  57. package/dist/default/UrlIssueNotice.js.map +1 -1
  58. package/dist/default/ViewSwitch.d.ts +66 -0
  59. package/dist/default/ViewSwitch.d.ts.map +1 -0
  60. package/dist/default/ViewSwitch.js +49 -0
  61. package/dist/default/ViewSwitch.js.map +1 -0
  62. package/dist/default/index.d.ts +38 -15
  63. package/dist/default/index.d.ts.map +1 -1
  64. package/dist/default/index.js +29 -12
  65. package/dist/default/index.js.map +1 -1
  66. package/dist/default/sortLabels.d.ts +5 -0
  67. package/dist/default/sortLabels.d.ts.map +1 -0
  68. package/dist/default/sortLabels.js +32 -0
  69. package/dist/default/sortLabels.js.map +1 -0
  70. package/dist/headless/FacetPanel.d.ts +17 -0
  71. package/dist/headless/FacetPanel.d.ts.map +1 -1
  72. package/dist/headless/FacetPanel.js +23 -2
  73. package/dist/headless/FacetPanel.js.map +1 -1
  74. package/dist/headless/useAppliedCount.d.ts +8 -0
  75. package/dist/headless/useAppliedCount.d.ts.map +1 -0
  76. package/dist/headless/useAppliedCount.js +30 -0
  77. package/dist/headless/useAppliedCount.js.map +1 -0
  78. package/dist/headless/useScorerNames.d.ts +4 -0
  79. package/dist/headless/useScorerNames.d.ts.map +1 -0
  80. package/dist/headless/useScorerNames.js +34 -0
  81. package/dist/headless/useScorerNames.js.map +1 -0
  82. package/dist/headless/useSearchBox.d.ts +44 -0
  83. package/dist/headless/useSearchBox.d.ts.map +1 -0
  84. package/dist/headless/useSearchBox.js +116 -0
  85. package/dist/headless/useSearchBox.js.map +1 -0
  86. package/dist/i18n/es.d.ts.map +1 -1
  87. package/dist/i18n/es.js +38 -4
  88. package/dist/i18n/es.js.map +1 -1
  89. package/dist/i18n/keys.d.ts +55 -0
  90. package/dist/i18n/keys.d.ts.map +1 -1
  91. package/dist/i18n/keys.js +101 -4
  92. package/dist/i18n/keys.js.map +1 -1
  93. package/dist/i18n/ru.d.ts.map +1 -1
  94. package/dist/i18n/ru.js +42 -4
  95. package/dist/i18n/ru.js.map +1 -1
  96. package/dist/index.d.ts +7 -2
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +5 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/model/queries.d.ts +26 -2
  101. package/dist/model/queries.d.ts.map +1 -1
  102. package/dist/model/queries.js +38 -1
  103. package/dist/model/queries.js.map +1 -1
  104. package/dist/state/limits.d.ts +44 -0
  105. package/dist/state/limits.d.ts.map +1 -0
  106. package/dist/state/limits.js +44 -0
  107. package/dist/state/limits.js.map +1 -0
  108. package/dist/state/ranges.d.ts +52 -0
  109. package/dist/state/ranges.d.ts.map +1 -0
  110. package/dist/state/ranges.js +108 -0
  111. package/dist/state/ranges.js.map +1 -0
  112. package/llms.txt +16 -4
  113. package/manifest.json +268 -22
  114. package/nav-manifest.json +1 -1
  115. package/package.json +15 -10
  116. package/src/analytics/generated/events.json +1 -1
  117. package/src/default/DegradationNotice.tsx +34 -12
  118. package/src/default/FacetGroupControl.tsx +312 -0
  119. package/src/default/FacetPanelPane.tsx +320 -87
  120. package/src/default/FilterChips.tsx +415 -0
  121. package/src/default/LanguageSelect.tsx +93 -0
  122. package/src/default/PageSizeSelect.tsx +80 -0
  123. package/src/default/RangeFilterRow.tsx +148 -0
  124. package/src/default/RankingDisclosurePane.tsx +67 -35
  125. package/src/default/SearchBox.tsx +130 -0
  126. package/src/default/SearchPage.tsx +454 -44
  127. package/src/default/SearchResultCard.tsx +231 -24
  128. package/src/default/SearchResultsPane.tsx +158 -71
  129. package/src/default/SortSelect.tsx +50 -37
  130. package/src/default/UrlIssueNotice.tsx +21 -3
  131. package/src/default/ViewSwitch.tsx +147 -0
  132. package/src/default/index.ts +55 -15
  133. package/src/default/sortLabels.ts +34 -0
  134. package/src/headless/FacetPanel.tsx +30 -2
  135. package/src/headless/useAppliedCount.ts +41 -0
  136. package/src/headless/useScorerNames.ts +36 -0
  137. package/src/headless/useSearchBox.ts +189 -0
  138. package/src/i18n/es.ts +46 -4
  139. package/src/i18n/keys.ts +114 -4
  140. package/src/i18n/ru.ts +50 -4
  141. package/src/index.ts +22 -2
  142. package/src/model/queries.ts +51 -1
  143. package/src/state/limits.ts +50 -0
  144. package/src/state/ranges.ts +144 -0
  145. package/dist/default/ErrorAlert.d.ts +0 -9
  146. package/dist/default/ErrorAlert.d.ts.map +0 -1
  147. package/dist/default/ErrorAlert.js +0 -27
  148. package/dist/default/ErrorAlert.js.map +0 -1
  149. package/dist/default/theme.d.ts +0 -24
  150. package/dist/default/theme.d.ts.map +0 -1
  151. package/dist/default/theme.js +0 -39
  152. package/dist/default/theme.js.map +0 -1
  153. package/src/default/ErrorAlert.tsx +0 -46
  154. package/src/default/theme.tsx +0 -66
@@ -1,32 +1,126 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Alert, Button, Checkbox, Empty, Flex, Spin, Tag, Typography } from "antd";
3
- import { matchList, toFlowError, useDescribeFlowError, useT } from "@stapel/core";
2
+ import { Alert, Button, Divider, Flex, InputNumber, Typography, } from "antd";
3
+ import { SlotPlaceholder, isDevBuild, useT } from "@stapel/core";
4
+ import { EmptyState, ErrorAlert, LoadList, SkinTheme, } from "@stapel/tokens-antd/skin";
5
+ import { spacing } from "@stapel/tokens";
6
+ import { featureName } from "@stapel/attributes-react";
4
7
  import { FacetPanel } from "../headless/FacetPanel.js";
8
+ import { useSearchState } from "../headless/SearchStateProvider.js";
9
+ import { FacetGroupControl } from "./FacetGroupControl.js";
10
+ import { buildRangeGroups } from "../state/ranges.js";
5
11
  import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
6
- import { ErrorAlert } from "./ErrorAlert.js";
7
- import { SearchSkinTheme } from "./theme.js";
8
- function OptionRow(props) {
12
+ import { LanguageSelect } from "./LanguageSelect.js";
13
+ import { RangeFilterRow } from "./RangeFilterRow.js";
14
+ /** The category constraint: the host's control, or the door out of it. */
15
+ function CategoryFilter(props) {
9
16
  const t = useT();
10
- const { option, group } = props;
11
- return (_jsxs(Flex, { justify: "space-between", align: "center", gap: 8, children: [_jsx(Checkbox, { checked: option.selected, "data-testid": `facet-option-${group.slug}-${option.value}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onChange: () => {
12
- props.onToggle(group.slug, option.value);
13
- }, children: option.label }), option.count === null ? (_jsx(Tag, { "data-testid": `facet-count-${group.slug}-${option.value}`, children: t(SEARCH_I18N_KEYS.facetsNotCounted) })) : (_jsx(Typography.Text, { type: "secondary", "data-testid": `facet-count-${group.slug}-${option.value}`, children: option.count }))] }));
17
+ const { state, setCategory } = useSearchState();
18
+ const value = state.category;
19
+ if (props.render !== undefined) {
20
+ return (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": "search-category", children: [_jsx(Typography.Text, { strong: true, children: t(SEARCH_I18N_KEYS.categoryTitle) }), props.render({
21
+ value,
22
+ onChange: (path) => {
23
+ setCategory(path);
24
+ },
25
+ })] }));
26
+ }
27
+ if (value === undefined) {
28
+ return _jsx(SlotPlaceholder, { name: "renderCategoryFilter", "data-testid": "search-category-slot" });
29
+ }
30
+ return (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": "search-category", children: [_jsx(Typography.Text, { strong: true, children: t(SEARCH_I18N_KEYS.categoryTitle) }), _jsx(Typography.Text, { type: "secondary", children: t(SEARCH_I18N_KEYS.categoryCurrent, { path: value }) }), _jsx(Button, { style: { alignSelf: "flex-start" }, "data-testid": "search-category-clear", "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
31
+ setCategory(null);
32
+ }, children: t(SEARCH_I18N_KEYS.categoryClear) })] }));
33
+ }
34
+ /**
35
+ * The location constraint.
36
+ *
37
+ * SETTING a centre needs a geocoder, which is the deployment's and
38
+ * `geo-react`'s. ADJUSTING one that already exists does not: the radius is a
39
+ * number in the URL, and a link shared with `lat/lon/radius_km` is a link this
40
+ * panel can widen, tighten and clear without knowing what a map is. That is the
41
+ * difference between a slot and a hole.
42
+ */
43
+ function GeoFilter(props) {
44
+ const t = useT();
45
+ const { state, setGeo } = useSearchState();
46
+ const geo = state.geo;
47
+ const slot = props.render !== undefined
48
+ ? props.render({
49
+ value: geo,
50
+ onChange: (next) => {
51
+ setGeo(next);
52
+ },
53
+ })
54
+ : geo === undefined
55
+ ? _jsx(SlotPlaceholder, { name: "renderGeoFilter", "data-testid": "search-geo-slot" })
56
+ : null;
57
+ if (geo === undefined) {
58
+ // An unfilled slot is a NAMED hole in development and nothing at all in a
59
+ // production build — so the heading has to follow the placeholder rather
60
+ // than outlive it. It did not, and the live desktop panel printed
61
+ // "Location" over empty space with no location control under it
62
+ // (class NC-ORPHANFIELD): a label is a promise that a control follows.
63
+ if (props.render === undefined && !isDevBuild())
64
+ return null;
65
+ return slot === null ? null : (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": "search-geo", children: [_jsx(Typography.Text, { strong: true, children: t(SEARCH_I18N_KEYS.geoTitle) }), slot] }));
66
+ }
67
+ return (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-testid": "search-geo", children: [_jsx(Typography.Text, { strong: true, children: t(SEARCH_I18N_KEYS.geoTitle) }), slot, _jsx(Typography.Text, { type: "secondary", "data-testid": "search-geo-summary", children: geo.kind === "bbox"
68
+ ? t(SEARCH_I18N_KEYS.geoBox)
69
+ : t(SEARCH_I18N_KEYS.geoCenter, {
70
+ lat: geo.lat.toFixed(3),
71
+ lon: geo.lon.toFixed(3),
72
+ }) }), geo.kind === "center" && (_jsxs(Flex, { gap: spacing[2], align: "center", wrap: true, children: [_jsx(Typography.Text, { type: "secondary", "aria-hidden": "true", children: t(SEARCH_I18N_KEYS.geoRadiusLabel) }), _jsx(InputNumber, { min: 1, value: geo.radiusKm ?? null, "aria-label": t(SEARCH_I18N_KEYS.geoRadiusLabel), "data-testid": "search-geo-radius", onChange: (value) => {
73
+ setGeo({
74
+ kind: "center",
75
+ lat: geo.lat,
76
+ lon: geo.lon,
77
+ ...(typeof value === "number" ? { radiusKm: value } : {}),
78
+ });
79
+ } })] })), _jsx(Button, { style: { alignSelf: "flex-start" }, "data-testid": "search-geo-clear", "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
80
+ setGeo(null);
81
+ }, children: t(SEARCH_I18N_KEYS.geoClear) })] }));
82
+ }
83
+ /**
84
+ * The slugs the server skipped, named the way the panel names everything else.
85
+ *
86
+ * `facet_meta.skipped` is a list of index slugs (`power_w`); the sentence that
87
+ * reports them was printing exactly that, so a shopper read "These filters
88
+ * were not counted for this search: power_w". The category schema is already
89
+ * in this component for the option labels — it names these too. A slug the
90
+ * schema does not know stays as it is, because a made-up name would be worse
91
+ * than an honest identifier.
92
+ */
93
+ function skippedNames(slugs, features, t) {
94
+ return slugs
95
+ .map((slug) => {
96
+ const feature = features?.find((candidate) => candidate.slug === slug);
97
+ if (feature === undefined)
98
+ return slug;
99
+ const name = t(featureName(feature));
100
+ return name.length > 0 ? name : slug;
101
+ })
102
+ .join(", ");
14
103
  }
15
104
  export function FacetPanelPane(props) {
16
105
  const t = useT();
17
- const describe = useDescribeFlowError();
18
- return (_jsx(SearchSkinTheme, { ...(props.mode !== undefined ? { mode: props.mode } : {}), children: _jsx(FacetPanel, { ...(props.categoryFeatures !== undefined
106
+ const { state } = useSearchState();
107
+ const ranges = buildRangeGroups({
108
+ state,
109
+ ...(props.categoryFeatures !== undefined
110
+ ? { categoryFeatures: props.categoryFeatures }
111
+ : {}),
112
+ t,
113
+ });
114
+ return (_jsx(SkinTheme, { ...(props.mode !== undefined ? { mode: props.mode } : {}), children: _jsx(FacetPanel, { ...(props.categoryFeatures !== undefined
19
115
  ? { categoryFeatures: props.categoryFeatures }
20
- : {}), ...(props.locale !== undefined ? { locale: props.locale } : {}), ...(props.enabled !== undefined ? { enabled: props.enabled } : {}), children: (bag) => (_jsxs(Flex, { vertical: true, gap: 12, "data-testid": "search-facets", children: [_jsxs(Flex, { justify: "space-between", align: "center", gap: 8, children: [_jsx(Typography.Title, { level: 5, style: { margin: 0 }, children: t(SEARCH_I18N_KEYS.facetsTitle) }), bag.activeFilters > 0 && (_jsx(Button, { size: "small", onClick: bag.clearAll, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", "data-testid": "facets-clear-all", children: t(SEARCH_I18N_KEYS.facetsClearAll, { count: bag.activeFilters }) }))] }), bag.approximate && (_jsx(Alert, { type: "info", showIcon: true, "data-testid": "facets-approximate", message: t(SEARCH_I18N_KEYS.facetsApproximate) })), bag.skipped.length > 0 && (_jsx(Alert, { type: "warning", showIcon: true, "data-testid": "facets-skipped", message: t(SEARCH_I18N_KEYS.facetsSkipped, {
21
- slugs: bag.skipped.join(", "),
22
- }) })), matchList(bag.state, {
23
- loading: () => (_jsx(Flex, { justify: "center", style: { padding: 16 }, children: _jsx(Spin, { "data-testid": "facets-loading" }) })),
24
- failed: (error) => (_jsx(ErrorAlert, { testId: "facets-failed", error: {
25
- ...describe(toFlowError(error)),
26
- message: t(SEARCH_I18N_KEYS.facetsLoadFailed),
27
- } })),
28
- empty: () => (_jsx(Empty, { "data-testid": "facets-empty", description: t(SEARCH_I18N_KEYS.facetsEmpty) })),
29
- ready: (groups) => (_jsxs(Flex, { vertical: true, gap: 16, children: [groups.map((group) => (_jsxs(Flex, { vertical: true, gap: 4, "data-testid": `facet-group-${group.slug}`, "data-counted": group.counted ? "true" : "false", children: [_jsx(Typography.Text, { strong: true, children: group.label }), group.options.map((option) => (_jsx(OptionRow, { group: group, option: option, onToggle: bag.toggle }, option.value)))] }, group.slug))), _jsx(Typography.Text, { type: "secondary", style: { fontSize: 12 }, children: t(SEARCH_I18N_KEYS.facetsDrillDownHint) })] })),
30
- })] })) }) }));
116
+ : {}), ...(props.locale !== undefined ? { locale: props.locale } : {}), ...(props.enabled !== undefined ? { enabled: props.enabled } : {}), children: (bag) => (_jsxs(Flex, { vertical: true, gap: spacing[3], "data-testid": "search-facets", children: [_jsxs(Flex, { justify: "space-between", align: "center", gap: spacing[2], children: [props.heading === null ? (_jsx("span", {})) : (_jsx(Typography.Title, { level: 5, style: { margin: 0 }, children: props.heading ?? t(SEARCH_I18N_KEYS.facetsTitle) })), bag.activeFilters > 0 && (_jsx(Button, { onClick: bag.clearAll, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", "data-testid": "facets-clear-all", children: t(SEARCH_I18N_KEYS.facetsClearAll, { count: bag.activeFilters }) }))] }), _jsx(CategoryFilter, { ...(props.renderCategoryFilter !== undefined
117
+ ? { render: props.renderCategoryFilter }
118
+ : {}) }), _jsx(LanguageSelect, { ...(props.languages !== undefined ? { languages: props.languages } : {}) }), _jsx(GeoFilter, { ...(props.renderGeoFilter !== undefined
119
+ ? { render: props.renderGeoFilter }
120
+ : {}) }), bag.approximate && (_jsx(Alert, { type: "info", showIcon: true, "data-testid": "facets-approximate", title: t(SEARCH_I18N_KEYS.facetsApproximate) })), bag.skipped.length > 0 && (_jsx(Alert, { type: "warning", showIcon: true, "data-testid": "facets-skipped", title: t(SEARCH_I18N_KEYS.facetsSkipped, {
121
+ slugs: skippedNames(bag.skipped, props.categoryFeatures, t),
122
+ }) })), ranges.length > 0 && (_jsx(Flex, { vertical: true, gap: spacing[3], "data-testid": "search-ranges", children: ranges.map((group) => (_jsx(RangeFilterRow, { group: group, onApply: bag.setRange }, group.slug))) })), ranges.length > 0 && _jsx(Divider, { style: { margin: 0 } }), _jsx(LoadList, { state: bag.state, testId: "facets", skeletonRows: 4, empty: _jsx(EmptyState, { compact: true, title: t(SEARCH_I18N_KEYS.facetsEmpty), testId: "facets-empty" }), failed: (error) => (_jsx(ErrorAlert, { testId: "facets-failed", thrown: error, message: t(SEARCH_I18N_KEYS.facetsLoadFailed) })), children: (groups) => (_jsxs(Flex, { vertical: true, gap: spacing[4], children: [groups
123
+ .filter((group) => group.options.length > 0)
124
+ .map((group) => (_jsx(FacetGroupControl, { group: group, onToggle: bag.toggle }, group.slug))), _jsx(Typography.Text, { type: "secondary", children: t(SEARCH_I18N_KEYS.facetsDrillDownHint) })] })) })] })) }) }));
31
125
  }
32
126
  //# sourceMappingURL=FacetPanelPane.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FacetPanelPane.js","sourceRoot":"","sources":["../../src/default/FacetPanelPane.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FacetPanelPane.js","sourceRoot":"","sources":["../../src/default/FacetPanelPane.tsx"],"names":[],"mappings":";AAoCA,OAAO,EACL,KAAK,EACL,MAAM,EACN,OAAO,EACP,IAAI,EACJ,WAAW,EACX,UAAU,GACX,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA0CrD,0EAA0E;AAC1E,SAAS,cAAc,CAAC,KAEvB;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC;IAE7B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CACL,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAc,iBAAiB,aAC3D,KAAC,UAAU,CAAC,IAAI,IAAC,MAAM,kBAAE,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,GAAmB,EAC5E,KAAK,CAAC,MAAM,CAAC;oBACZ,KAAK;oBACL,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;wBACjB,WAAW,CAAC,IAAI,CAAC,CAAC;oBACpB,CAAC;iBACF,CAAC,IACG,CACR,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,KAAC,eAAe,IAAC,IAAI,EAAC,sBAAsB,iBAAa,sBAAsB,GAAG,CAAC;IAC5F,CAAC;IAED,OAAO,CACL,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAc,iBAAiB,aAC3D,KAAC,UAAU,CAAC,IAAI,IAAC,MAAM,kBAAE,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,GAAmB,EAC7E,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,YAC9B,CAAC,CAAC,gBAAgB,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,GACrC,EAClB,KAAC,MAAM,IACL,KAAK,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,iBACtB,uBAAuB,oBACpB,MAAM,2BACC,qCAAqC,EAC3D,OAAO,EAAE,GAAG,EAAE;oBACZ,WAAW,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC,YAEA,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,GAC3B,IACJ,CACR,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,KAElB;IACC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC3C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAEtB,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,SAAS;QACxB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;YACX,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACjB,MAAM,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;SACF,CAAC;QACJ,CAAC,CAAC,GAAG,KAAK,SAAS;YACjB,CAAC,CAAC,KAAC,eAAe,IAAC,IAAI,EAAC,iBAAiB,iBAAa,iBAAiB,GAAG;YAC1E,CAAC,CAAC,IAAI,CAAC;IAEb,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,0EAA0E;QAC1E,yEAAyE;QACzE,kEAAkE;QAClE,gEAAgE;QAChE,uEAAuE;QACvE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,UAAU,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7D,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC5B,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAc,YAAY,aACtD,KAAC,UAAU,CAAC,IAAI,IAAC,MAAM,kBAAE,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAmB,EACvE,IAAI,IACA,CACR,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAc,YAAY,aACtD,KAAC,UAAU,CAAC,IAAI,IAAC,MAAM,kBAAE,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAmB,EACvE,IAAI,EACL,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,iBAAa,oBAAoB,YAC/D,GAAG,CAAC,IAAI,KAAK,MAAM;oBAClB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC;oBAC5B,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,EAAE;wBAC5B,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;wBACvB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;qBACxB,CAAC,GACU,EACjB,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CACxB,MAAC,IAAI,IAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAC,QAAQ,EAAC,IAAI,mBACxC,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,iBAAa,MAAM,YACjD,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,GACnB,EAClB,KAAC,WAAW,IACV,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI,gBACf,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,iBAClC,mBAAmB,EAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,MAAM,CAAC;gCACL,IAAI,EAAE,QAAQ;gCACd,GAAG,EAAE,GAAG,CAAC,GAAG;gCACZ,GAAG,EAAE,GAAG,CAAC,GAAG;gCACZ,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BAC1D,CAAC,CAAC;wBACL,CAAC,GACD,IACG,CACR,EACD,KAAC,MAAM,IACL,KAAK,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,iBACtB,kBAAkB,oBACf,MAAM,2BACC,qCAAqC,EAC3D,OAAO,EAAE,GAAG,EAAE;oBACZ,MAAM,CAAC,IAAI,CAAC,CAAC;gBACf,CAAC,YAEA,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GACtB,IACJ,CACR,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,YAAY,CACnB,KAAwB,EACxB,QAA2C,EAC3C,CAA0B;IAE1B,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,OAAO,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACvE,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,gBAAgB,CAAC;QAC9B,KAAK;QACL,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,SAAS,OAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YACnE,KAAC,UAAU,OACL,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC,KACH,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC5D,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YAElE,CAAC,GAAG,EAAE,EAAE,CAAC,CACR,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAc,eAAe,aACzD,MAAC,IAAI,IAAC,OAAO,EAAC,eAAe,EAAC,KAAK,EAAC,QAAQ,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,aACzD,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CACxB,gBAAQ,CACT,CAAC,CAAC,CAAC,CACF,KAAC,UAAU,CAAC,KAAK,IAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,YAC7C,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,GAChC,CACpB,EACA,GAAG,CAAC,aAAa,GAAG,CAAC,IAAI,CACxB,KAAC,MAAM,IACL,OAAO,EAAE,GAAG,CAAC,QAAQ,oBACN,MAAM,2BACC,qCAAqC,iBAC/C,kBAAkB,YAE7B,CAAC,CAAC,gBAAgB,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,GAC1D,CACV,IACI,EAEP,KAAC,cAAc,OACT,CAAC,KAAK,CAAC,oBAAoB,KAAK,SAAS;4BAC3C,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,oBAAoB,EAAE;4BACxC,CAAC,CAAC,EAAE,CAAC,GACP,EACF,KAAC,cAAc,OACT,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GACzE,EACF,KAAC,SAAS,OACJ,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS;4BACtC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,eAAe,EAAE;4BACnC,CAAC,CAAC,EAAE,CAAC,GACP,EAMD,GAAG,CAAC,WAAW,IAAI,CAClB,KAAC,KAAK,IACJ,IAAI,EAAC,MAAM,EACX,QAAQ,uBACI,oBAAoB,EAChC,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,GAC5C,CACH,EACA,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CACzB,KAAC,KAAK,IACJ,IAAI,EAAC,SAAS,EACd,QAAQ,uBACI,gBAAgB,EAC5B,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,aAAa,EAAE;4BACvC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC;yBAC5D,CAAC,GACF,CACH,EAEA,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CACpB,KAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAc,eAAe,YACxD,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACrB,KAAC,cAAc,IAEb,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,GAAG,CAAC,QAAQ,IAFhB,KAAK,CAAC,IAAI,CAGf,CACH,CAAC,GACG,CACR,EAEA,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,KAAC,OAAO,IAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAI,EAEvD,KAAC,QAAQ,IACP,KAAK,EAAE,GAAG,CAAC,KAAK,EAChB,MAAM,EAAC,QAAQ,EACf,YAAY,EAAE,CAAC,EACf,KAAK,EAAE,KAAC,UAAU,IAAC,OAAO,QAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAC,cAAc,GAAG,EAC3F,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CACjB,KAAC,UAAU,IACT,MAAM,EAAC,eAAe,EACtB,MAAM,EAAE,KAAK,EACb,OAAO,EAAE,CAAC,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,GAC7C,CACH,YAEA,CAAC,MAAM,EAAE,EAAE,CAAC,CACX,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,aAa3B,MAAM;qCACJ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;qCAC3C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACd,KAAC,iBAAiB,IAEhB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,GAAG,CAAC,MAAM,IAFf,KAAK,CAAC,IAAI,CAGf,CACH,CAAC,EACJ,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,YAC9B,CAAC,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,GACxB,IACb,CACR,GACQ,IACN,CACR,GACU,GACH,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { ReactElement, ReactNode } from "react";
2
+ import type { FeatureDef } from "@stapel/attributes-react";
3
+ import type { GeoFilterSlotProps } from "./FacetPanelPane.js";
4
+ /** The class the scroller carries, for {@link chipRowCss}. */
5
+ export declare const CHIP_ROW_CLASS = "stapel-filter-chips";
6
+ /** The `href` the hoisted chip-row stylesheet is deduplicated by. */
7
+ export declare const CHIP_ROW_STYLE_HREF = "stapel-search-filter-chips";
8
+ /**
9
+ * The two rules an inline style cannot express: Firefox's `scrollbar-width`
10
+ * and WebKit's `::-webkit-scrollbar`. Static (no theme values), so one hoisted
11
+ * copy serves the document.
12
+ */
13
+ export declare function chipRowCss(): string;
14
+ export interface FilterChipsProps {
15
+ /** The category's feature schema — the source of option labels, of which
16
+ * slugs get a range chip, and of how each group is drawn. */
17
+ readonly categoryFeatures?: readonly FeatureDef[];
18
+ readonly locale?: string;
19
+ /** The location control (`geo-react`), same slot the panel takes. Without
20
+ * it the location chip appears only when the URL already carries a point,
21
+ * so a shared link can still be widened. */
22
+ readonly renderGeoFilter?: (slot: GeoFilterSlotProps) => ReactNode;
23
+ /** Open the whole panel — the leading chip's action. The page owns that
24
+ * sheet, because the page is the surface it covers. */
25
+ readonly onOpenAll: () => void;
26
+ }
27
+ export declare function FilterChips(props: FilterChipsProps): ReactElement;
28
+ //# sourceMappingURL=FilterChips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../src/default/FilterChips.tsx"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAiB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAS3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,8DAA8D;AAC9D,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAqBD,MAAM,WAAW,gBAAgB;IAC/B;iEAC6D;IAC7D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;gDAE4C;IAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,SAAS,CAAC;IACnE;2DACuD;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;CAChC;AAiBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA+OjE"}
@@ -0,0 +1,204 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * `<FilterChips>` — the phone's filter row: one horizontally scrolling line of
4
+ * chips, each of which opens its OWN picker.
5
+ *
6
+ * ## What it replaces, and why the replacement is not cosmetic
7
+ *
8
+ * The phone filter path was a single full-width "Filters (3)" button that
9
+ * opened the whole panel. Everything about a search — the category, the price,
10
+ * the brand, where — was behind one tap onto a sheet you then had to scroll,
11
+ * and NOTHING about what was already applied was visible on the results page
12
+ * itself except a number in brackets. The chips row states the filters ON the
13
+ * page: the ones you have set read as set, the ones you have not are one tap
14
+ * from their own small picker, and the whole panel is still there behind the
15
+ * leading chip for the person who wants all of it at once.
16
+ *
17
+ * ## The row scrolls; the PAGE does not
18
+ *
19
+ * A row of chips wider than a 390px phone is the point — it is how the row
20
+ * holds eight filters. What must not happen is the page's own body growing a
21
+ * horizontal scrollbar, which is what a `flex-wrap: nowrap` row without an
22
+ * `overflow-x` owner does: the chips push the document wider, every other
23
+ * element on the page slides, and the visitor is left rubber-banding the whole
24
+ * screen sideways to read a price. So the row owns its overflow
25
+ * (`overflow-x: auto`), contains its overscroll so a flick past the last chip
26
+ * does not start scrolling the page behind it, and hides the scrollbar itself
27
+ * (a 15px grey trough under a 32px chip is chrome nobody asked for) — through
28
+ * a hoisted stylesheet, because `::-webkit-scrollbar` and `scrollbar-width`
29
+ * cannot be written as inline style.
30
+ *
31
+ * Hiding a scrollbar is only safe because nothing here is reachable ONLY by
32
+ * dragging it: every chip is a real `<button>`, so Tab walks the row and the
33
+ * browser scrolls the focused chip into view on its own.
34
+ *
35
+ * ## Every picker is a `SkinDialog`
36
+ *
37
+ * Which means every picker is a BOTTOM SHEET on a phone and a modal above it
38
+ * (owner ruling 2026-08-24, enforced by `stapel/no-bare-dialog`). The chips
39
+ * row is a phone surface, so in practice it is always the sheet — but the
40
+ * component does not decide that, the substrate does, and a tablet rendering
41
+ * the row gets the tablet answer without this file knowing.
42
+ *
43
+ * ## The library is not inventing a classified's filters
44
+ *
45
+ * A chip exists for each facet group the SERVER returned, each numeric range
46
+ * the CATEGORY SCHEMA declares, and the location — plus the leading
47
+ * "all filters" chip. Nothing here knows what a "brand" or a "mileage" is;
48
+ * a deployment with three facets gets three chips and a deployment with none
49
+ * gets the leading chip alone.
50
+ */
51
+ import { useState } from "react";
52
+ import { Button, Flex, Typography } from "antd";
53
+ import { SkinDialog, useDialogSurface } from "@stapel/tokens-antd/skin";
54
+ import { SlotPlaceholder, useT, useTPlural } from "@stapel/core";
55
+ import { radii, spacing } from "@stapel/tokens";
56
+ import { useFacetPanel } from "../headless/FacetPanel.js";
57
+ import { useAppliedCount } from "../headless/useAppliedCount.js";
58
+ import { useSearchState } from "../headless/SearchStateProvider.js";
59
+ import { buildRangeGroups } from "../state/ranges.js";
60
+ import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
61
+ import { FacetGroupControl } from "./FacetGroupControl.js";
62
+ import { RangeFilterRow } from "./RangeFilterRow.js";
63
+ /** The class the scroller carries, for {@link chipRowCss}. */
64
+ export const CHIP_ROW_CLASS = "stapel-filter-chips";
65
+ /** The `href` the hoisted chip-row stylesheet is deduplicated by. */
66
+ export const CHIP_ROW_STYLE_HREF = "stapel-search-filter-chips";
67
+ /**
68
+ * The two rules an inline style cannot express: Firefox's `scrollbar-width`
69
+ * and WebKit's `::-webkit-scrollbar`. Static (no theme values), so one hoisted
70
+ * copy serves the document.
71
+ */
72
+ export function chipRowCss() {
73
+ return [
74
+ `.${CHIP_ROW_CLASS}{scrollbar-width:none;-ms-overflow-style:none}`,
75
+ `.${CHIP_ROW_CLASS}::-webkit-scrollbar{display:none}`,
76
+ ].join("");
77
+ }
78
+ /** The scroller: one line, its own overflow, nobody else's. */
79
+ const ROW = {
80
+ display: "flex",
81
+ alignItems: "center",
82
+ gap: spacing[2],
83
+ flexWrap: "nowrap",
84
+ overflowX: "auto",
85
+ // A flick past the last chip must not hand the gesture to the page.
86
+ overscrollBehaviorInline: "contain",
87
+ // Room for the focus ring of the first and last chip, which a flush edge
88
+ // clips into invisibility.
89
+ paddingBlock: spacing[1],
90
+ };
91
+ const CHIP = { flex: "0 0 auto", borderRadius: radii.full };
92
+ /**
93
+ * The label a chip carries: the group's name alone when nothing is chosen,
94
+ * and the CHOICE when something is — "Brand" becomes "Bosch", "Brand, +2".
95
+ * A chip that reads "Brand" while filtering to Bosch is a lie the person can
96
+ * only catch by opening it.
97
+ */
98
+ function chipLabel(group, t) {
99
+ const chosen = group.options.filter((option) => option.selected);
100
+ const first = chosen[0];
101
+ if (first === undefined)
102
+ return group.label;
103
+ return chosen.length === 1
104
+ ? first.label
105
+ : `${first.label}${t(SEARCH_I18N_KEYS.filtersChipMore, { count: chosen.length - 1 })}`;
106
+ }
107
+ export function FilterChips(props) {
108
+ const t = useT();
109
+ const tPlural = useTPlural();
110
+ const { state, setGeo } = useSearchState();
111
+ const bag = useFacetPanel({
112
+ ...(props.categoryFeatures !== undefined
113
+ ? { categoryFeatures: props.categoryFeatures }
114
+ : {}),
115
+ ...(props.locale !== undefined ? { locale: props.locale } : {}),
116
+ });
117
+ const applied = useAppliedCount();
118
+ const surface = useDialogSurface();
119
+ const [open, setOpen] = useState(null);
120
+ const ranges = buildRangeGroups({
121
+ state,
122
+ ...(props.categoryFeatures !== undefined
123
+ ? { categoryFeatures: props.categoryFeatures }
124
+ : {}),
125
+ t,
126
+ });
127
+ const groups = bag.state.status === "ready"
128
+ ? bag.state.data.filter((group) => group.options.length > 0)
129
+ : [];
130
+ // The same sentence the panel's own commit button says, for the same reason:
131
+ // the results are BEHIND this sheet, so the button that closes it is the
132
+ // only place a person learns what their choice did.
133
+ const applyLabel = applied.count === null || applied.kind === "unknown"
134
+ ? t(SEARCH_I18N_KEYS.filtersApply)
135
+ : tPlural(applied.kind === "at_least"
136
+ ? SEARCH_I18N_KEYS.filtersShowCountAtLeast
137
+ : SEARCH_I18N_KEYS.filtersShowCount, { count: applied.count });
138
+ const close = () => {
139
+ setOpen(null);
140
+ };
141
+ const sheetFor = (id, title, body) => (_jsx(SkinDialog, { open: open === id, onClose: close, title: title, dismissLabel: t(SEARCH_I18N_KEYS.filtersDismiss), "data-testid": `filter-chip-sheet-${id}`, footer: _jsx(Button, { block: true, type: "primary", "data-testid": `filter-chip-apply-${id}`, "data-analytics": "none", "data-analytics-reason": "the filter is already applied; this closes the sheet", onClick: close, children: applyLabel }), children: body }));
142
+ const geo = state.geo;
143
+ const showGeoChip = props.renderGeoFilter !== undefined || geo !== undefined;
144
+ const geoLabel = geo === undefined
145
+ ? t(SEARCH_I18N_KEYS.geoTitle)
146
+ : geo.kind === "bbox"
147
+ ? t(SEARCH_I18N_KEYS.geoBox)
148
+ : t(SEARCH_I18N_KEYS.geoCenter, {
149
+ lat: geo.lat.toFixed(3),
150
+ lon: geo.lon.toFixed(3),
151
+ });
152
+ return (_jsxs(_Fragment, { children: [_jsx("style", { href: CHIP_ROW_STYLE_HREF, precedence: "default", children: chipRowCss() }), _jsxs("div", { className: CHIP_ROW_CLASS, style: ROW, role: "group", "aria-label": t(SEARCH_I18N_KEYS.filtersChipsLabel), "data-testid": "search-filter-chips", "data-surface": surface, children: [_jsx(Button, { shape: "circle", "aria-label": t(SEARCH_I18N_KEYS.filtersAll), icon: _jsx(SlidersGlyph, {}), style: CHIP, "data-testid": "search-filters-open", "data-active": bag.activeFilters > 0 ? "true" : "false", "data-analytics": "none", "data-analytics-reason": "opening the filter sheet is a read, not a flow step", onClick: props.onOpenAll, children: bag.activeFilters > 0 && _jsx(ActiveDot, {}) }), showGeoChip && (_jsx(Button, { style: CHIP, shape: "round", type: geo !== undefined ? "primary" : "default", "data-testid": "search-chip-geo", "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
153
+ setOpen("geo");
154
+ }, children: geoLabel })), ranges.map((group) => (_jsx(Button, { style: CHIP, shape: "round", type: group.active ? "primary" : "default", "data-testid": `search-chip-range-${group.slug}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
155
+ setOpen(`range:${group.slug}`);
156
+ }, children: group.label }, group.slug))), groups.map((group) => (_jsx(Button, { style: CHIP, shape: "round", type: group.selected.length > 0 ? "primary" : "default", "data-testid": `search-chip-${group.slug}`, "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
157
+ setOpen(`facet:${group.slug}`);
158
+ }, children: chipLabel(group, t) }, group.slug)))] }), open?.startsWith("facet:") === true &&
159
+ (() => {
160
+ const slug = open.slice("facet:".length);
161
+ const group = groups.find((candidate) => candidate.slug === slug);
162
+ return group === undefined
163
+ ? null
164
+ : sheetFor(open, group.label, _jsx(FacetGroupControl, { group: group, onToggle: bag.toggle, heading: false,
165
+ // A sheet devoted to ONE group has the room for all of it;
166
+ // "Show all" inside it would be a fold inside a fold.
167
+ visibleOptions: null }));
168
+ })(), open?.startsWith("range:") === true &&
169
+ (() => {
170
+ const slug = open.slice("range:".length);
171
+ const group = ranges.find((candidate) => candidate.slug === slug);
172
+ return group === undefined
173
+ ? null
174
+ : sheetFor(open, group.label, _jsx(RangeFilterRow, { group: group, onApply: bag.setRange }));
175
+ })(), open === "geo" &&
176
+ sheetFor("geo", t(SEARCH_I18N_KEYS.geoTitle), _jsxs(Flex, { vertical: true, gap: spacing[3], children: [props.renderGeoFilter?.({
177
+ value: geo,
178
+ onChange: (next) => {
179
+ setGeo(next);
180
+ },
181
+ }) ?? _jsx(SlotPlaceholder, { name: "renderGeoFilter", "data-testid": "search-chip-geo-slot" }), geo !== undefined && (_jsxs(_Fragment, { children: [_jsx(Typography.Text, { type: "secondary", "data-testid": "search-chip-geo-summary", children: geoLabel }), _jsx(Button, { style: { alignSelf: "flex-start" }, "data-testid": "search-chip-geo-clear", "data-analytics": "none", "data-analytics-reason": "a filter is a read, not a flow step", onClick: () => {
182
+ setGeo(null);
183
+ }, children: t(SEARCH_I18N_KEYS.geoClear) })] }))] }))] }));
184
+ }
185
+ /** The mark on the "all filters" chip: something is applied. Not a count —
186
+ * the counts are on the chips beside it, and a number inside a 32px circle is
187
+ * a number nobody reads. */
188
+ function ActiveDot() {
189
+ return (_jsx("span", { "aria-hidden": "true", "data-testid": "search-filters-dot", style: {
190
+ position: "absolute",
191
+ insetInlineEnd: spacing[1],
192
+ insetBlockStart: spacing[1],
193
+ width: spacing[2],
194
+ height: spacing[2],
195
+ borderRadius: radii.full,
196
+ background: "currentColor",
197
+ } }));
198
+ }
199
+ /** Sliders — the one glyph a filter control is universally drawn with. Inline
200
+ * SVG, like every other glyph in the fleet's skins: no icon-font dependency. */
201
+ function SlidersGlyph() {
202
+ return (_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", role: "img", "aria-hidden": "true", children: [_jsx("path", { d: "M4 7h10M18 7h2M4 17h4M12 17h8" }), _jsx("circle", { cx: "16", cy: "7", r: "2.2" }), _jsx("circle", { cx: "10", cy: "17", r: "2.2" })] }));
203
+ }
204
+ //# sourceMappingURL=FilterChips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterChips.js","sourceRoot":"","sources":["../../src/default/FilterChips.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ReactElement } from "react";
2
+ /** Width of the language select — a language name plus room for a long one. */
3
+ export declare const LANGUAGE_SELECT_MIN_WIDTH = 176;
4
+ export interface LanguageSelectProps {
5
+ /** BCP-47 tags the deployment indexes (e.g. `["ru", "en"]`). */
6
+ readonly languages?: readonly string[];
7
+ }
8
+ export declare function LanguageSelect(props: LanguageSelectProps): ReactElement | null;
9
+ //# sourceMappingURL=LanguageSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LanguageSelect.d.ts","sourceRoot":"","sources":["../../src/default/LanguageSelect.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAO1C,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAgBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAwC9E"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The query's LANGUAGE — `lang`, and the reason it is a filter rather than a
4
+ * display preference.
5
+ *
6
+ * `lang` does two things server-side (`query.py`): it picks the ANALYZER (so a
7
+ * Russian word stems as Russian rather than as an unknown token) and it
8
+ * NARROWS the corpus to documents indexed in that language. Getting it wrong therefore changes
9
+ * which results exist, not how they are written — which is why the control
10
+ * lives in the filter panel beside the facets and not in a settings menu.
11
+ *
12
+ * ── Which languages a deployment has is not this pair's fact ───────────────
13
+ *
14
+ * The index's languages come from what has been indexed; there is no endpoint
15
+ * that lists them. So the host names them (`languages`), and the labels come
16
+ * from `Intl.DisplayNames` in the reader's own locale — each language named
17
+ * the way THIS reader would name it — rather than from a translation table this
18
+ * pair would have to carry for every language a deployment might index.
19
+ *
20
+ * With no `languages` prop the control renders only when the URL already
21
+ * carries one, and then only to REMOVE it: a constraint that arrived in a
22
+ * shared link must always have a control that widens it again.
23
+ */
24
+ import { useMemo } from "react";
25
+ import { Flex, Select, Typography } from "antd";
26
+ import { useOptionalI18n, useT } from "@stapel/core";
27
+ import { spacing } from "@stapel/tokens";
28
+ import { useSearchState } from "../headless/SearchStateProvider.js";
29
+ import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
30
+ /** Width of the language select — a language name plus room for a long one. */
31
+ export const LANGUAGE_SELECT_MIN_WIDTH = 176;
32
+ /**
33
+ * A language tag as a person reads it, in THEIR locale. Falls back to the tag
34
+ * itself where the runtime has no name for it — a tag is at least honest,
35
+ * where a blank option is unclickable.
36
+ */
37
+ function languageName(tag, locale) {
38
+ try {
39
+ const names = new Intl.DisplayNames([locale], { type: "language" });
40
+ return names.of(tag) ?? tag;
41
+ }
42
+ catch {
43
+ return tag;
44
+ }
45
+ }
46
+ export function LanguageSelect(props) {
47
+ const t = useT();
48
+ // The reader's locale names the languages. Optional on purpose: every other
49
+ // control in this skin renders outside a provider (English floor) rather
50
+ // than throwing, and a language list is not the place to break that.
51
+ const locale = useOptionalI18n()?.locale ?? "en";
52
+ const { state, setLanguage } = useSearchState();
53
+ const active = state.lang;
54
+ const languages = props.languages;
55
+ const options = useMemo(() => {
56
+ const tags = [...(languages ?? [])];
57
+ if (active !== undefined && !tags.includes(active))
58
+ tags.push(active);
59
+ return [
60
+ { value: "", label: t(SEARCH_I18N_KEYS.languageAny) },
61
+ ...tags.map((tag) => ({ value: tag, label: languageName(tag, locale) })),
62
+ ];
63
+ }, [languages, active, locale, t]);
64
+ // Nothing offered and nothing applied: a select with one option ("any") is a
65
+ // control that cannot do anything, which §83 calls a dead control.
66
+ if ((languages ?? []).length === 0 && active === undefined)
67
+ return null;
68
+ return (_jsxs(Flex, { gap: spacing[2], align: "center", wrap: true, children: [_jsx(Typography.Text, { type: "secondary", "aria-hidden": "true", children: t(SEARCH_I18N_KEYS.languageLabel) }), _jsx(Select, { "data-testid": "search-language", "aria-label": t(SEARCH_I18N_KEYS.languageLabel), style: { minWidth: LANGUAGE_SELECT_MIN_WIDTH }, value: active ?? "", onChange: (next) => {
69
+ setLanguage(next === "" ? null : next);
70
+ }, options: options })] }));
71
+ }
72
+ //# sourceMappingURL=LanguageSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LanguageSelect.js","sourceRoot":"","sources":["../../src/default/LanguageSelect.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * How many results a page carries — `limit`, the fifth of the nine state
3
+ * setters that had no control.
4
+ *
5
+ * The offered sizes are the pair's, not the schema's: `docs/schema.json`
6
+ * declares `limit` as a bare integer, and the backend clamps it to
7
+ * `1..MAX_PAGE_SIZE` (100) with `DEFAULT_PAGE_SIZE` 24 when it is absent. So
8
+ * the select offers a short ladder around that default and never sends
9
+ * something the server would have to clamp — a person who lands on a link
10
+ * carrying `limit=37` keeps it (it is offered as its own option) rather than
11
+ * being silently moved to 24, which would change what a shared link shows.
12
+ *
13
+ * A page size is a PREFERENCE, not a step through the results: `setLimit`
14
+ * replaces the history entry rather than pushing one, so Back still undoes the
15
+ * last filter and not the last time somebody widened the page.
16
+ */
17
+ import type { ReactElement } from "react";
18
+ /** The shipped ladder, around stapel-search's own `DEFAULT_PAGE_SIZE` (24). */
19
+ export declare const SEARCH_PAGE_SIZES: readonly number[];
20
+ /** Width of the size select — the widest option plus its caption. */
21
+ export declare const PAGE_SIZE_SELECT_MIN_WIDTH = 148;
22
+ export interface PageSizeSelectProps {
23
+ /** Override the offered ladder (a deployment with its own `MAX_PAGE_SIZE`). */
24
+ readonly sizes?: readonly number[];
25
+ /** What the server uses when the URL names none. Default 24. */
26
+ readonly defaultSize?: number;
27
+ }
28
+ export declare function PageSizeSelect(props: PageSizeSelectProps): ReactElement;
29
+ //# sourceMappingURL=PageSizeSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageSizeSelect.d.ts","sourceRoot":"","sources":["../../src/default/PageSizeSelect.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAO1C,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAqB,CAAC;AAErE,qEAAqE;AACrE,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gEAAgE;IAChE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CA2CvE"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Flex, Select, Typography } from "antd";
3
+ import { useT } from "@stapel/core";
4
+ import { fontSize, spacing } from "@stapel/tokens";
5
+ import { useSearchState } from "../headless/SearchStateProvider.js";
6
+ import { SEARCH_I18N_KEYS } from "../i18n/keys.js";
7
+ /** The shipped ladder, around stapel-search's own `DEFAULT_PAGE_SIZE` (24). */
8
+ export const SEARCH_PAGE_SIZES = [12, 24, 48, 96];
9
+ /** Width of the size select — the widest option plus its caption. */
10
+ export const PAGE_SIZE_SELECT_MIN_WIDTH = 148;
11
+ export function PageSizeSelect(props) {
12
+ const t = useT();
13
+ const { state, setLimit } = useSearchState();
14
+ const ladder = props.sizes ?? SEARCH_PAGE_SIZES;
15
+ const active = state.limit ?? props.defaultSize ?? 24;
16
+ const offLadder = !ladder.includes(active);
17
+ const values = offLadder ? [...ladder, active].sort((a, b) => a - b) : ladder;
18
+ return (_jsxs(Flex, { vertical: true, gap: spacing[1], "data-off-ladder": offLadder ? "true" : "false", children: [_jsxs(Flex, { gap: spacing[2], align: "center", children: [_jsx(Typography.Text, { type: "secondary", "aria-hidden": "true", children: t(SEARCH_I18N_KEYS.limitLabel) }), _jsx(Select, { "data-testid": "search-limit", "aria-label": t(SEARCH_I18N_KEYS.limitLabel), style: { minWidth: PAGE_SIZE_SELECT_MIN_WIDTH }, value: active, onChange: (next) => {
19
+ setLimit(next);
20
+ }, options: values.map((size) => ({
21
+ value: size,
22
+ label: t(SEARCH_I18N_KEYS.limitOption, { count: size }),
23
+ })) })] }), offLadder && (_jsx(Typography.Text, { type: "secondary", style: { fontSize: fontSize.xs.fontSize }, "data-testid": "search-limit-from-link", children: t(SEARCH_I18N_KEYS.limitFromLink) }))] }));
24
+ }
25
+ //# sourceMappingURL=PageSizeSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageSizeSelect.js","sourceRoot":"","sources":["../../src/default/PageSizeSelect.tsx"],"names":[],"mappings":";AAiBA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAsB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAErE,qEAAqE;AACrE,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAS9C,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,IAAI,iBAAiB,CAAC;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;IACtD,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE9E,OAAO,CACL,MAAC,IAAI,IAAC,QAAQ,QAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAmB,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,aAC3E,MAAC,IAAI,IAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAC,QAAQ,aACnC,KAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAC,WAAW,iBAAa,MAAM,YACjD,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,GACf,EAClB,KAAC,MAAM,mBACO,cAAc,gBACd,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAC1C,KAAK,EAAE,EAAE,QAAQ,EAAE,0BAA0B,EAAE,EAC/C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;4BACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;wBACjB,CAAC,EACD,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;4BAC7B,KAAK,EAAE,IAAI;4BACX,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;yBACxD,CAAC,CAAC,GACH,IACG,EAKN,SAAS,IAAI,CACZ,KAAC,UAAU,CAAC,IAAI,IACd,IAAI,EAAC,WAAW,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAC7B,wBAAwB,YAEnC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,GAClB,CACnB,IACI,CACR,CAAC;AACJ,CAAC"}