@tbela99/css-parser 0.0.1-alpha3 → 0.0.1-alpha5

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.
@@ -55,7 +55,7 @@
55
55
  // -
56
56
  if (codepoint == 0x2d) {
57
57
  const nextCodepoint = name.charCodeAt(1);
58
- if (nextCodepoint == null) {
58
+ if (Number.isNaN(nextCodepoint)) {
59
59
  return false;
60
60
  }
61
61
  // -
@@ -104,6 +104,9 @@
104
104
  let codepoint = name.charCodeAt(0);
105
105
  let i = 0;
106
106
  const j = name.length;
107
+ if (j == 1 && !isDigit(codepoint)) {
108
+ return false;
109
+ }
107
110
  // '+' '-'
108
111
  if ([0x2b, 0x2d].includes(codepoint)) {
109
112
  i++;
@@ -247,7 +250,9 @@
247
250
  return codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
248
251
  }
249
252
  function isWhiteSpace(codepoint) {
250
- return codepoint == 0x9 || codepoint == 0x20 || isNewLine(codepoint);
253
+ return codepoint == 0x9 || codepoint == 0x20 ||
254
+ // isNewLine
255
+ codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
251
256
  }
252
257
 
253
258
  var properties = {
@@ -1452,7 +1457,6 @@
1452
1457
  return values;
1453
1458
  }
1454
1459
 
1455
- const indents = [];
1456
1460
  function render(data, opt = {}) {
1457
1461
  const options = Object.assign(opt.compress ? {
1458
1462
  indent: '',
@@ -1470,24 +1474,12 @@
1470
1474
  return acc;
1471
1475
  }
1472
1476
  }
1473
- if (options.compress && curr.typ == 'Whitespace') {
1474
- if (original[index + 1]?.typ == 'Start-parens' ||
1475
- (index > 0 && (original[index - 1].typ == 'Pseudo-class-func' ||
1476
- original[index - 1].typ == 'End-parens' ||
1477
- original[index - 1].typ == 'UrlFunc' ||
1478
- original[index - 1].typ == 'Func' ||
1479
- (original[index - 1].typ == 'Color' &&
1480
- original[index - 1].kin != 'hex' &&
1481
- original[index - 1].kin != 'lit')))) {
1482
- return acc;
1483
- }
1484
- }
1485
1477
  return acc + renderToken(curr, options);
1486
1478
  }
1487
- return { code: doRender(data, options, reducer) };
1479
+ return { code: doRender(data, options, reducer, 0) };
1488
1480
  }
1489
1481
  // @ts-ignore
1490
- function doRender(data, options, reducer, level = 0) {
1482
+ function doRender(data, options, reducer, level = 0, indents = []) {
1491
1483
  if (indents.length < level + 1) {
1492
1484
  indents.push(options.indent.repeat(level));
1493
1485
  }
@@ -1501,7 +1493,7 @@
1501
1493
  return options.removeComments ? '' : data.val;
1502
1494
  case 'StyleSheet':
1503
1495
  return data.chi.reduce((css, node) => {
1504
- const str = doRender(node, options, reducer, level);
1496
+ const str = doRender(node, options, reducer, level, indents);
1505
1497
  if (str === '') {
1506
1498
  return css;
1507
1499
  }
@@ -1528,7 +1520,7 @@
1528
1520
  str = `@${node.nam} ${node.val};`;
1529
1521
  }
1530
1522
  else {
1531
- str = doRender(node, options, reducer, level + 1);
1523
+ str = doRender(node, options, reducer, level + 1, indents);
1532
1524
  }
1533
1525
  if (css === '') {
1534
1526
  return str;
@@ -1536,8 +1528,7 @@
1536
1528
  if (str === '') {
1537
1529
  return css;
1538
1530
  }
1539
- if (str !== '')
1540
- return `${css}${options.newLine}${indentSub}${str}`;
1531
+ return `${css}${options.newLine}${indentSub}${str}`;
1541
1532
  }, '');
1542
1533
  if (children.endsWith(';')) {
1543
1534
  children = children.slice(0, -1);
@@ -1589,11 +1580,15 @@
1589
1580
  if (token.kin == 'hex' || token.kin == 'lit') {
1590
1581
  return token.val;
1591
1582
  }
1583
+ case 'Start-parens':
1584
+ if (!('chi' in token)) {
1585
+ return '(';
1586
+ }
1592
1587
  case 'Func':
1593
1588
  case 'UrlFunc':
1594
1589
  case 'Pseudo-class-func':
1595
1590
  // @ts-ignore
1596
- return (options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) : token.val) + '(' + token.chi.reduce((acc, curr) => {
1591
+ return ( /* options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
1597
1592
  if (options.removeComments && curr.typ == 'Comment') {
1598
1593
  if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
1599
1594
  return acc;
@@ -1609,8 +1604,6 @@
1609
1604
  return '<';
1610
1605
  case 'Gt':
1611
1606
  return '>';
1612
- case 'Start-parens':
1613
- return '(';
1614
1607
  case 'End-parens':
1615
1608
  return ')';
1616
1609
  case 'Attr-start':
@@ -1686,7 +1679,7 @@
1686
1679
  case 'String':
1687
1680
  case 'Iden':
1688
1681
  case 'Delim':
1689
- return options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : token.val;
1682
+ return /* options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
1690
1683
  }
1691
1684
  throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
1692
1685
  }
@@ -2247,6 +2240,54 @@
2247
2240
  }
2248
2241
 
2249
2242
  const configuration = getConfig();
2243
+ const combinators = ['+', '>', '~'];
2244
+ const notEndingWith = ['(', '['].concat(combinators);
2245
+ function wrapNodes(previous, node, match, ast, i, nodeIndex) {
2246
+ // @ts-ignore
2247
+ let pSel = match.selector1.reduce(reducer, []).join(',');
2248
+ // @ts-ignore
2249
+ let nSel = match.selector2.reduce(reducer, []).join(',');
2250
+ // @ts-ignore
2251
+ const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
2252
+ // @ts-ignore
2253
+ Object.defineProperty(wrapper, 'raw', {
2254
+ enumerable: false,
2255
+ writable: true,
2256
+ // @ts-ignore
2257
+ value: match.match.map(t => t.slice())
2258
+ });
2259
+ if (pSel == '&' || pSel === '') {
2260
+ // @ts-ignore
2261
+ wrapper.chi.push(...previous.chi);
2262
+ // @ts-ignore
2263
+ if ((nSel == '&' || nSel === '') && hasOnlyDeclarations(previous)) {
2264
+ // @ts-ignore
2265
+ wrapper.chi.push(...node.chi);
2266
+ }
2267
+ else {
2268
+ // @ts-ignore
2269
+ wrapper.chi.push(node);
2270
+ }
2271
+ }
2272
+ else {
2273
+ // @ts-ignore
2274
+ wrapper.chi.push(previous, node);
2275
+ }
2276
+ // @ts-ignore
2277
+ ast.chi.splice(i, 1, wrapper);
2278
+ // @ts-ignore
2279
+ ast.chi.splice(nodeIndex, 1);
2280
+ // @ts-ignore
2281
+ previous.sel = pSel;
2282
+ // @ts-ignore
2283
+ previous.raw = match.selector1;
2284
+ // @ts-ignore
2285
+ node.sel = nSel;
2286
+ // @ts-ignore
2287
+ node.raw = match.selector2;
2288
+ reduceRuleSelector(wrapper);
2289
+ return wrapper;
2290
+ }
2250
2291
  function deduplicate(ast, options = {}, recursive = false) {
2251
2292
  // @ts-ignore
2252
2293
  if (('chi' in ast) && ast.chi?.length > 0) {
@@ -2262,6 +2303,14 @@
2262
2303
  }
2263
2304
  // @ts-ignore
2264
2305
  node = ast.chi[i];
2306
+ // @ts-ignore
2307
+ if (previous == node) {
2308
+ // console.error('idem!');
2309
+ // @ts-ignore
2310
+ ast.chi.splice(i, 1);
2311
+ i--;
2312
+ continue;
2313
+ }
2265
2314
  if (node.typ == 'AtRule' && node.nam == 'font-face') {
2266
2315
  continue;
2267
2316
  }
@@ -2272,6 +2321,111 @@
2272
2321
  continue;
2273
2322
  }
2274
2323
  // @ts-ignore
2324
+ if (node.typ == 'Rule') {
2325
+ reduceRuleSelector(node);
2326
+ let wrapper;
2327
+ let match;
2328
+ // @ts-ignore
2329
+ if (options.nestingRules) {
2330
+ // @ts-ignore
2331
+ if (previous != null && previous.typ == 'Rule') {
2332
+ reduceRuleSelector(previous);
2333
+ // @ts-ignore
2334
+ match = matchSelectors(previous.raw, node.raw, ast.typ);
2335
+ // @ts-ignore
2336
+ if (match != null) {
2337
+ // @ts-ignore
2338
+ wrapper = wrapNodes(previous, node, match, ast, i, nodeIndex);
2339
+ nodeIndex = i - 1;
2340
+ // @ts-ignore
2341
+ previous = ast.chi[nodeIndex];
2342
+ }
2343
+ }
2344
+ // @ts-ignore
2345
+ if (wrapper != null) {
2346
+ // @ts-ignore
2347
+ while (i < ast.chi.length) {
2348
+ // @ts-ignore
2349
+ const nextNode = ast.chi[i];
2350
+ // @ts-ignore
2351
+ if (nextNode.typ != 'Rule') {
2352
+ // i--;
2353
+ // previous = wrapper;
2354
+ // nodeIndex = i;
2355
+ break;
2356
+ }
2357
+ reduceRuleSelector(nextNode);
2358
+ // @ts-ignore
2359
+ match = matchSelectors(wrapper.raw, nextNode.raw, ast.typ);
2360
+ // @ts-ignore
2361
+ if (match == null) {
2362
+ break;
2363
+ }
2364
+ // @ts-ignore
2365
+ wrapper = wrapNodes(wrapper, nextNode, match, ast, i, nodeIndex);
2366
+ }
2367
+ nodeIndex = --i;
2368
+ // @ts-ignore
2369
+ previous = ast.chi[nodeIndex];
2370
+ deduplicate(wrapper, options, recursive);
2371
+ continue;
2372
+ }
2373
+ // @ts-ignore
2374
+ else if (node.optimized != null &&
2375
+ // @ts-ignore
2376
+ node.optimized.match &&
2377
+ // @ts-ignore
2378
+ node.optimized.selector.length > 1) {
2379
+ // @ts-ignore
2380
+ wrapper = { ...node, chi: [], sel: node.optimized.optimized[0] };
2381
+ // @ts-ignore
2382
+ Object.defineProperty(wrapper, 'raw', {
2383
+ enumerable: false,
2384
+ writable: true,
2385
+ // @ts-ignore
2386
+ value: [[node.optimized.optimized[0]]]
2387
+ });
2388
+ // @ts-ignore
2389
+ node.sel = node.optimized.selector.reduce(reducer, []).join(',');
2390
+ // @ts-ignore
2391
+ node.raw = node.optimized.selector.slice();
2392
+ // @ts-ignore
2393
+ wrapper.chi.push(node);
2394
+ // @ts-ignore
2395
+ ast.chi.splice(i, 1, wrapper);
2396
+ node = wrapper;
2397
+ }
2398
+ }
2399
+ // @ts-ignore
2400
+ else if (node.optimized?.match) {
2401
+ let wrap = true;
2402
+ // @ts-ignore
2403
+ const selector = node.optimized.selector.reduce((acc, curr) => {
2404
+ if (curr[0] == '&') {
2405
+ if (curr[1] == ' ') {
2406
+ curr.splice(0, 2);
2407
+ }
2408
+ else {
2409
+ if (ast.typ != 'Rule' && combinators.includes(curr[1])) {
2410
+ wrap = false;
2411
+ }
2412
+ else {
2413
+ curr.splice(0, 1);
2414
+ }
2415
+ }
2416
+ }
2417
+ else if (combinators.includes(curr[0])) {
2418
+ curr.unshift('&');
2419
+ }
2420
+ // @ts-ignore
2421
+ acc.push(curr.map(t => t.replaceAll('&', node.optimized.optimized[0])).join(''));
2422
+ return acc;
2423
+ }, []);
2424
+ // @ts-ignore
2425
+ node.sel = (wrap ? node.optimized.optimized[0] : '') + `:is(${selector.join(',')})`;
2426
+ }
2427
+ }
2428
+ // @ts-ignore
2275
2429
  if (previous != null && 'chi' in previous && ('chi' in node)) {
2276
2430
  // @ts-ignore
2277
2431
  if (previous.typ == node.typ) {
@@ -2291,13 +2445,14 @@
2291
2445
  // @ts-ignore
2292
2446
  if ((node.typ == 'Rule' && node.sel == previous.sel) ||
2293
2447
  // @ts-ignore
2294
- (node.typ == 'AtRule') && node.val == previous.val) {
2448
+ (node.typ == 'AtRule') && node.val != 'font-face' && node.val == previous.val) {
2295
2449
  // @ts-ignore
2296
2450
  node.chi.unshift(...previous.chi);
2297
2451
  // @ts-ignore
2298
2452
  ast.chi.splice(nodeIndex, 1);
2299
2453
  // @ts-ignore
2300
2454
  if (hasDeclaration(node)) {
2455
+ // @ts-ignore
2301
2456
  deduplicateRule(node);
2302
2457
  }
2303
2458
  else {
@@ -2313,19 +2468,26 @@
2313
2468
  if (intersect != null) {
2314
2469
  if (intersect.node1.chi.length == 0) {
2315
2470
  // @ts-ignore
2316
- ast.chi.splice(i, 1);
2471
+ ast.chi.splice(i--, 1);
2472
+ // @ts-ignore
2473
+ node = ast.chi[i];
2317
2474
  }
2318
2475
  else {
2319
2476
  // @ts-ignore
2320
2477
  ast.chi.splice(i, 1, intersect.node1);
2478
+ node = intersect.node1;
2321
2479
  }
2322
2480
  if (intersect.node2.chi.length == 0) {
2323
2481
  // @ts-ignore
2324
2482
  ast.chi.splice(nodeIndex, 1, intersect.result);
2483
+ previous = intersect.result;
2325
2484
  }
2326
2485
  else {
2327
2486
  // @ts-ignore
2328
2487
  ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
2488
+ previous = intersect.result;
2489
+ // @ts-ignore
2490
+ i = nodeIndex;
2329
2491
  }
2330
2492
  }
2331
2493
  }
@@ -2335,6 +2497,7 @@
2335
2497
  if (recursive && previous != node) {
2336
2498
  // @ts-ignore
2337
2499
  if (hasDeclaration(previous)) {
2500
+ // @ts-ignore
2338
2501
  deduplicateRule(previous);
2339
2502
  }
2340
2503
  else {
@@ -2352,12 +2515,25 @@
2352
2515
  deduplicateRule(node);
2353
2516
  }
2354
2517
  else {
2355
- deduplicate(node, options, recursive);
2518
+ // @ts-ignore
2519
+ if (!(node.typ == 'AtRule' && node.nam != 'font-face')) {
2520
+ deduplicate(node, options, recursive);
2521
+ }
2356
2522
  }
2357
2523
  }
2358
2524
  }
2359
2525
  return ast;
2360
2526
  }
2527
+ function hasOnlyDeclarations(node) {
2528
+ let k = node.chi.length;
2529
+ while (k--) {
2530
+ if (node.chi[k].typ == 'Comment') {
2531
+ continue;
2532
+ }
2533
+ return node.chi[k].typ == 'Declaration';
2534
+ }
2535
+ return true;
2536
+ }
2361
2537
  function hasDeclaration(node) {
2362
2538
  // @ts-ignore
2363
2539
  for (let i = 0; i < node.chi?.length; i++) {
@@ -2370,7 +2546,7 @@
2370
2546
  }
2371
2547
  return true;
2372
2548
  }
2373
- function deduplicateRule(ast, options = {}) {
2549
+ function deduplicateRule(ast) {
2374
2550
  // @ts-ignore
2375
2551
  if (!('chi' in ast) || ast.chi?.length <= 1) {
2376
2552
  return ast;
@@ -2417,42 +2593,42 @@
2417
2593
  }
2418
2594
  // @ts-ignore
2419
2595
  ast.chi = children.concat(ast.chi?.slice(k));
2420
- /*
2421
- // @ts-ignore
2422
-
2423
- const properties: PropertyList = new PropertyList();
2424
-
2425
- for (; k < j; k++) {
2426
-
2427
- // @ts-ignore
2428
- if ('Comment' == ast.chi[k].typ || 'Declaration' == ast.chi[k].typ) {
2429
-
2430
- // @ts-ignore
2431
- properties.add(ast.chi[k]);
2432
- continue;
2433
- }
2434
-
2435
- break;
2436
- }
2437
-
2438
- // @ts-ignore
2439
- ast.chi = [...properties].concat(ast.chi.slice(k));
2440
- */
2441
- //
2442
- // @ts-ignore
2443
- // ast.chi.splice(0, k - 1, ...properties);
2444
2596
  return ast;
2445
2597
  }
2446
2598
  function splitRule(buffer) {
2447
- const result = [];
2599
+ const result = [[]];
2448
2600
  let str = '';
2449
2601
  for (let i = 0; i < buffer.length; i++) {
2450
2602
  let chr = buffer.charAt(i);
2603
+ if (isWhiteSpace(chr.charCodeAt(0))) {
2604
+ let k = i;
2605
+ while (k + 1 < buffer.length) {
2606
+ if (isWhiteSpace(buffer[k + 1].charCodeAt(0))) {
2607
+ k++;
2608
+ continue;
2609
+ }
2610
+ break;
2611
+ }
2612
+ if (str !== '') {
2613
+ // @ts-ignore
2614
+ result.at(-1).push(str);
2615
+ str = '';
2616
+ }
2617
+ // @ts-ignore
2618
+ if (result.at(-1).length > 0) {
2619
+ // @ts-ignore
2620
+ result.at(-1).push(' ');
2621
+ }
2622
+ i = k;
2623
+ continue;
2624
+ }
2451
2625
  if (chr == ',') {
2452
2626
  if (str !== '') {
2453
- result.push(str);
2627
+ // @ts-ignore
2628
+ result.at(-1).push(str);
2454
2629
  str = '';
2455
2630
  }
2631
+ result.push([]);
2456
2632
  continue;
2457
2633
  }
2458
2634
  str += chr;
@@ -2499,14 +2675,49 @@
2499
2675
  }
2500
2676
  }
2501
2677
  i = k;
2502
- continue;
2503
2678
  }
2504
2679
  }
2505
2680
  if (str !== '') {
2506
- result.push(str);
2681
+ // @ts-ignore
2682
+ result.at(-1).push(str);
2507
2683
  }
2508
2684
  return result;
2509
2685
  }
2686
+ function reduceRuleSelector(node) {
2687
+ if (node.raw == null) {
2688
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: splitRule(node.sel) });
2689
+ }
2690
+ // @ts-ignore
2691
+ // if (node.raw != null) {
2692
+ // @ts-ignore
2693
+ let optimized = reduceSelector(node.raw.reduce((acc, curr) => {
2694
+ acc.push(curr.slice());
2695
+ return acc;
2696
+ }, []));
2697
+ if (optimized != null) {
2698
+ Object.defineProperty(node, 'optimized', { enumerable: false, writable: true, value: optimized });
2699
+ }
2700
+ if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
2701
+ const raw = [
2702
+ [
2703
+ optimized.optimized[0], ':is('
2704
+ ].concat(optimized.selector.reduce((acc, curr) => {
2705
+ if (acc.length > 0) {
2706
+ acc.push(',');
2707
+ }
2708
+ acc.push(...curr);
2709
+ return acc;
2710
+ }, [])).concat(')')
2711
+ ];
2712
+ const sel = raw[0].join('');
2713
+ if (sel.length < node.sel.length) {
2714
+ node.sel = sel;
2715
+ // node.raw = raw;
2716
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
2717
+ }
2718
+ }
2719
+ // }
2720
+ }
2510
2721
  function diff(n1, n2, options = {}) {
2511
2722
  let node1 = n1;
2512
2723
  let node2 = n2;
@@ -2523,8 +2734,28 @@
2523
2734
  // @ts-ignore
2524
2735
  return null;
2525
2736
  }
2737
+ // @ts-ignore
2738
+ const raw1 = node1.raw;
2739
+ // @ts-ignore
2740
+ // const optimized1 = node1.optimized;
2741
+ // @ts-ignore
2742
+ const raw2 = node2.raw;
2743
+ // @ts-ignore
2744
+ // const optimized2 = node2.optimized;
2526
2745
  node1 = { ...node1, chi: node1.chi.slice() };
2527
2746
  node2 = { ...node2, chi: node2.chi.slice() };
2747
+ if (raw1 != null) {
2748
+ Object.defineProperty(node1, 'raw', { enumerable: false, writable: true, value: raw1 });
2749
+ }
2750
+ // if (optimized1 != null) {
2751
+ // Object.defineProperty(node1, 'optimized', {enumerable: false, writable: true, value: optimized1});
2752
+ // }
2753
+ if (raw2 != null) {
2754
+ Object.defineProperty(node2, 'raw', { enumerable: false, writable: true, value: raw2 });
2755
+ }
2756
+ // if (optimized2 != null) {
2757
+ // Object.defineProperty(node2, 'optimized', {enumerable: false, writable: true, value: optimized2});
2758
+ // }
2528
2759
  const intersect = [];
2529
2760
  while (i--) {
2530
2761
  if (node1.chi[i].typ == 'Comment') {
@@ -2552,7 +2783,7 @@
2552
2783
  const result = (intersect.length == 0 ? null : {
2553
2784
  ...node1,
2554
2785
  // @ts-ignore
2555
- sel: [...new Set([...(n1.raw || splitRule(n1.sel)).concat(n2.raw || splitRule(n2.sel))])].join(),
2786
+ sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(','),
2556
2787
  chi: intersect.reverse()
2557
2788
  });
2558
2789
  if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + render(curr, options).code.length, 0)) {
@@ -2561,6 +2792,262 @@
2561
2792
  }
2562
2793
  return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 };
2563
2794
  }
2795
+ function matchSelectors(selector1, selector2, parentType) {
2796
+ let match = [[]];
2797
+ const j = Math.min(selector1.reduce((acc, curr) => Math.min(acc, curr.length), selector1.length > 0 ? selector1[0].length : 0), selector2.reduce((acc, curr) => Math.min(acc, curr.length), selector2.length > 0 ? selector2[0].length : 0));
2798
+ let i = 0;
2799
+ let k;
2800
+ let l;
2801
+ let token;
2802
+ let matching = true;
2803
+ let matchFunction = 0;
2804
+ let inAttr = 0;
2805
+ for (; i < j; i++) {
2806
+ k = 0;
2807
+ token = selector1[0][i];
2808
+ for (; k < selector1.length; k++) {
2809
+ if (selector1[k][i] != token) {
2810
+ matching = false;
2811
+ break;
2812
+ }
2813
+ }
2814
+ if (matching) {
2815
+ l = 0;
2816
+ for (; l < selector2.length; l++) {
2817
+ if (selector2[l][i] != token) {
2818
+ matching = false;
2819
+ break;
2820
+ }
2821
+ }
2822
+ }
2823
+ if (!matching) {
2824
+ break;
2825
+ }
2826
+ if (token == ',') {
2827
+ match.push([]);
2828
+ }
2829
+ else {
2830
+ if (token.endsWith('(')) {
2831
+ matchFunction++;
2832
+ }
2833
+ if (token.endsWith('[')) {
2834
+ inAttr++;
2835
+ }
2836
+ else if (token == ')') {
2837
+ matchFunction--;
2838
+ }
2839
+ else if (token == ']') {
2840
+ inAttr--;
2841
+ }
2842
+ match.at(-1).push(token);
2843
+ }
2844
+ }
2845
+ // invalid function
2846
+ if (matchFunction != 0 || inAttr != 0) {
2847
+ return null;
2848
+ }
2849
+ if (parentType != 'Rule') {
2850
+ for (const part of match) {
2851
+ if (part.length > 0 && combinators.includes(part[0].charAt(0))) {
2852
+ return null;
2853
+ }
2854
+ }
2855
+ }
2856
+ if (match.length > 1) {
2857
+ console.error(`unsupported multilevel matching`);
2858
+ console.error({ match, selector1, selector2 });
2859
+ return null;
2860
+ }
2861
+ for (const part of match) {
2862
+ while (part.length > 0) {
2863
+ const token = part.at(-1);
2864
+ if (token == ' ' || combinators.includes(token) || notEndingWith.includes(token.at(-1))) {
2865
+ part.pop();
2866
+ continue;
2867
+ }
2868
+ break;
2869
+ }
2870
+ }
2871
+ if (match.every(t => t.length == 0)) {
2872
+ return null;
2873
+ }
2874
+ if (eq([['&']], match)) {
2875
+ return null;
2876
+ }
2877
+ function reduce(acc, curr) {
2878
+ if (acc === null) {
2879
+ return null;
2880
+ }
2881
+ let hasCompoundSelector = true;
2882
+ curr = curr.slice(match[0].length);
2883
+ while (curr.length > 0) {
2884
+ if (curr[0] == ' ') {
2885
+ hasCompoundSelector = false;
2886
+ curr.unshift('&');
2887
+ continue;
2888
+ }
2889
+ break;
2890
+ }
2891
+ // invalid function match
2892
+ if (curr.length > 0 && curr[0].endsWith('(') && curr.at(-1) != ')') {
2893
+ return null;
2894
+ }
2895
+ if (curr.length == 1 && combinators.includes(curr[0].charAt(0))) {
2896
+ return null;
2897
+ }
2898
+ if (hasCompoundSelector && curr.length > 0) {
2899
+ hasCompoundSelector = !['&'].concat(combinators).includes(curr[0].charAt(0));
2900
+ }
2901
+ if (curr[0] == ':is(') {
2902
+ let inFunction = 0;
2903
+ let canReduce = true;
2904
+ const isCompound = curr.reduce((acc, token, index) => {
2905
+ if (index == 0) {
2906
+ inFunction++;
2907
+ canReduce = curr[1] == '&';
2908
+ }
2909
+ else if (token.endsWith('(')) {
2910
+ if (inFunction == 0) {
2911
+ canReduce = false;
2912
+ }
2913
+ inFunction++;
2914
+ }
2915
+ else if (token == ')') {
2916
+ inFunction--;
2917
+ }
2918
+ else if (token == ',') {
2919
+ if (!canReduce) {
2920
+ canReduce = curr[index + 1] == '&';
2921
+ }
2922
+ acc.push([]);
2923
+ }
2924
+ else
2925
+ acc.at(-1)?.push(token);
2926
+ return acc;
2927
+ }, [[]]);
2928
+ if (inFunction > 0) {
2929
+ canReduce = false;
2930
+ }
2931
+ if (canReduce) {
2932
+ curr = isCompound.reduce((acc, curr) => {
2933
+ if (acc.length > 0) {
2934
+ acc.push(',');
2935
+ }
2936
+ acc.push(...curr);
2937
+ return acc;
2938
+ }, []);
2939
+ }
2940
+ }
2941
+ // @todo: check hasCompoundSelector && curr[0] == '&' && curr[1] == ' '
2942
+ acc.push(match.length == 0 ? ['&'] : (hasCompoundSelector && curr[0] != '&' && (curr.length == 0 || !combinators.includes(curr[0].charAt(0))) ? ['&'].concat(curr) : curr));
2943
+ return acc;
2944
+ }
2945
+ // @ts-ignore
2946
+ selector1 = selector1.reduce(reduce, []);
2947
+ // @ts-ignore
2948
+ selector2 = selector2.reduce(reduce, []);
2949
+ return selector1 == null || selector2 == null ? null : {
2950
+ eq: eq(selector1, selector2),
2951
+ match,
2952
+ selector1,
2953
+ selector2
2954
+ };
2955
+ }
2956
+ function reduceSelector(selector) {
2957
+ if (selector.length == 0) {
2958
+ return null;
2959
+ }
2960
+ const optimized = [];
2961
+ const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
2962
+ let i = 0;
2963
+ let j;
2964
+ let match;
2965
+ for (; i < k; i++) {
2966
+ const item = selector[0][i];
2967
+ match = true;
2968
+ for (j = 1; j < selector.length; j++) {
2969
+ if (item != selector[j][i]) {
2970
+ match = false;
2971
+ break;
2972
+ }
2973
+ }
2974
+ if (!match) {
2975
+ break;
2976
+ }
2977
+ optimized.push(item);
2978
+ }
2979
+ while (optimized.length > 0) {
2980
+ const last = optimized.at(-1);
2981
+ if ((last == ' ' || combinators.includes(last))) {
2982
+ optimized.pop();
2983
+ continue;
2984
+ }
2985
+ break;
2986
+ }
2987
+ selector.forEach((selector) => selector.splice(0, optimized.length));
2988
+ // combinator
2989
+ if (combinators.includes(optimized.at(-1))) {
2990
+ const combinator = optimized.pop();
2991
+ selector.forEach(selector => selector.unshift(combinator));
2992
+ }
2993
+ let reducible = optimized.length == 1;
2994
+ if (optimized[0] == '&' && optimized[1] == ' ') {
2995
+ optimized.splice(0, 2);
2996
+ }
2997
+ if (optimized.length == 0 ||
2998
+ (optimized[0].charAt(0) == '&' ||
2999
+ selector.length == 1)) {
3000
+ return {
3001
+ match: false,
3002
+ optimized,
3003
+ selector: selector.map(selector => selector[0] == '&' && selector[1] == ' ' ? selector.slice(2) : selector),
3004
+ reducible: selector.length > 1 && selector.every((selector) => !combinators.includes(selector[0]))
3005
+ };
3006
+ }
3007
+ return {
3008
+ match: true,
3009
+ optimized,
3010
+ selector: selector.reduce((acc, curr) => {
3011
+ let hasCompound = true;
3012
+ if (hasCompound && curr.length > 0) {
3013
+ hasCompound = !['&'].concat(combinators).includes(curr[0].charAt(0));
3014
+ }
3015
+ // @ts-ignore
3016
+ if (hasCompound && curr[0] == ' ') {
3017
+ hasCompound = false;
3018
+ curr.unshift('&');
3019
+ }
3020
+ if (curr.length == 0) {
3021
+ curr.push('&');
3022
+ hasCompound = false;
3023
+ }
3024
+ if (reducible) {
3025
+ const chr = curr[0].charAt(0);
3026
+ // @ts-ignore
3027
+ reducible = chr == '.' || chr == ':' || isIdentStart(chr.codePointAt(0));
3028
+ }
3029
+ acc.push(hasCompound ? ['&'].concat(curr) : curr);
3030
+ return acc;
3031
+ }, []),
3032
+ reducible: selector.every((selector) => !['>', '+', '~', '&'].includes(selector[0]))
3033
+ };
3034
+ }
3035
+ function reducer(acc, curr, index, array) {
3036
+ // trim :is()
3037
+ if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
3038
+ curr = curr.slice(1, -1);
3039
+ }
3040
+ if (curr[0] == '&') {
3041
+ if (curr[1] == ' ') {
3042
+ curr.splice(0, 2);
3043
+ }
3044
+ else if (combinators.includes(curr[1])) {
3045
+ curr.splice(0, 1);
3046
+ }
3047
+ }
3048
+ acc.push(curr.join(''));
3049
+ return acc;
3050
+ }
2564
3051
 
2565
3052
  const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
2566
3053
  const funcLike = ['Start-parens', 'Func', 'UrlFunc', 'Pseudo-class-func'];
@@ -2570,6 +3057,7 @@
2570
3057
  src: '',
2571
3058
  sourcemap: false,
2572
3059
  compress: false,
3060
+ nestingRules: false,
2573
3061
  resolveImport: false,
2574
3062
  resolveUrls: false,
2575
3063
  removeEmpty: true,
@@ -2840,11 +3328,16 @@
2840
3328
  try {
2841
3329
  // @ts-ignore
2842
3330
  const root = await options.load(url, options.src).then((src) => {
2843
- bytesIn += src.length;
2844
- // @ts-ignore
2845
- return parse$1(src, Object.assign({}, options, { src: options.resolve(url, options.src).absolute }));
3331
+ return parse$1(src, Object.assign({}, options, {
3332
+ compress: false,
3333
+ // @ts-ignore
3334
+ src: options.resolve(url, options.src).absolute
3335
+ }));
2846
3336
  });
2847
- context.chi.push(...root.ast.chi);
3337
+ bytesIn += root.bytesIn;
3338
+ if (root.ast.chi.length > 0) {
3339
+ context.chi.push(...root.ast.chi);
3340
+ }
2848
3341
  if (root.errors.length > 0) {
2849
3342
  errors.push(...root.errors);
2850
3343
  }
@@ -2859,20 +3352,16 @@
2859
3352
  // https://www.w3.org/TR/css-nesting-1/#conditionals
2860
3353
  // allowed nesting at-rules
2861
3354
  // there must be a top level rule in the stack
3355
+ const raw = tokens.reduce((acc, curr) => {
3356
+ acc.push(renderToken(curr, { removeComments: true }));
3357
+ return acc;
3358
+ }, []);
2862
3359
  const node = {
2863
3360
  typ: 'AtRule',
2864
3361
  nam: renderToken(atRule, { removeComments: true }),
2865
- val: tokens.reduce((acc, curr, index, array) => {
2866
- if (curr.typ == 'Whitespace') {
2867
- if (array[index + 1]?.typ == 'Start-parens' ||
2868
- array[index - 1]?.typ == 'End-parens' ||
2869
- array[index - 1]?.typ == 'Func') {
2870
- return acc;
2871
- }
2872
- }
2873
- return acc + renderToken(curr, { removeComments: true });
2874
- }, '')
3362
+ val: raw.join('')
2875
3363
  };
3364
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: false, value: raw });
2876
3365
  if (delim.typ == 'Block-start') {
2877
3366
  node.chi = [];
2878
3367
  }
@@ -2897,23 +3386,33 @@
2897
3386
  return null;
2898
3387
  }
2899
3388
  }
2900
- const sel = parseTokens(tokens, { compress: options.compress }).map(curr => renderToken(curr, { compress: true }));
2901
- const raw = [...new Set(sel.reduce((acc, curr) => {
2902
- if (curr == ',') {
2903
- acc.push('');
2904
- }
2905
- else {
2906
- acc[acc.length - 1] += curr;
3389
+ const uniq = new Map;
3390
+ parseTokens(tokens, 'Rule', { compress: options.compress }).reduce((acc, curr, index, array) => {
3391
+ if (curr.typ == 'Whitespace') {
3392
+ if (array[index - 1]?.val == '+' || array[index + 1]?.val == '+') {
3393
+ return acc;
2907
3394
  }
2908
- return acc;
2909
- }, ['']))];
3395
+ }
3396
+ let t = renderToken(curr, { compress: true });
3397
+ if (t == ',') {
3398
+ acc.push([]);
3399
+ }
3400
+ else {
3401
+ acc[acc.length - 1].push(t);
3402
+ }
3403
+ return acc;
3404
+ }, [[]]).reduce((acc, curr) => {
3405
+ acc.set(curr.join(''), curr);
3406
+ return acc;
3407
+ }, uniq);
2910
3408
  const node = {
2911
3409
  typ: 'Rule',
2912
3410
  // @ts-ignore
2913
- sel: raw.join(','),
3411
+ sel: [...uniq.keys()].join(','),
2914
3412
  chi: []
2915
3413
  };
2916
- Object.defineProperty(node, 'raw', { enumerable: false, get: () => raw });
3414
+ let raw = [...uniq.values()];
3415
+ Object.defineProperty(node, 'raw', { enumerable: false, writable: true, value: raw });
2917
3416
  loc = {
2918
3417
  sta: position,
2919
3418
  src
@@ -2937,7 +3436,13 @@
2937
3436
  }
2938
3437
  if (tokens[i].typ == 'Colon') {
2939
3438
  name = tokens.slice(0, i);
2940
- value = parseTokens(tokens.slice(i + 1), { parseColor: true, src: options.src, resolveUrls: options.resolveUrls, resolve: options.resolve, cwd: options.cwd });
3439
+ value = parseTokens(tokens.slice(i + 1), 'Declaration', {
3440
+ parseColor: true,
3441
+ src: options.src,
3442
+ resolveUrls: options.resolveUrls,
3443
+ resolve: options.resolve,
3444
+ cwd: options.cwd
3445
+ });
2941
3446
  }
2942
3447
  }
2943
3448
  if (name == null) {
@@ -2956,11 +3461,6 @@
2956
3461
  }
2957
3462
  }
2958
3463
  }
2959
- // if (name.length == 0) {
2960
- //
2961
- // errors.push({action: 'drop', message: 'invalid declaration', location: {src, ...position}});
2962
- // return null;
2963
- // }
2964
3464
  if (value == null) {
2965
3465
  errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
2966
3466
  return null;
@@ -2983,16 +3483,6 @@
2983
3483
  errors.push({ action: 'drop', message: 'invalid declaration', location: { src, ...position } });
2984
3484
  return null;
2985
3485
  }
2986
- // // location not needed for declaration
2987
- // loc = <Location>{
2988
- // sta: position,
2989
- // src
2990
- // };
2991
- //
2992
- // if (options.sourcemap) {
2993
- //
2994
- // node.loc = loc
2995
- // }
2996
3486
  // @ts-ignore
2997
3487
  context.chi.push(node);
2998
3488
  return null;
@@ -3035,7 +3525,6 @@
3035
3525
  position.ind = ind;
3036
3526
  position.lin = lin;
3037
3527
  position.col = col == 0 ? 1 : col;
3038
- // }
3039
3528
  }
3040
3529
  function consumeWhiteSpace() {
3041
3530
  let count = 0;
@@ -3217,11 +3706,6 @@
3217
3706
  }
3218
3707
  }
3219
3708
  }
3220
- // else {
3221
- //
3222
- // pushToken(getType(buffer));
3223
- // buffer = '';
3224
- // }
3225
3709
  break;
3226
3710
  case '<':
3227
3711
  if (buffer.length > 0) {
@@ -3272,6 +3756,9 @@
3272
3756
  break;
3273
3757
  case '~':
3274
3758
  case '|':
3759
+ if (tokens.at(-1)?.typ == 'Whitespace') {
3760
+ tokens.pop();
3761
+ }
3275
3762
  if (buffer.length > 0) {
3276
3763
  pushToken(getType(buffer));
3277
3764
  buffer = '';
@@ -3293,15 +3780,32 @@
3293
3780
  break;
3294
3781
  }
3295
3782
  pushToken(getType(buffer));
3783
+ while (isWhiteSpace(value.charCodeAt(0))) {
3784
+ value = next();
3785
+ }
3296
3786
  buffer = value;
3297
3787
  break;
3298
3788
  case '>':
3789
+ if (buffer !== '') {
3790
+ pushToken(getType(buffer));
3791
+ buffer = '';
3792
+ }
3299
3793
  if (tokens[tokens.length - 1]?.typ == 'Whitespace') {
3300
3794
  tokens.pop();
3301
3795
  }
3302
3796
  pushToken({ typ: 'Gt' });
3303
3797
  consumeWhiteSpace();
3304
3798
  break;
3799
+ case '.':
3800
+ const codepoint = peek().charCodeAt(0);
3801
+ if (!isDigit(codepoint) && buffer !== '') {
3802
+ pushToken(getType(buffer));
3803
+ buffer = value;
3804
+ break;
3805
+ }
3806
+ buffer += value;
3807
+ break;
3808
+ case '+':
3305
3809
  case ':':
3306
3810
  case ',':
3307
3811
  case '=':
@@ -3313,12 +3817,11 @@
3313
3817
  buffer += value + next();
3314
3818
  break;
3315
3819
  }
3316
- // if (value == ',' && tokens[tokens.length - 1]?.typ == 'Whitespace') {
3317
- //
3318
- // tokens.pop();
3319
- // }
3320
3820
  pushToken(getType(value));
3321
3821
  buffer = '';
3822
+ if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
3823
+ pushToken(getType(next()));
3824
+ }
3322
3825
  while (isWhiteSpace(peek().charCodeAt(0))) {
3323
3826
  next();
3324
3827
  }
@@ -3339,7 +3842,7 @@
3339
3842
  pushToken(getType(buffer));
3340
3843
  buffer = '';
3341
3844
  const token = tokens[tokens.length - 1];
3342
- if (token.typ == 'UrlFunc' /* && token.chi == 'url' */) {
3845
+ if (token.typ == 'UrlFunc') {
3343
3846
  // consume either string or url token
3344
3847
  let whitespace = '';
3345
3848
  value = peek();
@@ -3456,15 +3959,6 @@
3456
3959
  if (options.removeEmpty && previousNode != null && previousNode.chi.length == 0 && context.chi[context.chi.length - 1] == previousNode) {
3457
3960
  context.chi.pop();
3458
3961
  }
3459
- else if (previousNode != null && previousNode != ast && options.compress) {
3460
- // @ts-ignore
3461
- if (hasDeclaration(previousNode)) {
3462
- deduplicateRule(previousNode);
3463
- }
3464
- else {
3465
- deduplicate(previousNode, options);
3466
- }
3467
- }
3468
3962
  tokens.length = 0;
3469
3963
  map.clear();
3470
3964
  buffer = '';
@@ -3499,28 +3993,22 @@
3499
3993
  await parseNode(tokens);
3500
3994
  }
3501
3995
  if (options.compress) {
3502
- while (stack.length > 0) {
3503
- const node = stack.pop();
3504
- if (hasDeclaration(node)) {
3505
- deduplicateRule(node, options);
3506
- }
3507
- else {
3508
- deduplicate(node, options);
3509
- }
3510
- }
3511
3996
  if (ast.chi.length > 0) {
3512
- deduplicate(ast, options);
3997
+ deduplicate(ast, options, true);
3513
3998
  }
3514
3999
  }
3515
4000
  return { ast, errors, bytesIn };
3516
4001
  }
3517
- function parseTokens(tokens, options = {}) {
4002
+ function parseTokens(tokens, nodeType, options = {}) {
3518
4003
  for (let i = 0; i < tokens.length; i++) {
3519
4004
  const t = tokens[i];
3520
4005
  if (t.typ == 'Whitespace' && ((i == 0 ||
3521
4006
  i + 1 == tokens.length ||
3522
- ['Comma', 'Start-parens'].includes(tokens[i + 1].typ) ||
3523
- (i > 0 && funcLike.includes(tokens[i - 1].typ))))) {
4007
+ ['Comma'].includes(tokens[i + 1].typ) ||
4008
+ (i > 0 &&
4009
+ tokens[i + 1]?.typ != 'Literal' &&
4010
+ funcLike.includes(tokens[i - 1].typ) &&
4011
+ !['var', 'calc'].includes(tokens[i - 1].val))))) {
3524
4012
  tokens.splice(i--, 1);
3525
4013
  continue;
3526
4014
  }
@@ -3565,7 +4053,7 @@
3565
4053
  if (t.chi.length > 1) {
3566
4054
  /*(<AttrToken>t).chi =*/
3567
4055
  // @ts-ignore
3568
- parseTokens(t.chi, options);
4056
+ parseTokens(t.chi, t.typ, options);
3569
4057
  }
3570
4058
  // @ts-ignore
3571
4059
  t.chi.forEach(val => {
@@ -3618,9 +4106,9 @@
3618
4106
  // @ts-ignore
3619
4107
  t.chi.pop();
3620
4108
  }
4109
+ let isColor = true;
3621
4110
  // @ts-ignore
3622
4111
  if (options.parseColor && ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk'].includes(t.val)) {
3623
- let isColor = true;
3624
4112
  // @ts-ignore
3625
4113
  for (const v of t.chi) {
3626
4114
  if (v.typ == 'Func' && v.val == 'var') {
@@ -3628,37 +4116,38 @@
3628
4116
  break;
3629
4117
  }
3630
4118
  }
3631
- if (!isColor) {
3632
- continue;
3633
- }
3634
- // @ts-ignore
3635
- t.typ = 'Color';
3636
- // @ts-ignore
3637
- t.kin = t.val;
3638
- // @ts-ignore
3639
- let m = t.chi.length;
3640
- while (m-- > 0) {
4119
+ if (isColor) {
4120
+ // @ts-ignore
4121
+ t.typ = 'Color';
3641
4122
  // @ts-ignore
3642
- if (t.chi[m].typ == 'Literal') {
4123
+ t.kin = t.val;
4124
+ // @ts-ignore
4125
+ let m = t.chi.length;
4126
+ while (m-- > 0) {
3643
4127
  // @ts-ignore
3644
- if (t.chi[m + 1]?.typ == 'Whitespace') {
4128
+ if (t.chi[m].typ == 'Literal') {
3645
4129
  // @ts-ignore
3646
- t.chi.splice(m + 1, 1);
3647
- }
3648
- // @ts-ignore
3649
- if (t.chi[m - 1]?.typ == 'Whitespace') {
4130
+ if (t.chi[m + 1]?.typ == 'Whitespace') {
4131
+ // @ts-ignore
4132
+ t.chi.splice(m + 1, 1);
4133
+ }
3650
4134
  // @ts-ignore
3651
- t.chi.splice(m - 1, 1);
3652
- m--;
4135
+ if (t.chi[m - 1]?.typ == 'Whitespace') {
4136
+ // @ts-ignore
4137
+ t.chi.splice(m - 1, 1);
4138
+ m--;
4139
+ }
3653
4140
  }
3654
4141
  }
4142
+ continue;
3655
4143
  }
3656
4144
  }
3657
- else if (t.typ == 'UrlFunc') {
4145
+ if (t.typ == 'UrlFunc') {
3658
4146
  // @ts-ignore
3659
4147
  if (t.chi[0]?.typ == 'String') {
3660
4148
  // @ts-ignore
3661
4149
  const value = t.chi[0].val.slice(1, -1);
4150
+ // @ts-ignore
3662
4151
  if (t.chi[0].val.slice(1, 5) != 'data:' && urlTokenMatcher.test(value)) {
3663
4152
  // @ts-ignore
3664
4153
  t.chi[0].typ = 'Url-token';
@@ -3676,7 +4165,7 @@
3676
4165
  // @ts-ignore
3677
4166
  if (t.chi.length > 0) {
3678
4167
  // @ts-ignore
3679
- parseTokens(t.chi, options);
4168
+ parseTokens(t.chi, t.typ, options);
3680
4169
  if (t.typ == 'Pseudo-class-func' && t.val == ':is' && options.compress) {
3681
4170
  //
3682
4171
  const count = t.chi.filter(t => t.typ != 'Comment').length;
@@ -3742,7 +4231,7 @@
3742
4231
  yield { node, parent, root };
3743
4232
  if ('chi' in node) {
3744
4233
  for (const child of node.chi) {
3745
- yield* doWalk(child, node, (root == null ? node : root));
4234
+ yield* doWalk(child, node, (root ?? node));
3746
4235
  }
3747
4236
  }
3748
4237
  }
@@ -3882,20 +4371,18 @@
3882
4371
  }
3883
4372
 
3884
4373
  function parse(iterator, opt = {}) {
3885
- Object.assign(opt, {
4374
+ return parse$1(iterator, Object.assign(opt, {
3886
4375
  load,
3887
4376
  resolve,
3888
4377
  cwd: opt.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
3889
- });
3890
- return parse$1(iterator, opt);
4378
+ }));
3891
4379
  }
3892
4380
  function transform(css, options = {}) {
3893
- Object.assign(options, {
4381
+ return transform$1(css, Object.assign(options, {
3894
4382
  load,
3895
4383
  resolve,
3896
4384
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
3897
- });
3898
- return transform$1(css, options);
4385
+ }));
3899
4386
  }
3900
4387
 
3901
4388
  exports.deduplicate = deduplicate;
@@ -3905,6 +4392,7 @@
3905
4392
  exports.load = load;
3906
4393
  exports.matchUrl = matchUrl;
3907
4394
  exports.parse = parse;
4395
+ exports.reduceSelector = reduceSelector;
3908
4396
  exports.render = render;
3909
4397
  exports.renderToken = renderToken;
3910
4398
  exports.resolve = resolve;