@drskillissue/ganko 0.2.72 → 0.2.82

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.
@@ -150,7 +150,6 @@ var CHAR_DOUBLE_QUOTE = 34;
150
150
  var CHAR_SINGLE_QUOTE = 39;
151
151
  var CHAR_A = 97;
152
152
  var CHAR_E = 101;
153
- var CHAR_H = 104;
154
153
  var CHAR_I = 105;
155
154
  var CHAR_M = 109;
156
155
  var CHAR_N = 110;
@@ -521,7 +520,6 @@ var ID_STICKY = /#([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
521
520
  var CLASS_STICKY = /\.([a-zA-Z_-][a-zA-Z0-9_-]*)/y;
522
521
  var ATTRIBUTE_STICKY = /\[([^\]]+)\]/y;
523
522
  var PSEUDO_ELEMENT_STICKY = /::([a-zA-Z-]+)(?:\([^)]*\))?/y;
524
- var PSEUDO_CLASS_STICKY = /:([a-zA-Z-]+)(?:\([^)]*\))?/y;
525
523
  var ELEMENT_STICKY = /([a-zA-Z][a-zA-Z0-9-]*)/y;
526
524
  var WHITESPACE_SPLIT = /\s+/;
527
525
  var FUNCTION_CALL_RE = /([a-zA-Z_][\w-]*)\s*\(/g;
@@ -4020,6 +4018,10 @@ function getStaticStringFromJSXValue(node) {
4020
4018
  if (ts7.isTemplateExpression(expression) && expression.templateSpans.length === 0) {
4021
4019
  return expression.head.text;
4022
4020
  }
4021
+ if (ts7.isBinaryExpression(expression) && expression.operatorToken.kind === ts7.SyntaxKind.QuestionQuestionToken) {
4022
+ const fallback = getStaticStringFromJSXValue(expression.right);
4023
+ if (fallback !== null) return fallback;
4024
+ }
4023
4025
  }
4024
4026
  return null;
4025
4027
  }
@@ -23206,57 +23208,31 @@ var mediaQueryOverlapConflict = defineCSSRule({
23206
23208
  var messages101 = {
23207
23209
  descendingSpecificity: "Lower-specificity selector `{{laterSelector}}` appears after `{{earlierSelector}}` for `{{property}}`, creating brittle cascade behavior."
23208
23210
  };
23209
- var UNSUPPORTED_TYPES = /* @__PURE__ */ new Set(["attribute", "pseudo-class", "pseudo-element", "universal", "nesting"]);
23210
23211
  function extractCompounds(selector) {
23211
- const parts = selector.parts;
23212
- if (parts.length === 0) return null;
23213
- for (let i = 0; i < parts.length; i++) {
23214
- const part = parts[i];
23215
- if (!part) continue;
23216
- if (UNSUPPORTED_TYPES.has(part.type)) return null;
23212
+ const selectorCompounds = selector.compounds;
23213
+ if (selectorCompounds.length === 0) return null;
23214
+ for (let i = 0; i < selectorCompounds.length; i++) {
23215
+ const sc = selectorCompounds[i];
23216
+ if (!sc) continue;
23217
+ const parts = sc.parts;
23218
+ for (let j = 0; j < parts.length; j++) {
23219
+ const part = parts[j];
23220
+ if (!part) continue;
23221
+ const t = part.type;
23222
+ if (t === "attribute" || t === "pseudo-class" || t === "pseudo-element" || t === "universal" || t === "nesting") return null;
23223
+ }
23217
23224
  }
23218
- return splitIntoCompounds(selector);
23219
- }
23220
- function splitIntoCompounds(selector) {
23221
- const raw = selector.raw;
23222
- const combinators = selector.complexity.combinators;
23223
- const segments = splitRawByCombinators(raw);
23224
- if (!segments || segments.length !== combinators.length + 1) return null;
23225
23225
  const compounds = [];
23226
- for (let i = 0; i < segments.length; i++) {
23227
- const seg = segments[i];
23228
- if (!seg) continue;
23229
- const compound = parseCompoundFromParts(seg);
23230
- if (!compound) return null;
23231
- compounds.push(compound);
23226
+ for (let i = 0; i < selectorCompounds.length; i++) {
23227
+ const sc = selectorCompounds[i];
23228
+ if (!sc) continue;
23229
+ const ids = [];
23230
+ if (sc.idValue !== null) ids.push(sc.idValue);
23231
+ if (!sc.tagName && sc.classes.length === 0 && ids.length === 0) return null;
23232
+ compounds.push({ tag: sc.tagName, classes: sc.classes, ids });
23232
23233
  }
23233
23234
  return compounds;
23234
23235
  }
23235
- var COMBINATOR_SPLIT = /\s*[>+~]\s*|\s+/;
23236
- function splitRawByCombinators(raw) {
23237
- const trimmed = raw.trim();
23238
- if (trimmed.length === 0) return null;
23239
- const segments = trimmed.split(COMBINATOR_SPLIT).filter((s) => s.length > 0);
23240
- return segments.length > 0 ? segments : null;
23241
- }
23242
- var COMPOUND_TOKEN = /([.#]?)([_a-zA-Z][_a-zA-Z0-9-]*)/g;
23243
- function parseCompoundFromParts(segment) {
23244
- let tag = null;
23245
- const classes = [];
23246
- const ids = [];
23247
- COMPOUND_TOKEN.lastIndex = 0;
23248
- let match;
23249
- while ((match = COMPOUND_TOKEN.exec(segment)) !== null) {
23250
- const prefix = match[1];
23251
- const value2 = match[2];
23252
- if (!value2) continue;
23253
- if (prefix === ".") classes.push(value2);
23254
- else if (prefix === "#") ids.push(value2);
23255
- else tag = value2;
23256
- }
23257
- if (!tag && classes.length === 0 && ids.length === 0) return null;
23258
- return { tag, classes, ids };
23259
- }
23260
23236
  function hasToken(list, token) {
23261
23237
  for (let i = 0; i < list.length; i++) {
23262
23238
  if (list[i] === token) return true;
@@ -23298,8 +23274,8 @@ function isProvableDescendingPair(earlier, later) {
23298
23274
  if (!earlierCompounds) return false;
23299
23275
  const laterCompounds = extractCompounds(later);
23300
23276
  if (!laterCompounds) return false;
23301
- const earlierCombinators = earlier.complexity.combinators;
23302
- const laterCombinators = later.complexity.combinators;
23277
+ const earlierCombinators = earlier.combinators;
23278
+ const laterCombinators = later.combinators;
23303
23279
  if (earlierCompounds.length !== laterCompounds.length) return false;
23304
23280
  if (earlierCombinators.length !== laterCombinators.length) return false;
23305
23281
  for (let i = 0; i < earlierCombinators.length; i++) {
@@ -23579,7 +23555,7 @@ function splitWhitespaceTokens(value2) {
23579
23555
  return out;
23580
23556
  }
23581
23557
  function parseQuadShorthand(raw) {
23582
- const parts = splitWhitespaceTokens(raw);
23558
+ const parts = splitTopLevelWhitespace(raw);
23583
23559
  if (parts.length === 1) {
23584
23560
  const p0 = parts[0];
23585
23561
  if (!p0) return null;
@@ -23603,7 +23579,7 @@ function parseQuadShorthand(raw) {
23603
23579
  return null;
23604
23580
  }
23605
23581
  function parseBlockShorthand(raw) {
23606
- const parts = splitWhitespaceTokens(raw);
23582
+ const parts = splitTopLevelWhitespace(raw);
23607
23583
  if (parts.length === 1) {
23608
23584
  const p0 = parts[0];
23609
23585
  if (!p0) return null;
@@ -23688,8 +23664,14 @@ var NUMERIC_VALUE = /^([0-9]*\.?[0-9]+)(px|rem|em|pt)?$/;
23688
23664
  function parsePxValue(raw, contextFontSize = 16) {
23689
23665
  const trimmed = raw.trim().toLowerCase();
23690
23666
  if (trimmed.length === 0) return null;
23691
- if (trimmed.includes("var(") || trimmed.includes("calc(") || trimmed.includes("%")) return null;
23667
+ if (trimmed.includes("var(") || trimmed.includes("%")) return null;
23692
23668
  if (CSS_WIDE_KEYWORDS.has(trimmed)) return null;
23669
+ if (trimmed.includes("calc(")) {
23670
+ return tryEvalConstantCalc(trimmed, contextFontSize);
23671
+ }
23672
+ if (trimmed.startsWith("min(") || trimmed.startsWith("max(") || trimmed.startsWith("clamp(")) {
23673
+ return tryEvalMathFunction(trimmed, contextFontSize);
23674
+ }
23693
23675
  const match = NUMERIC_VALUE.exec(trimmed);
23694
23676
  if (!match) return null;
23695
23677
  const num = Number(match[1]);
@@ -23700,6 +23682,135 @@ function parsePxValue(raw, contextFontSize = 16) {
23700
23682
  if (unit === "pt") return num * 1.333;
23701
23683
  return null;
23702
23684
  }
23685
+ var CALC_CONSTANT_RE = /^calc\((.+)\)$/;
23686
+ var CALC_TOKEN_RE = /([0-9]*\.?[0-9]+)(px|rem|em|pt)?|([+\-*/])/g;
23687
+ function tryEvalConstantCalc(raw, contextFontSize) {
23688
+ const match = CALC_CONSTANT_RE.exec(raw);
23689
+ if (!match || !match[1]) return null;
23690
+ const inner = match[1].trim();
23691
+ if (inner.includes("var(") || inner.includes("%") || inner.includes("env(") || inner.includes("calc(")) return null;
23692
+ const values = [];
23693
+ const operators = [];
23694
+ let lastWasValue = false;
23695
+ CALC_TOKEN_RE.lastIndex = 0;
23696
+ let tokenMatch;
23697
+ while ((tokenMatch = CALC_TOKEN_RE.exec(inner)) !== null) {
23698
+ const op = tokenMatch[3];
23699
+ if (op !== void 0) {
23700
+ if (!lastWasValue && op === "-") {
23701
+ const nextToken = CALC_TOKEN_RE.exec(inner);
23702
+ if (!nextToken || nextToken[3] !== void 0) return null;
23703
+ const px2 = calcTokenToPx(nextToken, contextFontSize);
23704
+ if (px2 === null) return null;
23705
+ values.push(-px2);
23706
+ lastWasValue = true;
23707
+ continue;
23708
+ }
23709
+ if (!lastWasValue) return null;
23710
+ operators.push(op);
23711
+ lastWasValue = false;
23712
+ continue;
23713
+ }
23714
+ const px = calcTokenToPx(tokenMatch, contextFontSize);
23715
+ if (px === null) return null;
23716
+ values.push(px);
23717
+ lastWasValue = true;
23718
+ }
23719
+ if (values.length === 0 || values.length !== operators.length + 1) return null;
23720
+ const firstValue = values[0];
23721
+ if (firstValue === void 0) return null;
23722
+ const reducedValues = [firstValue];
23723
+ const reducedOps = [];
23724
+ for (let i = 0; i < operators.length; i++) {
23725
+ const op = operators[i];
23726
+ const right = values[i + 1];
23727
+ if (op === void 0 || right === void 0) return null;
23728
+ if (op === "*") {
23729
+ const last = reducedValues[reducedValues.length - 1];
23730
+ if (last === void 0) return null;
23731
+ reducedValues[reducedValues.length - 1] = last * right;
23732
+ } else if (op === "/") {
23733
+ if (right === 0) return null;
23734
+ const last = reducedValues[reducedValues.length - 1];
23735
+ if (last === void 0) return null;
23736
+ reducedValues[reducedValues.length - 1] = last / right;
23737
+ } else {
23738
+ reducedValues.push(right);
23739
+ reducedOps.push(op);
23740
+ }
23741
+ }
23742
+ const base = reducedValues[0];
23743
+ if (base === void 0) return null;
23744
+ let result = base;
23745
+ for (let i = 0; i < reducedOps.length; i++) {
23746
+ const op = reducedOps[i];
23747
+ const right = reducedValues[i + 1];
23748
+ if (op === void 0 || right === void 0) return null;
23749
+ if (op === "+") result += right;
23750
+ else if (op === "-") result -= right;
23751
+ else return null;
23752
+ }
23753
+ return Number.isFinite(result) ? result : null;
23754
+ }
23755
+ function calcTokenToPx(tokenMatch, contextFontSize) {
23756
+ const num = Number(tokenMatch[1]);
23757
+ if (Number.isNaN(num)) return null;
23758
+ const unit = tokenMatch[2] ?? "";
23759
+ if (unit === "px" || unit === "") return num;
23760
+ if (unit === "rem") return num * 16;
23761
+ if (unit === "em") return num * contextFontSize;
23762
+ if (unit === "pt") return num * 1.333;
23763
+ return null;
23764
+ }
23765
+ var MATH_FN_RE = /^(min|max|clamp)\((.+)\)$/;
23766
+ function tryEvalMathFunction(raw, contextFontSize) {
23767
+ const match = MATH_FN_RE.exec(raw);
23768
+ if (!match || !match[1] || !match[2]) return null;
23769
+ const fn = match[1];
23770
+ const inner = match[2];
23771
+ const args = splitMathArgs(inner);
23772
+ if (args === null) return null;
23773
+ const values = [];
23774
+ for (let i = 0; i < args.length; i++) {
23775
+ const arg = args[i];
23776
+ if (!arg) return null;
23777
+ const px = parsePxValue(arg.trim(), contextFontSize);
23778
+ if (px === null) return null;
23779
+ values.push(px);
23780
+ }
23781
+ if (values.length === 0) return null;
23782
+ if (fn === "min") return Math.min(...values);
23783
+ if (fn === "max") return Math.max(...values);
23784
+ if (fn === "clamp") {
23785
+ if (values.length !== 3) return null;
23786
+ const [lo, val, hi] = values;
23787
+ return Math.max(lo, Math.min(val, hi));
23788
+ }
23789
+ return null;
23790
+ }
23791
+ function splitMathArgs(inner) {
23792
+ const args = [];
23793
+ let depth = 0;
23794
+ let start = 0;
23795
+ for (let i = 0; i < inner.length; i++) {
23796
+ const ch = inner[i];
23797
+ if (ch === "(") depth++;
23798
+ else if (ch === ")") {
23799
+ if (depth > 0) depth--;
23800
+ else return null;
23801
+ } else if (ch === "," && depth === 0) {
23802
+ const arg = inner.slice(start, i).trim();
23803
+ if (arg.length === 0) return null;
23804
+ args.push(arg);
23805
+ start = i + 1;
23806
+ }
23807
+ }
23808
+ if (depth !== 0) return null;
23809
+ const tail = inner.slice(start).trim();
23810
+ if (tail.length === 0) return null;
23811
+ args.push(tail);
23812
+ return args;
23813
+ }
23703
23814
  function parseUnitlessValue(raw) {
23704
23815
  const trimmed = raw.trim().toLowerCase();
23705
23816
  if (trimmed.length === 0) return null;
@@ -26251,19 +26362,6 @@ var FONT_GENERIC_FAMILY_SET = /* @__PURE__ */ new Set([
26251
26362
  ]);
26252
26363
  var FONT_LAYOUT_PROPERTIES = /* @__PURE__ */ new Set(["font-family"]);
26253
26364
  var WHITESPACE_RE2 = /\s+/;
26254
- function classifyRuleElementKinds(rule) {
26255
- const kinds = rule.elementKinds;
26256
- for (let i = 0; i < rule.selectors.length; i++) {
26257
- const sel = rule.selectors[i];
26258
- if (!sel) continue;
26259
- const parts = sel.parts;
26260
- for (let j = 0; j < parts.length; j++) {
26261
- const part = parts[j];
26262
- if (!part) continue;
26263
- classifyPart(part, kinds);
26264
- }
26265
- }
26266
- }
26267
26365
  function classifyPart(part, kinds) {
26268
26366
  if (part.type === "element") {
26269
26367
  const lower = part.value.toLowerCase();
@@ -26391,7 +26489,19 @@ var CSSGraph = class {
26391
26489
  parseErrors = [];
26392
26490
  failedFilePaths = [];
26393
26491
  tokenCategories = [];
26394
- filesWithLayers = /* @__PURE__ */ new Set();
26492
+ _filesWithLayers = null;
26493
+ get filesWithLayers() {
26494
+ if (this._filesWithLayers === null) {
26495
+ const result = /* @__PURE__ */ new Set();
26496
+ for (let i = 0; i < this.layers.length; i++) {
26497
+ const layer = this.layers[i];
26498
+ if (!layer) continue;
26499
+ result.add(layer.file.path);
26500
+ }
26501
+ this._filesWithLayers = result;
26502
+ }
26503
+ return this._filesWithLayers;
26504
+ }
26395
26505
  selectorsByPseudoClass = /* @__PURE__ */ new Map();
26396
26506
  knownKeyframeNames = /* @__PURE__ */ new Set();
26397
26507
  unresolvedAnimationRefs = [];
@@ -26403,17 +26513,61 @@ var CSSGraph = class {
26403
26513
  multiDeclarationProperties = /* @__PURE__ */ new Map();
26404
26514
  /** Declarations whose parent rule is inside a @keyframes block. */
26405
26515
  keyframeDeclarations = [];
26406
- /** Rules with zero declarations and zero nested rules. */
26407
- emptyRules = [];
26516
+ /** Rules with zero declarations, zero nested rules, and zero nested at-rules. */
26517
+ _emptyRules = null;
26518
+ get emptyRules() {
26519
+ if (this._emptyRules === null) {
26520
+ this._emptyRules = this.rules.filter((r) => r.declarations.length === 0 && r.nestedRules.length === 0 && r.nestedAtRules.length === 0);
26521
+ }
26522
+ return this._emptyRules;
26523
+ }
26408
26524
  /** @keyframes at-rules with no effective keyframe declarations. */
26409
- emptyKeyframes = [];
26410
- colorDeclarations = [];
26411
- calcDeclarations = [];
26412
- varDeclarations = [];
26413
- urlDeclarations = [];
26414
- vendorPrefixedDeclarations = [];
26415
- hardcodedColorDeclarations = [];
26416
- overqualifiedSelectors = [];
26525
+ _emptyKeyframes = null;
26526
+ get emptyKeyframes() {
26527
+ if (this._emptyKeyframes === null) {
26528
+ const result = [];
26529
+ for (let i = 0; i < this.keyframes.length; i++) {
26530
+ const kf = this.keyframes[i];
26531
+ if (!kf) continue;
26532
+ if (!kf.parsedParams.animationName) continue;
26533
+ if (kf.rules.length === 0) {
26534
+ result.push(kf);
26535
+ continue;
26536
+ }
26537
+ let hasDeclaration = false;
26538
+ for (let j = 0; j < kf.rules.length; j++) {
26539
+ const kfRule = kf.rules[j];
26540
+ if (!kfRule) continue;
26541
+ if (kfRule.declarations.length > 0) {
26542
+ hasDeclaration = true;
26543
+ break;
26544
+ }
26545
+ }
26546
+ if (!hasDeclaration) result.push(kf);
26547
+ }
26548
+ this._emptyKeyframes = result;
26549
+ }
26550
+ return this._emptyKeyframes;
26551
+ }
26552
+ _overqualifiedSelectors = null;
26553
+ get overqualifiedSelectors() {
26554
+ if (this._overqualifiedSelectors === null) {
26555
+ const result = [];
26556
+ for (let i = 0, len = this.idSelectors.length; i < len; i++) {
26557
+ const sel = this.idSelectors[i];
26558
+ if (!sel) continue;
26559
+ const compounds = sel.compounds;
26560
+ if (compounds.length === 0) continue;
26561
+ const subject = compounds[compounds.length - 1];
26562
+ if (!subject) continue;
26563
+ if (subject.idValue !== null && (subject.tagName !== null || subject.classes.length > 0 || subject.attributes.length > 0)) {
26564
+ result.push(sel);
26565
+ }
26566
+ }
26567
+ this._overqualifiedSelectors = result;
26568
+ }
26569
+ return this._overqualifiedSelectors;
26570
+ }
26417
26571
  idSelectors = [];
26418
26572
  attributeSelectors = [];
26419
26573
  universalSelectors = [];
@@ -26429,7 +26583,13 @@ var CSSGraph = class {
26429
26583
  usedFontFamilies = /* @__PURE__ */ new Set();
26430
26584
  /** Tailwind validator for utility class lookup (null if not a Tailwind project). */
26431
26585
  tailwind;
26432
- deepNestedRules = [];
26586
+ _deepNestedRules = null;
26587
+ get deepNestedRules() {
26588
+ if (this._deepNestedRules === null) {
26589
+ this._deepNestedRules = this.rules.filter((r) => r.depth > 3);
26590
+ }
26591
+ return this._deepNestedRules;
26592
+ }
26433
26593
  constructor(input) {
26434
26594
  this.options = input.options ?? {};
26435
26595
  this.tailwind = input.tailwind ?? null;
@@ -26494,13 +26654,57 @@ var CSSGraph = class {
26494
26654
  }
26495
26655
  addSelector(selector) {
26496
26656
  this.selectors.push(selector);
26657
+ const anchor = selector.anchor;
26658
+ if (anchor.subjectTag === null) {
26659
+ this.selectorsWithoutSubjectTag.push(selector);
26660
+ } else {
26661
+ const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
26662
+ if (existingByTag) existingByTag.push(selector);
26663
+ else this.selectorsBySubjectTag.set(anchor.subjectTag, [selector]);
26664
+ }
26665
+ if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(selector);
26666
+ if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(selector);
26667
+ const compounds = selector.compounds;
26668
+ for (let ci = 0; ci < compounds.length; ci++) {
26669
+ const compound = compounds[ci];
26670
+ if (!compound) continue;
26671
+ const cls = compound.classes;
26672
+ for (let j = 0; j < cls.length; j++) {
26673
+ const className = cls[j];
26674
+ if (!className) continue;
26675
+ const existing = this.classNameIndex.get(className);
26676
+ if (existing) existing.push(selector);
26677
+ else this.classNameIndex.set(className, [selector]);
26678
+ }
26679
+ }
26680
+ const complexity = selector.complexity;
26681
+ const flags = complexity._flags;
26682
+ if (hasFlag(flags, SEL_HAS_ID)) this.idSelectors.push(selector);
26683
+ if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(selector);
26684
+ if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(selector);
26685
+ const pseudoClasses = complexity.pseudoClasses;
26686
+ for (let j = 0; j < pseudoClasses.length; j++) {
26687
+ const pc = pseudoClasses[j];
26688
+ if (!pc) continue;
26689
+ const pcExisting = this.selectorsByPseudoClass.get(pc);
26690
+ if (pcExisting) pcExisting.push(selector);
26691
+ else this.selectorsByPseudoClass.set(pc, [selector]);
26692
+ }
26497
26693
  }
26498
26694
  addDeclaration(decl) {
26499
26695
  this.declarations.push(decl);
26500
- const existing = this.declarationsByProperty.get(decl.property);
26696
+ const property = decl.property;
26697
+ const existing = this.declarationsByProperty.get(property);
26501
26698
  if (existing) existing.push(decl);
26502
- else this.declarationsByProperty.set(decl.property, [decl]);
26699
+ else this.declarationsByProperty.set(property, [decl]);
26503
26700
  if (hasFlag(decl._flags, DECL_IS_IMPORTANT) || decl.node.important) this.importantDeclarations.push(decl);
26701
+ if (decl.rule !== null) {
26702
+ const p = property.toLowerCase();
26703
+ const ruleIndex = decl.rule.declarationIndex;
26704
+ const ruleExisting = ruleIndex.get(p);
26705
+ if (ruleExisting) ruleExisting.push(decl);
26706
+ else ruleIndex.set(p, [decl]);
26707
+ }
26504
26708
  }
26505
26709
  addVariable(variable) {
26506
26710
  this.variables.push(variable);
@@ -26634,39 +26838,12 @@ var CSSGraph = class {
26634
26838
  * Called after all phases complete.
26635
26839
  */
26636
26840
  buildDerivedIndexes() {
26637
- this.buildRuleDeclarationIndexes();
26638
26841
  this.buildContainingMediaStacks();
26639
- this.buildKeyframeIndex();
26842
+ this.buildKeyframeIndexes();
26640
26843
  this.buildContainerNameIndexes();
26641
- this.buildElementKinds();
26642
- this.buildFilesWithLayers();
26643
- this.buildSelectorPseudoClassIndex();
26644
26844
  this.buildMultiDeclarationProperties();
26645
- this.buildKeyframeDeclarations();
26646
- this.buildKeyframeLayoutMutationsByName();
26647
- this.buildEmptyRules();
26648
- this.buildEmptyKeyframes();
26649
- this.buildDeclarationDerivedIndexes();
26650
- this.buildSelectorDerivedIndexes();
26651
26845
  this.buildLayoutPropertiesByClassToken();
26652
- this.buildFontFamilyUsageByRule();
26653
- this.buildFontFaceDescriptorsByFamily();
26654
- this.buildRuleDerivedIndexes();
26655
- }
26656
- buildRuleDeclarationIndexes() {
26657
- for (let i = 0; i < this.rules.length; i++) {
26658
- const rule = this.rules[i];
26659
- if (!rule) continue;
26660
- const index = rule.declarationIndex;
26661
- for (let j = 0; j < rule.declarations.length; j++) {
26662
- const d = rule.declarations[j];
26663
- if (!d) continue;
26664
- const p = d.property.toLowerCase();
26665
- const existing = index.get(p);
26666
- if (existing) existing.push(d);
26667
- else index.set(p, [d]);
26668
- }
26669
- }
26846
+ this.buildFontIndexes();
26670
26847
  }
26671
26848
  buildContainingMediaStacks() {
26672
26849
  for (let i = 0; i < this.rules.length; i++) {
@@ -26681,7 +26858,7 @@ var CSSGraph = class {
26681
26858
  rule.containingMediaStack = medias;
26682
26859
  }
26683
26860
  }
26684
- buildKeyframeIndex() {
26861
+ buildKeyframeIndexes() {
26685
26862
  const IGNORED = /* @__PURE__ */ new Set([...CSS_WIDE_KEYWORDS, "none"]);
26686
26863
  for (let i = 0; i < this.keyframes.length; i++) {
26687
26864
  const kf = this.keyframes[i];
@@ -26703,6 +26880,47 @@ var CSSGraph = class {
26703
26880
  this.unresolvedAnimationRefs.push({ declaration: d, name });
26704
26881
  }
26705
26882
  }
26883
+ const byAnimationByProperty = /* @__PURE__ */ new Map();
26884
+ for (let i = 0; i < this.declarations.length; i++) {
26885
+ const d = this.declarations[i];
26886
+ if (!d) continue;
26887
+ const rule = d.rule;
26888
+ if (!rule) continue;
26889
+ const parent = rule.parent;
26890
+ if (!parent) continue;
26891
+ if (parent.kind === "rule") continue;
26892
+ if (parent.kind !== "keyframes") continue;
26893
+ this.keyframeDeclarations.push(d);
26894
+ const property = d.property.toLowerCase();
26895
+ if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
26896
+ const animationName = normalizeAnimationName(parent.params);
26897
+ if (!animationName) continue;
26898
+ let byProperty = byAnimationByProperty.get(animationName);
26899
+ if (!byProperty) {
26900
+ byProperty = /* @__PURE__ */ new Map();
26901
+ byAnimationByProperty.set(animationName, byProperty);
26902
+ }
26903
+ let bucket = byProperty.get(property);
26904
+ if (!bucket) {
26905
+ bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
26906
+ byProperty.set(property, bucket);
26907
+ }
26908
+ bucket.values.add(normalizeCssValue(d.value));
26909
+ bucket.declarations.push(d);
26910
+ }
26911
+ for (const [animationName, byProperty] of byAnimationByProperty) {
26912
+ const mutations = [];
26913
+ for (const [property, bucket] of byProperty) {
26914
+ if (bucket.values.size <= 1) continue;
26915
+ mutations.push({
26916
+ property,
26917
+ values: [...bucket.values],
26918
+ declarations: bucket.declarations
26919
+ });
26920
+ }
26921
+ if (mutations.length === 0) continue;
26922
+ this.keyframeLayoutMutationsByName.set(animationName, mutations);
26923
+ }
26706
26924
  }
26707
26925
  buildContainerNameIndexes() {
26708
26926
  for (let i = 0; i < this.declarations.length; i++) {
@@ -26746,34 +26964,6 @@ var CSSGraph = class {
26746
26964
  }
26747
26965
  }
26748
26966
  }
26749
- buildElementKinds() {
26750
- for (let i = 0; i < this.rules.length; i++) {
26751
- const rule = this.rules[i];
26752
- if (!rule) continue;
26753
- classifyRuleElementKinds(rule);
26754
- }
26755
- }
26756
- buildFilesWithLayers() {
26757
- for (let i = 0; i < this.layers.length; i++) {
26758
- const layer = this.layers[i];
26759
- if (!layer) continue;
26760
- this.filesWithLayers.add(layer.file.path);
26761
- }
26762
- }
26763
- buildSelectorPseudoClassIndex() {
26764
- for (let i = 0; i < this.selectors.length; i++) {
26765
- const sel = this.selectors[i];
26766
- if (!sel) continue;
26767
- const pseudoClasses = sel.complexity.pseudoClasses;
26768
- for (let j = 0; j < pseudoClasses.length; j++) {
26769
- const pc = pseudoClasses[j];
26770
- if (!pc) continue;
26771
- const existing = this.selectorsByPseudoClass.get(pc);
26772
- if (existing) existing.push(sel);
26773
- else this.selectorsByPseudoClass.set(pc, [sel]);
26774
- }
26775
- }
26776
- }
26777
26967
  /**
26778
26968
  * Sort each declarationsByProperty list by sourceOrder and populate
26779
26969
  * multiDeclarationProperties with only those having 2+ entries.
@@ -26786,162 +26976,6 @@ var CSSGraph = class {
26786
26976
  }
26787
26977
  }
26788
26978
  }
26789
- /**
26790
- * Collect declarations whose parent rule is inside a @keyframes block.
26791
- */
26792
- buildKeyframeDeclarations() {
26793
- for (let i = 0; i < this.declarations.length; i++) {
26794
- const d = this.declarations[i];
26795
- if (!d) continue;
26796
- const rule = d.rule;
26797
- if (!rule) continue;
26798
- const parent = rule.parent;
26799
- if (!parent) continue;
26800
- if (parent.kind === "rule") continue;
26801
- if (parent.kind !== "keyframes") continue;
26802
- this.keyframeDeclarations.push(d);
26803
- }
26804
- }
26805
- buildKeyframeLayoutMutationsByName() {
26806
- const byAnimationByProperty = /* @__PURE__ */ new Map();
26807
- for (let i = 0; i < this.keyframeDeclarations.length; i++) {
26808
- const declaration = this.keyframeDeclarations[i];
26809
- if (!declaration) continue;
26810
- const rule = declaration.rule;
26811
- if (!rule || rule.parent === null || rule.parent.kind !== "keyframes") continue;
26812
- const property = declaration.property.toLowerCase();
26813
- if (!LAYOUT_ANIMATION_MUTATION_PROPERTIES.has(property)) continue;
26814
- const animationName = normalizeAnimationName(rule.parent.params);
26815
- if (!animationName) continue;
26816
- let byProperty = byAnimationByProperty.get(animationName);
26817
- if (!byProperty) {
26818
- byProperty = /* @__PURE__ */ new Map();
26819
- byAnimationByProperty.set(animationName, byProperty);
26820
- }
26821
- let bucket = byProperty.get(property);
26822
- if (!bucket) {
26823
- bucket = { values: /* @__PURE__ */ new Set(), declarations: [] };
26824
- byProperty.set(property, bucket);
26825
- }
26826
- bucket.values.add(normalizeCssValue(declaration.value));
26827
- bucket.declarations.push(declaration);
26828
- }
26829
- for (const [animationName, byProperty] of byAnimationByProperty) {
26830
- const mutations = [];
26831
- for (const [property, bucket] of byProperty) {
26832
- if (bucket.values.size <= 1) continue;
26833
- mutations.push({
26834
- property,
26835
- values: [...bucket.values],
26836
- declarations: bucket.declarations
26837
- });
26838
- }
26839
- if (mutations.length === 0) continue;
26840
- this.keyframeLayoutMutationsByName.set(animationName, mutations);
26841
- }
26842
- }
26843
- /**
26844
- * Collect rules with no declarations and no nested rules.
26845
- */
26846
- buildEmptyRules() {
26847
- for (let i = 0; i < this.rules.length; i++) {
26848
- const rule = this.rules[i];
26849
- if (!rule) continue;
26850
- if (rule.declarations.length === 0 && rule.nestedRules.length === 0) {
26851
- this.emptyRules.push(rule);
26852
- }
26853
- }
26854
- }
26855
- /**
26856
- * Collect @keyframes with no effective keyframe declarations.
26857
- */
26858
- buildEmptyKeyframes() {
26859
- for (let i = 0; i < this.keyframes.length; i++) {
26860
- const kf = this.keyframes[i];
26861
- if (!kf) continue;
26862
- if (!kf.parsedParams.animationName) continue;
26863
- if (kf.rules.length === 0) {
26864
- this.emptyKeyframes.push(kf);
26865
- continue;
26866
- }
26867
- let hasDeclaration = false;
26868
- for (let j = 0; j < kf.rules.length; j++) {
26869
- const kfRule = kf.rules[j];
26870
- if (!kfRule) continue;
26871
- if (kfRule.declarations.length > 0) {
26872
- hasDeclaration = true;
26873
- break;
26874
- }
26875
- }
26876
- if (!hasDeclaration) this.emptyKeyframes.push(kf);
26877
- }
26878
- }
26879
- buildDeclarationDerivedIndexes() {
26880
- const HARDCODED_HEX = /^#[0-9a-f]{3,8}$/i;
26881
- for (let i = 0, len = this.declarations.length; i < len; i++) {
26882
- const d = this.declarations[i];
26883
- if (!d) continue;
26884
- const pv = d.parsedValue;
26885
- if (pv.colors.length > 0) this.colorDeclarations.push(d);
26886
- if (pv.hasCalc) this.calcDeclarations.push(d);
26887
- if (pv.hasVar) this.varDeclarations.push(d);
26888
- if (pv.hasUrl) this.urlDeclarations.push(d);
26889
- if (d.property.charCodeAt(0) === CHAR_HYPHEN && d.property.charCodeAt(1) !== CHAR_HYPHEN) {
26890
- this.vendorPrefixedDeclarations.push(d);
26891
- }
26892
- if (!pv.hasVar && pv.colors.length > 0) {
26893
- for (let j = 0, clen = pv.colors.length; j < clen; j++) {
26894
- const c = pv.colors[j];
26895
- if (!c) continue;
26896
- if (HARDCODED_HEX.test(c) || c.charCodeAt(0) === CHAR_R || c.charCodeAt(0) === CHAR_H) {
26897
- this.hardcodedColorDeclarations.push(d);
26898
- break;
26899
- }
26900
- }
26901
- }
26902
- }
26903
- }
26904
- buildSelectorDerivedIndexes() {
26905
- for (let i = 0, len = this.selectors.length; i < len; i++) {
26906
- const sel = this.selectors[i];
26907
- if (!sel) continue;
26908
- const parts = sel.parts;
26909
- const anchor = sel.anchor;
26910
- if (anchor.subjectTag === null) {
26911
- this.selectorsWithoutSubjectTag.push(sel);
26912
- } else {
26913
- const existingByTag = this.selectorsBySubjectTag.get(anchor.subjectTag);
26914
- if (existingByTag) existingByTag.push(sel);
26915
- else this.selectorsBySubjectTag.set(anchor.subjectTag, [sel]);
26916
- }
26917
- if (anchor.targetsCheckbox) this.selectorsTargetingCheckbox.push(sel);
26918
- if (anchor.targetsTableCell) this.selectorsTargetingTableCell.push(sel);
26919
- for (let j = 0, plen = parts.length; j < plen; j++) {
26920
- const part = parts[j];
26921
- if (!part) continue;
26922
- if (part.type === "class") {
26923
- const existing = this.classNameIndex.get(part.value);
26924
- if (existing) existing.push(sel);
26925
- else this.classNameIndex.set(part.value, [sel]);
26926
- }
26927
- }
26928
- const flags = sel.complexity._flags;
26929
- if (hasFlag(flags, SEL_HAS_ID)) {
26930
- this.idSelectors.push(sel);
26931
- for (let j = 0, plen = parts.length; j < plen; j++) {
26932
- const p = parts[j];
26933
- if (!p) continue;
26934
- const t = p.type;
26935
- if (t === "element" || t === "class" || t === "attribute") {
26936
- this.overqualifiedSelectors.push(sel);
26937
- break;
26938
- }
26939
- }
26940
- }
26941
- if (hasFlag(flags, SEL_HAS_ATTRIBUTE)) this.attributeSelectors.push(sel);
26942
- if (hasFlag(flags, SEL_HAS_UNIVERSAL)) this.universalSelectors.push(sel);
26943
- }
26944
- }
26945
26979
  buildLayoutPropertiesByClassToken() {
26946
26980
  const byClass = /* @__PURE__ */ new Map();
26947
26981
  for (let i = 0; i < this.selectors.length; i++) {
@@ -26972,7 +27006,7 @@ var CSSGraph = class {
26972
27006
  this.layoutPropertiesByClassToken.set(className, [...properties]);
26973
27007
  }
26974
27008
  }
26975
- buildFontFamilyUsageByRule() {
27009
+ buildFontIndexes() {
26976
27010
  const declarations = this.declarationsForProperties(...FONT_LAYOUT_PROPERTIES);
26977
27011
  for (let i = 0; i < declarations.length; i++) {
26978
27012
  const declaration = declarations[i];
@@ -26999,8 +27033,6 @@ var CSSGraph = class {
26999
27033
  }
27000
27034
  this.usedFontFamiliesByRule.set(rule.id, [...merged]);
27001
27035
  }
27002
- }
27003
- buildFontFaceDescriptorsByFamily() {
27004
27036
  const byFamily = /* @__PURE__ */ new Map();
27005
27037
  for (let i = 0; i < this.fontFaces.length; i++) {
27006
27038
  const fontFace = this.fontFaces[i];
@@ -27032,13 +27064,6 @@ var CSSGraph = class {
27032
27064
  this.fontFaceDescriptorsByFamily.set(family, descriptors);
27033
27065
  }
27034
27066
  }
27035
- buildRuleDerivedIndexes() {
27036
- for (let i = 0, len = this.rules.length; i < len; i++) {
27037
- const rule = this.rules[i];
27038
- if (!rule) continue;
27039
- if (rule.depth > 3) this.deepNestedRules.push(rule);
27040
- }
27041
- }
27042
27067
  buildUnusedIndexes() {
27043
27068
  for (const v of this.variables) {
27044
27069
  if (!hasFlag(v._flags, VAR_IS_USED)) this.unusedVariables.push(v);
@@ -27352,102 +27377,6 @@ function buildComplexity(combinators, hasId, hasUniversal, hasAttribute, hasPseu
27352
27377
  }
27353
27378
 
27354
27379
  // src/css/parser/selector.ts
27355
- function parseSelector(raw) {
27356
- let start = 0;
27357
- let end = raw.length;
27358
- while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
27359
- while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
27360
- if (start === end) return [];
27361
- const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
27362
- const len = input.length;
27363
- const parts = [];
27364
- let pos = 0;
27365
- while (pos < len) {
27366
- const char = input.charCodeAt(pos);
27367
- if (isWhitespace(char) || isCombinator(char)) {
27368
- pos++;
27369
- continue;
27370
- }
27371
- if (char === CHAR_AMPERSAND) {
27372
- parts.push({ type: "nesting", value: "&", raw: "&" });
27373
- pos++;
27374
- continue;
27375
- }
27376
- if (char === CHAR_ASTERISK) {
27377
- parts.push({ type: "universal", value: "*", raw: "*" });
27378
- pos++;
27379
- continue;
27380
- }
27381
- if (char === CHAR_HASH) {
27382
- ID_STICKY.lastIndex = pos;
27383
- const match = ID_STICKY.exec(input);
27384
- if (match) {
27385
- const val = match[1];
27386
- if (!val) break;
27387
- parts.push({ type: "id", value: val, raw: match[0] });
27388
- pos = ID_STICKY.lastIndex;
27389
- continue;
27390
- }
27391
- }
27392
- if (char === CHAR_DOT) {
27393
- CLASS_STICKY.lastIndex = pos;
27394
- const match = CLASS_STICKY.exec(input);
27395
- if (match) {
27396
- const val = match[1];
27397
- if (!val) break;
27398
- parts.push({ type: "class", value: val, raw: match[0] });
27399
- pos = CLASS_STICKY.lastIndex;
27400
- continue;
27401
- }
27402
- }
27403
- if (char === CHAR_OPEN_BRACKET) {
27404
- ATTRIBUTE_STICKY.lastIndex = pos;
27405
- const match = ATTRIBUTE_STICKY.exec(input);
27406
- if (match) {
27407
- const val = match[1];
27408
- if (!val) break;
27409
- parts.push({ type: "attribute", value: val, raw: match[0] });
27410
- pos = ATTRIBUTE_STICKY.lastIndex;
27411
- continue;
27412
- }
27413
- }
27414
- if (char === CHAR_COLON) {
27415
- if (pos + 1 < len && input.charCodeAt(pos + 1) === CHAR_COLON) {
27416
- PSEUDO_ELEMENT_STICKY.lastIndex = pos;
27417
- const match2 = PSEUDO_ELEMENT_STICKY.exec(input);
27418
- if (match2) {
27419
- const val = match2[1];
27420
- if (!val) break;
27421
- parts.push({ type: "pseudo-element", value: val, raw: match2[0] });
27422
- pos = PSEUDO_ELEMENT_STICKY.lastIndex;
27423
- continue;
27424
- }
27425
- }
27426
- PSEUDO_CLASS_STICKY.lastIndex = pos;
27427
- const match = PSEUDO_CLASS_STICKY.exec(input);
27428
- if (match) {
27429
- const val = match[1];
27430
- if (!val) break;
27431
- parts.push({ type: "pseudo-class", value: val, raw: match[0] });
27432
- pos = PSEUDO_CLASS_STICKY.lastIndex;
27433
- continue;
27434
- }
27435
- }
27436
- if (isAlpha(char)) {
27437
- ELEMENT_STICKY.lastIndex = pos;
27438
- const match = ELEMENT_STICKY.exec(input);
27439
- if (match) {
27440
- const val = match[1];
27441
- if (!val) break;
27442
- parts.push({ type: "element", value: val, raw: match[0] });
27443
- pos = ELEMENT_STICKY.lastIndex;
27444
- continue;
27445
- }
27446
- }
27447
- pos++;
27448
- }
27449
- return parts;
27450
- }
27451
27380
  function parseSelectorList(selectorText) {
27452
27381
  const len = selectorText.length;
27453
27382
  if (len === 0) return [];
@@ -27535,18 +27464,80 @@ function extractPseudoClasses(selector) {
27535
27464
  }
27536
27465
  return pseudoClasses;
27537
27466
  }
27538
- function parseSelectorComplete(raw) {
27467
+ var CHAR_BACKSLASH = 92;
27468
+ function readCssIdentifier(input, start) {
27469
+ const length = input.length;
27470
+ let i = start;
27471
+ let hasEscape = false;
27472
+ while (i < length) {
27473
+ const code = input.charCodeAt(i);
27474
+ if (code === CHAR_BACKSLASH) {
27475
+ if (i + 1 >= length) break;
27476
+ hasEscape = true;
27477
+ i = skipCssEscape(input, i + 1);
27478
+ continue;
27479
+ }
27480
+ if (!isIdentChar(code)) break;
27481
+ i++;
27482
+ }
27483
+ if (i === start) return null;
27484
+ if (!hasEscape) {
27485
+ return { value: input.slice(start, i), end: i };
27486
+ }
27487
+ const parts = [];
27488
+ let j = start;
27489
+ while (j < i) {
27490
+ const code = input.charCodeAt(j);
27491
+ if (code !== CHAR_BACKSLASH) {
27492
+ parts.push(String.fromCharCode(code));
27493
+ j++;
27494
+ continue;
27495
+ }
27496
+ j++;
27497
+ if (j >= i) break;
27498
+ const first = input.charCodeAt(j);
27499
+ if (!isHexDigit(first)) {
27500
+ parts.push(String.fromCharCode(first));
27501
+ j++;
27502
+ continue;
27503
+ }
27504
+ const hexStart = j;
27505
+ const maxHex = Math.min(j + 6, i);
27506
+ while (j < maxHex && isHexDigit(input.charCodeAt(j))) j++;
27507
+ const codePoint = Number.parseInt(input.slice(hexStart, j), 16);
27508
+ if (codePoint > 0 && codePoint <= 1114111) parts.push(String.fromCodePoint(codePoint));
27509
+ if (j < i && isWhitespace(input.charCodeAt(j))) j++;
27510
+ }
27511
+ return { value: parts.join(""), end: i };
27512
+ }
27513
+ function skipCssEscape(input, afterBackslash) {
27514
+ const length = input.length;
27515
+ if (afterBackslash >= length) return afterBackslash;
27516
+ const first = input.charCodeAt(afterBackslash);
27517
+ if (!isHexDigit(first)) return afterBackslash + 1;
27518
+ let end = afterBackslash + 1;
27519
+ const maxHex = Math.min(afterBackslash + 6, length);
27520
+ while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
27521
+ if (end < length && isWhitespace(input.charCodeAt(end))) end++;
27522
+ return end;
27523
+ }
27524
+ var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
27525
+ var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
27526
+ var MAX_PSEUDO_PARSE_DEPTH = 4;
27527
+ function parseSelectorComplete(raw, _depth) {
27539
27528
  let start = 0;
27540
27529
  let end = raw.length;
27541
27530
  while (start < end && isWhitespace(raw.charCodeAt(start))) start++;
27542
27531
  while (end > start && isWhitespace(raw.charCodeAt(end - 1))) end--;
27543
27532
  if (start === end) {
27544
- return { parts: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
27533
+ return { parts: [], compounds: [], combinators: [], specificity: [0, 0, 0, 0], complexity: MINIMAL_COMPLEXITY };
27545
27534
  }
27546
27535
  const input = start === 0 && end === raw.length ? raw : raw.substring(start, end);
27547
27536
  const len = input.length;
27548
- const parts = [];
27537
+ const allParts = [];
27538
+ let currentCompoundParts = [];
27549
27539
  const combinators = [];
27540
+ const compounds = [];
27550
27541
  let ids = 0;
27551
27542
  let classes = 0;
27552
27543
  let elements = 0;
@@ -27556,10 +27547,11 @@ function parseSelectorComplete(raw) {
27556
27547
  let hasPseudoClassFlag = false;
27557
27548
  let hasPseudoElementFlag = false;
27558
27549
  let hasNesting = false;
27559
- const pseudoClasses = [];
27560
- const pseudoElements = [];
27550
+ const pseudoClassNames = [];
27551
+ const pseudoElementNames = [];
27561
27552
  let pos = 0;
27562
27553
  let inCompound = false;
27554
+ const depth = _depth ?? 0;
27563
27555
  while (pos < len) {
27564
27556
  const char = input.charCodeAt(pos);
27565
27557
  if (isWhitespace(char) || isCombinator(char)) {
@@ -27584,6 +27576,8 @@ function parseSelectorComplete(raw) {
27584
27576
  }
27585
27577
  }
27586
27578
  if (scanPos < len) {
27579
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
27580
+ currentCompoundParts = [];
27587
27581
  combinators.push(sawCombinator ?? "descendant");
27588
27582
  inCompound = false;
27589
27583
  }
@@ -27595,13 +27589,17 @@ function parseSelectorComplete(raw) {
27595
27589
  }
27596
27590
  inCompound = true;
27597
27591
  if (char === CHAR_AMPERSAND) {
27598
- parts.push({ type: "nesting", value: "&", raw: "&" });
27592
+ const part = { type: "nesting", value: "&", raw: "&" };
27593
+ allParts.push(part);
27594
+ currentCompoundParts.push(part);
27599
27595
  hasNesting = true;
27600
27596
  pos++;
27601
27597
  continue;
27602
27598
  }
27603
27599
  if (char === CHAR_ASTERISK) {
27604
- parts.push({ type: "universal", value: "*", raw: "*" });
27600
+ const part = { type: "universal", value: "*", raw: "*" };
27601
+ allParts.push(part);
27602
+ currentCompoundParts.push(part);
27605
27603
  hasUniversal = true;
27606
27604
  pos++;
27607
27605
  continue;
@@ -27612,10 +27610,26 @@ function parseSelectorComplete(raw) {
27612
27610
  if (match) {
27613
27611
  const val = match[1];
27614
27612
  if (!val) break;
27615
- parts.push({ type: "id", value: val, raw: match[0] });
27613
+ const ident2 = readCssIdentifier(input, pos + 1);
27614
+ const idVal = ident2 ? ident2.value : val;
27615
+ const idRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
27616
+ const idEnd = ident2 ? ident2.end : ID_STICKY.lastIndex;
27617
+ const part = { type: "id", value: idVal, raw: idRaw };
27618
+ allParts.push(part);
27619
+ currentCompoundParts.push(part);
27616
27620
  ids++;
27617
27621
  hasId = true;
27618
- pos = ID_STICKY.lastIndex;
27622
+ pos = idEnd;
27623
+ continue;
27624
+ }
27625
+ const ident = readCssIdentifier(input, pos + 1);
27626
+ if (ident) {
27627
+ const part = { type: "id", value: ident.value, raw: input.slice(pos, ident.end) };
27628
+ allParts.push(part);
27629
+ currentCompoundParts.push(part);
27630
+ ids++;
27631
+ hasId = true;
27632
+ pos = ident.end;
27619
27633
  continue;
27620
27634
  }
27621
27635
  }
@@ -27625,9 +27639,24 @@ function parseSelectorComplete(raw) {
27625
27639
  if (match) {
27626
27640
  const val = match[1];
27627
27641
  if (!val) break;
27628
- parts.push({ type: "class", value: val, raw: match[0] });
27642
+ const ident2 = readCssIdentifier(input, pos + 1);
27643
+ const clsVal = ident2 ? ident2.value : val;
27644
+ const clsRaw = ident2 ? input.slice(pos, ident2.end) : match[0];
27645
+ const clsEnd = ident2 ? ident2.end : CLASS_STICKY.lastIndex;
27646
+ const part = { type: "class", value: clsVal, raw: clsRaw };
27647
+ allParts.push(part);
27648
+ currentCompoundParts.push(part);
27649
+ classes++;
27650
+ pos = clsEnd;
27651
+ continue;
27652
+ }
27653
+ const ident = readCssIdentifier(input, pos + 1);
27654
+ if (ident) {
27655
+ const part = { type: "class", value: ident.value, raw: input.slice(pos, ident.end) };
27656
+ allParts.push(part);
27657
+ currentCompoundParts.push(part);
27629
27658
  classes++;
27630
- pos = CLASS_STICKY.lastIndex;
27659
+ pos = ident.end;
27631
27660
  continue;
27632
27661
  }
27633
27662
  }
@@ -27637,7 +27666,9 @@ function parseSelectorComplete(raw) {
27637
27666
  if (match) {
27638
27667
  const val = match[1];
27639
27668
  if (!val) break;
27640
- parts.push({ type: "attribute", value: val, raw: match[0] });
27669
+ const part = { type: "attribute", value: val, raw: match[0] };
27670
+ allParts.push(part);
27671
+ currentCompoundParts.push(part);
27641
27672
  classes++;
27642
27673
  hasAttribute = true;
27643
27674
  pos = ATTRIBUTE_STICKY.lastIndex;
@@ -27651,10 +27682,12 @@ function parseSelectorComplete(raw) {
27651
27682
  if (match) {
27652
27683
  const val = match[1];
27653
27684
  if (!val) break;
27654
- parts.push({ type: "pseudo-element", value: val, raw: match[0] });
27685
+ const part = { type: "pseudo-element", value: val, raw: match[0] };
27686
+ allParts.push(part);
27687
+ currentCompoundParts.push(part);
27655
27688
  elements++;
27656
27689
  hasPseudoElementFlag = true;
27657
- pseudoElements.push(val);
27690
+ pseudoElementNames.push(val);
27658
27691
  pos = PSEUDO_ELEMENT_STICKY.lastIndex;
27659
27692
  continue;
27660
27693
  }
@@ -27680,19 +27713,25 @@ function parseSelectorComplete(raw) {
27680
27713
  const fullMatch = input.substring(pseudoStart, argEnd);
27681
27714
  const argContent = input.substring(nameEnd + 1, argEnd - 1);
27682
27715
  if (pseudoName === "where") {
27683
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
27716
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
27717
+ allParts.push(part2);
27718
+ currentCompoundParts.push(part2);
27684
27719
  hasPseudoClassFlag = true;
27685
- pseudoClasses.push(pseudoName);
27720
+ pseudoClassNames.push(pseudoName);
27686
27721
  } else if (pseudoName === "is" || pseudoName === "not" || pseudoName === "has") {
27687
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
27722
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
27723
+ allParts.push(part2);
27724
+ currentCompoundParts.push(part2);
27688
27725
  hasPseudoClassFlag = true;
27689
- pseudoClasses.push(pseudoName);
27726
+ pseudoClassNames.push(pseudoName);
27690
27727
  const args = splitPseudoArgs(argContent);
27691
27728
  let maxIds = 0, maxClasses = 0, maxElements = 0;
27692
- for (const arg of args) {
27729
+ for (let ai = 0; ai < args.length; ai++) {
27730
+ const arg = args[ai];
27731
+ if (!arg) continue;
27693
27732
  const trimmed = arg.trim();
27694
27733
  if (trimmed) {
27695
- const { specificity: argSpec } = parseSelectorComplete(trimmed);
27734
+ const { specificity: argSpec } = parseSelectorComplete(trimmed, depth + 1);
27696
27735
  if (argSpec[1] > maxIds || argSpec[1] === maxIds && argSpec[2] > maxClasses || argSpec[1] === maxIds && argSpec[2] === maxClasses && argSpec[3] > maxElements) {
27697
27736
  maxIds = argSpec[1];
27698
27737
  maxClasses = argSpec[2];
@@ -27704,18 +27743,22 @@ function parseSelectorComplete(raw) {
27704
27743
  classes += maxClasses;
27705
27744
  elements += maxElements;
27706
27745
  } else {
27707
- parts.push({ type: "pseudo-class", value: pseudoName, raw: fullMatch });
27746
+ const part2 = { type: "pseudo-class", value: pseudoName, raw: fullMatch };
27747
+ allParts.push(part2);
27748
+ currentCompoundParts.push(part2);
27708
27749
  hasPseudoClassFlag = true;
27709
- pseudoClasses.push(pseudoName);
27750
+ pseudoClassNames.push(pseudoName);
27710
27751
  classes++;
27711
27752
  }
27712
27753
  pos = argEnd;
27713
27754
  continue;
27714
27755
  }
27715
27756
  const rawMatch = input.substring(pseudoStart, nameEnd);
27716
- parts.push({ type: "pseudo-class", value: pseudoName, raw: rawMatch });
27757
+ const part = { type: "pseudo-class", value: pseudoName, raw: rawMatch };
27758
+ allParts.push(part);
27759
+ currentCompoundParts.push(part);
27717
27760
  hasPseudoClassFlag = true;
27718
- pseudoClasses.push(pseudoName);
27761
+ pseudoClassNames.push(pseudoName);
27719
27762
  classes++;
27720
27763
  pos = nameEnd;
27721
27764
  continue;
@@ -27727,7 +27770,9 @@ function parseSelectorComplete(raw) {
27727
27770
  if (match) {
27728
27771
  const val = match[1];
27729
27772
  if (!val) break;
27730
- parts.push({ type: "element", value: val, raw: match[0] });
27773
+ const part = { type: "element", value: val, raw: match[0] };
27774
+ allParts.push(part);
27775
+ currentCompoundParts.push(part);
27731
27776
  elements++;
27732
27777
  pos = ELEMENT_STICKY.lastIndex;
27733
27778
  continue;
@@ -27735,6 +27780,9 @@ function parseSelectorComplete(raw) {
27735
27780
  }
27736
27781
  pos++;
27737
27782
  }
27783
+ if (currentCompoundParts.length > 0) {
27784
+ compounds.push(finalizeCompound(currentCompoundParts, depth));
27785
+ }
27738
27786
  const complexity = buildComplexity(
27739
27787
  combinators,
27740
27788
  hasId,
@@ -27743,16 +27791,157 @@ function parseSelectorComplete(raw) {
27743
27791
  hasPseudoClassFlag,
27744
27792
  hasPseudoElementFlag,
27745
27793
  hasNesting,
27746
- pseudoClasses,
27747
- pseudoElements
27794
+ pseudoClassNames,
27795
+ pseudoElementNames
27748
27796
  );
27749
27797
  return {
27750
- parts,
27798
+ parts: allParts,
27799
+ compounds,
27751
27800
  combinators,
27752
27801
  specificity: [0, ids, classes, elements],
27753
27802
  complexity
27754
27803
  };
27755
27804
  }
27805
+ function finalizeCompound(parts, depth) {
27806
+ let tagName = null;
27807
+ let idValue = null;
27808
+ const classes = [];
27809
+ const seenClasses = /* @__PURE__ */ new Set();
27810
+ const attributes = [];
27811
+ const pseudoClasses = [];
27812
+ for (let i = 0; i < parts.length; i++) {
27813
+ const part = parts[i];
27814
+ if (!part) continue;
27815
+ if (part.type === "element") {
27816
+ tagName = part.value.toLowerCase();
27817
+ } else if (part.type === "id") {
27818
+ idValue = part.value;
27819
+ } else if (part.type === "class") {
27820
+ if (!seenClasses.has(part.value)) {
27821
+ seenClasses.add(part.value);
27822
+ classes.push(part.value);
27823
+ }
27824
+ } else if (part.type === "attribute") {
27825
+ const constraint = parseAttributeConstraintFromRaw(part.value);
27826
+ if (constraint) attributes.push(constraint);
27827
+ } else if (part.type === "pseudo-class") {
27828
+ const parsed = parsePseudoToParsedConstraint(part.value, part.raw, depth);
27829
+ if (parsed) pseudoClasses.push(parsed);
27830
+ }
27831
+ }
27832
+ return { parts, tagName, idValue, classes, attributes, pseudoClasses };
27833
+ }
27834
+ function parseAttributeConstraintFromRaw(raw) {
27835
+ const trimmed = raw.trim();
27836
+ const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
27837
+ if (constrained) {
27838
+ const operatorToken = constrained[2];
27839
+ if (!operatorToken) return null;
27840
+ const operator = mapAttrOperator(operatorToken);
27841
+ if (operator === null) return null;
27842
+ const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
27843
+ if (value2 === null) return null;
27844
+ const nameToken = constrained[1];
27845
+ if (!nameToken) return null;
27846
+ return {
27847
+ name: nameToken.toLowerCase(),
27848
+ operator,
27849
+ value: value2,
27850
+ caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
27851
+ };
27852
+ }
27853
+ if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) return null;
27854
+ return { name: trimmed.toLowerCase(), operator: "exists", value: null, caseInsensitive: false };
27855
+ }
27856
+ function mapAttrOperator(op) {
27857
+ if (op === "=") return "equals";
27858
+ if (op === "~=") return "includes-word";
27859
+ if (op === "|=") return "dash-prefix";
27860
+ if (op === "^=") return "prefix";
27861
+ if (op === "$=") return "suffix";
27862
+ if (op === "*=") return "contains";
27863
+ return null;
27864
+ }
27865
+ function parsePseudoToParsedConstraint(name, raw, depth) {
27866
+ const lowerName = name.toLowerCase();
27867
+ if (lowerName === "first-child") return { name: lowerName, raw, kind: 1 /* FirstChild */, nthPattern: null, nestedCompounds: null };
27868
+ if (lowerName === "last-child") return { name: lowerName, raw, kind: 2 /* LastChild */, nthPattern: null, nestedCompounds: null };
27869
+ if (lowerName === "only-child") return { name: lowerName, raw, kind: 3 /* OnlyChild */, nthPattern: null, nestedCompounds: null };
27870
+ const parenIdx = raw.indexOf("(");
27871
+ if (parenIdx === -1) {
27872
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
27873
+ }
27874
+ const argContent = raw.substring(parenIdx + 1, raw.length - 1);
27875
+ if (lowerName === "nth-child") {
27876
+ const pattern = parseNthPatternFromArg(argContent);
27877
+ return pattern ? { name: lowerName, raw, kind: 4 /* NthChild */, nthPattern: pattern, nestedCompounds: null } : null;
27878
+ }
27879
+ if (lowerName === "nth-last-child") {
27880
+ const pattern = parseNthPatternFromArg(argContent);
27881
+ return pattern ? { name: lowerName, raw, kind: 5 /* NthLastChild */, nthPattern: pattern, nestedCompounds: null } : null;
27882
+ }
27883
+ if (lowerName === "nth-of-type") {
27884
+ const pattern = parseNthPatternFromArg(argContent);
27885
+ return pattern ? { name: lowerName, raw, kind: 6 /* NthOfType */, nthPattern: pattern, nestedCompounds: null } : null;
27886
+ }
27887
+ if (lowerName === "nth-last-of-type") {
27888
+ const pattern = parseNthPatternFromArg(argContent);
27889
+ return pattern ? { name: lowerName, raw, kind: 7 /* NthLastOfType */, nthPattern: pattern, nestedCompounds: null } : null;
27890
+ }
27891
+ if (lowerName === "is" || lowerName === "where") {
27892
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: null };
27893
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
27894
+ return { name: lowerName, raw, kind: 8 /* MatchesAny */, nthPattern: null, nestedCompounds: nested };
27895
+ }
27896
+ if (lowerName === "not") {
27897
+ if (depth >= MAX_PSEUDO_PARSE_DEPTH) return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: null };
27898
+ const nested = parseNestedCompoundGroups(argContent, depth + 1);
27899
+ return { name: lowerName, raw, kind: 9 /* NoneOf */, nthPattern: null, nestedCompounds: nested };
27900
+ }
27901
+ return { name: lowerName, raw, kind: 0 /* Simple */, nthPattern: null, nestedCompounds: null };
27902
+ }
27903
+ function parseNestedCompoundGroups(argContent, depth) {
27904
+ const args = splitPseudoArgs(argContent);
27905
+ const groups = [];
27906
+ for (let i = 0; i < args.length; i++) {
27907
+ const arg = args[i];
27908
+ if (!arg) continue;
27909
+ const trimmed = arg.trim();
27910
+ if (!trimmed) continue;
27911
+ const result = parseSelectorComplete(trimmed, depth);
27912
+ if (result.compounds.length > 0) {
27913
+ groups.push(result.compounds.slice());
27914
+ }
27915
+ }
27916
+ return groups;
27917
+ }
27918
+ function parseNthPatternFromArg(raw) {
27919
+ const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
27920
+ if (normalized.length === 0) return null;
27921
+ if (normalized === "odd") return { step: 2, offset: 1 };
27922
+ if (normalized === "even") return { step: 2, offset: 0 };
27923
+ const nIndex = normalized.indexOf("n");
27924
+ if (nIndex === -1) {
27925
+ const value2 = Number.parseInt(normalized, 10);
27926
+ if (Number.isNaN(value2)) return null;
27927
+ return { step: 0, offset: value2 };
27928
+ }
27929
+ const stepPart = normalized.slice(0, nIndex);
27930
+ const offsetPart = normalized.slice(nIndex + 1);
27931
+ let step;
27932
+ if (stepPart.length === 0 || stepPart === "+") step = 1;
27933
+ else if (stepPart === "-") step = -1;
27934
+ else {
27935
+ step = Number.parseInt(stepPart, 10);
27936
+ if (Number.isNaN(step)) return null;
27937
+ }
27938
+ let offset = 0;
27939
+ if (offsetPart.length > 0) {
27940
+ offset = Number.parseInt(offsetPart, 10);
27941
+ if (Number.isNaN(offset)) return null;
27942
+ }
27943
+ return { step, offset };
27944
+ }
27756
27945
  function splitPseudoArgs(content) {
27757
27946
  const result = [];
27758
27947
  let start = 0;
@@ -28101,8 +28290,6 @@ function extractVarReferences(value2) {
28101
28290
 
28102
28291
  // src/css/phases/ast.ts
28103
28292
  var CSS_IDENT = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
28104
- var ATTRIBUTE_EXISTS_RE = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
28105
- var ATTRIBUTE_CONSTRAINT_RE = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
28106
28293
  var ROOT_CONTEXT = {
28107
28294
  parentRule: null,
28108
28295
  parentAtRule: null,
@@ -28569,142 +28756,6 @@ function getRuleBlockOffsets(file, startOffset, endOffset) {
28569
28756
  blockEndOffset: close
28570
28757
  };
28571
28758
  }
28572
- function extractSubjectCompound(raw) {
28573
- const len = raw.length;
28574
- if (len === 0) return "";
28575
- let end = len - 1;
28576
- while (end >= 0 && isWhitespace(raw.charCodeAt(end))) end--;
28577
- if (end < 0) return "";
28578
- let parenDepth = 0;
28579
- let bracketDepth = 0;
28580
- for (let i = end; i >= 0; i--) {
28581
- const code = raw.charCodeAt(i);
28582
- if (code === CHAR_CLOSE_PAREN) {
28583
- parenDepth++;
28584
- continue;
28585
- }
28586
- if (code === CHAR_OPEN_PAREN) {
28587
- if (parenDepth > 0) parenDepth--;
28588
- continue;
28589
- }
28590
- if (code === CHAR_CLOSE_BRACKET) {
28591
- bracketDepth++;
28592
- continue;
28593
- }
28594
- if (code === CHAR_OPEN_BRACKET) {
28595
- if (bracketDepth > 0) bracketDepth--;
28596
- continue;
28597
- }
28598
- if (parenDepth > 0 || bracketDepth > 0) continue;
28599
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
28600
- return raw.slice(i + 1, end + 1).trim();
28601
- }
28602
- if (!isWhitespace(code)) continue;
28603
- return raw.slice(i + 1, end + 1).trim();
28604
- }
28605
- return raw.slice(0, end + 1).trim();
28606
- }
28607
- function parseAnchorAttributes(parts) {
28608
- const out = [];
28609
- for (let i = 0; i < parts.length; i++) {
28610
- const part = parts[i];
28611
- if (!part) continue;
28612
- if (part.type !== "attribute") continue;
28613
- const trimmed = part.value.trim();
28614
- const constrained = ATTRIBUTE_CONSTRAINT_RE.exec(trimmed);
28615
- if (constrained) {
28616
- const opToken = constrained[2];
28617
- if (!opToken) continue;
28618
- const operator = mapAttributeOperatorFromToken(opToken);
28619
- if (operator === null) continue;
28620
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
28621
- if (value2 === null) continue;
28622
- const attrName = constrained[1];
28623
- if (!attrName) continue;
28624
- out.push({
28625
- name: attrName.toLowerCase(),
28626
- operator,
28627
- value: value2,
28628
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
28629
- });
28630
- continue;
28631
- }
28632
- if (!ATTRIBUTE_EXISTS_RE.test(trimmed)) continue;
28633
- out.push({
28634
- name: trimmed.toLowerCase(),
28635
- operator: "exists",
28636
- value: null,
28637
- caseInsensitive: false
28638
- });
28639
- }
28640
- return out;
28641
- }
28642
- function mapAttributeOperatorFromToken(operator) {
28643
- if (operator === "=") return "equals";
28644
- if (operator === "~=") return "includes-word";
28645
- if (operator === "|=") return "dash-prefix";
28646
- if (operator === "^=") return "prefix";
28647
- if (operator === "$=") return "suffix";
28648
- if (operator === "*=") return "contains";
28649
- return null;
28650
- }
28651
- function buildSelectorAnchor(raw, parts, combinators) {
28652
- const subjectCompound = extractSubjectCompound(raw);
28653
- const subjectParts = parseSelector(subjectCompound);
28654
- let subjectTag = null;
28655
- const classes = [];
28656
- const seenClasses = /* @__PURE__ */ new Set();
28657
- for (let i = 0; i < subjectParts.length; i++) {
28658
- const part = subjectParts[i];
28659
- if (!part) continue;
28660
- if (part.type === "element") {
28661
- subjectTag = part.value.toLowerCase();
28662
- continue;
28663
- }
28664
- if (part.type !== "class") continue;
28665
- const cls = part.value;
28666
- if (seenClasses.has(cls)) continue;
28667
- seenClasses.add(cls);
28668
- classes.push(cls);
28669
- }
28670
- const attributes = parseAnchorAttributes(subjectParts);
28671
- const includesDescendantCombinator = combinators.includes("descendant");
28672
- let includesPseudoSelector = false;
28673
- let includesNesting = false;
28674
- for (let i = 0; i < parts.length; i++) {
28675
- const part = parts[i];
28676
- if (!part) continue;
28677
- if (part.type === "pseudo-class" || part.type === "pseudo-element") {
28678
- includesPseudoSelector = true;
28679
- continue;
28680
- }
28681
- if (part.type === "nesting") includesNesting = true;
28682
- }
28683
- let hasCheckboxAttribute = false;
28684
- for (let i = 0; i < attributes.length; i++) {
28685
- const a = attributes[i];
28686
- if (!a) continue;
28687
- if (a.name !== "type") continue;
28688
- if (a.operator !== "equals") continue;
28689
- if (a.value === null) continue;
28690
- const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
28691
- if (normalized !== "checkbox") continue;
28692
- hasCheckboxAttribute = true;
28693
- break;
28694
- }
28695
- const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
28696
- const targetsTableCell = subjectTag === "td" || subjectTag === "th";
28697
- return {
28698
- subjectTag,
28699
- classes,
28700
- attributes,
28701
- includesDescendantCombinator,
28702
- includesPseudoSelector,
28703
- dynamic: includesPseudoSelector || includesNesting,
28704
- targetsCheckbox,
28705
- targetsTableCell
28706
- };
28707
- }
28708
28759
  function createRuleEntity(graph, node, file, context) {
28709
28760
  const { parentRule, parentAtRule, containingMedia, containingLayer, depth } = context;
28710
28761
  const id = graph.nextRuleId();
@@ -28751,9 +28802,55 @@ function createRuleEntity(graph, node, file, context) {
28751
28802
  }
28752
28803
  function createSelectorEntity(graph, raw, rule) {
28753
28804
  const id = graph.nextSelectorId();
28754
- const { parts, specificity, complexity } = parseSelectorComplete(raw);
28805
+ const { parts, compounds, combinators, specificity, complexity } = parseSelectorComplete(raw);
28755
28806
  const specificityScore = specificityToScore(specificity);
28756
- const anchor = buildSelectorAnchor(raw, parts, complexity.combinators);
28807
+ const kinds = rule.elementKinds;
28808
+ for (let k = 0; k < parts.length; k++) {
28809
+ const part = parts[k];
28810
+ if (part) classifyPart(part, kinds);
28811
+ }
28812
+ const subject = compounds.length > 0 ? compounds[compounds.length - 1] : null;
28813
+ let includesPseudoSelector = false;
28814
+ let includesNesting = false;
28815
+ for (let i = 0; i < parts.length; i++) {
28816
+ const part = parts[i];
28817
+ if (!part) continue;
28818
+ if (part.type === "pseudo-class" || part.type === "pseudo-element") {
28819
+ includesPseudoSelector = true;
28820
+ continue;
28821
+ }
28822
+ if (part.type === "nesting") includesNesting = true;
28823
+ }
28824
+ const subjectTag = subject?.tagName ?? null;
28825
+ const subjectIdValue = subject?.idValue ?? null;
28826
+ const subjectClasses = subject?.classes ?? [];
28827
+ const subjectAttributes = subject?.attributes ?? [];
28828
+ const includesDescendantCombinator = combinators.includes("descendant");
28829
+ let hasCheckboxAttribute = false;
28830
+ for (let i = 0; i < subjectAttributes.length; i++) {
28831
+ const a = subjectAttributes[i];
28832
+ if (!a) continue;
28833
+ if (a.name !== "type") continue;
28834
+ if (a.operator !== "equals") continue;
28835
+ if (a.value === null) continue;
28836
+ const normalized = a.caseInsensitive ? a.value.toLowerCase() : a.value;
28837
+ if (normalized !== "checkbox") continue;
28838
+ hasCheckboxAttribute = true;
28839
+ break;
28840
+ }
28841
+ const targetsCheckbox = (subjectTag === "input" || subjectTag === null) && hasCheckboxAttribute;
28842
+ const targetsTableCell = subjectTag === "td" || subjectTag === "th";
28843
+ const anchor = {
28844
+ subjectTag,
28845
+ idValue: subjectIdValue,
28846
+ classes: subjectClasses,
28847
+ attributes: subjectAttributes,
28848
+ includesDescendantCombinator,
28849
+ includesPseudoSelector,
28850
+ dynamic: includesPseudoSelector || includesNesting,
28851
+ targetsCheckbox,
28852
+ targetsTableCell
28853
+ };
28757
28854
  return {
28758
28855
  id,
28759
28856
  raw,
@@ -28761,6 +28858,8 @@ function createSelectorEntity(graph, raw, rule) {
28761
28858
  specificity,
28762
28859
  specificityScore,
28763
28860
  complexity,
28861
+ compounds,
28862
+ combinators,
28764
28863
  parts: parts.length > 0 ? parts : [],
28765
28864
  anchor,
28766
28865
  overrides: [],
@@ -30761,23 +30860,44 @@ function collectCSSScopeBySolidFile(solids, css, moduleResolver) {
30761
30860
  if (!imp) continue;
30762
30861
  if (imp.isTypeOnly) continue;
30763
30862
  const resolvedCssPath = resolver.resolveCss(solid.file, imp.source);
30764
- if (resolvedCssPath === null) continue;
30765
- const transitiveScope = getOrCollectTransitiveScope(
30766
- resolvedCssPath,
30767
- resolver,
30768
- cssFilesByNormalizedPath,
30769
- transitiveScopeByEntryPath
30770
- );
30771
- for (let k = 0; k < transitiveScope.length; k++) {
30772
- const ts137 = transitiveScope[k];
30773
- if (!ts137) continue;
30774
- scope.add(ts137);
30863
+ if (resolvedCssPath !== null) {
30864
+ const transitiveScope = getOrCollectTransitiveScope(
30865
+ resolvedCssPath,
30866
+ resolver,
30867
+ cssFilesByNormalizedPath,
30868
+ transitiveScopeByEntryPath
30869
+ );
30870
+ for (let k = 0; k < transitiveScope.length; k++) {
30871
+ const ts137 = transitiveScope[k];
30872
+ if (!ts137) continue;
30873
+ scope.add(ts137);
30874
+ }
30875
+ if (imp.specifiers.length === 0) {
30876
+ for (let k = 0; k < transitiveScope.length; k++) {
30877
+ const ts137 = transitiveScope[k];
30878
+ if (!ts137) continue;
30879
+ globalSideEffectScope.add(ts137);
30880
+ }
30881
+ }
30775
30882
  }
30776
- if (imp.specifiers.length !== 0) continue;
30777
- for (let k = 0; k < transitiveScope.length; k++) {
30778
- const ts137 = transitiveScope[k];
30779
- if (!ts137) continue;
30780
- globalSideEffectScope.add(ts137);
30883
+ if (imp.specifiers.length !== 0) {
30884
+ const resolvedSolidPath = resolver.resolveSolid(solid.file, imp.source);
30885
+ if (resolvedSolidPath !== null) {
30886
+ const componentCssPath = resolveColocatedCss(resolvedSolidPath, cssFilesByNormalizedPath);
30887
+ if (componentCssPath !== null) {
30888
+ const componentCssScope = getOrCollectTransitiveScope(
30889
+ componentCssPath,
30890
+ resolver,
30891
+ cssFilesByNormalizedPath,
30892
+ transitiveScopeByEntryPath
30893
+ );
30894
+ for (let k = 0; k < componentCssScope.length; k++) {
30895
+ const cs = componentCssScope[k];
30896
+ if (!cs) continue;
30897
+ scope.add(cs);
30898
+ }
30899
+ }
30900
+ }
30781
30901
  }
30782
30902
  }
30783
30903
  localScopeBySolidFile.set(solid.file, scope);
@@ -30861,6 +30981,8 @@ var layoutSignalNames = [
30861
30981
  "min-width",
30862
30982
  "min-block-size",
30863
30983
  "min-height",
30984
+ "max-width",
30985
+ "max-height",
30864
30986
  "aspect-ratio",
30865
30987
  "vertical-align",
30866
30988
  "display",
@@ -30879,6 +31001,7 @@ var layoutSignalNames = [
30879
31001
  "place-items",
30880
31002
  "place-self",
30881
31003
  "flex-direction",
31004
+ "flex-basis",
30882
31005
  "grid-auto-flow",
30883
31006
  "appearance",
30884
31007
  "box-sizing",
@@ -31147,6 +31270,7 @@ import { readFileSync as readFileSync4 } from "fs";
31147
31270
  import { resolve as resolve4 } from "path";
31148
31271
  import ts123 from "typescript";
31149
31272
  var EMPTY_ATTRIBUTES = /* @__PURE__ */ new Map();
31273
+ var EMPTY_PROP_BINDINGS = /* @__PURE__ */ new Map();
31150
31274
  var TRANSPARENT_SOLID_PRIMITIVES = /* @__PURE__ */ new Set([
31151
31275
  "For",
31152
31276
  "Index",
@@ -31215,9 +31339,10 @@ function createLayoutComponentHostResolver(solids, moduleResolver, logger = noop
31215
31339
  const staticAttributes = innerHost !== null ? mergeStaticAttributes(entry.staticAttributes, innerHost.descriptor.staticAttributes) : entry.staticAttributes;
31216
31340
  const staticClassTokens = innerHost !== null ? mergeStaticClassTokens(entry.staticClassTokens, innerHost.descriptor.staticClassTokens) : entry.staticClassTokens;
31217
31341
  const forwardsChildren = entry.forwardsChildren || innerHost !== null && innerHost.descriptor.forwardsChildren;
31342
+ const attributePropBindings = innerHost !== null ? mergePropBindings(entry.attributePropBindings, innerHost.descriptor.attributePropBindings) : entry.attributePropBindings;
31218
31343
  if (logger.isLevelEnabled(Level.Trace)) logger.trace(`[component-host] resolved: tagName=${tagName}, attrs=[${[...staticAttributes.keys()]}], classes=[${staticClassTokens}]`);
31219
31344
  return {
31220
- descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren },
31345
+ descriptor: { tagName, staticAttributes, staticClassTokens, forwardsChildren, attributePropBindings },
31221
31346
  hostElementRef: innerHost?.hostElementRef ?? null
31222
31347
  };
31223
31348
  }
@@ -31644,7 +31769,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
31644
31769
  tagName: element.tagName,
31645
31770
  staticAttributes: collectStaticAttributes(element),
31646
31771
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
31647
- forwardsChildren: detectChildrenForwarding(element)
31772
+ forwardsChildren: detectChildrenForwarding(element),
31773
+ attributePropBindings: collectAttributePropBindings(element)
31648
31774
  },
31649
31775
  hostElementRef: { solid: graph, element }
31650
31776
  };
@@ -31659,7 +31785,8 @@ function resolveHostEntryFromJSXElement(graph, node) {
31659
31785
  filePath: graph.file,
31660
31786
  staticAttributes: collectStaticAttributes(element),
31661
31787
  staticClassTokens: getStaticClassTokensForElementEntity(graph, element),
31662
- forwardsChildren: detectChildrenForwarding(element)
31788
+ forwardsChildren: detectChildrenForwarding(element),
31789
+ attributePropBindings: collectAttributePropBindings(element)
31663
31790
  };
31664
31791
  }
31665
31792
  function isContextProviderTag(tag) {
@@ -31847,6 +31974,41 @@ function collectStaticAttributes(element) {
31847
31974
  if (out === null) return EMPTY_ATTRIBUTES;
31848
31975
  return out;
31849
31976
  }
31977
+ function extractPropMemberName(node) {
31978
+ if (!ts123.isJsxExpression(node)) return null;
31979
+ const expression = node.expression;
31980
+ if (!expression) return null;
31981
+ return extractMemberNameFromExpression(expression);
31982
+ }
31983
+ function extractMemberNameFromExpression(expression) {
31984
+ if (ts123.isPropertyAccessExpression(expression)) {
31985
+ return expression.name.text;
31986
+ }
31987
+ if (ts123.isCallExpression(expression) && ts123.isPropertyAccessExpression(expression.expression) && expression.arguments.length === 0) {
31988
+ return expression.expression.name.text;
31989
+ }
31990
+ if (ts123.isBinaryExpression(expression) && expression.operatorToken.kind === ts123.SyntaxKind.QuestionQuestionToken) {
31991
+ return extractMemberNameFromExpression(expression.left);
31992
+ }
31993
+ return null;
31994
+ }
31995
+ function collectAttributePropBindings(element) {
31996
+ let out = null;
31997
+ for (let i = 0; i < element.attributes.length; i++) {
31998
+ const attribute = element.attributes[i];
31999
+ if (!attribute) continue;
32000
+ if (!ts123.isJsxAttribute(attribute.node)) continue;
32001
+ if (!attribute.name) continue;
32002
+ if (attribute.valueNode === null) continue;
32003
+ const propName = extractPropMemberName(attribute.valueNode);
32004
+ if (propName === null) continue;
32005
+ const attrName = attribute.name.toLowerCase();
32006
+ if (out === null) out = /* @__PURE__ */ new Map();
32007
+ out.set(attrName, propName);
32008
+ }
32009
+ if (out === null) return EMPTY_PROP_BINDINGS;
32010
+ return out;
32011
+ }
31850
32012
  function collectTopLevelVariableInitializers(graph) {
31851
32013
  const out = /* @__PURE__ */ new Map();
31852
32014
  for (let i = 0; i < graph.variables.length; i++) {
@@ -31972,7 +32134,12 @@ function areHostDescriptorsEqual(left, right) {
31972
32134
  if (left.tagName !== right.tagName) return false;
31973
32135
  if (left.forwardsChildren !== right.forwardsChildren) return false;
31974
32136
  if (!areStringListsEqual(left.staticClassTokens, right.staticClassTokens)) return false;
31975
- return areAttributeMapsEqual(left.staticAttributes, right.staticAttributes);
32137
+ if (!areAttributeMapsEqual(left.staticAttributes, right.staticAttributes)) return false;
32138
+ if (left.attributePropBindings.size !== right.attributePropBindings.size) return false;
32139
+ for (const [key, value2] of left.attributePropBindings) {
32140
+ if (right.attributePropBindings.get(key) !== value2) return false;
32141
+ }
32142
+ return true;
31976
32143
  }
31977
32144
  function areComponentHostEntriesEqual(left, right) {
31978
32145
  if (left.resolution !== right.resolution) return false;
@@ -32015,6 +32182,18 @@ function mergeStaticAttributes(outer, inner) {
32015
32182
  }
32016
32183
  return out;
32017
32184
  }
32185
+ function mergePropBindings(outer, inner) {
32186
+ if (inner.size === 0) return outer;
32187
+ if (outer.size === 0) return inner;
32188
+ const out = /* @__PURE__ */ new Map();
32189
+ for (const [name, value2] of inner) {
32190
+ out.set(name, value2);
32191
+ }
32192
+ for (const [name, value2] of outer) {
32193
+ out.set(name, value2);
32194
+ }
32195
+ return out;
32196
+ }
32018
32197
  var HTML_TAG_NAMES = /* @__PURE__ */ new Set([
32019
32198
  "a",
32020
32199
  "abbr",
@@ -32220,80 +32399,6 @@ function parseSignedPxValue(raw) {
32220
32399
  return parsePxValue(trimmed);
32221
32400
  }
32222
32401
 
32223
- // src/cross-file/layout/shorthand-expansion.ts
32224
- var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
32225
- ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
32226
- ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
32227
- ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
32228
- ["inset", ["top", "right", "bottom", "left"]]
32229
- ]);
32230
- var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
32231
- ["margin-block", ["margin-top", "margin-bottom"]],
32232
- ["padding-block", ["padding-top", "padding-bottom"]],
32233
- ["inset-block", ["inset-block-start", "inset-block-end"]]
32234
- ]);
32235
- function expandShorthand(property, value2) {
32236
- const quadTarget = QUAD_EXPANSIONS.get(property);
32237
- if (quadTarget !== void 0) {
32238
- const parsed = parseQuadShorthand(value2);
32239
- if (parsed === null) return null;
32240
- return [
32241
- { name: quadTarget[0], value: parsed.top },
32242
- { name: quadTarget[1], value: parsed.right },
32243
- { name: quadTarget[2], value: parsed.bottom },
32244
- { name: quadTarget[3], value: parsed.left }
32245
- ];
32246
- }
32247
- const blockTarget = BLOCK_EXPANSIONS.get(property);
32248
- if (blockTarget !== void 0) {
32249
- const parsed = parseBlockShorthand(value2);
32250
- if (parsed === null) return null;
32251
- return [
32252
- { name: blockTarget[0], value: parsed.start },
32253
- { name: blockTarget[1], value: parsed.end }
32254
- ];
32255
- }
32256
- if (property === "flex-flow") {
32257
- return expandFlexFlow(value2);
32258
- }
32259
- return void 0;
32260
- }
32261
- var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
32262
- function expandFlexFlow(value2) {
32263
- const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
32264
- if (tokens.length === 0) return null;
32265
- if (tokens.length > 2) return null;
32266
- let direction = null;
32267
- let wrap = null;
32268
- for (let i = 0; i < tokens.length; i++) {
32269
- const token = tokens[i];
32270
- if (!token) continue;
32271
- if (FLEX_DIRECTION_VALUES.has(token)) {
32272
- if (direction !== null) return null;
32273
- direction = token;
32274
- } else {
32275
- if (wrap !== null) return null;
32276
- wrap = token;
32277
- }
32278
- }
32279
- const out = [];
32280
- if (direction !== null) {
32281
- out.push({ name: "flex-direction", value: direction });
32282
- }
32283
- if (wrap !== null) {
32284
- out.push({ name: "flex-wrap", value: wrap });
32285
- }
32286
- return out.length > 0 ? out : null;
32287
- }
32288
- function getShorthandLonghandNames(property) {
32289
- const quad = QUAD_EXPANSIONS.get(property);
32290
- if (quad !== void 0) return [...quad];
32291
- const block = BLOCK_EXPANSIONS.get(property);
32292
- if (block !== void 0) return [...block];
32293
- if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
32294
- return null;
32295
- }
32296
-
32297
32402
  // src/cross-file/layout/signal-normalization.ts
32298
32403
  var MONITORED_SIGNAL_SET = new Set(layoutSignalNames);
32299
32404
  var MONITORED_SIGNAL_NAME_MAP = new Map(
@@ -32304,6 +32409,7 @@ var MONITORED_SHORTHAND_SET = /* @__PURE__ */ new Set([
32304
32409
  "border-width",
32305
32410
  "margin-block",
32306
32411
  "padding-block",
32412
+ "padding-inline",
32307
32413
  "inset-block",
32308
32414
  "flex-flow"
32309
32415
  ]);
@@ -32316,6 +32422,9 @@ var LENGTH_SIGNAL_SET = /* @__PURE__ */ new Set([
32316
32422
  "min-width",
32317
32423
  "min-block-size",
32318
32424
  "min-height",
32425
+ "max-width",
32426
+ "max-height",
32427
+ "flex-basis",
32319
32428
  "top",
32320
32429
  "bottom",
32321
32430
  "margin-top",
@@ -32369,11 +32478,11 @@ function isMonitoredSignal(property) {
32369
32478
  }
32370
32479
  function isControlTag(tag) {
32371
32480
  if (tag === null) return false;
32372
- return CONTROL_ELEMENT_TAGS.has(tag.toLowerCase());
32481
+ return CONTROL_ELEMENT_TAGS.has(tag);
32373
32482
  }
32374
32483
  function isReplacedTag(tag) {
32375
32484
  if (tag === null) return false;
32376
- return REPLACED_ELEMENT_TAGS.has(tag.toLowerCase());
32485
+ return REPLACED_ELEMENT_TAGS.has(tag);
32377
32486
  }
32378
32487
  function normalizeSignalMapWithCounts(values) {
32379
32488
  const out = /* @__PURE__ */ new Map();
@@ -32388,16 +32497,12 @@ function normalizeSignalMapWithCounts(values) {
32388
32497
  null
32389
32498
  );
32390
32499
  out.set("font-size", parsedFontSize);
32391
- if (parsedFontSize.kind === "known" && parsedFontSize.guard.kind === 0 /* Unconditional */) {
32500
+ if (parsedFontSize.kind === 0 /* Known */ && parsedFontSize.guard.kind === 0 /* Unconditional */) {
32392
32501
  fontSizePx = parsedFontSize.px;
32393
32502
  }
32394
32503
  }
32395
32504
  for (const [property, declaration] of values) {
32396
32505
  if (property === "font-size") continue;
32397
- if (MONITORED_SHORTHAND_SET.has(property)) {
32398
- applyExpandedShorthand(out, property, declaration, fontSizePx);
32399
- continue;
32400
- }
32401
32506
  const name = toMonitoredSignalName(property);
32402
32507
  if (!name) continue;
32403
32508
  const normalized = normalizeSignal(
@@ -32417,7 +32522,7 @@ function normalizeSignalMapWithCounts(values) {
32417
32522
  conditionalSignalCount++;
32418
32523
  continue;
32419
32524
  }
32420
- if (value2.kind === "known") {
32525
+ if (value2.kind === 0 /* Known */) {
32421
32526
  knownSignalCount++;
32422
32527
  continue;
32423
32528
  }
@@ -32430,30 +32535,6 @@ function normalizeSignalMapWithCounts(values) {
32430
32535
  conditionalSignalCount
32431
32536
  };
32432
32537
  }
32433
- function applyExpandedShorthand(out, property, declaration, fontSizePx) {
32434
- const expanded = expandShorthand(property, declaration.value);
32435
- if (expanded === null) {
32436
- const reason = `${property} value is not statically parseable`;
32437
- const longhandNames = getShorthandLonghandNames(property);
32438
- if (longhandNames === null) return;
32439
- for (let i = 0; i < longhandNames.length; i++) {
32440
- const longhand = longhandNames[i];
32441
- if (!longhand) continue;
32442
- const name = MONITORED_SIGNAL_NAME_MAP.get(longhand);
32443
- if (name === void 0) continue;
32444
- out.set(name, createUnknown(name, declaration.source, declaration.guardProvenance, reason));
32445
- }
32446
- return;
32447
- }
32448
- if (expanded === void 0) return;
32449
- for (let i = 0; i < expanded.length; i++) {
32450
- const entry = expanded[i];
32451
- if (!entry) continue;
32452
- const name = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
32453
- if (name === void 0) continue;
32454
- out.set(name, normalizeSignal(name, entry.value, declaration.source, declaration.guardProvenance, fontSizePx));
32455
- }
32456
- }
32457
32538
  function toMonitoredSignalName(property) {
32458
32539
  return MONITORED_SIGNAL_NAME_MAP.get(property) ?? null;
32459
32540
  }
@@ -32494,13 +32575,13 @@ function parseAspectRatio(name, raw, source, guard) {
32494
32575
  if (!Number.isFinite(left) || !Number.isFinite(right) || left <= 0 || right <= 0) {
32495
32576
  return createUnknown(name, source, guard, "aspect-ratio ratio is invalid");
32496
32577
  }
32497
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
32578
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
32498
32579
  }
32499
32580
  const ratio = Number(trimmed);
32500
32581
  if (!Number.isFinite(ratio) || ratio <= 0) {
32501
32582
  return createUnknown(name, source, guard, "aspect-ratio is not statically parseable");
32502
32583
  }
32503
- return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
32584
+ return createKnown(name, trimmed, source, guard, null, 1 /* Unitless */, 0 /* Exact */);
32504
32585
  }
32505
32586
  function parseContainIntrinsicSize(name, raw, source, guard) {
32506
32587
  const trimmed = raw.trim().toLowerCase();
@@ -32518,18 +32599,19 @@ function parseContainIntrinsicSize(name, raw, source, guard) {
32518
32599
  const part = parts[i];
32519
32600
  if (!part) continue;
32520
32601
  const px = parseSignedPxValue(part);
32521
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
32602
+ if (px !== null) return createKnown(name, trimmed, source, guard, px, 0 /* Px */, 0 /* Exact */);
32522
32603
  }
32523
32604
  return createUnknown(name, source, guard, "contain-intrinsic-size is not statically parseable in px");
32524
32605
  }
32525
32606
  function parseLineHeight(name, raw, source, guard, fontSizePx) {
32607
+ const normalized = raw.trim().toLowerCase();
32526
32608
  const unitless = parseUnitlessValue(raw);
32527
32609
  if (unitless !== null) {
32528
32610
  const base = fontSizePx === null ? 16 : fontSizePx;
32529
- return createKnown(name, raw, source, guard, unitless * base, 1 /* Unitless */, "estimated");
32611
+ return createKnown(name, normalized, source, guard, unitless * base, 1 /* Unitless */, 1 /* Estimated */);
32530
32612
  }
32531
32613
  const px = parseSignedPxValue(raw);
32532
- if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
32614
+ if (px !== null) return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
32533
32615
  return createUnknown(name, source, guard, "line-height is not statically parseable");
32534
32616
  }
32535
32617
  var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
@@ -32538,16 +32620,21 @@ var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
32538
32620
  "fit-content",
32539
32621
  "min-content",
32540
32622
  "max-content",
32541
- "stretch"
32623
+ "stretch",
32624
+ "inherit",
32625
+ "initial",
32626
+ "unset",
32627
+ "revert",
32628
+ "revert-layer"
32542
32629
  ]);
32543
32630
  function parseLength(name, raw, source, guard) {
32544
32631
  const px = parseSignedPxValue(raw);
32632
+ const normalized = raw.trim().toLowerCase();
32545
32633
  if (px !== null) {
32546
- return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
32634
+ return createKnown(name, normalized, source, guard, px, 0 /* Px */, 0 /* Exact */);
32547
32635
  }
32548
- const normalized = raw.trim().toLowerCase();
32549
32636
  if (DIMENSION_KEYWORD_SET.has(normalized) || normalized.startsWith("fit-content(")) {
32550
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
32637
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
32551
32638
  }
32552
32639
  return createUnknown(name, source, guard, "length is not statically parseable in px");
32553
32640
  }
@@ -32559,7 +32646,7 @@ function parseKeyword(name, raw, source, guard) {
32559
32646
  if (hasDynamicExpression(normalized)) {
32560
32647
  return createUnknown(name, source, guard, "keyword uses runtime-dependent function");
32561
32648
  }
32562
- return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
32649
+ return createKnown(name, normalized, source, guard, null, 2 /* Keyword */, 0 /* Exact */);
32563
32650
  }
32564
32651
  function parseTransform(name, raw, source, guard) {
32565
32652
  const normalized = raw.trim().toLowerCase();
@@ -32570,7 +32657,7 @@ function parseTransform(name, raw, source, guard) {
32570
32657
  return createUnknown(name, source, guard, "transform uses runtime-dependent function");
32571
32658
  }
32572
32659
  const y = extractTransformYPx(normalized);
32573
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
32660
+ if (y !== null) return createKnown(name, normalized, source, guard, y, 0 /* Px */, 0 /* Exact */);
32574
32661
  return createUnknown(name, source, guard, "transform has non-translational or non-px functions");
32575
32662
  }
32576
32663
  function parseTranslateProperty(name, raw, source, guard) {
@@ -32582,24 +32669,20 @@ function parseTranslateProperty(name, raw, source, guard) {
32582
32669
  return createUnknown(name, source, guard, "translate uses runtime-dependent function");
32583
32670
  }
32584
32671
  const y = extractTranslatePropertyYPx(trimmed);
32585
- if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
32672
+ if (y !== null) return createKnown(name, trimmed, source, guard, y, 0 /* Px */, 0 /* Exact */);
32586
32673
  return createUnknown(name, source, guard, "translate property vertical component is not px");
32587
32674
  }
32588
32675
  function hasDynamicExpression(raw) {
32589
32676
  if (raw.includes("var(")) return true;
32590
- if (raw.includes("calc(")) return true;
32591
32677
  if (raw.includes("env(")) return true;
32592
32678
  if (raw.includes("attr(")) return true;
32593
- if (raw.includes("min(")) return true;
32594
- if (raw.includes("max(")) return true;
32595
- if (raw.includes("clamp(")) return true;
32596
32679
  return false;
32597
32680
  }
32598
- function createKnown(name, raw, source, guard, px, unit, quality) {
32681
+ function createKnown(name, normalized, source, guard, px, unit, quality) {
32599
32682
  return {
32600
- kind: "known",
32683
+ kind: 0 /* Known */,
32601
32684
  name,
32602
- normalized: raw.trim().toLowerCase(),
32685
+ normalized,
32603
32686
  source,
32604
32687
  guard,
32605
32688
  unit,
@@ -32609,7 +32692,7 @@ function createKnown(name, raw, source, guard, px, unit, quality) {
32609
32692
  }
32610
32693
  function createUnknown(name, source, guard, reason) {
32611
32694
  return {
32612
- kind: "unknown",
32695
+ kind: 1 /* Unknown */,
32613
32696
  name,
32614
32697
  source,
32615
32698
  guard,
@@ -32618,9 +32701,6 @@ function createUnknown(name, source, guard, reason) {
32618
32701
  }
32619
32702
 
32620
32703
  // src/cross-file/layout/selector-match.ts
32621
- var ATTRIBUTE_EXISTS_RE2 = /^[-_a-zA-Z][-_a-zA-Z0-9]*$/;
32622
- var ATTRIBUTE_CONSTRAINT_RE2 = /^([-_a-zA-Z][-_a-zA-Z0-9]*)\s*(=|~=|\|=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?:\s+([iIsS]))?$/;
32623
- var MAX_PSEUDO_COMPILE_DEPTH = 4;
32624
32704
  var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
32625
32705
  "active",
32626
32706
  "checked",
@@ -32644,14 +32724,25 @@ var STATEFUL_PSEUDO_CLASSES = /* @__PURE__ */ new Set([
32644
32724
  "valid",
32645
32725
  "visited"
32646
32726
  ]);
32727
+ var EMPTY_PSEUDO = {
32728
+ firstChild: false,
32729
+ lastChild: false,
32730
+ onlyChild: false,
32731
+ nthChild: null,
32732
+ nthLastChild: null,
32733
+ nthOfType: null,
32734
+ nthLastOfType: null,
32735
+ anyOfGroups: [],
32736
+ noneOfGroups: []
32737
+ };
32647
32738
  function compileSelectorMatcher(selector) {
32648
- const parsed = parseSelectorPattern(selector.raw);
32649
- if (parsed === null) return null;
32739
+ const selectorCompounds = selector.compounds;
32740
+ if (selectorCompounds.length === 0) return null;
32650
32741
  const compoundsLeftToRight = [];
32651
- for (let i = 0; i < parsed.compounds.length; i++) {
32652
- const compoundRaw = parsed.compounds[i];
32653
- if (compoundRaw === void 0) continue;
32654
- const compiled = compileCompound(compoundRaw, 0);
32742
+ for (let i = 0; i < selectorCompounds.length; i++) {
32743
+ const sc = selectorCompounds[i];
32744
+ if (sc === void 0) continue;
32745
+ const compiled = buildCompiledCompound(sc);
32655
32746
  if (compiled === null) return null;
32656
32747
  compoundsLeftToRight.push(compiled);
32657
32748
  }
@@ -32668,9 +32759,125 @@ function compileSelectorMatcher(selector) {
32668
32759
  },
32669
32760
  requirements: resolveFeatureRequirements(compoundsLeftToRight),
32670
32761
  compoundsRightToLeft: compoundsLeftToRight.toReversed(),
32671
- combinatorsRightToLeft: parsed.combinators.toReversed()
32762
+ combinatorsRightToLeft: selector.combinators.toReversed()
32672
32763
  };
32673
32764
  }
32765
+ function buildCompiledCompound(sc) {
32766
+ const parts = sc.parts;
32767
+ for (let i = 0; i < parts.length; i++) {
32768
+ const part = parts[i];
32769
+ if (!part) continue;
32770
+ if (part.type === "pseudo-element") return null;
32771
+ }
32772
+ const pseudoConstraints = sc.pseudoClasses;
32773
+ if (pseudoConstraints.length === 0) {
32774
+ return {
32775
+ tagName: sc.tagName,
32776
+ idValue: sc.idValue,
32777
+ classes: sc.classes,
32778
+ attributes: sc.attributes,
32779
+ pseudo: EMPTY_PSEUDO
32780
+ };
32781
+ }
32782
+ let firstChild = false;
32783
+ let lastChild = false;
32784
+ let onlyChild = false;
32785
+ let nthChild = null;
32786
+ let nthLastChild = null;
32787
+ let nthOfType = null;
32788
+ let nthLastOfType = null;
32789
+ const anyOfGroups = [];
32790
+ const noneOfGroups = [];
32791
+ for (let i = 0; i < pseudoConstraints.length; i++) {
32792
+ const pc = pseudoConstraints[i];
32793
+ if (!pc) continue;
32794
+ if (pc.kind === 0 /* Simple */) {
32795
+ if (STATEFUL_PSEUDO_CLASSES.has(pc.name)) return null;
32796
+ continue;
32797
+ }
32798
+ if (pc.kind === 1 /* FirstChild */) {
32799
+ firstChild = true;
32800
+ continue;
32801
+ }
32802
+ if (pc.kind === 2 /* LastChild */) {
32803
+ lastChild = true;
32804
+ continue;
32805
+ }
32806
+ if (pc.kind === 3 /* OnlyChild */) {
32807
+ firstChild = true;
32808
+ lastChild = true;
32809
+ onlyChild = true;
32810
+ continue;
32811
+ }
32812
+ if (pc.kind === 4 /* NthChild */) {
32813
+ if (!pc.nthPattern) return null;
32814
+ nthChild = pc.nthPattern;
32815
+ continue;
32816
+ }
32817
+ if (pc.kind === 5 /* NthLastChild */) {
32818
+ if (!pc.nthPattern) return null;
32819
+ nthLastChild = pc.nthPattern;
32820
+ continue;
32821
+ }
32822
+ if (pc.kind === 6 /* NthOfType */) {
32823
+ if (!pc.nthPattern) return null;
32824
+ nthOfType = pc.nthPattern;
32825
+ continue;
32826
+ }
32827
+ if (pc.kind === 7 /* NthLastOfType */) {
32828
+ if (!pc.nthPattern) return null;
32829
+ nthLastOfType = pc.nthPattern;
32830
+ continue;
32831
+ }
32832
+ if (pc.kind === 8 /* MatchesAny */) {
32833
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
32834
+ const group = buildNestedGroup(pc.nestedCompounds);
32835
+ if (group === null) return null;
32836
+ if (group.length > 0) anyOfGroups.push(group);
32837
+ }
32838
+ continue;
32839
+ }
32840
+ if (pc.kind === 9 /* NoneOf */) {
32841
+ if (pc.nestedCompounds && pc.nestedCompounds.length > 0) {
32842
+ const group = buildNestedGroup(pc.nestedCompounds);
32843
+ if (group === null) return null;
32844
+ if (group.length > 0) noneOfGroups.push(group);
32845
+ }
32846
+ continue;
32847
+ }
32848
+ }
32849
+ return {
32850
+ tagName: sc.tagName,
32851
+ idValue: sc.idValue,
32852
+ classes: sc.classes,
32853
+ attributes: sc.attributes,
32854
+ pseudo: {
32855
+ firstChild,
32856
+ lastChild,
32857
+ onlyChild,
32858
+ nthChild,
32859
+ nthLastChild,
32860
+ nthOfType,
32861
+ nthLastOfType,
32862
+ anyOfGroups,
32863
+ noneOfGroups
32864
+ }
32865
+ };
32866
+ }
32867
+ function buildNestedGroup(nestedCompounds) {
32868
+ const out = [];
32869
+ for (let i = 0; i < nestedCompounds.length; i++) {
32870
+ const compoundGroup = nestedCompounds[i];
32871
+ if (!compoundGroup) continue;
32872
+ if (compoundGroup.length !== 1) continue;
32873
+ const sc = compoundGroup[0];
32874
+ if (!sc) continue;
32875
+ const compiled = buildCompiledCompound(sc);
32876
+ if (compiled === null) return null;
32877
+ out.push(compiled);
32878
+ }
32879
+ return out;
32880
+ }
32674
32881
  function collectSubjectAttributeNames(subject) {
32675
32882
  if (subject.attributes.length === 0) return [];
32676
32883
  const names = /* @__PURE__ */ new Set();
@@ -32746,42 +32953,42 @@ function compoundGroupNeedsAttributes(groups) {
32746
32953
  }
32747
32954
  return false;
32748
32955
  }
32749
- function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger) {
32956
+ function selectorMatchesLayoutElement(matcher, node, perf, fileRootElements = null, logger = noopLogger, fileElementIndex = null) {
32750
32957
  const firstCompound = matcher.compoundsRightToLeft[0];
32751
- if (firstCompound === void 0) return "no-match";
32958
+ if (firstCompound === void 0) return 1 /* NoMatch */;
32752
32959
  const subjectResult = matchesCompound(node, firstCompound);
32753
- if (subjectResult === "no-match") return "no-match";
32960
+ if (subjectResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32754
32961
  if (matcher.compoundsRightToLeft.length === 1) return subjectResult;
32755
- const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger);
32756
- if (chainResult === "no-match") return "no-match";
32757
- if (subjectResult === "conditional" || chainResult === "conditional") return "conditional";
32758
- return "match";
32962
+ const chainResult = matchesChain(matcher, node, 0, perf, fileRootElements, logger, fileElementIndex);
32963
+ if (chainResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32964
+ if (subjectResult === 2 /* Conditional */ || chainResult === 2 /* Conditional */) return 2 /* Conditional */;
32965
+ return 0 /* Match */;
32759
32966
  }
32760
- function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
32967
+ function matchesChain(matcher, node, index, perf, fileRootElements, logger, fileElementIndex = null) {
32761
32968
  const combinator = matcher.combinatorsRightToLeft[index];
32762
- if (combinator === void 0) return "no-match";
32969
+ if (combinator === void 0) return 1 /* NoMatch */;
32763
32970
  const nextIndex = index + 1;
32764
32971
  const targetCompound = matcher.compoundsRightToLeft[nextIndex];
32765
- if (targetCompound === void 0) return "no-match";
32972
+ if (targetCompound === void 0) return 1 /* NoMatch */;
32766
32973
  const isFinal = nextIndex === matcher.compoundsRightToLeft.length - 1;
32767
32974
  if (combinator === "child") {
32768
32975
  const parent = node.parentElementNode;
32769
- if (parent === null) return "no-match";
32976
+ if (parent === null) return 1 /* NoMatch */;
32770
32977
  perf.ancestryChecks++;
32771
32978
  const compoundResult = matchesCompound(parent, targetCompound);
32772
- if (compoundResult === "no-match") return "no-match";
32979
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32773
32980
  if (isFinal) return compoundResult;
32774
- const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger);
32981
+ const chainResult = matchesChain(matcher, parent, nextIndex, perf, fileRootElements, logger, fileElementIndex);
32775
32982
  return mergeMatchResults(compoundResult, chainResult);
32776
32983
  }
32777
32984
  if (combinator === "adjacent") {
32778
32985
  const sibling = node.previousSiblingNode;
32779
- if (sibling === null) return "no-match";
32986
+ if (sibling === null) return 1 /* NoMatch */;
32780
32987
  perf.ancestryChecks++;
32781
32988
  const compoundResult = matchesCompound(sibling, targetCompound);
32782
- if (compoundResult === "no-match") return "no-match";
32989
+ if (compoundResult === 1 /* NoMatch */) return 1 /* NoMatch */;
32783
32990
  if (isFinal) return compoundResult;
32784
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
32991
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
32785
32992
  return mergeMatchResults(compoundResult, chainResult);
32786
32993
  }
32787
32994
  if (combinator === "sibling") {
@@ -32789,26 +32996,26 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
32789
32996
  while (sibling !== null) {
32790
32997
  perf.ancestryChecks++;
32791
32998
  const compoundResult = matchesCompound(sibling, targetCompound);
32792
- if (compoundResult !== "no-match") {
32999
+ if (compoundResult !== 1 /* NoMatch */) {
32793
33000
  if (isFinal) return compoundResult;
32794
- const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger);
32795
- if (chainResult !== "no-match") return mergeMatchResults(compoundResult, chainResult);
33001
+ const chainResult = matchesChain(matcher, sibling, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33002
+ if (chainResult !== 1 /* NoMatch */) return mergeMatchResults(compoundResult, chainResult);
32796
33003
  }
32797
33004
  sibling = sibling.previousSiblingNode;
32798
33005
  }
32799
- return "no-match";
33006
+ return 1 /* NoMatch */;
32800
33007
  }
32801
- let bestResult = "no-match";
33008
+ let bestResult = 1 /* NoMatch */;
32802
33009
  let ancestor = node.parentElementNode;
32803
33010
  while (ancestor !== null) {
32804
33011
  perf.ancestryChecks++;
32805
33012
  const compoundResult = matchesCompound(ancestor, targetCompound);
32806
- if (compoundResult !== "no-match") {
33013
+ if (compoundResult !== 1 /* NoMatch */) {
32807
33014
  if (isFinal) return compoundResult;
32808
- const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger);
32809
- if (chainResult !== "no-match") {
33015
+ const chainResult = matchesChain(matcher, ancestor, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33016
+ if (chainResult !== 1 /* NoMatch */) {
32810
33017
  const merged = mergeMatchResults(compoundResult, chainResult);
32811
- if (merged === "match") return "match";
33018
+ if (merged === 0 /* Match */) return 0 /* Match */;
32812
33019
  bestResult = merged;
32813
33020
  }
32814
33021
  }
@@ -32826,30 +33033,50 @@ function matchesChain(matcher, node, index, perf, fileRootElements, logger) {
32826
33033
  if (root.solidFile !== node.solidFile) continue;
32827
33034
  perf.ancestryChecks++;
32828
33035
  const compoundResult = matchesCompound(root, targetCompound);
32829
- if (logger.isLevelEnabled(Level.Trace) && compoundResult === "no-match") {
33036
+ if (logger.isLevelEnabled(Level.Trace) && compoundResult === 1 /* NoMatch */) {
32830
33037
  logger.trace(`[selector-match] fallback MISS: root=${root.key} tag=${root.tagName} attrs=[${[...root.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}]`);
32831
33038
  }
32832
- if (compoundResult !== "no-match") {
33039
+ if (compoundResult !== 1 /* NoMatch */) {
32833
33040
  if (logger.isLevelEnabled(Level.Debug)) {
32834
33041
  const compoundDesc = describeCompound(targetCompound);
32835
33042
  logger.debug(`[selector-match] fallback HIT: node=${node.key} tag=${node.tagName} matched root=${root.key} tag=${root.tagName} compound=${compoundDesc} isFinal=${isFinal}`);
32836
33043
  }
32837
33044
  if (isFinal) return compoundResult;
32838
- const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger);
32839
- if (chainResult !== "no-match") {
33045
+ const chainResult = matchesChain(matcher, root, nextIndex, perf, fileRootElements, logger, fileElementIndex);
33046
+ if (chainResult !== 1 /* NoMatch */) {
32840
33047
  const merged = mergeMatchResults(compoundResult, chainResult);
32841
- if (merged === "match") return "match";
33048
+ if (merged === 0 /* Match */) return 0 /* Match */;
32842
33049
  bestResult = merged;
32843
33050
  }
32844
33051
  }
32845
33052
  }
32846
33053
  }
33054
+ if (fileElementIndex !== null && bestResult === 1 /* NoMatch */) {
33055
+ const candidates = resolveCompoundCandidates(fileElementIndex, targetCompound);
33056
+ if (candidates !== null) {
33057
+ for (let r = 0; r < candidates.length; r++) {
33058
+ const elem = candidates[r];
33059
+ if (elem === void 0) continue;
33060
+ if (elem === node) continue;
33061
+ perf.ancestryChecks++;
33062
+ const compoundResult = matchesCompound(elem, targetCompound);
33063
+ if (compoundResult !== 1 /* NoMatch */) {
33064
+ if (logger.isLevelEnabled(Level.Debug)) {
33065
+ const compoundDesc = describeCompound(targetCompound);
33066
+ logger.debug(`[selector-match] indexed fallback HIT: node=${node.key} tag=${node.tagName} matched elem=${elem.key} tag=${elem.tagName} compound=${compoundDesc}`);
33067
+ }
33068
+ bestResult = 2 /* Conditional */;
33069
+ break;
33070
+ }
33071
+ }
33072
+ }
33073
+ }
32847
33074
  return bestResult;
32848
33075
  }
32849
33076
  function mergeMatchResults(a, b) {
32850
- if (a === "no-match" || b === "no-match") return "no-match";
32851
- if (a === "conditional" || b === "conditional") return "conditional";
32852
- return "match";
33077
+ if (a === 1 /* NoMatch */ || b === 1 /* NoMatch */) return 1 /* NoMatch */;
33078
+ if (a === 2 /* Conditional */ || b === 2 /* Conditional */) return 2 /* Conditional */;
33079
+ return 0 /* Match */;
32853
33080
  }
32854
33081
  function describeCompound(compound) {
32855
33082
  const parts = [];
@@ -32868,16 +33095,31 @@ function describeCompound(compound) {
32868
33095
  if (compound.idValue !== null) parts.push(`#${compound.idValue}`);
32869
33096
  return parts.join("") || "*";
32870
33097
  }
33098
+ function resolveCompoundCandidates(index, compound) {
33099
+ if (compound.idValue !== null) {
33100
+ return index.byDispatchKey.get(`id:${compound.idValue}`) ?? null;
33101
+ }
33102
+ if (compound.classes.length > 0 && compound.classes[0] !== void 0) {
33103
+ return index.byDispatchKey.get(`class:${compound.classes[0]}`) ?? null;
33104
+ }
33105
+ if (compound.attributes.length > 0 && compound.attributes[0] !== void 0) {
33106
+ return index.byDispatchKey.get(`attr:${compound.attributes[0].name}`) ?? null;
33107
+ }
33108
+ if (compound.tagName !== null) {
33109
+ return index.byTagName.get(compound.tagName) ?? null;
33110
+ }
33111
+ return null;
33112
+ }
32871
33113
  function matchesCompound(node, compound) {
32872
- if (compound.tagName !== null && node.tagName !== compound.tagName) return "no-match";
33114
+ if (compound.tagName !== null && node.tagName !== compound.tagName) return 1 /* NoMatch */;
32873
33115
  if (compound.idValue !== null) {
32874
33116
  const id = node.attributes.get("id");
32875
- if (id !== compound.idValue) return "no-match";
33117
+ if (id !== compound.idValue) return 1 /* NoMatch */;
32876
33118
  }
32877
- if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return "no-match";
33119
+ if (!matchesRequiredClasses(compound.classes, node.classTokenSet)) return 1 /* NoMatch */;
32878
33120
  const attrResult = matchesRequiredAttributes(compound.attributes, node.attributes);
32879
- if (attrResult === "no-match") return "no-match";
32880
- if (!matchesPseudoConstraints(node, compound.pseudo)) return "no-match";
33121
+ if (attrResult === 1 /* NoMatch */) return 1 /* NoMatch */;
33122
+ if (!matchesPseudoConstraints(node, compound.pseudo)) return 1 /* NoMatch */;
32881
33123
  return attrResult;
32882
33124
  }
32883
33125
  function matchesPseudoConstraints(node, pseudo) {
@@ -32903,7 +33145,7 @@ function matchesPseudoConstraints(node, pseudo) {
32903
33145
  for (let j = 0; j < group.length; j++) {
32904
33146
  const compound = group[j];
32905
33147
  if (compound === void 0) continue;
32906
- if (matchesCompound(node, compound) === "no-match") continue;
33148
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
32907
33149
  matched = true;
32908
33150
  break;
32909
33151
  }
@@ -32915,607 +33157,12 @@ function matchesPseudoConstraints(node, pseudo) {
32915
33157
  for (let j = 0; j < group.length; j++) {
32916
33158
  const compound = group[j];
32917
33159
  if (compound === void 0) continue;
32918
- if (matchesCompound(node, compound) === "no-match") continue;
33160
+ if (matchesCompound(node, compound) === 1 /* NoMatch */) continue;
32919
33161
  return false;
32920
33162
  }
32921
33163
  }
32922
33164
  return true;
32923
33165
  }
32924
- function parseSelectorPattern(raw) {
32925
- const compounds = [];
32926
- const combinators = [];
32927
- const length = raw.length;
32928
- let start = 0;
32929
- let bracketDepth = 0;
32930
- let parenDepth = 0;
32931
- let i = 0;
32932
- while (i < length) {
32933
- const code = raw.charCodeAt(i);
32934
- if (code === CHAR_OPEN_BRACKET) {
32935
- bracketDepth++;
32936
- i++;
32937
- continue;
32938
- }
32939
- if (code === CHAR_CLOSE_BRACKET) {
32940
- if (bracketDepth > 0) bracketDepth--;
32941
- i++;
32942
- continue;
32943
- }
32944
- if (code === CHAR_OPEN_PAREN) {
32945
- parenDepth++;
32946
- i++;
32947
- continue;
32948
- }
32949
- if (code === CHAR_CLOSE_PAREN) {
32950
- if (parenDepth > 0) parenDepth--;
32951
- i++;
32952
- continue;
32953
- }
32954
- if (bracketDepth === 0 && parenDepth === 0) {
32955
- if (code === CHAR_GT || code === CHAR_PLUS || code === CHAR_TILDE) {
32956
- const compound = raw.slice(start, i).trim();
32957
- if (compound.length === 0) return null;
32958
- compounds.push(compound);
32959
- combinators.push(combinatorFromCode(code));
32960
- i++;
32961
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
32962
- start = i;
32963
- continue;
32964
- }
32965
- if (isWhitespace(code)) {
32966
- const compound = raw.slice(start, i).trim();
32967
- if (compound.length > 0) compounds.push(compound);
32968
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
32969
- if (i >= length) break;
32970
- const next = raw.charCodeAt(i);
32971
- if (next === CHAR_GT || next === CHAR_PLUS || next === CHAR_TILDE) {
32972
- if (compound.length === 0) return null;
32973
- combinators.push(combinatorFromCode(next));
32974
- i++;
32975
- while (i < length && isWhitespace(raw.charCodeAt(i))) i++;
32976
- start = i;
32977
- continue;
32978
- }
32979
- if (compound.length > 0) combinators.push("descendant");
32980
- start = i;
32981
- continue;
32982
- }
32983
- }
32984
- i++;
32985
- }
32986
- const trailing = raw.slice(start).trim();
32987
- if (trailing.length > 0) compounds.push(trailing);
32988
- if (compounds.length === 0) return null;
32989
- if (combinators.length !== compounds.length - 1) return null;
32990
- return { compounds, combinators };
32991
- }
32992
- function combinatorFromCode(code) {
32993
- if (code === CHAR_GT) return "child";
32994
- if (code === CHAR_PLUS) return "adjacent";
32995
- return "sibling";
32996
- }
32997
- function compileCompound(raw, depth) {
32998
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
32999
- const parts = parseCompoundParts(raw);
33000
- if (parts.length === 0) return null;
33001
- let tagName = null;
33002
- let idValue = null;
33003
- const classes = [];
33004
- const seenClasses = /* @__PURE__ */ new Set();
33005
- const attributes = [];
33006
- let firstChild = false;
33007
- let lastChild = false;
33008
- let onlyChild = false;
33009
- let nthChild = null;
33010
- let nthLastChild = null;
33011
- let nthOfType = null;
33012
- let nthLastOfType = null;
33013
- const anyOfGroups = [];
33014
- const noneOfGroups = [];
33015
- for (let i = 0; i < parts.length; i++) {
33016
- const part = parts[i];
33017
- if (part === void 0) continue;
33018
- if (part.type === "element") {
33019
- tagName = part.value.toLowerCase();
33020
- continue;
33021
- }
33022
- if (part.type === "universal") continue;
33023
- if (part.type === "id") {
33024
- idValue = part.value;
33025
- continue;
33026
- }
33027
- if (part.type === "class") {
33028
- if (seenClasses.has(part.value)) continue;
33029
- seenClasses.add(part.value);
33030
- classes.push(part.value);
33031
- continue;
33032
- }
33033
- if (part.type === "attribute") {
33034
- const attribute = parseAttributeConstraint(part.value);
33035
- if (attribute === null) return null;
33036
- attributes.push(attribute);
33037
- continue;
33038
- }
33039
- if (part.type === "pseudo-class") {
33040
- const pseudo = parsePseudoConstraint(part.raw, depth);
33041
- if (pseudo === null) return null;
33042
- if (pseudo.kind === "first-child") {
33043
- firstChild = true;
33044
- continue;
33045
- }
33046
- if (pseudo.kind === "last-child") {
33047
- lastChild = true;
33048
- continue;
33049
- }
33050
- if (pseudo.kind === "only-child") {
33051
- firstChild = true;
33052
- lastChild = true;
33053
- onlyChild = true;
33054
- continue;
33055
- }
33056
- if (pseudo.kind === "nth-child") {
33057
- if (nthChild !== null && !isSameNthPattern(nthChild, pseudo.value)) return null;
33058
- nthChild = pseudo.value;
33059
- continue;
33060
- }
33061
- if (pseudo.kind === "nth-last-child") {
33062
- if (nthLastChild !== null && !isSameNthPattern(nthLastChild, pseudo.value)) return null;
33063
- nthLastChild = pseudo.value;
33064
- continue;
33065
- }
33066
- if (pseudo.kind === "nth-of-type") {
33067
- if (nthOfType !== null && !isSameNthPattern(nthOfType, pseudo.value)) return null;
33068
- nthOfType = pseudo.value;
33069
- continue;
33070
- }
33071
- if (pseudo.kind === "nth-last-of-type") {
33072
- if (nthLastOfType !== null && !isSameNthPattern(nthLastOfType, pseudo.value)) return null;
33073
- nthLastOfType = pseudo.value;
33074
- continue;
33075
- }
33076
- if (pseudo.kind === "ignore") continue;
33077
- if (pseudo.kind === "matches-any") {
33078
- anyOfGroups.push(pseudo.selectors);
33079
- continue;
33080
- }
33081
- noneOfGroups.push(pseudo.selectors);
33082
- continue;
33083
- }
33084
- return null;
33085
- }
33086
- if (firstChild && nthChild !== null && !matchesNthPattern(1, nthChild)) return null;
33087
- if (lastChild && nthLastChild !== null && !matchesNthPattern(1, nthLastChild)) return null;
33088
- return {
33089
- tagName,
33090
- idValue,
33091
- classes,
33092
- attributes,
33093
- pseudo: {
33094
- firstChild,
33095
- lastChild,
33096
- onlyChild,
33097
- nthChild,
33098
- nthLastChild,
33099
- nthOfType,
33100
- nthLastOfType,
33101
- anyOfGroups,
33102
- noneOfGroups
33103
- }
33104
- };
33105
- }
33106
- function parseAttributeConstraint(raw) {
33107
- const trimmed = raw.trim();
33108
- const constrained = ATTRIBUTE_CONSTRAINT_RE2.exec(trimmed);
33109
- if (constrained) {
33110
- const operatorToken = constrained[2];
33111
- if (operatorToken === void 0) return null;
33112
- const operator = mapAttributeOperatorFromToken2(operatorToken);
33113
- if (operator === null) return null;
33114
- const value2 = constrained[3] ?? constrained[4] ?? constrained[5] ?? null;
33115
- if (value2 === null) return null;
33116
- const nameToken = constrained[1];
33117
- if (nameToken === void 0) return null;
33118
- return {
33119
- name: nameToken.toLowerCase(),
33120
- operator,
33121
- value: value2,
33122
- caseInsensitive: (constrained[6] ?? "").toLowerCase() === "i"
33123
- };
33124
- }
33125
- if (!ATTRIBUTE_EXISTS_RE2.test(trimmed)) return null;
33126
- return {
33127
- name: trimmed.toLowerCase(),
33128
- operator: "exists",
33129
- value: null,
33130
- caseInsensitive: false
33131
- };
33132
- }
33133
- function mapAttributeOperatorFromToken2(operator) {
33134
- if (operator === "=") return "equals";
33135
- if (operator === "~=") return "includes-word";
33136
- if (operator === "|=") return "dash-prefix";
33137
- if (operator === "^=") return "prefix";
33138
- if (operator === "$=") return "suffix";
33139
- if (operator === "*=") return "contains";
33140
- return null;
33141
- }
33142
- function parsePseudoConstraint(raw, depth) {
33143
- const trimmed = raw.trim();
33144
- const normalized = trimmed.toLowerCase();
33145
- if (normalized === ":first-child") return { kind: "first-child" };
33146
- if (normalized === ":last-child") return { kind: "last-child" };
33147
- if (normalized === ":only-child") return { kind: "only-child" };
33148
- const nthChild = parseNthPseudoArgument(trimmed, "nth-child");
33149
- if (nthChild !== void 0) {
33150
- if (nthChild === null) return null;
33151
- return { kind: "nth-child", value: nthChild };
33152
- }
33153
- const nthLastChild = parseNthPseudoArgument(trimmed, "nth-last-child");
33154
- if (nthLastChild !== void 0) {
33155
- if (nthLastChild === null) return null;
33156
- return { kind: "nth-last-child", value: nthLastChild };
33157
- }
33158
- const nthOfType = parseNthPseudoArgument(trimmed, "nth-of-type");
33159
- if (nthOfType !== void 0) {
33160
- if (nthOfType === null) return null;
33161
- return { kind: "nth-of-type", value: nthOfType };
33162
- }
33163
- const nthLastOfType = parseNthPseudoArgument(trimmed, "nth-last-of-type");
33164
- if (nthLastOfType !== void 0) {
33165
- if (nthLastOfType === null) return null;
33166
- return { kind: "nth-last-of-type", value: nthLastOfType };
33167
- }
33168
- const name = readPseudoName(normalized);
33169
- if (name === null) return null;
33170
- if (STATEFUL_PSEUDO_CLASSES.has(name)) return null;
33171
- if (name !== "is" && name !== "where" && name !== "not") {
33172
- return { kind: "ignore" };
33173
- }
33174
- const content = extractFunctionalPseudoContent(trimmed, name);
33175
- if (content === null) return null;
33176
- const selectors = compileFunctionalPseudoArguments(content, depth + 1);
33177
- if (selectors === null || selectors.length === 0) return null;
33178
- if (name === "not") {
33179
- return {
33180
- kind: "matches-none",
33181
- selectors
33182
- };
33183
- }
33184
- return {
33185
- kind: "matches-any",
33186
- selectors
33187
- };
33188
- }
33189
- function parseNthPseudoArgument(raw, name) {
33190
- const content = extractFunctionalPseudoContent(raw, name);
33191
- if (content === null) return void 0;
33192
- return parseNthPattern(content);
33193
- }
33194
- function parseNthPattern(raw) {
33195
- const normalized = raw.trim().toLowerCase().replaceAll(" ", "");
33196
- if (normalized.length === 0) return null;
33197
- if (normalized === "odd") {
33198
- return { step: 2, offset: 1 };
33199
- }
33200
- if (normalized === "even") {
33201
- return { step: 2, offset: 0 };
33202
- }
33203
- const nIndex = normalized.indexOf("n");
33204
- if (nIndex === -1) {
33205
- const value2 = Number.parseInt(normalized, 10);
33206
- if (Number.isNaN(value2)) return null;
33207
- return { step: 0, offset: value2 };
33208
- }
33209
- const stepPart = normalized.slice(0, nIndex);
33210
- const offsetPart = normalized.slice(nIndex + 1);
33211
- let step;
33212
- if (stepPart.length === 0 || stepPart === "+") {
33213
- step = 1;
33214
- } else if (stepPart === "-") {
33215
- step = -1;
33216
- } else {
33217
- step = Number.parseInt(stepPart, 10);
33218
- if (Number.isNaN(step)) return null;
33219
- }
33220
- let offset = 0;
33221
- if (offsetPart.length > 0) {
33222
- offset = Number.parseInt(offsetPart, 10);
33223
- if (Number.isNaN(offset)) return null;
33224
- }
33225
- return {
33226
- step,
33227
- offset
33228
- };
33229
- }
33230
- function extractFunctionalPseudoContent(raw, name) {
33231
- const prefix = `:${name}(`;
33232
- if (!raw.toLowerCase().startsWith(prefix)) return null;
33233
- if (!raw.endsWith(")")) return null;
33234
- return raw.slice(prefix.length, -1);
33235
- }
33236
- function compileFunctionalPseudoArguments(content, depth) {
33237
- if (depth > MAX_PSEUDO_COMPILE_DEPTH) return null;
33238
- const args = splitTopLevelSelectorArguments(content);
33239
- if (args.length === 0) return null;
33240
- const out = [];
33241
- for (let i = 0; i < args.length; i++) {
33242
- const arg = args[i];
33243
- if (arg === void 0) return null;
33244
- const raw = arg.trim();
33245
- if (raw.length === 0) return null;
33246
- const parsed = parseSelectorPattern(raw);
33247
- if (parsed === null) return null;
33248
- if (parsed.combinators.length !== 0) return null;
33249
- if (parsed.compounds.length !== 1) return null;
33250
- const compoundRaw = parsed.compounds[0];
33251
- if (compoundRaw === void 0) return null;
33252
- const compiled = compileCompound(compoundRaw, depth);
33253
- if (compiled === null) return null;
33254
- out.push(compiled);
33255
- }
33256
- return out;
33257
- }
33258
- function splitTopLevelSelectorArguments(content) {
33259
- const out = [];
33260
- let start = 0;
33261
- let parenDepth = 0;
33262
- let bracketDepth = 0;
33263
- let quote = null;
33264
- for (let i = 0; i < content.length; i++) {
33265
- const code = content.charCodeAt(i);
33266
- if (quote !== null) {
33267
- if (code === quote) quote = null;
33268
- continue;
33269
- }
33270
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33271
- quote = code;
33272
- continue;
33273
- }
33274
- if (code === CHAR_OPEN_PAREN) {
33275
- parenDepth++;
33276
- continue;
33277
- }
33278
- if (code === CHAR_CLOSE_PAREN) {
33279
- if (parenDepth > 0) parenDepth--;
33280
- continue;
33281
- }
33282
- if (code === CHAR_OPEN_BRACKET) {
33283
- bracketDepth++;
33284
- continue;
33285
- }
33286
- if (code === CHAR_CLOSE_BRACKET) {
33287
- if (bracketDepth > 0) bracketDepth--;
33288
- continue;
33289
- }
33290
- if (code !== CHAR_COMMA) continue;
33291
- if (parenDepth !== 0) continue;
33292
- if (bracketDepth !== 0) continue;
33293
- out.push(content.slice(start, i));
33294
- start = i + 1;
33295
- }
33296
- out.push(content.slice(start));
33297
- return out;
33298
- }
33299
- function parseCompoundParts(raw) {
33300
- const trimmed = raw.trim();
33301
- if (trimmed.length === 0) return [];
33302
- const out = [];
33303
- const length = trimmed.length;
33304
- let i = 0;
33305
- let allowsElement = true;
33306
- while (i < length) {
33307
- const code = trimmed.charCodeAt(i);
33308
- if (code === CHAR_OPEN_BRACKET) {
33309
- const end = readBracketed(trimmed, i);
33310
- if (end === null) return [];
33311
- const inner = trimmed.slice(i + 1, end - 1);
33312
- out.push({
33313
- type: "attribute",
33314
- value: inner,
33315
- raw: trimmed.slice(i, end)
33316
- });
33317
- i = end;
33318
- allowsElement = false;
33319
- continue;
33320
- }
33321
- if (code === 35) {
33322
- const ident2 = readIdentifier(trimmed, i + 1);
33323
- if (ident2.consumed === 0) return [];
33324
- out.push({
33325
- type: "id",
33326
- value: ident2.value,
33327
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
33328
- });
33329
- i += 1 + ident2.consumed;
33330
- allowsElement = false;
33331
- continue;
33332
- }
33333
- if (code === 46) {
33334
- const ident2 = readIdentifier(trimmed, i + 1);
33335
- if (ident2.consumed === 0) return [];
33336
- out.push({
33337
- type: "class",
33338
- value: ident2.value,
33339
- raw: trimmed.slice(i, i + 1 + ident2.consumed)
33340
- });
33341
- i += 1 + ident2.consumed;
33342
- allowsElement = false;
33343
- continue;
33344
- }
33345
- if (code === 58) {
33346
- const pseudo = readPseudo(trimmed, i);
33347
- if (pseudo === null) return [];
33348
- out.push(pseudo);
33349
- i += pseudo.raw.length;
33350
- allowsElement = false;
33351
- continue;
33352
- }
33353
- if (code === 42) {
33354
- out.push({
33355
- type: "universal",
33356
- value: "*",
33357
- raw: "*"
33358
- });
33359
- i++;
33360
- allowsElement = false;
33361
- continue;
33362
- }
33363
- if (!allowsElement) return [];
33364
- const ident = readIdentifier(trimmed, i);
33365
- if (ident.consumed === 0) return [];
33366
- out.push({
33367
- type: "element",
33368
- value: ident.value,
33369
- raw: trimmed.slice(i, i + ident.consumed)
33370
- });
33371
- i += ident.consumed;
33372
- allowsElement = false;
33373
- }
33374
- return out;
33375
- }
33376
- function readPseudo(input, start) {
33377
- const second = input.charCodeAt(start + 1);
33378
- if (second === 58) return null;
33379
- let i = start + 1;
33380
- while (i < input.length) {
33381
- const code = input.charCodeAt(i);
33382
- if (!isIdentChar(code)) break;
33383
- i++;
33384
- }
33385
- if (i === start + 1) return null;
33386
- const value2 = input.slice(start + 1, i);
33387
- if (input.charCodeAt(i) !== CHAR_OPEN_PAREN) {
33388
- return {
33389
- type: "pseudo-class",
33390
- value: value2,
33391
- raw: input.slice(start, i)
33392
- };
33393
- }
33394
- const end = readParenthesized(input, i);
33395
- if (end === null) return null;
33396
- return {
33397
- type: "pseudo-class",
33398
- value: value2,
33399
- raw: input.slice(start, end)
33400
- };
33401
- }
33402
- function readBracketed(input, start) {
33403
- let quote = null;
33404
- let depth = 0;
33405
- for (let i = start; i < input.length; i++) {
33406
- const code = input.charCodeAt(i);
33407
- if (quote !== null) {
33408
- if (code === quote) quote = null;
33409
- continue;
33410
- }
33411
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33412
- quote = code;
33413
- continue;
33414
- }
33415
- if (code === CHAR_OPEN_BRACKET) {
33416
- depth++;
33417
- continue;
33418
- }
33419
- if (code !== CHAR_CLOSE_BRACKET) continue;
33420
- depth--;
33421
- if (depth === 0) return i + 1;
33422
- if (depth < 0) return null;
33423
- }
33424
- return null;
33425
- }
33426
- function readParenthesized(input, start) {
33427
- let quote = null;
33428
- let depth = 0;
33429
- for (let i = start; i < input.length; i++) {
33430
- const code = input.charCodeAt(i);
33431
- if (quote !== null) {
33432
- if (code === quote) quote = null;
33433
- continue;
33434
- }
33435
- if (code === CHAR_SINGLE_QUOTE || code === CHAR_DOUBLE_QUOTE) {
33436
- quote = code;
33437
- continue;
33438
- }
33439
- if (code === CHAR_OPEN_PAREN) {
33440
- depth++;
33441
- continue;
33442
- }
33443
- if (code !== CHAR_CLOSE_PAREN) continue;
33444
- depth--;
33445
- if (depth === 0) return i + 1;
33446
- if (depth < 0) return null;
33447
- }
33448
- return null;
33449
- }
33450
- var EMPTY_IDENTIFIER = { value: "", consumed: 0 };
33451
- function readIdentifier(input, start) {
33452
- const length = input.length;
33453
- let i = start;
33454
- let hasEscape = false;
33455
- while (i < length) {
33456
- const code = input.charCodeAt(i);
33457
- if (code === CHAR_BACKSLASH) {
33458
- if (i + 1 >= length) break;
33459
- hasEscape = true;
33460
- i = skipCssEscapeSequence(input, i + 1);
33461
- continue;
33462
- }
33463
- if (!isIdentChar(code)) break;
33464
- i++;
33465
- }
33466
- const consumed = i - start;
33467
- if (consumed === 0) return EMPTY_IDENTIFIER;
33468
- if (!hasEscape) {
33469
- const value2 = input.slice(start, i);
33470
- return { value: value2, consumed };
33471
- }
33472
- return { value: decodeCssEscapes(input, start, i), consumed };
33473
- }
33474
- var CHAR_BACKSLASH = 92;
33475
- function skipCssEscapeSequence(input, afterBackslash) {
33476
- const length = input.length;
33477
- if (afterBackslash >= length) return afterBackslash;
33478
- const first = input.charCodeAt(afterBackslash);
33479
- if (!isHexDigit(first)) return afterBackslash + 1;
33480
- let end = afterBackslash + 1;
33481
- const maxHex = Math.min(afterBackslash + 6, length);
33482
- while (end < maxHex && isHexDigit(input.charCodeAt(end))) end++;
33483
- if (end < length && isWhitespace(input.charCodeAt(end))) end++;
33484
- return end;
33485
- }
33486
- function decodeCssEscapes(input, start, end) {
33487
- const parts = [];
33488
- let i = start;
33489
- while (i < end) {
33490
- const code = input.charCodeAt(i);
33491
- if (code !== CHAR_BACKSLASH) {
33492
- parts.push(String.fromCharCode(code));
33493
- i++;
33494
- continue;
33495
- }
33496
- i++;
33497
- if (i >= end) break;
33498
- const first = input.charCodeAt(i);
33499
- if (!isHexDigit(first)) {
33500
- parts.push(String.fromCharCode(first));
33501
- i++;
33502
- continue;
33503
- }
33504
- const hexStart = i;
33505
- const maxHex = Math.min(i + 6, end);
33506
- while (i < maxHex && isHexDigit(input.charCodeAt(i))) i++;
33507
- const codePoint = Number.parseInt(input.slice(hexStart, i), 16);
33508
- if (codePoint > 0 && codePoint <= 1114111) {
33509
- parts.push(String.fromCodePoint(codePoint));
33510
- }
33511
- if (i < end && isWhitespace(input.charCodeAt(i))) i++;
33512
- }
33513
- return parts.join("");
33514
- }
33515
- function isSameNthPattern(left, right) {
33516
- if (left.step !== right.step) return false;
33517
- return left.offset === right.offset;
33518
- }
33519
33166
  function matchesNthPattern(index, pattern) {
33520
33167
  if (index < 1) return false;
33521
33168
  const step = pattern.step;
@@ -33534,20 +33181,6 @@ function matchesNthPattern(index, pattern) {
33534
33181
  if (delta < 0) return false;
33535
33182
  return delta % positiveStep === 0;
33536
33183
  }
33537
- function readPseudoName(raw) {
33538
- if (!raw.startsWith(":")) return null;
33539
- let index = 1;
33540
- while (index < raw.length) {
33541
- const code = raw.charCodeAt(index);
33542
- const isUpper = code >= 65 && code <= 90;
33543
- const isLower = code >= 97 && code <= 122;
33544
- const isDash = code === 45;
33545
- if (!isUpper && !isLower && !isDash) break;
33546
- index++;
33547
- }
33548
- if (index <= 1) return null;
33549
- return raw.slice(1, index);
33550
- }
33551
33184
  function matchesRequiredClasses(required, actual) {
33552
33185
  if (required.length === 0) return true;
33553
33186
  if (actual.size === 0) return false;
@@ -33560,24 +33193,24 @@ function matchesRequiredClasses(required, actual) {
33560
33193
  return true;
33561
33194
  }
33562
33195
  function matchesRequiredAttributes(required, actual) {
33563
- if (required.length === 0) return "match";
33196
+ if (required.length === 0) return 0 /* Match */;
33564
33197
  let hasConditional = false;
33565
33198
  for (let i = 0; i < required.length; i++) {
33566
33199
  const constraint = required[i];
33567
33200
  if (constraint === void 0) continue;
33568
- if (!actual.has(constraint.name)) return "no-match";
33201
+ if (!actual.has(constraint.name)) return 1 /* NoMatch */;
33569
33202
  if (constraint.operator === "exists") continue;
33570
33203
  const actualValue = actual.get(constraint.name);
33571
- if (actualValue === void 0) return "no-match";
33204
+ if (actualValue === void 0) return 1 /* NoMatch */;
33572
33205
  if (actualValue === null) {
33573
33206
  hasConditional = true;
33574
33207
  continue;
33575
33208
  }
33576
- if (constraint.value === null) return "no-match";
33209
+ if (constraint.value === null) return 1 /* NoMatch */;
33577
33210
  if (matchesAttributeValue(actualValue, constraint)) continue;
33578
- return "no-match";
33211
+ return 1 /* NoMatch */;
33579
33212
  }
33580
- return hasConditional ? "conditional" : "match";
33213
+ return hasConditional ? 2 /* Conditional */ : 0 /* Match */;
33581
33214
  }
33582
33215
  function matchesAttributeValue(actualValue, constraint) {
33583
33216
  const expectedValue = constraint.value;
@@ -33695,49 +33328,23 @@ var INHERITED_SIGNAL_NAMES = [
33695
33328
  "direction"
33696
33329
  ];
33697
33330
  function collectSignalSnapshot(context, node) {
33698
- const existing = context.layout.snapshotByElementNode.get(node);
33699
- if (existing) {
33331
+ const record = context.layout.records.get(node);
33332
+ if (record) {
33700
33333
  context.layout.perf.signalSnapshotCacheHits++;
33701
- return existing;
33702
- }
33703
- throw new Error(`missing precomputed layout snapshot for ${node.key}`);
33704
- }
33705
- function buildSignalSnapshotIndex(elements, cascadeByElementNode, perf) {
33706
- const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
33707
- for (let i = 0; i < elements.length; i++) {
33708
- const element = elements[i];
33709
- if (!element) continue;
33710
- buildSnapshotForNode(element, cascadeByElementNode, snapshotByElementNode, perf);
33334
+ return record.snapshot;
33711
33335
  }
33712
- return snapshotByElementNode;
33336
+ throw new Error(`missing precomputed layout record for ${node.key}`);
33713
33337
  }
33714
- function buildSnapshotForNode(node, cascadeByElementNode, snapshotByElementNode, perf) {
33715
- const existing = snapshotByElementNode.get(node);
33716
- if (existing) {
33717
- perf.signalSnapshotCacheHits++;
33718
- return existing;
33719
- }
33720
- const raw = cascadeByElementNode.get(node);
33721
- if (!raw) {
33722
- throw new Error(`missing cascade map for ${node.key}`);
33723
- }
33724
- const normalized = normalizeSignalMapWithCounts(raw);
33725
- const parent = node.parentElementNode;
33726
- const parentSnapshot = parent ? buildSnapshotForNode(parent, cascadeByElementNode, snapshotByElementNode, perf) : null;
33338
+ function buildSnapshotFromCascade(node, cascade, parentSnapshot) {
33339
+ const normalized = normalizeSignalMapWithCounts(cascade);
33727
33340
  const inherited = inheritSignalsFromParent(parentSnapshot, normalized.signals);
33728
- const knownSignalCount = normalized.knownSignalCount + inherited.knownDelta;
33729
- const unknownSignalCount = normalized.unknownSignalCount + inherited.unknownDelta;
33730
- const conditionalSignalCount = normalized.conditionalSignalCount + inherited.conditionalDelta;
33731
- const snapshot = {
33341
+ return {
33732
33342
  node,
33733
33343
  signals: inherited.signals,
33734
- knownSignalCount,
33735
- unknownSignalCount,
33736
- conditionalSignalCount
33344
+ knownSignalCount: normalized.knownSignalCount + inherited.knownDelta,
33345
+ unknownSignalCount: normalized.unknownSignalCount + inherited.unknownDelta,
33346
+ conditionalSignalCount: normalized.conditionalSignalCount + inherited.conditionalDelta
33737
33347
  };
33738
- snapshotByElementNode.set(node, snapshot);
33739
- perf.signalSnapshotsBuilt++;
33740
- return snapshot;
33741
33348
  }
33742
33349
  function inheritSignalsFromParent(parentSnapshot, local) {
33743
33350
  if (!parentSnapshot) {
@@ -33764,7 +33371,7 @@ function inheritSignalsFromParent(parentSnapshot, local) {
33764
33371
  conditionalDelta++;
33765
33372
  continue;
33766
33373
  }
33767
- if (inheritedValue.kind === "known") {
33374
+ if (inheritedValue.kind === 0 /* Known */) {
33768
33375
  knownDelta++;
33769
33376
  continue;
33770
33377
  }
@@ -33802,10 +33409,10 @@ var EMPTY_STATEFUL_BASE_VALUE_INDEX = /* @__PURE__ */ new Map();
33802
33409
  var EMPTY_LAYOUT_RESERVED_SPACE_FACT = Object.freeze({
33803
33410
  hasReservedSpace: false,
33804
33411
  reasons: EMPTY_RESERVED_SPACE_REASONS,
33805
- hasUsableInlineDimension: false,
33806
- hasUsableBlockDimension: false,
33807
33412
  hasContainIntrinsicSize: false,
33808
- hasUsableAspectRatio: false
33413
+ hasUsableAspectRatio: false,
33414
+ hasDeclaredInlineDimension: false,
33415
+ hasDeclaredBlockDimension: false
33809
33416
  });
33810
33417
  var EMPTY_LAYOUT_SCROLL_CONTAINER_FACT = Object.freeze({
33811
33418
  isScrollContainer: false,
@@ -33838,12 +33445,12 @@ var EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT = Object.freeze({
33838
33445
  function readKnownSignalWithGuard(snapshot, name) {
33839
33446
  const value2 = snapshot.signals.get(name);
33840
33447
  if (!value2) return null;
33841
- if (value2.kind !== "known") return null;
33448
+ if (value2.kind !== 0 /* Known */) return null;
33842
33449
  return value2;
33843
33450
  }
33844
33451
  function toEvidenceKind(value2) {
33845
33452
  if (value2.guard.kind === 1 /* Conditional */) return 2 /* Conditional */;
33846
- if (value2.quality === "estimated") return 1 /* Interval */;
33453
+ if (value2.quality === 1 /* Estimated */) return 1 /* Interval */;
33847
33454
  return 0 /* Exact */;
33848
33455
  }
33849
33456
  function readNormalizedSignalEvidence(snapshot, name) {
@@ -33854,7 +33461,7 @@ function readNormalizedSignalEvidence(snapshot, name) {
33854
33461
  kind: 3 /* Unknown */
33855
33462
  };
33856
33463
  }
33857
- if (value2.kind !== "known") {
33464
+ if (value2.kind !== 0 /* Known */) {
33858
33465
  if (value2.guard.kind === 1 /* Conditional */) {
33859
33466
  return {
33860
33467
  value: null,
@@ -33908,19 +33515,19 @@ function hasEffectivePosition(snapshot) {
33908
33515
  return position !== "static";
33909
33516
  }
33910
33517
  function readReservedSpaceFact(graph, node) {
33911
- return graph.reservedSpaceFactsByNode.get(node) ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
33518
+ return graph.records.get(node)?.reservedSpace ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
33912
33519
  }
33913
33520
  function readScrollContainerFact(graph, node) {
33914
- return graph.scrollContainerFactsByNode.get(node) ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
33521
+ return graph.records.get(node)?.scrollContainer ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
33915
33522
  }
33916
33523
  function readFlowParticipationFact(graph, node) {
33917
- return graph.flowParticipationFactsByNode.get(node) ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
33524
+ return graph.records.get(node)?.flowParticipation ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
33918
33525
  }
33919
33526
  function readContainingBlockFact(graph, node) {
33920
- return graph.containingBlockFactsByNode.get(node) ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
33527
+ return graph.records.get(node)?.containingBlock ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
33921
33528
  }
33922
33529
  function readConditionalSignalDeltaFact(graph, node, name) {
33923
- const byProperty = graph.conditionalSignalDeltaFactsByNode.get(node);
33530
+ const byProperty = graph.records.get(node)?.conditionalDelta;
33924
33531
  if (!byProperty) return EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
33925
33532
  return byProperty.get(name) ?? EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
33926
33533
  }
@@ -33948,7 +33555,7 @@ function readScrollContainerElements(graph) {
33948
33555
  return graph.scrollContainerElements;
33949
33556
  }
33950
33557
  function readBaselineOffsetFacts(graph, node) {
33951
- return graph.baselineOffsetFactsByNode.get(node) ?? EMPTY_BASELINE_FACTS;
33558
+ return graph.records.get(node)?.baselineOffsets ?? EMPTY_BASELINE_FACTS;
33952
33559
  }
33953
33560
  function readElementRef(graph, node) {
33954
33561
  return readElementRefById(graph, node.solidFile, node.elementId);
@@ -34373,11 +33980,11 @@ function accumulateSnapshotFacts(snapshot, sink) {
34373
33980
  sink.addConditional();
34374
33981
  continue;
34375
33982
  }
34376
- if (value2.kind === "unknown") {
33983
+ if (value2.kind === 1 /* Unknown */) {
34377
33984
  sink.addUnknown();
34378
33985
  continue;
34379
33986
  }
34380
- if (value2.quality === "estimated" && value2.px !== null) {
33987
+ if (value2.quality === 1 /* Estimated */ && value2.px !== null) {
34381
33988
  sink.addInterval();
34382
33989
  continue;
34383
33990
  }
@@ -34719,7 +34326,7 @@ function checkHeightContributions(snapshot, state) {
34719
34326
  if (!signalName) continue;
34720
34327
  const signal = snapshot.signals.get(signalName);
34721
34328
  if (!signal) continue;
34722
- if (signal.kind !== "known") continue;
34329
+ if (signal.kind !== 0 /* Known */) continue;
34723
34330
  if (signal.px !== null && signal.px > 0) {
34724
34331
  state.hasHeightContributingDescendant = true;
34725
34332
  return;
@@ -34729,7 +34336,7 @@ function checkHeightContributions(snapshot, state) {
34729
34336
  function checkVerticalAlignMitigation(snapshot, state) {
34730
34337
  const verticalAlign = snapshot.signals.get("vertical-align");
34731
34338
  if (!verticalAlign) return;
34732
- if (verticalAlign.kind !== "known") return;
34339
+ if (verticalAlign.kind !== 0 /* Known */) return;
34733
34340
  if (VERTICAL_ALIGN_MITIGATIONS.has(verticalAlign.normalized)) {
34734
34341
  state.hasVerticalAlignMitigation = true;
34735
34342
  }
@@ -35915,16 +35522,16 @@ function establishesFormattingContext2(node, snapshotByElementNode) {
35915
35522
  const snapshot = snapshotByElementNode.get(node);
35916
35523
  if (snapshot) {
35917
35524
  const displaySignal = snapshot.signals.get("display");
35918
- if (displaySignal && displaySignal.kind === "known") {
35525
+ if (displaySignal && displaySignal.kind === 0 /* Known */) {
35919
35526
  return !isInlineLevelDisplay(displaySignal.normalized);
35920
35527
  }
35921
35528
  const overflowSignal = snapshot.signals.get("overflow");
35922
- if (overflowSignal && overflowSignal.kind === "known") {
35529
+ if (overflowSignal && overflowSignal.kind === 0 /* Known */) {
35923
35530
  const ov = overflowSignal.normalized;
35924
35531
  if (ov !== "visible" && ov !== "clip") return true;
35925
35532
  }
35926
35533
  const overflowYSignal = snapshot.signals.get("overflow-y");
35927
- if (overflowYSignal && overflowYSignal.kind === "known") {
35534
+ if (overflowYSignal && overflowYSignal.kind === 0 /* Known */) {
35928
35535
  const ov = overflowYSignal.normalized;
35929
35536
  if (ov !== "visible" && ov !== "clip") return true;
35930
35537
  }
@@ -36117,18 +35724,21 @@ function buildSelectorCandidatesByNode(elements, scopedSelectorsBySolidFile, per
36117
35724
  }
36118
35725
  return out;
36119
35726
  }
35727
+ function buildDispatchKeys(idValue, classTokens, attributeNames) {
35728
+ const out = [];
35729
+ if (idValue !== null) out.push(`id:${idValue}`);
35730
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
35731
+ for (let i = 0; i < attributeNames.length; i++) out.push(`attr:${attributeNames[i]}`);
35732
+ if (out.length <= 1) return out;
35733
+ out.sort();
35734
+ return dedupeSorted(out);
35735
+ }
36120
35736
  function buildSelectorDispatchKeys(attributes, classTokens) {
36121
35737
  const out = [];
36122
35738
  const idValue = attributes.get("id");
36123
- if (idValue !== null && idValue !== void 0) {
36124
- out.push(`id:${idValue}`);
36125
- }
36126
- for (let i = 0; i < classTokens.length; i++) {
36127
- out.push(`class:${classTokens[i]}`);
36128
- }
36129
- for (const attributeName of attributes.keys()) {
36130
- out.push(`attr:${attributeName}`);
36131
- }
35739
+ if (idValue !== null && idValue !== void 0) out.push(`id:${idValue}`);
35740
+ for (let i = 0; i < classTokens.length; i++) out.push(`class:${classTokens[i]}`);
35741
+ for (const attributeName of attributes.keys()) out.push(`attr:${attributeName}`);
36132
35742
  if (out.length <= 1) return out;
36133
35743
  out.sort();
36134
35744
  return dedupeSorted(out);
@@ -36272,19 +35882,11 @@ function selectorMatchesDispatchKeys(candidate, dispatchKeys) {
36272
35882
  return subjectIndex === candidate.subjectDispatchKeys.length;
36273
35883
  }
36274
35884
  function resolveSubjectDispatchKeys(matcher) {
36275
- const out = [];
36276
- if (matcher.subject.idValue !== null) {
36277
- out.push(`id:${matcher.subject.idValue}`);
36278
- }
36279
- for (let i = 0; i < matcher.subject.classes.length; i++) {
36280
- out.push(`class:${matcher.subject.classes[i]}`);
36281
- }
36282
- for (let i = 0; i < matcher.subject.attributeNames.length; i++) {
36283
- out.push(`attr:${matcher.subject.attributeNames[i]}`);
36284
- }
36285
- if (out.length <= 1) return out;
36286
- out.sort();
36287
- return dedupeSorted(out);
35885
+ return buildDispatchKeys(
35886
+ matcher.subject.idValue,
35887
+ matcher.subject.classes,
35888
+ matcher.subject.attributeNames
35889
+ );
36288
35890
  }
36289
35891
  function dedupeSorted(values) {
36290
35892
  if (values.length <= 1) return values;
@@ -36354,6 +35956,94 @@ function normalizeWithCache(cache, path) {
36354
35956
  return normalized;
36355
35957
  }
36356
35958
 
35959
+ // src/cross-file/layout/shorthand-expansion.ts
35960
+ var QUAD_EXPANSIONS = /* @__PURE__ */ new Map([
35961
+ ["padding", ["padding-top", "padding-right", "padding-bottom", "padding-left"]],
35962
+ ["border-width", ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"]],
35963
+ ["margin", ["margin-top", "margin-right", "margin-bottom", "margin-left"]],
35964
+ ["inset", ["top", "right", "bottom", "left"]]
35965
+ ]);
35966
+ var BLOCK_EXPANSIONS = /* @__PURE__ */ new Map([
35967
+ ["margin-block", ["margin-top", "margin-bottom"]],
35968
+ ["padding-block", ["padding-top", "padding-bottom"]],
35969
+ ["inset-block", ["inset-block-start", "inset-block-end"]]
35970
+ ]);
35971
+ var INLINE_EXPANSIONS = /* @__PURE__ */ new Map([
35972
+ ["padding-inline", ["padding-left", "padding-right"]]
35973
+ ]);
35974
+ function expandShorthand(property, value2) {
35975
+ const quadTarget = QUAD_EXPANSIONS.get(property);
35976
+ if (quadTarget !== void 0) {
35977
+ const parsed = parseQuadShorthand(value2);
35978
+ if (parsed === null) return null;
35979
+ return [
35980
+ { name: quadTarget[0], value: parsed.top },
35981
+ { name: quadTarget[1], value: parsed.right },
35982
+ { name: quadTarget[2], value: parsed.bottom },
35983
+ { name: quadTarget[3], value: parsed.left }
35984
+ ];
35985
+ }
35986
+ const blockTarget = BLOCK_EXPANSIONS.get(property);
35987
+ if (blockTarget !== void 0) {
35988
+ const parsed = parseBlockShorthand(value2);
35989
+ if (parsed === null) return null;
35990
+ return [
35991
+ { name: blockTarget[0], value: parsed.start },
35992
+ { name: blockTarget[1], value: parsed.end }
35993
+ ];
35994
+ }
35995
+ const inlineTarget = INLINE_EXPANSIONS.get(property);
35996
+ if (inlineTarget !== void 0) {
35997
+ const parsed = parseBlockShorthand(value2);
35998
+ if (parsed === null) return null;
35999
+ return [
36000
+ { name: inlineTarget[0], value: parsed.start },
36001
+ { name: inlineTarget[1], value: parsed.end }
36002
+ ];
36003
+ }
36004
+ if (property === "flex-flow") {
36005
+ return expandFlexFlow(value2);
36006
+ }
36007
+ return void 0;
36008
+ }
36009
+ var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
36010
+ function expandFlexFlow(value2) {
36011
+ const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
36012
+ if (tokens.length === 0) return null;
36013
+ if (tokens.length > 2) return null;
36014
+ let direction = null;
36015
+ let wrap = null;
36016
+ for (let i = 0; i < tokens.length; i++) {
36017
+ const token = tokens[i];
36018
+ if (!token) continue;
36019
+ if (FLEX_DIRECTION_VALUES.has(token)) {
36020
+ if (direction !== null) return null;
36021
+ direction = token;
36022
+ } else {
36023
+ if (wrap !== null) return null;
36024
+ wrap = token;
36025
+ }
36026
+ }
36027
+ const out = [];
36028
+ if (direction !== null) {
36029
+ out.push({ name: "flex-direction", value: direction });
36030
+ }
36031
+ if (wrap !== null) {
36032
+ out.push({ name: "flex-wrap", value: wrap });
36033
+ }
36034
+ return out.length > 0 ? out : null;
36035
+ }
36036
+ function getShorthandLonghandNames(property) {
36037
+ const quad = QUAD_EXPANSIONS.get(property);
36038
+ if (quad !== void 0) return [...quad];
36039
+ const block = BLOCK_EXPANSIONS.get(property);
36040
+ if (block !== void 0) return [...block];
36041
+ const inline = INLINE_EXPANSIONS.get(property);
36042
+ if (inline !== void 0) return [...inline];
36043
+ if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
36044
+ return null;
36045
+ }
36046
+
36357
36047
  // src/cross-file/layout/stateful-rule-index.ts
36358
36048
  var EMPTY_STATEFUL_SELECTOR_ENTRY_LIST = [];
36359
36049
  var EMPTY_LAYOUT_NORMALIZED_DECLARATION_LIST = [];
@@ -36571,8 +36261,7 @@ var DYNAMIC_ATTRIBUTE_GUARD = {
36571
36261
  key: "dynamic-attribute:*"
36572
36262
  };
36573
36263
  var SCROLLABLE_VALUES = /* @__PURE__ */ new Set(["auto", "scroll"]);
36574
- var EMPTY_EXPANSION_RESULT = [];
36575
- function collectMonitoredDeclarations(selector, layerOrder, guard) {
36264
+ function collectMonitoredDeclarations(selector, layerOrder, guard, variablesByName) {
36576
36265
  const out = [];
36577
36266
  const declarations = selector.rule.declarations;
36578
36267
  for (let i = 0; i < declarations.length; i++) {
@@ -36580,59 +36269,52 @@ function collectMonitoredDeclarations(selector, layerOrder, guard) {
36580
36269
  if (!declaration) continue;
36581
36270
  const property = declaration.property.toLowerCase();
36582
36271
  if (!isMonitoredSignal(property)) continue;
36583
- const monitored = toMonitoredSignalKey(property);
36584
- if (!monitored) continue;
36585
- out.push({
36586
- property: monitored,
36587
- value: declaration.value,
36588
- guardProvenance: guard,
36589
- position: {
36590
- layer: declaration.cascadePosition.layer,
36591
- layerOrder,
36592
- sourceOrder: declaration.sourceOrder,
36593
- specificity: selector.specificity,
36594
- specificityScore: selector.specificityScore,
36595
- isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36272
+ const position = {
36273
+ layer: declaration.cascadePosition.layer,
36274
+ layerOrder,
36275
+ sourceOrder: declaration.sourceOrder,
36276
+ specificity: selector.specificity,
36277
+ specificityScore: selector.specificityScore,
36278
+ isImportant: declaration.cascadePosition.isImportant || declaration.node.important
36279
+ };
36280
+ const rawValue = declaration.value;
36281
+ const resolvedValue = variablesByName !== null && rawValue.includes("var(") ? substituteVarReferences(rawValue, variablesByName, 0) : rawValue;
36282
+ const directSignal = MONITORED_SIGNAL_NAME_MAP.get(property);
36283
+ if (directSignal !== void 0) {
36284
+ out.push({ property: directSignal, value: resolvedValue, guardProvenance: guard, position });
36285
+ continue;
36286
+ }
36287
+ const value2 = resolvedValue.trim().toLowerCase();
36288
+ const expanded = expandShorthand(property, value2);
36289
+ if (expanded === void 0) continue;
36290
+ if (expanded === null) {
36291
+ const longhandNames = getShorthandLonghandNames(property);
36292
+ if (longhandNames === null) continue;
36293
+ for (let j = 0; j < longhandNames.length; j++) {
36294
+ const longhand = longhandNames[j];
36295
+ if (!longhand) continue;
36296
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(longhand);
36297
+ if (signal === void 0) continue;
36298
+ out.push({ property: signal, value: resolvedValue, guardProvenance: guard, position });
36596
36299
  }
36597
- });
36300
+ continue;
36301
+ }
36302
+ for (let j = 0; j < expanded.length; j++) {
36303
+ const entry = expanded[j];
36304
+ if (!entry) continue;
36305
+ const signal = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36306
+ if (signal === void 0) continue;
36307
+ out.push({ property: signal, value: entry.value, guardProvenance: guard, position });
36308
+ }
36598
36309
  }
36599
36310
  return out;
36600
36311
  }
36601
- function toMonitoredSignalKey(property) {
36602
- const signal = MONITORED_SIGNAL_NAME_MAP.get(property);
36603
- if (signal) return signal;
36604
- switch (property) {
36605
- case "padding":
36606
- case "border-width":
36607
- case "margin-block":
36608
- case "padding-block":
36609
- case "inset-block":
36610
- case "flex-flow":
36611
- return property;
36612
- default:
36613
- return null;
36614
- }
36615
- }
36616
36312
  function expandMonitoredDeclarationForDelta(declaration) {
36617
- const value2 = declaration.value.trim().toLowerCase();
36618
- const expanded = expandShorthand(declaration.property, value2);
36619
- if (expanded !== void 0) {
36620
- if (expanded === null) return EMPTY_EXPANSION_RESULT;
36621
- const filtered = [];
36622
- for (let i = 0; i < expanded.length; i++) {
36623
- const entry = expanded[i];
36624
- if (!entry) continue;
36625
- const signalName2 = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
36626
- if (signalName2 !== void 0) filtered.push({ name: signalName2, value: entry.value });
36627
- }
36628
- return filtered;
36629
- }
36630
- const signalName = MONITORED_SIGNAL_NAME_MAP.get(declaration.property);
36631
- if (signalName === void 0) return EMPTY_EXPANSION_RESULT;
36632
- return [{ name: signalName, value: value2 }];
36313
+ return [{ name: declaration.property, value: declaration.value.trim().toLowerCase() }];
36633
36314
  }
36634
36315
  function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, appliesByElementNodeMutable) {
36635
36316
  const fileRoots = ctx.rootElementsByFile.get(node.solidFile) ?? null;
36317
+ const fileElementIndex = ctx.fileElementIndexByFile.get(node.solidFile) ?? null;
36636
36318
  for (let i = 0; i < selectorIds.length; i++) {
36637
36319
  const selectorId = selectorIds[i];
36638
36320
  if (selectorId === void 0) continue;
@@ -36644,13 +36326,13 @@ function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, app
36644
36326
  if (!selector) {
36645
36327
  throw new Error(`missing selector ${selectorId}`);
36646
36328
  }
36647
- const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger);
36648
- if (matchResult === "no-match") continue;
36329
+ const matchResult = selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger, fileElementIndex);
36330
+ if (matchResult === 1 /* NoMatch */) continue;
36649
36331
  const edge = {
36650
36332
  selectorId: selector.id,
36651
36333
  specificityScore: selector.specificityScore,
36652
36334
  sourceOrder: selector.rule.sourceOrder,
36653
- conditionalMatch: matchResult === "conditional"
36335
+ conditionalMatch: matchResult === 2 /* Conditional */
36654
36336
  };
36655
36337
  applies.push(edge);
36656
36338
  ctx.perf.matchEdgesCreated++;
@@ -36707,6 +36389,40 @@ function augmentCascadeWithTailwind(cascade, node, tailwind) {
36707
36389
  }
36708
36390
  }
36709
36391
  }
36392
+ var MAX_VAR_SUBSTITUTION_DEPTH = 10;
36393
+ function substituteVarReferences(value2, variablesByName, depth) {
36394
+ if (depth >= MAX_VAR_SUBSTITUTION_DEPTH) return value2;
36395
+ const refs = extractVarReferences(value2);
36396
+ if (refs.length === 0) return value2;
36397
+ let result = value2;
36398
+ for (let i = refs.length - 1; i >= 0; i--) {
36399
+ const ref = refs[i];
36400
+ if (!ref) continue;
36401
+ const candidates = variablesByName.get(ref.name);
36402
+ const resolvedValue = candidates !== void 0 && candidates.length > 0 ? selectBestVariableValue(candidates) : ref.fallback;
36403
+ if (resolvedValue === null) continue;
36404
+ result = result.slice(0, ref.sourceIndex) + resolvedValue + result.slice(ref.sourceIndex + ref.raw.length);
36405
+ }
36406
+ if (result !== value2 && result.includes("var(")) {
36407
+ return substituteVarReferences(result, variablesByName, depth + 1);
36408
+ }
36409
+ return result;
36410
+ }
36411
+ function selectBestVariableValue(candidates) {
36412
+ let bestGlobal = null;
36413
+ for (let i = 0; i < candidates.length; i++) {
36414
+ const candidate = candidates[i];
36415
+ if (!candidate) continue;
36416
+ if (candidate.scope.type === "global") {
36417
+ if (bestGlobal === null || candidate.declaration.sourceOrder > bestGlobal.declaration.sourceOrder) {
36418
+ bestGlobal = candidate;
36419
+ }
36420
+ }
36421
+ }
36422
+ if (bestGlobal !== null) return bestGlobal.value;
36423
+ const first = candidates[0];
36424
+ return first ? first.value : null;
36425
+ }
36710
36426
  function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind) {
36711
36427
  const out = /* @__PURE__ */ new Map();
36712
36428
  const positions = /* @__PURE__ */ new Map();
@@ -36805,14 +36521,14 @@ function resolveRuleLayerOrder(rule, css) {
36805
36521
  if (!name) return 0;
36806
36522
  return css.layerOrder.get(name) ?? 0;
36807
36523
  }
36808
- function buildConditionalDeltaIndex(elements, appliesByNode, monitoredDeclarationsBySelectorId, selectorsById) {
36524
+ function buildConditionalDeltaIndex(elements, records, monitoredDeclarationsBySelectorId, selectorsById) {
36809
36525
  const conditionalSignalDeltaFactsByNode = /* @__PURE__ */ new Map();
36810
36526
  const elementsWithConditionalDeltaBySignal = /* @__PURE__ */ new Map();
36811
36527
  const baselineOffsetFactsByNode = /* @__PURE__ */ new Map();
36812
36528
  for (let i = 0; i < elements.length; i++) {
36813
36529
  const node = elements[i];
36814
36530
  if (!node) continue;
36815
- const edges = appliesByNode.get(node);
36531
+ const edges = records.get(node)?.edges;
36816
36532
  let factByProperty = null;
36817
36533
  if (edges !== void 0 && edges.length > 0) {
36818
36534
  const byProperty = /* @__PURE__ */ new Map();
@@ -37167,7 +36883,7 @@ function collectLayoutElementRecordsForSolid(solid, selectorRequirements, inline
37167
36883
  const classTokenSet = classTokens.length === 0 ? EMPTY_CLASS_TOKEN_SET : createClassTokenSet(classTokens);
37168
36884
  const inlineStyleKeys = getStaticStyleKeysForElement(solid, element.id);
37169
36885
  const localAttributes = selectorRequirements.needsAttributes ? collectStaticAttributes(element) : EMPTY_ATTRIBUTES2;
37170
- const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes);
36886
+ const attributes = mergeAttributes(localAttributes, meta.resolvedHost?.descriptor.staticAttributes, meta.resolvedHost?.descriptor.attributePropBindings);
37171
36887
  const selectorDispatchKeys = buildSelectorDispatchKeys(attributes, classTokens);
37172
36888
  const inlineStyleValues = inlineStyleValuesByElementId.get(element.id) ?? EMPTY_INLINE_STYLE_VALUES;
37173
36889
  const textualContent = getTextualContentState(element, textContentMemo, compositionMetaByElementId, logger);
@@ -37223,7 +36939,63 @@ function collectCompositionMetaByElementId(solid, componentHostResolver) {
37223
36939
  function resolveHostForElement(componentHostResolver, solidFile, element) {
37224
36940
  if (element.tag === null) return null;
37225
36941
  if (element.isDomElement) return null;
37226
- return componentHostResolver.resolveHost(solidFile, element.tag);
36942
+ const defaultHost = componentHostResolver.resolveHost(solidFile, element.tag);
36943
+ const asTag = extractPolymorphicAsTag(element);
36944
+ if (asTag !== null) {
36945
+ const asHost = componentHostResolver.resolveHost(solidFile, asTag);
36946
+ if (asHost !== null) return composePolymorphicHost(defaultHost, asHost);
36947
+ }
36948
+ return defaultHost;
36949
+ }
36950
+ function extractPolymorphicAsTag(element) {
36951
+ for (let i = 0; i < element.attributes.length; i++) {
36952
+ const attr = element.attributes[i];
36953
+ if (!attr) continue;
36954
+ if (attr.name !== "as") continue;
36955
+ if (attr.valueNode === null) continue;
36956
+ if (!ts124.isJsxExpression(attr.valueNode)) continue;
36957
+ const expression = attr.valueNode.expression;
36958
+ if (!expression) continue;
36959
+ if (ts124.isIdentifier(expression)) return expression.text;
36960
+ if (ts124.isPropertyAccessExpression(expression)) return expression.getText();
36961
+ return null;
36962
+ }
36963
+ return null;
36964
+ }
36965
+ function composePolymorphicHost(outerHost, asHost) {
36966
+ if (outerHost === null) return asHost;
36967
+ const outerDesc = outerHost.descriptor;
36968
+ const asDesc = asHost.descriptor;
36969
+ const staticAttributes = /* @__PURE__ */ new Map();
36970
+ for (const [name, value2] of outerDesc.staticAttributes) staticAttributes.set(name, value2);
36971
+ for (const [name, value2] of asDesc.staticAttributes) staticAttributes.set(name, value2);
36972
+ const classTokenSet = /* @__PURE__ */ new Set();
36973
+ const staticClassTokens = [];
36974
+ for (const token of outerDesc.staticClassTokens) {
36975
+ if (!classTokenSet.has(token)) {
36976
+ classTokenSet.add(token);
36977
+ staticClassTokens.push(token);
36978
+ }
36979
+ }
36980
+ for (const token of asDesc.staticClassTokens) {
36981
+ if (!classTokenSet.has(token)) {
36982
+ classTokenSet.add(token);
36983
+ staticClassTokens.push(token);
36984
+ }
36985
+ }
36986
+ const attributePropBindings = /* @__PURE__ */ new Map();
36987
+ for (const [name, value2] of outerDesc.attributePropBindings) attributePropBindings.set(name, value2);
36988
+ for (const [name, value2] of asDesc.attributePropBindings) attributePropBindings.set(name, value2);
36989
+ return {
36990
+ descriptor: {
36991
+ tagName: asDesc.tagName ?? outerDesc.tagName,
36992
+ staticAttributes,
36993
+ staticClassTokens,
36994
+ forwardsChildren: asDesc.forwardsChildren || outerDesc.forwardsChildren,
36995
+ attributePropBindings
36996
+ },
36997
+ hostElementRef: asHost.hostElementRef ?? outerHost.hostElementRef
36998
+ };
37227
36999
  }
37228
37000
  function resolveTransparentPrimitiveStatus(componentHostResolver, solidFile, element, resolvedHost) {
37229
37001
  if (element.tag === null) return false;
@@ -37266,11 +37038,21 @@ function mergeClassTokens(localTokens, hostTokens) {
37266
37038
  }
37267
37039
  return out;
37268
37040
  }
37269
- function mergeAttributes(localAttributes, hostAttributes) {
37041
+ function mergeAttributes(localAttributes, hostAttributes, propBindings) {
37270
37042
  if (hostAttributes === void 0 || hostAttributes.size === 0) return localAttributes;
37271
- if (localAttributes.size === 0) return hostAttributes;
37043
+ if (localAttributes.size === 0 && (propBindings === void 0 || propBindings.size === 0)) return hostAttributes;
37272
37044
  const out = /* @__PURE__ */ new Map();
37273
37045
  for (const [name, value2] of hostAttributes) {
37046
+ if (propBindings !== void 0) {
37047
+ const propName = propBindings.get(name);
37048
+ if (propName !== void 0) {
37049
+ const callSiteValue = localAttributes.get(propName);
37050
+ if (callSiteValue !== void 0 && callSiteValue !== null) {
37051
+ out.set(name, callSiteValue);
37052
+ continue;
37053
+ }
37054
+ }
37055
+ }
37274
37056
  out.set(name, value2);
37275
37057
  }
37276
37058
  for (const [name, value2] of localAttributes) {
@@ -37336,7 +37118,9 @@ function resolveSiblingTypeCount(totalsByParentId, parentElementId, tagName, sib
37336
37118
 
37337
37119
  // src/cross-file/layout/build.ts
37338
37120
  var EMPTY_NUMBER_LIST2 = [];
37339
- var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch"]);
37121
+ var EMPTY_EDGE_LIST = Object.freeze([]);
37122
+ var NON_RESERVING_DIMENSION_KEYWORDS = /* @__PURE__ */ new Set(["auto", "none", "fit-content", "min-content", "max-content", "stretch", "inherit", "initial", "unset", "revert", "revert-layer"]);
37123
+ 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"]);
37340
37124
  function buildLayoutGraph(solids, css, logger = noopLogger) {
37341
37125
  const perf = createLayoutPerfStats();
37342
37126
  const startedAt = performance.now();
@@ -37351,7 +37135,6 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37351
37135
  const selectorsById = /* @__PURE__ */ new Map();
37352
37136
  const monitoredDeclarationsBySelectorId = /* @__PURE__ */ new Map();
37353
37137
  const selectorMetadataById = /* @__PURE__ */ new Map();
37354
- const cascadeByElementNode = /* @__PURE__ */ new WeakMap();
37355
37138
  for (let i = 0; i < css.selectors.length; i++) {
37356
37139
  const selector = css.selectors[i];
37357
37140
  if (!selector) continue;
@@ -37366,7 +37149,8 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37366
37149
  const monitoredDeclarations = collectMonitoredDeclarations(
37367
37150
  selector,
37368
37151
  resolveRuleLayerOrder(selector.rule, css),
37369
- guard
37152
+ guard,
37153
+ css.variablesByName
37370
37154
  );
37371
37155
  selectorsById.set(selector.id, selector);
37372
37156
  monitoredDeclarationsBySelectorId.set(selector.id, monitoredDeclarations);
@@ -37424,7 +37208,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37424
37208
  };
37425
37209
  const textContentMemo = /* @__PURE__ */ new Map();
37426
37210
  const inlineStyleValuesByElementId = collectInlineStyleValuesByElementId(solid);
37427
- const records = collectLayoutElementRecordsForSolid(
37211
+ const records2 = collectLayoutElementRecordsForSolid(
37428
37212
  solid,
37429
37213
  selectorRequirements,
37430
37214
  inlineStyleValuesByElementId,
@@ -37432,12 +37216,12 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37432
37216
  componentHostResolver,
37433
37217
  logger
37434
37218
  );
37435
- const siblingTotals = collectSiblingTotals(records);
37219
+ const siblingTotals = collectSiblingTotals(records2);
37436
37220
  const nodeByElementId = /* @__PURE__ */ new Map();
37437
37221
  const lastChildByParentId = /* @__PURE__ */ new Map();
37438
37222
  const siblingTypeSeenByParentId = /* @__PURE__ */ new Map();
37439
- for (let i = 0; i < records.length; i++) {
37440
- const record = records[i];
37223
+ for (let i = 0; i < records2.length; i++) {
37224
+ const record = records2[i];
37441
37225
  if (!record) continue;
37442
37226
  const parentElementId = record.parentElementId;
37443
37227
  const parentNode = parentElementId === null ? null : nodeByElementId.get(parentElementId) ?? null;
@@ -37502,6 +37286,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37502
37286
  }
37503
37287
  }
37504
37288
  }
37289
+ const fileElementIndexByFile = buildFileElementIndexByFile(elements);
37505
37290
  if (logger.isLevelEnabled(Level.Debug)) {
37506
37291
  for (const [file, roots] of rootElementsByFile) {
37507
37292
  const descs = roots.map((r) => `${r.key}(tag=${r.tagName}, attrs=[${[...r.attributes.entries()].map(([k, v]) => `${k}=${v}`).join(",")}])`);
@@ -37513,63 +37298,138 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37513
37298
  selectorMetadataById,
37514
37299
  selectorsById,
37515
37300
  rootElementsByFile,
37301
+ fileElementIndexByFile,
37516
37302
  perf,
37517
37303
  logger
37518
37304
  };
37519
- for (let i = 0; i < elements.length; i++) {
37520
- const node = elements[i];
37521
- if (!node) continue;
37522
- const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37523
- if (selectorIds.length === 0) continue;
37524
- appendMatchingEdgesFromSelectorIds(
37525
- selectorMatchCtx,
37526
- selectorIds,
37527
- node,
37528
- applies,
37529
- appliesByElementNodeMutable
37530
- );
37531
- }
37532
- perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
37533
- const cascadeStartedAt = performance.now();
37534
- for (const edges of appliesByElementNodeMutable.values()) {
37535
- edges.sort(compareLayoutEdge);
37536
- }
37537
- const appliesByNode = /* @__PURE__ */ new Map();
37538
37305
  const tailwind = css.tailwind;
37306
+ const records = /* @__PURE__ */ new Map();
37307
+ const snapshotByElementNode = /* @__PURE__ */ new WeakMap();
37308
+ const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37309
+ const elementsByTagName = /* @__PURE__ */ new Map();
37310
+ const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37311
+ const dynamicSlotCandidateElements = [];
37312
+ const scrollContainerElements = [];
37313
+ const positionedAncestorByKey = /* @__PURE__ */ new Map();
37314
+ const trace = logger.isLevelEnabled(Level.Trace);
37539
37315
  for (let i = 0; i < elements.length; i++) {
37540
37316
  const node = elements[i];
37541
37317
  if (!node) continue;
37542
- const edges = appliesByElementNodeMutable.get(node) ?? [];
37318
+ const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
37319
+ if (selectorIds.length > 0) {
37320
+ appendMatchingEdgesFromSelectorIds(
37321
+ selectorMatchCtx,
37322
+ selectorIds,
37323
+ node,
37324
+ applies,
37325
+ appliesByElementNodeMutable
37326
+ );
37327
+ }
37328
+ const mutableEdges = appliesByElementNodeMutable.get(node);
37329
+ if (mutableEdges) mutableEdges.sort(compareLayoutEdge);
37330
+ const edges = mutableEdges ?? EMPTY_EDGE_LIST;
37543
37331
  const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind);
37544
- cascadeByElementNode.set(node, cascade);
37545
- appliesByNode.set(node, edges);
37546
- }
37547
- perf.cascadeBuildMs = performance.now() - cascadeStartedAt;
37548
- if (logger.isLevelEnabled(Level.Trace)) {
37549
- for (let i = 0; i < elements.length; i++) {
37550
- const node = elements[i];
37551
- if (!node) continue;
37552
- const cascade = cascadeByElementNode.get(node);
37553
- if (!cascade || cascade.size === 0) continue;
37332
+ if (trace && cascade.size > 0) {
37554
37333
  const displayDecl = cascade.get("display");
37555
37334
  const flexDirDecl = cascade.get("flex-direction");
37556
- if (!displayDecl && !flexDirDecl) continue;
37557
- const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37558
- const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37559
- logger.trace(
37560
- `[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(",")}]`
37561
- );
37335
+ if (displayDecl || flexDirDecl) {
37336
+ const displayGuard = displayDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37337
+ const flexDirGuard = flexDirDecl?.guardProvenance.kind === 1 /* Conditional */ ? "conditional" : "unconditional";
37338
+ logger.trace(
37339
+ `[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(",")}]`
37340
+ );
37341
+ }
37342
+ }
37343
+ const parentSnapshot = node.parentElementNode ? records.get(node.parentElementNode)?.snapshot ?? null : null;
37344
+ const snapshot = buildSnapshotFromCascade(node, cascade, parentSnapshot);
37345
+ snapshotByElementNode.set(node, snapshot);
37346
+ perf.signalSnapshotsBuilt++;
37347
+ if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37348
+ dynamicSlotCandidateElements.push(node);
37349
+ }
37350
+ if (node.tagName) {
37351
+ const existing = elementsByTagName.get(node.tagName);
37352
+ if (existing) existing.push(node);
37353
+ else elementsByTagName.set(node.tagName, [node]);
37354
+ }
37355
+ for (const [signal, value2] of snapshot.signals) {
37356
+ if (value2.kind !== 0 /* Known */) continue;
37357
+ let byValue = elementsByKnownSignalValue.get(signal);
37358
+ if (!byValue) {
37359
+ byValue = /* @__PURE__ */ new Map();
37360
+ elementsByKnownSignalValue.set(signal, byValue);
37361
+ }
37362
+ const existingNodes = byValue.get(value2.normalized);
37363
+ if (existingNodes) existingNodes.push(node);
37364
+ else byValue.set(value2.normalized, [node]);
37562
37365
  }
37366
+ const parentKey = node.parentElementNode?.key ?? null;
37367
+ let nearestPositionedAncestorKey = null;
37368
+ let nearestPositionedAncestorHasReservedSpace = false;
37369
+ if (parentKey !== null) {
37370
+ const parentPositioned = positionedAncestorByKey.get(parentKey);
37371
+ if (parentPositioned !== void 0) {
37372
+ nearestPositionedAncestorKey = parentPositioned.key;
37373
+ nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37374
+ }
37375
+ }
37376
+ const containingBlock = {
37377
+ nearestPositionedAncestorKey,
37378
+ nearestPositionedAncestorHasReservedSpace
37379
+ };
37380
+ const reservedSpace = computeReservedSpaceFact(snapshot);
37381
+ const scrollContainer = computeScrollContainerFact(snapshot);
37382
+ if (scrollContainer.isScrollContainer) scrollContainerElements.push(node);
37383
+ const flowParticipation = computeFlowParticipationFact(snapshot);
37384
+ const hotSignals = computeHotSignals(snapshot);
37385
+ snapshotHotSignalsByNode.set(node, hotSignals);
37386
+ const positionSignal = snapshot.signals.get("position");
37387
+ const isPositioned = positionSignal !== void 0 && positionSignal.kind === 0 /* Known */ && positionSignal.normalized !== "static";
37388
+ if (isPositioned) {
37389
+ positionedAncestorByKey.set(node.key, { key: node.key, hasReservedSpace: reservedSpace.hasReservedSpace });
37390
+ } else if (parentKey !== null) {
37391
+ const inherited = positionedAncestorByKey.get(parentKey);
37392
+ if (inherited !== void 0) positionedAncestorByKey.set(node.key, inherited);
37393
+ }
37394
+ records.set(node, {
37395
+ ref: elementRefsBySolidFileAndIdMutable.get(node.solidFile)?.get(node.elementId) ?? null,
37396
+ edges,
37397
+ cascade,
37398
+ snapshot,
37399
+ hotSignals,
37400
+ reservedSpace,
37401
+ scrollContainer,
37402
+ flowParticipation,
37403
+ containingBlock,
37404
+ conditionalDelta: null,
37405
+ baselineOffsets: null
37406
+ });
37563
37407
  }
37564
- const snapshotByElementNode = buildSignalSnapshotIndex(elements, cascadeByElementNode, perf);
37565
- const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
37566
- const factIndex = buildElementFactIndex(elements, snapshotByElementNode);
37408
+ perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
37567
37409
  const conditionalDeltaIndex = buildConditionalDeltaIndex(
37568
37410
  elements,
37569
- appliesByNode,
37411
+ records,
37570
37412
  monitoredDeclarationsBySelectorId,
37571
37413
  selectorsById
37572
37414
  );
37415
+ for (const [node, deltaByProperty] of conditionalDeltaIndex.conditionalSignalDeltaFactsByNode) {
37416
+ const record = records.get(node);
37417
+ if (!record) continue;
37418
+ const baselineOffsets = conditionalDeltaIndex.baselineOffsetFactsByNode.get(node) ?? null;
37419
+ records.set(node, {
37420
+ ref: record.ref,
37421
+ edges: record.edges,
37422
+ cascade: record.cascade,
37423
+ snapshot: record.snapshot,
37424
+ hotSignals: record.hotSignals,
37425
+ reservedSpace: record.reservedSpace,
37426
+ scrollContainer: record.scrollContainer,
37427
+ flowParticipation: record.flowParticipation,
37428
+ containingBlock: record.containingBlock,
37429
+ conditionalDelta: deltaByProperty,
37430
+ baselineOffsets
37431
+ });
37432
+ }
37573
37433
  const elementsWithConditionalOverflowDelta = buildConditionalDeltaSignalGroupElements(
37574
37434
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37575
37435
  ["overflow", "overflow-y"]
@@ -37578,6 +37438,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37578
37438
  conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37579
37439
  layoutOffsetSignals
37580
37440
  );
37441
+ const measurementNodeByRootKey = buildMeasurementNodeIndex(elements, childrenByParentNodeMutable, snapshotByElementNode);
37581
37442
  const statefulRuleIndexes = buildStatefulRuleIndexes(css.rules);
37582
37443
  const contextByParentNode = buildContextIndex(childrenByParentNodeMutable, snapshotByElementNode, perf, logger);
37583
37444
  const cohortIndex = buildCohortIndex({
@@ -37585,7 +37446,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37585
37446
  contextByParentNode,
37586
37447
  measurementNodeByRootKey,
37587
37448
  snapshotByElementNode,
37588
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode
37449
+ snapshotHotSignalsByNode
37589
37450
  });
37590
37451
  finalizeTableCellBaselineRelevance(contextByParentNode, cohortIndex.verticalAlignConsensusByParent);
37591
37452
  perf.conditionalSignals = cohortIndex.conditionalSignals;
@@ -37602,122 +37463,71 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
37602
37463
  elementBySolidFileAndId: elementBySolidFileAndIdMutable,
37603
37464
  elementRefsBySolidFileAndId: elementRefsBySolidFileAndIdMutable,
37604
37465
  hostElementRefsByNode: hostElementRefsByNodeMutable,
37605
- appliesByNode,
37606
37466
  selectorCandidatesByNode,
37607
37467
  selectorsById,
37608
37468
  measurementNodeByRootKey,
37609
- snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode,
37610
- elementsByTagName: factIndex.elementsByTagName,
37469
+ records,
37470
+ elementsByTagName,
37611
37471
  elementsWithConditionalDeltaBySignal: conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
37612
37472
  elementsWithConditionalOverflowDelta,
37613
37473
  elementsWithConditionalOffsetDelta,
37614
- elementsByKnownSignalValue: factIndex.elementsByKnownSignalValue,
37615
- dynamicSlotCandidateElements: factIndex.dynamicSlotCandidateElements,
37616
- scrollContainerElements: factIndex.scrollContainerElements,
37617
- reservedSpaceFactsByNode: factIndex.reservedSpaceFactsByNode,
37618
- scrollContainerFactsByNode: factIndex.scrollContainerFactsByNode,
37619
- flowParticipationFactsByNode: factIndex.flowParticipationFactsByNode,
37620
- containingBlockFactsByNode: factIndex.containingBlockFactsByNode,
37621
- conditionalSignalDeltaFactsByNode: conditionalDeltaIndex.conditionalSignalDeltaFactsByNode,
37622
- baselineOffsetFactsByNode: conditionalDeltaIndex.baselineOffsetFactsByNode,
37474
+ elementsByKnownSignalValue,
37475
+ dynamicSlotCandidateElements,
37476
+ scrollContainerElements,
37623
37477
  statefulSelectorEntriesByRuleId: statefulRuleIndexes.selectorEntriesByRuleId,
37624
37478
  statefulNormalizedDeclarationsByRuleId: statefulRuleIndexes.normalizedDeclarationsByRuleId,
37625
37479
  statefulBaseValueIndex: statefulRuleIndexes.baseValueIndex,
37626
37480
  cohortStatsByParentNode: cohortIndex.statsByParentNode,
37627
- cascadeByElementNode,
37628
- snapshotByElementNode,
37629
37481
  contextByParentNode,
37630
37482
  perf
37631
37483
  };
37632
37484
  }
37633
- function buildElementFactIndex(elements, snapshotByElementNode) {
37634
- const reservedSpaceFactsByNode = /* @__PURE__ */ new Map();
37635
- const scrollContainerFactsByNode = /* @__PURE__ */ new Map();
37636
- const flowParticipationFactsByNode = /* @__PURE__ */ new Map();
37637
- const containingBlockFactsByNode = /* @__PURE__ */ new Map();
37638
- const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
37639
- const elementsByTagName = /* @__PURE__ */ new Map();
37640
- const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
37641
- const dynamicSlotCandidateElements = [];
37642
- const scrollContainerElements = [];
37643
- const positionedAncestorByKey = /* @__PURE__ */ new Map();
37485
+ function buildFileElementIndexByFile(elements) {
37486
+ const byFileDispatch = /* @__PURE__ */ new Map();
37487
+ const byFileTag = /* @__PURE__ */ new Map();
37644
37488
  for (let i = 0; i < elements.length; i++) {
37645
37489
  const node = elements[i];
37646
37490
  if (!node) continue;
37647
- const snapshot = snapshotByElementNode.get(node);
37648
- if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
37649
- dynamicSlotCandidateElements.push(node);
37650
- }
37651
- if (node.tagName) {
37652
- const existing = elementsByTagName.get(node.tagName);
37491
+ if (node.parentElementNode === null) continue;
37492
+ const file = node.solidFile;
37493
+ let dispatchMap = byFileDispatch.get(file);
37494
+ if (!dispatchMap) {
37495
+ dispatchMap = /* @__PURE__ */ new Map();
37496
+ byFileDispatch.set(file, dispatchMap);
37497
+ }
37498
+ const keys = node.selectorDispatchKeys;
37499
+ for (let j = 0; j < keys.length; j++) {
37500
+ const key = keys[j];
37501
+ if (!key) continue;
37502
+ const existing = dispatchMap.get(key);
37653
37503
  if (existing) {
37654
37504
  existing.push(node);
37655
37505
  } else {
37656
- elementsByTagName.set(node.tagName, [node]);
37506
+ dispatchMap.set(key, [node]);
37657
37507
  }
37658
37508
  }
37659
- const parentKey = node.parentElementNode?.key ?? null;
37660
- let nearestPositionedAncestorKey = null;
37661
- let nearestPositionedAncestorHasReservedSpace = false;
37662
- if (parentKey !== null) {
37663
- const parentPositioned = positionedAncestorByKey.get(parentKey);
37664
- if (parentPositioned !== void 0) {
37665
- nearestPositionedAncestorKey = parentPositioned.key;
37666
- nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
37667
- }
37668
- }
37669
- containingBlockFactsByNode.set(node, {
37670
- nearestPositionedAncestorKey,
37671
- nearestPositionedAncestorHasReservedSpace
37672
- });
37673
- if (!snapshot) continue;
37674
- const reservedSpaceFact = computeReservedSpaceFact(snapshot);
37675
- reservedSpaceFactsByNode.set(node, reservedSpaceFact);
37676
- const scrollFact = computeScrollContainerFact(snapshot);
37677
- scrollContainerFactsByNode.set(node, scrollFact);
37678
- if (scrollFact.isScrollContainer) scrollContainerElements.push(node);
37679
- flowParticipationFactsByNode.set(node, computeFlowParticipationFact(snapshot));
37680
- snapshotHotSignalsByNode.set(node, computeHotSignals(snapshot));
37681
- const positionSignal = snapshot.signals.get("position");
37682
- const isPositioned = positionSignal !== void 0 && positionSignal.kind === "known" && positionSignal.normalized !== "static";
37683
- if (isPositioned) {
37684
- positionedAncestorByKey.set(node.key, {
37685
- key: node.key,
37686
- hasReservedSpace: reservedSpaceFact.hasReservedSpace
37687
- });
37688
- } else if (parentKey !== null) {
37689
- const inherited = positionedAncestorByKey.get(parentKey);
37690
- if (inherited !== void 0) {
37691
- positionedAncestorByKey.set(node.key, inherited);
37509
+ if (node.tagName !== null) {
37510
+ let tagMap = byFileTag.get(file);
37511
+ if (!tagMap) {
37512
+ tagMap = /* @__PURE__ */ new Map();
37513
+ byFileTag.set(file, tagMap);
37692
37514
  }
37693
- }
37694
- for (const [signal, value2] of snapshot.signals) {
37695
- if (value2.kind !== "known") continue;
37696
- const normalized = value2.normalized;
37697
- let byValue = elementsByKnownSignalValue.get(signal);
37698
- if (!byValue) {
37699
- byValue = /* @__PURE__ */ new Map();
37700
- elementsByKnownSignalValue.set(signal, byValue);
37701
- }
37702
- const existingNodes = byValue.get(normalized);
37703
- if (existingNodes) {
37704
- existingNodes.push(node);
37515
+ const existing = tagMap.get(node.tagName);
37516
+ if (existing) {
37517
+ existing.push(node);
37705
37518
  } else {
37706
- byValue.set(normalized, [node]);
37519
+ tagMap.set(node.tagName, [node]);
37707
37520
  }
37708
37521
  }
37709
37522
  }
37710
- return {
37711
- reservedSpaceFactsByNode,
37712
- scrollContainerFactsByNode,
37713
- scrollContainerElements,
37714
- flowParticipationFactsByNode,
37715
- containingBlockFactsByNode,
37716
- snapshotHotSignalsByNode,
37717
- elementsByTagName,
37718
- elementsByKnownSignalValue,
37719
- dynamicSlotCandidateElements
37720
- };
37523
+ const out = /* @__PURE__ */ new Map();
37524
+ for (const [file, dispatchMap] of byFileDispatch) {
37525
+ out.set(file, {
37526
+ byDispatchKey: dispatchMap,
37527
+ byTagName: byFileTag.get(file) ?? /* @__PURE__ */ new Map()
37528
+ });
37529
+ }
37530
+ return out;
37721
37531
  }
37722
37532
  var ABSENT_NUMERIC = Object.freeze({
37723
37533
  present: false,
@@ -37730,7 +37540,7 @@ var ABSENT_NORMALIZED = Object.freeze({
37730
37540
  kind: 3 /* Unknown */
37731
37541
  });
37732
37542
  function toHotNumeric(signal) {
37733
- if (signal.kind !== "known") {
37543
+ if (signal.kind !== 0 /* Known */) {
37734
37544
  return {
37735
37545
  present: true,
37736
37546
  value: null,
@@ -37740,11 +37550,11 @@ function toHotNumeric(signal) {
37740
37550
  return {
37741
37551
  present: true,
37742
37552
  value: signal.px,
37743
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
37553
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
37744
37554
  };
37745
37555
  }
37746
37556
  function toHotNormalized(signal) {
37747
- if (signal.kind !== "known") {
37557
+ if (signal.kind !== 0 /* Known */) {
37748
37558
  return {
37749
37559
  present: true,
37750
37560
  value: null,
@@ -37754,7 +37564,7 @@ function toHotNormalized(signal) {
37754
37564
  return {
37755
37565
  present: true,
37756
37566
  value: signal.normalized,
37757
- kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
37567
+ kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === 1 /* Estimated */ ? 1 /* Interval */ : 0 /* Exact */
37758
37568
  };
37759
37569
  }
37760
37570
  function computeHotSignals(snapshot) {
@@ -37869,62 +37679,61 @@ function computeHotSignals(snapshot) {
37869
37679
  }
37870
37680
  function computeReservedSpaceFact(snapshot) {
37871
37681
  const reasons = [];
37872
- const hasHeight = hasPositiveOrDeclaredDimension(snapshot, "height");
37682
+ const hasHeight = hasDeclaredDimension(snapshot, "height");
37873
37683
  if (hasHeight) reasons.push("height");
37874
- const hasBlockSize = hasPositiveOrDeclaredDimension(snapshot, "block-size");
37684
+ const hasBlockSize = hasDeclaredDimension(snapshot, "block-size");
37875
37685
  if (hasBlockSize) reasons.push("block-size");
37876
- const hasMinHeight = hasPositiveOrDeclaredDimension(snapshot, "min-height");
37686
+ const hasMinHeight = hasDeclaredDimension(snapshot, "min-height");
37877
37687
  if (hasMinHeight) reasons.push("min-height");
37878
- const hasMinBlockSize = hasPositiveOrDeclaredDimension(snapshot, "min-block-size");
37688
+ const hasMinBlockSize = hasDeclaredDimension(snapshot, "min-block-size");
37879
37689
  if (hasMinBlockSize) reasons.push("min-block-size");
37880
- const hasContainIntrinsic = hasPositiveOrDeclaredDimension(snapshot, "contain-intrinsic-size");
37690
+ const hasContainIntrinsic = hasDeclaredDimension(snapshot, "contain-intrinsic-size");
37881
37691
  if (hasContainIntrinsic) reasons.push("contain-intrinsic-size");
37882
37692
  const hasAspectRatio = hasUsableAspectRatio(snapshot);
37883
37693
  if (hasAspectRatio) {
37884
- if (hasPositiveOrDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
37885
- if (hasPositiveOrDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
37886
- if (hasPositiveOrDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
37694
+ if (hasDeclaredDimension(snapshot, "width")) reasons.push("aspect-ratio+width");
37695
+ if (hasDeclaredDimension(snapshot, "inline-size")) reasons.push("aspect-ratio+inline-size");
37696
+ if (hasDeclaredDimension(snapshot, "min-width")) reasons.push("aspect-ratio+min-width");
37887
37697
  if (hasMinBlockSize) reasons.push("aspect-ratio+min-block-size");
37888
37698
  if (hasMinHeight) reasons.push("aspect-ratio+min-height");
37889
37699
  }
37890
37700
  return {
37891
37701
  hasReservedSpace: reasons.length > 0,
37892
37702
  reasons,
37893
- hasUsableInlineDimension: hasPositiveOrDeclaredDimension(snapshot, "width") || hasPositiveOrDeclaredDimension(snapshot, "inline-size") || hasPositiveOrDeclaredDimension(snapshot, "min-width"),
37894
- hasUsableBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
37895
37703
  hasContainIntrinsicSize: hasContainIntrinsic,
37896
- hasUsableAspectRatio: hasAspectRatio
37704
+ hasUsableAspectRatio: hasAspectRatio,
37705
+ hasDeclaredBlockDimension: hasHeight || hasBlockSize || hasMinHeight || hasMinBlockSize,
37706
+ hasDeclaredInlineDimension: hasDeclaredDimension(snapshot, "width") || hasDeclaredDimension(snapshot, "inline-size") || hasDeclaredDimension(snapshot, "min-width") || hasDeclaredDimension(snapshot, "flex-basis") || isBlockLevelDisplay(snapshot)
37897
37707
  };
37898
37708
  }
37899
- function hasPositiveOrDeclaredDimension(snapshot, property) {
37709
+ function hasDeclaredDimension(snapshot, property) {
37900
37710
  const signal = snapshot.signals.get(property);
37901
37711
  if (!signal) return false;
37902
- if (signal.guard.kind !== 0 /* Unconditional */) return false;
37903
- let normalized = "";
37904
- if (signal.kind === "known") {
37712
+ if (signal.kind === 0 /* Known */) {
37905
37713
  if (signal.px !== null) return signal.px > 0;
37906
- normalized = signal.normalized.trim().toLowerCase();
37714
+ if (signal.normalized.length === 0) return false;
37715
+ return !isNonReservingDimension(signal.normalized);
37907
37716
  }
37908
- if (signal.kind === "unknown") {
37717
+ if (signal.kind === 1 /* Unknown */) {
37909
37718
  return signal.source !== null;
37910
37719
  }
37911
- if (normalized.length === 0) return false;
37912
- if (isNonReservingDimension(normalized)) return false;
37913
- return true;
37720
+ return false;
37721
+ }
37722
+ function isBlockLevelDisplay(snapshot) {
37723
+ const signal = snapshot.signals.get("display");
37724
+ if (!signal || signal.kind !== 0 /* Known */) return false;
37725
+ return BLOCK_LEVEL_DISPLAY_VALUES.has(signal.normalized);
37914
37726
  }
37915
37727
  function hasUsableAspectRatio(snapshot) {
37916
37728
  const signal = snapshot.signals.get("aspect-ratio");
37917
37729
  if (!signal) return false;
37918
37730
  if (signal.guard.kind !== 0 /* Unconditional */) return false;
37919
- if (signal.kind === "unknown") {
37731
+ if (signal.kind === 1 /* Unknown */) {
37920
37732
  return false;
37921
37733
  }
37922
- let normalized = "";
37923
- if (signal.kind === "known") {
37924
- normalized = signal.normalized.trim().toLowerCase();
37925
- }
37926
- if (normalized.length === 0) return false;
37927
- return normalized !== "auto";
37734
+ if (signal.kind !== 0 /* Known */) return false;
37735
+ if (signal.normalized.length === 0) return false;
37736
+ return signal.normalized !== "auto";
37928
37737
  }
37929
37738
  function isNonReservingDimension(value2) {
37930
37739
  if (NON_RESERVING_DIMENSION_KEYWORDS.has(value2)) return true;
@@ -37934,8 +37743,8 @@ function isNonReservingDimension(value2) {
37934
37743
  function computeScrollContainerFact(snapshot) {
37935
37744
  const overflowSignal = snapshot.signals.get("overflow");
37936
37745
  const overflowYSignal = snapshot.signals.get("overflow-y");
37937
- const overflow = overflowSignal && overflowSignal.kind === "known" ? overflowSignal.normalized : null;
37938
- const overflowY = overflowYSignal && overflowYSignal.kind === "known" ? overflowYSignal.normalized : null;
37746
+ const overflow = overflowSignal && overflowSignal.kind === 0 /* Known */ ? overflowSignal.normalized : null;
37747
+ const overflowY = overflowYSignal && overflowYSignal.kind === 0 /* Known */ ? overflowYSignal.normalized : null;
37939
37748
  const shorthandAxis = parseOverflowShorthandAxis(overflow);
37940
37749
  const yFromLonghand = parseSingleAxisScroll(overflowY);
37941
37750
  const xScroll = shorthandAxis.x;
@@ -37983,7 +37792,7 @@ function toScrollAxis(x, y) {
37983
37792
  }
37984
37793
  function computeFlowParticipationFact(snapshot) {
37985
37794
  const signal = snapshot.signals.get("position");
37986
- if (!signal || signal.kind !== "known") {
37795
+ if (!signal || signal.kind !== 0 /* Known */) {
37987
37796
  return {
37988
37797
  inFlow: true,
37989
37798
  position: null,
@@ -38015,8 +37824,8 @@ function buildContextIndex(childrenByParentNode, snapshotByElementNode, perf, lo
38015
37824
  if (trace) {
38016
37825
  const displaySignal = snapshot.signals.get("display");
38017
37826
  const flexDirSignal = snapshot.signals.get("flex-direction");
38018
- const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === "known" ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38019
- const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === "known" ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37827
+ const displayDesc = displaySignal ? `${displaySignal.kind}:${displaySignal.kind === 0 /* Known */ ? displaySignal.normalized : "?"}(guard=${displaySignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
37828
+ const flexDirDesc = flexDirSignal ? `${flexDirSignal.kind}:${flexDirSignal.kind === 0 /* Known */ ? flexDirSignal.normalized : "?"}(guard=${flexDirSignal.guard.kind === 1 /* Conditional */ ? "conditional" : "unconditional"})` : "absent";
38020
37829
  logger.trace(
38021
37830
  `[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}`
38022
37831
  );
@@ -40222,8 +40031,8 @@ function hasReservedSize(solid, attributes, element, reservedSpaceFact, hostElem
40222
40031
  const hostJsxWidth = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "width") : false;
40223
40032
  const hostJsxHeight = hostElementRef !== null ? readPositiveJsxAttribute(hostElementRef.solid, hostElementRef.element, "height") : false;
40224
40033
  if (attrWidth && attrHeight || jsxAttrWidth && jsxAttrHeight || hostJsxWidth && hostJsxHeight) return true;
40225
- const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasUsableInlineDimension;
40226
- const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasUsableBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
40034
+ const hasAnyWidth = attrWidth || jsxAttrWidth || hostJsxWidth || reservedSpaceFact.hasDeclaredInlineDimension;
40035
+ const hasAnyHeight = attrHeight || jsxAttrHeight || hostJsxHeight || reservedSpaceFact.hasDeclaredBlockDimension || reservedSpaceFact.hasContainIntrinsicSize;
40227
40036
  if (reservedSpaceFact.hasUsableAspectRatio && (hasAnyWidth || hasAnyHeight)) return true;
40228
40037
  if (reservedSpaceFact.hasContainIntrinsicSize && (hasAnyWidth || hasAnyHeight)) return true;
40229
40038
  return false;
@@ -40700,7 +40509,7 @@ function collectConditionalOffsets(layout, node, snapshot) {
40700
40509
  const signal = snapshot.signals.get(name);
40701
40510
  if (!signal) continue;
40702
40511
  if (signal.guard.kind !== 1 /* Conditional */) continue;
40703
- if (signal.kind !== "known") continue;
40512
+ if (signal.kind !== 0 /* Known */) continue;
40704
40513
  if (signal.px === null) continue;
40705
40514
  if (Math.abs(signal.px) <= 0.25) continue;
40706
40515
  out.push({ property: name, value: signal.px, guardKey: signal.guard.key });
@@ -40723,7 +40532,7 @@ function hasEffectivePositionForConditionalOffset(snapshot, guardKey) {
40723
40532
  if (hasEffectivePosition(snapshot)) return true;
40724
40533
  const position = snapshot.signals.get("position");
40725
40534
  if (!position) return false;
40726
- if (position.kind !== "known") return false;
40535
+ if (position.kind !== 0 /* Known */) return false;
40727
40536
  if (position.guard.kind !== 1 /* Conditional */) return false;
40728
40537
  if (position.guard.key !== guardKey) return false;
40729
40538
  return position.normalized !== "static";
@@ -41183,6 +40992,9 @@ function isVisuallyHidden(snapshot) {
41183
40992
  const opacityAttr = node.inlineStyleValues.get("opacity");
41184
40993
  if (opacityAttr === "0") return true;
41185
40994
  if (node.classTokenSet.has("opacity-0")) return true;
40995
+ const width = readKnownPx(snapshot, "width");
40996
+ const height = readKnownPx(snapshot, "height");
40997
+ if (width === 1 && height === 1) return true;
41186
40998
  return false;
41187
40999
  }
41188
41000
  var jsxLayoutPolicyTouchTarget = defineCrossRule({
@@ -41234,6 +41046,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41234
41046
  tag,
41235
41047
  policyName
41236
41048
  );
41049
+ checkDimension(
41050
+ snapshot,
41051
+ "max-height",
41052
+ kind === "button" ? policy.minButtonHeight : policy.minInputHeight,
41053
+ layout,
41054
+ node,
41055
+ emit,
41056
+ "heightTooSmall",
41057
+ messages161.heightTooSmall,
41058
+ tag,
41059
+ policyName
41060
+ );
41237
41061
  checkDimension(
41238
41062
  snapshot,
41239
41063
  "width",
@@ -41258,6 +41082,18 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41258
41082
  tag,
41259
41083
  policyName
41260
41084
  );
41085
+ checkDimension(
41086
+ snapshot,
41087
+ "max-width",
41088
+ kind === "button" ? policy.minButtonWidth : policy.minTouchTarget,
41089
+ layout,
41090
+ node,
41091
+ emit,
41092
+ "widthTooSmall",
41093
+ messages161.widthTooSmall,
41094
+ tag,
41095
+ policyName
41096
+ );
41261
41097
  if (kind === "button") {
41262
41098
  checkDimension(
41263
41099
  snapshot,
@@ -41287,7 +41123,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41287
41123
  const reservedSpace = readReservedSpaceFact(layout, node);
41288
41124
  const minBlock = kind === "button" ? policy.minButtonHeight : policy.minInputHeight;
41289
41125
  const minInline = kind === "button" ? policy.minButtonWidth : policy.minTouchTarget;
41290
- if (!reservedSpace.hasUsableBlockDimension) {
41126
+ if (!reservedSpace.hasDeclaredBlockDimension) {
41291
41127
  emitLayoutDiagnostic(
41292
41128
  layout,
41293
41129
  node,
@@ -41299,7 +41135,7 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41299
41135
  { tag, min: String(minBlock), policy: policyName }
41300
41136
  );
41301
41137
  }
41302
- if (!reservedSpace.hasUsableInlineDimension) {
41138
+ if (!reservedSpace.hasDeclaredInlineDimension) {
41303
41139
  emitLayoutDiagnostic(
41304
41140
  layout,
41305
41141
  node,
@@ -41315,7 +41151,13 @@ var jsxLayoutPolicyTouchTarget = defineCrossRule({
41315
41151
  }
41316
41152
  });
41317
41153
  function checkDimension(snapshot, signal, min, layout, node, emit, messageId, template, tag, policyName) {
41318
- const px = readKnownPx(snapshot, signal);
41154
+ let px = readKnownPx(snapshot, signal);
41155
+ if (px === null) {
41156
+ const signalValue = readKnownSignalWithGuard(snapshot, signal);
41157
+ if (signalValue !== null && signalValue.guard.kind === 1 /* Conditional */) {
41158
+ px = resolveUnconditionalFallbackPx(layout, node, signal);
41159
+ }
41160
+ }
41319
41161
  if (px === null) return;
41320
41162
  if (px >= min) return;
41321
41163
  emitLayoutDiagnostic(
@@ -41335,6 +41177,20 @@ function checkDimension(snapshot, signal, min, layout, node, emit, messageId, te
41335
41177
  }
41336
41178
  );
41337
41179
  }
41180
+ function resolveUnconditionalFallbackPx(layout, node, signal) {
41181
+ const delta = readConditionalSignalDeltaFact(layout, node, signal);
41182
+ if (!delta.hasConditional) return null;
41183
+ const values = delta.unconditionalValues;
41184
+ let bestPx = null;
41185
+ for (let i = 0; i < values.length; i++) {
41186
+ const raw = values[i];
41187
+ if (!raw) continue;
41188
+ const px = parsePxValue(raw);
41189
+ if (px === null) continue;
41190
+ if (bestPx === null || px > bestPx) bestPx = px;
41191
+ }
41192
+ return bestPx;
41193
+ }
41338
41194
 
41339
41195
  // src/cross-file/rules/index.ts
41340
41196
  var rules3 = [
@@ -41465,4 +41321,4 @@ export {
41465
41321
  rules3,
41466
41322
  runCrossFileRules
41467
41323
  };
41468
- //# sourceMappingURL=chunk-MJKIL7DJ.js.map
41324
+ //# sourceMappingURL=chunk-CHVGY25Z.js.map