@blotch/rsbuild-plugin-angular-lynx 22.2.3 → 22.2.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.
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import { availableParallelism } from "node:os";
12
12
  import { workspaces } from "@angular-devkit/core";
13
13
  import { NodeJsSyncHost } from "@angular-devkit/core/node";
14
14
  import { access, constants } from "node:fs/promises";
15
+ import postcss_value_parser from "postcss-value-parser";
15
16
  import * as __rspack_external_typescript from "typescript";
16
17
  import * as __rspack_external_node_path_c5b9b54f from "node:path";
17
18
  const ANGULAR_CLI_CONTEXT = Symbol.for('@blotch/rsbuild-plugin-angular-lynx:angular-cli-context');
@@ -527,7 +528,7 @@ const checkThresholds = (thresholds, size, label)=>thresholds.flatMap(({ limit,
527
528
  }
528
529
  ];
529
530
  });
530
- const sum = (sizes)=>sizes.reduce((total, { size })=>total + size, 0);
531
+ const budgets_sum = (sizes)=>sizes.reduce((total, { size })=>total + size, 0);
531
532
  const calculateSizes = (budget, assets, componentStyles)=>{
532
533
  switch(budget.type){
533
534
  case 'initial':
@@ -541,21 +542,21 @@ const calculateSizes = (budget, assets, componentStyles)=>{
541
542
  case 'bundle':
542
543
  return budget.name ? [
543
544
  {
544
- size: sum(assets.filter((asset)=>asset.entryName === budget.name)),
545
+ size: budgets_sum(assets.filter((asset)=>asset.entryName === budget.name)),
545
546
  label: budget.name
546
547
  }
547
548
  ] : [];
548
549
  case 'all':
549
550
  return [
550
551
  {
551
- size: sum(assets),
552
+ size: budgets_sum(assets),
552
553
  label: 'total'
553
554
  }
554
555
  ];
555
556
  case 'allScript':
556
557
  return [
557
558
  {
558
- size: sum(assets),
559
+ size: budgets_sum(assets),
559
560
  label: "total scripts"
560
561
  }
561
562
  ];
@@ -2287,6 +2288,1830 @@ const applySplitChunksRule = (api, options)=>{
2287
2288
  return rspackConfig;
2288
2289
  });
2289
2290
  };
2291
+ const foldCalc = (value)=>{
2292
+ if (!value.includes('calc(')) return value;
2293
+ const parsed = postcss_value_parser(value);
2294
+ foldNodes(parsed.nodes);
2295
+ return parsed.toString();
2296
+ };
2297
+ const foldNodes = (nodes)=>{
2298
+ for (const node of nodes){
2299
+ if ('function' !== node.type) continue;
2300
+ const folded = 'calc' === node.value.toLowerCase() ? evaluate(node.nodes) : void 0;
2301
+ if (folded) Object.assign(node, {
2302
+ type: 'word',
2303
+ value: formatDimension(folded)
2304
+ });
2305
+ else foldNodes(node.nodes);
2306
+ }
2307
+ };
2308
+ const INFINITY_VALUE = 9999;
2309
+ const formatDimension = ({ value, unit })=>`${Number(value.toFixed(6))}${unit}`;
2310
+ const evaluate = (nodes)=>{
2311
+ const tokens = tokenize(nodes);
2312
+ if (!tokens) return;
2313
+ let position = 0;
2314
+ const peek = ()=>tokens[position];
2315
+ const factor = ()=>{
2316
+ const token = tokens[position++];
2317
+ return 'object' == typeof token ? token : void 0;
2318
+ };
2319
+ const term = ()=>{
2320
+ let left = factor();
2321
+ while(left && ('*' === peek() || '/' === peek())){
2322
+ const operator = tokens[position++];
2323
+ const right = factor();
2324
+ left = right && ('*' === operator ? multiply(left, right) : divide(left, right));
2325
+ }
2326
+ return left;
2327
+ };
2328
+ const expression = ()=>{
2329
+ let left = term();
2330
+ while(left && ('+' === peek() || '-' === peek())){
2331
+ const operator = tokens[position++];
2332
+ const right = term();
2333
+ left = right && add(left, '-' === operator ? negate(right) : right);
2334
+ }
2335
+ return left;
2336
+ };
2337
+ const result = expression();
2338
+ return position === tokens.length ? result : void 0;
2339
+ };
2340
+ const tokenize = (nodes)=>{
2341
+ const tokens = [];
2342
+ for (const node of nodes){
2343
+ if ('space' === node.type || 'comment' === node.type) continue;
2344
+ if ('function' === node.type) {
2345
+ const name = node.value.toLowerCase();
2346
+ const group = 'calc' === name || '' === name ? evaluate(node.nodes) : void 0;
2347
+ if (!group) return;
2348
+ tokens.push(group);
2349
+ continue;
2350
+ }
2351
+ if ('word' !== node.type) return;
2352
+ if ([
2353
+ '+',
2354
+ '-',
2355
+ '*',
2356
+ '/'
2357
+ ].includes(node.value)) {
2358
+ tokens.push(node.value);
2359
+ continue;
2360
+ }
2361
+ if (/^-?infinity$/i.test(node.value)) {
2362
+ tokens.push({
2363
+ value: node.value.startsWith('-') ? -INFINITY_VALUE : INFINITY_VALUE,
2364
+ unit: ''
2365
+ });
2366
+ continue;
2367
+ }
2368
+ const unit = postcss_value_parser.unit(node.value);
2369
+ if (!unit) return;
2370
+ tokens.push({
2371
+ value: Number(unit.number),
2372
+ unit: unit.unit.toLowerCase()
2373
+ });
2374
+ }
2375
+ return tokens;
2376
+ };
2377
+ const negate = ({ value, unit })=>({
2378
+ value: -value,
2379
+ unit
2380
+ });
2381
+ const add = (a, b)=>a.unit === b.unit ? {
2382
+ value: a.value + b.value,
2383
+ unit: a.unit
2384
+ } : void 0;
2385
+ const multiply = (a, b)=>{
2386
+ if (a.unit && b.unit) return;
2387
+ return {
2388
+ value: a.value * b.value,
2389
+ unit: a.unit || b.unit
2390
+ };
2391
+ };
2392
+ const divide = (a, b)=>b.unit || 0 === b.value ? void 0 : {
2393
+ value: a.value / b.value,
2394
+ unit: a.unit
2395
+ };
2396
+ const clampHugeNumbers = (value)=>value.replace(/(-?)\d*\.?\d+e\+?(\d+)([a-z%]*)/gi, (match, sign, exponent, unit)=>Number(exponent) >= 7 ? `${sign}${INFINITY_VALUE}${unit}` : match);
2397
+ const COLOR_FUNCTIONS = new Set([
2398
+ 'rgb',
2399
+ 'rgba',
2400
+ 'hsl',
2401
+ 'hsla',
2402
+ 'hwb',
2403
+ 'lab',
2404
+ 'lch',
2405
+ 'oklab',
2406
+ 'oklch',
2407
+ 'color-mix'
2408
+ ]);
2409
+ const LOWERED_FUNCTIONS = new Set([
2410
+ ...COLOR_FUNCTIONS
2411
+ ].filter((name)=>'rgb' !== name && 'rgba' !== name));
2412
+ const NAMED_COLORS = {
2413
+ aliceblue: 'f0f8ff',
2414
+ antiquewhite: 'faebd7',
2415
+ aqua: '00ffff',
2416
+ aquamarine: '7fffd4',
2417
+ azure: 'f0ffff',
2418
+ beige: 'f5f5dc',
2419
+ bisque: 'ffe4c4',
2420
+ black: '000000',
2421
+ blanchedalmond: 'ffebcd',
2422
+ blue: '0000ff',
2423
+ blueviolet: '8a2be2',
2424
+ brown: 'a52a2a',
2425
+ burlywood: 'deb887',
2426
+ cadetblue: '5f9ea0',
2427
+ chartreuse: '7fff00',
2428
+ chocolate: 'd2691e',
2429
+ coral: 'ff7f50',
2430
+ cornflowerblue: '6495ed',
2431
+ cornsilk: 'fff8dc',
2432
+ crimson: 'dc143c',
2433
+ cyan: '00ffff',
2434
+ darkblue: '00008b',
2435
+ darkcyan: '008b8b',
2436
+ darkgoldenrod: 'b8860b',
2437
+ darkgray: 'a9a9a9',
2438
+ darkgreen: '006400',
2439
+ darkgrey: 'a9a9a9',
2440
+ darkkhaki: 'bdb76b',
2441
+ darkmagenta: '8b008b',
2442
+ darkolivegreen: '556b2f',
2443
+ darkorange: 'ff8c00',
2444
+ darkorchid: '9932cc',
2445
+ darkred: '8b0000',
2446
+ darksalmon: 'e9967a',
2447
+ darkseagreen: '8fbc8f',
2448
+ darkslateblue: '483d8b',
2449
+ darkslategray: '2f4f4f',
2450
+ darkslategrey: '2f4f4f',
2451
+ darkturquoise: '00ced1',
2452
+ darkviolet: '9400d3',
2453
+ deeppink: 'ff1493',
2454
+ deepskyblue: '00bfff',
2455
+ dimgray: '696969',
2456
+ dimgrey: '696969',
2457
+ dodgerblue: '1e90ff',
2458
+ firebrick: 'b22222',
2459
+ floralwhite: 'fffaf0',
2460
+ forestgreen: '228b22',
2461
+ fuchsia: 'ff00ff',
2462
+ gainsboro: 'dcdcdc',
2463
+ ghostwhite: 'f8f8ff',
2464
+ gold: 'ffd700',
2465
+ goldenrod: 'daa520',
2466
+ gray: '808080',
2467
+ green: '008000',
2468
+ greenyellow: 'adff2f',
2469
+ grey: '808080',
2470
+ honeydew: 'f0fff0',
2471
+ hotpink: 'ff69b4',
2472
+ indianred: 'cd5c5c',
2473
+ indigo: '4b0082',
2474
+ ivory: 'fffff0',
2475
+ khaki: 'f0e68c',
2476
+ lavender: 'e6e6fa',
2477
+ lavenderblush: 'fff0f5',
2478
+ lawngreen: '7cfc00',
2479
+ lemonchiffon: 'fffacd',
2480
+ lightblue: 'add8e6',
2481
+ lightcoral: 'f08080',
2482
+ lightcyan: 'e0ffff',
2483
+ lightgoldenrodyellow: 'fafad2',
2484
+ lightgray: 'd3d3d3',
2485
+ lightgreen: '90ee90',
2486
+ lightgrey: 'd3d3d3',
2487
+ lightpink: 'ffb6c1',
2488
+ lightsalmon: 'ffa07a',
2489
+ lightseagreen: '20b2aa',
2490
+ lightskyblue: '87cefa',
2491
+ lightslategray: '778899',
2492
+ lightslategrey: '778899',
2493
+ lightsteelblue: 'b0c4de',
2494
+ lightyellow: 'ffffe0',
2495
+ lime: '00ff00',
2496
+ limegreen: '32cd32',
2497
+ linen: 'faf0e6',
2498
+ magenta: 'ff00ff',
2499
+ maroon: '800000',
2500
+ mediumaquamarine: '66cdaa',
2501
+ mediumblue: '0000cd',
2502
+ mediumorchid: 'ba55d3',
2503
+ mediumpurple: '9370db',
2504
+ mediumseagreen: '3cb371',
2505
+ mediumslateblue: '7b68ee',
2506
+ mediumspringgreen: '00fa9a',
2507
+ mediumturquoise: '48d1cc',
2508
+ mediumvioletred: 'c71585',
2509
+ midnightblue: '191970',
2510
+ mintcream: 'f5fffa',
2511
+ mistyrose: 'ffe4e1',
2512
+ moccasin: 'ffe4b5',
2513
+ navajowhite: 'ffdead',
2514
+ navy: '000080',
2515
+ oldlace: 'fdf5e6',
2516
+ olive: '808000',
2517
+ olivedrab: '6b8e23',
2518
+ orange: 'ffa500',
2519
+ orangered: 'ff4500',
2520
+ orchid: 'da70d6',
2521
+ palegoldenrod: 'eee8aa',
2522
+ palegreen: '98fb98',
2523
+ paleturquoise: 'afeeee',
2524
+ palevioletred: 'db7093',
2525
+ papayawhip: 'ffefd5',
2526
+ peachpuff: 'ffdab9',
2527
+ peru: 'cd853f',
2528
+ pink: 'ffc0cb',
2529
+ plum: 'dda0dd',
2530
+ powderblue: 'b0e0e6',
2531
+ purple: '800080',
2532
+ rebeccapurple: '663399',
2533
+ red: 'ff0000',
2534
+ rosybrown: 'bc8f8f',
2535
+ royalblue: '4169e1',
2536
+ saddlebrown: '8b4513',
2537
+ salmon: 'fa8072',
2538
+ sandybrown: 'f4a460',
2539
+ seagreen: '2e8b57',
2540
+ seashell: 'fff5ee',
2541
+ sienna: 'a0522d',
2542
+ silver: 'c0c0c0',
2543
+ skyblue: '87ceeb',
2544
+ slateblue: '6a5acd',
2545
+ slategray: '708090',
2546
+ slategrey: '708090',
2547
+ snow: 'fffafa',
2548
+ springgreen: '00ff7f',
2549
+ steelblue: '4682b4',
2550
+ tan: 'd2b48c',
2551
+ teal: '008080',
2552
+ thistle: 'd8bfd8',
2553
+ tomato: 'ff6347',
2554
+ turquoise: '40e0d0',
2555
+ violet: 'ee82ee',
2556
+ wheat: 'f5deb3',
2557
+ white: 'ffffff',
2558
+ whitesmoke: 'f5f5f5',
2559
+ yellow: 'ffff00',
2560
+ yellowgreen: '9acd32'
2561
+ };
2562
+ const lowerColors = (value, channelVariables = new Set())=>{
2563
+ if (![
2564
+ ...LOWERED_FUNCTIONS
2565
+ ].some((name)=>value.includes(`${name}(`))) return value;
2566
+ const parsed = postcss_value_parser(value);
2567
+ rewriteColorFunctions(parsed.nodes, channelVariables);
2568
+ return parsed.toString();
2569
+ };
2570
+ const rewriteColorFunctions = (nodes, channelVariables)=>{
2571
+ for (const node of nodes){
2572
+ if ('function' !== node.type) continue;
2573
+ const name = node.value.toLowerCase();
2574
+ const color = LOWERED_FUNCTIONS.has(name) ? parseColor(node) : void 0;
2575
+ if (color) {
2576
+ Object.assign(node, {
2577
+ type: 'word',
2578
+ value: formatRgb(color)
2579
+ });
2580
+ continue;
2581
+ }
2582
+ rewriteColorFunctions(node.nodes, channelVariables);
2583
+ const mixed = 'color-mix' === name ? mixWithChannels(node.nodes, channelVariables) : void 0;
2584
+ if (mixed) Object.assign(node, {
2585
+ type: 'word',
2586
+ value: mixed
2587
+ });
2588
+ }
2589
+ };
2590
+ const mixWithChannels = (nodes, channelVariables)=>{
2591
+ const parts = splitByComma(nodes);
2592
+ if (3 !== parts.length) return;
2593
+ const [, first, second] = parts;
2594
+ const variable = first.find((node)=>'function' === node.type && 'var' === node.value.toLowerCase());
2595
+ const name = variable?.nodes[0]?.value;
2596
+ const percentage = first.filter((node)=>node !== variable).map((node)=>postcss_value_parser.unit(node.value) || {
2597
+ number: '',
2598
+ unit: ''
2599
+ });
2600
+ const isTransparent = 1 === second.length && 'transparent' === second[0].value.toLowerCase();
2601
+ if (!name || !channelVariables.has(name) || 1 !== variable.nodes.length || !isTransparent || percentage.length > 1 || 1 === percentage.length && percentage[0]?.unit !== '%') return;
2602
+ const alpha = percentage[0] ? Number(percentage[0].number) / 100 : 0.5;
2603
+ return `rgba(var(${name}-rgb), ${Number(alpha.toFixed(4))})`;
2604
+ };
2605
+ const formatRgb = ({ r, g, b, alpha })=>{
2606
+ const channel = (value)=>Math.round(255 * clamp01(value));
2607
+ const channels = `${channel(r)}, ${channel(g)}, ${channel(b)}`;
2608
+ const a = Number(clamp01(alpha).toFixed(4));
2609
+ return 1 === a ? `rgb(${channels})` : `rgba(${channels}, ${a})`;
2610
+ };
2611
+ const clamp01 = (value)=>Math.min(1, Math.max(0, value));
2612
+ const parseColor = (node)=>{
2613
+ if ('word' === node.type) {
2614
+ const word = node.value.toLowerCase();
2615
+ if ('transparent' === word) return {
2616
+ r: 0,
2617
+ g: 0,
2618
+ b: 0,
2619
+ alpha: 0
2620
+ };
2621
+ const named = NAMED_COLORS[word];
2622
+ return parseHex('string' == typeof named ? `#${named}` : word);
2623
+ }
2624
+ if ('function' !== node.type) return;
2625
+ const name = node.value.toLowerCase();
2626
+ if (!COLOR_FUNCTIONS.has(name)) return;
2627
+ if ('color-mix' === name) return parseColorMix(node.nodes);
2628
+ const args = colorArguments(node.nodes);
2629
+ if (!args) return;
2630
+ const { channels, alpha } = args;
2631
+ switch(name){
2632
+ case 'rgb':
2633
+ case 'rgba':
2634
+ return withAlpha(rgbFromChannels(channels.map((c)=>colors_channel(c, 255))), alpha);
2635
+ case 'hsl':
2636
+ case 'hsla':
2637
+ return withAlpha(hslToRgb(angle(channels[0]), percent(channels[1]), percent(channels[2])), alpha);
2638
+ case 'hwb':
2639
+ return withAlpha(hwbToRgb(angle(channels[0]), percent(channels[1]), percent(channels[2])), alpha);
2640
+ case 'lab':
2641
+ return withAlpha(labToRgb([
2642
+ colors_channel(channels[0], 100),
2643
+ colors_channel(channels[1], 125),
2644
+ colors_channel(channels[2], 125)
2645
+ ]), alpha);
2646
+ case 'lch':
2647
+ return withAlpha(labToRgb(polarToRectangular([
2648
+ colors_channel(channels[0], 100),
2649
+ colors_channel(channels[1], 150),
2650
+ angle(channels[2])
2651
+ ])), alpha);
2652
+ case 'oklab':
2653
+ return withAlpha(oklabToRgb([
2654
+ colors_channel(channels[0], 1),
2655
+ colors_channel(channels[1], 0.4),
2656
+ colors_channel(channels[2], 0.4)
2657
+ ]), alpha);
2658
+ default:
2659
+ return withAlpha(oklabToRgb(polarToRectangular([
2660
+ colors_channel(channels[0], 1),
2661
+ colors_channel(channels[1], 0.4),
2662
+ angle(channels[2])
2663
+ ])), alpha);
2664
+ }
2665
+ };
2666
+ const rgbFromChannels = ([r, g, b])=>({
2667
+ r: r / 255,
2668
+ g: g / 255,
2669
+ b: b / 255,
2670
+ alpha: 1
2671
+ });
2672
+ const withAlpha = (color, alpha)=>({
2673
+ ...color,
2674
+ alpha: void 0 === alpha ? 1 : colors_channel(alpha, 1)
2675
+ });
2676
+ const parseHex = (word)=>{
2677
+ const match = /^#([\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i.exec(word);
2678
+ if (!match) return;
2679
+ let hex = match[1];
2680
+ if (hex.length <= 4) hex = [
2681
+ ...hex
2682
+ ].map((digit)=>digit + digit).join('');
2683
+ const byte = (index)=>Number.parseInt(hex.slice(2 * index, 2 * index + 2), 16) / 255;
2684
+ return {
2685
+ r: byte(0),
2686
+ g: byte(1),
2687
+ b: byte(2),
2688
+ alpha: 8 === hex.length ? byte(3) : 1
2689
+ };
2690
+ };
2691
+ const colorArguments = (nodes)=>{
2692
+ const words = [];
2693
+ let alpha;
2694
+ let afterSlash = false;
2695
+ for (const node of nodes)if ('space' !== node.type && 'comment' !== node.type) {
2696
+ if ('div' === node.type) {
2697
+ afterSlash ||= '/' === node.value;
2698
+ continue;
2699
+ }
2700
+ if ('word' !== node.type) return;
2701
+ if (afterSlash) alpha = node.value;
2702
+ else words.push(node.value);
2703
+ }
2704
+ if (void 0 === alpha && 4 === words.length) alpha = words.pop();
2705
+ if (3 !== words.length || ![
2706
+ ...words,
2707
+ ...void 0 === alpha ? [] : [
2708
+ alpha
2709
+ ]
2710
+ ].every(isNumeric)) return;
2711
+ return {
2712
+ channels: words,
2713
+ alpha
2714
+ };
2715
+ };
2716
+ const isNumeric = (word)=>'none' === word.toLowerCase() || false !== postcss_value_parser.unit(word);
2717
+ const colors_channel = (word, full)=>{
2718
+ const { number, unit } = postcss_value_parser.unit(word) || {
2719
+ number: '0',
2720
+ unit: ''
2721
+ };
2722
+ return '%' === unit ? Number(number) / 100 * full : Number(number);
2723
+ };
2724
+ const percent = (word)=>colors_channel(word, 100) / 100;
2725
+ const angle = (word)=>{
2726
+ const { number, unit } = postcss_value_parser.unit(word) || {
2727
+ number: '0',
2728
+ unit: ''
2729
+ };
2730
+ const value = Number(number);
2731
+ switch(unit.toLowerCase()){
2732
+ case 'rad':
2733
+ return 180 * value / Math.PI;
2734
+ case 'grad':
2735
+ return 0.9 * value;
2736
+ case 'turn':
2737
+ return 360 * value;
2738
+ default:
2739
+ return value;
2740
+ }
2741
+ };
2742
+ const hslToRgb = (hue, saturation, lightness)=>{
2743
+ const h = (hue % 360 + 360) % 360;
2744
+ const f = (n)=>{
2745
+ const k = (n + h / 30) % 12;
2746
+ const a = saturation * Math.min(lightness, 1 - lightness);
2747
+ return lightness - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
2748
+ };
2749
+ return {
2750
+ r: f(0),
2751
+ g: f(8),
2752
+ b: f(4),
2753
+ alpha: 1
2754
+ };
2755
+ };
2756
+ const hwbToRgb = (hue, whiteness, blackness)=>{
2757
+ if (whiteness + blackness >= 1) {
2758
+ const gray = whiteness / (whiteness + blackness);
2759
+ return {
2760
+ r: gray,
2761
+ g: gray,
2762
+ b: gray,
2763
+ alpha: 1
2764
+ };
2765
+ }
2766
+ const { r, g, b } = hslToRgb(hue, 1, 0.5);
2767
+ const scale = (value)=>value * (1 - whiteness - blackness) + whiteness;
2768
+ return {
2769
+ r: scale(r),
2770
+ g: scale(g),
2771
+ b: scale(b),
2772
+ alpha: 1
2773
+ };
2774
+ };
2775
+ const polarToRectangular = ([lightness, chroma, hue])=>{
2776
+ const radians = hue * Math.PI / 180;
2777
+ return [
2778
+ lightness,
2779
+ chroma * Math.cos(radians),
2780
+ chroma * Math.sin(radians)
2781
+ ];
2782
+ };
2783
+ const rectangularToPolar = ([lightness, a, b])=>{
2784
+ const hue = 180 * Math.atan2(b, a) / Math.PI;
2785
+ return [
2786
+ lightness,
2787
+ Math.hypot(a, b),
2788
+ (hue + 360) % 360
2789
+ ];
2790
+ };
2791
+ const gammaEncode = (value)=>{
2792
+ const sign = value < 0 ? -1 : 1;
2793
+ const abs = Math.abs(value);
2794
+ return abs > 0.0031308 ? sign * (1.055 * abs ** (1 / 2.4) - 0.055) : 12.92 * value;
2795
+ };
2796
+ const gammaDecode = (value)=>{
2797
+ const sign = value < 0 ? -1 : 1;
2798
+ const abs = Math.abs(value);
2799
+ return abs > 0.04045 ? sign * ((abs + 0.055) / 1.055) ** 2.4 : value / 12.92;
2800
+ };
2801
+ const oklabToLinearRgb = ([l, a, b])=>{
2802
+ const lms = [
2803
+ (l + 0.3963377773761749 * a + 0.2158037573099136 * b) ** 3,
2804
+ (l - 0.1055613458156586 * a - 0.0638541728258133 * b) ** 3,
2805
+ (l - 0.0894841775298119 * a - 1.2914855480194092 * b) ** 3
2806
+ ];
2807
+ return [
2808
+ 4.0767416360759583 * lms[0] - 3.3077115392580629 * lms[1] + 0.2309699031821043 * lms[2],
2809
+ -1.2684379732850315 * lms[0] + 2.6097573492876882 * lms[1] - 0.341319376002657 * lms[2],
2810
+ -0.0041960761386756 * lms[0] - 0.7034186179359363 * lms[1] + 1.7076146940746117 * lms[2]
2811
+ ];
2812
+ };
2813
+ const linearRgbToOklab = ([r, g, b])=>{
2814
+ const lms = [
2815
+ Math.cbrt(0.4122214694707629 * r + 0.5363325372617349 * g + 0.0514459932675022 * b),
2816
+ Math.cbrt(0.2119034958178251 * r + 0.6806995506452344 * g + 0.1073969535369406 * b),
2817
+ Math.cbrt(0.0883024591900564 * r + 0.2817188391361215 * g + 0.6299787016738223 * b)
2818
+ ];
2819
+ return [
2820
+ 0.2104542553 * lms[0] + 0.793617785 * lms[1] - 0.0040720468 * lms[2],
2821
+ 1.9779984951 * lms[0] - 2.428592205 * lms[1] + 0.4505937099 * lms[2],
2822
+ 0.0259040371 * lms[0] + 0.7827717662 * lms[1] - 0.808675766 * lms[2]
2823
+ ];
2824
+ };
2825
+ const encodeRgb = ([r, g, b])=>({
2826
+ r: gammaEncode(r),
2827
+ g: gammaEncode(g),
2828
+ b: gammaEncode(b),
2829
+ alpha: 1
2830
+ });
2831
+ const rgbToOklab = ({ r, g, b })=>linearRgbToOklab([
2832
+ gammaDecode(r),
2833
+ gammaDecode(g),
2834
+ gammaDecode(b)
2835
+ ]);
2836
+ const isInGamut = ({ r, g, b })=>[
2837
+ r,
2838
+ g,
2839
+ b
2840
+ ].every((value)=>value >= -0.000001 && value <= 1 + 1e-6);
2841
+ const clip = ({ r, g, b, alpha })=>({
2842
+ r: clamp01(r),
2843
+ g: clamp01(g),
2844
+ b: clamp01(b),
2845
+ alpha
2846
+ });
2847
+ const oklabToRgb = (oklab)=>{
2848
+ const color = encodeRgb(oklabToLinearRgb(oklab));
2849
+ if (isInGamut(color)) return color;
2850
+ const [lightness, chroma, hue] = rectangularToPolar(oklab);
2851
+ if (lightness >= 1) return {
2852
+ r: 1,
2853
+ g: 1,
2854
+ b: 1,
2855
+ alpha: 1
2856
+ };
2857
+ if (lightness <= 0) return {
2858
+ r: 0,
2859
+ g: 0,
2860
+ b: 0,
2861
+ alpha: 1
2862
+ };
2863
+ const JND = 0.02;
2864
+ const EPSILON = 0.0001;
2865
+ const atChroma = (c)=>encodeRgb(oklabToLinearRgb(polarToRectangular([
2866
+ lightness,
2867
+ c,
2868
+ hue
2869
+ ])));
2870
+ const deltaE = (a, b)=>Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
2871
+ let clipped = clip(color);
2872
+ if (deltaE(rgbToOklab(clipped), oklab) < JND) return clipped;
2873
+ let min = 0;
2874
+ let max = chroma;
2875
+ let minInGamut = true;
2876
+ while(max - min > EPSILON){
2877
+ const c = (min + max) / 2;
2878
+ const current = atChroma(c);
2879
+ if (minInGamut && isInGamut(current)) {
2880
+ min = c;
2881
+ continue;
2882
+ }
2883
+ clipped = clip(current);
2884
+ const e = deltaE(rgbToOklab(clipped), polarToRectangular([
2885
+ lightness,
2886
+ c,
2887
+ hue
2888
+ ]));
2889
+ if (e < JND) {
2890
+ if (JND - e < EPSILON) break;
2891
+ minInGamut = false;
2892
+ min = c;
2893
+ } else max = c;
2894
+ }
2895
+ return clipped;
2896
+ };
2897
+ const labToRgb = ([l, a, b])=>{
2898
+ const k = 24389 / 27;
2899
+ const e = 216 / 24389;
2900
+ const fy = (l + 16) / 116;
2901
+ const fx = a / 500 + fy;
2902
+ const fz = fy - b / 200;
2903
+ const xyz = [
2904
+ (fx ** 3 > e ? fx ** 3 : (116 * fx - 16) / k) * 0.3457 / 0.3585,
2905
+ l > k * e ? fy ** 3 : l / k,
2906
+ (fz ** 3 > e ? fz ** 3 : (116 * fz - 16) / k) * 0.2958 / 0.3585
2907
+ ];
2908
+ const d65 = [
2909
+ 0.955473421488075 * xyz[0] - 0.02309845494876471 * xyz[1] + 0.06325924320057072 * xyz[2],
2910
+ -0.0283697093338637 * xyz[0] + 1.0099953980813041 * xyz[1] + 0.021041441191917323 * xyz[2],
2911
+ 0.012314014864481998 * xyz[0] - 0.020507649298898964 * xyz[1] + 1.330365926242124 * xyz[2]
2912
+ ];
2913
+ const linear = [
2914
+ 3.2409699419045226 * d65[0] - 1.537383177570094 * d65[1] - 0.4986107602930034 * d65[2],
2915
+ -0.9692436362808796 * d65[0] + 1.8759675015077202 * d65[1] + 0.04155505740717559 * d65[2],
2916
+ 0.05563007969699366 * d65[0] - 0.20397695888897652 * d65[1] + 1.0569715142428786 * d65[2]
2917
+ ];
2918
+ const color = encodeRgb(linear);
2919
+ return isInGamut(color) ? color : oklabToRgb(linearRgbToOklab(linear));
2920
+ };
2921
+ const parseColorMix = (nodes)=>{
2922
+ const parts = splitByComma(nodes);
2923
+ if (3 !== parts.length) return;
2924
+ const space = mixSpace(parts[0]);
2925
+ const first = mixColor(parts[1]);
2926
+ const second = mixColor(parts[2]);
2927
+ if (!space || !first || !second) return;
2928
+ let p1 = first.percentage;
2929
+ let p2 = second.percentage;
2930
+ if (void 0 === p1 && void 0 === p2) p1 = p2 = 50;
2931
+ else if (void 0 === p1) p1 = 100 - p2;
2932
+ else if (void 0 === p2) p2 = 100 - p1;
2933
+ const sum = p1 + p2;
2934
+ if (sum <= 0) return;
2935
+ const mixed = interpolate(space, first.color, second.color, p2 / sum);
2936
+ return {
2937
+ ...mixed,
2938
+ alpha: mixed.alpha * Math.min(sum, 100) / 100
2939
+ };
2940
+ };
2941
+ const splitByComma = (nodes)=>{
2942
+ const parts = [
2943
+ []
2944
+ ];
2945
+ for (const node of nodes)if ('div' === node.type && ',' === node.value) parts.push([]);
2946
+ else if ('space' !== node.type && 'comment' !== node.type) parts[parts.length - 1].push(node);
2947
+ return parts;
2948
+ };
2949
+ const MIX_SPACES = new Set([
2950
+ 'srgb',
2951
+ 'srgb-linear',
2952
+ 'oklab',
2953
+ 'oklch'
2954
+ ]);
2955
+ const mixSpace = (nodes)=>{
2956
+ const words = nodes.map((node)=>node.value.toLowerCase());
2957
+ const [keyword, space, ...hue] = words;
2958
+ const defaultHue = 0 === hue.length || 'shorter' === hue[0] && 'hue' === hue[1];
2959
+ return 'in' === keyword && MIX_SPACES.has(space) && defaultHue ? space : void 0;
2960
+ };
2961
+ const mixColor = (nodes)=>{
2962
+ let color;
2963
+ let percentage;
2964
+ for (const node of nodes){
2965
+ const unit = 'word' === node.type && postcss_value_parser.unit(node.value);
2966
+ if (unit && '%' === unit.unit && void 0 === percentage) percentage = Number(unit.number);
2967
+ else {
2968
+ if (color) return;
2969
+ color = parseColor(node);
2970
+ if (!color) return;
2971
+ }
2972
+ }
2973
+ return color && {
2974
+ color,
2975
+ percentage
2976
+ };
2977
+ };
2978
+ const interpolate = (space, from, to, weight)=>{
2979
+ const alpha = from.alpha * (1 - weight) + to.alpha * weight;
2980
+ if (0 === alpha) return {
2981
+ r: 0,
2982
+ g: 0,
2983
+ b: 0,
2984
+ alpha: 0
2985
+ };
2986
+ const blend = (a, b)=>(a * from.alpha * (1 - weight) + b * to.alpha * weight) / alpha;
2987
+ switch(space){
2988
+ case 'srgb':
2989
+ return {
2990
+ r: blend(from.r, to.r),
2991
+ g: blend(from.g, to.g),
2992
+ b: blend(from.b, to.b),
2993
+ alpha
2994
+ };
2995
+ case 'srgb-linear':
2996
+ return {
2997
+ ...encodeRgb([
2998
+ blend(gammaDecode(from.r), gammaDecode(to.r)),
2999
+ blend(gammaDecode(from.g), gammaDecode(to.g)),
3000
+ blend(gammaDecode(from.b), gammaDecode(to.b))
3001
+ ]),
3002
+ alpha
3003
+ };
3004
+ case 'oklab':
3005
+ {
3006
+ const a = rgbToOklab(from);
3007
+ const b = rgbToOklab(to);
3008
+ return {
3009
+ ...oklabToRgb([
3010
+ blend(a[0], b[0]),
3011
+ blend(a[1], b[1]),
3012
+ blend(a[2], b[2])
3013
+ ]),
3014
+ alpha
3015
+ };
3016
+ }
3017
+ default:
3018
+ {
3019
+ const a = rectangularToPolar(rgbToOklab(from));
3020
+ const b = rectangularToPolar(rgbToOklab(to));
3021
+ const powerless = (color, source)=>color[1] < 1e-4 || 0 === source.alpha;
3022
+ const hueA = powerless(a, from) ? b[2] : a[2];
3023
+ const hueB = powerless(b, to) ? a[2] : b[2];
3024
+ let delta = hueB - hueA;
3025
+ if (delta > 180) delta -= 360;
3026
+ else if (delta < -180) delta += 360;
3027
+ const hue = hueA + delta * weight;
3028
+ return {
3029
+ ...oklabToRgb(polarToRectangular([
3030
+ blend(a[0], b[0]),
3031
+ blend(a[1], b[1]),
3032
+ hue
3033
+ ])),
3034
+ alpha
3035
+ };
3036
+ }
3037
+ }
3038
+ };
3039
+ const LYNX_PROPERTIES = new Set([
3040
+ '-x-animation-color-interpolation',
3041
+ '-x-app-region',
3042
+ '-x-auto-font-size',
3043
+ '-x-auto-font-size-line-ranges',
3044
+ '-x-auto-font-size-preset-sizes',
3045
+ '-x-box-match-parent-size',
3046
+ '-x-box-propagate-min-constraints',
3047
+ '-x-caret-gradient',
3048
+ '-x-caret-height',
3049
+ '-x-caret-radius',
3050
+ '-x-caret-width',
3051
+ '-x-handle-color',
3052
+ '-x-handle-size',
3053
+ '-x-placeholder-color',
3054
+ '-x-placeholder-font-family',
3055
+ '-x-placeholder-font-size',
3056
+ '-x-placeholder-font-style',
3057
+ '-x-placeholder-font-weight',
3058
+ '-x-text-decoration-gap',
3059
+ '-x-text-decoration-width',
3060
+ 'adapt-font-size',
3061
+ 'align-content',
3062
+ 'align-items',
3063
+ 'align-self',
3064
+ 'animation',
3065
+ 'animation-delay',
3066
+ 'animation-direction',
3067
+ 'animation-duration',
3068
+ 'animation-fill-mode',
3069
+ 'animation-iteration-count',
3070
+ 'animation-name',
3071
+ 'animation-play-state',
3072
+ 'animation-timing-function',
3073
+ 'aspect-ratio',
3074
+ 'background',
3075
+ 'background-clip',
3076
+ 'background-color',
3077
+ 'background-image',
3078
+ 'background-origin',
3079
+ 'background-position',
3080
+ 'background-repeat',
3081
+ 'background-size',
3082
+ 'border',
3083
+ 'border-bottom',
3084
+ 'border-bottom-color',
3085
+ 'border-bottom-left-radius',
3086
+ 'border-bottom-right-radius',
3087
+ 'border-bottom-style',
3088
+ 'border-bottom-width',
3089
+ 'border-color',
3090
+ 'border-end-end-radius',
3091
+ 'border-end-start-radius',
3092
+ 'border-inline-end-color',
3093
+ 'border-inline-end-style',
3094
+ 'border-inline-end-width',
3095
+ 'border-inline-start-color',
3096
+ 'border-inline-start-style',
3097
+ 'border-inline-start-width',
3098
+ 'border-left',
3099
+ 'border-left-color',
3100
+ 'border-left-style',
3101
+ 'border-left-width',
3102
+ 'border-radius',
3103
+ 'border-right',
3104
+ 'border-right-color',
3105
+ 'border-right-style',
3106
+ 'border-right-width',
3107
+ 'border-start-end-radius',
3108
+ 'border-start-start-radius',
3109
+ 'border-style',
3110
+ 'border-top',
3111
+ 'border-top-color',
3112
+ 'border-top-left-radius',
3113
+ 'border-top-right-radius',
3114
+ 'border-top-style',
3115
+ 'border-top-width',
3116
+ 'border-width',
3117
+ 'bottom',
3118
+ 'box-shadow',
3119
+ 'box-sizing',
3120
+ 'caret-color',
3121
+ 'clip-path',
3122
+ 'color',
3123
+ 'column-gap',
3124
+ 'content',
3125
+ 'cursor',
3126
+ 'direction',
3127
+ 'display',
3128
+ 'enter-transition-name',
3129
+ 'exit-transition-name',
3130
+ 'filter',
3131
+ 'flex',
3132
+ 'flex-basis',
3133
+ 'flex-direction',
3134
+ 'flex-flow',
3135
+ 'flex-grow',
3136
+ 'flex-shrink',
3137
+ 'flex-wrap',
3138
+ 'font-family',
3139
+ 'font-feature-settings',
3140
+ 'font-optical-sizing',
3141
+ 'font-size',
3142
+ 'font-style',
3143
+ 'font-variation-settings',
3144
+ 'font-weight',
3145
+ 'gap',
3146
+ 'grid-auto-columns',
3147
+ 'grid-auto-flow',
3148
+ 'grid-auto-rows',
3149
+ 'grid-column',
3150
+ 'grid-column-end',
3151
+ 'grid-column-gap',
3152
+ 'grid-column-span',
3153
+ 'grid-column-start',
3154
+ 'grid-row',
3155
+ 'grid-row-end',
3156
+ 'grid-row-gap',
3157
+ 'grid-row-span',
3158
+ 'grid-row-start',
3159
+ 'grid-template-columns',
3160
+ 'grid-template-rows',
3161
+ 'height',
3162
+ 'hyphens',
3163
+ 'image-rendering',
3164
+ 'implicit-animation',
3165
+ 'inset-inline-end',
3166
+ 'inset-inline-start',
3167
+ 'justify-content',
3168
+ 'justify-items',
3169
+ 'justify-self',
3170
+ 'layout-animation-create-delay',
3171
+ 'layout-animation-create-duration',
3172
+ 'layout-animation-create-property',
3173
+ 'layout-animation-create-timing-function',
3174
+ 'layout-animation-delete-delay',
3175
+ 'layout-animation-delete-duration',
3176
+ 'layout-animation-delete-property',
3177
+ 'layout-animation-delete-timing-function',
3178
+ 'layout-animation-update-delay',
3179
+ 'layout-animation-update-duration',
3180
+ 'layout-animation-update-timing-function',
3181
+ 'left',
3182
+ 'letter-spacing',
3183
+ 'line-height',
3184
+ 'line-spacing',
3185
+ 'linear-cross-gravity',
3186
+ 'linear-direction',
3187
+ 'linear-gravity',
3188
+ 'linear-layout-gravity',
3189
+ 'linear-orientation',
3190
+ 'linear-weight',
3191
+ 'linear-weight-sum',
3192
+ 'list-cross-axis-gap',
3193
+ 'list-main-axis-gap',
3194
+ 'margin',
3195
+ 'margin-bottom',
3196
+ 'margin-inline-end',
3197
+ 'margin-inline-start',
3198
+ 'margin-left',
3199
+ 'margin-right',
3200
+ 'margin-top',
3201
+ 'mask',
3202
+ 'mask-clip',
3203
+ 'mask-composite',
3204
+ 'mask-image',
3205
+ 'mask-origin',
3206
+ 'mask-position',
3207
+ 'mask-repeat',
3208
+ 'mask-size',
3209
+ 'max-height',
3210
+ 'max-width',
3211
+ 'min-height',
3212
+ 'min-width',
3213
+ 'offset-distance',
3214
+ 'offset-path',
3215
+ 'offset-rotate',
3216
+ 'opacity',
3217
+ 'order',
3218
+ 'outline',
3219
+ 'outline-color',
3220
+ 'outline-style',
3221
+ 'outline-width',
3222
+ 'overflow',
3223
+ 'overflow-x',
3224
+ 'overflow-y',
3225
+ 'padding',
3226
+ 'padding-bottom',
3227
+ 'padding-inline-end',
3228
+ 'padding-inline-start',
3229
+ 'padding-left',
3230
+ 'padding-right',
3231
+ 'padding-top',
3232
+ 'pause-transition-name',
3233
+ 'perspective',
3234
+ 'pointer-events',
3235
+ 'position',
3236
+ 'relative-align-bottom',
3237
+ 'relative-align-inline-end',
3238
+ 'relative-align-inline-start',
3239
+ 'relative-align-left',
3240
+ 'relative-align-right',
3241
+ 'relative-align-top',
3242
+ 'relative-bottom-of',
3243
+ 'relative-center',
3244
+ 'relative-id',
3245
+ 'relative-inline-end-of',
3246
+ 'relative-inline-start-of',
3247
+ 'relative-layout-once',
3248
+ 'relative-left-of',
3249
+ 'relative-right-of',
3250
+ 'relative-top-of',
3251
+ 'resume-transition-name',
3252
+ 'right',
3253
+ 'row-gap',
3254
+ 'text-align',
3255
+ 'text-decoration',
3256
+ 'text-decoration-color',
3257
+ 'text-decoration-thickness',
3258
+ 'text-indent',
3259
+ 'text-overflow',
3260
+ 'text-shadow',
3261
+ 'text-stroke',
3262
+ 'text-stroke-color',
3263
+ 'text-stroke-width',
3264
+ 'top',
3265
+ 'transform',
3266
+ 'transform-origin',
3267
+ 'transition',
3268
+ 'transition-delay',
3269
+ 'transition-duration',
3270
+ 'transition-property',
3271
+ 'transition-timing-function',
3272
+ 'vertical-align',
3273
+ 'visibility',
3274
+ 'white-space',
3275
+ 'width',
3276
+ 'word-break',
3277
+ 'z-index'
3278
+ ]);
3279
+ const LYNX_KEYWORDS = new Map(Object.entries({
3280
+ '-x-animation-color-interpolation': [
3281
+ 'auto',
3282
+ 'srgb',
3283
+ 'linearrgb'
3284
+ ],
3285
+ '-x-app-region': [
3286
+ 'none',
3287
+ 'drag',
3288
+ 'no-drag'
3289
+ ],
3290
+ '-x-placeholder-font-style': [
3291
+ 'normal',
3292
+ 'italic',
3293
+ 'oblique'
3294
+ ],
3295
+ '-x-placeholder-font-weight': [
3296
+ 'normal',
3297
+ 'bold',
3298
+ '100',
3299
+ '200',
3300
+ '300',
3301
+ '400',
3302
+ '500',
3303
+ '600',
3304
+ '700',
3305
+ '800',
3306
+ '900'
3307
+ ],
3308
+ 'align-content': [
3309
+ 'flex-start',
3310
+ 'flex-end',
3311
+ 'center',
3312
+ 'stretch',
3313
+ 'space-between',
3314
+ 'space-around',
3315
+ 'start',
3316
+ 'end'
3317
+ ],
3318
+ 'box-sizing': [
3319
+ 'border-box',
3320
+ 'content-box',
3321
+ 'auto'
3322
+ ],
3323
+ direction: [
3324
+ 'normal',
3325
+ 'lynx-rtl',
3326
+ 'rtl',
3327
+ 'ltr'
3328
+ ],
3329
+ display: [
3330
+ 'none',
3331
+ 'flex',
3332
+ 'grid',
3333
+ 'linear',
3334
+ 'relative',
3335
+ 'block',
3336
+ 'auto',
3337
+ '-x-box'
3338
+ ],
3339
+ 'flex-direction': [
3340
+ 'column',
3341
+ 'row',
3342
+ 'row-reverse',
3343
+ 'column-reverse'
3344
+ ],
3345
+ 'flex-wrap': [
3346
+ 'wrap',
3347
+ 'nowrap',
3348
+ 'wrap-reverse'
3349
+ ],
3350
+ 'font-optical-sizing': [
3351
+ 'none',
3352
+ 'auto'
3353
+ ],
3354
+ 'font-style': [
3355
+ 'normal',
3356
+ 'italic',
3357
+ 'oblique'
3358
+ ],
3359
+ 'font-weight': [
3360
+ 'normal',
3361
+ 'bold',
3362
+ '100',
3363
+ '200',
3364
+ '300',
3365
+ '400',
3366
+ '500',
3367
+ '600',
3368
+ '700',
3369
+ '800',
3370
+ '900'
3371
+ ],
3372
+ hyphens: [
3373
+ 'none',
3374
+ 'manual',
3375
+ 'auto'
3376
+ ],
3377
+ 'image-rendering': [
3378
+ 'auto',
3379
+ 'crisp-edges',
3380
+ 'pixelated'
3381
+ ],
3382
+ 'justify-content': [
3383
+ 'flex-start',
3384
+ 'center',
3385
+ 'flex-end',
3386
+ 'space-between',
3387
+ 'space-around',
3388
+ 'space-evenly',
3389
+ 'stretch',
3390
+ 'start',
3391
+ 'end'
3392
+ ],
3393
+ 'linear-cross-gravity': [
3394
+ 'none',
3395
+ 'start',
3396
+ 'end',
3397
+ 'center',
3398
+ 'stretch'
3399
+ ],
3400
+ 'linear-gravity': [
3401
+ 'none',
3402
+ 'top',
3403
+ 'bottom',
3404
+ 'left',
3405
+ 'right',
3406
+ 'center-vertical',
3407
+ 'center-horizontal',
3408
+ 'space-between',
3409
+ 'start',
3410
+ 'end',
3411
+ 'center'
3412
+ ],
3413
+ 'linear-layout-gravity': [
3414
+ 'none',
3415
+ 'top',
3416
+ 'bottom',
3417
+ 'left',
3418
+ 'right',
3419
+ 'center-vertical',
3420
+ 'center-horizontal',
3421
+ 'fill-vertical',
3422
+ 'fill-horizontal',
3423
+ 'center',
3424
+ 'stretch',
3425
+ 'start',
3426
+ 'end'
3427
+ ],
3428
+ 'linear-orientation': [
3429
+ 'horizontal',
3430
+ 'vertical',
3431
+ 'horizontal-reverse',
3432
+ 'vertical-reverse',
3433
+ 'row',
3434
+ 'column',
3435
+ 'row-reverse',
3436
+ 'column-reverse'
3437
+ ],
3438
+ 'pointer-events': [
3439
+ 'auto',
3440
+ 'none'
3441
+ ],
3442
+ position: [
3443
+ 'absolute',
3444
+ 'relative',
3445
+ 'fixed',
3446
+ 'sticky'
3447
+ ],
3448
+ 'relative-center': [
3449
+ 'none',
3450
+ 'vertical',
3451
+ 'horizontal',
3452
+ 'both'
3453
+ ],
3454
+ 'text-align': [
3455
+ 'left',
3456
+ 'center',
3457
+ 'right',
3458
+ 'start',
3459
+ 'end',
3460
+ 'justify'
3461
+ ],
3462
+ 'text-overflow': [
3463
+ 'clip',
3464
+ 'ellipsis'
3465
+ ],
3466
+ visibility: [
3467
+ 'hidden',
3468
+ 'visible',
3469
+ 'none',
3470
+ 'collapse'
3471
+ ],
3472
+ 'white-space': [
3473
+ 'normal',
3474
+ 'nowrap'
3475
+ ],
3476
+ 'word-break': [
3477
+ 'normal',
3478
+ 'break-all',
3479
+ 'keep-all'
3480
+ ]
3481
+ }).map(([property, keywords])=>[
3482
+ property,
3483
+ new Set(keywords)
3484
+ ]));
3485
+ const COMPOSED_TRANSFORM = "translate3d(var(--tw-translate-x), var(--tw-translate-y), var(--tw-translate-z)) rotate(var(--tw-rotate)) scale(var(--tw-scale-x), var(--tw-scale-y)) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)";
3486
+ const TRANSFORM_DEFAULTS = new Map([
3487
+ [
3488
+ '--tw-translate-x',
3489
+ '0'
3490
+ ],
3491
+ [
3492
+ '--tw-translate-y',
3493
+ '0'
3494
+ ],
3495
+ [
3496
+ '--tw-translate-z',
3497
+ '0'
3498
+ ],
3499
+ [
3500
+ '--tw-rotate',
3501
+ '0deg'
3502
+ ],
3503
+ [
3504
+ '--tw-scale-x',
3505
+ '1'
3506
+ ],
3507
+ [
3508
+ '--tw-scale-y',
3509
+ '1'
3510
+ ]
3511
+ ]);
3512
+ const lowerDeclarations = (rule, channelVariables = new Set())=>{
3513
+ const composed = [];
3514
+ for (const declaration of rule.nodes.slice())if ('decl' === declaration.type) {
3515
+ declaration.value = lowerColors(declaration.value, channelVariables);
3516
+ if (lowerTransformProperty(declaration)) {
3517
+ composed.push(declaration);
3518
+ continue;
3519
+ }
3520
+ lowerValue(declaration);
3521
+ expandLogical(declaration);
3522
+ }
3523
+ if (composed.length > 0) {
3524
+ composed[composed.length - 1].before({
3525
+ prop: 'transform',
3526
+ value: COMPOSED_TRANSFORM
3527
+ });
3528
+ for (const declaration of composed)declaration.remove();
3529
+ }
3530
+ dropUnsupportedProperties(rule);
3531
+ return {
3532
+ composesTransform: composed.length > 0
3533
+ };
3534
+ };
3535
+ const TRANSFORM_VARIABLES = /^--tw-(?:translate-[xyz]|rotate(?:-[xyz])?|skew-[xy]|scale-[xyz])$/;
3536
+ const lowerTransformVariables = (root)=>{
3537
+ root.walkDecls(TRANSFORM_VARIABLES, (declaration)=>{
3538
+ declaration.value = transformValue(declaration.prop, declaration.value);
3539
+ });
3540
+ };
3541
+ const lowerTransformProperty = (declaration)=>{
3542
+ const { prop } = declaration;
3543
+ const values = splitSpaces(declaration.value);
3544
+ switch(prop){
3545
+ case 'translate':
3546
+ if (!isTailwindComposition(values, '--tw-translate-')) {
3547
+ const [x, y = '0', z = '0'] = 'none' === values[0] ? [
3548
+ '0',
3549
+ '0',
3550
+ '0'
3551
+ ] : values;
3552
+ setVariables(declaration, {
3553
+ '--tw-translate-x': x,
3554
+ '--tw-translate-y': y,
3555
+ '--tw-translate-z': z
3556
+ });
3557
+ }
3558
+ break;
3559
+ case 'rotate':
3560
+ if (1 !== values.length) return false;
3561
+ setVariables(declaration, {
3562
+ '--tw-rotate': 'none' === values[0] ? '0deg' : values[0]
3563
+ });
3564
+ break;
3565
+ case 'scale':
3566
+ if (!isTailwindComposition(values, '--tw-scale-')) {
3567
+ const [x, y = x] = 'none' === values[0] ? [
3568
+ '1',
3569
+ '1'
3570
+ ] : values;
3571
+ setVariables(declaration, {
3572
+ '--tw-scale-x': x,
3573
+ '--tw-scale-y': y
3574
+ });
3575
+ }
3576
+ break;
3577
+ case 'transform':
3578
+ if (!isTailwindComposition(values, '--tw-')) return false;
3579
+ break;
3580
+ default:
3581
+ return false;
3582
+ }
3583
+ return true;
3584
+ };
3585
+ const isTailwindComposition = (values, prefix)=>values.length > 0 && values.every((value)=>value.startsWith(`var(${prefix}`));
3586
+ const setVariables = (declaration, variables)=>{
3587
+ for (const [prop, value] of Object.entries(variables))declaration.before({
3588
+ prop,
3589
+ value: transformValue(prop, value)
3590
+ });
3591
+ };
3592
+ const transformValue = (prop, value)=>{
3593
+ const folded = foldCalc(value);
3594
+ if (!prop.startsWith('--tw-scale-')) return folded;
3595
+ const unit = postcss_value_parser.unit(folded);
3596
+ return unit && '%' === unit.unit ? String(Number(unit.number) / 100) : folded;
3597
+ };
3598
+ const splitSpaces = (value)=>postcss_value_parser(value).nodes.filter((node)=>'space' !== node.type && 'comment' !== node.type).map((node)=>postcss_value_parser.stringify(node));
3599
+ const lowerValue = (declaration)=>{
3600
+ switch(declaration.prop){
3601
+ case 'opacity':
3602
+ {
3603
+ const unit = postcss_value_parser.unit(declaration.value);
3604
+ if (unit && '%' === unit.unit) declaration.value = String(Number(unit.number) / 100);
3605
+ break;
3606
+ }
3607
+ case 'text-decoration-line':
3608
+ declaration.prop = 'text-decoration';
3609
+ break;
3610
+ case 'transition-property':
3611
+ declaration.value = lowerTransitionProperty(declaration.value);
3612
+ break;
3613
+ case '--tw-gradient-position':
3614
+ declaration.value = lowerGradientPosition(declaration);
3615
+ break;
3616
+ default:
3617
+ if (/\binfinity\b/i.test(declaration.value)) declaration.value = foldCalc(declaration.value);
3618
+ declaration.value = clampHugeNumbers(declaration.value);
3619
+ break;
3620
+ }
3621
+ };
3622
+ const lowerTransitionProperty = (value)=>{
3623
+ const properties = value.split(',').map((property)=>{
3624
+ const name = property.trim().toLowerCase();
3625
+ return [
3626
+ 'translate',
3627
+ 'rotate',
3628
+ 'scale'
3629
+ ].includes(name) ? 'transform' : name;
3630
+ }).filter((name)=>'all' === name || 'none' === name || LYNX_PROPERTIES.has(name));
3631
+ return [
3632
+ ...new Set(properties)
3633
+ ].join(', ') || 'none';
3634
+ };
3635
+ const lowerGradientPosition = (declaration)=>{
3636
+ const position = declaration.value.replace(/\s*\bin\s+[a-z0-9-]+(?:\s+(?:shorter|longer|increasing|decreasing)\s+hue)?/gi, '').trim();
3637
+ if (position) return position;
3638
+ let gradient = 'linear';
3639
+ declaration.parent?.walkDecls('background-image', ({ value })=>{
3640
+ gradient = /^(radial|conic)-gradient\(/.exec(value)?.[1] ?? gradient;
3641
+ });
3642
+ return ({
3643
+ linear: 'to bottom',
3644
+ radial: 'ellipse',
3645
+ conic: 'from 0deg'
3646
+ })[gradient];
3647
+ };
3648
+ const LOGICAL_PAIRS = {
3649
+ 'padding-inline': [
3650
+ 'padding-left',
3651
+ 'padding-right'
3652
+ ],
3653
+ 'padding-block': [
3654
+ 'padding-top',
3655
+ 'padding-bottom'
3656
+ ],
3657
+ 'margin-inline': [
3658
+ 'margin-left',
3659
+ 'margin-right'
3660
+ ],
3661
+ 'margin-block': [
3662
+ 'margin-top',
3663
+ 'margin-bottom'
3664
+ ],
3665
+ 'inset-inline': [
3666
+ 'left',
3667
+ 'right'
3668
+ ],
3669
+ 'inset-block': [
3670
+ 'top',
3671
+ 'bottom'
3672
+ ],
3673
+ 'border-inline-width': [
3674
+ 'border-left-width',
3675
+ 'border-right-width'
3676
+ ],
3677
+ 'border-block-width': [
3678
+ 'border-top-width',
3679
+ 'border-bottom-width'
3680
+ ],
3681
+ 'border-inline-style': [
3682
+ 'border-left-style',
3683
+ 'border-right-style'
3684
+ ],
3685
+ 'border-block-style': [
3686
+ 'border-top-style',
3687
+ 'border-bottom-style'
3688
+ ],
3689
+ 'border-inline-color': [
3690
+ 'border-left-color',
3691
+ 'border-right-color'
3692
+ ],
3693
+ 'border-block-color': [
3694
+ 'border-top-color',
3695
+ 'border-bottom-color'
3696
+ ]
3697
+ };
3698
+ const LOGICAL_BOTH_SIDES = {
3699
+ 'border-inline': [
3700
+ 'border-left',
3701
+ 'border-right'
3702
+ ],
3703
+ 'border-block': [
3704
+ 'border-top',
3705
+ 'border-bottom'
3706
+ ]
3707
+ };
3708
+ const LOGICAL_LONGHANDS = {
3709
+ 'padding-inline-start': 'padding-left',
3710
+ 'padding-inline-end': 'padding-right',
3711
+ 'padding-block-start': 'padding-top',
3712
+ 'padding-block-end': 'padding-bottom',
3713
+ 'margin-inline-start': 'margin-left',
3714
+ 'margin-inline-end': 'margin-right',
3715
+ 'margin-block-start': 'margin-top',
3716
+ 'margin-block-end': 'margin-bottom',
3717
+ 'inset-inline-start': 'left',
3718
+ 'inset-inline-end': 'right',
3719
+ 'inset-block-start': 'top',
3720
+ 'inset-block-end': 'bottom',
3721
+ 'border-inline-start': 'border-left',
3722
+ 'border-inline-end': 'border-right',
3723
+ 'border-block-start': 'border-top',
3724
+ 'border-block-end': 'border-bottom',
3725
+ 'border-inline-start-width': 'border-left-width',
3726
+ 'border-inline-end-width': 'border-right-width',
3727
+ 'border-block-start-width': 'border-top-width',
3728
+ 'border-block-end-width': 'border-bottom-width',
3729
+ 'border-inline-start-style': 'border-left-style',
3730
+ 'border-inline-end-style': 'border-right-style',
3731
+ 'border-block-start-style': 'border-top-style',
3732
+ 'border-block-end-style': 'border-bottom-style',
3733
+ 'border-inline-start-color': 'border-left-color',
3734
+ 'border-inline-end-color': 'border-right-color',
3735
+ 'border-block-start-color': 'border-top-color',
3736
+ 'border-block-end-color': 'border-bottom-color',
3737
+ 'border-start-start-radius': 'border-top-left-radius',
3738
+ 'border-start-end-radius': 'border-top-right-radius',
3739
+ 'border-end-start-radius': 'border-bottom-left-radius',
3740
+ 'border-end-end-radius': 'border-bottom-right-radius'
3741
+ };
3742
+ const expandLogical = (declaration)=>{
3743
+ const { prop, value, important } = declaration;
3744
+ const longhand = LOGICAL_LONGHANDS[prop];
3745
+ if (longhand) {
3746
+ declaration.prop = longhand;
3747
+ return;
3748
+ }
3749
+ let expanded;
3750
+ const pair = LOGICAL_PAIRS[prop];
3751
+ const bothSides = LOGICAL_BOTH_SIDES[prop];
3752
+ if (pair) {
3753
+ const [start, end = start] = splitSpaces(value);
3754
+ expanded = [
3755
+ [
3756
+ pair[0],
3757
+ start
3758
+ ],
3759
+ [
3760
+ pair[1],
3761
+ end
3762
+ ]
3763
+ ];
3764
+ } else if (bothSides) expanded = [
3765
+ [
3766
+ bothSides[0],
3767
+ value
3768
+ ],
3769
+ [
3770
+ bothSides[1],
3771
+ value
3772
+ ]
3773
+ ];
3774
+ else if ('inset' === prop) {
3775
+ const [top, right = top, bottom = top, left = right] = splitSpaces(value);
3776
+ expanded = [
3777
+ [
3778
+ 'top',
3779
+ top
3780
+ ],
3781
+ [
3782
+ 'right',
3783
+ right
3784
+ ],
3785
+ [
3786
+ 'bottom',
3787
+ bottom
3788
+ ],
3789
+ [
3790
+ 'left',
3791
+ left
3792
+ ]
3793
+ ];
3794
+ }
3795
+ if (!expanded) return;
3796
+ for (const [physical, physicalValue] of expanded)declaration.before({
3797
+ prop: physical,
3798
+ value: physicalValue,
3799
+ important
3800
+ });
3801
+ declaration.remove();
3802
+ };
3803
+ const dropUnsupportedProperties = (rule)=>{
3804
+ rule.each((node)=>{
3805
+ if ('decl' !== node.type || node.prop.startsWith('--')) return;
3806
+ const prop = node.prop.toLowerCase();
3807
+ const keywords = LYNX_KEYWORDS.get(prop);
3808
+ const value = node.value.trim().toLowerCase();
3809
+ if (!LYNX_PROPERTIES.has(prop) || void 0 !== keywords && /^[a-z-]+$/.test(value) && !GLOBAL_KEYWORDS.has(value) && !keywords.has(value)) node.remove();
3810
+ });
3811
+ };
3812
+ const GLOBAL_KEYWORDS = new Set([
3813
+ 'inherit',
3814
+ 'initial',
3815
+ 'unset',
3816
+ 'revert'
3817
+ ]);
3818
+ const lowerSelectors = (rule)=>{
3819
+ const selectors = rule.selectors.filter((selector)=>!/(?<!\\):host\b/.test(selector)).flatMap(unwrapWhereAndIs);
3820
+ if (0 === selectors.length) return false;
3821
+ rule.selectors = selectors.every((selector)=>NOT_LAST_CHILD.test(selector)) && mirrorBetweenChildren(rule) ? selectors.map((selector)=>selector.replace(NOT_LAST_CHILD, ' > * + *')) : selectors;
3822
+ return true;
3823
+ };
3824
+ const unwrapWhereAndIs = (selector)=>{
3825
+ const match = /^:(?:where|is)\(/i.exec(selector);
3826
+ if (!match || closingParenthesis(selector, match[0].length) !== selector.length - 1) return [
3827
+ selector
3828
+ ];
3829
+ return splitTopLevel(selector.slice(match[0].length, -1)).flatMap(unwrapWhereAndIs);
3830
+ };
3831
+ const closingParenthesis = (text, start)=>{
3832
+ let depth = 1;
3833
+ for(let index = start; index < text.length; index++){
3834
+ const character = text[index];
3835
+ if ('\\' === character) index++;
3836
+ else if ('(' === character) depth++;
3837
+ else if (')' === character && 0 === --depth) return index;
3838
+ }
3839
+ return -1;
3840
+ };
3841
+ const splitTopLevel = (list)=>{
3842
+ const parts = [];
3843
+ let depth = 0;
3844
+ let current = '';
3845
+ for(let index = 0; index < list.length; index++){
3846
+ const character = list[index];
3847
+ if ('\\' === character) {
3848
+ current += list.slice(index, index + 2);
3849
+ index++;
3850
+ continue;
3851
+ }
3852
+ if ('(' === character) depth++;
3853
+ else if (')' === character) depth--;
3854
+ else if (',' === character && 0 === depth) {
3855
+ parts.push(current.trim());
3856
+ current = '';
3857
+ continue;
3858
+ }
3859
+ current += character;
3860
+ }
3861
+ parts.push(current.trim());
3862
+ return parts;
3863
+ };
3864
+ const NOT_LAST_CHILD = /\s*>\s*:not\(:last-child\)$/;
3865
+ const OPPOSITE_SIDES = {
3866
+ top: 'bottom',
3867
+ bottom: 'top',
3868
+ left: 'right',
3869
+ right: 'left',
3870
+ 'block-start': 'block-end',
3871
+ 'block-end': 'block-start',
3872
+ 'inline-start': 'inline-end',
3873
+ 'inline-end': 'inline-start'
3874
+ };
3875
+ const mirrorBetweenChildren = (rule)=>{
3876
+ const sidesOnly = rule.nodes.every((node)=>'decl' !== node.type || node.prop.startsWith('--') || /^(margin|padding|border)-/.test(node.prop));
3877
+ if (!sidesOnly) return false;
3878
+ rule.walkDecls((declaration)=>{
3879
+ if (declaration.prop.startsWith('--')) return;
3880
+ declaration.prop = declaration.prop.replace(/\b(top|bottom|left|right|block-start|block-end|inline-start|inline-end)\b/, (side)=>OPPOSITE_SIDES[side]);
3881
+ });
3882
+ return true;
3883
+ };
3884
+ const flattenNesting = (root)=>{
3885
+ root.each((node)=>{
3886
+ flattenNode(node);
3887
+ });
3888
+ };
3889
+ const flattenNode = (node)=>{
3890
+ if ('rule' === node.type) flattenRule(node);
3891
+ else if ('atrule' === node.type && node.nodes) node.each((child)=>{
3892
+ flattenNode(child);
3893
+ });
3894
+ };
3895
+ const flattenRule = (rule)=>{
3896
+ let last = rule;
3897
+ for (const child of rule.nodes.slice())if ('rule' === child.type) {
3898
+ child.selectors = resolveNested(child.selectors, rule.selectors);
3899
+ last.after(child);
3900
+ last = flattenRule(child);
3901
+ } else if ('atrule' === child.type) {
3902
+ wrapDeclarations(child, rule);
3903
+ last.after(child);
3904
+ last = child;
3905
+ flattenNode(child);
3906
+ }
3907
+ return last;
3908
+ };
3909
+ const wrapDeclarations = (atRule, rule)=>{
3910
+ if (!atRule.nodes) return;
3911
+ for (const child of atRule.nodes)if ('rule' === child.type) child.selectors = resolveNested(child.selectors, rule.selectors);
3912
+ else if ('atrule' === child.type) wrapDeclarations(child, rule);
3913
+ const declarations = atRule.nodes.filter((node)=>'decl' === node.type);
3914
+ if (declarations.length > 0) {
3915
+ const wrapper = rule.clone();
3916
+ wrapper.removeAll();
3917
+ wrapper.append(declarations);
3918
+ atRule.prepend(wrapper);
3919
+ }
3920
+ };
3921
+ const resolveNested = (selectors, parents)=>parents.flatMap((parent)=>selectors.map((selector)=>/(?<!\\)&/.test(selector) ? selector.replaceAll(/(?<!\\)&/g, parent) : `${parent} ${selector}`));
3922
+ const unwrapLayers = (container)=>{
3923
+ container.each((node)=>{
3924
+ if ('atrule' !== node.type) return;
3925
+ if ('layer' === node.name.toLowerCase()) if (node.nodes) {
3926
+ unwrapLayers(node);
3927
+ node.replaceWith(node.nodes);
3928
+ } else node.remove();
3929
+ else if (node.nodes) unwrapLayers(node);
3930
+ });
3931
+ };
3932
+ const takePropertyRegistrations = (root)=>{
3933
+ const initialValues = new Map();
3934
+ root.walkAtRules(/^property$/i, (atRule)=>{
3935
+ atRule.walkDecls('initial-value', (declaration)=>{
3936
+ initialValues.set(atRule.params.trim(), declaration.value);
3937
+ });
3938
+ atRule.remove();
3939
+ });
3940
+ root.walkAtRules(/^supports$/i, (atRule)=>{
3941
+ const rules = atRule.nodes?.filter((node)=>'rule' === node.type) ?? [];
3942
+ if (rules.length > 0 && rules.every((rule)=>rule.selector.includes('::backdrop'))) atRule.remove();
3943
+ });
3944
+ return initialValues;
3945
+ };
3946
+ const removeEmptyContainers = (container)=>{
3947
+ container.each((node)=>{
3948
+ if ('rule' !== node.type && 'atrule' !== node.type) return;
3949
+ if (!node.nodes) return;
3950
+ removeEmptyContainers(node);
3951
+ if (node.nodes.every((child)=>'comment' === child.type)) node.remove();
3952
+ });
3953
+ };
3954
+ const IMPLIED_KEYFRAME_VALUES = {
3955
+ transform: 'none',
3956
+ opacity: '1'
3957
+ };
3958
+ const completeKeyframes = (root)=>{
3959
+ root.walkAtRules(/^(?:-webkit-)?keyframes$/i, (atRule)=>{
3960
+ const offsets = new Set();
3961
+ const properties = new Set();
3962
+ atRule.walkRules((rule)=>{
3963
+ for (const selector of rule.selectors)offsets.add({
3964
+ from: '0%',
3965
+ to: '100%'
3966
+ }[selector.toLowerCase()] ?? selector);
3967
+ rule.walkDecls(({ prop })=>{
3968
+ if (prop in IMPLIED_KEYFRAME_VALUES) properties.add(prop);
3969
+ });
3970
+ });
3971
+ const first = atRule.first;
3972
+ if (0 === properties.size || first?.type !== 'rule') return;
3973
+ for (const [offset, selector] of [
3974
+ [
3975
+ '0%',
3976
+ 'from'
3977
+ ],
3978
+ [
3979
+ '100%',
3980
+ 'to'
3981
+ ]
3982
+ ]){
3983
+ if (offsets.has(offset)) continue;
3984
+ const keyframe = first.clone({
3985
+ selector
3986
+ });
3987
+ keyframe.removeAll();
3988
+ for (const prop of properties)keyframe.append({
3989
+ prop,
3990
+ value: IMPLIED_KEYFRAME_VALUES[prop]
3991
+ });
3992
+ if ('from' === selector) atRule.prepend(keyframe);
3993
+ else atRule.append(keyframe);
3994
+ }
3995
+ });
3996
+ };
3997
+ const resolveNestedVariables = (root, registrations)=>{
3998
+ const theme = themeVariables(root);
3999
+ root.walkDecls(/^--/, (declaration)=>{
4000
+ if (!declaration.value.includes('var(')) return;
4001
+ const parsed = postcss_value_parser(declaration.value);
4002
+ const lookup = (name)=>sameRuleValue(declaration, name) ?? theme.get(name) ?? registrations.get(name);
4003
+ if (resolveInFunctions(parsed.nodes, false, lookup, new Set())) declaration.value = foldCalc(parsed.toString());
4004
+ });
4005
+ };
4006
+ const themeVariables = (root)=>{
4007
+ const variables = new Map();
4008
+ root.walkRules((rule)=>{
4009
+ if (rule.selectors.includes(':root')) rule.walkDecls(/^--/, ({ prop, value })=>{
4010
+ variables.set(prop, value);
4011
+ });
4012
+ });
4013
+ return variables;
4014
+ };
4015
+ const sameRuleValue = (declaration, name)=>{
4016
+ let value;
4017
+ declaration.parent.each((node)=>{
4018
+ if ('decl' === node.type && node.prop === name && node !== declaration) value = node.value;
4019
+ });
4020
+ return value;
4021
+ };
4022
+ const resolveInFunctions = (nodes, insideFunction, lookup, seen)=>{
4023
+ let changed = false;
4024
+ for (const node of nodes){
4025
+ if ('function' !== node.type) continue;
4026
+ if ('var' !== node.value.toLowerCase()) {
4027
+ changed = resolveInFunctions(node.nodes, true, lookup, seen) || changed;
4028
+ continue;
4029
+ }
4030
+ const resolved = insideFunction ? resolveVariable(node, lookup, seen) : void 0;
4031
+ if (void 0 === resolved) {
4032
+ changed = resolveInFunctions(node.nodes, insideFunction, lookup, seen) || changed;
4033
+ continue;
4034
+ }
4035
+ Object.assign(node, {
4036
+ type: 'word',
4037
+ value: resolved
4038
+ });
4039
+ changed = true;
4040
+ }
4041
+ return changed;
4042
+ };
4043
+ const resolveVariable = (node, lookup, seen)=>{
4044
+ const name = node.nodes[0]?.value ?? '';
4045
+ if (seen.has(name)) return;
4046
+ const commaIndex = node.nodes.findIndex((child)=>'div' === child.type && ',' === child.value);
4047
+ const fallback = -1 === commaIndex ? void 0 : postcss_value_parser.stringify(node.nodes.slice(commaIndex + 1)).trim();
4048
+ const value = lookup(name) ?? fallback;
4049
+ if (void 0 === value) return;
4050
+ const parsed = postcss_value_parser(value);
4051
+ resolveInFunctions(parsed.nodes, true, lookup, new Set([
4052
+ ...seen,
4053
+ name
4054
+ ]));
4055
+ return parsed.toString();
4056
+ };
4057
+ const TAILWIND_POSTCSS = '@tailwindcss/postcss';
4058
+ const tailwindForLynx = ()=>({
4059
+ postcssPlugin: 'angular-lynx-tailwind',
4060
+ OnceExit (root, { result, rule }) {
4061
+ if (!compiledByTailwind(result)) return;
4062
+ lowerForLynx(root, (selector)=>rule({
4063
+ selector
4064
+ }));
4065
+ }
4066
+ });
4067
+ tailwindForLynx.postcss = true;
4068
+ const compiledByTailwind = (result)=>result.messages.some((message)=>message.plugin === TAILWIND_POSTCSS);
4069
+ const lowerForLynx = (root, createRule)=>{
4070
+ flattenNesting(root);
4071
+ unwrapLayers(root);
4072
+ const registrations = takePropertyRegistrations(root);
4073
+ const defaults = new Map(registrations);
4074
+ const channelVariables = colorChannelVariables(root);
4075
+ root.walkRules((rule)=>{
4076
+ const inKeyframes = rule.parent?.type === 'atrule' && /keyframes$/i.test(rule.parent.name);
4077
+ if (!inKeyframes && !lowerSelectors(rule)) return void rule.remove();
4078
+ if (lowerDeclarations(rule, channelVariables).composesTransform) {
4079
+ for (const [name, value] of TRANSFORM_DEFAULTS)if (!defaults.has(name)) defaults.set(name, value);
4080
+ }
4081
+ });
4082
+ unwrapLoweredColorMixSupports(root);
4083
+ resolveNestedVariables(root, registrations);
4084
+ lowerTransformVariables(root);
4085
+ completeKeyframes(root);
4086
+ removeEmptyContainers(root);
4087
+ if (defaults.size > 0) {
4088
+ const defaultsRule = createRule('*');
4089
+ for (const [prop, value] of defaults)defaultsRule.append({
4090
+ prop,
4091
+ value
4092
+ });
4093
+ const imports = root.nodes.filter((node)=>'atrule' === node.type && /^(charset|import)$/i.test(node.name));
4094
+ if (imports.length > 0) imports[imports.length - 1].after(defaultsRule);
4095
+ else root.prepend(defaultsRule);
4096
+ }
4097
+ };
4098
+ const colorChannelVariables = (root)=>{
4099
+ const names = new Set();
4100
+ root.walkDecls(/^--.+-rgb$/, ({ prop })=>{
4101
+ names.add(prop.slice(0, -4));
4102
+ });
4103
+ return names;
4104
+ };
4105
+ const unwrapLoweredColorMixSupports = (root)=>{
4106
+ root.walkAtRules(/^supports$/i, (atRule)=>{
4107
+ if (!atRule.params.includes('color-mix(') || !atRule.nodes) return;
4108
+ let mixes = false;
4109
+ atRule.walkDecls((declaration)=>{
4110
+ mixes ||= declaration.value.includes('color-mix(');
4111
+ });
4112
+ if (!mixes) atRule.replaceWith(atRule.nodes);
4113
+ });
4114
+ };
2290
4115
  const TAILWIND_CONFIG_FILES = [
2291
4116
  'tailwind.config.ts',
2292
4117
  'tailwind.config.js',
@@ -2294,17 +4119,28 @@ const TAILWIND_CONFIG_FILES = [
2294
4119
  'tailwind.config.cjs'
2295
4120
  ];
2296
4121
  const isTailwind = (plugin)=>'function' == typeof plugin ? 'tailwindcss' === plugin.name : plugin?.postcssPlugin === 'tailwindcss';
4122
+ const isTailwind4 = (plugin)=>plugin?.postcssPlugin === '@tailwindcss/postcss';
2297
4123
  const applyTailwind = (api)=>{
2298
4124
  const configFile = findUp(TAILWIND_CONFIG_FILES, process.cwd());
2299
- if (!configFile) return;
4125
+ let warned = false;
2300
4126
  api.modifyRsbuildConfig((config, { mergeRsbuildConfig })=>mergeRsbuildConfig(config, {
2301
4127
  tools: {
2302
4128
  postcss: ({ postcssOptions }, { addPlugins })=>{
2303
- if ('object' == typeof postcssOptions && postcssOptions.plugins?.some(isTailwind)) return;
2304
- const tailwindcss = createRequire(configFile)('tailwindcss');
2305
- addPlugins(tailwindcss({
2306
- config: configFile
2307
- }));
4129
+ const configured = 'object' == typeof postcssOptions ? postcssOptions.plugins ?? [] : [];
4130
+ if (configFile && !configured.some(isTailwind)) {
4131
+ const require = createRequire(configFile);
4132
+ const { version } = require('tailwindcss/package.json');
4133
+ if (Number.parseInt(version, 10) < 4) {
4134
+ const tailwindcss = require('tailwindcss');
4135
+ addPlugins(tailwindcss({
4136
+ config: configFile
4137
+ }));
4138
+ } else if (!configured.some(isTailwind4) && !warned) {
4139
+ warned = true;
4140
+ api.logger.warn(`Found ${configFile}, but Tailwind CSS ${version} is installed, which doesn't run from a Tailwind config file. List @tailwindcss/postcss in a .postcssrc.json, or run \`ng generate @blotch/angular-lynx:add-tailwind\`.`);
4141
+ }
4142
+ }
4143
+ addPlugins(tailwindForLynx());
2308
4144
  }
2309
4145
  }
2310
4146
  }));