@tenphi/tasty 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +2 -2
  2. package/dist/debug.js +1 -1
  3. package/dist/debug.js.map +1 -1
  4. package/dist/pipeline/conditions.js +14 -8
  5. package/dist/pipeline/conditions.js.map +1 -1
  6. package/dist/pipeline/index.js +59 -40
  7. package/dist/pipeline/index.js.map +1 -1
  8. package/dist/pipeline/materialize.js +34 -98
  9. package/dist/pipeline/materialize.js.map +1 -1
  10. package/dist/pipeline/parseStateKey.js +17 -9
  11. package/dist/pipeline/parseStateKey.js.map +1 -1
  12. package/dist/pipeline/simplify.js +111 -152
  13. package/dist/pipeline/simplify.js.map +1 -1
  14. package/dist/pipeline/warnings.js +18 -0
  15. package/dist/pipeline/warnings.js.map +1 -0
  16. package/dist/styles/align.d.ts +1 -1
  17. package/dist/styles/align.js.map +1 -1
  18. package/dist/styles/border.d.ts +1 -1
  19. package/dist/styles/border.js.map +1 -1
  20. package/dist/styles/color.d.ts +2 -2
  21. package/dist/styles/color.js.map +1 -1
  22. package/dist/styles/createStyle.js +1 -1
  23. package/dist/styles/createStyle.js.map +1 -1
  24. package/dist/styles/fade.d.ts +1 -1
  25. package/dist/styles/fade.js.map +1 -1
  26. package/dist/styles/fill.d.ts +14 -16
  27. package/dist/styles/fill.js.map +1 -1
  28. package/dist/styles/flow.d.ts +3 -3
  29. package/dist/styles/flow.js.map +1 -1
  30. package/dist/styles/justify.d.ts +1 -1
  31. package/dist/styles/justify.js.map +1 -1
  32. package/dist/styles/predefined.js.map +1 -1
  33. package/dist/styles/radius.d.ts +1 -1
  34. package/dist/styles/radius.js.map +1 -1
  35. package/dist/styles/scrollbar.d.ts +1 -1
  36. package/dist/styles/scrollbar.js +19 -12
  37. package/dist/styles/scrollbar.js.map +1 -1
  38. package/dist/styles/shadow.d.ts +2 -2
  39. package/dist/styles/shadow.js.map +1 -1
  40. package/dist/styles/styledScrollbar.d.ts +1 -1
  41. package/dist/styles/styledScrollbar.js.map +1 -1
  42. package/dist/styles/transition.d.ts +1 -1
  43. package/dist/styles/transition.js.map +1 -1
  44. package/dist/utils/colors.d.ts +1 -1
  45. package/dist/utils/colors.js.map +1 -1
  46. package/dist/utils/dotize.d.ts +1 -1
  47. package/dist/utils/mod-attrs.js.map +1 -1
  48. package/dist/utils/string.js.map +1 -1
  49. package/dist/utils/styles.d.ts +7 -12
  50. package/dist/utils/styles.js +13 -8
  51. package/dist/utils/styles.js.map +1 -1
  52. package/package.json +47 -1
package/README.md CHANGED
@@ -17,9 +17,9 @@
17
17
 
18
18
  ---
19
19
 
20
- Most CSS-in-JS libraries generate CSS. Tasty generates **mutually exclusive CSS** — for any combination of states, exactly one rule matches per property. No cascade conflicts, no specificity wars, no `!important` hacks. Components compose and extend without breaking each other. That's the foundation everything else is built on.
20
+ Most CSS-in-JS libraries emit rules that compete through cascade and specificity. Tasty emits **mutually exclusive CSS selectors** — for any component state combination, exactly one selector matches each property at a time. No cascade conflicts, no specificity wars, no `!important` escapes. Components compose and extend without breaking each other.
21
21
 
22
- On top of that foundation, Tasty gives you a concise, CSS-like DSL with design tokens, custom units, responsive states, container queries, dark mode, sub-element styling, and zero-runtime extraction all in one coherent system that scales from a single component to an enterprise design system.
22
+ That guarantee unlocks a concise, CSS-like DSL where design tokens, custom units, responsive states, container queries, sub-element styling, and theming all compose without surprises one coherent system that scales from a single component to an enterprise design system.
23
23
 
24
24
  ## Why Tasty
25
25
 
package/dist/debug.js CHANGED
@@ -665,7 +665,7 @@ const tastyDebug = {
665
665
  const ruleCount = (css.match(/\{/g) || []).length;
666
666
  console.group(`🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`);
667
667
  const subElementMatches = css.match(/\[data-element="([^"]+)"\]/g) || [];
668
- const subElements = [...new Set(subElementMatches.map((match) => match.match(/\[data-element="([^"]+)"\]/)?.[1]).filter(Boolean))];
668
+ const subElements = [...new Set(subElementMatches.map((match) => match.match(/\[data-element="([^"]+)"\]/)?.[1]).filter((v) => !!v))];
669
669
  if (subElements.length > 0) {
670
670
  console.log(`🧩 Sub-elements found: ${subElements.join(", ")}`);
671
671
  subElements.forEach((element) => {
package/dist/debug.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"debug.js","names":[],"sources":["../src/debug.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Debug utilities for inspecting tasty-generated CSS at runtime\n */\n\nimport { CHUNK_NAMES } from './chunks/definitions';\nimport { getCssTextForNode, injector } from './injector';\nimport type { CleanupStats } from './injector/types';\nimport { isDevEnv } from './utils/is-dev-env';\n\ndeclare global {\n interface Window {\n tastyDebug?: typeof tastyDebug;\n }\n}\n\n// Type definitions for the new API\ntype CSSTarget =\n | 'all' // tasty CSS + tasty global CSS + raw CSS\n | 'global' // only tasty global CSS\n | 'active' // tasty CSS for classes currently in DOM\n | 'unused' // tasty CSS with refCount = 0 (still in cache but not actively used)\n | 'page' // ALL CSS on the page across stylesheets (not only tasty)\n | string // 't123' tasty class or a CSS selector\n | string[] // array of tasty classes like ['t1', 't2']\n | Element; // a DOM element\n\ninterface CssOptions {\n root?: Document | ShadowRoot;\n prettify?: boolean; // default: true\n log?: boolean; // default: false\n}\n\ninterface ChunkInfo {\n className: string;\n chunkName: string | null;\n}\n\ninterface InspectResult {\n element?: Element | null;\n classes: string[]; // tasty classes found on the element\n chunks: ChunkInfo[]; // chunk information per class (with chunking enabled)\n css: string; // full, prettified CSS affecting the element\n size: number; // characters in css\n rules: number; // number of rule blocks\n}\n\ninterface CacheMetrics {\n hits: number;\n misses: number;\n bulkCleanups: number;\n totalInsertions: number;\n totalUnused: number;\n stylesCleanedUp: number;\n cleanupHistory: {\n timestamp: number;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n }[];\n startTime: number;\n\n // Calculated metrics\n unusedHits?: number; // calculated as current unused count\n}\n\ninterface CacheStatus {\n classes: {\n active: string[]; // classes with refCount > 0 and present in DOM\n unused: string[]; // classes with refCount = 0 but still in cache\n all: string[]; // union of both\n };\n metrics: CacheMetrics | null;\n}\n\ninterface Definitions {\n properties: string[]; // defined via @property\n keyframes: { name: string; refCount: number }[];\n}\n\ninterface SummaryOptions {\n root?: Document | ShadowRoot;\n log?: boolean;\n includePageCSS?:\n | false // do not include page-level CSS stats (default)\n | true // include sizes/counts only\n | 'all'; // include stats and return full page CSS string\n}\n\ninterface Summary {\n // Classes\n activeClasses: string[];\n unusedClasses: string[];\n totalStyledClasses: string[];\n\n // Tasty CSS sizes\n activeCSSSize: number;\n unusedCSSSize: number;\n globalCSSSize: number; // injectGlobal() CSS\n rawCSSSize: number; // injectRawCSS() / useRawCSS() CSS\n keyframesCSSSize: number; // @keyframes CSS\n propertyCSSSize: number; // @property CSS\n totalCSSSize: number; // all tasty CSS (active + unused + global + raw + keyframes + property)\n\n // Tasty CSS payloads\n activeCSS: string;\n unusedCSS: string;\n globalCSS: string; // injectGlobal() CSS\n rawCSS: string; // injectRawCSS() / useRawCSS() CSS\n keyframesCSS: string; // @keyframes CSS\n propertyCSS: string; // @property CSS\n allCSS: string; // all tasty CSS combined\n\n // Rule counts\n globalRuleCount: number;\n rawRuleCount: number;\n keyframesRuleCount: number;\n propertyRuleCount: number;\n\n // Page-level CSS (across all stylesheets, not only tasty) — shown when includePageCSS != false\n page?: {\n css?: string; // present only when includePageCSS === 'all'\n cssSize: number; // total characters\n ruleCount: number; // approximate rule count\n stylesheetCount: number; // stylesheets scanned (CORS-safe)\n skippedStylesheets: number; // stylesheets skipped due to cross-origin/CORS\n };\n\n // Metrics & definitions\n metrics: CacheMetrics | null;\n definedProperties: string[];\n definedKeyframes: { name: string; refCount: number }[];\n propertyCount: number;\n keyframeCount: number;\n\n // Cleanup summary\n cleanupSummary: {\n enabled: boolean;\n totalCleanups: number;\n totalClassesDeleted: number;\n totalCssDeleted: number;\n totalRulesDeleted: number;\n averageClassesPerCleanup: number;\n averageCssPerCleanup: number;\n averageRulesPerCleanup: number;\n lastCleanup?: {\n timestamp: number;\n date: string;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n };\n };\n\n // Chunk breakdown (style chunking optimization)\n chunkBreakdown: {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n };\n}\n\n/**\n * Pretty-print CSS with proper indentation and formatting\n */\nfunction prettifyCSS(css: string): string {\n if (!css || css.trim() === '') {\n return '';\n }\n\n // First, normalize whitespace but preserve structure\n let formatted = css.replace(/\\s+/g, ' ').trim();\n\n // Add newlines after opening braces\n formatted = formatted.replace(/\\s*\\{\\s*/g, ' {\\n');\n\n // Add newlines after semicolons (but not inside strings or functions)\n formatted = formatted.replace(/;(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))/g, ';\\n');\n\n // Add newlines before closing braces\n formatted = formatted.replace(/\\s*\\}\\s*/g, '\\n}\\n');\n\n // Handle comma-separated selectors (only outside of property values)\n // This regex looks for commas that are:\n // 1. Not inside quotes\n // 2. Not inside parentheses (CSS functions)\n // 3. Not followed by a colon (not in a property value)\n formatted = formatted.replace(\n /,(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))(?=.*:.*\\{|.*\\{)/g,\n ',\\n',\n );\n\n // Process line by line for proper indentation\n const lines = formatted.split('\\n');\n let indentLevel = 0;\n const indentSize = 2;\n\n const formattedLines = lines.map((line) => {\n const trimmed = line.trim();\n if (!trimmed) return '';\n\n // Handle closing braces - decrease indent first\n if (trimmed === '}') {\n indentLevel = Math.max(0, indentLevel - 1);\n return ' '.repeat(indentLevel * indentSize) + trimmed;\n }\n\n // Current line with proper indentation\n const indent = ' '.repeat(indentLevel * indentSize);\n const result = indent + trimmed;\n\n // Handle opening braces - increase indent for next line\n if (trimmed.endsWith('{')) {\n indentLevel++;\n }\n\n return result;\n });\n\n // Clean up the result and ensure proper spacing\n let result = formattedLines\n .filter((line) => line.trim()) // Remove empty lines\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n') // Max 2 consecutive newlines\n .trim();\n\n // Final cleanup: ensure single spaces in function calls\n result = result.replace(/,\\s+/g, ', ');\n\n return result;\n}\n\n// Helper functions\nfunction findAllTastyClasses(root: Document | ShadowRoot = document): string[] {\n const classes = new Set<string>();\n const elements = (root as Document).querySelectorAll?.('[class]') || [];\n\n elements.forEach((element) => {\n const classList = element.getAttribute('class');\n if (classList) {\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n tastyClasses.forEach((cls) => classes.add(cls));\n }\n });\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction findAllStyledClasses(\n root: Document | ShadowRoot = document,\n): string[] {\n // Extract tasty classes from all CSS text by parsing selectors\n const allCSS = injector.instance.getCssText({ root });\n const classes = new Set<string>();\n\n // Simple regex to find .t{number} class selectors\n const classRegex = /\\.t(\\d+)/g;\n let match;\n while ((match = classRegex.exec(allCSS)) !== null) {\n classes.add(`t${match[1]}`);\n }\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction extractCSSRules(\n css: string,\n): { selector: string; declarations: string }[] {\n const rules: { selector: string; declarations: string }[] = [];\n\n // Remove comments\n const cleanCSS = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n let i = 0;\n while (i < cleanCSS.length) {\n // Skip whitespace\n while (i < cleanCSS.length && /\\s/.test(cleanCSS[i])) {\n i++;\n }\n if (i >= cleanCSS.length) break;\n\n // Find selector start\n const selectorStart = i;\n let braceDepth = 0;\n let inString = false;\n let stringChar = '';\n\n // Find opening brace\n while (i < cleanCSS.length) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n if (braceDepth === 1) break;\n }\n }\n i++;\n }\n\n if (i >= cleanCSS.length) break;\n const selector = cleanCSS.substring(selectorStart, i).trim();\n i++; // Skip opening brace\n\n // Find matching closing brace\n const contentStart = i;\n braceDepth = 1;\n inString = false;\n\n while (i < cleanCSS.length && braceDepth > 0) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n } else if (char === '}') {\n braceDepth--;\n }\n }\n i++;\n }\n\n const content = cleanCSS.substring(contentStart, i - 1).trim();\n if (content && selector) {\n rules.push({ selector, declarations: content });\n }\n }\n\n return rules;\n}\n\nfunction getGlobalCSS(root: Document | ShadowRoot = document): string {\n const allCSS = injector.instance.getCssText({ root });\n const rules = extractCSSRules(allCSS);\n\n const globalRules = rules.filter((rule) => {\n const selectors = rule.selector.split(',').map((s) => s.trim());\n return !selectors.every((selector) => {\n const cleanSelector = selector.replace(/[.#:\\s>+~[\\]()]/g, ' ');\n const parts = cleanSelector.split(/\\s+/).filter(Boolean);\n return parts.length > 0 && parts.every((part) => /^t\\d+$/.test(part));\n });\n });\n\n const globalCSS = globalRules\n .map((rule) => `${rule.selector} { ${rule.declarations} }`)\n .join('\\n');\n return prettifyCSS(globalCSS);\n}\n\nfunction getPageCSS(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): string {\n const root = options?.root || document;\n const includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n const cssChunks: string[] = [];\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n cssChunks.push(rules.map((rule) => rule.cssText).join('\\n'));\n }\n } catch {\n // Cross-origin sheet or other access error\n if (includeCrossOrigin) {\n cssChunks.push(\n `/* Cross-origin stylesheet: ${sheet.href || 'inline'} */`,\n );\n }\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return cssChunks.join('\\n');\n}\n\nfunction getPageStats(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n} {\n const root = options?.root || document;\n\n const _includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n let cssSize = 0;\n let ruleCount = 0;\n let stylesheetCount = 0;\n let skippedStylesheets = 0;\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n stylesheetCount = styleSheets.length;\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n ruleCount += rules.length;\n cssSize += rules.reduce(\n (sum, rule) => sum + rule.cssText.length,\n 0,\n );\n }\n } catch {\n skippedStylesheets++;\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return { cssSize, ruleCount, stylesheetCount, skippedStylesheets };\n}\n\n// ============================================================================\n// Chunk-aware helpers (for style chunking optimization)\n// ============================================================================\n\n/**\n * Extract chunk name from a cache key.\n *\n * Cache keys have the format: \"chunkName\\0key:value\\0key:value...\"\n * or \"[states:...]\\0chunkName\\0...\" for predefined states.\n *\n * @param cacheKey - The cache key to parse\n * @returns The chunk name, or null if not found\n */\nfunction extractChunkNameFromCacheKey(cacheKey: string): string | null {\n // Cache keys are separated by \\0 (null character)\n const parts = cacheKey.split('\\0');\n\n for (const part of parts) {\n // Skip predefined states prefix\n if (part.startsWith('[states:')) continue;\n // First non-states part that doesn't contain : is the chunk name\n if (!part.includes(':') && part.length > 0) {\n return part;\n }\n }\n return null;\n}\n\n/**\n * Get chunk info for a className by reverse-looking up its cache key.\n *\n * @param className - The tasty class name (e.g., \"t0\", \"t123\")\n * @param root - The document or shadow root to search in\n * @returns Object with chunk name and cache key, or nulls if not found\n */\nfunction getChunkForClassName(\n className: string,\n root: Document | ShadowRoot = document,\n): { chunkName: string | null; cacheKey: string | null } {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (!registry) {\n return { chunkName: null, cacheKey: null };\n }\n\n // Reverse lookup: find the cache key for this className\n for (const [cacheKey, cn] of registry.cacheKeyToClassName) {\n if (cn === className) {\n return {\n chunkName: extractChunkNameFromCacheKey(cacheKey),\n cacheKey,\n };\n }\n }\n return { chunkName: null, cacheKey: null };\n}\n\n/**\n * Get chunk breakdown statistics for all styles.\n *\n * @param root - The document or shadow root to search in\n * @returns Object with breakdown by chunk type and totals\n */\nfunction getChunkBreakdown(root: Document | ShadowRoot = document): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n} {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return {\n byChunk: {},\n totalChunkTypes: 0,\n };\n }\n\n const byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n > = {};\n\n // Group classes by chunk\n for (const [cacheKey, className] of registry.cacheKeyToClassName) {\n const chunkName = extractChunkNameFromCacheKey(cacheKey) || 'unknown';\n\n if (!byChunk[chunkName]) {\n byChunk[chunkName] = { classes: [], cssSize: 0, ruleCount: 0 };\n }\n\n byChunk[chunkName].classes.push(className);\n\n // Get CSS for this class\n const css = injector.instance.getCssTextForClasses([className], { root });\n byChunk[chunkName].cssSize += css.length;\n byChunk[chunkName].ruleCount += (css.match(/\\{[^}]*\\}/g) || []).length;\n }\n\n // Sort classes within each chunk for consistency\n for (const entry of Object.values(byChunk)) {\n entry.classes.sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n }\n\n return {\n byChunk,\n totalChunkTypes: Object.keys(byChunk).length,\n };\n}\n\n/**\n * Concise tastyDebug API for inspecting styles at runtime\n */\nexport const tastyDebug = {\n // 1) One function to get CSS from anywhere\n css(target: CSSTarget, opts?: CssOptions): string {\n const { root = document, prettify = true, log = false } = opts || {};\n let css = '';\n\n if (typeof target === 'string') {\n if (target === 'all') {\n css = injector.instance.getCssText({ root });\n } else if (target === 'global') {\n css = getGlobalCSS(root);\n } else if (target === 'active') {\n const activeClasses = findAllTastyClasses(root);\n css = injector.instance.getCssTextForClasses(activeClasses, { root });\n } else if (target === 'unused') {\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<\n [string, number]\n >,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n css = injector.instance.getCssTextForClasses(unusedClasses, { root });\n } else if (target === 'page') {\n css = getPageCSS({ root, includeCrossOrigin: true });\n } else if (/^t\\d+$/.test(target)) {\n // Single tasty class\n css = injector.instance.getCssTextForClasses([target], { root });\n } else {\n // CSS selector - find element and get its CSS\n const element = (root as Document).querySelector?.(target);\n if (element) {\n css = getCssTextForNode(element, { root });\n }\n }\n } else if (Array.isArray(target)) {\n // Array of tasty classes\n css = injector.instance.getCssTextForClasses(target, { root });\n } else if (target instanceof Element) {\n // DOM element\n css = getCssTextForNode(target, { root });\n }\n\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group(\n `🎨 CSS for ${Array.isArray(target) ? `[${target.join(', ')}]` : target}`,\n );\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n // 2) Element-level inspection\n inspect(\n target: string | Element,\n opts?: { root?: Document | ShadowRoot },\n ): InspectResult {\n const { root = document } = opts || {};\n const element =\n typeof target === 'string'\n ? (root as Document).querySelector?.(target)\n : target;\n\n if (!element) {\n return {\n element: null,\n classes: [],\n chunks: [],\n css: '',\n size: 0,\n rules: 0,\n };\n }\n\n const classList = element.getAttribute('class') || '';\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n\n // Get chunk info for each tasty class\n const chunks: ChunkInfo[] = tastyClasses.map((className) => ({\n className,\n chunkName: getChunkForClassName(className, root).chunkName,\n }));\n\n const css = getCssTextForNode(element, { root });\n const prettifiedCSS = prettifyCSS(css);\n const ruleCount = (css.match(/\\{[^}]*\\}/g) || []).length;\n\n return {\n element,\n classes: tastyClasses,\n chunks,\n css: prettifiedCSS,\n size: css.length,\n rules: ruleCount,\n };\n },\n\n // 3) Cache + metrics at a glance\n cache(opts?: {\n root?: Document | ShadowRoot;\n includeHistory?: boolean;\n }): CacheStatus {\n const { root = document } = opts || {};\n const activeClasses = findAllTastyClasses(root);\n\n const _allClasses = findAllStyledClasses(root);\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<[string, number]>,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n\n return {\n classes: {\n active: activeClasses,\n unused: unusedClasses,\n all: [...activeClasses, ...unusedClasses],\n },\n metrics: injector.instance.getMetrics({ root }),\n };\n },\n\n // 4) Cleanup + metrics utilities\n cleanup(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.cleanup(root);\n },\n\n metrics(opts?: { root?: Document | ShadowRoot }): CacheMetrics | null {\n const { root } = opts || {};\n return injector.instance.getMetrics({ root });\n },\n\n resetMetrics(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.resetMetrics({ root });\n },\n\n // 5) Chunk breakdown (style chunking optimization)\n /**\n * Get breakdown of styles by chunk type.\n *\n * With style chunking enabled, styles are split into logical chunks\n * (appearance, font, dimension, container, etc.) for better caching\n * and CSS reuse.\n *\n * @param opts - Options including root document/shadow root\n * @returns Breakdown by chunk type with class counts and CSS sizes\n */\n chunks(opts?: { root?: Document | ShadowRoot; log?: boolean }): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n totalClasses: number;\n } {\n const { root = document, log = false } = opts || {};\n const breakdown = getChunkBreakdown(root);\n\n const totalClasses = Object.values(breakdown.byChunk).reduce(\n (sum, entry) => sum + entry.classes.length,\n 0,\n );\n\n if (log) {\n console.group('🧩 Style Chunk Breakdown');\n\n // Define display order matching CHUNK_NAMES\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n\n // Show chunks in order\n for (const chunkName of displayOrder) {\n const data = breakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n // Show any unknown chunks\n for (const [chunkName, data] of Object.entries(breakdown.byChunk)) {\n if (\n !displayOrder.includes(chunkName as (typeof displayOrder)[number])\n ) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n console.log(\n `📊 Total: ${totalClasses} classes across ${breakdown.totalChunkTypes} chunk types`,\n );\n console.groupEnd();\n }\n\n return {\n ...breakdown,\n totalClasses,\n };\n },\n\n // 6) Get CSS for specific global types\n getGlobalTypeCSS(\n type: 'global' | 'raw' | 'keyframes' | 'property',\n opts?: { root?: Document | ShadowRoot },\n ): { css: string; ruleCount: number; size: number } {\n const { root = document } = opts || {};\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return { css: '', ruleCount: 0, size: 0 };\n }\n\n const cssChunks: string[] = [];\n let ruleCount = 0;\n\n if (type === 'keyframes') {\n // Handle keyframes separately - they're stored in keyframesCache\n for (const [, entry] of registry.keyframesCache) {\n const info = entry.info;\n const sheet = registry.sheets[info.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n\n if (styleSheet && info.ruleIndex < styleSheet.cssRules.length) {\n const rule = styleSheet.cssRules[info.ruleIndex] as\n | CSSRule\n | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n } else if (info.cssText) {\n cssChunks.push(info.cssText);\n ruleCount++;\n }\n }\n } else {\n // Handle other global types stored in globalRules\n const prefix =\n type === 'global' ? 'global:' : type === 'raw' ? 'raw:' : 'property:';\n\n for (const [key, ruleInfo] of registry.globalRules) {\n if (key.startsWith(prefix)) {\n const sheet = registry.sheets[ruleInfo.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n if (styleSheet) {\n const start = Math.max(0, ruleInfo.ruleIndex);\n const end = Math.min(\n styleSheet.cssRules.length - 1,\n (ruleInfo.endRuleIndex as number) ?? ruleInfo.ruleIndex,\n );\n\n if (\n start >= 0 &&\n end >= start &&\n start < styleSheet.cssRules.length\n ) {\n for (let i = start; i <= end; i++) {\n const rule = styleSheet.cssRules[i] as CSSRule | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n }\n }\n } else if (ruleInfo.cssText && ruleInfo.cssText.length) {\n // Fallback in environments without CSSOM access\n cssChunks.push(...ruleInfo.cssText);\n ruleCount += ruleInfo.cssText.length;\n }\n }\n }\n }\n\n const rawCSS = cssChunks.join('\\n');\n\n return {\n css: prettifyCSS(rawCSS),\n ruleCount,\n size: rawCSS.length, // Use raw CSS size for consistent calculations\n };\n },\n\n // 6) Defined @property and keyframes\n defs(opts?: { root?: Document | ShadowRoot }): Definitions {\n const { root = document } = opts || {};\n\n // Get properties from injector if available, otherwise scan CSS\n let properties: string[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry?.injectedProperties) {\n properties = Array.from(\n (registry.injectedProperties as Map<string, string>).keys(),\n ).sort();\n }\n } catch {\n // Fallback: scan CSS for @property rules\n const allCSS = injector.instance.getCssText({ root });\n const propRegex = /@property\\s+(--[a-z0-9-]+)/gi;\n const propSet = new Set<string>();\n let match;\n while ((match = propRegex.exec(allCSS)) !== null) {\n propSet.add(match[1]);\n }\n properties = Array.from(propSet).sort();\n }\n\n // Get keyframes\n let keyframes: { name: string; refCount: number }[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry) {\n for (const entry of registry.keyframesCache.values()) {\n keyframes.push({\n name: entry.name,\n refCount: entry.refCount,\n });\n }\n keyframes.sort((a, b) => a.name.localeCompare(b.name));\n }\n } catch {\n // Fallback: scan CSS for @keyframes rules\n const allCSS = injector.instance.getCssText({ root });\n const keyframesRegex = /@keyframes\\s+([a-zA-Z0-9_-]+)/gi;\n const keyframesSet = new Set<string>();\n let match;\n while ((match = keyframesRegex.exec(allCSS)) !== null) {\n keyframesSet.add(match[1]);\n }\n keyframes = Array.from(keyframesSet)\n .sort()\n .map((name) => ({ name, refCount: 1 }));\n }\n\n return { properties, keyframes };\n },\n\n // 7) One-shot overview\n summary(opts?: SummaryOptions): Summary {\n const { root = document, log = false, includePageCSS = false } = opts || {};\n const cacheStatus = this.cache({ root });\n const definitions = this.defs({ root });\n const metrics = this.metrics({ root });\n\n const activeCSS = this.css('active', { root, prettify: false });\n const unusedCSS = this.css('unused', { root, prettify: false });\n const allCSS = this.css('all', { root, prettify: false });\n\n // Calculate global CSS by subtracting class-based CSS from total\n const classCSSSize = activeCSS.length + unusedCSS.length;\n const totalGlobalCSSSize = allCSS.length - classCSSSize;\n\n // Get CSS for each global type separately for display purposes\n const globalData = this.getGlobalTypeCSS('global', { root });\n const rawData = this.getGlobalTypeCSS('raw', { root });\n const keyframesData = this.getGlobalTypeCSS('keyframes', { root });\n const propertyData = this.getGlobalTypeCSS('property', { root });\n\n // Use the calculated sizes to avoid double-counting\n const globalTypesTotalSize =\n globalData.size + rawData.size + keyframesData.size + propertyData.size;\n\n // Build cleanup summary from metrics\n const cleanupSummary = {\n enabled: !!metrics,\n totalCleanups: metrics?.cleanupHistory?.length || 0,\n totalClassesDeleted:\n metrics?.cleanupHistory?.reduce(\n (sum, c) => sum + c.classesDeleted,\n 0,\n ) || 0,\n totalCssDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.cssSize, 0) || 0,\n totalRulesDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.rulesDeleted, 0) ||\n 0,\n averageClassesPerCleanup: 0,\n averageCssPerCleanup: 0,\n averageRulesPerCleanup: 0,\n lastCleanup: undefined as (CleanupStats & { date: string }) | undefined,\n };\n\n if (cleanupSummary.totalCleanups > 0) {\n cleanupSummary.averageClassesPerCleanup =\n cleanupSummary.totalClassesDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageCssPerCleanup =\n cleanupSummary.totalCssDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageRulesPerCleanup =\n cleanupSummary.totalRulesDeleted / cleanupSummary.totalCleanups;\n\n const lastCleanup =\n metrics?.cleanupHistory?.[metrics.cleanupHistory.length - 1];\n if (lastCleanup) {\n cleanupSummary.lastCleanup = {\n ...lastCleanup,\n date: new Date(lastCleanup.timestamp).toISOString(),\n };\n }\n }\n\n let page: Summary['page'] | undefined;\n if (includePageCSS) {\n const pageStats = getPageStats({ root, includeCrossOrigin: true });\n page = {\n ...pageStats,\n css:\n includePageCSS === 'all'\n ? getPageCSS({ root, includeCrossOrigin: true })\n : undefined,\n };\n }\n\n // If individual extraction matches total, use individual sizes\n // Otherwise, proportionally scale the individual sizes to match the total\n const useIndividualSizes =\n Math.abs(globalTypesTotalSize - totalGlobalCSSSize) < 100;\n\n let adjustedGlobalSizes;\n if (useIndividualSizes) {\n adjustedGlobalSizes = {\n globalCSSSize: globalData.size,\n rawCSSSize: rawData.size,\n keyframesCSSSize: keyframesData.size,\n propertyCSSSize: propertyData.size,\n };\n } else {\n // Scale proportionally to match the actual total\n const scaleFactor = totalGlobalCSSSize / globalTypesTotalSize;\n adjustedGlobalSizes = {\n globalCSSSize: Math.round(globalData.size * scaleFactor),\n rawCSSSize: Math.round(rawData.size * scaleFactor),\n keyframesCSSSize: Math.round(keyframesData.size * scaleFactor),\n propertyCSSSize: Math.round(propertyData.size * scaleFactor),\n };\n }\n\n // Get chunk breakdown\n const chunkBreakdown = getChunkBreakdown(root);\n\n const summary: Summary = {\n activeClasses: cacheStatus.classes.active,\n unusedClasses: cacheStatus.classes.unused,\n totalStyledClasses: cacheStatus.classes.all,\n activeCSSSize: activeCSS.length,\n unusedCSSSize: unusedCSS.length,\n ...adjustedGlobalSizes,\n totalCSSSize: allCSS.length,\n activeCSS: prettifyCSS(activeCSS),\n unusedCSS: prettifyCSS(unusedCSS),\n globalCSS: globalData.css,\n rawCSS: rawData.css,\n keyframesCSS: keyframesData.css,\n propertyCSS: propertyData.css,\n allCSS: prettifyCSS(allCSS),\n globalRuleCount: globalData.ruleCount,\n rawRuleCount: rawData.ruleCount,\n keyframesRuleCount: keyframesData.ruleCount,\n propertyRuleCount: propertyData.ruleCount,\n page,\n metrics,\n definedProperties: definitions.properties,\n definedKeyframes: definitions.keyframes,\n propertyCount: definitions.properties.length,\n keyframeCount: definitions.keyframes.length,\n cleanupSummary,\n chunkBreakdown,\n };\n\n if (log) {\n console.group('🎨 Comprehensive Tasty Debug Summary');\n console.log(`📊 Style Cache Status:`);\n console.log(\n ` • Active classes (in DOM): ${summary.activeClasses.length}`,\n );\n console.log(\n ` • Unused classes (refCount = 0): ${summary.unusedClasses.length}`,\n );\n console.log(\n ` • Total styled classes: ${summary.totalStyledClasses.length}`,\n );\n console.log(`💾 CSS Size:`);\n console.log(` • Active CSS: ${summary.activeCSSSize} characters`);\n console.log(` • Unused CSS: ${summary.unusedCSSSize} characters`);\n console.log(\n ` • Global CSS (injectGlobal): ${summary.globalCSSSize} characters (${summary.globalRuleCount} rules)`,\n );\n console.log(\n ` • Raw CSS (injectRawCSS/useRawCSS): ${summary.rawCSSSize} characters (${summary.rawRuleCount} rules)`,\n );\n console.log(\n ` • Keyframes CSS: ${summary.keyframesCSSSize} characters (${summary.keyframesRuleCount} rules)`,\n );\n console.log(\n ` • Property CSS: ${summary.propertyCSSSize} characters (${summary.propertyRuleCount} rules)`,\n );\n\n // Show breakdown calculation\n const calculatedTotal =\n summary.activeCSSSize +\n summary.unusedCSSSize +\n summary.globalCSSSize +\n summary.rawCSSSize +\n summary.keyframesCSSSize +\n summary.propertyCSSSize;\n console.log(` • Calculated Total: ${calculatedTotal} characters`);\n console.log(` • Actual Total: ${summary.totalCSSSize} characters`);\n\n const difference = Math.abs(calculatedTotal - summary.totalCSSSize);\n if (difference > 100) {\n console.warn(\n ` ⚠️ Size mismatch: ${difference} characters difference`,\n );\n\n // Debug: show what might be missing\n console.group('🔍 Debugging size mismatch:');\n console.log(\n `Active + Unused = ${summary.activeCSSSize + summary.unusedCSSSize}`,\n );\n console.log(\n `All Global Types = ${summary.globalCSSSize + summary.rawCSSSize + summary.keyframesCSSSize + summary.propertyCSSSize}`,\n );\n console.log(\n `Class-based vs Total difference = ${summary.totalCSSSize - (summary.activeCSSSize + summary.unusedCSSSize)}`,\n );\n\n // Show scaling information\n console.log(`Raw global extraction total: ${globalTypesTotalSize}`);\n console.log(`Calculated global size: ${totalGlobalCSSSize}`);\n console.log(`Used individual sizes: ${useIndividualSizes}`);\n if (!useIndividualSizes) {\n console.log(\n `Scale factor applied: ${(totalGlobalCSSSize / globalTypesTotalSize).toFixed(3)}`,\n );\n }\n console.groupEnd();\n }\n\n if (page) {\n console.log(`📄 Page CSS:`);\n console.log(` • Total page CSS: ${page.cssSize} characters`);\n console.log(` • Total page rules: ${page.ruleCount}`);\n console.log(\n ` • Stylesheets: ${page.stylesheetCount} (${page.skippedStylesheets} skipped)`,\n );\n }\n\n console.log('🏷️ Properties & Keyframes:');\n console.log(` • Defined @property: ${summary.propertyCount}`);\n console.log(` • Defined @keyframes: ${summary.keyframeCount}`);\n\n if (metrics) {\n console.log(`⚡ Performance Metrics:`);\n console.log(` • Cache hits: ${metrics.hits}`);\n console.log(` • Cache misses: ${metrics.misses}`);\n console.log(` • Cached style reuses: ${metrics.unusedHits}`);\n const hitRate =\n metrics.hits + metrics.misses > 0\n ? (\n ((metrics.hits + (metrics.unusedHits || 0)) /\n (metrics.hits + metrics.misses)) *\n 100\n ).toFixed(1)\n : '0';\n console.log(` • Overall cache hit rate: ${hitRate}%`);\n }\n\n // Show chunk breakdown\n if (summary.chunkBreakdown.totalChunkTypes > 0) {\n console.log('🧩 Style Chunk Breakdown:');\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n for (const chunkName of displayOrder) {\n const data = summary.chunkBreakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n }\n\n console.log('🔍 Details:');\n console.log(' • Active classes:', summary.activeClasses);\n console.log(' • Unused classes:', summary.unusedClasses);\n console.groupEnd();\n }\n\n return summary;\n },\n\n // 8) Page-level CSS helpers\n pageCSS(opts?: {\n root?: Document | ShadowRoot;\n prettify?: boolean;\n log?: boolean;\n includeCrossOrigin?: boolean;\n }): string {\n const {\n root = document,\n prettify = true,\n log = false,\n includeCrossOrigin = true,\n } = opts || {};\n const css = getPageCSS({ root, includeCrossOrigin });\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group('📄 Page CSS (All Stylesheets)');\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n pageStats(opts?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n }): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n } {\n const { root = document, includeCrossOrigin = true } = opts || {};\n return getPageStats({ root, includeCrossOrigin });\n },\n\n // 9) Install globally\n install(): void {\n if (typeof window !== 'undefined' && window.tastyDebug !== tastyDebug) {\n window.tastyDebug = tastyDebug;\n console.log(\n '🎨 tastyDebug installed on window. Run tastyDebug.help() for quick start guide.',\n );\n }\n },\n\n // 10) Beautiful console logging with collapsible CSS\n log(target: CSSTarget, opts?: CssOptions & { title?: string }): void {\n const { title, ...cssOpts } = opts || {};\n const css = tastyDebug.css(target, cssOpts);\n\n if (!css.trim()) {\n console.warn(`🎨 No CSS found for target: ${String(target)}`);\n return;\n }\n\n const targetStr = Array.isArray(target)\n ? target.join(', ')\n : String(target);\n const displayTitle = title || `CSS for \"${targetStr}\"`;\n\n // Get some stats about the CSS\n const lines = css.split('\\n').length;\n const size = new Blob([css]).size;\n const sizeStr = size > 1024 ? `${(size / 1024).toFixed(1)}KB` : `${size}B`;\n\n // Count CSS rules (blocks with opening braces)\n const ruleCount = (css.match(/\\{/g) || []).length;\n\n console.group(\n `🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`,\n );\n\n // Detect sub-elements in CSS\n const subElementMatches = css.match(/\\[data-element=\"([^\"]+)\"\\]/g) || [];\n const subElements = [\n ...new Set(\n subElementMatches\n .map((match) => match.match(/\\[data-element=\"([^\"]+)\"\\]/)?.[1])\n .filter(Boolean),\n ),\n ];\n\n if (subElements.length > 0) {\n console.log(`🧩 Sub-elements found: ${subElements.join(', ')}`);\n\n // Show stats and CSS for each sub-element\n subElements.forEach((element) => {\n const _elementSelector = `[data-element=\"${element}\"]`;\n const elementRegex = new RegExp(\n `[^}]*\\\\[data-element=\"${element.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\"\\\\][^{]*\\\\{[^}]*\\\\}`,\n 'gm',\n );\n const elementCSS = (css.match(elementRegex) || []).join('\\n');\n\n if (elementCSS) {\n const elementRules = (elementCSS.match(/\\{/g) || []).length;\n const elementLines = elementCSS.split('\\n').length;\n const elementSize = new Blob([elementCSS]).size;\n const elementSizeStr =\n elementSize > 1024\n ? `${(elementSize / 1024).toFixed(1)}KB`\n : `${elementSize}B`;\n\n console.groupCollapsed(\n `🧩 ${element} (${elementRules} rules, ${elementLines} lines, ${elementSizeStr})`,\n );\n console.log(\n `%c${elementCSS}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n }\n });\n }\n\n // Full CSS in collapsible group (hidden by default)\n console.groupCollapsed('📄 Full CSS (click to expand)');\n console.log(\n `%c${css}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n\n console.groupEnd();\n },\n\n // 12) Show help and usage examples\n help(): void {\n console.group('🎨 tastyDebug - Quick Start Guide');\n console.log('💡 Essential commands:');\n console.log(\n ' • tastyDebug.summary({ log: true }) - comprehensive overview',\n );\n console.log(' • tastyDebug.chunks({ log: true }) - style chunk breakdown');\n console.log(' • tastyDebug.log(\"active\") - beautiful CSS display');\n console.log(' • tastyDebug.css(\"active\") - get active CSS');\n console.log(\n ' • tastyDebug.inspect(\".my-element\") - element inspection with chunk info',\n );\n console.log(' • tastyDebug.cache() - cache status');\n console.log(' • tastyDebug.defs() - defined properties & keyframes');\n console.log(' • tastyDebug.pageCSS({ log: true }) - all page CSS');\n console.log('');\n console.log('📖 Common targets for css()/log():');\n console.log(' • \"all\" - all tasty CSS + global CSS');\n console.log(' • \"active\" - CSS for classes in DOM');\n console.log(' • \"unused\" - CSS for classes with refCount = 0');\n console.log(' • \"global\" - only global CSS (injectGlobal)');\n console.log(' • \"page\" - ALL page CSS (including non-tasty)');\n console.log(' • \"t123\" - specific tasty class');\n console.log(' • [\".my-selector\"] - CSS selector');\n console.log('');\n console.log('🔧 Available options:');\n console.log(' • { log: true } - auto-log results to console');\n console.log(' • { title: \"Custom\" } - custom title for log()');\n console.log(' • { root: shadowRoot } - target Shadow DOM');\n console.log(' • { prettify: false } - skip CSS formatting');\n console.log('');\n console.log('🧩 Style Chunking:');\n console.log(\n ' Elements have multiple classes (one per chunk: appearance, font, dimension, etc.)',\n );\n console.log(\n ' • tastyDebug.chunks({ log: true }) - breakdown by chunk type',\n );\n console.log(\n ' • tastyDebug.inspect() - shows which chunk each class belongs to',\n );\n console.log(\n ' Chunk types: combined (non-chunked), appearance, font, dimension, container, scrollbar, position, misc, subcomponents',\n );\n console.groupEnd();\n },\n};\n\n/**\n * Auto-install in development\n */\nif (typeof window !== 'undefined' && isDevEnv()) {\n tastyDebug.install();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"debug.js","names":[],"sources":["../src/debug.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Debug utilities for inspecting tasty-generated CSS at runtime\n */\n\nimport { CHUNK_NAMES } from './chunks/definitions';\nimport { getCssTextForNode, injector } from './injector';\nimport type { CleanupStats } from './injector/types';\nimport { isDevEnv } from './utils/is-dev-env';\n\ndeclare global {\n interface Window {\n tastyDebug?: typeof tastyDebug;\n }\n}\n\n// Type definitions for the new API\ntype CSSTarget =\n | 'all' // tasty CSS + tasty global CSS + raw CSS\n | 'global' // only tasty global CSS\n | 'active' // tasty CSS for classes currently in DOM\n | 'unused' // tasty CSS with refCount = 0 (still in cache but not actively used)\n | 'page' // ALL CSS on the page across stylesheets (not only tasty)\n | string // 't123' tasty class or a CSS selector\n | string[] // array of tasty classes like ['t1', 't2']\n | Element; // a DOM element\n\ninterface CssOptions {\n root?: Document | ShadowRoot;\n prettify?: boolean; // default: true\n log?: boolean; // default: false\n}\n\ninterface ChunkInfo {\n className: string;\n chunkName: string | null;\n}\n\ninterface InspectResult {\n element?: Element | null;\n classes: string[]; // tasty classes found on the element\n chunks: ChunkInfo[]; // chunk information per class (with chunking enabled)\n css: string; // full, prettified CSS affecting the element\n size: number; // characters in css\n rules: number; // number of rule blocks\n}\n\ninterface CacheMetrics {\n hits: number;\n misses: number;\n bulkCleanups: number;\n totalInsertions: number;\n totalUnused: number;\n stylesCleanedUp: number;\n cleanupHistory: {\n timestamp: number;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n }[];\n startTime: number;\n\n // Calculated metrics\n unusedHits?: number; // calculated as current unused count\n}\n\ninterface CacheStatus {\n classes: {\n active: string[]; // classes with refCount > 0 and present in DOM\n unused: string[]; // classes with refCount = 0 but still in cache\n all: string[]; // union of both\n };\n metrics: CacheMetrics | null;\n}\n\ninterface Definitions {\n properties: string[]; // defined via @property\n keyframes: { name: string; refCount: number }[];\n}\n\ninterface SummaryOptions {\n root?: Document | ShadowRoot;\n log?: boolean;\n includePageCSS?:\n | false // do not include page-level CSS stats (default)\n | true // include sizes/counts only\n | 'all'; // include stats and return full page CSS string\n}\n\ninterface Summary {\n // Classes\n activeClasses: string[];\n unusedClasses: string[];\n totalStyledClasses: string[];\n\n // Tasty CSS sizes\n activeCSSSize: number;\n unusedCSSSize: number;\n globalCSSSize: number; // injectGlobal() CSS\n rawCSSSize: number; // injectRawCSS() / useRawCSS() CSS\n keyframesCSSSize: number; // @keyframes CSS\n propertyCSSSize: number; // @property CSS\n totalCSSSize: number; // all tasty CSS (active + unused + global + raw + keyframes + property)\n\n // Tasty CSS payloads\n activeCSS: string;\n unusedCSS: string;\n globalCSS: string; // injectGlobal() CSS\n rawCSS: string; // injectRawCSS() / useRawCSS() CSS\n keyframesCSS: string; // @keyframes CSS\n propertyCSS: string; // @property CSS\n allCSS: string; // all tasty CSS combined\n\n // Rule counts\n globalRuleCount: number;\n rawRuleCount: number;\n keyframesRuleCount: number;\n propertyRuleCount: number;\n\n // Page-level CSS (across all stylesheets, not only tasty) — shown when includePageCSS != false\n page?: {\n css?: string; // present only when includePageCSS === 'all'\n cssSize: number; // total characters\n ruleCount: number; // approximate rule count\n stylesheetCount: number; // stylesheets scanned (CORS-safe)\n skippedStylesheets: number; // stylesheets skipped due to cross-origin/CORS\n };\n\n // Metrics & definitions\n metrics: CacheMetrics | null;\n definedProperties: string[];\n definedKeyframes: { name: string; refCount: number }[];\n propertyCount: number;\n keyframeCount: number;\n\n // Cleanup summary\n cleanupSummary: {\n enabled: boolean;\n totalCleanups: number;\n totalClassesDeleted: number;\n totalCssDeleted: number;\n totalRulesDeleted: number;\n averageClassesPerCleanup: number;\n averageCssPerCleanup: number;\n averageRulesPerCleanup: number;\n lastCleanup?: {\n timestamp: number;\n date: string;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n };\n };\n\n // Chunk breakdown (style chunking optimization)\n chunkBreakdown: {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n };\n}\n\n/**\n * Pretty-print CSS with proper indentation and formatting\n */\nfunction prettifyCSS(css: string): string {\n if (!css || css.trim() === '') {\n return '';\n }\n\n // First, normalize whitespace but preserve structure\n let formatted = css.replace(/\\s+/g, ' ').trim();\n\n // Add newlines after opening braces\n formatted = formatted.replace(/\\s*\\{\\s*/g, ' {\\n');\n\n // Add newlines after semicolons (but not inside strings or functions)\n formatted = formatted.replace(/;(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))/g, ';\\n');\n\n // Add newlines before closing braces\n formatted = formatted.replace(/\\s*\\}\\s*/g, '\\n}\\n');\n\n // Handle comma-separated selectors (only outside of property values)\n // This regex looks for commas that are:\n // 1. Not inside quotes\n // 2. Not inside parentheses (CSS functions)\n // 3. Not followed by a colon (not in a property value)\n formatted = formatted.replace(\n /,(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))(?=.*:.*\\{|.*\\{)/g,\n ',\\n',\n );\n\n // Process line by line for proper indentation\n const lines = formatted.split('\\n');\n let indentLevel = 0;\n const indentSize = 2;\n\n const formattedLines = lines.map((line) => {\n const trimmed = line.trim();\n if (!trimmed) return '';\n\n // Handle closing braces - decrease indent first\n if (trimmed === '}') {\n indentLevel = Math.max(0, indentLevel - 1);\n return ' '.repeat(indentLevel * indentSize) + trimmed;\n }\n\n // Current line with proper indentation\n const indent = ' '.repeat(indentLevel * indentSize);\n const result = indent + trimmed;\n\n // Handle opening braces - increase indent for next line\n if (trimmed.endsWith('{')) {\n indentLevel++;\n }\n\n return result;\n });\n\n // Clean up the result and ensure proper spacing\n let result = formattedLines\n .filter((line) => line.trim()) // Remove empty lines\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n') // Max 2 consecutive newlines\n .trim();\n\n // Final cleanup: ensure single spaces in function calls\n result = result.replace(/,\\s+/g, ', ');\n\n return result;\n}\n\n// Helper functions\nfunction findAllTastyClasses(root: Document | ShadowRoot = document): string[] {\n const classes = new Set<string>();\n const elements = (root as Document).querySelectorAll?.('[class]') || [];\n\n elements.forEach((element) => {\n const classList = element.getAttribute('class');\n if (classList) {\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n tastyClasses.forEach((cls) => classes.add(cls));\n }\n });\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction findAllStyledClasses(\n root: Document | ShadowRoot = document,\n): string[] {\n // Extract tasty classes from all CSS text by parsing selectors\n const allCSS = injector.instance.getCssText({ root });\n const classes = new Set<string>();\n\n // Simple regex to find .t{number} class selectors\n const classRegex = /\\.t(\\d+)/g;\n let match;\n while ((match = classRegex.exec(allCSS)) !== null) {\n classes.add(`t${match[1]}`);\n }\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction extractCSSRules(\n css: string,\n): { selector: string; declarations: string }[] {\n const rules: { selector: string; declarations: string }[] = [];\n\n // Remove comments\n const cleanCSS = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n let i = 0;\n while (i < cleanCSS.length) {\n // Skip whitespace\n while (i < cleanCSS.length && /\\s/.test(cleanCSS[i])) {\n i++;\n }\n if (i >= cleanCSS.length) break;\n\n // Find selector start\n const selectorStart = i;\n let braceDepth = 0;\n let inString = false;\n let stringChar = '';\n\n // Find opening brace\n while (i < cleanCSS.length) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n if (braceDepth === 1) break;\n }\n }\n i++;\n }\n\n if (i >= cleanCSS.length) break;\n const selector = cleanCSS.substring(selectorStart, i).trim();\n i++; // Skip opening brace\n\n // Find matching closing brace\n const contentStart = i;\n braceDepth = 1;\n inString = false;\n\n while (i < cleanCSS.length && braceDepth > 0) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n } else if (char === '}') {\n braceDepth--;\n }\n }\n i++;\n }\n\n const content = cleanCSS.substring(contentStart, i - 1).trim();\n if (content && selector) {\n rules.push({ selector, declarations: content });\n }\n }\n\n return rules;\n}\n\nfunction getGlobalCSS(root: Document | ShadowRoot = document): string {\n const allCSS = injector.instance.getCssText({ root });\n const rules = extractCSSRules(allCSS);\n\n const globalRules = rules.filter((rule) => {\n const selectors = rule.selector.split(',').map((s) => s.trim());\n return !selectors.every((selector) => {\n const cleanSelector = selector.replace(/[.#:\\s>+~[\\]()]/g, ' ');\n const parts = cleanSelector.split(/\\s+/).filter(Boolean);\n return parts.length > 0 && parts.every((part) => /^t\\d+$/.test(part));\n });\n });\n\n const globalCSS = globalRules\n .map((rule) => `${rule.selector} { ${rule.declarations} }`)\n .join('\\n');\n return prettifyCSS(globalCSS);\n}\n\nfunction getPageCSS(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): string {\n const root = options?.root || document;\n const includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n const cssChunks: string[] = [];\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n cssChunks.push(rules.map((rule) => rule.cssText).join('\\n'));\n }\n } catch {\n // Cross-origin sheet or other access error\n if (includeCrossOrigin) {\n cssChunks.push(\n `/* Cross-origin stylesheet: ${sheet.href || 'inline'} */`,\n );\n }\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return cssChunks.join('\\n');\n}\n\nfunction getPageStats(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n} {\n const root = options?.root || document;\n\n const _includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n let cssSize = 0;\n let ruleCount = 0;\n let stylesheetCount = 0;\n let skippedStylesheets = 0;\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n stylesheetCount = styleSheets.length;\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n ruleCount += rules.length;\n cssSize += rules.reduce(\n (sum, rule) => sum + rule.cssText.length,\n 0,\n );\n }\n } catch {\n skippedStylesheets++;\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return { cssSize, ruleCount, stylesheetCount, skippedStylesheets };\n}\n\n// ============================================================================\n// Chunk-aware helpers (for style chunking optimization)\n// ============================================================================\n\n/**\n * Extract chunk name from a cache key.\n *\n * Cache keys have the format: \"chunkName\\0key:value\\0key:value...\"\n * or \"[states:...]\\0chunkName\\0...\" for predefined states.\n *\n * @param cacheKey - The cache key to parse\n * @returns The chunk name, or null if not found\n */\nfunction extractChunkNameFromCacheKey(cacheKey: string): string | null {\n // Cache keys are separated by \\0 (null character)\n const parts = cacheKey.split('\\0');\n\n for (const part of parts) {\n // Skip predefined states prefix\n if (part.startsWith('[states:')) continue;\n // First non-states part that doesn't contain : is the chunk name\n if (!part.includes(':') && part.length > 0) {\n return part;\n }\n }\n return null;\n}\n\n/**\n * Get chunk info for a className by reverse-looking up its cache key.\n *\n * @param className - The tasty class name (e.g., \"t0\", \"t123\")\n * @param root - The document or shadow root to search in\n * @returns Object with chunk name and cache key, or nulls if not found\n */\nfunction getChunkForClassName(\n className: string,\n root: Document | ShadowRoot = document,\n): { chunkName: string | null; cacheKey: string | null } {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (!registry) {\n return { chunkName: null, cacheKey: null };\n }\n\n // Reverse lookup: find the cache key for this className\n for (const [cacheKey, cn] of registry.cacheKeyToClassName) {\n if (cn === className) {\n return {\n chunkName: extractChunkNameFromCacheKey(cacheKey),\n cacheKey,\n };\n }\n }\n return { chunkName: null, cacheKey: null };\n}\n\n/**\n * Get chunk breakdown statistics for all styles.\n *\n * @param root - The document or shadow root to search in\n * @returns Object with breakdown by chunk type and totals\n */\nfunction getChunkBreakdown(root: Document | ShadowRoot = document): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n} {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return {\n byChunk: {},\n totalChunkTypes: 0,\n };\n }\n\n const byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n > = {};\n\n // Group classes by chunk\n for (const [cacheKey, className] of registry.cacheKeyToClassName) {\n const chunkName = extractChunkNameFromCacheKey(cacheKey) || 'unknown';\n\n if (!byChunk[chunkName]) {\n byChunk[chunkName] = { classes: [], cssSize: 0, ruleCount: 0 };\n }\n\n byChunk[chunkName].classes.push(className);\n\n // Get CSS for this class\n const css = injector.instance.getCssTextForClasses([className], { root });\n byChunk[chunkName].cssSize += css.length;\n byChunk[chunkName].ruleCount += (css.match(/\\{[^}]*\\}/g) || []).length;\n }\n\n // Sort classes within each chunk for consistency\n for (const entry of Object.values(byChunk)) {\n entry.classes.sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n }\n\n return {\n byChunk,\n totalChunkTypes: Object.keys(byChunk).length,\n };\n}\n\n/**\n * Concise tastyDebug API for inspecting styles at runtime\n */\nexport const tastyDebug = {\n // 1) One function to get CSS from anywhere\n css(target: CSSTarget, opts?: CssOptions): string {\n const { root = document, prettify = true, log = false } = opts || {};\n let css = '';\n\n if (typeof target === 'string') {\n if (target === 'all') {\n css = injector.instance.getCssText({ root });\n } else if (target === 'global') {\n css = getGlobalCSS(root);\n } else if (target === 'active') {\n const activeClasses = findAllTastyClasses(root);\n css = injector.instance.getCssTextForClasses(activeClasses, { root });\n } else if (target === 'unused') {\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<\n [string, number]\n >,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n css = injector.instance.getCssTextForClasses(unusedClasses, { root });\n } else if (target === 'page') {\n css = getPageCSS({ root, includeCrossOrigin: true });\n } else if (/^t\\d+$/.test(target)) {\n // Single tasty class\n css = injector.instance.getCssTextForClasses([target], { root });\n } else {\n // CSS selector - find element and get its CSS\n const element = (root as Document).querySelector?.(target);\n if (element) {\n css = getCssTextForNode(element, { root });\n }\n }\n } else if (Array.isArray(target)) {\n // Array of tasty classes\n css = injector.instance.getCssTextForClasses(target, { root });\n } else if (target instanceof Element) {\n // DOM element\n css = getCssTextForNode(target, { root });\n }\n\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group(\n `🎨 CSS for ${Array.isArray(target) ? `[${target.join(', ')}]` : target}`,\n );\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n // 2) Element-level inspection\n inspect(\n target: string | Element,\n opts?: { root?: Document | ShadowRoot },\n ): InspectResult {\n const { root = document } = opts || {};\n const element =\n typeof target === 'string'\n ? (root as Document).querySelector?.(target)\n : target;\n\n if (!element) {\n return {\n element: null,\n classes: [],\n chunks: [],\n css: '',\n size: 0,\n rules: 0,\n };\n }\n\n const classList = element.getAttribute('class') || '';\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n\n // Get chunk info for each tasty class\n const chunks: ChunkInfo[] = tastyClasses.map((className) => ({\n className,\n chunkName: getChunkForClassName(className, root).chunkName,\n }));\n\n const css = getCssTextForNode(element, { root });\n const prettifiedCSS = prettifyCSS(css);\n const ruleCount = (css.match(/\\{[^}]*\\}/g) || []).length;\n\n return {\n element,\n classes: tastyClasses,\n chunks,\n css: prettifiedCSS,\n size: css.length,\n rules: ruleCount,\n };\n },\n\n // 3) Cache + metrics at a glance\n cache(opts?: {\n root?: Document | ShadowRoot;\n includeHistory?: boolean;\n }): CacheStatus {\n const { root = document } = opts || {};\n const activeClasses = findAllTastyClasses(root);\n\n const _allClasses = findAllStyledClasses(root);\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<[string, number]>,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n\n return {\n classes: {\n active: activeClasses,\n unused: unusedClasses,\n all: [...activeClasses, ...unusedClasses],\n },\n metrics: injector.instance.getMetrics({ root }),\n };\n },\n\n // 4) Cleanup + metrics utilities\n cleanup(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.cleanup(root);\n },\n\n metrics(opts?: { root?: Document | ShadowRoot }): CacheMetrics | null {\n const { root } = opts || {};\n return injector.instance.getMetrics({ root });\n },\n\n resetMetrics(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.resetMetrics({ root });\n },\n\n // 5) Chunk breakdown (style chunking optimization)\n /**\n * Get breakdown of styles by chunk type.\n *\n * With style chunking enabled, styles are split into logical chunks\n * (appearance, font, dimension, container, etc.) for better caching\n * and CSS reuse.\n *\n * @param opts - Options including root document/shadow root\n * @returns Breakdown by chunk type with class counts and CSS sizes\n */\n chunks(opts?: { root?: Document | ShadowRoot; log?: boolean }): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n totalClasses: number;\n } {\n const { root = document, log = false } = opts || {};\n const breakdown = getChunkBreakdown(root);\n\n const totalClasses = Object.values(breakdown.byChunk).reduce(\n (sum, entry) => sum + entry.classes.length,\n 0,\n );\n\n if (log) {\n console.group('🧩 Style Chunk Breakdown');\n\n // Define display order matching CHUNK_NAMES\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n\n // Show chunks in order\n for (const chunkName of displayOrder) {\n const data = breakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n // Show any unknown chunks\n for (const [chunkName, data] of Object.entries(breakdown.byChunk)) {\n if (\n !displayOrder.includes(chunkName as (typeof displayOrder)[number])\n ) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n console.log(\n `📊 Total: ${totalClasses} classes across ${breakdown.totalChunkTypes} chunk types`,\n );\n console.groupEnd();\n }\n\n return {\n ...breakdown,\n totalClasses,\n };\n },\n\n // 6) Get CSS for specific global types\n getGlobalTypeCSS(\n type: 'global' | 'raw' | 'keyframes' | 'property',\n opts?: { root?: Document | ShadowRoot },\n ): { css: string; ruleCount: number; size: number } {\n const { root = document } = opts || {};\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return { css: '', ruleCount: 0, size: 0 };\n }\n\n const cssChunks: string[] = [];\n let ruleCount = 0;\n\n if (type === 'keyframes') {\n // Handle keyframes separately - they're stored in keyframesCache\n for (const [, entry] of registry.keyframesCache) {\n const info = entry.info;\n const sheet = registry.sheets[info.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n\n if (styleSheet && info.ruleIndex < styleSheet.cssRules.length) {\n const rule = styleSheet.cssRules[info.ruleIndex] as\n | CSSRule\n | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n } else if (info.cssText) {\n cssChunks.push(info.cssText);\n ruleCount++;\n }\n }\n } else {\n // Handle other global types stored in globalRules\n const prefix =\n type === 'global' ? 'global:' : type === 'raw' ? 'raw:' : 'property:';\n\n for (const [key, ruleInfo] of registry.globalRules) {\n if (key.startsWith(prefix)) {\n const sheet = registry.sheets[ruleInfo.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n if (styleSheet) {\n const start = Math.max(0, ruleInfo.ruleIndex);\n const end = Math.min(\n styleSheet.cssRules.length - 1,\n (ruleInfo.endRuleIndex as number) ?? ruleInfo.ruleIndex,\n );\n\n if (\n start >= 0 &&\n end >= start &&\n start < styleSheet.cssRules.length\n ) {\n for (let i = start; i <= end; i++) {\n const rule = styleSheet.cssRules[i] as CSSRule | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n }\n }\n } else if (ruleInfo.cssText && ruleInfo.cssText.length) {\n // Fallback in environments without CSSOM access\n cssChunks.push(...ruleInfo.cssText);\n ruleCount += ruleInfo.cssText.length;\n }\n }\n }\n }\n\n const rawCSS = cssChunks.join('\\n');\n\n return {\n css: prettifyCSS(rawCSS),\n ruleCount,\n size: rawCSS.length, // Use raw CSS size for consistent calculations\n };\n },\n\n // 6) Defined @property and keyframes\n defs(opts?: { root?: Document | ShadowRoot }): Definitions {\n const { root = document } = opts || {};\n\n // Get properties from injector if available, otherwise scan CSS\n let properties: string[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry?.injectedProperties) {\n properties = Array.from(\n (registry.injectedProperties as Map<string, string>).keys(),\n ).sort();\n }\n } catch {\n // Fallback: scan CSS for @property rules\n const allCSS = injector.instance.getCssText({ root });\n const propRegex = /@property\\s+(--[a-z0-9-]+)/gi;\n const propSet = new Set<string>();\n let match;\n while ((match = propRegex.exec(allCSS)) !== null) {\n propSet.add(match[1]);\n }\n properties = Array.from(propSet).sort();\n }\n\n // Get keyframes\n let keyframes: { name: string; refCount: number }[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry) {\n for (const entry of registry.keyframesCache.values()) {\n keyframes.push({\n name: entry.name,\n refCount: entry.refCount,\n });\n }\n keyframes.sort((a, b) => a.name.localeCompare(b.name));\n }\n } catch {\n // Fallback: scan CSS for @keyframes rules\n const allCSS = injector.instance.getCssText({ root });\n const keyframesRegex = /@keyframes\\s+([a-zA-Z0-9_-]+)/gi;\n const keyframesSet = new Set<string>();\n let match;\n while ((match = keyframesRegex.exec(allCSS)) !== null) {\n keyframesSet.add(match[1]);\n }\n keyframes = Array.from(keyframesSet)\n .sort()\n .map((name) => ({ name, refCount: 1 }));\n }\n\n return { properties, keyframes };\n },\n\n // 7) One-shot overview\n summary(opts?: SummaryOptions): Summary {\n const { root = document, log = false, includePageCSS = false } = opts || {};\n const cacheStatus = this.cache({ root });\n const definitions = this.defs({ root });\n const metrics = this.metrics({ root });\n\n const activeCSS = this.css('active', { root, prettify: false });\n const unusedCSS = this.css('unused', { root, prettify: false });\n const allCSS = this.css('all', { root, prettify: false });\n\n // Calculate global CSS by subtracting class-based CSS from total\n const classCSSSize = activeCSS.length + unusedCSS.length;\n const totalGlobalCSSSize = allCSS.length - classCSSSize;\n\n // Get CSS for each global type separately for display purposes\n const globalData = this.getGlobalTypeCSS('global', { root });\n const rawData = this.getGlobalTypeCSS('raw', { root });\n const keyframesData = this.getGlobalTypeCSS('keyframes', { root });\n const propertyData = this.getGlobalTypeCSS('property', { root });\n\n // Use the calculated sizes to avoid double-counting\n const globalTypesTotalSize =\n globalData.size + rawData.size + keyframesData.size + propertyData.size;\n\n // Build cleanup summary from metrics\n const cleanupSummary = {\n enabled: !!metrics,\n totalCleanups: metrics?.cleanupHistory?.length || 0,\n totalClassesDeleted:\n metrics?.cleanupHistory?.reduce(\n (sum, c) => sum + c.classesDeleted,\n 0,\n ) || 0,\n totalCssDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.cssSize, 0) || 0,\n totalRulesDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.rulesDeleted, 0) ||\n 0,\n averageClassesPerCleanup: 0,\n averageCssPerCleanup: 0,\n averageRulesPerCleanup: 0,\n lastCleanup: undefined as (CleanupStats & { date: string }) | undefined,\n };\n\n if (cleanupSummary.totalCleanups > 0) {\n cleanupSummary.averageClassesPerCleanup =\n cleanupSummary.totalClassesDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageCssPerCleanup =\n cleanupSummary.totalCssDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageRulesPerCleanup =\n cleanupSummary.totalRulesDeleted / cleanupSummary.totalCleanups;\n\n const lastCleanup =\n metrics?.cleanupHistory?.[metrics.cleanupHistory.length - 1];\n if (lastCleanup) {\n cleanupSummary.lastCleanup = {\n ...lastCleanup,\n date: new Date(lastCleanup.timestamp).toISOString(),\n };\n }\n }\n\n let page: Summary['page'] | undefined;\n if (includePageCSS) {\n const pageStats = getPageStats({ root, includeCrossOrigin: true });\n page = {\n ...pageStats,\n css:\n includePageCSS === 'all'\n ? getPageCSS({ root, includeCrossOrigin: true })\n : undefined,\n };\n }\n\n // If individual extraction matches total, use individual sizes\n // Otherwise, proportionally scale the individual sizes to match the total\n const useIndividualSizes =\n Math.abs(globalTypesTotalSize - totalGlobalCSSSize) < 100;\n\n let adjustedGlobalSizes;\n if (useIndividualSizes) {\n adjustedGlobalSizes = {\n globalCSSSize: globalData.size,\n rawCSSSize: rawData.size,\n keyframesCSSSize: keyframesData.size,\n propertyCSSSize: propertyData.size,\n };\n } else {\n // Scale proportionally to match the actual total\n const scaleFactor = totalGlobalCSSSize / globalTypesTotalSize;\n adjustedGlobalSizes = {\n globalCSSSize: Math.round(globalData.size * scaleFactor),\n rawCSSSize: Math.round(rawData.size * scaleFactor),\n keyframesCSSSize: Math.round(keyframesData.size * scaleFactor),\n propertyCSSSize: Math.round(propertyData.size * scaleFactor),\n };\n }\n\n // Get chunk breakdown\n const chunkBreakdown = getChunkBreakdown(root);\n\n const summary: Summary = {\n activeClasses: cacheStatus.classes.active,\n unusedClasses: cacheStatus.classes.unused,\n totalStyledClasses: cacheStatus.classes.all,\n activeCSSSize: activeCSS.length,\n unusedCSSSize: unusedCSS.length,\n ...adjustedGlobalSizes,\n totalCSSSize: allCSS.length,\n activeCSS: prettifyCSS(activeCSS),\n unusedCSS: prettifyCSS(unusedCSS),\n globalCSS: globalData.css,\n rawCSS: rawData.css,\n keyframesCSS: keyframesData.css,\n propertyCSS: propertyData.css,\n allCSS: prettifyCSS(allCSS),\n globalRuleCount: globalData.ruleCount,\n rawRuleCount: rawData.ruleCount,\n keyframesRuleCount: keyframesData.ruleCount,\n propertyRuleCount: propertyData.ruleCount,\n page,\n metrics,\n definedProperties: definitions.properties,\n definedKeyframes: definitions.keyframes,\n propertyCount: definitions.properties.length,\n keyframeCount: definitions.keyframes.length,\n cleanupSummary,\n chunkBreakdown,\n };\n\n if (log) {\n console.group('🎨 Comprehensive Tasty Debug Summary');\n console.log(`📊 Style Cache Status:`);\n console.log(\n ` • Active classes (in DOM): ${summary.activeClasses.length}`,\n );\n console.log(\n ` • Unused classes (refCount = 0): ${summary.unusedClasses.length}`,\n );\n console.log(\n ` • Total styled classes: ${summary.totalStyledClasses.length}`,\n );\n console.log(`💾 CSS Size:`);\n console.log(` • Active CSS: ${summary.activeCSSSize} characters`);\n console.log(` • Unused CSS: ${summary.unusedCSSSize} characters`);\n console.log(\n ` • Global CSS (injectGlobal): ${summary.globalCSSSize} characters (${summary.globalRuleCount} rules)`,\n );\n console.log(\n ` • Raw CSS (injectRawCSS/useRawCSS): ${summary.rawCSSSize} characters (${summary.rawRuleCount} rules)`,\n );\n console.log(\n ` • Keyframes CSS: ${summary.keyframesCSSSize} characters (${summary.keyframesRuleCount} rules)`,\n );\n console.log(\n ` • Property CSS: ${summary.propertyCSSSize} characters (${summary.propertyRuleCount} rules)`,\n );\n\n // Show breakdown calculation\n const calculatedTotal =\n summary.activeCSSSize +\n summary.unusedCSSSize +\n summary.globalCSSSize +\n summary.rawCSSSize +\n summary.keyframesCSSSize +\n summary.propertyCSSSize;\n console.log(` • Calculated Total: ${calculatedTotal} characters`);\n console.log(` • Actual Total: ${summary.totalCSSSize} characters`);\n\n const difference = Math.abs(calculatedTotal - summary.totalCSSSize);\n if (difference > 100) {\n console.warn(\n ` ⚠️ Size mismatch: ${difference} characters difference`,\n );\n\n // Debug: show what might be missing\n console.group('🔍 Debugging size mismatch:');\n console.log(\n `Active + Unused = ${summary.activeCSSSize + summary.unusedCSSSize}`,\n );\n console.log(\n `All Global Types = ${summary.globalCSSSize + summary.rawCSSSize + summary.keyframesCSSSize + summary.propertyCSSSize}`,\n );\n console.log(\n `Class-based vs Total difference = ${summary.totalCSSSize - (summary.activeCSSSize + summary.unusedCSSSize)}`,\n );\n\n // Show scaling information\n console.log(`Raw global extraction total: ${globalTypesTotalSize}`);\n console.log(`Calculated global size: ${totalGlobalCSSSize}`);\n console.log(`Used individual sizes: ${useIndividualSizes}`);\n if (!useIndividualSizes) {\n console.log(\n `Scale factor applied: ${(totalGlobalCSSSize / globalTypesTotalSize).toFixed(3)}`,\n );\n }\n console.groupEnd();\n }\n\n if (page) {\n console.log(`📄 Page CSS:`);\n console.log(` • Total page CSS: ${page.cssSize} characters`);\n console.log(` • Total page rules: ${page.ruleCount}`);\n console.log(\n ` • Stylesheets: ${page.stylesheetCount} (${page.skippedStylesheets} skipped)`,\n );\n }\n\n console.log('🏷️ Properties & Keyframes:');\n console.log(` • Defined @property: ${summary.propertyCount}`);\n console.log(` • Defined @keyframes: ${summary.keyframeCount}`);\n\n if (metrics) {\n console.log(`⚡ Performance Metrics:`);\n console.log(` • Cache hits: ${metrics.hits}`);\n console.log(` • Cache misses: ${metrics.misses}`);\n console.log(` • Cached style reuses: ${metrics.unusedHits}`);\n const hitRate =\n metrics.hits + metrics.misses > 0\n ? (\n ((metrics.hits + (metrics.unusedHits || 0)) /\n (metrics.hits + metrics.misses)) *\n 100\n ).toFixed(1)\n : '0';\n console.log(` • Overall cache hit rate: ${hitRate}%`);\n }\n\n // Show chunk breakdown\n if (summary.chunkBreakdown.totalChunkTypes > 0) {\n console.log('🧩 Style Chunk Breakdown:');\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n for (const chunkName of displayOrder) {\n const data = summary.chunkBreakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n }\n\n console.log('🔍 Details:');\n console.log(' • Active classes:', summary.activeClasses);\n console.log(' • Unused classes:', summary.unusedClasses);\n console.groupEnd();\n }\n\n return summary;\n },\n\n // 8) Page-level CSS helpers\n pageCSS(opts?: {\n root?: Document | ShadowRoot;\n prettify?: boolean;\n log?: boolean;\n includeCrossOrigin?: boolean;\n }): string {\n const {\n root = document,\n prettify = true,\n log = false,\n includeCrossOrigin = true,\n } = opts || {};\n const css = getPageCSS({ root, includeCrossOrigin });\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group('📄 Page CSS (All Stylesheets)');\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n pageStats(opts?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n }): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n } {\n const { root = document, includeCrossOrigin = true } = opts || {};\n return getPageStats({ root, includeCrossOrigin });\n },\n\n // 9) Install globally\n install(): void {\n if (typeof window !== 'undefined' && window.tastyDebug !== tastyDebug) {\n window.tastyDebug = tastyDebug;\n console.log(\n '🎨 tastyDebug installed on window. Run tastyDebug.help() for quick start guide.',\n );\n }\n },\n\n // 10) Beautiful console logging with collapsible CSS\n log(target: CSSTarget, opts?: CssOptions & { title?: string }): void {\n const { title, ...cssOpts } = opts || {};\n const css = tastyDebug.css(target, cssOpts);\n\n if (!css.trim()) {\n console.warn(`🎨 No CSS found for target: ${String(target)}`);\n return;\n }\n\n const targetStr = Array.isArray(target)\n ? target.join(', ')\n : String(target);\n const displayTitle = title || `CSS for \"${targetStr}\"`;\n\n // Get some stats about the CSS\n const lines = css.split('\\n').length;\n const size = new Blob([css]).size;\n const sizeStr = size > 1024 ? `${(size / 1024).toFixed(1)}KB` : `${size}B`;\n\n // Count CSS rules (blocks with opening braces)\n const ruleCount = (css.match(/\\{/g) || []).length;\n\n console.group(\n `🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`,\n );\n\n // Detect sub-elements in CSS\n const subElementMatches = css.match(/\\[data-element=\"([^\"]+)\"\\]/g) || [];\n const subElements = [\n ...new Set(\n subElementMatches\n .map((match) => match.match(/\\[data-element=\"([^\"]+)\"\\]/)?.[1])\n .filter((v): v is string => !!v),\n ),\n ];\n\n if (subElements.length > 0) {\n console.log(`🧩 Sub-elements found: ${subElements.join(', ')}`);\n\n // Show stats and CSS for each sub-element\n subElements.forEach((element) => {\n const _elementSelector = `[data-element=\"${element}\"]`;\n const elementRegex = new RegExp(\n `[^}]*\\\\[data-element=\"${element.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\"\\\\][^{]*\\\\{[^}]*\\\\}`,\n 'gm',\n );\n const elementCSS = (css.match(elementRegex) || []).join('\\n');\n\n if (elementCSS) {\n const elementRules = (elementCSS.match(/\\{/g) || []).length;\n const elementLines = elementCSS.split('\\n').length;\n const elementSize = new Blob([elementCSS]).size;\n const elementSizeStr =\n elementSize > 1024\n ? `${(elementSize / 1024).toFixed(1)}KB`\n : `${elementSize}B`;\n\n console.groupCollapsed(\n `🧩 ${element} (${elementRules} rules, ${elementLines} lines, ${elementSizeStr})`,\n );\n console.log(\n `%c${elementCSS}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n }\n });\n }\n\n // Full CSS in collapsible group (hidden by default)\n console.groupCollapsed('📄 Full CSS (click to expand)');\n console.log(\n `%c${css}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n\n console.groupEnd();\n },\n\n // 12) Show help and usage examples\n help(): void {\n console.group('🎨 tastyDebug - Quick Start Guide');\n console.log('💡 Essential commands:');\n console.log(\n ' • tastyDebug.summary({ log: true }) - comprehensive overview',\n );\n console.log(' • tastyDebug.chunks({ log: true }) - style chunk breakdown');\n console.log(' • tastyDebug.log(\"active\") - beautiful CSS display');\n console.log(' • tastyDebug.css(\"active\") - get active CSS');\n console.log(\n ' • tastyDebug.inspect(\".my-element\") - element inspection with chunk info',\n );\n console.log(' • tastyDebug.cache() - cache status');\n console.log(' • tastyDebug.defs() - defined properties & keyframes');\n console.log(' • tastyDebug.pageCSS({ log: true }) - all page CSS');\n console.log('');\n console.log('📖 Common targets for css()/log():');\n console.log(' • \"all\" - all tasty CSS + global CSS');\n console.log(' • \"active\" - CSS for classes in DOM');\n console.log(' • \"unused\" - CSS for classes with refCount = 0');\n console.log(' • \"global\" - only global CSS (injectGlobal)');\n console.log(' • \"page\" - ALL page CSS (including non-tasty)');\n console.log(' • \"t123\" - specific tasty class');\n console.log(' • [\".my-selector\"] - CSS selector');\n console.log('');\n console.log('🔧 Available options:');\n console.log(' • { log: true } - auto-log results to console');\n console.log(' • { title: \"Custom\" } - custom title for log()');\n console.log(' • { root: shadowRoot } - target Shadow DOM');\n console.log(' • { prettify: false } - skip CSS formatting');\n console.log('');\n console.log('🧩 Style Chunking:');\n console.log(\n ' Elements have multiple classes (one per chunk: appearance, font, dimension, etc.)',\n );\n console.log(\n ' • tastyDebug.chunks({ log: true }) - breakdown by chunk type',\n );\n console.log(\n ' • tastyDebug.inspect() - shows which chunk each class belongs to',\n );\n console.log(\n ' Chunk types: combined (non-chunked), appearance, font, dimension, container, scrollbar, position, misc, subcomponents',\n );\n console.groupEnd();\n },\n};\n\n/**\n * Auto-install in development\n */\nif (typeof window !== 'undefined' && isDevEnv()) {\n tastyDebug.install();\n}\n"],"mappings":"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"}
@@ -381,18 +381,24 @@ function createSupportsCondition(subtype, condition, negated = false, raw) {
381
381
  condition
382
382
  };
383
383
  }
384
+ const uniqueIdCache = /* @__PURE__ */ new WeakMap();
384
385
  /**
385
- * Get the unique ID for any condition node
386
+ * Get the unique ID for any condition node.
387
+ * Results are memoized via WeakMap since condition nodes are immutable.
386
388
  */
387
389
  function getConditionUniqueId(node) {
388
- if (node.kind === "true") return "TRUE";
389
- if (node.kind === "false") return "FALSE";
390
- if (node.kind === "state") return node.uniqueId;
391
- if (node.kind === "compound") {
390
+ const cached = uniqueIdCache.get(node);
391
+ if (cached !== void 0) return cached;
392
+ let id;
393
+ if (node.kind === "true") id = "TRUE";
394
+ else if (node.kind === "false") id = "FALSE";
395
+ else if (node.kind === "state") id = node.uniqueId;
396
+ else if (node.kind === "compound") {
392
397
  const childIds = node.children.map(getConditionUniqueId).sort();
393
- return `${node.operator}(${childIds.join(",")})`;
394
- }
395
- return "UNKNOWN";
398
+ id = `${node.operator}(${childIds.join(",")})`;
399
+ } else id = "UNKNOWN";
400
+ uniqueIdCache.set(node, id);
401
+ return id;
396
402
  }
397
403
 
398
404
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"conditions.js","names":[],"sources":["../../src/pipeline/conditions.ts"],"sourcesContent":["/**\n * ConditionNode Types and Helpers\n *\n * Core data structures for representing style conditions as an abstract syntax tree.\n * Used throughout the pipeline for parsing, simplification, and CSS generation.\n */\n\n// ============================================================================\n// Core ConditionNode Types\n// ============================================================================\n\n/**\n * Base interface for all state conditions (leaf nodes)\n */\ninterface BaseStateCondition {\n kind: 'state';\n negated: boolean;\n raw: string; // Original string for debugging/caching\n uniqueId: string; // Normalized ID for comparison (built from props)\n}\n\n/**\n * Modifier condition: [data-attr] or [data-attr=\"value\"]\n */\nexport interface ModifierCondition extends BaseStateCondition {\n type: 'modifier';\n attribute: string; // e.g., 'data-theme', 'data-size'\n value?: string; // e.g., 'danger', 'large' (undefined = boolean attr)\n operator?: '=' | '^=' | '$=' | '*='; // Attribute match operator\n}\n\n/**\n * Pseudo-class condition: :hover, :focus-visible\n */\nexport interface PseudoCondition extends BaseStateCondition {\n type: 'pseudo';\n pseudo: string; // e.g., ':hover', ':focus-visible', ':nth-child(2n)'\n}\n\n/**\n * Numeric bound for dimension queries\n */\nexport interface NumericBound {\n value: string; // e.g., '768px', 'calc(var(--gap) * 40)'\n valueNumeric: number | null; // Parsed numeric value for comparison\n inclusive: boolean; // true for >=/<= , false for >/<\n}\n\n/**\n * Media query condition\n */\nexport interface MediaCondition extends BaseStateCondition {\n type: 'media';\n subtype: 'dimension' | 'feature' | 'type';\n\n // For dimension queries: @media(w < 768px), @media(600px <= w < 1200px)\n dimension?: 'width' | 'height' | 'inline-size' | 'block-size';\n lowerBound?: NumericBound; // >= or >\n upperBound?: NumericBound; // <= or <\n\n // For feature queries: @media(prefers-contrast: high)\n feature?: string; // e.g., 'prefers-contrast', 'prefers-color-scheme'\n featureValue?: string; // e.g., 'high', 'dark' (undefined = boolean feature)\n\n // For type queries: @media:print\n mediaType?: 'print' | 'screen' | 'all' | 'speech';\n}\n\n/**\n * Container query condition\n */\nexport interface ContainerCondition extends BaseStateCondition {\n type: 'container';\n subtype: 'dimension' | 'style' | 'raw';\n containerName?: string; // e.g., 'layout', 'sidebar' (undefined = nearest)\n\n // For dimension queries: @(w < 600px), @(layout, w < 600px)\n dimension?: 'width' | 'height' | 'inline-size' | 'block-size';\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n\n // For style queries: @(layout, $variant=danger), @($theme)\n property?: string; // CSS custom property name (without --)\n propertyValue?: string; // e.g., 'danger' (undefined = existence check)\n\n // For raw function queries: @(scroll-state(stuck: top)), @(style(display: flex))\n rawCondition?: string; // Verbatim CSS condition string\n}\n\n/**\n * Root state condition: @root(theme=dark)\n */\nexport interface RootCondition extends BaseStateCondition {\n type: 'root';\n innerCondition: ConditionNode;\n}\n\n/**\n * Parent state condition: @parent(hovered), @parent(theme=dark, >)\n */\nexport interface ParentCondition extends BaseStateCondition {\n type: 'parent';\n innerCondition: ConditionNode;\n direct: boolean; // true for @parent(..., >) — direct parent only\n}\n\n/**\n * Own state condition: @own(hovered)\n */\nexport interface OwnCondition extends BaseStateCondition {\n type: 'own';\n innerCondition: ConditionNode; // The parsed inner condition\n}\n\n/**\n * Starting style condition: @starting\n */\nexport interface StartingCondition extends BaseStateCondition {\n type: 'starting';\n}\n\n/**\n * Supports query condition: @supports(display: grid), @supports($, :has(*))\n */\nexport interface SupportsCondition extends BaseStateCondition {\n type: 'supports';\n subtype: 'feature' | 'selector';\n // The raw condition string (e.g., \"display: grid\" or \":has(*)\")\n condition: string;\n}\n\n/**\n * Union of all state condition types\n */\nexport type StateCondition =\n | ModifierCondition\n | PseudoCondition\n | MediaCondition\n | ContainerCondition\n | RootCondition\n | ParentCondition\n | OwnCondition\n | StartingCondition\n | SupportsCondition;\n\n/**\n * Compound node: combines conditions with AND/OR\n */\nexport interface CompoundCondition {\n kind: 'compound';\n operator: 'AND' | 'OR';\n children: ConditionNode[];\n}\n\n/**\n * True condition (matches everything)\n */\nexport interface TrueCondition {\n kind: 'true';\n}\n\n/**\n * False condition (matches nothing - skip this rule)\n */\nexport interface FalseCondition {\n kind: 'false';\n}\n\n/**\n * Union of all condition node types\n */\nexport type ConditionNode =\n | StateCondition\n | CompoundCondition\n | TrueCondition\n | FalseCondition;\n\n// ============================================================================\n// Constructor Functions\n// ============================================================================\n\n/**\n * Create a TRUE condition (matches everything)\n */\nexport function trueCondition(): TrueCondition {\n return { kind: 'true' };\n}\n\n/**\n * Create a FALSE condition (matches nothing)\n */\nexport function falseCondition(): FalseCondition {\n return { kind: 'false' };\n}\n\n/**\n * Create an AND compound condition\n */\nexport function and(...children: ConditionNode[]): ConditionNode {\n const filtered: ConditionNode[] = [];\n\n for (const child of children) {\n // Short-circuit on FALSE\n if (child.kind === 'false') {\n return falseCondition();\n }\n // Skip TRUE (identity for AND)\n if (child.kind === 'true') {\n continue;\n }\n // Flatten nested ANDs\n if (child.kind === 'compound' && child.operator === 'AND') {\n filtered.push(...child.children);\n } else {\n filtered.push(child);\n }\n }\n\n if (filtered.length === 0) {\n return trueCondition();\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n\n return {\n kind: 'compound',\n operator: 'AND',\n children: filtered,\n };\n}\n\n/**\n * Create an OR compound condition\n */\nexport function or(...children: ConditionNode[]): ConditionNode {\n const filtered: ConditionNode[] = [];\n\n for (const child of children) {\n // Short-circuit on TRUE\n if (child.kind === 'true') {\n return trueCondition();\n }\n // Skip FALSE (identity for OR)\n if (child.kind === 'false') {\n continue;\n }\n // Flatten nested ORs\n if (child.kind === 'compound' && child.operator === 'OR') {\n filtered.push(...child.children);\n } else {\n filtered.push(child);\n }\n }\n\n if (filtered.length === 0) {\n return falseCondition();\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n\n return {\n kind: 'compound',\n operator: 'OR',\n children: filtered,\n };\n}\n\n/**\n * Negate a condition\n */\nexport function not(node: ConditionNode): ConditionNode {\n // NOT(TRUE) = FALSE\n if (node.kind === 'true') {\n return falseCondition();\n }\n\n // NOT(FALSE) = TRUE\n if (node.kind === 'false') {\n return trueCondition();\n }\n\n // NOT(state) = toggle negated flag\n if (node.kind === 'state') {\n return {\n ...node,\n negated: !node.negated,\n uniqueId: node.negated\n ? node.uniqueId.replace(/^!/, '')\n : `!${node.uniqueId}`,\n };\n }\n\n // NOT(AND(a, b, ...)) = OR(NOT(a), NOT(b), ...) - De Morgan's law\n if (node.kind === 'compound' && node.operator === 'AND') {\n return or(...node.children.map((c) => not(c)));\n }\n\n // NOT(OR(a, b, ...)) = AND(NOT(a), NOT(b), ...) - De Morgan's law\n if (node.kind === 'compound' && node.operator === 'OR') {\n return and(...node.children.map((c) => not(c)));\n }\n\n // Fallback - should not reach here\n return node;\n}\n\n// ============================================================================\n// Condition Type Checking\n// ============================================================================\n\n/**\n * Check if a condition is a compound condition\n */\nexport function isCompoundCondition(\n node: ConditionNode,\n): node is CompoundCondition {\n return node.kind === 'compound';\n}\n\n// ============================================================================\n// UniqueId Generation\n// ============================================================================\n\n/**\n * Generate a normalized unique ID for a modifier condition\n */\nexport function modifierUniqueId(\n attribute: string,\n value?: string,\n operator = '=',\n negated = false,\n): string {\n const base = value\n ? `mod:${attribute}${operator}${value}`\n : `mod:${attribute}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a pseudo condition\n */\nexport function pseudoUniqueId(pseudo: string, negated = false): string {\n const base = `pseudo:${pseudo}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a media condition\n */\nexport function mediaUniqueId(\n subtype: 'dimension' | 'feature' | 'type',\n props: {\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n feature?: string;\n featureValue?: string;\n mediaType?: string;\n },\n negated = false,\n): string {\n let base: string;\n\n if (subtype === 'dimension') {\n const parts = ['media', 'dim', props.dimension];\n if (props.lowerBound) {\n parts.push(props.lowerBound.inclusive ? '>=' : '>');\n parts.push(props.lowerBound.value);\n }\n if (props.upperBound) {\n parts.push(props.upperBound.inclusive ? '<=' : '<');\n parts.push(props.upperBound.value);\n }\n base = parts.join(':');\n } else if (subtype === 'feature') {\n base = props.featureValue\n ? `media:feat:${props.feature}:${props.featureValue}`\n : `media:feat:${props.feature}`;\n } else {\n base = `media:type:${props.mediaType}`;\n }\n\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a container condition\n */\nexport function containerUniqueId(\n subtype: 'dimension' | 'style' | 'raw',\n props: {\n containerName?: string;\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n property?: string;\n propertyValue?: string;\n rawCondition?: string;\n },\n negated = false,\n): string {\n let base: string;\n const name = props.containerName || '_';\n\n if (subtype === 'dimension') {\n const parts = ['container', 'dim', name, props.dimension];\n if (props.lowerBound) {\n parts.push(props.lowerBound.inclusive ? '>=' : '>');\n parts.push(props.lowerBound.value);\n }\n if (props.upperBound) {\n parts.push(props.upperBound.inclusive ? '<=' : '<');\n parts.push(props.upperBound.value);\n }\n base = parts.join(':');\n } else if (subtype === 'raw') {\n base = `container:raw:${name}:${props.rawCondition}`;\n } else {\n base = props.propertyValue\n ? `container:style:${name}:--${props.property}:${props.propertyValue}`\n : `container:style:${name}:--${props.property}`;\n }\n\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a root condition\n */\nexport function rootUniqueId(innerUniqueId: string, negated = false): string {\n const base = `root:${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a parent condition\n */\nexport function parentUniqueId(\n innerUniqueId: string,\n direct: boolean,\n negated = false,\n): string {\n const base = `parent:${direct ? '>' : ''}${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for an own condition\n */\nexport function ownUniqueId(innerUniqueId: string, negated = false): string {\n const base = `own:${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a starting condition\n */\nexport function startingUniqueId(negated = false): string {\n return negated ? '!starting' : 'starting';\n}\n\n/**\n * Generate a normalized unique ID for a supports condition\n */\nexport function supportsUniqueId(\n subtype: 'feature' | 'selector',\n condition: string,\n negated = false,\n): string {\n const base = `supports:${subtype}:${condition}`;\n return negated ? `!${base}` : base;\n}\n\n// ============================================================================\n// Condition Creation Helpers\n// ============================================================================\n\n/**\n * Create a modifier condition\n */\nexport function createModifierCondition(\n attribute: string,\n value?: string,\n operator: '=' | '^=' | '$=' | '*=' = '=',\n negated = false,\n raw?: string,\n): ModifierCondition {\n return {\n kind: 'state',\n type: 'modifier',\n negated,\n raw: raw || (value ? `${attribute}${operator}${value}` : attribute),\n uniqueId: modifierUniqueId(attribute, value, operator, negated),\n attribute,\n value,\n operator: value ? operator : undefined,\n };\n}\n\n/**\n * Create a pseudo condition\n */\nexport function createPseudoCondition(\n pseudo: string,\n negated = false,\n raw?: string,\n): PseudoCondition {\n return {\n kind: 'state',\n type: 'pseudo',\n negated,\n raw: raw || pseudo,\n uniqueId: pseudoUniqueId(pseudo, negated),\n pseudo,\n };\n}\n\n/**\n * Create a media dimension condition\n */\nexport function createMediaDimensionCondition(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'dimension',\n negated,\n raw: raw || `@media(${dimension})`,\n uniqueId: mediaUniqueId(\n 'dimension',\n { dimension, lowerBound, upperBound },\n negated,\n ),\n dimension,\n lowerBound,\n upperBound,\n };\n}\n\n/**\n * Create a media feature condition\n */\nexport function createMediaFeatureCondition(\n feature: string,\n featureValue?: string,\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'feature',\n negated,\n raw: raw || `@media(${feature}${featureValue ? `: ${featureValue}` : ''})`,\n uniqueId: mediaUniqueId('feature', { feature, featureValue }, negated),\n feature,\n featureValue,\n };\n}\n\n/**\n * Create a media type condition\n */\nexport function createMediaTypeCondition(\n mediaType: 'print' | 'screen' | 'all' | 'speech',\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'type',\n negated,\n raw: raw || `@media:${mediaType}`,\n uniqueId: mediaUniqueId('type', { mediaType }, negated),\n mediaType,\n };\n}\n\n/**\n * Create a container dimension condition\n */\nexport function createContainerDimensionCondition(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'dimension',\n negated,\n raw: raw || `@(${containerName ? containerName + ', ' : ''}${dimension})`,\n uniqueId: containerUniqueId(\n 'dimension',\n { containerName, dimension, lowerBound, upperBound },\n negated,\n ),\n containerName,\n dimension,\n lowerBound,\n upperBound,\n };\n}\n\n/**\n * Create a container style condition\n */\nexport function createContainerStyleCondition(\n property: string,\n propertyValue?: string,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'style',\n negated,\n raw:\n raw ||\n `@(${containerName ? containerName + ', ' : ''}$${property}${propertyValue ? '=' + propertyValue : ''})`,\n uniqueId: containerUniqueId(\n 'style',\n { containerName, property, propertyValue },\n negated,\n ),\n containerName,\n property,\n propertyValue,\n };\n}\n\n/**\n * Create a container raw function condition (e.g., scroll-state(), style(), etc.)\n * The condition string is passed through to CSS verbatim.\n */\nexport function createContainerRawCondition(\n rawCondition: string,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'raw',\n negated,\n raw:\n raw || `@(${containerName ? containerName + ', ' : ''}${rawCondition})`,\n uniqueId: containerUniqueId(\n 'raw',\n { containerName, rawCondition },\n negated,\n ),\n containerName,\n rawCondition,\n };\n}\n\n/**\n * Create a root condition\n */\nexport function createRootCondition(\n innerCondition: ConditionNode,\n negated = false,\n raw?: string,\n): RootCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'root',\n negated,\n raw: raw || `@root(${innerUniqueId})`,\n uniqueId: rootUniqueId(innerUniqueId, negated),\n innerCondition,\n };\n}\n\n/**\n * Create a parent condition\n */\nexport function createParentCondition(\n innerCondition: ConditionNode,\n direct: boolean,\n negated = false,\n raw?: string,\n): ParentCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'parent',\n negated,\n raw: raw || `@parent(${innerUniqueId})`,\n uniqueId: parentUniqueId(innerUniqueId, direct, negated),\n innerCondition,\n direct,\n };\n}\n\n/**\n * Create an own condition\n */\nexport function createOwnCondition(\n innerCondition: ConditionNode,\n negated = false,\n raw?: string,\n): OwnCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'own',\n negated,\n raw: raw || `@own(...)`,\n uniqueId: ownUniqueId(innerUniqueId, negated),\n innerCondition,\n };\n}\n\n/**\n * Create a starting condition\n */\nexport function createStartingCondition(\n negated = false,\n raw?: string,\n): StartingCondition {\n return {\n kind: 'state',\n type: 'starting',\n negated,\n raw: raw || '@starting',\n uniqueId: startingUniqueId(negated),\n };\n}\n\n/**\n * Create a supports condition\n *\n * @param subtype 'feature' for @supports(display: grid), 'selector' for @supports($, :has(*))\n * @param condition The condition string (e.g., \"display: grid\" or \":has(*)\")\n */\nexport function createSupportsCondition(\n subtype: 'feature' | 'selector',\n condition: string,\n negated = false,\n raw?: string,\n): SupportsCondition {\n return {\n kind: 'state',\n type: 'supports',\n subtype,\n negated,\n raw: raw || `@supports(${condition})`,\n uniqueId: supportsUniqueId(subtype, condition, negated),\n condition,\n };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Get the unique ID for any condition node\n */\nexport function getConditionUniqueId(node: ConditionNode): string {\n if (node.kind === 'true') {\n return 'TRUE';\n }\n if (node.kind === 'false') {\n return 'FALSE';\n }\n if (node.kind === 'state') {\n return node.uniqueId;\n }\n if (node.kind === 'compound') {\n const childIds = node.children.map(getConditionUniqueId).sort();\n return `${node.operator}(${childIds.join(',')})`;\n }\n return 'UNKNOWN';\n}\n"],"mappings":";;;;AAwLA,SAAgB,gBAA+B;AAC7C,QAAO,EAAE,MAAM,QAAQ;;;;;AAMzB,SAAgB,iBAAiC;AAC/C,QAAO,EAAE,MAAM,SAAS;;;;;AAM1B,SAAgB,IAAI,GAAG,UAA0C;CAC/D,MAAM,WAA4B,EAAE;AAEpC,MAAK,MAAM,SAAS,UAAU;AAE5B,MAAI,MAAM,SAAS,QACjB,QAAO,gBAAgB;AAGzB,MAAI,MAAM,SAAS,OACjB;AAGF,MAAI,MAAM,SAAS,cAAc,MAAM,aAAa,MAClD,UAAS,KAAK,GAAG,MAAM,SAAS;MAEhC,UAAS,KAAK,MAAM;;AAIxB,KAAI,SAAS,WAAW,EACtB,QAAO,eAAe;AAExB,KAAI,SAAS,WAAW,EACtB,QAAO,SAAS;AAGlB,QAAO;EACL,MAAM;EACN,UAAU;EACV,UAAU;EACX;;;;;AAMH,SAAgB,GAAG,GAAG,UAA0C;CAC9D,MAAM,WAA4B,EAAE;AAEpC,MAAK,MAAM,SAAS,UAAU;AAE5B,MAAI,MAAM,SAAS,OACjB,QAAO,eAAe;AAGxB,MAAI,MAAM,SAAS,QACjB;AAGF,MAAI,MAAM,SAAS,cAAc,MAAM,aAAa,KAClD,UAAS,KAAK,GAAG,MAAM,SAAS;MAEhC,UAAS,KAAK,MAAM;;AAIxB,KAAI,SAAS,WAAW,EACtB,QAAO,gBAAgB;AAEzB,KAAI,SAAS,WAAW,EACtB,QAAO,SAAS;AAGlB,QAAO;EACL,MAAM;EACN,UAAU;EACV,UAAU;EACX;;;;;AAMH,SAAgB,IAAI,MAAoC;AAEtD,KAAI,KAAK,SAAS,OAChB,QAAO,gBAAgB;AAIzB,KAAI,KAAK,SAAS,QAChB,QAAO,eAAe;AAIxB,KAAI,KAAK,SAAS,QAChB,QAAO;EACL,GAAG;EACH,SAAS,CAAC,KAAK;EACf,UAAU,KAAK,UACX,KAAK,SAAS,QAAQ,MAAM,GAAG,GAC/B,IAAI,KAAK;EACd;AAIH,KAAI,KAAK,SAAS,cAAc,KAAK,aAAa,MAChD,QAAO,GAAG,GAAG,KAAK,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;AAIhD,KAAI,KAAK,SAAS,cAAc,KAAK,aAAa,KAChD,QAAO,IAAI,GAAG,KAAK,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;AAIjD,QAAO;;;;;AAUT,SAAgB,oBACd,MAC2B;AAC3B,QAAO,KAAK,SAAS;;;;;AAUvB,SAAgB,iBACd,WACA,OACA,WAAW,KACX,UAAU,OACF;CACR,MAAM,OAAO,QACT,OAAO,YAAY,WAAW,UAC9B,OAAO;AACX,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,eAAe,QAAgB,UAAU,OAAe;CACtE,MAAM,OAAO,UAAU;AACvB,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,cACd,SACA,OAQA,UAAU,OACF;CACR,IAAI;AAEJ,KAAI,YAAY,aAAa;EAC3B,MAAM,QAAQ;GAAC;GAAS;GAAO,MAAM;GAAU;AAC/C,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,SAAO,MAAM,KAAK,IAAI;YACb,YAAY,UACrB,QAAO,MAAM,eACT,cAAc,MAAM,QAAQ,GAAG,MAAM,iBACrC,cAAc,MAAM;KAExB,QAAO,cAAc,MAAM;AAG7B,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,kBACd,SACA,OASA,UAAU,OACF;CACR,IAAI;CACJ,MAAM,OAAO,MAAM,iBAAiB;AAEpC,KAAI,YAAY,aAAa;EAC3B,MAAM,QAAQ;GAAC;GAAa;GAAO;GAAM,MAAM;GAAU;AACzD,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,SAAO,MAAM,KAAK,IAAI;YACb,YAAY,MACrB,QAAO,iBAAiB,KAAK,GAAG,MAAM;KAEtC,QAAO,MAAM,gBACT,mBAAmB,KAAK,KAAK,MAAM,SAAS,GAAG,MAAM,kBACrD,mBAAmB,KAAK,KAAK,MAAM;AAGzC,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,aAAa,eAAuB,UAAU,OAAe;CAC3E,MAAM,OAAO,QAAQ;AACrB,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,eACd,eACA,QACA,UAAU,OACF;CACR,MAAM,OAAO,UAAU,SAAS,MAAM,KAAK;AAC3C,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,YAAY,eAAuB,UAAU,OAAe;CAC1E,MAAM,OAAO,OAAO;AACpB,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,iBAAiB,UAAU,OAAe;AACxD,QAAO,UAAU,cAAc;;;;;AAMjC,SAAgB,iBACd,SACA,WACA,UAAU,OACF;CACR,MAAM,OAAO,YAAY,QAAQ,GAAG;AACpC,QAAO,UAAU,IAAI,SAAS;;;;;AAUhC,SAAgB,wBACd,WACA,OACA,WAAqC,KACrC,UAAU,OACV,KACmB;AACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,QAAQ,QAAQ,GAAG,YAAY,WAAW,UAAU;EACzD,UAAU,iBAAiB,WAAW,OAAO,UAAU,QAAQ;EAC/D;EACA;EACA,UAAU,QAAQ,WAAW;EAC9B;;;;;AAMH,SAAgB,sBACd,QACA,UAAU,OACV,KACiB;AACjB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO;EACZ,UAAU,eAAe,QAAQ,QAAQ;EACzC;EACD;;;;;AAMH,SAAgB,8BACd,WACA,YACA,YACA,UAAU,OACV,KACgB;AAChB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,UAAU,UAAU;EAChC,UAAU,cACR,aACA;GAAE;GAAW;GAAY;GAAY,EACrC,QACD;EACD;EACA;EACA;EACD;;;;;AAMH,SAAgB,4BACd,SACA,cACA,UAAU,OACV,KACgB;AAChB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,UAAU,UAAU,eAAe,KAAK,iBAAiB,GAAG;EACxE,UAAU,cAAc,WAAW;GAAE;GAAS;GAAc,EAAE,QAAQ;EACtE;EACA;EACD;;;;;AAMH,SAAgB,yBACd,WACA,UAAU,OACV,KACgB;AAChB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,UAAU;EACtB,UAAU,cAAc,QAAQ,EAAE,WAAW,EAAE,QAAQ;EACvD;EACD;;;;;AAMH,SAAgB,kCACd,WACA,YACA,YACA,eACA,UAAU,OACV,KACoB;AACpB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,KAAK,gBAAgB,gBAAgB,OAAO,KAAK,UAAU;EACvE,UAAU,kBACR,aACA;GAAE;GAAe;GAAW;GAAY;GAAY,EACpD,QACD;EACD;EACA;EACA;EACA;EACD;;;;;AAMH,SAAgB,8BACd,UACA,eACA,eACA,UAAU,OACV,KACoB;AACpB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KACE,OACA,KAAK,gBAAgB,gBAAgB,OAAO,GAAG,GAAG,WAAW,gBAAgB,MAAM,gBAAgB,GAAG;EACxG,UAAU,kBACR,SACA;GAAE;GAAe;GAAU;GAAe,EAC1C,QACD;EACD;EACA;EACA;EACD;;;;;;AAOH,SAAgB,4BACd,cACA,eACA,UAAU,OACV,KACoB;AACpB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KACE,OAAO,KAAK,gBAAgB,gBAAgB,OAAO,KAAK,aAAa;EACvE,UAAU,kBACR,OACA;GAAE;GAAe;GAAc,EAC/B,QACD;EACD;EACA;EACD;;;;;AAMH,SAAgB,oBACd,gBACA,UAAU,OACV,KACe;CACf,MAAM,gBAAgB,qBAAqB,eAAe;AAC1D,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO,SAAS,cAAc;EACnC,UAAU,aAAa,eAAe,QAAQ;EAC9C;EACD;;;;;AAMH,SAAgB,sBACd,gBACA,QACA,UAAU,OACV,KACiB;CACjB,MAAM,gBAAgB,qBAAqB,eAAe;AAC1D,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO,WAAW,cAAc;EACrC,UAAU,eAAe,eAAe,QAAQ,QAAQ;EACxD;EACA;EACD;;;;;AAMH,SAAgB,mBACd,gBACA,UAAU,OACV,KACc;CACd,MAAM,gBAAgB,qBAAqB,eAAe;AAC1D,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO;EACZ,UAAU,YAAY,eAAe,QAAQ;EAC7C;EACD;;;;;AAMH,SAAgB,wBACd,UAAU,OACV,KACmB;AACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO;EACZ,UAAU,iBAAiB,QAAQ;EACpC;;;;;;;;AASH,SAAgB,wBACd,SACA,WACA,UAAU,OACV,KACmB;AACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA;EACA,KAAK,OAAO,aAAa,UAAU;EACnC,UAAU,iBAAiB,SAAS,WAAW,QAAQ;EACvD;EACD;;;;;AAUH,SAAgB,qBAAqB,MAA6B;AAChE,KAAI,KAAK,SAAS,OAChB,QAAO;AAET,KAAI,KAAK,SAAS,QAChB,QAAO;AAET,KAAI,KAAK,SAAS,QAChB,QAAO,KAAK;AAEd,KAAI,KAAK,SAAS,YAAY;EAC5B,MAAM,WAAW,KAAK,SAAS,IAAI,qBAAqB,CAAC,MAAM;AAC/D,SAAO,GAAG,KAAK,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;;AAEhD,QAAO"}
1
+ {"version":3,"file":"conditions.js","names":[],"sources":["../../src/pipeline/conditions.ts"],"sourcesContent":["/**\n * ConditionNode Types and Helpers\n *\n * Core data structures for representing style conditions as an abstract syntax tree.\n * Used throughout the pipeline for parsing, simplification, and CSS generation.\n */\n\n// ============================================================================\n// Core ConditionNode Types\n// ============================================================================\n\n/**\n * Base interface for all state conditions (leaf nodes)\n */\ninterface BaseStateCondition {\n kind: 'state';\n negated: boolean;\n raw: string; // Original string for debugging/caching\n uniqueId: string; // Normalized ID for comparison (built from props)\n}\n\n/**\n * Modifier condition: [data-attr] or [data-attr=\"value\"]\n */\nexport interface ModifierCondition extends BaseStateCondition {\n type: 'modifier';\n attribute: string; // e.g., 'data-theme', 'data-size'\n value?: string; // e.g., 'danger', 'large' (undefined = boolean attr)\n operator?: '=' | '^=' | '$=' | '*='; // Attribute match operator\n}\n\n/**\n * Pseudo-class condition: :hover, :focus-visible\n */\nexport interface PseudoCondition extends BaseStateCondition {\n type: 'pseudo';\n pseudo: string; // e.g., ':hover', ':focus-visible', ':nth-child(2n)'\n}\n\n/**\n * Numeric bound for dimension queries\n */\nexport interface NumericBound {\n value: string; // e.g., '768px', 'calc(var(--gap) * 40)'\n valueNumeric: number | null; // Parsed numeric value for comparison\n inclusive: boolean; // true for >=/<= , false for >/<\n}\n\n/**\n * Media query condition\n */\nexport interface MediaCondition extends BaseStateCondition {\n type: 'media';\n subtype: 'dimension' | 'feature' | 'type';\n\n // For dimension queries: @media(w < 768px), @media(600px <= w < 1200px)\n dimension?: 'width' | 'height' | 'inline-size' | 'block-size';\n lowerBound?: NumericBound; // >= or >\n upperBound?: NumericBound; // <= or <\n\n // For feature queries: @media(prefers-contrast: high)\n feature?: string; // e.g., 'prefers-contrast', 'prefers-color-scheme'\n featureValue?: string; // e.g., 'high', 'dark' (undefined = boolean feature)\n\n // For type queries: @media:print\n mediaType?: 'print' | 'screen' | 'all' | 'speech';\n}\n\n/**\n * Container query condition\n */\nexport interface ContainerCondition extends BaseStateCondition {\n type: 'container';\n subtype: 'dimension' | 'style' | 'raw';\n containerName?: string; // e.g., 'layout', 'sidebar' (undefined = nearest)\n\n // For dimension queries: @(w < 600px), @(layout, w < 600px)\n dimension?: 'width' | 'height' | 'inline-size' | 'block-size';\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n\n // For style queries: @(layout, $variant=danger), @($theme)\n property?: string; // CSS custom property name (without --)\n propertyValue?: string; // e.g., 'danger' (undefined = existence check)\n\n // For raw function queries: @(scroll-state(stuck: top)), @(style(display: flex))\n rawCondition?: string; // Verbatim CSS condition string\n}\n\n/**\n * Root state condition: @root(theme=dark)\n */\nexport interface RootCondition extends BaseStateCondition {\n type: 'root';\n innerCondition: ConditionNode;\n}\n\n/**\n * Parent state condition: @parent(hovered), @parent(theme=dark, >)\n */\nexport interface ParentCondition extends BaseStateCondition {\n type: 'parent';\n innerCondition: ConditionNode;\n direct: boolean; // true for @parent(..., >) — direct parent only\n}\n\n/**\n * Own state condition: @own(hovered)\n */\nexport interface OwnCondition extends BaseStateCondition {\n type: 'own';\n innerCondition: ConditionNode; // The parsed inner condition\n}\n\n/**\n * Starting style condition: @starting\n */\nexport interface StartingCondition extends BaseStateCondition {\n type: 'starting';\n}\n\n/**\n * Supports query condition: @supports(display: grid), @supports($, :has(*))\n */\nexport interface SupportsCondition extends BaseStateCondition {\n type: 'supports';\n subtype: 'feature' | 'selector';\n // The raw condition string (e.g., \"display: grid\" or \":has(*)\")\n condition: string;\n}\n\n/**\n * Union of all state condition types\n */\nexport type StateCondition =\n | ModifierCondition\n | PseudoCondition\n | MediaCondition\n | ContainerCondition\n | RootCondition\n | ParentCondition\n | OwnCondition\n | StartingCondition\n | SupportsCondition;\n\n/**\n * Compound node: combines conditions with AND/OR\n */\nexport interface CompoundCondition {\n kind: 'compound';\n operator: 'AND' | 'OR';\n children: ConditionNode[];\n}\n\n/**\n * True condition (matches everything)\n */\nexport interface TrueCondition {\n kind: 'true';\n}\n\n/**\n * False condition (matches nothing - skip this rule)\n */\nexport interface FalseCondition {\n kind: 'false';\n}\n\n/**\n * Union of all condition node types\n */\nexport type ConditionNode =\n | StateCondition\n | CompoundCondition\n | TrueCondition\n | FalseCondition;\n\n// ============================================================================\n// Constructor Functions\n// ============================================================================\n\n/**\n * Create a TRUE condition (matches everything)\n */\nexport function trueCondition(): TrueCondition {\n return { kind: 'true' };\n}\n\n/**\n * Create a FALSE condition (matches nothing)\n */\nexport function falseCondition(): FalseCondition {\n return { kind: 'false' };\n}\n\n/**\n * Create an AND compound condition\n */\nexport function and(...children: ConditionNode[]): ConditionNode {\n const filtered: ConditionNode[] = [];\n\n for (const child of children) {\n // Short-circuit on FALSE\n if (child.kind === 'false') {\n return falseCondition();\n }\n // Skip TRUE (identity for AND)\n if (child.kind === 'true') {\n continue;\n }\n // Flatten nested ANDs\n if (child.kind === 'compound' && child.operator === 'AND') {\n filtered.push(...child.children);\n } else {\n filtered.push(child);\n }\n }\n\n if (filtered.length === 0) {\n return trueCondition();\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n\n return {\n kind: 'compound',\n operator: 'AND',\n children: filtered,\n };\n}\n\n/**\n * Create an OR compound condition\n */\nexport function or(...children: ConditionNode[]): ConditionNode {\n const filtered: ConditionNode[] = [];\n\n for (const child of children) {\n // Short-circuit on TRUE\n if (child.kind === 'true') {\n return trueCondition();\n }\n // Skip FALSE (identity for OR)\n if (child.kind === 'false') {\n continue;\n }\n // Flatten nested ORs\n if (child.kind === 'compound' && child.operator === 'OR') {\n filtered.push(...child.children);\n } else {\n filtered.push(child);\n }\n }\n\n if (filtered.length === 0) {\n return falseCondition();\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n\n return {\n kind: 'compound',\n operator: 'OR',\n children: filtered,\n };\n}\n\n/**\n * Negate a condition\n */\nexport function not(node: ConditionNode): ConditionNode {\n // NOT(TRUE) = FALSE\n if (node.kind === 'true') {\n return falseCondition();\n }\n\n // NOT(FALSE) = TRUE\n if (node.kind === 'false') {\n return trueCondition();\n }\n\n // NOT(state) = toggle negated flag\n if (node.kind === 'state') {\n return {\n ...node,\n negated: !node.negated,\n uniqueId: node.negated\n ? node.uniqueId.replace(/^!/, '')\n : `!${node.uniqueId}`,\n };\n }\n\n // NOT(AND(a, b, ...)) = OR(NOT(a), NOT(b), ...) - De Morgan's law\n if (node.kind === 'compound' && node.operator === 'AND') {\n return or(...node.children.map((c) => not(c)));\n }\n\n // NOT(OR(a, b, ...)) = AND(NOT(a), NOT(b), ...) - De Morgan's law\n if (node.kind === 'compound' && node.operator === 'OR') {\n return and(...node.children.map((c) => not(c)));\n }\n\n // Fallback - should not reach here\n return node;\n}\n\n// ============================================================================\n// Condition Type Checking\n// ============================================================================\n\n/**\n * Check if a condition is a compound condition\n */\nexport function isCompoundCondition(\n node: ConditionNode,\n): node is CompoundCondition {\n return node.kind === 'compound';\n}\n\n// ============================================================================\n// UniqueId Generation\n// ============================================================================\n\n/**\n * Generate a normalized unique ID for a modifier condition\n */\nexport function modifierUniqueId(\n attribute: string,\n value?: string,\n operator = '=',\n negated = false,\n): string {\n const base = value\n ? `mod:${attribute}${operator}${value}`\n : `mod:${attribute}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a pseudo condition\n */\nexport function pseudoUniqueId(pseudo: string, negated = false): string {\n const base = `pseudo:${pseudo}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a media condition\n */\nexport function mediaUniqueId(\n subtype: 'dimension' | 'feature' | 'type',\n props: {\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n feature?: string;\n featureValue?: string;\n mediaType?: string;\n },\n negated = false,\n): string {\n let base: string;\n\n if (subtype === 'dimension') {\n const parts = ['media', 'dim', props.dimension];\n if (props.lowerBound) {\n parts.push(props.lowerBound.inclusive ? '>=' : '>');\n parts.push(props.lowerBound.value);\n }\n if (props.upperBound) {\n parts.push(props.upperBound.inclusive ? '<=' : '<');\n parts.push(props.upperBound.value);\n }\n base = parts.join(':');\n } else if (subtype === 'feature') {\n base = props.featureValue\n ? `media:feat:${props.feature}:${props.featureValue}`\n : `media:feat:${props.feature}`;\n } else {\n base = `media:type:${props.mediaType}`;\n }\n\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a container condition\n */\nexport function containerUniqueId(\n subtype: 'dimension' | 'style' | 'raw',\n props: {\n containerName?: string;\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n property?: string;\n propertyValue?: string;\n rawCondition?: string;\n },\n negated = false,\n): string {\n let base: string;\n const name = props.containerName || '_';\n\n if (subtype === 'dimension') {\n const parts = ['container', 'dim', name, props.dimension];\n if (props.lowerBound) {\n parts.push(props.lowerBound.inclusive ? '>=' : '>');\n parts.push(props.lowerBound.value);\n }\n if (props.upperBound) {\n parts.push(props.upperBound.inclusive ? '<=' : '<');\n parts.push(props.upperBound.value);\n }\n base = parts.join(':');\n } else if (subtype === 'raw') {\n base = `container:raw:${name}:${props.rawCondition}`;\n } else {\n base = props.propertyValue\n ? `container:style:${name}:--${props.property}:${props.propertyValue}`\n : `container:style:${name}:--${props.property}`;\n }\n\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a root condition\n */\nexport function rootUniqueId(innerUniqueId: string, negated = false): string {\n const base = `root:${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a parent condition\n */\nexport function parentUniqueId(\n innerUniqueId: string,\n direct: boolean,\n negated = false,\n): string {\n const base = `parent:${direct ? '>' : ''}${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for an own condition\n */\nexport function ownUniqueId(innerUniqueId: string, negated = false): string {\n const base = `own:${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a starting condition\n */\nexport function startingUniqueId(negated = false): string {\n return negated ? '!starting' : 'starting';\n}\n\n/**\n * Generate a normalized unique ID for a supports condition\n */\nexport function supportsUniqueId(\n subtype: 'feature' | 'selector',\n condition: string,\n negated = false,\n): string {\n const base = `supports:${subtype}:${condition}`;\n return negated ? `!${base}` : base;\n}\n\n// ============================================================================\n// Condition Creation Helpers\n// ============================================================================\n\n/**\n * Create a modifier condition\n */\nexport function createModifierCondition(\n attribute: string,\n value?: string,\n operator: '=' | '^=' | '$=' | '*=' = '=',\n negated = false,\n raw?: string,\n): ModifierCondition {\n return {\n kind: 'state',\n type: 'modifier',\n negated,\n raw: raw || (value ? `${attribute}${operator}${value}` : attribute),\n uniqueId: modifierUniqueId(attribute, value, operator, negated),\n attribute,\n value,\n operator: value ? operator : undefined,\n };\n}\n\n/**\n * Create a pseudo condition\n */\nexport function createPseudoCondition(\n pseudo: string,\n negated = false,\n raw?: string,\n): PseudoCondition {\n return {\n kind: 'state',\n type: 'pseudo',\n negated,\n raw: raw || pseudo,\n uniqueId: pseudoUniqueId(pseudo, negated),\n pseudo,\n };\n}\n\n/**\n * Create a media dimension condition\n */\nexport function createMediaDimensionCondition(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'dimension',\n negated,\n raw: raw || `@media(${dimension})`,\n uniqueId: mediaUniqueId(\n 'dimension',\n { dimension, lowerBound, upperBound },\n negated,\n ),\n dimension,\n lowerBound,\n upperBound,\n };\n}\n\n/**\n * Create a media feature condition\n */\nexport function createMediaFeatureCondition(\n feature: string,\n featureValue?: string,\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'feature',\n negated,\n raw: raw || `@media(${feature}${featureValue ? `: ${featureValue}` : ''})`,\n uniqueId: mediaUniqueId('feature', { feature, featureValue }, negated),\n feature,\n featureValue,\n };\n}\n\n/**\n * Create a media type condition\n */\nexport function createMediaTypeCondition(\n mediaType: 'print' | 'screen' | 'all' | 'speech',\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'type',\n negated,\n raw: raw || `@media:${mediaType}`,\n uniqueId: mediaUniqueId('type', { mediaType }, negated),\n mediaType,\n };\n}\n\n/**\n * Create a container dimension condition\n */\nexport function createContainerDimensionCondition(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'dimension',\n negated,\n raw: raw || `@(${containerName ? containerName + ', ' : ''}${dimension})`,\n uniqueId: containerUniqueId(\n 'dimension',\n { containerName, dimension, lowerBound, upperBound },\n negated,\n ),\n containerName,\n dimension,\n lowerBound,\n upperBound,\n };\n}\n\n/**\n * Create a container style condition\n */\nexport function createContainerStyleCondition(\n property: string,\n propertyValue?: string,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'style',\n negated,\n raw:\n raw ||\n `@(${containerName ? containerName + ', ' : ''}$${property}${propertyValue ? '=' + propertyValue : ''})`,\n uniqueId: containerUniqueId(\n 'style',\n { containerName, property, propertyValue },\n negated,\n ),\n containerName,\n property,\n propertyValue,\n };\n}\n\n/**\n * Create a container raw function condition (e.g., scroll-state(), style(), etc.)\n * The condition string is passed through to CSS verbatim.\n */\nexport function createContainerRawCondition(\n rawCondition: string,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'raw',\n negated,\n raw:\n raw || `@(${containerName ? containerName + ', ' : ''}${rawCondition})`,\n uniqueId: containerUniqueId(\n 'raw',\n { containerName, rawCondition },\n negated,\n ),\n containerName,\n rawCondition,\n };\n}\n\n/**\n * Create a root condition\n */\nexport function createRootCondition(\n innerCondition: ConditionNode,\n negated = false,\n raw?: string,\n): RootCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'root',\n negated,\n raw: raw || `@root(${innerUniqueId})`,\n uniqueId: rootUniqueId(innerUniqueId, negated),\n innerCondition,\n };\n}\n\n/**\n * Create a parent condition\n */\nexport function createParentCondition(\n innerCondition: ConditionNode,\n direct: boolean,\n negated = false,\n raw?: string,\n): ParentCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'parent',\n negated,\n raw: raw || `@parent(${innerUniqueId})`,\n uniqueId: parentUniqueId(innerUniqueId, direct, negated),\n innerCondition,\n direct,\n };\n}\n\n/**\n * Create an own condition\n */\nexport function createOwnCondition(\n innerCondition: ConditionNode,\n negated = false,\n raw?: string,\n): OwnCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'own',\n negated,\n raw: raw || `@own(...)`,\n uniqueId: ownUniqueId(innerUniqueId, negated),\n innerCondition,\n };\n}\n\n/**\n * Create a starting condition\n */\nexport function createStartingCondition(\n negated = false,\n raw?: string,\n): StartingCondition {\n return {\n kind: 'state',\n type: 'starting',\n negated,\n raw: raw || '@starting',\n uniqueId: startingUniqueId(negated),\n };\n}\n\n/**\n * Create a supports condition\n *\n * @param subtype 'feature' for @supports(display: grid), 'selector' for @supports($, :has(*))\n * @param condition The condition string (e.g., \"display: grid\" or \":has(*)\")\n */\nexport function createSupportsCondition(\n subtype: 'feature' | 'selector',\n condition: string,\n negated = false,\n raw?: string,\n): SupportsCondition {\n return {\n kind: 'state',\n type: 'supports',\n subtype,\n negated,\n raw: raw || `@supports(${condition})`,\n uniqueId: supportsUniqueId(subtype, condition, negated),\n condition,\n };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nconst uniqueIdCache = new WeakMap<ConditionNode, string>();\n\n/**\n * Get the unique ID for any condition node.\n * Results are memoized via WeakMap since condition nodes are immutable.\n */\nexport function getConditionUniqueId(node: ConditionNode): string {\n const cached = uniqueIdCache.get(node);\n if (cached !== undefined) return cached;\n\n let id: string;\n if (node.kind === 'true') {\n id = 'TRUE';\n } else if (node.kind === 'false') {\n id = 'FALSE';\n } else if (node.kind === 'state') {\n id = node.uniqueId;\n } else if (node.kind === 'compound') {\n const childIds = node.children.map(getConditionUniqueId).sort();\n id = `${node.operator}(${childIds.join(',')})`;\n } else {\n id = 'UNKNOWN';\n }\n\n uniqueIdCache.set(node, id);\n return id;\n}\n"],"mappings":";;;;AAwLA,SAAgB,gBAA+B;AAC7C,QAAO,EAAE,MAAM,QAAQ;;;;;AAMzB,SAAgB,iBAAiC;AAC/C,QAAO,EAAE,MAAM,SAAS;;;;;AAM1B,SAAgB,IAAI,GAAG,UAA0C;CAC/D,MAAM,WAA4B,EAAE;AAEpC,MAAK,MAAM,SAAS,UAAU;AAE5B,MAAI,MAAM,SAAS,QACjB,QAAO,gBAAgB;AAGzB,MAAI,MAAM,SAAS,OACjB;AAGF,MAAI,MAAM,SAAS,cAAc,MAAM,aAAa,MAClD,UAAS,KAAK,GAAG,MAAM,SAAS;MAEhC,UAAS,KAAK,MAAM;;AAIxB,KAAI,SAAS,WAAW,EACtB,QAAO,eAAe;AAExB,KAAI,SAAS,WAAW,EACtB,QAAO,SAAS;AAGlB,QAAO;EACL,MAAM;EACN,UAAU;EACV,UAAU;EACX;;;;;AAMH,SAAgB,GAAG,GAAG,UAA0C;CAC9D,MAAM,WAA4B,EAAE;AAEpC,MAAK,MAAM,SAAS,UAAU;AAE5B,MAAI,MAAM,SAAS,OACjB,QAAO,eAAe;AAGxB,MAAI,MAAM,SAAS,QACjB;AAGF,MAAI,MAAM,SAAS,cAAc,MAAM,aAAa,KAClD,UAAS,KAAK,GAAG,MAAM,SAAS;MAEhC,UAAS,KAAK,MAAM;;AAIxB,KAAI,SAAS,WAAW,EACtB,QAAO,gBAAgB;AAEzB,KAAI,SAAS,WAAW,EACtB,QAAO,SAAS;AAGlB,QAAO;EACL,MAAM;EACN,UAAU;EACV,UAAU;EACX;;;;;AAMH,SAAgB,IAAI,MAAoC;AAEtD,KAAI,KAAK,SAAS,OAChB,QAAO,gBAAgB;AAIzB,KAAI,KAAK,SAAS,QAChB,QAAO,eAAe;AAIxB,KAAI,KAAK,SAAS,QAChB,QAAO;EACL,GAAG;EACH,SAAS,CAAC,KAAK;EACf,UAAU,KAAK,UACX,KAAK,SAAS,QAAQ,MAAM,GAAG,GAC/B,IAAI,KAAK;EACd;AAIH,KAAI,KAAK,SAAS,cAAc,KAAK,aAAa,MAChD,QAAO,GAAG,GAAG,KAAK,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;AAIhD,KAAI,KAAK,SAAS,cAAc,KAAK,aAAa,KAChD,QAAO,IAAI,GAAG,KAAK,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;AAIjD,QAAO;;;;;AAUT,SAAgB,oBACd,MAC2B;AAC3B,QAAO,KAAK,SAAS;;;;;AAUvB,SAAgB,iBACd,WACA,OACA,WAAW,KACX,UAAU,OACF;CACR,MAAM,OAAO,QACT,OAAO,YAAY,WAAW,UAC9B,OAAO;AACX,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,eAAe,QAAgB,UAAU,OAAe;CACtE,MAAM,OAAO,UAAU;AACvB,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,cACd,SACA,OAQA,UAAU,OACF;CACR,IAAI;AAEJ,KAAI,YAAY,aAAa;EAC3B,MAAM,QAAQ;GAAC;GAAS;GAAO,MAAM;GAAU;AAC/C,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,SAAO,MAAM,KAAK,IAAI;YACb,YAAY,UACrB,QAAO,MAAM,eACT,cAAc,MAAM,QAAQ,GAAG,MAAM,iBACrC,cAAc,MAAM;KAExB,QAAO,cAAc,MAAM;AAG7B,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,kBACd,SACA,OASA,UAAU,OACF;CACR,IAAI;CACJ,MAAM,OAAO,MAAM,iBAAiB;AAEpC,KAAI,YAAY,aAAa;EAC3B,MAAM,QAAQ;GAAC;GAAa;GAAO;GAAM,MAAM;GAAU;AACzD,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,MAAI,MAAM,YAAY;AACpB,SAAM,KAAK,MAAM,WAAW,YAAY,OAAO,IAAI;AACnD,SAAM,KAAK,MAAM,WAAW,MAAM;;AAEpC,SAAO,MAAM,KAAK,IAAI;YACb,YAAY,MACrB,QAAO,iBAAiB,KAAK,GAAG,MAAM;KAEtC,QAAO,MAAM,gBACT,mBAAmB,KAAK,KAAK,MAAM,SAAS,GAAG,MAAM,kBACrD,mBAAmB,KAAK,KAAK,MAAM;AAGzC,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,aAAa,eAAuB,UAAU,OAAe;CAC3E,MAAM,OAAO,QAAQ;AACrB,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,eACd,eACA,QACA,UAAU,OACF;CACR,MAAM,OAAO,UAAU,SAAS,MAAM,KAAK;AAC3C,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,YAAY,eAAuB,UAAU,OAAe;CAC1E,MAAM,OAAO,OAAO;AACpB,QAAO,UAAU,IAAI,SAAS;;;;;AAMhC,SAAgB,iBAAiB,UAAU,OAAe;AACxD,QAAO,UAAU,cAAc;;;;;AAMjC,SAAgB,iBACd,SACA,WACA,UAAU,OACF;CACR,MAAM,OAAO,YAAY,QAAQ,GAAG;AACpC,QAAO,UAAU,IAAI,SAAS;;;;;AAUhC,SAAgB,wBACd,WACA,OACA,WAAqC,KACrC,UAAU,OACV,KACmB;AACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,QAAQ,QAAQ,GAAG,YAAY,WAAW,UAAU;EACzD,UAAU,iBAAiB,WAAW,OAAO,UAAU,QAAQ;EAC/D;EACA;EACA,UAAU,QAAQ,WAAW;EAC9B;;;;;AAMH,SAAgB,sBACd,QACA,UAAU,OACV,KACiB;AACjB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO;EACZ,UAAU,eAAe,QAAQ,QAAQ;EACzC;EACD;;;;;AAMH,SAAgB,8BACd,WACA,YACA,YACA,UAAU,OACV,KACgB;AAChB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,UAAU,UAAU;EAChC,UAAU,cACR,aACA;GAAE;GAAW;GAAY;GAAY,EACrC,QACD;EACD;EACA;EACA;EACD;;;;;AAMH,SAAgB,4BACd,SACA,cACA,UAAU,OACV,KACgB;AAChB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,UAAU,UAAU,eAAe,KAAK,iBAAiB,GAAG;EACxE,UAAU,cAAc,WAAW;GAAE;GAAS;GAAc,EAAE,QAAQ;EACtE;EACA;EACD;;;;;AAMH,SAAgB,yBACd,WACA,UAAU,OACV,KACgB;AAChB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,UAAU;EACtB,UAAU,cAAc,QAAQ,EAAE,WAAW,EAAE,QAAQ;EACvD;EACD;;;;;AAMH,SAAgB,kCACd,WACA,YACA,YACA,eACA,UAAU,OACV,KACoB;AACpB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KAAK,OAAO,KAAK,gBAAgB,gBAAgB,OAAO,KAAK,UAAU;EACvE,UAAU,kBACR,aACA;GAAE;GAAe;GAAW;GAAY;GAAY,EACpD,QACD;EACD;EACA;EACA;EACA;EACD;;;;;AAMH,SAAgB,8BACd,UACA,eACA,eACA,UAAU,OACV,KACoB;AACpB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KACE,OACA,KAAK,gBAAgB,gBAAgB,OAAO,GAAG,GAAG,WAAW,gBAAgB,MAAM,gBAAgB,GAAG;EACxG,UAAU,kBACR,SACA;GAAE;GAAe;GAAU;GAAe,EAC1C,QACD;EACD;EACA;EACA;EACD;;;;;;AAOH,SAAgB,4BACd,cACA,eACA,UAAU,OACV,KACoB;AACpB,QAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS;EACT;EACA,KACE,OAAO,KAAK,gBAAgB,gBAAgB,OAAO,KAAK,aAAa;EACvE,UAAU,kBACR,OACA;GAAE;GAAe;GAAc,EAC/B,QACD;EACD;EACA;EACD;;;;;AAMH,SAAgB,oBACd,gBACA,UAAU,OACV,KACe;CACf,MAAM,gBAAgB,qBAAqB,eAAe;AAC1D,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO,SAAS,cAAc;EACnC,UAAU,aAAa,eAAe,QAAQ;EAC9C;EACD;;;;;AAMH,SAAgB,sBACd,gBACA,QACA,UAAU,OACV,KACiB;CACjB,MAAM,gBAAgB,qBAAqB,eAAe;AAC1D,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO,WAAW,cAAc;EACrC,UAAU,eAAe,eAAe,QAAQ,QAAQ;EACxD;EACA;EACD;;;;;AAMH,SAAgB,mBACd,gBACA,UAAU,OACV,KACc;CACd,MAAM,gBAAgB,qBAAqB,eAAe;AAC1D,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO;EACZ,UAAU,YAAY,eAAe,QAAQ;EAC7C;EACD;;;;;AAMH,SAAgB,wBACd,UAAU,OACV,KACmB;AACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA,KAAK,OAAO;EACZ,UAAU,iBAAiB,QAAQ;EACpC;;;;;;;;AASH,SAAgB,wBACd,SACA,WACA,UAAU,OACV,KACmB;AACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN;EACA;EACA,KAAK,OAAO,aAAa,UAAU;EACnC,UAAU,iBAAiB,SAAS,WAAW,QAAQ;EACvD;EACD;;AAOH,MAAM,gCAAgB,IAAI,SAAgC;;;;;AAM1D,SAAgB,qBAAqB,MAA6B;CAChE,MAAM,SAAS,cAAc,IAAI,KAAK;AACtC,KAAI,WAAW,OAAW,QAAO;CAEjC,IAAI;AACJ,KAAI,KAAK,SAAS,OAChB,MAAK;UACI,KAAK,SAAS,QACvB,MAAK;UACI,KAAK,SAAS,QACvB,MAAK,KAAK;UACD,KAAK,SAAS,YAAY;EACnC,MAAM,WAAW,KAAK,SAAS,IAAI,qBAAqB,CAAC,MAAM;AAC/D,OAAK,GAAG,KAAK,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;OAE5C,MAAK;AAGP,eAAc,IAAI,MAAM,GAAG;AAC3B,QAAO"}