@tbela99/css-parser 1.3.4 → 1.4.0

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,147 @@
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
+ // @ts-ignore
19295
+ delete node.raw;
19296
+ context.chi.push(node);
19297
+ return null;
19298
+ }
19299
+ Object.assign(node, {
19300
+ typ: exports.EnumToken.CssVariableTokenType,
19301
+ nam: tokens[i].val,
19302
+ val: tokens.slice(offset)
19303
+ });
19304
+ context.chi.push(node);
19305
+ return null;
19306
+ }
19307
+ if (tokens[k].typ == exports.EnumToken.PseudoClassTokenType) {
19308
+ Object.assign(tokens[k], {
19309
+ typ: exports.EnumToken.IdenTokenType,
19310
+ val: tokens[k].val.slice(1)
19311
+ });
19312
+ Object.assign(node, {
19313
+ typ: exports.EnumToken.CssVariableTokenType,
19314
+ nam: tokens[i].val,
19315
+ val: tokens.slice(k)
19316
+ });
19317
+ context.chi.push(node);
19318
+ return null;
19319
+ }
19320
+ if (tokens[k].typ == exports.EnumToken.CommaTokenType) {
19321
+ let j = i;
19322
+ while (++j < tokens.length) {
19323
+ if (tokens[j].typ == exports.EnumToken.IdenTokenType && tokens[j].val.toLowerCase() == 'from') {
19324
+ const vars = tokens.slice(i, j);
19325
+ const from = tokens.slice(j + 1);
19326
+ let l = 0;
19327
+ let expect = exports.EnumToken.IdenTokenType;
19328
+ for (; l < vars.length; l++) {
19329
+ if (vars[l].typ == exports.EnumToken.WhitespaceTokenType || vars[l].typ == exports.EnumToken.CommentTokenType) {
19330
+ continue;
19331
+ }
19332
+ if (expect == vars[l].typ || (expect == exports.EnumToken.IdenTokenType && isIdentColor(vars[l]))) {
19333
+ expect = expect == exports.EnumToken.CommaTokenType ? exports.EnumToken.IdenTokenType : exports.EnumToken.CommaTokenType;
19334
+ continue;
19335
+ }
19336
+ errors.push({
19337
+ action: 'drop',
19338
+ node: node,
19339
+ location: map.get(vars[l]) ?? location,
19340
+ message: `expecting '${exports.EnumToken[expect]}' but found ${renderToken(vars[l])}`
19341
+ });
19342
+ return null;
19343
+ }
19344
+ l = 0;
19345
+ expect = exports.EnumToken.IdenTokenType;
19346
+ for (; l < from.length; l++) {
19347
+ if (from[l].typ == exports.EnumToken.WhitespaceTokenType || from[l].typ == exports.EnumToken.CommentTokenType) {
19348
+ continue;
19349
+ }
19350
+ if (expect == from[l].typ || isIdentColor(from[l])) {
19351
+ while (++l < from.length) {
19352
+ if (from[l].typ == exports.EnumToken.WhitespaceTokenType || from[l].typ == exports.EnumToken.CommentTokenType) {
19353
+ continue;
19354
+ }
19355
+ errors.push({
19356
+ action: 'drop',
19357
+ node: node,
19358
+ location: map.get(from[l]) ?? location,
19359
+ message: `unexpected '${renderToken(from[l])}'`
19360
+ });
19361
+ return null;
19362
+ }
19363
+ break;
19364
+ }
19365
+ errors.push({
19366
+ action: 'drop',
19367
+ node: node,
19368
+ location: map.get(from[l]) ?? location,
19369
+ message: `expecting <string> but found ${renderToken(from[l])}`
19370
+ });
19371
+ return null;
19372
+ }
19373
+ // @ts-ignore
19374
+ delete node.nam;
19375
+ // @ts-ignore
19376
+ delete node.val;
19377
+ Object.assign(node, {
19378
+ typ: exports.EnumToken.CssVariableDeclarationMapTokenType,
19379
+ vars,
19380
+ from
19381
+ });
19382
+ context.chi.push(node);
19383
+ return null;
19384
+ }
19385
+ }
19386
+ }
19387
+ k++;
19388
+ }
19389
+ Object.assign(node, {
19390
+ typ: exports.EnumToken.CssVariableTokenType,
19391
+ nam: tokens[i].val,
19392
+ val: tokens.slice(k)
19393
+ });
19394
+ context.chi.push(node);
19395
+ return null;
19396
+ }
19397
+ }
19398
+ }
18388
19399
  // @ts-ignore
18389
19400
  const skipValidate = (options.validation & exports.ValidationLevel.AtRule) == 0;
18390
19401
  const isAllowed = skipValidate || isNodeAllowedInContext(node, context);
@@ -18923,6 +19934,7 @@
18923
19934
  return doParse(tokenize$1({
18924
19935
  stream: `.x{${declaration}}`,
18925
19936
  buffer: '',
19937
+ offset: 0,
18926
19938
  position: { ind: 0, lin: 1, col: 1 },
18927
19939
  currentPosition: { ind: -1, lin: 1, col: 0 }
18928
19940
  }), { setParent: false, minify: false, validation: false }).then(result => {
@@ -19043,6 +20055,7 @@
19043
20055
  const parseInfo = {
19044
20056
  stream: src,
19045
20057
  buffer: '',
20058
+ offset: 0,
19046
20059
  position: { ind: 0, lin: 1, col: 1 },
19047
20060
  currentPosition: { ind: -1, lin: 1, col: 0 }
19048
20061
  };
@@ -19168,12 +20181,10 @@
19168
20181
  val: +val.slice(0, -1)
19169
20182
  };
19170
20183
  }
19171
- // if (isDimension(val)) {
19172
20184
  const dimension = parseDimension(val);
19173
20185
  if (dimension != null) {
19174
20186
  return dimension;
19175
20187
  }
19176
- // }
19177
20188
  const v = val.toLowerCase();
19178
20189
  if (v == 'currentcolor' || v == 'transparent' || v in COLORS_NAMES) {
19179
20190
  return {
@@ -19202,6 +20213,12 @@
19202
20213
  val
19203
20214
  };
19204
20215
  }
20216
+ if (val.charAt(0) == '.' && isIdent(val.slice(1))) {
20217
+ return {
20218
+ typ: exports.EnumToken.ClassSelectorTokenType,
20219
+ val
20220
+ };
20221
+ }
19205
20222
  if (val.charAt(0) == '#' && isHexColor(val)) {
19206
20223
  return {
19207
20224
  typ: exports.EnumToken.ColorTokenType,
@@ -19249,6 +20266,55 @@
19249
20266
  function parseTokens(tokens, options = {}) {
19250
20267
  for (let i = 0; i < tokens.length; i++) {
19251
20268
  const t = tokens[i];
20269
+ if (t.typ == exports.EnumToken.IdenTokenType && t.val == 'from' && i > 0) {
20270
+ const left = [];
20271
+ const right = [];
20272
+ let foundLeft = 0;
20273
+ let foundRight = 0;
20274
+ let k = i;
20275
+ let l = i;
20276
+ while (k > 0) {
20277
+ if (tokens[k - 1].typ == exports.EnumToken.CommentTokenType || tokens[k - 1].typ == exports.EnumToken.WhitespaceTokenType) {
20278
+ left.push(tokens[--k]);
20279
+ continue;
20280
+ }
20281
+ if (tokens[k - 1].typ == exports.EnumToken.IdenTokenType || tokens[k - 1].typ == exports.EnumToken.DashedIdenTokenType) {
20282
+ foundLeft++;
20283
+ left.push(tokens[--k]);
20284
+ continue;
20285
+ }
20286
+ break;
20287
+ }
20288
+ while (++l < tokens.length) {
20289
+ if (tokens[l].typ == exports.EnumToken.CommentTokenType || tokens[l].typ == exports.EnumToken.WhitespaceTokenType) {
20290
+ right.push(tokens[l]);
20291
+ continue;
20292
+ }
20293
+ if (tokens[l].typ == exports.EnumToken.IdenTokenType || tokens[l].typ == exports.EnumToken.StringTokenType) {
20294
+ foundRight++;
20295
+ right.push(tokens[l]);
20296
+ continue;
20297
+ }
20298
+ break;
20299
+ }
20300
+ if (foundLeft > 0 && foundRight == 1) {
20301
+ while (left?.[0].typ == exports.EnumToken.WhitespaceTokenType) {
20302
+ left.shift();
20303
+ }
20304
+ while (left.at(-1)?.typ == exports.EnumToken.WhitespaceTokenType) {
20305
+ left.pop();
20306
+ }
20307
+ tokens.splice(k, l - k + 1, {
20308
+ typ: exports.EnumToken.ComposesSelectorNodeType,
20309
+ l: left,
20310
+ r: right.reduce((a, b) => {
20311
+ return a == null ? b : b.typ == exports.EnumToken.IdenTokenType || b.typ == exports.EnumToken.StringTokenType ? b : a;
20312
+ }, null)
20313
+ });
20314
+ i = k;
20315
+ continue;
20316
+ }
20317
+ }
19252
20318
  if (t.typ == exports.EnumToken.WhitespaceTokenType && ((i == 0 ||
19253
20319
  i + 1 == tokens.length ||
19254
20320
  [exports.EnumToken.CommaTokenType, exports.EnumToken.GteTokenType, exports.EnumToken.LteTokenType, exports.EnumToken.ColumnCombinatorTokenType].includes(tokens[i + 1].typ)) ||
@@ -19757,7 +20823,6 @@
19757
20823
  * ```
19758
20824
  */
19759
20825
  function* walkValues(values, root = null, filter, reverse) {
19760
- // const set = new Set<Token>();
19761
20826
  const stack = values.slice();
19762
20827
  const map = new Map;
19763
20828
  let previous = null;
@@ -19791,8 +20856,12 @@
19791
20856
  continue;
19792
20857
  }
19793
20858
  // @ts-ignore
19794
- if (option != null && typeof option == 'object' && 'typ' in option) {
19795
- map.set(option, map.get(value) ?? root);
20859
+ if (option != null && typeof option == 'object' && ('typ' in option || Array.isArray(option))) {
20860
+ const op = Array.isArray(option) ? option : [option];
20861
+ for (const o of op) {
20862
+ map.set(o, map.get(value) ?? root);
20863
+ }
20864
+ stack[reverse ? 'push' : 'unshift'](...op);
19796
20865
  }
19797
20866
  }
19798
20867
  }
@@ -19815,12 +20884,12 @@
19815
20884
  const values = [];
19816
20885
  if ('l' in value && value.l != null) {
19817
20886
  // @ts-ignore
19818
- values[reverse ? 'push' : 'unshift'](value.l);
20887
+ values.push(value.l);
19819
20888
  // @ts-ignore
19820
20889
  map.set(value.l, value);
19821
20890
  }
19822
20891
  if ('op' in value && typeof value.op == 'object') {
19823
- values[reverse ? 'push' : 'unshift'](value.op);
20892
+ values.push(value.op);
19824
20893
  // @ts-ignore
19825
20894
  map.set(value.op, value);
19826
20895
  }
@@ -19828,14 +20897,14 @@
19828
20897
  if (Array.isArray(value.r)) {
19829
20898
  for (const r of value.r) {
19830
20899
  // @ts-ignore
19831
- values[reverse ? 'push' : 'unshift'](r);
20900
+ values.push(r);
19832
20901
  // @ts-ignore
19833
20902
  map.set(r, value);
19834
20903
  }
19835
20904
  }
19836
20905
  else {
19837
20906
  // @ts-ignore
19838
- values[reverse ? 'push' : 'unshift'](value.r);
20907
+ values.push(value.r);
19839
20908
  // @ts-ignore
19840
20909
  map.set(value.r, value);
19841
20910
  }
@@ -19851,8 +20920,12 @@
19851
20920
  if (isValid) {
19852
20921
  option = filter.fn(value, map.get(value), exports.WalkerEvent.Leave);
19853
20922
  // @ts-ignore
19854
- if (option != null && 'typ' in option) {
19855
- map.set(option, map.get(value) ?? root);
20923
+ if (option != null && ('typ' in option || Array.isArray(option))) {
20924
+ const op = Array.isArray(option) ? option : [option];
20925
+ for (const o of op) {
20926
+ map.set(o, map.get(value) ?? root);
20927
+ }
20928
+ stack[reverse ? 'push' : 'unshift'](...op);
19856
20929
  }
19857
20930
  }
19858
20931
  }
@@ -19863,7 +20936,7 @@
19863
20936
  /**
19864
20937
  * feature walk mode
19865
20938
  *
19866
- * @internal
20939
+ * @private
19867
20940
  */
19868
20941
  exports.FeatureWalkMode = void 0;
19869
20942
  (function (FeatureWalkMode) {
@@ -20947,9 +22020,12 @@
20947
22020
  });
20948
22021
  }
20949
22022
  add(...declarations) {
22023
+ let name;
20950
22024
  for (const declaration of declarations) {
22025
+ name = declaration.typ != exports.EnumToken.DeclarationNodeType ? null : declaration.nam.toLowerCase();
20951
22026
  if (declaration.typ != exports.EnumToken.DeclarationNodeType ||
20952
- (typeof this.options.removeDuplicateDeclarations === 'string' && this.options.removeDuplicateDeclarations === declaration.nam.toLowerCase()) ||
22027
+ 'composes' === name ||
22028
+ (typeof this.options.removeDuplicateDeclarations === 'string' && this.options.removeDuplicateDeclarations === name) ||
20953
22029
  (Array.isArray(this.options.removeDuplicateDeclarations) ? this.options.removeDuplicateDeclarations.includes(declaration.nam) : !this.options.removeDuplicateDeclarations)) {
20954
22030
  this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
20955
22031
  continue;
@@ -22511,7 +23587,7 @@
22511
23587
  continue;
22512
23588
  }
22513
23589
  else if (node.typ == previous?.typ && [exports.EnumToken.KeyFramesRuleNodeType, exports.EnumToken.RuleNodeType].includes(node.typ)) {
22514
- const intersect = diff(previous, node, reducer, options);
23590
+ const intersect = diff$1(previous, node, reducer, options);
22515
23591
  if (intersect != null) {
22516
23592
  if (intersect.node1.chi.length == 0) {
22517
23593
  ast.chi.splice(i--, 1);
@@ -22557,7 +23633,7 @@
22557
23633
  nodeIndex = i;
22558
23634
  }
22559
23635
  if (recursive && node != null && ('chi' in node)) {
22560
- if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType || !node.chi.some(n => n.typ == exports.EnumToken.DeclarationNodeType)) {
23636
+ if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType || !node.chi.some((n) => n.typ == exports.EnumToken.DeclarationNodeType)) {
22561
23637
  if (!(node.typ == exports.EnumToken.AtRuleNodeType && node.nam != 'font-face')) {
22562
23638
  doMinify(node, options, recursive, errors, nestingContent, context);
22563
23639
  }
@@ -22990,7 +24066,7 @@
22990
24066
  *
22991
24067
  * @private
22992
24068
  */
22993
- function diff(n1, n2, reducer, options = {}) {
24069
+ function diff$1(n1, n2, reducer, options = {}) {
22994
24070
  if (!('cache' in options)) {
22995
24071
  options.cache = new WeakMap();
22996
24072
  }
@@ -23388,6 +24464,9 @@
23388
24464
  //
23389
24465
  // return path;
23390
24466
  // }
24467
+ if (path === '') {
24468
+ return '';
24469
+ }
23391
24470
  let i = 0;
23392
24471
  let parts = [''];
23393
24472
  for (; i < path.length; i++) {
@@ -23412,6 +24491,12 @@
23412
24491
  * @private
23413
24492
  */
23414
24493
  function splitPath(result) {
24494
+ if (result.length == 0) {
24495
+ return { parts: [], i: 0 };
24496
+ }
24497
+ if (result === '/') {
24498
+ return { parts: ['/'], i: 0 };
24499
+ }
23415
24500
  const parts = [''];
23416
24501
  let i = 0;
23417
24502
  for (; i < result.length; i++) {
@@ -23455,6 +24540,21 @@
23455
24540
  }
23456
24541
  cwd ??= '';
23457
24542
  currentDirectory ??= '';
24543
+ if (currentDirectory !== '' && url.startsWith(currentDirectory + '/')) {
24544
+ return {
24545
+ absolute: url,
24546
+ relative: url.slice(currentDirectory.length + 1)
24547
+ };
24548
+ }
24549
+ if (currentDirectory === '' && cwd !== '' && url.startsWith(cwd == '/' ? cwd : cwd + '/')) {
24550
+ cwd = normalize(cwd);
24551
+ const absolute = normalize(url);
24552
+ const prefix = cwd == '/' ? cwd : cwd + '/';
24553
+ return {
24554
+ absolute,
24555
+ relative: absolute.startsWith(prefix) ? absolute.slice(prefix.length) : diff(absolute, cwd)
24556
+ };
24557
+ }
23458
24558
  if (matchUrl.test(currentDirectory)) {
23459
24559
  const path = new URL(url, currentDirectory).href;
23460
24560
  return {
@@ -23469,9 +24569,15 @@
23469
24569
  else if (currentDirectory.charAt(0) == '/') {
23470
24570
  result = dirname(currentDirectory) + '/' + url;
23471
24571
  }
23472
- let { parts, i } = splitPath(result);
23473
- const absolute = parts.join('/');
23474
- const { parts: dirs } = splitPath(cwd ?? currentDirectory);
24572
+ const absolute = normalize(result);
24573
+ return {
24574
+ absolute,
24575
+ relative: absolute === '' ? '' : diff(absolute, cwd ?? currentDirectory),
24576
+ };
24577
+ }
24578
+ function diff(path1, path2) {
24579
+ let { parts } = splitPath(path1);
24580
+ const { parts: dirs } = splitPath(path2);
23475
24581
  for (const p of dirs) {
23476
24582
  if (parts[0] == p) {
23477
24583
  parts.shift();
@@ -23480,21 +24586,69 @@
23480
24586
  parts.unshift('..');
23481
24587
  }
23482
24588
  }
23483
- return {
23484
- absolute,
23485
- relative: parts.join('/') + (i < result.length ? result.slice(i) : '')
23486
- };
24589
+ return parts.join('/');
24590
+ }
24591
+ function normalize(path) {
24592
+ let parts = [];
24593
+ let i = 0;
24594
+ for (; i < path.length; i++) {
24595
+ const chr = path.charAt(i);
24596
+ if (chr == '/') {
24597
+ if (parts.length == 0 || parts[parts.length - 1] !== '') {
24598
+ parts.push('');
24599
+ }
24600
+ }
24601
+ else if (chr == '?' || chr == '#') {
24602
+ break;
24603
+ }
24604
+ else {
24605
+ parts[parts.length - 1] += chr;
24606
+ }
24607
+ }
24608
+ let k = -1;
24609
+ while (++k < parts.length) {
24610
+ if (parts[k] == '.') {
24611
+ parts.splice(k--, 1);
24612
+ }
24613
+ else if (parts[k] == '..') {
24614
+ parts.splice(k - 1, 2);
24615
+ k -= 2;
24616
+ }
24617
+ }
24618
+ return (path.charAt(0) == '/' ? '/' : '') + parts.join('/');
23487
24619
  }
23488
24620
 
24621
+ /**
24622
+ * response type
24623
+ */
24624
+ exports.ResponseType = void 0;
24625
+ (function (ResponseType) {
24626
+ /**
24627
+ * return text
24628
+ */
24629
+ ResponseType[ResponseType["Text"] = 0] = "Text";
24630
+ /**
24631
+ * return a readable stream
24632
+ */
24633
+ ResponseType[ResponseType["ReadableStream"] = 1] = "ReadableStream";
24634
+ /**
24635
+ * return an arraybuffer
24636
+ */
24637
+ ResponseType[ResponseType["ArrayBuffer"] = 2] = "ArrayBuffer";
24638
+ })(exports.ResponseType || (exports.ResponseType = {}));
24639
+
23489
24640
  /**
23490
24641
  * default file or url loader
23491
24642
  * @param url
23492
24643
  * @param currentFile
23493
24644
  *
23494
- * @param asStream
24645
+ * @param responseType
23495
24646
  * @private
23496
24647
  */
23497
- async function load(url, currentFile = '.', asStream = false) {
24648
+ async function load(url, currentFile = '.', responseType = false) {
24649
+ if (typeof responseType == 'boolean') {
24650
+ responseType = responseType ? exports.ResponseType.ReadableStream : exports.ResponseType.Text;
24651
+ }
23498
24652
  let t;
23499
24653
  if (matchUrl.test(url)) {
23500
24654
  t = new URL(url);
@@ -23510,13 +24664,17 @@
23510
24664
  if (!response.ok) {
23511
24665
  throw new Error(`${response.status} ${response.statusText} ${response.url}`);
23512
24666
  }
23513
- return asStream ? response.body : await response.text();
24667
+ if (responseType == exports.ResponseType.ArrayBuffer) {
24668
+ return response.arrayBuffer();
24669
+ }
24670
+ return responseType == exports.ResponseType.ReadableStream ? response.body : await response.text();
23514
24671
  });
23515
24672
  }
23516
24673
  /**
23517
24674
  * render the ast tree
23518
24675
  * @param data
23519
24676
  * @param options
24677
+ * @param mapping
23520
24678
  *
23521
24679
  * Example:
23522
24680
  *
@@ -23541,12 +24699,12 @@
23541
24699
  * // }
23542
24700
  * ```
23543
24701
  */
23544
- function render(data, options = {}) {
24702
+ function render(data, options = {}, mapping) {
23545
24703
  return doRender(data, Object.assign(options, {
23546
24704
  resolve,
23547
24705
  dirname,
23548
24706
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
23549
- }));
24707
+ }), mapping);
23550
24708
  }
23551
24709
  /**
23552
24710
  * parse css file
@@ -23606,6 +24764,7 @@
23606
24764
  return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
23607
24765
  stream,
23608
24766
  buffer: '',
24767
+ offset: 0,
23609
24768
  position: { ind: 0, lin: 1, col: 1 },
23610
24769
  currentPosition: { ind: -1, lin: 1, col: 0 }
23611
24770
  }), Object.assign(options, {
@@ -23613,7 +24772,10 @@
23613
24772
  resolve,
23614
24773
  dirname,
23615
24774
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
23616
- }));
24775
+ })).then(result => {
24776
+ const { revMapping, ...res } = result;
24777
+ return res;
24778
+ });
23617
24779
  }
23618
24780
  /**
23619
24781
  * transform css file
@@ -23665,8 +24827,21 @@
23665
24827
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
23666
24828
  const startTime = performance.now();
23667
24829
  return parse(css, options).then((parseResult) => {
24830
+ let mapping = null;
24831
+ let importMapping = null;
24832
+ if (typeof options.module == 'number' && (options.module & exports.ModuleScopeEnumOptions.ICSS)) {
24833
+ mapping = parseResult.mapping;
24834
+ importMapping = parseResult.importMapping;
24835
+ }
24836
+ else if (typeof options.module == 'object' && typeof options.module.scoped == 'number' && (options.module.scoped & exports.ModuleScopeEnumOptions.ICSS)) {
24837
+ mapping = parseResult.mapping;
24838
+ importMapping = parseResult.importMapping;
24839
+ }
23668
24840
  // ast already expanded by parse
23669
- const rendered = render(parseResult.ast, { ...options, expandNestingRules: false });
24841
+ const rendered = render(parseResult.ast, {
24842
+ ...options,
24843
+ expandNestingRules: false
24844
+ }, mapping != null ? { mapping, importMapping } : null);
23670
24845
  return {
23671
24846
  ...parseResult,
23672
24847
  ...rendered,