@jesscss/less-parser 2.0.0-alpha.5 → 2.0.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,75 +1,4092 @@
1
- import { Lexer } from 'chevrotain';
2
- import { lessTokens, lessFragments } from './lessTokens.js';
3
- import { createLexerDefinition } from '@jesscss/css-parser';
4
- import { LessActionsParser } from './lessActionsParser.js';
5
- import { LessErrorMessageProvider } from './lessErrorMessageProvider.js';
6
- export * from './lessActionsParser.js';
7
- export * from './lessTokens.js';
8
- const errorMessageProvider = new LessErrorMessageProvider();
9
- export class Parser {
10
- lexer;
11
- /** @todo - return Jess AST as parser */
12
- parser;
13
- constructor(config = {}) {
14
- config = {
15
- errorMessageProvider,
16
- /**
17
- * Override this if you want a stricter Less/CSS parser.
18
- * @todo - Allow overriding when parsing a single rule.
19
- */
20
- looseMode: true,
21
- skipValidations: process.env.TEST !== 'true',
22
- ...config
23
- };
24
- const { lexer, T } = createLexerDefinition(lessFragments(), lessTokens());
25
- this.lexer = new Lexer(lexer, {
26
- ensureOptimizations: true,
27
- skipValidations: process.env.TEST !== 'true'
28
- });
29
- this.parser = new LessActionsParser(lexer, T, config);
30
- /** Not sure why this is necessary, but Less tests were a problem */
31
- this.parse = this.parse.bind(this);
32
- }
33
- parse(text, rule = 'stylesheet', ...args) {
34
- const parser = this.parser;
35
- const lexerResult = this.lexer.tokenize(text);
36
- const lexedTokens = lexerResult.tokens;
37
- // Reset warnings BEFORE setting input, in case input setter does something that affects warnings
38
- parser.warnings = [];
39
- parser.input = lexedTokens;
40
- const tree = parser[rule](...args);
41
- // Capture warnings immediately after parsing to ensure they're not lost
42
- const warnings = [...parser.warnings];
43
- if (parser.errors.length > 0) {
44
- const firstError = parser.errors[0];
45
- const firstToken = firstError?.token;
46
- }
47
- return { tree, lexerResult, errors: parser.errors, warnings };
48
- }
49
- /**
50
- * IDE helper: suggest next possible token types at `offset` using Chevrotain's
51
- * syntactic content assist. This is syntactic-only (not semantic completion).
52
- *
53
- * Note: content assist is significantly slower than normal parsing, so it
54
- * should be called on-demand (e.g. near the cursor).
55
- */
56
- suggest(text, init) {
57
- const { offset, rule = 'stylesheet' } = init;
58
- const prefix = text.slice(0, Math.max(0, offset));
59
- const lexerResult = this.lexer.tokenize(prefix);
60
- const tokens = lexerResult.tokens;
61
- try {
62
- const paths = this.parser.computeContentAssist(rule, tokens);
63
- return paths.map(p => ({
64
- nextTokenType: p.nextTokenType.name,
65
- nextTokenLabel: p.nextTokenType.LABEL,
66
- ruleStack: p.ruleStack,
67
- occurrenceStack: p.occurrenceStack
68
- }));
69
- }
70
- catch {
71
- return [];
72
- }
73
- }
1
+ import { CssRecursiveParser, LexerType, SKIPPED_LABEL, createLexerDefinition, groupCapture, productions, rawCssFragments, rawCssTokens } from "@jesscss/css-parser";
2
+ import { AMPERSAND_TEMPLATE_CONTENTS_REGEX, Ampersand, Any, AtRule, AttributeSelector, BasicSelector, Block, Bool, Call, Collection, Combinator, ComplexSelector, CompoundSelector, Condition, Declaration, DefaultGuard, Dimension, Expression, Extend, INTERPOLATION_PLACEHOLDER, Interpolated, InterpolatedSelector, Keyword, List, Mixin, N, Negative, Nil, Node, Num, Operation, Paren, QueryCondition, Quoted, Reference, Rest, Rules, Ruleset, SelectorCapture, SelectorList, Sequence, StyleImport, Url, VarDeclaration, isNode, shouldOperateWithMathFrames } from "@jesscss/core";
3
+ import { Lexer, NoViableAltException, tokenMatcher } from "chevrotain";
4
+ import { all } from "known-css-properties";
5
+ //#region \0rolldown/runtime.js
6
+ var __defProp = Object.defineProperty;
7
+ var __exportAll = (all, no_symbols) => {
8
+ let target = {};
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
14
+ return target;
15
+ };
16
+ //#endregion
17
+ //#region src/lessTokens.ts
18
+ function $preBuildFragments() {
19
+ const fragments = rawCssFragments().map((f) => [...f]);
20
+ fragments.unshift(["lineComment", "\\/\\/[^\\n\\r]*"]);
21
+ fragments.push(["interpolated", "[@$]\\{(?:{{nmchar}}*)\\}"]);
22
+ return fragments;
74
23
  }
24
+ function $preBuildTokens() {
25
+ const tokens = rawCssTokens();
26
+ /**
27
+ * Keyed by what to insert after
28
+ *
29
+ * @todo - Move merge utility to css-parser
30
+ */
31
+ const merges = {
32
+ Assign: [{
33
+ name: "Ellipsis",
34
+ pattern: /\.\.\./,
35
+ categories: ["BlockMarker"]
36
+ }, (
37
+ /**
38
+ * Less's historical parser unfortunately allows
39
+ * at-keywords that are not valid in CSS. One is
40
+ * that Less allows at-keywords to begin with numbers.
41
+ * Another is that it allows an at-rule that only
42
+ * contains a single dash. So we capture this as
43
+ * a separate token.
44
+ *
45
+ * We also do this later in the token stack so that we
46
+ * don't accidentally grab something like
47
+ * @-webkit-keyframes while looking for @-.
48
+ */
49
+ {
50
+ name: "AtKeywordLessExtension",
51
+ pattern: "@(?:-|\\d(?:{{nmchar}})*)",
52
+ categories: ["BlockMarker", "AtName"]
53
+ })],
54
+ PlainIdent: [
55
+ {
56
+ name: "Interpolated",
57
+ pattern: LexerType.NA
58
+ },
59
+ {
60
+ name: "LineComment",
61
+ pattern: "{{lineComment}}",
62
+ label: SKIPPED_LABEL
63
+ },
64
+ {
65
+ name: "PlusAssign",
66
+ pattern: "\\+{{whitespace}}*:",
67
+ categories: ["BlockMarker", "Assign"]
68
+ },
69
+ {
70
+ name: "UnderscoreAssign",
71
+ pattern: "\\+{{whitespace}}*_{{whitespace}}*:",
72
+ categories: ["BlockMarker", "Assign"]
73
+ },
74
+ {
75
+ name: "AnonMixinStart",
76
+ pattern: /[.#]\(/,
77
+ categories: ["BlockMarker"]
78
+ },
79
+ {
80
+ name: "GtEqAlias",
81
+ pattern: /=>/,
82
+ categories: ["CompareOperator"]
83
+ },
84
+ {
85
+ name: "LtEqAlias",
86
+ pattern: /=</,
87
+ categories: ["CompareOperator"]
88
+ },
89
+ {
90
+ name: "Extend",
91
+ pattern: /:extend\(/,
92
+ categories: ["BlockMarker"]
93
+ },
94
+ {
95
+ name: "VarOrProp",
96
+ pattern: LexerType.NA
97
+ },
98
+ {
99
+ name: "NestedReference",
100
+ pattern: ["([@$]+{{ident}}?){2,}", groupCapture],
101
+ start_chars_hint: ["@", "$"],
102
+ categories: ["VarOrProp"],
103
+ line_breaks: true
104
+ },
105
+ {
106
+ name: "PropertyReference",
107
+ pattern: "\\${{ident}}",
108
+ categories: ["VarOrProp"]
109
+ },
110
+ (
111
+ /** Can be used in unit function or mod operation */
112
+ {
113
+ name: "Percent",
114
+ pattern: /%/
115
+ }),
116
+ {
117
+ name: "DefaultGuardIdent",
118
+ pattern: /default/,
119
+ longer_alt: "PlainIdent",
120
+ categories: ["Ident"]
121
+ },
122
+ {
123
+ name: "DefaultGuardFunc",
124
+ pattern: /default(?:\(\))/
125
+ }
126
+ ],
127
+ Ampersand: [
128
+ {
129
+ name: "AmpersandExtend",
130
+ pattern: /&:extend\(/,
131
+ categories: ["BlockMarker"]
132
+ },
133
+ {
134
+ name: "AmpersandLParen",
135
+ pattern: /&\(/,
136
+ push_mode: "AmpersandTemplate",
137
+ categories: [
138
+ "Selector",
139
+ "NestedRuleStart",
140
+ "BlockMarker"
141
+ ]
142
+ },
143
+ {
144
+ name: "AllFlag",
145
+ pattern: /!all/,
146
+ categories: ["BlockMarker"]
147
+ }
148
+ ],
149
+ UrlStart: [
150
+ (
151
+ /**
152
+ * Keywords that we don't identify as idents
153
+ * should be manually added to other places where an ident is valid.
154
+ */
155
+ {
156
+ name: "When",
157
+ pattern: /when/i,
158
+ longer_alt: "PlainIdent",
159
+ categories: ["BlockMarker"]
160
+ }),
161
+ {
162
+ name: "FormatFunction",
163
+ pattern: /%\(/,
164
+ categories: ["BlockMarker", "FunctionStart"]
165
+ },
166
+ {
167
+ name: "IfFunction",
168
+ pattern: /if\(/,
169
+ categories: ["BlockMarker", "FunctionStart"]
170
+ },
171
+ {
172
+ name: "BooleanFunction",
173
+ pattern: /boolean\(/,
174
+ categories: ["BlockMarker", "FunctionStart"]
175
+ },
176
+ {
177
+ name: "JavaScript",
178
+ pattern: /~?`[^`]*`/,
179
+ line_breaks: true
180
+ }
181
+ ],
182
+ Signed: [
183
+ {
184
+ name: "InterpolatedIdent",
185
+ pattern: "(?:{{ident}}|-)?{{interpolated}}(?:{{interpolated}}|{{nmchar}})*",
186
+ categories: [
187
+ "Interpolated",
188
+ "Selector",
189
+ "Ident"
190
+ ]
191
+ },
192
+ {
193
+ name: "InterpolatedCustomProperty",
194
+ pattern: "--{{ident}}?{{interpolated}}(?:{{interpolated}}|{{nmchar}})*",
195
+ categories: ["Interpolated"]
196
+ },
197
+ (
198
+ /**
199
+ * Unfortunately, there's grammatical ambiguity between
200
+ * interpolated props and a naked interpolated selector name,
201
+ * making this awkward token necessary.
202
+ */
203
+ {
204
+ name: "InterpolatedSelector",
205
+ pattern: ["[.#]{{ident}}?{{interpolated}}(?:{{interpolated}}|{{nmchar}})*", groupCapture],
206
+ categories: ["Interpolated", "Selector"],
207
+ start_chars_hint: [".", "#"],
208
+ line_breaks: true
209
+ })
210
+ ]
211
+ };
212
+ let defaultTokens = tokens.modes.Default.slice();
213
+ let tokenLength = defaultTokens.length;
214
+ for (let i = 0; i < tokenLength; i++) {
215
+ let token = defaultTokens[i];
216
+ const { name } = token;
217
+ const copyToken = () => {
218
+ token = structuredClone(token);
219
+ };
220
+ let alterations = true;
221
+ switch (name) {
222
+ case "Ampersand":
223
+ copyToken();
224
+ /**
225
+ * Captures not just ampersands, but "ampersand merges", where
226
+ * the intent of the author was to merge the parent selector with a token
227
+ * suffix or prefix.
228
+ *
229
+ * e.g.
230
+ * 1. &-foo
231
+ * 2. &(foo)
232
+ * 3. &1
233
+ * 4. .foo-&
234
+ */
235
+ token.pattern = "(?:[.#](?:{{ident}}-)?&|&){{nmchar}}*";
236
+ token.start_chars_hint = [
237
+ "&",
238
+ ".",
239
+ "#"
240
+ ];
241
+ break;
242
+ case "DotName":
243
+ case "HashName":
244
+ copyToken();
245
+ token.longer_alt = "Ampersand";
246
+ break;
247
+ case "Divide":
248
+ copyToken();
249
+ token.pattern = /\.?\//;
250
+ break;
251
+ case "SingleQuoteStart":
252
+ copyToken();
253
+ token.pattern = /~?'/;
254
+ break;
255
+ case "DoubleQuoteStart":
256
+ copyToken();
257
+ token.pattern = /~?"/;
258
+ break;
259
+ default: alterations = false;
260
+ }
261
+ if (alterations) defaultTokens[i] = token;
262
+ const merge = merges[name];
263
+ if (merge) {
264
+ /** Insert after current token */
265
+ defaultTokens = defaultTokens.slice(0, i + 1).concat(merge, defaultTokens.slice(i + 1));
266
+ tokens.modes.Default = defaultTokens;
267
+ const mergeLength = merge.length;
268
+ tokenLength += mergeLength;
269
+ i += mergeLength;
270
+ }
271
+ }
272
+ tokens.modes.AmpersandTemplate = [
273
+ {
274
+ name: "AmpersandTemplateEnd",
275
+ pattern: /\)/,
276
+ pop_mode: true,
277
+ categories: ["FunctionLikeEnd"]
278
+ },
279
+ {
280
+ name: "AmpersandTemplateContents",
281
+ pattern: AMPERSAND_TEMPLATE_CONTENTS_REGEX,
282
+ categories: ["Selector"]
283
+ },
284
+ "SingleQuoteStart",
285
+ "DoubleQuoteStart",
286
+ "WS"
287
+ ];
288
+ return tokens;
289
+ }
290
+ const Fragments = $preBuildFragments();
291
+ const Tokens = $preBuildTokens();
292
+ const lessFragments = () => Fragments;
293
+ const lessTokens = () => Tokens;
294
+ //#endregion
295
+ //#region src/utils.ts
296
+ const INTERPOLATION_REGEX = /([$@]){([^}]+)}/g;
297
+ const createInterpolatedReference$4 = (prefix, varName, location, context) => {
298
+ const isProperty = prefix === "$";
299
+ return new Reference({ key: isProperty ? new Quoted(varName, { quote: "'" }, location, context) : varName }, {
300
+ type: isProperty ? "property" : "variable",
301
+ role: "ident"
302
+ }, location, context);
303
+ };
304
+ const getInterpolatedOrString = (name, location, context) => {
305
+ const matches = [];
306
+ INTERPOLATION_REGEX.lastIndex = 0;
307
+ let result;
308
+ while ((result = INTERPOLATION_REGEX.exec(name)) !== null) {
309
+ const [fullMatch, prefix, varName] = result;
310
+ if (varName && prefix) matches.push({
311
+ fullMatch,
312
+ prefix,
313
+ varName,
314
+ index: result.index
315
+ });
316
+ }
317
+ if (matches.length > 0) {
318
+ let source = name;
319
+ const replacements = [];
320
+ let offset = 0;
321
+ for (let i = 0; i < matches.length; i++) {
322
+ const match = matches[i];
323
+ const adjustedIndex = match.index - offset;
324
+ const beforeMatch = source.substring(0, adjustedIndex);
325
+ const afterMatch = source.substring(adjustedIndex + match.fullMatch.length);
326
+ source = beforeMatch + INTERPOLATION_PLACEHOLDER + afterMatch;
327
+ offset += match.fullMatch.length - INTERPOLATION_PLACEHOLDER.length;
328
+ const ref = createInterpolatedReference$4(match.prefix, match.varName, location, context);
329
+ replacements.push(ref);
330
+ }
331
+ return new Interpolated({
332
+ source,
333
+ replacements
334
+ }, { role: "ident" }, location, context);
335
+ }
336
+ const atPos = name.indexOf("@", 1);
337
+ const dollarPos = name.indexOf("$", 1);
338
+ if (atPos === -1 && dollarPos === -1) if (name.startsWith("@") || name.startsWith("$")) return name.slice(1);
339
+ else return name;
340
+ const nextPos = atPos !== -1 ? atPos : dollarPos;
341
+ const start = name.slice(1, nextPos);
342
+ const end = name.slice(nextPos);
343
+ const type = end.startsWith("@") ? "variable" : "property";
344
+ const endResult = getInterpolatedOrString(end, location, context);
345
+ if (typeof endResult === "string") {
346
+ const endKey = type === "property" ? new Quoted(endResult, { quote: "'" }, location, context) : endResult;
347
+ return new Interpolated({
348
+ source: start + INTERPOLATION_PLACEHOLDER,
349
+ replacements: [new Reference({ key: endKey }, {
350
+ type,
351
+ role: "ident"
352
+ }, location, context)]
353
+ }, { role: "ident" });
354
+ } else
355
+ /**
356
+ * endResult is already an Interpolated node, so we need to handle this
357
+ * differently.
358
+ *
359
+ * @todo - test deep nesting
360
+ */
361
+ return new Interpolated({
362
+ source: start + INTERPOLATION_PLACEHOLDER,
363
+ replacements: [endResult]
364
+ }, { role: "ident" });
365
+ };
366
+ //#endregion
367
+ //#region src/productions/root.ts
368
+ const cssMain = productions.main;
369
+ const cssDeclaration = productions.declaration;
370
+ productions.mediaTypeQuery;
371
+ function getParenFrames$2(ctx) {
372
+ return ctx?.parenFrames ?? [];
373
+ }
374
+ function getCalcFrames(ctx) {
375
+ return ctx?.calcFrames ?? 0;
376
+ }
377
+ function guardContainsDefaultCall(node) {
378
+ if (!node) return false;
379
+ const isNodeLike = (value) => {
380
+ return Boolean(value && typeof value === "object" && "type" in value && typeof value.type === "string" && "valueOf" in value && typeof value.valueOf === "function");
381
+ };
382
+ const queue = [node];
383
+ const seen = /* @__PURE__ */ new Set();
384
+ while (queue.length > 0) {
385
+ const current = queue.shift();
386
+ if (!current || seen.has(current) || !isNodeLike(current)) continue;
387
+ seen.add(current);
388
+ if (current.type === "DefaultGuard") return true;
389
+ if (isNode(current, N.Call)) {
390
+ const callName = current.name;
391
+ const callNameStr = String(typeof callName === "object" && callName !== null && "valueOf" in callName ? callName.valueOf() : callName ?? "");
392
+ if (callNameStr === "default" || callNameStr === "??") return true;
393
+ if (callName instanceof Reference) {
394
+ const key = callName.key;
395
+ const keyStr = String(typeof key === "object" && key !== null && "valueOf" in key ? key.valueOf() : key ?? "");
396
+ if (keyStr === "default" || keyStr === "??") return true;
397
+ }
398
+ }
399
+ if ("data" in current) {
400
+ const value = current.data;
401
+ if (Array.isArray(value)) queue.push(...value);
402
+ else if (value && typeof value === "object") queue.push(...Object.values(value));
403
+ }
404
+ }
405
+ return false;
406
+ }
407
+ function loc(node) {
408
+ const location = node.location;
409
+ return location.length === 6 ? location : void 0;
410
+ }
411
+ function wrapOuterExpressionIfNeeded(node, ctx) {
412
+ if (!this.wrapOuterExpressions) return node;
413
+ if (!ctx?.wrapInExpression) return node;
414
+ if (node instanceof Expression) return node;
415
+ if (isNode(node, N.Operation)) {
416
+ const left = node.left;
417
+ const op = node.get("operator");
418
+ const right = node.right;
419
+ if (shouldOperateWithMathFrames({
420
+ mathMode: this.mathMode ?? "parens-division",
421
+ parenFrames: getParenFrames$2(ctx),
422
+ calcFrames: getCalcFrames(ctx)
423
+ }, op, left, right)) return new Expression(node, { parens: true }, loc(node), this.context);
424
+ }
425
+ return node;
426
+ }
427
+ function isEscapedString($, T) {
428
+ const next = $.LA(1);
429
+ return next.image.startsWith("~") && ($.matchToken(next, T.QuoteStart) || $.matchToken(next, T.DoubleQuoteStart) || $.matchToken(next, T.SingleQuoteStart));
430
+ }
431
+ function startsLessMediaQueryReference($, T) {
432
+ if ($.isType(T.AtName) || $.isType(T.PropertyReference) || $.isType(T.NestedReference) || $.isType(T.DotName) || $.isType(T.HashName) || $.isType(T.InterpolatedIdent) || $.isType(T.InterpolatedSelector)) return true;
433
+ if (!$.isType(T.ColorIdentStart)) return false;
434
+ const tt2 = $.LA(2).tokenType;
435
+ return tt2 === T.Gt || tt2 === T.DotName || tt2 === T.HashName || tt2 === T.InterpolatedSelector || $.noSep(1) && (tt2 === T.LParen || tt2 === T.LSquare || tt2 === T.HashName || tt2 === T.DotName);
436
+ }
437
+ function startsCustomValue($, T) {
438
+ return $.isType(T.LParen) || $.isType(T.FunctionStart) || $.isType(T.FunctionalPseudoClass) || $.isType(T.LSquare) || $.isType(T.LCurly) || $.isType(T.SingleQuoteStart) || $.isType(T.DoubleQuoteStart) || $.isType(T.Value) || $.isType(T.PlainIdent) || $.isType(T.AtKeyword) || $.isType(T.PropertyReference) || $.isType(T.CustomProperty) || $.isType(T.Dimension) || $.isType(T.Number) || $.isType(T.Color) || $.isType(T.UnicodeRange) || $.isType(T.Colon) || $.isType(T.Comma) || $.isType(T.Important) || $.isType(T.Unknown);
439
+ }
440
+ function isVariableLike($, T) {
441
+ let token = $.LA(2);
442
+ let isColon = token.tokenType === T.Colon;
443
+ let isParen = token.tokenType === T.LParen;
444
+ let postToken = $.LA(3);
445
+ if (!$.preSkippedTokenMap) return false;
446
+ if (!isColon && !isParen) return false;
447
+ if (isParen && $.matchToken($.LA(1), T.AtName) && $.LA(1).tokenType !== T.AtKeyword) {
448
+ if (postToken.tokenType === T.RParen) {
449
+ $.warnDeprecation("Using known at-rule names as variables is deprecated", $.LA(1), "at-rule-variable");
450
+ return true;
451
+ }
452
+ return false;
453
+ }
454
+ return !$.preSkippedTokenMap.has(token.startOffset) || isColon && $.preSkippedTokenMap.has(postToken.startOffset);
455
+ }
456
+ let interpolatedRegex$2 = /([$@]){([^}]+)}/g;
457
+ const createInterpolatedReference$3 = (prefix, value, location, context) => {
458
+ const isProperty = prefix === "$";
459
+ return new Reference({ key: isProperty ? new Quoted(value, { quote: "'" }, location, context) : value }, {
460
+ type: isProperty ? "property" : "variable",
461
+ role: "ident"
462
+ }, location, context);
463
+ };
464
+ const getInterpolated$2 = (name, location, context) => {
465
+ const replacements = [];
466
+ let result;
467
+ let source = name;
468
+ while (result = interpolatedRegex$2.exec(name)) {
469
+ const [match, propOrVar, value] = result;
470
+ source = source.replace(match, INTERPOLATION_PLACEHOLDER);
471
+ const reference = createInterpolatedReference$3(propOrVar, value, location, context);
472
+ replacements.push(reference);
473
+ }
474
+ return new Interpolated({
475
+ source,
476
+ replacements
477
+ }, { role: "ident" }, location, context);
478
+ };
479
+ const { isArray: isArray$1 } = Array;
480
+ /**
481
+ * Groups extends by target (using valueOf()) and flag.
482
+ * Returns an array of grouped Extend nodes where extends with the same target and flag
483
+ * are combined into a single Extend node with a SelectorList of all matching selectors.
484
+ *
485
+ * @todo Group complex selectors into selector lists
486
+ */
487
+ function groupExtendsByTargetAndFlag(extendNodes) {
488
+ const groups = /* @__PURE__ */ new Map();
489
+ for (const ext of extendNodes) {
490
+ let target = ext.target;
491
+ let flag = ext.get("flag") ?? 1;
492
+ const key = `${target.valueOf()}|${flag}`;
493
+ let group = groups.get(key);
494
+ if (!group) groups.set(key, ext);
495
+ else if (isArray$1(group)) group.push(ext);
496
+ else groups.set(key, [group, ext]);
497
+ }
498
+ return Array.from(groups.values());
499
+ }
500
+ /** Charset moved within `main` (explained in that rule) */
501
+ function stylesheet(T) {
502
+ const $ = this;
503
+ return (options = {}) => {
504
+ let context;
505
+ if (options.context) context = $.context = options.context;
506
+ else context = $.context;
507
+ let charset;
508
+ if (!$.looseMode) $.OPTION(() => {
509
+ charset = $.CONSUME(T.Charset);
510
+ });
511
+ let root = $.SUBRULE($.main, { ARGS: [{ isRoot: true }] });
512
+ if (charset && isNode(root, N.Rules)) {
513
+ let charsetLoc = $.getLocationInfo(charset);
514
+ let rootLoc = root.location;
515
+ root.setData([new Any(charset.image, { role: "charset" }, charsetLoc, context), ...root.value]);
516
+ rootLoc[0] = charsetLoc[0];
517
+ rootLoc[1] = charsetLoc[1];
518
+ rootLoc[2] = charsetLoc[2];
519
+ }
520
+ return root;
521
+ };
522
+ }
523
+ /**
524
+ * Starts with a colon, with these conditions
525
+ * 1. It is not preceded by a space or
526
+ * 2. If it is preceded by a space, then it is
527
+ * followed by a space.
528
+ */
529
+ function main(T) {
530
+ const $ = this;
531
+ return (ctx = {}) => {
532
+ const shouldTryQualifiedRuleInDeclarationList = () => {
533
+ const isSelectorLikeContinuation = (offset) => {
534
+ const tok = $.LA(offset);
535
+ return $.matchToken(tok, T.LCurly) || $.matchToken(tok, T.Comma) || $.matchToken(tok, T.Combinator) || $.matchToken(tok, T.LSquare) || $.matchToken(tok, T.Colon) || $.matchToken(tok, T.NthPseudoClass) || $.matchToken(tok, T.SelectorPseudoClass);
536
+ };
537
+ if (typeof $.shouldTryQualifiedRuleInDeclarationList === "function") return $.shouldTryQualifiedRuleInDeclarationList();
538
+ if (!$.isTypeAt(1, T.Ident)) return true;
539
+ if (!$.isTypeAt(2, T.Assign)) return true;
540
+ if ($.hasWS(2)) return false;
541
+ const tt3 = $.LA(3).tokenType;
542
+ if (tt3 === T.Colon || tt3 === T.NthPseudoClass || tt3 === T.SelectorPseudoClass || $.matchToken($.LA(3), T.FunctionStart)) return true;
543
+ if (!$.matchToken($.LA(3), T.Ident)) return false;
544
+ return isSelectorLikeContinuation(4);
545
+ };
546
+ const isMixinOrQualifiedStart = () => {
547
+ const next = $.LA(1).tokenType;
548
+ return next === T.DotName || next === T.HashName || next === T.ColorIdentStart;
549
+ };
550
+ const isCustomPropertyStart = () => $.isType(T.InterpolatedCustomProperty) || $.isType(T.CustomProperty);
551
+ const isAtRuleStart = () => $.matchToken($.LA(1), T.AtName);
552
+ const shouldTryQualifiedRule = () => !isCustomPropertyStart() && !isMixinOrQualifiedStart() && !isAtRuleStart() && shouldTryQualifiedRuleInDeclarationList();
553
+ const ruleAlt = (ctx = {}) => {
554
+ let isVariable = isVariableLike($, T);
555
+ return [
556
+ { ALT: () => $.SUBRULE($.functionCall, { ARGS: [ctx] }) },
557
+ { ALT: () => $.SUBRULE2($.ampersandExtend, { ARGS: [ctx] }) },
558
+ {
559
+ GATE: isMixinOrQualifiedStart,
560
+ ALT: () => $.SUBRULE3($.mixinOrQualifiedRule, { ARGS: [ctx] })
561
+ },
562
+ {
563
+ GATE: () => isVariable,
564
+ ALT: () => $.SUBRULE4($.varDeclarationOrCall, { ARGS: [ctx] })
565
+ },
566
+ {
567
+ GATE: () => !isVariable && isAtRuleStart(),
568
+ ALT: () => $.SUBRULE5($.atRule, { ARGS: [ctx] })
569
+ },
570
+ {
571
+ GATE: isCustomPropertyStart,
572
+ ALT: () => $.SUBRULE7($.declaration, { ARGS: [ctx] })
573
+ },
574
+ {
575
+ GATE: shouldTryQualifiedRule,
576
+ ALT: () => $.SUBRULE6($.qualifiedRule, { ARGS: [ctx] })
577
+ },
578
+ (
579
+ /**
580
+ * Historically, Less allows `@charset` anywhere,
581
+ * to avoid outputting it in the wrong place.
582
+ * Ideally, this would result in an error if, say,
583
+ * the `@charset` was defined at the bottom of the file,
584
+ * but that wasn't the solution made.
585
+ * @see https://github.com/less/less.js/issues/2126
586
+ */
587
+ {
588
+ GATE: () => $.looseMode,
589
+ ALT: () => $.CONSUME(T.Charset)
590
+ }),
591
+ { ALT: () => $.CONSUME(T.Semi) }
592
+ ];
593
+ };
594
+ let RECORDING_PHASE = $.RECORDING_PHASE;
595
+ let context;
596
+ let rules;
597
+ if (!RECORDING_PHASE) {
598
+ context = $.context;
599
+ rules = [];
600
+ }
601
+ let requiredSemi = false;
602
+ let lastRule;
603
+ /**
604
+ * In this production rule, semi-colons are not required
605
+ * but this is repurposed by declarationList and by Less / Sass,
606
+ * so that's why this gate is here.
607
+ */
608
+ $.MANY({
609
+ GATE: () => {
610
+ const next = $.LA(1);
611
+ if ($.isType(T.RCurly) || next.tokenType.name === "EOF") return false;
612
+ return !requiredSemi || requiredSemi && ($.isType(T.Semi) || $.isTypeAt(0, T.Semi));
613
+ },
614
+ DEF: () => {
615
+ const localAlt = ruleAlt(ctx);
616
+ let value = $.OR(localAlt);
617
+ if (!RECORDING_PHASE) {
618
+ /** @todo - When do we not have a value? */
619
+ if (value) if (!(value instanceof Node)) {
620
+ /** This is a semi-colon or charset token */
621
+ let tok = value;
622
+ if (tok.image.includes("@charset")) rules.push(new Any(tok.image, { role: "charset" }, $.getLocationInfo(tok), context));
623
+ else if (lastRule) lastRule.options.semi = true;
624
+ else rules.push(new Any(";", { role: "semi" }, $.getLocationInfo($.LA(1)), context));
625
+ } else {
626
+ requiredSemi = !!value.requiredSemi;
627
+ rules.push(value);
628
+ lastRule = value;
629
+ }
630
+ }
631
+ }
632
+ });
633
+ if (RECORDING_PHASE) return;
634
+ if (ctx.extendNodes && ctx.extendNodes.length > 0) {
635
+ const filteredRules = rules.filter((r) => !(r instanceof Nil));
636
+ rules = [...ctx.extendNodes, ...filteredRules];
637
+ ctx.extendNodes = void 0;
638
+ }
639
+ let returnNode = $.getRulesWithComments(rules, $.getLocationInfo($.LA(1)));
640
+ return $.wrap(returnNode, true);
641
+ };
642
+ }
643
+ function declarationList(T) {
644
+ const $ = this;
645
+ return (ctx = {}) => {
646
+ const shouldTryQualifiedRuleInDeclarationList = () => {
647
+ const isSelectorLikeContinuation = (offset) => {
648
+ const tok = $.LA(offset);
649
+ return $.matchToken(tok, T.LCurly) || $.matchToken(tok, T.Comma) || $.matchToken(tok, T.Combinator) || $.matchToken(tok, T.LSquare) || $.matchToken(tok, T.Colon) || $.matchToken(tok, T.NthPseudoClass) || $.matchToken(tok, T.SelectorPseudoClass);
650
+ };
651
+ if (typeof $.shouldTryQualifiedRuleInDeclarationList === "function") return $.shouldTryQualifiedRuleInDeclarationList();
652
+ if (!$.isTypeAt(1, T.Ident)) return true;
653
+ if (!$.isTypeAt(2, T.Assign)) return true;
654
+ if ($.hasWS(2)) return false;
655
+ const tt3 = $.LA(3).tokenType;
656
+ if (tt3 === T.Colon || tt3 === T.NthPseudoClass || tt3 === T.SelectorPseudoClass || $.matchToken($.LA(3), T.FunctionStart)) return true;
657
+ if (!$.matchToken($.LA(3), T.Ident)) return false;
658
+ return isSelectorLikeContinuation(4);
659
+ };
660
+ const isMixinOrQualifiedStart = () => {
661
+ const next = $.LA(1).tokenType;
662
+ return next === T.DotName || next === T.HashName || next === T.ColorIdentStart;
663
+ };
664
+ const isCustomPropertyStart = () => $.isType(T.InterpolatedCustomProperty) || $.isType(T.CustomProperty);
665
+ const isAtRuleStart = () => $.matchToken($.LA(1), T.AtName);
666
+ const shouldTryQualifiedRule = () => !isCustomPropertyStart() && !isMixinOrQualifiedStart() && !isAtRuleStart() && shouldTryQualifiedRuleInDeclarationList();
667
+ const ruleAlt = (ctx = {}) => {
668
+ const isVariable = isVariableLike($, T);
669
+ return [
670
+ {
671
+ GATE: isMixinOrQualifiedStart,
672
+ ALT: () => {
673
+ return $.SUBRULE($.mixinOrQualifiedRule, { ARGS: [{
674
+ ...ctx,
675
+ inner: true
676
+ }] });
677
+ }
678
+ },
679
+ {
680
+ GATE: () => isVariable,
681
+ ALT: () => $.SUBRULE2($.varDeclarationOrCall, { ARGS: [ctx] })
682
+ },
683
+ {
684
+ GATE: () => !isVariable && isAtRuleStart(),
685
+ ALT: () => $.SUBRULE3($.innerAtRule, { ARGS: [ctx] })
686
+ },
687
+ { ALT: () => $.SUBRULE4($.ampersandExtend, { ARGS: [ctx] }) },
688
+ {
689
+ GATE: () => $.check(T.FunctionStart),
690
+ ALT: () => {
691
+ const fnCall = $.SUBRULE5($.functionCall, { ARGS: [ctx] });
692
+ if (fnCall instanceof Call) fnCall.requiredSemi = false;
693
+ return fnCall;
694
+ }
695
+ },
696
+ {
697
+ GATE: isCustomPropertyStart,
698
+ ALT: () => $.SUBRULE8($.declaration, { ARGS: [ctx] })
699
+ },
700
+ {
701
+ GATE: shouldTryQualifiedRule,
702
+ ALT: () => {
703
+ return $.SUBRULE6($.qualifiedRule, { ARGS: [{
704
+ ...ctx,
705
+ inner: true
706
+ }] });
707
+ }
708
+ },
709
+ { ALT: () => {
710
+ return $.SUBRULE7($.declaration, { ARGS: [ctx] });
711
+ } },
712
+ { ALT: () => $.CONSUME(T.Semi) }
713
+ ];
714
+ };
715
+ return cssMain.call($, T, ruleAlt)(ctx);
716
+ };
717
+ }
718
+ function declaration(T) {
719
+ const $ = this;
720
+ return (ctx = {}) => {
721
+ const customPropertyAlt = (consumeName, occurrence) => ({ ALT: () => {
722
+ let nodes;
723
+ if (!$.RECORDING_PHASE) nodes = [];
724
+ const name = consumeName();
725
+ const assign = occurrence === 2 ? $.CONSUME2(T.Assign) : $.CONSUME3(T.Assign);
726
+ $.startRule();
727
+ while (startsCustomValue($, T)) {
728
+ const val = occurrence === 2 ? $.SUBRULE2($.customValue, { ARGS: [{
729
+ ...ctx,
730
+ inCustomPropertyValue: true
731
+ }] }) : $.SUBRULE3($.customValue, { ARGS: [{
732
+ ...ctx,
733
+ inCustomPropertyValue: true
734
+ }] });
735
+ if (!$.RECORDING_PHASE) nodes.push(val);
736
+ }
737
+ if (!$.RECORDING_PHASE) {
738
+ const location = $.endRule();
739
+ let nameNode;
740
+ const nameValue = name.image;
741
+ if (nameValue.includes("@") || nameValue.includes("$")) nameNode = getInterpolated$2(nameValue, $.getLocationInfo(name), $.context);
742
+ else nameNode = $.wrap(new Any(name.image, { role: "property" }, $.getLocationInfo(name), $.context), true);
743
+ const value = new Sequence(nodes, void 0, location, $.context);
744
+ return [
745
+ nameNode,
746
+ assign,
747
+ value
748
+ ];
749
+ }
750
+ } });
751
+ const ruleAlt = (ctx = {}) => [
752
+ { ALT: () => {
753
+ let name;
754
+ $.OR2([{ ALT: () => {
755
+ name = $.CONSUME(T.Ident);
756
+ } }, {
757
+ GATE: () => $.legacyMode,
758
+ ALT: () => name = $.CONSUME(T.LegacyPropIdent)
759
+ }]);
760
+ const assign = $.CONSUME(T.Assign);
761
+ let value;
762
+ if ($.looseMode) {
763
+ $.OPTION2({
764
+ GATE: () => !($.isType(T.Semi) || $.isType(T.RCurly)),
765
+ DEF: () => {
766
+ value = $.SUBRULE($.valueList, { ARGS: [ctx] });
767
+ }
768
+ });
769
+ if (!$.RECORDING_PHASE && !value) value = new Sequence([], void 0, void 0, $.context);
770
+ } else value = $.SUBRULE($.valueList, { ARGS: [ctx] });
771
+ let important;
772
+ $.OPTION(() => {
773
+ important = $.CONSUME(T.Important);
774
+ });
775
+ if (!$.RECORDING_PHASE) {
776
+ let nameNode;
777
+ const nameValue = name.image;
778
+ if (nameValue.includes("@") || nameValue.includes("$")) nameNode = getInterpolated$2(nameValue, $.getLocationInfo(name), $.context);
779
+ else nameNode = $.wrap(new Any(name.image, { role: "property" }, $.getLocationInfo(name), $.context), true);
780
+ return [
781
+ nameNode,
782
+ assign,
783
+ value,
784
+ important
785
+ ];
786
+ }
787
+ } },
788
+ customPropertyAlt(() => $.CONSUME(T.InterpolatedCustomProperty), 2),
789
+ customPropertyAlt(() => $.CONSUME(T.CustomProperty), 3)
790
+ ];
791
+ return cssDeclaration.call($, T, ruleAlt)(ctx);
792
+ };
793
+ }
794
+ function mediaInParens(T) {
795
+ const $ = this;
796
+ return (ctx = {}) => {
797
+ const RECORDING_PHASE = $.RECORDING_PHASE;
798
+ $.startRule();
799
+ $.CONSUME(T.LParen);
800
+ const node = $.OR([
801
+ {
802
+ GATE: () => $.startsMediaCondition(T),
803
+ ALT: () => $.SUBRULE($.mediaCondition, { ARGS: [ctx] })
804
+ },
805
+ {
806
+ GATE: () => isEscapedString($, T),
807
+ ALT: () => $.SUBRULE($.string, { ARGS: [ctx] })
808
+ },
809
+ {
810
+ GATE: () => $.isType(T.PropertyReference) || $.isType(T.NestedReference) || $.isType(T.AtName) || $.isType(T.HashName) || $.isType(T.DotName) || $.isType(T.ColorIdentStart) || $.isType(T.InterpolatedSelector),
811
+ ALT: () => $.SUBRULE2($.valueReference, { ARGS: [{
812
+ ...ctx,
813
+ requireAccessorsAfterMixinCall: true
814
+ }] })
815
+ },
816
+ { ALT: () => $.SUBRULE($.mediaFeature, { ARGS: [ctx] }) }
817
+ ]);
818
+ $.CONSUME(T.RParen);
819
+ if (RECORDING_PHASE) return;
820
+ const location = $.endRule();
821
+ return $.wrap(new Paren($.wrap(node, "both"), void 0, location, $.context));
822
+ };
823
+ }
824
+ function mediaQuery(T) {
825
+ const $ = this;
826
+ return (ctx = {}) => {
827
+ return $.OR2([
828
+ {
829
+ GATE: () => $.startsMediaCondition(T),
830
+ ALT: () => $.SUBRULE($.mediaConditionWithoutOr, { ARGS: [ctx] })
831
+ },
832
+ {
833
+ GATE: () => isEscapedString($, T),
834
+ ALT: () => $.SUBRULE($.lessMediaQueryFromString, { ARGS: [ctx] })
835
+ },
836
+ {
837
+ GATE: () => startsLessMediaQueryReference($, T),
838
+ ALT: () => $.SUBRULE2($.lessMediaQueryFromReference, { ARGS: [ctx] })
839
+ },
840
+ { ALT: () => $.SUBRULE7($.mediaTypeQuery, { ARGS: [ctx] }) }
841
+ ]);
842
+ };
843
+ }
844
+ function mediaCondition(T) {
845
+ const $ = this;
846
+ return (ctx = {}) => $.SUBRULE($.mediaConditionWithoutOr, { ARGS: [ctx] });
847
+ }
848
+ function lessMediaQueryFromString(T) {
849
+ const $ = this;
850
+ return (ctx = {}) => {
851
+ const first = $.SUBRULE($.string, { ARGS: [ctx] });
852
+ return $.SUBRULE($.lessMediaQueryTail, { ARGS: [{
853
+ ...ctx,
854
+ startValue: first
855
+ }] });
856
+ };
857
+ }
858
+ function lessMediaQueryFromReference(T) {
859
+ const $ = this;
860
+ return (ctx = {}) => {
861
+ const first = $.SUBRULE($.valueReference, { ARGS: [{
862
+ ...ctx,
863
+ requireAccessorsAfterMixinCall: true
864
+ }] });
865
+ return $.SUBRULE2($.lessMediaQueryTail, { ARGS: [{
866
+ ...ctx,
867
+ startValue: first
868
+ }] });
869
+ };
870
+ }
871
+ function lessMediaQueryTail(T) {
872
+ const $ = this;
873
+ return (ctx = {}) => {
874
+ const RECORDING_PHASE = $.RECORDING_PHASE;
875
+ $.startRule();
876
+ let nodes;
877
+ if (!RECORDING_PHASE) nodes = [ctx.startValue];
878
+ $.MANY({
879
+ GATE: () => $.isType(T.And),
880
+ DEF: () => {
881
+ const andToken = $.CONSUME(T.And);
882
+ const next = $.OR([
883
+ {
884
+ GATE: () => isEscapedString($, T),
885
+ ALT: () => $.SUBRULE2($.string, { ARGS: [ctx] })
886
+ },
887
+ {
888
+ GATE: () => startsLessMediaQueryReference($, T),
889
+ ALT: () => $.SUBRULE2($.valueReference, { ARGS: [{
890
+ ...ctx,
891
+ requireAccessorsAfterMixinCall: true
892
+ }] })
893
+ },
894
+ {
895
+ GATE: () => $.startsMediaCondition(T),
896
+ ALT: () => $.SUBRULE2($.mediaConditionWithoutOr, { ARGS: [ctx] })
897
+ },
898
+ { ALT: () => $.SUBRULE2($.mediaType, { ARGS: [ctx] }) }
899
+ ]);
900
+ if (!RECORDING_PHASE) {
901
+ nodes.push($.wrap(new Keyword(andToken.image, void 0, $.getLocationInfo(andToken), $.context), "both"));
902
+ nodes.push(next);
903
+ }
904
+ }
905
+ });
906
+ if (RECORDING_PHASE) return;
907
+ const location = $.endRule();
908
+ if (nodes.length === 1) return nodes[0];
909
+ return new QueryCondition(nodes, void 0, location, $.context);
910
+ };
911
+ }
912
+ function mediaConditionWithoutOr(T) {
913
+ const $ = this;
914
+ return (ctx = {}) => $.OR([{ ALT: () => $.SUBRULE($.mediaNot, { ARGS: [ctx] }) }, { ALT: () => {
915
+ const RECORDING_PHASE = $.RECORDING_PHASE;
916
+ $.startRule();
917
+ let nodes;
918
+ if (!RECORDING_PHASE) nodes = [];
919
+ const node = $.SUBRULE($.mediaInParens, { ARGS: [ctx] });
920
+ if (!RECORDING_PHASE) nodes.push(node);
921
+ $.MANY({
922
+ GATE: () => $.isType(T.And),
923
+ DEF: () => {
924
+ const rule = $.SUBRULE($.mediaAnd, { ARGS: [ctx] });
925
+ if (!RECORDING_PHASE) nodes.push(...rule);
926
+ }
927
+ });
928
+ if (RECORDING_PHASE) return;
929
+ if (nodes.length === 1) {
930
+ $.endRule();
931
+ return nodes[0];
932
+ }
933
+ return new QueryCondition(nodes, void 0, $.endRule(), $.context);
934
+ } }]);
935
+ }
936
+ function mediaFeature(T) {
937
+ const $ = this;
938
+ const createFeatureIdentNode = (token, role) => {
939
+ const location = $.getLocationInfo(token);
940
+ const resolved = getInterpolatedOrString(token.image, location, $.context);
941
+ if (typeof resolved === "string") return new Any(resolved, { role }, location, $.context);
942
+ return resolved;
943
+ };
944
+ return (ctx = {}) => $.OR([{
945
+ GATE: () => {
946
+ return $.isType(T.InterpolatedIdent) || $.isType(T.Ident);
947
+ },
948
+ ALT: () => {
949
+ const RECORDING_PHASE = $.RECORDING_PHASE;
950
+ $.startRule();
951
+ let rule;
952
+ const ident = $.LA(1).tokenType === T.InterpolatedIdent ? $.CONSUME(T.InterpolatedIdent) : $.CONSUME(T.Ident);
953
+ $.OPTION(() => {
954
+ rule = $.OR2([
955
+ { ALT: () => {
956
+ $.CONSUME(T.Colon);
957
+ const value = $.SUBRULE($.mfValue, { ARGS: [ctx] });
958
+ if (!RECORDING_PHASE) {
959
+ const location = $.endRule();
960
+ return $.wrap(new Declaration({
961
+ name: $.wrap(createFeatureIdentNode(ident, "property"), true),
962
+ value: $.wrap(value)
963
+ }, void 0, location, $.context), "both");
964
+ }
965
+ } },
966
+ {
967
+ GATE: () => ($.isTypeAt(1, T.MfLt) || $.isTypeAt(1, T.MfGt)) && ($.isTypeAt(2, T.Ident) || $.isTypeAt(2, T.InterpolatedIdent)),
968
+ ALT: () => {
969
+ const seq = $.SUBRULE($.mediaRange, { ARGS: [ctx] });
970
+ if (!RECORDING_PHASE) {
971
+ const [startOffset, startLine, startColumn] = $.endRule();
972
+ seq.value.unshift($.wrap(createFeatureIdentNode(ident, "ident"), true));
973
+ seq.location[0] = startOffset;
974
+ seq.location[1] = startLine;
975
+ seq.location[2] = startColumn;
976
+ return new QueryCondition(seq.value, void 0, seq.location, $.context);
977
+ }
978
+ return seq;
979
+ }
980
+ },
981
+ {
982
+ GATE: () => $.isTypeAt(1, T.MfLt) || $.isTypeAt(1, T.MfGt) || $.LA(1).tokenType === T.Eq,
983
+ ALT: () => {
984
+ const op = $.SUBRULE($.mfComparison, { ARGS: [ctx] });
985
+ const value = $.SUBRULE($.mfNonIdentifierValue, { ARGS: [ctx] });
986
+ if (!RECORDING_PHASE) {
987
+ const location = $.endRule();
988
+ return new QueryCondition([
989
+ $.wrap(createFeatureIdentNode(ident, "ident"), true),
990
+ $.wrap(new Any(op.image, { role: "operator" }, $.getLocationInfo(op), $.context), "both"),
991
+ value
992
+ ], void 0, location, $.context);
993
+ }
994
+ }
995
+ }
996
+ ]);
997
+ });
998
+ if (!RECORDING_PHASE && !rule) {
999
+ const location = $.endRule();
1000
+ const identNode = createFeatureIdentNode(ident, "ident");
1001
+ return $.wrap(new QueryCondition([identNode], void 0, location, $.context), "both");
1002
+ }
1003
+ return rule;
1004
+ }
1005
+ }, { ALT: () => {
1006
+ const RECORDING_PHASE = $.RECORDING_PHASE;
1007
+ $.startRule();
1008
+ const left = $.SUBRULE2($.mfNonIdentifierValue, { ARGS: [{ ...ctx }] });
1009
+ return $.OR3([{
1010
+ GATE: () => {
1011
+ const tt2 = $.LA(2).tokenType;
1012
+ if (!(($.isTypeAt(1, T.MfLt) || $.isTypeAt(1, T.MfGt) || $.LA(1).tokenType === T.Eq) && (tt2 === T.Ident || tt2 === T.InterpolatedIdent))) return false;
1013
+ if ($.isTypeAt(3, T.MfLt) || $.isTypeAt(3, T.MfGt)) return false;
1014
+ return true;
1015
+ },
1016
+ ALT: () => {
1017
+ const op = $.SUBRULE2($.mfComparison, { ARGS: [{ ...ctx }] });
1018
+ const value = $.LA(1).tokenType === T.Ident ? $.CONSUME2(T.Ident) : $.CONSUME2(T.InterpolatedIdent);
1019
+ if (!RECORDING_PHASE) {
1020
+ const location = $.endRule();
1021
+ return new QueryCondition([
1022
+ left,
1023
+ $.wrap(new Any(op.image, { role: "operator" }, $.getLocationInfo(op), $.context)),
1024
+ $.wrap(createFeatureIdentNode(value, "ident"), "both")
1025
+ ], void 0, location, $.context);
1026
+ }
1027
+ }
1028
+ }, { ALT: () => {
1029
+ const seq = $.SUBRULE2($.mediaRange, { ARGS: [{ ...ctx }] });
1030
+ if (!RECORDING_PHASE) {
1031
+ const [startOffset, startLine, startColumn] = $.endRule();
1032
+ seq.value.unshift(left);
1033
+ seq.location[0] = startOffset;
1034
+ seq.location[1] = startLine;
1035
+ seq.location[2] = startColumn;
1036
+ return new QueryCondition(seq.value, void 0, seq.location, $.context);
1037
+ }
1038
+ return seq;
1039
+ } }]);
1040
+ } }]);
1041
+ }
1042
+ function mfValue(T) {
1043
+ const $ = this;
1044
+ return (ctx = {}) => {
1045
+ /**
1046
+ * Like the original Less Parser, we're
1047
+ * going to allow any value expression,
1048
+ * and it's up to the Less author to know
1049
+ * if it's valid.
1050
+ */
1051
+ const exprCtx = {
1052
+ ...ctx,
1053
+ wrapInExpression: true
1054
+ };
1055
+ const node = $.SUBRULE($.expressionSum, { ARGS: [exprCtx] });
1056
+ return wrapOuterExpressionIfNeeded.call($, node, exprCtx);
1057
+ };
1058
+ }
1059
+ function mfNonIdentifierValue(T) {
1060
+ const $ = this;
1061
+ return (ctx = {}) => {
1062
+ return $.OR2([
1063
+ {
1064
+ GATE: () => {
1065
+ const next = $.LA(1);
1066
+ return next.tokenType === T.AtKeyword || next.tokenType === T.PropertyReference || next.tokenType === T.NestedReference;
1067
+ },
1068
+ ALT: () => $.SUBRULE($.valueReference, { ARGS: [{
1069
+ ...ctx,
1070
+ requireAccessorsAfterMixinCall: true
1071
+ }] })
1072
+ },
1073
+ { ALT: () => {
1074
+ $.startRule();
1075
+ let num1 = $.CONSUME(T.Number);
1076
+ let num2;
1077
+ $.OPTION(() => {
1078
+ $.CONSUME(T.Slash);
1079
+ num2 = $.CONSUME2(T.Number);
1080
+ });
1081
+ let location = $.endRule();
1082
+ let num1Node = $.wrap($.processValueToken(num1), "both");
1083
+ if (!num2) return num1Node;
1084
+ return new List([num1Node, $.wrap($.processValueToken(num2), "both")], { sep: "/" }, location, $.context);
1085
+ } },
1086
+ { ALT: () => {
1087
+ let dim = $.CONSUME(T.Dimension);
1088
+ return $.wrap($.processValueToken(dim), "both");
1089
+ } }
1090
+ ]);
1091
+ };
1092
+ }
1093
+ function wrappedDeclarationList(T) {
1094
+ const $ = this;
1095
+ return (ctx = {}) => {
1096
+ $.CONSUME(T.LCurly);
1097
+ let rules = $.SUBRULE($.declarationList, { ARGS: [ctx] });
1098
+ $.CONSUME(T.RCurly);
1099
+ return rules;
1100
+ };
1101
+ }
1102
+ function qualifiedRuleBody(T) {
1103
+ const $ = this;
1104
+ return (ctx = {}) => {
1105
+ let selector;
1106
+ let isSelectorList;
1107
+ selector = ctx.selector;
1108
+ isSelectorList = typeof ctx.isSelectorList === "boolean" ? ctx.isSelectorList : selector instanceof SelectorList;
1109
+ let guard;
1110
+ if (!isSelectorList) $.OPTION(() => {
1111
+ guard = $.SUBRULE($.guard, { ARGS: [ctx] });
1112
+ });
1113
+ $.CONSUME(T.LCurly);
1114
+ let savedExtendNodes;
1115
+ if (!$.RECORDING_PHASE) {
1116
+ savedExtendNodes = ctx.extendNodes ? [...ctx.extendNodes] : void 0;
1117
+ ctx.extendNodes = void 0;
1118
+ }
1119
+ let rules = $.SUBRULE2($.declarationList, { ARGS: [ctx] });
1120
+ let end = $.CONSUME(T.RCurly);
1121
+ if (!$.RECORDING_PHASE) {
1122
+ const newExtends = ctx.extendNodes;
1123
+ if (newExtends && newExtends.length) if (savedExtendNodes && savedExtendNodes.length > 0) ctx.extendNodes = [...savedExtendNodes, ...newExtends];
1124
+ else ctx.extendNodes = newExtends;
1125
+ else ctx.extendNodes = savedExtendNodes;
1126
+ let extend = ctx.extendNodes;
1127
+ if (extend?.length)
1128
+ /** If it's not a selector list, then our only extend does not need to be grouped */
1129
+ if (!isSelectorList) {
1130
+ /** For extends inside rulesets (not bubbled), selector should be undefined
1131
+ * so it defaults to ampersand and resolves to the ruleset's selector */
1132
+ for (let e of extend) e.setData("selector", void 0);
1133
+ rules.setData([...extend, ...rules.value]);
1134
+ ctx.extendNodes = void 0;
1135
+ } else {
1136
+ const selectorList = selector instanceof SelectorList ? selector : void 0;
1137
+ if (!selectorList) return;
1138
+ const selectorCount = selectorList.value.length;
1139
+ const extendCount = extend.length;
1140
+ let shouldBubble = false;
1141
+ if (extendCount < selectorCount) shouldBubble = true;
1142
+ else if (extendCount === selectorCount) {
1143
+ let finalExtends = groupExtendsByTargetAndFlag(extend);
1144
+ if (finalExtends.length === 1) {
1145
+ let extendNodes = finalExtends[0];
1146
+ let finalExtend = isArray$1(extendNodes) ? extendNodes[0] : extendNodes;
1147
+ finalExtend.setData("selector", void 0);
1148
+ rules.setData([finalExtend, ...rules.value]);
1149
+ ctx.extendNodes = void 0;
1150
+ } else shouldBubble = true;
1151
+ } else shouldBubble = true;
1152
+ if (shouldBubble) {}
1153
+ }
1154
+ let node = new Ruleset({
1155
+ selector,
1156
+ rules,
1157
+ guard
1158
+ }, void 0, void 0, $.context);
1159
+ let [startOffset, startLine, startColumn] = selector.location;
1160
+ let { endOffset, endLine, endColumn } = end;
1161
+ node._location = [
1162
+ startOffset,
1163
+ startLine,
1164
+ startColumn,
1165
+ endOffset,
1166
+ endLine,
1167
+ endColumn
1168
+ ];
1169
+ return node;
1170
+ }
1171
+ };
1172
+ }
1173
+ function qualifiedRule(T) {
1174
+ const $ = this;
1175
+ return (ctx = {}, altContext) => {
1176
+ let selectorAlt = altContext ?? ((ctx) => [{
1177
+ GATE: () => !ctx.inner,
1178
+ ALT: () => {
1179
+ let initialQualifiedRule = ctx.qualifiedRule;
1180
+ ctx.qualifiedRule = true;
1181
+ try {
1182
+ return $.SUBRULE($.selectorList, { ARGS: [ctx] });
1183
+ } finally {
1184
+ ctx.qualifiedRule = initialQualifiedRule;
1185
+ }
1186
+ }
1187
+ }, {
1188
+ GATE: () => !!ctx.inner,
1189
+ ALT: () => {
1190
+ let initialQualifiedRule = ctx.qualifiedRule;
1191
+ let initialFirstSelector = ctx.firstSelector;
1192
+ ctx.firstSelector = true;
1193
+ ctx.qualifiedRule = true;
1194
+ try {
1195
+ return $.SUBRULE2($.forgivingSelectorList, { ARGS: [ctx] });
1196
+ } finally {
1197
+ ctx.qualifiedRule = initialQualifiedRule;
1198
+ ctx.firstSelector = initialFirstSelector;
1199
+ }
1200
+ }
1201
+ }]);
1202
+ let savedExtendNodes = ctx.extendNodes ? [...ctx.extendNodes] : void 0;
1203
+ ctx.extendNodes = void 0;
1204
+ let selector = $.OR(selectorAlt(ctx));
1205
+ ctx.selector = selector;
1206
+ let thisExtendNodes = ctx.extendNodes ? [...ctx.extendNodes] : void 0;
1207
+ ctx.extendNodes = void 0;
1208
+ let rule = $.SUBRULE3($.qualifiedRuleBody, { ARGS: [ctx] });
1209
+ const bubblingExtends = ctx.extendNodes;
1210
+ ctx.extendNodes = thisExtendNodes;
1211
+ let parentExtendNodes = savedExtendNodes;
1212
+ if (ctx.extendNodes) {
1213
+ let qRuleset = rule;
1214
+ for (const extendNode of ctx.extendNodes) if (extendNode.selector === void 0 || extendNode.selector instanceof Ampersand) extendNode.setData("selector", selector);
1215
+ /** Prepend a rules block */
1216
+ rule = new Rules([...ctx.extendNodes, qRuleset]);
1217
+ if (qRuleset._location) rule._location = qRuleset._location;
1218
+ ctx.extendNodes = void 0;
1219
+ }
1220
+ if (bubblingExtends && bubblingExtends.length > 0) if (parentExtendNodes && parentExtendNodes.length > 0) ctx.extendNodes = [...parentExtendNodes, ...bubblingExtends];
1221
+ else ctx.extendNodes = bubblingExtends;
1222
+ else ctx.extendNodes = parentExtendNodes;
1223
+ return rule;
1224
+ };
1225
+ }
1226
+ /**
1227
+ * In order to not do any backtracking, anything with a class or id selector start
1228
+ * will end up here, and everything else will be shunted to the qualified rule.
1229
+ */
1230
+ function mixinOrQualifiedRule(T) {
1231
+ const $ = this;
1232
+ return (ctx = {}) => {
1233
+ const convertArgsForDefinition = (args) => {
1234
+ if (!args || !args.value.length) return;
1235
+ for (let i = 0; i < args.value.length; i++) {
1236
+ const node = args.value[i];
1237
+ const location = node.location && node.location.length > 0 ? node.location : void 0;
1238
+ if (node instanceof Any && node.role === "name") {
1239
+ const nameNode = new Any(node.valueOf(), {
1240
+ ...node.options,
1241
+ role: "property"
1242
+ }, node.location, $.context);
1243
+ args.setData(i, new VarDeclaration({
1244
+ name: nameNode,
1245
+ value: new Nil(void 0, void 0, location, $.context)
1246
+ }, { paramVar: true }, location, $.context));
1247
+ }
1248
+ }
1249
+ };
1250
+ const convertArgsForCall = (args) => {
1251
+ if (!args || !args.value.length) return;
1252
+ for (let i = 0; i < args.value.length; i++) {
1253
+ const node = args.value[i];
1254
+ const location = node.location && node.location.length > 0 ? node.location : void 0;
1255
+ if (node instanceof Any && node.role === "name") args.setData(i, new Reference({ key: node.valueOf() }, { type: "variable" }, location, $.context));
1256
+ else if (node instanceof Rest) {
1257
+ const restValue = node.get("value");
1258
+ if (typeof restValue === "string") args.setData(i, new Rest(new Reference({ key: restValue }, { type: "variable" }, location, $.context), void 0, location, $.context));
1259
+ }
1260
+ }
1261
+ };
1262
+ $.startRule();
1263
+ let selector = $.OR([{
1264
+ GATE: () => !ctx.inner,
1265
+ ALT: () => {
1266
+ let initialQualifiedRule = ctx.qualifiedRule;
1267
+ ctx.qualifiedRule = true;
1268
+ try {
1269
+ return $.SUBRULE($.selectorList, { ARGS: [ctx] });
1270
+ } finally {
1271
+ ctx.qualifiedRule = initialQualifiedRule;
1272
+ }
1273
+ }
1274
+ }, {
1275
+ GATE: () => !!ctx.inner,
1276
+ ALT: () => {
1277
+ let initialQualifiedRule = ctx.qualifiedRule;
1278
+ let initialFirstSelector = ctx.firstSelector;
1279
+ ctx.firstSelector = true;
1280
+ ctx.qualifiedRule = true;
1281
+ try {
1282
+ return $.SUBRULE2($.forgivingSelectorList, { ARGS: [ctx] });
1283
+ } finally {
1284
+ ctx.qualifiedRule = initialQualifiedRule;
1285
+ ctx.firstSelector = initialFirstSelector;
1286
+ }
1287
+ }
1288
+ }]);
1289
+ let isSelectorList = selector instanceof SelectorList;
1290
+ let guard;
1291
+ let args;
1292
+ let important;
1293
+ const createMixinCall = (location) => {
1294
+ let leftNode;
1295
+ if (!isSelectorList && (selector instanceof CompoundSelector || selector instanceof ComplexSelector || selector instanceof BasicSelector)) leftNode = new Reference({ key: selector }, {
1296
+ type: "mixin-ruleset",
1297
+ role: "name"
1298
+ }, void 0, $.context);
1299
+ else for (let s of selector.nodes()) if (s instanceof BasicSelector) leftNode = new Reference({
1300
+ target: leftNode instanceof Reference ? leftNode : leftNode instanceof Call ? leftNode : void 0,
1301
+ key: s.valueOf()
1302
+ }, {
1303
+ type: "mixin-ruleset",
1304
+ role: "name"
1305
+ }, void 0, $.context);
1306
+ /** Finally, pass this reference into a call */
1307
+ leftNode = new Call({
1308
+ name: leftNode,
1309
+ args
1310
+ }, { markImportant: !!important }, location, $.context);
1311
+ return leftNode;
1312
+ };
1313
+ let isPossibleMixinDefinition = selector instanceof BasicSelector && (selector.isClass || selector.isId) || selector instanceof InterpolatedSelector && (selector.isClass || selector.isId);
1314
+ let isPossibleMixinCall = true;
1315
+ if (!$.RECORDING_PHASE && !isSelectorList && !isPossibleMixinDefinition) for (let s of selector.nodes()) {
1316
+ /** Keep going until we get to basic selectors. */
1317
+ if (s instanceof ComplexSelector || s instanceof CompoundSelector) continue;
1318
+ if (s instanceof BasicSelector && (s.isClass || s.isId) || s instanceof InterpolatedSelector && (s.isClass || s.isId) || s instanceof Combinator && (s.value === ">" || s.value === " ")) continue;
1319
+ isPossibleMixinCall = false;
1320
+ break;
1321
+ }
1322
+ return $.OR2([
1323
+ {
1324
+ GATE: () => (isPossibleMixinDefinition || isPossibleMixinCall) && $.isType(T.LParen),
1325
+ ALT: () => {
1326
+ args = $.SUBRULE3($.mixinArgs, { ARGS: [ctx] });
1327
+ let next = $.LA(1).tokenType;
1328
+ if (next === T.LCurly || next === T.When) isPossibleMixinCall = false;
1329
+ return $.OR3([{
1330
+ GATE: () => isPossibleMixinDefinition,
1331
+ ALT: () => {
1332
+ $.OPTION(() => {
1333
+ guard = $.SUBRULE4($.guard, { ARGS: [ctx] });
1334
+ });
1335
+ $.CONSUME(T.LCurly);
1336
+ let rules = $.SUBRULE5($.declarationList, { ARGS: [ctx] });
1337
+ $.CONSUME(T.RCurly);
1338
+ if (!$.RECORDING_PHASE) {
1339
+ convertArgsForDefinition(args);
1340
+ const guardText = String(guard?.toString?.() ?? "");
1341
+ const hasDefault = Boolean(ctx.hasDefault) || guardContainsDefaultCall(guard) || guardText.includes("??()");
1342
+ const node = new Mixin({
1343
+ name: selector.valueOf(),
1344
+ params: args,
1345
+ rules,
1346
+ guard
1347
+ }, hasDefault ? { hasDefault: true } : void 0, $.endRule(), $.context);
1348
+ ctx.hasDefault = false;
1349
+ return node;
1350
+ }
1351
+ $.endRule();
1352
+ }
1353
+ }, {
1354
+ GATE: () => isPossibleMixinCall,
1355
+ ALT: () => {
1356
+ $.OPTION2(() => {
1357
+ important = $.CONSUME(T.Important);
1358
+ });
1359
+ let location = $.endRule();
1360
+ if (!$.RECORDING_PHASE) convertArgsForCall(args);
1361
+ let result;
1362
+ {
1363
+ /** in Less legacy mode, mixin calls can happen without a space. */
1364
+ let noSpace = $.noSep();
1365
+ let next = $.LA(1).tokenType;
1366
+ if (noSpace && next === T.LSquare || (noSpace || $.looseMode) && next === T.LParen) result = $.OPTION3(() => $.SUBRULE6($.lookupOrCall, { ARGS: [{
1367
+ ...ctx,
1368
+ node: $.RECORDING_PHASE ? void 0 : createMixinCall(location)
1369
+ }] }));
1370
+ }
1371
+ return $.RECORDING_PHASE ? void 0 : result ?? createMixinCall(location);
1372
+ }
1373
+ }]);
1374
+ }
1375
+ },
1376
+ {
1377
+ GATE: () => isPossibleMixinCall && $.isType(T.Semi),
1378
+ ALT: () => {
1379
+ const semi = $.CONSUME(T.Semi);
1380
+ const location = $.endRule();
1381
+ if (!$.RECORDING_PHASE) {
1382
+ $.warnDeprecation("Calling a mixin without parentheses is deprecated", semi, "mixin-call-no-parens");
1383
+ return createMixinCall(location);
1384
+ }
1385
+ }
1386
+ },
1387
+ { ALT: () => {
1388
+ $.endRule();
1389
+ let initialSelector = ctx.selector;
1390
+ let initialIsSelectorList = ctx.isSelectorList;
1391
+ ctx.selector = selector;
1392
+ ctx.isSelectorList = isSelectorList;
1393
+ let rule;
1394
+ try {
1395
+ rule = $.SUBRULE7($.qualifiedRuleBody, { ARGS: [ctx] });
1396
+ } finally {
1397
+ ctx.selector = initialSelector;
1398
+ ctx.isSelectorList = initialIsSelectorList;
1399
+ }
1400
+ if (ctx.extendNodes) {
1401
+ /** Prepend a rules block */
1402
+ let qRule = rule;
1403
+ for (const extendNode of ctx.extendNodes) if (extendNode.selector === void 0 || extendNode.selector instanceof Ampersand) extendNode.setData("selector", selector);
1404
+ rule = new Rules([...ctx.extendNodes, qRule]);
1405
+ rule._location = qRule._location;
1406
+ ctx.extendNodes = void 0;
1407
+ }
1408
+ return rule;
1409
+ } }
1410
+ ]);
1411
+ };
1412
+ }
1413
+ //#endregion
1414
+ //#region src/productions/selectors.ts
1415
+ let interpolatedRegex$1 = /([$@]){([^}]+)}/g;
1416
+ const createInterpolatedReference$2 = (prefix, value, location, context) => {
1417
+ const isProperty = prefix === "$";
1418
+ return new Reference({ key: isProperty ? new Quoted(value, { quote: "'" }, location, context) : value }, {
1419
+ type: isProperty ? "property" : "variable",
1420
+ role: "ident"
1421
+ }, location, context);
1422
+ };
1423
+ const getInterpolated$1 = (name, location, context) => {
1424
+ const replacements = [];
1425
+ let result;
1426
+ let source = name;
1427
+ while (result = interpolatedRegex$1.exec(name)) {
1428
+ const [match, propOrVar, value] = result;
1429
+ source = source.replace(match, INTERPOLATION_PLACEHOLDER);
1430
+ const reference = createInterpolatedReference$2(propOrVar, value, location, context);
1431
+ replacements.push(reference);
1432
+ }
1433
+ return new Interpolated({
1434
+ source,
1435
+ replacements
1436
+ }, { role: "ident" }, location, context);
1437
+ };
1438
+ function attributeSelector(T, valueAlt) {
1439
+ const $ = this;
1440
+ valueAlt ??= () => [
1441
+ {
1442
+ GATE: () => !$.isType(T.InterpolatedIdent),
1443
+ ALT: () => {
1444
+ const token = $.CONSUME5(T.Ident);
1445
+ if ($.RECORDING_PHASE) return;
1446
+ return new Any(token.image, { role: "ident" }, $.getLocationInfo(token), $.context);
1447
+ }
1448
+ },
1449
+ {
1450
+ GATE: () => $.isType(T.InterpolatedIdent),
1451
+ ALT: () => {
1452
+ const token = $.CONSUME(T.InterpolatedIdent);
1453
+ if ($.RECORDING_PHASE) return;
1454
+ const match = interpolatedRegex$1.exec(token.image);
1455
+ interpolatedRegex$1.lastIndex = 0;
1456
+ if (match && match[0] === token.image) return createInterpolatedReference$2(match[1], match[2], $.getLocationInfo(token), $.context);
1457
+ const result = getInterpolatedOrString(token.image, $.getLocationInfo(token), $.context);
1458
+ return typeof result === "string" ? new Any(result, { role: "ident" }, $.getLocationInfo(token), $.context) : result;
1459
+ }
1460
+ },
1461
+ { ALT: () => $.SUBRULE($.string) }
1462
+ ];
1463
+ return (ctx = {}) => {
1464
+ const RECORDING_PHASE = $.RECORDING_PHASE;
1465
+ $.startRule();
1466
+ $.CONSUME2(T.LSquare);
1467
+ const key = $.SUBRULE2($.attributeName);
1468
+ let op;
1469
+ let value;
1470
+ let mod;
1471
+ $.OPTION(() => {
1472
+ op = $.OR([{ ALT: () => $.CONSUME4(T.Eq) }, { ALT: () => $.CONSUME6(T.AttrMatch) }]);
1473
+ value = $.OR2(valueAlt(ctx));
1474
+ });
1475
+ $.OPTION2(() => mod = $.CONSUME7(T.AttrFlag));
1476
+ $.CONSUME8(T.RSquare);
1477
+ if (!RECORDING_PHASE) {
1478
+ const location = $.endRule();
1479
+ return new AttributeSelector({
1480
+ name: key.valueOf(),
1481
+ op: op?.image,
1482
+ value,
1483
+ mod: mod?.image
1484
+ }, void 0, location, $.context);
1485
+ }
1486
+ };
1487
+ }
1488
+ function getAmpersandTemplateValue(image) {
1489
+ if (image === "&") return;
1490
+ if (image.startsWith("&")) return image.slice(1) || void 0;
1491
+ if (image.includes("&")) return image;
1492
+ }
1493
+ const { isArray } = Array;
1494
+ function getAllowedExtendSelectors(context) {
1495
+ return context.opts.allowExtendSelectors;
1496
+ }
1497
+ function findDisallowedExtendSelector(selector, allowed) {
1498
+ if (!allowed) return;
1499
+ if (isNode(selector, N.SelectorList)) {
1500
+ for (const item of selector.value) {
1501
+ const disallowed = findDisallowedExtendSelector(item, allowed);
1502
+ if (disallowed) return disallowed;
1503
+ }
1504
+ return;
1505
+ }
1506
+ const kinds = isNode(selector, N.BasicSelector) ? ["simple", "basic"] : isNode(selector, N.PseudoSelector) ? ["simple", "pseudo"] : isNode(selector, N.CompoundSelector) ? ["compound"] : isNode(selector, N.ComplexSelector) ? ["complex"] : ["simple"];
1507
+ if (kinds.some((kind) => allowed.includes(kind))) return;
1508
+ return {
1509
+ kind: kinds[0],
1510
+ selector
1511
+ };
1512
+ }
1513
+ function formatAllowedExtendSelectors(allowed) {
1514
+ if (allowed.length === 0) return "no selector kinds";
1515
+ if (allowed.length === 1) return `${allowed[0]} selectors`;
1516
+ return `${allowed.slice(0, -1).join(", ")}, or ${allowed[allowed.length - 1]} selectors`;
1517
+ }
1518
+ function validateExtendTarget($, selector, source) {
1519
+ const allowed = getAllowedExtendSelectors($.context);
1520
+ const disallowed = findDisallowedExtendSelector(selector, allowed);
1521
+ if (!disallowed || !allowed) return;
1522
+ throw new Error(`${source} only allows ${formatAllowedExtendSelectors(allowed)}, but found ${disallowed.kind} selector "${disallowed.selector.valueOf()}".`);
1523
+ }
1524
+ function mergeExtends(selector, extendTargets, location, context, flag) {
1525
+ let extendNodes;
1526
+ let currentTarget = extendTargets[0].target;
1527
+ let currentFlag = extendTargets[0].flag ?? flag ? 0 : 1;
1528
+ let currentNode = new Extend({
1529
+ selector,
1530
+ target: currentTarget,
1531
+ flag: currentFlag
1532
+ }, void 0, location, context);
1533
+ for (let i = 1; i < extendTargets.length; i++) {
1534
+ let ext = extendTargets[i];
1535
+ let thisFlag = ext.flag ?? flag ? 0 : 1;
1536
+ /**
1537
+ * Merge extends. We do this instead of merging earlier so that
1538
+ * selector lists with different flags are not merged.
1539
+ */
1540
+ if (thisFlag === currentFlag) {
1541
+ let target = currentNode.target;
1542
+ if (!(target instanceof SelectorList)) currentNode.setData("target", new SelectorList([target, ext.target], void 0, location, context));
1543
+ else target.setData([...target.value, ext.target]);
1544
+ } else {
1545
+ if (!extendNodes || !extendNodes.includes(currentNode)) (extendNodes ??= []).push(currentNode);
1546
+ currentFlag = thisFlag;
1547
+ currentTarget = ext.target;
1548
+ currentNode = new Extend({
1549
+ selector,
1550
+ target: currentTarget,
1551
+ flag: currentFlag
1552
+ }, void 0, location, context);
1553
+ extendNodes.push(currentNode);
1554
+ }
1555
+ }
1556
+ if (!extendNodes) return currentNode;
1557
+ if (extendNodes.length === 1) return extendNodes[0];
1558
+ return extendNodes;
1559
+ }
1560
+ /** True for a node that could be one item in the old unquoted selector list (e.g. .a or #id). */
1561
+ function isSelectorLikeListItem(node) {
1562
+ if (node.type === "SelectorCapture" || isNode(node, N.Call)) return false;
1563
+ if (isNode(node, N.Reference)) return node.options.type === "mixin-ruleset";
1564
+ if (node instanceof List || node instanceof Sequence) return node.value.length > 0 && node.value.every(isSelectorLikeListItem);
1565
+ return false;
1566
+ }
1567
+ /** True only for the legacy unquoted selector-list form (e.g. @var: .a, .b, .c), not @var: .a; */
1568
+ function isLegacySelectorLikeValue(node) {
1569
+ if (node.type === "SelectorCapture" || isNode(node, N.Call)) return false;
1570
+ if (isNode(node, N.Reference)) return false;
1571
+ if (node instanceof List || node instanceof Sequence) return node.value.length > 1 && node.value.every(isSelectorLikeListItem);
1572
+ return false;
1573
+ }
1574
+ /**
1575
+ * We need to now handle a returned `Extend` node from the complexSelector rule
1576
+ */
1577
+ function relativeSelector(T) {
1578
+ const $ = this;
1579
+ return (ctx = {}) => {
1580
+ return $.OR([{ ALT: () => {
1581
+ let co = $.CONSUME(T.Combinator);
1582
+ let node = $.SUBRULE2($.complexSelector, { ARGS: [ctx] });
1583
+ const coImage = co.image;
1584
+ let combinator = new Combinator(coImage, void 0, $.getLocationInfo(co), $.context);
1585
+ let targetNode = node instanceof Extend ? node.selector : node;
1586
+ if (targetNode instanceof ComplexSelector) {
1587
+ targetNode.setData([combinator, ...targetNode.value]);
1588
+ targetNode._location = $.getLocationFromNodes(targetNode.value);
1589
+ } else {
1590
+ let nodes = [combinator, targetNode];
1591
+ let complex = new ComplexSelector(nodes, void 0, $.getLocationFromNodes(nodes), $.context);
1592
+ if (node instanceof Extend) {
1593
+ node.setData("selector", complex);
1594
+ let location = node.location;
1595
+ location[0] = co.startOffset;
1596
+ location[1] = co.startLine;
1597
+ location[2] = co.startColumn;
1598
+ } else node = complex;
1599
+ }
1600
+ return node;
1601
+ } }, { ALT: () => $.SUBRULE3($.complexSelector, { ARGS: [ctx] }) }]);
1602
+ };
1603
+ }
1604
+ function forgivingSelectorList(T) {
1605
+ const $ = this;
1606
+ return (ctx = {}) => {
1607
+ const RECORDING_PHASE = $.RECORDING_PHASE;
1608
+ $.startRule();
1609
+ let sequences;
1610
+ let i = 0;
1611
+ if (!RECORDING_PHASE) sequences = [];
1612
+ $.AT_LEAST_ONE_SEP({
1613
+ SEP: T.Comma,
1614
+ DEF: () => {
1615
+ const selector = $.SUBRULE($.relativeSelector, { ARGS: [ctx] });
1616
+ if (!RECORDING_PHASE) {
1617
+ i++;
1618
+ if (i === 1 && ctx.qualifiedRule) sequences.push($.wrap(selector, true));
1619
+ else sequences.push($.wrap(selector, i === 1 ? true : "both"));
1620
+ }
1621
+ }
1622
+ });
1623
+ if (RECORDING_PHASE) return;
1624
+ const location = $.endRule();
1625
+ if (sequences.length === 1) return sequences[0];
1626
+ return new SelectorList(sequences, void 0, location, $.context);
1627
+ };
1628
+ }
1629
+ function selectorList(T) {
1630
+ const $ = this;
1631
+ return (ctx = {}) => {
1632
+ const RECORDING_PHASE = $.RECORDING_PHASE;
1633
+ $.startRule();
1634
+ let sequences;
1635
+ let i = 0;
1636
+ if (!RECORDING_PHASE) sequences = [];
1637
+ $.AT_LEAST_ONE_SEP({
1638
+ SEP: T.Comma,
1639
+ DEF: () => {
1640
+ const selector = $.SUBRULE2($.complexSelector, { ARGS: [ctx] });
1641
+ if (!RECORDING_PHASE) {
1642
+ i++;
1643
+ if (i === 1 && ctx.qualifiedRule) sequences.push($.wrap(selector, true));
1644
+ else sequences.push($.wrap(selector, i === 1 ? true : "both"));
1645
+ }
1646
+ }
1647
+ });
1648
+ if (RECORDING_PHASE) return;
1649
+ const location = $.endRule();
1650
+ if (sequences.length === 1) return sequences[0];
1651
+ return new SelectorList(sequences, void 0, location, $.context);
1652
+ };
1653
+ }
1654
+ function compoundSelector(T) {
1655
+ const $ = this;
1656
+ return (ctx = {}) => {
1657
+ /**
1658
+ A sequence of simple selectors that are not separated by
1659
+ a combinator.
1660
+ .e.g. `a#selected`
1661
+ */
1662
+ let RECORDING_PHASE = $.RECORDING_PHASE;
1663
+ let selectors;
1664
+ if (!RECORDING_PHASE) selectors = [];
1665
+ let sel = $.SUBRULE($.simpleSelector, { ARGS: [ctx] });
1666
+ if (!RECORDING_PHASE) selectors.push(sel);
1667
+ $.MANY({
1668
+ GATE: () => !$.hasWS() && !(ctx.inExtend && $.isType(T.All)),
1669
+ DEF: () => {
1670
+ let sel = $.SUBRULE2($.simpleSelector, { ARGS: [ctx] });
1671
+ if (!RECORDING_PHASE) {
1672
+ /** Make sure we don't add implicit whitespace */
1673
+ sel.pre = 0;
1674
+ selectors.push(sel);
1675
+ }
1676
+ }
1677
+ });
1678
+ if (RECORDING_PHASE) return;
1679
+ if (selectors.length === 1) return selectors[0];
1680
+ return new CompoundSelector(selectors, void 0, $.getLocationFromNodes(selectors), $.context);
1681
+ };
1682
+ }
1683
+ /**
1684
+ * Extended with :extend
1685
+ */
1686
+ function complexSelector(T) {
1687
+ const $ = this;
1688
+ return (ctx = {}) => {
1689
+ const RECORDING_PHASE = $.RECORDING_PHASE;
1690
+ $.startRule();
1691
+ let selectors;
1692
+ if (!RECORDING_PHASE) selectors = [$.SUBRULE($.compoundSelector, { ARGS: [ctx] })];
1693
+ else $.SUBRULE($.compoundSelector, { ARGS: [ctx] });
1694
+ $.MANY({
1695
+ GATE: () => {
1696
+ if (ctx.inExtend && $.isType(T.All)) return false;
1697
+ return $.hasWS() || $.isType(T.Combinator);
1698
+ },
1699
+ DEF: () => {
1700
+ let co;
1701
+ let combinator;
1702
+ $.OPTION(() => {
1703
+ co = $.CONSUME(T.Combinator);
1704
+ });
1705
+ if (!RECORDING_PHASE) if (co) {
1706
+ const coImg = co.image;
1707
+ combinator = $.wrap(new Combinator(coImg, void 0, $.getLocationInfo(co), $.context), "both");
1708
+ } else {
1709
+ const startOffset = $.LA(1).startOffset;
1710
+ combinator = new Combinator(" ", void 0, void 0, $.context);
1711
+ let pre = $.getPrePost(startOffset);
1712
+ if (pre === 1) pre = 0;
1713
+ else if (pre) {
1714
+ const last = pre[pre.length - 1];
1715
+ if (typeof last === "string" && last.endsWith(" ")) pre[pre.length - 1] = last.slice(0, -1);
1716
+ }
1717
+ combinator.pre = pre;
1718
+ }
1719
+ const compound = $.SUBRULE2($.compoundSelector, { ARGS: [ctx] });
1720
+ if (!RECORDING_PHASE) selectors.push(combinator, compound);
1721
+ }
1722
+ });
1723
+ let selector;
1724
+ if (!RECORDING_PHASE) {
1725
+ const location = $.endRule();
1726
+ selector = selectors.length === 1 ? selectors[0] : new ComplexSelector(selectors, void 0, location, $.context);
1727
+ }
1728
+ let flag;
1729
+ /** Inside :extend(...), only consume the optional trailing "all" keyword. */
1730
+ $.OPTION2({
1731
+ GATE: () => !!ctx.inExtend && $.isType(T.All),
1732
+ DEF: () => {
1733
+ flag = $.CONSUME(T.All);
1734
+ }
1735
+ });
1736
+ /**
1737
+ * Outside :extend(...), only enter the extend production when the next token
1738
+ * is actually :extend(. Do not commit based on context alone.
1739
+ */
1740
+ $.OPTION3({
1741
+ GATE: () => !ctx.inExtend && !!ctx.qualifiedRule && $.isType(T.Extend),
1742
+ DEF: () => {
1743
+ const initialSelector = ctx.selector;
1744
+ if (!RECORDING_PHASE) ctx.selector = selector;
1745
+ try {
1746
+ $.SUBRULE($.extend, { ARGS: [ctx] });
1747
+ } finally {
1748
+ ctx.selector = initialSelector;
1749
+ }
1750
+ }
1751
+ });
1752
+ if (ctx.inExtend) {
1753
+ validateExtendTarget($, selector, ":extend()");
1754
+ (ctx.extendTargets ??= []).push({
1755
+ selector: ctx.selector,
1756
+ target: selector,
1757
+ flag
1758
+ });
1759
+ }
1760
+ return selector;
1761
+ };
1762
+ }
1763
+ /**
1764
+ * &:extend(...) statement ending with a semicolon.
1765
+ * This is the only valid standalone extend statement in Less.
1766
+ */
1767
+ function ampersandExtend(T) {
1768
+ const $ = this;
1769
+ return (ctx = {}) => {
1770
+ $.startRule();
1771
+ $.CONSUME(T.AmpersandExtend);
1772
+ ctx.inExtend = true;
1773
+ $.SUBRULE($.selectorList, { ARGS: [ctx] });
1774
+ ctx.inExtend = false;
1775
+ let extendTargets = ctx.extendTargets;
1776
+ let flag = $.OPTION(() => $.CONSUME(T.AllFlag));
1777
+ $.CONSUME(T.RParen);
1778
+ $.CONSUME(T.Semi);
1779
+ let location = $.endRule();
1780
+ if (!$.RECORDING_PHASE) {
1781
+ let result = mergeExtends(void 0, extendTargets, location, $.context, flag);
1782
+ /** We've converted these extend targets to nodes, so we can reset extend targets */
1783
+ ctx.extendTargets = void 0;
1784
+ if (ctx.extendNodes) if (isArray(result)) ctx.extendNodes = [...ctx.extendNodes, ...result];
1785
+ else ctx.extendNodes.push(result);
1786
+ else if (isArray(result)) ctx.extendNodes = result;
1787
+ else ctx.extendNodes = [result];
1788
+ return new Nil(void 0, void 0, location, $.context);
1789
+ }
1790
+ };
1791
+ }
1792
+ function extend(T) {
1793
+ const $ = this;
1794
+ return (ctx = {}) => {
1795
+ $.startRule();
1796
+ $.CONSUME(T.Extend);
1797
+ ctx.inExtend = true;
1798
+ $.SUBRULE($.selectorList, { ARGS: [ctx] });
1799
+ let extendTargets = ctx.extendTargets;
1800
+ ctx.inExtend = false;
1801
+ let selector = ctx.selector;
1802
+ let flag = $.OPTION(() => $.CONSUME(T.AllFlag));
1803
+ $.CONSUME(T.RParen);
1804
+ let location = $.endRule();
1805
+ if (!$.RECORDING_PHASE) {
1806
+ let merged = mergeExtends(selector, extendTargets, location, $.context, flag);
1807
+ /**
1808
+ * If we don't have as many extends as we have selectors, we need a way to signal
1809
+ * that these should be bumped above the ruleset.
1810
+ */
1811
+ /** We've converted these extend targets to nodes, so we can reset extend targets */
1812
+ ctx.extendTargets = void 0;
1813
+ if (ctx.extendNodes) if (isArray(merged)) ctx.extendNodes = [...ctx.extendNodes, ...merged];
1814
+ else ctx.extendNodes.push(merged);
1815
+ else if (isArray(merged)) ctx.extendNodes = merged;
1816
+ else ctx.extendNodes = [merged];
1817
+ }
1818
+ };
1819
+ }
1820
+ function simpleSelector(T) {
1821
+ const $ = this;
1822
+ return (ctx = {}) => {
1823
+ let selector = $.OR([
1824
+ {
1825
+ GATE: () => (!ctx.inExtend || $.LA(1).tokenType !== T.All) && $.LA(1).tokenType !== T.InterpolatedIdent,
1826
+ ALT: () => $.CONSUME(T.Ident)
1827
+ },
1828
+ { ALT: () => {
1829
+ let amp = $.CONSUME(T.Ampersand);
1830
+ return new Ampersand({ template: getAmpersandTemplateValue(amp.image) }, void 0, $.getLocationInfo(amp), $.context);
1831
+ } },
1832
+ { ALT: () => {
1833
+ $.startRule();
1834
+ $.CONSUME(T.AmpersandLParen);
1835
+ const parts = [];
1836
+ let sawQuoted = false;
1837
+ $.MANY(() => {
1838
+ $.OR2([
1839
+ {
1840
+ GATE: () => $.isType(T.QuoteStart),
1841
+ ALT: () => {
1842
+ const quoted = $.SUBRULE($.string, { ARGS: [ctx] });
1843
+ parts.push(quoted.valueOf());
1844
+ sawQuoted = true;
1845
+ }
1846
+ },
1847
+ {
1848
+ GATE: () => $.isType(T.WS),
1849
+ ALT: () => {
1850
+ parts.push($.CONSUME(T.WS).image);
1851
+ }
1852
+ },
1853
+ { ALT: () => {
1854
+ parts.push($.CONSUME(T.AmpersandTemplateContents).image);
1855
+ } }
1856
+ ]);
1857
+ });
1858
+ $.CONSUME(T.AmpersandTemplateEnd);
1859
+ const location = $.endRule();
1860
+ const value = parts.join("");
1861
+ return new Ampersand({ template: sawQuoted && value === "" ? new Nil() : value === "nil" ? new Nil() : value }, void 0, location, $.context);
1862
+ } },
1863
+ { ALT: () => $.CONSUME(T.InterpolatedIdent) },
1864
+ { ALT: () => $.CONSUME(T.InterpolatedSelector) },
1865
+ { ALT: () => $.SUBRULE($.classSelector, { ARGS: [ctx] }) },
1866
+ { ALT: () => $.SUBRULE($.idSelector, { ARGS: [ctx] }) },
1867
+ { ALT: () => $.CONSUME(T.Star) },
1868
+ { ALT: () => {
1869
+ let initialIsQualifiedRule = ctx.qualifiedRule;
1870
+ ctx.qualifiedRule = false;
1871
+ /** Make sure we prevent things like :extend() inside pseudo-selectors */
1872
+ try {
1873
+ return $.SUBRULE($.pseudoSelector, { ARGS: [ctx] });
1874
+ } finally {
1875
+ ctx.qualifiedRule = initialIsQualifiedRule;
1876
+ }
1877
+ } },
1878
+ (
1879
+ /** @todo - replicate this fix we made with the Jess parser
1880
+ *
1881
+ * { ALT: () => $.attributeSelector(ctx, () => [
1882
+ {
1883
+ ALT: () => {
1884
+ let token = $.CONSUME($.T.InterpolatedIdent);
1885
+ let location = $.getLocationInfo(token);
1886
+ let image = token.image;
1887
+ let match = interpolatedRegex.exec(image);
1888
+ interpolatedRegex.lastIndex = 0;
1889
+ if (match && match[0] === image) {
1890
+ return new Reference(
1891
+ { key: new Keyword(match[2]!, undefined, location, $.context) },
1892
+ { type: 'index' },
1893
+ location,
1894
+ $.context
1895
+ );
1896
+ }
1897
+ return getInterpolated(image, location, $.context);
1898
+ }
1899
+ },
1900
+ */
1901
+ { ALT: () => $.SUBRULE($.attributeSelector, { ARGS: [ctx] }) }),
1902
+ (
1903
+ /** Supports keyframes selectors */
1904
+ { ALT: () => $.CONSUME(T.DimensionInt) }),
1905
+ { ALT: () => $.CONSUME(T.DimensionNum) }
1906
+ ]);
1907
+ if ($.isToken(selector)) {
1908
+ if (selector.tokenType.name === "Ampersand") return new Ampersand({ template: getAmpersandTemplateValue(selector.image) }, void 0, $.getLocationInfo(selector), $.context);
1909
+ if (selector.tokenType.name === "InterpolatedSelector" || selector.tokenType.name === "InterpolatedIdent") {
1910
+ let nameValue = selector.image;
1911
+ return new InterpolatedSelector(getInterpolated$1(nameValue, $.getLocationInfo(selector), $.context), void 0, $.getLocationInfo(selector), $.context);
1912
+ }
1913
+ return new BasicSelector(selector.image, void 0, $.getLocationInfo(selector), $.context);
1914
+ }
1915
+ return selector;
1916
+ };
1917
+ }
1918
+ function anonymousMixinDefinition(T) {
1919
+ const $ = this;
1920
+ return (ctx = {}) => {
1921
+ $.startRule();
1922
+ let params;
1923
+ let anonToken;
1924
+ $.OPTION(() => {
1925
+ anonToken = $.CONSUME(T.AnonMixinStart);
1926
+ $.OPTION2(() => {
1927
+ params = $.SUBRULE($.mixinArgList, { ARGS: [{
1928
+ ...ctx,
1929
+ isDefinition: true
1930
+ }] });
1931
+ });
1932
+ $.CONSUME(T.RParen);
1933
+ });
1934
+ let rules = $.SUBRULE($.wrappedDeclarationList, { ARGS: [ctx] });
1935
+ if ($.RECORDING_PHASE) return;
1936
+ if (!rules.options.rulesVisibility) rules.options.rulesVisibility = {};
1937
+ if ($.leakyRules) {
1938
+ rules.options.rulesVisibility.Mixin = "public";
1939
+ rules.options.rulesVisibility.VarDeclaration = "private";
1940
+ } else {
1941
+ rules.options.rulesVisibility.Mixin = "private";
1942
+ rules.options.rulesVisibility.VarDeclaration = "private";
1943
+ }
1944
+ if (!anonToken) {
1945
+ /** To Less, this is a "detached ruleset" */
1946
+ const shouldBeCollection = (() => {
1947
+ let properties = [];
1948
+ for (const node of rules.value) if (node.type === "Declaration") properties.push(node);
1949
+ else if (node.type === "Comment" || node.type === "VarDeclaration") continue;
1950
+ else
1951
+ /** Not a valid collection, parse as anonymous mixin */
1952
+ return false;
1953
+ if (properties.length === 0)
1954
+ /** If just var declarations and/or comments, parse as collection */
1955
+ return true;
1956
+ /** If this looks like mostly CSS properties, parse as mixin instead */
1957
+ return !(properties.filter((decl) => {
1958
+ const name = decl.name;
1959
+ const propName = typeof name === "string" ? name : name.valueOf();
1960
+ if (propName.startsWith("--")) return true;
1961
+ return all.includes(propName);
1962
+ }).length > properties.length / 2);
1963
+ })();
1964
+ const usage = ctx.detachedRulesetUsage ?? "none";
1965
+ if (shouldBeCollection && !(usage === "function-arg" || usage === "mixin-arg" || usage === "default-param")) return new Collection(rules.value, rules.options, $.endRule(), $.context);
1966
+ }
1967
+ return new Mixin({
1968
+ params,
1969
+ rules
1970
+ }, void 0, $.endRule(), $.context);
1971
+ };
1972
+ }
1973
+ /**
1974
+ * Mostly copied from css importAtRule, but it maps
1975
+ * differently to Jess nodes depending on if it's meant
1976
+ * to be a Jess-style import or just an at-rule
1977
+ */
1978
+ function importAtRule(T) {
1979
+ const $ = this;
1980
+ return (ctx = {}) => {
1981
+ const isCssUrl = (url, options) => {
1982
+ if (options.includes("inline")) return false;
1983
+ const lower = url.toLowerCase();
1984
+ if (options.includes("less")) return false;
1985
+ if (options.includes("css")) return true;
1986
+ if (/\.css([?#].*)?$/.test(lower)) return true;
1987
+ if (/\.less([?#].*)?$/.test(lower)) return false;
1988
+ if (lower.startsWith("http://") || lower.startsWith("https://") || lower.startsWith("//")) return true;
1989
+ return false;
1990
+ };
1991
+ $.startRule();
1992
+ let name = $.CONSUME(T.AtImport);
1993
+ let options = [];
1994
+ $.OPTION(() => {
1995
+ $.CONSUME(T.LParen);
1996
+ $.AT_LEAST_ONE_SEP({
1997
+ SEP: T.Comma,
1998
+ DEF: () => {
1999
+ let opt = $.CONSUME(T.PlainIdent);
2000
+ options.push(opt.image);
2001
+ }
2002
+ });
2003
+ $.CONSUME(T.RParen);
2004
+ });
2005
+ let urlNode = $.OR([{ ALT: () => $.SUBRULE($.urlFunction, { ARGS: [ctx] }) }, { ALT: () => $.SUBRULE($.string, { ARGS: [ctx] }) }]);
2006
+ let extraNodes;
2007
+ $.OPTION2(() => {
2008
+ extraNodes = $.SUBRULE($.importPostlude, { ARGS: [{}] });
2009
+ });
2010
+ $.CONSUME(T.Semi);
2011
+ if (!$.RECORDING_PHASE) {
2012
+ let isAtRule;
2013
+ let postludeNode;
2014
+ isAtRule = isCssUrl(urlNode.valueOf(), options);
2015
+ let preludeNodes = [$.wrap(urlNode)];
2016
+ if (extraNodes && extraNodes.length) if (isAtRule) {
2017
+ isAtRule = true;
2018
+ for (const n of extraNodes) preludeNodes.push(n);
2019
+ } else {
2020
+ const postludeLoc = $.getLocationFromNodes(extraNodes);
2021
+ postludeNode = new Sequence(extraNodes, void 0, postludeLoc, $.context);
2022
+ }
2023
+ let location = $.endRule();
2024
+ if (isAtRule) {
2025
+ const prelude = new Sequence(preludeNodes, void 0, $.getLocationFromNodes(preludeNodes), $.context);
2026
+ return new AtRule({
2027
+ name: $.wrap(new Any(name.image, { role: "atkeyword" }, $.getLocationInfo(name), $.context), true),
2028
+ prelude
2029
+ }, void 0, location, $.context);
2030
+ }
2031
+ return new StyleImport({ path: urlNode }, {
2032
+ type: "import",
2033
+ importOptions: {
2034
+ type: options.includes("less") ? "less" : void 0,
2035
+ reference: options.includes("reference"),
2036
+ once: !options.includes("multiple"),
2037
+ multiple: options.includes("multiple"),
2038
+ optional: options.includes("optional"),
2039
+ inline: options.includes("inline"),
2040
+ postlude: postludeNode
2041
+ }
2042
+ }, location, $.context);
2043
+ }
2044
+ };
2045
+ }
2046
+ /** Less variables */
2047
+ function varDeclarationOrCall(T) {
2048
+ const $ = this;
2049
+ return (ctx = {}) => {
2050
+ $.startRule();
2051
+ let name = $.SUBRULE($.varName, { ARGS: [{}] });
2052
+ let value;
2053
+ let args;
2054
+ let important;
2055
+ $.OR([{ ALT: () => {
2056
+ $.CONSUME(T.Colon);
2057
+ return $.OR2([{
2058
+ GATE: () => {
2059
+ const type = $.LA(1).tokenType;
2060
+ return type === T.AnonMixinStart || type === T.LCurly;
2061
+ },
2062
+ ALT: () => {
2063
+ value = $.SUBRULE($.anonymousMixinDefinition, { ARGS: [ctx] });
2064
+ $.OPTION(() => $.CONSUME(T.Semi));
2065
+ return value;
2066
+ }
2067
+ }, {
2068
+ GATE: () => {
2069
+ const type = $.LA(1).tokenType;
2070
+ return type !== T.AnonMixinStart && type !== T.LCurly;
2071
+ },
2072
+ ALT: () => {
2073
+ value = $.SUBRULE($.valueList, { ARGS: [{
2074
+ ...ctx,
2075
+ allowMixinCallWithoutAccessor: true
2076
+ }] });
2077
+ $.OPTION2(() => {
2078
+ important = $.CONSUME(T.Important);
2079
+ });
2080
+ return value;
2081
+ }
2082
+ }]);
2083
+ } }, (
2084
+ /** This is a variable call. Allow optional whitespace between name and (. */
2085
+ {
2086
+ GATE: () => $.isType(T.LParen),
2087
+ ALT: () => {
2088
+ args = $.SUBRULE($.mixinArgs, { ARGS: [ctx] });
2089
+ return args;
2090
+ }
2091
+ })]);
2092
+ let location = $.endRule();
2093
+ if ($.RECORDING_PHASE) return;
2094
+ let nameVal = getInterpolatedOrString(name.image);
2095
+ let nameNode;
2096
+ if (!(nameVal instanceof Interpolated)) nameNode = new Any(nameVal, { role: "ident" }, $.getLocationInfo(name), $.context);
2097
+ else nameNode = nameVal;
2098
+ /** An anonymous mixin call */
2099
+ if (!value) {
2100
+ const callNode = new Call({
2101
+ name: new Reference({ key: nameNode }, {
2102
+ type: "variable",
2103
+ role: "name"
2104
+ }),
2105
+ args
2106
+ }, important ? { markImportant: true } : void 0, location, $.context);
2107
+ if (important) important = void 0;
2108
+ return new Expression(callNode, void 0, location, $.context);
2109
+ }
2110
+ if (important && value instanceof Call) {
2111
+ value.options = value.options || {};
2112
+ value.options.markImportant = true;
2113
+ important = void 0;
2114
+ }
2115
+ if (value && isLegacySelectorLikeValue(value)) {
2116
+ const varName = String(nameNode.valueOf());
2117
+ $.warnDeprecation(`Unquoted selector capture in '${varName}' is no longer supported. Use '*[ ... ]' (e.g. ${varName}: *[.a, .b]).`, $.LA(1), "unquoted-selector-capture");
2118
+ }
2119
+ return new VarDeclaration({
2120
+ name: $.wrap(nameNode, true),
2121
+ value: $.wrap(value, true),
2122
+ important: important ? $.wrap(new Any(important.image, { role: "flag" }, $.getLocationInfo(important), $.context), true) : void 0
2123
+ }, void 0, location, $.context);
2124
+ };
2125
+ }
2126
+ function selectorCapture(T) {
2127
+ const $ = this;
2128
+ return (ctx = {}) => {
2129
+ $.startRule();
2130
+ $.CONSUME(T.Star);
2131
+ const selector = $.OR([{
2132
+ GATE: $.noSep.bind($),
2133
+ ALT: () => {
2134
+ $.CONSUME(T.LSquare);
2135
+ const selector = $.SUBRULE($.forgivingSelectorList, { ARGS: [{
2136
+ ...ctx,
2137
+ inner: true
2138
+ }] });
2139
+ $.CONSUME(T.RSquare);
2140
+ return selector;
2141
+ }
2142
+ }]);
2143
+ const location = $.endRule();
2144
+ if ($.RECORDING_PHASE) return;
2145
+ return new SelectorCapture($.wrap(selector, true), void 0, location, $.context);
2146
+ };
2147
+ }
2148
+ function valueSequence(_T) {
2149
+ const $ = this;
2150
+ return (ctx = {}) => {
2151
+ const RECORDING_PHASE = $.RECORDING_PHASE;
2152
+ $.startRule();
2153
+ let nodes;
2154
+ if (!RECORDING_PHASE) nodes = [];
2155
+ {
2156
+ const exprCtx = {
2157
+ ...ctx,
2158
+ wrapInExpression: true
2159
+ };
2160
+ let value = $.SUBRULE2($.expressionSum, { ARGS: [exprCtx] });
2161
+ if (!RECORDING_PHASE) {
2162
+ value = wrapOuterExpressionIfNeeded.call($, value, exprCtx);
2163
+ nodes.push(value);
2164
+ }
2165
+ }
2166
+ $.MANY(() => {
2167
+ const exprCtx = {
2168
+ ...ctx,
2169
+ wrapInExpression: true
2170
+ };
2171
+ let value = $.SUBRULE3($.expressionSum, { ARGS: [exprCtx] });
2172
+ if (!RECORDING_PHASE) {
2173
+ value = wrapOuterExpressionIfNeeded.call($, value, exprCtx);
2174
+ nodes.push(value);
2175
+ }
2176
+ });
2177
+ if (RECORDING_PHASE) return;
2178
+ let location = $.endRule();
2179
+ if (nodes.length === 1) return nodes[0];
2180
+ return new Sequence(nodes, void 0, location, $.context);
2181
+ };
2182
+ }
2183
+ function squareValue(T) {
2184
+ const $ = this;
2185
+ return (ctx = {}) => {
2186
+ $.startRule();
2187
+ $.CONSUME(T.LSquare);
2188
+ let node = $.OR([{
2189
+ GATE: () => !$.looseMode,
2190
+ ALT: () => {
2191
+ let ident = $.CONSUME(T.Ident);
2192
+ return new Any(ident.image, { role: "ident" }, $.getLocationInfo(ident), $.context);
2193
+ }
2194
+ }, {
2195
+ GATE: () => !!$.looseMode,
2196
+ ALT: () => {
2197
+ let nodes = [];
2198
+ $.MANY(() => {
2199
+ let node = $.SUBRULE($.anyInnerValue, { ARGS: [ctx] });
2200
+ const wrapped = $.wrap(node);
2201
+ nodes.push(wrapped);
2202
+ });
2203
+ return new Sequence(nodes, void 0, $.getLocationFromNodes(nodes), $.context);
2204
+ }
2205
+ }]);
2206
+ $.CONSUME(T.RSquare);
2207
+ return new Block(node, { type: "square" }, $.endRule(), $.context);
2208
+ };
2209
+ }
2210
+ //#endregion
2211
+ //#region src/productions/values.ts
2212
+ const cssNthValue = productions.nthValue;
2213
+ const cssKnownFunctions = productions.knownFunctions;
2214
+ const cssMathValue = productions.mathValue;
2215
+ function getParenFrames$1(ctx) {
2216
+ return ctx?.parenFrames ?? [];
2217
+ }
2218
+ function withCalcFrame(ctx, delta) {
2219
+ const calcFrames = (ctx?.calcFrames ?? 0) + delta;
2220
+ return {
2221
+ ...ctx ?? {},
2222
+ calcFrames
2223
+ };
2224
+ }
2225
+ function startsCustomValueToken($, T) {
2226
+ return $.isType(T.LParen) || $.isType(T.FunctionStart) || $.isType(T.FunctionalPseudoClass) || $.isType(T.LSquare) || $.isType(T.LCurly) || $.isType(T.SingleQuoteStart) || $.isType(T.DoubleQuoteStart) || $.isType(T.Value) || $.isType(T.PlainIdent) || $.isType(T.AtKeyword) || $.isType(T.PropertyReference) || $.isType(T.CustomProperty) || $.isType(T.Dimension) || $.isType(T.Number) || $.isType(T.Color) || $.isType(T.UnicodeRange) || $.isType(T.Colon) || $.isType(T.Comma) || $.isType(T.Important) || $.isType(T.Unknown);
2227
+ }
2228
+ const createInterpolatedReference$1 = (prefix, value, location, context) => {
2229
+ const isProperty = prefix === "$";
2230
+ return new Reference({ key: isProperty ? new Quoted(value, { quote: "'" }, location, context) : value }, {
2231
+ type: isProperty ? "property" : "variable",
2232
+ role: "ident"
2233
+ }, location, context);
2234
+ };
2235
+ function expressionSum(T) {
2236
+ const $ = this;
2237
+ return (ctx = {}) => {
2238
+ $.startRule();
2239
+ let left = $.SUBRULE($.expressionProduct, { ARGS: [ctx] });
2240
+ while (true) {
2241
+ let op;
2242
+ let right;
2243
+ if ($.isType(T.Plus)) {
2244
+ op = $.CONSUME(T.Plus).image;
2245
+ right = $.SUBRULE2($.expressionProduct, { ARGS: [ctx] });
2246
+ } else if ($.isType(T.Minus)) {
2247
+ op = $.CONSUME(T.Minus).image;
2248
+ right = $.SUBRULE4($.expressionProduct, { ARGS: [ctx] });
2249
+ } else if ($.noSep() && $.matchToken($.LA(1), T.Signed)) {
2250
+ const tok = $.CONSUME(T.Signed);
2251
+ let startValue;
2252
+ const str = tok.image;
2253
+ op = str[0];
2254
+ if (tok.payload && tok.payload[1]) startValue = new Dimension({
2255
+ number: parseFloat(tok.payload[0]),
2256
+ unit: tok.payload[1]
2257
+ }, void 0, $.getLocationInfo(tok), $.context);
2258
+ else {
2259
+ const num = parseFloat(str);
2260
+ if (!Number.isNaN(num)) startValue = new Num(num, void 0, $.getLocationInfo(tok), $.context);
2261
+ else startValue = $.processValueToken(tok);
2262
+ }
2263
+ right = $.SUBRULE3($.expressionProduct, { ARGS: [{
2264
+ ...ctx,
2265
+ startValue
2266
+ }] });
2267
+ } else break;
2268
+ left = new Operation([
2269
+ $.wrap(left, true),
2270
+ op,
2271
+ $.wrap(right)
2272
+ ], void 0, $.getLocationFromNodes([left, right]), $.context);
2273
+ }
2274
+ $.endRule();
2275
+ return left;
2276
+ };
2277
+ }
2278
+ function expressionProduct(T) {
2279
+ const $ = this;
2280
+ return (ctx = {}) => {
2281
+ $.startRule();
2282
+ let left = ctx.startValue ?? $.SUBRULE($.expressionValue, { ARGS: [ctx] });
2283
+ while (true) {
2284
+ let op;
2285
+ if ($.isType(T.Star)) op = $.CONSUME(T.Star);
2286
+ else if ($.isType(T.Slash)) op = $.CONSUME(T.Slash);
2287
+ else if ($.isType(T.Percent)) op = $.CONSUME(T.Percent);
2288
+ else break;
2289
+ if (op.image === "./") $.warnDeprecation("./ operator is deprecated", op, "dot-slash-operator");
2290
+ let right = $.SUBRULE2($.expressionValue, { ARGS: [ctx] });
2291
+ left = new Operation([
2292
+ $.wrap(left, true),
2293
+ op.image,
2294
+ $.wrap(right)
2295
+ ], void 0, $.getLocationFromNodes([left, right]), $.context);
2296
+ }
2297
+ $.endRule();
2298
+ return left;
2299
+ };
2300
+ }
2301
+ function customValue(T) {
2302
+ const $ = this;
2303
+ return (ctx = {}) => {
2304
+ if ($.isType(T.LParen) || $.isType(T.FunctionStart) || $.isType(T.FunctionalPseudoClass) || $.isType(T.LSquare) || $.isType(T.LCurly)) return $.SUBRULE($.customBlock, { ARGS: [ctx] });
2305
+ if ($.isType(T.SingleQuoteStart) || $.isType(T.DoubleQuoteStart)) return $.SUBRULE($.string, { ARGS: [ctx] });
2306
+ let token;
2307
+ if ($.isType(T.Value)) token = $.CONSUME(T.Value);
2308
+ else if ($.isType(T.PlainIdent)) token = $.CONSUME(T.PlainIdent);
2309
+ else if ($.isType(T.AtKeyword)) token = $.CONSUME(T.AtKeyword);
2310
+ else if ($.isType(T.PropertyReference)) token = $.CONSUME(T.PropertyReference);
2311
+ else if ($.isType(T.CustomProperty)) token = $.CONSUME(T.CustomProperty);
2312
+ else if ($.isType(T.Dimension)) token = $.CONSUME(T.Dimension);
2313
+ else if ($.isType(T.Number)) token = $.CONSUME(T.Number);
2314
+ else if ($.isType(T.Color)) token = $.CONSUME(T.Color);
2315
+ else if ($.isType(T.UnicodeRange)) token = $.CONSUME(T.UnicodeRange);
2316
+ else if ($.isType(T.Colon)) token = $.CONSUME(T.Colon);
2317
+ else if ($.isType(T.Comma)) token = $.CONSUME(T.Comma);
2318
+ else if ($.isType(T.Important)) token = $.CONSUME(T.Important);
2319
+ else token = $.CONSUME(T.Unknown);
2320
+ if (!$.RECORDING_PHASE) return $.wrap($.processValueToken(token, ctx), void 0, ctx);
2321
+ };
2322
+ }
2323
+ function innerCustomValue(T) {
2324
+ const $ = this;
2325
+ return (ctx = {}) => {
2326
+ if ($.isType(T.Semi)) {
2327
+ const semi = $.CONSUME(T.Semi);
2328
+ if ($.RECORDING_PHASE) return;
2329
+ return $.wrap(new Any(semi.image, { role: "semi" }, $.getLocationInfo(semi), $.context));
2330
+ }
2331
+ return $.SUBRULE($.customValue, { ARGS: [ctx] });
2332
+ };
2333
+ }
2334
+ function customBlock(T) {
2335
+ const $ = this;
2336
+ return (ctx = {}) => {
2337
+ const RECORDING_PHASE = $.RECORDING_PHASE;
2338
+ $.startRule();
2339
+ let start;
2340
+ let end;
2341
+ let nodes;
2342
+ if (!RECORDING_PHASE) nodes = [];
2343
+ if ($.isType(T.LParen)) {
2344
+ start = $.CONSUME(T.LParen);
2345
+ while (!$.isType(T.RParen) && (startsCustomValueToken($, T) || $.isType(T.Semi))) {
2346
+ const val = $.SUBRULE($.innerCustomValue, { ARGS: [ctx] });
2347
+ if (!RECORDING_PHASE) nodes.push(val);
2348
+ }
2349
+ end = $.CONSUME(T.RParen);
2350
+ } else if ($.isType(T.FunctionStart) || $.isType(T.FunctionalPseudoClass)) {
2351
+ start = $.isType(T.FunctionStart) ? $.CONSUME(T.FunctionStart) : $.CONSUME(T.FunctionalPseudoClass);
2352
+ while (!$.isType(T.RParen) && (startsCustomValueToken($, T) || $.isType(T.Semi))) {
2353
+ const val = $.SUBRULE2($.innerCustomValue, { ARGS: [ctx] });
2354
+ if (!RECORDING_PHASE) nodes.push(val);
2355
+ }
2356
+ end = $.CONSUME2(T.RParen);
2357
+ } else if ($.isType(T.LSquare)) {
2358
+ start = $.CONSUME(T.LSquare);
2359
+ while (!$.isType(T.RSquare) && (startsCustomValueToken($, T) || $.isType(T.Semi))) {
2360
+ const val = $.SUBRULE3($.innerCustomValue, { ARGS: [ctx] });
2361
+ if (!RECORDING_PHASE) nodes.push(val);
2362
+ }
2363
+ end = $.CONSUME(T.RSquare);
2364
+ } else {
2365
+ start = $.CONSUME(T.LCurly);
2366
+ while (!$.isType(T.RCurly) && (startsCustomValueToken($, T) || $.isType(T.Semi))) {
2367
+ const val = $.SUBRULE4($.innerCustomValue, { ARGS: [ctx] });
2368
+ if (!RECORDING_PHASE) nodes.push(val);
2369
+ }
2370
+ end = $.CONSUME(T.RCurly);
2371
+ }
2372
+ if (RECORDING_PHASE) return;
2373
+ const location = $.endRule();
2374
+ let type;
2375
+ switch (start.image) {
2376
+ case "[":
2377
+ type = "square";
2378
+ break;
2379
+ case "{":
2380
+ type = "curly";
2381
+ break;
2382
+ }
2383
+ if (type) {
2384
+ const seqLoc = nodes.length ? $.getLocationFromNodes(nodes) : void 0;
2385
+ const seq = new Sequence(nodes, void 0, seqLoc, $.context);
2386
+ return $.wrap(new Block($.wrap(seq, true, ctx), { type }, location, $.context), void 0, ctx);
2387
+ }
2388
+ const startNode = $.wrap(new Any(start.image, { role: "any" }, $.getLocationInfo(start), $.context), void 0, ctx);
2389
+ const endNode = $.wrap(new Any(end.image, { role: "any" }, $.getLocationInfo(end), $.context), void 0, ctx);
2390
+ return new Sequence([
2391
+ startNode,
2392
+ ...nodes,
2393
+ endNode
2394
+ ], void 0, location, $.context);
2395
+ };
2396
+ }
2397
+ function expressionValue(T) {
2398
+ const $ = this;
2399
+ return (ctx = {}) => {
2400
+ $.startRule();
2401
+ /** Can create a negative expression */
2402
+ let minus = $.OPTION(() => $.CONSUME(T.Minus));
2403
+ let node = $.OR([{ ALT: () => {
2404
+ $.startRule();
2405
+ let escape;
2406
+ $.OPTION2(() => {
2407
+ escape = $.CONSUME(T.Tilde);
2408
+ });
2409
+ $.CONSUME(T.LParen);
2410
+ const innerCtx = {
2411
+ ...ctx,
2412
+ inner: true,
2413
+ allowComma: true,
2414
+ parenFrames: [...getParenFrames$1(ctx), true]
2415
+ };
2416
+ let node = $.SUBRULE($.valueList, { ARGS: [innerCtx] });
2417
+ let isSemiList = false;
2418
+ if (escape) {
2419
+ let semiNodes = [];
2420
+ $.OPTION3(() => {
2421
+ $.CONSUME(T.Semi);
2422
+ isSemiList = true;
2423
+ semiNodes.push($.wrap(node, true));
2424
+ node = $.SUBRULE2($.valueList, { ARGS: [innerCtx] });
2425
+ semiNodes.push($.wrap(node, true));
2426
+ $.MANY({
2427
+ GATE: () => $.isType(T.Semi),
2428
+ DEF: () => {
2429
+ $.CONSUME2(T.Semi);
2430
+ node = $.SUBRULE3($.valueList, { ARGS: [innerCtx] });
2431
+ semiNodes.push($.wrap(node, true));
2432
+ }
2433
+ });
2434
+ });
2435
+ if (isSemiList) node = new List(semiNodes, { sep: ";" });
2436
+ }
2437
+ $.CONSUME(T.RParen);
2438
+ let location = $.endRule();
2439
+ node = $.wrap(node, "both");
2440
+ return new Paren(node, { escaped: !!escape }, location, $.context);
2441
+ } }, { ALT: () => $.SUBRULE($.value, { ARGS: [ctx] }) }]);
2442
+ let location = $.endRule();
2443
+ if (minus) return new Negative(node, void 0, location, $.context);
2444
+ return node;
2445
+ };
2446
+ }
2447
+ /**
2448
+ * Add interpolation
2449
+ */
2450
+ function nthValue(T) {
2451
+ const $ = this;
2452
+ return (ctx = {}) => {
2453
+ let nthValueAlt = (ctx = {}) => [
2454
+ { ALT: () => $.CONSUME(T.InterpolatedIdent) },
2455
+ { ALT: () => $.CONSUME(T.NthOdd) },
2456
+ { ALT: () => $.CONSUME(T.NthEven) },
2457
+ { ALT: () => $.CONSUME(T.Integer) },
2458
+ { ALT: () => {
2459
+ $.OR2([
2460
+ { ALT: () => $.CONSUME(T.NthSignedDimension) },
2461
+ { ALT: () => $.CONSUME(T.NthUnsignedDimension) },
2462
+ { ALT: () => $.CONSUME(T.NthSignedPlus) },
2463
+ { ALT: () => $.CONSUME(T.NthIdent) }
2464
+ ]);
2465
+ $.OPTION(() => {
2466
+ $.OR3([{ ALT: () => $.CONSUME(T.SignedInt) }, { ALT: () => {
2467
+ $.CONSUME(T.Minus);
2468
+ $.CONSUME(T.UnsignedInt);
2469
+ } }]);
2470
+ });
2471
+ $.OPTION2(() => {
2472
+ $.CONSUME(T.Of);
2473
+ $.SUBRULE($.complexSelector, { ARGS: [ctx] });
2474
+ });
2475
+ } }
2476
+ ];
2477
+ return cssNthValue.call($, T, nthValueAlt)(ctx);
2478
+ };
2479
+ }
2480
+ function knownFunctions(T) {
2481
+ const $ = this;
2482
+ return (ctx = {}) => {
2483
+ let functions = (ctx = {}) => [
2484
+ { ALT: () => $.SUBRULE($.urlFunction, { ARGS: [ctx] }) },
2485
+ { ALT: () => $.SUBRULE2($.varFunction, { ARGS: [ctx] }) },
2486
+ { ALT: () => $.SUBRULE3($.calcFunction, { ARGS: [ctx] }) },
2487
+ { ALT: () => $.SUBRULE4($.ifFunction, { ARGS: [ctx] }) },
2488
+ { ALT: () => $.SUBRULE5($.booleanFunction, { ARGS: [ctx] }) }
2489
+ ];
2490
+ return cssKnownFunctions.call($, T, functions)(ctx);
2491
+ };
2492
+ }
2493
+ function urlFunction(T) {
2494
+ const $ = this;
2495
+ return (ctx = {}) => {
2496
+ $.startRule();
2497
+ $.CONSUME(T.UrlStart);
2498
+ let node = $.OR([
2499
+ { ALT: () => $.SUBRULE($.string, { ARGS: [ctx] }) },
2500
+ { ALT: () => $.SUBRULE($.varReference, { ARGS: [ctx] }) },
2501
+ { ALT: () => $.CONSUME(T.NonQuotedUrl) }
2502
+ ]);
2503
+ $.CONSUME(T.UrlEnd);
2504
+ if ($.RECORDING_PHASE) return;
2505
+ const location = $.endRule();
2506
+ if (!(node instanceof Node)) {
2507
+ const rawValue = node.image;
2508
+ const tokenLocation = $.getLocationInfo(node);
2509
+ if (rawValue.startsWith("@") || rawValue.startsWith("$")) {
2510
+ const resolved = getInterpolatedOrString(rawValue, tokenLocation, $.context);
2511
+ if (resolved instanceof Interpolated) node = resolved;
2512
+ else node = new Reference(resolved, { type: rawValue.startsWith("$") ? "property" : "variable" }, tokenLocation, $.context);
2513
+ } else node = new Any(rawValue, { role: "urlvalue" }, tokenLocation, $.context);
2514
+ }
2515
+ return new Url(node, void 0, location, $.context);
2516
+ };
2517
+ }
2518
+ /**
2519
+ * Override CSS calc() parsing so we can maintain parse-time `calcFrames`.
2520
+ * This is the parse-time analogue of `Call.evalNode`'s calcFrames++/--.
2521
+ */
2522
+ function calcFunction(T) {
2523
+ const $ = this;
2524
+ return (ctx = {}) => {
2525
+ $.startRule();
2526
+ $.CONSUME(T.Calc);
2527
+ const innerCtx = withCalcFrame(ctx, 1);
2528
+ const args = $.SUBRULE($.mathSum, { ARGS: [innerCtx] });
2529
+ $.CONSUME(T.RParen);
2530
+ const location = $.endRule();
2531
+ return new Call({
2532
+ name: "calc",
2533
+ args: new List([args])
2534
+ }, void 0, location, $.context);
2535
+ };
2536
+ }
2537
+ function ifFunction(T) {
2538
+ const $ = this;
2539
+ return (ctx = {}) => {
2540
+ $.startRule();
2541
+ let name = $.CONSUME(T.IfFunction);
2542
+ let args = new List([]);
2543
+ let isCssBranch = false;
2544
+ const firstNode = $.SUBRULE($.guardInner, { ARGS: [{
2545
+ ...ctx,
2546
+ inValueList: true
2547
+ }] });
2548
+ if ($.isType(T.Assign)) {
2549
+ isCssBranch = true;
2550
+ const branches = [];
2551
+ const pushBranch = (condition, value) => {
2552
+ const sep = $.wrap(new Any(":", { role: "operator" }, void 0, $.context), true);
2553
+ const loc = $.getLocationFromNodes([condition, value]);
2554
+ branches.push(new Sequence([
2555
+ $.wrap(condition, true),
2556
+ sep,
2557
+ $.wrap(value, true)
2558
+ ], void 0, loc, $.context));
2559
+ };
2560
+ $.CONSUME(T.Assign);
2561
+ pushBranch(firstNode, $.SUBRULE($.valueList, { ARGS: [{
2562
+ ...ctx,
2563
+ inner: true
2564
+ }] }));
2565
+ $.MANY({
2566
+ GATE: () => $.isType(T.Semi) && !$.isTypeAt(2, T.RParen),
2567
+ DEF: () => {
2568
+ $.CONSUME2(T.Semi);
2569
+ const condition = $.SUBRULE2($.guardInner, { ARGS: [{
2570
+ ...ctx,
2571
+ inValueList: true
2572
+ }] });
2573
+ $.CONSUME2(T.Assign);
2574
+ pushBranch(condition, $.SUBRULE2($.valueList, { ARGS: [{
2575
+ ...ctx,
2576
+ inner: true
2577
+ }] }));
2578
+ }
2579
+ });
2580
+ $.OPTION(() => $.CONSUME3(T.Semi));
2581
+ $.CONSUME2(T.RParen);
2582
+ args = new List([branches.length === 1 ? branches[0] : new List(branches, { sep: ";" }, $.getLocationFromNodes(branches), $.context)]);
2583
+ } else {
2584
+ isCssBranch = false;
2585
+ let node = firstNode;
2586
+ const parenValue = node instanceof Paren ? node.get("value") : void 0;
2587
+ args = new List([parenValue instanceof Node ? parenValue : node]);
2588
+ $.OR([{ ALT: () => {
2589
+ $.CONSUME(T.Semi);
2590
+ node = $.SUBRULE2($.valueList, { ARGS: [{
2591
+ ...ctx,
2592
+ allowAnonymousMixins: true
2593
+ }] });
2594
+ args = new List([...args.value, node], args.options, $.getLocationFromNodes([...args.value, node]), $.context);
2595
+ $.OPTION(() => {
2596
+ $.CONSUME4(T.Semi);
2597
+ node = $.SUBRULE3($.valueList, { ARGS: [{
2598
+ ...ctx,
2599
+ allowAnonymousMixins: true
2600
+ }] });
2601
+ args = new List([...args.value, node], args.options, $.getLocationFromNodes([...args.value, node]), $.context);
2602
+ });
2603
+ } }, { ALT: () => {
2604
+ $.CONSUME(T.Comma);
2605
+ node = $.SUBRULE($.callArgument, { ARGS: [{
2606
+ ...ctx,
2607
+ allowAnonymousMixins: true
2608
+ }] });
2609
+ args = new List([...args.value, node], args.options, $.getLocationFromNodes([...args.value, node]), $.context);
2610
+ $.OPTION2(() => {
2611
+ $.CONSUME2(T.Comma);
2612
+ node = $.SUBRULE2($.callArgument, { ARGS: [{
2613
+ ...ctx,
2614
+ allowAnonymousMixins: true
2615
+ }] });
2616
+ args = new List([...args.value, node], args.options, $.getLocationFromNodes([...args.value, node]), $.context);
2617
+ });
2618
+ } }]);
2619
+ $.CONSUME3(T.RParen);
2620
+ }
2621
+ let location = $.endRule();
2622
+ return new Call({
2623
+ name: new Reference("if", {
2624
+ type: "function",
2625
+ fallbackValue: isCssBranch ? true : void 0
2626
+ }, $.getLocationInfo(name), $.context),
2627
+ args
2628
+ }, void 0, location, $.context);
2629
+ };
2630
+ }
2631
+ function booleanFunction(T) {
2632
+ const $ = this;
2633
+ return (ctx = {}) => {
2634
+ $.startRule();
2635
+ $.CONSUME(T.BooleanFunction);
2636
+ let arg = $.SUBRULE($.guardInner, { ARGS: [{
2637
+ ...ctx,
2638
+ inValueList: true
2639
+ }] });
2640
+ $.CONSUME(T.RParen);
2641
+ let location = $.endRule();
2642
+ const argValue = arg instanceof Paren ? arg.get("value") : void 0;
2643
+ return new Expression(argValue instanceof Node ? argValue : arg, { parens: true }, location, $.context);
2644
+ };
2645
+ }
2646
+ function varReference(T) {
2647
+ const $ = this;
2648
+ return (ctx = {}) => {
2649
+ let node = $.OR([
2650
+ { ALT: () => {
2651
+ let token = $.CONSUME(T.PropertyReference);
2652
+ if ($.RECORDING_PHASE) return;
2653
+ if (ctx.inCustomPropertyValue) {
2654
+ const atName = token.image;
2655
+ const ident = token.image.slice(1);
2656
+ $.warnDeprecation(`${atName} in custom property values is treated as literal text, not a property reference. Use \${${ident}} if you want it to be evaluated.`, token, "property-in-unknown-value");
2657
+ return new Reference({ key: token.image.slice(1) }, {
2658
+ type: "property",
2659
+ role: "ident"
2660
+ }, $.getLocationInfo(token), $.context);
2661
+ }
2662
+ return new Reference(token.image.slice(1), { type: "property" }, $.getLocationInfo(token), $.context);
2663
+ } },
2664
+ { ALT: () => {
2665
+ let token = $.CONSUME(T.NestedReference);
2666
+ if ($.RECORDING_PHASE) return;
2667
+ const raw = token.image;
2668
+ const type = raw.startsWith("@") ? "variable" : "property";
2669
+ const key = getInterpolatedOrString(raw);
2670
+ if (ctx.inCustomPropertyValue && typeof key === "string") return new Reference({ key }, {
2671
+ type: "variable",
2672
+ role: "ident"
2673
+ }, $.getLocationInfo(token), $.context);
2674
+ if (typeof key === "string") return new Reference(key, { type }, $.getLocationInfo(token), $.context);
2675
+ return new Reference({ key }, { type }, $.getLocationInfo(token), $.context);
2676
+ } },
2677
+ { ALT: () => {
2678
+ let token = $.SUBRULE($.varName, { ARGS: [ctx] });
2679
+ if ($.RECORDING_PHASE) return;
2680
+ if (ctx.inCustomPropertyValue) {
2681
+ const atName = token.image;
2682
+ const ident = token.image.slice(1);
2683
+ $.warnDeprecation(`${atName} in custom property values is treated as literal text, not a variable reference. Use @{${ident}} if you want it to be evaluated.`, token, "variable-in-unknown-value");
2684
+ return new Reference({ key: token.image.slice(1) }, {
2685
+ type: "variable",
2686
+ role: "ident"
2687
+ }, $.getLocationInfo(token), $.context);
2688
+ }
2689
+ return new Reference(token.image.slice(1), { type: "variable" }, $.getLocationInfo(token), $.context);
2690
+ } }
2691
+ ]);
2692
+ $.OR2([
2693
+ { ALT: () => {
2694
+ /** This spreads a (list) value within a containing list when evaluated */
2695
+ let token = $.CONSUME(T.Ellipsis);
2696
+ if (!$.RECORDING_PHASE) node = new Rest(node, void 0, $.getLocationFromNodes([node, token]), $.context);
2697
+ } },
2698
+ {
2699
+ GATE: () => {
2700
+ if (node?.options?.type !== "variable") return false;
2701
+ let next = $.LA(1).tokenType;
2702
+ if (next !== T.LSquare && next !== T.LParen) return false;
2703
+ if (!$.noSep()) return false;
2704
+ return true;
2705
+ },
2706
+ ALT: () => {
2707
+ $.AT_LEAST_ONE({
2708
+ GATE: () => {
2709
+ let next = $.LA(1).tokenType;
2710
+ if (next !== T.LSquare && next !== T.LParen) return false;
2711
+ if (!$.noSep()) return false;
2712
+ return true;
2713
+ },
2714
+ DEF: () => {
2715
+ node = $.SUBRULE($.lookupOrCall, { ARGS: [{
2716
+ ...ctx,
2717
+ node
2718
+ }] });
2719
+ }
2720
+ });
2721
+ $.OPTION(() => {
2722
+ $.OPTION2(() => $.CONSUME(T.Gt));
2723
+ node = $.SUBRULE($.mixinReference, { ARGS: [{
2724
+ ...ctx,
2725
+ node
2726
+ }] });
2727
+ });
2728
+ }
2729
+ },
2730
+ { ALT: () => void 0 }
2731
+ ]);
2732
+ return $.wrap(node);
2733
+ };
2734
+ }
2735
+ function valueReference(T) {
2736
+ const $ = this;
2737
+ return (ctx = {}) => {
2738
+ return $.OR([{ ALT: () => $.SUBRULE($.varReference, { ARGS: [ctx] }) }, { ALT: () => $.SUBRULE2($.mixinReference, { ARGS: [ctx] }) }]);
2739
+ };
2740
+ }
2741
+ function functionCall(T) {
2742
+ const $ = this;
2743
+ return (ctx = {}) => {
2744
+ const modernColorFunctions = new Set([
2745
+ "rgb",
2746
+ "rgba",
2747
+ "hsl",
2748
+ "hsla"
2749
+ ]);
2750
+ const isModernColorCall = (name, args) => {
2751
+ if (!modernColorFunctions.has(name.toLowerCase())) return false;
2752
+ if (!args || args.value.length !== 1) return false;
2753
+ const firstArg = args.value[0];
2754
+ return Boolean(isNode(firstArg, N.Sequence) && firstArg.value.length >= 2);
2755
+ };
2756
+ let funcAlt = (ctx = {}) => [{
2757
+ GATE: () => {
2758
+ let tokenType = $.LA(1).tokenType;
2759
+ return tokenType === T.UrlStart || tokenType === T.Var || tokenType === T.Calc || tokenType === T.IfFunction || tokenType === T.BooleanFunction;
2760
+ },
2761
+ ALT: () => $.SUBRULE($.knownFunctions, { ARGS: [ctx] })
2762
+ }, {
2763
+ GATE: () => {
2764
+ let tokenType = $.LA(1).tokenType;
2765
+ return tokenType !== T.UrlStart && tokenType !== T.Var && tokenType !== T.Calc && tokenType !== T.IfFunction && tokenType !== T.BooleanFunction;
2766
+ },
2767
+ ALT: () => {
2768
+ $.startRule();
2769
+ const fnStart = $.CONSUME(T.FunctionStart);
2770
+ const fnNameForCtx = fnStart.image.slice(0, -1);
2771
+ let args;
2772
+ $.OPTION(() => args = $.SUBRULE2($.functionCallArgs, { ARGS: [{
2773
+ ...ctx,
2774
+ currentFunctionName: fnNameForCtx
2775
+ }] }));
2776
+ $.CONSUME(T.RParen);
2777
+ const location = $.endRule();
2778
+ const nameValue = fnNameForCtx;
2779
+ if (nameValue === "unit" && args?.value[1] instanceof Any) {
2780
+ const unitArg = args.value[1];
2781
+ const quotedUnit = new Quoted(unitArg.valueOf(), { quote: "\"" }, void 0, $.context);
2782
+ quotedUnit.pre = unitArg.pre;
2783
+ quotedUnit.post = unitArg.post;
2784
+ const newArgsData = [...args.value];
2785
+ newArgsData[1] = quotedUnit;
2786
+ args = new List(newArgsData, args.options, $.getLocationFromNodes(newArgsData), $.context);
2787
+ }
2788
+ const nameNode = new Reference(nameValue, {
2789
+ type: "function",
2790
+ fallbackValue: true
2791
+ }, $.getLocationInfo(fnStart), $.context);
2792
+ /** Less / Sass functions we try to call that throw just get turned into calls. */
2793
+ const modernSyntax = isModernColorCall(nameValue, args);
2794
+ return new Call({
2795
+ name: nameNode,
2796
+ args
2797
+ }, {
2798
+ silentFail: true,
2799
+ ...modernSyntax ? { modernSyntax: true } : {}
2800
+ }, location, $.context);
2801
+ }
2802
+ }];
2803
+ return $.OR(funcAlt(ctx));
2804
+ };
2805
+ }
2806
+ function functionCallArgs(T) {
2807
+ const $ = this;
2808
+ return (ctx = {}) => {
2809
+ $.startRule();
2810
+ const prevInner = ctx.inner;
2811
+ ctx.inner = true;
2812
+ const argCtx = {
2813
+ ...ctx,
2814
+ allowComma: false,
2815
+ parenFrames: [...getParenFrames$1(ctx), false],
2816
+ detachedRulesetUsage: "function-arg",
2817
+ inFunctionArgs: true
2818
+ };
2819
+ let commaNodes;
2820
+ let semiNodes = [];
2821
+ let isSemiList = false;
2822
+ try {
2823
+ let node = $.SUBRULE($.callArgument, { ARGS: [argCtx] });
2824
+ commaNodes = [$.wrap(node, true)];
2825
+ $.MANY({
2826
+ GATE: () => $.isType(T.Comma),
2827
+ DEF: () => {
2828
+ $.CONSUME(T.Comma);
2829
+ node = $.SUBRULE2($.callArgument, { ARGS: [argCtx] });
2830
+ commaNodes.push($.wrap(node, true));
2831
+ }
2832
+ });
2833
+ $.OPTION(() => {
2834
+ $.CONSUME(T.Semi);
2835
+ isSemiList = true;
2836
+ if (commaNodes.length > 1) semiNodes.push(new List(commaNodes, void 0, $.getLocationFromNodes(commaNodes), $.context));
2837
+ else semiNodes.push(commaNodes[0]);
2838
+ node = $.SUBRULE3($.callArgument, { ARGS: [{
2839
+ ...argCtx,
2840
+ allowComma: true
2841
+ }] });
2842
+ semiNodes.push($.wrap(node, true));
2843
+ $.MANY2({
2844
+ GATE: () => $.isType(T.Semi),
2845
+ DEF: () => {
2846
+ $.CONSUME2(T.Semi);
2847
+ node = $.SUBRULE4($.callArgument, { ARGS: [{
2848
+ ...argCtx,
2849
+ allowComma: true
2850
+ }] });
2851
+ semiNodes.push($.wrap(node, true));
2852
+ }
2853
+ });
2854
+ });
2855
+ } finally {
2856
+ ctx.inner = prevInner;
2857
+ }
2858
+ $.endRule();
2859
+ return new List(isSemiList ? semiNodes : commaNodes, isSemiList ? { sep: ";" } : void 0);
2860
+ };
2861
+ }
2862
+ function value(T) {
2863
+ const $ = this;
2864
+ return (ctx = {}) => {
2865
+ if ($.isType(T.Percent)) {}
2866
+ let _isMixinReference = void 0;
2867
+ const isMixinReference = () => {
2868
+ if (_isMixinReference === void 0) {
2869
+ let tt1 = $.LA(1).tokenType;
2870
+ let tt2 = $.LA(2).tokenType;
2871
+ /**
2872
+ * We'll allow a few "bare" mixin references without parens
2873
+ * or square brackets, but not if they'll conflict with
2874
+ * other syntax.
2875
+ */
2876
+ _isMixinReference = tt1 === T.DotName || tt1 === T.HashName || tt1 === T.InterpolatedSelector || (tt1 === T.ColorIdentStart || tt1 === T.InterpolatedSelector) && (tt2 === T.Gt || tt2 === T.DotName || tt2 === T.HashName || tt2 === T.InterpolatedSelector || $.noSep(1) && (tt2 === T.LParen || tt2 === T.LSquare || tt2 === T.HashName || tt2 === T.DotName));
2877
+ }
2878
+ return _isMixinReference;
2879
+ };
2880
+ let node = $.OR([
2881
+ {
2882
+ GATE: () => $.check(T.FunctionStart),
2883
+ ALT: () => $.SUBRULE($.functionCall, { ARGS: [ctx] })
2884
+ },
2885
+ {
2886
+ GATE: () => $.isType(T.Star) && $.isTypeAt(2, T.LSquare),
2887
+ ALT: () => $.SUBRULE($.selectorCapture, { ARGS: [ctx] })
2888
+ },
2889
+ {
2890
+ GATE: isMixinReference,
2891
+ ALT: () => $.SUBRULE($.mixinReference, { ARGS: [ctx] })
2892
+ },
2893
+ {
2894
+ GATE: () => !isMixinReference(),
2895
+ ALT: () => $.CONSUME(T.Color)
2896
+ },
2897
+ {
2898
+ GATE: () => !isMixinReference(),
2899
+ ALT: () => $.CONSUME2(T.Ident)
2900
+ },
2901
+ { ALT: () => $.SUBRULE($.varReference, { ARGS: [ctx] }) },
2902
+ { ALT: () => $.CONSUME(T.DefaultGuardFunc) },
2903
+ { ALT: () => $.CONSUME(T.Dimension) },
2904
+ { ALT: () => $.CONSUME(T.Number) },
2905
+ {
2906
+ GATE: () => ctx.currentFunctionName === "unit",
2907
+ ALT: () => $.CONSUME(T.Percent)
2908
+ },
2909
+ { ALT: () => $.CONSUME(T.UnicodeRange) },
2910
+ { ALT: () => $.SUBRULE($.string, { ARGS: [ctx] }) },
2911
+ { ALT: () => $.CONSUME(T.JavaScript) },
2912
+ (
2913
+ /** Explicitly not marked as an ident */
2914
+ { ALT: () => $.CONSUME(T.When) }),
2915
+ { ALT: () => $.SUBRULE($.squareValue, { ARGS: [ctx] }) },
2916
+ {
2917
+ GATE: () => $.looseMode && !!ctx.inner,
2918
+ ALT: () => $.CONSUME(T.Colon)
2919
+ },
2920
+ {
2921
+ GATE: () => $.looseMode && !!ctx.inFunctionArgs,
2922
+ ALT: () => $.CONSUME(T.Eq)
2923
+ },
2924
+ {
2925
+ GATE: () => $.looseMode,
2926
+ ALT: () => $.CONSUME(T.Unknown)
2927
+ },
2928
+ {
2929
+ GATE: () => $.legacyMode,
2930
+ ALT: () => $.CONSUME(T.LegacyMSFilter)
2931
+ }
2932
+ ]);
2933
+ if (!$.RECORDING_PHASE) {
2934
+ if (!(node instanceof Node)) node = $.processValueToken(node);
2935
+ return $.wrap(node);
2936
+ }
2937
+ };
2938
+ }
2939
+ function string(T) {
2940
+ const $ = this;
2941
+ return (ctx = {}) => {
2942
+ return $.OR([{
2943
+ GATE: () => $.isType(T.SingleQuoteStart),
2944
+ ALT: () => {
2945
+ $.startRule();
2946
+ let quote = $.CONSUME(T.SingleQuoteStart);
2947
+ let contents;
2948
+ $.OPTION2(() => contents = $.CONSUME(T.SingleQuoteStringContents));
2949
+ $.CONSUME(T.SingleQuoteEnd);
2950
+ let quoteImg = quote.image;
2951
+ let escaped = false;
2952
+ if (quoteImg.startsWith("~")) {
2953
+ escaped = true;
2954
+ quoteImg = quoteImg.slice(1);
2955
+ }
2956
+ let location = $.endRule();
2957
+ let value = contents?.image;
2958
+ if (escaped && value) value = value.replace(/\\(?:\r\n?|\n|\f)/g, "\n");
2959
+ const quoteChar = quoteImg;
2960
+ if (value && (value.includes("@{") || value.includes("${"))) return new Quoted(processStringInterpolation(value, location, $.context), {
2961
+ quote: quoteChar,
2962
+ escaped
2963
+ }, location, $.context);
2964
+ return new Quoted(new Any(value ?? "", { role: "any" }), {
2965
+ quote: quoteChar,
2966
+ escaped
2967
+ }, location, $.context);
2968
+ }
2969
+ }, {
2970
+ GATE: () => $.isType(T.DoubleQuoteStart),
2971
+ ALT: () => {
2972
+ $.startRule();
2973
+ let quote = $.CONSUME(T.DoubleQuoteStart);
2974
+ let contents;
2975
+ $.OPTION3(() => contents = $.CONSUME(T.DoubleQuoteStringContents));
2976
+ $.CONSUME(T.DoubleQuoteEnd);
2977
+ let quoteImg = quote.image;
2978
+ let escaped = false;
2979
+ if (quoteImg.startsWith("~")) {
2980
+ escaped = true;
2981
+ quoteImg = quoteImg.slice(1);
2982
+ }
2983
+ let location = $.endRule();
2984
+ let value = contents?.image;
2985
+ if (escaped && value) value = value.replace(/\\(?:\r\n?|\n|\f)/g, "\n");
2986
+ const quoteChar = quoteImg;
2987
+ if (value && (value.includes("@{") || value.includes("${"))) return new Quoted(processStringInterpolation(value, location, $.context), {
2988
+ quote: quoteChar,
2989
+ escaped
2990
+ }, location, $.context);
2991
+ return new Quoted(new Any(value ?? "", { role: "any" }), {
2992
+ quote: quoteChar,
2993
+ escaped
2994
+ }, location, $.context);
2995
+ }
2996
+ }]);
2997
+ };
2998
+ }
2999
+ /**
3000
+ * Find interpolation patterns like @{...} or ${...}, handling nested braces.
3001
+ * Returns an array of { start, end, prefix, content } for each match.
3002
+ */
3003
+ function findInterpolations(value) {
3004
+ const matches = [];
3005
+ let i = 0;
3006
+ while (i < value.length) if ((value[i] === "@" || value[i] === "$") && value[i + 1] === "{") {
3007
+ const prefix = value[i];
3008
+ const start = i;
3009
+ i += 2;
3010
+ let braceCount = 1;
3011
+ const contentStart = i;
3012
+ while (i < value.length && braceCount > 0) {
3013
+ if (value[i] === "{") braceCount++;
3014
+ else if (value[i] === "}") braceCount--;
3015
+ i++;
3016
+ }
3017
+ if (braceCount === 0) {
3018
+ const content = value.slice(contentStart, i - 1);
3019
+ matches.push({
3020
+ start,
3021
+ end: i,
3022
+ prefix,
3023
+ content
3024
+ });
3025
+ }
3026
+ } else i++;
3027
+ return matches;
3028
+ }
3029
+ function processStringInterpolation(value, location, context) {
3030
+ const matches = findInterpolations(value);
3031
+ if (matches.length === 0) return new Any(value, { role: "any" }, location, context);
3032
+ const replacements = [];
3033
+ let source = value;
3034
+ let offset = 0;
3035
+ for (const match of matches) {
3036
+ const adjustedStart = match.start - offset;
3037
+ const adjustedEnd = match.end - offset;
3038
+ const before = source.slice(0, adjustedStart);
3039
+ const after = source.slice(adjustedEnd);
3040
+ source = before + INTERPOLATION_PLACEHOLDER + after;
3041
+ offset += match.end - match.start - INTERPOLATION_PLACEHOLDER.length;
3042
+ const innerResult = processStringInterpolation(match.content, location, context);
3043
+ if (innerResult instanceof Interpolated) {
3044
+ const nestedRef = new Reference({ key: innerResult }, {
3045
+ type: "variable",
3046
+ role: "ident"
3047
+ }, location, context);
3048
+ replacements.push(new Expression(nestedRef, void 0, location, context));
3049
+ } else replacements.push(createInterpolatedReference$1(match.prefix, match.content, location, context));
3050
+ }
3051
+ return new Interpolated({
3052
+ source,
3053
+ replacements
3054
+ }, { role: "ident" }, location, context);
3055
+ }
3056
+ function mathValue(T) {
3057
+ const $ = this;
3058
+ return (ctx = {}) => {
3059
+ let valueAlt = (ctx = {}) => [
3060
+ { ALT: () => $.CONSUME(T.AtKeyword) },
3061
+ { ALT: () => $.CONSUME(T.Number) },
3062
+ { ALT: () => $.CONSUME(T.Dimension) },
3063
+ { ALT: () => $.CONSUME(T.Ident) },
3064
+ { ALT: () => $.SUBRULE($.functionCall, { ARGS: [ctx] }) },
3065
+ {
3066
+ GATE: () => $.LA(1).image.startsWith("~"),
3067
+ ALT: () => $.SUBRULE2($.string, { ARGS: [ctx] })
3068
+ },
3069
+ {
3070
+ GATE: () => !$.isTypeAt(2, T.LParen),
3071
+ ALT: () => $.CONSUME(T.MathConstant)
3072
+ },
3073
+ { ALT: () => $.SUBRULE($.mathParen, { ARGS: [ctx] }) }
3074
+ ];
3075
+ return cssMathValue.call($, T, valueAlt)(ctx);
3076
+ };
3077
+ }
3078
+ function mathProduct(T) {
3079
+ const $ = this;
3080
+ return (ctx = {}) => {
3081
+ const RECORDING_PHASE = $.RECORDING_PHASE;
3082
+ $.startRule();
3083
+ let left = $.SUBRULE($.mathValue, { ARGS: [ctx] });
3084
+ while ($.isType(T.Star) || $.isType(T.Divide)) {
3085
+ const op = $.isType(T.Star) ? $.CONSUME(T.Star) : $.CONSUME(T.Divide);
3086
+ const right = $.SUBRULE2($.mathValue, { ARGS: [ctx] });
3087
+ if (!RECORDING_PHASE) {
3088
+ const opStr = op.image;
3089
+ left = new Operation([
3090
+ left,
3091
+ opStr,
3092
+ right
3093
+ ], { inCalc: true }, void 0, $.context);
3094
+ }
3095
+ }
3096
+ if (RECORDING_PHASE) return;
3097
+ left._location = $.endRule();
3098
+ return left;
3099
+ };
3100
+ }
3101
+ function mathSum(T) {
3102
+ const $ = this;
3103
+ return (ctx = {}) => {
3104
+ const RECORDING_PHASE = $.RECORDING_PHASE;
3105
+ $.startRule();
3106
+ let left = $.SUBRULE($.mathProduct, { ARGS: [ctx] });
3107
+ $.MANY(() => {
3108
+ const op = $.CONSUME(T.AdditionOperator);
3109
+ const right = $.SUBRULE2($.mathProduct, { ARGS: [ctx] });
3110
+ if (!RECORDING_PHASE) {
3111
+ const opStr = op.image;
3112
+ left = new Operation([
3113
+ left,
3114
+ opStr,
3115
+ right
3116
+ ], { inCalc: true }, void 0, $.context);
3117
+ }
3118
+ });
3119
+ if (RECORDING_PHASE) return;
3120
+ left._location = $.endRule();
3121
+ return left;
3122
+ };
3123
+ }
3124
+ //#endregion
3125
+ //#region src/productions/guards.ts
3126
+ function getParenFrames(ctx) {
3127
+ return ctx?.parenFrames ?? [];
3128
+ }
3129
+ const interpolatedRegex = /([$@])\{([^}]+)\}/g;
3130
+ const createInterpolatedReference = (prefix, value, location, context) => {
3131
+ const isProperty = prefix === "$";
3132
+ return new Reference({ key: isProperty ? new Quoted(value, { quote: "'" }, location, context) : value }, {
3133
+ type: isProperty ? "property" : "variable",
3134
+ role: "ident"
3135
+ }, location, context);
3136
+ };
3137
+ const getInterpolated = (name, location, context) => {
3138
+ const replacements = [];
3139
+ let result;
3140
+ let source = name;
3141
+ interpolatedRegex.lastIndex = 0;
3142
+ while (result = interpolatedRegex.exec(name)) {
3143
+ const [match, propOrVar, value] = result;
3144
+ source = source.replace(match, INTERPOLATION_PLACEHOLDER);
3145
+ const reference = createInterpolatedReference(propOrVar, value, location, context);
3146
+ replacements.push(reference);
3147
+ }
3148
+ return new Interpolated({
3149
+ source,
3150
+ replacements
3151
+ }, { role: "ident" }, location, context);
3152
+ };
3153
+ function isDefaultGuardCall(node) {
3154
+ if (!node || !isNode(node, N.Call)) return false;
3155
+ const callName = node.name;
3156
+ const callNameStr = String(typeof callName === "object" && callName !== null && "valueOf" in callName ? callName.valueOf() : callName ?? "");
3157
+ if (callNameStr === "default" || callNameStr === "??") return true;
3158
+ if (callName instanceof Reference) {
3159
+ const key = callName.key;
3160
+ const keyStr = String(typeof key === "object" && key !== null && "valueOf" in key ? key.valueOf() : key ?? "");
3161
+ return keyStr === "default" || keyStr === "??";
3162
+ }
3163
+ return false;
3164
+ }
3165
+ const cssUnknownAtRule = productions.unknownAtRule;
3166
+ function isGuardComparisonToken(tt, T) {
3167
+ return tt === T.CompareOperator || tt === T.Eq || tt === T.Gt || tt === T.GtEq || tt === T.GtEqAlias || tt === T.Lt || tt === T.LtEq || tt === T.LtEqAlias;
3168
+ }
3169
+ function normalizeComparisonOperator(op) {
3170
+ if (op === "=>") return ">=";
3171
+ if (op === "=<") return "<=";
3172
+ return op;
3173
+ }
3174
+ function guard(T) {
3175
+ const $ = this;
3176
+ return (ctx = {}) => {
3177
+ $.CONSUME(T.When);
3178
+ return $.OR([{
3179
+ GATE: () => !!ctx.inValueList,
3180
+ ALT: () => $.SUBRULE($.comparison, { ARGS: [ctx] })
3181
+ }, { ALT: () => {
3182
+ ctx.allowComma = true;
3183
+ return $.SUBRULE($.guardOr, { ARGS: [ctx] });
3184
+ } }]);
3185
+ };
3186
+ }
3187
+ /**
3188
+ * 'or' expression
3189
+ * Allows an (outer) comma like historical media queries
3190
+ */
3191
+ function guardOr(T) {
3192
+ const $ = this;
3193
+ return (ctx = {}) => {
3194
+ $.startRule();
3195
+ let left = $.SUBRULE($.guardAnd, { ARGS: [ctx] });
3196
+ let right;
3197
+ $.MANY({
3198
+ GATE: () => ctx.allowComma && $.isType(T.Comma) || $.isType(T.Or),
3199
+ DEF: () => {
3200
+ /**
3201
+ * Nest expressions within expressions for correct
3202
+ * order of operations.
3203
+ */
3204
+ $.OR([{ ALT: () => $.CONSUME(T.Comma) }, { ALT: () => $.CONSUME(T.Or) }]);
3205
+ right = $.SUBRULE2($.guardAnd, { ARGS: [ctx] });
3206
+ let location = $.endRule();
3207
+ $.startRule();
3208
+ left = new Condition([
3209
+ $.wrap(left, true),
3210
+ "or",
3211
+ $.wrap(right)
3212
+ ], void 0, location, $.context);
3213
+ }
3214
+ });
3215
+ $.endRule();
3216
+ return left;
3217
+ };
3218
+ }
3219
+ function guardDefault(T) {
3220
+ const $ = this;
3221
+ return (ctx = {}) => {
3222
+ let guard = $.OR([{ ALT: () => $.CONSUME(T.DefaultGuardIdent) }, { ALT: () => $.CONSUME(T.DefaultGuardFunc) }]);
3223
+ if ($.RECORDING_PHASE) return;
3224
+ ctx.hasDefault = true;
3225
+ return new DefaultGuard(guard.image, void 0, $.getLocationInfo(guard), $.context);
3226
+ };
3227
+ }
3228
+ /**
3229
+ * 'and' and 'or' expressions
3230
+ *
3231
+ * In Media queries level 4, you cannot have
3232
+ * `([expr]) or ([expr]) and ([expr])` because
3233
+ * of evaluation order ambiguity.
3234
+ * However, Less allows it.
3235
+ */
3236
+ function guardAnd(T) {
3237
+ const $ = this;
3238
+ return (ctx = {}) => {
3239
+ let left;
3240
+ $.MANY_SEP({
3241
+ SEP: T.And,
3242
+ DEF: () => {
3243
+ let not;
3244
+ $.OPTION(() => not = $.CONSUME(T.Not));
3245
+ let allowComma = ctx.allowComma;
3246
+ ctx.allowComma = false;
3247
+ let right;
3248
+ try {
3249
+ right = $.OR([{ ALT: () => $.SUBRULE($.guardInParens, { ARGS: [ctx] }) }, {
3250
+ GATE: () => {
3251
+ const tokenType = $.LA(1).tokenType;
3252
+ return tokenType !== T.Not && tokenType !== T.DefaultGuardFunc && tokenType !== T.DefaultGuardIdent;
3253
+ },
3254
+ ALT: () => $.SUBRULE($.expressionSum, { ARGS: [ctx] })
3255
+ }]);
3256
+ $.OPTION2({
3257
+ GATE: () => isGuardComparisonToken($.LA(1).tokenType, T),
3258
+ DEF: () => {
3259
+ const op = $.CONSUME(T.CompareOperator);
3260
+ const compareRight = $.SUBRULE2($.expressionSum, { ARGS: [ctx] });
3261
+ if (!$.RECORDING_PHASE) right = new Condition([
3262
+ $.wrap(right, true),
3263
+ normalizeComparisonOperator(op.image),
3264
+ $.wrap(compareRight)
3265
+ ], void 0, $.getLocationFromNodes([right, compareRight]), $.context);
3266
+ }
3267
+ });
3268
+ } finally {
3269
+ ctx.allowComma = allowComma;
3270
+ }
3271
+ if (!$.RECORDING_PHASE) {
3272
+ if (isDefaultGuardCall(right)) {
3273
+ ctx.hasDefault = true;
3274
+ right = new DefaultGuard("default()", void 0, Array.isArray(right.location) && right.location.length === 6 ? right.location : void 0, $.context);
3275
+ }
3276
+ if (not) {
3277
+ let [, , , endOffset, endLine, endColumn] = right.location;
3278
+ let [startOffset, startLine, startColumn] = $.getLocationInfo(not);
3279
+ right = new Condition([$.wrap(right, true)], { negate: true }, [
3280
+ startOffset,
3281
+ startLine,
3282
+ startColumn,
3283
+ endOffset,
3284
+ endLine,
3285
+ endColumn
3286
+ ], $.context);
3287
+ }
3288
+ if (!left) {
3289
+ left = right;
3290
+ return;
3291
+ }
3292
+ left = new Condition([
3293
+ $.wrap(left, true),
3294
+ "and",
3295
+ $.wrap(right)
3296
+ ], void 0, $.getLocationFromNodes([left, right]), $.context);
3297
+ }
3298
+ }
3299
+ });
3300
+ return left;
3301
+ };
3302
+ }
3303
+ function guardInParens(T) {
3304
+ const $ = this;
3305
+ return (ctx) => {
3306
+ $.startRule();
3307
+ let node = $.OR([{ ALT: () => $.SUBRULE($.guardDefault, { ARGS: [ctx] }) }, { ALT: () => {
3308
+ $.CONSUME(T.LParen);
3309
+ let node = $.SUBRULE($.guardInner, { ARGS: [ctx] });
3310
+ $.CONSUME(T.RParen);
3311
+ return node;
3312
+ } }]);
3313
+ if (isDefaultGuardCall(node)) {
3314
+ ctx.hasDefault = true;
3315
+ node = new DefaultGuard("default()", void 0, Array.isArray(node.location) && node.location.length === 6 ? node.location : void 0, $.context);
3316
+ }
3317
+ node = $.wrap(node, "both");
3318
+ return new Paren(node, void 0, $.endRule(), $.context);
3319
+ };
3320
+ }
3321
+ function guardInner(_T) {
3322
+ const $ = this;
3323
+ return (ctx = {}) => {
3324
+ return $.SUBRULE($.guardOr, { ARGS: [ctx] });
3325
+ };
3326
+ }
3327
+ function guardWithConditionValue(T) {
3328
+ const $ = this;
3329
+ return (ctx = {}) => {
3330
+ if ($.isType(T.DefaultGuardIdent) || $.isType(T.DefaultGuardFunc)) {
3331
+ $.OR([{ ALT: () => $.CONSUME(T.DefaultGuardIdent) }, { ALT: () => $.CONSUME(T.DefaultGuardFunc) }]);
3332
+ return;
3333
+ }
3334
+ return $.SUBRULE($.guardInParens, { ARGS: [ctx] });
3335
+ };
3336
+ }
3337
+ function guardWithCondition(T) {
3338
+ const $ = this;
3339
+ return (ctx = {}) => {
3340
+ $.SUBRULE($.guardWithConditionValue, { ARGS: [ctx] });
3341
+ $.AT_LEAST_ONE(() => {
3342
+ $.OR([
3343
+ { ALT: () => $.CONSUME(T.Or) },
3344
+ { ALT: () => $.CONSUME(T.And) },
3345
+ { ALT: () => $.CONSUME(T.Comma) }
3346
+ ]);
3347
+ $.SUBRULE2($.guardWithConditionValue, { ARGS: [ctx] });
3348
+ });
3349
+ };
3350
+ }
3351
+ /**
3352
+ * Currently, Less only allows a single comparison expression,
3353
+ * unlike Media Queries Level 4, which allows a left and right
3354
+ * comparison.
3355
+ */
3356
+ function comparison(T) {
3357
+ const $ = this;
3358
+ return (ctx = {}) => {
3359
+ let left = $.SUBRULE($.expressionSum, { ARGS: [ctx] });
3360
+ const op = $.CONSUME(T.CompareOperator);
3361
+ let right = $.SUBRULE2($.expressionSum, { ARGS: [ctx] });
3362
+ if (isDefaultGuardCall(right)) {
3363
+ ctx.hasDefault = true;
3364
+ right = new DefaultGuard("default()", void 0, Array.isArray(right.location) && right.location.length === 6 ? right.location : void 0, $.context);
3365
+ }
3366
+ left = new Condition([
3367
+ $.wrap(left, true),
3368
+ normalizeComparisonOperator(op.image),
3369
+ $.wrap(right)
3370
+ ], void 0, $.getLocationFromNodes([left, right]), $.context);
3371
+ return left;
3372
+ };
3373
+ }
3374
+ /**
3375
+ * Less (perhaps unwisely) allows bubbling of normally document-root
3376
+ * at-rules, so we need to override CSS here.
3377
+ */
3378
+ function innerAtRule(_T) {
3379
+ const $ = this;
3380
+ return (ctx = {}) => {
3381
+ return $.OR([
3382
+ { ALT: () => $.SUBRULE($.mediaAtRule, { ARGS: [{
3383
+ ...ctx,
3384
+ inner: true
3385
+ }] }) },
3386
+ { ALT: () => $.SUBRULE($.supportsAtRule, { ARGS: [{
3387
+ ...ctx,
3388
+ inner: true
3389
+ }] }) },
3390
+ { ALT: () => $.SUBRULE($.layerAtRule, { ARGS: [{
3391
+ ...ctx,
3392
+ inner: true
3393
+ }] }) },
3394
+ { ALT: () => $.SUBRULE($.containerAtRule, { ARGS: [{
3395
+ ...ctx,
3396
+ inner: true
3397
+ }] }) },
3398
+ { ALT: () => $.SUBRULE($.keyframesAtRule, { ARGS: [{
3399
+ ...ctx,
3400
+ inner: true
3401
+ }] }) },
3402
+ { ALT: () => $.SUBRULE($.documentAtRule, { ARGS: [{
3403
+ ...ctx,
3404
+ inner: true
3405
+ }] }) },
3406
+ { ALT: () => $.SUBRULE($.importAtRule, { ARGS: [ctx] }) },
3407
+ { ALT: () => $.SUBRULE($.pageAtRule, { ARGS: [ctx] }) },
3408
+ { ALT: () => $.SUBRULE($.fontFaceAtRule, { ARGS: [ctx] }) },
3409
+ { ALT: () => $.SUBRULE($.nestedAtRule, { ARGS: [ctx] }) },
3410
+ { ALT: () => $.SUBRULE($.nonNestedAtRule, { ARGS: [ctx] }) },
3411
+ { ALT: () => $.SUBRULE($.unknownAtRule, { ARGS: [{
3412
+ ...ctx,
3413
+ inner: true
3414
+ }] }) }
3415
+ ]);
3416
+ };
3417
+ }
3418
+ /**
3419
+ * Less override: allow variable reference as the first segment of a layer-name
3420
+ * CSS: <ident> ('.' <ident>)*
3421
+ * Less: (<var-ref> | <ident>) ('.' <ident>)*
3422
+ */
3423
+ function layerName(T) {
3424
+ const $ = this;
3425
+ return (ctx = {}) => {
3426
+ $.startRule();
3427
+ let RECORDING_PHASE = $.RECORDING_PHASE;
3428
+ let nodes;
3429
+ if (!RECORDING_PHASE) nodes = [];
3430
+ const first = $.OR([{ ALT: () => $.SUBRULE($.valueReference, { ARGS: [ctx] }) }, {
3431
+ GATE: () => $.isType(T.Ident),
3432
+ ALT: () => $.CONSUME(T.Ident)
3433
+ }]);
3434
+ if (!RECORDING_PHASE) if (first instanceof Node) nodes.push($.wrap(first));
3435
+ else nodes.push($.wrap($.processValueToken(first)));
3436
+ $.MANY({
3437
+ GATE: $.noSep.bind($),
3438
+ DEF: () => {
3439
+ const seg = $.CONSUME(T.DotName);
3440
+ if (!RECORDING_PHASE) nodes.push($.wrap($.processValueToken(seg)));
3441
+ }
3442
+ });
3443
+ if (RECORDING_PHASE) return;
3444
+ const loc = $.endRule();
3445
+ return new Sequence(nodes, void 0, loc, $.context);
3446
+ };
3447
+ }
3448
+ /**
3449
+ * Less override: allow variable reference for @keyframes name
3450
+ * CSS: Ident | String
3451
+ * Less: valueReference | Ident | String
3452
+ */
3453
+ function keyframesName(T) {
3454
+ const $ = this;
3455
+ return (ctx = {}) => {
3456
+ let node;
3457
+ $.OR([
3458
+ { ALT: () => node = $.SUBRULE($.valueReference, { ARGS: [ctx] }) },
3459
+ {
3460
+ GATE: () => $.isType(T.Ident) && !$.isType(T.InterpolatedIdent),
3461
+ ALT: () => {
3462
+ const tok = $.CONSUME(T.Ident);
3463
+ node = $.wrap($.processValueToken(tok));
3464
+ }
3465
+ },
3466
+ { ALT: () => node = $.SUBRULE($.string, { ARGS: [] }) }
3467
+ ]);
3468
+ return node;
3469
+ };
3470
+ }
3471
+ /**
3472
+ * One of the rare rules that returns a token, because
3473
+ * other rules will transform it differently.
3474
+ */
3475
+ function mixinName(T) {
3476
+ const $ = this;
3477
+ return (ctx = {}) => {
3478
+ /** e.g. .mixin, #mixin */
3479
+ let name = $.OR([
3480
+ { ALT: () => $.CONSUME(T.HashName) },
3481
+ { ALT: () => $.CONSUME(T.ColorIdentStart) },
3482
+ { ALT: () => $.CONSUME(T.DotName) },
3483
+ { ALT: () => $.CONSUME(T.InterpolatedIdent) },
3484
+ { ALT: () => $.CONSUME(T.InterpolatedSelector) }
3485
+ ]);
3486
+ if ($.RECORDING_PHASE) return;
3487
+ const asReference = ctx.asReference;
3488
+ let nameNode;
3489
+ let nameValue = name.image;
3490
+ let location = $.getLocationInfo(name);
3491
+ if (nameValue.includes("@") || nameValue.includes("$")) {
3492
+ const interpolated = getInterpolated(nameValue, location, $.context);
3493
+ nameNode = interpolated;
3494
+ if (asReference) if (isNode(ctx.node, N.Reference) && ctx.node.options.type === "mixin-ruleset") nameNode = new Reference({
3495
+ target: ctx.node,
3496
+ key: interpolated
3497
+ }, {
3498
+ type: "mixin-ruleset",
3499
+ role: "name"
3500
+ }, location, $.context);
3501
+ else {
3502
+ const target = ctx.node;
3503
+ nameNode = new Reference({
3504
+ target: target instanceof Call ? target : target instanceof Reference ? target : void 0,
3505
+ key: interpolated
3506
+ }, {
3507
+ type: "mixin-ruleset",
3508
+ role: "name"
3509
+ }, location, $.context);
3510
+ }
3511
+ } else if (asReference) if (isNode(ctx.node, N.Reference) && ctx.node.options.type === "mixin-ruleset") {
3512
+ const existingKey = ctx.node.key;
3513
+ let mergedKeys;
3514
+ if (Array.isArray(existingKey)) mergedKeys = [...existingKey];
3515
+ else mergedKeys = [String(existingKey)];
3516
+ mergedKeys.push(nameValue);
3517
+ nameNode = new Reference({ key: mergedKeys.length === 1 ? mergedKeys[0] : mergedKeys }, {
3518
+ type: "mixin-ruleset",
3519
+ role: "name"
3520
+ }, location, $.context);
3521
+ } else {
3522
+ const target = ctx.node;
3523
+ nameNode = new Reference({
3524
+ target: target instanceof Call ? target : target instanceof Reference ? target : void 0,
3525
+ key: nameValue
3526
+ }, {
3527
+ type: "mixin-ruleset",
3528
+ role: "name"
3529
+ }, location, $.context);
3530
+ }
3531
+ else nameNode = $.wrap(new Any(nameValue, { role: "name" }, $.getLocationInfo(name), $.context), true);
3532
+ return nameNode;
3533
+ };
3534
+ }
3535
+ /**
3536
+ * Used within a value. These can be
3537
+ * chained more recursively, unlike
3538
+ * Less 1.x-4.x
3539
+ * e.g. .mixin1() > .mixin2[@val1].ns() > .sub-mixin[@val2]
3540
+ *
3541
+ * This production intelligently decides whether to produce a Call or Reference
3542
+ * based on whether there are parentheses at the end:
3543
+ * - foo: #id; // Reference
3544
+ * - foo: .class; // Reference
3545
+ * - foo: #id > .scoped; // Reference
3546
+ * - foo: #id > .scoped(); // Call
3547
+ * - foo: #id[]; // Reference with accessor
3548
+ * - foo: #id > .scoped[foo]; // Reference with accessor
3549
+ * - foo: #id > .scoped[@ref](); // Call with accessor
3550
+ */
3551
+ function mixinReference(T) {
3552
+ const $ = this;
3553
+ return (ctx = {}) => {
3554
+ let leftNode = $.SUBRULE($.mixinName, { ARGS: [{
3555
+ ...ctx,
3556
+ asReference: true
3557
+ }] });
3558
+ $.MANY({
3559
+ GATE: () => {
3560
+ let next = $.LA(1).tokenType;
3561
+ return $.noSep() && (next === T.LParen || next === T.LSquare);
3562
+ },
3563
+ DEF: () => {
3564
+ leftNode = $.SUBRULE($.lookupOrCall, { ARGS: [{
3565
+ ...ctx,
3566
+ node: leftNode
3567
+ }] });
3568
+ }
3569
+ });
3570
+ $.OPTION(() => {
3571
+ $.OPTION2(() => $.CONSUME(T.Gt));
3572
+ leftNode = $.SUBRULE($.mixinReference, { ARGS: [{
3573
+ ...ctx,
3574
+ node: leftNode
3575
+ }] });
3576
+ });
3577
+ return leftNode;
3578
+ };
3579
+ }
3580
+ function mixinArgs(T) {
3581
+ const $ = this;
3582
+ return (ctx = {}) => {
3583
+ let args;
3584
+ const hasWhitespace = !$.noSep();
3585
+ const openingParenToken = hasWhitespace ? $.LA(1) : void 0;
3586
+ $.CONSUME(T.LParen);
3587
+ const argCtx = {
3588
+ ...ctx,
3589
+ node: void 0,
3590
+ allowComma: false,
3591
+ parenFrames: [...getParenFrames(ctx), false],
3592
+ detachedRulesetUsage: ctx.isDefinition ? "default-param" : "mixin-arg"
3593
+ };
3594
+ if (!$.isType(T.RParen)) args = $.SUBRULE($.mixinArgList, { ARGS: [argCtx] });
3595
+ $.CONSUME(T.RParen);
3596
+ if (hasWhitespace && openingParenToken) {
3597
+ const nextAfterParens = $.LA(1).tokenType;
3598
+ if (!(nextAfterParens === T.LCurly || nextAfterParens === T.When)) $.warnDeprecation("Whitespace between a mixin name and parentheses for a mixin call is deprecated", openingParenToken, "mixin-call-whitespace");
3599
+ }
3600
+ return args;
3601
+ };
3602
+ }
3603
+ function lookupOrCall(T) {
3604
+ const $ = this;
3605
+ return (ctx = {}) => {
3606
+ $.startRule();
3607
+ return $.OR([{ ALT: () => {
3608
+ let keyToken;
3609
+ $.CONSUME(T.LSquare);
3610
+ $.OPTION(() => keyToken = $.OR2([
3611
+ { ALT: () => $.CONSUME(T.NestedReference) },
3612
+ { ALT: () => $.CONSUME(T.AtKeyword) },
3613
+ { ALT: () => $.CONSUME(T.PropertyReference) },
3614
+ { ALT: () => $.CONSUME(T.InterpolatedIdent) },
3615
+ {
3616
+ GATE: () => !$.isType(T.NestedReference) && !$.isType(T.AtKeyword) && !$.isType(T.PropertyReference) && !$.isType(T.InterpolatedIdent) && $.isType(T.Ident),
3617
+ ALT: () => $.CONSUME(T.Ident)
3618
+ }
3619
+ ]));
3620
+ $.CONSUME(T.RSquare);
3621
+ if ($.RECORDING_PHASE) return;
3622
+ let ref;
3623
+ const targetNode = ctx.node;
3624
+ const target = targetNode instanceof Call ? targetNode : targetNode instanceof Reference ? targetNode : void 0;
3625
+ if (keyToken) {
3626
+ let tokenStr = keyToken.image;
3627
+ let type = tokenStr.startsWith("@") ? "variable" : "property";
3628
+ if (keyToken.tokenType === T.NestedReference) {
3629
+ let tokenStr = keyToken.image;
3630
+ if (!tokenStr.startsWith("$") && !tokenStr.startsWith("@")) tokenStr = "$" + tokenStr;
3631
+ }
3632
+ let result = getInterpolatedOrString(tokenStr, $.getLocationInfo(keyToken), $.context);
3633
+ const targetType = isNode(target, N.Reference) ? target.options.type : void 0;
3634
+ const shouldMergeKeys = targetType === "mixin" || targetType === "mixin-ruleset" || targetType === "ruleset";
3635
+ if (isNode(target, N.Reference) && target.options.type === type && typeof result === "string" && shouldMergeKeys) {
3636
+ const existingKey = target.key;
3637
+ let mergedKeys;
3638
+ if (Array.isArray(existingKey)) mergedKeys = [...existingKey];
3639
+ else mergedKeys = [String(existingKey)];
3640
+ mergedKeys.push(result);
3641
+ ref = new Reference({ key: mergedKeys.length === 1 ? mergedKeys[0] : mergedKeys }, { type }, $.endRule(), $.context);
3642
+ } else ref = new Reference({
3643
+ target,
3644
+ key: result
3645
+ }, { type }, $.endRule(), $.context);
3646
+ } else ref = new Reference({
3647
+ target,
3648
+ key: -1
3649
+ }, { type: "index" }, $.endRule(), $.context);
3650
+ /** Reference targets will technically precede the reference, so we need to update the location to the target start location */
3651
+ if (target) {
3652
+ let [targetStartOffset, targetStartLine, targetStartColumn] = target.location;
3653
+ ref.location[0] = targetStartOffset;
3654
+ ref.location[1] = targetStartLine;
3655
+ ref.location[2] = targetStartColumn;
3656
+ }
3657
+ return ref;
3658
+ } }, { ALT: () => {
3659
+ let args = $.SUBRULE($.mixinArgs, { ARGS: [ctx] });
3660
+ if ($.RECORDING_PHASE) return;
3661
+ return new Call({
3662
+ name: ctx.node,
3663
+ args
3664
+ }, void 0, $.endRule(), $.context);
3665
+ } }]);
3666
+ };
3667
+ }
3668
+ /**
3669
+ * @see https://lesscss.org/features/#mixins-feature-mixins-parametric-feature
3670
+ *
3671
+ * This rule is recursive to allow chevrotain-allstar (hopefully) to lookahead
3672
+ * and find semi-colon separators vs. commas.
3673
+ */
3674
+ function mixinArgList(T) {
3675
+ const $ = this;
3676
+ return (ctx = {}) => {
3677
+ $.startRule();
3678
+ const first = $.SUBRULE($.mixinArg, { ARGS: [ctx] });
3679
+ let commaNodes = [$.wrap(first, true)];
3680
+ const semiNodes = [];
3681
+ let isSemiList = false;
3682
+ const collapseCommaNodesIntoSemiNodes = (semi) => {
3683
+ if (!commaNodes) return;
3684
+ if (commaNodes.length > 1) {
3685
+ const [head, ...rest] = commaNodes;
3686
+ let hasDeclarations = false;
3687
+ if (head instanceof VarDeclaration) {
3688
+ const nodes = [head.value, ...rest];
3689
+ hasDeclarations = rest.some((n) => n instanceof VarDeclaration);
3690
+ head.setData("value", new List(nodes, void 0, $.getLocationFromNodes(nodes), $.context));
3691
+ semiNodes.push(head);
3692
+ } else {
3693
+ hasDeclarations = commaNodes.some((n) => n instanceof VarDeclaration);
3694
+ semiNodes.push(new List(commaNodes, void 0, $.getLocationFromNodes(commaNodes), $.context));
3695
+ }
3696
+ if (hasDeclarations) {
3697
+ const indexOfSemi = $.input.indexOf(semi);
3698
+ const previousToken = $.input[indexOfSemi - 1];
3699
+ $.SAVE_ERROR(new NoViableAltException("Cannot mix ; and , as delimiter types", semi, previousToken));
3700
+ }
3701
+ } else semiNodes.push(commaNodes[0]);
3702
+ commaNodes = void 0;
3703
+ };
3704
+ while ($.isType(T.Comma) || $.isType(T.Semi)) {
3705
+ if ($.isType(T.Comma)) {
3706
+ const comma = $.CONSUME(T.Comma);
3707
+ const node = $.SUBRULE2($.mixinArg, { ARGS: [ctx] });
3708
+ if (commaNodes) commaNodes.push($.wrap(node, true));
3709
+ else {
3710
+ $.SAVE_ERROR(new NoViableAltException("Cannot mix ; and , as delimiter types", comma, $.LA(0)));
3711
+ semiNodes.push($.wrap(node, true));
3712
+ }
3713
+ continue;
3714
+ }
3715
+ const semi = $.CONSUME(T.Semi);
3716
+ isSemiList = true;
3717
+ collapseCommaNodesIntoSemiNodes(semi);
3718
+ if ($.isType(T.RParen)) break;
3719
+ const prevAllow = ctx.allowComma;
3720
+ ctx.allowComma = true;
3721
+ const node = $.SUBRULE3($.mixinArg, { ARGS: [ctx] });
3722
+ ctx.allowComma = prevAllow;
3723
+ semiNodes.push($.wrap(node, true));
3724
+ }
3725
+ let location = $.endRule();
3726
+ let nodes = isSemiList ? semiNodes : commaNodes;
3727
+ let sep = isSemiList ? ";" : ",";
3728
+ return $.wrap(new List(nodes, { sep }, location, $.context), "both");
3729
+ };
3730
+ }
3731
+ /**
3732
+ * Less is more lenient about at-keywords. See lessTokens.ts for more details.
3733
+ */
3734
+ function varName(T) {
3735
+ const $ = this;
3736
+ return () => {
3737
+ return $.CONSUME(T.AtName);
3738
+ };
3739
+ }
3740
+ /**
3741
+ * Originally, we were creating alternatives for mixin calls and mixin definitions
3742
+ * that could mostly overlap, which led to longer parsing. Instead, we parse
3743
+ * as if it could be either, and then we disambiguate at the end.
3744
+ */
3745
+ function mixinArg(T) {
3746
+ const $ = this;
3747
+ return (ctx = {}) => {
3748
+ const firstToken = $.LA(1);
3749
+ const atStart = $.matchToken(firstToken, T.AtName);
3750
+ const tt2 = $.LA(2).tokenType;
3751
+ const tt3 = $.LA(3).tokenType;
3752
+ const hasWsAfterName = tt2 === T.WS;
3753
+ const nextTokenType = hasWsAfterName ? tt3 : tt2;
3754
+ if (atStart && nextTokenType === T.Ellipsis) {
3755
+ $.startRule();
3756
+ const name = $.CONSUME(T.AtName);
3757
+ if (hasWsAfterName) $.CONSUME(T.WS);
3758
+ $.CONSUME(T.Ellipsis);
3759
+ if ($.RECORDING_PHASE) return;
3760
+ return new Rest(name.image.slice(1), void 0, $.endRule(), $.context);
3761
+ }
3762
+ if (atStart && nextTokenType === T.Colon) {
3763
+ $.startRule();
3764
+ const name = $.CONSUME2(T.AtName);
3765
+ if (hasWsAfterName) $.CONSUME2(T.WS);
3766
+ $.CONSUME(T.Colon);
3767
+ const value = $.SUBRULE3($.callArgument, { ARGS: [{
3768
+ ...ctx,
3769
+ allowComma: !!ctx.allowComma,
3770
+ detachedRulesetUsage: "default-param"
3771
+ }] });
3772
+ const location = $.endRule();
3773
+ if ($.RECORDING_PHASE) return;
3774
+ return new VarDeclaration({
3775
+ name: new Any(name.image.slice(1), { role: "property" }, $.getLocationInfo(name), $.context),
3776
+ value
3777
+ }, { paramVar: true }, location, $.context);
3778
+ }
3779
+ if (atStart && (nextTokenType === T.RParen || nextTokenType === T.Comma || nextTokenType === T.Semi)) {
3780
+ $.startRule();
3781
+ const name = $.CONSUME3(T.AtName);
3782
+ if ($.RECORDING_PHASE) return;
3783
+ return new Any(name.image.slice(1), { role: "name" }, $.endRule(), $.context);
3784
+ }
3785
+ if ($.isType(T.Ellipsis)) {
3786
+ const ellipsis = $.CONSUME2(T.Ellipsis);
3787
+ return new Rest(void 0, void 0, $.getLocationInfo(ellipsis), $.context);
3788
+ }
3789
+ return $.SUBRULE($.callArgument, { ARGS: [ctx] });
3790
+ };
3791
+ }
3792
+ function callArgument(T) {
3793
+ const $ = this;
3794
+ return (ctx = {}) => {
3795
+ return $.OR([
3796
+ {
3797
+ GATE: () => $.isType(T.AnonMixinStart) || $.isType(T.LCurly),
3798
+ ALT: () => $.SUBRULE($.anonymousMixinDefinition, { ARGS: [ctx] })
3799
+ },
3800
+ {
3801
+ GATE: () => !ctx.allowComma,
3802
+ ALT: () => $.SUBRULE($.valueSequence, { ARGS: [ctx] })
3803
+ },
3804
+ {
3805
+ GATE: () => !!ctx.allowComma,
3806
+ ALT: () => $.SUBRULE($.valueList, { ARGS: [ctx] })
3807
+ }
3808
+ ]);
3809
+ };
3810
+ }
3811
+ /**
3812
+ * Override unknownAtRule to handle @-export for stylesheet forwarding.
3813
+ * @-export is like @-compose but with forward semantics and no `with` support.
3814
+ */
3815
+ function unknownAtRule(T) {
3816
+ const $ = this;
3817
+ return (ctx = {}) => {
3818
+ if ($.LA(1).image === "@-export") return $.SUBRULE($.exportAtRule, { ARGS: [ctx] });
3819
+ return cssUnknownAtRule.call($, T)(ctx);
3820
+ };
3821
+ }
3822
+ /**
3823
+ * Parse @-export './foo.jess' [as <namespace>]
3824
+ *
3825
+ * Creates a StyleImport with forward semantics (members not visible locally but transitive).
3826
+ * Does NOT support `with` (unlike @-compose).
3827
+ * Participates in evaldTrees caching like @-compose.
3828
+ */
3829
+ function exportAtRule(T) {
3830
+ const $ = this;
3831
+ return (ctx = {}) => {
3832
+ $.startRule();
3833
+ $.CONSUME(T.AtKeyword);
3834
+ const pathNode = $.OR([{ ALT: () => $.SUBRULE($.urlFunction, { ARGS: [ctx] }) }, { ALT: () => $.SUBRULE($.string, { ARGS: [ctx] }) }]);
3835
+ let namespace;
3836
+ $.OPTION(() => {
3837
+ const la = $.LA(1);
3838
+ if (!((la.tokenType === T.PlainIdent || la.tokenType === T.Ident) && la.image === "as")) return;
3839
+ if ($.isType(T.Ident)) $.CONSUME(T.Ident);
3840
+ else $.CONSUME(T.PlainIdent);
3841
+ namespace = ($.isType(T.Ident) ? $.CONSUME(T.Ident) : $.CONSUME(T.PlainIdent)).image;
3842
+ });
3843
+ $.CONSUME(T.Semi);
3844
+ const loc = $.endRule();
3845
+ return new StyleImport({ path: pathNode }, {
3846
+ type: "compose",
3847
+ namespace,
3848
+ importOptions: { forward: true }
3849
+ }, loc, $.context);
3850
+ };
3851
+ }
3852
+ //#endregion
3853
+ //#region src/productions/index.ts
3854
+ var productions_exports = /* @__PURE__ */ __exportAll({
3855
+ ampersandExtend: () => ampersandExtend,
3856
+ anonymousMixinDefinition: () => anonymousMixinDefinition,
3857
+ attributeSelector: () => attributeSelector,
3858
+ booleanFunction: () => booleanFunction,
3859
+ calcFunction: () => calcFunction,
3860
+ callArgument: () => callArgument,
3861
+ comparison: () => comparison,
3862
+ complexSelector: () => complexSelector,
3863
+ compoundSelector: () => compoundSelector,
3864
+ customBlock: () => customBlock,
3865
+ customValue: () => customValue,
3866
+ declaration: () => declaration,
3867
+ declarationList: () => declarationList,
3868
+ exportAtRule: () => exportAtRule,
3869
+ expressionProduct: () => expressionProduct,
3870
+ expressionSum: () => expressionSum,
3871
+ expressionValue: () => expressionValue,
3872
+ extend: () => extend,
3873
+ forgivingSelectorList: () => forgivingSelectorList,
3874
+ functionCall: () => functionCall,
3875
+ functionCallArgs: () => functionCallArgs,
3876
+ guard: () => guard,
3877
+ guardAnd: () => guardAnd,
3878
+ guardDefault: () => guardDefault,
3879
+ guardInParens: () => guardInParens,
3880
+ guardInner: () => guardInner,
3881
+ guardOr: () => guardOr,
3882
+ guardWithCondition: () => guardWithCondition,
3883
+ guardWithConditionValue: () => guardWithConditionValue,
3884
+ ifFunction: () => ifFunction,
3885
+ importAtRule: () => importAtRule,
3886
+ innerAtRule: () => innerAtRule,
3887
+ innerCustomValue: () => innerCustomValue,
3888
+ keyframesName: () => keyframesName,
3889
+ knownFunctions: () => knownFunctions,
3890
+ layerName: () => layerName,
3891
+ lessMediaQueryFromReference: () => lessMediaQueryFromReference,
3892
+ lessMediaQueryFromString: () => lessMediaQueryFromString,
3893
+ lessMediaQueryTail: () => lessMediaQueryTail,
3894
+ lookupOrCall: () => lookupOrCall,
3895
+ main: () => main,
3896
+ mathProduct: () => mathProduct,
3897
+ mathSum: () => mathSum,
3898
+ mathValue: () => mathValue,
3899
+ mediaCondition: () => mediaCondition,
3900
+ mediaConditionWithoutOr: () => mediaConditionWithoutOr,
3901
+ mediaFeature: () => mediaFeature,
3902
+ mediaInParens: () => mediaInParens,
3903
+ mediaQuery: () => mediaQuery,
3904
+ mfNonIdentifierValue: () => mfNonIdentifierValue,
3905
+ mfValue: () => mfValue,
3906
+ mixinArg: () => mixinArg,
3907
+ mixinArgList: () => mixinArgList,
3908
+ mixinArgs: () => mixinArgs,
3909
+ mixinName: () => mixinName,
3910
+ mixinOrQualifiedRule: () => mixinOrQualifiedRule,
3911
+ mixinReference: () => mixinReference,
3912
+ nthValue: () => nthValue,
3913
+ qualifiedRule: () => qualifiedRule,
3914
+ qualifiedRuleBody: () => qualifiedRuleBody,
3915
+ relativeSelector: () => relativeSelector,
3916
+ selectorCapture: () => selectorCapture,
3917
+ selectorList: () => selectorList,
3918
+ simpleSelector: () => simpleSelector,
3919
+ squareValue: () => squareValue,
3920
+ string: () => string,
3921
+ stylesheet: () => stylesheet,
3922
+ unknownAtRule: () => unknownAtRule,
3923
+ urlFunction: () => urlFunction,
3924
+ value: () => value,
3925
+ valueReference: () => valueReference,
3926
+ valueSequence: () => valueSequence,
3927
+ varDeclarationOrCall: () => varDeclarationOrCall,
3928
+ varName: () => varName,
3929
+ varReference: () => varReference,
3930
+ wrappedDeclarationList: () => wrappedDeclarationList
3931
+ });
3932
+ //#endregion
3933
+ //#region src/lessRecursiveParser.ts
3934
+ var LessRecursiveParser = class LessRecursiveParser extends CssRecursiveParser {
3935
+ looseMode;
3936
+ leakyRules;
3937
+ /** Warnings collected during parsing */
3938
+ warnings = [];
3939
+ /** See `LessParserConfig.mathMode` */
3940
+ mathMode;
3941
+ /** See `LessParserConfig.wrapOuterExpressions` */
3942
+ wrapOuterExpressions;
3943
+ constructor(T, config = {}) {
3944
+ let { legacyMode, looseMode = true, leakyRules = true, mathMode = "parens-division", wrapOuterExpressions = true, ...rest } = config;
3945
+ legacyMode = legacyMode ?? looseMode;
3946
+ super(T, {
3947
+ legacyMode,
3948
+ ...rest
3949
+ });
3950
+ this.T = T;
3951
+ this.looseMode = looseMode;
3952
+ this.leakyRules = leakyRules;
3953
+ this.mathMode = mathMode;
3954
+ this.wrapOuterExpressions = wrapOuterExpressions;
3955
+ this.warnings = [];
3956
+ for (const [key, factory] of Object.entries(productions_exports)) {
3957
+ if (typeof factory !== "function") continue;
3958
+ const rule = factory.call(this, this.T);
3959
+ if (key in productions) this.OVERRIDE_RULE(key, rule);
3960
+ else this.RULE(key, rule);
3961
+ }
3962
+ if (this.constructor === LessRecursiveParser) this.performSelfAnalysis();
3963
+ }
3964
+ processValueToken(token, ctx) {
3965
+ let tokenType = token.tokenType;
3966
+ const T = this.T;
3967
+ if (tokenType.name === "AtKeyword" || tokenMatcher(token, T.AtKeyword)) {
3968
+ if (ctx?.inCustomPropertyValue) {
3969
+ const atName = token.image;
3970
+ const ident = token.image.slice(1);
3971
+ this.warnDeprecation(`"${atName}" in custom property values is treated as literal text, not a variable reference. Use "\@{${ident}}" if you want it to be evaluated.`, token, "variable-in-unknown-value");
3972
+ return new Any(token.image, { role: "any" }, this.getLocationInfo(token), this.context);
3973
+ }
3974
+ return new Reference(token.image.slice(1), { type: "variable" }, this.getLocationInfo(token), this.context);
3975
+ } else if (tokenType.name === "PropertyReference") {
3976
+ if (ctx?.inCustomPropertyValue) {
3977
+ const atName = token.image;
3978
+ const ident = token.image.slice(1);
3979
+ this.warnDeprecation(`"${atName}" in custom property values is treated as literal text, not a property reference. Use "\${${ident}}" if you want it to be evaluated.`, token, "property-in-unknown-value");
3980
+ return new Any(token.image, { role: "any" }, this.getLocationInfo(token), this.context);
3981
+ }
3982
+ return super.processValueToken(token, ctx);
3983
+ } else if (tokenType === T["DefaultGuardFunc"]) return new DefaultGuard(token.image, void 0, this.getLocationInfo(token), this.context);
3984
+ else if (tokenType.name === "JavaScript" || T["JavaScript"] && tokenMatcher(token, T["JavaScript"])) throw new Error("Inline JavaScript using backticks is not supported. Use @use to import a JavaScript/TypeScript module instead. Script-module documentation is coming soon.");
3985
+ else if (tokenType === T["InterpolatedIdent"]) {
3986
+ const result = getInterpolatedOrString(token.image, this.getLocationInfo(token), this.context);
3987
+ if (result instanceof Interpolated) return result;
3988
+ else return new Any(result, { role: "ident" }, this.getLocationInfo(token), this.context);
3989
+ } else if (tokenType === T["PlainIdent"]) {
3990
+ const image = token.image;
3991
+ if (image === "true" || image === "false") return new Bool(image === "true", void 0, this.getLocationInfo(token), this.context);
3992
+ }
3993
+ return super.processValueToken(token, ctx);
3994
+ }
3995
+ shouldTryQualifiedRuleInDeclarationList() {
3996
+ const { Ident, Assign, Colon, LCurly, Comma, LSquare, NthPseudoClass, SelectorPseudoClass, FunctionStart } = this.T;
3997
+ const isSelectorLikeContinuation = (offset) => {
3998
+ const tok = this.LA(offset);
3999
+ return tokenMatcher(tok, LCurly) || tokenMatcher(tok, Comma) || tokenMatcher(tok, this.T.Combinator) || tokenMatcher(tok, LSquare) || tokenMatcher(tok, Colon) || tokenMatcher(tok, NthPseudoClass) || tokenMatcher(tok, SelectorPseudoClass);
4000
+ };
4001
+ if (!this.isTypeAt(1, Ident)) return true;
4002
+ if (!this.isTypeAt(2, Assign)) return true;
4003
+ if (this.hasWS(2)) return false;
4004
+ const tt3 = this.LA(3).tokenType;
4005
+ if (tt3 === Colon || tt3 === NthPseudoClass || tt3 === SelectorPseudoClass || tokenMatcher(this.LA(3), FunctionStart)) return true;
4006
+ if (!tokenMatcher(this.LA(3), Ident)) return false;
4007
+ return isSelectorLikeContinuation(4);
4008
+ }
4009
+ warnDeprecation(message, token, deprecationId) {
4010
+ this.warnings.push({
4011
+ message,
4012
+ token,
4013
+ deprecation: deprecationId
4014
+ });
4015
+ }
4016
+ };
4017
+ //#endregion
4018
+ //#region src/lessParser.ts
4019
+ /**
4020
+ * Cached lexer + parser singletons. Chevrotain initialization (~500ms)
4021
+ * only happens once — config changes are applied via instance properties
4022
+ * before each parse.
4023
+ */
4024
+ let cachedLexer;
4025
+ let cachedParser;
4026
+ let cachedTokenMap;
4027
+ function getSharedLexerAndParser(config) {
4028
+ if (!cachedLexer || !cachedParser) {
4029
+ const { lexer, T } = createLexerDefinition(lessFragments(), lessTokens());
4030
+ cachedTokenMap = T;
4031
+ cachedLexer = new Lexer(lexer, {
4032
+ ensureOptimizations: true,
4033
+ skipValidations: process.env.TEST !== "true"
4034
+ });
4035
+ cachedParser = new LessRecursiveParser(cachedTokenMap, config);
4036
+ }
4037
+ const { looseMode = true, leakyRules = true, mathMode = "parens-division", wrapOuterExpressions = true, legacyMode = looseMode } = config;
4038
+ cachedParser.looseMode = looseMode;
4039
+ cachedParser.leakyRules = leakyRules;
4040
+ cachedParser.mathMode = mathMode;
4041
+ cachedParser.wrapOuterExpressions = wrapOuterExpressions;
4042
+ cachedParser.legacyMode = legacyMode;
4043
+ return {
4044
+ lexer: cachedLexer,
4045
+ parser: cachedParser
4046
+ };
4047
+ }
4048
+ /**
4049
+ * Less parser using the new recursive-descent engine.
4050
+ * Keeps Chevrotain's lexer, replaces the parser.
4051
+ */
4052
+ var LessParser = class {
4053
+ lexer;
4054
+ parser;
4055
+ constructor(config = {}) {
4056
+ config = {
4057
+ looseMode: true,
4058
+ ...config
4059
+ };
4060
+ const shared = getSharedLexerAndParser(config);
4061
+ this.lexer = shared.lexer;
4062
+ this.parser = shared.parser;
4063
+ this.parse = this.parse.bind(this);
4064
+ }
4065
+ parse(text, rule = "stylesheet", options) {
4066
+ const parser = this.parser;
4067
+ const lexerResult = this.lexer.tokenize(text);
4068
+ parser.warnings = [];
4069
+ if (options?.context) parser.context = options.context;
4070
+ parser.input = lexerResult.tokens;
4071
+ const ruleMethod = parser[rule];
4072
+ if (typeof ruleMethod !== "function") throw new Error(`Unknown parser rule: ${rule}`);
4073
+ const tree = ruleMethod.call(parser);
4074
+ const warnings = [...parser.warnings];
4075
+ return {
4076
+ tree,
4077
+ lexerResult,
4078
+ errors: parser.errors,
4079
+ warnings
4080
+ };
4081
+ }
4082
+ /**
4083
+ * @todo Implement content assist for the new parser
4084
+ */
4085
+ suggest(text, init) {
4086
+ return [];
4087
+ }
4088
+ };
4089
+ //#endregion
4090
+ export { Fragments, LessParser, LessParser as Parser, LessRecursiveParser, Tokens, lessFragments, lessTokens };
4091
+
75
4092
  //# sourceMappingURL=index.js.map