@tenphi/tasty 2.0.2 → 2.0.4

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 (321) hide show
  1. package/dist/{ssr/async-storage.js → async-storage-B7_o6FKt.js} +2 -2
  2. package/dist/async-storage-B7_o6FKt.js.map +1 -0
  3. package/dist/{ssr/collector.d.ts → collector-CkZ517g4.d.ts} +3 -3
  4. package/dist/{ssr/collector.js → collector-DXqvGOb1.js} +5 -10
  5. package/dist/collector-DXqvGOb1.js.map +1 -0
  6. package/dist/config-5jzS6k6B.js +10005 -0
  7. package/dist/config-5jzS6k6B.js.map +1 -0
  8. package/dist/config-DknGsfMo.d.ts +857 -0
  9. package/dist/{ssr/context.js → context-CkSg-kDT.js} +11 -3
  10. package/dist/context-CkSg-kDT.js.map +1 -0
  11. package/dist/core/index.d.ts +5 -34
  12. package/dist/core/index.js +5 -26
  13. package/dist/core-CtU6-9OC.js +1507 -0
  14. package/dist/core-CtU6-9OC.js.map +1 -0
  15. package/dist/{zero/extractor.js → css-writer-DHkX0JuE.js} +74 -11
  16. package/dist/css-writer-DHkX0JuE.js.map +1 -0
  17. package/dist/{ssr/format-global-rules.js → format-global-rules-Dbc_1tc3.js} +2 -2
  18. package/dist/format-global-rules-Dbc_1tc3.js.map +1 -0
  19. package/dist/format-rules-DH13ewDu.js +143 -0
  20. package/dist/format-rules-DH13ewDu.js.map +1 -0
  21. package/dist/{ssr/hydrate.js → hydrate-C1Gv-DoS.js} +3 -3
  22. package/dist/hydrate-C1Gv-DoS.js.map +1 -0
  23. package/dist/{styles/types.d.ts → index-PzENbpAq.d.ts} +701 -5
  24. package/dist/index-o7zV2yCr.d.ts +1561 -0
  25. package/dist/index.d.ts +5 -51
  26. package/dist/index.js +728 -35
  27. package/dist/index.js.map +1 -0
  28. package/dist/keyframes-b7X3UxDV.js +587 -0
  29. package/dist/keyframes-b7X3UxDV.js.map +1 -0
  30. package/dist/{utils/merge-styles.d.ts → merge-styles-C7KTy7MY.d.ts} +3 -3
  31. package/dist/{utils/merge-styles.js → merge-styles-Tgo3BbL2.js} +3 -4
  32. package/dist/merge-styles-Tgo3BbL2.js.map +1 -0
  33. package/dist/{utils/resolve-recipes.js → resolve-recipes-Ca2-5CxM.js} +4 -6
  34. package/dist/resolve-recipes-Ca2-5CxM.js.map +1 -0
  35. package/dist/ssr/astro-client.js +1 -1
  36. package/dist/ssr/astro.js +4 -4
  37. package/dist/ssr/index.d.ts +44 -4
  38. package/dist/ssr/index.js +4 -4
  39. package/dist/ssr/next.d.ts +1 -1
  40. package/dist/ssr/next.js +6 -6
  41. package/dist/ssr/next.js.map +1 -1
  42. package/dist/static/index.d.ts +91 -5
  43. package/dist/static/index.js +49 -3
  44. package/dist/static/index.js.map +1 -0
  45. package/dist/zero/babel.d.ts +1 -1
  46. package/dist/zero/babel.js +10 -6
  47. package/dist/zero/babel.js.map +1 -1
  48. package/dist/zero/index.d.ts +67 -3
  49. package/dist/zero/index.js +1 -2
  50. package/docs/pipeline.md +204 -50
  51. package/package.json +3 -3
  52. package/dist/_virtual/_rolldown/runtime.js +0 -7
  53. package/dist/chunks/cacheKey.d.ts +0 -1
  54. package/dist/chunks/cacheKey.js +0 -77
  55. package/dist/chunks/cacheKey.js.map +0 -1
  56. package/dist/chunks/definitions.d.ts +0 -37
  57. package/dist/chunks/definitions.js +0 -258
  58. package/dist/chunks/definitions.js.map +0 -1
  59. package/dist/chunks/index.d.ts +0 -1
  60. package/dist/chunks/renderChunk.d.ts +0 -1
  61. package/dist/chunks/renderChunk.js +0 -59
  62. package/dist/chunks/renderChunk.js.map +0 -1
  63. package/dist/compute-styles.d.ts +0 -31
  64. package/dist/compute-styles.js +0 -322
  65. package/dist/compute-styles.js.map +0 -1
  66. package/dist/config.d.ts +0 -407
  67. package/dist/config.js +0 -591
  68. package/dist/config.js.map +0 -1
  69. package/dist/counter-style/index.js +0 -51
  70. package/dist/counter-style/index.js.map +0 -1
  71. package/dist/debug.d.ts +0 -89
  72. package/dist/debug.js +0 -453
  73. package/dist/debug.js.map +0 -1
  74. package/dist/font-face/index.js +0 -63
  75. package/dist/font-face/index.js.map +0 -1
  76. package/dist/hooks/index.d.ts +0 -7
  77. package/dist/hooks/useCounterStyle.d.ts +0 -36
  78. package/dist/hooks/useCounterStyle.js +0 -65
  79. package/dist/hooks/useCounterStyle.js.map +0 -1
  80. package/dist/hooks/useFontFace.d.ts +0 -45
  81. package/dist/hooks/useFontFace.js +0 -66
  82. package/dist/hooks/useFontFace.js.map +0 -1
  83. package/dist/hooks/useGlobalStyles.d.ts +0 -46
  84. package/dist/hooks/useGlobalStyles.js +0 -88
  85. package/dist/hooks/useGlobalStyles.js.map +0 -1
  86. package/dist/hooks/useKeyframes.d.ts +0 -58
  87. package/dist/hooks/useKeyframes.js +0 -55
  88. package/dist/hooks/useKeyframes.js.map +0 -1
  89. package/dist/hooks/useProperty.d.ts +0 -81
  90. package/dist/hooks/useProperty.js +0 -96
  91. package/dist/hooks/useProperty.js.map +0 -1
  92. package/dist/hooks/useRawCSS.d.ts +0 -22
  93. package/dist/hooks/useRawCSS.js +0 -103
  94. package/dist/hooks/useRawCSS.js.map +0 -1
  95. package/dist/hooks/useStyles.d.ts +0 -40
  96. package/dist/hooks/useStyles.js +0 -31
  97. package/dist/hooks/useStyles.js.map +0 -1
  98. package/dist/injector/index.d.ts +0 -182
  99. package/dist/injector/index.js +0 -185
  100. package/dist/injector/index.js.map +0 -1
  101. package/dist/injector/injector.d.ts +0 -198
  102. package/dist/injector/injector.js +0 -651
  103. package/dist/injector/injector.js.map +0 -1
  104. package/dist/injector/sheet-manager.d.ts +0 -132
  105. package/dist/injector/sheet-manager.js +0 -699
  106. package/dist/injector/sheet-manager.js.map +0 -1
  107. package/dist/injector/types.d.ts +0 -235
  108. package/dist/keyframes/index.js +0 -206
  109. package/dist/keyframes/index.js.map +0 -1
  110. package/dist/parser/classify.js +0 -319
  111. package/dist/parser/classify.js.map +0 -1
  112. package/dist/parser/const.js +0 -60
  113. package/dist/parser/const.js.map +0 -1
  114. package/dist/parser/lru.js +0 -109
  115. package/dist/parser/lru.js.map +0 -1
  116. package/dist/parser/parser.d.ts +0 -25
  117. package/dist/parser/parser.js +0 -115
  118. package/dist/parser/parser.js.map +0 -1
  119. package/dist/parser/tokenizer.js +0 -69
  120. package/dist/parser/tokenizer.js.map +0 -1
  121. package/dist/parser/types.d.ts +0 -51
  122. package/dist/parser/types.js +0 -46
  123. package/dist/parser/types.js.map +0 -1
  124. package/dist/pipeline/conditions.d.ts +0 -134
  125. package/dist/pipeline/conditions.js +0 -406
  126. package/dist/pipeline/conditions.js.map +0 -1
  127. package/dist/pipeline/exclusive.js +0 -382
  128. package/dist/pipeline/exclusive.js.map +0 -1
  129. package/dist/pipeline/index.d.ts +0 -55
  130. package/dist/pipeline/index.js +0 -708
  131. package/dist/pipeline/index.js.map +0 -1
  132. package/dist/pipeline/materialize.js +0 -1157
  133. package/dist/pipeline/materialize.js.map +0 -1
  134. package/dist/pipeline/parseStateKey.d.ts +0 -15
  135. package/dist/pipeline/parseStateKey.js +0 -446
  136. package/dist/pipeline/parseStateKey.js.map +0 -1
  137. package/dist/pipeline/simplify.js +0 -690
  138. package/dist/pipeline/simplify.js.map +0 -1
  139. package/dist/pipeline/warnings.js +0 -18
  140. package/dist/pipeline/warnings.js.map +0 -1
  141. package/dist/plugins/index.d.ts +0 -2
  142. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  143. package/dist/plugins/okhsl-plugin.js +0 -97
  144. package/dist/plugins/okhsl-plugin.js.map +0 -1
  145. package/dist/plugins/types.d.ts +0 -87
  146. package/dist/properties/index.js +0 -222
  147. package/dist/properties/index.js.map +0 -1
  148. package/dist/properties/property-type-resolver.d.ts +0 -24
  149. package/dist/properties/property-type-resolver.js +0 -90
  150. package/dist/properties/property-type-resolver.js.map +0 -1
  151. package/dist/rsc-cache.js +0 -79
  152. package/dist/rsc-cache.js.map +0 -1
  153. package/dist/ssr/async-storage.d.ts +0 -17
  154. package/dist/ssr/async-storage.js.map +0 -1
  155. package/dist/ssr/collect-auto-properties.js +0 -58
  156. package/dist/ssr/collect-auto-properties.js.map +0 -1
  157. package/dist/ssr/collector.js.map +0 -1
  158. package/dist/ssr/context.js.map +0 -1
  159. package/dist/ssr/format-global-rules.js.map +0 -1
  160. package/dist/ssr/format-keyframes.js +0 -69
  161. package/dist/ssr/format-keyframes.js.map +0 -1
  162. package/dist/ssr/format-property.js +0 -49
  163. package/dist/ssr/format-property.js.map +0 -1
  164. package/dist/ssr/format-rules.js +0 -73
  165. package/dist/ssr/format-rules.js.map +0 -1
  166. package/dist/ssr/hydrate.d.ts +0 -29
  167. package/dist/ssr/hydrate.js.map +0 -1
  168. package/dist/ssr/ssr-collector-ref.js +0 -29
  169. package/dist/ssr/ssr-collector-ref.js.map +0 -1
  170. package/dist/states/index.d.ts +0 -49
  171. package/dist/states/index.js +0 -170
  172. package/dist/states/index.js.map +0 -1
  173. package/dist/static/tastyStatic.d.ts +0 -46
  174. package/dist/static/tastyStatic.js +0 -30
  175. package/dist/static/tastyStatic.js.map +0 -1
  176. package/dist/static/types.d.ts +0 -49
  177. package/dist/static/types.js +0 -24
  178. package/dist/static/types.js.map +0 -1
  179. package/dist/styles/border.d.ts +0 -25
  180. package/dist/styles/border.js +0 -120
  181. package/dist/styles/border.js.map +0 -1
  182. package/dist/styles/color.d.ts +0 -14
  183. package/dist/styles/color.js +0 -26
  184. package/dist/styles/color.js.map +0 -1
  185. package/dist/styles/const.js +0 -17
  186. package/dist/styles/const.js.map +0 -1
  187. package/dist/styles/createStyle.js +0 -79
  188. package/dist/styles/createStyle.js.map +0 -1
  189. package/dist/styles/dimension.js +0 -109
  190. package/dist/styles/dimension.js.map +0 -1
  191. package/dist/styles/directional.js +0 -133
  192. package/dist/styles/directional.js.map +0 -1
  193. package/dist/styles/display.d.ts +0 -30
  194. package/dist/styles/display.js +0 -73
  195. package/dist/styles/display.js.map +0 -1
  196. package/dist/styles/fade.d.ts +0 -15
  197. package/dist/styles/fade.js +0 -62
  198. package/dist/styles/fade.js.map +0 -1
  199. package/dist/styles/fill.d.ts +0 -42
  200. package/dist/styles/fill.js +0 -51
  201. package/dist/styles/fill.js.map +0 -1
  202. package/dist/styles/flow.d.ts +0 -16
  203. package/dist/styles/flow.js +0 -12
  204. package/dist/styles/flow.js.map +0 -1
  205. package/dist/styles/gap.d.ts +0 -31
  206. package/dist/styles/gap.js +0 -38
  207. package/dist/styles/gap.js.map +0 -1
  208. package/dist/styles/height.d.ts +0 -17
  209. package/dist/styles/height.js +0 -19
  210. package/dist/styles/height.js.map +0 -1
  211. package/dist/styles/index.d.ts +0 -1
  212. package/dist/styles/index.js +0 -8
  213. package/dist/styles/index.js.map +0 -1
  214. package/dist/styles/inset.d.ts +0 -24
  215. package/dist/styles/inset.js +0 -34
  216. package/dist/styles/inset.js.map +0 -1
  217. package/dist/styles/list.d.ts +0 -16
  218. package/dist/styles/list.js +0 -100
  219. package/dist/styles/list.js.map +0 -1
  220. package/dist/styles/margin.d.ts +0 -24
  221. package/dist/styles/margin.js +0 -32
  222. package/dist/styles/margin.js.map +0 -1
  223. package/dist/styles/outline.d.ts +0 -29
  224. package/dist/styles/outline.js +0 -55
  225. package/dist/styles/outline.js.map +0 -1
  226. package/dist/styles/padding.d.ts +0 -24
  227. package/dist/styles/padding.js +0 -32
  228. package/dist/styles/padding.js.map +0 -1
  229. package/dist/styles/placement.d.ts +0 -37
  230. package/dist/styles/placement.js +0 -74
  231. package/dist/styles/placement.js.map +0 -1
  232. package/dist/styles/predefined.d.ts +0 -71
  233. package/dist/styles/predefined.js +0 -237
  234. package/dist/styles/predefined.js.map +0 -1
  235. package/dist/styles/preset.d.ts +0 -52
  236. package/dist/styles/preset.js +0 -127
  237. package/dist/styles/preset.js.map +0 -1
  238. package/dist/styles/radius.d.ts +0 -12
  239. package/dist/styles/radius.js +0 -83
  240. package/dist/styles/radius.js.map +0 -1
  241. package/dist/styles/scrollMargin.d.ts +0 -24
  242. package/dist/styles/scrollMargin.js +0 -32
  243. package/dist/styles/scrollMargin.js.map +0 -1
  244. package/dist/styles/scrollbar.d.ts +0 -25
  245. package/dist/styles/scrollbar.js +0 -51
  246. package/dist/styles/scrollbar.js.map +0 -1
  247. package/dist/styles/shadow.d.ts +0 -14
  248. package/dist/styles/shadow.js +0 -25
  249. package/dist/styles/shadow.js.map +0 -1
  250. package/dist/styles/shared.js +0 -17
  251. package/dist/styles/shared.js.map +0 -1
  252. package/dist/styles/transition.d.ts +0 -14
  253. package/dist/styles/transition.js +0 -159
  254. package/dist/styles/transition.js.map +0 -1
  255. package/dist/styles/width.d.ts +0 -17
  256. package/dist/styles/width.js +0 -19
  257. package/dist/styles/width.js.map +0 -1
  258. package/dist/tasty.d.ts +0 -134
  259. package/dist/tasty.js +0 -248
  260. package/dist/tasty.js.map +0 -1
  261. package/dist/types.d.ts +0 -184
  262. package/dist/utils/cache-wrapper.js +0 -21
  263. package/dist/utils/cache-wrapper.js.map +0 -1
  264. package/dist/utils/case-converter.js +0 -8
  265. package/dist/utils/case-converter.js.map +0 -1
  266. package/dist/utils/color-math.d.ts +0 -46
  267. package/dist/utils/color-math.js +0 -749
  268. package/dist/utils/color-math.js.map +0 -1
  269. package/dist/utils/color-space.d.ts +0 -5
  270. package/dist/utils/color-space.js +0 -228
  271. package/dist/utils/color-space.js.map +0 -1
  272. package/dist/utils/colors.d.ts +0 -5
  273. package/dist/utils/colors.js +0 -10
  274. package/dist/utils/colors.js.map +0 -1
  275. package/dist/utils/css-types.d.ts +0 -7
  276. package/dist/utils/deps-equal.js +0 -15
  277. package/dist/utils/deps-equal.js.map +0 -1
  278. package/dist/utils/dotize.d.ts +0 -26
  279. package/dist/utils/dotize.js +0 -122
  280. package/dist/utils/dotize.js.map +0 -1
  281. package/dist/utils/filter-base-props.d.ts +0 -15
  282. package/dist/utils/filter-base-props.js +0 -45
  283. package/dist/utils/filter-base-props.js.map +0 -1
  284. package/dist/utils/get-display-name.d.ts +0 -7
  285. package/dist/utils/get-display-name.js +0 -10
  286. package/dist/utils/get-display-name.js.map +0 -1
  287. package/dist/utils/has-keys.js +0 -13
  288. package/dist/utils/has-keys.js.map +0 -1
  289. package/dist/utils/hash.js +0 -14
  290. package/dist/utils/hash.js.map +0 -1
  291. package/dist/utils/is-dev-env.js +0 -19
  292. package/dist/utils/is-dev-env.js.map +0 -1
  293. package/dist/utils/is-valid-element-type.js +0 -15
  294. package/dist/utils/is-valid-element-type.js.map +0 -1
  295. package/dist/utils/merge-styles.js.map +0 -1
  296. package/dist/utils/mod-attrs.d.ts +0 -6
  297. package/dist/utils/mod-attrs.js +0 -20
  298. package/dist/utils/mod-attrs.js.map +0 -1
  299. package/dist/utils/process-tokens.d.ts +0 -17
  300. package/dist/utils/process-tokens.js +0 -83
  301. package/dist/utils/process-tokens.js.map +0 -1
  302. package/dist/utils/resolve-recipes.d.ts +0 -17
  303. package/dist/utils/resolve-recipes.js.map +0 -1
  304. package/dist/utils/selector-transform.js +0 -32
  305. package/dist/utils/selector-transform.js.map +0 -1
  306. package/dist/utils/string.js +0 -8
  307. package/dist/utils/string.js.map +0 -1
  308. package/dist/utils/styles.d.ts +0 -99
  309. package/dist/utils/styles.js +0 -220
  310. package/dist/utils/styles.js.map +0 -1
  311. package/dist/utils/typography.d.ts +0 -58
  312. package/dist/utils/typography.js +0 -51
  313. package/dist/utils/typography.js.map +0 -1
  314. package/dist/utils/warnings.d.ts +0 -16
  315. package/dist/utils/warnings.js +0 -16
  316. package/dist/utils/warnings.js.map +0 -1
  317. package/dist/zero/css-writer.d.ts +0 -45
  318. package/dist/zero/css-writer.js +0 -73
  319. package/dist/zero/css-writer.js.map +0 -1
  320. package/dist/zero/extractor.d.ts +0 -24
  321. package/dist/zero/extractor.js.map +0 -1
@@ -1,1157 +0,0 @@
1
- import { Lru } from "../parser/lru.js";
2
- import { and, getConditionUniqueId, isCompoundCondition, not } from "./conditions.js";
3
- import { simplifyCondition } from "./simplify.js";
4
- //#region src/pipeline/materialize.ts
5
- /**
6
- * CSS Materialization
7
- *
8
- * Converts condition trees into CSS selectors and at-rules.
9
- * This is the final stage that produces actual CSS output.
10
- */
11
- const conditionCache = new Lru(3e3);
12
- /**
13
- * Convert a condition tree to CSS components
14
- */
15
- function conditionToCSS(node) {
16
- const key = getConditionUniqueId(node);
17
- const cached = conditionCache.get(key);
18
- if (cached) return cached;
19
- const result = conditionToCSSInner(node);
20
- conditionCache.set(key, result);
21
- return result;
22
- }
23
- function emptyVariant() {
24
- return {
25
- modifierConditions: [],
26
- pseudoConditions: [],
27
- selectorGroups: [],
28
- ownGroups: [],
29
- mediaConditions: [],
30
- containerConditions: [],
31
- supportsConditions: [],
32
- rootGroups: [],
33
- parentGroups: [],
34
- startingStyle: false
35
- };
36
- }
37
- function conditionToCSSInner(node) {
38
- if (node.kind === "true") return {
39
- variants: [emptyVariant()],
40
- isImpossible: false
41
- };
42
- if (node.kind === "false") return {
43
- variants: [],
44
- isImpossible: true
45
- };
46
- if (node.kind === "state") return stateToCSS(node);
47
- if (node.kind === "compound") if (node.operator === "AND") return andToCSS(node.children);
48
- else return orToCSS(node.children);
49
- return {
50
- variants: [emptyVariant()],
51
- isImpossible: false
52
- };
53
- }
54
- /**
55
- * Convert a state condition to CSS
56
- */
57
- function stateToCSS(state) {
58
- switch (state.type) {
59
- case "media": return {
60
- variants: mediaToParsed(state).map((mediaCond) => {
61
- const v = emptyVariant();
62
- v.mediaConditions.push(mediaCond);
63
- return v;
64
- }),
65
- isImpossible: false
66
- };
67
- case "root": return innerConditionToVariants(state.innerCondition, state.negated ?? false, "rootGroups");
68
- case "parent": return parentConditionToVariants(state.innerCondition, state.negated ?? false, state.direct);
69
- case "own": return innerConditionToVariants(state.innerCondition, state.negated ?? false, "ownGroups");
70
- case "modifier": {
71
- const v = emptyVariant();
72
- v.modifierConditions.push(modifierToParsed(state));
73
- return {
74
- variants: [v],
75
- isImpossible: false
76
- };
77
- }
78
- case "pseudo": {
79
- const v = emptyVariant();
80
- v.pseudoConditions.push(pseudoToParsed(state));
81
- return {
82
- variants: [v],
83
- isImpossible: false
84
- };
85
- }
86
- case "container": {
87
- const v = emptyVariant();
88
- v.containerConditions.push(containerToParsed(state));
89
- return {
90
- variants: [v],
91
- isImpossible: false
92
- };
93
- }
94
- case "supports": {
95
- const v = emptyVariant();
96
- v.supportsConditions.push(supportsToParsed(state));
97
- return {
98
- variants: [v],
99
- isImpossible: false
100
- };
101
- }
102
- case "starting": {
103
- const v = emptyVariant();
104
- v.startingStyle = !state.negated;
105
- return {
106
- variants: [v],
107
- isImpossible: false
108
- };
109
- }
110
- }
111
- }
112
- /**
113
- * Convert modifier condition to parsed structure
114
- */
115
- function modifierToParsed(state) {
116
- return {
117
- attribute: state.attribute,
118
- value: state.value,
119
- operator: state.operator,
120
- negated: state.negated ?? false
121
- };
122
- }
123
- /**
124
- * Convert parsed modifier to CSS selector string (for final output)
125
- */
126
- function modifierToCSS(mod) {
127
- let selector;
128
- if (mod.value !== void 0) {
129
- const op = mod.operator || "=";
130
- selector = `[${mod.attribute}${op}"${mod.value}"]`;
131
- } else selector = `[${mod.attribute}]`;
132
- if (mod.negated) return `:not(${selector})`;
133
- return selector;
134
- }
135
- /**
136
- * Convert pseudo condition to parsed structure
137
- */
138
- function pseudoToParsed(state) {
139
- return {
140
- pseudo: state.pseudo,
141
- negated: state.negated ?? false
142
- };
143
- }
144
- /**
145
- * Convert parsed pseudo to CSS selector string (for final output).
146
- *
147
- * :not() is normalized to negated :is() at parse time, so pseudo.pseudo
148
- * never starts with ':not(' here. When negated:
149
- * - :is(X) → :not(X) (unwrap :is)
150
- * - :where(X) → :not(X) (unwrap :where)
151
- * - :has(X) → :not(:has(X))
152
- * - other → :not(other)
153
- *
154
- * When not negated, single-argument :is()/:where() is unwrapped when the
155
- * inner content is a simple compound selector that can safely append to
156
- * the base selector (this happens after double-negation of :not()).
157
- */
158
- function pseudoToCSS(pseudo) {
159
- const p = pseudo.pseudo;
160
- if (pseudo.negated) {
161
- if (p.startsWith(":is(") || p.startsWith(":where(")) return `:not(${p.slice(p.indexOf("(") + 1, -1)})`;
162
- return `:not(${p})`;
163
- }
164
- if ((p.startsWith(":is(") || p.startsWith(":where(")) && !p.includes(",")) {
165
- const inner = p.slice(p.indexOf("(") + 1, -1);
166
- const ch = inner[0];
167
- if ((ch === ":" || ch === "." || ch === "[" || ch === "#") && !/\s/.test(inner)) return inner;
168
- }
169
- return p;
170
- }
171
- /**
172
- * Convert media condition to parsed structure(s)
173
- * Returns an array because negated ranges produce OR branches (two separate conditions)
174
- */
175
- function mediaToParsed(state) {
176
- if (state.subtype === "type") {
177
- const mediaType = state.mediaType || "all";
178
- return [{
179
- subtype: "type",
180
- negated: state.negated ?? false,
181
- condition: mediaType,
182
- mediaType: state.mediaType
183
- }];
184
- } else if (state.subtype === "feature") {
185
- let condition;
186
- if (state.featureValue) condition = `(${state.feature}: ${state.featureValue})`;
187
- else condition = `(${state.feature})`;
188
- return [{
189
- subtype: "feature",
190
- negated: state.negated ?? false,
191
- condition,
192
- feature: state.feature,
193
- featureValue: state.featureValue
194
- }];
195
- } else return dimensionToMediaParsed(state.dimension || "width", state.lowerBound, state.upperBound, state.negated ?? false);
196
- }
197
- /**
198
- * Convert dimension bounds to parsed media condition(s)
199
- * Uses CSS Media Queries Level 4 `not (condition)` syntax for negation.
200
- */
201
- function dimensionToMediaParsed(dimension, lowerBound, upperBound, negated) {
202
- let condition;
203
- if (lowerBound && upperBound) {
204
- const lowerOp = lowerBound.inclusive ? "<=" : "<";
205
- const upperOp = upperBound.inclusive ? "<=" : "<";
206
- condition = `(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;
207
- } else if (upperBound) condition = `(${dimension} ${upperBound.inclusive ? "<=" : "<"} ${upperBound.value})`;
208
- else if (lowerBound) condition = `(${dimension} ${lowerBound.inclusive ? ">=" : ">"} ${lowerBound.value})`;
209
- else condition = `(${dimension})`;
210
- return [{
211
- subtype: "dimension",
212
- negated: negated ?? false,
213
- condition,
214
- dimension,
215
- lowerBound,
216
- upperBound
217
- }];
218
- }
219
- /**
220
- * Convert container condition to parsed structure
221
- * This enables structured analysis for contradiction detection and condition combining
222
- */
223
- function containerToParsed(state) {
224
- let condition;
225
- if (state.subtype === "style") if (state.propertyValue) condition = `style(--${state.property}: ${state.propertyValue})`;
226
- else condition = `style(--${state.property})`;
227
- else if (state.subtype === "raw") condition = state.rawCondition;
228
- else condition = dimensionToContainerCondition(state.dimension || "width", state.lowerBound, state.upperBound);
229
- return {
230
- name: state.containerName,
231
- condition,
232
- negated: state.negated ?? false,
233
- subtype: state.subtype,
234
- property: state.property,
235
- propertyValue: state.propertyValue
236
- };
237
- }
238
- /**
239
- * Convert dimension bounds to container query condition (single string)
240
- * Container queries support "not (condition)", so no need to invert manually
241
- */
242
- function dimensionToContainerCondition(dimension, lowerBound, upperBound) {
243
- if (lowerBound && upperBound) {
244
- const lowerOp = lowerBound.inclusive ? "<=" : "<";
245
- const upperOp = upperBound.inclusive ? "<=" : "<";
246
- return `(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;
247
- } else if (upperBound) return `(${dimension} ${upperBound.inclusive ? "<=" : "<"} ${upperBound.value})`;
248
- else if (lowerBound) return `(${dimension} ${lowerBound.inclusive ? ">=" : ">"} ${lowerBound.value})`;
249
- return "(width)";
250
- }
251
- /**
252
- * Convert supports condition to parsed structure
253
- */
254
- function supportsToParsed(state) {
255
- return {
256
- subtype: state.subtype,
257
- condition: state.condition,
258
- negated: state.negated ?? false
259
- };
260
- }
261
- /**
262
- * Collect all modifier and pseudo conditions from a variant as a flat array.
263
- */
264
- function collectSelectorConditions(variant) {
265
- return [...variant.modifierConditions, ...variant.pseudoConditions];
266
- }
267
- /**
268
- * Convert an inner condition tree into a single SelectorVariant with
269
- * one SelectorGroup whose branches represent the inner OR alternatives.
270
- * Shared by @root() and @own().
271
- *
272
- * Both positive and negated cases produce one variant with one group.
273
- * Negation simply sets the `negated` flag, which swaps :is() for :not()
274
- * in the final CSS output — no De Morgan transformation is needed.
275
- *
276
- * This mirrors parentConditionToVariants: OR branches are kept inside
277
- * a single group and rendered as comma-separated arguments in
278
- * :is()/:not(), e.g. :root:is([a], [b]) or [el]:not([a], [b]).
279
- */
280
- function innerConditionToVariants(innerCondition, negated, target) {
281
- const innerCSS = conditionToCSS(innerCondition);
282
- if (innerCSS.isImpossible || innerCSS.variants.length === 0) return {
283
- variants: [],
284
- isImpossible: true
285
- };
286
- const branches = [];
287
- for (const innerVariant of innerCSS.variants) {
288
- const conditions = collectSelectorConditions(innerVariant);
289
- if (conditions.length > 0) branches.push(conditions);
290
- }
291
- if (branches.length === 0) return {
292
- variants: [emptyVariant()],
293
- isImpossible: false
294
- };
295
- const v = emptyVariant();
296
- v[target].push({
297
- branches,
298
- negated
299
- });
300
- return {
301
- variants: [v],
302
- isImpossible: false
303
- };
304
- }
305
- /**
306
- * Convert a @parent() inner condition into a single SelectorVariant with
307
- * one ParentGroup whose branches represent the inner OR alternatives.
308
- *
309
- * Both positive and negated cases produce one variant with one group.
310
- * Negation simply sets the `negated` flag, which swaps :is() for :not()
311
- * in the final CSS output — no structural transformation is needed.
312
- */
313
- function parentConditionToVariants(innerCondition, negated, direct) {
314
- const innerCSS = conditionToCSS(innerCondition);
315
- if (innerCSS.isImpossible || innerCSS.variants.length === 0) return {
316
- variants: [],
317
- isImpossible: true
318
- };
319
- const branches = [];
320
- for (const innerVariant of innerCSS.variants) {
321
- const conditions = collectSelectorConditions(innerVariant);
322
- if (conditions.length > 0) branches.push(conditions);
323
- }
324
- if (branches.length === 0) return {
325
- variants: [emptyVariant()],
326
- isImpossible: false
327
- };
328
- const v = emptyVariant();
329
- v.parentGroups.push({
330
- branches,
331
- direct,
332
- negated
333
- });
334
- return {
335
- variants: [v],
336
- isImpossible: false
337
- };
338
- }
339
- /**
340
- * Sort key for canonical condition output within selectors.
341
- *
342
- * Priority order:
343
- * 0: Boolean attribute selectors ([data-hovered])
344
- * 1: Value attribute selectors ([data-size="small"])
345
- * 2: Negated boolean attributes (:not([data-disabled]))
346
- * 3: Negated value attributes (:not([data-size="small"]))
347
- * 4: Pseudo-classes (:hover, :focus)
348
- * 5: Negated pseudo-classes (:not(:disabled))
349
- *
350
- * Secondary sort: alphabetical by attribute name / pseudo string.
351
- */
352
- function conditionSortKey(cond) {
353
- if ("attribute" in cond) {
354
- const hasValue = cond.value !== void 0 ? 1 : 0;
355
- return `${(cond.negated ? 2 : 0) + hasValue}|${cond.attribute}|${cond.value ?? ""}`;
356
- }
357
- return `${cond.negated ? 5 : 4}|${cond.pseudo}`;
358
- }
359
- function sortConditions(conditions) {
360
- return conditions.toSorted((a, b) => conditionSortKey(a).localeCompare(conditionSortKey(b)));
361
- }
362
- function branchToCSS(branch) {
363
- let parts = "";
364
- for (const cond of sortConditions(branch)) parts += selectorConditionToCSS(cond);
365
- return parts;
366
- }
367
- /**
368
- * Wrap serialized selector arguments in :is() or :not().
369
- * Arguments are sorted for canonical output.
370
- */
371
- function wrapInIsOrNot(args, negated) {
372
- return `${negated ? ":not" : ":is"}(${args.sort().join(", ")})`;
373
- }
374
- /**
375
- * Convert a selector group to a CSS selector fragment.
376
- *
377
- * Single-branch groups are unwrapped (no :is() wrapper).
378
- * Multi-branch groups use :is() or :not().
379
- * Negation swaps :is() for :not().
380
- */
381
- function selectorGroupToCSS(group) {
382
- if (group.branches.length === 0) return "";
383
- if (group.branches.length === 1) {
384
- const parts = branchToCSS(group.branches[0]);
385
- if (group.negated) return `:not(${parts})`;
386
- return parts;
387
- }
388
- return wrapInIsOrNot(group.branches.map(branchToCSS), group.negated);
389
- }
390
- /**
391
- * Collect facts about modifier conditions for subsumption analysis.
392
- * Tracks negated boolean attrs (:not([attr])) and positive exact values ([attr="X"]).
393
- */
394
- function collectSubsumptionFacts(modifiers) {
395
- const negatedBooleanAttrs = /* @__PURE__ */ new Set();
396
- const positiveExactValuesByAttr = /* @__PURE__ */ new Map();
397
- for (const mod of modifiers) {
398
- if (mod.negated && mod.value === void 0) negatedBooleanAttrs.add(mod.attribute);
399
- if (!mod.negated && mod.value !== void 0 && (mod.operator ?? "=") === "=") {
400
- let vals = positiveExactValuesByAttr.get(mod.attribute);
401
- if (!vals) {
402
- vals = /* @__PURE__ */ new Set();
403
- positiveExactValuesByAttr.set(mod.attribute, vals);
404
- }
405
- vals.add(mod.value);
406
- }
407
- }
408
- return {
409
- negatedBooleanAttrs,
410
- positiveExactValuesByAttr
411
- };
412
- }
413
- /**
414
- * Check if a negated-value modifier is subsumed by stronger facts:
415
- * - :not([attr]) subsumes :not([attr="val"])
416
- * - [attr="X"] implies :not([attr="Y"]) is redundant (single exact value)
417
- *
418
- * Only applies to exact-match (=) operators; substring operators don't
419
- * imply exclusivity between values.
420
- */
421
- function isSubsumedNegatedModifier(mod, facts) {
422
- if (!mod.negated || mod.value === void 0) return false;
423
- if (facts.negatedBooleanAttrs.has(mod.attribute)) return true;
424
- if ((mod.operator ?? "=") === "=") {
425
- const posVals = facts.positiveExactValuesByAttr.get(mod.attribute);
426
- if (posVals && posVals.size === 1 && !posVals.has(mod.value)) return true;
427
- }
428
- return false;
429
- }
430
- /**
431
- * Remove redundant single-condition groups that are subsumed by stronger
432
- * groups on the same attribute. O(n) — only inspects single-branch,
433
- * single-condition groups.
434
- */
435
- function optimizeGroups(groups) {
436
- if (groups.length <= 1) return groups;
437
- const seen = /* @__PURE__ */ new Set();
438
- const result = [];
439
- for (const g of groups) {
440
- const key = getSelectorGroupKey(g);
441
- if (!seen.has(key)) {
442
- seen.add(key);
443
- result.push(g);
444
- }
445
- }
446
- if (result.length <= 1) return result;
447
- const effectiveModifiers = [];
448
- for (const g of result) {
449
- if (g.branches.length !== 1 || g.branches[0].length !== 1) continue;
450
- const cond = g.branches[0][0];
451
- if (!("attribute" in cond)) continue;
452
- effectiveModifiers.push({
453
- ...cond,
454
- negated: g.negated !== cond.negated
455
- });
456
- }
457
- const facts = collectSubsumptionFacts(effectiveModifiers);
458
- if (facts.negatedBooleanAttrs.size === 0 && facts.positiveExactValuesByAttr.size === 0) return result;
459
- return result.filter((g) => {
460
- if (g.branches.length !== 1 || g.branches[0].length !== 1) return true;
461
- const cond = g.branches[0][0];
462
- if (!("attribute" in cond) || !g.negated || cond.negated || cond.value === void 0) return true;
463
- return !isSubsumedNegatedModifier({
464
- ...cond,
465
- negated: true
466
- }, facts);
467
- });
468
- }
469
- /**
470
- * Convert root groups to CSS selector prefix (for final output)
471
- */
472
- function rootGroupsToCSS(groups) {
473
- if (groups.length === 0) return void 0;
474
- const optimized = optimizeGroups(groups);
475
- if (optimized.length === 0) return void 0;
476
- let prefix = ":root";
477
- for (const group of optimized) prefix += selectorGroupToCSS(group);
478
- return prefix;
479
- }
480
- /**
481
- * Convert parent groups to CSS selector fragments (for final output).
482
- * Each group produces its own :is()/:not() wrapper with a combinator
483
- * suffix (` *` or ` > *`) appended to each branch.
484
- */
485
- function parentGroupsToCSS(groups) {
486
- let result = "";
487
- for (const group of groups) {
488
- const combinator = group.direct ? " > *" : " *";
489
- const args = group.branches.map((branch) => branchToCSS(branch) + combinator);
490
- result += wrapInIsOrNot(args, group.negated);
491
- }
492
- return result;
493
- }
494
- /**
495
- * Convert a modifier or pseudo condition to a CSS selector fragment
496
- */
497
- function selectorConditionToCSS(cond) {
498
- if ("attribute" in cond) return modifierToCSS(cond);
499
- return pseudoToCSS(cond);
500
- }
501
- /**
502
- * Get unique key for a modifier condition
503
- */
504
- function getModifierKey(mod) {
505
- const base = mod.value ? `${mod.attribute}${mod.operator || "="}${mod.value}` : mod.attribute;
506
- return mod.negated ? `!${base}` : base;
507
- }
508
- /**
509
- * Get unique key for a pseudo condition
510
- */
511
- function getPseudoKey(pseudo) {
512
- return pseudo.negated ? `!${pseudo.pseudo}` : pseudo.pseudo;
513
- }
514
- /**
515
- * Get unique key for any selector condition (modifier or pseudo)
516
- */
517
- function getSelectorConditionKey(cond) {
518
- return "attribute" in cond ? `mod:${getModifierKey(cond)}` : `pseudo:${getPseudoKey(cond)}`;
519
- }
520
- /**
521
- * Deduplicate selector conditions (modifiers or pseudos).
522
- * Shared by root, parent, and own conditions.
523
- */
524
- function dedupeSelectorConditions(conditions) {
525
- const seen = /* @__PURE__ */ new Set();
526
- const result = [];
527
- for (const c of conditions) {
528
- const key = getSelectorConditionKey(c);
529
- if (!seen.has(key)) {
530
- seen.add(key);
531
- result.push(c);
532
- }
533
- }
534
- const facts = collectSubsumptionFacts(result.filter((c) => "attribute" in c));
535
- if (facts.negatedBooleanAttrs.size === 0 && facts.positiveExactValuesByAttr.size === 0) return result;
536
- return result.filter((c) => {
537
- if (!("attribute" in c)) return true;
538
- return !isSubsumedNegatedModifier(c, facts);
539
- });
540
- }
541
- /**
542
- * Check for modifier contradiction: same attribute with opposite negation
543
- */
544
- function hasModifierContradiction(conditions) {
545
- const byKey = /* @__PURE__ */ new Map();
546
- for (const mod of conditions) {
547
- const baseKey = mod.value ? `${mod.attribute}${mod.operator || "="}${mod.value}` : mod.attribute;
548
- const existing = byKey.get(baseKey);
549
- if (existing !== void 0 && existing !== !mod.negated) return true;
550
- byKey.set(baseKey, !mod.negated);
551
- }
552
- return false;
553
- }
554
- /**
555
- * Check for pseudo contradiction: same pseudo with opposite negation
556
- */
557
- function hasPseudoContradiction(conditions) {
558
- const byKey = /* @__PURE__ */ new Map();
559
- for (const pseudo of conditions) {
560
- const existing = byKey.get(pseudo.pseudo);
561
- if (existing !== void 0 && existing !== !pseudo.negated) return true;
562
- byKey.set(pseudo.pseudo, !pseudo.negated);
563
- }
564
- return false;
565
- }
566
- /**
567
- * Check for selector condition contradiction (modifier or pseudo with opposite negation).
568
- * Shared by root, parent, and own conditions.
569
- */
570
- function hasSelectorConditionContradiction(conditions) {
571
- const modifiers = [];
572
- const pseudos = [];
573
- for (const c of conditions) if ("attribute" in c) modifiers.push(c);
574
- else pseudos.push(c);
575
- return hasModifierContradiction(modifiers) || hasPseudoContradiction(pseudos);
576
- }
577
- /**
578
- * Check for parent group contradiction: same target (direct + conditions)
579
- * with opposite negation. E.g. :not([data-hovered] *) and :is([data-hovered] *)
580
- * in the same variant is impossible.
581
- */
582
- function getBranchesKey(branches) {
583
- if (branches.length === 1) {
584
- const b = branches[0];
585
- if (b.length === 1) return getSelectorConditionKey(b[0]);
586
- return b.map(getSelectorConditionKey).sort().join("+");
587
- }
588
- return branches.map((b) => b.map(getSelectorConditionKey).sort().join("+")).sort().join(",");
589
- }
590
- function hasParentGroupContradiction(groups) {
591
- const byBaseKey = /* @__PURE__ */ new Map();
592
- for (const g of groups) {
593
- const baseKey = `${g.direct ? ">" : ""}(${getBranchesKey(g.branches)})`;
594
- const existing = byBaseKey.get(baseKey);
595
- if (existing !== void 0 && existing !== !g.negated) return true;
596
- byBaseKey.set(baseKey, !g.negated);
597
- }
598
- return false;
599
- }
600
- /**
601
- * Check for selector group contradiction: same branches with opposite negation.
602
- * E.g. :is([data-a]) and :not([data-a]) in the same variant is impossible.
603
- */
604
- function hasSelectorGroupContradiction(groups) {
605
- const byBaseKey = /* @__PURE__ */ new Map();
606
- for (const g of groups) {
607
- const baseKey = getBranchesKey(g.branches);
608
- const existing = byBaseKey.get(baseKey);
609
- if (existing !== void 0 && existing !== !g.negated) return true;
610
- byBaseKey.set(baseKey, !g.negated);
611
- }
612
- return false;
613
- }
614
- /**
615
- * Merge two selector variants (AND operation)
616
- * Deduplicates conditions and checks for contradictions
617
- */
618
- function mergeVariants(a, b) {
619
- const mergedMedia = dedupeMediaConditions([...a.mediaConditions, ...b.mediaConditions]);
620
- if (hasMediaContradiction(mergedMedia)) return null;
621
- const mergedRootGroups = optimizeGroups([...a.rootGroups, ...b.rootGroups]);
622
- if (hasSelectorGroupContradiction(mergedRootGroups)) return null;
623
- const mergedModifiers = dedupeSelectorConditions([...a.modifierConditions, ...b.modifierConditions]);
624
- const mergedPseudos = dedupeSelectorConditions([...a.pseudoConditions, ...b.pseudoConditions]);
625
- if (hasSelectorConditionContradiction([...mergedModifiers, ...mergedPseudos])) return null;
626
- const mergedSelectorGroups = optimizeGroups([...a.selectorGroups, ...b.selectorGroups]);
627
- if (hasSelectorGroupContradiction(mergedSelectorGroups)) return null;
628
- const mergedParentGroups = [...a.parentGroups, ...b.parentGroups];
629
- if (hasParentGroupContradiction(mergedParentGroups)) return null;
630
- const mergedOwnGroups = optimizeGroups([...a.ownGroups, ...b.ownGroups]);
631
- if (hasSelectorGroupContradiction(mergedOwnGroups)) return null;
632
- const mergedContainers = dedupeContainerConditions([...a.containerConditions, ...b.containerConditions]);
633
- if (hasContainerStyleContradiction(mergedContainers)) return null;
634
- const mergedSupports = dedupeSupportsConditions([...a.supportsConditions, ...b.supportsConditions]);
635
- if (hasSupportsContradiction(mergedSupports)) return null;
636
- return {
637
- modifierConditions: mergedModifiers,
638
- pseudoConditions: mergedPseudos,
639
- selectorGroups: mergedSelectorGroups,
640
- ownGroups: mergedOwnGroups,
641
- mediaConditions: mergedMedia,
642
- containerConditions: mergedContainers,
643
- supportsConditions: mergedSupports,
644
- rootGroups: mergedRootGroups,
645
- parentGroups: mergedParentGroups,
646
- startingStyle: a.startingStyle || b.startingStyle
647
- };
648
- }
649
- /**
650
- * Generic deduplication by a key extraction function.
651
- * Preserves insertion order, keeping the first occurrence of each key.
652
- */
653
- function dedupeByKey(items, getKey) {
654
- const seen = /* @__PURE__ */ new Set();
655
- const result = [];
656
- for (const item of items) {
657
- const key = getKey(item);
658
- if (!seen.has(key)) {
659
- seen.add(key);
660
- result.push(item);
661
- }
662
- }
663
- return result;
664
- }
665
- function dedupeMediaConditions(conditions) {
666
- return dedupeByKey(conditions, (c) => `${c.subtype}|${c.condition}|${c.negated}`);
667
- }
668
- function dedupeContainerConditions(conditions) {
669
- return dedupeByKey(conditions, (c) => `${c.name ?? ""}|${c.condition}|${c.negated}`);
670
- }
671
- function dedupeSupportsConditions(conditions) {
672
- return dedupeByKey(conditions, (c) => `${c.subtype}|${c.condition}|${c.negated}`);
673
- }
674
- /**
675
- * Check if supports conditions contain contradictions
676
- * e.g., @supports(display: grid) AND NOT @supports(display: grid)
677
- */
678
- function hasSupportsContradiction(conditions) {
679
- const conditionMap = /* @__PURE__ */ new Map();
680
- for (const cond of conditions) {
681
- const key = `${cond.subtype}|${cond.condition}`;
682
- const existing = conditionMap.get(key);
683
- if (existing !== void 0 && existing !== !cond.negated) return true;
684
- conditionMap.set(key, !cond.negated);
685
- }
686
- return false;
687
- }
688
- /**
689
- * Check if a set of media conditions contains contradictions
690
- * e.g., (prefers-color-scheme: light) AND NOT (prefers-color-scheme: light)
691
- * or (width >= 900px) AND (width < 600px)
692
- *
693
- * Uses parsed media conditions for efficient analysis without regex parsing.
694
- */
695
- function hasMediaContradiction(conditions) {
696
- const featureConditions = /* @__PURE__ */ new Map();
697
- const typeConditions = /* @__PURE__ */ new Map();
698
- const dimensionConditions = /* @__PURE__ */ new Map();
699
- const dimensionsByDim = /* @__PURE__ */ new Map();
700
- for (const cond of conditions) if (cond.subtype === "type") {
701
- const key = cond.mediaType || "all";
702
- const existing = typeConditions.get(key);
703
- if (existing !== void 0 && existing !== !cond.negated) return true;
704
- typeConditions.set(key, !cond.negated);
705
- } else if (cond.subtype === "feature") {
706
- const key = cond.condition;
707
- const existing = featureConditions.get(key);
708
- if (existing !== void 0 && existing !== !cond.negated) return true;
709
- featureConditions.set(key, !cond.negated);
710
- } else if (cond.subtype === "dimension") {
711
- const condKey = cond.condition;
712
- const existing = dimensionConditions.get(condKey);
713
- if (existing !== void 0 && existing !== !cond.negated) return true;
714
- dimensionConditions.set(condKey, !cond.negated);
715
- if (!cond.negated) {
716
- const dim = cond.dimension || "width";
717
- let bounds = dimensionsByDim.get(dim);
718
- if (!bounds) {
719
- bounds = {
720
- lowerBound: null,
721
- upperBound: null
722
- };
723
- dimensionsByDim.set(dim, bounds);
724
- }
725
- if (cond.lowerBound?.valueNumeric != null) {
726
- const value = cond.lowerBound.valueNumeric;
727
- if (bounds.lowerBound === null || value > bounds.lowerBound) bounds.lowerBound = value;
728
- }
729
- if (cond.upperBound?.valueNumeric != null) {
730
- const value = cond.upperBound.valueNumeric;
731
- if (bounds.upperBound === null || value < bounds.upperBound) bounds.upperBound = value;
732
- }
733
- if (bounds.lowerBound !== null && bounds.upperBound !== null && bounds.lowerBound >= bounds.upperBound) return true;
734
- }
735
- }
736
- return false;
737
- }
738
- /**
739
- * Check if container conditions contain contradictions in style queries
740
- * e.g., style(--variant: danger) and style(--variant: success) together
741
- * Same property with different values = always false
742
- *
743
- * Uses parsed container conditions for efficient analysis without regex parsing.
744
- */
745
- function hasContainerStyleContradiction(conditions) {
746
- const styleQueries = /* @__PURE__ */ new Map();
747
- for (const cond of conditions) {
748
- if (cond.subtype !== "style" || !cond.property) continue;
749
- const property = cond.property;
750
- const value = cond.propertyValue;
751
- if (!styleQueries.has(property)) styleQueries.set(property, {
752
- hasExistence: false,
753
- values: /* @__PURE__ */ new Set(),
754
- hasNegatedExistence: false
755
- });
756
- const entry = styleQueries.get(property);
757
- if (cond.negated) {
758
- if (value === void 0) entry.hasNegatedExistence = true;
759
- } else if (value === void 0) entry.hasExistence = true;
760
- else entry.values.add(value);
761
- }
762
- for (const [, entry] of styleQueries) {
763
- if (entry.hasExistence && entry.hasNegatedExistence) return true;
764
- if (entry.values.size > 1) return true;
765
- if (entry.hasNegatedExistence && entry.values.size > 0) return true;
766
- }
767
- return false;
768
- }
769
- const variantKeyCache = /* @__PURE__ */ new WeakMap();
770
- /**
771
- * Get a unique key for a variant (for deduplication).
772
- * Cached via WeakMap since variants are compared multiple times during
773
- * deduplication and sorting.
774
- */
775
- function getSelectorGroupKey(g) {
776
- return `${g.negated ? "!" : ""}(${getBranchesKey(g.branches)})`;
777
- }
778
- /**
779
- * Get a context key for a variant — everything except flat modifier/pseudo
780
- * conditions. Variants with the same context key can be merged into an
781
- * :is() group. Also used by getVariantKey as the shared non-selector portion.
782
- */
783
- function getVariantContextKey(v) {
784
- return [
785
- v.mediaConditions.map((c) => `${c.subtype}:${c.negated ? "!" : ""}${c.condition}`).sort().join("|"),
786
- v.containerConditions.map((c) => `${c.name ?? ""}:${c.negated ? "!" : ""}${c.condition}`).sort().join("|"),
787
- v.supportsConditions.map((c) => `${c.subtype}:${c.negated ? "!" : ""}${c.condition}`).sort().join("|"),
788
- v.rootGroups.map(getSelectorGroupKey).sort().join("|"),
789
- v.parentGroups.map(getParentGroupKey).sort().join("|"),
790
- v.ownGroups.map(getSelectorGroupKey).sort().join("|"),
791
- v.selectorGroups.map(getSelectorGroupKey).sort().join("|"),
792
- v.startingStyle ? "1" : "0"
793
- ].join("###");
794
- }
795
- function getVariantKey(v) {
796
- const cached = variantKeyCache.get(v);
797
- if (cached !== void 0) return cached;
798
- const modifierKey = v.modifierConditions.map(getModifierKey).sort().join("|");
799
- const pseudoKey = v.pseudoConditions.map(getPseudoKey).sort().join("|");
800
- const key = modifierKey + "###" + pseudoKey + "###" + getVariantContextKey(v);
801
- variantKeyCache.set(v, key);
802
- return key;
803
- }
804
- /**
805
- * Total number of leaf conditions in a variant (for superset / dedup comparisons).
806
- */
807
- function groupConditionCount(groups) {
808
- return groups.reduce((sum, g) => sum + g.branches.reduce((s, b) => s + b.length, 0), 0);
809
- }
810
- function variantConditionCount(v) {
811
- return v.modifierConditions.length + v.pseudoConditions.length + groupConditionCount(v.selectorGroups) + groupConditionCount(v.ownGroups) + v.mediaConditions.length + v.containerConditions.length + v.supportsConditions.length + groupConditionCount(v.rootGroups) + groupConditionCount(v.parentGroups);
812
- }
813
- /**
814
- * Check if variant A is a superset of variant B (A is more restrictive)
815
- *
816
- * If A has all of B's conditions plus more, then A is redundant
817
- * because B already covers the same cases (and more).
818
- *
819
- * Example:
820
- * A: :not([size=large]):not([size=medium]):not([size=small])
821
- * B: :not([size=large])
822
- * A is a superset of B, so A is redundant when B exists.
823
- */
824
- function isVariantSuperset(a, b) {
825
- if (a.startingStyle !== b.startingStyle) return false;
826
- if (!isSelectorGroupsSuperset(a.rootGroups, b.rootGroups)) return false;
827
- if (!isMediaConditionsSuperset(a.mediaConditions, b.mediaConditions)) return false;
828
- if (!isContainerConditionsSuperset(a.containerConditions, b.containerConditions)) return false;
829
- if (!isSupportsConditionsSuperset(a.supportsConditions, b.supportsConditions)) return false;
830
- if (!isModifierConditionsSuperset(a.modifierConditions, b.modifierConditions)) return false;
831
- if (!isPseudoConditionsSuperset(a.pseudoConditions, b.pseudoConditions)) return false;
832
- if (!isSelectorGroupsSuperset(a.selectorGroups, b.selectorGroups)) return false;
833
- if (!isSelectorGroupsSuperset(a.ownGroups, b.ownGroups)) return false;
834
- if (!isParentGroupsSuperset(a.parentGroups, b.parentGroups)) return false;
835
- return variantConditionCount(a) > variantConditionCount(b);
836
- }
837
- /**
838
- * Generic superset check: true if every item in B has a matching key in A.
839
- */
840
- function isConditionsSuperset(a, b, getKey) {
841
- const aKeys = new Set(a.map(getKey));
842
- return b.every((c) => aKeys.has(getKey(c)));
843
- }
844
- function isMediaConditionsSuperset(a, b) {
845
- return isConditionsSuperset(a, b, (c) => `${c.subtype}|${c.condition}|${c.negated}`);
846
- }
847
- function isContainerConditionsSuperset(a, b) {
848
- return isConditionsSuperset(a, b, (c) => `${c.name ?? ""}|${c.condition}|${c.negated}`);
849
- }
850
- function isSupportsConditionsSuperset(a, b) {
851
- return isConditionsSuperset(a, b, (c) => `${c.subtype}|${c.condition}|${c.negated}`);
852
- }
853
- function isModifierConditionsSuperset(a, b) {
854
- return isConditionsSuperset(a, b, getModifierKey);
855
- }
856
- function isPseudoConditionsSuperset(a, b) {
857
- return isConditionsSuperset(a, b, getPseudoKey);
858
- }
859
- function isSelectorGroupsSuperset(a, b) {
860
- if (a.length < b.length) return false;
861
- return isConditionsSuperset(a, b, getSelectorGroupKey);
862
- }
863
- /**
864
- * Check if parent groups A is a superset of B.
865
- * Each group in B must have a matching group in A.
866
- */
867
- function isParentGroupsSuperset(a, b) {
868
- if (a.length < b.length) return false;
869
- return isConditionsSuperset(a, b, getParentGroupKey);
870
- }
871
- function getParentGroupKey(g) {
872
- return `${g.negated ? "!" : ""}${g.direct ? ">" : ""}(${getBranchesKey(g.branches)})`;
873
- }
874
- /**
875
- * Deduplicate variants
876
- *
877
- * Removes:
878
- * 1. Exact duplicates (same key)
879
- * 2. Superset variants (more restrictive selectors that are redundant)
880
- */
881
- function dedupeVariants(variants) {
882
- if (variants.length <= 1) return variants;
883
- const seen = /* @__PURE__ */ new Set();
884
- const result = [];
885
- for (const v of variants) {
886
- const key = getVariantKey(v);
887
- if (!seen.has(key)) {
888
- seen.add(key);
889
- result.push(v);
890
- }
891
- }
892
- if (result.length <= 1) return result;
893
- result.sort((a, b) => variantConditionCount(a) - variantConditionCount(b));
894
- const filtered = [];
895
- for (const candidate of result) {
896
- let isRedundant = false;
897
- for (const kept of filtered) if (isVariantSuperset(candidate, kept)) {
898
- isRedundant = true;
899
- break;
900
- }
901
- if (!isRedundant) filtered.push(candidate);
902
- }
903
- return filtered;
904
- }
905
- /**
906
- * Combine AND conditions into CSS
907
- *
908
- * AND of conditions means cartesian product of variants:
909
- * (A1 | A2) & (B1 | B2) = A1&B1 | A1&B2 | A2&B1 | A2&B2
910
- *
911
- * Variants that result in contradictions (e.g., conflicting media rules)
912
- * are filtered out.
913
- */
914
- function andToCSS(children) {
915
- const exclusiveChildren = makeOrBranchesExclusive(children);
916
- let currentVariants = [emptyVariant()];
917
- for (const child of exclusiveChildren) {
918
- const childCSS = conditionToCSSInner(child);
919
- if (childCSS.isImpossible || childCSS.variants.length === 0) return {
920
- variants: [],
921
- isImpossible: true
922
- };
923
- const newVariants = [];
924
- for (const current of currentVariants) for (const childVariant of childCSS.variants) {
925
- const merged = mergeVariants(current, childVariant);
926
- if (merged !== null) newVariants.push(merged);
927
- }
928
- if (newVariants.length === 0) return {
929
- variants: [],
930
- isImpossible: true
931
- };
932
- currentVariants = dedupeVariants(newVariants);
933
- }
934
- return {
935
- variants: currentVariants,
936
- isImpossible: false
937
- };
938
- }
939
- /**
940
- * Make OR branches within AND children mutually exclusive.
941
- *
942
- * For an AND child that is OR(A, B), transforms it to OR(A, B & !A)
943
- * so that when andToCSS does a Cartesian product, the resulting
944
- * CSS variants don't overlap.
945
- *
946
- * Only transforms OR children whose branches actually produce
947
- * different at-rule contexts when materialized. This avoids
948
- * breaking cases where contradiction detection in the Cartesian
949
- * product naturally handles deduplication.
950
- */
951
- function makeOrBranchesExclusive(children) {
952
- return children.map((child) => {
953
- if (!isCompoundCondition(child) || child.operator !== "OR") return child;
954
- if (child.children.length <= 1) return child;
955
- if (!branchesProduceDifferentContexts(child.children)) return child;
956
- const exclusiveBranches = [];
957
- const priorBranches = [];
958
- for (const branch of child.children) {
959
- if (priorBranches.length === 0) exclusiveBranches.push(branch);
960
- else {
961
- let exclusive = branch;
962
- for (const prior of priorBranches) exclusive = and(exclusive, not(prior));
963
- const simplified = simplifyCondition(exclusive);
964
- if (simplified.kind !== "false") exclusiveBranches.push(simplified);
965
- }
966
- priorBranches.push(branch);
967
- }
968
- if (exclusiveBranches.length === 0) return child;
969
- if (exclusiveBranches.length === 1) return exclusiveBranches[0];
970
- return {
971
- kind: "compound",
972
- operator: "OR",
973
- children: exclusiveBranches
974
- };
975
- });
976
- }
977
- /**
978
- * Check if OR branches produce different at-rule contexts when
979
- * materialized. If so, the Cartesian product in andToCSS will
980
- * create overlapping CSS variants that need exclusive expansion.
981
- */
982
- function branchesProduceDifferentContexts(branches) {
983
- const contextKeys = /* @__PURE__ */ new Set();
984
- for (const branch of branches) {
985
- const css = conditionToCSSInner(branch);
986
- if (css.isImpossible) continue;
987
- for (const v of css.variants) contextKeys.add(getVariantContextKey(v));
988
- }
989
- return contextKeys.size > 1;
990
- }
991
- /**
992
- * Combine OR conditions into CSS
993
- *
994
- * OR in CSS means multiple selector variants (DNF).
995
- * After deduplication, variants that differ only in their base
996
- * modifier/pseudo conditions are merged into :is() groups.
997
- *
998
- * Note: OR exclusivity is handled at the pipeline level (expandOrConditions),
999
- * so here we just collect all variants. Any remaining ORs in the condition
1000
- * tree (e.g., from De Morgan expansion) are handled as simple alternatives.
1001
- */
1002
- function orToCSS(children) {
1003
- const allVariants = [];
1004
- for (const child of children) {
1005
- const childCSS = conditionToCSSInner(child);
1006
- if (childCSS.isImpossible) continue;
1007
- allVariants.push(...childCSS.variants);
1008
- }
1009
- if (allVariants.length === 0) return {
1010
- variants: [],
1011
- isImpossible: true
1012
- };
1013
- return {
1014
- variants: dedupeVariants(allVariants),
1015
- isImpossible: false
1016
- };
1017
- }
1018
- /**
1019
- * Find keys present in ALL condition arrays.
1020
- */
1021
- function findCommonKeys(conditionSets, getKey) {
1022
- if (conditionSets.length === 0) return /* @__PURE__ */ new Set();
1023
- const common = new Set(conditionSets[0].map(getKey));
1024
- for (let i = 1; i < conditionSets.length; i++) {
1025
- const keys = new Set(conditionSets[i].map(getKey));
1026
- for (const key of common) if (!keys.has(key)) common.delete(key);
1027
- }
1028
- return common;
1029
- }
1030
- /**
1031
- * Merge OR variants that share the same "context" (at-rules, root, parent,
1032
- * own, starting) into a single variant with a SelectorGroup.
1033
- *
1034
- * Variants with no modifier/pseudo conditions are kept separate (they match
1035
- * unconditionally and can't be expressed inside :is()).
1036
- */
1037
- function mergeVariantsIntoSelectorGroups(variants) {
1038
- if (variants.length <= 1) return variants;
1039
- const groups = /* @__PURE__ */ new Map();
1040
- for (const v of variants) {
1041
- const key = getVariantContextKey(v);
1042
- const group = groups.get(key);
1043
- if (group) group.push(v);
1044
- else groups.set(key, [v]);
1045
- }
1046
- const result = [];
1047
- for (const group of groups.values()) {
1048
- if (group.length === 1) {
1049
- result.push(group[0]);
1050
- continue;
1051
- }
1052
- const withSelectors = [];
1053
- const withoutSelectors = [];
1054
- for (const v of group) if (v.modifierConditions.length === 0 && v.pseudoConditions.length === 0) withoutSelectors.push(v);
1055
- else withSelectors.push(v);
1056
- result.push(...withoutSelectors);
1057
- if (withSelectors.length <= 1) {
1058
- result.push(...withSelectors);
1059
- continue;
1060
- }
1061
- result.push(factorAndGroup(withSelectors));
1062
- }
1063
- return result;
1064
- }
1065
- /**
1066
- * Factor common modifier/pseudo conditions out of variants and create
1067
- * a single variant with a SelectorGroup for the remaining (differing)
1068
- * conditions.
1069
- *
1070
- * Precondition: all variants must share the same context key (identical
1071
- * at-rules, root/parent/own/selector groups, startingStyle).
1072
- */
1073
- function factorAndGroup(variants) {
1074
- {
1075
- const key0 = getVariantContextKey(variants[0]);
1076
- for (let i = 1; i < variants.length; i++) {
1077
- const keyI = getVariantContextKey(variants[i]);
1078
- if (keyI !== key0) throw new Error(`factorAndGroup: context key mismatch at index ${i}.\n expected: ${key0}\n got: ${keyI}`);
1079
- }
1080
- }
1081
- const commonModKeys = findCommonKeys(variants.map((v) => v.modifierConditions), getModifierKey);
1082
- const commonPseudoKeys = findCommonKeys(variants.map((v) => v.pseudoConditions), getPseudoKey);
1083
- const commonModifiers = variants[0].modifierConditions.filter((m) => commonModKeys.has(getModifierKey(m)));
1084
- const commonPseudos = variants[0].pseudoConditions.filter((p) => commonPseudoKeys.has(getPseudoKey(p)));
1085
- const branches = [];
1086
- let hasEmptyBranch = false;
1087
- for (const v of variants) {
1088
- const branch = [];
1089
- for (const mod of v.modifierConditions) if (!commonModKeys.has(getModifierKey(mod))) branch.push(mod);
1090
- for (const pseudo of v.pseudoConditions) if (!commonPseudoKeys.has(getPseudoKey(pseudo))) branch.push(pseudo);
1091
- if (branch.length > 0) branches.push(branch);
1092
- else hasEmptyBranch = true;
1093
- }
1094
- if (hasEmptyBranch) return {
1095
- ...variants[0],
1096
- modifierConditions: commonModifiers,
1097
- pseudoConditions: commonPseudos
1098
- };
1099
- return {
1100
- modifierConditions: commonModifiers,
1101
- pseudoConditions: commonPseudos,
1102
- selectorGroups: [...variants[0].selectorGroups, {
1103
- branches,
1104
- negated: false
1105
- }],
1106
- ownGroups: [...variants[0].ownGroups],
1107
- mediaConditions: [...variants[0].mediaConditions],
1108
- containerConditions: [...variants[0].containerConditions],
1109
- supportsConditions: [...variants[0].supportsConditions],
1110
- rootGroups: [...variants[0].rootGroups],
1111
- parentGroups: [...variants[0].parentGroups],
1112
- startingStyle: variants[0].startingStyle
1113
- };
1114
- }
1115
- /**
1116
- * Build at-rules array from a variant
1117
- */
1118
- function buildAtRulesFromVariant(variant) {
1119
- const atRules = [];
1120
- if (variant.mediaConditions.length > 0) {
1121
- const conditionParts = variant.mediaConditions.map((c) => {
1122
- if (c.subtype === "type") return c.negated ? `not ${c.condition}` : c.condition;
1123
- else return c.negated ? `(not ${c.condition})` : c.condition;
1124
- });
1125
- atRules.push(`@media ${conditionParts.join(" and ")}`);
1126
- }
1127
- if (variant.containerConditions.length > 0) {
1128
- const byName = /* @__PURE__ */ new Map();
1129
- for (const cond of variant.containerConditions) {
1130
- const group = byName.get(cond.name) || [];
1131
- group.push(cond);
1132
- byName.set(cond.name, group);
1133
- }
1134
- for (const [name, conditions] of byName) {
1135
- const conditionParts = conditions.map((c) => c.negated ? `(not ${c.condition})` : c.condition);
1136
- const namePrefix = name ? `${name} ` : "";
1137
- atRules.push(`@container ${namePrefix}${conditionParts.join(" and ")}`);
1138
- }
1139
- }
1140
- if (variant.supportsConditions.length > 0) {
1141
- const conditionParts = variant.supportsConditions.map((c) => {
1142
- if (c.subtype === "selector") {
1143
- const selectorCond = `selector(${c.condition})`;
1144
- return c.negated ? `(not ${selectorCond})` : selectorCond;
1145
- } else {
1146
- const featureCond = `(${c.condition})`;
1147
- return c.negated ? `(not ${featureCond})` : featureCond;
1148
- }
1149
- });
1150
- atRules.push(`@supports ${conditionParts.join(" and ")}`);
1151
- }
1152
- return atRules;
1153
- }
1154
- //#endregion
1155
- export { branchToCSS, buildAtRulesFromVariant, conditionToCSS, mergeVariantsIntoSelectorGroups, optimizeGroups, parentGroupsToCSS, rootGroupsToCSS, selectorGroupToCSS };
1156
-
1157
- //# sourceMappingURL=materialize.js.map