
/**
 * @import { CssNode, CssNodePlain, Comment, Lexer, StyleSheetPlain, SyntaxConfig, SyntaxMatchError, SyntaxReferenceError, AtrulePlain, ValuePlain, FunctionNodePlain, CssLocationRange, Identifier } from "@eslint/css-tree"
 * @import { SourceRange, SourceLocation, FileProblem, DirectiveType, RulesConfig, Language, OkParseResult, ParseResult, File, FileError } from "@eslint/core"
 * @import { CSSSyntaxElement, CSSRuleDefinition } from "./types.js"
 */
// @ts-self-types="./index.d.ts"
import { tokenTypes, fork, lexer, parse, toPlainObject } from '@eslint/css-tree';
import { ConfigCommentParser, TextSourceCodeBase, Directive, VisitNodeStep } from '@eslint/plugin-kit';

/**
 * @fileoverview Visitor keys for the CSS Tree AST.
 * @author Nicholas C. Zakas
 */

const visitorKeys = {
	AnPlusB: [],
	Atrule: ["prelude", "block"],
	AtrulePrelude: ["children"],
	AttributeSelector: ["name", "value"],
	Block: ["children"],
	Brackets: ["children"],
	CDC: [],
	CDO: [],
	ClassSelector: [],
	Combinator: [],
	Comment: [],
	Condition: ["children"],
	Declaration: ["value"],
	DeclarationList: ["children"],
	Dimension: [],
	Feature: ["value"],
	FeatureFunction: ["value"],
	FeatureRange: ["left", "middle", "right"],
	Function: ["children"],
	GeneralEnclosed: ["children"],
	Hash: [],
	IdSelector: [],
	Identifier: [],
	Layer: [],
	LayerList: ["children"],
	MediaQuery: ["condition"],
	MediaQueryList: ["children"],
	NestingSelector: [],
	Nth: ["nth", "selector"],
	Number: [],
	Operator: [],
	Parentheses: ["children"],
	Percentage: [],
	PseudoClassSelector: ["children"],
	PseudoElementSelector: ["children"],
	Ratio: ["left", "right"],
	Raw: [],
	Rule: ["prelude", "block"],
	Scope: ["root", "limit"],
	Selector: ["children"],
	SelectorList: ["children"],
	String: [],
	StyleSheet: ["children"],
	SupportsDeclaration: ["declaration"],
	TypeSelector: [],
	UnicodeRange: [],
	Url: [],
	Value: ["children"],
	WhiteSpace: [],
};

/**
 * @fileoverview The CSSSourceCode class.
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------

/**
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

const commentParser = new ConfigCommentParser();

const INLINE_CONFIG =
	/^\s*(?:eslint(?:-enable|-disable(?:(?:-next)?-line)?)?)(?:\s|$)/u;

/**
 * A class to represent a step in the traversal process.
 */
class CSSTraversalStep extends VisitNodeStep {
	/**
	 * The target of the step.
	 * @type {CssNode}
	 */
	target = undefined;

	/**
	 * Creates a new instance.
	 * @param {Object} options The options for the step.
	 * @param {CssNode} options.target The target of the step.
	 * @param {1|2} options.phase The phase of the step.
	 * @param {Array<any>} options.args The arguments of the step.
	 */
	constructor({ target, phase, args }) {
		super({ target, phase, args });

		this.target = target;
	}
}

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

/**
 * CSS Source Code Object.
 * @extends {TextSourceCodeBase<{LangOptions: CSSLanguageOptions, RootNode: StyleSheetPlain, SyntaxElementWithLoc: CSSSyntaxElement, ConfigNode: Comment}>}
 */
class CSSSourceCode extends TextSourceCodeBase {
	/**
	 * Cached traversal steps.
	 * @type {Array<CSSTraversalStep>|undefined}
	 */
	#steps;

	/**
	 * Cache of parent nodes.
	 * @type {WeakMap<CssNodePlain, CssNodePlain>}
	 */
	#parents = new WeakMap();

	/**
	 * Collection of inline configuration comments.
	 * @type {Array<Comment>}
	 */
	#inlineConfigComments;

	/**
	 * The AST of the source code.
	 * @type {StyleSheetPlain}
	 */
	ast = undefined;

	/**
	 * The comment node in the source code.
	 * @type {Array<Comment>|undefined}
	 */
	comments;

	/**
	 * The lexer for this instance.
	 * @type {Lexer}
	 */
	lexer;

	/**
	 * Creates a new instance.
	 * @param {Object} options The options for the instance.
	 * @param {string} options.text The source code text.
	 * @param {StyleSheetPlain} options.ast The root AST node.
	 * @param {Array<Comment>} options.comments The comment nodes in the source code.
	 * @param {Lexer} options.lexer The lexer used to parse the source code.
	 */
	constructor({ text, ast, comments, lexer }) {
		super({ text, ast });
		this.ast = ast;
		this.comments = comments;
		this.lexer = lexer;
	}

	/**
	 * Returns the range of the given node.
	 * @param {CssNodePlain} node The node to get the range of.
	 * @returns {SourceRange} The range of the node.
	 * @override
	 */
	getRange(node) {
		return [node.loc.start.offset, node.loc.end.offset];
	}

	/**
	 * Returns an array of all inline configuration nodes found in the
	 * source code.
	 * @returns {Array<Comment>} An array of all inline configuration nodes.
	 */
	getInlineConfigNodes() {
		if (!this.#inlineConfigComments) {
			this.#inlineConfigComments = this.comments.filter(comment =>
				INLINE_CONFIG.test(comment.value),
			);
		}

		return this.#inlineConfigComments;
	}

	/**
	 * Returns directives that enable or disable rules along with any problems
	 * encountered while parsing the directives.
	 * @returns {{problems:Array<FileProblem>,directives:Array<Directive>}} Information
	 *      that ESLint needs to further process the directives.
	 */
	getDisableDirectives() {
		const problems = [];
		const directives = [];

		this.getInlineConfigNodes().forEach(comment => {
			const { label, value, justification } =
				commentParser.parseDirective(comment.value);

			// `eslint-disable-line` directives are not allowed to span multiple lines as it would be confusing to which lines they apply
			if (
				label === "eslint-disable-line" &&
				comment.loc.start.line !== comment.loc.end.line
			) {
				const message = `${label} comment should not span multiple lines.`;

				problems.push({
					ruleId: null,
					message,
					loc: comment.loc,
				});
				return;
			}

			switch (label) {
				case "eslint-disable":
				case "eslint-enable":
				case "eslint-disable-next-line":
				case "eslint-disable-line": {
					const directiveType = label.slice("eslint-".length);

					directives.push(
						new Directive({
							type: /** @type {DirectiveType} */ (directiveType),
							node: comment,
							value,
							justification,
						}),
					);
				}

				// no default
			}
		});

		return { problems, directives };
	}

	/**
	 * Returns inline rule configurations along with any problems
	 * encountered while parsing the configurations.
	 * @returns {{problems:Array<FileProblem>,configs:Array<{config:{rules:RulesConfig},loc:SourceLocation}>}} Information
	 *      that ESLint needs to further process the rule configurations.
	 */
	applyInlineConfig() {
		const problems = [];
		const configs = [];

		this.getInlineConfigNodes().forEach(comment => {
			const { label, value } = commentParser.parseDirective(
				comment.value,
			);

			if (label === "eslint") {
				const parseResult = commentParser.parseJSONLikeConfig(value);

				if (parseResult.ok) {
					configs.push({
						config: {
							rules: parseResult.config,
						},
						loc: comment.loc,
					});
				} else {
					problems.push({
						ruleId: null,
						message:
							/** @type {{ok: false, error: { message: string }}} */ (
								parseResult
							).error.message,
						loc: comment.loc,
					});
				}
			}
		});

		return {
			configs,
			problems,
		};
	}

	/**
	 * Returns the parent of the given node.
	 * @param {CssNodePlain} node The node to get the parent of.
	 * @returns {CssNodePlain|undefined} The parent of the node.
	 */
	getParent(node) {
		return this.#parents.get(node);
	}

	/**
	 * Traverse the source code and return the steps that were taken.
	 * @returns {Iterable<CSSTraversalStep>} The steps that were taken while traversing the source code.
	 */
	traverse() {
		// Because the AST doesn't mutate, we can cache the steps
		if (this.#steps) {
			return this.#steps.values();
		}

		/** @type {Array<CSSTraversalStep>} */
		const steps = (this.#steps = []);

		// Note: We can't use `walk` from `css-tree` because it uses `CssNode` instead of `CssNodePlain`

		const visit = (node, parent) => {
			// first set the parent
			this.#parents.set(node, parent);

			// then add the step
			steps.push(
				new CSSTraversalStep({
					target: node,
					phase: 1,
					args: [node, parent],
				}),
			);

			// then visit the children
			for (const key of visitorKeys[node.type] || []) {
				const child = node[key];

				if (child) {
					if (Array.isArray(child)) {
						child.forEach(grandchild => {
							visit(grandchild, node);
						});
					} else {
						visit(child, node);
					}
				}
			}

			// then add the exit step
			steps.push(
				new CSSTraversalStep({
					target: node,
					phase: 2,
					args: [node, parent],
				}),
			);
		};

		visit(this.ast);

		return steps;
	}
}

/**
 * @fileoverview The CSSLanguage class.
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------

/**
 */

/** @typedef {OkParseResult<StyleSheetPlain> & { comments: Comment[], lexer: Lexer }} CSSOkParseResult */
/** @typedef {ParseResult<StyleSheetPlain>} CSSParseResult */
/**
 * @typedef {Object} CSSLanguageOptions
 * @property {boolean} [tolerant] Whether to be tolerant of recoverable parsing errors.
 * @property {SyntaxConfig} [customSyntax] Custom syntax to use for parsing.
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

const blockOpenerTokenTypes = new Map([
	[tokenTypes.Function, ")"],
	[tokenTypes.LeftCurlyBracket, "}"],
	[tokenTypes.LeftParenthesis, ")"],
	[tokenTypes.LeftSquareBracket, "]"],
]);

const blockCloserTokenTypes = new Map([
	[tokenTypes.RightCurlyBracket, "{"],
	[tokenTypes.RightParenthesis, "("],
	[tokenTypes.RightSquareBracket, "["],
]);

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

/**
 * CSS Language Object
 * @implements {Language<{ LangOptions: CSSLanguageOptions; Code: CSSSourceCode; RootNode: StyleSheetPlain; Node: CssNodePlain}>}
 */
class CSSLanguage {
	/**
	 * The type of file to read.
	 * @type {"text"}
	 */
	fileType = "text";

	/**
	 * The line number at which the parser starts counting.
	 * @type {0|1}
	 */
	lineStart = 1;

	/**
	 * The column number at which the parser starts counting.
	 * @type {0|1}
	 */
	columnStart = 1;

	/**
	 * The name of the key that holds the type of the node.
	 * @type {string}
	 */
	nodeTypeKey = "type";

	/**
	 * The visitor keys for the CSSTree AST.
	 * @type {Record<string, string[]>}
	 */
	visitorKeys = visitorKeys;

	/**
	 * The default language options.
	 * @type {CSSLanguageOptions}
	 */
	defaultLanguageOptions = {
		tolerant: false,
	};

	/**
	 * Validates the language options.
	 * @param {CSSLanguageOptions} languageOptions The language options to validate.
	 * @throws {Error} When the language options are invalid.
	 */
	validateLanguageOptions(languageOptions) {
		if (
			"tolerant" in languageOptions &&
			typeof languageOptions.tolerant !== "boolean"
		) {
			throw new TypeError(
				"Expected a boolean value for 'tolerant' option.",
			);
		}

		if ("customSyntax" in languageOptions) {
			if (
				typeof languageOptions.customSyntax !== "object" ||
				languageOptions.customSyntax === null
			) {
				throw new TypeError(
					"Expected an object value for 'customSyntax' option.",
				);
			}
		}
	}

	/**
	 * Parses the given file into an AST.
	 * @param {File} file The virtual file to parse.
	 * @param {Object} [context] The parsing context.
	 * @param {CSSLanguageOptions} [context.languageOptions] The language options to use for parsing.
	 * @returns {CSSParseResult} The result of parsing.
	 */
	parse(file, { languageOptions = {} } = {}) {
		// Note: BOM already removed
		const text = /** @type {string} */ (file.body);

		/** @type {Comment[]} */
		const comments = [];

		/** @type {FileError[]} */
		const errors = [];

		const { tolerant } = languageOptions;
		const { parse: parse$1, lexer: lexer$1 } = languageOptions.customSyntax
			? fork(languageOptions.customSyntax)
			: { parse: parse, lexer: lexer };

		/*
		 * Check for parsing errors first. If there's a parsing error, nothing
		 * else can happen. However, a parsing error does not throw an error
		 * from this method - it's just considered a fatal error message, a
		 * problem that ESLint identified just like any other.
		 */
		try {
			const root = toPlainObject(
				parse$1(text, {
					filename: file.path,
					positions: true,
					onComment(value, loc) {
						comments.push({
							type: "Comment",
							value,
							loc,
						});
					},
					onParseError(error) {
						if (!tolerant) {
							errors.push(error);
						}
					},
					onToken(type, start, end, index) {
						if (tolerant) {
							return;
						}

						switch (type) {
							// these already generate errors
							case tokenTypes.BadString:
							case tokenTypes.BadUrl:
								break;

							default:
								/* eslint-disable new-cap -- This is a valid call */
								if (this.isBlockOpenerTokenType(type)) {
									if (
										this.getBlockTokenPairIndex(index) ===
										-1
									) {
										const loc = this.getRangeLocation(
											start,
											end,
										);
										errors.push(
											parse$1.SyntaxError(
												`Missing closing ${blockOpenerTokenTypes.get(type)}`,
												text,
												start,
												loc.start.line,
												loc.start.column,
											),
										);
									}
								} else if (this.isBlockCloserTokenType(type)) {
									if (
										this.getBlockTokenPairIndex(index) ===
										-1
									) {
										const loc = this.getRangeLocation(
											start,
											end,
										);
										errors.push(
											parse$1.SyntaxError(
												`Missing opening ${blockCloserTokenTypes.get(type)}`,
												text,
												start,
												loc.start.line,
												loc.start.column,
											),
										);
									}
								}
							/* eslint-enable new-cap -- This is a valid call */
						}
					},
				}),
			);

			if (errors.length) {
				return {
					ok: false,
					errors,
				};
			}

			return {
				ok: true,
				ast: /** @type {StyleSheetPlain} */ (root),
				comments,
				lexer: lexer$1,
			};
		} catch (ex) {
			return {
				ok: false,
				errors: [ex],
			};
		}
	}

	/**
	 * Creates a new `CSSSourceCode` object from the given information.
	 * @param {File} file The virtual file to create a `CSSSourceCode` object from.
	 * @param {CSSOkParseResult} parseResult The result returned from `parse()`.
	 * @returns {CSSSourceCode} The new `CSSSourceCode` object.
	 */
	createSourceCode(file, parseResult) {
		return new CSSSourceCode({
			text: /** @type {string} */ (file.body),
			ast: parseResult.ast,
			comments: parseResult.comments,
			lexer: parseResult.lexer,
		});
	}
}

const rules$1 = /** @type {const} */ ({
    "css/no-duplicate-imports": "error",
    "css/no-empty-blocks": "error",
    "css/no-important": "error",
    "css/no-invalid-at-rule-placement": "error",
    "css/no-invalid-at-rules": "error",
    "css/no-invalid-named-grid-areas": "error",
    "css/no-invalid-properties": "error",
    "css/use-baseline": "error"
});

/**
 * @fileoverview Rule to prevent duplicate imports in CSS.
 * @author Nicholas C. Zakas
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"duplicateImport"} NoDuplicateKeysMessageIds
 * @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateImportsRuleDefinition
 */

//-----------------------------------------------------------------------------
// Rule
//-----------------------------------------------------------------------------

/**
 * @type {NoDuplicateImportsRuleDefinition}
 */
var rule0 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow duplicate @import rules",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-duplicate-imports.md",
		},

		messages: {
			duplicateImport: "Unexpected duplicate @import rule for {{url}}.",
		},
	},

	create(context) {
		const imports = new Set();

		return {
			"Atrule[name=import]"(node) {
				const url = node.prelude.children[0].value;

				if (imports.has(url)) {
					context.report({
						loc: node.loc,
						messageId: "duplicateImport",
						data: { url },
					});
				} else {
					imports.add(url);
				}
			},
		};
	},
};

/**
 * @fileoverview Rule to prevent empty blocks in CSS.
 * @author Nicholas C. Zakas
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"emptyBlock"} NoEmptyBlocksMessageIds
 * @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoEmptyBlocksMessageIds }>} NoEmptyBlocksRuleDefinition
 */

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {NoEmptyBlocksRuleDefinition} */
var rule1 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow empty blocks",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-empty-blocks.md",
		},

		messages: {
			emptyBlock: "Unexpected empty block found.",
		},
	},

	create(context) {
		return {
			Block(node) {
				if (node.children.length === 0) {
					context.report({
						loc: node.loc,
						messageId: "emptyBlock",
					});
				}
			},
		};
	},
};

/**
 * @fileoverview Utility functions for ESLint CSS plugin.
 * @author Nicholas C. Zakas
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

/**
 * Determines if an error is a syntax match error.
 * @param {Object} error The error object to check.
 * @returns {error is SyntaxMatchError} True if the error is a syntax match error, false if not.
 */
function isSyntaxMatchError(error) {
	return typeof error.syntax === "string";
}

/**
 * Determines if an error is a syntax reference error.
 * @param {Object} error The error object to check.
 * @returns {error is SyntaxReferenceError} True if the error is a syntax reference error, false if not.
 */
function isSyntaxReferenceError(error) {
	return typeof error.reference === "string";
}

/**
 * Finds the line and column offsets for a given offset in a string.
 * @param {string} text The text to search.
 * @param {number} offset The offset to find.
 * @returns {{lineOffset:number,columnOffset:number}} The location of the offset.
 */
function findOffsets(text, offset) {
	let lineOffset = 0;
	let columnOffset = 0;

	for (let i = 0; i < offset; i++) {
		if (text[i] === "\n") {
			lineOffset++;
			columnOffset = 0;
		} else {
			columnOffset++;
		}
	}

	return {
		lineOffset,
		columnOffset,
	};
}

/**
 * @fileoverview Rule to disallow `!important` flags.
 * @author thecalamiity
 * @author Yann Bertrand
 */


//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"unexpectedImportant"} NoImportantMessageIds
 * @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoImportantMessageIds }>} NoImportantRuleDefinition
 */

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {NoImportantRuleDefinition} */
var rule2 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow !important flags",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-important.md",
		},

		messages: {
			unexpectedImportant: "Unexpected !important flag found.",
		},
	},

	create(context) {
		const importantPattern = /!(\s|\/\*.*?\*\/)*important/iu;

		return {
			Declaration(node) {
				if (node.important) {
					const declarationText = context.sourceCode.getText(node);
					const importantMatch =
						importantPattern.exec(declarationText);

					const {
						lineOffset: startLineOffset,
						columnOffset: startColumnOffset,
					} = findOffsets(declarationText, importantMatch.index);

					const {
						lineOffset: endLineOffset,
						columnOffset: endColumnOffset,
					} = findOffsets(
						declarationText,
						importantMatch.index + importantMatch[0].length,
					);

					const nodeStartLine = node.loc.start.line;
					const nodeStartColumn = node.loc.start.column;
					const startLine = nodeStartLine + startLineOffset;
					const endLine = nodeStartLine + endLineOffset;
					const startColumn =
						(startLine === nodeStartLine ? nodeStartColumn : 1) +
						startColumnOffset;
					const endColumn =
						(endLine === nodeStartLine ? nodeStartColumn : 1) +
						endColumnOffset;

					context.report({
						loc: {
							start: {
								line: startLine,
								column: startColumn,
							},
							end: {
								line: endLine,
								column: endColumn,
							},
						},
						messageId: "unexpectedImportant",
					});
				}
			},
		};
	},
};

/**
 * @fileoverview Rule to enforce correct placement of at-rules.
 * @author thecalamiity
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"invalidCharsetPlacement" | "invalidImportPlacement"} NoInvalidAtRulePlacementMessageIds
 * @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoInvalidAtRulePlacementMessageIds }>} NoInvalidAtRulePlacementRuleDefinition
 */

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {NoInvalidAtRulePlacementRuleDefinition} */
var rule3 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow invalid placement of at-rules",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-invalid-at-rule-placement.md",
		},

		messages: {
			invalidCharsetPlacement:
				"@charset must be placed at the very beginning of the stylesheet, before any rules, comments, or whitespace.",
			invalidImportPlacement:
				"@import must be placed before all other rules, except @charset and @layer statements.",
		},
	},

	create(context) {
		let hasSeenNonImportRule = false;
		let hasSeenLayerBlock = false;

		return {
			Atrule(node) {
				const name = node.name.toLowerCase();

				if (name === "charset") {
					if (
						node.loc.start.line !== 1 ||
						node.loc.start.column !== 1
					) {
						context.report({
							node,
							messageId: "invalidCharsetPlacement",
						});
					}
					return;
				}

				if (name === "layer") {
					if (node.block) {
						hasSeenLayerBlock = true;
					}
					return;
				}

				if (name === "import") {
					if (hasSeenNonImportRule || hasSeenLayerBlock) {
						context.report({
							node,
							messageId: "invalidImportPlacement",
						});
					}
					return;
				}

				hasSeenNonImportRule = true;
			},

			Rule() {
				hasSeenNonImportRule = true;
			},
		};
	},
};

/**
 * @fileoverview Rule to prevent the use of unknown at-rules in CSS.
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"unknownAtRule" | "invalidPrelude" | "unknownDescriptor" | "invalidDescriptor" | "invalidExtraPrelude" | "missingPrelude"} NoInvalidAtRulesMessageIds
 * @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoInvalidAtRulesMessageIds }>} NoInvalidAtRulesRuleDefinition
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

/**
 * Extracts metadata from an error object.
 * @param {SyntaxError} error The error object to extract metadata from.
 * @returns {Object} The metadata extracted from the error.
 */
function extractMetaDataFromError(error) {
	const message = error.message;
	const atRuleName = /`@(.*)`/u.exec(message)[1];
	let messageId = "unknownAtRule";

	if (message.endsWith("prelude")) {
		messageId = message.includes("should not")
			? "invalidExtraPrelude"
			: "missingPrelude";
	}

	return {
		messageId,
		data: {
			name: atRuleName,
		},
	};
}

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {NoInvalidAtRulesRuleDefinition} */
var rule4 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow invalid at-rules",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-invalid-at-rules.md",
		},

		messages: {
			unknownAtRule: "Unknown at-rule '@{{name}}' found.",
			invalidPrelude:
				"Invalid prelude '{{prelude}}' found for at-rule '@{{name}}'. Expected '{{expected}}'.",
			unknownDescriptor:
				"Unknown descriptor '{{descriptor}}' found for at-rule '@{{name}}'.",
			invalidDescriptor:
				"Invalid value '{{value}}' for descriptor '{{descriptor}}' found for at-rule '@{{name}}'. Expected {{expected}}.",
			invalidExtraPrelude:
				"At-rule '@{{name}}' should not contain a prelude.",
			missingPrelude: "At-rule '@{{name}}' should contain a prelude.",
		},
	},

	create(context) {
		const { sourceCode } = context;
		const lexer = sourceCode.lexer;

		return {
			Atrule(node) {
				// checks both name and prelude
				const { error } = lexer.matchAtrulePrelude(
					node.name,
					node.prelude,
				);

				if (error) {
					if (isSyntaxMatchError(error)) {
						context.report({
							loc: error.loc,
							messageId: "invalidPrelude",
							data: {
								name: node.name,
								prelude: error.css,
								expected: error.syntax,
							},
						});
						return;
					}

					const loc = node.loc;

					context.report({
						loc: {
							start: loc.start,
							end: {
								line: loc.start.line,

								// add 1 to account for the @ symbol
								column: loc.start.column + node.name.length + 1,
							},
						},
						...extractMetaDataFromError(error),
					});
				}
			},

			"AtRule > Block > Declaration"(node) {
				// skip custom descriptors
				if (node.property.startsWith("--")) {
					return;
				}

				// get at rule node
				const atRule = /** @type {AtrulePlain} */ (
					sourceCode.getParent(sourceCode.getParent(node))
				);

				const { error } = lexer.matchAtruleDescriptor(
					atRule.name,
					node.property,
					node.value,
				);

				if (error) {
					if (isSyntaxMatchError(error)) {
						context.report({
							loc: error.loc,
							messageId: "invalidDescriptor",
							data: {
								name: atRule.name,
								descriptor: node.property,
								value: error.css,
								expected: error.syntax,
							},
						});
						return;
					}

					const loc = node.loc;

					context.report({
						loc: {
							start: loc.start,
							end: {
								line: loc.start.line,
								column: loc.start.column + node.property.length,
							},
						},
						messageId: "unknownDescriptor",
						data: {
							name: atRule.name,
							descriptor: node.property,
						},
					});
				}
			},
		};
	},
};

/**
 * @fileoverview Rule to prevent invalid named grid areas in CSS grid templates.
 * @author xbinaryx
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"emptyGridArea" | "unevenGridArea" | "nonRectangularGridArea"} NoInvalidNamedGridAreasMessageIds
 * @typedef {CSSRuleDefinition<{ RuleOptions: [], MessageIds: NoInvalidNamedGridAreasMessageIds }>} NoInvalidNamedGridAreasRuleDefinition
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

/**
 * Regular expression to match null cell tokens (sequences of one or more dots)
 */
const nullCellToken = /^\.+$/u;

/**
 * Finds non-rectangular grid areas in a 2D grid
 * @param {string[][]} grid 2D array representing the grid areas
 * @returns {Array<{name: string, row: number}>} Array of errors found
 */
function findNonRectangularAreas(grid) {
	const errors = [];
	const reported = new Set();
	const names = [...new Set(grid.flat())].filter(
		name => !nullCellToken.test(name),
	);

	for (const name of names) {
		const indicesByRow = grid.map(row => {
			const indices = [];
			let idx = row.indexOf(name);

			while (idx !== -1) {
				indices.push(idx);
				idx = row.indexOf(name, idx + 1);
			}

			return indices;
		});

		for (let i = 0; i < indicesByRow.length; i++) {
			for (let j = i + 1; j < indicesByRow.length; j++) {
				const row1 = indicesByRow[i];
				const row2 = indicesByRow[j];

				if (row1.length === 0 || row2.length === 0) {
					continue;
				}

				if (
					row1.length !== row2.length ||
					!row1.every((val, idx) => val === row2[idx])
				) {
					const key = `${name}|${j}`;
					if (!reported.has(key)) {
						errors.push({ name, row: j });
						reported.add(key);
					}
				}
			}
		}
	}

	return errors;
}

const validProps = new Set(["grid-template-areas", "grid-template", "grid"]);

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {NoInvalidNamedGridAreasRuleDefinition} */
var rule5 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow invalid named grid areas",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-invalid-named-grid-areas.md",
		},

		messages: {
			emptyGridArea: "Grid area must contain at least one cell token.",
			unevenGridArea:
				"Grid area strings must have the same number of cell tokens.",
			nonRectangularGridArea:
				"Cell tokens with name '{{name}}' must form a rectangle.",
		},
	},

	create(context) {
		return {
			Declaration(node) {
				const propName = node.property.toLowerCase();

				if (
					validProps.has(propName) &&
					node.value.type === "Value" &&
					node.value.children.length > 0
				) {
					const stringNodes = node.value.children.filter(
						child => child.type === "String",
					);

					if (stringNodes.length === 0) {
						return;
					}

					const grid = [];
					const emptyNodes = [];
					const unevenNodes = [];
					let firstRowLen = null;

					for (const stringNode of stringNodes) {
						const trimmedValue = stringNode.value.trim();

						if (trimmedValue === "") {
							emptyNodes.push(stringNode);
							continue;
						}

						const row = trimmedValue.split(" ").filter(Boolean);
						grid.push(row);

						if (firstRowLen === null) {
							firstRowLen = row.length;
						} else if (row.length !== firstRowLen) {
							unevenNodes.push(stringNode);
						}
					}

					if (emptyNodes.length > 0) {
						emptyNodes.forEach(emptyNode =>
							context.report({
								node: emptyNode,
								messageId: "emptyGridArea",
							}),
						);
						return;
					}

					if (unevenNodes.length > 0) {
						unevenNodes.forEach(unevenNode =>
							context.report({
								node: unevenNode,
								messageId: "unevenGridArea",
							}),
						);
						return;
					}

					const nonRectErrors = findNonRectangularAreas(grid);
					nonRectErrors.forEach(({ name, row }) => {
						const stringNode = stringNodes[row];
						context.report({
							node: stringNode,
							messageId: "nonRectangularGridArea",
							data: {
								name,
							},
						});
					});
				}
			},
		};
	},
};

/**
 * @fileoverview Rule to prevent invalid properties in CSS.
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"invalidPropertyValue" | "unknownProperty" | "unknownVar"} NoInvalidPropertiesMessageIds
 * @typedef {[{allowUnknownVariables?: boolean}]} NoInvalidPropertiesOptions
 * @typedef {CSSRuleDefinition<{ RuleOptions: NoInvalidPropertiesOptions, MessageIds: NoInvalidPropertiesMessageIds }>} NoInvalidPropertiesRuleDefinition
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

/**
 * Replaces all instances of a regex pattern with a replacement and tracks the offsets
 * @param {string} text The text to perform replacements on
 * @param {string} varName The regex pattern string to search for
 * @param {string} replaceValue The string to replace with
 * @returns {{text: string, offsets: Array<number>}} The updated text and array of offsets
 * where replacements occurred
 */
function replaceWithOffsets(text, varName, replaceValue) {
	const offsets = [];
	let result = "";
	let lastIndex = 0;

	const regex = new RegExp(`var\\(\\s*${varName}\\s*\\)`, "gu");
	let match;

	while ((match = regex.exec(text)) !== null) {
		result += text.slice(lastIndex, match.index);

		/*
		 * We need the offset of the replacement after other replacements have
		 * been made, so we push the current length of the result before appending
		 * the replacement value.
		 */
		offsets.push(result.length);
		result += replaceValue;
		lastIndex = match.index + match[0].length;
	}

	result += text.slice(lastIndex);
	return { text: result, offsets };
}

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {NoInvalidPropertiesRuleDefinition} */
var rule6 = {
	meta: {
		type: "problem",

		docs: {
			description: "Disallow invalid properties",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/no-invalid-properties.md",
		},

		schema: [
			{
				type: "object",
				properties: {
					allowUnknownVariables: {
						type: "boolean",
					},
				},
				additionalProperties: false,
			},
		],

		defaultOptions: [
			{
				allowUnknownVariables: false,
			},
		],

		messages: {
			invalidPropertyValue:
				"Invalid value '{{value}}' for property '{{property}}'. Expected {{expected}}.",
			unknownProperty: "Unknown property '{{property}}' found.",
			unknownVar: "Can't validate with unknown variable '{{var}}'.",
		},
	},

	create(context) {
		const sourceCode = context.sourceCode;
		const lexer = sourceCode.lexer;

		/** @type {Map<string,ValuePlain>} */
		const vars = new Map();

		/**
		 * We need to track this as a stack because we can have nested
		 * rules that use the `var()` function, and we need to
		 * ensure that we validate the innermost rule first.
		 * @type {Array<Map<string,FunctionNodePlain>>}
		 */
		const replacements = [];

		const [{ allowUnknownVariables }] = context.options;

		return {
			"Rule > Block > Declaration"() {
				replacements.push(new Map());
			},

			"Function[name=var]"(node) {
				const map = replacements.at(-1);
				if (!map) {
					return;
				}

				/*
				 * Store the custom property name and the function node
				 * so can use these to validate the value later.
				 */
				const name = node.children[0].name;
				map.set(name, node);
			},

			"Rule > Block > Declaration:exit"(node) {
				if (node.property.startsWith("--")) {
					// store the custom property name and value to validate later
					vars.set(node.property, node.value);

					// don't validate custom properties
					return;
				}

				const varsFound = replacements.pop();

				/** @type {Map<number,CssLocationRange>} */
				const varsFoundLocs = new Map();
				const usingVars = varsFound?.size > 0;
				let value = node.value;

				if (usingVars) {
					// need to use a text version of the value here
					value = sourceCode.getText(node.value);
					let offsets;

					// replace any custom properties with their values
					for (const [name, func] of varsFound) {
						const varValue = vars.get(name);

						if (varValue) {
							({ text: value, offsets } = replaceWithOffsets(
								value,
								name,
								sourceCode.getText(varValue).trim(),
							));

							/*
							 * Store the offsets of the replacements so we can
							 * report the correct location of any validation error.
							 */
							offsets.forEach(offset => {
								varsFoundLocs.set(offset, func.loc);
							});
						} else if (!allowUnknownVariables) {
							context.report({
								loc: func.children[0].loc,
								messageId: "unknownVar",
								data: {
									var: name,
								},
							});

							return;
						}
					}
				}

				const { error } = lexer.matchProperty(node.property, value);

				if (error) {
					// validation failure
					if (isSyntaxMatchError(error)) {
						context.report({
							/*
							 * When using variables, check to see if the error
							 * occurred at a location where a variable was replaced.
							 * If so, use that location; otherwise, use the error's
							 * reported location.
							 */
							loc: usingVars
								? (varsFoundLocs.get(error.mismatchOffset) ??
									node.value.loc)
								: error.loc,
							messageId: "invalidPropertyValue",
							data: {
								property: node.property,

								/*
								 * When using variables, slice the value to
								 * only include the part that caused the error.
								 * Otherwise, use the full value from the error.
								 */
								value: usingVars
									? value.slice(
											error.mismatchOffset,
											error.mismatchOffset +
												error.mismatchLength,
										)
									: error.css,
								expected: error.syntax,
							},
						});
						return;
					}

					if (
						!allowUnknownVariables ||
						isSyntaxReferenceError(error)
					) {
						// unknown property
						context.report({
							loc: {
								start: node.loc.start,
								end: {
									line: node.loc.start.line,
									column:
										node.loc.start.column +
										node.property.length,
								},
							},
							messageId: "unknownProperty",
							data: {
								property: node.property,
							},
						});
					}
				}
			},
		};
	},
};

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"notLogicalProperty" | "notLogicalValue" | "notLogicalUnit"} PreferLogicalPropertiesMessageIds
 * @typedef {[{
 *     allowProperties?: string[],
 *     allowUnits?: string[]
 * }]} PreferLogicalPropertiesOptions
 * @typedef {CSSRuleDefinition<{ RuleOptions: PreferLogicalPropertiesOptions, MessageIds: PreferLogicalPropertiesMessageIds }>} PreferLogicalPropertiesRuleDefinition
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

const propertiesReplacements = new Map([
	["bottom", "inset-block-end"],
	["border-bottom", "border-block-end"],
	["border-bottom-color", "border-block-end-color"],
	["border-bottom-left-radius", "border-end-start-radius"],
	["border-bottom-right-radius", "border-end-end-radius"],
	["border-bottom-style", "border-block-end-style"],
	["border-bottom-width", "border-block-end-width"],
	["border-left", "border-inline-start"],
	["border-left-color", "border-inline-start-color"],
	["border-left-style", "border-inline-start-style"],
	["border-left-width", "border-inline-start-width"],
	["border-right", "border-inline-end"],
	["border-right-color", "border-inline-end-color"],
	["border-right-style", "border-inline-end-style"],
	["border-right-width", "border-inline-end-width"],
	["border-top", "border-block-start"],
	["border-top-color", "border-block-start-color"],
	["border-top-left-radius", "border-start-start-radius"],
	["border-top-right-radius", "border-start-end-radius"],
	["border-top-style", "border-block-start-style"],
	["border-top-width", "border-block-start-width"],
	["contain-intrinsic-height", "contain-intrinsic-block-size"],
	["contain-intrinsic-width", "contain-intrinsic-inline-size"],
	["height", "block-size"],
	["left", "inset-inline-start"],
	["margin-bottom", "margin-block-end"],
	["margin-left", "margin-inline-start"],
	["margin-right", "margin-inline-end"],
	["margin-top", "margin-block-start"],
	["max-height", "max-block-size"],
	["max-width", "max-inline-size"],
	["min-height", "min-block-size"],
	["min-width", "min-inline-size"],
	["overflow-x", "overflow-inline"],
	["overflow-y", "overflow-block"],
	["overscroll-behavior-x", "overscroll-behavior-inline"],
	["overscroll-behavior-y", "overscroll-behavior-block"],
	["padding-bottom", "padding-block-end"],
	["padding-left", "padding-inline-start"],
	["padding-right", "padding-inline-end"],
	["padding-top", "padding-block-start"],
	["right", "inset-inline-end"],
	["scroll-margin-bottom", "scroll-margin-block-end"],
	["scroll-margin-left", "scroll-margin-inline-start"],
	["scroll-margin-right", "scroll-margin-inline-end"],
	["scroll-margin-top", "scroll-margin-block-start"],
	["scroll-padding-bottom", "scroll-padding-block-end"],
	["scroll-padding-left", "scroll-padding-inline-start"],
	["scroll-padding-right", "scroll-padding-inline-end"],
	["scroll-padding-top", "scroll-padding-block-start"],
	["top", "inset-block-start"],
	["width", "inline-size"],
]);

const propertyValuesReplacements = new Map([
	[
		"text-align",
		{
			left: "start",
			right: "end",
		},
	],
	[
		"resize",
		{
			horizontal: "inline",
			vertical: "block",
		},
	],
	[
		"caption-side",
		{
			left: "inline-start",
			right: "inline-end",
		},
	],
	[
		"box-orient",
		{
			horizontal: "inline-axis",
			vertical: "block-axis",
		},
	],
	[
		"float",
		{
			left: "inline-start",
			right: "inline-end",
		},
	],
	[
		"clear",
		{
			left: "inline-start",
			right: "inline-end",
		},
	],
]);

const unitReplacements = new Map([
	["cqh", "cqb"],
	["cqw", "cqi"],
	["dvh", "dvb"],
	["dvw", "dvi"],
	["lvh", "lvb"],
	["lvw", "lvi"],
	["svh", "svb"],
	["svw", "svi"],
	["vh", "vb"],
	["vw", "vi"],
]);

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {PreferLogicalPropertiesRuleDefinition} */
var rule7 = {
	meta: {
		type: "problem",

		fixable: "code",

		docs: {
			description: "Enforce the use of logical properties",
			url: "https://github.com/eslint/css/blob/main/docs/rules/prefer-logical-properties.md",
		},

		schema: [
			{
				type: "object",
				properties: {
					allowProperties: {
						type: "array",
						items: {
							type: "string",
						},
						uniqueItems: true,
					},
					allowUnits: {
						type: "array",
						items: {
							type: "string",
						},
						uniqueItems: true,
					},
				},
				additionalProperties: false,
			},
		],

		defaultOptions: [
			{
				allowProperties: [],
				allowUnits: [],
			},
		],

		messages: {
			notLogicalProperty:
				"Expected logical property '{{replacement}}' instead of '{{property}}'.",
			notLogicalValue:
				"Expected logical value '{{replacement}}' instead of '{{value}}'.",
			notLogicalUnit:
				"Expected logical unit '{{replacement}}' instead of '{{unit}}'.",
		},
	},

	create(context) {
		return {
			Declaration(node) {
				const parent = context.sourceCode.getParent(node);
				if (parent.type === "SupportsDeclaration") {
					return;
				}

				const allowProperties = context.options[0].allowProperties;
				if (
					propertiesReplacements.get(node.property) &&
					!allowProperties.includes(node.property)
				) {
					context.report({
						loc: node.loc,
						messageId: "notLogicalProperty",
						data: {
							property: node.property,
							replacement: propertiesReplacements.get(
								node.property,
							),
						},
					});
				}

				if (
					propertyValuesReplacements.get(node.property) &&
					node.value.type === "Value" &&
					node.value.children[0].type === "Identifier"
				) {
					const nodeValue = node.value.children[0].name;
					if (
						propertyValuesReplacements.get(node.property)[nodeValue]
					) {
						const replacement = propertyValuesReplacements.get(
							node.property,
						)[nodeValue];
						if (replacement) {
							context.report({
								loc: node.value.children[0].loc,
								messageId: "notLogicalValue",
								data: {
									value: nodeValue,
									replacement,
								},
							});
						}
					}
				}
			},
			Dimension(node) {
				const allowUnits = context.options[0].allowUnits;
				if (
					unitReplacements.get(node.unit) &&
					!allowUnits.includes(node.unit)
				) {
					context.report({
						loc: node.loc,
						messageId: "notLogicalUnit",
						data: {
							unit: node.unit,
							replacement: unitReplacements.get(node.unit),
						},
					});
				}
			},
		};
	},
};

/**
 * @fileoverview Enforce the use of relative units for font size.
 * @author Tanuj Kanti
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"allowedFontUnits"} RelativeFontUnitsMessageIds
 * @typedef {[{allowUnits?: string[]}]} RelativeFontUnitsOptions
 * @typedef {CSSRuleDefinition<{ RuleOptions: RelativeFontUnitsOptions, MessageIds: RelativeFontUnitsMessageIds}>} RelativeFontUnitsRuleDefinition
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

const relativeFontUnits = [
	"%",
	"cap",
	"ch",
	"em",
	"ex",
	"ic",
	"lh",
	"rcap",
	"rch",
	"rem",
	"rex",
	"ric",
	"rlh",
];

const fontSizeIdentifiers = new Set([
	"xx-small",
	"x-small",
	"small",
	"medium",
	"large",
	"x-large",
	"xx-large",
	"xxx-large",
	"smaller",
	"larger",
	"math",
	"inherit",
	"initial",
	"revert",
	"revert-layer",
	"unset",
]);

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {RelativeFontUnitsRuleDefinition} */
var rule8 = {
	meta: {
		type: "suggestion",

		docs: {
			description: "Enforce the use of relative font units",
			recommended: false,
			url: "https://github.com/eslint/css/blob/main/docs/rules/relative-font-units.md",
		},

		schema: [
			{
				type: "object",
				properties: {
					allowUnits: {
						type: "array",
						items: {
							enum: relativeFontUnits,
							uniqueItems: true,
						},
					},
				},
			},
		],

		defaultOptions: [
			{
				allowUnits: ["rem"],
			},
		],

		messages: {
			allowedFontUnits:
				"Use only allowed relative units for 'font-size' - {{allowedFontUnits}}.",
		},
	},

	create(context) {
		const [{ allowUnits: allowedFontUnits }] = context.options;

		return {
			Declaration(node) {
				if (node.property === "font-size") {
					if (
						node.value.type === "Value" &&
						node.value.children.length > 0
					) {
						const value = node.value.children[0];

						if (
							(value.type === "Dimension" &&
								!allowedFontUnits.includes(value.unit)) ||
							value.type === "Identifier" ||
							(value.type === "Percentage" &&
								!allowedFontUnits.includes("%"))
						) {
							context.report({
								loc: value.loc,
								messageId: "allowedFontUnits",
								data: {
									allowedFontUnits:
										allowedFontUnits.join(", "),
								},
							});
						}
					}
				}

				if (node.property === "font") {
					if (
						node.value.type === "Value" &&
						node.value.children.length > 0
					) {
						const value = node.value;

						const dimensionNode = value.children.find(
							child => child.type === "Dimension",
						);
						const identifierNode = value.children.find(
							child =>
								child.type === "Identifier" &&
								fontSizeIdentifiers.has(child.name),
						);
						const percentageNode = value.children.find(
							child => child.type === "Percentage",
						);
						let location;
						let shouldReport = false;

						const conditions = [
							{
								check:
									!allowedFontUnits.includes("%") &&
									percentageNode,
								loc: percentageNode?.loc,
							},
							{
								check: identifierNode,
								loc: identifierNode?.loc,
							},
							{
								check:
									dimensionNode &&
									!allowedFontUnits.includes(
										dimensionNode.unit,
									),
								loc: dimensionNode?.loc,
							},
						];
						for (const condition of conditions) {
							if (condition.check) {
								shouldReport = true;
								location = condition.loc;
								break;
							}
						}

						if (shouldReport) {
							context.report({
								loc: location,
								messageId: "allowedFontUnits",
								data: {
									allowedFontUnits:
										allowedFontUnits.join(", "),
								},
							});
						}
					}
				}
			},
		};
	},
};

/**
 * @fileoverview CSS features extracted from the web-features package.
 * @author tools/generate-baseline.js
 *
 * THIS FILE IS AUTOGENERATED. DO NOT MODIFY DIRECTLY.
 */

const BASELINE_HIGH = 10;
const BASELINE_LOW = 5;

const properties = new Map([
	["accent-color", "0:"],
	["alignment-baseline", "0:"],
	["all", "10:2020"],
	["anchor-name", "0:"],
	["anchor-scope", "0:"],
	["position-anchor", "0:"],
	["position-area", "0:"],
	["position-try", "0:"],
	["position-try-fallbacks", "0:"],
	["position-try-order", "0:"],
	["position-visibility", "0:"],
	["animation-composition", "5:2023"],
	["animation", "10:2015"],
	["animation-delay", "10:2015"],
	["animation-direction", "10:2015"],
	["animation-duration", "10:2015"],
	["animation-fill-mode", "10:2015"],
	["animation-iteration-count", "10:2015"],
	["animation-name", "10:2015"],
	["animation-play-state", "10:2015"],
	["animation-timing-function", "10:2015"],
	["appearance", "10:2022"],
	["aspect-ratio", "10:2021"],
	["backdrop-filter", "5:2024"],
	["background", "10:2015"],
	["background-attachment", "10:2015"],
	["background-blend-mode", "10:2020"],
	["background-clip", "10:2015"],
	["background-color", "10:2015"],
	["background-image", "10:2015"],
	["background-origin", "10:2015"],
	["background-position", "10:2015"],
	["background-position-x", "10:2016"],
	["background-position-y", "10:2016"],
	["background-repeat", "10:2015"],
	["background-size", "10:2015"],
	["baseline-shift", "0:"],
	["baseline-source", "0:"],
	["border-image", "10:2015"],
	["border-image-outset", "10:2015"],
	["border-image-repeat", "10:2016"],
	["border-image-slice", "10:2015"],
	["border-image-source", "10:2015"],
	["border-image-width", "10:2015"],
	["border-bottom-left-radius", "10:2015"],
	["border-bottom-right-radius", "10:2015"],
	["border-radius", "10:2015"],
	["border-top-left-radius", "10:2015"],
	["border-top-right-radius", "10:2015"],
	["border", "10:2015"],
	["border-bottom", "10:2015"],
	["border-bottom-color", "10:2015"],
	["border-bottom-style", "10:2015"],
	["border-bottom-width", "10:2015"],
	["border-color", "10:2015"],
	["border-left", "10:2015"],
	["border-left-color", "10:2015"],
	["border-left-style", "10:2015"],
	["border-left-width", "10:2015"],
	["border-right", "10:2015"],
	["border-right-color", "10:2015"],
	["border-right-style", "10:2015"],
	["border-right-width", "10:2015"],
	["border-style", "10:2015"],
	["border-top", "10:2015"],
	["border-top-color", "10:2015"],
	["border-top-style", "10:2015"],
	["border-top-width", "10:2015"],
	["border-width", "10:2015"],
	["box-decoration-break", "0:"],
	["box-shadow", "10:2015"],
	["box-sizing", "10:2015"],
	["caret-color", "10:2020"],
	["clip", "0:"],
	["clip-path", "10:2020"],
	["color", "10:2015"],
	["color-adjust", "0:"],
	["color-scheme", "10:2022"],
	["column-fill", "10:2017"],
	["column-span", "10:2020"],
	["contain", "10:2022"],
	["contain-intrinsic-block-size", "5:2023"],
	["contain-intrinsic-height", "5:2023"],
	["contain-intrinsic-inline-size", "5:2023"],
	["contain-intrinsic-size", "5:2023"],
	["contain-intrinsic-width", "5:2023"],
	["container", "5:2023"],
	["container-name", "5:2023"],
	["container-type", "5:2023"],
	["content", "10:2015"],
	["content-visibility", "5:2024"],
	["counter-set", "5:2023"],
	["counter-increment", "10:2015"],
	["counter-reset", "10:2015"],
	["custom-property", "10:2017"],
	["display", "10:2015"],
	["dominant-baseline", "10:2020"],
	["field-sizing", "0:"],
	["filter", "10:2016"],
	["align-content", "10:2015"],
	["align-items", "10:2015"],
	["align-self", "10:2015"],
	["flex", "10:2015"],
	["flex-basis", "10:2015"],
	["flex-direction", "10:2015"],
	["flex-flow", "10:2015"],
	["flex-grow", "10:2015"],
	["flex-shrink", "10:2015"],
	["flex-wrap", "10:2015"],
	["justify-content", "10:2015"],
	["justify-items", "10:2016"],
	["order", "10:2015"],
	["place-content", "10:2020"],
	["place-items", "10:2020"],
	["place-self", "10:2020"],
	["clear", "10:2015"],
	["float", "10:2015"],
	["font-family", "10:2015"],
	["font-feature-settings", "10:2017"],
	["font-kerning", "10:2020"],
	["font-language-override", "0:"],
	["font-optical-sizing", "10:2020"],
	["font-palette", "10:2022"],
	["font", "10:2015"],
	["font-size", "10:2015"],
	["font-size-adjust", "5:2024"],
	["font-stretch", "0:"],
	["font-style", "10:2015"],
	["font-synthesis", "10:2022"],
	["font-synthesis-position", "0:"],
	["font-synthesis-small-caps", "5:2023"],
	["font-synthesis-style", "5:2023"],
	["font-synthesis-weight", "5:2023"],
	["font-variant", "10:2015"],
	["font-variant-alternates", "5:2023"],
	["font-variant-caps", "10:2020"],
	["font-variant-east-asian", "10:2020"],
	["font-variant-emoji", "0:"],
	["font-variant-ligatures", "10:2020"],
	["font-variant-numeric", "10:2020"],
	["font-variant-position", "0:"],
	["font-variation-settings", "10:2018"],
	["font-weight", "10:2015"],
	["font-width", "0:"],
	["forced-color-adjust", "0:"],
	["glyph-orientation-vertical", "0:"],
	["gap", "10:2017"],
	["grid", "10:2017"],
	["grid-area", "10:2017"],
	["grid-auto-columns", "10:2020"],
	["grid-auto-flow", "10:2017"],
	["grid-auto-rows", "10:2020"],
	["grid-column", "10:2017"],
	["grid-column-end", "10:2017"],
	["grid-column-start", "10:2017"],
	["grid-row", "10:2017"],
	["grid-row-end", "10:2017"],
	["grid-row-start", "10:2017"],
	["grid-template", "10:2017"],
	["grid-template-areas", "10:2017"],
	["grid-template-columns", "10:2017"],
	["grid-template-rows", "10:2017"],
	["justify-self", "10:2017"],
	["row-gap", "10:2017"],
	["hanging-punctuation", "0:"],
	["hyphenate-character", "5:2023"],
	["hyphenate-limit-chars", "0:"],
	["hyphens", "5:2023"],
	["image-orientation", "10:2020"],
	["image-rendering", "10:2020"],
	["ime-mode", "0:"],
	["rotate", "10:2022"],
	["scale", "10:2022"],
	["translate", "10:2022"],
	["initial-letter", "0:"],
	["interpolate-size", "0:"],
	["isolation", "10:2020"],
	["direction", "10:2015"],
	["unicode-bidi", "10:2015"],
	["letter-spacing", "10:2015"],
	["line-break", "10:2020"],
	["line-clamp", "0:"],
	["line-height", "10:2015"],
	["list-style", "10:2015"],
	["list-style-image", "10:2015"],
	["list-style-position", "10:2015"],
	["list-style-type", "10:2015"],
	["block-size", "10:2020"],
	["border-block", "10:2021"],
	["border-block-color", "10:2021"],
	["border-block-end", "10:2020"],
	["border-block-end-color", "10:2020"],
	["border-block-end-style", "10:2020"],
	["border-block-end-width", "10:2020"],
	["border-block-start", "10:2020"],
	["border-block-start-color", "10:2020"],
	["border-block-start-style", "10:2020"],
	["border-block-start-width", "10:2020"],
	["border-block-style", "10:2021"],
	["border-block-width", "10:2021"],
	["border-end-end-radius", "10:2021"],
	["border-end-start-radius", "10:2021"],
	["border-inline", "10:2021"],
	["border-inline-color", "10:2021"],
	["border-inline-end", "10:2020"],
	["border-inline-end-color", "10:2020"],
	["border-inline-end-style", "10:2020"],
	["border-inline-end-width", "10:2020"],
	["border-inline-start", "10:2020"],
	["border-inline-start-color", "10:2020"],
	["border-inline-start-style", "10:2020"],
	["border-inline-start-width", "10:2020"],
	["border-inline-style", "10:2021"],
	["border-inline-width", "10:2021"],
	["border-start-end-radius", "10:2021"],
	["border-start-start-radius", "10:2021"],
	["inline-size", "10:2020"],
	["inset", "10:2021"],
	["inset-block", "10:2021"],
	["inset-block-end", "10:2021"],
	["inset-block-start", "10:2021"],
	["inset-inline", "10:2021"],
	["inset-inline-end", "10:2021"],
	["inset-inline-start", "10:2021"],
	["margin-block", "10:2021"],
	["margin-block-end", "10:2020"],
	["margin-block-start", "10:2020"],
	["margin-inline", "10:2021"],
	["margin-inline-end", "10:2020"],
	["margin-inline-start", "10:2020"],
	["max-block-size", "10:2020"],
	["max-inline-size", "10:2020"],
	["min-block-size", "10:2020"],
	["min-inline-size", "10:2020"],
	["overflow-block", "0:"],
	["overflow-inline", "0:"],
	["padding-block", "10:2021"],
	["padding-block-end", "10:2020"],
	["padding-block-start", "10:2020"],
	["padding-inline", "10:2021"],
	["padding-inline-end", "10:2020"],
	["padding-inline-start", "10:2020"],
	["margin", "10:2015"],
	["margin-bottom", "10:2015"],
	["margin-left", "10:2015"],
	["margin-right", "10:2015"],
	["margin-top", "10:2015"],
	["margin-trim", "0:"],
	["mask-border", "0:"],
	["mask-border-outset", "0:"],
	["mask-border-repeat", "0:"],
	["mask-border-slice", "0:"],
	["mask-border-source", "0:"],
	["mask-border-width", "0:"],
	["mask-type", "10:2020"],
	["mask", "5:2023"],
	["mask-clip", "5:2023"],
	["mask-composite", "5:2023"],
	["mask-image", "5:2023"],
	["mask-mode", "5:2023"],
	["mask-origin", "5:2023"],
	["mask-position", "5:2023"],
	["mask-repeat", "5:2023"],
	["mask-size", "5:2023"],
	["math-depth", "0:"],
	["math-shift", "0:"],
	["math-style", "5:2023"],
	["max-height", "10:2015"],
	["max-width", "10:2015"],
	["min-height", "10:2015"],
	["min-width", "10:2015"],
	["mix-blend-mode", "10:2020"],
	["offset", "10:2022"],
	["offset-anchor", "5:2023"],
	["offset-distance", "10:2022"],
	["offset-path", "10:2022"],
	["offset-position", "5:2024"],
	["offset-rotate", "10:2022"],
	["column-count", "10:2017"],
	["column-gap", "10:2015"],
	["column-rule", "10:2017"],
	["column-rule-color", "10:2017"],
	["column-rule-style", "10:2017"],
	["column-rule-width", "10:2017"],
	["column-width", "10:2016"],
	["columns", "10:2017"],
	["object-fit", "10:2020"],
	["object-position", "10:2020"],
	["object-view-box", "0:"],
	["opacity", "10:2015"],
	["fill-opacity", "10:2017"],
	["stroke-opacity", "10:2017"],
	["outline", "5:2023"],
	["outline-color", "10:2015"],
	["outline-offset", "10:2017"],
	["outline-style", "10:2015"],
	["outline-width", "10:2015"],
	["overflow-anchor", "0:"],
	["overflow-clip-margin", "0:"],
	["overflow", "10:2015"],
	["overflow-x", "10:2015"],
	["overflow-y", "10:2015"],
	["overflow-wrap", "10:2018"],
	["overlay", "0:"],
	["overscroll-behavior", "10:2022"],
	["overscroll-behavior-block", "10:2022"],
	["overscroll-behavior-inline", "10:2022"],
	["overscroll-behavior-x", "10:2022"],
	["overscroll-behavior-y", "10:2022"],
	["padding", "10:2015"],
	["padding-bottom", "10:2015"],
	["padding-left", "10:2015"],
	["padding-right", "10:2015"],
	["padding-top", "10:2015"],
	["page-break-after", "0:"],
	["page-break-before", "0:"],
	["page-break-inside", "0:"],
	["break-after", "10:2019"],
	["break-before", "10:2019"],
	["break-inside", "10:2019"],
	["page", "5:2023"],
	["paint-order", "5:2024"],
	["bottom", "10:2015"],
	["left", "10:2015"],
	["right", "10:2015"],
	["top", "10:2015"],
	["pointer-events", "10:2015"],
	["position", "10:2015"],
	["print-color-adjust", "5:2025"],
	["quotes", "10:2015"],
	["reading-flow", "0:"],
	["resize", "0:"],
	["ruby-align", "5:2024"],
	["ruby-overhang", "0:"],
	["ruby-position", "5:2024"],
	["scroll-behavior", "10:2022"],
	["animation-range", "0:"],
	["animation-range-end", "0:"],
	["animation-range-start", "0:"],
	["animation-timeline", "0:"],
	["scroll-timeline", "0:"],
	["scroll-timeline-axis", "0:"],
	["scroll-timeline-name", "0:"],
	["timeline-scope", "0:"],
	["view-timeline", "0:"],
	["view-timeline-axis", "0:"],
	["view-timeline-inset", "0:"],
	["view-timeline-name", "0:"],
	["scroll-initial-target", "0:"],
	["scroll-marker-group", "0:"],
	["scroll-margin", "10:2021"],
	["scroll-margin-block", "10:2021"],
	["scroll-margin-block-end", "10:2021"],
	["scroll-margin-block-start", "10:2021"],
	["scroll-margin-bottom", "10:2021"],
	["scroll-margin-inline", "10:2021"],
	["scroll-margin-inline-end", "10:2021"],
	["scroll-margin-inline-start", "10:2021"],
	["scroll-margin-left", "10:2021"],
	["scroll-margin-right", "10:2021"],
	["scroll-margin-top", "10:2021"],
	["scroll-padding", "10:2021"],
	["scroll-padding-block", "10:2021"],
	["scroll-padding-block-end", "10:2021"],
	["scroll-padding-block-start", "10:2021"],
	["scroll-padding-bottom", "10:2021"],
	["scroll-padding-inline", "10:2021"],
	["scroll-padding-inline-end", "10:2021"],
	["scroll-padding-inline-start", "10:2021"],
	["scroll-padding-left", "10:2021"],
	["scroll-padding-right", "10:2021"],
	["scroll-padding-top", "10:2021"],
	["scroll-snap-align", "10:2020"],
	["scroll-snap-stop", "10:2022"],
	["scroll-snap-type", "10:2022"],
	["scrollbar-color", "0:"],
	["scrollbar-gutter", "5:2024"],
	["scrollbar-width", "5:2024"],
	["shape-image-threshold", "10:2020"],
	["shape-margin", "10:2020"],
	["shape-outside", "10:2020"],
	["speak", "0:"],
	["speak-as", "0:"],
	["clip-rule", "10:2020"],
	["color-interpolation", "10:2020"],
	["cx", "10:2020"],
	["cy", "10:2020"],
	["d", "0:"],
	["fill", "10:2017"],
	["fill-rule", "10:2017"],
	["marker", "10:2017"],
	["marker-end", "10:2017"],
	["marker-mid", "10:2017"],
	["marker-start", "10:2017"],
	["r", "10:2020"],
	["rx", "5:2024"],
	["ry", "5:2024"],
	["shape-rendering", "10:2020"],
	["stop-color", "10:2017"],
	["stop-opacity", "10:2017"],
	["stroke", "10:2017"],
	["stroke-color", "0:"],
	["stroke-dasharray", "10:2017"],
	["stroke-dashoffset", "10:2017"],
	["stroke-linecap", "10:2017"],
	["stroke-linejoin", "10:2017"],
	["stroke-miterlimit", "10:2017"],
	["stroke-width", "10:2017"],
	["text-anchor", "10:2016"],
	["text-rendering", "10:2020"],
	["vector-effect", "10:2020"],
	["x", "10:2020"],
	["y", "10:2020"],
	["color-interpolation-filters", "10:2020"],
	["flood-color", "10:2015"],
	["flood-opacity", "10:2015"],
	["lighting-color", "10:2015"],
	["tab-size", "10:2021"],
	["border-collapse", "10:2015"],
	["border-spacing", "10:2015"],
	["caption-side", "10:2015"],
	["empty-cells", "10:2015"],
	["table-layout", "10:2015"],
	["text-align", "10:2015"],
	["text-align-last", "10:2022"],
	["text-autospace", "0:"],
	["text-box", "0:"],
	["text-box-edge", "0:"],
	["text-box-trim", "0:"],
	["text-combine-upright", "10:2022"],
	["text-decoration", "10:2015"],
	["text-decoration-color", "10:2020"],
	["text-decoration-line", "10:2020"],
	["text-decoration-skip", "0:"],
	["text-decoration-skip-ink", "10:2022"],
	["text-decoration-style", "10:2020"],
	["text-decoration-thickness", "10:2021"],
	["text-emphasis", "10:2022"],
	["text-emphasis-color", "10:2022"],
	["text-emphasis-position", "10:2022"],
	["text-emphasis-style", "10:2022"],
	["text-indent", "10:2015"],
	["text-justify", "0:"],
	["text-orientation", "10:2020"],
	["text-overflow", "10:2015"],
	["text-shadow", "10:2015"],
	["text-size-adjust", "0:"],
	["text-spacing-trim", "0:"],
	["-webkit-text-fill-color", "10:2016"],
	["-webkit-text-stroke", "10:2017"],
	["-webkit-text-stroke-color", "10:2017"],
	["-webkit-text-stroke-width", "10:2017"],
	["text-transform", "10:2015"],
	["text-underline-offset", "10:2020"],
	["text-underline-position", "10:2020"],
	["text-wrap", "5:2024"],
	["text-wrap-mode", "5:2024"],
	["text-wrap-style", "5:2024"],
	["touch-action", "10:2019"],
	["transform-box", "10:2020"],
	["transform", "10:2015"],
	["transform-origin", "10:2015"],
	["backface-visibility", "10:2022"],
	["perspective", "10:2015"],
	["perspective-origin", "10:2015"],
	["transform-style", "10:2015"],
	["transition-behavior", "5:2024"],
	["transition", "10:2015"],
	["transition-delay", "10:2015"],
	["transition-duration", "10:2015"],
	["transition-property", "10:2015"],
	["transition-timing-function", "10:2015"],
	["user-select", "0:"],
	["vertical-align", "10:2015"],
	["view-transition-class", "0:"],
	["view-transition-name", "0:"],
	["visibility", "10:2015"],
	["white-space", "10:2015"],
	["white-space-collapse", "5:2024"],
	["orphans", "0:"],
	["widows", "0:"],
	["height", "10:2015"],
	["width", "10:2015"],
	["will-change", "10:2020"],
	["word-break", "10:2015"],
	["word-spacing", "10:2015"],
	["writing-mode", "10:2017"],
	["z-index", "10:2015"],
	["zoom", "5:2024"],
]);
const atRules = new Map([
	["position-try", "0:"],
	["keyframes", "10:2015"],
	["layer", "10:2022"],
	["charset", "10:2015"],
	["container", "5:2023"],
	["counter-style", "5:2023"],
	["view-transition", "0:"],
	["font-face", "10:2015"],
	["font-palette-values", "10:2022"],
	["font-feature-values", "5:2023"],
	["import", "10:2015"],
	["media", "10:2015"],
	["namespace", "10:2015"],
	["page", "5:2024"],
	["property", "5:2024"],
	["scope", "0:"],
	["starting-style", "5:2024"],
	["supports", "10:2015"],
]);
const mediaConditions = new Map([
	["color-gamut", "5:2023"],
	["device-posture", "0:"],
	["device-aspect-ratio", "0:"],
	["device-height", "0:"],
	["device-width", "0:"],
	["display-mode", "0:"],
	["dynamic-range", "10:2022"],
	["forced-colors", "10:2022"],
	["any-hover", "10:2018"],
	["any-pointer", "10:2018"],
	["hover", "10:2018"],
	["pointer", "10:2018"],
	["inverted-colors", "0:"],
	["aspect-ratio", "10:2015"],
	["calc", "10:2020"],
	["color", "10:2015"],
	["color-index", "0:"],
	["grid", "10:2015"],
	["height", "10:2015"],
	["monochrome", "10:2020"],
	["nested-queries", "10:2015"],
	["orientation", "10:2015"],
	["width", "10:2015"],
	["overflow-block", "5:2023"],
	["overflow-inline", "5:2023"],
	["prefers-color-scheme", "10:2020"],
	["prefers-contrast", "10:2022"],
	["prefers-reduced-data", "0:"],
	["prefers-reduced-motion", "10:2020"],
	["prefers-reduced-transparency", "0:"],
	["resolution", "10:2022"],
	["-webkit-device-pixel-ratio", "10:2018"],
	["-webkit-max-device-pixel-ratio", "10:2018"],
	["-webkit-min-device-pixel-ratio", "10:2018"],
	["scripting", "5:2023"],
	["-webkit-transform-3d", "10:2016"],
	["update", "5:2023"],
	["video-dynamic-range", "0:"],
]);
const types = new Map([
	["abs", "5:2025"],
	["sign", "0:"],
	["anchor", "0:"],
	["anchor-size", "0:"],
	["color", "5:2023"],
	["attr", "10:2015"],
	["calc", "10:2015"],
	["calc-size", "0:"],
	["rect", "0:"],
	["color-mix", "5:2023"],
	["conic-gradient", "10:2020"],
	["repeating-conic-gradient", "10:2020"],
	["counter", "10:2015"],
	["counters", "10:2015"],
	["cross-fade", "0:"],
	["cubic-bezier", "10:2015"],
	["var", "10:2017"],
	["element", "0:"],
	["exp", "5:2023"],
	["hypot", "5:2023"],
	["log", "5:2023"],
	["pow", "5:2023"],
	["sqrt", "5:2023"],
	["blur", "10:2016"],
	["brightness", "10:2016"],
	["contrast", "10:2016"],
	["drop-shadow", "10:2016"],
	["grayscale", "10:2016"],
	["hue-rotate", "10:2016"],
	["invert", "10:2016"],
	["opacity", "10:2016"],
	["saturate", "10:2016"],
	["sepia", "10:2016"],
	["linear-gradient", "10:2015"],
	["radial-gradient", "10:2015"],
	["repeating-linear-gradient", "10:2015"],
	["repeating-radial-gradient", "10:2015"],
	["image", "10:2015"],
	["hsl", "10:2015"],
	["hwb", "10:2022"],
	["image-set", "5:2023"],
	["lab", "5:2023"],
	["lch", "5:2023"],
	["light-dark", "5:2024"],
	["clamp", "10:2020"],
	["max", "10:2020"],
	["min", "10:2020"],
	["ray", "5:2024"],
	["oklab", "5:2023"],
	["oklch", "5:2023"],
	["paint", "0:"],
	["path", "10:2020"],
	["rem", "5:2024"],
	["rgb", "10:2015"],
	["mod", "5:2024"],
	["round", "5:2024"],
	["env", "10:2020"],
	["circle", "10:2020"],
	["ellipse", "10:2020"],
	["inset", "10:2020"],
	["polygon", "10:2020"],
	["xywh", "0:"],
	["steps", "10:2015"],
	["matrix", "10:2015"],
	["rotate", "10:2015"],
	["scale", "10:2015"],
	["scaleX", "10:2015"],
	["scaleY", "10:2015"],
	["skew", "10:2015"],
	["skewX", "10:2015"],
	["skewY", "10:2015"],
	["translate", "10:2015"],
	["translateX", "10:2015"],
	["translateY", "10:2015"],
	["matrix3d", "10:2015"],
	["perspective", "10:2015"],
	["rotate3d", "10:2015"],
	["rotateX", "10:2015"],
	["rotateY", "10:2015"],
	["rotateZ", "10:2015"],
	["scale3d", "10:2015"],
	["scaleZ", "10:2015"],
	["translate3d", "10:2015"],
	["translateZ", "10:2015"],
	["acos", "5:2023"],
	["asin", "5:2023"],
	["atan", "5:2023"],
	["atan2", "5:2023"],
	["cos", "5:2023"],
	["sin", "5:2023"],
	["tan", "5:2023"],
]);
const selectors = new Map([
	["active-view-transition", "0:"],
	["active-view-transition-type", "0:"],
	["autofill", "5:2023"],
	["defined", "10:2020"],
	["backdrop", "10:2022"],
	["after", "10:2015"],
	["before", "10:2015"],
	["checkmark", "0:"],
	["picker", "0:"],
	["picker-icon", "0:"],
	["default", "10:2020"],
	["details-content", "0:"],
	["dir", "5:2023"],
	["empty", "10:2015"],
	["file-selector-button", "10:2021"],
	["first-letter", "10:2015"],
	["first-line", "10:2015"],
	["focus-visible", "10:2022"],
	["focus-within", "10:2020"],
	["in-range", "10:2015"],
	["invalid", "10:2015"],
	["optional", "10:2015"],
	["out-of-range", "10:2015"],
	["required", "10:2015"],
	["valid", "10:2015"],
	["fullscreen", "0:"],
	["has", "5:2023"],
	["has-slotted", "0:"],
	["highlight", "0:"],
	["host", "10:2020"],
	["hostfunction", "10:2020"],
	["host-context", "0:"],
	["indeterminate", "10:2015"],
	["checked", "10:2015"],
	["disabled", "10:2015"],
	["enabled", "10:2015"],
	["is", "10:2021"],
	["lang", "10:2015"],
	["any-link", "10:2020"],
	["link", "10:2015"],
	["visited", "10:2015"],
	["marker", "0:"],
	["buffering", "0:"],
	["muted", "0:"],
	["paused", "0:"],
	["playing", "0:"],
	["seeking", "0:"],
	["stalled", "0:"],
	["volume-locked", "0:"],
	["modal", "10:2022"],
	["namespace", "10:2015"],
	["nesting", "5:2023"],
	["not", "10:2015"],
	["first-child", "10:2015"],
	["last-child", "10:2015"],
	["nth-child", "10:2015"],
	["nth-last-child", "10:2015"],
	["only-child", "10:2015"],
	["first-of-type", "10:2015"],
	["last-of-type", "10:2015"],
	["nth-last-of-type", "10:2015"],
	["nth-of-type", "10:2015"],
	["only-of-type", "10:2015"],
	["closed", "0:"],
	["open", "0:"],
	["first", "5:2023"],
	["left", "0:"],
	["right", "0:"],
	["picture-in-picture", "0:"],
	["placeholder", "10:2020"],
	["placeholder-shown", "10:2020"],
	["popover-open", "5:2024"],
	["read-only", "10:2020"],
	["read-write", "10:2020"],
	["root", "10:2015"],
	["scope", "10:2020"],
	["scroll-marker", "0:"],
	["scroll-marker-group", "0:"],
	["selection", "0:"],
	["attribute", "10:2015"],
	["child", "10:2015"],
	["class", "10:2015"],
	["descendant", "10:2015"],
	["id", "10:2015"],
	["list", "10:2015"],
	["next-sibling", "10:2015"],
	["subsequent-sibling", "10:2015"],
	["type", "10:2015"],
	["universal", "10:2015"],
	["part", "10:2020"],
	["slotted", "10:2020"],
	["grammar-error", "0:"],
	["spelling-error", "0:"],
	["state", "5:2024"],
	["target", "10:2015"],
	["target-text", "5:2024"],
	["future", "0:"],
	["past", "0:"],
	["active", "10:2015"],
	["focus", "10:2015"],
	["hover", "10:2015"],
	["user-invalid", "5:2023"],
	["user-valid", "5:2023"],
	["view-transition", "0:"],
	["view-transition-group", "0:"],
	["view-transition-image-pair", "0:"],
	["view-transition-new", "0:"],
	["view-transition-old", "0:"],
	["cue", "10:2020"],
	["xr-overlay", "0:"],
	["where", "10:2021"],
]);
const propertyValues = new Map([
	[
		"position",
		new Map([
			["absolute", "10:2015"],
			["fixed", "10:2015"],
			["relative", "10:2015"],
			["static", "10:2015"],
			["sticky", "10:2019"],
		]),
	],
	["accent-color", new Map([["auto", "0:"]])],
	[
		"alignment-baseline",
		new Map([
			["alphabetic", "0:"],
			["baseline", "0:"],
			["central", "0:"],
			["ideographic", "0:"],
			["mathematical", "0:"],
			["middle", "0:"],
		]),
	],
	["align-items", new Map([["anchor-center", "0:"]])],
	["align-self", new Map([["anchor-center", "0:"]])],
	["anchor-name", new Map([["none", "0:"]])],
	[
		"anchor-scope",
		new Map([
			["all", "0:"],
			["none", "0:"],
		]),
	],
	[
		"block-size",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
		]),
	],
	[
		"bottom",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"height",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["stretch", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"inline-size",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
		]),
	],
	[
		"inset-block-end",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	[
		"inset-block-start",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	[
		"inset-block",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	[
		"inset-inline-end",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	[
		"inset-inline-start",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	[
		"inset-inline",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	[
		"inset",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2021"],
		]),
	],
	["justify-items", new Map([["anchor-center", "0:"]])],
	["justify-self", new Map([["anchor-center", "0:"]])],
	[
		"left",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	["margin-block-end", new Map([["anchor-size", "0:"]])],
	["margin-block-start", new Map([["anchor-size", "0:"]])],
	["margin-block", new Map([["anchor-size", "0:"]])],
	[
		"margin-bottom",
		new Map([
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	["margin-inline-end", new Map([["anchor-size", "0:"]])],
	["margin-inline-start", new Map([["anchor-size", "0:"]])],
	["margin-inline", new Map([["anchor-size", "0:"]])],
	[
		"margin-left",
		new Map([
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"margin-right",
		new Map([
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"margin-top",
		new Map([
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"margin",
		new Map([
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"max-block-size",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
		]),
	],
	[
		"max-height",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["none", "10:2015"],
			["stretch", "0:"],
		]),
	],
	[
		"max-inline-size",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
		]),
	],
	[
		"max-width",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["none", "10:2015"],
			["stretch", "0:"],
		]),
	],
	[
		"min-block-size",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
		]),
	],
	[
		"min-height",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["auto", "10:2015"],
			["stretch", "0:"],
		]),
	],
	[
		"min-inline-size",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
		]),
	],
	[
		"min-width",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["auto", "10:2015"],
			["stretch", "0:"],
		]),
	],
	["place-items", new Map([["anchor-center", "0:"]])],
	["place-self", new Map([["anchor-center", "0:"]])],
	["position-anchor", new Map([["auto", "0:"]])],
	[
		"position-area",
		new Map([
			["block-end", "0:"],
			["block-start", "0:"],
			["bottom", "0:"],
			["center", "0:"],
			["end", "0:"],
			["inline-end", "0:"],
			["inline-start", "0:"],
			["left", "0:"],
			["none", "0:"],
			["right", "0:"],
			["self-end", "0:"],
			["self-start", "0:"],
			["span-all", "0:"],
			["span-block-end", "0:"],
			["span-block-start", "0:"],
			["span-bottom", "0:"],
			["span-end", "0:"],
			["span-inline-end", "0:"],
			["span-inline-start", "0:"],
			["span-start", "0:"],
			["span-top", "0:"],
			["span-x-end", "0:"],
			["span-x-start", "0:"],
			["span-y-end", "0:"],
			["span-y-start", "0:"],
			["start", "0:"],
			["top", "0:"],
			["x-end", "0:"],
			["x-self-end", "0:"],
			["x-self-start", "0:"],
			["x-start", "0:"],
			["y-end", "0:"],
			["y-self-end", "0:"],
			["y-self-start", "0:"],
			["y-start", "0:"],
		]),
	],
	[
		"position-try-fallbacks",
		new Map([
			["flip-block", "0:"],
			["flip-inline", "0:"],
			["flip-start", "0:"],
			["none", "0:"],
			["position-area", "0:"],
		]),
	],
	[
		"position-try-order",
		new Map([
			["most-block-size", "0:"],
			["most-height", "0:"],
			["most-inline-size", "0:"],
			["most-width", "0:"],
			["normal", "0:"],
		]),
	],
	[
		"position-visibility",
		new Map([
			["always", "0:"],
			["anchors-visible", "0:"],
			["no-overflow", "0:"],
		]),
	],
	[
		"right",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"top",
		new Map([
			["anchor", "0:"],
			["anchor-size", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"width",
		new Map([
			["anchor-size", "0:"],
			["fit-content", "10:2021"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["stretch", "0:"],
			["auto", "10:2015"],
		]),
	],
	[
		"animation-direction",
		new Map([
			["alternate", "10:2015"],
			["alternate-reverse", "10:2015"],
			["normal", "10:2015"],
			["reverse", "10:2015"],
		]),
	],
	["animation-duration", new Map([["auto", "0:"]])],
	[
		"animation-fill-mode",
		new Map([
			["backwards", "10:2015"],
			["both", "10:2015"],
			["forwards", "10:2015"],
			["none", "10:2015"],
		]),
	],
	["animation-iteration-count", new Map([["infinite", "10:2015"]])],
	["animation-name", new Map([["none", "10:2015"]])],
	[
		"animation-play-state",
		new Map([
			["paused", "10:2015"],
			["running", "10:2015"],
		]),
	],
	["animation-timing-function", new Map([["jump", "10:2020"]])],
	[
		"appearance",
		new Map([
			["auto", "10:2022"],
			["button", "10:2022"],
			["checkbox", "10:2022"],
			["listbox", "10:2022"],
			["menulist", "10:2022"],
			["menulist-button", "10:2022"],
			["meter", "10:2022"],
			["none", "10:2022"],
			["progress-bar", "10:2022"],
			["radio", "10:2022"],
			["searchfield", "10:2022"],
			["textarea", "10:2022"],
			["textfield", "10:2022"],
			["base-select", "0:"],
		]),
	],
	["aspect-ratio", new Map([["auto", "10:2021"]])],
	[
		"background-attachment",
		new Map([
			["fixed", "10:2022"],
			["local", "10:2022"],
			["scroll", "10:2015"],
		]),
	],
	[
		"background-clip",
		new Map([
			["border-box", "10:2015"],
			["content-box", "10:2015"],
			["padding-box", "10:2015"],
			["border-area", "0:"],
			["text", "0:"],
		]),
	],
	[
		"background",
		new Map([
			["background-clip", "10:2015"],
			["background-origin", "10:2015"],
			["background-size", "10:2015"],
		]),
	],
	[
		"background-image",
		new Map([
			["none", "10:2015"],
			["element", "0:"],
			["gradients", "10:2015"],
			["image-set", "5:2023"],
		]),
	],
	[
		"background-origin",
		new Map([
			["border-box", "10:2015"],
			["content-box", "10:2015"],
			["padding-box", "10:2015"],
		]),
	],
	[
		"background-position",
		new Map([
			["bottom", "10:2020"],
			["center", "10:2020"],
			["left", "10:2020"],
			["right", "10:2020"],
			["top", "10:2020"],
		]),
	],
	[
		"background-repeat",
		new Map([
			["2-value", "10:2015"],
			["no-repeat", "10:2015"],
			["repeat", "10:2015"],
			["repeat-x", "10:2015"],
			["repeat-y", "10:2015"],
			["round", "10:2016"],
			["space", "10:2016"],
		]),
	],
	[
		"background-size",
		new Map([
			["auto", "10:2015"],
			["contain", "10:2015"],
			["cover", "10:2015"],
		]),
	],
	[
		"baseline-shift",
		new Map([
			["baseline", "0:"],
			["sub", "0:"],
			["super", "0:"],
		]),
	],
	[
		"baseline-source",
		new Map([
			["auto", "0:"],
			["first", "0:"],
			["last", "0:"],
		]),
	],
	[
		"border-image-repeat",
		new Map([
			["repeat", "10:2016"],
			["round", "10:2016"],
			["space", "10:2017"],
			["stretch", "10:2016"],
		]),
	],
	["border-image-width", new Map([["auto", "10:2015"]])],
	[
		"border-image",
		new Map([
			["fill", "10:2015"],
			["gradient", "10:2015"],
		]),
	],
	["border-bottom-left-radius", new Map([["percentages", "10:2015"]])],
	["border-bottom-right-radius", new Map([["percentages", "10:2015"]])],
	["border-radius", new Map([["percentages", "10:2015"]])],
	["border-top-left-radius", new Map([["percentages", "10:2015"]])],
	["border-top-right-radius", new Map([["percentages", "10:2015"]])],
	[
		"border-style",
		new Map([
			["dashed", "10:2015"],
			["dotted", "10:2015"],
			["double", "10:2015"],
			["groove", "10:2015"],
			["hidden", "10:2015"],
			["inset", "10:2015"],
			["none", "10:2015"],
			["outset", "10:2015"],
			["ridge", "10:2015"],
			["solid", "10:2015"],
		]),
	],
	[
		"box-decoration-break",
		new Map([
			["clone", "0:"],
			["slice", "0:"],
		]),
	],
	["box-shadow", new Map([["inset", "10:2015"]])],
	[
		"box-sizing",
		new Map([
			["border-box", "10:2015"],
			["content-box", "10:2015"],
		]),
	],
	["clip", new Map([["auto", "0:"]])],
	[
		"clip-path",
		new Map([
			["path", "10:2021"],
			["fill-box", "5:2023"],
			["stroke-box", "5:2023"],
			["view-box", "5:2023"],
		]),
	],
	[
		"color-scheme",
		new Map([
			["dark", "10:2022"],
			["light", "10:2022"],
			["normal", "10:2022"],
		]),
	],
	[
		"break-after",
		new Map([
			["avoid-column", "0:"],
			["column", "0:"],
			["always", "0:"],
			["auto", "10:2020"],
			["avoid", "0:"],
			["avoid-page", "0:"],
			["left", "10:2020"],
			["page", "10:2020"],
			["recto", "0:"],
			["right", "10:2020"],
			["verso", "0:"],
		]),
	],
	[
		"break-before",
		new Map([
			["avoid-column", "0:"],
			["column", "0:"],
			["always", "0:"],
			["auto", "10:2020"],
			["avoid", "0:"],
			["avoid-page", "0:"],
			["left", "10:2020"],
			["page", "10:2020"],
			["recto", "0:"],
			["right", "10:2020"],
			["verso", "0:"],
		]),
	],
	[
		"break-inside",
		new Map([
			["avoid-column", "10:2021"],
			["auto", "10:2020"],
			["avoid", "10:2020"],
			["avoid-page", "10:2021"],
		]),
	],
	[
		"column-fill",
		new Map([
			["auto", "10:2017"],
			["balance", "10:2017"],
		]),
	],
	[
		"column-span",
		new Map([
			["all", "10:2020"],
			["none", "10:2020"],
		]),
	],
	[
		"contain",
		new Map([
			["content", "10:2022"],
			["none", "10:2022"],
			["strict", "10:2022"],
			["inline-size", "10:2022"],
			["layout", "10:2022"],
			["paint", "10:2022"],
			["size", "10:2022"],
			["style", "10:2022"],
		]),
	],
	["contain-intrinsic-block-size", new Map([["none", "5:2023"]])],
	["contain-intrinsic-height", new Map([["none", "5:2023"]])],
	["contain-intrinsic-inline-size", new Map([["none", "5:2023"]])],
	["contain-intrinsic-size", new Map([["none", "5:2023"]])],
	["contain-intrinsic-width", new Map([["none", "5:2023"]])],
	["container-name", new Map([["none", "5:2023"]])],
	[
		"container-type",
		new Map([
			["inline-size", "5:2023"],
			["normal", "5:2023"],
			["size", "5:2023"],
			["scroll-state", "0:"],
		]),
	],
	[
		"content",
		new Map([
			["gradient", "0:"],
			["none", "10:2015"],
			["normal", "10:2015"],
			["url", "10:2015"],
			["image-set", "5:2023"],
		]),
	],
	[
		"content-visibility",
		new Map([
			["auto", "0:"],
			["hidden", "5:2024"],
			["visible", "5:2024"],
		]),
	],
	[
		"counter-reset",
		new Map([
			["reversed", "0:"],
			["list-item", "0:"],
			["none", "10:2015"],
		]),
	],
	[
		"counter-set",
		new Map([
			["list-item", "5:2023"],
			["none", "5:2023"],
		]),
	],
	[
		"counter-increment",
		new Map([
			["list-item", "10:2015"],
			["none", "10:2015"],
		]),
	],
	[
		"image-rendering",
		new Map([
			["crisp-edges", "0:"],
			["auto", "10:2020"],
			["pixelated", "10:2021"],
			["smooth", "0:"],
		]),
	],
	[
		"text-overflow",
		new Map([
			["string", "0:"],
			["clip", "10:2015"],
			["ellipsis", "10:2015"],
		]),
	],
	[
		"display",
		new Map([
			["block", "10:2015"],
			["inline", "10:2015"],
			["inline-block", "10:2015"],
			["none", "10:2015"],
			["contents", "10:2020"],
			["flow-root", "10:2020"],
			["list-item", "10:2015"],
			["ruby", "0:"],
			["ruby-base", "0:"],
			["ruby-base-container", "0:"],
			["ruby-text", "0:"],
			["ruby-text-container", "0:"],
			["inline-table", "10:2015"],
			["table", "10:2015"],
			["table-caption", "10:2017"],
			["table-cell", "10:2015"],
			["table-column", "10:2015"],
			["table-column-group", "10:2015"],
			["table-footer-group", "10:2015"],
			["table-header-group", "10:2015"],
			["table-row", "10:2015"],
			["table-row-group", "10:2015"],
			["flex", "10:2015"],
			["inline-flex", "10:2015"],
			["grid", "10:2017"],
			["inline-grid", "10:2017"],
			["math", "0:"],
		]),
	],
	[
		"ruby-position",
		new Map([
			["alternate", "0:"],
			["inter-character", "0:"],
			["over", "5:2024"],
			["under", "5:2024"],
		]),
	],
	[
		"dominant-baseline",
		new Map([
			["alphabetic", "10:2020"],
			["auto", "10:2020"],
			["central", "10:2020"],
			["hanging", "10:2020"],
			["ideographic", "10:2020"],
			["mathematical", "10:2020"],
			["middle", "10:2020"],
		]),
	],
	[
		"field-sizing",
		new Map([
			["content", "0:"],
			["fixed", "0:"],
		]),
	],
	["align-content", new Map([["normal", "10:2015"]])],
	[
		"flex-basis",
		new Map([
			["auto", "10:2015"],
			["content", "10:2022"],
			["fit-content", "10:2022"],
			["max-content", "10:2022"],
			["min-content", "10:2022"],
		]),
	],
	[
		"flex-direction",
		new Map([
			["column", "10:2020"],
			["column-reverse", "10:2020"],
			["row", "10:2020"],
			["row-reverse", "10:2020"],
		]),
	],
	[
		"flex-wrap",
		new Map([
			["nowrap", "10:2015"],
			["wrap", "10:2015"],
			["wrap-reverse", "10:2015"],
		]),
	],
	["flex", new Map([["none", "10:2020"]])],
	[
		"clear",
		new Map([
			["both", "10:2015"],
			["left", "10:2015"],
			["right", "10:2015"],
			["inline-end", "5:2023"],
			["inline-start", "5:2023"],
		]),
	],
	[
		"float",
		new Map([
			["left", "10:2015"],
			["none", "10:2015"],
			["right", "10:2015"],
			["inline-end", "5:2023"],
			["inline-start", "5:2023"],
		]),
	],
	[
		"font-family",
		new Map([
			["math", "0:"],
			["system-ui", "10:2021"],
			["ui-monospace", "0:"],
			["ui-rounded", "0:"],
			["ui-sans-serif", "0:"],
			["ui-serif", "0:"],
		]),
	],
	["font-feature-settings", new Map([["normal", "10:2017"]])],
	[
		"font-kerning",
		new Map([
			["auto", "10:2020"],
			["none", "10:2020"],
			["normal", "10:2020"],
		]),
	],
	[
		"font-optical-sizing",
		new Map([
			["auto", "10:2020"],
			["none", "10:2020"],
		]),
	],
	[
		"font-palette",
		new Map([
			["dark", "10:2022"],
			["light", "10:2022"],
			["normal", "10:2022"],
		]),
	],
	[
		"font",
		new Map([
			["caption", "10:2015"],
			["icon", "10:2015"],
			["menu", "10:2015"],
			["message-box", "10:2015"],
			["small-caption", "10:2015"],
			["status-bar", "10:2015"],
		]),
	],
	[
		"font-size",
		new Map([
			["xxx-large", "5:2023"],
			["math", "0:"],
		]),
	],
	[
		"font-size-adjust",
		new Map([
			["from-font", "5:2024"],
			["none", "5:2024"],
			["two-values", "5:2024"],
		]),
	],
	["font-stretch", new Map([["percentage", "0:"]])],
	[
		"font-style",
		new Map([
			["italic", "10:2015"],
			["normal", "10:2015"],
			["oblique-angle", "0:"],
		]),
	],
	[
		"font-synthesis",
		new Map([
			["position", "0:"],
			["small-caps", "10:2022"],
			["style", "10:2022"],
			["weight", "10:2022"],
		]),
	],
	[
		"font-synthesis-position",
		new Map([
			["auto", "0:"],
			["none", "0:"],
		]),
	],
	[
		"font-synthesis-small-caps",
		new Map([
			["auto", "5:2023"],
			["none", "5:2023"],
		]),
	],
	[
		"font-synthesis-style",
		new Map([
			["auto", "5:2023"],
			["none", "5:2023"],
		]),
	],
	[
		"font-synthesis-weight",
		new Map([
			["auto", "5:2023"],
			["none", "5:2023"],
		]),
	],
	[
		"font-variant",
		new Map([
			["historical-forms", "5:2023"],
			["none", "10:2020"],
			["normal", "10:2015"],
			["sub", "5:2023"],
			["super", "5:2023"],
		]),
	],
	[
		"font-variant-alternates",
		new Map([
			["annotation", "5:2023"],
			["historical-forms", "5:2023"],
			["normal", "5:2023"],
			["ornaments", "5:2023"],
			["styleset", "5:2023"],
			["stylistic", "5:2023"],
			["swash", "5:2023"],
		]),
	],
	[
		"font-variant-caps",
		new Map([
			["all-petite-caps", "10:2020"],
			["all-small-caps", "10:2020"],
			["normal", "10:2020"],
			["petite-caps", "10:2020"],
			["small-caps", "10:2020"],
			["titling-caps", "10:2020"],
			["unicase", "10:2020"],
		]),
	],
	[
		"font-variant-east-asian",
		new Map([
			["full-width", "10:2020"],
			["jis04", "10:2020"],
			["jis78", "10:2020"],
			["jis83", "10:2020"],
			["jis90", "10:2020"],
			["normal", "10:2020"],
			["proportional-width", "10:2020"],
			["ruby", "10:2020"],
			["simplified", "10:2020"],
			["traditional", "10:2020"],
		]),
	],
	[
		"font-variant-emoji",
		new Map([
			["emoji", "0:"],
			["normal", "0:"],
			["text", "0:"],
			["unicode", "0:"],
		]),
	],
	[
		"font-variant-ligatures",
		new Map([
			["common-ligatures", "10:2020"],
			["contextual", "10:2020"],
			["discretionary-ligatures", "10:2020"],
			["historical-ligatures", "10:2020"],
			["no-common-ligatures", "10:2020"],
			["no-contextual", "10:2020"],
			["no-discretionary-ligatures", "10:2020"],
			["no-historical-ligatures", "10:2020"],
			["none", "10:2020"],
			["normal", "10:2020"],
		]),
	],
	[
		"font-variant-numeric",
		new Map([
			["diagonal-fractions", "10:2020"],
			["lining-nums", "10:2020"],
			["normal", "10:2020"],
			["oldstyle-nums", "10:2020"],
			["ordinal", "10:2020"],
			["proportional-nums", "10:2020"],
			["slashed-zero", "10:2020"],
			["stacked-fractions", "10:2020"],
			["tabular-nums", "10:2020"],
		]),
	],
	[
		"font-variant-position",
		new Map([
			["normal", "0:"],
			["sub", "0:"],
			["super", "0:"],
		]),
	],
	[
		"font-weight",
		new Map([
			["bold", "10:2015"],
			["bolder", "10:2015"],
			["lighter", "10:2015"],
			["normal", "10:2015"],
			["number", "10:2018"],
		]),
	],
	[
		"font-width",
		new Map([
			["condensed", "0:"],
			["expanded", "0:"],
			["extra-condensed", "0:"],
			["extra-expanded", "0:"],
			["normal", "0:"],
			["semi-condensed", "0:"],
			["semi-expanded", "0:"],
			["ultra-condensed", "0:"],
			["ultra-expanded", "0:"],
		]),
	],
	[
		"forced-color-adjust",
		new Map([
			["auto", "0:"],
			["none", "0:"],
			["preserve-parent-color", "0:"],
		]),
	],
	["gap", new Map([["normal", "10:2017"]])],
	[
		"grid-auto-flow",
		new Map([
			["column", "10:2020"],
			["dense", "10:2020"],
			["row", "10:2020"],
		]),
	],
	["grid-template-areas", new Map([["none", "10:2020"]])],
	[
		"grid-template-columns",
		new Map([
			["auto", "10:2020"],
			["fit-content", "10:2017"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["minmax", "10:2017"],
			["none", "10:2020"],
			["repeat", "10:2020"],
			["animation", "10:2022"],
			["masonry", "0:"],
			["subgrid", "5:2023"],
		]),
	],
	[
		"grid-template-rows",
		new Map([
			["auto", "10:2020"],
			["fit-content", "10:2017"],
			["max-content", "10:2020"],
			["min-content", "10:2020"],
			["minmax", "10:2017"],
			["none", "10:2020"],
			["repeat", "10:2020"],
			["animation", "10:2022"],
			["masonry", "0:"],
			["subgrid", "5:2023"],
		]),
	],
	["grid-template", new Map([["none", "10:2020"]])],
	["row-gap", new Map([["normal", "10:2017"]])],
	[
		"hanging-punctuation",
		new Map([
			["allow-end", "0:"],
			["first", "0:"],
			["last", "0:"],
			["none", "0:"],
		]),
	],
	["hyphenate-character", new Map([["auto", "5:2023"]])],
	["hyphenate-limit-chars", new Map([["auto", "0:"]])],
	["hyphens", new Map([["auto", "5:2023"]])],
	[
		"image-orientation",
		new Map([
			["from-image", "10:2020"],
			["none", "10:2020"],
		]),
	],
	["rotate", new Map([["none", "10:2022"]])],
	["scale", new Map([["none", "10:2022"]])],
	["translate", new Map([["none", "10:2022"]])],
	["initial-letter", new Map([["normal", "0:"]])],
	[
		"interpolate-size",
		new Map([
			["allow-keywords", "0:"],
			["numeric-only", "0:"],
		]),
	],
	[
		"direction",
		new Map([
			["ltr", "10:2015"],
			["rtl", "10:2015"],
		]),
	],
	[
		"unicode-bidi",
		new Map([
			["bidi-override", "10:2015"],
			["embed", "10:2015"],
			["isolate", "10:2020"],
			["isolate-override", "10:2020"],
			["normal", "10:2015"],
			["plaintext", "10:2020"],
		]),
	],
	["letter-spacing", new Map([["normal", "10:2015"]])],
	[
		"line-break",
		new Map([
			["anywhere", "10:2020"],
			["auto", "10:2020"],
			["loose", "10:2020"],
			["normal", "10:2020"],
			["strict", "10:2020"],
		]),
	],
	["line-clamp", new Map([["none", "0:"]])],
	["line-height", new Map([["normal", "10:2015"]])],
	["list-style-image", new Map([["none", "10:2015"]])],
	[
		"list-style-position",
		new Map([
			["inside", "10:2015"],
			["outside", "10:2015"],
		]),
	],
	[
		"list-style-type",
		new Map([
			["arabic-indic", "10:2020"],
			["armenian", "10:2015"],
			["bengali", "10:2020"],
			["cambodian", "10:2020"],
			["circle", "10:2015"],
			["cjk-decimal", "10:2021"],
			["cjk-earthly-branch", "10:2020"],
			["cjk-heavenly-stem", "10:2020"],
			["cjk-ideographic", "10:2020"],
			["decimal", "10:2015"],
			["decimal-leading-zero", "10:2015"],
			["devanagari", "10:2020"],
			["disc", "10:2015"],
			["disclosure-closed", "10:2021"],
			["disclosure-open", "10:2021"],
			["ethiopic-numeric", "10:2021"],
			["georgian", "10:2015"],
			["gujarati", "10:2020"],
			["gurmukhi", "10:2020"],
			["hebrew", "10:2015"],
			["hiragana", "10:2015"],
			["hiragana-iroha", "10:2015"],
			["japanese-formal", "10:2021"],
			["japanese-informal", "10:2021"],
			["kannada", "10:2020"],
			["katakana", "10:2015"],
			["katakana-iroha", "10:2015"],
			["khmer", "10:2020"],
			["korean-hangul-formal", "10:2021"],
			["korean-hanja-formal", "10:2021"],
			["korean-hanja-informal", "10:2021"],
			["lao", "10:2020"],
			["lower-alpha", "10:2015"],
			["lower-armenian", "10:2020"],
			["lower-greek", "10:2015"],
			["lower-latin", "10:2015"],
			["lower-roman", "10:2015"],
			["malayalam", "10:2020"],
			["mongolian", "10:2020"],
			["myanmar", "10:2020"],
			["none", "10:2015"],
			["oriya", "10:2020"],
			["persian", "10:2020"],
			["simp-chinese-formal", "10:2021"],
			["simp-chinese-informal", "10:2021"],
			["square", "10:2015"],
			["string", "10:2021"],
			["symbols", "0:"],
			["tamil", "10:2021"],
			["telugu", "10:2020"],
			["thai", "10:2020"],
			["tibetan", "10:2020"],
			["trad-chinese-formal", "10:2021"],
			["trad-chinese-informal", "10:2021"],
			["upper-alpha", "10:2015"],
			["upper-armenian", "10:2020"],
			["upper-latin", "10:2015"],
			["upper-roman", "10:2015"],
		]),
	],
	["list-style", new Map([["symbols", "0:"]])],
	["overflow-block", new Map([["overlay", "0:"]])],
	["overflow-inline", new Map([["overlay", "0:"]])],
	[
		"margin-trim",
		new Map([
			["block", "0:"],
			["block-end", "0:"],
			["block-start", "0:"],
			["inline", "0:"],
			["inline-end", "0:"],
			["inline-start", "0:"],
			["none", "0:"],
		]),
	],
	[
		"mask-type",
		new Map([
			["alpha", "10:2020"],
			["luminance", "10:2020"],
		]),
	],
	[
		"mask-clip",
		new Map([
			["border", "0:"],
			["content", "0:"],
			["padding", "0:"],
			["text", "0:"],
		]),
	],
	[
		"mask-composite",
		new Map([
			["add", "5:2023"],
			["exclude", "5:2023"],
			["intersect", "5:2023"],
			["subtract", "5:2023"],
		]),
	],
	[
		"mask-mode",
		new Map([
			["alpha", "5:2023"],
			["luminance", "5:2023"],
			["match-source", "5:2023"],
		]),
	],
	[
		"mask-origin",
		new Map([
			["border", "0:"],
			["content", "0:"],
			["fill-box", "0:"],
			["padding", "0:"],
			["stroke-box", "0:"],
			["view-box", "0:"],
		]),
	],
	[
		"text-transform",
		new Map([
			["math-auto", "0:"],
			["capitalize", "10:2015"],
			["full-size-kana", "0:"],
			["full-width", "0:"],
			["lowercase", "10:2015"],
			["none", "10:2015"],
			["uppercase", "10:2015"],
		]),
	],
	[
		"mix-blend-mode",
		new Map([
			["plus-darker", "0:"],
			["plus-lighter", "10:2022"],
		]),
	],
	[
		"offset-anchor",
		new Map([
			["auto", "5:2023"],
			["bottom", "5:2023"],
			["center", "5:2023"],
			["left", "5:2023"],
			["right", "5:2023"],
			["top", "5:2023"],
		]),
	],
	[
		"offset-path",
		new Map([
			["border-box", "5:2024"],
			["content-box", "5:2024"],
			["fill-box", "5:2024"],
			["margin-box", "0:"],
			["none", "5:2024"],
			["padding-box", "5:2024"],
			["path", "10:2022"],
			["ray", "5:2024"],
			["stroke-box", "5:2024"],
			["url", "5:2024"],
			["view-box", "5:2024"],
		]),
	],
	[
		"offset-position",
		new Map([
			["auto", "5:2024"],
			["bottom", "5:2024"],
			["center", "5:2024"],
			["left", "5:2024"],
			["normal", "5:2024"],
			["right", "5:2024"],
			["top", "5:2024"],
		]),
	],
	[
		"offset-rotate",
		new Map([
			["auto", "10:2022"],
			["reverse", "10:2022"],
		]),
	],
	["column-count", new Map([["auto", "10:2017"]])],
	["column-gap", new Map([["normal", "10:2015"]])],
	["column-width", new Map([["auto", "10:2016"]])],
	[
		"object-fit",
		new Map([
			["contain", "10:2020"],
			["cover", "10:2020"],
			["fill", "10:2020"],
			["none", "10:2020"],
			["scale-down", "10:2020"],
		]),
	],
	["object-view-box", new Map([["none", "0:"]])],
	["opacity", new Map([["percentages", "10:2020"]])],
	[
		"outline-style",
		new Map([
			["auto", "10:2015"],
			["dashed", "10:2015"],
			["dotted", "10:2015"],
			["double", "10:2015"],
			["groove", "10:2015"],
			["inset", "10:2015"],
			["none", "10:2015"],
			["outset", "10:2015"],
			["ridge", "10:2015"],
			["solid", "10:2015"],
		]),
	],
	[
		"overflow-anchor",
		new Map([
			["auto", "0:"],
			["none", "0:"],
		]),
	],
	[
		"overflow-x",
		new Map([
			["clip", "10:2022"],
			["auto", "10:2015"],
			["hidden", "10:2015"],
			["scroll", "10:2015"],
			["visible", "10:2015"],
		]),
	],
	[
		"overflow-y",
		new Map([
			["clip", "10:2022"],
			["auto", "10:2015"],
			["hidden", "10:2015"],
			["scroll", "10:2015"],
			["visible", "10:2015"],
		]),
	],
	[
		"overflow",
		new Map([
			["clip", "10:2022"],
			["auto", "10:2015"],
			["hidden", "10:2015"],
			["scroll", "10:2015"],
			["visible", "10:2015"],
		]),
	],
	[
		"overflow-clip-margin",
		new Map([
			["border-box", "0:"],
			["content-box", "0:"],
			["padding-box", "0:"],
		]),
	],
	[
		"overflow-wrap",
		new Map([
			["anywhere", "10:2022"],
			["break-word", "10:2018"],
			["normal", "10:2018"],
		]),
	],
	[
		"overlay",
		new Map([
			["auto", "0:"],
			["none", "0:"],
		]),
	],
	[
		"overscroll-behavior-block",
		new Map([
			["auto", "10:2022"],
			["contain", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"overscroll-behavior-inline",
		new Map([
			["auto", "10:2022"],
			["contain", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"overscroll-behavior-x",
		new Map([
			["auto", "10:2022"],
			["contain", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"overscroll-behavior-y",
		new Map([
			["auto", "10:2022"],
			["contain", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"overscroll-behavior",
		new Map([
			["auto", "10:2022"],
			["contain", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"page-break-after",
		new Map([
			["always", "0:"],
			["auto", "0:"],
			["avoid", "0:"],
			["left", "0:"],
			["right", "0:"],
		]),
	],
	[
		"page-break-before",
		new Map([
			["always", "0:"],
			["auto", "0:"],
			["avoid", "0:"],
			["left", "0:"],
			["right", "0:"],
		]),
	],
	[
		"page-break-inside",
		new Map([
			["auto", "0:"],
			["avoid", "0:"],
		]),
	],
	[
		"print-color-adjust",
		new Map([
			["economy", "5:2025"],
			["exact", "5:2025"],
		]),
	],
	[
		"quotes",
		new Map([
			["auto", "10:2021"],
			["none", "10:2015"],
		]),
	],
	[
		"reading-flow",
		new Map([
			["flex-flow", "0:"],
			["flex-visual", "0:"],
			["grid-columns", "0:"],
			["grid-order", "0:"],
			["grid-rows", "0:"],
			["normal", "0:"],
			["source-order", "0:"],
		]),
	],
	[
		"resize",
		new Map([
			["block", "0:"],
			["inline", "0:"],
		]),
	],
	[
		"ruby-align",
		new Map([
			["center", "5:2024"],
			["space-around", "5:2024"],
			["space-between", "5:2024"],
			["start", "5:2024"],
		]),
	],
	[
		"ruby-overhang",
		new Map([
			["auto", "0:"],
			["none", "0:"],
		]),
	],
	[
		"scroll-behavior",
		new Map([
			["auto", "10:2022"],
			["smooth", "10:2022"],
		]),
	],
	["animation-range-end", new Map([["normal", "0:"]])],
	["animation-range-start", new Map([["normal", "0:"]])],
	[
		"animation-timeline",
		new Map([
			["scroll", "0:"],
			["view", "0:"],
		]),
	],
	[
		"scroll-timeline-axis",
		new Map([
			["block", "0:"],
			["inline", "0:"],
			["x", "0:"],
			["y", "0:"],
		]),
	],
	[
		"timeline-scope",
		new Map([
			["all", "0:"],
			["none", "0:"],
		]),
	],
	[
		"view-timeline-axis",
		new Map([
			["block", "0:"],
			["inline", "0:"],
			["x", "0:"],
			["y", "0:"],
		]),
	],
	["view-timeline-inset", new Map([["auto", "0:"]])],
	[
		"scroll-initial-target",
		new Map([
			["nearest", "0:"],
			["none", "0:"],
		]),
	],
	[
		"scroll-marker-group",
		new Map([
			["after", "0:"],
			["before", "0:"],
			["none", "0:"],
		]),
	],
	["scroll-padding-block-end", new Map([["auto", "10:2021"]])],
	["scroll-padding-block-start", new Map([["auto", "10:2021"]])],
	["scroll-padding-block", new Map([["auto", "10:2021"]])],
	["scroll-padding-inline-end", new Map([["auto", "10:2021"]])],
	["scroll-padding-inline-start", new Map([["auto", "10:2021"]])],
	["scroll-padding-inline", new Map([["auto", "10:2021"]])],
	["scroll-padding", new Map([["auto", "10:2021"]])],
	[
		"scroll-snap-align",
		new Map([
			["center", "10:2020"],
			["end", "10:2020"],
			["none", "10:2020"],
			["start", "10:2020"],
		]),
	],
	[
		"scroll-snap-stop",
		new Map([
			["always", "10:2022"],
			["normal", "10:2022"],
		]),
	],
	[
		"scroll-snap-type",
		new Map([
			["block", "10:2022"],
			["both", "10:2022"],
			["inline", "10:2022"],
			["none", "10:2022"],
			["x", "10:2022"],
			["y", "10:2022"],
		]),
	],
	["scrollbar-color", new Map([["auto", "0:"]])],
	[
		"scrollbar-gutter",
		new Map([
			["auto", "5:2024"],
			["stable", "5:2024"],
		]),
	],
	[
		"scrollbar-width",
		new Map([
			["auto", "5:2024"],
			["none", "5:2024"],
			["thin", "5:2024"],
		]),
	],
	["shape-image-threshold", new Map([["percentages", "0:"]])],
	[
		"shape-outside",
		new Map([
			["circle", "10:2020"],
			["gradient", "10:2020"],
			["image", "10:2020"],
			["inset", "10:2020"],
			["none", "10:2020"],
			["path", "0:"],
			["polygon", "10:2020"],
		]),
	],
	[
		"speak-as",
		new Map([
			["digits", "0:"],
			["literal-punctuation", "0:"],
			["no-punctuation", "0:"],
			["normal", "0:"],
			["spell-out", "0:"],
		]),
	],
	[
		"clip-rule",
		new Map([
			["evenodd", "10:2020"],
			["nonzero", "10:2020"],
		]),
	],
	[
		"color-interpolation",
		new Map([
			["linearGradient", "0:"],
			["sRGB", "10:2020"],
		]),
	],
	[
		"fill-rule",
		new Map([
			["evenodd", "10:2017"],
			["nonzero", "10:2017"],
		]),
	],
	["stroke-dasharray", new Map([["none", "10:2017"]])],
	[
		"stroke-linecap",
		new Map([
			["butt", "10:2017"],
			["round", "10:2017"],
			["square", "10:2017"],
		]),
	],
	[
		"stroke-linejoin",
		new Map([
			["bevel", "10:2017"],
			["miter", "10:2017"],
			["round", "10:2017"],
		]),
	],
	[
		"text-rendering",
		new Map([
			["auto", "10:2020"],
			["geometricPrecision", "10:2020"],
		]),
	],
	[
		"color-interpolation-filters",
		new Map([
			["auto", "10:2020"],
			["linearRGB", "10:2020"],
			["sRGB", "10:2020"],
		]),
	],
	["tab-size", new Map([["length", "10:2021"]])],
	[
		"border-collapse",
		new Map([
			["collapse", "10:2020"],
			["separate", "10:2020"],
		]),
	],
	[
		"caption-side",
		new Map([
			["bottom", "10:2020"],
			["bottom-outside", "0:"],
			["top", "10:2020"],
			["top-outside", "0:"],
		]),
	],
	[
		"empty-cells",
		new Map([
			["hide", "10:2015"],
			["show", "10:2015"],
		]),
	],
	[
		"table-layout",
		new Map([
			["auto", "10:2015"],
			["fixed", "10:2015"],
		]),
	],
	[
		"text-align",
		new Map([
			["center", "10:2020"],
			["end", "10:2020"],
			["justify", "10:2015"],
			["left", "10:2020"],
			["match-parent", "0:"],
			["right", "10:2020"],
			["start", "10:2020"],
		]),
	],
	["text-align-last", new Map([["auto", "10:2022"]])],
	[
		"text-autospace",
		new Map([
			["auto", "0:"],
			["ideograph-alpha", "0:"],
			["ideograph-numeric", "0:"],
			["no-autospace", "0:"],
			["normal", "0:"],
		]),
	],
	["text-box-edge", new Map([["auto", "0:"]])],
	[
		"text-box-trim",
		new Map([
			["none", "0:"],
			["trim-both", "0:"],
			["trim-end", "0:"],
			["trim-start", "0:"],
		]),
	],
	["text-box", new Map([["normal", "0:"]])],
	[
		"text-combine-upright",
		new Map([
			["all", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"text-decoration-line",
		new Map([
			["grammar-error", "0:"],
			["line-through", "10:2020"],
			["none", "10:2020"],
			["overline", "10:2020"],
			["spelling-error", "0:"],
			["underline", "10:2020"],
			["blink", "0:"],
		]),
	],
	[
		"text-decoration-skip-ink",
		new Map([
			["all", "0:"],
			["auto", "10:2022"],
			["none", "10:2022"],
		]),
	],
	[
		"text-decoration-skip",
		new Map([
			["auto", "0:"],
			["none", "0:"],
		]),
	],
	["text-decoration-style", new Map([["wavy", "10:2020"]])],
	[
		"text-decoration-thickness",
		new Map([
			["auto", "10:2021"],
			["from-font", "10:2021"],
			["percentage", "5:2024"],
		]),
	],
	[
		"text-emphasis-position",
		new Map([
			["auto", "0:"],
			["left", "10:2022"],
			["over", "10:2022"],
			["right", "10:2022"],
			["under", "10:2022"],
		]),
	],
	[
		"text-emphasis-style",
		new Map([
			["circle", "10:2022"],
			["dot", "10:2022"],
			["double-circle", "10:2022"],
			["filled", "10:2022"],
			["none", "10:2022"],
			["sesame", "10:2022"],
			["triangle", "10:2022"],
		]),
	],
	[
		"text-indent",
		new Map([
			["each-line", "0:"],
			["hanging", "0:"],
		]),
	],
	[
		"text-justify",
		new Map([
			["auto", "0:"],
			["inter-character", "0:"],
			["inter-word", "0:"],
			["none", "0:"],
		]),
	],
	[
		"text-orientation",
		new Map([
			["mixed", "10:2020"],
			["sideways", "10:2020"],
			["upright", "10:2020"],
		]),
	],
	[
		"text-size-adjust",
		new Map([
			["auto", "0:"],
			["none", "0:"],
			["percentages", "0:"],
		]),
	],
	[
		"text-spacing-trim",
		new Map([
			["normal", "0:"],
			["space-all", "0:"],
			["space-first", "0:"],
			["trim-start", "0:"],
		]),
	],
	[
		"text-underline-offset",
		new Map([
			["auto", "10:2020"],
			["percentage", "5:2024"],
		]),
	],
	[
		"text-underline-position",
		new Map([
			["auto", "10:2020"],
			["from-font", "10:2020"],
			["left", "5:2024"],
			["right", "5:2024"],
			["under", "10:2020"],
		]),
	],
	[
		"text-wrap",
		new Map([
			["wrap", "5:2024"],
			["balance", "5:2024"],
			["nowrap", "5:2024"],
			["pretty", "0:"],
			["stable", "5:2024"],
		]),
	],
	[
		"text-wrap-mode",
		new Map([
			["nowrap", "5:2024"],
			["wrap", "5:2024"],
		]),
	],
	[
		"text-wrap-style",
		new Map([
			["auto", "5:2024"],
			["balance", "5:2024"],
			["pretty", "0:"],
			["stable", "5:2024"],
		]),
	],
	[
		"touch-action",
		new Map([
			["manipulation", "10:2019"],
			["none", "10:2019"],
			["pan-down", "0:"],
			["pan-left", "0:"],
			["pan-right", "0:"],
			["pan-up", "0:"],
			["pan-x", "10:2019"],
			["pan-y", "10:2019"],
			["pinch-zoom", "10:2021"],
		]),
	],
	[
		"transform-box",
		new Map([
			["border-box", "5:2023"],
			["content-box", "5:2024"],
			["fill-box", "10:2020"],
			["stroke-box", "5:2024"],
			["view-box", "10:2020"],
		]),
	],
	[
		"transform-origin",
		new Map([
			["bottom", "10:2015"],
			["center", "10:2015"],
			["left", "10:2015"],
			["right", "10:2015"],
			["top", "10:2015"],
		]),
	],
	[
		"perspective-origin",
		new Map([
			["bottom", "10:2015"],
			["center", "10:2015"],
			["left", "10:2015"],
			["right", "10:2015"],
			["top", "10:2015"],
		]),
	],
	["perspective", new Map([["none", "10:2015"]])],
	["transform", new Map([["3d", "10:2015"]])],
	["transition", new Map([["transition-behavior", "5:2024"]])],
	[
		"transition-property",
		new Map([
			["all", "10:2015"],
			["none", "10:2015"],
		]),
	],
	["transition-timing-function", new Map([["jump", "10:2020"]])],
	[
		"user-select",
		new Map([
			["all", "0:"],
			["auto", "0:"],
			["none", "0:"],
			["text", "0:"],
		]),
	],
	[
		"vertical-align",
		new Map([
			["baseline", "10:2015"],
			["bottom", "10:2015"],
			["middle", "10:2015"],
			["sub", "10:2015"],
			["super", "10:2015"],
			["text-bottom", "10:2015"],
			["text-top", "10:2015"],
			["top", "10:2015"],
		]),
	],
	["view-transition-class", new Map([["none", "0:"]])],
	[
		"view-transition-name",
		new Map([
			["match-element", "0:"],
			["none", "0:"],
		]),
	],
	[
		"visibility",
		new Map([
			["collapse", "10:2015"],
			["hidden", "10:2015"],
			["visible", "10:2015"],
		]),
	],
	[
		"white-space",
		new Map([
			["break-spaces", "10:2020"],
			["normal", "10:2015"],
			["nowrap", "10:2015"],
			["pre", "10:2015"],
			["pre-line", "10:2015"],
			["pre-wrap", "10:2015"],
		]),
	],
	[
		"white-space-collapse",
		new Map([
			["break-spaces", "5:2024"],
			["collapse", "5:2024"],
			["preserve", "5:2024"],
			["preserve-breaks", "5:2024"],
			["preserve-spaces", "0:"],
		]),
	],
	[
		"will-change",
		new Map([
			["auto", "10:2020"],
			["contents", "10:2020"],
			["scroll-position", "10:2020"],
		]),
	],
	[
		"word-break",
		new Map([
			["break-all", "10:2015"],
			["keep-all", "10:2015"],
			["normal", "10:2015"],
			["auto-phrase", "0:"],
			["break-word", "0:"],
		]),
	],
	["word-spacing", new Map([["normal", "10:2015"]])],
	[
		"writing-mode",
		new Map([
			["horizontal-tb", "10:2017"],
			["sideways-lr", "5:2025"],
			["sideways-rl", "5:2025"],
			["vertical-lr", "10:2017"],
			["vertical-rl", "10:2017"],
			["lr", "0:"],
			["lr-tb", "0:"],
			["rl", "0:"],
			["rl-tb", "0:"],
			["tb", "0:"],
			["tb-rl", "0:"],
		]),
	],
	["z-index", new Map([["auto", "10:2015"]])],
]);

/**
 * @fileoverview Color information for CSS.
 * @author Nicholas C. Zakas
 */

const namedColors = new Set([
	"aliceblue",
	"antiquewhite",
	"aqua",
	"aquamarine",
	"azure",
	"beige",
	"bisque",
	"black",
	"blanchedalmond",
	"blue",
	"blueviolet",
	"brown",
	"burlywood",
	"cadetblue",
	"chartreuse",
	"chocolate",
	"coral",
	"cornflowerblue",
	"cornsilk",
	"crimson",
	"cyan",
	"darkblue",
	"darkcyan",
	"darkgoldenrod",
	"darkgray",
	"darkgreen",
	"darkgrey",
	"darkkhaki",
	"darkmagenta",
	"darkolivegreen",
	"darkorange",
	"darkorchid",
	"darkred",
	"darksalmon",
	"darkseagreen",
	"darkslateblue",
	"darkslategray",
	"darkslategrey",
	"darkturquoise",
	"darkviolet",
	"deeppink",
	"deepskyblue",
	"dimgray",
	"dimgrey",
	"dodgerblue",
	"firebrick",
	"floralwhite",
	"forestgreen",
	"fuchsia",
	"gainsboro",
	"ghostwhite",
	"gold",
	"goldenrod",
	"gray",
	"green",
	"greenyellow",
	"grey",
	"honeydew",
	"hotpink",
	"indianred",
	"indigo",
	"ivory",
	"khaki",
	"lavender",
	"lavenderblush",
	"lawngreen",
	"lemonchiffon",
	"lightblue",
	"lightcoral",
	"lightcyan",
	"lightgoldenrodyellow",
	"lightgray",
	"lightgreen",
	"lightgrey",
	"lightpink",
	"lightsalmon",
	"lightseagreen",
	"lightskyblue",
	"lightslategray",
	"lightslategrey",
	"lightsteelblue",
	"lightyellow",
	"lime",
	"limegreen",
	"linen",
	"magenta",
	"maroon",
	"mediumaquamarine",
	"mediumblue",
	"mediumorchid",
	"mediumpurple",
	"mediumseagreen",
	"mediumslateblue",
	"mediumspringgreen",
	"mediumturquoise",
	"mediumvioletred",
	"midnightblue",
	"mintcream",
	"mistyrose",
	"moccasin",
	"navajowhite",
	"navy",
	"oldlace",
	"olive",
	"olivedrab",
	"orange",
	"orangered",
	"orchid",
	"palegoldenrod",
	"palegreen",
	"paleturquoise",
	"palevioletred",
	"papayawhip",
	"peachpuff",
	"peru",
	"pink",
	"plum",
	"powderblue",
	"purple",
	"rebeccapurple",
	"red",
	"rosybrown",
	"royalblue",
	"saddlebrown",
	"salmon",
	"sandybrown",
	"seagreen",
	"seashell",
	"sienna",
	"silver",
	"skyblue",
	"slateblue",
	"slategray",
	"slategrey",
	"snow",
	"springgreen",
	"steelblue",
	"tan",
	"teal",
	"thistle",
	"tomato",
	"turquoise",
	"violet",
	"wheat",
	"white",
	"whitesmoke",
	"yellow",
	"yellowgreen",
]);

/**
 * @fileoverview Rule to enforce the use of baseline features.
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"notBaselineProperty" | "notBaselinePropertyValue" | "notBaselineAtRule" | "notBaselineType" | "notBaselineMediaCondition" | "notBaselineSelector"} UseBaselineMessageIds
 * @typedef {[{
 *     available?: "widely" | "newly" | number
 * }]} UseBaselineOptions
 * @typedef {CSSRuleDefinition<{ RuleOptions: UseBaselineOptions, MessageIds: UseBaselineMessageIds }>} UseBaselineRuleDefinition
 */

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

/**
 * Represents a property that is supported via @supports.
 */
class SupportedProperty {
	/**
	 * The name of the property.
	 * @type {string}
	 */
	name;

	/**
	 * Supported identifier values.
	 * @type {Set<string>}
	 */
	#identifiers = new Set();

	/**
	 * Supported function types.
	 * @type {Set<string>}
	 */
	#functions = new Set();

	/**
	 * Creates a new instance.
	 * @param {string} name The name of the property.
	 */
	constructor(name) {
		this.name = name;
	}

	/**
	 * Adds an identifier to the list of supported identifiers.
	 * @param {string} identifier The identifier to add.
	 * @returns {void}
	 */
	addIdentifier(identifier) {
		this.#identifiers.add(identifier);
	}

	/**
	 * Determines if an identifier is supported.
	 * @param {string} identifier The identifier to check.
	 * @returns {boolean} `true` if the identifier is supported, `false` if not.
	 */
	hasIdentifier(identifier) {
		return this.#identifiers.has(identifier);
	}

	/**
	 * Determines if any identifiers are supported.
	 * @returns {boolean} `true` if any identifiers are supported, `false` if not.
	 */
	hasIdentifiers() {
		return this.#identifiers.size > 0;
	}

	/**
	 * Adds a function to the list of supported functions.
	 * @param {string} func The function to add.
	 * @returns {void}
	 */
	addFunction(func) {
		this.#functions.add(func);
	}

	/**
	 * Determines if a function is supported.
	 * @param {string} func The function to check.
	 * @returns {boolean} `true` if the function is supported, `false` if not.
	 */
	hasFunction(func) {
		return this.#functions.has(func);
	}

	/**
	 * Determines if any functions are supported.
	 * @returns {boolean} `true` if any functions are supported, `false` if not.
	 */
	hasFunctions() {
		return this.#functions.size > 0;
	}
}

/**
 * Represents an `@supports` rule and everything it enables.
 */
class SupportsRule {
	/**
	 * The properties supported by this rule.
	 * @type {Map<string, SupportedProperty>}
	 */
	#properties = new Map();

	/**
	 * The selectors supported by this rule.
	 * @type {Set<string>}
	 */
	#selectors = new Set();

	/**
	 * Adds a property to the rule.
	 * @param {string} property The name of the property.
	 * @returns {SupportedProperty} The supported property object.
	 */
	addProperty(property) {
		if (this.#properties.has(property)) {
			return this.#properties.get(property);
		}

		const supportedProperty = new SupportedProperty(property);
		this.#properties.set(property, supportedProperty);

		return supportedProperty;
	}

	/**
	 * Determines if the rule supports a property.
	 * @param {string} property The name of the property.
	 * @returns {boolean} `true` if the property is supported, `false` if not.
	 */
	hasProperty(property) {
		return this.#properties.has(property);
	}

	/**
	 * Gets the supported property.
	 * @param {string} property The name of the property.
	 * @returns {SupportedProperty} The supported property.
	 */
	getProperty(property) {
		return this.#properties.get(property);
	}

	/**
	 * Determines if the rule supports a property value.
	 * @param {string} property The name of the property.
	 * @param {string} identifier The identifier to check.
	 * @returns {boolean} `true` if the property value is supported, `false` if not.
	 */
	hasPropertyIdentifier(property, identifier) {
		const supportedProperty = this.#properties.get(property);

		if (!supportedProperty) {
			return false;
		}

		return supportedProperty.hasIdentifier(identifier);
	}

	/**
	 * Determines if the rule supports any property values.
	 * @param {string} property The name of the property.
	 * @returns {boolean} `true` if any property values are supported, `false` if not.
	 */
	hasPropertyIdentifiers(property) {
		const supportedProperty = this.#properties.get(property);

		if (!supportedProperty) {
			return false;
		}

		return supportedProperty.hasIdentifiers();
	}

	/**
	 * Determines if the rule supports a function.
	 * @param {string} property The name of the property.
	 * @param {string} func The function to check.
	 * @returns {boolean} `true` if the function is supported, `false` if not.
	 */
	hasFunction(property, func) {
		const supportedProperty = this.#properties.get(property);

		if (!supportedProperty) {
			return false;
		}

		return supportedProperty.hasFunction(func);
	}

	/**
	 * Determines if the rule supports any functions.
	 * @param {string} property The name of the property.
	 * @returns {boolean} `true` if any functions are supported, `false` if not.
	 */
	hasFunctions(property) {
		const supportedProperty = this.#properties.get(property);

		if (!supportedProperty) {
			return false;
		}

		return supportedProperty.hasFunctions();
	}

	/**
	 * Adds a selector to the rule.
	 * @param {string} selector The name of the selector.
	 * @returns {void}
	 */
	addSelector(selector) {
		this.#selectors.add(selector);
	}

	/**
	 * Determines if the rule supports a selector.
	 * @param {string} selector The name of the selector.
	 * @returns {boolean} `true` if the selector is supported, `false` if not.
	 */
	hasSelector(selector) {
		return this.#selectors.has(selector);
	}
}

/**
 * Represents a collection of supports rules.
 */
class SupportsRules {
	/**
	 * A collection of supports rules.
	 * @type {Array<SupportsRule>}
	 */
	#rules = [];

	/**
	 * Adds a rule to the collection.
	 * @param {SupportsRule} rule The rule to add.
	 * @returns {void}
	 */
	push(rule) {
		this.#rules.push(rule);
	}

	/**
	 * Removes the last rule from the collection.
	 * @returns {SupportsRule} The last rule in the collection.
	 */
	pop() {
		return this.#rules.pop();
	}

	/**
	 * Retrieves the last rule in the collection.
	 * @returns {SupportsRule} The last rule in the collection.
	 */
	last() {
		return this.#rules.at(-1);
	}

	/**
	 * Determines if any rule supports a property.
	 * @param {string} property The name of the property.
	 * @returns {boolean} `true` if any rule supports the property, `false` if not.
	 */
	hasProperty(property) {
		return this.#rules.some(rule => rule.hasProperty(property));
	}

	/**
	 * Determines if any rule supports a property identifier.
	 * @param {string} property The name of the property.
	 * @param {string} identifier The identifier to check.
	 * @returns {boolean} `true` if any rule supports the property value, `false` if not.
	 */
	hasPropertyIdentifier(property, identifier) {
		return this.#rules.some(rule =>
			rule.hasPropertyIdentifier(property, identifier),
		);
	}

	/**
	 * Determines if any rule supports any property identifiers.
	 * @param {string} property The name of the property.
	 * @returns {boolean} `true` if any rule supports the property values, `false` if not.
	 */
	hasPropertyIdentifiers(property) {
		return this.#rules.some(rule => rule.hasPropertyIdentifiers(property));
	}

	/**
	 * Determines if any rule supports a function.
	 * @param {string} property The name of the property.
	 * @param {string} func The function to check.
	 * @returns {boolean} `true` if any rule supports the function, `false` if not.
	 */
	hasPropertyFunction(property, func) {
		return this.#rules.some(rule => rule.hasFunction(property, func));
	}

	/**
	 * Determines if any rule supports any functions.
	 * @param {string} property The name of the property.
	 * @returns {boolean} `true` if any rule supports the functions, `false` if not.
	 */
	hasPropertyFunctions(property) {
		return this.#rules.some(rule => rule.hasFunctions(property));
	}

	/**
	 * Determines if any rule supports a selector.
	 * @param {string} selector The name of the selector.
	 * @returns {boolean} `true` if any rule supports the selector, `false` if not.
	 */
	hasSelector(selector) {
		return this.#rules.some(rule => rule.hasSelector(selector));
	}
}

/**
 * Represents the required availability of a feature.
 */
class BaselineAvailability {
	/**
	 * The preferred Baseline year.
	 * @type {number}
	 */
	#baselineYear = undefined;

	/**
	 * The preferred Baseline status.
	 * @type {number}
	 */
	#baselineStatus = undefined;

	/**
	 * @param {string | number} availability The required level of feature availability.
	 */
	constructor(availability) {
		this.availability = availability;

		if (typeof availability === "number") {
			this.#baselineYear = availability;
		} else {
			this.#baselineStatus =
				availability === "widely" ? BASELINE_HIGH : BASELINE_LOW;
		}
	}

	/**
	 * Determines whether a feature meets the required availability.
	 * @param {Object} encodedStatus A feature's encoded baseline status and year.
	 * @returns {boolean} `true` if the feature is supported, `false` if not.
	 */
	isSupported(encodedStatus) {
		if (!encodedStatus) {
			// if we don't know the status, assume it's supported
			return true;
		}

		const parts = encodedStatus.split(":");
		const status = Number(parts[0]);
		const year = Number(parts[1] || NaN);

		if (this.#baselineYear) {
			return year <= this.#baselineYear;
		}

		return status >= this.#baselineStatus;
	}
}

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {UseBaselineRuleDefinition} */
var rule9 = {
	meta: {
		type: "problem",

		docs: {
			description: "Enforce the use of baseline features",
			recommended: true,
			url: "https://github.com/eslint/css/blob/main/docs/rules/use-baseline.md",
		},

		schema: [
			{
				type: "object",
				properties: {
					available: {
						anyOf: [
							{
								enum: ["widely", "newly"],
							},
							{
								// baseline year
								type: "integer",
								minimum: 2000,
								maximum: new Date().getFullYear(),
							},
						],
					},
				},
				additionalProperties: false,
			},
		],

		defaultOptions: [
			{
				available: "widely",
			},
		],

		messages: {
			notBaselineProperty:
				"Property '{{property}}' is not a {{availability}} available baseline feature.",
			notBaselinePropertyValue:
				"Value '{{value}}' of property '{{property}}' is not a {{availability}} available baseline feature.",
			notBaselineAtRule:
				"At-rule '@{{atRule}}' is not a {{availability}} available baseline feature.",
			notBaselineType:
				"Type '{{type}}' is not a {{availability}} available baseline feature.",
			notBaselineMediaCondition:
				"Media condition '{{condition}}' is not a {{availability}} available baseline feature.",
			notBaselineSelector:
				"Selector '{{selector}}' is not a {{availability}} available baseline feature.",
		},
	},

	create(context) {
		const baselineAvailability = new BaselineAvailability(
			context.options[0].available,
		);
		const supportsRules = new SupportsRules();

		/**
		 * Checks a property value identifier to see if it's a baseline feature.
		 * @param {string} property The name of the property.
		 * @param {Identifier} child The node to check.
		 * @returns {void}
		 */
		function checkPropertyValueIdentifier(property, child) {
			// named colors are always valid
			if (namedColors.has(child.name)) {
				return;
			}
			const possiblePropertyValues = propertyValues.get(property);

			// if we don't know of any possible property values, just skip it
			if (!possiblePropertyValues) {
				return;
			}

			const featureStatus = possiblePropertyValues.get(child.name);

			// if we don't know of any possible property values, just skip it
			if (featureStatus === undefined) {
				return;
			}

			if (!baselineAvailability.isSupported(featureStatus)) {
				context.report({
					loc: child.loc,
					messageId: "notBaselinePropertyValue",
					data: {
						property,
						value: child.name,
						availability: String(baselineAvailability.availability),
					},
				});
			}
		}

		/**
		 * Checks a property value function to see if it's a baseline feature.
		 * @param {FunctionNodePlain} child The node to check.
		 * @returns {void}
		 **/
		function checkPropertyValueFunction(child) {
			const featureStatus = types.get(child.name);

			// if we don't know of any possible property values, just skip it
			if (featureStatus === undefined) {
				return;
			}

			if (!baselineAvailability.isSupported(featureStatus)) {
				context.report({
					loc: child.loc,
					messageId: "notBaselineType",
					data: {
						type: child.name,
						availability: String(baselineAvailability.availability),
					},
				});
			}
		}

		return {
			"Atrule[name=supports]"() {
				supportsRules.push(new SupportsRule());
			},

			"Atrule[name=supports] > AtrulePrelude > Condition"(node) {
				const supportsRule = supportsRules.last();

				for (let i = 0; i < node.children.length; i++) {
					const conditionChild = node.children[i];

					// if a SupportsDeclaration is preceded by "not" then we don't consider it
					if (
						conditionChild.type === "Identifier" &&
						conditionChild.name === "not"
					) {
						i++;
						continue;
					}

					// save the supported properties and values for this at-rule
					if (conditionChild.type === "SupportsDeclaration") {
						const { declaration } = conditionChild;
						const property = declaration.property;
						const supportedProperty =
							supportsRule.addProperty(property);

						declaration.value.children.forEach(child => {
							if (child.type === "Identifier") {
								supportedProperty.addIdentifier(child.name);
								return;
							}

							if (child.type === "Function") {
								supportedProperty.addFunction(child.name);
							}
						});

						continue;
					}

					if (
						conditionChild.type === "FeatureFunction" &&
						conditionChild.feature === "selector"
					) {
						for (const selectorChild of conditionChild.value
							.children) {
							supportsRule.addSelector(selectorChild.name);
						}
					}
				}
			},

			"Rule > Block > Declaration"(node) {
				const property = node.property;

				// ignore unknown properties - no-invalid-properties already catches this
				if (!properties.has(property)) {
					return;
				}

				/*
				 * Step 1: Check that the property is in the baseline.
				 *
				 * If the property has been tested in a @supports rule, we don't need to
				 * check it because it won't be applied if the browser doesn't support it.
				 */
				if (!supportsRules.hasProperty(property)) {
					const featureStatus = properties.get(property);

					if (!baselineAvailability.isSupported(featureStatus)) {
						context.report({
							loc: {
								start: node.loc.start,
								end: {
									line: node.loc.start.line,
									column:
										node.loc.start.column +
										node.property.length,
								},
							},
							messageId: "notBaselineProperty",
							data: {
								property,
								availability: String(
									baselineAvailability.availability,
								),
							},
						});

						/*
						 * If the property isn't in baseline, then we don't go
						 * on to check the values. If the property itself isn't
						 * in baseline then chances are the values aren't too,
						 * and there's no need to report multiple errors for the
						 * same property.
						 */
						return;
					}
				}

				/*
				 * With tolerant parsing, it's possible that the value is `Raw`
				 * and therefore doesn't have children. If that's the case then
				 * we just exit.
				 */
				if (!node.value?.children) {
					return;
				}

				/*
				 * Step 2: Check that the property values are in the baseline.
				 */
				for (const child of node.value.children) {
					if (child.type === "Identifier") {
						// if the property value has been tested in a @supports rule, don't check it
						if (
							!supportsRules.hasPropertyIdentifier(
								property,
								child.name,
							)
						) {
							checkPropertyValueIdentifier(property, child);
						}

						continue;
					}

					if (child.type === "Function") {
						if (
							!supportsRules.hasPropertyFunction(
								property,
								child.name,
							)
						) {
							checkPropertyValueFunction(child);
						}
					}
				}
			},

			"Atrule[name=supports]:exit"() {
				supportsRules.pop();
			},

			"Atrule[name=media] > AtrulePrelude > MediaQueryList > MediaQuery > Condition"(
				node,
			) {
				for (const child of node.children) {
					// ignore unknown media conditions - no-invalid-at-rules already catches this
					if (!mediaConditions.has(child.name)) {
						continue;
					}

					if (child.type !== "Feature") {
						continue;
					}

					const featureStatus = mediaConditions.get(child.name);

					if (!baselineAvailability.isSupported(featureStatus)) {
						const loc = child.loc;

						context.report({
							loc: {
								start: {
									line: loc.start.line,
									// add 1 to account for the @ symbol
									column: loc.start.column + 1,
								},
								end: {
									line: loc.start.line,
									column:
										// add 1 to account for the @ symbol
										loc.start.column +
										child.name.length +
										1,
								},
							},
							messageId: "notBaselineMediaCondition",
							data: {
								condition: child.name,
								availability: String(
									baselineAvailability.availability,
								),
							},
						});
					}
				}
			},

			Atrule(node) {
				// ignore unknown at-rules - no-invalid-at-rules already catches this
				if (!atRules.has(node.name)) {
					return;
				}

				const featureStatus = atRules.get(node.name);

				if (!baselineAvailability.isSupported(featureStatus)) {
					const loc = node.loc;

					context.report({
						loc: {
							start: loc.start,
							end: {
								line: loc.start.line,

								// add 1 to account for the @ symbol
								column: loc.start.column + node.name.length + 1,
							},
						},
						messageId: "notBaselineAtRule",
						data: {
							atRule: node.name,
							availability: String(
								baselineAvailability.availability,
							),
						},
					});
				}
			},

			"PseudoClassSelector,PseudoElementSelector"(node) {
				const selector = node.name;

				if (!selectors.has(selector)) {
					return;
				}

				// if the selector has been tested in a @supports rule, don't check it
				if (supportsRules.hasSelector(selector)) {
					return;
				}

				const featureStatus = selectors.get(selector);

				if (!baselineAvailability.isSupported(featureStatus)) {
					const loc = node.loc;

					// some selectors are prefixed with the : or :: symbols
					let prefixSymbolLength = 0;
					if (node.type.startsWith("PseudoClass")) {
						prefixSymbolLength = 1;
					} else if (node.type.startsWith("PseudoElement")) {
						prefixSymbolLength = 2;
					}

					context.report({
						loc: {
							start: loc.start,
							end: {
								line: loc.start.line,
								column:
									loc.start.column +
									selector.length +
									prefixSymbolLength,
							},
						},
						messageId: "notBaselineSelector",
						data: {
							selector,
							availability: String(
								baselineAvailability.availability,
							),
						},
					});
				}
			},

			NestingSelector(node) {
				// NestingSelector implies CSS nesting
				const selector = "nesting";
				const featureStatus = selectors.get(selector);
				if (baselineAvailability.isSupported(featureStatus)) {
					return;
				}

				context.report({
					loc: node.loc,
					messageId: "notBaselineSelector",
					data: {
						selector,
						availability: String(baselineAvailability.availability),
					},
				});
			},
		};
	},
};

/**
 * @fileoverview Rule to require layers in CSS.
 * @author Nicholas C. Zakas
 */

//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------

/**
 * @typedef {"missingLayer" | "missingLayerName" | "missingImportLayer" | "layerNameMismatch"} UseLayersMessageIds
 * @typedef {[{
 *     allowUnnamedLayers?: boolean,
 *     requireImportLayers?: boolean,
 *     layerNamePattern?: string
 * }]} UseLayersOptions
 * @typedef {CSSRuleDefinition<{ RuleOptions: UseLayersOptions, MessageIds: UseLayersMessageIds }>} UseLayersRuleDefinition
 */

//-----------------------------------------------------------------------------
// Rule Definition
//-----------------------------------------------------------------------------

/** @type {UseLayersRuleDefinition} */
var rule10 = {
	meta: {
		type: "problem",

		docs: {
			description: "Require use of layers",
			url: "https://github.com/eslint/css/blob/main/docs/rules/use-layers.md",
		},

		schema: [
			{
				type: "object",
				properties: {
					allowUnnamedLayers: {
						type: "boolean",
					},
					requireImportLayers: {
						type: "boolean",
					},
					layerNamePattern: {
						type: "string",
					},
				},
				additionalProperties: false,
			},
		],

		defaultOptions: [
			{
				allowUnnamedLayers: false,
				requireImportLayers: true,
				layerNamePattern: "",
			},
		],

		messages: {
			missingLayer: "Expected rule to be within a layer.",
			missingLayerName: "Expected layer to have a name.",
			missingImportLayer: "Expected import to be within a layer.",
			layerNameMismatch:
				"Expected layer name '{{ name }}' to match pattern '{{pattern}}'.",
		},
	},

	create(context) {
		let layerDepth = 0;
		const options = context.options[0];
		const layerNameRegex = options.layerNamePattern
			? new RegExp(options.layerNamePattern, "u")
			: null;

		return {
			"Atrule[name=import]"(node) {
				// layer, if present, must always be the second child of the prelude
				const secondChild = node.prelude.children[1];
				const layerNode =
					secondChild?.name === "layer" ? secondChild : null;

				if (options.requireImportLayers && !layerNode) {
					context.report({
						loc: node.loc,
						messageId: "missingImportLayer",
					});
				}

				if (layerNode) {
					const isLayerFunction = layerNode.type === "Function";

					if (!options.allowUnnamedLayers && !isLayerFunction) {
						context.report({
							loc: layerNode.loc,
							messageId: "missingLayerName",
						});
					}
				}
			},

			Layer(node) {
				if (!layerNameRegex) {
					return;
				}

				const parts = node.name.split(".");
				let currentPos = 0;

				parts.forEach((part, index) => {
					if (!layerNameRegex.test(part)) {
						const startColumn = node.loc.start.column + currentPos;
						const endColumn = startColumn + part.length;

						context.report({
							loc: {
								start: {
									line: node.loc.start.line,
									column: startColumn,
								},
								end: {
									line: node.loc.start.line,
									column: endColumn,
								},
							},
							messageId: "layerNameMismatch",
							data: {
								name: part,
								pattern: options.layerNamePattern,
							},
						});
					}

					currentPos += part.length;
					// add 1 to account for the . symbol
					if (index < parts.length - 1) {
						currentPos += 1;
					}
				});
			},

			"Atrule[name=layer]"(node) {
				layerDepth++;

				if (!options.allowUnnamedLayers && !node.prelude) {
					context.report({
						loc: node.loc,
						messageId: "missingLayerName",
					});
				}
			},

			"Atrule[name=layer]:exit"() {
				layerDepth--;
			},

			Rule(node) {
				if (layerDepth > 0) {
					return;
				}

				context.report({
					loc: node.loc,
					messageId: "missingLayer",
				});
			},
		};
	},
};

var rules = {
    "no-duplicate-imports": rule0,
    "no-empty-blocks": rule1,
    "no-important": rule2,
    "no-invalid-at-rule-placement": rule3,
    "no-invalid-at-rules": rule4,
    "no-invalid-named-grid-areas": rule5,
    "no-invalid-properties": rule6,
    "prefer-logical-properties": rule7,
    "relative-font-units": rule8,
    "use-baseline": rule9,
    "use-layers": rule10,
};

/**
 * @fileoverview CSS plugin.
 * @author Nicholas C. Zakas
 */


//-----------------------------------------------------------------------------
// Plugin
//-----------------------------------------------------------------------------

const plugin = {
	meta: {
		name: "@eslint/css",
		version: "0.10.0", // x-release-please-version
	},
	languages: {
		css: new CSSLanguage(),
	},
	rules,
	configs: {
		recommended: {
			plugins: {},
			rules: rules$1,
		},
	},
};

// eslint-disable-next-line no-lone-blocks -- The block syntax { ... } ensures that TypeScript does not get confused about the type of `plugin`.
{
	plugin.configs.recommended.plugins.css = plugin;
}

export { CSSLanguage, CSSSourceCode, plugin as default };
