@drskillissue/ganko 0.2.72 → 0.2.81

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.
@@ -225,7 +225,6 @@ var CHAR_DOUBLE_QUOTE = 34;
225
225
  var CHAR_SINGLE_QUOTE = 39;
226
226
  var CHAR_A = 97;
227
227
  var CHAR_E = 101;
228
- var CHAR_H = 104;
229
228
  var CHAR_I = 105;
230
229
  var CHAR_M = 109;
231
230
  var CHAR_N = 110;
@@ -596,7 +595,6 @@ var ID_STICKY = /#([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
596
595
  var CLASS_STICKY = /\.([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
597
596
  var ATTRIBUTE_STICKY = /\[([^\]]+)\]/y;
598
597
  var PSEUDO_ELEMENT_STICKY = /::([a-zA-Z-]+)(?:\([^)]*\))?/y;
599
- var PSEUDO_CLASS_STICKY = /:([a-zA-Z-]+)(?:\([^)]*\))?/y;
600
598
  var ELEMENT_STICKY = /([a-zA-Z][a-zA-Z0-9-]*)/y;
601
599
  var WHITESPACE_SPLIT = /\s+/;
602
600
  var FUNCTION_CALL_RE = /([a-zA-Z_][\w-]*)\s*\(/g;
@@ -3535,6 +3533,10 @@ function getStaticStringFromJSXValue(node) {
3535
3533
  if (import_typescript4.default.isTemplateExpression(expression) && expression.templateSpans.length === 0) {
3536
3534
  return expression.head.text;
3537
3535
  }
3536
+ if (import_typescript4.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript4.default.SyntaxKind.QuestionQuestionToken) {
3537
+ const fallback = getStaticStringFromJSXValue(expression.right);
3538
+ if (fallback !== null) return fallback;
3539
+ }
3538
3540
  }
3539
3541
  return null;
3540
3542
  }
@@ -22981,7 +22983,7 @@ function splitWhitespaceTokens(value2) {
22981
22983
  return out;
22982
22984
  }
22983
22985
  function parseQuadShorthand(raw) {
22984
- const parts = splitWhitespaceTokens(raw);
22986
+ const parts = splitTopLevelWhitespace(raw);
22985
22987
  if (parts.length === 1) {
22986
22988
  const p0 = parts[0];
22987
22989
  if (!p0) return null;
@@ -23005,7 +23007,7 @@ function parseQuadShorthand(raw) {
23005
23007
  return null;
23006
23008
  }
23007
23009
  function parseBlockShorthand(raw) {
23008
- const parts = splitWhitespaceTokens(raw);
23010
+ const parts = splitTopLevelWhitespace(raw);
23009
23011
  if (parts.length === 1) {
23010
23012
  const p0 = parts[0];
23011
23013
  if (!p0) return null;
@@ -23090,8 +23092,14 @@ var NUMERIC_VALUE = /^([0-9]*\.?[0-9]+)(px|rem|em|pt)?$/;
23090
23092
  function parsePxValue(raw, contextFontSize = 16) {
23091
23093
  const trimmed = raw.trim().toLowerCase();
23092
23094
  if (trimmed.length === 0) return null;
23093
- if (trimmed.includes("var(") || trimmed.includes("calc(") || trimmed.includes("%")) return null;
23095
+ if (trimmed.includes("var(") || trimmed.includes("%")) return null;
23094
23096
  if (CSS_WIDE_KEYWORDS.has(trimmed)) return null;
23097
+ if (trimmed.includes("calc(")) {
23098
+ return tryEvalConstantCalc(trimmed, contextFontSize);
23099
+ }
23100
+ if (trimmed.startsWith("min(") || trimmed.startsWith("max(") || trimmed.startsWith("clamp(")) {
23101
+ return tryEvalMathFunction(trimmed, contextFontSize);
23102
+ }
23095
23103
  const match = NUMERIC_VALUE.exec(trimmed);
23096
23104
  if (!match) return null;
23097
23105
  const num = Number(match[1]);
@@ -23102,6 +23110,135 @@ function parsePxValue(raw, contextFontSize = 16) {
23102
23110
  if (unit === "pt") return num * 1.333;
23103
23111
  return null;
23104
23112
  }
23113
+ var CALC_CONSTANT_RE = /^calc\((.+)\)$/;
23114
+ var CALC_TOKEN_RE = /([0-9]*\.?[0-9]+)(px|rem|em|pt)?|([+\-*/])/g;
23115
+ function tryEvalConstantCalc(raw, contextFontSize) {
23116
+ const match = CALC_CONSTANT_RE.exec(raw);
23117
+ if (!match || !match[1]) return null;
23118
+ const inner = match[1].trim();
23119
+ if (inner.includes("var(") || inner.includes("%") || inner.includes("env(") || inner.includes("calc(")) return null;
23120
+ const values = [];
23121
+ const operators = [];
23122
+ let lastWasValue = false;
23123
+ CALC_TOKEN_RE.lastIndex = 0;
23124
+ let tokenMatch;
23125
+ while ((tokenMatch = CALC_TOKEN_RE.exec(inner)) !== null) {
23126
+ const op = tokenMatch[3];
23127
+ if (op !== void 0) {
23128
+ if (!lastWasValue && op === "-") {
23129
+ const nextToken = CALC_TOKEN_RE.exec(inner);
23130
+ if (!nextToken || nextToken[3] !== void 0) return null;
23131
+ const px2 = calcTokenToPx(nextToken, contextFontSize);
23132
+ if (px2 === null) return null;
23133
+ values.push(-px2);
23134
+ lastWasValue = true;
23135
+ continue;
23136
+ }
23137
+ if (!lastWasValue) return null;
23138
+ operators.push(op);
23139
+ lastWasValue = false;
23140
+ continue;
23141
+ }
23142
+ const px = calcTokenToPx(tokenMatch, contextFontSize);
23143
+ if (px === null) return null;
23144
+ values.push(px);
23145
+ lastWasValue = true;
23146
+ }
23147
+ if (values.length === 0 || values.length !== operators.length + 1) return null;
23148
+ const firstValue = values[0];
23149
+ if (firstValue === void 0) return null;
23150
+ const reducedValues = [firstValue];
23151
+ const reducedOps = [];
23152
+ for (let i = 0; i < operators.length; i++) {
23153
+ const op = operators[i];
23154
+ const right = values[i + 1];
23155
+ if (op === void 0 || right === void 0) return null;
23156
+ if (op === "*") {
23157
+ const last = reducedValues[reducedValues.length - 1];
23158
+ if (last === void 0) return null;
23159
+ reducedValues[reducedValues.length - 1] = last * right;
23160
+ } else if (op === "/") {
23161
+ if (right === 0) return null;
23162
+ const last = reducedValues[reducedValues.length - 1];
23163
+ if (last === void 0) return null;
23164
+ reducedValues[reducedValues.length - 1] = last / right;
23165
+ } else {
23166
+ reducedValues.push(right);
23167
+ reducedOps.push(op);
23168
+ }
23169
+ }
23170
+ const base = reducedValues[0];
23171
+ if (base === void 0) return null;
23172
+ let result = base;
23173
+ for (let i = 0; i < reducedOps.length; i++) {
23174
+ const op = reducedOps[i];
23175
+ const right = reducedValues[i + 1];
23176
+ if (op === void 0 || right === void 0) return null;
23177
+ if (op === "+") result += right;
23178
+ else if (op === "-") result -= right;
23179
+ else return null;
23180
+ }
23181
+ return Number.isFinite(result) ? result : null;
23182
+ }
23183
+ function calcTokenToPx(tokenMatch, contextFontSize) {
23184
+ const num = Number(tokenMatch[1]);
23185
+ if (Number.isNaN(num)) return null;
23186
+ const unit = tokenMatch[2] ?? "";
23187
+ if (unit === "px" || unit === "") return num;
23188
+ if (unit === "rem") return num * 16;
23189
+ if (unit === "em") return num * contextFontSize;
23190
+ if (unit === "pt") return num * 1.333;
23191
+ return null;
23192
+ }
23193
+ var MATH_FN_RE = /^(min|max|clamp)\((.+)\)$/;
23194
+ function tryEvalMathFunction(raw, contextFontSize) {
23195
+ const match = MATH_FN_RE.exec(raw);
23196
+ if (!match || !match[1] || !match[2]) return null;
23197
+ const fn = match[1];
23198
+ const inner = match[2];
23199
+ const args = splitMathArgs(inner);
23200
+ if (args === null) return null;
23201
+ const values = [];
23202
+ for (let i = 0; i < args.length; i++) {
23203
+ const arg = args[i];
23204
+ if (!arg) return null;
23205
+ const px = parsePxValue(arg.trim(), contextFontSize);
23206
+ if (px === null) return null;
23207
+ values.push(px);
23208
+ }
23209
+ if (values.length === 0) return null;
23210
+ if (fn === "min") return Math.min(...values);
23211
+ if (fn === "max") return Math.max(...values);
23212
+ if (fn === "clamp") {
23213
+ if (values.length !== 3) return null;
23214
+ const [lo, val, hi] = values;
23215
+ return Math.max(lo, Math.min(val, hi));
23216
+ }
23217
+ return null;
23218
+ }
23219
+ function splitMathArgs(inner) {
23220
+ const args = [];
23221
+ let depth = 0;
23222
+ let start = 0;
23223
+ for (let i = 0; i < inner.length; i++) {
23224
+ const ch = inner[i];
23225
+ if (ch === "(") depth++;
23226
+ else if (ch === ")") {
23227
+ if (depth > 0) depth--;
23228
+ else return null;
23229
+ } else if (ch === "," && depth === 0) {
23230
+ const arg = inner.slice(start, i).trim();
23231
+ if (arg.length === 0) return null;
23232
+ args.push(arg);
23233
+ start = i + 1;
23234
+ }
23235
+ }
23236
+ if (depth !== 0) return null;
23237
+ const tail = inner.slice(start).trim();
23238
+ if (tail.length === 0) return null;
23239
+ args.push(tail);
23240
+ return args;
23241
+ }
23105
23242
  function parseUnitlessValue(raw) {
23106
23243
  const trimmed = raw.trim().toLowerCase();
23107
23244
  if (trimmed.length === 0) return null;
@@ -23503,19 +23640,6 @@ var FONT_GENERIC_FAMILY_SET = /* @__PURE__ */ new Set([
23503
23640
  ]);
23504
23641
  var FONT_LAYOUT_PROPERTIES = /* @__PURE__ */ new Set(["font-family"]);
23505
23642
  var WHITESPACE_RE2 = /\s+/;
23506
- function classifyRuleElementKinds(rule) {
23507
- const kinds = rule.elementKinds;
23508
- for (let i = 0; i < rule.selectors.length; i++) {
23509
- const sel = rule.selectors[i];
23510
- if (!sel) continue;
23511
- const parts = sel.parts;
23512
- for (let j = 0; j < parts.length; j++) {
23513
- const part = parts[j];
23514
- if (!part) continue;
23515
- classifyPart(part, kinds);
23516
- }
23517
- }
23518
- }
23519
23643
  function classifyPart(part, kinds) {
23520
23644
  if (part.type === "element") {
23521
23645
  const lower = part.value.toLowerCase();
@@ -23643,7 +23767,19 @@ var CSSGraph = class {
23643
23767
  parseErrors = [];
23644
23768
  failedFilePaths = [];
23645
23769
  tokenCategories = [];
23646
- filesWithLayers = /* @__PURE__ */ new Set();
23770
+ _filesWithLayers = null;
23771
+ get filesWithLayers() {
23772
+ if (this._filesWithLayers === null) {
23773
+ const result = /* @__PURE__ */ new Set();
23774
+ for (let i = 0; i < this.layers.length; i++) {
23775
+ const layer = this.layers[i];
23776
+ if (!layer) continue;
23777
+ result.add(layer.file.path);
23778
+ }
23779
+ this._filesWithLayers = result;
23780
+ }
23781
+ return this._filesWithLayers;
23782
+ }
23647
23783
  selectorsByPseudoClass = /* @__PURE__ */ new Map();
23648
23784
  knownKeyframeNames = /* @__PURE__ */ new Set();
23649
23785
  unresolvedAnimationRefs = [];
@@ -23655,17 +23791,61 @@ var CSSGraph = class {
23655
23791
  multiDeclarationProperties = /* @__PURE__ */ new Map();
23656
23792
  /** Declarations whose parent rule is inside a @keyframes block. */
23657
23793
  keyframeDeclarations = [];
23658
- /** Rules with zero declarations and zero nested rules. */
23659
- emptyRules = [];
23794
+ /** Rules with zero declarations, zero nested rules, and zero nested at-rules. */
23795
+ _emptyRules = null;
23796
+ get emptyRules() {
23797
+ if (this._emptyRules === null) {
23798
+ this._emptyRules = this.rules.filter((r) => r.declarations.length === 0 && r.nestedRules.length === 0 && r.nestedAtRules.length === 0);
23799
+ }
23800
+ return this._emptyRules;
23801
+ }
23660
23802
  /** @keyframes at-rules with no effective keyframe declarations. */
23661
- emptyKeyframes = [];
23662
- colorDeclarations = [];
23663
- calcDeclarations = [];
23664
- varDeclarations = [];
23665
- urlDeclarations = [];
23666
- vendorPrefixedDeclarations = [];
23667
- hardcodedColorDeclarations = [];
23668
- overqualifiedSelectors = [];
23803
+ _emptyKeyframes = null;
23804
+ get emptyKeyframes() {
23805
+ if (this._emptyKeyframes === null) {
23806
+ const result = [];
23807
+ for (let i = 0; i < this.keyframes.length; i++) {
23808
+ const kf = this.keyframes[i];
23809
+ if (!kf) continue;
23810
+ if (!kf.parsedParams.animationName) continue;
23811
+ if (kf.rules.length === 0) {
23812
+ result.push(kf);
23813
+ continue;
23814
+ }
23815
+ let hasDeclaration = false;
23816
+ for (let j = 0; j < kf.rules.length; j++) {
23817
+ const kfRule = kf.rules[j];
23818
+ if (!kfRule) continue;
23819
+ if (kfRule.declarations.length > 0) {
23820
+ hasDeclaration = true;
23821
+ break;
23822
+ }
23823
+ }
23824
+ if (!hasDeclaration) result.push(kf);
23825
+ }
23826
+ this._emptyKeyframes = result;
23827
+ }
23828
+ return this._emptyKeyframes;
23829
+ }
23830
+ _overqualifiedSelectors = null;
23831
+ get overqualifiedSelectors() {
23832
+ if (this._overqualifiedSelectors === null) {
23833
+ const result = [];
23834
+ for (let i = 0, len = this.idSelectors.length; i < len; i++) {
23835
+ const sel = this.idSelectors[i];
23836
+ if (!sel) continue;
23837
+ const compounds = sel.compounds;
23838
+ if (compounds.length === 0) continue;
23839
+ const subject = compounds[compounds.length - 1];
23840
+ if (!subject) continue;
23841
+ if (subject.idValue !== null && (subject.tagName !== null || subject.classes.length > 0 || subject.attributes.length > 0)) {
23842
+ result.push(sel);
23843
+ }
23844
+ }
23845
+ this._overqualifiedSelectors = result;
23846
+ }
23847
+ return this._overqualifiedSelectors;
23848
+ }
23669
23849
  idSelectors = [];
23670
23850
  attributeSelectors = [];
23671
23851
  universalSelectors = [];
@@ -23681,7 +23861,13 @@ var CSSGraph = class {
23681
23861
  usedFontFamilies = /* @__PURE__ */ new Set();
23682
23862
  /** Tailwind validator for utility class lookup (null if not a Tailwind project). */
23683
23863
  tailwind;
23684
- deepNestedRules = [];
23864
+ _deepNestedRules = null;
23865
+ get deepNestedRules() {
23866
+ if (this._deepNestedRules === null) {
23867
+ this._deepNestedRules = this.rules.filter((r) => r.depth > 3);
23868
+ }
23869
+ return this._deepNestedRules;
23870
+ }
23685
23871
  constructor(input) {
23686
23872
  this.options = input.options ?? {};
23687
23873
  this.tailwind = input.tailwind ?? null;
@@ -23746,13 +23932,57 @@ var CSSGraph = class {
23746
23932
  }
23747
23933
  addSelector(selector) {
23748
23934
  this.selectors.push(selector);
23935
+ const anchor = selector.anchor;
23936
+ if (anchor.subjectTag === null) {
23937
+ this.selectorsWithoutSubjectTag.push(selector);
23938
+ } else {
23939
+ const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
23940
+ if (existingByTag) existingByTag.push(selector);
23941
+ else this.selectorsBySubjectTag.set(anchor.subjectTag, [selector]);
23942
+ }
23943
+ if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(selector);
23944
+ if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(selector);
23945
+ const compounds = selector.compounds;
23946
+ for (let ci = 0; ci < compounds.length; ci++) {
23947
+ const compound = compounds[ci];
23948
+ if (!compound) continue;
23949
+ const cls = compound.classes;
23950
+ for (let j = 0; j < cls.length; j++) {
23951
+ const className = cls[j];
23952
+ if (!className) continue;
23953
+ const existing = this.classNameIndex.get(className);
23954
+ if (existing) existing.push(selector);
23955
+ else this.classNameIndex.set(className, [selector]);
23956
+ }
23957
+ }
23958
+ const complexity = selector.complexity;
23959
+ const flags = complexity._flags;
23960
+ if (hasFlag(flags, SEL_HAS_ID)) this.idSelectors.push(selector);
23961
+ if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(selector);
23962
+ if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(selector);
23963
+ const pseudoClasses = complexity.pseudoClasses;
23964
+ for (let j = 0; j < pseudoClasses.length; j++) {
23965
+ const pc = pseudoClasses[j];
23966
+ if (!pc) continue;
23967
+ const pcExisting = this.selectorsByPseudoClass.get(pc);
23968
+ if (pcExisting) pcExisting.push(selector);
23969
+ else this.selectorsByPseudoClass.set(pc, [selector]);
23970
+ }
23749
23971
  }
23750
23972
  addDeclaration(decl) {
23751
23973
  this.declarations.push(decl);
23752
- const existing = this.declarationsByProperty.get(decl.property);
23974
+ const property = decl.property;
23975
+ const existing = this.declarationsByProperty.get(property);
23753
23976
  if (existing) existing.push(decl);
23754
- else this.declarationsByProperty.set(decl.property, [decl]);
23977
+ else this.declarationsByProperty.set(property, [decl]);
23755
23978
  if (hasFlag(decl._flags, DECL_IS_IMPORTANT) || decl.node.important) this.importantDeclarations.push(decl);
23979
+ if (decl.rule !== null) {
23980
+ const p = property.toLowerCase();
23981
+ const ruleIndex = decl.rule.declarationIndex;
23982
+ const ruleExisting = ruleIndex.get(p);
23983
+ if (ruleExisting) ruleExisting.push(decl);
23984
+ else ruleIndex.set(p, [decl]);
23985
+ }
23756
23986
  }
23757
23987
  addVariable(variable) {
23758
23988
  this.variables.push(variable);
@@ -23886,39 +24116,12 @@ var CSSGraph = class {
23886
24116
  * Called after all phases complete.
23887
24117
  */
23888
24118
  buildDerivedIndexes() {
23889
- this.buildRuleDeclarationIndexes();
23890
24119
  this.buildContainingMediaStacks();
23891
- this.buildKeyframeIndex();
24120
+ this.buildKeyframeIndexes();
23892
24121
  this.buildContainerNameIndexes();
23893
- this.buildElementKinds();
23894
- this.buildFilesWithLayers();
23895
- this.buildSelectorPseudoClassIndex();
23896
24122
  this.buildMultiDeclarationProperties();
23897
- this.buildKeyframeDeclarations();
23898
- this.buildKeyframeLayoutMutationsByName();
23899
- this.buildEmptyRules();
23900
- this.buildEmptyKeyframes();
23901
- this.buildDeclarationDerivedIndexes();
23902
- this.buildSelectorDerivedIndexes();
23903
24123
  this.buildLayoutPropertiesByClassToken();
23904
- this.buildFontFamilyUsageByRule();
23905
- this.buildFontFaceDescriptorsByFamily();
23906
- this.buildRuleDerivedIndexes();
23907
- }
23908
- buildRuleDeclarationIndexes() {
23909
- for (let i = 0; i < this.rules.length; i++) {
23910
- const rule = this.rules[i];
23911
- if (!rule) continue;
23912
- const index = rule.declarationIndex;
23913
- for (let j = 0; j < rule.declarations.length; j++) {
23914
- const d = rule.declarations[j];
23915
- if (!d) continue;
23916
- const p = d.property.toLowerCase();
23917
- const existing = index.get(p);
23918
- if (existing) existing.push(d);
23919
- else index.set(p, [d]);
23920
- }
23921
- }
24124
+ this.buildFontIndexes();
23922
24125
  }
23923
24126
  buildContainingMediaStacks() {
23924
24127
  for (let i = 0; i < this.rules.length; i++) {
@@ -23933,7 +24136,7 @@ var CSSGraph = class {
23933
24136
  rule.containingMediaStack = medias;
23934
24137
  }
23935
24138
  }
23936
- buildKeyframeIndex() {
24139
+ buildKeyframeIndexes() {
23937
24140
  const IGNORED = /* @__PURE__ */ new Set([...CSS_WIDE_KEYWORDS, "none"]);
23938
24141
  for (let i = 0; i < this.keyframes.length; i++) {
23939
24142
  const kf = this.keyframes[i];
@@ -23955,6 +24158,47 @@ var CSSGraph = class {
23955
24158
  this.unresolvedAnimationRefs.push({ declaration: d, name });
23956
24159
  }
23957
24160
  }
24161
+ const byAnimationByProperty = /* @__PURE__ */ new Map();
24162
+ for (let i = 0; i < this.declarations.length; i++) {
24163
+ const d = this.declarations[i];
24164
+ if (!d) continue;
24165
+ const rule = d.rule;
24166
+ if (!rule) continue;
24167
+ const parent = rule.parent;
24168
+ if (!parent) continue;
24169
+ if (parent.kind === "rule") continue;
24170
+ if (parent.kind !== "keyframes") continue;
24171
+ this.keyframeDeclarations.push(d);
24172
+ const property = d.property.toLowerCase();
24173
+ if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
24174
+ const animationName = normalizeAnimationName(parent.params);
24175
+ if (!animationName) continue;
24176
+ let byProperty = byAnimationByProperty.get(animationName);
24177
+ if (!byProperty) {
24178
+ byProperty = /* @__PURE__ */ new Map();
24179
+ byAnimationByProperty.set(animationName, byProperty);
24180
+ }
24181
+ let bucket = byProperty.get(property);
24182
+ if (!bucket) {
24183
+ bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
24184
+ byProperty.set(property, bucket);
24185
+ }
24186
+ bucket.values.add(normalizeCssValue(d.value));
24187
+ bucket.declarations.push(d);
24188
+ }
24189
+ for (const [animationName, byProperty] of byAnimationByProperty) {
24190
+ const mutations = [];
24191
+ for (const [property, bucket] of byProperty) {
24192
+ if (bucket.values.size <= 1) continue;
24193
+ mutations.push({
24194
+ property,
24195
+ values: [...bucket.values],
24196
+ declarations: bucket.declarations
24197
+ });
24198
+ }
24199
+ if (mutations.length === 0) continue;
24200
+ this.keyframeLayoutMutationsByName.set(animationName, mutations);
24201
+ }
23958
24202
  }
23959
24203
  buildContainerNameIndexes() {
23960
24204
  for (let i = 0; i < this.declarations.length; i++) {
@@ -23998,34 +24242,6 @@ var CSSGraph = class {
23998
24242
  }
23999
24243
  }
24000
24244
  }
24001
- buildElementKinds() {
24002
- for (let i = 0; i < this.rules.length; i++) {
24003
- const rule = this.rules[i];
24004
- if (!rule) continue;
24005
- classifyRuleElementKinds(rule);
24006
- }
24007
- }
24008
- buildFilesWithLayers() {
24009
- for (let i = 0; i < this.layers.length; i++) {
24010
- const layer = this.layers[i];
24011
- if (!layer) continue;
24012
- this.filesWithLayers.add(layer.file.path);
24013
- }
24014
- }
24015
- buildSelectorPseudoClassIndex() {
24016
- for (let i = 0; i < this.selectors.length; i++) {
24017
- const sel = this.selectors[i];
24018
- if (!sel) continue;
24019
- const pseudoClasses = sel.complexity.pseudoClasses;
24020
- for (let j = 0; j < pseudoClasses.length; j++) {
24021
- const pc = pseudoClasses[j];
24022
- if (!pc) continue;
24023
- const existing = this.selectorsByPseudoClass.get(pc);
24024
- if (existing) existing.push(sel);
24025
- else this.selectorsByPseudoClass.set(pc, [sel]);
24026
- }
24027
- }
24028
- }
24029
24245
  /**
24030
24246
  * Sort each declarationsByProperty list by sourceOrder and populate
24031
24247
  * multiDeclarationProperties with only those having 2+ entries.
@@ -24038,162 +24254,6 @@ var CSSGraph = class {
24038
24254
  }
24039
24255
  }
24040
24256
  }
24041
- /**
24042
- * Collect declarations whose parent rule is inside a @keyframes block.
24043
- */
24044
- buildKeyframeDeclarations() {
24045
- for (let i = 0; i < this.declarations.length; i++) {
24046
- const d = this.declarations[i];
24047
- if (!d) continue;
24048
- const rule = d.rule;
24049
- if (!rule) continue;
24050
- const parent = rule.parent;
24051
- if (!parent) continue;
24052
- if (parent.kind === "rule") continue;
24053
- if (parent.kind !== "keyframes") continue;
24054
- this.keyframeDeclarations.push(d);
24055
- }
24056
- }
24057
- buildKeyframeLayoutMutationsByName() {
24058
- const byAnimationByProperty = /* @__PURE__ */ new Map();
24059
- for (let i = 0; i < this.keyframeDeclarations.length; i++) {
24060
- const declaration = this.keyframeDeclarations[i];
24061
- if (!declaration) continue;
24062
- const rule = declaration.rule;
24063
- if (!rule || rule.parent === null || rule.parent.kind !== "keyframes") continue;
24064
- const property = declaration.property.toLowerCase();
24065
- if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
24066
- const animationName = normalizeAnimationName(rule.parent.params);
24067
- if (!animationName) continue;
24068
- let byProperty = byAnimationByProperty.get(animationName);
24069
- if (!byProperty) {
24070
- byProperty = /* @__PURE__ */ new Map();
24071
- byAnimationByProperty.set(animationName, byProperty);
24072
- }
24073
- let bucket = byProperty.get(property);
24074
- if (!bucket) {
24075
- bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
24076
- byProperty.set(property, bucket);
24077
- }
24078
- bucket.values.add(normalizeCssValue(declaration.value));
24079
- bucket.declarations.push(declaration);
24080
- }
24081
- for (const [animationName, byProperty] of byAnimationByProperty) {
24082
- const mutations = [];
24083
- for (const [property, bucket] of byProperty) {
24084
- if (bucket.values.size <= 1) continue;
24085
- mutations.push({
24086
- property,
24087
- values: [...bucket.values],
24088
- declarations: bucket.declarations
24089
- });
24090
- }
24091
- if (mutations.length === 0) continue;
24092
- this.keyframeLayoutMutationsByName.set(animationName, mutations);
24093
- }
24094
- }
24095
- /**
24096
- * Collect rules with no declarations and no nested rules.
24097
- */
24098
- buildEmptyRules() {
24099
- for (let i = 0; i < this.rules.length; i++) {
24100
- const rule = this.rules[i];
24101
- if (!rule) continue;
24102
- if (rule.declarations.length === 0 && rule.nestedRules.length === 0) {
24103
- this.emptyRules.push(rule);
24104
- }
24105
- }
24106
- }
24107
- /**
24108
- * Collect @keyframes with no effective keyframe declarations.
24109
- */
24110
- buildEmptyKeyframes() {
24111
- for (let i = 0; i < this.keyframes.length; i++) {
24112
- const kf = this.keyframes[i];
24113
- if (!kf) continue;
24114
- if (!kf.parsedParams.animationName) continue;
24115
- if (kf.rules.length === 0) {
24116
- this.emptyKeyframes.push(kf);
24117
- continue;
24118
- }
24119
- let hasDeclaration = false;
24120
- for (let j = 0; j < kf.rules.length; j++) {
24121
- const kfRule = kf.rules[j];
24122
- if (!kfRule) continue;
24123
- if (kfRule.declarations.length > 0) {
24124
- hasDeclaration = true;
24125
- break;
24126
- }
24127
- }
24128
- if (!hasDeclaration) this.emptyKeyframes.push(kf);
24129
- }
24130
- }
24131
- buildDeclarationDerivedIndexes() {
24132
- const HARDCODED_HEX = /^#[0-9a-f]{3,8}$/i;
24133
- for (let i = 0, len = this.declarations.length; i < len; i++) {
24134
- const d = this.declarations[i];
24135
- if (!d) continue;
24136
- const pv = d.parsedValue;
24137
- if (pv.colors.length > 0) this.colorDeclarations.push(d);
24138
- if (pv.hasCalc) this.calcDeclarations.push(d);
24139
- if (pv.hasVar) this.varDeclarations.push(d);
24140
- if (pv.hasUrl) this.urlDeclarations.push(d);
24141
- if (d.property.charCodeAt(0) === CHAR_HYPHEN && d.property.charCodeAt(1) !== CHAR_HYPHEN) {
24142
- this.vendorPrefixedDeclarations.push(d);
24143
- }
24144
- if (!pv.hasVar && pv.colors.length > 0) {
24145
- for (let j = 0, clen = pv.colors.length; j < clen; j++) {
24146
- const c = pv.colors[j];
24147
- if (!c) continue;
24148
- if (HARDCODED_HEX.test(c) || c.charCodeAt(0) === CHAR_R || c.charCodeAt(0) === CHAR_H) {
24149
- this.hardcodedColorDeclarations.push(d);
24150
- break;
24151
- }
24152
- }
24153
- }
24154
- }
24155
- }
24156
- buildSelectorDerivedIndexes() {
24157
- for (let i = 0, len = this.selectors.length; i < len; i++) {
24158
- const sel = this.selectors[i];
24159
- if (!sel) continue;
24160
- const parts = sel.parts;
24161
- const anchor = sel.anchor;
24162
- if (anchor.subjectTag === null) {
24163
- this.selectorsWithoutSubjectTag.push(sel);
24164
- } else {
24165
- const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
24166
- if (existingByTag) existingByTag.push(sel);
24167
- else this.selectorsBySubjectTag.set(anchor.subjectTag, [sel]);
24168
- }
24169
- if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(sel);
24170
- if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(sel);
24171
- for (let j = 0, plen = parts.length; j < plen; j++) {
24172
- const part = parts[j];
24173
- if (!part) continue;
24174
- if (part.type === "class") {
24175
- const existing = this.classNameIndex.get(part.value);
24176
- if (existing) existing.push(sel);
24177
- else this.classNameIndex.set(part.value, [sel]);
24178
- }
24179
- }
24180
- const flags = sel.complexity._flags;
24181
- if (hasFlag(flags, SEL_HAS_ID)) {
24182
- this.idSelectors.push(sel);
24183
- for (let j = 0, plen = parts.length; j < plen; j++) {
24184
- const p = parts[j];
24185
- if (!p) continue;
24186
- const t = p.type;
24187
- if (t === "element" || t === "class" || t === "attribute") {
24188
- this.overqualifiedSelectors.push(sel);
24189
- break;
24190
- }
24191
- }
24192
- }
24193
- if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(sel);
24194
- if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(sel);
24195
- }
24196
- }
24197
24257
  buildLayoutPropertiesByClassToken() {
24198
24258
  const byClass = /* @__PURE__ */ new Map();
24199
24259
  for (let i = 0; i < this.selectors.length; i++) {
@@ -24224,7 +24284,7 @@ var CSSGraph = class {
24224
24284
  this.layoutPropertiesByClassToken.set(className, [...properties]);
24225
24285
  }
24226
24286
  }
24227
- buildFontFamilyUsageByRule() {
24287
+ buildFontIndexes() {
24228
24288
  const declarations = this.declarationsForProperties(...FONT_LAYOUT_PROPERTIES);
24229
24289
  for (let i = 0; i < declarations.length; i++) {
24230
24290
  const declaration = declarations[i];
@@ -24251,8 +24311,6 @@ var CSSGraph = class {
24251
24311
  }
24252
24312
  this.usedFontFamiliesByRule.set(rule.id, [...merged]);
24253
24313
  }
24254
- }
24255
- buildFontFaceDescriptorsByFamily() {
24256
24314
  const byFamily = /* @__PURE__ */ new Map();
24257
24315
  for (let i = 0; i < this.fontFaces.length; i++) {
24258
24316
  const fontFace = this.fontFaces[i];
@@ -24284,13 +24342,6 @@ var CSSGraph = class {
24284
24342
  this.fontFaceDescriptorsByFamily.set(family, descriptors);
24285
24343
  }
24286
24344
  }
24287
- buildRuleDerivedIndexes() {
24288
- for (let i = 0, len = this.rules.length; i < len; i++) {
24289
- const rule = this.rules[i];
24290
- if (!rule) continue;
24291
- if (rule.depth > 3) this.deepNestedRules.push(rule);
24292
- }
24293
- }
24294
24345
  buildUnusedIndexes() {
24295
24346
  for (const v of this.variables) {
24296
24347
  if (!hasFlag(v._flags, VAR_IS_USED)) this.unusedVariables.push(v);
@@ -24604,102 +24655,6 @@ function buildComplexity(combinators, hasId, hasUniversal, hasAttribute, hasPseu
24604
24655
  }
24605
24656
 
24606
24657
  // src/css/parser/selector.ts
24607
- function parseSelector(raw) {
24608
- let start = 0;
24609
- let end = raw.length;
24610
- while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
24611
- while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
24612
- if (start === end) return [];
24613
- const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
24614
- const len = input.length;
24615
- const parts = [];
24616
- let pos = 0;
24617
- while (pos < len) {
24618
- const char = input.charCodeAt(pos);
24619
- if (isWhitespace(char) || isCombinator(char)) {
24620
- pos++;
24621
- continue;
24622
- }
24623
- if (char === CHAR_AMPERSAND) {
24624
- parts.push({ type: "nesting", value: "&", raw: "&" });
24625
- pos++;
24626
- continue;
24627
- }
24628
- if (char === CHAR_ASTERISK) {
24629
- parts.push({ type: "universal", value: "*", raw: "*" });
24630
- pos++;
24631
- continue;
24632
- }
24633
- if (char === CHAR_HASH) {
24634
- ID_STICKY.lastIndex = pos;
24635
- const match = ID_STICKY.exec(input);
24636
- if (match) {
24637
- const val = match[1];
24638
- if (!val) break;
24639
- parts.push({ type: "id", value: val, raw: match[0] });
24640
- pos = ID_STICKY.lastIndex;
24641
- continue;
24642
- }
24643
- }
24644
- if (char === CHAR_DOT) {
24645
- CLASS_STICKY.lastIndex = pos;
24646
- const match = CLASS_STICKY.exec(input);
24647
- if (match) {
24648
- const val = match[1];
24649
- if (!val) break;
24650
- parts.push({ type: "class", value: val, raw: match[0] });
24651
- pos = CLASS_STICKY.lastIndex;
24652
- continue;
24653
- }
24654
- }
24655
- if (char === CHAR_OPEN_BRACKET) {
24656
- ATTRIBUTE_STICKY.lastIndex = pos;
24657
- const match = ATTRIBUTE_STICKY.exec(input);
24658
- if (match) {
24659
- const val = match[1];
24660
- if (!val) break;
24661
- parts.push({ type: "attribute", value: val, raw: match[0] });
24662
- pos = ATTRIBUTE_STICKY.lastIndex;
24663
- continue;
24664
- }
24665
- }
24666
- if (char === CHAR_COLON) {
24667
- if (pos + 1 < len && input.charCodeAt(pos + 1) === CHAR_COLON) {
24668
- PSEUDO_ELEMENT_STICKY.lastIndex = pos;
24669
- const match2 = PSEUDO_ELEMENT_STICKY.exec(input);
24670
- if (match2) {
24671
- const val = match2[1];
24672
- if (!val) break;
24673
- parts.push({ type: "pseudo-element", value: val, raw: match2[0] });
24674
- pos = PSEUDO_ELEMENT_STICKY.lastIndex;
24675
- continue;
24676
- }
24677
- }
24678
- PSEUDO_CLASS_STICKY.lastIndex = pos;
24679
- const match = PSEUDO_CLASS_STICKY.exec(input);
24680
- if (match) {
24681
- const val = match[1];
24682
- if (!val) break;
24683
- parts.push({ type: "pseudo-class", value: val, raw: match[0] });
24684
- pos = PSEUDO_CLASS_STICKY.lastIndex;
24685
- continue;
24686
- }
24687
- }
24688
- if (isAlpha(char)) {
24689
- ELEMENT_STICKY.lastIndex = pos;
24690
- const match = ELEMENT_STICKY.exec(input);
24691
- if (match) {
24692
- const val = match[1];
24693
- if (!val) break;
24694
- parts.push({ type: "element", value: val, raw: match[0] });
24695
- pos = ELEMENT_STICKY.lastIndex;
24696
- continue;
24697
- }
24698
- }
24699
- pos++;
24700
- }
24701
- return parts;
24702
- }
24703
24658
  function parseSelectorList(selectorText) {
24704
24659
  const len = selectorText.length;
24705
24660
  if (len === 0) return [];
@@ -24787,18 +24742,80 @@ function extractPseudoClasses(selector) {
24787
24742
  }
24788
24743
  return pseudoClasses;
24789
24744
  }
24790
- function parseSelectorComplete(raw) {
24745
+ var CHAR_BACKSLASH = 92;
24746
+ function readCssIdentifier(input, start) {
24747
+ const length = input.length;
24748
+ let i = start;
24749
+ let hasEscape = false;
24750
+ while (i < length) {
24751
+ const code = input.charCodeAt(i);
24752
+ if (code === CHAR_BACKSLASH) {
24753
+ if (i + 1 >= length) break;
24754
+ hasEscape = true;
24755
+ i = skipCssEscape(input, i + 1);
24756
+ continue;
24757
+ }
24758
+ if (!isIdentChar(code)) break;
24759
+ i++;
24760
+ }
24761
+ if (i === start) return null;
24762
+ if (!hasEscape) {
24763
+ return { value: input.slice(start, i), end: i };
24764
+ }
24765
+ const parts = [];
24766
+ let j = start;
24767
+ while (j < i) {
24768
+ const code = input.charCodeAt(j);
24769
+ if (code !== CHAR_BACKSLASH) {
24770
+ parts.push(String.fromCharCode(code));
24771
+ j++;
24772
+ continue;
24773
+ }
24774
+ j++;
24775
+ if (j >= i) break;
24776
+ const first = input.charCodeAt(j);
24777
+ if (!isHexDigit(first)) {
24778
+ parts.push(String.fromCharCode(first));
24779
+ j++;
24780
+ continue;
24781
+ }
24782
+ const hexStart = j;
24783
+ const maxHex = Math.min(j + 6, i);
24784
+ while (j < maxHex && isHexDigit(input.charCodeAt(j))) j++;
24785
+ const codePoint = Number.parseInt(input.slice(hexStart, j), 16);
24786
+ if (codePoint > 0 && codePoint <= 1114111) parts.push(String.fromCodePoint(codePoint));
24787
+ if (j < i && isWhitespace(input.charCodeAt(j))) j++;
24788
+ }
24789
+ return { value: parts.join(""), end: i };
24790
+ }
24791
+ function skipCssEscape(input, afterBackslash) {
24792
+ const length = input.length;
24793
+ if (afterBackslash >= length) return afterBackslash;
24794
+ const first = input.charCodeAt(afterBackslash);
24795
+ if (!isHexDigit(first)) return afterBackslash + 1;
24796
+ let end = afterBackslash + 1;
24797
+ const maxHex = Math.min(afterBackslash + 6, length);
24798
+ while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
24799
+ if (end < length && isWhitespace(input.charCodeAt(end))) end++;
24800
+ return end;
24801
+ }
24802
+ var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
24803
+ var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
24804
+ var MAX_PSEUDO_PARSE_DEPTH = 4;
24805
+ function parseSelectorComplete(raw, _depth) {
24791
24806
  let start = 0;
24792
24807
  let end = raw.length;
24793
24808
  while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
24794
24809
  while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
24795
24810
  if (start === end) {
24796
- return { parts: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
24811
+ return { parts: [], compounds: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
24797
24812
  }
24798
24813
  const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
24799
24814
  const len = input.length;
24800
- const parts = [];
24815
+ const allParts = [];
24816
+ let currentCompoundParts = [];
24801
24817
  const combinators = [];
24818
+ const compounds = [];
24802
24819
  let ids = 0;
24803
24820
  let classes = 0;
24804
24821
  let elements = 0;
@@ -24808,10 +24825,11 @@ function parseSelectorComplete(raw) {
24808
24825
  let hasPseudoClassFlag = false;
24809
24826
  let hasPseudoElementFlag = false;
24810
24827
  let hasNesting = false;
24811
- const pseudoClasses = [];
24812
- const pseudoElements = [];
24828
+ const pseudoClassNames = [];
24829
+ const pseudoElementNames = [];
24813
24830
  let pos = 0;
24814
24831
  let inCompound = false;
24832
+ const depth = _depth ?? 0;
24815
24833
  while (pos < len) {
24816
24834
  const char = input.charCodeAt(pos);
24817
24835
  if (isWhitespace(char) || isCombinator(char)) {
@@ -24836,6 +24854,8 @@ function parseSelectorComplete(raw) {
24836
24854
  }
24837
24855
  }
24838
24856
  if (scanPos < len) {
24857
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
24858
+ currentCompoundParts = [];
24839
24859
  combinators.push(sawCombinator ?? "descendant");
24840
24860
  inCompound = false;
24841
24861
  }
@@ -24847,13 +24867,17 @@ function parseSelectorComplete(raw) {
24847
24867
  }
24848
24868
  inCompound = true;
24849
24869
  if (char === CHAR_AMPERSAND) {
24850
- parts.push({ type: "nesting", value: "&", raw: "&" });
24870
+ const part = { type: "nesting", value: "&", raw: "&" };
24871
+ allParts.push(part);
24872
+ currentCompoundParts.push(part);
24851
24873
  hasNesting = true;
24852
24874
  pos++;
24853
24875
  continue;
24854
24876
  }
24855
24877
  if (char === CHAR_ASTERISK) {
24856
- parts.push({ type: "universal", value: "*", raw: "*" });
24878
+ const part = { type: "universal", value: "*", raw: "*" };
24879
+ allParts.push(part);
24880
+ currentCompoundParts.push(part);
24857
24881
  hasUniversal = true;
24858
24882
  pos++;
24859
24883
  continue;
@@ -24864,10 +24888,26 @@ function parseSelectorComplete(raw) {
24864
24888
  if (match) {
24865
24889
  const val = match[1];
24866
24890
  if (!val) break;
24867
- parts.push({ type: "id", value: val, raw: match[0] });
24891
+ const ident2 = readCssIdentifier(input, pos + 1);
24892
+ const idVal = ident2 ? ident2.value : val;
24893
+ const idRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
24894
+ const idEnd = ident2 ? ident2.end : ID_STICKY.lastIndex;
24895
+ const part = { type: "id", value: idVal, raw: idRaw };
24896
+ allParts.push(part);
24897
+ currentCompoundParts.push(part);
24868
24898
  ids++;
24869
24899
  hasId = true;
24870
- pos = ID_STICKY.lastIndex;
24900
+ pos = idEnd;
24901
+ continue;
24902
+ }
24903
+ const ident = readCssIdentifier(input, pos + 1);
24904
+ if (ident) {
24905
+ const part = { type: "id", value: ident.value, raw: input.slice(pos, ident.end) };
24906
+ allParts.push(part);
24907
+ currentCompoundParts.push(part);
24908
+ ids++;
24909
+ hasId = true;
24910
+ pos = ident.end;
24871
24911
  continue;
24872
24912
  }
24873
24913
  }
@@ -24877,9 +24917,24 @@ function parseSelectorComplete(raw) {
24877
24917
  if (match) {
24878
24918
  const val = match[1];
24879
24919
  if (!val) break;
24880
- parts.push({ type: "class", value: val, raw: match[0] });
24920
+ const ident2 = readCssIdentifier(input, pos + 1);
24921
+ const clsVal = ident2 ? ident2.value : val;
24922
+ const clsRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
24923
+ const clsEnd = ident2 ? ident2.end : CLASS_STICKY.lastIndex;
24924
+ const part = { type: "class", value: clsVal, raw: clsRaw };
24925
+ allParts.push(part);
24926
+ currentCompoundParts.push(part);
24927
+ classes++;
24928
+ pos = clsEnd;
24929
+ continue;
24930
+ }
24931
+ const ident = readCssIdentifier(input, pos + 1);
24932
+ if (ident) {
24933
+ const part = { type: "class", value: ident.value, raw: input.slice(pos, ident.end) };
24934
+ allParts.push(part);
24935
+ currentCompoundParts.push(part);
24881
24936
  classes++;
24882
- pos = CLASS_STICKY.lastIndex;
24937
+ pos = ident.end;
24883
24938
  continue;
24884
24939
  }
24885
24940
  }
@@ -24889,7 +24944,9 @@ function parseSelectorComplete(raw) {
24889
24944
  if (match) {
24890
24945
  const val = match[1];
24891
24946
  if (!val) break;
24892
- parts.push({ type: "attribute", value: val, raw: match[0] });
24947
+ const part = { type: "attribute", value: val, raw: match[0] };
24948
+ allParts.push(part);
24949
+ currentCompoundParts.push(part);
24893
24950
  classes++;
24894
24951
  hasAttribute = true;
24895
24952
  pos = ATTRIBUTE_STICKY.lastIndex;
@@ -24903,10 +24960,12 @@ function parseSelectorComplete(raw) {
24903
24960
  if (match) {
24904
24961
  const val = match[1];
24905
24962
  if (!val) break;
24906
- parts.push({ type: "pseudo-element", value: val, raw: match[0] });
24963
+ const part = { type: "pseudo-element", value: val, raw: match[0] };
24964
+ allParts.push(part);
24965
+ currentCompoundParts.push(part);
24907
24966
  elements++;
24908
24967
  hasPseudoElementFlag = true;
24909
- pseudoElements.push(val);
24968
+ pseudoElementNames.push(val);
24910
24969
  pos = PSEUDO_ELEMENT_STICKY.lastIndex;
24911
24970
  continue;
24912
24971
  }
@@ -24932,19 +24991,25 @@ function parseSelectorComplete(raw) {
24932
24991
  const fullMatch = input.substring(pseudoStart, argEnd);
24933
24992
  const argContent = input.substring(nameEnd + 1, argEnd - 1);
24934
24993
  if (pseudoName === "where") {
24935
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
24994
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
24995
+ allParts.push(part2);
24996
+ currentCompoundParts.push(part2);
24936
24997
  hasPseudoClassFlag = true;
24937
- pseudoClasses.push(pseudoName);
24998
+ pseudoClassNames.push(pseudoName);
24938
24999
  } else if (pseudoName === "is" || pseudoName === "not" || pseudoName === "has") {
24939
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
25000
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
25001
+ allParts.push(part2);
25002
+ currentCompoundParts.push(part2);
24940
25003
  hasPseudoClassFlag = true;
24941
- pseudoClasses.push(pseudoName);
25004
+ pseudoClassNames.push(pseudoName);
24942
25005
  const args = splitPseudoArgs(argContent);
24943
25006
  let maxIds = 0, maxClasses = 0, maxElements = 0;
24944
- for (const arg of args) {
25007
+ for (let ai = 0; ai < args.length; ai++) {
25008
+ const arg = args[ai];
25009
+ if (!arg) continue;
24945
25010
  const trimmed = arg.trim();
24946
25011
  if (trimmed) {
24947
- const { specificity: argSpec } = parseSelectorComplete(trimmed);
25012
+ const { specificity: argSpec } = parseSelectorComplete(trimmed, depth + 1);
24948
25013
  if (argSpec[1] > maxIds || argSpec[1] === maxIds && argSpec[2] > maxClasses || argSpec[1] === maxIds && argSpec[2] === maxClasses && argSpec[3] > maxElements) {
24949
25014
  maxIds = argSpec[1];
24950
25015
  maxClasses = argSpec[2];
@@ -24956,18 +25021,22 @@ function parseSelectorComplete(raw) {
24956
25021
  classes += maxClasses;
24957
25022
  elements += maxElements;
24958
25023
  } else {
24959
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
25024
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
25025
+ allParts.push(part2);
25026
+ currentCompoundParts.push(part2);
24960
25027
  hasPseudoClassFlag = true;
24961
- pseudoClasses.push(pseudoName);
25028
+ pseudoClassNames.push(pseudoName);
24962
25029
  classes++;
24963
25030
  }
24964
25031
  pos = argEnd;
24965
25032
  continue;
24966
25033
  }
24967
25034
  const rawMatch = input.substring(pseudoStart, nameEnd);
24968
- parts.push({ type: "pseudo-class", value: pseudoName, raw: rawMatch });
25035
+ const part = { type: "pseudo-class", value: pseudoName, raw: rawMatch };
25036
+ allParts.push(part);
25037
+ currentCompoundParts.push(part);
24969
25038
  hasPseudoClassFlag = true;
24970
- pseudoClasses.push(pseudoName);
25039
+ pseudoClassNames.push(pseudoName);
24971
25040
  classes++;
24972
25041
  pos = nameEnd;
24973
25042
  continue;
@@ -24979,7 +25048,9 @@ function parseSelectorComplete(raw) {
24979
25048
  if (match) {
24980
25049
  const val = match[1];
24981
25050
  if (!val) break;
24982
- parts.push({ type: "element", value: val, raw: match[0] });
25051
+ const part = { type: "element", value: val, raw: match[0] };
25052
+ allParts.push(part);
25053
+ currentCompoundParts.push(part);
24983
25054
  elements++;
24984
25055
  pos = ELEMENT_STICKY.lastIndex;
24985
25056
  continue;
@@ -24987,6 +25058,9 @@ function parseSelectorComplete(raw) {
24987
25058
  }
24988
25059
  pos++;
24989
25060
  }
25061
+ if (currentCompoundParts.length > 0) {
25062
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
25063
+ }
24990
25064
  const complexity = buildComplexity(
24991
25065
  combinators,
24992
25066
  hasId,
@@ -24995,16 +25069,157 @@ function parseSelectorComplete(raw) {
24995
25069
  hasPseudoClassFlag,
24996
25070
  hasPseudoElementFlag,
24997
25071
  hasNesting,
24998
- pseudoClasses,
24999
- pseudoElements
25072
+ pseudoClassNames,
25073
+ pseudoElementNames
25000
25074
  );
25001
25075
  return {
25002
- parts,
25076
+ parts: allParts,
25077
+ compounds,
25003
25078
  combinators,
25004
25079
  specificity: [0, ids, classes, elements],
25005
25080
  complexity
25006
25081
  };
25007
25082
  }
25083
+ function finalizeCompound(parts, depth) {
25084
+ let tagName = null;
25085
+ let idValue = null;
25086
+ const classes = [];
25087
+ const seenClasses = /* @__PURE__ */ new Set();
25088
+ const attributes = [];
25089
+ const pseudoClasses = [];
25090
+ for (let i = 0; i < parts.length; i++) {
25091
+ const part = parts[i];
25092
+ if (!part) continue;
25093
+ if (part.type === "element") {
25094
+ tagName = part.value.toLowerCase();
25095
+ } else if (part.type === "id") {
25096
+ idValue = part.value;
25097
+ } else if (part.type === "class") {
25098
+ if (!seenClasses.has(part.value)) {
25099
+ seenClasses.add(part.value);
25100
+ classes.push(part.value);
25101
+ }
25102
+ } else if (part.type === "attribute") {
25103
+ const constraint = parseAttributeConstraintFromRaw(part.value);
25104
+ if (constraint) attributes.push(constraint);
25105
+ } else if (part.type === "pseudo-class") {
25106
+ const parsed = parsePseudoToParsedConstraint(part.value, part.raw, depth);
25107
+ if (parsed) pseudoClasses.push(parsed);
25108
+ }
25109
+ }
25110
+ return { parts, tagName, idValue, classes, attributes, pseudoClasses };
25111
+ }
25112
+ function parseAttributeConstraintFromRaw(raw) {
25113
+ const trimmed = raw.trim();
25114
+ const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
25115
+ if (constrained) {
25116
+ const operatorToken = constrained[2];
25117
+ if (!operatorToken) return null;
25118
+ const operator = mapAttrOperator(operatorToken);
25119
+ if (operator === null) return null;
25120
+ const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
25121
+ if (value2 === null) return null;
25122
+ const nameToken = constrained[1];
25123
+ if (!nameToken) return null;
25124
+ return {
25125
+ name: nameToken.toLowerCase(),
25126
+ operator,
25127
+ value: value2,
25128
+ caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
25129
+ };
25130
+ }
25131
+ if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) return null;
25132
+ return { name: trimmed.toLowerCase(), operator: "exists", value: null, caseInsensitive: false };
25133
+ }
25134
+ function mapAttrOperator(op) {
25135
+ if (op === "=") return "equals";
25136
+ if (op === "~=") return "includes-word";
25137
+ if (op === "|=") return "dash-prefix";
25138
+ if (op === "^=") return "prefix";
25139
+ if (op === "$=") return "suffix";
25140
+ if (op === "*=") return "contains";
25141
+ return null;
25142
+ }
25143
+ function parsePseudoToParsedConstraint(name, raw, depth) {
25144
+ const lowerName = name.toLowerCase();
25145
+ if (lowerName === "first-child") return { name: lowerName, raw, kind: 1 /* FirstChild */, nthPattern: null, nestedCompounds: null };
25146
+ if (lowerName === "last-child") return { name: lowerName, raw, kind: 2 /* LastChild */, nthPattern: null, nestedCompounds: null };
25147
+ if (lowerName === "only-child") return { name: lowerName, raw, kind: 3 /* OnlyChild */, nthPattern: null, nestedCompounds: null };
25148
+ const parenIdx = raw.indexOf("(");
25149
+ if (parenIdx === -1) {
25150
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
25151
+ }
25152
+ const argContent = raw.substring(parenIdx + 1, raw.length - 1);
25153
+ if (lowerName === "nth-child") {
25154
+ const pattern = parseNthPatternFromArg(argContent);
25155
+ return pattern ? { name: lowerName, raw, kind: 4 /* NthChild */, nthPattern: pattern, nestedCompounds: null } : null;
25156
+ }
25157
+ if (lowerName === "nth-last-child") {
25158
+ const pattern = parseNthPatternFromArg(argContent);
25159
+ return pattern ? { name: lowerName, raw, kind: 5 /* NthLastChild */, nthPattern: pattern, nestedCompounds: null } : null;
25160
+ }
25161
+ if (lowerName === "nth-of-type") {
25162
+ const pattern = parseNthPatternFromArg(argContent);
25163
+ return pattern ? { name: lowerName, raw, kind: 6 /* NthOfType */, nthPattern: pattern, nestedCompounds: null } : null;
25164
+ }
25165
+ if (lowerName === "nth-last-of-type") {
25166
+ const pattern = parseNthPatternFromArg(argContent);
25167
+ return pattern ? { name: lowerName, raw, kind: 7 /* NthLastOfType */, nthPattern: pattern, nestedCompounds: null } : null;
25168
+ }
25169
+ if (lowerName === "is" || lowerName === "where") {
25170
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: null };
25171
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
25172
+ return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: nested };
25173
+ }
25174
+ if (lowerName === "not") {
25175
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: null };
25176
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
25177
+ return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: nested };
25178
+ }
25179
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
25180
+ }
25181
+ function parseNestedCompoundGroups(argContent, depth) {
25182
+ const args = splitPseudoArgs(argContent);
25183
+ const groups = [];
25184
+ for (let i = 0; i < args.length; i++) {
25185
+ const arg = args[i];
25186
+ if (!arg) continue;
25187
+ const trimmed = arg.trim();
25188
+ if (!trimmed) continue;
25189
+ const result = parseSelectorComplete(trimmed, depth);
25190
+ if (result.compounds.length > 0) {
25191
+ groups.push(result.compounds.slice());
25192
+ }
25193
+ }
25194
+ return groups;
25195
+ }
25196
+ function parseNthPatternFromArg(raw) {
25197
+ const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
25198
+ if (normalized.length === 0) return null;
25199
+ if (normalized === "odd") return { step: 2, offset: 1 };
25200
+ if (normalized === "even") return { step: 2, offset: 0 };
25201
+ const nIndex = normalized.indexOf("n");
25202
+ if (nIndex === -1) {
25203
+ const value2 = Number.parseInt(normalized, 10);
25204
+ if (Number.isNaN(value2)) return null;
25205
+ return { step: 0, offset: value2 };
25206
+ }
25207
+ const stepPart = normalized.slice(0, nIndex);
25208
+ const offsetPart = normalized.slice(nIndex + 1);
25209
+ let step;
25210
+ if (stepPart.length === 0 || stepPart === "+") step = 1;
25211
+ else if (stepPart === "-") step = -1;
25212
+ else {
25213
+ step = Number.parseInt(stepPart, 10);
25214
+ if (Number.isNaN(step)) return null;
25215
+ }
25216
+ let offset = 0;
25217
+ if (offsetPart.length > 0) {
25218
+ offset = Number.parseInt(offsetPart, 10);
25219
+ if (Number.isNaN(offset)) return null;
25220
+ }
25221
+ return { step, offset };
25222
+ }
25008
25223
  function splitPseudoArgs(content) {
25009
25224
  const result = [];
25010
25225
  let start = 0;
@@ -25353,8 +25568,6 @@ function extractVarReferences(value2) {
25353
25568
 
25354
25569
  // src/css/phases/ast.ts
25355
25570
  var CSS_IDENT = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
25356
- var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
25357
- var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
25358
25571
  var ROOT_CONTEXT = {
25359
25572
  parentRule: null,
25360
25573
  parentAtRule: null,
@@ -25821,142 +26034,6 @@ function getRuleBlockOffsets(file, startOffset, endOffset) {
25821
26034
  blockEndOffset: close
25822
26035
  };
25823
26036
  }
25824
- function extractSubjectCompound(raw) {
25825
- const len = raw.length;
25826
- if (len === 0) return "";
25827
- let end = len - 1;
25828
- while (end >= 0 && isWhitespace(raw.charCodeAt(end))) end--;
25829
- if (end < 0) return "";
25830
- let parenDepth = 0;
25831
- let bracketDepth = 0;
25832
- for (let i = end; i >= 0; i--) {
25833
- const code = raw.charCodeAt(i);
25834
- if (code === CHAR_CLOSE_PAREN) {
25835
- parenDepth++;
25836
- continue;
25837
- }
25838
- if (code === CHAR_OPEN_PAREN) {
25839
- if (parenDepth > 0) parenDepth--;
25840
- continue;
25841
- }
25842
- if (code === CHAR_CLOSE_BRACKET) {
25843
- bracketDepth++;
25844
- continue;
25845
- }
25846
- if (code === CHAR_OPEN_BRACKET) {
25847
- if (bracketDepth > 0) bracketDepth--;
25848
- continue;
25849
- }
25850
- if (parenDepth > 0 || bracketDepth > 0) continue;
25851
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
25852
- return raw.slice(i + 1, end + 1).trim();
25853
- }
25854
- if (!isWhitespace(code)) continue;
25855
- return raw.slice(i + 1, end + 1).trim();
25856
- }
25857
- return raw.slice(0, end + 1).trim();
25858
- }
25859
- function parseAnchorAttributes(parts) {
25860
- const out = [];
25861
- for (let i = 0; i < parts.length; i++) {
25862
- const part = parts[i];
25863
- if (!part) continue;
25864
- if (part.type !== "attribute") continue;
25865
- const trimmed = part.value.trim();
25866
- const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
25867
- if (constrained) {
25868
- const opToken = constrained[2];
25869
- if (!opToken) continue;
25870
- const operator = mapAttributeOperatorFromToken(opToken);
25871
- if (operator === null) continue;
25872
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
25873
- if (value2 === null) continue;
25874
- const attrName = constrained[1];
25875
- if (!attrName) continue;
25876
- out.push({
25877
- name: attrName.toLowerCase(),
25878
- operator,
25879
- value: value2,
25880
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
25881
- });
25882
- continue;
25883
- }
25884
- if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) continue;
25885
- out.push({
25886
- name: trimmed.toLowerCase(),
25887
- operator: "exists",
25888
- value: null,
25889
- caseInsensitive: false
25890
- });
25891
- }
25892
- return out;
25893
- }
25894
- function mapAttributeOperatorFromToken(operator) {
25895
- if (operator === "=") return "equals";
25896
- if (operator === "~=") return "includes-word";
25897
- if (operator === "|=") return "dash-prefix";
25898
- if (operator === "^=") return "prefix";
25899
- if (operator === "$=") return "suffix";
25900
- if (operator === "*=") return "contains";
25901
- return null;
25902
- }
25903
- function buildSelectorAnchor(raw, parts, combinators) {
25904
- const subjectCompound = extractSubjectCompound(raw);
25905
- const subjectParts = parseSelector(subjectCompound);
25906
- let subjectTag = null;
25907
- const classes = [];
25908
- const seenClasses = /* @__PURE__ */ new Set();
25909
- for (let i = 0; i < subjectParts.length; i++) {
25910
- const part = subjectParts[i];
25911
- if (!part) continue;
25912
- if (part.type === "element") {
25913
- subjectTag = part.value.toLowerCase();
25914
- continue;
25915
- }
25916
- if (part.type !== "class") continue;
25917
- const cls = part.value;
25918
- if (seenClasses.has(cls)) continue;
25919
- seenClasses.add(cls);
25920
- classes.push(cls);
25921
- }
25922
- const attributes = parseAnchorAttributes(subjectParts);
25923
- const includesDescendantCombinator = combinators.includes("descendant");
25924
- let includesPseudoSelector = false;
25925
- let includesNesting = false;
25926
- for (let i = 0; i < parts.length; i++) {
25927
- const part = parts[i];
25928
- if (!part) continue;
25929
- if (part.type === "pseudo-class" || part.type === "pseudo-element") {
25930
- includesPseudoSelector = true;
25931
- continue;
25932
- }
25933
- if (part.type === "nesting") includesNesting = true;
25934
- }
25935
- let hasCheckboxAttribute = false;
25936
- for (let i = 0; i < attributes.length; i++) {
25937
- const a = attributes[i];
25938
- if (!a) continue;
25939
- if (a.name !== "type") continue;
25940
- if (a.operator !== "equals") continue;
25941
- if (a.value === null) continue;
25942
- const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
25943
- if (normalized !== "checkbox") continue;
25944
- hasCheckboxAttribute = true;
25945
- break;
25946
- }
25947
- const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
25948
- const targetsTableCell = subjectTag === "td" || subjectTag === "th";
25949
- return {
25950
- subjectTag,
25951
- classes,
25952
- attributes,
25953
- includesDescendantCombinator,
25954
- includesPseudoSelector,
25955
- dynamic: includesPseudoSelector || includesNesting,
25956
- targetsCheckbox,
25957
- targetsTableCell
25958
- };
25959
- }
25960
26037
  function createRuleEntity(graph, node, file, context) {
25961
26038
  const { parentRule, parentAtRule, containingMedia, containingLayer, depth } = context;
25962
26039
  const id = graph.nextRuleId();
@@ -26003,9 +26080,55 @@ function createRuleEntity(graph, node, file, context) {
26003
26080
  }
26004
26081
  function createSelectorEntity(graph, raw, rule) {
26005
26082
  const id = graph.nextSelectorId();
26006
- const { parts, specificity, complexity } = parseSelectorComplete(raw);
26083
+ const { parts, compounds, combinators, specificity, complexity } = parseSelectorComplete(raw);
26007
26084
  const specificityScore = specificityToScore(specificity);
26008
- const anchor = buildSelectorAnchor(raw, parts, complexity.combinators);
26085
+ const kinds = rule.elementKinds;
26086
+ for (let k = 0; k < parts.length; k++) {
26087
+ const part = parts[k];
26088
+ if (part) classifyPart(part, kinds);
26089
+ }
26090
+ const subject = compounds.length > 0 ? compounds[compounds.length - 1] : null;
26091
+ let includesPseudoSelector = false;
26092
+ let includesNesting = false;
26093
+ for (let i = 0; i < parts.length; i++) {
26094
+ const part = parts[i];
26095
+ if (!part) continue;
26096
+ if (part.type === "pseudo-class" || part.type === "pseudo-element") {
26097
+ includesPseudoSelector = true;
26098
+ continue;
26099
+ }
26100
+ if (part.type === "nesting") includesNesting = true;
26101
+ }
26102
+ const subjectTag = subject?.tagName ?? null;
26103
+ const subjectIdValue = subject?.idValue ?? null;
26104
+ const subjectClasses = subject?.classes ?? [];
26105
+ const subjectAttributes = subject?.attributes ?? [];
26106
+ const includesDescendantCombinator = combinators.includes("descendant");
26107
+ let hasCheckboxAttribute = false;
26108
+ for (let i = 0; i < subjectAttributes.length; i++) {
26109
+ const a = subjectAttributes[i];
26110
+ if (!a) continue;
26111
+ if (a.name !== "type") continue;
26112
+ if (a.operator !== "equals") continue;
26113
+ if (a.value === null) continue;
26114
+ const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
26115
+ if (normalized !== "checkbox") continue;
26116
+ hasCheckboxAttribute = true;
26117
+ break;
26118
+ }
26119
+ const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
26120
+ const targetsTableCell = subjectTag === "td" || subjectTag === "th";
26121
+ const anchor = {
26122
+ subjectTag,
26123
+ idValue: subjectIdValue,
26124
+ classes: subjectClasses,
26125
+ attributes: subjectAttributes,
26126
+ includesDescendantCombinator,
26127
+ includesPseudoSelector,
26128
+ dynamic: includesPseudoSelector || includesNesting,
26129
+ targetsCheckbox,
26130
+ targetsTableCell
26131
+ };
26009
26132
  return {
26010
26133
  id,
26011
26134
  raw,
@@ -26013,6 +26136,8 @@ function createSelectorEntity(graph, raw, rule) {
26013
26136
  specificity,
26014
26137
  specificityScore,
26015
26138
  complexity,
26139
+ compounds,
26140
+ combinators,
26016
26141
  parts: parts.length > 0 ? parts : [],
26017
26142
  anchor,
26018
26143
  overrides: [],
@@ -27673,57 +27798,31 @@ var mediaQueryOverlapConflict = defineCSSRule({
27673
27798
  var messages101 = {
27674
27799
  descendingSpecificity: "Lower-specificity selector `{{laterSelector}}` appears after `{{earlierSelector}}` for `{{property}}`, creating brittle cascade behavior."
27675
27800
  };
27676
- var UNSUPPORTED_TYPES = /* @__PURE__ */ new Set(["attribute", "pseudo-class", "pseudo-element", "universal", "nesting"]);
27677
27801
  function extractCompounds(selector) {
27678
- const parts = selector.parts;
27679
- if (parts.length === 0) return null;
27680
- for (let i = 0; i < parts.length; i++) {
27681
- const part = parts[i];
27682
- if (!part) continue;
27683
- if (UNSUPPORTED_TYPES.has(part.type)) return null;
27802
+ const selectorCompounds = selector.compounds;
27803
+ if (selectorCompounds.length === 0) return null;
27804
+ for (let i = 0; i < selectorCompounds.length; i++) {
27805
+ const sc = selectorCompounds[i];
27806
+ if (!sc) continue;
27807
+ const parts = sc.parts;
27808
+ for (let j = 0; j < parts.length; j++) {
27809
+ const part = parts[j];
27810
+ if (!part) continue;
27811
+ const t = part.type;
27812
+ if (t === "attribute" || t === "pseudo-class" || t === "pseudo-element" || t === "universal" || t === "nesting") return null;
27813
+ }
27684
27814
  }
27685
- return splitIntoCompounds(selector);
27686
- }
27687
- function splitIntoCompounds(selector) {
27688
- const raw = selector.raw;
27689
- const combinators = selector.complexity.combinators;
27690
- const segments = splitRawByCombinators(raw);
27691
- if (!segments || segments.length !== combinators.length + 1) return null;
27692
27815
  const compounds = [];
27693
- for (let i = 0; i < segments.length; i++) {
27694
- const seg = segments[i];
27695
- if (!seg) continue;
27696
- const compound = parseCompoundFromParts(seg);
27697
- if (!compound) return null;
27698
- compounds.push(compound);
27816
+ for (let i = 0; i < selectorCompounds.length; i++) {
27817
+ const sc = selectorCompounds[i];
27818
+ if (!sc) continue;
27819
+ const ids = [];
27820
+ if (sc.idValue !== null) ids.push(sc.idValue);
27821
+ if (!sc.tagName && sc.classes.length === 0 && ids.length === 0) return null;
27822
+ compounds.push({ tag: sc.tagName, classes: sc.classes, ids });
27699
27823
  }
27700
27824
  return compounds;
27701
27825
  }
27702
- var COMBINATOR_SPLIT = /\s*[>+~]\s*|\s+/;
27703
- function splitRawByCombinators(raw) {
27704
- const trimmed = raw.trim();
27705
- if (trimmed.length === 0) return null;
27706
- const segments = trimmed.split(COMBINATOR_SPLIT).filter((s) => s.length > 0);
27707
- return segments.length > 0 ? segments : null;
27708
- }
27709
- var COMPOUND_TOKEN = /([.#]?)([_a-zA-Z][_a-zA-Z0-9-]*)/g;
27710
- function parseCompoundFromParts(segment) {
27711
- let tag = null;
27712
- const classes = [];
27713
- const ids = [];
27714
- COMPOUND_TOKEN.lastIndex = 0;
27715
- let match;
27716
- while ((match = COMPOUND_TOKEN.exec(segment)) !== null) {
27717
- const prefix = match[1];
27718
- const value2 = match[2];
27719
- if (!value2) continue;
27720
- if (prefix === ".") classes.push(value2);
27721
- else if (prefix === "#") ids.push(value2);
27722
- else tag = value2;
27723
- }
27724
- if (!tag && classes.length === 0 && ids.length === 0) return null;
27725
- return { tag, classes, ids };
27726
- }
27727
27826
  function hasToken(list, token) {
27728
27827
  for (let i = 0; i < list.length; i++) {
27729
27828
  if (list[i] === token) return true;
@@ -27765,8 +27864,8 @@ function isProvableDescendingPair(earlier, later) {
27765
27864
  if (!earlierCompounds) return false;
27766
27865
  const laterCompounds = extractCompounds(later);
27767
27866
  if (!laterCompounds) return false;
27768
- const earlierCombinators = earlier.complexity.combinators;
27769
- const laterCombinators = later.complexity.combinators;
27867
+ const earlierCombinators = earlier.combinators;
27868
+ const laterCombinators = later.combinators;
27770
27869
  if (earlierCompounds.length !== laterCompounds.length) return false;
27771
27870
  if (earlierCombinators.length !== laterCombinators.length) return false;
27772
27871
  for (let i = 0; i < earlierCombinators.length; i++) {
@@ -30069,6 +30168,8 @@ var layoutSignalNames = [
30069
30168
  "min-width",
30070
30169
  "min-block-size",
30071
30170
  "min-height",
30171
+ "max-width",
30172
+ "max-height",
30072
30173
  "aspect-ratio",
30073
30174
  "vertical-align",
30074
30175
  "display",
@@ -30087,6 +30188,7 @@ var layoutSignalNames = [
30087
30188
  "place-items",
30088
30189
  "place-self",
30089
30190
  "flex-direction",
30191
+ "flex-basis",
30090
30192
  "grid-auto-flow",
30091
30193
  "appearance",
30092
30194
  "box-sizing",
@@ -30174,80 +30276,6 @@ function parseSignedPxValue(raw) {
30174
30276
  return parsePxValue(trimmed);
30175
30277
  }
30176
30278
 
30177
- // src/cross-file/layout/shorthand-expansion.ts
30178
- var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
30179
- ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
30180
- ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
30181
- ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
30182
- ["inset", ["top", "right", "bottom", "left"]]
30183
- ]);
30184
- var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
30185
- ["margin-block", ["margin-top", "margin-bottom"]],
30186
- ["padding-block", ["padding-top", "padding-bottom"]],
30187
- ["inset-block", ["inset-block-start", "inset-block-end"]]
30188
- ]);
30189
- function expandShorthand(property, value2) {
30190
- const quadTarget = QUAD_EXPANSIONS.get(property);
30191
- if (quadTarget !== void 0) {
30192
- const parsed = parseQuadShorthand(value2);
30193
- if (parsed === null) return null;
30194
- return [
30195
- { name: quadTarget[0], value: parsed.top },
30196
- { name: quadTarget[1], value: parsed.right },
30197
- { name: quadTarget[2], value: parsed.bottom },
30198
- { name: quadTarget[3], value: parsed.left }
30199
- ];
30200
- }
30201
- const blockTarget = BLOCK_EXPANSIONS.get(property);
30202
- if (blockTarget !== void 0) {
30203
- const parsed = parseBlockShorthand(value2);
30204
- if (parsed === null) return null;
30205
- return [
30206
- { name: blockTarget[0], value: parsed.start },
30207
- { name: blockTarget[1], value: parsed.end }
30208
- ];
30209
- }
30210
- if (property === "flex-flow") {
30211
- return expandFlexFlow(value2);
30212
- }
30213
- return void 0;
30214
- }
30215
- var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
30216
- function expandFlexFlow(value2) {
30217
- const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
30218
- if (tokens.length === 0) return null;
30219
- if (tokens.length > 2) return null;
30220
- let direction = null;
30221
- let wrap = null;
30222
- for (let i = 0; i < tokens.length; i++) {
30223
- const token = tokens[i];
30224
- if (!token) continue;
30225
- if (FLEX_DIRECTION_VALUES.has(token)) {
30226
- if (direction !== null) return null;
30227
- direction = token;
30228
- } else {
30229
- if (wrap !== null) return null;
30230
- wrap = token;
30231
- }
30232
- }
30233
- const out = [];
30234
- if (direction !== null) {
30235
- out.push({ name: "flex-direction", value: direction });
30236
- }
30237
- if (wrap !== null) {
30238
- out.push({ name: "flex-wrap", value: wrap });
30239
- }
30240
- return out.length > 0 ? out : null;
30241
- }
30242
- function getShorthandLonghandNames(property) {
30243
- const quad = QUAD_EXPANSIONS.get(property);
30244
- if (quad !== void 0) return [...quad];
30245
- const block = BLOCK_EXPANSIONS.get(property);
30246
- if (block !== void 0) return [...block];
30247
- if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
30248
- return null;
30249
- }
30250
-
30251
30279
  // src/cross-file/layout/util.ts
30252
30280
  var CONTROL_ELEMENT_TAGS = /* @__PURE__ */ new Set([
30253
30281
  "input",
@@ -30352,6 +30380,7 @@ var MONITORED_SHORTHAND_SET = /* @__PURE__ */ new Set([
30352
30380
  "border-width",
30353
30381
  "margin-block",
30354
30382
  "padding-block",
30383
+ "padding-inline",
30355
30384
  "inset-block",
30356
30385
  "flex-flow"
30357
30386
  ]);
@@ -30364,6 +30393,9 @@ var LENGTH_SIGNAL_SET = /* @__PURE__ */ new Set([
30364
30393
  "min-width",
30365
30394
  "min-block-size",
30366
30395
  "min-height",
30396
+ "max-width",
30397
+ "max-height",
30398
+ "flex-basis",
30367
30399
  "top",
30368
30400
  "bottom",
30369
30401
  "margin-top",
@@ -30417,11 +30449,11 @@ function isMonitoredSignal(property) {
30417
30449
  }
30418
30450
  function isControlTag(tag) {
30419
30451
  if (tag === null) return false;
30420
- return CONTROL_ELEMENT_TAGS.has(tag.toLowerCase());
30452
+ return CONTROL_ELEMENT_TAGS.has(tag);
30421
30453
  }
30422
30454
  function isReplacedTag(tag) {
30423
30455
  if (tag === null) return false;
30424
- return REPLACED_ELEMENT_TAGS.has(tag.toLowerCase());
30456
+ return REPLACED_ELEMENT_TAGS.has(tag);
30425
30457
  }
30426
30458
  function normalizeSignalMapWithCounts(values) {
30427
30459
  const out = /* @__PURE__ */ new Map();
@@ -30436,16 +30468,12 @@ function normalizeSignalMapWithCounts(values) {
30436
30468
  null
30437
30469
  );
30438
30470
  out.set("font-size", parsedFontSize);
30439
- if (parsedFontSize.kind === "known" && parsedFontSize.guard.kind === 0 /* Unconditional */) {
30471
+ if (parsedFontSize.kind === 0 /* Known */ && parsedFontSize.guard.kind === 0 /* Unconditional */) {
30440
30472
  fontSizePx = parsedFontSize.px;
30441
30473
  }
30442
30474
  }
30443
30475
  for (const [property, declaration] of values) {
30444
30476
  if (property === "font-size") continue;
30445
- if (MONITORED_SHORTHAND_SET.has(property)) {
30446
- applyExpandedShorthand(out, property, declaration, fontSizePx);
30447
- continue;
30448
- }
30449
30477
  const name = toMonitoredSignalName(property);
30450
30478
  if (!name) continue;
30451
30479
  const normalized = normalizeSignal(
@@ -30465,7 +30493,7 @@ function normalizeSignalMapWithCounts(values) {
30465
30493
  conditionalSignalCount++;
30466
30494
  continue;
30467
30495
  }
30468
- if (value2.kind === "known") {
30496
+ if (value2.kind === 0 /* Known */) {
30469
30497
  knownSignalCount++;
30470
30498
  continue;
30471
30499
  }
@@ -30478,30 +30506,6 @@ function normalizeSignalMapWithCounts(values) {
30478
30506
  conditionalSignalCount
30479
30507
  };
30480
30508
  }
30481
- function applyExpandedShorthand(out, property, declaration, fontSizePx) {
30482
- const expanded = expandShorthand(property, declaration.value);
30483
- if (expanded === null) {
30484
- const reason = `${property} value is not statically parseable`;
30485
- const longhandNames = getShorthandLonghandNames(property);
30486
- if (longhandNames === null) return;
30487
- for (let i = 0; i < longhandNames.length; i++) {
30488
- const longhand = longhandNames[i];
30489
- if (!longhand) continue;
30490
- const name = MONITORED_SIGNAL_NAME_MAP.get(longhand);
30491
- if (name === void 0) continue;
30492
- out.set(name, createUnknown(name, declaration.source, declaration.guardProvenance, reason));
30493
- }
30494
- return;
30495
- }
30496
- if (expanded === void 0) return;
30497
- for (let i = 0; i < expanded.length; i++) {
30498
- const entry = expanded[i];
30499
- if (!entry) continue;
30500
- const name = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
30501
- if (name === void 0) continue;
30502
- out.set(name, normalizeSignal(name, entry.value, declaration.source, declaration.guardProvenance, fontSizePx));
30503
- }
30504
- }
30505
30509
  function toMonitoredSignalName(property) {
30506
30510
  return MONITORED_SIGNAL_NAME_MAP.get(property) ?? null;
30507
30511
  }
@@ -30542,13 +30546,13 @@ function parseAspectRatio(name, raw, source, guard) {
30542
30546
  if (!Number.isFinite(left) || !Number.isFinite(right) || left <= 0 || right <= 0) {
30543
30547
  return createUnknown(name, source, guard, "aspect-ratio ratio is invalid");
30544
30548
  }
30545
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
30549
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
30546
30550
  }
30547
30551
  const ratio = Number(trimmed);
30548
30552
  if (!Number.isFinite(ratio) || ratio <= 0) {
30549
30553
  return createUnknown(name, source, guard, "aspect-ratio is not statically parseable");
30550
30554
  }
30551
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
30555
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
30552
30556
  }
30553
30557
  function parseContainIntrinsicSize(name, raw, source, guard) {
30554
30558
  const trimmed = raw.trim().toLowerCase();
@@ -30566,18 +30570,19 @@ function parseContainIntrinsicSize(name, raw, source, guard) {
30566
30570
  const part = parts[i];
30567
30571
  if (!part) continue;
30568
30572
  const px = parseSignedPxValue(part);
30569
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
30573
+ if (px !== null) return createKnown(name, trimmed, source, guard, px, 0 /* Px */, 0 /* Exact */);
30570
30574
  }
30571
30575
  return createUnknown(name, source, guard, "contain-intrinsic-size is not statically parseable in px");
30572
30576
  }
30573
30577
  function parseLineHeight(name, raw, source, guard, fontSizePx) {
30578
+ const normalized = raw.trim().toLowerCase();
30574
30579
  const unitless = parseUnitlessValue(raw);
30575
30580
  if (unitless !== null) {
30576
30581
  const base = fontSizePx === null ? 16 : fontSizePx;
30577
- return createKnown(name, raw, source, guard, unitless * base, 1 /* Unitless */, "estimated");
30582
+ return createKnown(name, normalized, source, guard, unitless * base, 1 /* Unitless */, 1 /* Estimated */);
30578
30583
  }
30579
30584
  const px = parseSignedPxValue(raw);
30580
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
30585
+ if (px !== null) return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
30581
30586
  return createUnknown(name, source, guard, "line-height is not statically parseable");
30582
30587
  }
30583
30588
  var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
@@ -30586,16 +30591,21 @@ var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
30586
30591
  "fit-content",
30587
30592
  "min-content",
30588
30593
  "max-content",
30589
- "stretch"
30594
+ "stretch",
30595
+ "inherit",
30596
+ "initial",
30597
+ "unset",
30598
+ "revert",
30599
+ "revert-layer"
30590
30600
  ]);
30591
30601
  function parseLength(name, raw, source, guard) {
30592
30602
  const px = parseSignedPxValue(raw);
30603
+ const normalized = raw.trim().toLowerCase();
30593
30604
  if (px !== null) {
30594
- return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
30605
+ return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
30595
30606
  }
30596
- const normalized = raw.trim().toLowerCase();
30597
30607
  if (DIMENSION_KEYWORD_SET.has(normalized) || normalized.startsWith("fit-content(")) {
30598
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
30608
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
30599
30609
  }
30600
30610
  return createUnknown(name, source, guard, "length is not statically parseable in px");
30601
30611
  }
@@ -30607,7 +30617,7 @@ function parseKeyword(name, raw, source, guard) {
30607
30617
  if (hasDynamicExpression(normalized)) {
30608
30618
  return createUnknown(name, source, guard, "keyword uses runtime-dependent function");
30609
30619
  }
30610
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
30620
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
30611
30621
  }
30612
30622
  function parseTransform(name, raw, source, guard) {
30613
30623
  const normalized = raw.trim().toLowerCase();
@@ -30618,7 +30628,7 @@ function parseTransform(name, raw, source, guard) {
30618
30628
  return createUnknown(name, source, guard, "transform uses runtime-dependent function");
30619
30629
  }
30620
30630
  const y = extractTransformYPx(normalized);
30621
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
30631
+ if (y !== null) return createKnown(name, normalized, source, guard, y, 0 /* Px */, 0 /* Exact */);
30622
30632
  return createUnknown(name, source, guard, "transform has non-translational or non-px functions");
30623
30633
  }
30624
30634
  function parseTranslateProperty(name, raw, source, guard) {
@@ -30630,24 +30640,20 @@ function parseTranslateProperty(name, raw, source, guard) {
30630
30640
  return createUnknown(name, source, guard, "translate uses runtime-dependent function");
30631
30641
  }
30632
30642
  const y = extractTranslatePropertyYPx(trimmed);
30633
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
30643
+ if (y !== null) return createKnown(name, trimmed, source, guard, y, 0 /* Px */, 0 /* Exact */);
30634
30644
  return createUnknown(name, source, guard, "translate property vertical component is not px");
30635
30645
  }
30636
30646
  function hasDynamicExpression(raw) {
30637
30647
  if (raw.includes("var(")) return true;
30638
- if (raw.includes("calc(")) return true;
30639
30648
  if (raw.includes("env(")) return true;
30640
30649
  if (raw.includes("attr(")) return true;
30641
- if (raw.includes("min(")) return true;
30642
- if (raw.includes("max(")) return true;
30643
- if (raw.includes("clamp(")) return true;
30644
30650
  return false;
30645
30651
  }
30646
- function createKnown(name, raw, source, guard, px, unit, quality) {
30652
+ function createKnown(name, normalized, source, guard, px, unit, quality) {
30647
30653
  return {
30648
- kind: "known",
30654
+ kind: 0 /* Known */,
30649
30655
  name,
30650
- normalized: raw.trim().toLowerCase(),
30656
+ normalized,
30651
30657
  source,
30652
30658
  guard,
30653
30659
  unit,
@@ -30657,7 +30663,7 @@ function createKnown(name, raw, source, guard, px, unit, quality) {
30657
30663
  }
30658
30664
  function createUnknown(name, source, guard, reason) {
30659
30665
  return {
30660
- kind: "unknown",
30666
+ kind: 1 /* Unknown */,
30661
30667
  name,
30662
30668
  source,
30663
30669
  guard,
@@ -30673,49 +30679,23 @@ var INHERITED_SIGNAL_NAMES = [
30673
30679
  "direction"
30674
30680
  ];
30675
30681
  function collectSignalSnapshot(context, node) {
30676
- const existing = context.layout.snapshotByElementNode.get(node);
30677
- if (existing) {
30682
+ const record = context.layout.records.get(node);
30683
+ if (record) {
30678
30684
  context.layout.perf.signalSnapshotCacheHits++;
30679
- return existing;
30680
- }
30681
- throw new Error(`missing precomputed layout snapshot for ${node.key}`);
30682
- }
30683
- function buildSignalSnapshotIndex(elements, cascadeByElementNode, perf) {
30684
- const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
30685
- for (let i = 0; i < elements.length; i++) {
30686
- const element = elements[i];
30687
- if (!element) continue;
30688
- buildSnapshotForNode(element, cascadeByElementNode, snapshotByElementNode, perf);
30685
+ return record.snapshot;
30689
30686
  }
30690
- return snapshotByElementNode;
30687
+ throw new Error(`missing precomputed layout record for ${node.key}`);
30691
30688
  }
30692
- function buildSnapshotForNode(node, cascadeByElementNode, snapshotByElementNode, perf) {
30693
- const existing = snapshotByElementNode.get(node);
30694
- if (existing) {
30695
- perf.signalSnapshotCacheHits++;
30696
- return existing;
30697
- }
30698
- const raw = cascadeByElementNode.get(node);
30699
- if (!raw) {
30700
- throw new Error(`missing cascade map for ${node.key}`);
30701
- }
30702
- const normalized = normalizeSignalMapWithCounts(raw);
30703
- const parent = node.parentElementNode;
30704
- const parentSnapshot = parent ? buildSnapshotForNode(parent, cascadeByElementNode, snapshotByElementNode, perf) : null;
30689
+ function buildSnapshotFromCascade(node, cascade, parentSnapshot) {
30690
+ const normalized = normalizeSignalMapWithCounts(cascade);
30705
30691
  const inherited = inheritSignalsFromParent(parentSnapshot, normalized.signals);
30706
- const knownSignalCount = normalized.knownSignalCount + inherited.knownDelta;
30707
- const unknownSignalCount = normalized.unknownSignalCount + inherited.unknownDelta;
30708
- const conditionalSignalCount = normalized.conditionalSignalCount + inherited.conditionalDelta;
30709
- const snapshot = {
30692
+ return {
30710
30693
  node,
30711
30694
  signals: inherited.signals,
30712
- knownSignalCount,
30713
- unknownSignalCount,
30714
- conditionalSignalCount
30695
+ knownSignalCount: normalized.knownSignalCount + inherited.knownDelta,
30696
+ unknownSignalCount: normalized.unknownSignalCount + inherited.unknownDelta,
30697
+ conditionalSignalCount: normalized.conditionalSignalCount + inherited.conditionalDelta
30715
30698
  };
30716
- snapshotByElementNode.set(node, snapshot);
30717
- perf.signalSnapshotsBuilt++;
30718
- return snapshot;
30719
30699
  }
30720
30700
  function inheritSignalsFromParent(parentSnapshot, local) {
30721
30701
  if (!parentSnapshot) {
@@ -30742,7 +30722,7 @@ function inheritSignalsFromParent(parentSnapshot, local) {
30742
30722
  conditionalDelta++;
30743
30723
  continue;
30744
30724
  }
30745
- if (inheritedValue.kind === "known") {
30725
+ if (inheritedValue.kind === 0 /* Known */) {
30746
30726
  knownDelta++;
30747
30727
  continue;
30748
30728
  }
@@ -30775,10 +30755,10 @@ var EMPTY_STATEFUL_BASE_VALUE_INDEX = /* @__PURE__ */ new Map();
30775
30755
  var EMPTY_LAYOUT_RESERVED_SPACE_FACT = Object.freeze({
30776
30756
  hasReservedSpace: false,
30777
30757
  reasons: EMPTY_RESERVED_SPACE_REASONS,
30778
- hasUsableInlineDimension: false,
30779
- hasUsableBlockDimension: false,
30780
30758
  hasContainIntrinsicSize: false,
30781
- hasUsableAspectRatio: false
30759
+ hasUsableAspectRatio: false,
30760
+ hasDeclaredInlineDimension: false,
30761
+ hasDeclaredBlockDimension: false
30782
30762
  });
30783
30763
  var EMPTY_LAYOUT_SCROLL_CONTAINER_FACT = Object.freeze({
30784
30764
  isScrollContainer: false,
@@ -30811,12 +30791,12 @@ var EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT = Object.freeze({
30811
30791
  function readKnownSignalWithGuard(snapshot, name) {
30812
30792
  const value2 = snapshot.signals.get(name);
30813
30793
  if (!value2) return null;
30814
- if (value2.kind !== "known") return null;
30794
+ if (value2.kind !== 0 /* Known */) return null;
30815
30795
  return value2;
30816
30796
  }
30817
30797
  function toEvidenceKind(value2) {
30818
30798
  if (value2.guard.kind === 1 /* Conditional */) return 2 /* Conditional */;
30819
- if (value2.quality === "estimated") return 1 /* Interval */;
30799
+ if (value2.quality === 1 /* Estimated */) return 1 /* Interval */;
30820
30800
  return 0 /* Exact */;
30821
30801
  }
30822
30802
  function readNormalizedSignalEvidence(snapshot, name) {
@@ -30827,7 +30807,7 @@ function readNormalizedSignalEvidence(snapshot, name) {
30827
30807
  kind: 3 /* Unknown */
30828
30808
  };
30829
30809
  }
30830
- if (value2.kind !== "known") {
30810
+ if (value2.kind !== 0 /* Known */) {
30831
30811
  if (value2.guard.kind === 1 /* Conditional */) {
30832
30812
  return {
30833
30813
  value: null,
@@ -30881,19 +30861,19 @@ function hasEffectivePosition(snapshot) {
30881
30861
  return position !== "static";
30882
30862
  }
30883
30863
  function readReservedSpaceFact(graph, node) {
30884
- return graph.reservedSpaceFactsByNode.get(node) ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
30864
+ return graph.records.get(node)?.reservedSpace ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
30885
30865
  }
30886
30866
  function readScrollContainerFact(graph, node) {
30887
- return graph.scrollContainerFactsByNode.get(node) ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
30867
+ return graph.records.get(node)?.scrollContainer ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
30888
30868
  }
30889
30869
  function readFlowParticipationFact(graph, node) {
30890
- return graph.flowParticipationFactsByNode.get(node) ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
30870
+ return graph.records.get(node)?.flowParticipation ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
30891
30871
  }
30892
30872
  function readContainingBlockFact(graph, node) {
30893
- return graph.containingBlockFactsByNode.get(node) ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
30873
+ return graph.records.get(node)?.containingBlock ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
30894
30874
  }
30895
30875
  function readConditionalSignalDeltaFact(graph, node, name) {
30896
- const byProperty = graph.conditionalSignalDeltaFactsByNode.get(node);
30876
+ const byProperty = graph.records.get(node)?.conditionalDelta;
30897
30877
  if (!byProperty) return EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
30898
30878
  return byProperty.get(name) ?? EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
30899
30879
  }
@@ -30921,7 +30901,7 @@ function readScrollContainerElements(graph) {
30921
30901
  return graph.scrollContainerElements;
30922
30902
  }
30923
30903
  function readBaselineOffsetFacts(graph, node) {
30924
- return graph.baselineOffsetFactsByNode.get(node) ?? EMPTY_BASELINE_FACTS;
30904
+ return graph.records.get(node)?.baselineOffsets ?? EMPTY_BASELINE_FACTS;
30925
30905
  }
30926
30906
  function readElementRef(graph, node) {
30927
30907
  return readElementRefById(graph, node.solidFile, node.elementId);
@@ -31775,23 +31755,44 @@ function collectCSSScopeBySolidFile(solids, css, moduleResolver) {
31775
31755
  if (!imp) continue;
31776
31756
  if (imp.isTypeOnly) continue;
31777
31757
  const resolvedCssPath = resolver.resolveCss(solid.file, imp.source);
31778
- if (resolvedCssPath === null) continue;
31779
- const transitiveScope = getOrCollectTransitiveScope(
31780
- resolvedCssPath,
31781
- resolver,
31782
- cssFilesByNormalizedPath,
31783
- transitiveScopeByEntryPath
31784
- );
31785
- for (let k = 0; k < transitiveScope.length; k++) {
31786
- const ts137 = transitiveScope[k];
31787
- if (!ts137) continue;
31788
- scope.add(ts137);
31758
+ if (resolvedCssPath !== null) {
31759
+ const transitiveScope = getOrCollectTransitiveScope(
31760
+ resolvedCssPath,
31761
+ resolver,
31762
+ cssFilesByNormalizedPath,
31763
+ transitiveScopeByEntryPath
31764
+ );
31765
+ for (let k = 0; k < transitiveScope.length; k++) {
31766
+ const ts137 = transitiveScope[k];
31767
+ if (!ts137) continue;
31768
+ scope.add(ts137);
31769
+ }
31770
+ if (imp.specifiers.length === 0) {
31771
+ for (let k = 0; k < transitiveScope.length; k++) {
31772
+ const ts137 = transitiveScope[k];
31773
+ if (!ts137) continue;
31774
+ globalSideEffectScope.add(ts137);
31775
+ }
31776
+ }
31789
31777
  }
31790
- if (imp.specifiers.length !== 0) continue;
31791
- for (let k = 0; k < transitiveScope.length; k++) {
31792
- const ts137 = transitiveScope[k];
31793
- if (!ts137) continue;
31794
- globalSideEffectScope.add(ts137);
31778
+ if (imp.specifiers.length !== 0) {
31779
+ const resolvedSolidPath = resolver.resolveSolid(solid.file, imp.source);
31780
+ if (resolvedSolidPath !== null) {
31781
+ const componentCssPath = resolveColocatedCss(resolvedSolidPath, cssFilesByNormalizedPath);
31782
+ if (componentCssPath !== null) {
31783
+ const componentCssScope = getOrCollectTransitiveScope(
31784
+ componentCssPath,
31785
+ resolver,
31786
+ cssFilesByNormalizedPath,
31787
+ transitiveScopeByEntryPath
31788
+ );
31789
+ for (let k = 0; k < componentCssScope.length; k++) {
31790
+ const cs = componentCssScope[k];
31791
+ if (!cs) continue;
31792
+ scope.add(cs);
31793
+ }
31794
+ }
31795
+ }
31795
31796
  }
31796
31797
  }
31797
31798
  localScopeBySolidFile.set(solid.file, scope);
@@ -32030,6 +32031,7 @@ function createSolidInput(filePath, program, logger) {
32030
32031
 
32031
32032
  // src/cross-file/layout/component-host.ts
32032
32033
  var EMPTY_ATTRIBUTES = /* @__PURE__ */ new Map();
32034
+ var EMPTY_PROP_BINDINGS = /* @__PURE__ */ new Map();
32033
32035
  var TRANSPARENT_SOLID_PRIMITIVES = /* @__PURE__ */ new Set([
32034
32036
  "For",
32035
32037
  "Index",
@@ -32098,9 +32100,10 @@ function createLayoutComponentHostResolver(solids, moduleResolver, logger = noop
32098
32100
  const staticAttributes = innerHost !== null ? mergeStaticAttributes(entry.staticAttributes, innerHost.descriptor.staticAttributes) : entry.staticAttributes;
32099
32101
  const staticClassTokens = innerHost !== null ? mergeStaticClassTokens(entry.staticClassTokens, innerHost.descriptor.staticClassTokens) : entry.staticClassTokens;
32100
32102
  const forwardsChildren = entry.forwardsChildren || innerHost !== null && innerHost.descriptor.forwardsChildren;
32103
+ const attributePropBindings = innerHost !== null ? mergePropBindings(entry.attributePropBindings, innerHost.descriptor.attributePropBindings) : entry.attributePropBindings;
32101
32104
  if (logger.isLevelEnabled(Level.Trace)) logger.trace(`[component-host] resolved: tagName=${tagName}, attrs=[${[...staticAttributes.keys()]}], classes=[${staticClassTokens}]`);
32102
32105
  return {
32103
- descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren },
32106
+ descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren, attributePropBindings },
32104
32107
  hostElementRef: innerHost?.hostElementRef ?? null
32105
32108
  };
32106
32109
  }
@@ -32527,7 +32530,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
32527
32530
  tagName: element.tagName,
32528
32531
  staticAttributes: collectStaticAttributes(element),
32529
32532
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
32530
- forwardsChildren: detectChildrenForwarding(element)
32533
+ forwardsChildren: detectChildrenForwarding(element),
32534
+ attributePropBindings: collectAttributePropBindings(element)
32531
32535
  },
32532
32536
  hostElementRef: { solid: graph, element }
32533
32537
  };
@@ -32542,7 +32546,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
32542
32546
  filePath: graph.file,
32543
32547
  staticAttributes: collectStaticAttributes(element),
32544
32548
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
32545
- forwardsChildren: detectChildrenForwarding(element)
32549
+ forwardsChildren: detectChildrenForwarding(element),
32550
+ attributePropBindings: collectAttributePropBindings(element)
32546
32551
  };
32547
32552
  }
32548
32553
  function isContextProviderTag(tag) {
@@ -32730,6 +32735,41 @@ function collectStaticAttributes(element) {
32730
32735
  if (out === null) return EMPTY_ATTRIBUTES;
32731
32736
  return out;
32732
32737
  }
32738
+ function extractPropMemberName(node) {
32739
+ if (!import_typescript125.default.isJsxExpression(node)) return null;
32740
+ const expression = node.expression;
32741
+ if (!expression) return null;
32742
+ return extractMemberNameFromExpression(expression);
32743
+ }
32744
+ function extractMemberNameFromExpression(expression) {
32745
+ if (import_typescript125.default.isPropertyAccessExpression(expression)) {
32746
+ return expression.name.text;
32747
+ }
32748
+ if (import_typescript125.default.isCallExpression(expression) && import_typescript125.default.isPropertyAccessExpression(expression.expression) && expression.arguments.length === 0) {
32749
+ return expression.expression.name.text;
32750
+ }
32751
+ if (import_typescript125.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript125.default.SyntaxKind.QuestionQuestionToken) {
32752
+ return extractMemberNameFromExpression(expression.left);
32753
+ }
32754
+ return null;
32755
+ }
32756
+ function collectAttributePropBindings(element) {
32757
+ let out = null;
32758
+ for (let i = 0; i < element.attributes.length; i++) {
32759
+ const attribute = element.attributes[i];
32760
+ if (!attribute) continue;
32761
+ if (!import_typescript125.default.isJsxAttribute(attribute.node)) continue;
32762
+ if (!attribute.name) continue;
32763
+ if (attribute.valueNode === null) continue;
32764
+ const propName = extractPropMemberName(attribute.valueNode);
32765
+ if (propName === null) continue;
32766
+ const attrName = attribute.name.toLowerCase();
32767
+ if (out === null) out = /* @__PURE__ */ new Map();
32768
+ out.set(attrName, propName);
32769
+ }
32770
+ if (out === null) return EMPTY_PROP_BINDINGS;
32771
+ return out;
32772
+ }
32733
32773
  function collectTopLevelVariableInitializers(graph) {
32734
32774
  const out = /* @__PURE__ */ new Map();
32735
32775
  for (let i = 0; i < graph.variables.length; i++) {
@@ -32855,7 +32895,12 @@ function areHostDescriptorsEqual(left, right) {
32855
32895
  if (left.tagName !== right.tagName) return false;
32856
32896
  if (left.forwardsChildren !== right.forwardsChildren) return false;
32857
32897
  if (!areStringListsEqual(left.staticClassTokens, right.staticClassTokens)) return false;
32858
- return areAttributeMapsEqual(left.staticAttributes, right.staticAttributes);
32898
+ if (!areAttributeMapsEqual(left.staticAttributes, right.staticAttributes)) return false;
32899
+ if (left.attributePropBindings.size !== right.attributePropBindings.size) return false;
32900
+ for (const [key, value2] of left.attributePropBindings) {
32901
+ if (right.attributePropBindings.get(key) !== value2) return false;
32902
+ }
32903
+ return true;
32859
32904
  }
32860
32905
  function areComponentHostEntriesEqual(left, right) {
32861
32906
  if (left.resolution !== right.resolution) return false;
@@ -32898,6 +32943,18 @@ function mergeStaticAttributes(outer, inner) {
32898
32943
  }
32899
32944
  return out;
32900
32945
  }
32946
+ function mergePropBindings(outer, inner) {
32947
+ if (inner.size === 0) return outer;
32948
+ if (outer.size === 0) return inner;
32949
+ const out = /* @__PURE__ */ new Map();
32950
+ for (const [name, value2] of inner) {
32951
+ out.set(name, value2);
32952
+ }
32953
+ for (const [name, value2] of outer) {
32954
+ out.set(name, value2);
32955
+ }
32956
+ return out;
32957
+ }
32901
32958
  var HTML_TAG_NAMES = /* @__PURE__ */ new Set([
32902
32959
  "a",
32903
32960
  "abbr",
@@ -33042,9 +33099,6 @@ function mergeStaticClassTokens(outer, inner) {
33042
33099
  }
33043
33100
 
33044
33101
  // src/cross-file/layout/selector-match.ts
33045
- var ATTRIBUTE_EXISTS_RE2 = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
33046
- var ATTRIBUTE_CONSTRAINT_RE2 = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
33047
- var MAX_PSEUDO_COMPILE_DEPTH = 4;
33048
33102
  var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
33049
33103
  "active",
33050
33104
  "checked",
@@ -33068,14 +33122,25 @@ var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
33068
33122
  "valid",
33069
33123
  "visited"
33070
33124
  ]);
33125
+ var EMPTY_PSEUDO = {
33126
+ firstChild: false,
33127
+ lastChild: false,
33128
+ onlyChild: false,
33129
+ nthChild: null,
33130
+ nthLastChild: null,
33131
+ nthOfType: null,
33132
+ nthLastOfType: null,
33133
+ anyOfGroups: [],
33134
+ noneOfGroups: []
33135
+ };
33071
33136
  function compileSelectorMatcher(selector) {
33072
- const parsed = parseSelectorPattern(selector.raw);
33073
- if (parsed === null) return null;
33137
+ const selectorCompounds = selector.compounds;
33138
+ if (selectorCompounds.length === 0) return null;
33074
33139
  const compoundsLeftToRight = [];
33075
- for (let i = 0; i < parsed.compounds.length; i++) {
33076
- const compoundRaw = parsed.compounds[i];
33077
- if (compoundRaw === void 0) continue;
33078
- const compiled = compileCompound(compoundRaw, 0);
33140
+ for (let i = 0; i < selectorCompounds.length; i++) {
33141
+ const sc = selectorCompounds[i];
33142
+ if (sc === void 0) continue;
33143
+ const compiled = buildCompiledCompound(sc);
33079
33144
  if (compiled === null) return null;
33080
33145
  compoundsLeftToRight.push(compiled);
33081
33146
  }
@@ -33092,9 +33157,125 @@ function compileSelectorMatcher(selector) {
33092
33157
  },
33093
33158
  requirements: resolveFeatureRequirements(compoundsLeftToRight),
33094
33159
  compoundsRightToLeft: compoundsLeftToRight.toReversed(),
33095
- combinatorsRightToLeft: parsed.combinators.toReversed()
33160
+ combinatorsRightToLeft: selector.combinators.toReversed()
33096
33161
  };
33097
33162
  }
33163
+ function buildCompiledCompound(sc) {
33164
+ const parts = sc.parts;
33165
+ for (let i = 0; i < parts.length; i++) {
33166
+ const part = parts[i];
33167
+ if (!part) continue;
33168
+ if (part.type === "pseudo-element") return null;
33169
+ }
33170
+ const pseudoConstraints = sc.pseudoClasses;
33171
+ if (pseudoConstraints.length === 0) {
33172
+ return {
33173
+ tagName: sc.tagName,
33174
+ idValue: sc.idValue,
33175
+ classes: sc.classes,
33176
+ attributes: sc.attributes,
33177
+ pseudo: EMPTY_PSEUDO
33178
+ };
33179
+ }
33180
+ let firstChild = false;
33181
+ let lastChild = false;
33182
+ let onlyChild = false;
33183
+ let nthChild = null;
33184
+ let nthLastChild = null;
33185
+ let nthOfType = null;
33186
+ let nthLastOfType = null;
33187
+ const anyOfGroups = [];
33188
+ const noneOfGroups = [];
33189
+ for (let i = 0; i < pseudoConstraints.length; i++) {
33190
+ const pc = pseudoConstraints[i];
33191
+ if (!pc) continue;
33192
+ if (pc.kind === 0 /* Simple */) {
33193
+ if (STATEFUL_PSEUDO_CLASSES.has(pc.name)) return null;
33194
+ continue;
33195
+ }
33196
+ if (pc.kind === 1 /* FirstChild */) {
33197
+ firstChild = true;
33198
+ continue;
33199
+ }
33200
+ if (pc.kind === 2 /* LastChild */) {
33201
+ lastChild = true;
33202
+ continue;
33203
+ }
33204
+ if (pc.kind === 3 /* OnlyChild */) {
33205
+ firstChild = true;
33206
+ lastChild = true;
33207
+ onlyChild = true;
33208
+ continue;
33209
+ }
33210
+ if (pc.kind === 4 /* NthChild */) {
33211
+ if (!pc.nthPattern) return null;
33212
+ nthChild = pc.nthPattern;
33213
+ continue;
33214
+ }
33215
+ if (pc.kind === 5 /* NthLastChild */) {
33216
+ if (!pc.nthPattern) return null;
33217
+ nthLastChild = pc.nthPattern;
33218
+ continue;
33219
+ }
33220
+ if (pc.kind === 6 /* NthOfType */) {
33221
+ if (!pc.nthPattern) return null;
33222
+ nthOfType = pc.nthPattern;
33223
+ continue;
33224
+ }
33225
+ if (pc.kind === 7 /* NthLastOfType */) {
33226
+ if (!pc.nthPattern) return null;
33227
+ nthLastOfType = pc.nthPattern;
33228
+ continue;
33229
+ }
33230
+ if (pc.kind === 8 /* MatchesAny */) {
33231
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
33232
+ const group = buildNestedGroup(pc.nestedCompounds);
33233
+ if (group === null) return null;
33234
+ if (group.length > 0) anyOfGroups.push(group);
33235
+ }
33236
+ continue;
33237
+ }
33238
+ if (pc.kind === 9 /* NoneOf */) {
33239
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
33240
+ const group = buildNestedGroup(pc.nestedCompounds);
33241
+ if (group === null) return null;
33242
+ if (group.length > 0) noneOfGroups.push(group);
33243
+ }
33244
+ continue;
33245
+ }
33246
+ }
33247
+ return {
33248
+ tagName: sc.tagName,
33249
+ idValue: sc.idValue,
33250
+ classes: sc.classes,
33251
+ attributes: sc.attributes,
33252
+ pseudo: {
33253
+ firstChild,
33254
+ lastChild,
33255
+ onlyChild,
33256
+ nthChild,
33257
+ nthLastChild,
33258
+ nthOfType,
33259
+ nthLastOfType,
33260
+ anyOfGroups,
33261
+ noneOfGroups
33262
+ }
33263
+ };
33264
+ }
33265
+ function buildNestedGroup(nestedCompounds) {
33266
+ const out = [];
33267
+ for (let i = 0; i < nestedCompounds.length; i++) {
33268
+ const compoundGroup = nestedCompounds[i];
33269
+ if (!compoundGroup) continue;
33270
+ if (compoundGroup.length !== 1) continue;
33271
+ const sc = compoundGroup[0];
33272
+ if (!sc) continue;
33273
+ const compiled = buildCompiledCompound(sc);
33274
+ if (compiled === null) return null;
33275
+ out.push(compiled);
33276
+ }
33277
+ return out;
33278
+ }
33098
33279
  function collectSubjectAttributeNames(subject) {
33099
33280
  if (subject.attributes.length === 0) return [];
33100
33281
  const names = /* @__PURE__ */ new Set();
@@ -33170,42 +33351,42 @@ function compoundGroupNeedsAttributes(groups) {
33170
33351
  }
33171
33352
  return false;
33172
33353
  }
33173
- function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger) {
33354
+ function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger, fileElementIndex = null) {
33174
33355
  const firstCompound = matcher.compoundsRightToLeft[0];
33175
- if (firstCompound === void 0) return "no-match";
33356
+ if (firstCompound === void 0) return 1 /* NoMatch */;
33176
33357
  const subjectResult = matchesCompound(node, firstCompound);
33177
- if (subjectResult === "no-match") return "no-match";
33358
+ if (subjectResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33178
33359
  if (matcher.compoundsRightToLeft.length === 1) return subjectResult;
33179
- const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger);
33180
- if (chainResult === "no-match") return "no-match";
33181
- if (subjectResult === "conditional" || chainResult === "conditional") return "conditional";
33182
- return "match";
33360
+ const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger, fileElementIndex);
33361
+ if (chainResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33362
+ if (subjectResult === 2 /* Conditional */ || chainResult === 2 /* Conditional */) return 2 /* Conditional */;
33363
+ return 0 /* Match */;
33183
33364
  }
33184
- function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
33365
+ function matchesChain(matcher, node, index, perf, fileRootElements, logger, fileElementIndex = null) {
33185
33366
  const combinator = matcher.combinatorsRightToLeft[index];
33186
- if (combinator === void 0) return "no-match";
33367
+ if (combinator === void 0) return 1 /* NoMatch */;
33187
33368
  const nextIndex = index + 1;
33188
33369
  const targetCompound = matcher.compoundsRightToLeft[nextIndex];
33189
- if (targetCompound === void 0) return "no-match";
33370
+ if (targetCompound === void 0) return 1 /* NoMatch */;
33190
33371
  const isFinal = nextIndex === matcher.compoundsRightToLeft.length - 1;
33191
33372
  if (combinator === "child") {
33192
33373
  const parent = node.parentElementNode;
33193
- if (parent === null) return "no-match";
33374
+ if (parent === null) return 1 /* NoMatch */;
33194
33375
  perf.ancestryChecks++;
33195
33376
  const compoundResult = matchesCompound(parent, targetCompound);
33196
- if (compoundResult === "no-match") return "no-match";
33377
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33197
33378
  if (isFinal) return compoundResult;
33198
- const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger);
33379
+ const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33199
33380
  return mergeMatchResults(compoundResult, chainResult);
33200
33381
  }
33201
33382
  if (combinator === "adjacent") {
33202
33383
  const sibling = node.previousSiblingNode;
33203
- if (sibling === null) return "no-match";
33384
+ if (sibling === null) return 1 /* NoMatch */;
33204
33385
  perf.ancestryChecks++;
33205
33386
  const compoundResult = matchesCompound(sibling, targetCompound);
33206
- if (compoundResult === "no-match") return "no-match";
33387
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33207
33388
  if (isFinal) return compoundResult;
33208
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
33389
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33209
33390
  return mergeMatchResults(compoundResult, chainResult);
33210
33391
  }
33211
33392
  if (combinator === "sibling") {
@@ -33213,26 +33394,26 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
33213
33394
  while (sibling !== null) {
33214
33395
  perf.ancestryChecks++;
33215
33396
  const compoundResult = matchesCompound(sibling, targetCompound);
33216
- if (compoundResult !== "no-match") {
33397
+ if (compoundResult !== 1 /* NoMatch */) {
33217
33398
  if (isFinal) return compoundResult;
33218
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
33219
- if (chainResult !== "no-match") return mergeMatchResults(compoundResult, chainResult);
33399
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33400
+ if (chainResult !== 1 /* NoMatch */) return mergeMatchResults(compoundResult, chainResult);
33220
33401
  }
33221
33402
  sibling = sibling.previousSiblingNode;
33222
33403
  }
33223
- return "no-match";
33404
+ return 1 /* NoMatch */;
33224
33405
  }
33225
- let bestResult = "no-match";
33406
+ let bestResult = 1 /* NoMatch */;
33226
33407
  let ancestor = node.parentElementNode;
33227
33408
  while (ancestor !== null) {
33228
33409
  perf.ancestryChecks++;
33229
33410
  const compoundResult = matchesCompound(ancestor, targetCompound);
33230
- if (compoundResult !== "no-match") {
33411
+ if (compoundResult !== 1 /* NoMatch */) {
33231
33412
  if (isFinal) return compoundResult;
33232
- const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger);
33233
- if (chainResult !== "no-match") {
33413
+ const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33414
+ if (chainResult !== 1 /* NoMatch */) {
33234
33415
  const merged = mergeMatchResults(compoundResult, chainResult);
33235
- if (merged === "match") return "match";
33416
+ if (merged === 0 /* Match */) return 0 /* Match */;
33236
33417
  bestResult = merged;
33237
33418
  }
33238
33419
  }
@@ -33250,30 +33431,50 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
33250
33431
  if (root.solidFile !== node.solidFile) continue;
33251
33432
  perf.ancestryChecks++;
33252
33433
  const compoundResult = matchesCompound(root, targetCompound);
33253
- if (logger.isLevelEnabled(Level.Trace) && compoundResult === "no-match") {
33434
+ if (logger.isLevelEnabled(Level.Trace) && compoundResult === 1 /* NoMatch */) {
33254
33435
  logger.trace(`[selector-match] fallback MISS: root=${root.key} tag=${root.tagName} attrs=[${[...root.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}]`);
33255
33436
  }
33256
- if (compoundResult !== "no-match") {
33437
+ if (compoundResult !== 1 /* NoMatch */) {
33257
33438
  if (logger.isLevelEnabled(Level.Debug)) {
33258
33439
  const compoundDesc = describeCompound(targetCompound);
33259
33440
  logger.debug(`[selector-match] fallback HIT: node=${node.key} tag=${node.tagName} matched root=${root.key} tag=${root.tagName} compound=${compoundDesc} isFinal=${isFinal}`);
33260
33441
  }
33261
33442
  if (isFinal) return compoundResult;
33262
- const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger);
33263
- if (chainResult !== "no-match") {
33443
+ const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33444
+ if (chainResult !== 1 /* NoMatch */) {
33264
33445
  const merged = mergeMatchResults(compoundResult, chainResult);
33265
- if (merged === "match") return "match";
33446
+ if (merged === 0 /* Match */) return 0 /* Match */;
33266
33447
  bestResult = merged;
33267
33448
  }
33268
33449
  }
33269
33450
  }
33270
33451
  }
33452
+ if (fileElementIndex !== null && bestResult === 1 /* NoMatch */) {
33453
+ const candidates = resolveCompoundCandidates(fileElementIndex, targetCompound);
33454
+ if (candidates !== null) {
33455
+ for (let r = 0; r < candidates.length; r++) {
33456
+ const elem = candidates[r];
33457
+ if (elem === void 0) continue;
33458
+ if (elem === node) continue;
33459
+ perf.ancestryChecks++;
33460
+ const compoundResult = matchesCompound(elem, targetCompound);
33461
+ if (compoundResult !== 1 /* NoMatch */) {
33462
+ if (logger.isLevelEnabled(Level.Debug)) {
33463
+ const compoundDesc = describeCompound(targetCompound);
33464
+ logger.debug(`[selector-match] indexed fallback HIT: node=${node.key} tag=${node.tagName} matched elem=${elem.key} tag=${elem.tagName} compound=${compoundDesc}`);
33465
+ }
33466
+ bestResult = 2 /* Conditional */;
33467
+ break;
33468
+ }
33469
+ }
33470
+ }
33471
+ }
33271
33472
  return bestResult;
33272
33473
  }
33273
33474
  function mergeMatchResults(a, b) {
33274
- if (a === "no-match" || b === "no-match") return "no-match";
33275
- if (a === "conditional" || b === "conditional") return "conditional";
33276
- return "match";
33475
+ if (a === 1 /* NoMatch */ || b === 1 /* NoMatch */) return 1 /* NoMatch */;
33476
+ if (a === 2 /* Conditional */ || b === 2 /* Conditional */) return 2 /* Conditional */;
33477
+ return 0 /* Match */;
33277
33478
  }
33278
33479
  function describeCompound(compound) {
33279
33480
  const parts = [];
@@ -33292,16 +33493,31 @@ function describeCompound(compound) {
33292
33493
  if (compound.idValue !== null) parts.push(`#${compound.idValue}`);
33293
33494
  return parts.join("") || "*";
33294
33495
  }
33496
+ function resolveCompoundCandidates(index, compound) {
33497
+ if (compound.idValue !== null) {
33498
+ return index.byDispatchKey.get(`id:${compound.idValue}`) ?? null;
33499
+ }
33500
+ if (compound.classes.length > 0 && compound.classes[0] !== void 0) {
33501
+ return index.byDispatchKey.get(`class:${compound.classes[0]}`) ?? null;
33502
+ }
33503
+ if (compound.attributes.length > 0 && compound.attributes[0] !== void 0) {
33504
+ return index.byDispatchKey.get(`attr:${compound.attributes[0].name}`) ?? null;
33505
+ }
33506
+ if (compound.tagName !== null) {
33507
+ return index.byTagName.get(compound.tagName) ?? null;
33508
+ }
33509
+ return null;
33510
+ }
33295
33511
  function matchesCompound(node, compound) {
33296
- if (compound.tagName !== null && node.tagName !== compound.tagName) return "no-match";
33512
+ if (compound.tagName !== null && node.tagName !== compound.tagName) return 1 /* NoMatch */;
33297
33513
  if (compound.idValue !== null) {
33298
33514
  const id = node.attributes.get("id");
33299
- if (id !== compound.idValue) return "no-match";
33515
+ if (id !== compound.idValue) return 1 /* NoMatch */;
33300
33516
  }
33301
- if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return "no-match";
33517
+ if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return 1 /* NoMatch */;
33302
33518
  const attrResult = matchesRequiredAttributes(compound.attributes, node.attributes);
33303
- if (attrResult === "no-match") return "no-match";
33304
- if (!matchesPseudoConstraints(node, compound.pseudo)) return "no-match";
33519
+ if (attrResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33520
+ if (!matchesPseudoConstraints(node, compound.pseudo)) return 1 /* NoMatch */;
33305
33521
  return attrResult;
33306
33522
  }
33307
33523
  function matchesPseudoConstraints(node, pseudo) {
@@ -33327,7 +33543,7 @@ function matchesPseudoConstraints(node, pseudo) {
33327
33543
  for (let j = 0; j < group.length; j++) {
33328
33544
  const compound = group[j];
33329
33545
  if (compound === void 0) continue;
33330
- if (matchesCompound(node, compound) === "no-match") continue;
33546
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
33331
33547
  matched = true;
33332
33548
  break;
33333
33549
  }
@@ -33339,607 +33555,12 @@ function matchesPseudoConstraints(node, pseudo) {
33339
33555
  for (let j = 0; j < group.length; j++) {
33340
33556
  const compound = group[j];
33341
33557
  if (compound === void 0) continue;
33342
- if (matchesCompound(node, compound) === "no-match") continue;
33558
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
33343
33559
  return false;
33344
33560
  }
33345
33561
  }
33346
33562
  return true;
33347
33563
  }
33348
- function parseSelectorPattern(raw) {
33349
- const compounds = [];
33350
- const combinators = [];
33351
- const length = raw.length;
33352
- let start = 0;
33353
- let bracketDepth = 0;
33354
- let parenDepth = 0;
33355
- let i = 0;
33356
- while (i < length) {
33357
- const code = raw.charCodeAt(i);
33358
- if (code === CHAR_OPEN_BRACKET) {
33359
- bracketDepth++;
33360
- i++;
33361
- continue;
33362
- }
33363
- if (code === CHAR_CLOSE_BRACKET) {
33364
- if (bracketDepth > 0) bracketDepth--;
33365
- i++;
33366
- continue;
33367
- }
33368
- if (code === CHAR_OPEN_PAREN) {
33369
- parenDepth++;
33370
- i++;
33371
- continue;
33372
- }
33373
- if (code === CHAR_CLOSE_PAREN) {
33374
- if (parenDepth > 0) parenDepth--;
33375
- i++;
33376
- continue;
33377
- }
33378
- if (bracketDepth === 0 && parenDepth === 0) {
33379
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
33380
- const compound = raw.slice(start, i).trim();
33381
- if (compound.length === 0) return null;
33382
- compounds.push(compound);
33383
- combinators.push(combinatorFromCode(code));
33384
- i++;
33385
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
33386
- start = i;
33387
- continue;
33388
- }
33389
- if (isWhitespace(code)) {
33390
- const compound = raw.slice(start, i).trim();
33391
- if (compound.length > 0) compounds.push(compound);
33392
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
33393
- if (i >= length) break;
33394
- const next = raw.charCodeAt(i);
33395
- if (next === CHAR_GT || next === CHAR_PLUS || next === CHAR_TILDE) {
33396
- if (compound.length === 0) return null;
33397
- combinators.push(combinatorFromCode(next));
33398
- i++;
33399
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
33400
- start = i;
33401
- continue;
33402
- }
33403
- if (compound.length > 0) combinators.push("descendant");
33404
- start = i;
33405
- continue;
33406
- }
33407
- }
33408
- i++;
33409
- }
33410
- const trailing = raw.slice(start).trim();
33411
- if (trailing.length > 0) compounds.push(trailing);
33412
- if (compounds.length === 0) return null;
33413
- if (combinators.length !== compounds.length - 1) return null;
33414
- return { compounds, combinators };
33415
- }
33416
- function combinatorFromCode(code) {
33417
- if (code === CHAR_GT) return "child";
33418
- if (code === CHAR_PLUS) return "adjacent";
33419
- return "sibling";
33420
- }
33421
- function compileCompound(raw, depth) {
33422
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
33423
- const parts = parseCompoundParts(raw);
33424
- if (parts.length === 0) return null;
33425
- let tagName = null;
33426
- let idValue = null;
33427
- const classes = [];
33428
- const seenClasses = /* @__PURE__ */ new Set();
33429
- const attributes = [];
33430
- let firstChild = false;
33431
- let lastChild = false;
33432
- let onlyChild = false;
33433
- let nthChild = null;
33434
- let nthLastChild = null;
33435
- let nthOfType = null;
33436
- let nthLastOfType = null;
33437
- const anyOfGroups = [];
33438
- const noneOfGroups = [];
33439
- for (let i = 0; i < parts.length; i++) {
33440
- const part = parts[i];
33441
- if (part === void 0) continue;
33442
- if (part.type === "element") {
33443
- tagName = part.value.toLowerCase();
33444
- continue;
33445
- }
33446
- if (part.type === "universal") continue;
33447
- if (part.type === "id") {
33448
- idValue = part.value;
33449
- continue;
33450
- }
33451
- if (part.type === "class") {
33452
- if (seenClasses.has(part.value)) continue;
33453
- seenClasses.add(part.value);
33454
- classes.push(part.value);
33455
- continue;
33456
- }
33457
- if (part.type === "attribute") {
33458
- const attribute = parseAttributeConstraint(part.value);
33459
- if (attribute === null) return null;
33460
- attributes.push(attribute);
33461
- continue;
33462
- }
33463
- if (part.type === "pseudo-class") {
33464
- const pseudo = parsePseudoConstraint(part.raw, depth);
33465
- if (pseudo === null) return null;
33466
- if (pseudo.kind === "first-child") {
33467
- firstChild = true;
33468
- continue;
33469
- }
33470
- if (pseudo.kind === "last-child") {
33471
- lastChild = true;
33472
- continue;
33473
- }
33474
- if (pseudo.kind === "only-child") {
33475
- firstChild = true;
33476
- lastChild = true;
33477
- onlyChild = true;
33478
- continue;
33479
- }
33480
- if (pseudo.kind === "nth-child") {
33481
- if (nthChild !== null && !isSameNthPattern(nthChild, pseudo.value)) return null;
33482
- nthChild = pseudo.value;
33483
- continue;
33484
- }
33485
- if (pseudo.kind === "nth-last-child") {
33486
- if (nthLastChild !== null && !isSameNthPattern(nthLastChild, pseudo.value)) return null;
33487
- nthLastChild = pseudo.value;
33488
- continue;
33489
- }
33490
- if (pseudo.kind === "nth-of-type") {
33491
- if (nthOfType !== null && !isSameNthPattern(nthOfType, pseudo.value)) return null;
33492
- nthOfType = pseudo.value;
33493
- continue;
33494
- }
33495
- if (pseudo.kind === "nth-last-of-type") {
33496
- if (nthLastOfType !== null && !isSameNthPattern(nthLastOfType, pseudo.value)) return null;
33497
- nthLastOfType = pseudo.value;
33498
- continue;
33499
- }
33500
- if (pseudo.kind === "ignore") continue;
33501
- if (pseudo.kind === "matches-any") {
33502
- anyOfGroups.push(pseudo.selectors);
33503
- continue;
33504
- }
33505
- noneOfGroups.push(pseudo.selectors);
33506
- continue;
33507
- }
33508
- return null;
33509
- }
33510
- if (firstChild && nthChild !== null && !matchesNthPattern(1, nthChild)) return null;
33511
- if (lastChild && nthLastChild !== null && !matchesNthPattern(1, nthLastChild)) return null;
33512
- return {
33513
- tagName,
33514
- idValue,
33515
- classes,
33516
- attributes,
33517
- pseudo: {
33518
- firstChild,
33519
- lastChild,
33520
- onlyChild,
33521
- nthChild,
33522
- nthLastChild,
33523
- nthOfType,
33524
- nthLastOfType,
33525
- anyOfGroups,
33526
- noneOfGroups
33527
- }
33528
- };
33529
- }
33530
- function parseAttributeConstraint(raw) {
33531
- const trimmed = raw.trim();
33532
- const constrained = ATTRIBUTE_CONSTRAINT_RE2.exec(trimmed);
33533
- if (constrained) {
33534
- const operatorToken = constrained[2];
33535
- if (operatorToken === void 0) return null;
33536
- const operator = mapAttributeOperatorFromToken2(operatorToken);
33537
- if (operator === null) return null;
33538
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
33539
- if (value2 === null) return null;
33540
- const nameToken = constrained[1];
33541
- if (nameToken === void 0) return null;
33542
- return {
33543
- name: nameToken.toLowerCase(),
33544
- operator,
33545
- value: value2,
33546
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
33547
- };
33548
- }
33549
- if (!ATTRIBUTE_EXISTS_RE2.test(trimmed)) return null;
33550
- return {
33551
- name: trimmed.toLowerCase(),
33552
- operator: "exists",
33553
- value: null,
33554
- caseInsensitive: false
33555
- };
33556
- }
33557
- function mapAttributeOperatorFromToken2(operator) {
33558
- if (operator === "=") return "equals";
33559
- if (operator === "~=") return "includes-word";
33560
- if (operator === "|=") return "dash-prefix";
33561
- if (operator === "^=") return "prefix";
33562
- if (operator === "$=") return "suffix";
33563
- if (operator === "*=") return "contains";
33564
- return null;
33565
- }
33566
- function parsePseudoConstraint(raw, depth) {
33567
- const trimmed = raw.trim();
33568
- const normalized = trimmed.toLowerCase();
33569
- if (normalized === ":first-child") return { kind: "first-child" };
33570
- if (normalized === ":last-child") return { kind: "last-child" };
33571
- if (normalized === ":only-child") return { kind: "only-child" };
33572
- const nthChild = parseNthPseudoArgument(trimmed, "nth-child");
33573
- if (nthChild !== void 0) {
33574
- if (nthChild === null) return null;
33575
- return { kind: "nth-child", value: nthChild };
33576
- }
33577
- const nthLastChild = parseNthPseudoArgument(trimmed, "nth-last-child");
33578
- if (nthLastChild !== void 0) {
33579
- if (nthLastChild === null) return null;
33580
- return { kind: "nth-last-child", value: nthLastChild };
33581
- }
33582
- const nthOfType = parseNthPseudoArgument(trimmed, "nth-of-type");
33583
- if (nthOfType !== void 0) {
33584
- if (nthOfType === null) return null;
33585
- return { kind: "nth-of-type", value: nthOfType };
33586
- }
33587
- const nthLastOfType = parseNthPseudoArgument(trimmed, "nth-last-of-type");
33588
- if (nthLastOfType !== void 0) {
33589
- if (nthLastOfType === null) return null;
33590
- return { kind: "nth-last-of-type", value: nthLastOfType };
33591
- }
33592
- const name = readPseudoName(normalized);
33593
- if (name === null) return null;
33594
- if (STATEFUL_PSEUDO_CLASSES.has(name)) return null;
33595
- if (name !== "is" && name !== "where" && name !== "not") {
33596
- return { kind: "ignore" };
33597
- }
33598
- const content = extractFunctionalPseudoContent(trimmed, name);
33599
- if (content === null) return null;
33600
- const selectors = compileFunctionalPseudoArguments(content, depth + 1);
33601
- if (selectors === null || selectors.length === 0) return null;
33602
- if (name === "not") {
33603
- return {
33604
- kind: "matches-none",
33605
- selectors
33606
- };
33607
- }
33608
- return {
33609
- kind: "matches-any",
33610
- selectors
33611
- };
33612
- }
33613
- function parseNthPseudoArgument(raw, name) {
33614
- const content = extractFunctionalPseudoContent(raw, name);
33615
- if (content === null) return void 0;
33616
- return parseNthPattern(content);
33617
- }
33618
- function parseNthPattern(raw) {
33619
- const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
33620
- if (normalized.length === 0) return null;
33621
- if (normalized === "odd") {
33622
- return { step: 2, offset: 1 };
33623
- }
33624
- if (normalized === "even") {
33625
- return { step: 2, offset: 0 };
33626
- }
33627
- const nIndex = normalized.indexOf("n");
33628
- if (nIndex === -1) {
33629
- const value2 = Number.parseInt(normalized, 10);
33630
- if (Number.isNaN(value2)) return null;
33631
- return { step: 0, offset: value2 };
33632
- }
33633
- const stepPart = normalized.slice(0, nIndex);
33634
- const offsetPart = normalized.slice(nIndex + 1);
33635
- let step;
33636
- if (stepPart.length === 0 || stepPart === "+") {
33637
- step = 1;
33638
- } else if (stepPart === "-") {
33639
- step = -1;
33640
- } else {
33641
- step = Number.parseInt(stepPart, 10);
33642
- if (Number.isNaN(step)) return null;
33643
- }
33644
- let offset = 0;
33645
- if (offsetPart.length > 0) {
33646
- offset = Number.parseInt(offsetPart, 10);
33647
- if (Number.isNaN(offset)) return null;
33648
- }
33649
- return {
33650
- step,
33651
- offset
33652
- };
33653
- }
33654
- function extractFunctionalPseudoContent(raw, name) {
33655
- const prefix = `:${name}(`;
33656
- if (!raw.toLowerCase().startsWith(prefix)) return null;
33657
- if (!raw.endsWith(")")) return null;
33658
- return raw.slice(prefix.length, -1);
33659
- }
33660
- function compileFunctionalPseudoArguments(content, depth) {
33661
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
33662
- const args = splitTopLevelSelectorArguments(content);
33663
- if (args.length === 0) return null;
33664
- const out = [];
33665
- for (let i = 0; i < args.length; i++) {
33666
- const arg = args[i];
33667
- if (arg === void 0) return null;
33668
- const raw = arg.trim();
33669
- if (raw.length === 0) return null;
33670
- const parsed = parseSelectorPattern(raw);
33671
- if (parsed === null) return null;
33672
- if (parsed.combinators.length !== 0) return null;
33673
- if (parsed.compounds.length !== 1) return null;
33674
- const compoundRaw = parsed.compounds[0];
33675
- if (compoundRaw === void 0) return null;
33676
- const compiled = compileCompound(compoundRaw, depth);
33677
- if (compiled === null) return null;
33678
- out.push(compiled);
33679
- }
33680
- return out;
33681
- }
33682
- function splitTopLevelSelectorArguments(content) {
33683
- const out = [];
33684
- let start = 0;
33685
- let parenDepth = 0;
33686
- let bracketDepth = 0;
33687
- let quote = null;
33688
- for (let i = 0; i < content.length; i++) {
33689
- const code = content.charCodeAt(i);
33690
- if (quote !== null) {
33691
- if (code === quote) quote = null;
33692
- continue;
33693
- }
33694
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33695
- quote = code;
33696
- continue;
33697
- }
33698
- if (code === CHAR_OPEN_PAREN) {
33699
- parenDepth++;
33700
- continue;
33701
- }
33702
- if (code === CHAR_CLOSE_PAREN) {
33703
- if (parenDepth > 0) parenDepth--;
33704
- continue;
33705
- }
33706
- if (code === CHAR_OPEN_BRACKET) {
33707
- bracketDepth++;
33708
- continue;
33709
- }
33710
- if (code === CHAR_CLOSE_BRACKET) {
33711
- if (bracketDepth > 0) bracketDepth--;
33712
- continue;
33713
- }
33714
- if (code !== CHAR_COMMA) continue;
33715
- if (parenDepth !== 0) continue;
33716
- if (bracketDepth !== 0) continue;
33717
- out.push(content.slice(start, i));
33718
- start = i + 1;
33719
- }
33720
- out.push(content.slice(start));
33721
- return out;
33722
- }
33723
- function parseCompoundParts(raw) {
33724
- const trimmed = raw.trim();
33725
- if (trimmed.length === 0) return [];
33726
- const out = [];
33727
- const length = trimmed.length;
33728
- let i = 0;
33729
- let allowsElement = true;
33730
- while (i < length) {
33731
- const code = trimmed.charCodeAt(i);
33732
- if (code === CHAR_OPEN_BRACKET) {
33733
- const end = readBracketed(trimmed, i);
33734
- if (end === null) return [];
33735
- const inner = trimmed.slice(i + 1, end - 1);
33736
- out.push({
33737
- type: "attribute",
33738
- value: inner,
33739
- raw: trimmed.slice(i, end)
33740
- });
33741
- i = end;
33742
- allowsElement = false;
33743
- continue;
33744
- }
33745
- if (code === 35) {
33746
- const ident2 = readIdentifier(trimmed, i + 1);
33747
- if (ident2.consumed === 0) return [];
33748
- out.push({
33749
- type: "id",
33750
- value: ident2.value,
33751
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
33752
- });
33753
- i += 1 + ident2.consumed;
33754
- allowsElement = false;
33755
- continue;
33756
- }
33757
- if (code === 46) {
33758
- const ident2 = readIdentifier(trimmed, i + 1);
33759
- if (ident2.consumed === 0) return [];
33760
- out.push({
33761
- type: "class",
33762
- value: ident2.value,
33763
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
33764
- });
33765
- i += 1 + ident2.consumed;
33766
- allowsElement = false;
33767
- continue;
33768
- }
33769
- if (code === 58) {
33770
- const pseudo = readPseudo(trimmed, i);
33771
- if (pseudo === null) return [];
33772
- out.push(pseudo);
33773
- i += pseudo.raw.length;
33774
- allowsElement = false;
33775
- continue;
33776
- }
33777
- if (code === 42) {
33778
- out.push({
33779
- type: "universal",
33780
- value: "*",
33781
- raw: "*"
33782
- });
33783
- i++;
33784
- allowsElement = false;
33785
- continue;
33786
- }
33787
- if (!allowsElement) return [];
33788
- const ident = readIdentifier(trimmed, i);
33789
- if (ident.consumed === 0) return [];
33790
- out.push({
33791
- type: "element",
33792
- value: ident.value,
33793
- raw: trimmed.slice(i, i + ident.consumed)
33794
- });
33795
- i += ident.consumed;
33796
- allowsElement = false;
33797
- }
33798
- return out;
33799
- }
33800
- function readPseudo(input, start) {
33801
- const second = input.charCodeAt(start + 1);
33802
- if (second === 58) return null;
33803
- let i = start + 1;
33804
- while (i < input.length) {
33805
- const code = input.charCodeAt(i);
33806
- if (!isIdentChar(code)) break;
33807
- i++;
33808
- }
33809
- if (i === start + 1) return null;
33810
- const value2 = input.slice(start + 1, i);
33811
- if (input.charCodeAt(i) !== CHAR_OPEN_PAREN) {
33812
- return {
33813
- type: "pseudo-class",
33814
- value: value2,
33815
- raw: input.slice(start, i)
33816
- };
33817
- }
33818
- const end = readParenthesized(input, i);
33819
- if (end === null) return null;
33820
- return {
33821
- type: "pseudo-class",
33822
- value: value2,
33823
- raw: input.slice(start, end)
33824
- };
33825
- }
33826
- function readBracketed(input, start) {
33827
- let quote = null;
33828
- let depth = 0;
33829
- for (let i = start; i < input.length; i++) {
33830
- const code = input.charCodeAt(i);
33831
- if (quote !== null) {
33832
- if (code === quote) quote = null;
33833
- continue;
33834
- }
33835
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33836
- quote = code;
33837
- continue;
33838
- }
33839
- if (code === CHAR_OPEN_BRACKET) {
33840
- depth++;
33841
- continue;
33842
- }
33843
- if (code !== CHAR_CLOSE_BRACKET) continue;
33844
- depth--;
33845
- if (depth === 0) return i + 1;
33846
- if (depth < 0) return null;
33847
- }
33848
- return null;
33849
- }
33850
- function readParenthesized(input, start) {
33851
- let quote = null;
33852
- let depth = 0;
33853
- for (let i = start; i < input.length; i++) {
33854
- const code = input.charCodeAt(i);
33855
- if (quote !== null) {
33856
- if (code === quote) quote = null;
33857
- continue;
33858
- }
33859
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33860
- quote = code;
33861
- continue;
33862
- }
33863
- if (code === CHAR_OPEN_PAREN) {
33864
- depth++;
33865
- continue;
33866
- }
33867
- if (code !== CHAR_CLOSE_PAREN) continue;
33868
- depth--;
33869
- if (depth === 0) return i + 1;
33870
- if (depth < 0) return null;
33871
- }
33872
- return null;
33873
- }
33874
- var EMPTY_IDENTIFIER = { value: "", consumed: 0 };
33875
- function readIdentifier(input, start) {
33876
- const length = input.length;
33877
- let i = start;
33878
- let hasEscape = false;
33879
- while (i < length) {
33880
- const code = input.charCodeAt(i);
33881
- if (code === CHAR_BACKSLASH) {
33882
- if (i + 1 >= length) break;
33883
- hasEscape = true;
33884
- i = skipCssEscapeSequence(input, i + 1);
33885
- continue;
33886
- }
33887
- if (!isIdentChar(code)) break;
33888
- i++;
33889
- }
33890
- const consumed = i - start;
33891
- if (consumed === 0) return EMPTY_IDENTIFIER;
33892
- if (!hasEscape) {
33893
- const value2 = input.slice(start, i);
33894
- return { value: value2, consumed };
33895
- }
33896
- return { value: decodeCssEscapes(input, start, i), consumed };
33897
- }
33898
- var CHAR_BACKSLASH = 92;
33899
- function skipCssEscapeSequence(input, afterBackslash) {
33900
- const length = input.length;
33901
- if (afterBackslash >= length) return afterBackslash;
33902
- const first = input.charCodeAt(afterBackslash);
33903
- if (!isHexDigit(first)) return afterBackslash + 1;
33904
- let end = afterBackslash + 1;
33905
- const maxHex = Math.min(afterBackslash + 6, length);
33906
- while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
33907
- if (end < length && isWhitespace(input.charCodeAt(end))) end++;
33908
- return end;
33909
- }
33910
- function decodeCssEscapes(input, start, end) {
33911
- const parts = [];
33912
- let i = start;
33913
- while (i < end) {
33914
- const code = input.charCodeAt(i);
33915
- if (code !== CHAR_BACKSLASH) {
33916
- parts.push(String.fromCharCode(code));
33917
- i++;
33918
- continue;
33919
- }
33920
- i++;
33921
- if (i >= end) break;
33922
- const first = input.charCodeAt(i);
33923
- if (!isHexDigit(first)) {
33924
- parts.push(String.fromCharCode(first));
33925
- i++;
33926
- continue;
33927
- }
33928
- const hexStart = i;
33929
- const maxHex = Math.min(i + 6, end);
33930
- while (i < maxHex && isHexDigit(input.charCodeAt(i))) i++;
33931
- const codePoint = Number.parseInt(input.slice(hexStart, i), 16);
33932
- if (codePoint > 0 && codePoint <= 1114111) {
33933
- parts.push(String.fromCodePoint(codePoint));
33934
- }
33935
- if (i < end && isWhitespace(input.charCodeAt(i))) i++;
33936
- }
33937
- return parts.join("");
33938
- }
33939
- function isSameNthPattern(left, right) {
33940
- if (left.step !== right.step) return false;
33941
- return left.offset === right.offset;
33942
- }
33943
33564
  function matchesNthPattern(index, pattern) {
33944
33565
  if (index < 1) return false;
33945
33566
  const step = pattern.step;
@@ -33958,20 +33579,6 @@ function matchesNthPattern(index, pattern) {
33958
33579
  if (delta < 0) return false;
33959
33580
  return delta % positiveStep === 0;
33960
33581
  }
33961
- function readPseudoName(raw) {
33962
- if (!raw.startsWith(":")) return null;
33963
- let index = 1;
33964
- while (index < raw.length) {
33965
- const code = raw.charCodeAt(index);
33966
- const isUpper = code >= 65 && code <= 90;
33967
- const isLower = code >= 97 && code <= 122;
33968
- const isDash = code === 45;
33969
- if (!isUpper && !isLower && !isDash) break;
33970
- index++;
33971
- }
33972
- if (index <= 1) return null;
33973
- return raw.slice(1, index);
33974
- }
33975
33582
  function matchesRequiredClasses(required, actual) {
33976
33583
  if (required.length === 0) return true;
33977
33584
  if (actual.size === 0) return false;
@@ -33984,24 +33591,24 @@ function matchesRequiredClasses(required, actual) {
33984
33591
  return true;
33985
33592
  }
33986
33593
  function matchesRequiredAttributes(required, actual) {
33987
- if (required.length === 0) return "match";
33594
+ if (required.length === 0) return 0 /* Match */;
33988
33595
  let hasConditional = false;
33989
33596
  for (let i = 0; i < required.length; i++) {
33990
33597
  const constraint = required[i];
33991
33598
  if (constraint === void 0) continue;
33992
- if (!actual.has(constraint.name)) return "no-match";
33599
+ if (!actual.has(constraint.name)) return 1 /* NoMatch */;
33993
33600
  if (constraint.operator === "exists") continue;
33994
33601
  const actualValue = actual.get(constraint.name);
33995
- if (actualValue === void 0) return "no-match";
33602
+ if (actualValue === void 0) return 1 /* NoMatch */;
33996
33603
  if (actualValue === null) {
33997
33604
  hasConditional = true;
33998
33605
  continue;
33999
33606
  }
34000
- if (constraint.value === null) return "no-match";
33607
+ if (constraint.value === null) return 1 /* NoMatch */;
34001
33608
  if (matchesAttributeValue(actualValue, constraint)) continue;
34002
- return "no-match";
33609
+ return 1 /* NoMatch */;
34003
33610
  }
34004
- return hasConditional ? "conditional" : "match";
33611
+ return hasConditional ? 2 /* Conditional */ : 0 /* Match */;
34005
33612
  }
34006
33613
  function matchesAttributeValue(actualValue, constraint) {
34007
33614
  const expectedValue = constraint.value;
@@ -34175,11 +33782,11 @@ function accumulateSnapshotFacts(snapshot, sink) {
34175
33782
  sink.addConditional();
34176
33783
  continue;
34177
33784
  }
34178
- if (value2.kind === "unknown") {
33785
+ if (value2.kind === 1 /* Unknown */) {
34179
33786
  sink.addUnknown();
34180
33787
  continue;
34181
33788
  }
34182
- if (value2.quality === "estimated" && value2.px !== null) {
33789
+ if (value2.quality === 1 /* Estimated */ && value2.px !== null) {
34183
33790
  sink.addInterval();
34184
33791
  continue;
34185
33792
  }
@@ -34521,7 +34128,7 @@ function checkHeightContributions(snapshot, state) {
34521
34128
  if (!signalName) continue;
34522
34129
  const signal = snapshot.signals.get(signalName);
34523
34130
  if (!signal) continue;
34524
- if (signal.kind !== "known") continue;
34131
+ if (signal.kind !== 0 /* Known */) continue;
34525
34132
  if (signal.px !== null && signal.px > 0) {
34526
34133
  state.hasHeightContributingDescendant = true;
34527
34134
  return;
@@ -34531,7 +34138,7 @@ function checkHeightContributions(snapshot, state) {
34531
34138
  function checkVerticalAlignMitigation(snapshot, state) {
34532
34139
  const verticalAlign = snapshot.signals.get("vertical-align");
34533
34140
  if (!verticalAlign) return;
34534
- if (verticalAlign.kind !== "known") return;
34141
+ if (verticalAlign.kind !== 0 /* Known */) return;
34535
34142
  if (VERTICAL_ALIGN_MITIGATIONS.has(verticalAlign.normalized)) {
34536
34143
  state.hasVerticalAlignMitigation = true;
34537
34144
  }
@@ -35717,16 +35324,16 @@ function establishesFormattingContext2(node, snapshotByElementNode) {
35717
35324
  const snapshot = snapshotByElementNode.get(node);
35718
35325
  if (snapshot) {
35719
35326
  const displaySignal = snapshot.signals.get("display");
35720
- if (displaySignal && displaySignal.kind === "known") {
35327
+ if (displaySignal && displaySignal.kind === 0 /* Known */) {
35721
35328
  return !isInlineLevelDisplay(displaySignal.normalized);
35722
35329
  }
35723
35330
  const overflowSignal = snapshot.signals.get("overflow");
35724
- if (overflowSignal && overflowSignal.kind === "known") {
35331
+ if (overflowSignal && overflowSignal.kind === 0 /* Known */) {
35725
35332
  const ov = overflowSignal.normalized;
35726
35333
  if (ov !== "visible" && ov !== "clip") return true;
35727
35334
  }
35728
35335
  const overflowYSignal = snapshot.signals.get("overflow-y");
35729
- if (overflowYSignal && overflowYSignal.kind === "known") {
35336
+ if (overflowYSignal && overflowYSignal.kind === 0 /* Known */) {
35730
35337
  const ov = overflowYSignal.normalized;
35731
35338
  if (ov !== "visible" && ov !== "clip") return true;
35732
35339
  }
@@ -35919,18 +35526,21 @@ function buildSelectorCandidatesByNode(elements, scopedSelectorsBySolidFile, per
35919
35526
  }
35920
35527
  return out;
35921
35528
  }
35529
+ function buildDispatchKeys(idValue, classTokens, attributeNames) {
35530
+ const out = [];
35531
+ if (idValue !== null) out.push(`id:${idValue}`);
35532
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
35533
+ for (let i = 0; i < attributeNames.length; i++) out.push(`attr:${attributeNames[i]}`);
35534
+ if (out.length <= 1) return out;
35535
+ out.sort();
35536
+ return dedupeSorted(out);
35537
+ }
35922
35538
  function buildSelectorDispatchKeys(attributes, classTokens) {
35923
35539
  const out = [];
35924
35540
  const idValue = attributes.get("id");
35925
- if (idValue !== null && idValue !== void 0) {
35926
- out.push(`id:${idValue}`);
35927
- }
35928
- for (let i = 0; i < classTokens.length; i++) {
35929
- out.push(`class:${classTokens[i]}`);
35930
- }
35931
- for (const attributeName of attributes.keys()) {
35932
- out.push(`attr:${attributeName}`);
35933
- }
35541
+ if (idValue !== null && idValue !== void 0) out.push(`id:${idValue}`);
35542
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
35543
+ for (const attributeName of attributes.keys()) out.push(`attr:${attributeName}`);
35934
35544
  if (out.length <= 1) return out;
35935
35545
  out.sort();
35936
35546
  return dedupeSorted(out);
@@ -36074,19 +35684,11 @@ function selectorMatchesDispatchKeys(candidate, dispatchKeys) {
36074
35684
  return subjectIndex === candidate.subjectDispatchKeys.length;
36075
35685
  }
36076
35686
  function resolveSubjectDispatchKeys(matcher) {
36077
- const out = [];
36078
- if (matcher.subject.idValue !== null) {
36079
- out.push(`id:${matcher.subject.idValue}`);
36080
- }
36081
- for (let i = 0; i < matcher.subject.classes.length; i++) {
36082
- out.push(`class:${matcher.subject.classes[i]}`);
36083
- }
36084
- for (let i = 0; i < matcher.subject.attributeNames.length; i++) {
36085
- out.push(`attr:${matcher.subject.attributeNames[i]}`);
36086
- }
36087
- if (out.length <= 1) return out;
36088
- out.sort();
36089
- return dedupeSorted(out);
35687
+ return buildDispatchKeys(
35688
+ matcher.subject.idValue,
35689
+ matcher.subject.classes,
35690
+ matcher.subject.attributeNames
35691
+ );
36090
35692
  }
36091
35693
  function dedupeSorted(values) {
36092
35694
  if (values.length <= 1) return values;
@@ -36156,6 +35758,94 @@ function normalizeWithCache(cache, path) {
36156
35758
  return normalized;
36157
35759
  }
36158
35760
 
35761
+ // src/cross-file/layout/shorthand-expansion.ts
35762
+ var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
35763
+ ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
35764
+ ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
35765
+ ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
35766
+ ["inset", ["top", "right", "bottom", "left"]]
35767
+ ]);
35768
+ var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
35769
+ ["margin-block", ["margin-top", "margin-bottom"]],
35770
+ ["padding-block", ["padding-top", "padding-bottom"]],
35771
+ ["inset-block", ["inset-block-start", "inset-block-end"]]
35772
+ ]);
35773
+ var INLINE_EXPANSIONS = /* @__PURE__ */ new Map([
35774
+ ["padding-inline", ["padding-left", "padding-right"]]
35775
+ ]);
35776
+ function expandShorthand(property, value2) {
35777
+ const quadTarget = QUAD_EXPANSIONS.get(property);
35778
+ if (quadTarget !== void 0) {
35779
+ const parsed = parseQuadShorthand(value2);
35780
+ if (parsed === null) return null;
35781
+ return [
35782
+ { name: quadTarget[0], value: parsed.top },
35783
+ { name: quadTarget[1], value: parsed.right },
35784
+ { name: quadTarget[2], value: parsed.bottom },
35785
+ { name: quadTarget[3], value: parsed.left }
35786
+ ];
35787
+ }
35788
+ const blockTarget = BLOCK_EXPANSIONS.get(property);
35789
+ if (blockTarget !== void 0) {
35790
+ const parsed = parseBlockShorthand(value2);
35791
+ if (parsed === null) return null;
35792
+ return [
35793
+ { name: blockTarget[0], value: parsed.start },
35794
+ { name: blockTarget[1], value: parsed.end }
35795
+ ];
35796
+ }
35797
+ const inlineTarget = INLINE_EXPANSIONS.get(property);
35798
+ if (inlineTarget !== void 0) {
35799
+ const parsed = parseBlockShorthand(value2);
35800
+ if (parsed === null) return null;
35801
+ return [
35802
+ { name: inlineTarget[0], value: parsed.start },
35803
+ { name: inlineTarget[1], value: parsed.end }
35804
+ ];
35805
+ }
35806
+ if (property === "flex-flow") {
35807
+ return expandFlexFlow(value2);
35808
+ }
35809
+ return void 0;
35810
+ }
35811
+ var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
35812
+ function expandFlexFlow(value2) {
35813
+ const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
35814
+ if (tokens.length === 0) return null;
35815
+ if (tokens.length > 2) return null;
35816
+ let direction = null;
35817
+ let wrap = null;
35818
+ for (let i = 0; i < tokens.length; i++) {
35819
+ const token = tokens[i];
35820
+ if (!token) continue;
35821
+ if (FLEX_DIRECTION_VALUES.has(token)) {
35822
+ if (direction !== null) return null;
35823
+ direction = token;
35824
+ } else {
35825
+ if (wrap !== null) return null;
35826
+ wrap = token;
35827
+ }
35828
+ }
35829
+ const out = [];
35830
+ if (direction !== null) {
35831
+ out.push({ name: "flex-direction", value: direction });
35832
+ }
35833
+ if (wrap !== null) {
35834
+ out.push({ name: "flex-wrap", value: wrap });
35835
+ }
35836
+ return out.length > 0 ? out : null;
35837
+ }
35838
+ function getShorthandLonghandNames(property) {
35839
+ const quad = QUAD_EXPANSIONS.get(property);
35840
+ if (quad !== void 0) return [...quad];
35841
+ const block = BLOCK_EXPANSIONS.get(property);
35842
+ if (block !== void 0) return [...block];
35843
+ const inline = INLINE_EXPANSIONS.get(property);
35844
+ if (inline !== void 0) return [...inline];
35845
+ if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
35846
+ return null;
35847
+ }
35848
+
36159
35849
  // src/cross-file/layout/stateful-rule-index.ts
36160
35850
  var EMPTY_STATEFUL_SELECTOR_ENTRY_LIST = [];
36161
35851
  var EMPTY_LAYOUT_NORMALIZED_DECLARATION_LIST = [];
@@ -36373,7 +36063,6 @@ var DYNAMIC_ATTRIBUTE_GUARD = {
36373
36063
  key: "dynamic-attribute:*"
36374
36064
  };
36375
36065
  var SCROLLABLE_VALUES = /* @__PURE__ */ new Set(["auto", "scroll"]);
36376
- var EMPTY_EXPANSION_RESULT = [];
36377
36066
  function collectMonitoredDeclarations(selector, layerOrder, guard) {
36378
36067
  const out = [];
36379
36068
  const declarations = selector.rule.declarations;
@@ -36382,59 +36071,50 @@ function collectMonitoredDeclarations(selector, layerOrder, guard) {
36382
36071
  if (!declaration) continue;
36383
36072
  const property = declaration.property.toLowerCase();
36384
36073
  if (!isMonitoredSignal(property)) continue;
36385
- const monitored = toMonitoredSignalKey(property);
36386
- if (!monitored) continue;
36387
- out.push({
36388
- property: monitored,
36389
- value: declaration.value,
36390
- guardProvenance: guard,
36391
- position: {
36392
- layer: declaration.cascadePosition.layer,
36393
- layerOrder,
36394
- sourceOrder: declaration.sourceOrder,
36395
- specificity: selector.specificity,
36396
- specificityScore: selector.specificityScore,
36397
- isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36074
+ const position = {
36075
+ layer: declaration.cascadePosition.layer,
36076
+ layerOrder,
36077
+ sourceOrder: declaration.sourceOrder,
36078
+ specificity: selector.specificity,
36079
+ specificityScore: selector.specificityScore,
36080
+ isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36081
+ };
36082
+ const directSignal = MONITORED_SIGNAL_NAME_MAP.get(property);
36083
+ if (directSignal !== void 0) {
36084
+ out.push({ property: directSignal, value: declaration.value, guardProvenance: guard, position });
36085
+ continue;
36086
+ }
36087
+ const value2 = declaration.value.trim().toLowerCase();
36088
+ const expanded = expandShorthand(property, value2);
36089
+ if (expanded === void 0) continue;
36090
+ if (expanded === null) {
36091
+ const longhandNames = getShorthandLonghandNames(property);
36092
+ if (longhandNames === null) continue;
36093
+ for (let j = 0; j < longhandNames.length; j++) {
36094
+ const longhand = longhandNames[j];
36095
+ if (!longhand) continue;
36096
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(longhand);
36097
+ if (signal === void 0) continue;
36098
+ out.push({ property: signal, value: declaration.value, guardProvenance: guard, position });
36398
36099
  }
36399
- });
36100
+ continue;
36101
+ }
36102
+ for (let j = 0; j < expanded.length; j++) {
36103
+ const entry = expanded[j];
36104
+ if (!entry) continue;
36105
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36106
+ if (signal === void 0) continue;
36107
+ out.push({ property: signal, value: entry.value, guardProvenance: guard, position });
36108
+ }
36400
36109
  }
36401
36110
  return out;
36402
36111
  }
36403
- function toMonitoredSignalKey(property) {
36404
- const signal = MONITORED_SIGNAL_NAME_MAP.get(property);
36405
- if (signal) return signal;
36406
- switch (property) {
36407
- case "padding":
36408
- case "border-width":
36409
- case "margin-block":
36410
- case "padding-block":
36411
- case "inset-block":
36412
- case "flex-flow":
36413
- return property;
36414
- default:
36415
- return null;
36416
- }
36417
- }
36418
36112
  function expandMonitoredDeclarationForDelta(declaration) {
36419
- const value2 = declaration.value.trim().toLowerCase();
36420
- const expanded = expandShorthand(declaration.property, value2);
36421
- if (expanded !== void 0) {
36422
- if (expanded === null) return EMPTY_EXPANSION_RESULT;
36423
- const filtered = [];
36424
- for (let i = 0; i < expanded.length; i++) {
36425
- const entry = expanded[i];
36426
- if (!entry) continue;
36427
- const signalName2 = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36428
- if (signalName2 !== void 0) filtered.push({ name: signalName2, value: entry.value });
36429
- }
36430
- return filtered;
36431
- }
36432
- const signalName = MONITORED_SIGNAL_NAME_MAP.get(declaration.property);
36433
- if (signalName === void 0) return EMPTY_EXPANSION_RESULT;
36434
- return [{ name: signalName, value: value2 }];
36113
+ return [{ name: declaration.property, value: declaration.value.trim().toLowerCase() }];
36435
36114
  }
36436
36115
  function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, appliesByElementNodeMutable) {
36437
36116
  const fileRoots = ctx.rootElementsByFile.get(node.solidFile) ?? null;
36117
+ const fileElementIndex = ctx.fileElementIndexByFile.get(node.solidFile) ?? null;
36438
36118
  for (let i = 0; i < selectorIds.length; i++) {
36439
36119
  const selectorId = selectorIds[i];
36440
36120
  if (selectorId === void 0) continue;
@@ -36446,13 +36126,13 @@ function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, app
36446
36126
  if (!selector) {
36447
36127
  throw new Error(`missing selector ${selectorId}`);
36448
36128
  }
36449
- const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger);
36450
- if (matchResult === "no-match") continue;
36129
+ const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger, fileElementIndex);
36130
+ if (matchResult === 1 /* NoMatch */) continue;
36451
36131
  const edge = {
36452
36132
  selectorId: selector.id,
36453
36133
  specificityScore: selector.specificityScore,
36454
36134
  sourceOrder: selector.rule.sourceOrder,
36455
- conditionalMatch: matchResult === "conditional"
36135
+ conditionalMatch: matchResult === 2 /* Conditional */
36456
36136
  };
36457
36137
  applies.push(edge);
36458
36138
  ctx.perf.matchEdgesCreated++;
@@ -36509,7 +36189,54 @@ function augmentCascadeWithTailwind(cascade, node, tailwind) {
36509
36189
  }
36510
36190
  }
36511
36191
  }
36512
- function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind) {
36192
+ var MAX_VAR_SUBSTITUTION_DEPTH = 10;
36193
+ function resolveVarReferencesInCascade(cascade, variablesByName) {
36194
+ for (const [property, declaration] of cascade) {
36195
+ if (!declaration.value.includes("var(")) continue;
36196
+ const resolved = substituteVarReferences(declaration.value, variablesByName, 0);
36197
+ if (resolved !== declaration.value) {
36198
+ cascade.set(property, {
36199
+ value: resolved,
36200
+ source: declaration.source,
36201
+ guardProvenance: declaration.guardProvenance
36202
+ });
36203
+ }
36204
+ }
36205
+ }
36206
+ function substituteVarReferences(value2, variablesByName, depth) {
36207
+ if (depth >= MAX_VAR_SUBSTITUTION_DEPTH) return value2;
36208
+ const refs = extractVarReferences(value2);
36209
+ if (refs.length === 0) return value2;
36210
+ let result = value2;
36211
+ for (let i = refs.length - 1; i >= 0; i--) {
36212
+ const ref = refs[i];
36213
+ if (!ref) continue;
36214
+ const candidates = variablesByName.get(ref.name);
36215
+ const resolvedValue = candidates !== void 0 && candidates.length > 0 ? selectBestVariableValue(candidates) : ref.fallback;
36216
+ if (resolvedValue === null) continue;
36217
+ result = result.slice(0, ref.sourceIndex) + resolvedValue + result.slice(ref.sourceIndex + ref.raw.length);
36218
+ }
36219
+ if (result !== value2 && result.includes("var(")) {
36220
+ return substituteVarReferences(result, variablesByName, depth + 1);
36221
+ }
36222
+ return result;
36223
+ }
36224
+ function selectBestVariableValue(candidates) {
36225
+ let bestGlobal = null;
36226
+ for (let i = 0; i < candidates.length; i++) {
36227
+ const candidate = candidates[i];
36228
+ if (!candidate) continue;
36229
+ if (candidate.scope.type === "global") {
36230
+ if (bestGlobal === null || candidate.declaration.sourceOrder > bestGlobal.declaration.sourceOrder) {
36231
+ bestGlobal = candidate;
36232
+ }
36233
+ }
36234
+ }
36235
+ if (bestGlobal !== null) return bestGlobal.value;
36236
+ const first = candidates[0];
36237
+ return first ? first.value : null;
36238
+ }
36239
+ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind, variablesByName) {
36513
36240
  const out = /* @__PURE__ */ new Map();
36514
36241
  const positions = /* @__PURE__ */ new Map();
36515
36242
  for (let i = 0; i < edges.length; i++) {
@@ -36567,6 +36294,9 @@ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorI
36567
36294
  if (tailwind !== null) {
36568
36295
  augmentCascadeWithTailwind(out, node, tailwind);
36569
36296
  }
36297
+ if (variablesByName !== null) {
36298
+ resolveVarReferencesInCascade(out, variablesByName);
36299
+ }
36570
36300
  return out;
36571
36301
  }
36572
36302
  function compareLayoutEdge(a, b) {
@@ -36607,14 +36337,14 @@ function resolveRuleLayerOrder(rule, css) {
36607
36337
  if (!name) return 0;
36608
36338
  return css.layerOrder.get(name) ?? 0;
36609
36339
  }
36610
- function buildConditionalDeltaIndex(elements, appliesByNode, monitoredDeclarationsBySelectorId, selectorsById) {
36340
+ function buildConditionalDeltaIndex(elements, records, monitoredDeclarationsBySelectorId, selectorsById) {
36611
36341
  const conditionalSignalDeltaFactsByNode = /* @__PURE__ */ new Map();
36612
36342
  const elementsWithConditionalDeltaBySignal = /* @__PURE__ */ new Map();
36613
36343
  const baselineOffsetFactsByNode = /* @__PURE__ */ new Map();
36614
36344
  for (let i = 0; i < elements.length; i++) {
36615
36345
  const node = elements[i];
36616
36346
  if (!node) continue;
36617
- const edges = appliesByNode.get(node);
36347
+ const edges = records.get(node)?.edges;
36618
36348
  let factByProperty = null;
36619
36349
  if (edges !== void 0 && edges.length > 0) {
36620
36350
  const byProperty = /* @__PURE__ */ new Map();
@@ -36969,7 +36699,7 @@ function collectLayoutElementRecordsForSolid(solid, selectorRequirements, inline
36969
36699
  const classTokenSet = classTokens.length === 0 ? EMPTY_CLASS_TOKEN_SET : createClassTokenSet(classTokens);
36970
36700
  const inlineStyleKeys = getStaticStyleKeysForElement(solid, element.id);
36971
36701
  const localAttributes = selectorRequirements.needsAttributes ? collectStaticAttributes(element) : EMPTY_ATTRIBUTES2;
36972
- const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes);
36702
+ const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes, meta.resolvedHost?.descriptor.attributePropBindings);
36973
36703
  const selectorDispatchKeys = buildSelectorDispatchKeys(attributes, classTokens);
36974
36704
  const inlineStyleValues = inlineStyleValuesByElementId.get(element.id) ?? EMPTY_INLINE_STYLE_VALUES;
36975
36705
  const textualContent = getTextualContentState(element, textContentMemo, compositionMetaByElementId, logger);
@@ -37025,7 +36755,63 @@ function collectCompositionMetaByElementId(solid, componentHostResolver) {
37025
36755
  function resolveHostForElement(componentHostResolver, solidFile, element) {
37026
36756
  if (element.tag === null) return null;
37027
36757
  if (element.isDomElement) return null;
37028
- return componentHostResolver.resolveHost(solidFile, element.tag);
36758
+ const defaultHost = componentHostResolver.resolveHost(solidFile, element.tag);
36759
+ const asTag = extractPolymorphicAsTag(element);
36760
+ if (asTag !== null) {
36761
+ const asHost = componentHostResolver.resolveHost(solidFile, asTag);
36762
+ if (asHost !== null) return composePolymorphicHost(defaultHost, asHost);
36763
+ }
36764
+ return defaultHost;
36765
+ }
36766
+ function extractPolymorphicAsTag(element) {
36767
+ for (let i = 0; i < element.attributes.length; i++) {
36768
+ const attr = element.attributes[i];
36769
+ if (!attr) continue;
36770
+ if (attr.name !== "as") continue;
36771
+ if (attr.valueNode === null) continue;
36772
+ if (!import_typescript126.default.isJsxExpression(attr.valueNode)) continue;
36773
+ const expression = attr.valueNode.expression;
36774
+ if (!expression) continue;
36775
+ if (import_typescript126.default.isIdentifier(expression)) return expression.text;
36776
+ if (import_typescript126.default.isPropertyAccessExpression(expression)) return expression.getText();
36777
+ return null;
36778
+ }
36779
+ return null;
36780
+ }
36781
+ function composePolymorphicHost(outerHost, asHost) {
36782
+ if (outerHost === null) return asHost;
36783
+ const outerDesc = outerHost.descriptor;
36784
+ const asDesc = asHost.descriptor;
36785
+ const staticAttributes = /* @__PURE__ */ new Map();
36786
+ for (const [name, value2] of outerDesc.staticAttributes) staticAttributes.set(name, value2);
36787
+ for (const [name, value2] of asDesc.staticAttributes) staticAttributes.set(name, value2);
36788
+ const classTokenSet = /* @__PURE__ */ new Set();
36789
+ const staticClassTokens = [];
36790
+ for (const token of outerDesc.staticClassTokens) {
36791
+ if (!classTokenSet.has(token)) {
36792
+ classTokenSet.add(token);
36793
+ staticClassTokens.push(token);
36794
+ }
36795
+ }
36796
+ for (const token of asDesc.staticClassTokens) {
36797
+ if (!classTokenSet.has(token)) {
36798
+ classTokenSet.add(token);
36799
+ staticClassTokens.push(token);
36800
+ }
36801
+ }
36802
+ const attributePropBindings = /* @__PURE__ */ new Map();
36803
+ for (const [name, value2] of outerDesc.attributePropBindings) attributePropBindings.set(name, value2);
36804
+ for (const [name, value2] of asDesc.attributePropBindings) attributePropBindings.set(name, value2);
36805
+ return {
36806
+ descriptor: {
36807
+ tagName: asDesc.tagName ?? outerDesc.tagName,
36808
+ staticAttributes,
36809
+ staticClassTokens,
36810
+ forwardsChildren: asDesc.forwardsChildren || outerDesc.forwardsChildren,
36811
+ attributePropBindings
36812
+ },
36813
+ hostElementRef: asHost.hostElementRef ?? outerHost.hostElementRef
36814
+ };
37029
36815
  }
37030
36816
  function resolveTransparentPrimitiveStatus(componentHostResolver, solidFile, element, resolvedHost) {
37031
36817
  if (element.tag === null) return false;
@@ -37068,11 +36854,21 @@ function mergeClassTokens(localTokens, hostTokens) {
37068
36854
  }
37069
36855
  return out;
37070
36856
  }
37071
- function mergeAttributes(localAttributes, hostAttributes) {
36857
+ function mergeAttributes(localAttributes, hostAttributes, propBindings) {
37072
36858
  if (hostAttributes === void 0 || hostAttributes.size === 0) return localAttributes;
37073
- if (localAttributes.size === 0) return hostAttributes;
36859
+ if (localAttributes.size === 0 && (propBindings === void 0 || propBindings.size === 0)) return hostAttributes;
37074
36860
  const out = /* @__PURE__ */ new Map();
37075
36861
  for (const [name, value2] of hostAttributes) {
36862
+ if (propBindings !== void 0) {
36863
+ const propName = propBindings.get(name);
36864
+ if (propName !== void 0) {
36865
+ const callSiteValue = localAttributes.get(propName);
36866
+ if (callSiteValue !== void 0 && callSiteValue !== null) {
36867
+ out.set(name, callSiteValue);
36868
+ continue;
36869
+ }
36870
+ }
36871
+ }
37076
36872
  out.set(name, value2);
37077
36873
  }
37078
36874
  for (const [name, value2] of localAttributes) {
@@ -37138,7 +36934,9 @@ function resolveSiblingTypeCount(totalsByParentId, parentElementId, tagName, sib
37138
36934
 
37139
36935
  // src/cross-file/layout/build.ts
37140
36936
  var EMPTY_NUMBER_LIST2 = [];
37141
- var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch"]);
36937
+ var EMPTY_EDGE_LIST = Object.freeze([]);
36938
+ var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch", "inherit", "initial", "unset", "revert", "revert-layer"]);
36939
+ var BLOCK_LEVEL_DISPLAY_VALUES = /* @__PURE__ */ new Set(["block", "flex", "grid", "table", "list-item", "flow-root", "table-row", "table-cell", "table-caption", "table-row-group", "table-header-group", "table-footer-group", "table-column", "table-column-group"]);
37142
36940
  function buildLayoutGraph(solids, css, logger = noopLogger) {
37143
36941
  const perf = createLayoutPerfStats();
37144
36942
  const startedAt = performance.now();
@@ -37153,7 +36951,6 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37153
36951
  const selectorsById = /* @__PURE__ */ new Map();
37154
36952
  const monitoredDeclarationsBySelectorId = /* @__PURE__ */ new Map();
37155
36953
  const selectorMetadataById = /* @__PURE__ */ new Map();
37156
- const cascadeByElementNode = /* @__PURE__ */ new WeakMap();
37157
36954
  for (let i = 0; i < css.selectors.length; i++) {
37158
36955
  const selector = css.selectors[i];
37159
36956
  if (!selector) continue;
@@ -37226,7 +37023,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37226
37023
  };
37227
37024
  const textContentMemo = /* @__PURE__ */ new Map();
37228
37025
  const inlineStyleValuesByElementId = collectInlineStyleValuesByElementId(solid);
37229
- const records = collectLayoutElementRecordsForSolid(
37026
+ const records2 = collectLayoutElementRecordsForSolid(
37230
37027
  solid,
37231
37028
  selectorRequirements,
37232
37029
  inlineStyleValuesByElementId,
@@ -37234,12 +37031,12 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37234
37031
  componentHostResolver,
37235
37032
  logger
37236
37033
  );
37237
- const siblingTotals = collectSiblingTotals(records);
37034
+ const siblingTotals = collectSiblingTotals(records2);
37238
37035
  const nodeByElementId = /* @__PURE__ */ new Map();
37239
37036
  const lastChildByParentId = /* @__PURE__ */ new Map();
37240
37037
  const siblingTypeSeenByParentId = /* @__PURE__ */ new Map();
37241
- for (let i = 0; i < records.length; i++) {
37242
- const record = records[i];
37038
+ for (let i = 0; i < records2.length; i++) {
37039
+ const record = records2[i];
37243
37040
  if (!record) continue;
37244
37041
  const parentElementId = record.parentElementId;
37245
37042
  const parentNode = parentElementId === null ? null : nodeByElementId.get(parentElementId) ?? null;
@@ -37304,6 +37101,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37304
37101
  }
37305
37102
  }
37306
37103
  }
37104
+ const fileElementIndexByFile = buildFileElementIndexByFile(elements);
37307
37105
  if (logger.isLevelEnabled(Level.Debug)) {
37308
37106
  for (const [file, roots] of rootElementsByFile) {
37309
37107
  const descs = roots.map((r) => `${r.key}(tag=${r.tagName}, attrs=[${[...r.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}])`);
@@ -37315,63 +37113,138 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37315
37113
  selectorMetadataById,
37316
37114
  selectorsById,
37317
37115
  rootElementsByFile,
37116
+ fileElementIndexByFile,
37318
37117
  perf,
37319
37118
  logger
37320
37119
  };
37321
- for (let i = 0; i < elements.length; i++) {
37322
- const node = elements[i];
37323
- if (!node) continue;
37324
- const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37325
- if (selectorIds.length === 0) continue;
37326
- appendMatchingEdgesFromSelectorIds(
37327
- selectorMatchCtx,
37328
- selectorIds,
37329
- node,
37330
- applies,
37331
- appliesByElementNodeMutable
37332
- );
37333
- }
37334
- perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
37335
- const cascadeStartedAt = performance.now();
37336
- for (const edges of appliesByElementNodeMutable.values()) {
37337
- edges.sort(compareLayoutEdge);
37338
- }
37339
- const appliesByNode = /* @__PURE__ */ new Map();
37340
37120
  const tailwind = css.tailwind;
37121
+ const records = /* @__PURE__ */ new Map();
37122
+ const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
37123
+ const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37124
+ const elementsByTagName = /* @__PURE__ */ new Map();
37125
+ const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37126
+ const dynamicSlotCandidateElements = [];
37127
+ const scrollContainerElements = [];
37128
+ const positionedAncestorByKey = /* @__PURE__ */ new Map();
37129
+ const trace = logger.isLevelEnabled(Level.Trace);
37341
37130
  for (let i = 0; i < elements.length; i++) {
37342
37131
  const node = elements[i];
37343
37132
  if (!node) continue;
37344
- const edges = appliesByElementNodeMutable.get(node) ?? [];
37345
- const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind);
37346
- cascadeByElementNode.set(node, cascade);
37347
- appliesByNode.set(node, edges);
37348
- }
37349
- perf.cascadeBuildMs = performance.now() - cascadeStartedAt;
37350
- if (logger.isLevelEnabled(Level.Trace)) {
37351
- for (let i = 0; i < elements.length; i++) {
37352
- const node = elements[i];
37353
- if (!node) continue;
37354
- const cascade = cascadeByElementNode.get(node);
37355
- if (!cascade || cascade.size === 0) continue;
37133
+ const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37134
+ if (selectorIds.length > 0) {
37135
+ appendMatchingEdgesFromSelectorIds(
37136
+ selectorMatchCtx,
37137
+ selectorIds,
37138
+ node,
37139
+ applies,
37140
+ appliesByElementNodeMutable
37141
+ );
37142
+ }
37143
+ const mutableEdges = appliesByElementNodeMutable.get(node);
37144
+ if (mutableEdges) mutableEdges.sort(compareLayoutEdge);
37145
+ const edges = mutableEdges ?? EMPTY_EDGE_LIST;
37146
+ const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind, css.variablesByName);
37147
+ if (trace && cascade.size > 0) {
37356
37148
  const displayDecl = cascade.get("display");
37357
37149
  const flexDirDecl = cascade.get("flex-direction");
37358
- if (!displayDecl && !flexDirDecl) continue;
37359
- const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37360
- const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37361
- logger.trace(
37362
- `[cascade] node=${node.key} tag=${node.tagName ?? "null"} display=${displayDecl ? `${displayDecl.value}(${displayGuard})` : "absent"} flex-direction=${flexDirDecl ? `${flexDirDecl.value}(${flexDirGuard})` : "absent"} edges=${(appliesByNode.get(node) ?? []).length} attrs=[${[...node.attributes.keys()].join(",")}]`
37363
- );
37150
+ if (displayDecl || flexDirDecl) {
37151
+ const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37152
+ const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37153
+ logger.trace(
37154
+ `[cascade] node=${node.key} tag=${node.tagName ?? "null"} display=${displayDecl ? `${displayDecl.value}(${displayGuard})` : "absent"} flex-direction=${flexDirDecl ? `${flexDirDecl.value}(${flexDirGuard})` : "absent"} edges=${edges.length} attrs=[${[...node.attributes.keys()].join(",")}]`
37155
+ );
37156
+ }
37157
+ }
37158
+ const parentSnapshot = node.parentElementNode ? records.get(node.parentElementNode)?.snapshot ?? null : null;
37159
+ const snapshot = buildSnapshotFromCascade(node, cascade, parentSnapshot);
37160
+ snapshotByElementNode.set(node, snapshot);
37161
+ perf.signalSnapshotsBuilt++;
37162
+ if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37163
+ dynamicSlotCandidateElements.push(node);
37164
+ }
37165
+ if (node.tagName) {
37166
+ const existing = elementsByTagName.get(node.tagName);
37167
+ if (existing) existing.push(node);
37168
+ else elementsByTagName.set(node.tagName, [node]);
37169
+ }
37170
+ for (const [signal, value2] of snapshot.signals) {
37171
+ if (value2.kind !== 0 /* Known */) continue;
37172
+ let byValue = elementsByKnownSignalValue.get(signal);
37173
+ if (!byValue) {
37174
+ byValue = /* @__PURE__ */ new Map();
37175
+ elementsByKnownSignalValue.set(signal, byValue);
37176
+ }
37177
+ const existingNodes = byValue.get(value2.normalized);
37178
+ if (existingNodes) existingNodes.push(node);
37179
+ else byValue.set(value2.normalized, [node]);
37364
37180
  }
37181
+ const parentKey = node.parentElementNode?.key ?? null;
37182
+ let nearestPositionedAncestorKey = null;
37183
+ let nearestPositionedAncestorHasReservedSpace = false;
37184
+ if (parentKey !== null) {
37185
+ const parentPositioned = positionedAncestorByKey.get(parentKey);
37186
+ if (parentPositioned !== void 0) {
37187
+ nearestPositionedAncestorKey = parentPositioned.key;
37188
+ nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37189
+ }
37190
+ }
37191
+ const containingBlock = {
37192
+ nearestPositionedAncestorKey,
37193
+ nearestPositionedAncestorHasReservedSpace
37194
+ };
37195
+ const reservedSpace = computeReservedSpaceFact(snapshot);
37196
+ const scrollContainer = computeScrollContainerFact(snapshot);
37197
+ if (scrollContainer.isScrollContainer) scrollContainerElements.push(node);
37198
+ const flowParticipation = computeFlowParticipationFact(snapshot);
37199
+ const hotSignals = computeHotSignals(snapshot);
37200
+ snapshotHotSignalsByNode.set(node, hotSignals);
37201
+ const positionSignal = snapshot.signals.get("position");
37202
+ const isPositioned = positionSignal !== void 0 && positionSignal.kind === 0 /* Known */ && positionSignal.normalized !== "static";
37203
+ if (isPositioned) {
37204
+ positionedAncestorByKey.set(node.key, { key: node.key, hasReservedSpace: reservedSpace.hasReservedSpace });
37205
+ } else if (parentKey !== null) {
37206
+ const inherited = positionedAncestorByKey.get(parentKey);
37207
+ if (inherited !== void 0) positionedAncestorByKey.set(node.key, inherited);
37208
+ }
37209
+ records.set(node, {
37210
+ ref: elementRefsBySolidFileAndIdMutable.get(node.solidFile)?.get(node.elementId) ?? null,
37211
+ edges,
37212
+ cascade,
37213
+ snapshot,
37214
+ hotSignals,
37215
+ reservedSpace,
37216
+ scrollContainer,
37217
+ flowParticipation,
37218
+ containingBlock,
37219
+ conditionalDelta: null,
37220
+ baselineOffsets: null
37221
+ });
37365
37222
  }
37366
- const snapshotByElementNode = buildSignalSnapshotIndex(elements, cascadeByElementNode, perf);
37367
- const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
37368
- const factIndex = buildElementFactIndex(elements, snapshotByElementNode);
37223
+ perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
37369
37224
  const conditionalDeltaIndex = buildConditionalDeltaIndex(
37370
37225
  elements,
37371
- appliesByNode,
37226
+ records,
37372
37227
  monitoredDeclarationsBySelectorId,
37373
37228
  selectorsById
37374
37229
  );
37230
+ for (const [node, deltaByProperty] of conditionalDeltaIndex.conditionalSignalDeltaFactsByNode) {
37231
+ const record = records.get(node);
37232
+ if (!record) continue;
37233
+ const baselineOffsets = conditionalDeltaIndex.baselineOffsetFactsByNode.get(node) ?? null;
37234
+ records.set(node, {
37235
+ ref: record.ref,
37236
+ edges: record.edges,
37237
+ cascade: record.cascade,
37238
+ snapshot: record.snapshot,
37239
+ hotSignals: record.hotSignals,
37240
+ reservedSpace: record.reservedSpace,
37241
+ scrollContainer: record.scrollContainer,
37242
+ flowParticipation: record.flowParticipation,
37243
+ containingBlock: record.containingBlock,
37244
+ conditionalDelta: deltaByProperty,
37245
+ baselineOffsets
37246
+ });
37247
+ }
37375
37248
  const elementsWithConditionalOverflowDelta = buildConditionalDeltaSignalGroupElements(
37376
37249
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37377
37250
  ["overflow", "overflow-y"]
@@ -37380,6 +37253,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37380
37253
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37381
37254
  layoutOffsetSignals
37382
37255
  );
37256
+ const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
37383
37257
  const statefulRuleIndexes = buildStatefulRuleIndexes(css.rules);
37384
37258
  const contextByParentNode = buildContextIndex(childrenByParentNodeMutable, snapshotByElementNode, perf, logger);
37385
37259
  const cohortIndex = buildCohortIndex({
@@ -37387,7 +37261,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37387
37261
  contextByParentNode,
37388
37262
  measurementNodeByRootKey,
37389
37263
  snapshotByElementNode,
37390
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode
37264
+ snapshotHotSignalsByNode
37391
37265
  });
37392
37266
  finalizeTableCellBaselineRelevance(contextByParentNode, cohortIndex.verticalAlignConsensusByParent);
37393
37267
  perf.conditionalSignals = cohortIndex.conditionalSignals;
@@ -37404,122 +37278,71 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37404
37278
  elementBySolidFileAndId: elementBySolidFileAndIdMutable,
37405
37279
  elementRefsBySolidFileAndId: elementRefsBySolidFileAndIdMutable,
37406
37280
  hostElementRefsByNode: hostElementRefsByNodeMutable,
37407
- appliesByNode,
37408
37281
  selectorCandidatesByNode,
37409
37282
  selectorsById,
37410
37283
  measurementNodeByRootKey,
37411
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode,
37412
- elementsByTagName: factIndex.elementsByTagName,
37284
+ records,
37285
+ elementsByTagName,
37413
37286
  elementsWithConditionalDeltaBySignal: conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37414
37287
  elementsWithConditionalOverflowDelta,
37415
37288
  elementsWithConditionalOffsetDelta,
37416
- elementsByKnownSignalValue: factIndex.elementsByKnownSignalValue,
37417
- dynamicSlotCandidateElements: factIndex.dynamicSlotCandidateElements,
37418
- scrollContainerElements: factIndex.scrollContainerElements,
37419
- reservedSpaceFactsByNode: factIndex.reservedSpaceFactsByNode,
37420
- scrollContainerFactsByNode: factIndex.scrollContainerFactsByNode,
37421
- flowParticipationFactsByNode: factIndex.flowParticipationFactsByNode,
37422
- containingBlockFactsByNode: factIndex.containingBlockFactsByNode,
37423
- conditionalSignalDeltaFactsByNode: conditionalDeltaIndex.conditionalSignalDeltaFactsByNode,
37424
- baselineOffsetFactsByNode: conditionalDeltaIndex.baselineOffsetFactsByNode,
37289
+ elementsByKnownSignalValue,
37290
+ dynamicSlotCandidateElements,
37291
+ scrollContainerElements,
37425
37292
  statefulSelectorEntriesByRuleId: statefulRuleIndexes.selectorEntriesByRuleId,
37426
37293
  statefulNormalizedDeclarationsByRuleId: statefulRuleIndexes.normalizedDeclarationsByRuleId,
37427
37294
  statefulBaseValueIndex: statefulRuleIndexes.baseValueIndex,
37428
37295
  cohortStatsByParentNode: cohortIndex.statsByParentNode,
37429
- cascadeByElementNode,
37430
- snapshotByElementNode,
37431
37296
  contextByParentNode,
37432
37297
  perf
37433
37298
  };
37434
37299
  }
37435
- function buildElementFactIndex(elements, snapshotByElementNode) {
37436
- const reservedSpaceFactsByNode = /* @__PURE__ */ new Map();
37437
- const scrollContainerFactsByNode = /* @__PURE__ */ new Map();
37438
- const flowParticipationFactsByNode = /* @__PURE__ */ new Map();
37439
- const containingBlockFactsByNode = /* @__PURE__ */ new Map();
37440
- const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37441
- const elementsByTagName = /* @__PURE__ */ new Map();
37442
- const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37443
- const dynamicSlotCandidateElements = [];
37444
- const scrollContainerElements = [];
37445
- const positionedAncestorByKey = /* @__PURE__ */ new Map();
37300
+ function buildFileElementIndexByFile(elements) {
37301
+ const byFileDispatch = /* @__PURE__ */ new Map();
37302
+ const byFileTag = /* @__PURE__ */ new Map();
37446
37303
  for (let i = 0; i < elements.length; i++) {
37447
37304
  const node = elements[i];
37448
37305
  if (!node) continue;
37449
- const snapshot = snapshotByElementNode.get(node);
37450
- if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37451
- dynamicSlotCandidateElements.push(node);
37452
- }
37453
- if (node.tagName) {
37454
- const existing = elementsByTagName.get(node.tagName);
37306
+ if (node.parentElementNode === null) continue;
37307
+ const file = node.solidFile;
37308
+ let dispatchMap = byFileDispatch.get(file);
37309
+ if (!dispatchMap) {
37310
+ dispatchMap = /* @__PURE__ */ new Map();
37311
+ byFileDispatch.set(file, dispatchMap);
37312
+ }
37313
+ const keys = node.selectorDispatchKeys;
37314
+ for (let j = 0; j < keys.length; j++) {
37315
+ const key = keys[j];
37316
+ if (!key) continue;
37317
+ const existing = dispatchMap.get(key);
37455
37318
  if (existing) {
37456
37319
  existing.push(node);
37457
37320
  } else {
37458
- elementsByTagName.set(node.tagName, [node]);
37321
+ dispatchMap.set(key, [node]);
37459
37322
  }
37460
37323
  }
37461
- const parentKey = node.parentElementNode?.key ?? null;
37462
- let nearestPositionedAncestorKey = null;
37463
- let nearestPositionedAncestorHasReservedSpace = false;
37464
- if (parentKey !== null) {
37465
- const parentPositioned = positionedAncestorByKey.get(parentKey);
37466
- if (parentPositioned !== void 0) {
37467
- nearestPositionedAncestorKey = parentPositioned.key;
37468
- nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37324
+ if (node.tagName !== null) {
37325
+ let tagMap = byFileTag.get(file);
37326
+ if (!tagMap) {
37327
+ tagMap = /* @__PURE__ */ new Map();
37328
+ byFileTag.set(file, tagMap);
37469
37329
  }
37470
- }
37471
- containingBlockFactsByNode.set(node, {
37472
- nearestPositionedAncestorKey,
37473
- nearestPositionedAncestorHasReservedSpace
37474
- });
37475
- if (!snapshot) continue;
37476
- const reservedSpaceFact = computeReservedSpaceFact(snapshot);
37477
- reservedSpaceFactsByNode.set(node, reservedSpaceFact);
37478
- const scrollFact = computeScrollContainerFact(snapshot);
37479
- scrollContainerFactsByNode.set(node, scrollFact);
37480
- if (scrollFact.isScrollContainer) scrollContainerElements.push(node);
37481
- flowParticipationFactsByNode.set(node, computeFlowParticipationFact(snapshot));
37482
- snapshotHotSignalsByNode.set(node, computeHotSignals(snapshot));
37483
- const positionSignal = snapshot.signals.get("position");
37484
- const isPositioned = positionSignal !== void 0 && positionSignal.kind === "known" && positionSignal.normalized !== "static";
37485
- if (isPositioned) {
37486
- positionedAncestorByKey.set(node.key, {
37487
- key: node.key,
37488
- hasReservedSpace: reservedSpaceFact.hasReservedSpace
37489
- });
37490
- } else if (parentKey !== null) {
37491
- const inherited = positionedAncestorByKey.get(parentKey);
37492
- if (inherited !== void 0) {
37493
- positionedAncestorByKey.set(node.key, inherited);
37494
- }
37495
- }
37496
- for (const [signal, value2] of snapshot.signals) {
37497
- if (value2.kind !== "known") continue;
37498
- const normalized = value2.normalized;
37499
- let byValue = elementsByKnownSignalValue.get(signal);
37500
- if (!byValue) {
37501
- byValue = /* @__PURE__ */ new Map();
37502
- elementsByKnownSignalValue.set(signal, byValue);
37503
- }
37504
- const existingNodes = byValue.get(normalized);
37505
- if (existingNodes) {
37506
- existingNodes.push(node);
37330
+ const existing = tagMap.get(node.tagName);
37331
+ if (existing) {
37332
+ existing.push(node);
37507
37333
  } else {
37508
- byValue.set(normalized, [node]);
37334
+ tagMap.set(node.tagName, [node]);
37509
37335
  }
37510
37336
  }
37511
37337
  }
37512
- return {
37513
- reservedSpaceFactsByNode,
37514
- scrollContainerFactsByNode,
37515
- scrollContainerElements,
37516
- flowParticipationFactsByNode,
37517
- containingBlockFactsByNode,
37518
- snapshotHotSignalsByNode,
37519
- elementsByTagName,
37520
- elementsByKnownSignalValue,
37521
- dynamicSlotCandidateElements
37522
- };
37338
+ const out = /* @__PURE__ */ new Map();
37339
+ for (const [file, dispatchMap] of byFileDispatch) {
37340
+ out.set(file, {
37341
+ byDispatchKey: dispatchMap,
37342
+ byTagName: byFileTag.get(file) ?? /* @__PURE__ */ new Map()
37343
+ });
37344
+ }
37345
+ return out;
37523
37346
  }
37524
37347
  var ABSENT_NUMERIC = Object.freeze({
37525
37348
  present: false,
@@ -37532,7 +37355,7 @@ var ABSENT_NORMALIZED = Object.freeze({
37532
37355
  kind: 3 /* Unknown */
37533
37356
  });
37534
37357
  function toHotNumeric(signal) {
37535
- if (signal.kind !== "known") {
37358
+ if (signal.kind !== 0 /* Known */) {
37536
37359
  return {
37537
37360
  present: true,
37538
37361
  value: null,
@@ -37542,11 +37365,11 @@ function toHotNumeric(signal) {
37542
37365
  return {
37543
37366
  present: true,
37544
37367
  value: signal.px,
37545
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
37368
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
37546
37369
  };
37547
37370
  }
37548
37371
  function toHotNormalized(signal) {
37549
- if (signal.kind !== "known") {
37372
+ if (signal.kind !== 0 /* Known */) {
37550
37373
  return {
37551
37374
  present: true,
37552
37375
  value: null,
@@ -37556,7 +37379,7 @@ function toHotNormalized(signal) {
37556
37379
  return {
37557
37380
  present: true,
37558
37381
  value: signal.normalized,
37559
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
37382
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
37560
37383
  };
37561
37384
  }
37562
37385
  function computeHotSignals(snapshot) {
@@ -37671,62 +37494,61 @@ function computeHotSignals(snapshot) {
37671
37494
  }
37672
37495
  function computeReservedSpaceFact(snapshot) {
37673
37496
  const reasons = [];
37674
- const hasHeight = hasPositiveOrDeclaredDimension(snapshot, "height");
37497
+ const hasHeight = hasDeclaredDimension(snapshot, "height");
37675
37498
  if (hasHeight) reasons.push("height");
37676
- const hasBlockSize = hasPositiveOrDeclaredDimension(snapshot, "block-size");
37499
+ const hasBlockSize = hasDeclaredDimension(snapshot, "block-size");
37677
37500
  if (hasBlockSize) reasons.push("block-size");
37678
- const hasMinHeight = hasPositiveOrDeclaredDimension(snapshot, "min-height");
37501
+ const hasMinHeight = hasDeclaredDimension(snapshot, "min-height");
37679
37502
  if (hasMinHeight) reasons.push("min-height");
37680
- const hasMinBlockSize = hasPositiveOrDeclaredDimension(snapshot, "min-block-size");
37503
+ const hasMinBlockSize = hasDeclaredDimension(snapshot, "min-block-size");
37681
37504
  if (hasMinBlockSize) reasons.push("min-block-size");
37682
- const hasContainIntrinsic = hasPositiveOrDeclaredDimension(snapshot, "contain-intrinsic-size");
37505
+ const hasContainIntrinsic = hasDeclaredDimension(snapshot, "contain-intrinsic-size");
37683
37506
  if (hasContainIntrinsic) reasons.push("contain-intrinsic-size");
37684
37507
  const hasAspectRatio = hasUsableAspectRatio(snapshot);
37685
37508
  if (hasAspectRatio) {
37686
- if (hasPositiveOrDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
37687
- if (hasPositiveOrDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
37688
- if (hasPositiveOrDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
37509
+ if (hasDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
37510
+ if (hasDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
37511
+ if (hasDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
37689
37512
  if (hasMinBlockSize) reasons.push("aspect-ratio+min-block-size");
37690
37513
  if (hasMinHeight) reasons.push("aspect-ratio+min-height");
37691
37514
  }
37692
37515
  return {
37693
37516
  hasReservedSpace: reasons.length > 0,
37694
37517
  reasons,
37695
- hasUsableInlineDimension: hasPositiveOrDeclaredDimension(snapshot, "width") || hasPositiveOrDeclaredDimension(snapshot, "inline-size") || hasPositiveOrDeclaredDimension(snapshot, "min-width"),
37696
- hasUsableBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
37697
37518
  hasContainIntrinsicSize: hasContainIntrinsic,
37698
- hasUsableAspectRatio: hasAspectRatio
37519
+ hasUsableAspectRatio: hasAspectRatio,
37520
+ hasDeclaredBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
37521
+ hasDeclaredInlineDimension: hasDeclaredDimension(snapshot, "width") || hasDeclaredDimension(snapshot, "inline-size") || hasDeclaredDimension(snapshot, "min-width") || hasDeclaredDimension(snapshot, "flex-basis") || isBlockLevelDisplay(snapshot)
37699
37522
  };
37700
37523
  }
37701
- function hasPositiveOrDeclaredDimension(snapshot, property) {
37524
+ function hasDeclaredDimension(snapshot, property) {
37702
37525
  const signal = snapshot.signals.get(property);
37703
37526
  if (!signal) return false;
37704
- if (signal.guard.kind !== 0 /* Unconditional */) return false;
37705
- let normalized = "";
37706
- if (signal.kind === "known") {
37527
+ if (signal.kind === 0 /* Known */) {
37707
37528
  if (signal.px !== null) return signal.px > 0;
37708
- normalized = signal.normalized.trim().toLowerCase();
37529
+ if (signal.normalized.length === 0) return false;
37530
+ return !isNonReservingDimension(signal.normalized);
37709
37531
  }
37710
- if (signal.kind === "unknown") {
37532
+ if (signal.kind === 1 /* Unknown */) {
37711
37533
  return signal.source !== null;
37712
37534
  }
37713
- if (normalized.length === 0) return false;
37714
- if (isNonReservingDimension(normalized)) return false;
37715
- return true;
37535
+ return false;
37536
+ }
37537
+ function isBlockLevelDisplay(snapshot) {
37538
+ const signal = snapshot.signals.get("display");
37539
+ if (!signal || signal.kind !== 0 /* Known */) return false;
37540
+ return BLOCK_LEVEL_DISPLAY_VALUES.has(signal.normalized);
37716
37541
  }
37717
37542
  function hasUsableAspectRatio(snapshot) {
37718
37543
  const signal = snapshot.signals.get("aspect-ratio");
37719
37544
  if (!signal) return false;
37720
37545
  if (signal.guard.kind !== 0 /* Unconditional */) return false;
37721
- if (signal.kind === "unknown") {
37546
+ if (signal.kind === 1 /* Unknown */) {
37722
37547
  return false;
37723
37548
  }
37724
- let normalized = "";
37725
- if (signal.kind === "known") {
37726
- normalized = signal.normalized.trim().toLowerCase();
37727
- }
37728
- if (normalized.length === 0) return false;
37729
- return normalized !== "auto";
37549
+ if (signal.kind !== 0 /* Known */) return false;
37550
+ if (signal.normalized.length === 0) return false;
37551
+ return signal.normalized !== "auto";
37730
37552
  }
37731
37553
  function isNonReservingDimension(value2) {
37732
37554
  if (NON_RESERVING_DIMENSION_KEYWORDS.has(value2)) return true;
@@ -37736,8 +37558,8 @@ function isNonReservingDimension(value2) {
37736
37558
  function computeScrollContainerFact(snapshot) {
37737
37559
  const overflowSignal = snapshot.signals.get("overflow");
37738
37560
  const overflowYSignal = snapshot.signals.get("overflow-y");
37739
- const overflow = overflowSignal && overflowSignal.kind === "known" ? overflowSignal.normalized : null;
37740
- const overflowY = overflowYSignal && overflowYSignal.kind === "known" ? overflowYSignal.normalized : null;
37561
+ const overflow = overflowSignal && overflowSignal.kind === 0 /* Known */ ? overflowSignal.normalized : null;
37562
+ const overflowY = overflowYSignal && overflowYSignal.kind === 0 /* Known */ ? overflowYSignal.normalized : null;
37741
37563
  const shorthandAxis = parseOverflowShorthandAxis(overflow);
37742
37564
  const yFromLonghand = parseSingleAxisScroll(overflowY);
37743
37565
  const xScroll = shorthandAxis.x;
@@ -37785,7 +37607,7 @@ function toScrollAxis(x, y) {
37785
37607
  }
37786
37608
  function computeFlowParticipationFact(snapshot) {
37787
37609
  const signal = snapshot.signals.get("position");
37788
- if (!signal || signal.kind !== "known") {
37610
+ if (!signal || signal.kind !== 0 /* Known */) {
37789
37611
  return {
37790
37612
  inFlow: true,
37791
37613
  position: null,
@@ -37817,8 +37639,8 @@ function buildContextIndex(childrenByParentNode, snapshotByElementNode, perf, lo
37817
37639
  if (trace) {
37818
37640
  const displaySignal = snapshot.signals.get("display");
37819
37641
  const flexDirSignal = snapshot.signals.get("flex-direction");
37820
- const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === "known" ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37821
- const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === "known" ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37642
+ const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === 0 /* Known */ ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37643
+ const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === 0 /* Known */ ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37822
37644
  logger.trace(
37823
37645
  `[context] parent=${parent.key} tag=${parent.tagName ?? "null"} children=${children.length} display=${displayDesc} flex-direction=${flexDirDesc} \u2192 kind=${ctx.kind} certainty=${ctx.certainty} crossAxisIsBlockAxis=${ctx.crossAxisIsBlockAxis} baseline=${ctx.baselineRelevance}`
37824
37646
  );
@@ -39980,8 +39802,8 @@ function hasReservedSize(solid, attributes, element, reservedSpaceFact, hostElem
39980
39802
  const hostJsxWidth = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "width") : false;
39981
39803
  const hostJsxHeight = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "height") : false;
39982
39804
  if (attrWidth && attrHeight || jsxAttrWidth && jsxAttrHeight || hostJsxWidth && hostJsxHeight) return true;
39983
- const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasUsableInlineDimension;
39984
- const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasUsableBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
39805
+ const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasDeclaredInlineDimension;
39806
+ const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasDeclaredBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
39985
39807
  if (reservedSpaceFact.hasUsableAspectRatio && (hasAnyWidth || hasAnyHeight)) return true;
39986
39808
  if (reservedSpaceFact.hasContainIntrinsicSize && (hasAnyWidth || hasAnyHeight)) return true;
39987
39809
  return false;
@@ -40458,7 +40280,7 @@ function collectConditionalOffsets(layout, node, snapshot) {
40458
40280
  const signal = snapshot.signals.get(name);
40459
40281
  if (!signal) continue;
40460
40282
  if (signal.guard.kind !== 1 /* Conditional */) continue;
40461
- if (signal.kind !== "known") continue;
40283
+ if (signal.kind !== 0 /* Known */) continue;
40462
40284
  if (signal.px === null) continue;
40463
40285
  if (Math.abs(signal.px) <= 0.25) continue;
40464
40286
  out.push({ property: name, value: signal.px, guardKey: signal.guard.key });
@@ -40481,7 +40303,7 @@ function hasEffectivePositionForConditionalOffset(snapshot, guardKey) {
40481
40303
  if (hasEffectivePosition(snapshot)) return true;
40482
40304
  const position = snapshot.signals.get("position");
40483
40305
  if (!position) return false;
40484
- if (position.kind !== "known") return false;
40306
+ if (position.kind !== 0 /* Known */) return false;
40485
40307
  if (position.guard.kind !== 1 /* Conditional */) return false;
40486
40308
  if (position.guard.key !== guardKey) return false;
40487
40309
  return position.normalized !== "static";
@@ -40941,6 +40763,9 @@ function isVisuallyHidden(snapshot) {
40941
40763
  const opacityAttr = node.inlineStyleValues.get("opacity");
40942
40764
  if (opacityAttr === "0") return true;
40943
40765
  if (node.classTokenSet.has("opacity-0")) return true;
40766
+ const width = readKnownPx(snapshot, "width");
40767
+ const height = readKnownPx(snapshot, "height");
40768
+ if (width === 1 && height === 1) return true;
40944
40769
  return false;
40945
40770
  }
40946
40771
  var jsxLayoutPolicyTouchTarget = defineCrossRule({
@@ -40992,6 +40817,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
40992
40817
  tag,
40993
40818
  policyName
40994
40819
  );
40820
+ checkDimension(
40821
+ snapshot,
40822
+ "max-height",
40823
+ kind === "button" ? policy.minButtonHeight : policy.minInputHeight,
40824
+ layout,
40825
+ node,
40826
+ emit,
40827
+ "heightTooSmall",
40828
+ messages161.heightTooSmall,
40829
+ tag,
40830
+ policyName
40831
+ );
40995
40832
  checkDimension(
40996
40833
  snapshot,
40997
40834
  "width",
@@ -41016,6 +40853,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41016
40853
  tag,
41017
40854
  policyName
41018
40855
  );
40856
+ checkDimension(
40857
+ snapshot,
40858
+ "max-width",
40859
+ kind === "button" ? policy.minButtonWidth : policy.minTouchTarget,
40860
+ layout,
40861
+ node,
40862
+ emit,
40863
+ "widthTooSmall",
40864
+ messages161.widthTooSmall,
40865
+ tag,
40866
+ policyName
40867
+ );
41019
40868
  if (kind === "button") {
41020
40869
  checkDimension(
41021
40870
  snapshot,
@@ -41045,7 +40894,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41045
40894
  const reservedSpace = readReservedSpaceFact(layout, node);
41046
40895
  const minBlock = kind === "button" ? policy.minButtonHeight : policy.minInputHeight;
41047
40896
  const minInline = kind === "button" ? policy.minButtonWidth : policy.minTouchTarget;
41048
- if (!reservedSpace.hasUsableBlockDimension) {
40897
+ if (!reservedSpace.hasDeclaredBlockDimension) {
41049
40898
  emitLayoutDiagnostic(
41050
40899
  layout,
41051
40900
  node,
@@ -41057,7 +40906,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41057
40906
  { tag, min: String(minBlock), policy: policyName }
41058
40907
  );
41059
40908
  }
41060
- if (!reservedSpace.hasUsableInlineDimension) {
40909
+ if (!reservedSpace.hasDeclaredInlineDimension) {
41061
40910
  emitLayoutDiagnostic(
41062
40911
  layout,
41063
40912
  node,