@tbela99/css-parser 1.3.4 → 1.4.1

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.
@@ -433,6 +433,23 @@
433
433
  * invalid declaration node type
434
434
  */
435
435
  EnumToken[EnumToken["InvalidDeclarationNodeType"] = 94] = "InvalidDeclarationNodeType";
436
+ /* css module nodes */
437
+ /**
438
+ * composes token node type
439
+ */
440
+ EnumToken[EnumToken["ComposesSelectorNodeType"] = 95] = "ComposesSelectorNodeType";
441
+ /**
442
+ * css variable token type
443
+ */
444
+ EnumToken[EnumToken["CssVariableTokenType"] = 96] = "CssVariableTokenType";
445
+ /**
446
+ * css variable import token type
447
+ */
448
+ EnumToken[EnumToken["CssVariableImportTokenType"] = 97] = "CssVariableImportTokenType";
449
+ /**
450
+ * css variable declaration map token type
451
+ */
452
+ EnumToken[EnumToken["CssVariableDeclarationMapTokenType"] = 98] = "CssVariableDeclarationMapTokenType";
436
453
  /* aliases */
437
454
  /**
438
455
  * alias for time token type
@@ -549,7 +566,7 @@
549
566
  exports.ColorType = void 0;
550
567
  (function (ColorType) {
551
568
  /**
552
- * system colors
569
+ * deprecated system colors
553
570
  */
554
571
  ColorType[ColorType["SYS"] = 0] = "SYS";
555
572
  /**
@@ -557,7 +574,7 @@
557
574
  */
558
575
  ColorType[ColorType["DPSYS"] = 1] = "DPSYS";
559
576
  /**
560
- * colors as literals
577
+ * named colors
561
578
  */
562
579
  ColorType[ColorType["LIT"] = 2] = "LIT";
563
580
  /**
@@ -657,6 +674,48 @@
657
674
  */
658
675
  ColorType[ColorType["DEVICE_CMYK"] = 7] = "DEVICE_CMYK";
659
676
  })(exports.ColorType || (exports.ColorType = {}));
677
+ exports.ModuleCaseTransformEnum = void 0;
678
+ (function (ModuleCaseTransformEnum) {
679
+ /**
680
+ * export class names as-is
681
+ */
682
+ ModuleCaseTransformEnum[ModuleCaseTransformEnum["IgnoreCase"] = 1] = "IgnoreCase";
683
+ /**
684
+ * transform mapping key name to camel case
685
+ */
686
+ ModuleCaseTransformEnum[ModuleCaseTransformEnum["CamelCase"] = 2] = "CamelCase";
687
+ /**
688
+ * transform class names and mapping key name to camel case
689
+ */
690
+ ModuleCaseTransformEnum[ModuleCaseTransformEnum["CamelCaseOnly"] = 4] = "CamelCaseOnly";
691
+ /**
692
+ * transform mapping key name to dash case
693
+ */
694
+ ModuleCaseTransformEnum[ModuleCaseTransformEnum["DashCase"] = 8] = "DashCase";
695
+ /**
696
+ * transform class names and mapping key name to dash case
697
+ */
698
+ ModuleCaseTransformEnum[ModuleCaseTransformEnum["DashCaseOnly"] = 16] = "DashCaseOnly";
699
+ })(exports.ModuleCaseTransformEnum || (exports.ModuleCaseTransformEnum = {}));
700
+ exports.ModuleScopeEnumOptions = void 0;
701
+ (function (ModuleScopeEnumOptions) {
702
+ /**
703
+ * use the global scope
704
+ */
705
+ ModuleScopeEnumOptions[ModuleScopeEnumOptions["Global"] = 32] = "Global";
706
+ /**
707
+ * use the local scope
708
+ */
709
+ ModuleScopeEnumOptions[ModuleScopeEnumOptions["Local"] = 64] = "Local";
710
+ /**
711
+ * do not allow selector without an id or class
712
+ */
713
+ ModuleScopeEnumOptions[ModuleScopeEnumOptions["Pure"] = 128] = "Pure";
714
+ /**
715
+ * export using ICSS module format
716
+ */
717
+ ModuleScopeEnumOptions[ModuleScopeEnumOptions["ICSS"] = 256] = "ICSS";
718
+ })(exports.ModuleScopeEnumOptions || (exports.ModuleScopeEnumOptions = {}));
660
719
 
661
720
  // from https://www.w3.org/TR/css-color-4/multiply-matrices.js
662
721
  /**
@@ -3915,10 +3974,7 @@
3915
3974
  // normalize hue
3916
3975
  for (const k of walkValues([object.h])) {
3917
3976
  if (k.value.typ == exports.EnumToken.AngleTokenType && k.value.unit == 'deg') {
3918
- // @ts-ignore
3919
3977
  k.value.typ = exports.EnumToken.NumberTokenType;
3920
- // @ts-ignore
3921
- delete k.value.unit;
3922
3978
  }
3923
3979
  }
3924
3980
  }
@@ -4121,7 +4177,7 @@
4121
4177
  function identity() {
4122
4178
  return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
4123
4179
  }
4124
- function normalize(point) {
4180
+ function normalize$1(point) {
4125
4181
  const [x, y, z] = point;
4126
4182
  const norm = Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
4127
4183
  return norm === 0 ? [0, 0, 0] : [x / norm, y / norm, z / norm];
@@ -4248,7 +4304,7 @@
4248
4304
  ];
4249
4305
  // Compute scale
4250
4306
  const scaleX = Math.hypot(...row0);
4251
- const row0Norm = normalize(row0);
4307
+ const row0Norm = normalize$1(row0);
4252
4308
  const skewXY = dot(row0Norm, row1);
4253
4309
  const row1Proj = [
4254
4310
  row1[0] - skewXY * row0Norm[0],
@@ -4256,7 +4312,7 @@
4256
4312
  row1[2] - skewXY * row0Norm[2]
4257
4313
  ];
4258
4314
  const scaleY = Math.hypot(...row1Proj);
4259
- const row1Norm = normalize(row1Proj);
4315
+ const row1Norm = normalize$1(row1Proj);
4260
4316
  const skewXZ = dot(row0Norm, row2);
4261
4317
  const skewYZ = dot(row1Norm, row2);
4262
4318
  const row2Proj = [
@@ -4264,7 +4320,7 @@
4264
4320
  row2[1] - skewXZ * row0Norm[1] - skewYZ * row1Norm[1],
4265
4321
  row2[2] - skewXZ * row0Norm[2] - skewYZ * row1Norm[2]
4266
4322
  ];
4267
- const row2Norm = normalize(row2Proj);
4323
+ const row2Norm = normalize$1(row2Proj);
4268
4324
  const determinant = row0[0] * cross[0] + row0[1] * cross[1] + row0[2] * cross[2];
4269
4325
  const scaleZ = Math.hypot(...row2Proj) * (determinant < 0 ? -1 : 1);
4270
4326
  // Build rotation matrix from orthonormalized vectors
@@ -6530,6 +6586,9 @@
6530
6586
  },
6531
6587
  animation: {
6532
6588
  shorthand: "animation",
6589
+ separator: {
6590
+ typ: "Comma"
6591
+ },
6533
6592
  pattern: "animation-name animation-duration animation-timing-function animation-delay animation-iteration-count animation-direction animation-fill-mode animation-play-state animation-timeline",
6534
6593
  "default": [
6535
6594
  "1",
@@ -7480,6 +7539,60 @@
7480
7539
  });
7481
7540
  return null;
7482
7541
  }
7542
+ if ('composes' == node.nam.toLowerCase()) {
7543
+ let left = [];
7544
+ let right = [];
7545
+ let current = 0;
7546
+ let hasFrom = 0;
7547
+ for (; current < node.val.length; current++) {
7548
+ if (exports.EnumToken.WhitespaceTokenType == node.val[current].typ || exports.EnumToken.CommentTokenType == node.val[current].typ) {
7549
+ if (!hasFrom) {
7550
+ left.push(node.val[current]);
7551
+ }
7552
+ else {
7553
+ right.push(node.val[current]);
7554
+ }
7555
+ continue;
7556
+ }
7557
+ if (exports.EnumToken.IdenTokenType == node.val[current].typ || exports.EnumToken.DashedIdenTokenType == node.val[current].typ || exports.EnumToken.StringTokenType == node.val[current].typ) {
7558
+ if (exports.EnumToken.IdenTokenType == node.val[current].typ) {
7559
+ if ('from' == node.val[current].val) {
7560
+ if (hasFrom) {
7561
+ return null;
7562
+ }
7563
+ hasFrom++;
7564
+ continue;
7565
+ }
7566
+ }
7567
+ if (hasFrom) {
7568
+ right.push(node.val[current]);
7569
+ }
7570
+ else {
7571
+ left.push(node.val[current]);
7572
+ }
7573
+ continue;
7574
+ }
7575
+ break;
7576
+ }
7577
+ if (hasFrom <= 1 && current > 0) {
7578
+ if (hasFrom == 0) {
7579
+ node.val.splice(0, left.length, {
7580
+ typ: exports.EnumToken.ComposesSelectorNodeType,
7581
+ l: left,
7582
+ r: null
7583
+ });
7584
+ }
7585
+ else {
7586
+ node.val.splice(0, current, {
7587
+ typ: exports.EnumToken.ComposesSelectorNodeType,
7588
+ l: left,
7589
+ r: right.reduce((a, b) => {
7590
+ return a == null ? b : b.typ == exports.EnumToken.WhitespaceTokenType || b.typ == exports.EnumToken.CommentTokenType ? a : b;
7591
+ }, null)
7592
+ });
7593
+ }
7594
+ }
7595
+ }
7483
7596
  for (const { value: val, parent } of walkValues(node.val, node)) {
7484
7597
  if (val.typ == exports.EnumToken.AttrTokenType && val.chi.every((t) => [exports.EnumToken.IdenTokenType, exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ))) {
7485
7598
  // @ts-ignore
@@ -7526,6 +7639,13 @@
7526
7639
  return buffer.length > 0 ? result + buffer : result;
7527
7640
  }
7528
7641
 
7642
+ function dasherize(value) {
7643
+ return value.replace(/([A-Z])/g, (all, one) => `-${one.toLowerCase()}`);
7644
+ }
7645
+ function camelize(value) {
7646
+ return value.replace(/-([a-z])/g, (all, one) => one.toUpperCase());
7647
+ }
7648
+
7529
7649
  // from https://github.com/Rich-Harris/vlq/tree/master
7530
7650
  // credit: Rich Harris
7531
7651
  const integer_to_char = {};
@@ -7672,9 +7792,10 @@
7672
7792
  * render ast
7673
7793
  * @param data
7674
7794
  * @param options
7795
+ * @param mapping
7675
7796
  * @private
7676
7797
  */
7677
- function doRender(data, options = {}) {
7798
+ function doRender(data, options = {}, mapping) {
7678
7799
  const minify = options.minify ?? true;
7679
7800
  const beautify = options.beautify ?? !minify;
7680
7801
  options = {
@@ -7711,12 +7832,23 @@
7711
7832
  const errors = [];
7712
7833
  const sourcemap = options.sourcemap ? new SourceMap : null;
7713
7834
  const cache = Object.create(null);
7835
+ const position = {
7836
+ ind: 0,
7837
+ lin: 1,
7838
+ col: 1
7839
+ };
7840
+ let code = '';
7841
+ if (mapping != null) {
7842
+ if (mapping.importMapping != null) {
7843
+ for (const [key, value] of Object.entries(mapping.importMapping)) {
7844
+ code += `:import("${key}")${options.indent}{${options.newLine}${Object.entries(value).reduce((acc, [k, v]) => acc + (acc.length > 0 ? options.newLine : '') + `${options.indent}${v}:${options.indent}${k};`, '')}${options.newLine}}${options.newLine}`;
7845
+ }
7846
+ }
7847
+ code += `:export${options.indent}{${options.newLine}${Object.entries(mapping.mapping).reduce((acc, [k, v]) => acc + (acc.length > 0 ? options.newLine : '') + `${options.indent}${k}:${options.indent}${v};`, '')}${options.newLine}}${options.newLine}`;
7848
+ update(position, code);
7849
+ }
7714
7850
  const result = {
7715
- code: renderAstNode(options.expandNestingRules && [exports.EnumToken.StyleSheetNodeType, exports.EnumToken.AtRuleNodeType, exports.EnumToken.RuleNodeType].includes(data.typ) && 'chi' in data ? expand(data) : data, options, sourcemap, {
7716
- ind: 0,
7717
- lin: 1,
7718
- col: 1
7719
- }, errors, function reducer(acc, curr) {
7851
+ code: code + renderAstNode(options.expandNestingRules && [exports.EnumToken.StyleSheetNodeType, exports.EnumToken.AtRuleNodeType, exports.EnumToken.RuleNodeType].includes(data.typ) && 'chi' in data ? expand(data) : data, options, sourcemap, position, errors, function reducer(acc, curr) {
7720
7852
  if (curr.typ == exports.EnumToken.CommentTokenType && options.removeComments) {
7721
7853
  if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
7722
7854
  return acc;
@@ -7875,6 +8007,11 @@
7875
8007
  return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
7876
8008
  }
7877
8009
  return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
8010
+ case exports.EnumToken.CssVariableTokenType:
8011
+ case exports.EnumToken.CssVariableImportTokenType:
8012
+ return `@value ${data.nam}:${options.indent}${filterValues((options.minify ? data.val : data.val)).reduce(reducer, '').trim()};`;
8013
+ case exports.EnumToken.CssVariableDeclarationMapTokenType:
8014
+ return `@value ${filterValues(data.vars).reduce((acc, curr) => acc + renderToken(curr), '').trim()} from ${filterValues(data.from).reduce((acc, curr) => acc + renderToken(curr), '').trim()};`;
7878
8015
  case exports.EnumToken.InvalidDeclarationNodeType:
7879
8016
  case exports.EnumToken.InvalidRuleTokenType:
7880
8017
  case exports.EnumToken.InvalidAtRuleTokenType:
@@ -8029,6 +8166,8 @@
8029
8166
  case exports.EnumToken.NameSpaceAttributeTokenType:
8030
8167
  return (token.l == null ? '' : renderToken(token.l, options, cache, reducer, errors)) + '|' +
8031
8168
  renderToken(token.r, options, cache, reducer, errors);
8169
+ case exports.EnumToken.ComposesSelectorNodeType:
8170
+ return token.l.reduce((acc, curr) => acc + renderToken(curr, options, cache), '') + (token.r == null ? '' : ' from ' + renderToken(token.r, options, cache, reducer, errors));
8032
8171
  case exports.EnumToken.BlockStartTokenType:
8033
8172
  return '{';
8034
8173
  case exports.EnumToken.BlockEndTokenType:
@@ -8399,23 +8538,27 @@
8399
8538
  }
8400
8539
  }
8401
8540
  function match$1(parseInfo, input) {
8402
- return parseInfo.stream.slice(parseInfo.currentPosition.ind + 1, parseInfo.currentPosition.ind + input.length + 1) == input;
8541
+ const position = parseInfo.currentPosition.ind - parseInfo.offset;
8542
+ return parseInfo.stream.slice(position + 1, position + input.length + 1) == input;
8403
8543
  }
8404
8544
  function peek(parseInfo, count = 1) {
8405
8545
  if (count == 1) {
8406
- return parseInfo.stream.charAt(parseInfo.currentPosition.ind + 1);
8546
+ return parseInfo.stream.charAt(parseInfo.currentPosition.ind - parseInfo.offset + 1);
8407
8547
  }
8408
- return parseInfo.stream.slice(parseInfo.currentPosition.ind + 1, parseInfo.currentPosition.ind + count + 1);
8548
+ const position = parseInfo.currentPosition.ind - parseInfo.offset;
8549
+ return parseInfo.stream.slice(position + 1, position + count + 1);
8409
8550
  }
8410
8551
  function prev(parseInfo) {
8411
- return parseInfo.stream.charAt(parseInfo.currentPosition.ind - 1);
8552
+ return parseInfo.offset == parseInfo.currentPosition.ind ? parseInfo.buffer.slice(-1) : parseInfo.stream.charAt(parseInfo.currentPosition.ind - parseInfo.offset - 1);
8412
8553
  }
8413
8554
  function next(parseInfo, count = 1) {
8414
8555
  let char = '';
8415
8556
  let chr = '';
8416
- while (count-- && (chr = parseInfo.stream.charAt(parseInfo.currentPosition.ind + 1))) {
8557
+ let position = parseInfo.currentPosition.ind - parseInfo.offset;
8558
+ while (count-- && (chr = parseInfo.stream.charAt(position + 1))) {
8417
8559
  char += chr;
8418
- const codepoint = parseInfo.stream.charCodeAt(++parseInfo.currentPosition.ind);
8560
+ const codepoint = parseInfo.stream.charCodeAt(++position);
8561
+ ++parseInfo.currentPosition.ind;
8419
8562
  if (isNewLine(codepoint)) {
8420
8563
  parseInfo.currentPosition.lin++;
8421
8564
  parseInfo.currentPosition.col = 0;
@@ -8831,6 +8974,7 @@
8831
8974
  const parseInfo = {
8832
8975
  stream: '',
8833
8976
  buffer: '',
8977
+ offset: 0,
8834
8978
  position: { ind: 0, lin: 1, col: 1 },
8835
8979
  currentPosition: { ind: -1, lin: 1, col: 0 }
8836
8980
  };
@@ -8838,7 +8982,17 @@
8838
8982
  const reader = input.getReader();
8839
8983
  while (true) {
8840
8984
  const { done, value } = await reader.read();
8841
- parseInfo.stream += ArrayBuffer.isView(value) ? decoder.decode(value, { stream: true }) : value;
8985
+ const stream = ArrayBuffer.isView(value) ? decoder.decode(value, { stream: true }) : value;
8986
+ if (!done) {
8987
+ if (parseInfo.stream.length > 2) {
8988
+ parseInfo.stream = parseInfo.stream.slice(-2) + stream;
8989
+ parseInfo.offset = parseInfo.currentPosition.ind - 1;
8990
+ }
8991
+ else {
8992
+ parseInfo.stream = stream;
8993
+ parseInfo.offset = Math.max(0, parseInfo.currentPosition.ind);
8994
+ }
8995
+ }
8842
8996
  yield* tokenize$1(parseInfo, done);
8843
8997
  if (done) {
8844
8998
  break;
@@ -9601,7 +9755,7 @@
9601
9755
  syntax: "[ <counter-name> <integer>? ]+ | none"
9602
9756
  },
9603
9757
  cursor: {
9604
- syntax: "[ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing ] ] [ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing | hand | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out | -moz-grab | -moz-grabbing | -moz-zoom-in | -moz-zoom-out ] ]"
9758
+ syntax: "[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ] [ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing | hand | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out | -moz-grab | -moz-grabbing | -moz-zoom-in | -moz-zoom-out ] ]"
9605
9759
  },
9606
9760
  cx: {
9607
9761
  syntax: "<length> | <percentage>"
@@ -10829,6 +10983,12 @@
10829
10983
  },
10830
10984
  "white-space-trim": {
10831
10985
  syntax: "none | discard-before || discard-after || discard-inner"
10986
+ },
10987
+ composes: {
10988
+ syntax: "<composes-selector>#"
10989
+ },
10990
+ "composes-selector": {
10991
+ syntax: "<ident>+ [from [global&&<string>]]?"
10832
10992
  }
10833
10993
  };
10834
10994
  var functions = {
@@ -10854,7 +11014,7 @@
10854
11014
  syntax: "atan2( <calc-sum>, <calc-sum> )"
10855
11015
  },
10856
11016
  attr: {
10857
- syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
11017
+ syntax: "attr( <attr-name> <attr-type>? , <declaration-value>? )"
10858
11018
  },
10859
11019
  blur: {
10860
11020
  syntax: "blur( <length>? )"
@@ -11207,7 +11367,7 @@
11207
11367
  syntax: "scroll | fixed | local"
11208
11368
  },
11209
11369
  "attr()": {
11210
- syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
11370
+ syntax: "attr( <attr-name> <attr-type>? , <declaration-value>? )"
11211
11371
  },
11212
11372
  "attr-matcher": {
11213
11373
  syntax: "[ '~' | '|' | '^' | '$' | '*' ]? '='"
@@ -11215,6 +11375,9 @@
11215
11375
  "attr-modifier": {
11216
11376
  syntax: "i | s"
11217
11377
  },
11378
+ "attr-type": {
11379
+ syntax: "type( <syntax> ) | raw-string | number | <attr-unit>"
11380
+ },
11218
11381
  "attribute-selector": {
11219
11382
  syntax: "'[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'"
11220
11383
  },
@@ -11428,6 +11591,9 @@
11428
11591
  "cubic-bezier-easing-function": {
11429
11592
  syntax: "ease | ease-in | ease-out | ease-in-out | cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )"
11430
11593
  },
11594
+ "cursor-predefined": {
11595
+ syntax: "auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing"
11596
+ },
11431
11597
  "custom-color-space": {
11432
11598
  syntax: "<dashed-ident>"
11433
11599
  },
@@ -14349,8 +14515,7 @@
14349
14515
  node: root,
14350
14516
  // @ts-ignore
14351
14517
  syntax: null,
14352
- error: 'expected selector',
14353
- tokens
14518
+ error: 'expected selector'
14354
14519
  };
14355
14520
  }
14356
14521
  tokens = tokens.slice();
@@ -14598,15 +14763,12 @@
14598
14763
  return result;
14599
14764
  }
14600
14765
  }
14766
+ // @ts-ignore
14601
14767
  return {
14602
14768
  valid: SyntaxValidationResult.Valid,
14603
- matches: [],
14604
- // @ts-ignore
14605
14769
  node: root,
14606
- // @ts-ignore
14607
14770
  syntax: null,
14608
- error: '',
14609
- tokens
14771
+ error: ''
14610
14772
  };
14611
14773
  }
14612
14774
 
@@ -15250,6 +15412,7 @@
15250
15412
  'color',
15251
15413
  'integer',
15252
15414
  'bg-position',
15415
+ 'composes-selector',
15253
15416
  'length-percentage', 'flex', 'calc-sum', 'color',
15254
15417
  'color-base', 'system-color', 'deprecated-system-color',
15255
15418
  'pseudo-class-selector', 'pseudo-element-selector', 'feature-value-declaration'
@@ -15280,6 +15443,9 @@
15280
15443
  return { ...result, context };
15281
15444
  }
15282
15445
  switch (syntax.val) {
15446
+ case 'composes-selector':
15447
+ success = token.typ == exports.EnumToken.ComposesSelectorNodeType;
15448
+ break;
15283
15449
  case 'bg-position': {
15284
15450
  let val;
15285
15451
  let keyworkMatchCount = 0;
@@ -15447,7 +15613,7 @@
15447
15613
  }
15448
15614
  break;
15449
15615
  case 'integer':
15450
- success = (token.typ == exports.EnumToken.NumberTokenType && Number.isInteger(+token.val) && token.val > 0) || (token.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == exports.EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
15616
+ success = (token.typ == exports.EnumToken.NumberTokenType && /^[+-]?\d+$/.test(token.val.toString())) || (token.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == exports.EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
15451
15617
  if ('range' in syntax) {
15452
15618
  success = success && +token.val >= +syntax.range[0] && +token.val <= +syntax.range[1];
15453
15619
  }
@@ -17610,6 +17776,91 @@
17610
17776
  };
17611
17777
  }
17612
17778
 
17779
+ // Alphabet: a-z, A-Z, 0-9, _, -
17780
+ const LOWER = "abcdefghijklmnopqrstuvwxyz";
17781
+ const DIGITS = "0123456789";
17782
+ const FULL_ALPHABET = (LOWER + DIGITS).split(""); // 64 chars
17783
+ const FIRST_ALPHABET = (LOWER).split(""); // 54 chars (no digits)
17784
+ /**
17785
+ * supported hash algorithms
17786
+ */
17787
+ const hashAlgorithms = ['hex', 'base64', 'base64url', 'sha1', 'sha256', 'sha384', 'sha512'];
17788
+ // simple deterministic hash → number
17789
+ function hashCode(str) {
17790
+ let hash = 0;
17791
+ let l = str.length;
17792
+ let i = 0;
17793
+ while (i < l) {
17794
+ hash = (hash * 31 + str.charCodeAt(i++)) >>> 0;
17795
+ }
17796
+ return hash;
17797
+ }
17798
+ /**
17799
+ * generate a hash id
17800
+ * @param input
17801
+ * @param length
17802
+ */
17803
+ function hashId(input, length = 6) {
17804
+ let n = hashCode(input);
17805
+ const chars = [];
17806
+ // First character: must not be a digit
17807
+ chars.push(FIRST_ALPHABET[n % FIRST_ALPHABET.length]);
17808
+ // Remaining characters
17809
+ for (let i = 1; i < length; i++) {
17810
+ n = (n + chars.length + i) % FULL_ALPHABET.length;
17811
+ chars.push(FULL_ALPHABET[n]);
17812
+ }
17813
+ return chars.join("");
17814
+ }
17815
+ /**
17816
+ * convert input to hex
17817
+ * @param input
17818
+ */
17819
+ function toHex(input) {
17820
+ let result = '';
17821
+ if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {
17822
+ for (const byte of Array.from(new Uint8Array(input))) {
17823
+ result += byte.toString(16).padStart(2, '0');
17824
+ }
17825
+ }
17826
+ else {
17827
+ for (const char of String(input)) {
17828
+ result += char.charCodeAt(0).toString(16).padStart(2, '0');
17829
+ }
17830
+ }
17831
+ return result;
17832
+ }
17833
+ /**
17834
+ * generate a hash
17835
+ * @param input
17836
+ * @param length
17837
+ * @param algo
17838
+ */
17839
+ async function hash(input, length = 6, algo) {
17840
+ let result;
17841
+ if (algo != null) {
17842
+ switch (algo) {
17843
+ case 'hex':
17844
+ return toHex(input).slice(0, length);
17845
+ case 'base64':
17846
+ case 'base64url':
17847
+ result = btoa(input);
17848
+ if (algo == 'base64url') {
17849
+ result = result.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
17850
+ }
17851
+ return result.slice(0, length);
17852
+ case 'sha1':
17853
+ case 'sha256':
17854
+ case 'sha384':
17855
+ case 'sha512':
17856
+ return toHex(await crypto.subtle.digest(algo.replace('sha', 'SHA-'), new TextEncoder().encode(input))).slice(0, length);
17857
+ default:
17858
+ throw new Error(`Unsupported hash algorithm: ${algo}`);
17859
+ }
17860
+ }
17861
+ return hashId(input, length);
17862
+ }
17863
+
17613
17864
  const urlTokenMatcher = /^(["']?)[a-zA-Z0-9_/.-][a-zA-Z0-9_/:.#?-]+(\1)$/;
17614
17865
  const trimWhiteSpace = [exports.EnumToken.CommentTokenType, exports.EnumToken.GtTokenType, exports.EnumToken.GteTokenType, exports.EnumToken.LtTokenType, exports.EnumToken.LteTokenType, exports.EnumToken.ColumnCombinatorTokenType];
17615
17866
  const BadTokensTypes = [
@@ -17628,9 +17879,12 @@
17628
17879
  function reject(reason) {
17629
17880
  throw new Error(reason ?? 'Parsing aborted');
17630
17881
  }
17631
- function normalizeVisitorKeyName(keyName) {
17632
- return keyName.replace(/-([a-z])/g, (all, one) => one.toUpperCase());
17633
- }
17882
+ /**
17883
+ * replace token in its parent node
17884
+ * @param parent
17885
+ * @param value
17886
+ * @param replacement
17887
+ */
17634
17888
  function replaceToken(parent, value, replacement) {
17635
17889
  for (const node of (Array.isArray(replacement) ? replacement : [replacement])) {
17636
17890
  if ('parent' in value && value.parent != node.parent) {
@@ -17658,11 +17912,129 @@
17658
17912
  target.splice(index, 1, ...(Array.isArray(replacement) ? replacement : [replacement]));
17659
17913
  }
17660
17914
  }
17915
+ /**
17916
+ * transform case of key name
17917
+ * @param key
17918
+ * @param how
17919
+ *
17920
+ * @throws Error
17921
+ * @private
17922
+ */
17923
+ function getKeyName(key, how) {
17924
+ switch (how) {
17925
+ case exports.ModuleCaseTransformEnum.CamelCase:
17926
+ case exports.ModuleCaseTransformEnum.CamelCaseOnly:
17927
+ return camelize(key);
17928
+ case exports.ModuleCaseTransformEnum.DashCase:
17929
+ case exports.ModuleCaseTransformEnum.DashCaseOnly:
17930
+ return dasherize(key);
17931
+ }
17932
+ return key;
17933
+ }
17934
+ /**
17935
+ * generate scoped name
17936
+ * @param localName
17937
+ * @param filePath
17938
+ * @param pattern
17939
+ * @param hashLength
17940
+ *
17941
+ * @throws Error
17942
+ * @private
17943
+ */
17944
+ async function generateScopedName(localName, filePath, pattern, hashLength = 5) {
17945
+ if (localName.startsWith('--')) {
17946
+ localName = localName.slice(2);
17947
+ }
17948
+ const matches = /.*?(([^/]+)\/)?([^/\\]*?)(\.([^?/]+))?([?].*)?$/.exec(filePath);
17949
+ const folder = matches?.[2]?.replace?.(/[^A-Za-z0-9_-]/g, "_") ?? '';
17950
+ const fileBase = matches?.[3] ?? '';
17951
+ const ext = matches?.[5] ?? '';
17952
+ const path = filePath.replace(/[^A-Za-z0-9_-]/g, "_");
17953
+ // sanitize localName for safe char set (replace spaces/illegal chars)
17954
+ const safeLocal = localName.replace(/[^A-Za-z0-9_-]/g, "_");
17955
+ const hashString = `${localName}::${filePath}`;
17956
+ let result = '';
17957
+ let inParens = 0;
17958
+ let key = '';
17959
+ let position = 0;
17960
+ // Compose final scoped name. Ensure the entire class doesn't start with digit:
17961
+ for (const char of pattern) {
17962
+ position += char.length;
17963
+ if (char == '[') {
17964
+ inParens++;
17965
+ if (inParens != 1) {
17966
+ throw new Error(`Unexpected character: '${char} at position ${position - 1}' in pattern '${pattern}'`);
17967
+ }
17968
+ continue;
17969
+ }
17970
+ if (char == ']') {
17971
+ inParens--;
17972
+ if (inParens != 0) {
17973
+ throw new Error(`Unexpected character: '${char}:${position - 1}'`);
17974
+ }
17975
+ let hashAlgo = null;
17976
+ let length = null;
17977
+ if (key.includes(':')) {
17978
+ const parts = key.split(':');
17979
+ if (parts.length == 2) {
17980
+ // @ts-ignore
17981
+ [key, length] = parts;
17982
+ // @ts-ignore
17983
+ if (key == 'hash' && hashAlgorithms.includes(length)) {
17984
+ // @ts-ignore
17985
+ hashAlgo = length;
17986
+ length = null;
17987
+ }
17988
+ }
17989
+ if (parts.length == 3) {
17990
+ // @ts-ignore
17991
+ [key, hashAlgo, length] = parts;
17992
+ }
17993
+ if (length != null && !Number.isInteger(+length)) {
17994
+ throw new Error(`Unsupported hash length: '${length}'. expecting format [hash:length] or [hash:hash-algo:length]`);
17995
+ }
17996
+ }
17997
+ switch (key) {
17998
+ case 'hash':
17999
+ result += await hash(hashString, length ?? hashLength, hashAlgo);
18000
+ break;
18001
+ case 'name':
18002
+ result += length != null ? fileBase.slice(0, +length) : fileBase;
18003
+ break;
18004
+ case 'local':
18005
+ result += length != null ? safeLocal.slice(0, +length) : localName;
18006
+ break;
18007
+ case 'ext':
18008
+ result += length != null ? ext.slice(0, +length) : ext;
18009
+ break;
18010
+ case 'path':
18011
+ result += length != null ? path.slice(0, +length) : path;
18012
+ break;
18013
+ case 'folder':
18014
+ result += length != null ? folder.slice(0, +length) : folder;
18015
+ break;
18016
+ default:
18017
+ throw new Error(`Unsupported key: '${key}'`);
18018
+ }
18019
+ key = '';
18020
+ continue;
18021
+ }
18022
+ if (inParens > 0) {
18023
+ key += char;
18024
+ }
18025
+ else {
18026
+ result += char;
18027
+ }
18028
+ }
18029
+ // if leading char is digit, prefix underscore (very rare)
18030
+ return (/^[0-9]/.test(result) ? '_' : '') + result;
18031
+ }
17661
18032
  /**
17662
18033
  * parse css string
17663
18034
  * @param iter
17664
18035
  * @param options
17665
18036
  *
18037
+ * @throws Error
17666
18038
  * @private
17667
18039
  */
17668
18040
  async function doParse(iter, options = {}) {
@@ -17694,6 +18066,9 @@
17694
18066
  if (typeof options.validation == 'boolean') {
17695
18067
  options.validation = options.validation ? exports.ValidationLevel.All : exports.ValidationLevel.None;
17696
18068
  }
18069
+ if (options.module) {
18070
+ options.expandNestingRules = true;
18071
+ }
17697
18072
  if (options.expandNestingRules) {
17698
18073
  options.nestingRules = false;
17699
18074
  }
@@ -17959,6 +18334,7 @@
17959
18334
  const root = await doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
17960
18335
  stream,
17961
18336
  buffer: '',
18337
+ offset: 0,
17962
18338
  position: { ind: 0, lin: 1, col: 1 },
17963
18339
  currentPosition: { ind: -1, lin: 1, col: 0 }
17964
18340
  }), Object.assign({}, options, {
@@ -18018,7 +18394,7 @@
18018
18394
  }
18019
18395
  let node = result.node;
18020
18396
  for (const handler of handlers) {
18021
- callable = typeof handler == 'function' ? handler : handler[normalizeVisitorKeyName(node.typ == exports.EnumToken.DeclarationNodeType || node.typ == exports.EnumToken.AtRuleNodeType ? node.nam : node.val)];
18397
+ callable = typeof handler == 'function' ? handler : handler[camelize(node.typ == exports.EnumToken.DeclarationNodeType || node.typ == exports.EnumToken.AtRuleNodeType ? node.nam : node.val)];
18022
18398
  if (callable == null) {
18023
18399
  continue;
18024
18400
  }
@@ -18153,12 +18529,9 @@
18153
18529
  }
18154
18530
  }
18155
18531
  }
18156
- const endTime = performance.now();
18157
- if (options.signal != null) {
18158
- options.signal.removeEventListener('abort', reject);
18159
- }
18160
18532
  stats.bytesIn += stats.importedBytesIn;
18161
- return {
18533
+ let endTime = performance.now();
18534
+ const result = {
18162
18535
  ast,
18163
18536
  errors,
18164
18537
  stats: {
@@ -18168,6 +18541,503 @@
18168
18541
  total: `${(endTime - startTime).toFixed(2)}ms`
18169
18542
  }
18170
18543
  };
18544
+ if (options.module) {
18545
+ const moduleSettings = {
18546
+ hashLength: 5,
18547
+ filePath: '',
18548
+ scoped: exports.ModuleScopeEnumOptions.Local,
18549
+ naming: exports.ModuleCaseTransformEnum.IgnoreCase,
18550
+ pattern: '',
18551
+ generateScopedName,
18552
+ ...(typeof options.module != 'object' ? {} : options.module)
18553
+ };
18554
+ const parseModuleTime = performance.now();
18555
+ const namesMapping = {};
18556
+ const global = new Set;
18557
+ const processed = new Set;
18558
+ const pattern = typeof options.module == 'boolean' ? null : moduleSettings.pattern;
18559
+ const importMapping = {};
18560
+ const cssVariablesMap = {};
18561
+ const importedCssVariables = {};
18562
+ let mapping = {};
18563
+ let revMapping = {};
18564
+ let filePath = typeof options.module == 'boolean' ? options.src : (moduleSettings.filePath ?? options.src);
18565
+ filePath = filePath === '' ? options.src : options.resolve(filePath, options.dirname(options.src), options.cwd).relative;
18566
+ if (typeof options.module == 'number') {
18567
+ if (options.module & exports.ModuleCaseTransformEnum.CamelCase) {
18568
+ moduleSettings.naming = exports.ModuleCaseTransformEnum.CamelCase;
18569
+ }
18570
+ else if (options.module & exports.ModuleCaseTransformEnum.CamelCaseOnly) {
18571
+ moduleSettings.naming = exports.ModuleCaseTransformEnum.CamelCaseOnly;
18572
+ }
18573
+ else if (options.module & exports.ModuleCaseTransformEnum.DashCase) {
18574
+ moduleSettings.naming = exports.ModuleCaseTransformEnum.DashCase;
18575
+ }
18576
+ else if (options.module & exports.ModuleCaseTransformEnum.DashCaseOnly) {
18577
+ moduleSettings.naming = exports.ModuleCaseTransformEnum.DashCaseOnly;
18578
+ }
18579
+ if (options.module & exports.ModuleScopeEnumOptions.Global) {
18580
+ moduleSettings.scoped = exports.ModuleScopeEnumOptions.Global;
18581
+ }
18582
+ if (options.module & exports.ModuleScopeEnumOptions.Pure) {
18583
+ // @ts-ignore
18584
+ moduleSettings.scoped |= exports.ModuleScopeEnumOptions.Pure;
18585
+ }
18586
+ if (options.module & exports.ModuleScopeEnumOptions.ICSS) {
18587
+ // @ts-ignore
18588
+ moduleSettings.scoped |= exports.ModuleScopeEnumOptions.ICSS;
18589
+ }
18590
+ }
18591
+ if (typeof moduleSettings.scoped == 'boolean') {
18592
+ moduleSettings.scoped = moduleSettings.scoped ? exports.ModuleScopeEnumOptions.Local : exports.ModuleScopeEnumOptions.Global;
18593
+ }
18594
+ moduleSettings.filePath = filePath;
18595
+ moduleSettings.pattern = pattern != null && pattern !== '' ? pattern : (filePath === '' ? `[local]_[hash]` : `[local]_[hash]_[name]`);
18596
+ for (const { node, parent } of walk(ast)) {
18597
+ if (node.typ == exports.EnumToken.CssVariableImportTokenType) {
18598
+ const url = node.val.find(t => t.typ == exports.EnumToken.StringTokenType).val.slice(1, -1);
18599
+ const src = options.resolve(url, options.dirname(options.src), options.cwd);
18600
+ const result = options.load(url, options.src);
18601
+ const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == 'AsyncFunction' ? await result : result;
18602
+ const root = await doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
18603
+ stream,
18604
+ buffer: '',
18605
+ offset: 0,
18606
+ position: { ind: 0, lin: 1, col: 1 },
18607
+ currentPosition: { ind: -1, lin: 1, col: 0 }
18608
+ }), Object.assign({}, options, {
18609
+ minify: false,
18610
+ setParent: false,
18611
+ src: src.relative
18612
+ }));
18613
+ cssVariablesMap[node.nam] = root.cssModuleVariables;
18614
+ parent.chi.splice(parent.chi.indexOf(node), 1);
18615
+ continue;
18616
+ }
18617
+ if (node.typ == exports.EnumToken.CssVariableDeclarationMapTokenType) {
18618
+ const from = node.from.find(t => t.typ == exports.EnumToken.IdenTokenType || isIdentColor(t));
18619
+ if (!(from.val in cssVariablesMap)) {
18620
+ errors.push({
18621
+ node,
18622
+ message: `could not resolve @value import from '${from.val}'`,
18623
+ action: 'drop'
18624
+ });
18625
+ }
18626
+ else {
18627
+ for (const token of node.vars) {
18628
+ if (token.typ == exports.EnumToken.IdenTokenType || isIdentColor(token)) {
18629
+ if (!(token.val in cssVariablesMap[from.val])) {
18630
+ errors.push({
18631
+ node,
18632
+ message: `value '${token.val}' is not exported from '${from.val}'`,
18633
+ action: 'drop'
18634
+ });
18635
+ continue;
18636
+ }
18637
+ result.cssModuleVariables ??= {};
18638
+ result.cssModuleVariables[token.val] = importedCssVariables[token.val] = cssVariablesMap[from.val][token.val];
18639
+ }
18640
+ }
18641
+ }
18642
+ parent.chi.splice(parent.chi.indexOf(node), 1);
18643
+ continue;
18644
+ }
18645
+ if (node.typ == exports.EnumToken.CssVariableTokenType) {
18646
+ if (parent?.typ == exports.EnumToken.StyleSheetNodeType) {
18647
+ if (result.cssModuleVariables == null) {
18648
+ result.cssModuleVariables = {};
18649
+ }
18650
+ result.cssModuleVariables[node.nam] = node;
18651
+ }
18652
+ parent.chi.splice(parent.chi.indexOf(node), 1);
18653
+ continue;
18654
+ }
18655
+ if (node.typ == exports.EnumToken.DeclarationNodeType) {
18656
+ if (node.nam.startsWith('--')) {
18657
+ if (!(node.nam in namesMapping)) {
18658
+ let result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? node.nam : moduleSettings.generateScopedName(node.nam, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18659
+ let value = result instanceof Promise ? await result : result;
18660
+ mapping[node.nam] = '--' + (moduleSettings.naming & exports.ModuleCaseTransformEnum.DashCaseOnly || moduleSettings.naming & exports.ModuleCaseTransformEnum.CamelCaseOnly ? getKeyName(value, moduleSettings.naming) : value);
18661
+ revMapping[node.nam] = node.nam;
18662
+ }
18663
+ node.nam = mapping[node.nam];
18664
+ }
18665
+ if ('composes' == node.nam.toLowerCase()) {
18666
+ const tokens = [];
18667
+ let isValid = true;
18668
+ for (const token of node.val) {
18669
+ if (token.typ == exports.EnumToken.ComposesSelectorNodeType) {
18670
+ if (!(token.r == null || token.r.typ == exports.EnumToken.StringTokenType || token.r.typ == exports.EnumToken.IdenTokenType)) {
18671
+ errors.push({
18672
+ action: 'drop',
18673
+ message: `composes '${exports.EnumToken[token.r.typ]}' is not supported`,
18674
+ node
18675
+ });
18676
+ isValid = false;
18677
+ break;
18678
+ }
18679
+ tokens.push(token);
18680
+ }
18681
+ }
18682
+ // find parent rule
18683
+ let parentRule = node.parent;
18684
+ while (parentRule != null && parentRule.typ != exports.EnumToken.RuleNodeType) {
18685
+ parentRule = parentRule.parent;
18686
+ }
18687
+ if (!isValid || tokens.length == 0) {
18688
+ if (tokens.length == 0) {
18689
+ errors.push({
18690
+ action: 'drop',
18691
+ message: `composes is empty`,
18692
+ node
18693
+ });
18694
+ }
18695
+ parentRule.chi.splice(parentRule.chi.indexOf(node), 1);
18696
+ continue;
18697
+ }
18698
+ for (const token of tokens) {
18699
+ // composes: a b c;
18700
+ if (token.r == null) {
18701
+ for (const rule of token.l) {
18702
+ if (rule.typ == exports.EnumToken.WhitespaceTokenType || rule.typ == exports.EnumToken.CommentTokenType) {
18703
+ continue;
18704
+ }
18705
+ if (!(rule.val in mapping)) {
18706
+ let result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? rule.val : moduleSettings.generateScopedName(rule.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18707
+ let value = result instanceof Promise ? await result : result;
18708
+ mapping[rule.val] = (rule.typ == exports.EnumToken.DashedIdenTokenType ? '--' : '') + (moduleSettings.naming & exports.ModuleCaseTransformEnum.DashCaseOnly || moduleSettings.naming & exports.ModuleCaseTransformEnum.CamelCaseOnly ? getKeyName(value, moduleSettings.naming) : value);
18709
+ revMapping[mapping[rule.val]] = rule.val;
18710
+ }
18711
+ if (parentRule != null) {
18712
+ for (const tk of parentRule.tokens) {
18713
+ if (tk.typ == exports.EnumToken.ClassSelectorTokenType) {
18714
+ const val = tk.val.slice(1);
18715
+ if (val in revMapping) {
18716
+ const key = revMapping[val];
18717
+ mapping[key] = [...new Set([...mapping[key].split(' '), mapping[rule.val]])].join(' ');
18718
+ }
18719
+ }
18720
+ }
18721
+ }
18722
+ }
18723
+ }
18724
+ // composes: a b c from 'file.css';
18725
+ else if (token.r.typ == exports.EnumToken.String) {
18726
+ const url = token.r.val.slice(1, -1);
18727
+ const src = options.resolve(url, options.dirname(options.src), options.cwd);
18728
+ const result = options.load(url, options.src);
18729
+ const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == 'AsyncFunction' ? await result : result;
18730
+ const root = await doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
18731
+ stream,
18732
+ buffer: '',
18733
+ offset: 0,
18734
+ position: { ind: 0, lin: 1, col: 1 },
18735
+ currentPosition: { ind: -1, lin: 1, col: 0 }
18736
+ }), Object.assign({}, options, {
18737
+ minify: false,
18738
+ setParent: false,
18739
+ src: src.relative
18740
+ }));
18741
+ const srcIndex = (src.relative.startsWith('/') || src.relative.startsWith('../') ? '' : './') + src.relative;
18742
+ if (Object.keys(root.mapping).length > 0) {
18743
+ importMapping[srcIndex] = {};
18744
+ }
18745
+ if (parentRule != null) {
18746
+ for (const tk of parentRule.tokens) {
18747
+ if (tk.typ == exports.EnumToken.ClassSelectorTokenType) {
18748
+ const val = tk.val.slice(1);
18749
+ if (val in revMapping) {
18750
+ const key = revMapping[val];
18751
+ const values = [];
18752
+ for (const iden of token.l) {
18753
+ if (iden.typ != exports.EnumToken.IdenTokenType && iden.typ != exports.EnumToken.DashedIdenTokenType) {
18754
+ continue;
18755
+ }
18756
+ if (!(iden.val in root.mapping)) {
18757
+ const result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? iden.val : moduleSettings.generateScopedName(iden.val, srcIndex, moduleSettings.pattern, moduleSettings.hashLength);
18758
+ let value = result instanceof Promise ? await result : result;
18759
+ root.mapping[iden.val] = (moduleSettings.naming & exports.ModuleCaseTransformEnum.DashCaseOnly || moduleSettings.naming & exports.ModuleCaseTransformEnum.CamelCaseOnly ? getKeyName(value, moduleSettings.naming) : value);
18760
+ root.revMapping[root.mapping[iden.val]] = iden.val;
18761
+ }
18762
+ importMapping[srcIndex][iden.val] = root.mapping[iden.val];
18763
+ values.push(root.mapping[iden.val]);
18764
+ }
18765
+ mapping[key] = [...new Set([...mapping[key].split(' '), ...values])].join(' ');
18766
+ }
18767
+ }
18768
+ }
18769
+ }
18770
+ }
18771
+ // composes: a b c from global;
18772
+ else if (token.r.typ == exports.EnumToken.IdenTokenType) {
18773
+ // global
18774
+ if (parentRule != null) {
18775
+ if ('global' == token.r.val.toLowerCase()) {
18776
+ for (const tk of parentRule.tokens) {
18777
+ if (tk.typ == exports.EnumToken.ClassSelectorTokenType) {
18778
+ const val = tk.val.slice(1);
18779
+ if (val in revMapping) {
18780
+ const key = revMapping[val];
18781
+ mapping[key] = [...new Set([...mapping[key].split(' '), ...(token.l.reduce((acc, curr) => {
18782
+ if (curr.typ == exports.EnumToken.IdenTokenType) {
18783
+ acc.push(curr.val);
18784
+ }
18785
+ return acc;
18786
+ }, []))])].join(' ');
18787
+ }
18788
+ }
18789
+ }
18790
+ }
18791
+ else {
18792
+ errors.push({
18793
+ action: 'drop',
18794
+ message: `composes '${token.r.val}' is not supported`,
18795
+ node
18796
+ });
18797
+ }
18798
+ }
18799
+ }
18800
+ }
18801
+ parentRule.chi.splice(parentRule.chi.indexOf(node), 1);
18802
+ }
18803
+ if (node.typ == exports.EnumToken.DeclarationNodeType && ['grid-column', 'grid-column-start', 'grid-column-end', 'grid-row', 'grid-row-start', 'grid-row-end', 'grid-template', 'grid-template-columns', 'grid-template-rows'].includes(node.nam)) {
18804
+ for (const { value } of walkValues(node.val, node)) {
18805
+ if (value.typ != exports.EnumToken.IdenTokenType) {
18806
+ continue;
18807
+ }
18808
+ let idenToken = value.val;
18809
+ let suffix = '';
18810
+ if (idenToken.endsWith('-start')) {
18811
+ suffix = '-start';
18812
+ idenToken = idenToken.slice(0, -6);
18813
+ }
18814
+ else if (idenToken.endsWith('-end')) {
18815
+ suffix = '-end';
18816
+ idenToken = idenToken.slice(0, -4);
18817
+ }
18818
+ if (!(idenToken in mapping)) {
18819
+ let result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? idenToken : moduleSettings.generateScopedName(idenToken, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18820
+ if (result instanceof Promise) {
18821
+ result = await result;
18822
+ }
18823
+ mapping[idenToken] = result;
18824
+ revMapping[result] = idenToken;
18825
+ if (suffix !== '') {
18826
+ idenToken += suffix;
18827
+ if (!(idenToken in mapping)) {
18828
+ mapping[idenToken] = result + suffix;
18829
+ revMapping[result + suffix] = idenToken;
18830
+ }
18831
+ }
18832
+ }
18833
+ value.val = mapping[idenToken];
18834
+ }
18835
+ }
18836
+ else if (node.nam == 'grid-template-areas' || node.nam == 'grid-template') {
18837
+ for (let i = 0; i < node.val.length; i++) {
18838
+ if (node.val[i].typ == exports.EnumToken.String) {
18839
+ const tokens = parseString(node.val[i].val.slice(1, -1), { location: true });
18840
+ for (const { value } of walkValues(tokens)) {
18841
+ if (value.typ == exports.EnumToken.IdenTokenType || value.typ == exports.EnumToken.DashedIdenTokenType) {
18842
+ if (value.val in mapping) {
18843
+ value.val = mapping[value.val];
18844
+ }
18845
+ else {
18846
+ let result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? value.val : moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18847
+ if (result instanceof Promise) {
18848
+ result = await result;
18849
+ }
18850
+ mapping[value.val] = result;
18851
+ revMapping[result] = value.val;
18852
+ value.val = result;
18853
+ }
18854
+ }
18855
+ }
18856
+ node.val[i].val = node.val[i].val.charAt(0) + tokens.reduce((acc, curr) => acc + renderToken(curr), '') + node.val[i].val.charAt(node.val[i].val.length - 1);
18857
+ }
18858
+ }
18859
+ }
18860
+ else if (node.nam == 'animation' || node.nam == 'animation-name') {
18861
+ for (const { value } of walkValues(node.val, node)) {
18862
+ if (value.typ == exports.EnumToken.IdenTokenType && ![
18863
+ 'none', 'infinite', 'normal', 'reverse', 'alternate',
18864
+ 'alternate-reverse', 'forwards', 'backwards', 'both',
18865
+ 'running', 'paused', 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out',
18866
+ 'step-start', 'step-end', 'jump-start', 'jump-end',
18867
+ 'jump-none', 'jump-both', 'start', 'end',
18868
+ 'inherit', 'initial', 'unset'
18869
+ ].includes(value.val)) {
18870
+ if (!(value.val in mapping)) {
18871
+ const result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? value.val : moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18872
+ mapping[value.val] = result instanceof Promise ? await result : result;
18873
+ revMapping[mapping[value.val]] = value.val;
18874
+ }
18875
+ value.val = mapping[value.val];
18876
+ }
18877
+ }
18878
+ }
18879
+ for (const { value, parent } of walkValues(node.val, node)) {
18880
+ if (value.typ == exports.EnumToken.DashedIdenTokenType) {
18881
+ if (!(value.val in mapping)) {
18882
+ const result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? value.val : moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18883
+ let val = result instanceof Promise ? await result : result;
18884
+ mapping[value.val] = '--' + (moduleSettings.naming & exports.ModuleCaseTransformEnum.DashCaseOnly || moduleSettings.naming & exports.ModuleCaseTransformEnum.CamelCaseOnly ? getKeyName(val, moduleSettings.naming) : val);
18885
+ revMapping[mapping[value.val]] = value.val;
18886
+ }
18887
+ value.val = mapping[value.val];
18888
+ }
18889
+ else if ((value.typ == exports.EnumToken.IdenTokenType || isIdentColor(value)) && value.val in importedCssVariables) {
18890
+ replaceToken(parent, value, importedCssVariables[value.val].val);
18891
+ }
18892
+ }
18893
+ }
18894
+ else if (node.typ == exports.EnumToken.RuleNodeType) {
18895
+ if (node.tokens == null) {
18896
+ Object.defineProperty(node, 'tokens', {
18897
+ ...definedPropertySettings,
18898
+ value: parseSelector(parseString(node.sel, { location: true }))
18899
+ });
18900
+ }
18901
+ let hasIdOrClass = false;
18902
+ for (const { value } of walkValues(node.tokens, node,
18903
+ // @ts-ignore
18904
+ (value, parent) => {
18905
+ if (value.typ == exports.EnumToken.PseudoClassTokenType) {
18906
+ const val = value.val.toLowerCase();
18907
+ switch (val) {
18908
+ case ':local':
18909
+ case ':global':
18910
+ {
18911
+ let index = parent.tokens.indexOf(value);
18912
+ parent.tokens.splice(index, 1);
18913
+ if (parent.tokens[index]?.typ == exports.EnumToken.WhitespaceTokenType || parent.tokens[index]?.typ == exports.EnumToken.DescendantCombinatorTokenType) {
18914
+ parent.tokens.splice(index, 1);
18915
+ }
18916
+ if (val == ':global') {
18917
+ for (; index < parent.tokens.length; index++) {
18918
+ if (parent.tokens[index].typ == exports.EnumToken.CommaTokenType ||
18919
+ ([exports.EnumToken.PseudoClassFuncTokenType, exports.EnumToken.PseudoClassTokenType].includes(parent.tokens[index].typ) &&
18920
+ [':global', ':local'].includes(parent.tokens[index].val.toLowerCase()))) {
18921
+ break;
18922
+ }
18923
+ global.add(parent.tokens[index]);
18924
+ }
18925
+ }
18926
+ }
18927
+ break;
18928
+ }
18929
+ }
18930
+ else if (value.typ == exports.EnumToken.PseudoClassFuncTokenType) {
18931
+ switch (value.val.toLowerCase()) {
18932
+ case ':global':
18933
+ for (const token of value.chi) {
18934
+ global.add(token);
18935
+ }
18936
+ parent.tokens.splice(parent.tokens.indexOf(value), 1, ...value.chi);
18937
+ break;
18938
+ case ':local':
18939
+ parent.tokens.splice(parent.tokens.indexOf(value), 1, ...value.chi);
18940
+ break;
18941
+ }
18942
+ }
18943
+ })) {
18944
+ if (value.typ == exports.EnumToken.HashTokenType || value.typ == exports.EnumToken.ClassSelectorTokenType) {
18945
+ hasIdOrClass = true;
18946
+ }
18947
+ if (processed.has(value)) {
18948
+ continue;
18949
+ }
18950
+ processed.add(value);
18951
+ if (value.typ == exports.EnumToken.PseudoClassTokenType) ;
18952
+ else if (value.typ == exports.EnumToken.PseudoClassFuncTokenType) ;
18953
+ else {
18954
+ if (global.has(value)) {
18955
+ continue;
18956
+ }
18957
+ if (value.typ == exports.EnumToken.ClassSelectorTokenType) {
18958
+ const val = value.val.slice(1);
18959
+ if (!(val in mapping)) {
18960
+ const result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? val : moduleSettings.generateScopedName(val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18961
+ let value = result instanceof Promise ? await result : result;
18962
+ mapping[val] = (moduleSettings.naming & exports.ModuleCaseTransformEnum.DashCaseOnly || moduleSettings.naming & exports.ModuleCaseTransformEnum.CamelCaseOnly ? getKeyName(value, moduleSettings.naming) : value);
18963
+ revMapping[mapping[val]] = val;
18964
+ }
18965
+ value.val = '.' + mapping[val];
18966
+ }
18967
+ }
18968
+ }
18969
+ if (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Pure) {
18970
+ if (!hasIdOrClass) {
18971
+ throw new Error(`pure module: No id or class found in selector '${node.sel}' at '${node.loc?.src ?? ''}':${node.loc?.sta?.lin ?? ''}:${node.loc?.sta?.col ?? ''}`);
18972
+ }
18973
+ }
18974
+ node.sel = '';
18975
+ for (const token of node.tokens) {
18976
+ node.sel += renderToken(token);
18977
+ }
18978
+ }
18979
+ else if (node.typ == exports.EnumToken.AtRuleNodeType || node.typ == exports.EnumToken.KeyframesAtRuleNodeType) {
18980
+ const val = node.nam.toLowerCase();
18981
+ if (node.tokens == null) {
18982
+ Object.defineProperty(node, 'tokens', {
18983
+ ...definedPropertySettings,
18984
+ // @ts-ignore
18985
+ value: parseAtRulePrelude(parseString(node.val), node)
18986
+ });
18987
+ }
18988
+ if (val == 'property' || val == 'keyframes') {
18989
+ const prefix = val == 'property' ? '--' : '';
18990
+ for (const value of node.tokens) {
18991
+ if ((prefix == '--' && value.typ == exports.EnumToken.DashedIdenTokenType) || (prefix == '' && value.typ == exports.EnumToken.IdenTokenType)) {
18992
+ if (!(value.val in mapping)) {
18993
+ const result = (moduleSettings.scoped & exports.ModuleScopeEnumOptions.Global) ? value.val : moduleSettings.generateScopedName(value.val, moduleSettings.filePath, moduleSettings.pattern, moduleSettings.hashLength);
18994
+ let val = result instanceof Promise ? await result : result;
18995
+ mapping[value.val] = prefix + (moduleSettings.naming & exports.ModuleCaseTransformEnum.DashCaseOnly || moduleSettings.naming & exports.ModuleCaseTransformEnum.CamelCaseOnly ? getKeyName(val, moduleSettings.naming) : val);
18996
+ revMapping[mapping[value.val]] = value.val;
18997
+ }
18998
+ value.val = mapping[value.val];
18999
+ }
19000
+ }
19001
+ node.val = node.tokens.reduce((a, b) => a + renderToken(b), '');
19002
+ }
19003
+ else {
19004
+ let isReplaced = false;
19005
+ for (const { value, parent } of walkValues(node.tokens, node)) {
19006
+ if (exports.EnumToken.MediaQueryConditionTokenType == parent.typ && value != parent.l) {
19007
+ if ((value.typ == exports.EnumToken.IdenTokenType || isIdentColor(value)) && value.val in importedCssVariables) {
19008
+ isReplaced = true;
19009
+ parent.r.splice(parent.r.indexOf(value), 1, ...importedCssVariables[value.val].val);
19010
+ }
19011
+ }
19012
+ }
19013
+ if (isReplaced) {
19014
+ node.val = node.tokens.reduce((a, b) => a + renderToken(b), '');
19015
+ }
19016
+ }
19017
+ }
19018
+ }
19019
+ if (moduleSettings.naming != exports.ModuleCaseTransformEnum.IgnoreCase) {
19020
+ revMapping = {};
19021
+ mapping = Object.entries(mapping).reduce((acc, [key, value]) => {
19022
+ const keyName = getKeyName(key, moduleSettings.naming);
19023
+ acc[keyName] = value;
19024
+ revMapping[value] = keyName;
19025
+ return acc;
19026
+ }, {});
19027
+ }
19028
+ result.mapping = mapping;
19029
+ result.revMapping = revMapping;
19030
+ if ((moduleSettings.scoped & exports.ModuleScopeEnumOptions.ICSS) && Object.keys(importMapping).length > 0) {
19031
+ result.importMapping = importMapping;
19032
+ }
19033
+ endTime = performance.now();
19034
+ result.stats.module = `${(endTime - parseModuleTime).toFixed(2)}ms`;
19035
+ result.stats.total = `${(endTime - startTime).toFixed(2)}ms`;
19036
+ }
19037
+ if (options.signal != null) {
19038
+ options.signal.removeEventListener('abort', reject);
19039
+ }
19040
+ return result;
18171
19041
  }
18172
19042
  function getLastNode(context) {
18173
19043
  let i = context.chi.length;
@@ -18385,6 +19255,145 @@
18385
19255
  isValid = false;
18386
19256
  }
18387
19257
  }
19258
+ if (node.nam == 'value') {
19259
+ let i = 0;
19260
+ while (i < tokens.length) {
19261
+ if (tokens[i].typ == exports.EnumToken.WhitespaceTokenType || tokens[i].typ == exports.EnumToken.CommentTokenType) {
19262
+ i++;
19263
+ continue;
19264
+ }
19265
+ break;
19266
+ }
19267
+ if (i < tokens.length) {
19268
+ if (tokens[i].typ == exports.EnumToken.IdenTokenType || isIdentColor(tokens[i])) {
19269
+ let k = i + 1;
19270
+ while (k < tokens.length) {
19271
+ if (tokens[k].typ == exports.EnumToken.WhitespaceTokenType || tokens[k].typ == exports.EnumToken.CommentTokenType) {
19272
+ k++;
19273
+ continue;
19274
+ }
19275
+ // var or import
19276
+ if (tokens[k].typ == exports.EnumToken.ColonTokenType) {
19277
+ let j = k;
19278
+ while (++j < tokens.length) {
19279
+ if (tokens[j].typ != exports.EnumToken.WhitespaceTokenType && tokens[j].typ != exports.EnumToken.CommentTokenType) {
19280
+ break;
19281
+ }
19282
+ }
19283
+ let offset = k + 1;
19284
+ while (offset < tokens.length && tokens[offset].typ == exports.EnumToken.WhitespaceTokenType) {
19285
+ offset++;
19286
+ }
19287
+ if (tokens[j].typ == exports.EnumToken.StringTokenType) {
19288
+ Object.assign(node, {
19289
+ typ: exports.EnumToken.CssVariableImportTokenType,
19290
+ nam: tokens[i].val,
19291
+ val: tokens.slice(offset)
19292
+ });
19293
+ delete node.tokens;
19294
+ context.chi.push(node);
19295
+ return null;
19296
+ }
19297
+ Object.assign(node, {
19298
+ typ: exports.EnumToken.CssVariableTokenType,
19299
+ nam: tokens[i].val,
19300
+ val: tokens.slice(offset)
19301
+ });
19302
+ context.chi.push(node);
19303
+ return null;
19304
+ }
19305
+ if (tokens[k].typ == exports.EnumToken.PseudoClassTokenType) {
19306
+ Object.assign(tokens[k], {
19307
+ typ: exports.EnumToken.IdenTokenType,
19308
+ val: tokens[k].val.slice(1)
19309
+ });
19310
+ Object.assign(node, {
19311
+ typ: exports.EnumToken.CssVariableTokenType,
19312
+ nam: tokens[i].val,
19313
+ val: tokens.slice(k)
19314
+ });
19315
+ context.chi.push(node);
19316
+ return null;
19317
+ }
19318
+ if (tokens[k].typ == exports.EnumToken.CommaTokenType) {
19319
+ let j = i;
19320
+ while (++j < tokens.length) {
19321
+ if (tokens[j].typ == exports.EnumToken.IdenTokenType && tokens[j].val.toLowerCase() == 'from') {
19322
+ const vars = tokens.slice(i, j);
19323
+ const from = tokens.slice(j + 1);
19324
+ let l = 0;
19325
+ let expect = exports.EnumToken.IdenTokenType;
19326
+ for (; l < vars.length; l++) {
19327
+ if (vars[l].typ == exports.EnumToken.WhitespaceTokenType || vars[l].typ == exports.EnumToken.CommentTokenType) {
19328
+ continue;
19329
+ }
19330
+ if (expect == vars[l].typ || (expect == exports.EnumToken.IdenTokenType && isIdentColor(vars[l]))) {
19331
+ expect = expect == exports.EnumToken.CommaTokenType ? exports.EnumToken.IdenTokenType : exports.EnumToken.CommaTokenType;
19332
+ continue;
19333
+ }
19334
+ errors.push({
19335
+ action: 'drop',
19336
+ node: node,
19337
+ location: map.get(vars[l]) ?? location,
19338
+ message: `expecting '${exports.EnumToken[expect]}' but found ${renderToken(vars[l])}`
19339
+ });
19340
+ return null;
19341
+ }
19342
+ l = 0;
19343
+ expect = exports.EnumToken.IdenTokenType;
19344
+ for (; l < from.length; l++) {
19345
+ if (from[l].typ == exports.EnumToken.WhitespaceTokenType || from[l].typ == exports.EnumToken.CommentTokenType) {
19346
+ continue;
19347
+ }
19348
+ if (expect == from[l].typ || isIdentColor(from[l])) {
19349
+ while (++l < from.length) {
19350
+ if (from[l].typ == exports.EnumToken.WhitespaceTokenType || from[l].typ == exports.EnumToken.CommentTokenType) {
19351
+ continue;
19352
+ }
19353
+ errors.push({
19354
+ action: 'drop',
19355
+ node: node,
19356
+ location: map.get(from[l]) ?? location,
19357
+ message: `unexpected '${renderToken(from[l])}'`
19358
+ });
19359
+ return null;
19360
+ }
19361
+ break;
19362
+ }
19363
+ errors.push({
19364
+ action: 'drop',
19365
+ node: node,
19366
+ location: map.get(from[l]) ?? location,
19367
+ message: `expecting <string> but found ${renderToken(from[l])}`
19368
+ });
19369
+ return null;
19370
+ }
19371
+ // @ts-ignore
19372
+ delete node.nam;
19373
+ // @ts-ignore
19374
+ delete node.val;
19375
+ Object.assign(node, {
19376
+ typ: exports.EnumToken.CssVariableDeclarationMapTokenType,
19377
+ vars,
19378
+ from
19379
+ });
19380
+ context.chi.push(node);
19381
+ return null;
19382
+ }
19383
+ }
19384
+ }
19385
+ k++;
19386
+ }
19387
+ Object.assign(node, {
19388
+ typ: exports.EnumToken.CssVariableTokenType,
19389
+ nam: tokens[i].val,
19390
+ val: tokens.slice(k)
19391
+ });
19392
+ context.chi.push(node);
19393
+ return null;
19394
+ }
19395
+ }
19396
+ }
18388
19397
  // @ts-ignore
18389
19398
  const skipValidate = (options.validation & exports.ValidationLevel.AtRule) == 0;
18390
19399
  const isAllowed = skipValidate || isNodeAllowedInContext(node, context);
@@ -18923,6 +19932,7 @@
18923
19932
  return doParse(tokenize$1({
18924
19933
  stream: `.x{${declaration}}`,
18925
19934
  buffer: '',
19935
+ offset: 0,
18926
19936
  position: { ind: 0, lin: 1, col: 1 },
18927
19937
  currentPosition: { ind: -1, lin: 1, col: 0 }
18928
19938
  }), { setParent: false, minify: false, validation: false }).then(result => {
@@ -19043,6 +20053,7 @@
19043
20053
  const parseInfo = {
19044
20054
  stream: src,
19045
20055
  buffer: '',
20056
+ offset: 0,
19046
20057
  position: { ind: 0, lin: 1, col: 1 },
19047
20058
  currentPosition: { ind: -1, lin: 1, col: 0 }
19048
20059
  };
@@ -19168,12 +20179,10 @@
19168
20179
  val: +val.slice(0, -1)
19169
20180
  };
19170
20181
  }
19171
- // if (isDimension(val)) {
19172
20182
  const dimension = parseDimension(val);
19173
20183
  if (dimension != null) {
19174
20184
  return dimension;
19175
20185
  }
19176
- // }
19177
20186
  const v = val.toLowerCase();
19178
20187
  if (v == 'currentcolor' || v == 'transparent' || v in COLORS_NAMES) {
19179
20188
  return {
@@ -19202,6 +20211,12 @@
19202
20211
  val
19203
20212
  };
19204
20213
  }
20214
+ if (val.charAt(0) == '.' && isIdent(val.slice(1))) {
20215
+ return {
20216
+ typ: exports.EnumToken.ClassSelectorTokenType,
20217
+ val
20218
+ };
20219
+ }
19205
20220
  if (val.charAt(0) == '#' && isHexColor(val)) {
19206
20221
  return {
19207
20222
  typ: exports.EnumToken.ColorTokenType,
@@ -19249,6 +20264,55 @@
19249
20264
  function parseTokens(tokens, options = {}) {
19250
20265
  for (let i = 0; i < tokens.length; i++) {
19251
20266
  const t = tokens[i];
20267
+ if (t.typ == exports.EnumToken.IdenTokenType && t.val == 'from' && i > 0) {
20268
+ const left = [];
20269
+ const right = [];
20270
+ let foundLeft = 0;
20271
+ let foundRight = 0;
20272
+ let k = i;
20273
+ let l = i;
20274
+ while (k > 0) {
20275
+ if (tokens[k - 1].typ == exports.EnumToken.CommentTokenType || tokens[k - 1].typ == exports.EnumToken.WhitespaceTokenType) {
20276
+ left.push(tokens[--k]);
20277
+ continue;
20278
+ }
20279
+ if (tokens[k - 1].typ == exports.EnumToken.IdenTokenType || tokens[k - 1].typ == exports.EnumToken.DashedIdenTokenType) {
20280
+ foundLeft++;
20281
+ left.push(tokens[--k]);
20282
+ continue;
20283
+ }
20284
+ break;
20285
+ }
20286
+ while (++l < tokens.length) {
20287
+ if (tokens[l].typ == exports.EnumToken.CommentTokenType || tokens[l].typ == exports.EnumToken.WhitespaceTokenType) {
20288
+ right.push(tokens[l]);
20289
+ continue;
20290
+ }
20291
+ if (tokens[l].typ == exports.EnumToken.IdenTokenType || tokens[l].typ == exports.EnumToken.StringTokenType) {
20292
+ foundRight++;
20293
+ right.push(tokens[l]);
20294
+ continue;
20295
+ }
20296
+ break;
20297
+ }
20298
+ if (foundLeft > 0 && foundRight == 1) {
20299
+ while (left?.[0].typ == exports.EnumToken.WhitespaceTokenType) {
20300
+ left.shift();
20301
+ }
20302
+ while (left.at(-1)?.typ == exports.EnumToken.WhitespaceTokenType) {
20303
+ left.pop();
20304
+ }
20305
+ tokens.splice(k, l - k + 1, {
20306
+ typ: exports.EnumToken.ComposesSelectorNodeType,
20307
+ l: left,
20308
+ r: right.reduce((a, b) => {
20309
+ return a == null ? b : b.typ == exports.EnumToken.IdenTokenType || b.typ == exports.EnumToken.StringTokenType ? b : a;
20310
+ }, null)
20311
+ });
20312
+ i = k;
20313
+ continue;
20314
+ }
20315
+ }
19252
20316
  if (t.typ == exports.EnumToken.WhitespaceTokenType && ((i == 0 ||
19253
20317
  i + 1 == tokens.length ||
19254
20318
  [exports.EnumToken.CommaTokenType, exports.EnumToken.GteTokenType, exports.EnumToken.LteTokenType, exports.EnumToken.ColumnCombinatorTokenType].includes(tokens[i + 1].typ)) ||
@@ -19757,7 +20821,6 @@
19757
20821
  * ```
19758
20822
  */
19759
20823
  function* walkValues(values, root = null, filter, reverse) {
19760
- // const set = new Set<Token>();
19761
20824
  const stack = values.slice();
19762
20825
  const map = new Map;
19763
20826
  let previous = null;
@@ -19791,8 +20854,12 @@
19791
20854
  continue;
19792
20855
  }
19793
20856
  // @ts-ignore
19794
- if (option != null && typeof option == 'object' && 'typ' in option) {
19795
- map.set(option, map.get(value) ?? root);
20857
+ if (option != null && typeof option == 'object' && ('typ' in option || Array.isArray(option))) {
20858
+ const op = Array.isArray(option) ? option : [option];
20859
+ for (const o of op) {
20860
+ map.set(o, map.get(value) ?? root);
20861
+ }
20862
+ stack[reverse ? 'push' : 'unshift'](...op);
19796
20863
  }
19797
20864
  }
19798
20865
  }
@@ -19815,12 +20882,12 @@
19815
20882
  const values = [];
19816
20883
  if ('l' in value && value.l != null) {
19817
20884
  // @ts-ignore
19818
- values[reverse ? 'push' : 'unshift'](value.l);
20885
+ values.push(value.l);
19819
20886
  // @ts-ignore
19820
20887
  map.set(value.l, value);
19821
20888
  }
19822
20889
  if ('op' in value && typeof value.op == 'object') {
19823
- values[reverse ? 'push' : 'unshift'](value.op);
20890
+ values.push(value.op);
19824
20891
  // @ts-ignore
19825
20892
  map.set(value.op, value);
19826
20893
  }
@@ -19828,14 +20895,14 @@
19828
20895
  if (Array.isArray(value.r)) {
19829
20896
  for (const r of value.r) {
19830
20897
  // @ts-ignore
19831
- values[reverse ? 'push' : 'unshift'](r);
20898
+ values.push(r);
19832
20899
  // @ts-ignore
19833
20900
  map.set(r, value);
19834
20901
  }
19835
20902
  }
19836
20903
  else {
19837
20904
  // @ts-ignore
19838
- values[reverse ? 'push' : 'unshift'](value.r);
20905
+ values.push(value.r);
19839
20906
  // @ts-ignore
19840
20907
  map.set(value.r, value);
19841
20908
  }
@@ -19851,8 +20918,12 @@
19851
20918
  if (isValid) {
19852
20919
  option = filter.fn(value, map.get(value), exports.WalkerEvent.Leave);
19853
20920
  // @ts-ignore
19854
- if (option != null && 'typ' in option) {
19855
- map.set(option, map.get(value) ?? root);
20921
+ if (option != null && ('typ' in option || Array.isArray(option))) {
20922
+ const op = Array.isArray(option) ? option : [option];
20923
+ for (const o of op) {
20924
+ map.set(o, map.get(value) ?? root);
20925
+ }
20926
+ stack[reverse ? 'push' : 'unshift'](...op);
19856
20927
  }
19857
20928
  }
19858
20929
  }
@@ -19863,7 +20934,7 @@
19863
20934
  /**
19864
20935
  * feature walk mode
19865
20936
  *
19866
- * @internal
20937
+ * @private
19867
20938
  */
19868
20939
  exports.FeatureWalkMode = void 0;
19869
20940
  (function (FeatureWalkMode) {
@@ -20947,9 +22018,12 @@
20947
22018
  });
20948
22019
  }
20949
22020
  add(...declarations) {
22021
+ let name;
20950
22022
  for (const declaration of declarations) {
22023
+ name = declaration.typ != exports.EnumToken.DeclarationNodeType ? null : declaration.nam.toLowerCase();
20951
22024
  if (declaration.typ != exports.EnumToken.DeclarationNodeType ||
20952
- (typeof this.options.removeDuplicateDeclarations === 'string' && this.options.removeDuplicateDeclarations === declaration.nam.toLowerCase()) ||
22025
+ 'composes' === name ||
22026
+ (typeof this.options.removeDuplicateDeclarations === 'string' && this.options.removeDuplicateDeclarations === name) ||
20953
22027
  (Array.isArray(this.options.removeDuplicateDeclarations) ? this.options.removeDuplicateDeclarations.includes(declaration.nam) : !this.options.removeDuplicateDeclarations)) {
20954
22028
  this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
20955
22029
  continue;
@@ -22511,7 +23585,7 @@
22511
23585
  continue;
22512
23586
  }
22513
23587
  else if (node.typ == previous?.typ && [exports.EnumToken.KeyFramesRuleNodeType, exports.EnumToken.RuleNodeType].includes(node.typ)) {
22514
- const intersect = diff(previous, node, reducer, options);
23588
+ const intersect = diff$1(previous, node, reducer, options);
22515
23589
  if (intersect != null) {
22516
23590
  if (intersect.node1.chi.length == 0) {
22517
23591
  ast.chi.splice(i--, 1);
@@ -22557,7 +23631,7 @@
22557
23631
  nodeIndex = i;
22558
23632
  }
22559
23633
  if (recursive && node != null && ('chi' in node)) {
22560
- if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType || !node.chi.some(n => n.typ == exports.EnumToken.DeclarationNodeType)) {
23634
+ if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType || !node.chi.some((n) => n.typ == exports.EnumToken.DeclarationNodeType)) {
22561
23635
  if (!(node.typ == exports.EnumToken.AtRuleNodeType && node.nam != 'font-face')) {
22562
23636
  doMinify(node, options, recursive, errors, nestingContent, context);
22563
23637
  }
@@ -22990,7 +24064,7 @@
22990
24064
  *
22991
24065
  * @private
22992
24066
  */
22993
- function diff(n1, n2, reducer, options = {}) {
24067
+ function diff$1(n1, n2, reducer, options = {}) {
22994
24068
  if (!('cache' in options)) {
22995
24069
  options.cache = new WeakMap();
22996
24070
  }
@@ -23388,6 +24462,9 @@
23388
24462
  //
23389
24463
  // return path;
23390
24464
  // }
24465
+ if (path === '') {
24466
+ return '';
24467
+ }
23391
24468
  let i = 0;
23392
24469
  let parts = [''];
23393
24470
  for (; i < path.length; i++) {
@@ -23412,6 +24489,12 @@
23412
24489
  * @private
23413
24490
  */
23414
24491
  function splitPath(result) {
24492
+ if (result.length == 0) {
24493
+ return { parts: [], i: 0 };
24494
+ }
24495
+ if (result === '/') {
24496
+ return { parts: ['/'], i: 0 };
24497
+ }
23415
24498
  const parts = [''];
23416
24499
  let i = 0;
23417
24500
  for (; i < result.length; i++) {
@@ -23455,6 +24538,21 @@
23455
24538
  }
23456
24539
  cwd ??= '';
23457
24540
  currentDirectory ??= '';
24541
+ if (currentDirectory !== '' && url.startsWith(currentDirectory + '/')) {
24542
+ return {
24543
+ absolute: url,
24544
+ relative: url.slice(currentDirectory.length + 1)
24545
+ };
24546
+ }
24547
+ if (currentDirectory === '' && cwd !== '' && url.startsWith(cwd == '/' ? cwd : cwd + '/')) {
24548
+ cwd = normalize(cwd);
24549
+ const absolute = normalize(url);
24550
+ const prefix = cwd == '/' ? cwd : cwd + '/';
24551
+ return {
24552
+ absolute,
24553
+ relative: absolute.startsWith(prefix) ? absolute.slice(prefix.length) : diff(absolute, cwd)
24554
+ };
24555
+ }
23458
24556
  if (matchUrl.test(currentDirectory)) {
23459
24557
  const path = new URL(url, currentDirectory).href;
23460
24558
  return {
@@ -23469,9 +24567,15 @@
23469
24567
  else if (currentDirectory.charAt(0) == '/') {
23470
24568
  result = dirname(currentDirectory) + '/' + url;
23471
24569
  }
23472
- let { parts, i } = splitPath(result);
23473
- const absolute = parts.join('/');
23474
- const { parts: dirs } = splitPath(cwd ?? currentDirectory);
24570
+ const absolute = normalize(result);
24571
+ return {
24572
+ absolute,
24573
+ relative: absolute === '' ? '' : diff(absolute, cwd ?? currentDirectory),
24574
+ };
24575
+ }
24576
+ function diff(path1, path2) {
24577
+ let { parts } = splitPath(path1);
24578
+ const { parts: dirs } = splitPath(path2);
23475
24579
  for (const p of dirs) {
23476
24580
  if (parts[0] == p) {
23477
24581
  parts.shift();
@@ -23480,21 +24584,69 @@
23480
24584
  parts.unshift('..');
23481
24585
  }
23482
24586
  }
23483
- return {
23484
- absolute,
23485
- relative: parts.join('/') + (i < result.length ? result.slice(i) : '')
23486
- };
24587
+ return parts.join('/');
24588
+ }
24589
+ function normalize(path) {
24590
+ let parts = [];
24591
+ let i = 0;
24592
+ for (; i < path.length; i++) {
24593
+ const chr = path.charAt(i);
24594
+ if (chr == '/') {
24595
+ if (parts.length == 0 || parts[parts.length - 1] !== '') {
24596
+ parts.push('');
24597
+ }
24598
+ }
24599
+ else if (chr == '?' || chr == '#') {
24600
+ break;
24601
+ }
24602
+ else {
24603
+ parts[parts.length - 1] += chr;
24604
+ }
24605
+ }
24606
+ let k = -1;
24607
+ while (++k < parts.length) {
24608
+ if (parts[k] == '.') {
24609
+ parts.splice(k--, 1);
24610
+ }
24611
+ else if (parts[k] == '..') {
24612
+ parts.splice(k - 1, 2);
24613
+ k -= 2;
24614
+ }
24615
+ }
24616
+ return (path.charAt(0) == '/' ? '/' : '') + parts.join('/');
23487
24617
  }
23488
24618
 
24619
+ /**
24620
+ * response type
24621
+ */
24622
+ exports.ResponseType = void 0;
24623
+ (function (ResponseType) {
24624
+ /**
24625
+ * return text
24626
+ */
24627
+ ResponseType[ResponseType["Text"] = 0] = "Text";
24628
+ /**
24629
+ * return a readable stream
24630
+ */
24631
+ ResponseType[ResponseType["ReadableStream"] = 1] = "ReadableStream";
24632
+ /**
24633
+ * return an arraybuffer
24634
+ */
24635
+ ResponseType[ResponseType["ArrayBuffer"] = 2] = "ArrayBuffer";
24636
+ })(exports.ResponseType || (exports.ResponseType = {}));
24637
+
23489
24638
  /**
23490
24639
  * default file or url loader
23491
24640
  * @param url
23492
24641
  * @param currentFile
23493
24642
  *
23494
- * @param asStream
24643
+ * @param responseType
23495
24644
  * @private
23496
24645
  */
23497
- async function load(url, currentFile = '.', asStream = false) {
24646
+ async function load(url, currentFile = '.', responseType = false) {
24647
+ if (typeof responseType == 'boolean') {
24648
+ responseType = responseType ? exports.ResponseType.ReadableStream : exports.ResponseType.Text;
24649
+ }
23498
24650
  let t;
23499
24651
  if (matchUrl.test(url)) {
23500
24652
  t = new URL(url);
@@ -23510,13 +24662,17 @@
23510
24662
  if (!response.ok) {
23511
24663
  throw new Error(`${response.status} ${response.statusText} ${response.url}`);
23512
24664
  }
23513
- return asStream ? response.body : await response.text();
24665
+ if (responseType == exports.ResponseType.ArrayBuffer) {
24666
+ return response.arrayBuffer();
24667
+ }
24668
+ return responseType == exports.ResponseType.ReadableStream ? response.body : await response.text();
23514
24669
  });
23515
24670
  }
23516
24671
  /**
23517
24672
  * render the ast tree
23518
24673
  * @param data
23519
24674
  * @param options
24675
+ * @param mapping
23520
24676
  *
23521
24677
  * Example:
23522
24678
  *
@@ -23541,12 +24697,12 @@
23541
24697
  * // }
23542
24698
  * ```
23543
24699
  */
23544
- function render(data, options = {}) {
24700
+ function render(data, options = {}, mapping) {
23545
24701
  return doRender(data, Object.assign(options, {
23546
24702
  resolve,
23547
24703
  dirname,
23548
24704
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
23549
- }));
24705
+ }), mapping);
23550
24706
  }
23551
24707
  /**
23552
24708
  * parse css file
@@ -23606,6 +24762,7 @@
23606
24762
  return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
23607
24763
  stream,
23608
24764
  buffer: '',
24765
+ offset: 0,
23609
24766
  position: { ind: 0, lin: 1, col: 1 },
23610
24767
  currentPosition: { ind: -1, lin: 1, col: 0 }
23611
24768
  }), Object.assign(options, {
@@ -23613,7 +24770,10 @@
23613
24770
  resolve,
23614
24771
  dirname,
23615
24772
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
23616
- }));
24773
+ })).then(result => {
24774
+ const { revMapping, ...res } = result;
24775
+ return res;
24776
+ });
23617
24777
  }
23618
24778
  /**
23619
24779
  * transform css file
@@ -23665,8 +24825,21 @@
23665
24825
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
23666
24826
  const startTime = performance.now();
23667
24827
  return parse(css, options).then((parseResult) => {
24828
+ let mapping = null;
24829
+ let importMapping = null;
24830
+ if (typeof options.module == 'number' && (options.module & exports.ModuleScopeEnumOptions.ICSS)) {
24831
+ mapping = parseResult.mapping;
24832
+ importMapping = parseResult.importMapping;
24833
+ }
24834
+ else if (typeof options.module == 'object' && typeof options.module.scoped == 'number' && (options.module.scoped & exports.ModuleScopeEnumOptions.ICSS)) {
24835
+ mapping = parseResult.mapping;
24836
+ importMapping = parseResult.importMapping;
24837
+ }
23668
24838
  // ast already expanded by parse
23669
- const rendered = render(parseResult.ast, { ...options, expandNestingRules: false });
24839
+ const rendered = render(parseResult.ast, {
24840
+ ...options,
24841
+ expandNestingRules: false
24842
+ }, mapping != null ? { mapping, importMapping } : null);
23670
24843
  return {
23671
24844
  ...parseResult,
23672
24845
  ...rendered,