@stapel/search-react 0.20.0 → 0.22.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 (98) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +65 -2
  3. package/dist/api/generated/schema.d.ts +96 -4
  4. package/dist/api/generated/schema.d.ts.map +1 -1
  5. package/dist/api/types.d.ts +68 -6
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/api/types.js.map +1 -1
  8. package/dist/default/FacetGroupControl.d.ts +34 -4
  9. package/dist/default/FacetGroupControl.d.ts.map +1 -1
  10. package/dist/default/FacetGroupControl.js +112 -7
  11. package/dist/default/FacetGroupControl.js.map +1 -1
  12. package/dist/default/FacetPanelPane.d.ts.map +1 -1
  13. package/dist/default/FacetPanelPane.js +27 -1
  14. package/dist/default/FacetPanelPane.js.map +1 -1
  15. package/dist/default/LocationSummaryLine.d.ts +3 -0
  16. package/dist/default/LocationSummaryLine.d.ts.map +1 -1
  17. package/dist/default/LocationSummaryLine.js +55 -8
  18. package/dist/default/LocationSummaryLine.js.map +1 -1
  19. package/dist/default/PartitionChips.d.ts +23 -0
  20. package/dist/default/PartitionChips.d.ts.map +1 -0
  21. package/dist/default/PartitionChips.js +94 -0
  22. package/dist/default/PartitionChips.js.map +1 -0
  23. package/dist/default/PopularValues.d.ts +58 -0
  24. package/dist/default/PopularValues.d.ts.map +1 -0
  25. package/dist/default/PopularValues.js +46 -0
  26. package/dist/default/PopularValues.js.map +1 -0
  27. package/dist/default/SearchPage.d.ts.map +1 -1
  28. package/dist/default/SearchPage.js +5 -0
  29. package/dist/default/SearchPage.js.map +1 -1
  30. package/dist/default/index.d.ts +5 -1
  31. package/dist/default/index.d.ts.map +1 -1
  32. package/dist/default/index.js +6 -1
  33. package/dist/default/index.js.map +1 -1
  34. package/dist/headless/FacetPanel.d.ts +29 -1
  35. package/dist/headless/FacetPanel.d.ts.map +1 -1
  36. package/dist/headless/FacetPanel.js +14 -0
  37. package/dist/headless/FacetPanel.js.map +1 -1
  38. package/dist/headless/SearchStateProvider.d.ts +15 -0
  39. package/dist/headless/SearchStateProvider.d.ts.map +1 -1
  40. package/dist/headless/SearchStateProvider.js +38 -3
  41. package/dist/headless/SearchStateProvider.js.map +1 -1
  42. package/dist/headless/useFacetLabels.js +7 -7
  43. package/dist/headless/useFacetLabels.js.map +1 -1
  44. package/dist/i18n/es.d.ts.map +1 -1
  45. package/dist/i18n/es.js +12 -0
  46. package/dist/i18n/es.js.map +1 -1
  47. package/dist/i18n/keys.d.ts +72 -0
  48. package/dist/i18n/keys.d.ts.map +1 -1
  49. package/dist/i18n/keys.js +86 -0
  50. package/dist/i18n/keys.js.map +1 -1
  51. package/dist/i18n/ru.d.ts.map +1 -1
  52. package/dist/i18n/ru.js +14 -0
  53. package/dist/i18n/ru.js.map +1 -1
  54. package/dist/index.d.ts +4 -3
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +2 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/state/degradations.d.ts +9 -0
  59. package/dist/state/degradations.d.ts.map +1 -1
  60. package/dist/state/degradations.js +13 -0
  61. package/dist/state/degradations.js.map +1 -1
  62. package/dist/state/facets.d.ts +29 -6
  63. package/dist/state/facets.d.ts.map +1 -1
  64. package/dist/state/facets.js +120 -16
  65. package/dist/state/facets.js.map +1 -1
  66. package/dist/state/translit.d.ts +58 -0
  67. package/dist/state/translit.d.ts.map +1 -0
  68. package/dist/state/translit.js +115 -0
  69. package/dist/state/translit.js.map +1 -0
  70. package/dist/state/urlState.d.ts +26 -1
  71. package/dist/state/urlState.d.ts.map +1 -1
  72. package/dist/state/urlState.js +43 -17
  73. package/dist/state/urlState.js.map +1 -1
  74. package/llms.txt +4 -2
  75. package/manifest.json +49 -2
  76. package/nav-manifest.json +1 -1
  77. package/package.json +8 -8
  78. package/src/analytics/generated/events.json +1 -1
  79. package/src/api/generated/schema.ts +96 -4
  80. package/src/api/types.ts +77 -5
  81. package/src/default/FacetGroupControl.tsx +213 -8
  82. package/src/default/FacetPanelPane.tsx +36 -1
  83. package/src/default/LocationSummaryLine.tsx +114 -53
  84. package/src/default/PartitionChips.tsx +161 -0
  85. package/src/default/PopularValues.tsx +151 -0
  86. package/src/default/SearchPage.tsx +5 -0
  87. package/src/default/index.ts +15 -0
  88. package/src/headless/FacetPanel.tsx +49 -1
  89. package/src/headless/SearchStateProvider.tsx +59 -3
  90. package/src/headless/useFacetLabels.ts +7 -7
  91. package/src/i18n/es.ts +16 -0
  92. package/src/i18n/keys.ts +91 -0
  93. package/src/i18n/ru.ts +20 -0
  94. package/src/index.ts +12 -0
  95. package/src/state/degradations.ts +14 -0
  96. package/src/state/facets.ts +154 -28
  97. package/src/state/translit.ts +113 -0
  98. package/src/state/urlState.ts +72 -13
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC;AAsBxB,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EACL,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,GACb,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAO3B,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAMzD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEtF,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAMxF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAKlE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAM/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,gFAAgF;AAChF,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,uBAAuB,EACvB,YAAY,GACb,MAAM,gBAAgB,CAAC;AA0BxB,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,GACb,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EACtB,8BAA8B,EAC9B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAMzD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEtF,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAMxF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAKlE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAM/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,gFAAgF;AAChF,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
@@ -14,6 +14,15 @@
14
14
  * with the literal beside it, not silence.
15
15
  */
16
16
  import type { SearchDegradation, SearchDegradationKind } from "../api/types.js";
17
+ /**
18
+ * "This answer's facet plan could not be drawn from evidence."
19
+ *
20
+ * Named rather than inlined because the FACET PANEL reads the raw literal
21
+ * off the envelope: whether "this search offers no filters" is a true
22
+ * sentence is a question about THIS answer, not about the banner, and the
23
+ * panel must not have to parse the whole list to ask it.
24
+ */
25
+ export declare const FACET_PLAN_EVIDENCE = "facet_plan_evidence";
17
26
  /** i18n key per kind (`search.degraded.*`). */
18
27
  export declare function degradationMessageKey(kind: SearchDegradationKind): string;
19
28
  /** Parse and de-duplicate the envelope's `degraded[]`. */
@@ -1 +1 @@
1
- {"version":3,"file":"degradations.d.ts","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAYhF,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAEzE;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACtC,SAAS,iBAAiB,EAAE,CAwB9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAET;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/D;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,YAAY,EAAE,OAAO,GAAG,SAAS,EACjC,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,eAAe,CAIjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAKT;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAa9D,sDAAsD;AACtD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,qBAAqB,GAC1B,yBAAyB,CAE3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,SAAS,iBAAiB,EAAE,CAI9B"}
1
+ {"version":3,"file":"degradations.d.ts","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAIhF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAczD,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAEzE;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACtC,SAAS,iBAAiB,EAAE,CAwB9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAET;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/D;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,YAAY,EAAE,OAAO,GAAG,SAAS,EACjC,UAAU,EAAE,OAAO,EACnB,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,eAAe,CAIjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,OAAO,CAKT;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAa9D,sDAAsD;AACtD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,qBAAqB,GAC1B,yBAAyB,CAE3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,SAAS,iBAAiB,EAAE,GACzC,SAAS,iBAAiB,EAAE,CAI9B"}
@@ -1,10 +1,23 @@
1
1
  const SCORER_PREFIX = "scorer:";
2
+ /**
3
+ * "This answer's facet plan could not be drawn from evidence."
4
+ *
5
+ * Named rather than inlined because the FACET PANEL reads the raw literal
6
+ * off the envelope: whether "this search offers no filters" is a true
7
+ * sentence is a question about THIS answer, not about the banner, and the
8
+ * panel must not have to parse the whole list to ask it.
9
+ */
10
+ export const FACET_PLAN_EVIDENCE = "facet_plan_evidence";
2
11
  const KNOWN = {
3
12
  typo_tolerance: "typo_tolerance",
4
13
  phrase_synonyms: "phrase_synonyms",
5
14
  exact_total: "exact_total",
6
15
  exact_facet_counts: "exact_facet_counts",
7
16
  category_rollup: "category_rollup",
17
+ // Reader-facing by omission from OPERATOR_KINDS below, and deliberately:
18
+ // it changes what an empty filter panel MEANS, which is the one thing on
19
+ // the page a buyer can act on (widen, or filter by category instead).
20
+ [FACET_PLAN_EVIDENCE]: "facet_plan_evidence",
8
21
  };
9
22
  /** i18n key per kind (`search.degraded.*`). */
10
23
  export function degradationMessageKey(kind) {
@@ -1 +1 @@
1
- {"version":3,"file":"degradations.js","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"degradations.js","sourceRoot":"","sources":["../../src/state/degradations.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,15 @@
1
1
  import type { FeatureDef } from "@stapel/attributes-react";
2
- import type { FacetMeta, SearchQueryState } from "../api/types.js";
2
+ import type { FacetLabelsMap, FacetMeta, SearchQueryState } from "../api/types.js";
3
+ /**
4
+ * Where a caption came from — the group's heading and every option carry it,
5
+ * because "did anybody actually name this?" is a question two surfaces have
6
+ * to answer and neither can answer by looking at the string.
7
+ *
8
+ * `"none"` is the honest bottom: the raw slug for a heading, the raw index
9
+ * term for an option. It is not a label, it is what is printed when there is
10
+ * none, and it is the one value a storefront's own test asserts against.
11
+ */
12
+ export type FacetLabelSource = "server" | "schema" | "host" | "none";
3
13
  /**
4
14
  * Value types whose values are a BOUNDED OPTION SET — the only kind of
5
15
  * feature a person can be offered as a filter.
@@ -42,13 +52,21 @@ export interface FacetOption {
42
52
  readonly count: number | null;
43
53
  /** Resolved through the category schema; the raw value when there is none. */
44
54
  readonly label: string;
55
+ /** Which of the three sources named it — `"none"` means {@link label} IS
56
+ * the raw index term. The host seam reads this rather than comparing the
57
+ * two strings. */
58
+ readonly labelSource: FacetLabelSource;
45
59
  readonly selected: boolean;
46
60
  }
47
61
  /** One facet slug, with its options. */
48
62
  export interface FacetGroup {
49
63
  readonly slug: string;
50
- /** The feature's display name (translated when it is a key), else the slug. */
64
+ /** The group's heading: the answer's own `label`, else the feature's
65
+ * display name, else — with a dev warning — the raw slug. */
51
66
  readonly label: string;
67
+ /** Which source named the heading. `"none"` is the slug standing in for a
68
+ * name nobody has; a surface marks it so a storefront test can fail on it. */
69
+ readonly labelSource: FacetLabelSource;
52
70
  /** The category-schema entry behind the slug, when the host supplied one. */
53
71
  readonly feature: FeatureDef | undefined;
54
72
  /** `false` when the server skipped this slug — counts are `null`. */
@@ -113,15 +131,17 @@ export interface BuildFacetGroupsInput {
113
131
  * `apple` or `chernyy`. The server read that vocabulary against the
114
132
  * snapshot the documents were written with.
115
133
  *
134
+ * Each entry also carries the GROUP's own `label` — the heading, resolved
135
+ * from the feature definition server-side and localized like everything
136
+ * else. It leads for the same two reasons, and it is what a category whose
137
+ * host passed no feature list has instead of a rail full of index slugs.
138
+ *
116
139
  * ABSENT on a server older than 0.4.0 — absent, not empty — which is why
117
140
  * every read of it here is optional-chained and every option falls through
118
141
  * to the schema and then to its raw self. No labels are invented at any
119
142
  * step.
120
143
  */
121
- readonly facetLabels?: Readonly<Record<string, {
122
- readonly translatable: boolean;
123
- readonly values: Readonly<Record<string, string>>;
124
- }>>;
144
+ readonly facetLabels?: FacetLabelsMap;
125
145
  /** Translator for label keys. */
126
146
  readonly t?: (key: string) => string;
127
147
  /** BCP-47 tag, forwarded to `formatFeatureValue` for `date` options. */
@@ -159,6 +179,9 @@ export declare function facetOptionLabel(feature: FeatureDef | undefined, value:
159
179
  * a chip in the row. The APPLIED-filter clause outranks the type rule: a
160
180
  * constraint the URL carries always gets its control back, whatever the schema
161
181
  * now says about it, or a person is left holding a filter they cannot clear.
182
+ *
183
+ * A COUNTED group with zero coverage goes the same way, and for the same
184
+ * reason — see {@link keepsAnAxisOpen}.
162
185
  */
163
186
  export declare function buildFacetGroups(input: BuildFacetGroupsInput): readonly FacetGroup[];
164
187
  //# sourceMappingURL=facets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"facets.d.ts","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facets.d.ts","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,12 @@
8
8
  * they would have if you swapped to them. A panel that greys the siblings
9
9
  * out has silently converted a drill-down facet into a naive one, and the
10
10
  * e2e leg in the spec (§7.2) exists to catch exactly that.
11
- * 2. **Option LABELS have one stated order: ANSWER, then schema, then the
12
- * raw value** — with a host resolver between the last two, applied by
13
- * `useHostFacetLabels` on what this module could not name.
11
+ * 2. **LABELS have one stated order: ANSWER, then schema, then the raw
12
+ * term** — for the group's heading and for every option alike, with a host
13
+ * resolver between the last two for options, applied by
14
+ * `useHostFacetLabels` on what this module could not name. The bottom of
15
+ * that order is not a label and is marked as such: `labelSource: "none"`,
16
+ * a warning in development, and a data attribute on the drawn group.
14
17
  *
15
18
  * The answer leads because it is the only source that always exists and
16
19
  * the only one that has RESOLVED anything: `categoryFeatures` is an
@@ -47,7 +50,29 @@
47
50
  * chipped is therefore decided from the category's own feature defs, by
48
51
  * value TYPE (see {@link FACETABLE_FEATURE_TYPES}), not by what came back.
49
52
  */
50
- import { VOCABULARY_BACKED_TYPES, featureConfig, featureName, featureType, formatFeatureValue, } from "@stapel/attributes-react";
53
+ import { VOCABULARY_BACKED_TYPES, featureConfig, featureType, formatFeatureValue, } from "@stapel/attributes-react";
54
+ /** Slugs already complained about — one warning per slug per page load, not
55
+ * one per render. */
56
+ const warnedSlugs = new Set();
57
+ /**
58
+ * A heading nobody named, said once, in development only.
59
+ *
60
+ * A raw slug in a filter panel is a wiring fault — the category has no
61
+ * feature definition for the slug and the server sent no label — and it is
62
+ * invisible to everyone but the buyer who meets it. The group still renders,
63
+ * because a heading a person cannot read still beats options with no heading
64
+ * at all; `FacetGroup.labelSource` is how a surface marks it up for a test.
65
+ */
66
+ function warnUnnamedGroup(slug) {
67
+ const env = typeof process === "undefined" ? undefined : process.env;
68
+ if (env?.NODE_ENV === "production")
69
+ return;
70
+ if (warnedSlugs.has(slug))
71
+ return;
72
+ warnedSlugs.add(slug);
73
+ console.warn(`[search-react] facet group "${slug}" has no label: the answer sent none ` +
74
+ `and no category feature defines it, so the heading is the raw slug.`);
75
+ }
51
76
  /**
52
77
  * Value types whose values are a BOUNDED OPTION SET — the only kind of
53
78
  * feature a person can be offered as a filter.
@@ -200,8 +225,44 @@ function declaredOptionValues(feature) {
200
225
  * value — never a blank, and never a guess.
201
226
  */
202
227
  function resolveLabel(input, feature, slug, value, labelOptions) {
203
- return (serverLabel(input.facetLabels, slug, value, input.t) ??
204
- facetOptionLabel(feature, value, labelOptions));
228
+ const answer = serverLabel(input.facetLabels, slug, value, input.t);
229
+ if (answer !== undefined)
230
+ return { label: answer, labelSource: "server" };
231
+ const schema = facetOptionLabel(feature, value, labelOptions);
232
+ // `facetOptionLabel` hands back the value unchanged for an option it
233
+ // cannot name, and that identity is the whole test — a formatter that
234
+ // returned the term is a formatter that named nothing.
235
+ return schema === value
236
+ ? { label: value, labelSource: "none" }
237
+ : { label: schema, labelSource: "schema" };
238
+ }
239
+ /**
240
+ * The group's HEADING, in the one order the fleet states: the answer, then
241
+ * the category schema, then the slug under a dev warning.
242
+ *
243
+ * The answer leads because it is the only source that always exists. The
244
+ * schema slot is optional, and at a live classified's cars branch the
245
+ * storefront passed an empty feature list, so every heading in the rail was
246
+ * a raw index slug — the make group was on screen, unlabelled, and the
247
+ * complaint that came back was "I cannot pick a make".
248
+ *
249
+ * The slug is not a fallback anyone may ship: it renders, because a heading
250
+ * beats no heading, and it renders MARKED — `labelSource: "none"`, a warning
251
+ * in development, and a data attribute on the drawn group.
252
+ */
253
+ function resolveGroupLabel(input, feature, slug) {
254
+ const answer = input.facetLabels?.[slug]?.label;
255
+ if (typeof answer === "string" && answer.length > 0) {
256
+ return { label: translate(input.t, answer), labelSource: "server" };
257
+ }
258
+ // `featureName` falls back to the slug itself, so the def has to be asked
259
+ // for a NAME rather than for a name-or-slug: a def with none names nothing.
260
+ const declared = feature?.name;
261
+ if (typeof declared === "string" && declared.length > 0) {
262
+ return { label: translate(input.t, declared), labelSource: "schema" };
263
+ }
264
+ warnUnnamedGroup(slug);
265
+ return { label: slug, labelSource: "none" };
205
266
  }
206
267
  /**
207
268
  * A facet value as a person reads it, through
@@ -262,6 +323,9 @@ export function facetOptionLabel(feature, value, options) {
262
323
  * a chip in the row. The APPLIED-filter clause outranks the type rule: a
263
324
  * constraint the URL carries always gets its control back, whatever the schema
264
325
  * now says about it, or a person is left holding a filter they cannot clear.
326
+ *
327
+ * A COUNTED group with zero coverage goes the same way, and for the same
328
+ * reason — see {@link keepsAnAxisOpen}.
265
329
  */
266
330
  export function buildFacetGroups(input) {
267
331
  const bySlug = new Map();
@@ -347,24 +411,64 @@ export function buildFacetGroups(input) {
347
411
  };
348
412
  return {
349
413
  slug,
350
- label: feature === undefined
351
- ? slug
352
- : translate(input.t, featureName(feature)),
414
+ ...resolveGroupLabel(input, feature, slug),
353
415
  feature,
354
416
  counted,
355
417
  selected,
356
418
  options: values.map((value) => ({
357
419
  value,
358
420
  count: counted ? (counts[value] ?? 0) : null,
359
- // The host's schema first when it actually resolves the value, the
360
- // answer's caption when it does not (or when there is no schema at
361
- // all), the raw value when neither knows. `facetOptionLabel` returns
362
- // the value unchanged for an option it cannot name, which is what
363
- // makes "did it resolve?" answerable without a second lookup.
364
- label: resolveLabel(input, feature, slug, value, labelOptions),
421
+ // The answer's caption first, then the schema's own option table,
422
+ // then the raw value and the source is carried rather than
423
+ // re-derived, so "did it resolve?" needs no second lookup.
424
+ ...resolveLabel(input, feature, slug, value, labelOptions),
365
425
  selected: selected.includes(value),
366
426
  })),
367
427
  };
368
- });
428
+ }).filter(keepsAnAxisOpen);
429
+ }
430
+ /**
431
+ * Is this group an axis a person can actually move along?
432
+ *
433
+ * The coverage floor stops at the queried category's own schema, on the
434
+ * server, on purpose: `FACET_MIN_COVERAGE` governs only the slugs an
435
+ * evidence plan BORROWED from sibling leaves, because "a closed option set
436
+ * answering with its zeros is a shipped decision". That is right about an
437
+ * option and wrong about a GROUP. A size chart showing `XL — 0` beside
438
+ * `M — 12` is telling the truth about a shape the reader wants to see whole;
439
+ * a group whose every option is 0 is not a shape, it is three checkboxes that
440
+ * are each guaranteed to return nothing, and it costs a heading in the rail
441
+ * and a chip on a 390px row to say so.
442
+ *
443
+ * Measured on the deployed phones leaf: `sim_config`, `device_history` and
444
+ * `set` are authored `select` features that no listing in the leaf fills.
445
+ * The server's `fill_zero_options` creates the slug and zero-fills every
446
+ * authored option, so all three arrive counted, complete and dead, and the
447
+ * withholding loop never looks at them because an authored plan has no
448
+ * `evidence`. Nothing on the wire marks them: the client has to sum the
449
+ * buckets itself, which is exactly what {@link facetCoverage} already does
450
+ * for two other surfaces.
451
+ *
452
+ * Three things this must NOT drop, which is why the predicate is this narrow:
453
+ *
454
+ * - an UNCOUNTED group (`counted: false`). Its options carry `count: null`,
455
+ * so it sums to zero for the opposite reason — nobody looked. "We did not
456
+ * count this" and "there are none" are different sentences, and dropping
457
+ * on the first is the regression the `MAX_FACET_FIELDS` branch below
458
+ * exists to prevent (a live cars leaf: 26 facetable features declared, 12
459
+ * counted, and `/query` accepts `f.<slug>` for all 26).
460
+ * - a group the reader has ALREADY filtered on, whatever its counts say —
461
+ * the same clause that outranks the type rule. Withholding that group
462
+ * leaves a constraint applied with no control to undo it.
463
+ * - a group with any non-zero option. A zero option beside a live one is
464
+ * drill-down working as designed: it reports what swapping to that value
465
+ * would get you, and the answer being "nothing" is information.
466
+ */
467
+ function keepsAnAxisOpen(group) {
468
+ if (!group.counted)
469
+ return true;
470
+ if (group.selected.length > 0)
471
+ return true;
472
+ return facetCoverage(group) > 0;
369
473
  }
370
474
  //# sourceMappingURL=facets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"facets.js","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facets.js","sourceRoot":"","sources":["../../src/state/facets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Matching a typed prefix against a dictionary value ACROSS ALPHABETS.
3
+ *
4
+ * A vocabulary of car makes holds `Toyota`, `Land Rover`, `Timberland` — Latin
5
+ * words, in a catalogue read by people typing Cyrillic. "toyota" spelled in
6
+ * Cyrillic and `Toyota` are the same word said in two scripts, and a
7
+ * `String.includes` over the caption answers "no" to every one of them. The
8
+ * autocatalog has 418 makes: without this, the search box in a dictionary
9
+ * facet is a box that works only for the half of the buyers whose keyboard
10
+ * matches the catalogue's.
11
+ *
12
+ * ── Two keys per word, and why the second one exists ──────────────────────
13
+ *
14
+ * The first key is a plain transliteration: Cyrillic → Latin through the table
15
+ * below, lowercased, everything but letters and digits dropped. That alone
16
+ * gets the Cyrillic spelling of "toyota" to `toiota` and `Toyota` to `toyota`
17
+ * — still not equal, and this is the general case rather than a bad table.
18
+ * Vowels are exactly where two scripts disagree: `i` against `y`, `e` against
19
+ * `a` in a borrowed word, `timberlend` against `timberland`. A vowel-perfect
20
+ * table does not exist, because the disagreement is in the borrowing, not in
21
+ * the letters.
22
+ *
23
+ * So the second key is the CONSONANT SKELETON: the first key with its vowels
24
+ * removed. `timberlend` and `timberland` are both `tmbrlnd`; `toiota` and
25
+ * `toyota` are both `tt`. Digits stay — a skeleton is about letters people
26
+ * disagree on, and `5` is not one.
27
+ *
28
+ * A candidate matches when either key of any of its WORDS starts with the
29
+ * corresponding key of the needle: a typed "rover" in either script finds
30
+ * `Land Rover`, and typing into the box narrows as you go, which is the whole
31
+ * point of a prefix rule. The skeleton arm is skipped for a needle that has no
32
+ * consonants at all — an empty skeleton is a prefix of everything, and a box
33
+ * that matches all 418 makes after one vowel is a box that has stopped
34
+ * answering.
35
+ *
36
+ * Table-driven and dependency-free on purpose: this is 40 pairs of characters,
37
+ * and a transliteration library is a page-weight decision made for a lookup
38
+ * table.
39
+ */
40
+ /**
41
+ * One word, transliterated and folded to `[a-z0-9]`.
42
+ *
43
+ * `NFKD` + combining-mark strip first, so `Škoda` and `Skoda` are one word
44
+ * before anything else looks at them.
45
+ */
46
+ export declare function translitKey(text: string): string;
47
+ /** {@link translitKey} without its vowels — the key two spellings of one
48
+ * borrowed name agree on. */
49
+ export declare function consonantKey(text: string): string;
50
+ /**
51
+ * Does `candidate` answer the typed `needle`?
52
+ *
53
+ * Prefix, not substring: a dictionary of makes searched by substring puts
54
+ * `Great Wall` under `all`. Every word of the candidate is a starting point,
55
+ * and both keys are tried — see the module note.
56
+ */
57
+ export declare function translitPrefixMatch(needle: string, candidate: string): boolean;
58
+ //# sourceMappingURL=translit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translit.d.ts","sourceRoot":"","sources":["../../src/state/translit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAuBH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;6BAC6B;AAC7B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjD;AAQD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAU9E"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Matching a typed prefix against a dictionary value ACROSS ALPHABETS.
3
+ *
4
+ * A vocabulary of car makes holds `Toyota`, `Land Rover`, `Timberland` — Latin
5
+ * words, in a catalogue read by people typing Cyrillic. "toyota" spelled in
6
+ * Cyrillic and `Toyota` are the same word said in two scripts, and a
7
+ * `String.includes` over the caption answers "no" to every one of them. The
8
+ * autocatalog has 418 makes: without this, the search box in a dictionary
9
+ * facet is a box that works only for the half of the buyers whose keyboard
10
+ * matches the catalogue's.
11
+ *
12
+ * ── Two keys per word, and why the second one exists ──────────────────────
13
+ *
14
+ * The first key is a plain transliteration: Cyrillic → Latin through the table
15
+ * below, lowercased, everything but letters and digits dropped. That alone
16
+ * gets the Cyrillic spelling of "toyota" to `toiota` and `Toyota` to `toyota`
17
+ * — still not equal, and this is the general case rather than a bad table.
18
+ * Vowels are exactly where two scripts disagree: `i` against `y`, `e` against
19
+ * `a` in a borrowed word, `timberlend` against `timberland`. A vowel-perfect
20
+ * table does not exist, because the disagreement is in the borrowing, not in
21
+ * the letters.
22
+ *
23
+ * So the second key is the CONSONANT SKELETON: the first key with its vowels
24
+ * removed. `timberlend` and `timberland` are both `tmbrlnd`; `toiota` and
25
+ * `toyota` are both `tt`. Digits stay — a skeleton is about letters people
26
+ * disagree on, and `5` is not one.
27
+ *
28
+ * A candidate matches when either key of any of its WORDS starts with the
29
+ * corresponding key of the needle: a typed "rover" in either script finds
30
+ * `Land Rover`, and typing into the box narrows as you go, which is the whole
31
+ * point of a prefix rule. The skeleton arm is skipped for a needle that has no
32
+ * consonants at all — an empty skeleton is a prefix of everything, and a box
33
+ * that matches all 418 makes after one vowel is a box that has stopped
34
+ * answering.
35
+ *
36
+ * Table-driven and dependency-free on purpose: this is 40 pairs of characters,
37
+ * and a transliteration library is a page-weight decision made for a lookup
38
+ * table.
39
+ */
40
+ /**
41
+ * Cyrillic → Latin, chosen for how the two scripts spell the SAME borrowed
42
+ * name rather than for a standard's fidelity: `kha` is `h` (Honda, not
43
+ * Khonda), `tse` is `c`, the two signs are nothing. Any letter absent here is
44
+ * kept as it is, so a Latin caption passes through untouched. Keys are
45
+ * quoted — the fleet's source is English, and a Cyrillic identifier is not.
46
+ */
47
+ const CYRILLIC_TO_LATIN = {
48
+ "а": "a", "б": "b", "в": "v", "г": "g", "д": "d", "е": "e", "ё": "e",
49
+ "ж": "zh", "з": "z", "и": "i", "й": "i", "к": "k", "л": "l", "м": "m",
50
+ "н": "n", "о": "o", "п": "p", "р": "r", "с": "s", "т": "t", "у": "u",
51
+ "ф": "f", "х": "h", "ц": "c", "ч": "ch", "ш": "sh", "щ": "sh", "ъ": "",
52
+ "ы": "y", "ь": "", "э": "e", "ю": "u", "я": "a",
53
+ // Ukrainian/Belarusian letters a shared vocabulary can carry.
54
+ "і": "i", "ї": "i", "є": "e", "ґ": "g", "ў": "u",
55
+ };
56
+ /** Vowels of the transliterated form — `y` included, because it stands for a
57
+ * Cyrillic semi-vowel as often as it stands for a consonant. */
58
+ const VOWELS = new Set(["a", "e", "i", "o", "u", "y"]);
59
+ /**
60
+ * One word, transliterated and folded to `[a-z0-9]`.
61
+ *
62
+ * `NFKD` + combining-mark strip first, so `Škoda` and `Skoda` are one word
63
+ * before anything else looks at them.
64
+ */
65
+ export function translitKey(text) {
66
+ const folded = text
67
+ .normalize("NFKD")
68
+ .replace(/[\u0300-\u036f]/g, "")
69
+ .toLowerCase();
70
+ let out = "";
71
+ for (const char of folded) {
72
+ const mapped = CYRILLIC_TO_LATIN[char];
73
+ if (mapped !== undefined)
74
+ out += mapped;
75
+ else if (/[a-z0-9]/.test(char))
76
+ out += char;
77
+ }
78
+ return out;
79
+ }
80
+ /** {@link translitKey} without its vowels — the key two spellings of one
81
+ * borrowed name agree on. */
82
+ export function consonantKey(text) {
83
+ let out = "";
84
+ for (const char of translitKey(text))
85
+ if (!VOWELS.has(char))
86
+ out += char;
87
+ return out;
88
+ }
89
+ /** The words of a caption, split on everything that is not a letter or a
90
+ * digit — so `Land Rover` is reachable by "rover" in either script. */
91
+ function words(text) {
92
+ return text.split(/[^\p{L}\p{N}]+/u).filter((word) => word.length > 0);
93
+ }
94
+ /**
95
+ * Does `candidate` answer the typed `needle`?
96
+ *
97
+ * Prefix, not substring: a dictionary of makes searched by substring puts
98
+ * `Great Wall` under `all`. Every word of the candidate is a starting point,
99
+ * and both keys are tried — see the module note.
100
+ */
101
+ export function translitPrefixMatch(needle, candidate) {
102
+ const key = translitKey(needle);
103
+ if (key.length === 0)
104
+ return true;
105
+ const skeleton = consonantKey(needle);
106
+ for (const word of [candidate, ...words(candidate)]) {
107
+ const wordKey = translitKey(word);
108
+ if (wordKey.startsWith(key))
109
+ return true;
110
+ if (skeleton.length > 0 && consonantKey(word).startsWith(skeleton))
111
+ return true;
112
+ }
113
+ return false;
114
+ }
115
+ //# sourceMappingURL=translit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translit.js","sourceRoot":"","sources":["../../src/state/translit.ts"],"names":[],"mappings":"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"}
@@ -65,11 +65,36 @@ export type SearchStateIssueCode =
65
65
  /** `bbox` was not four numbers. */
66
66
  | "bbox_malformed"
67
67
  /** `r.<slug>` was not `from..to`. */
68
- | "range_malformed";
68
+ | "range_malformed"
69
+ /**
70
+ * `radius_km` with nothing to measure it FROM — no `lat`/`lon`, no `bbox`.
71
+ *
72
+ * Not malformed: `radius_km=300` is a perfectly good number, and the search
73
+ * that ran is the honest one (a radius with no centre narrows nothing, so
74
+ * the count is the full count). What was wrong was the SILENCE. The URL said
75
+ * 300km, the results were unnarrowed, and the location control went on
76
+ * advertising its own default — measured on a live leaf as "300 in the
77
+ * address bar, 25 on the screen" with no way for a person to tell which one
78
+ * the page had used. Neither number is dropped and neither is rewritten;
79
+ * the disagreement is simply stated.
80
+ */
81
+ | "radius_without_place";
69
82
  /** What {@link parseSearchState} answers: the state, plus what it could not read. */
70
83
  export interface ParsedSearchState {
71
84
  readonly state: SearchQueryState;
72
85
  readonly issues: readonly SearchStateIssue[];
86
+ /**
87
+ * A `radius_km` the URL carries with no place to measure it from.
88
+ *
89
+ * NOT part of the state — a radius with no centre is not a filter and
90
+ * nothing is sent to the server — but it is a number the person typed, and
91
+ * dropping it on the floor is how the control and the address ended up
92
+ * disagreeing: `?radius_km=300`, a button offering "within 25 km", and a
93
+ * press that silently rewrote 300 to 25. Whoever draws the offer reads this
94
+ * so that what the button SAYS, what pressing it DOES, and what the link
95
+ * ASKED FOR are one number.
96
+ */
97
+ readonly orphanRadiusKm?: number;
73
98
  }
74
99
  export interface ParseSearchStateOptions {
75
100
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"urlState.d.ts","sourceRoot":"","sources":["../../src/state/urlState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAGV,gBAAgB,EAChB,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,kEAAkE;AAClE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;CAef,CAAC;AAEX,4DAA4D;AAC5D,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,+DAA+D;AAC/D,eAAO,MAAM,YAAY,OAAO,CAAC;AAEjC;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,oBAAoB;AAC9B,4CAA4C;AAC1C,cAAc;AAChB,mDAAmD;GACjD,gBAAgB;AAClB,mCAAmC;GACjC,gBAAgB;AAClB,qCAAqC;GACnC,iBAAiB,CAAC;AAStB,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAwFD,wEAAwE;AACxE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,uBAAuB,GAC/B,iBAAiB,CAsEnB;AAWD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,gBAAgB,EACvB,IAAI,CAAC,EAAE,eAAe,GACrB,eAAe,CAqDjB;AAED,uDAAuD;AACvD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG9C;AAED,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,CAAC,IAAI,MAAM,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;CACpE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,CAkBlB;AAED;oDACoD;AACpD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,gBAAgB,CAMlB;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,gBAAgB,CAMlB;AAED,yCAAyC;AACzC,wBAAgB,aAAa,CAC3B,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GAAG,IAAI,GACxB,gBAAgB,CAQlB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAOtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAKjE"}
1
+ {"version":3,"file":"urlState.d.ts","sourceRoot":"","sources":["../../src/state/urlState.ts"],"names":[],"mappings":"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"}