diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-13 21:34:48 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-13 21:34:48 -0800 |
| commit | 76cb9c2a39d477a64824a985ade40507e3bbade1 (patch) | |
| tree | 41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/css-tree | |
| parent | 819a39a21ac992b1393244a4c283bbb125208c69 (diff) | |
| download | neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2 neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip | |
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
Diffstat (limited to 'vanilla/node_modules/css-tree')
287 files changed, 28653 insertions, 0 deletions
diff --git a/vanilla/node_modules/css-tree/LICENSE b/vanilla/node_modules/css-tree/LICENSE new file mode 100644 index 0000000..c627ec0 --- /dev/null +++ b/vanilla/node_modules/css-tree/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2016-2024 by Roman Dvornov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vanilla/node_modules/css-tree/README.md b/vanilla/node_modules/css-tree/README.md new file mode 100644 index 0000000..92e6f15 --- /dev/null +++ b/vanilla/node_modules/css-tree/README.md @@ -0,0 +1,192 @@ +<img align="right" width="111" height="111" alt="CSSTree logo" src="assets/csstree-logo-rounded.svg" /> + +# CSSTree + +[](https://www.npmjs.com/package/css-tree) +[](https://github.com/csstree/csstree/actions/workflows/build.yml) +[](https://coveralls.io/github/csstree/csstree?branch=master) +[](https://www.npmjs.com/package/css-tree) +[](https://twitter.com/csstree) + +CSSTree is a tool set for CSS: [fast](https://github.com/postcss/benchmark) detailed parser (CSS → AST), walker (AST traversal), generator (AST → CSS) and lexer (validation and matching) based on specs and browser implementations. The main goal is to be efficient and W3C spec compliant, with focus on CSS analyzing and source-to-source transforming tasks. + +## Features + +- **Detailed parsing with an adjustable level of detail** + + By default CSSTree parses CSS as detailed as possible, i.e. each single logical part is representing with its own AST node (see [AST format](docs/ast.md) for all possible node types). The parsing detail level can be changed through [parser options](docs/parsing.md#parsesource-options), for example, you can disable parsing of selectors or declaration values for component parts. + +- **Tolerant to errors by design** + + Parser behaves as [spec says](https://www.w3.org/TR/css-syntax-3/#error-handling): "When errors occur in CSS, the parser attempts to recover gracefully, throwing away only the minimum amount of content before returning to parsing as normal". The only thing the parser departs from the specification is that it doesn't throw away bad content, but wraps it in a special node type (`Raw`) that allows processing it later. + +- **Fast and efficient** + + CSSTree is created with focus on performance and effective memory consumption. Therefore it's [one of the fastest CSS parsers](https://github.com/postcss/benchmark) at the moment. + +- **Syntax validation** + + The built-in lexer can test CSS against syntaxes defined by W3C. CSSTree uses [mdn/data](https://github.com/mdn/data/) as a basis for lexer's dictionaries and extends it with vendor specific and legacy syntaxes. Lexer can only check the declaration values and at-rules currently, but this feature will be extended to other parts of the CSS in the future. + +## Projects using CSSTree + +- [Svelte](https://github.com/sveltejs/svelte) – Cybernetically enhanced web apps +- [SVGO](https://github.com/svg/svgo) – Node.js tool for optimizing SVG files +- [CSSO](https://github.com/css/csso) – CSS minifier with structural optimizations +- [NativeScript](https://github.com/NativeScript/NativeScript) – NativeScript empowers you to access native APIs from JavaScript directly +- [react-native-svg](https://github.com/react-native-svg/react-native-svg) – SVG library for React Native, React Native Web, and plain React web projects +- [penthouse](https://github.com/pocketjoso/penthouse) – Critical Path CSS Generator +- [Bit](https://github.com/teambit/bit) – Bit is the platform for collaborating on components +- and more... + +## Documentation + +- [AST format](docs/ast.md) +- [Parsing CSS → AST](docs/parsing.md) + - [parse(source[, options])](docs/parsing.md#parsesource-options) +- [Serialization AST → CSS](docs/generate.md) + - [generate(ast[, options])](docs/generate.md#generateast-options) +- [AST traversal](docs/traversal.md) + - [walk(ast, options)](docs/traversal.md#walkast-options) + - [find(ast, fn)](docs/traversal.md#findast-fn) + - [findLast(ast, fn)](docs/traversal.md#findlastast-fn) + - [findAll(ast, fn)](docs/traversal.md#findallast-fn) +- [Util functions](docs/utils.md) + - Value encoding & decoding + - [property(name)](docs/utils.md#propertyname) + - [keyword(name)](docs/utils.md#keywordname) + - [ident](docs/utils.md#ident) + - [string](docs/utils.md#string) + - [url](docs/utils.md#url) + - [List class](docs/list.md) + - AST transforming + - [clone(ast)](docs/utils.md#cloneast) + - [fromPlainObject(object)](docs/utils.md#fromplainobjectobject) + - [toPlainObject(ast)](docs/utils.md#toplainobjectast) +- [Value Definition Syntax](docs/definition-syntax.md) + - [parse(source)](docs/definition-syntax.md#parsesource) + - [walk(node, options, context)](docs/definition-syntax.md#walknode-options-context) + - [generate(node, options)](docs/definition-syntax.md#generatenode-options) + - [AST format](docs/definition-syntax.md#ast-format) + +## Tools + +* [AST Explorer](https://astexplorer.net/#/gist/244e2fb4da940df52bf0f4b94277db44/e79aff44611020b22cfd9708f3a99ce09b7d67a8) – explore CSSTree AST format with zero setup +* [CSS syntax reference](https://csstree.github.io/docs/syntax.html) +* [CSS syntax validator](https://csstree.github.io/docs/validator.html) + +## Related projects + +* [csstree-validator](https://github.com/csstree/validator) – NPM package to validate CSS +* [stylelint-csstree-validator](https://github.com/csstree/stylelint-validator) – plugin for stylelint to validate CSS +* [Grunt plugin](https://github.com/sergejmueller/grunt-csstree-validator) +* [Gulp plugin](https://github.com/csstree/gulp-csstree) +* [Sublime plugin](https://github.com/csstree/SublimeLinter-contrib-csstree) +* [VS Code plugin](https://github.com/csstree/vscode-plugin) +* [Atom plugin](https://github.com/csstree/atom-plugin) + +## Usage + +Install with npm: + +``` +npm install css-tree +``` + +Basic usage: + +```js +import * as csstree from 'css-tree'; + +// parse CSS to AST +const ast = csstree.parse('.example { world: "!" }'); + +// traverse AST and modify it +csstree.walk(ast, (node) => { + if (node.type === 'ClassSelector' && node.name === 'example') { + node.name = 'hello'; + } +}); + +// generate CSS from AST +console.log(csstree.generate(ast)); +// .hello{world:"!"} +``` + +Syntax matching: + +```js +// parse CSS to AST as a declaration value +const ast = csstree.parse('red 1px solid', { context: 'value' }); + +// match to syntax of `border` property +const matchResult = csstree.lexer.matchProperty('border', ast); + +// check first value node is a <color> +console.log(matchResult.isType(ast.children.first, 'color')); +// true + +// get a type list matched to a node +console.log(matchResult.getTrace(ast.children.first)); +// [ { type: 'Property', name: 'border' }, +// { type: 'Type', name: 'color' }, +// { type: 'Type', name: 'named-color' }, +// { type: 'Keyword', name: 'red' } ] +``` + +### Exports + +Is it possible to import just a needed part of library like a parser or a walker. That's might useful for loading time or bundle size optimisations. + +```js +import * as tokenizer from 'css-tree/tokenizer'; +import * as parser from 'css-tree/parser'; +import * as walker from 'css-tree/walker'; +import * as lexer from 'css-tree/lexer'; +import * as definitionSyntax from 'css-tree/definition-syntax'; +import * as data from 'css-tree/definition-syntax-data'; +import * as dataPatch from 'css-tree/definition-syntax-data-patch'; +import * as utils from 'css-tree/utils'; +``` + +### Using in a browser + +Bundles are available for use in a browser: + +- `dist/csstree.js` – minified IIFE with `csstree` as global +```html +<script src="node_modules/css-tree/dist/csstree.js"></script> +<script> + csstree.parse('.example { color: green }'); +</script> +``` + +- `dist/csstree.esm.js` – minified ES module +```html +<script type="module"> + import { parse } from 'node_modules/css-tree/dist/csstree.esm.js' + parse('.example { color: green }'); +</script> +``` + +One of CDN services like `unpkg` or `jsDelivr` can be used. By default (for short path) a ESM version is exposing. For IIFE version a full path to a bundle should be specified: + +```html +<!-- ESM --> +<script type="module"> + import * as csstree from 'https://cdn.jsdelivr.net/npm/css-tree'; + import * as csstree from 'https://unpkg.com/css-tree'; +</script> + +<!-- IIFE with an export to global --> +<script src="https://cdn.jsdelivr.net/npm/css-tree/dist/csstree.js"></script> +<script src="https://unpkg.com/css-tree/dist/csstree.js"></script> +``` + +## Top level API + + + +## License + +MIT diff --git a/vanilla/node_modules/css-tree/cjs/convertor/create.cjs b/vanilla/node_modules/css-tree/cjs/convertor/create.cjs new file mode 100644 index 0000000..55c655b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/convertor/create.cjs @@ -0,0 +1,32 @@ +'use strict'; + +const List = require('../utils/List.cjs'); + +function createConvertor(walk) { + return { + fromPlainObject(ast) { + walk(ast, { + enter(node) { + if (node.children && node.children instanceof List.List === false) { + node.children = new List.List().fromArray(node.children); + } + } + }); + + return ast; + }, + toPlainObject(ast) { + walk(ast, { + leave(node) { + if (node.children && node.children instanceof List.List) { + node.children = node.children.toArray(); + } + } + }); + + return ast; + } + }; +} + +exports.createConvertor = createConvertor; diff --git a/vanilla/node_modules/css-tree/cjs/convertor/index.cjs b/vanilla/node_modules/css-tree/cjs/convertor/index.cjs new file mode 100644 index 0000000..6654278 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/convertor/index.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const index$1 = require('../walker/index.cjs'); + +const index = create.createConvertor(index$1); + +module.exports = index; diff --git a/vanilla/node_modules/css-tree/cjs/data-patch.cjs b/vanilla/node_modules/css-tree/cjs/data-patch.cjs new file mode 100644 index 0000000..9103ea4 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/data-patch.cjs @@ -0,0 +1,7 @@ +'use strict'; + +const patch = require('../data/patch.json'); + +const patch$1 = patch; + +module.exports = patch$1; diff --git a/vanilla/node_modules/css-tree/cjs/data.cjs b/vanilla/node_modules/css-tree/cjs/data.cjs new file mode 100644 index 0000000..258ac6a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/data.cjs @@ -0,0 +1,120 @@ +'use strict'; + +const dataPatch = require('./data-patch.cjs'); + +const mdnAtrules = require('mdn-data/css/at-rules.json'); +const mdnProperties = require('mdn-data/css/properties.json'); +const mdnSyntaxes = require('mdn-data/css/syntaxes.json'); + +const hasOwn = Object.hasOwn || ((object, property) => Object.prototype.hasOwnProperty.call(object, property)); +const extendSyntax = /^\s*\|\s*/; + +function preprocessAtrules(dict) { + const result = Object.create(null); + + for (const [atruleName, atrule] of Object.entries(dict)) { + let descriptors = null; + + if (atrule.descriptors) { + descriptors = Object.create(null); + + for (const [name, descriptor] of Object.entries(atrule.descriptors)) { + descriptors[name] = descriptor.syntax; + } + } + + result[atruleName.substr(1)] = { + prelude: atrule.syntax.trim().replace(/\{(.|\s)+\}/, '').match(/^@\S+\s+([^;\{]*)/)[1].trim() || null, + descriptors + }; + } + + return result; +} + +function patchDictionary(dict, patchDict) { + const result = Object.create(null); + + // copy all syntaxes for an original dict + for (const [key, value] of Object.entries(dict)) { + if (value) { + result[key] = value.syntax || value; + } + } + + // apply a patch + for (const key of Object.keys(patchDict)) { + if (hasOwn(dict, key)) { + if (patchDict[key].syntax) { + result[key] = extendSyntax.test(patchDict[key].syntax) + ? result[key] + ' ' + patchDict[key].syntax.trim() + : patchDict[key].syntax; + } else { + delete result[key]; + } + } else { + if (patchDict[key].syntax) { + result[key] = patchDict[key].syntax.replace(extendSyntax, ''); + } + } + } + + return result; +} + +function preprocessPatchAtrulesDescritors(declarations) { + const result = {}; + + for (const [key, value] of Object.entries(declarations || {})) { + result[key] = typeof value === 'string' + ? { syntax: value } + : value; + } + + return result; +} + +function patchAtrules(dict, patchDict) { + const result = {}; + + // copy all syntaxes for an original dict + for (const key in dict) { + if (patchDict[key] === null) { + continue; + } + + const atrulePatch = patchDict[key] || {}; + + result[key] = { + prelude: key in patchDict && 'prelude' in atrulePatch + ? atrulePatch.prelude + : dict[key].prelude || null, + descriptors: patchDictionary( + dict[key].descriptors || {}, + preprocessPatchAtrulesDescritors(atrulePatch.descriptors) + ) + }; + } + + // apply a patch + for (const [key, atrulePatch] of Object.entries(patchDict)) { + if (atrulePatch && !hasOwn(dict, key)) { + result[key] = { + prelude: atrulePatch.prelude || null, + descriptors: atrulePatch.descriptors + ? patchDictionary({}, preprocessPatchAtrulesDescritors(atrulePatch.descriptors)) + : null + }; + } + } + + return result; +} + +const definitions = { + types: patchDictionary(mdnSyntaxes, dataPatch.types), + atrules: patchAtrules(preprocessAtrules(mdnAtrules), dataPatch.atrules), + properties: patchDictionary(mdnProperties, dataPatch.properties) +}; + +module.exports = definitions; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs new file mode 100644 index 0000000..d24e7ce --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const createCustomError = require('../utils/create-custom-error.cjs'); + +function SyntaxError(message, input, offset) { + return Object.assign(createCustomError.createCustomError('SyntaxError', message), { + input, + offset, + rawMessage: message, + message: message + '\n' + + ' ' + input + '\n' + + '--' + new Array((offset || input.length) + 1).join('-') + '^' + }); +} + +exports.SyntaxError = SyntaxError; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs new file mode 100644 index 0000000..ff9f0ad --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs @@ -0,0 +1,139 @@ +'use strict'; + +function noop(value) { + return value; +} + +function generateMultiplier(multiplier) { + const { min, max, comma } = multiplier; + + if (min === 0 && max === 0) { + return comma ? '#?' : '*'; + } + + if (min === 0 && max === 1) { + return '?'; + } + + if (min === 1 && max === 0) { + return comma ? '#' : '+'; + } + + if (min === 1 && max === 1) { + return ''; + } + + return ( + (comma ? '#' : '') + + (min === max + ? '{' + min + '}' + : '{' + min + ',' + (max !== 0 ? max : '') + '}' + ) + ); +} + +function generateTypeOpts(node) { + switch (node.type) { + case 'Range': + return ( + ' [' + + (node.min === null ? '-∞' : node.min) + + ',' + + (node.max === null ? '∞' : node.max) + + ']' + ); + + default: + throw new Error('Unknown node type `' + node.type + '`'); + } +} + +function generateSequence(node, decorate, forceBraces, compact) { + const combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' '; + const result = node.terms + .map(term => internalGenerate(term, decorate, forceBraces, compact)) + .join(combinator); + + if (node.explicit || forceBraces) { + return (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]'); + } + + return result; +} + +function internalGenerate(node, decorate, forceBraces, compact) { + let result; + + switch (node.type) { + case 'Group': + result = + generateSequence(node, decorate, forceBraces, compact) + + (node.disallowEmpty ? '!' : ''); + break; + + case 'Multiplier': + // return since node is a composition + return ( + internalGenerate(node.term, decorate, forceBraces, compact) + + decorate(generateMultiplier(node), node) + ); + + case 'Boolean': + result = '<boolean-expr[' + internalGenerate(node.term, decorate, forceBraces, compact) + ']>'; + break; + + case 'Type': + result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>'; + break; + + case 'Property': + result = '<\'' + node.name + '\'>'; + break; + + case 'Keyword': + result = node.name; + break; + + case 'AtKeyword': + result = '@' + node.name; + break; + + case 'Function': + result = node.name + '('; + break; + + case 'String': + case 'Token': + result = node.value; + break; + + case 'Comma': + result = ','; + break; + + default: + throw new Error('Unknown node type `' + node.type + '`'); + } + + return decorate(result, node); +} + +function generate(node, options) { + let decorate = noop; + let forceBraces = false; + let compact = false; + + if (typeof options === 'function') { + decorate = options; + } else if (options) { + forceBraces = Boolean(options.forceBraces); + compact = Boolean(options.compact); + if (typeof options.decorate === 'function') { + decorate = options.decorate; + } + } + + return internalGenerate(node, decorate, forceBraces, compact); +} + +exports.generate = generate; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs new file mode 100644 index 0000000..0afb505 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs @@ -0,0 +1,13 @@ +'use strict'; + +const SyntaxError = require('./SyntaxError.cjs'); +const generate = require('./generate.cjs'); +const parse = require('./parse.cjs'); +const walk = require('./walk.cjs'); + + + +exports.SyntaxError = SyntaxError.SyntaxError; +exports.generate = generate.generate; +exports.parse = parse.parse; +exports.walk = walk.walk; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs new file mode 100644 index 0000000..b17b267 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs @@ -0,0 +1,556 @@ +'use strict'; + +const scanner = require('./scanner.cjs'); + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; +const EXCLAMATIONMARK = 33; // ! +const NUMBERSIGN = 35; // # +const AMPERSAND = 38; // & +const APOSTROPHE = 39; // ' +const LEFTPARENTHESIS = 40; // ( +const RIGHTPARENTHESIS = 41; // ) +const ASTERISK = 42; // * +const PLUSSIGN = 43; // + +const COMMA = 44; // , +const HYPERMINUS = 45; // - +const LESSTHANSIGN = 60; // < +const GREATERTHANSIGN = 62; // > +const QUESTIONMARK = 63; // ? +const COMMERCIALAT = 64; // @ +const LEFTSQUAREBRACKET = 91; // [ +const RIGHTSQUAREBRACKET = 93; // ] +const LEFTCURLYBRACKET = 123; // { +const VERTICALLINE = 124; // | +const RIGHTCURLYBRACKET = 125; // } +const INFINITY = 8734; // ∞ +const COMBINATOR_PRECEDENCE = { + ' ': 1, + '&&': 2, + '||': 3, + '|': 4 +}; + +function readMultiplierRange(scanner) { + let min = null; + let max = null; + + scanner.eat(LEFTCURLYBRACKET); + scanner.skipWs(); + + min = scanner.scanNumber(scanner); + scanner.skipWs(); + + if (scanner.charCode() === COMMA) { + scanner.pos++; + scanner.skipWs(); + + if (scanner.charCode() !== RIGHTCURLYBRACKET) { + max = scanner.scanNumber(scanner); + scanner.skipWs(); + } + } else { + max = min; + } + + scanner.eat(RIGHTCURLYBRACKET); + + return { + min: Number(min), + max: max ? Number(max) : 0 + }; +} + +function readMultiplier(scanner) { + let range = null; + let comma = false; + + switch (scanner.charCode()) { + case ASTERISK: + scanner.pos++; + + range = { + min: 0, + max: 0 + }; + + break; + + case PLUSSIGN: + scanner.pos++; + + range = { + min: 1, + max: 0 + }; + + break; + + case QUESTIONMARK: + scanner.pos++; + + range = { + min: 0, + max: 1 + }; + + break; + + case NUMBERSIGN: + scanner.pos++; + + comma = true; + + if (scanner.charCode() === LEFTCURLYBRACKET) { + range = readMultiplierRange(scanner); + } else if (scanner.charCode() === QUESTIONMARK) { + // https://www.w3.org/TR/css-values-4/#component-multipliers + // > the # and ? multipliers may be stacked as #? + // In this case just treat "#?" as a single multiplier + // { min: 0, max: 0, comma: true } + scanner.pos++; + range = { + min: 0, + max: 0 + }; + } else { + range = { + min: 1, + max: 0 + }; + } + + break; + + case LEFTCURLYBRACKET: + range = readMultiplierRange(scanner); + break; + + default: + return null; + } + + return { + type: 'Multiplier', + comma, + min: range.min, + max: range.max, + term: null + }; +} + +function maybeMultiplied(scanner, node) { + const multiplier = readMultiplier(scanner); + + if (multiplier !== null) { + multiplier.term = node; + + // https://www.w3.org/TR/css-values-4/#component-multipliers + // > The + and # multipliers may be stacked as +#; + // Represent "+#" as nested multipliers: + // { ...<multiplier #>, + // term: { + // ...<multipler +>, + // term: node + // } + // } + if (scanner.charCode() === NUMBERSIGN && + scanner.charCodeAt(scanner.pos - 1) === PLUSSIGN) { + return maybeMultiplied(scanner, multiplier); + } + + return multiplier; + } + + return node; +} + +function maybeToken(scanner) { + const ch = scanner.peek(); + + if (ch === '') { + return null; + } + + return maybeMultiplied(scanner, { + type: 'Token', + value: ch + }); +} + +function readProperty(scanner) { + let name; + + scanner.eat(LESSTHANSIGN); + scanner.eat(APOSTROPHE); + + name = scanner.scanWord(); + + scanner.eat(APOSTROPHE); + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Property', + name + }); +} + +// https://drafts.csswg.org/css-values-3/#numeric-ranges +// 4.1. Range Restrictions and Range Definition Notation +// +// Range restrictions can be annotated in the numeric type notation using CSS bracketed +// range notation—[min,max]—within the angle brackets, after the identifying keyword, +// indicating a closed range between (and including) min and max. +// For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive. +function readTypeRange(scanner) { + // use null for Infinity to make AST format JSON serializable/deserializable + let min = null; // -Infinity + let max = null; // Infinity + let sign = 1; + + scanner.eat(LEFTSQUAREBRACKET); + + if (scanner.charCode() === HYPERMINUS) { + scanner.peek(); + sign = -1; + } + + if (sign == -1 && scanner.charCode() === INFINITY) { + scanner.peek(); + } else { + min = sign * Number(scanner.scanNumber(scanner)); + + if (scanner.isNameCharCode()) { + min += scanner.scanWord(); + } + } + + scanner.skipWs(); + scanner.eat(COMMA); + scanner.skipWs(); + + if (scanner.charCode() === INFINITY) { + scanner.peek(); + } else { + sign = 1; + + if (scanner.charCode() === HYPERMINUS) { + scanner.peek(); + sign = -1; + } + + max = sign * Number(scanner.scanNumber(scanner)); + + if (scanner.isNameCharCode()) { + max += scanner.scanWord(); + } + } + + scanner.eat(RIGHTSQUAREBRACKET); + + return { + type: 'Range', + min, + max + }; +} + +function readType(scanner) { + let name; + let opts = null; + + scanner.eat(LESSTHANSIGN); + name = scanner.scanWord(); + + // https://drafts.csswg.org/css-values-5/#boolean + if (name === 'boolean-expr') { + scanner.eat(LEFTSQUAREBRACKET); + + const implicitGroup = readImplicitGroup(scanner, RIGHTSQUAREBRACKET); + + scanner.eat(RIGHTSQUAREBRACKET); + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Boolean', + term: implicitGroup.terms.length === 1 + ? implicitGroup.terms[0] + : implicitGroup + }); + } + + if (scanner.charCode() === LEFTPARENTHESIS && + scanner.nextCharCode() === RIGHTPARENTHESIS) { + scanner.pos += 2; + name += '()'; + } + + if (scanner.charCodeAt(scanner.findWsEnd(scanner.pos)) === LEFTSQUAREBRACKET) { + scanner.skipWs(); + opts = readTypeRange(scanner); + } + + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Type', + name, + opts + }); +} + +function readKeywordOrFunction(scanner) { + const name = scanner.scanWord(); + + if (scanner.charCode() === LEFTPARENTHESIS) { + scanner.pos++; + + return { + type: 'Function', + name + }; + } + + return maybeMultiplied(scanner, { + type: 'Keyword', + name + }); +} + +function regroupTerms(terms, combinators) { + function createGroup(terms, combinator) { + return { + type: 'Group', + terms, + combinator, + disallowEmpty: false, + explicit: false + }; + } + + let combinator; + + combinators = Object.keys(combinators) + .sort((a, b) => COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b]); + + while (combinators.length > 0) { + combinator = combinators.shift(); + + let i = 0; + let subgroupStart = 0; + + for (; i < terms.length; i++) { + const term = terms[i]; + + if (term.type === 'Combinator') { + if (term.value === combinator) { + if (subgroupStart === -1) { + subgroupStart = i - 1; + } + terms.splice(i, 1); + i--; + } else { + if (subgroupStart !== -1 && i - subgroupStart > 1) { + terms.splice( + subgroupStart, + i - subgroupStart, + createGroup(terms.slice(subgroupStart, i), combinator) + ); + i = subgroupStart + 1; + } + subgroupStart = -1; + } + } + } + + if (subgroupStart !== -1 && combinators.length) { + terms.splice( + subgroupStart, + i - subgroupStart, + createGroup(terms.slice(subgroupStart, i), combinator) + ); + } + } + + return combinator; +} + +function readImplicitGroup(scanner, stopCharCode) { + const combinators = Object.create(null); + const terms = []; + let token; + let prevToken = null; + let prevTokenPos = scanner.pos; + + while (scanner.charCode() !== stopCharCode && (token = peek(scanner, stopCharCode))) { + if (token.type !== 'Spaces') { + if (token.type === 'Combinator') { + // check for combinator in group beginning and double combinator sequence + if (prevToken === null || prevToken.type === 'Combinator') { + scanner.pos = prevTokenPos; + scanner.error('Unexpected combinator'); + } + + combinators[token.value] = true; + } else if (prevToken !== null && prevToken.type !== 'Combinator') { + combinators[' '] = true; // a b + terms.push({ + type: 'Combinator', + value: ' ' + }); + } + + terms.push(token); + prevToken = token; + prevTokenPos = scanner.pos; + } + } + + // check for combinator in group ending + if (prevToken !== null && prevToken.type === 'Combinator') { + scanner.pos -= prevTokenPos; + scanner.error('Unexpected combinator'); + } + + return { + type: 'Group', + terms, + combinator: regroupTerms(terms, combinators) || ' ', + disallowEmpty: false, + explicit: false + }; +} + +function readGroup(scanner, stopCharCode) { + let result; + + scanner.eat(LEFTSQUAREBRACKET); + result = readImplicitGroup(scanner, stopCharCode); + scanner.eat(RIGHTSQUAREBRACKET); + + result.explicit = true; + + if (scanner.charCode() === EXCLAMATIONMARK) { + scanner.pos++; + result.disallowEmpty = true; + } + + return result; +} + +function peek(scanner, stopCharCode) { + let code = scanner.charCode(); + + switch (code) { + case RIGHTSQUAREBRACKET: + // don't eat, stop scan a group + break; + + case LEFTSQUAREBRACKET: + return maybeMultiplied(scanner, readGroup(scanner, stopCharCode)); + + case LESSTHANSIGN: + return scanner.nextCharCode() === APOSTROPHE + ? readProperty(scanner) + : readType(scanner); + + case VERTICALLINE: + return { + type: 'Combinator', + value: scanner.substringToPos( + scanner.pos + (scanner.nextCharCode() === VERTICALLINE ? 2 : 1) + ) + }; + + case AMPERSAND: + scanner.pos++; + scanner.eat(AMPERSAND); + + return { + type: 'Combinator', + value: '&&' + }; + + case COMMA: + scanner.pos++; + return { + type: 'Comma' + }; + + case APOSTROPHE: + return maybeMultiplied(scanner, { + type: 'String', + value: scanner.scanString() + }); + + case SPACE: + case TAB: + case N: + case R: + case F: + return { + type: 'Spaces', + value: scanner.scanSpaces() + }; + + case COMMERCIALAT: + code = scanner.nextCharCode(); + + if (scanner.isNameCharCode(code)) { + scanner.pos++; + return { + type: 'AtKeyword', + name: scanner.scanWord() + }; + } + + return maybeToken(scanner); + + case ASTERISK: + case PLUSSIGN: + case QUESTIONMARK: + case NUMBERSIGN: + case EXCLAMATIONMARK: + // prohibited tokens (used as a multiplier start) + break; + + case LEFTCURLYBRACKET: + // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting + // check next char isn't a number, because it's likely a disjoined multiplier + code = scanner.nextCharCode(); + + if (code < 48 || code > 57) { + return maybeToken(scanner); + } + + break; + + default: + if (scanner.isNameCharCode(code)) { + return readKeywordOrFunction(scanner); + } + + return maybeToken(scanner); + } +} + +function parse(source) { + const scanner$1 = new scanner.Scanner(source); + const result = readImplicitGroup(scanner$1); + + if (scanner$1.pos !== source.length) { + scanner$1.error('Unexpected input'); + } + + // reduce redundant groups with single group term + if (result.terms.length === 1 && result.terms[0].type === 'Group') { + return result.terms[0]; + } + + return result; +} + +exports.parse = parse; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs new file mode 100644 index 0000000..0bad36a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs @@ -0,0 +1,113 @@ +'use strict'; + +const SyntaxError = require('./SyntaxError.cjs'); + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; +const NAME_CHAR = new Uint8Array(128).map((_, idx) => + /[a-zA-Z0-9\-]/.test(String.fromCharCode(idx)) ? 1 : 0 +); + +class Scanner { + constructor(str) { + this.str = str; + this.pos = 0; + } + + charCodeAt(pos) { + return pos < this.str.length ? this.str.charCodeAt(pos) : 0; + } + charCode() { + return this.charCodeAt(this.pos); + } + isNameCharCode(code = this.charCode()) { + return code < 128 && NAME_CHAR[code] === 1; + } + nextCharCode() { + return this.charCodeAt(this.pos + 1); + } + nextNonWsCode(pos) { + return this.charCodeAt(this.findWsEnd(pos)); + } + skipWs() { + this.pos = this.findWsEnd(this.pos); + } + findWsEnd(pos) { + for (; pos < this.str.length; pos++) { + const code = this.str.charCodeAt(pos); + if (code !== R && code !== N && code !== F && code !== SPACE && code !== TAB) { + break; + } + } + + return pos; + } + substringToPos(end) { + return this.str.substring(this.pos, this.pos = end); + } + eat(code) { + if (this.charCode() !== code) { + this.error('Expect `' + String.fromCharCode(code) + '`'); + } + + this.pos++; + } + peek() { + return this.pos < this.str.length ? this.str.charAt(this.pos++) : ''; + } + error(message) { + throw new SyntaxError.SyntaxError(message, this.str, this.pos); + } + + scanSpaces() { + return this.substringToPos(this.findWsEnd(this.pos)); + } + scanWord() { + let end = this.pos; + + for (; end < this.str.length; end++) { + const code = this.str.charCodeAt(end); + if (code >= 128 || NAME_CHAR[code] === 0) { + break; + } + } + + if (this.pos === end) { + this.error('Expect a keyword'); + } + + return this.substringToPos(end); + } + scanNumber() { + let end = this.pos; + + for (; end < this.str.length; end++) { + const code = this.str.charCodeAt(end); + + if (code < 48 || code > 57) { + break; + } + } + + if (this.pos === end) { + this.error('Expect a number'); + } + + return this.substringToPos(end); + } + scanString() { + const end = this.str.indexOf('\'', this.pos + 1); + + if (end === -1) { + this.pos = this.str.length; + this.error('Expect an apostrophe'); + } + + return this.substringToPos(end + 1); + } +} + +exports.Scanner = Scanner; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs new file mode 100644 index 0000000..2b934bd --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs @@ -0,0 +1,59 @@ +'use strict'; + +const SyntaxError = require('./SyntaxError.cjs'); + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; + +class Tokenizer { + constructor(str) { + this.str = str; + this.pos = 0; + } + charCodeAt(pos) { + return pos < this.str.length ? this.str.charCodeAt(pos) : 0; + } + charCode() { + return this.charCodeAt(this.pos); + } + nextCharCode() { + return this.charCodeAt(this.pos + 1); + } + nextNonWsCode(pos) { + return this.charCodeAt(this.findWsEnd(pos)); + } + skipWs() { + this.pos = this.findWsEnd(this.pos); + } + findWsEnd(pos) { + for (; pos < this.str.length; pos++) { + const code = this.str.charCodeAt(pos); + if (code !== R && code !== N && code !== F && code !== SPACE && code !== TAB) { + break; + } + } + + return pos; + } + substringToPos(end) { + return this.str.substring(this.pos, this.pos = end); + } + eat(code) { + if (this.charCode() !== code) { + this.error('Expect `' + String.fromCharCode(code) + '`'); + } + + this.pos++; + } + peek() { + return this.pos < this.str.length ? this.str.charAt(this.pos++) : ''; + } + error(message) { + throw new SyntaxError.SyntaxError(message, this.str, this.pos); + } +} + +exports.Tokenizer = Tokenizer; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs new file mode 100644 index 0000000..fdba065 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs @@ -0,0 +1,57 @@ +'use strict'; + +const noop = function() {}; + +function ensureFunction(value) { + return typeof value === 'function' ? value : noop; +} + +function walk(node, options, context) { + function walk(node) { + enter.call(context, node); + + switch (node.type) { + case 'Group': + node.terms.forEach(walk); + break; + + case 'Multiplier': + case 'Boolean': + walk(node.term); + break; + + case 'Type': + case 'Property': + case 'Keyword': + case 'AtKeyword': + case 'Function': + case 'String': + case 'Token': + case 'Comma': + break; + + default: + throw new Error('Unknown type: ' + node.type); + } + + leave.call(context, node); + } + + let enter = noop; + let leave = noop; + + if (typeof options === 'function') { + enter = options; + } else if (options) { + enter = ensureFunction(options.enter); + leave = ensureFunction(options.leave); + } + + if (enter === noop && leave === noop) { + throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function'); + } + + walk(node); +} + +exports.walk = walk; diff --git a/vanilla/node_modules/css-tree/cjs/generator/create.cjs b/vanilla/node_modules/css-tree/cjs/generator/create.cjs new file mode 100644 index 0000000..87a54b2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/create.cjs @@ -0,0 +1,102 @@ +'use strict'; + +const index = require('../tokenizer/index.cjs'); +const sourceMap = require('./sourceMap.cjs'); +const tokenBefore = require('./token-before.cjs'); +const types = require('../tokenizer/types.cjs'); + +const REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) + +function processChildren(node, delimeter) { + if (typeof delimeter === 'function') { + let prev = null; + + node.children.forEach(node => { + if (prev !== null) { + delimeter.call(this, prev); + } + + this.node(node); + prev = node; + }); + + return; + } + + node.children.forEach(this.node, this); +} + +function processChunk(chunk) { + index.tokenize(chunk, (type, start, end) => { + this.token(type, chunk.slice(start, end)); + }); +} + +function createGenerator(config) { + const types$1 = new Map(); + + for (let [name, item] of Object.entries(config.node)) { + const fn = item.generate || item; + + if (typeof fn === 'function') { + types$1.set(name, item.generate || item); + } + } + + return function(node, options) { + let buffer = ''; + let prevCode = 0; + let handlers = { + node(node) { + if (types$1.has(node.type)) { + types$1.get(node.type).call(publicApi, node); + } else { + throw new Error('Unknown node type: ' + node.type); + } + }, + tokenBefore: tokenBefore.safe, + token(type, value) { + prevCode = this.tokenBefore(prevCode, type, value); + + this.emit(value, type, false); + + if (type === types.Delim && value.charCodeAt(0) === REVERSESOLIDUS) { + this.emit('\n', types.WhiteSpace, true); + } + }, + emit(value) { + buffer += value; + }, + result() { + return buffer; + } + }; + + if (options) { + if (typeof options.decorator === 'function') { + handlers = options.decorator(handlers); + } + + if (options.sourceMap) { + handlers = sourceMap.generateSourceMap(handlers); + } + + if (options.mode in tokenBefore) { + handlers.tokenBefore = tokenBefore[options.mode]; + } + } + + const publicApi = { + node: (node) => handlers.node(node), + children: processChildren, + token: (type, value) => handlers.token(type, value), + tokenize: processChunk + }; + + handlers.node(node); + + return handlers.result(); + }; +} + +exports.createGenerator = createGenerator; diff --git a/vanilla/node_modules/css-tree/cjs/generator/index.cjs b/vanilla/node_modules/css-tree/cjs/generator/index.cjs new file mode 100644 index 0000000..5c87cd3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/index.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const generator = require('../syntax/config/generator.cjs'); + +const index = create.createGenerator(generator); + +module.exports = index; diff --git a/vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs b/vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs new file mode 100644 index 0000000..efbc5b9 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs @@ -0,0 +1,96 @@ +'use strict'; + +const sourceMapGenerator_js = require('source-map-js/lib/source-map-generator.js'); + +const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']); + +function generateSourceMap(handlers) { + const map = new sourceMapGenerator_js.SourceMapGenerator(); + const generated = { + line: 1, + column: 0 + }; + const original = { + line: 0, // should be zero to add first mapping + column: 0 + }; + const activatedGenerated = { + line: 1, + column: 0 + }; + const activatedMapping = { + generated: activatedGenerated + }; + let line = 1; + let column = 0; + let sourceMappingActive = false; + + const origHandlersNode = handlers.node; + handlers.node = function(node) { + if (node.loc && node.loc.start && trackNodes.has(node.type)) { + const nodeLine = node.loc.start.line; + const nodeColumn = node.loc.start.column - 1; + + if (original.line !== nodeLine || + original.column !== nodeColumn) { + original.line = nodeLine; + original.column = nodeColumn; + + generated.line = line; + generated.column = column; + + if (sourceMappingActive) { + sourceMappingActive = false; + if (generated.line !== activatedGenerated.line || + generated.column !== activatedGenerated.column) { + map.addMapping(activatedMapping); + } + } + + sourceMappingActive = true; + map.addMapping({ + source: node.loc.source, + original, + generated + }); + } + } + + origHandlersNode.call(this, node); + + if (sourceMappingActive && trackNodes.has(node.type)) { + activatedGenerated.line = line; + activatedGenerated.column = column; + } + }; + + const origHandlersEmit = handlers.emit; + handlers.emit = function(value, type, auto) { + for (let i = 0; i < value.length; i++) { + if (value.charCodeAt(i) === 10) { // \n + line++; + column = 0; + } else { + column++; + } + } + + origHandlersEmit(value, type, auto); + }; + + const origHandlersResult = handlers.result; + handlers.result = function() { + if (sourceMappingActive) { + map.addMapping(activatedMapping); + } + + return { + css: origHandlersResult(), + map + }; + }; + + return handlers; +} + +exports.generateSourceMap = generateSourceMap; diff --git a/vanilla/node_modules/css-tree/cjs/generator/token-before.cjs b/vanilla/node_modules/css-tree/cjs/generator/token-before.cjs new file mode 100644 index 0000000..87bf4a3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/token-before.cjs @@ -0,0 +1,170 @@ +'use strict'; + +const types = require('../tokenizer/types.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) + +const code = (type, value) => { + if (type === types.Delim) { + type = value; + } + + if (typeof type === 'string') { + const charCode = type.charCodeAt(0); + return charCode > 0x7F ? 0x8000 : charCode << 8; + } + + return type; +}; + +// https://www.w3.org/TR/css-syntax-3/#serialization +// The only requirement for serialization is that it must "round-trip" with parsing, +// that is, parsing the stylesheet must produce the same data structures as parsing, +// serializing, and parsing again, except for consecutive <whitespace-token>s, +// which may be collapsed into a single token. + +const specPairs = [ + [types.Ident, types.Ident], + [types.Ident, types.Function], + [types.Ident, types.Url], + [types.Ident, types.BadUrl], + [types.Ident, '-'], + [types.Ident, types.Number], + [types.Ident, types.Percentage], + [types.Ident, types.Dimension], + [types.Ident, types.CDC], + [types.Ident, types.LeftParenthesis], + + [types.AtKeyword, types.Ident], + [types.AtKeyword, types.Function], + [types.AtKeyword, types.Url], + [types.AtKeyword, types.BadUrl], + [types.AtKeyword, '-'], + [types.AtKeyword, types.Number], + [types.AtKeyword, types.Percentage], + [types.AtKeyword, types.Dimension], + [types.AtKeyword, types.CDC], + + [types.Hash, types.Ident], + [types.Hash, types.Function], + [types.Hash, types.Url], + [types.Hash, types.BadUrl], + [types.Hash, '-'], + [types.Hash, types.Number], + [types.Hash, types.Percentage], + [types.Hash, types.Dimension], + [types.Hash, types.CDC], + + [types.Dimension, types.Ident], + [types.Dimension, types.Function], + [types.Dimension, types.Url], + [types.Dimension, types.BadUrl], + [types.Dimension, '-'], + [types.Dimension, types.Number], + [types.Dimension, types.Percentage], + [types.Dimension, types.Dimension], + [types.Dimension, types.CDC], + + ['#', types.Ident], + ['#', types.Function], + ['#', types.Url], + ['#', types.BadUrl], + ['#', '-'], + ['#', types.Number], + ['#', types.Percentage], + ['#', types.Dimension], + ['#', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['-', types.Ident], + ['-', types.Function], + ['-', types.Url], + ['-', types.BadUrl], + ['-', '-'], + ['-', types.Number], + ['-', types.Percentage], + ['-', types.Dimension], + ['-', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + [types.Number, types.Ident], + [types.Number, types.Function], + [types.Number, types.Url], + [types.Number, types.BadUrl], + [types.Number, types.Number], + [types.Number, types.Percentage], + [types.Number, types.Dimension], + [types.Number, '%'], + [types.Number, types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['@', types.Ident], + ['@', types.Function], + ['@', types.Url], + ['@', types.BadUrl], + ['@', '-'], + ['@', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['.', types.Number], + ['.', types.Percentage], + ['.', types.Dimension], + + ['+', types.Number], + ['+', types.Percentage], + ['+', types.Dimension], + + ['/', '*'] +]; +// validate with scripts/generate-safe +const safePairs = specPairs.concat([ + [types.Ident, types.Hash], + + [types.Dimension, types.Hash], + + [types.Hash, types.Hash], + + [types.AtKeyword, types.LeftParenthesis], + [types.AtKeyword, types.String], + [types.AtKeyword, types.Colon], + + [types.Percentage, types.Percentage], + [types.Percentage, types.Dimension], + [types.Percentage, types.Function], + [types.Percentage, '-'], + + [types.RightParenthesis, types.Ident], + [types.RightParenthesis, types.Function], + [types.RightParenthesis, types.Percentage], + [types.RightParenthesis, types.Dimension], + [types.RightParenthesis, types.Hash], + [types.RightParenthesis, '-'] +]); + +function createMap(pairs) { + const isWhiteSpaceRequired = new Set( + pairs.map(([prev, next]) => (code(prev) << 16 | code(next))) + ); + + return function(prevCode, type, value) { + const nextCode = code(type, value); + const nextCharCode = value.charCodeAt(0); + const emitWs = + (nextCharCode === HYPHENMINUS && + type !== types.Ident && + type !== types.Function && + type !== types.CDC) || + (nextCharCode === PLUSSIGN) + ? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8) + : isWhiteSpaceRequired.has(prevCode << 16 | nextCode); + + if (emitWs) { + this.emit(' ', types.WhiteSpace, true); + } + + return nextCode; + }; +} + +const spec = createMap(specPairs); +const safe = createMap(safePairs); + +exports.safe = safe; +exports.spec = spec; diff --git a/vanilla/node_modules/css-tree/cjs/index.cjs b/vanilla/node_modules/css-tree/cjs/index.cjs new file mode 100644 index 0000000..cc61137 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/index.cjs @@ -0,0 +1,65 @@ +'use strict'; + +const index$1 = require('./syntax/index.cjs'); +const version = require('./version.cjs'); +const create = require('./syntax/create.cjs'); +const List = require('./utils/List.cjs'); +const Lexer = require('./lexer/Lexer.cjs'); +const index = require('./definition-syntax/index.cjs'); +const clone = require('./utils/clone.cjs'); +const names$1 = require('./utils/names.cjs'); +const ident = require('./utils/ident.cjs'); +const string = require('./utils/string.cjs'); +const url = require('./utils/url.cjs'); +const types = require('./tokenizer/types.cjs'); +const names = require('./tokenizer/names.cjs'); +const TokenStream = require('./tokenizer/TokenStream.cjs'); +const OffsetToLocation = require('./tokenizer/OffsetToLocation.cjs'); + +const { + tokenize, + parse, + generate, + lexer, + createLexer, + + walk, + find, + findLast, + findAll, + + toPlainObject, + fromPlainObject, + + fork +} = index$1; + +exports.version = version.version; +exports.createSyntax = create; +exports.List = List.List; +exports.Lexer = Lexer.Lexer; +exports.definitionSyntax = index; +exports.clone = clone.clone; +exports.isCustomProperty = names$1.isCustomProperty; +exports.keyword = names$1.keyword; +exports.property = names$1.property; +exports.vendorPrefix = names$1.vendorPrefix; +exports.ident = ident; +exports.string = string; +exports.url = url; +exports.tokenTypes = types; +exports.tokenNames = names; +exports.TokenStream = TokenStream.TokenStream; +exports.OffsetToLocation = OffsetToLocation.OffsetToLocation; +exports.createLexer = createLexer; +exports.find = find; +exports.findAll = findAll; +exports.findLast = findLast; +exports.fork = fork; +exports.fromPlainObject = fromPlainObject; +exports.generate = generate; +exports.lexer = lexer; +exports.parse = parse; +exports.toPlainObject = toPlainObject; +exports.tokenize = tokenize; +exports.walk = walk; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs b/vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs new file mode 100644 index 0000000..a6d1fcb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs @@ -0,0 +1,517 @@ +'use strict'; + +const error = require('./error.cjs'); +const names = require('../utils/names.cjs'); +const genericConst = require('./generic-const.cjs'); +const generic = require('./generic.cjs'); +const units = require('./units.cjs'); +const prepareTokens = require('./prepare-tokens.cjs'); +const matchGraph = require('./match-graph.cjs'); +const match = require('./match.cjs'); +const trace = require('./trace.cjs'); +const search = require('./search.cjs'); +const structure = require('./structure.cjs'); +const parse = require('../definition-syntax/parse.cjs'); +const generate = require('../definition-syntax/generate.cjs'); +const walk = require('../definition-syntax/walk.cjs'); + +function dumpMapSyntax(map, compact, syntaxAsAst) { + const result = {}; + + for (const name in map) { + if (map[name].syntax) { + result[name] = syntaxAsAst + ? map[name].syntax + : generate.generate(map[name].syntax, { compact }); + } + } + + return result; +} + +function dumpAtruleMapSyntax(map, compact, syntaxAsAst) { + const result = {}; + + for (const [name, atrule] of Object.entries(map)) { + result[name] = { + prelude: atrule.prelude && ( + syntaxAsAst + ? atrule.prelude.syntax + : generate.generate(atrule.prelude.syntax, { compact }) + ), + descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst) + }; + } + + return result; +} + +function valueHasVar(tokens) { + for (let i = 0; i < tokens.length; i++) { + if (tokens[i].value.toLowerCase() === 'var(') { + return true; + } + } + + return false; +} + +function syntaxHasTopLevelCommaMultiplier(syntax) { + const singleTerm = syntax.terms[0]; + + return ( + syntax.explicit === false && + syntax.terms.length === 1 && + singleTerm.type === 'Multiplier' && + singleTerm.comma === true + ); +} + +function buildMatchResult(matched, error, iterations) { + return { + matched, + iterations, + error, + ...trace + }; +} + +function matchSyntax(lexer, syntax, value, useCssWideKeywords) { + const tokens = prepareTokens(value, lexer.syntax); + let result; + + if (valueHasVar(tokens)) { + return buildMatchResult(null, new Error('Matching for a tree with var() is not supported')); + } + + if (useCssWideKeywords) { + result = match.matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer); + } + + if (!useCssWideKeywords || !result.match) { + result = match.matchAsTree(tokens, syntax.match, lexer); + if (!result.match) { + return buildMatchResult( + null, + new error.SyntaxMatchError(result.reason, syntax.syntax, value, result), + result.iterations + ); + } + } + + return buildMatchResult(result.match, null, result.iterations); +} + +class Lexer { + constructor(config, syntax, structure$1) { + this.cssWideKeywords = genericConst.cssWideKeywords; + this.syntax = syntax; + this.generic = false; + this.units = { ...units }; + this.atrules = Object.create(null); + this.properties = Object.create(null); + this.types = Object.create(null); + this.structure = structure$1 || structure.getStructureFromConfig(config); + + if (config) { + if (config.cssWideKeywords) { + this.cssWideKeywords = config.cssWideKeywords; + } + + if (config.units) { + for (const group of Object.keys(units)) { + if (Array.isArray(config.units[group])) { + this.units[group] = config.units[group]; + } + } + } + + if (config.types) { + for (const [name, type] of Object.entries(config.types)) { + this.addType_(name, type); + } + } + + if (config.generic) { + this.generic = true; + for (const [name, value] of Object.entries(generic.createGenericTypes(this.units))) { + this.addType_(name, value); + } + } + + if (config.atrules) { + for (const [name, atrule] of Object.entries(config.atrules)) { + this.addAtrule_(name, atrule); + } + } + + if (config.properties) { + for (const [name, property] of Object.entries(config.properties)) { + this.addProperty_(name, property); + } + } + } + + this.cssWideKeywordsSyntax = matchGraph.buildMatchGraph(this.cssWideKeywords.join(' | ')); + } + + checkStructure(ast) { + function collectWarning(node, message) { + warns.push({ node, message }); + } + + const structure = this.structure; + const warns = []; + + this.syntax.walk(ast, function(node) { + if (structure.hasOwnProperty(node.type)) { + structure[node.type].check(node, collectWarning); + } else { + collectWarning(node, 'Unknown node type `' + node.type + '`'); + } + }); + + return warns.length ? warns : false; + } + + createDescriptor(syntax, type, name, parent = null) { + const ref = { + type, + name + }; + const descriptor = { + type, + name, + parent, + serializable: typeof syntax === 'string' || (syntax && typeof syntax.type === 'string'), + syntax: null, + match: null, + matchRef: null // used for properties when a syntax referenced as <'property'> in other syntax definitions + }; + + if (typeof syntax === 'function') { + descriptor.match = matchGraph.buildMatchGraph(syntax, ref); + } else { + if (typeof syntax === 'string') { + // lazy parsing on first access + Object.defineProperty(descriptor, 'syntax', { + get() { + Object.defineProperty(descriptor, 'syntax', { + value: parse.parse(syntax) + }); + + return descriptor.syntax; + } + }); + } else { + descriptor.syntax = syntax; + } + + // lazy graph build on first access + Object.defineProperty(descriptor, 'match', { + get() { + Object.defineProperty(descriptor, 'match', { + value: matchGraph.buildMatchGraph(descriptor.syntax, ref) + }); + + return descriptor.match; + } + }); + + if (type === 'Property') { + Object.defineProperty(descriptor, 'matchRef', { + get() { + const syntax = descriptor.syntax; + const value = syntaxHasTopLevelCommaMultiplier(syntax) + ? matchGraph.buildMatchGraph({ + ...syntax, + terms: [syntax.terms[0].term] + }, ref) + : null; + + Object.defineProperty(descriptor, 'matchRef', { + value + }); + + return value; + } + }); + } + } + + return descriptor; + } + addAtrule_(name, syntax) { + if (!syntax) { + return; + } + + this.atrules[name] = { + type: 'Atrule', + name: name, + prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null, + descriptors: syntax.descriptors + ? Object.keys(syntax.descriptors).reduce( + (map, descName) => { + map[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name); + return map; + }, + Object.create(null) + ) + : null + }; + } + addProperty_(name, syntax) { + if (!syntax) { + return; + } + + this.properties[name] = this.createDescriptor(syntax, 'Property', name); + } + addType_(name, syntax) { + if (!syntax) { + return; + } + + this.types[name] = this.createDescriptor(syntax, 'Type', name); + } + + checkAtruleName(atruleName) { + if (!this.getAtrule(atruleName)) { + return new error.SyntaxReferenceError('Unknown at-rule', '@' + atruleName); + } + } + checkAtrulePrelude(atruleName, prelude) { + const error = this.checkAtruleName(atruleName); + + if (error) { + return error; + } + + const atrule = this.getAtrule(atruleName); + + if (!atrule.prelude && prelude) { + return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude'); + } + + if (atrule.prelude && !prelude) { + if (!matchSyntax(this, atrule.prelude, '', false).matched) { + return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude'); + } + } + } + checkAtruleDescriptorName(atruleName, descriptorName) { + const error$1 = this.checkAtruleName(atruleName); + + if (error$1) { + return error$1; + } + + const atrule = this.getAtrule(atruleName); + const descriptor = names.keyword(descriptorName); + + if (!atrule.descriptors) { + return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors'); + } + + if (!atrule.descriptors[descriptor.name] && + !atrule.descriptors[descriptor.basename]) { + return new error.SyntaxReferenceError('Unknown at-rule descriptor', descriptorName); + } + } + checkPropertyName(propertyName) { + if (!this.getProperty(propertyName)) { + return new error.SyntaxReferenceError('Unknown property', propertyName); + } + } + + matchAtrulePrelude(atruleName, prelude) { + const error = this.checkAtrulePrelude(atruleName, prelude); + + if (error) { + return buildMatchResult(null, error); + } + + const atrule = this.getAtrule(atruleName); + + if (!atrule.prelude) { + return buildMatchResult(null, null); + } + + return matchSyntax(this, atrule.prelude, prelude || '', false); + } + matchAtruleDescriptor(atruleName, descriptorName, value) { + const error = this.checkAtruleDescriptorName(atruleName, descriptorName); + + if (error) { + return buildMatchResult(null, error); + } + + const atrule = this.getAtrule(atruleName); + const descriptor = names.keyword(descriptorName); + + return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false); + } + matchDeclaration(node) { + if (node.type !== 'Declaration') { + return buildMatchResult(null, new Error('Not a Declaration node')); + } + + return this.matchProperty(node.property, node.value); + } + matchProperty(propertyName, value) { + // don't match syntax for a custom property at the moment + if (names.property(propertyName).custom) { + return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties')); + } + + const error = this.checkPropertyName(propertyName); + + if (error) { + return buildMatchResult(null, error); + } + + return matchSyntax(this, this.getProperty(propertyName), value, true); + } + matchType(typeName, value) { + const typeSyntax = this.getType(typeName); + + if (!typeSyntax) { + return buildMatchResult(null, new error.SyntaxReferenceError('Unknown type', typeName)); + } + + return matchSyntax(this, typeSyntax, value, false); + } + match(syntax, value) { + if (typeof syntax !== 'string' && (!syntax || !syntax.type)) { + return buildMatchResult(null, new error.SyntaxReferenceError('Bad syntax')); + } + + if (typeof syntax === 'string' || !syntax.match) { + syntax = this.createDescriptor(syntax, 'Type', 'anonymous'); + } + + return matchSyntax(this, syntax, value, false); + } + + findValueFragments(propertyName, value, type, name) { + return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name); + } + findDeclarationValueFragments(declaration, type, name) { + return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name); + } + findAllFragments(ast, type, name) { + const result = []; + + this.syntax.walk(ast, { + visit: 'Declaration', + enter: (declaration) => { + result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name)); + } + }); + + return result; + } + + getAtrule(atruleName, fallbackBasename = true) { + const atrule = names.keyword(atruleName); + const atruleEntry = atrule.vendor && fallbackBasename + ? this.atrules[atrule.name] || this.atrules[atrule.basename] + : this.atrules[atrule.name]; + + return atruleEntry || null; + } + getAtrulePrelude(atruleName, fallbackBasename = true) { + const atrule = this.getAtrule(atruleName, fallbackBasename); + + return atrule && atrule.prelude || null; + } + getAtruleDescriptor(atruleName, name) { + return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators + ? this.atrules[atruleName].declarators[name] || null + : null; + } + getProperty(propertyName, fallbackBasename = true) { + const property = names.property(propertyName); + const propertyEntry = property.vendor && fallbackBasename + ? this.properties[property.name] || this.properties[property.basename] + : this.properties[property.name]; + + return propertyEntry || null; + } + getType(name) { + return hasOwnProperty.call(this.types, name) ? this.types[name] : null; + } + + validate() { + function syntaxRef(name, isType) { + return isType ? `<${name}>` : `<'${name}'>`; + } + + function validate(syntax, name, broken, descriptor) { + if (broken.has(name)) { + return broken.get(name); + } + + broken.set(name, false); + if (descriptor.syntax !== null) { + walk.walk(descriptor.syntax, function(node) { + if (node.type !== 'Type' && node.type !== 'Property') { + return; + } + + const map = node.type === 'Type' ? syntax.types : syntax.properties; + const brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties; + + if (!hasOwnProperty.call(map, node.name)) { + errors.push(`${syntaxRef(name, broken === brokenTypes)} used missed syntax definition ${syntaxRef(node.name, node.type === 'Type')}`); + broken.set(name, true); + } else if (validate(syntax, node.name, brokenMap, map[node.name])) { + errors.push(`${syntaxRef(name, broken === brokenTypes)} used broken syntax definition ${syntaxRef(node.name, node.type === 'Type')}`); + broken.set(name, true); + } + }, this); + } + } + + const errors = []; + let brokenTypes = new Map(); + let brokenProperties = new Map(); + + for (const key in this.types) { + validate(this, key, brokenTypes, this.types[key]); + } + + for (const key in this.properties) { + validate(this, key, brokenProperties, this.properties[key]); + } + + const brokenTypesArray = [...brokenTypes.keys()].filter(name => brokenTypes.get(name)); + const brokenPropertiesArray = [...brokenProperties.keys()].filter(name => brokenProperties.get(name)); + + if (brokenTypesArray.length || brokenPropertiesArray.length) { + return { + errors, + types: brokenTypesArray, + properties: brokenPropertiesArray + }; + } + + return null; + } + dump(syntaxAsAst, pretty) { + return { + generic: this.generic, + cssWideKeywords: this.cssWideKeywords, + units: this.units, + types: dumpMapSyntax(this.types, !pretty, syntaxAsAst), + properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst), + atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst) + }; + } + toString() { + return JSON.stringify(this.dump()); + } +} + +exports.Lexer = Lexer; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/error.cjs b/vanilla/node_modules/css-tree/cjs/lexer/error.cjs new file mode 100644 index 0000000..8d252ee --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/error.cjs @@ -0,0 +1,128 @@ +'use strict'; + +const createCustomError = require('../utils/create-custom-error.cjs'); +const generate = require('../definition-syntax/generate.cjs'); + +const defaultLoc = { offset: 0, line: 1, column: 1 }; + +function locateMismatch(matchResult, node) { + const tokens = matchResult.tokens; + const longestMatch = matchResult.longestMatch; + const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null; + const badNode = mismatchNode !== node ? mismatchNode : null; + let mismatchOffset = 0; + let mismatchLength = 0; + let entries = 0; + let css = ''; + let start; + let end; + + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i].value; + + if (i === longestMatch) { + mismatchLength = token.length; + mismatchOffset = css.length; + } + + if (badNode !== null && tokens[i].node === badNode) { + if (i <= longestMatch) { + entries++; + } else { + entries = 0; + } + } + + css += token; + } + + if (longestMatch === tokens.length || entries > 1) { // last + start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css); + end = buildLoc(start); + } else { + start = fromLoc(badNode, 'start') || + buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset)); + end = fromLoc(badNode, 'end') || + buildLoc(start, css.substr(mismatchOffset, mismatchLength)); + } + + return { + css, + mismatchOffset, + mismatchLength, + start, + end + }; +} + +function fromLoc(node, point) { + const value = node && node.loc && node.loc[point]; + + if (value) { + return 'line' in value ? buildLoc(value) : value; + } + + return null; +} + +function buildLoc({ offset, line, column }, extra) { + const loc = { + offset, + line, + column + }; + + if (extra) { + const lines = extra.split(/\n|\r\n?|\f/); + + loc.offset += extra.length; + loc.line += lines.length - 1; + loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1; + } + + return loc; +} + +const SyntaxReferenceError = function(type, referenceName) { + const error = createCustomError.createCustomError( + 'SyntaxReferenceError', + type + (referenceName ? ' `' + referenceName + '`' : '') + ); + + error.reference = referenceName; + + return error; +}; + +const SyntaxMatchError = function(message, syntax, node, matchResult) { + const error = createCustomError.createCustomError('SyntaxMatchError', message); + const { + css, + mismatchOffset, + mismatchLength, + start, + end + } = locateMismatch(matchResult, node); + + error.rawMessage = message; + error.syntax = syntax ? generate.generate(syntax) : '<generic>'; + error.css = css; + error.mismatchOffset = mismatchOffset; + error.mismatchLength = mismatchLength; + error.message = message + '\n' + + ' syntax: ' + error.syntax + '\n' + + ' value: ' + (css || '<empty string>') + '\n' + + ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^'; + + Object.assign(error, start); + error.loc = { + source: (node && node.loc && node.loc.source) || '<unknown>', + start, + end + }; + + return error; +}; + +exports.SyntaxMatchError = SyntaxMatchError; +exports.SyntaxReferenceError = SyntaxReferenceError; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs new file mode 100644 index 0000000..a5dfba3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs @@ -0,0 +1,235 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const types = require('../tokenizer/types.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const N = 0x006E; // U+006E LATIN SMALL LETTER N (n) +const DISALLOW_SIGN = true; +const ALLOW_SIGN = false; + +function isDelim(token, code) { + return token !== null && token.type === types.Delim && token.value.charCodeAt(0) === code; +} + +function skipSC(token, offset, getNextToken) { + while (token !== null && (token.type === types.WhiteSpace || token.type === types.Comment)) { + token = getNextToken(++offset); + } + + return offset; +} + +function checkInteger(token, valueOffset, disallowSign, offset) { + if (!token) { + return 0; + } + + const code = token.value.charCodeAt(valueOffset); + + if (code === PLUSSIGN || code === HYPHENMINUS) { + if (disallowSign) { + // Number sign is not allowed + return 0; + } + valueOffset++; + } + + for (; valueOffset < token.value.length; valueOffset++) { + if (!charCodeDefinitions.isDigit(token.value.charCodeAt(valueOffset))) { + // Integer is expected + return 0; + } + } + + return offset + 1; +} + +// ... <signed-integer> +// ... ['+' | '-'] <signless-integer> +function consumeB(token, offset_, getNextToken) { + let sign = false; + let offset = skipSC(token, offset_, getNextToken); + + token = getNextToken(offset); + + if (token === null) { + return offset_; + } + + if (token.type !== types.Number) { + if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS)) { + sign = true; + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + if (token === null || token.type !== types.Number) { + return 0; + } + } else { + return offset_; + } + } + + if (!sign) { + const code = token.value.charCodeAt(0); + if (code !== PLUSSIGN && code !== HYPHENMINUS) { + // Number sign is expected + return 0; + } + } + + return checkInteger(token, sign ? 0 : 1, sign, offset); +} + +// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb +function anPlusB(token, getNextToken) { + /* eslint-disable brace-style*/ + let offset = 0; + + if (!token) { + return 0; + } + + // <integer> + if (token.type === types.Number) { + return checkInteger(token, 0, ALLOW_SIGN, offset); // b + } + + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + // -n- <signless-integer> + // <dashndashdigit-ident> + else if (token.type === types.Ident && token.value.charCodeAt(0) === HYPHENMINUS) { + // expect 1st char is N + if (!utils.cmpChar(token.value, 1, N)) { + return 0; + } + + switch (token.value.length) { + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + case 2: + return consumeB(getNextToken(++offset), offset, getNextToken); + + // -n- <signless-integer> + case 3: + if (token.value.charCodeAt(2) !== HYPHENMINUS) { + return 0; + } + + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + + // <dashndashdigit-ident> + default: + if (token.value.charCodeAt(2) !== HYPHENMINUS) { + return 0; + } + + return checkInteger(token, 3, DISALLOW_SIGN, offset); + } + } + + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + // '+'? n- <signless-integer> + // '+'? <ndashdigit-ident> + else if (token.type === types.Ident || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === types.Ident)) { + // just ignore a plus + if (token.type !== types.Ident) { + token = getNextToken(++offset); + } + + if (token === null || !utils.cmpChar(token.value, 0, N)) { + return 0; + } + + switch (token.value.length) { + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + case 1: + return consumeB(getNextToken(++offset), offset, getNextToken); + + // '+'? n- <signless-integer> + case 2: + if (token.value.charCodeAt(1) !== HYPHENMINUS) { + return 0; + } + + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + + // '+'? <ndashdigit-ident> + default: + if (token.value.charCodeAt(1) !== HYPHENMINUS) { + return 0; + } + + return checkInteger(token, 2, DISALLOW_SIGN, offset); + } + } + + // <ndashdigit-dimension> + // <ndash-dimension> <signless-integer> + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + else if (token.type === types.Dimension) { + let code = token.value.charCodeAt(0); + let sign = code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0; + let i = sign; + + for (; i < token.value.length; i++) { + if (!charCodeDefinitions.isDigit(token.value.charCodeAt(i))) { + break; + } + } + + if (i === sign) { + // Integer is expected + return 0; + } + + if (!utils.cmpChar(token.value, i, N)) { + return 0; + } + + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + if (i + 1 === token.value.length) { + return consumeB(getNextToken(++offset), offset, getNextToken); + } else { + if (token.value.charCodeAt(i + 1) !== HYPHENMINUS) { + return 0; + } + + // <ndash-dimension> <signless-integer> + if (i + 2 === token.value.length) { + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + } + // <ndashdigit-dimension> + else { + return checkInteger(token, i + 2, DISALLOW_SIGN, offset); + } + } + } + + return 0; +} + +module.exports = anPlusB; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs new file mode 100644 index 0000000..9b9f615 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs @@ -0,0 +1,12 @@ +'use strict'; + +// https://drafts.csswg.org/css-cascade-5/ +const cssWideKeywords = [ + 'initial', + 'inherit', + 'unset', + 'revert', + 'revert-layer' +]; + +exports.cssWideKeywords = cssWideKeywords; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs new file mode 100644 index 0000000..ce167bb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs @@ -0,0 +1,149 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const types = require('../tokenizer/types.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?) +const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u) + +function isDelim(token, code) { + return token !== null && token.type === types.Delim && token.value.charCodeAt(0) === code; +} + +function startsWith(token, code) { + return token.value.charCodeAt(0) === code; +} + +function hexSequence(token, offset, allowDash) { + let hexlen = 0; + + for (let pos = offset; pos < token.value.length; pos++) { + const code = token.value.charCodeAt(pos); + + if (code === HYPHENMINUS && allowDash && hexlen !== 0) { + hexSequence(token, offset + hexlen + 1, false); + return 6; // dissallow following question marks + } + + if (!charCodeDefinitions.isHexDigit(code)) { + return 0; // not a hex digit + } + + if (++hexlen > 6) { + return 0; // too many hex digits + } } + + return hexlen; +} + +function withQuestionMarkSequence(consumed, length, getNextToken) { + if (!consumed) { + return 0; // nothing consumed + } + + while (isDelim(getNextToken(length), QUESTIONMARK)) { + if (++consumed > 6) { + return 0; // too many question marks + } + + length++; + } + + return length; +} + +// https://drafts.csswg.org/css-syntax/#urange +// Informally, the <urange> production has three forms: +// U+0001 +// Defines a range consisting of a single code point, in this case the code point "1". +// U+0001-00ff +// Defines a range of codepoints between the first and the second value, in this case +// the range between "1" and "ff" (255 in decimal) inclusive. +// U+00?? +// Defines a range of codepoints where the "?" characters range over all hex digits, +// in this case defining the same as the value U+0000-00ff. +// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit). +// +// <urange> = +// u '+' <ident-token> '?'* | +// u <dimension-token> '?'* | +// u <number-token> '?'* | +// u <number-token> <dimension-token> | +// u <number-token> <number-token> | +// u '+' '?'+ +function urange(token, getNextToken) { + let length = 0; + + // should start with `u` or `U` + if (token === null || token.type !== types.Ident || !utils.cmpChar(token.value, 0, U)) { + return 0; + } + + token = getNextToken(++length); + if (token === null) { + return 0; + } + + // u '+' <ident-token> '?'* + // u '+' '?'+ + if (isDelim(token, PLUSSIGN)) { + token = getNextToken(++length); + if (token === null) { + return 0; + } + + if (token.type === types.Ident) { + // u '+' <ident-token> '?'* + return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken); + } + + if (isDelim(token, QUESTIONMARK)) { + // u '+' '?'+ + return withQuestionMarkSequence(1, ++length, getNextToken); + } + + // Hex digit or question mark is expected + return 0; + } + + // u <number-token> '?'* + // u <number-token> <dimension-token> + // u <number-token> <number-token> + if (token.type === types.Number) { + const consumedHexLength = hexSequence(token, 1, true); + if (consumedHexLength === 0) { + return 0; + } + + token = getNextToken(++length); + if (token === null) { + // u <number-token> <eof> + return length; + } + + if (token.type === types.Dimension || token.type === types.Number) { + // u <number-token> <dimension-token> + // u <number-token> <number-token> + if (!startsWith(token, HYPHENMINUS) || !hexSequence(token, 1, false)) { + return 0; + } + + return length + 1; + } + + // u <number-token> '?'* + return withQuestionMarkSequence(consumedHexLength, length, getNextToken); + } + + // u <dimension-token> '?'* + if (token.type === types.Dimension) { + return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken); + } + + return 0; +} + +module.exports = urange; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic.cjs new file mode 100644 index 0000000..8489911 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic.cjs @@ -0,0 +1,589 @@ +'use strict'; + +const genericConst = require('./generic-const.cjs'); +const genericAnPlusB = require('./generic-an-plus-b.cjs'); +const genericUrange = require('./generic-urange.cjs'); +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const types = require('../tokenizer/types.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc(']; +const balancePair = new Map([ + [types.Function, types.RightParenthesis], + [types.LeftParenthesis, types.RightParenthesis], + [types.LeftSquareBracket, types.RightSquareBracket], + [types.LeftCurlyBracket, types.RightCurlyBracket] +]); + +// safe char code getter +function charCodeAt(str, index) { + return index < str.length ? str.charCodeAt(index) : 0; +} + +function eqStr(actual, expected) { + return utils.cmpStr(actual, 0, actual.length, expected); +} + +function eqStrAny(actual, expected) { + for (let i = 0; i < expected.length; i++) { + if (eqStr(actual, expected[i])) { + return true; + } + } + + return false; +} + +// IE postfix hack, i.e. 123\0 or 123px\9 +function isPostfixIeHack(str, offset) { + if (offset !== str.length - 2) { + return false; + } + + return ( + charCodeAt(str, offset) === 0x005C && // U+005C REVERSE SOLIDUS (\) + charCodeDefinitions.isDigit(charCodeAt(str, offset + 1)) + ); +} + +function outOfRange(opts, value, numEnd) { + if (opts && opts.type === 'Range') { + const num = Number( + numEnd !== undefined && numEnd !== value.length + ? value.substr(0, numEnd) + : value + ); + + if (isNaN(num)) { + return true; + } + + // FIXME: when opts.min is a string it's a dimension, skip a range validation + // for now since it requires a type covertation which is not implmented yet + if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') { + return true; + } + + // FIXME: when opts.max is a string it's a dimension, skip a range validation + // for now since it requires a type covertation which is not implmented yet + if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') { + return true; + } + } + + return false; +} + +function consumeFunction(token, getNextToken) { + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // balanced token consuming + scan: + do { + switch (token.type) { + case types.RightCurlyBracket: + case types.RightParenthesis: + case types.RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + + if (balanceStash.length === 0) { + length++; + break scan; + } + + break; + + case types.Function: + case types.LeftParenthesis: + case types.LeftSquareBracket: + case types.LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// TODO: implement +// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed +// https://drafts.csswg.org/css-values/#calc-notation +function calc(next) { + return function(token, getNextToken, opts) { + if (token === null) { + return 0; + } + + if (token.type === types.Function && eqStrAny(token.value, calcFunctionNames)) { + return consumeFunction(token, getNextToken); + } + + return next(token, getNextToken, opts); + }; +} + +function tokenType(expectedTokenType) { + return function(token) { + if (token === null || token.type !== expectedTokenType) { + return 0; + } + + return 1; + }; +} + +// ========================= +// Complex types +// + +// https://drafts.csswg.org/css-values-4/#custom-idents +// 4.2. Author-defined Identifiers: the <custom-ident> type +// Some properties accept arbitrary author-defined identifiers as a component value. +// This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier +// that would not be misinterpreted as a pre-defined keyword in that property’s value definition. +// +// See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident +function customIdent(token) { + if (token === null || token.type !== types.Ident) { + return 0; + } + + const name = token.value.toLowerCase(); + + // The CSS-wide keywords are not valid <custom-ident>s + if (eqStrAny(name, genericConst.cssWideKeywords)) { + return 0; + } + + // The default keyword is reserved and is also not a valid <custom-ident> + if (eqStr(name, 'default')) { + return 0; + } + + // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident) + // Specifications using <custom-ident> must specify clearly what other keywords + // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords + // in that property’s value definition are excluded. Excluded keywords are excluded + // in all ASCII case permutations. + + return 1; +} + +// https://drafts.csswg.org/css-values-4/#dashed-idents +// The <dashed-ident> production is a <custom-ident>, with all the case-sensitivity that implies, +// with the additional restriction that it must start with two dashes (U+002D HYPHEN-MINUS). +function dashedIdent(token) { + if (token === null || token.type !== types.Ident) { + return 0; + } + + // ... must start with two dashes (U+002D HYPHEN-MINUS) + if (charCodeAt(token.value, 0) !== 0x002D || charCodeAt(token.value, 1) !== 0x002D) { + return 0; + } + + return 1; +} + +// https://drafts.csswg.org/css-variables/#typedef-custom-property-name +// A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo. +// The <custom-property-name> production corresponds to this: it’s defined as any <dashed-ident> +// (a valid identifier that starts with two dashes), except -- itself, which is reserved for future use by CSS. +function customPropertyName(token) { + // ... it’s defined as any <dashed-ident> + if (!dashedIdent(token)) { + return 0; + } + + // ... except -- itself, which is reserved for future use by CSS + if (token.value === '--') { + return 0; + } + + return 1; +} + +// https://drafts.csswg.org/css-color-4/#hex-notation +// The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits. +// In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or +// letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00). +function hexColor(token) { + if (token === null || token.type !== types.Hash) { + return 0; + } + + const length = token.value.length; + + // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9) + if (length !== 4 && length !== 5 && length !== 7 && length !== 9) { + return 0; + } + + for (let i = 1; i < length; i++) { + if (!charCodeDefinitions.isHexDigit(charCodeAt(token.value, i))) { + return 0; + } + } + + return 1; +} + +function idSelector(token) { + if (token === null || token.type !== types.Hash) { + return 0; + } + + if (!charCodeDefinitions.isIdentifierStart(charCodeAt(token.value, 1), charCodeAt(token.value, 2), charCodeAt(token.value, 3))) { + return 0; + } + + return 1; +} + +// https://drafts.csswg.org/css-syntax/#any-value +// It represents the entirety of what a valid declaration can have as its value. +function declarationValue(token, getNextToken) { + if (!token) { + return 0; + } + + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // The <declaration-value> production matches any sequence of one or more tokens, + // so long as the sequence does not contain ... + scan: + do { + switch (token.type) { + // ... <bad-string-token>, <bad-url-token>, + case types.BadString: + case types.BadUrl: + break scan; + + // ... unmatched <)-token>, <]-token>, or <}-token>, + case types.RightCurlyBracket: + case types.RightParenthesis: + case types.RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + break; + + // ... or top-level <semicolon-token> tokens + case types.Semicolon: + if (balanceCloseType === 0) { + break scan; + } + + break; + + // ... or <delim-token> tokens with a value of "!" + case types.Delim: + if (balanceCloseType === 0 && token.value === '!') { + break scan; + } + + break; + + case types.Function: + case types.LeftParenthesis: + case types.LeftSquareBracket: + case types.LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// https://drafts.csswg.org/css-syntax/#any-value +// The <any-value> production is identical to <declaration-value>, but also +// allows top-level <semicolon-token> tokens and <delim-token> tokens +// with a value of "!". It represents the entirety of what valid CSS can be in any context. +function anyValue(token, getNextToken) { + if (!token) { + return 0; + } + + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // The <any-value> production matches any sequence of one or more tokens, + // so long as the sequence ... + scan: + do { + switch (token.type) { + // ... does not contain <bad-string-token>, <bad-url-token>, + case types.BadString: + case types.BadUrl: + break scan; + + // ... unmatched <)-token>, <]-token>, or <}-token>, + case types.RightCurlyBracket: + case types.RightParenthesis: + case types.RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + break; + + case types.Function: + case types.LeftParenthesis: + case types.LeftSquareBracket: + case types.LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// ========================= +// Dimensions +// + +function dimension(type) { + if (type) { + type = new Set(type); + } + + return function(token, getNextToken, opts) { + if (token === null || token.type !== types.Dimension) { + return 0; + } + + const numberEnd = utils.consumeNumber(token.value, 0); + + // check unit + if (type !== null) { + // check for IE postfix hack, i.e. 123px\0 or 123px\9 + const reverseSolidusOffset = token.value.indexOf('\\', numberEnd); + const unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset) + ? token.value.substr(numberEnd) + : token.value.substring(numberEnd, reverseSolidusOffset); + + if (type.has(unit.toLowerCase()) === false) { + return 0; + } + } + + // check range if specified + if (outOfRange(opts, token.value, numberEnd)) { + return 0; + } + + return 1; + }; +} + +// ========================= +// Percentage +// + +// §5.5. Percentages: the <percentage> type +// https://drafts.csswg.org/css-values-4/#percentages +function percentage(token, getNextToken, opts) { + // ... corresponds to the <percentage-token> production + if (token === null || token.type !== types.Percentage) { + return 0; + } + + // check range if specified + if (outOfRange(opts, token.value, token.value.length - 1)) { + return 0; + } + + return 1; +} + +// ========================= +// Numeric +// + +// https://drafts.csswg.org/css-values-4/#numbers +// The value <zero> represents a literal number with the value 0. Expressions that merely +// evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>; +// only literal <number-token>s do. +function zero(next) { + if (typeof next !== 'function') { + next = function() { + return 0; + }; + } + + return function(token, getNextToken, opts) { + if (token !== null && token.type === types.Number) { + if (Number(token.value) === 0) { + return 1; + } + } + + return next(token, getNextToken, opts); + }; +} + +// § 5.3. Real Numbers: the <number> type +// https://drafts.csswg.org/css-values-4/#numbers +// Number values are denoted by <number>, and represent real numbers, possibly with a fractional component. +// ... It corresponds to the <number-token> production +function number(token, getNextToken, opts) { + if (token === null) { + return 0; + } + + const numberEnd = utils.consumeNumber(token.value, 0); + const isNumber = numberEnd === token.value.length; + if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) { + return 0; + } + + // check range if specified + if (outOfRange(opts, token.value, numberEnd)) { + return 0; + } + + return 1; +} + +// §5.2. Integers: the <integer> type +// https://drafts.csswg.org/css-values-4/#integers +function integer(token, getNextToken, opts) { + // ... corresponds to a subset of the <number-token> production + if (token === null || token.type !== types.Number) { + return 0; + } + + // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign. + let i = charCodeAt(token.value, 0) === 0x002B || // U+002B PLUS SIGN (+) + charCodeAt(token.value, 0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-) + + // When written literally, an integer is one or more decimal digits 0 through 9 ... + for (; i < token.value.length; i++) { + if (!charCodeDefinitions.isDigit(charCodeAt(token.value, i))) { + return 0; + } + } + + // check range if specified + if (outOfRange(opts, token.value, i)) { + return 0; + } + + return 1; +} + +// token types +const tokenTypes = { + 'ident-token': tokenType(types.Ident), + 'function-token': tokenType(types.Function), + 'at-keyword-token': tokenType(types.AtKeyword), + 'hash-token': tokenType(types.Hash), + 'string-token': tokenType(types.String), + 'bad-string-token': tokenType(types.BadString), + 'url-token': tokenType(types.Url), + 'bad-url-token': tokenType(types.BadUrl), + 'delim-token': tokenType(types.Delim), + 'number-token': tokenType(types.Number), + 'percentage-token': tokenType(types.Percentage), + 'dimension-token': tokenType(types.Dimension), + 'whitespace-token': tokenType(types.WhiteSpace), + 'CDO-token': tokenType(types.CDO), + 'CDC-token': tokenType(types.CDC), + 'colon-token': tokenType(types.Colon), + 'semicolon-token': tokenType(types.Semicolon), + 'comma-token': tokenType(types.Comma), + '[-token': tokenType(types.LeftSquareBracket), + ']-token': tokenType(types.RightSquareBracket), + '(-token': tokenType(types.LeftParenthesis), + ')-token': tokenType(types.RightParenthesis), + '{-token': tokenType(types.LeftCurlyBracket), + '}-token': tokenType(types.RightCurlyBracket) +}; + +// token production types +const productionTypes = { + // token type aliases + 'string': tokenType(types.String), + 'ident': tokenType(types.Ident), + + // percentage + 'percentage': calc(percentage), + + // numeric + 'zero': zero(), + 'number': calc(number), + 'integer': calc(integer), + + // complex types + 'custom-ident': customIdent, + 'dashed-ident': dashedIdent, + 'custom-property-name': customPropertyName, + 'hex-color': hexColor, + 'id-selector': idSelector, // element( <id-selector> ) + 'an-plus-b': genericAnPlusB, + 'urange': genericUrange, + 'declaration-value': declarationValue, + 'any-value': anyValue +}; + +// dimensions types depend on units set +function createDemensionTypes(units) { + const { + angle, + decibel, + frequency, + flex, + length, + resolution, + semitones, + time + } = units || {}; + + return { + 'dimension': calc(dimension(null)), + 'angle': calc(dimension(angle)), + 'decibel': calc(dimension(decibel)), + 'frequency': calc(dimension(frequency)), + 'flex': calc(dimension(flex)), + 'length': calc(zero(dimension(length))), + 'resolution': calc(dimension(resolution)), + 'semitones': calc(dimension(semitones)), + 'time': calc(dimension(time)) + }; +} + +function createGenericTypes(units) { + return { + ...tokenTypes, + ...productionTypes, + ...createDemensionTypes(units) + }; +} + +exports.createDemensionTypes = createDemensionTypes; +exports.createGenericTypes = createGenericTypes; +exports.productionTypes = productionTypes; +exports.tokenTypes = tokenTypes; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/index.cjs b/vanilla/node_modules/css-tree/cjs/lexer/index.cjs new file mode 100644 index 0000000..2e3633e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/index.cjs @@ -0,0 +1,7 @@ +'use strict'; + +const Lexer = require('./Lexer.cjs'); + + + +exports.Lexer = Lexer.Lexer; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/match-graph.cjs b/vanilla/node_modules/css-tree/cjs/lexer/match-graph.cjs new file mode 100644 index 0000000..9f9675e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/match-graph.cjs @@ -0,0 +1,530 @@ +'use strict'; + +const parse = require('../definition-syntax/parse.cjs'); + +const MATCH = { type: 'Match' }; +const MISMATCH = { type: 'Mismatch' }; +const DISALLOW_EMPTY = { type: 'DisallowEmpty' }; + +const LEFTPARENTHESIS = 40; // ( +const RIGHTPARENTHESIS = 41; // ) + +function createCondition(match, thenBranch, elseBranch) { + // reduce node count + if (thenBranch === MATCH && elseBranch === MISMATCH) { + return match; + } + + if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) { + return match; + } + + if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) { + thenBranch = match.then; + match = match.match; + } + + return { + type: 'If', + match, + then: thenBranch, + else: elseBranch + }; +} + +function isFunctionType(name) { + return ( + name.length > 2 && + name.charCodeAt(name.length - 2) === LEFTPARENTHESIS && + name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS + ); +} + +function isEnumCapatible(term) { + return ( + term.type === 'Keyword' || + term.type === 'AtKeyword' || + term.type === 'Function' || + term.type === 'Type' && isFunctionType(term.name) + ); +} + +function groupNode(terms, combinator = ' ', explicit = false) { + return { + type: 'Group', + terms, + combinator, + disallowEmpty: false, + explicit + }; +} + +function replaceTypeInGraph(node, replacements, visited = new Set()) { + if (!visited.has(node)) { + visited.add(node); + + switch (node.type) { + case 'If': + node.match = replaceTypeInGraph(node.match, replacements, visited); + node.then = replaceTypeInGraph(node.then, replacements, visited); + node.else = replaceTypeInGraph(node.else, replacements, visited); + break; + + case 'Type': + return replacements[node.name] || node; + } + } + + return node; +} + +function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) { + switch (combinator) { + case ' ': { + // Juxtaposing components means that all of them must occur, in the given order. + // + // a b c + // = + // match a + // then match b + // then match c + // then MATCH + // else MISMATCH + // else MISMATCH + // else MISMATCH + let result = MATCH; + + for (let i = terms.length - 1; i >= 0; i--) { + const term = terms[i]; + + result = createCondition( + term, + result, + MISMATCH + ); + } + return result; + } + + case '|': { + // A bar (|) separates two or more alternatives: exactly one of them must occur. + // + // a | b | c + // = + // match a + // then MATCH + // else match b + // then MATCH + // else match c + // then MATCH + // else MISMATCH + + let result = MISMATCH; + let map = null; + + for (let i = terms.length - 1; i >= 0; i--) { + let term = terms[i]; + + // reduce sequence of keywords into a Enum + if (isEnumCapatible(term)) { + if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) { + map = Object.create(null); + result = createCondition( + { + type: 'Enum', + map + }, + MATCH, + result + ); + } + + if (map !== null) { + const key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase(); + if (key in map === false) { + map[key] = term; + continue; + } + } + } + + map = null; + + // create a new conditonal node + result = createCondition( + term, + MATCH, + result + ); + } + return result; + } + + case '&&': { + // A double ampersand (&&) separates two or more components, + // all of which must occur, in any order. + + // Use MatchOnce for groups with a large number of terms, + // since &&-groups produces at least N!-node trees + if (terms.length > 5) { + return { + type: 'MatchOnce', + terms, + all: true + }; + } + + // Use a combination tree for groups with small number of terms + // + // a && b && c + // = + // match a + // then [b && c] + // else match b + // then [a && c] + // else match c + // then [a && b] + // else MISMATCH + // + // a && b + // = + // match a + // then match b + // then MATCH + // else MISMATCH + // else match b + // then match a + // then MATCH + // else MISMATCH + // else MISMATCH + let result = MISMATCH; + + for (let i = terms.length - 1; i >= 0; i--) { + const term = terms[i]; + let thenClause; + + if (terms.length > 1) { + thenClause = buildGroupMatchGraph( + combinator, + terms.filter(function(newGroupTerm) { + return newGroupTerm !== term; + }), + false + ); + } else { + thenClause = MATCH; + } + + result = createCondition( + term, + thenClause, + result + ); + } + return result; + } + + case '||': { + // A double bar (||) separates two or more options: + // one or more of them must occur, in any order. + + // Use MatchOnce for groups with a large number of terms, + // since ||-groups produces at least N!-node trees + if (terms.length > 5) { + return { + type: 'MatchOnce', + terms, + all: false + }; + } + + // Use a combination tree for groups with small number of terms + // + // a || b || c + // = + // match a + // then [b || c] + // else match b + // then [a || c] + // else match c + // then [a || b] + // else MISMATCH + // + // a || b + // = + // match a + // then match b + // then MATCH + // else MATCH + // else match b + // then match a + // then MATCH + // else MATCH + // else MISMATCH + let result = atLeastOneTermMatched ? MATCH : MISMATCH; + + for (let i = terms.length - 1; i >= 0; i--) { + const term = terms[i]; + let thenClause; + + if (terms.length > 1) { + thenClause = buildGroupMatchGraph( + combinator, + terms.filter(function(newGroupTerm) { + return newGroupTerm !== term; + }), + true + ); + } else { + thenClause = MATCH; + } + + result = createCondition( + term, + thenClause, + result + ); + } + return result; + } + } +} + +function buildMultiplierMatchGraph(node) { + let result = MATCH; + let matchTerm = buildMatchGraphInternal(node.term); + + if (node.max === 0) { + // disable repeating of empty match to prevent infinite loop + matchTerm = createCondition( + matchTerm, + DISALLOW_EMPTY, + MISMATCH + ); + + // an occurrence count is not limited, make a cycle; + // to collect more terms on each following matching mismatch + result = createCondition( + matchTerm, + null, // will be a loop + MISMATCH + ); + + result.then = createCondition( + MATCH, + MATCH, + result // make a loop + ); + + if (node.comma) { + result.then.else = createCondition( + { type: 'Comma', syntax: node }, + result, + MISMATCH + ); + } + } else { + // create a match node chain for [min .. max] interval with optional matches + for (let i = node.min || 1; i <= node.max; i++) { + if (node.comma && result !== MATCH) { + result = createCondition( + { type: 'Comma', syntax: node }, + result, + MISMATCH + ); + } + + result = createCondition( + matchTerm, + createCondition( + MATCH, + MATCH, + result + ), + MISMATCH + ); + } + } + + if (node.min === 0) { + // allow zero match + result = createCondition( + MATCH, + MATCH, + result + ); + } else { + // create a match node chain to collect [0 ... min - 1] required matches + for (let i = 0; i < node.min - 1; i++) { + if (node.comma && result !== MATCH) { + result = createCondition( + { type: 'Comma', syntax: node }, + result, + MISMATCH + ); + } + + result = createCondition( + matchTerm, + result, + MISMATCH + ); + } + } + + return result; +} + +function buildMatchGraphInternal(node) { + if (typeof node === 'function') { + return { + type: 'Generic', + fn: node + }; + } + + switch (node.type) { + case 'Group': { + let result = buildGroupMatchGraph( + node.combinator, + node.terms.map(buildMatchGraphInternal), + false + ); + + if (node.disallowEmpty) { + result = createCondition( + result, + DISALLOW_EMPTY, + MISMATCH + ); + } + + return result; + } + + case 'Multiplier': + return buildMultiplierMatchGraph(node); + + // https://drafts.csswg.org/css-values-5/#boolean + case 'Boolean': { + const term = buildMatchGraphInternal(node.term); + // <boolean-expr[ <test> ]> = not <boolean-expr-group> | <boolean-expr-group> [ [ and <boolean-expr-group> ]* | [ or <boolean-expr-group> ]* ] + const matchNode = buildMatchGraphInternal(groupNode([ + groupNode([ + { type: 'Keyword', name: 'not' }, + { type: 'Type', name: '!boolean-group' } + ]), + groupNode([ + { type: 'Type', name: '!boolean-group' }, + groupNode([ + { type: 'Multiplier', comma: false, min: 0, max: 0, term: groupNode([ + { type: 'Keyword', name: 'and' }, + { type: 'Type', name: '!boolean-group' } + ]) }, + { type: 'Multiplier', comma: false, min: 0, max: 0, term: groupNode([ + { type: 'Keyword', name: 'or' }, + { type: 'Type', name: '!boolean-group' } + ]) } + ], '|') + ]) + ], '|')); + // <boolean-expr-group> = <test> | ( <boolean-expr[ <test> ]> ) | <general-enclosed> + const booleanGroup = buildMatchGraphInternal( + groupNode([ + { type: 'Type', name: '!term' }, + groupNode([ + { type: 'Token', value: '(' }, + { type: 'Type', name: '!self' }, + { type: 'Token', value: ')' } + ]), + { type: 'Type', name: 'general-enclosed' } + ], '|') + ); + + replaceTypeInGraph(booleanGroup, { '!term': term, '!self': matchNode }); + replaceTypeInGraph(matchNode, { '!boolean-group': booleanGroup }); + + return matchNode; + } + + case 'Type': + case 'Property': + return { + type: node.type, + name: node.name, + syntax: node + }; + + case 'Keyword': + return { + type: node.type, + name: node.name.toLowerCase(), + syntax: node + }; + + case 'AtKeyword': + return { + type: node.type, + name: '@' + node.name.toLowerCase(), + syntax: node + }; + + case 'Function': + return { + type: node.type, + name: node.name.toLowerCase() + '(', + syntax: node + }; + + case 'String': + // convert a one char length String to a Token + if (node.value.length === 3) { + return { + type: 'Token', + value: node.value.charAt(1), + syntax: node + }; + } + + // otherwise use it as is + return { + type: node.type, + value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''), + syntax: node + }; + + case 'Token': + return { + type: node.type, + value: node.value, + syntax: node + }; + + case 'Comma': + return { + type: node.type, + syntax: node + }; + + default: + throw new Error('Unknown node type:', node.type); + } +} + +function buildMatchGraph(syntaxTree, ref) { + if (typeof syntaxTree === 'string') { + syntaxTree = parse.parse(syntaxTree); + } + + return { + type: 'MatchGraph', + match: buildMatchGraphInternal(syntaxTree), + syntax: ref || null, + source: syntaxTree + }; +} + +exports.DISALLOW_EMPTY = DISALLOW_EMPTY; +exports.MATCH = MATCH; +exports.MISMATCH = MISMATCH; +exports.buildMatchGraph = buildMatchGraph; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/match.cjs b/vanilla/node_modules/css-tree/cjs/lexer/match.cjs new file mode 100644 index 0000000..86f44ae --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/match.cjs @@ -0,0 +1,632 @@ +'use strict'; + +const matchGraph = require('./match-graph.cjs'); +const types = require('../tokenizer/types.cjs'); + +const { hasOwnProperty } = Object.prototype; +const STUB = 0; +const TOKEN = 1; +const OPEN_SYNTAX = 2; +const CLOSE_SYNTAX = 3; + +const EXIT_REASON_MATCH = 'Match'; +const EXIT_REASON_MISMATCH = 'Mismatch'; +const EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)'; + +const ITERATION_LIMIT = 15000; + +function reverseList(list) { + let prev = null; + let next = null; + let item = list; + + while (item !== null) { + next = item.prev; + item.prev = prev; + prev = item; + item = next; + } + + return prev; +} + +function areStringsEqualCaseInsensitive(testStr, referenceStr) { + if (testStr.length !== referenceStr.length) { + return false; + } + + for (let i = 0; i < testStr.length; i++) { + const referenceCode = referenceStr.charCodeAt(i); + let testCode = testStr.charCodeAt(i); + + // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z). + if (testCode >= 0x0041 && testCode <= 0x005A) { + testCode = testCode | 32; + } + + if (testCode !== referenceCode) { + return false; + } + } + + return true; +} + +function isContextEdgeDelim(token) { + if (token.type !== types.Delim) { + return false; + } + + // Fix matching for unicode-range: U+30??, U+FF00-FF9F + // Probably we need to check out previous match instead + return token.value !== '?'; +} + +function isCommaContextStart(token) { + if (token === null) { + return true; + } + + return ( + token.type === types.Comma || + token.type === types.Function || + token.type === types.LeftParenthesis || + token.type === types.LeftSquareBracket || + token.type === types.LeftCurlyBracket || + isContextEdgeDelim(token) + ); +} + +function isCommaContextEnd(token) { + if (token === null) { + return true; + } + + return ( + token.type === types.RightParenthesis || + token.type === types.RightSquareBracket || + token.type === types.RightCurlyBracket || + (token.type === types.Delim && token.value === '/') + ); +} + +function internalMatch(tokens, state, syntaxes) { + function moveToNextToken() { + do { + tokenIndex++; + token = tokenIndex < tokens.length ? tokens[tokenIndex] : null; + } while (token !== null && (token.type === types.WhiteSpace || token.type === types.Comment)); + } + + function getNextToken(offset) { + const nextIndex = tokenIndex + offset; + + return nextIndex < tokens.length ? tokens[nextIndex] : null; + } + + function stateSnapshotFromSyntax(nextState, prev) { + return { + nextState, + matchStack, + syntaxStack, + thenStack, + tokenIndex, + prev + }; + } + + function pushThenStack(nextState) { + thenStack = { + nextState, + matchStack, + syntaxStack, + prev: thenStack + }; + } + + function pushElseStack(nextState) { + elseStack = stateSnapshotFromSyntax(nextState, elseStack); + } + + function addTokenToMatch() { + matchStack = { + type: TOKEN, + syntax: state.syntax, + token, + prev: matchStack + }; + + moveToNextToken(); + syntaxStash = null; + + if (tokenIndex > longestMatch) { + longestMatch = tokenIndex; + } + } + + function openSyntax() { + syntaxStack = { + syntax: state.syntax, + opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null, + prev: syntaxStack + }; + + matchStack = { + type: OPEN_SYNTAX, + syntax: state.syntax, + token: matchStack.token, + prev: matchStack + }; + } + + function closeSyntax() { + if (matchStack.type === OPEN_SYNTAX) { + matchStack = matchStack.prev; + } else { + matchStack = { + type: CLOSE_SYNTAX, + syntax: syntaxStack.syntax, + token: matchStack.token, + prev: matchStack + }; + } + + syntaxStack = syntaxStack.prev; + } + + let syntaxStack = null; + let thenStack = null; + let elseStack = null; + + // null – stashing allowed, nothing stashed + // false – stashing disabled, nothing stashed + // anithing else – fail stashable syntaxes, some syntax stashed + let syntaxStash = null; + + let iterationCount = 0; // count iterations and prevent infinite loop + let exitReason = null; + + let token = null; + let tokenIndex = -1; + let longestMatch = 0; + let matchStack = { + type: STUB, + syntax: null, + token: null, + prev: null + }; + + moveToNextToken(); + + while (exitReason === null && ++iterationCount < ITERATION_LIMIT) { + // function mapList(list, fn) { + // const result = []; + // while (list) { + // result.unshift(fn(list)); + // list = list.prev; + // } + // return result; + // } + // console.log('--\n', + // '#' + iterationCount, + // require('util').inspect({ + // match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null), + // token: token && token.value, + // tokenIndex, + // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '') + // }, { depth: null }) + // ); + switch (state.type) { + case 'Match': + if (thenStack === null) { + // turn to MISMATCH when some tokens left unmatched + if (token !== null) { + // doesn't mismatch if just one token left and it's an IE hack + if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) { + state = matchGraph.MISMATCH; + break; + } + } + + // break the main loop, return a result - MATCH + exitReason = EXIT_REASON_MATCH; + break; + } + + // go to next syntax (`then` branch) + state = thenStack.nextState; + + // check match is not empty + if (state === matchGraph.DISALLOW_EMPTY) { + if (thenStack.matchStack === matchStack) { + state = matchGraph.MISMATCH; + break; + } else { + state = matchGraph.MATCH; + } + } + + // close syntax if needed + while (thenStack.syntaxStack !== syntaxStack) { + closeSyntax(); + } + + // pop stack + thenStack = thenStack.prev; + break; + + case 'Mismatch': + // when some syntax is stashed + if (syntaxStash !== null && syntaxStash !== false) { + // there is no else branches or a branch reduce match stack + if (elseStack === null || tokenIndex > elseStack.tokenIndex) { + // restore state from the stash + elseStack = syntaxStash; + syntaxStash = false; // disable stashing + } + } else if (elseStack === null) { + // no else branches -> break the main loop + // return a result - MISMATCH + exitReason = EXIT_REASON_MISMATCH; + break; + } + + // go to next syntax (`else` branch) + state = elseStack.nextState; + + // restore all the rest stack states + thenStack = elseStack.thenStack; + syntaxStack = elseStack.syntaxStack; + matchStack = elseStack.matchStack; + tokenIndex = elseStack.tokenIndex; + token = tokenIndex < tokens.length ? tokens[tokenIndex] : null; + + // pop stack + elseStack = elseStack.prev; + break; + + case 'MatchGraph': + state = state.match; + break; + + case 'If': + // IMPORTANT: else stack push must go first, + // since it stores the state of thenStack before changes + if (state.else !== matchGraph.MISMATCH) { + pushElseStack(state.else); + } + + if (state.then !== matchGraph.MATCH) { + pushThenStack(state.then); + } + + state = state.match; + break; + + case 'MatchOnce': + state = { + type: 'MatchOnceBuffer', + syntax: state, + index: 0, + mask: 0 + }; + break; + + case 'MatchOnceBuffer': { + const terms = state.syntax.terms; + + if (state.index === terms.length) { + // no matches at all or it's required all terms to be matched + if (state.mask === 0 || state.syntax.all) { + state = matchGraph.MISMATCH; + break; + } + + // a partial match is ok + state = matchGraph.MATCH; + break; + } + + // all terms are matched + if (state.mask === (1 << terms.length) - 1) { + state = matchGraph.MATCH; + break; + } + + for (; state.index < terms.length; state.index++) { + const matchFlag = 1 << state.index; + + if ((state.mask & matchFlag) === 0) { + // IMPORTANT: else stack push must go first, + // since it stores the state of thenStack before changes + pushElseStack(state); + pushThenStack({ + type: 'AddMatchOnce', + syntax: state.syntax, + mask: state.mask | matchFlag + }); + + // match + state = terms[state.index++]; + break; + } + } + break; + } + + case 'AddMatchOnce': + state = { + type: 'MatchOnceBuffer', + syntax: state.syntax, + index: 0, + mask: state.mask + }; + break; + + case 'Enum': + if (token !== null) { + let name = token.value.toLowerCase(); + + // drop \0 and \9 hack from keyword name + if (name.indexOf('\\') !== -1) { + name = name.replace(/\\[09].*$/, ''); + } + + if (hasOwnProperty.call(state.map, name)) { + state = state.map[name]; + break; + } + } + + state = matchGraph.MISMATCH; + break; + + case 'Generic': { + const opts = syntaxStack !== null ? syntaxStack.opts : null; + const lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts)); + + if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) { + while (tokenIndex < lastTokenIndex) { + addTokenToMatch(); + } + + state = matchGraph.MATCH; + } else { + state = matchGraph.MISMATCH; + } + + break; + } + + case 'Type': + case 'Property': { + const syntaxDict = state.type === 'Type' ? 'types' : 'properties'; + const dictSyntax = hasOwnProperty.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null; + + if (!dictSyntax || !dictSyntax.match) { + throw new Error( + 'Bad syntax reference: ' + + (state.type === 'Type' + ? '<' + state.name + '>' + : '<\'' + state.name + '\'>') + ); + } + + // stash a syntax for types with low priority + if (syntaxStash !== false && token !== null && state.type === 'Type') { + const lowPriorityMatching = + // https://drafts.csswg.org/css-values-4/#custom-idents + // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production + // can only claim the keyword if no other unfulfilled production can claim it. + (state.name === 'custom-ident' && token.type === types.Ident) || + + // https://drafts.csswg.org/css-values-4/#lengths + // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height), + // it must parse as a <number> + (state.name === 'length' && token.value === '0'); + + if (lowPriorityMatching) { + if (syntaxStash === null) { + syntaxStash = stateSnapshotFromSyntax(state, elseStack); + } + + state = matchGraph.MISMATCH; + break; + } + } + + openSyntax(); + state = dictSyntax.matchRef || dictSyntax.match; + break; + } + + case 'Keyword': { + const name = state.name; + + if (token !== null) { + let keywordName = token.value; + + // drop \0 and \9 hack from keyword name + if (keywordName.indexOf('\\') !== -1) { + keywordName = keywordName.replace(/\\[09].*$/, ''); + } + + if (areStringsEqualCaseInsensitive(keywordName, name)) { + addTokenToMatch(); + state = matchGraph.MATCH; + break; + } + } + + state = matchGraph.MISMATCH; + break; + } + + case 'AtKeyword': + case 'Function': + if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) { + addTokenToMatch(); + state = matchGraph.MATCH; + break; + } + + state = matchGraph.MISMATCH; + break; + + case 'Token': + if (token !== null && token.value === state.value) { + addTokenToMatch(); + state = matchGraph.MATCH; + break; + } + + state = matchGraph.MISMATCH; + break; + + case 'Comma': + if (token !== null && token.type === types.Comma) { + if (isCommaContextStart(matchStack.token)) { + state = matchGraph.MISMATCH; + } else { + addTokenToMatch(); + state = isCommaContextEnd(token) ? matchGraph.MISMATCH : matchGraph.MATCH; + } + } else { + state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? matchGraph.MATCH : matchGraph.MISMATCH; + } + + break; + + case 'String': + let string = ''; + let lastTokenIndex = tokenIndex; + + for (; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) { + string += tokens[lastTokenIndex].value; + } + + if (areStringsEqualCaseInsensitive(string, state.value)) { + while (tokenIndex < lastTokenIndex) { + addTokenToMatch(); + } + + state = matchGraph.MATCH; + } else { + state = matchGraph.MISMATCH; + } + + break; + + default: + throw new Error('Unknown node type: ' + state.type); + } + } + + switch (exitReason) { + case null: + console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations'); + exitReason = EXIT_REASON_ITERATION_LIMIT; + matchStack = null; + break; + + case EXIT_REASON_MATCH: + while (syntaxStack !== null) { + closeSyntax(); + } + break; + + default: + matchStack = null; + } + + return { + tokens, + reason: exitReason, + iterations: iterationCount, + match: matchStack, + longestMatch + }; +} + +function matchAsList(tokens, matchGraph, syntaxes) { + const matchResult = internalMatch(tokens, matchGraph, syntaxes || {}); + + if (matchResult.match !== null) { + let item = reverseList(matchResult.match).prev; + + matchResult.match = []; + + while (item !== null) { + switch (item.type) { + case OPEN_SYNTAX: + case CLOSE_SYNTAX: + matchResult.match.push({ + type: item.type, + syntax: item.syntax + }); + break; + + default: + matchResult.match.push({ + token: item.token.value, + node: item.token.node + }); + break; + } + + item = item.prev; + } + } + + return matchResult; +} + +function matchAsTree(tokens, matchGraph, syntaxes) { + const matchResult = internalMatch(tokens, matchGraph, syntaxes || {}); + + if (matchResult.match === null) { + return matchResult; + } + + let item = matchResult.match; + let host = matchResult.match = { + syntax: matchGraph.syntax || null, + match: [] + }; + const hostStack = [host]; + + // revert a list and start with 2nd item since 1st is a stub item + item = reverseList(item).prev; + + // build a tree + while (item !== null) { + switch (item.type) { + case OPEN_SYNTAX: + host.match.push(host = { + syntax: item.syntax, + match: [] + }); + hostStack.push(host); + break; + + case CLOSE_SYNTAX: + hostStack.pop(); + host = hostStack[hostStack.length - 1]; + break; + + default: + host.match.push({ + syntax: item.syntax || null, + token: item.token.value, + node: item.token.node + }); + } + + item = item.prev; + } + + return matchResult; +} + +exports.matchAsList = matchAsList; +exports.matchAsTree = matchAsTree; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/prepare-tokens.cjs b/vanilla/node_modules/css-tree/cjs/lexer/prepare-tokens.cjs new file mode 100644 index 0000000..24647a5 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/prepare-tokens.cjs @@ -0,0 +1,54 @@ +'use strict'; + +const index = require('../tokenizer/index.cjs'); + +const astToTokens = { + decorator(handlers) { + const tokens = []; + let curNode = null; + + return { + ...handlers, + node(node) { + const tmp = curNode; + curNode = node; + handlers.node.call(this, node); + curNode = tmp; + }, + emit(value, type, auto) { + tokens.push({ + type, + value, + node: auto ? null : curNode + }); + }, + result() { + return tokens; + } + }; + } +}; + +function stringToTokens(str) { + const tokens = []; + + index.tokenize(str, (type, start, end) => + tokens.push({ + type, + value: str.slice(start, end), + node: null + }) + ); + + return tokens; +} + +function prepareTokens(value, syntax) { + if (typeof value === 'string') { + return stringToTokens(value); + } + + return syntax.generate(value, astToTokens); +} + +module.exports = prepareTokens; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/search.cjs b/vanilla/node_modules/css-tree/cjs/lexer/search.cjs new file mode 100644 index 0000000..2b1e12c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/search.cjs @@ -0,0 +1,65 @@ +'use strict'; + +const List = require('../utils/List.cjs'); + +function getFirstMatchNode(matchNode) { + if ('node' in matchNode) { + return matchNode.node; + } + + return getFirstMatchNode(matchNode.match[0]); +} + +function getLastMatchNode(matchNode) { + if ('node' in matchNode) { + return matchNode.node; + } + + return getLastMatchNode(matchNode.match[matchNode.match.length - 1]); +} + +function matchFragments(lexer, ast, match, type, name) { + function findFragments(matchNode) { + if (matchNode.syntax !== null && + matchNode.syntax.type === type && + matchNode.syntax.name === name) { + const start = getFirstMatchNode(matchNode); + const end = getLastMatchNode(matchNode); + + lexer.syntax.walk(ast, function(node, item, list) { + if (node === start) { + const nodes = new List.List(); + + do { + nodes.appendData(item.data); + + if (item.data === end) { + break; + } + + item = item.next; + } while (item !== null); + + fragments.push({ + parent: list, + nodes + }); + } + }); + } + + if (Array.isArray(matchNode.match)) { + matchNode.match.forEach(findFragments); + } + } + + const fragments = []; + + if (match.matched !== null) { + findFragments(match.matched); + } + + return fragments; +} + +exports.matchFragments = matchFragments; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/structure.cjs b/vanilla/node_modules/css-tree/cjs/lexer/structure.cjs new file mode 100644 index 0000000..473b209 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/structure.cjs @@ -0,0 +1,173 @@ +'use strict'; + +const List = require('../utils/List.cjs'); + +const { hasOwnProperty } = Object.prototype; + +function isValidNumber(value) { + // Number.isInteger(value) && value >= 0 + return ( + typeof value === 'number' && + isFinite(value) && + Math.floor(value) === value && + value >= 0 + ); +} + +function isValidLocation(loc) { + return ( + Boolean(loc) && + isValidNumber(loc.offset) && + isValidNumber(loc.line) && + isValidNumber(loc.column) + ); +} + +function createNodeStructureChecker(type, fields) { + return function checkNode(node, warn) { + if (!node || node.constructor !== Object) { + return warn(node, 'Type of node should be an Object'); + } + + for (let key in node) { + let valid = true; + + if (hasOwnProperty.call(node, key) === false) { + continue; + } + + if (key === 'type') { + if (node.type !== type) { + warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`'); + } + } else if (key === 'loc') { + if (node.loc === null) { + continue; + } else if (node.loc && node.loc.constructor === Object) { + if (typeof node.loc.source !== 'string') { + key += '.source'; + } else if (!isValidLocation(node.loc.start)) { + key += '.start'; + } else if (!isValidLocation(node.loc.end)) { + key += '.end'; + } else { + continue; + } + } + + valid = false; + } else if (fields.hasOwnProperty(key)) { + valid = false; + + for (let i = 0; !valid && i < fields[key].length; i++) { + const fieldType = fields[key][i]; + + switch (fieldType) { + case String: + valid = typeof node[key] === 'string'; + break; + + case Boolean: + valid = typeof node[key] === 'boolean'; + break; + + case null: + valid = node[key] === null; + break; + + default: + if (typeof fieldType === 'string') { + valid = node[key] && node[key].type === fieldType; + } else if (Array.isArray(fieldType)) { + valid = node[key] instanceof List.List; + } + } + } + } else { + warn(node, 'Unknown field `' + key + '` for ' + type + ' node type'); + } + + if (!valid) { + warn(node, 'Bad value for `' + type + '.' + key + '`'); + } + } + + for (const key in fields) { + if (hasOwnProperty.call(fields, key) && + hasOwnProperty.call(node, key) === false) { + warn(node, 'Field `' + type + '.' + key + '` is missed'); + } + } + }; +} + +function genTypesList(fieldTypes, path) { + const docsTypes = []; + + for (let i = 0; i < fieldTypes.length; i++) { + const fieldType = fieldTypes[i]; + if (fieldType === String || fieldType === Boolean) { + docsTypes.push(fieldType.name.toLowerCase()); + } else if (fieldType === null) { + docsTypes.push('null'); + } else if (typeof fieldType === 'string') { + docsTypes.push(fieldType); + } else if (Array.isArray(fieldType)) { + docsTypes.push('List<' + (genTypesList(fieldType, path) || 'any') + '>'); // TODO: use type enum + } else { + throw new Error('Wrong value `' + fieldType + '` in `' + path + '` structure definition'); + } + } + + return docsTypes.join(' | '); +} + +function processStructure(name, nodeType) { + const structure = nodeType.structure; + const fields = { + type: String, + loc: true + }; + const docs = { + type: '"' + name + '"' + }; + + for (const key in structure) { + if (hasOwnProperty.call(structure, key) === false) { + continue; + } + + const fieldTypes = fields[key] = Array.isArray(structure[key]) + ? structure[key].slice() + : [structure[key]]; + + docs[key] = genTypesList(fieldTypes, name + '.' + key); + } + + return { + docs, + check: createNodeStructureChecker(name, fields) + }; +} + +function getStructureFromConfig(config) { + const structure = {}; + + if (config.node) { + for (const name in config.node) { + if (hasOwnProperty.call(config.node, name)) { + const nodeType = config.node[name]; + + if (nodeType.structure) { + structure[name] = processStructure(name, nodeType); + } else { + throw new Error('Missed `structure` field in `' + name + '` node type definition'); + } + } + } + } + + return structure; +} + +exports.getStructureFromConfig = getStructureFromConfig; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/trace.cjs b/vanilla/node_modules/css-tree/cjs/lexer/trace.cjs new file mode 100644 index 0000000..13753f2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/trace.cjs @@ -0,0 +1,73 @@ +'use strict'; + +function getTrace(node) { + function shouldPutToTrace(syntax) { + if (syntax === null) { + return false; + } + + return ( + syntax.type === 'Type' || + syntax.type === 'Property' || + syntax.type === 'Keyword' + ); + } + + function hasMatch(matchNode) { + if (Array.isArray(matchNode.match)) { + // use for-loop for better perfomance + for (let i = 0; i < matchNode.match.length; i++) { + if (hasMatch(matchNode.match[i])) { + if (shouldPutToTrace(matchNode.syntax)) { + result.unshift(matchNode.syntax); + } + + return true; + } + } + } else if (matchNode.node === node) { + result = shouldPutToTrace(matchNode.syntax) + ? [matchNode.syntax] + : []; + + return true; + } + + return false; + } + + let result = null; + + if (this.matched !== null) { + hasMatch(this.matched); + } + + return result; +} + +function isType(node, type) { + return testNode(this, node, match => match.type === 'Type' && match.name === type); +} + +function isProperty(node, property) { + return testNode(this, node, match => match.type === 'Property' && match.name === property); +} + +function isKeyword(node) { + return testNode(this, node, match => match.type === 'Keyword'); +} + +function testNode(match, node, fn) { + const trace = getTrace.call(match, node); + + if (trace === null) { + return false; + } + + return trace.some(fn); +} + +exports.getTrace = getTrace; +exports.isKeyword = isKeyword; +exports.isProperty = isProperty; +exports.isType = isType; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/units.cjs b/vanilla/node_modules/css-tree/cjs/lexer/units.cjs new file mode 100644 index 0000000..13f4e97 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/units.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const length = [ + // absolute length units https://www.w3.org/TR/css-values-3/#lengths + 'cm', 'mm', 'q', 'in', 'pt', 'pc', 'px', + // font-relative length units https://drafts.csswg.org/css-values-4/#font-relative-lengths + 'em', 'rem', + 'ex', 'rex', + 'cap', 'rcap', + 'ch', 'rch', + 'ic', 'ric', + 'lh', 'rlh', + // viewport-percentage lengths https://drafts.csswg.org/css-values-4/#viewport-relative-lengths + 'vw', 'svw', 'lvw', 'dvw', + 'vh', 'svh', 'lvh', 'dvh', + 'vi', 'svi', 'lvi', 'dvi', + 'vb', 'svb', 'lvb', 'dvb', + 'vmin', 'svmin', 'lvmin', 'dvmin', + 'vmax', 'svmax', 'lvmax', 'dvmax', + // container relative lengths https://drafts.csswg.org/css-contain-3/#container-lengths + 'cqw', 'cqh', 'cqi', 'cqb', 'cqmin', 'cqmax' +]; +const angle = ['deg', 'grad', 'rad', 'turn']; // https://www.w3.org/TR/css-values-3/#angles +const time = ['s', 'ms']; // https://www.w3.org/TR/css-values-3/#time +const frequency = ['hz', 'khz']; // https://www.w3.org/TR/css-values-3/#frequency +const resolution = ['dpi', 'dpcm', 'dppx', 'x']; // https://www.w3.org/TR/css-values-3/#resolution +const flex = ['fr']; // https://drafts.csswg.org/css-grid/#fr-unit +const decibel = ['db']; // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume +const semitones = ['st']; // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch + +exports.angle = angle; +exports.decibel = decibel; +exports.flex = flex; +exports.frequency = frequency; +exports.length = length; +exports.resolution = resolution; +exports.semitones = semitones; +exports.time = time; diff --git a/vanilla/node_modules/css-tree/cjs/parser/SyntaxError.cjs b/vanilla/node_modules/css-tree/cjs/parser/SyntaxError.cjs new file mode 100644 index 0000000..4de5ab3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/parser/SyntaxError.cjs @@ -0,0 +1,74 @@ +'use strict'; + +const createCustomError = require('../utils/create-custom-error.cjs'); + +const MAX_LINE_LENGTH = 100; +const OFFSET_CORRECTION = 60; +const TAB_REPLACEMENT = ' '; + +function sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) { + function processLines(start, end) { + return lines + .slice(start, end) + .map((line, idx) => + String(start + idx + 1).padStart(maxNumLength) + ' |' + line + ).join('\n'); + } + + const prelines = '\n'.repeat(Math.max(baseLine - 1, 0)); + const precolumns = ' '.repeat(Math.max(baseColumn - 1, 0)); + const lines = (prelines + precolumns + source).split(/\r\n?|\n|\f/); + const startLine = Math.max(1, line - extraLines) - 1; + const endLine = Math.min(line + extraLines, lines.length + 1); + const maxNumLength = Math.max(4, String(endLine).length) + 1; + let cutLeft = 0; + + // column correction according to replaced tab before column + column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length; + + if (column > MAX_LINE_LENGTH) { + cutLeft = column - OFFSET_CORRECTION + 3; + column = OFFSET_CORRECTION - 2; + } + + for (let i = startLine; i <= endLine; i++) { + if (i >= 0 && i < lines.length) { + lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT); + lines[i] = + (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') + + lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) + + (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : ''); + } + } + + return [ + processLines(startLine, line), + new Array(column + maxNumLength + 2).join('-') + '^', + processLines(line, endLine) + ].filter(Boolean) + .join('\n') + .replace(/^(\s+\d+\s+\|\n)+/, '') + .replace(/\n(\s+\d+\s+\|)+$/, ''); +} + +function SyntaxError(message, source, offset, line, column, baseLine = 1, baseColumn = 1) { + const error = Object.assign(createCustomError.createCustomError('SyntaxError', message), { + source, + offset, + line, + column, + sourceFragment(extraLines) { + return sourceFragment({ source, line, column, baseLine, baseColumn }, isNaN(extraLines) ? 0 : extraLines); + }, + get formattedMessage() { + return ( + `Parse error: ${message}\n` + + sourceFragment({ source, line, column, baseLine, baseColumn }, 2) + ); + } + }); + + return error; +} + +exports.SyntaxError = SyntaxError; diff --git a/vanilla/node_modules/css-tree/cjs/parser/create.cjs b/vanilla/node_modules/css-tree/cjs/parser/create.cjs new file mode 100644 index 0000000..0a59c4e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/parser/create.cjs @@ -0,0 +1,340 @@ +'use strict'; + +const List = require('../utils/List.cjs'); +const SyntaxError = require('./SyntaxError.cjs'); +const index = require('../tokenizer/index.cjs'); +const sequence = require('./sequence.cjs'); +const OffsetToLocation = require('../tokenizer/OffsetToLocation.cjs'); +const TokenStream = require('../tokenizer/TokenStream.cjs'); +const utils = require('../tokenizer/utils.cjs'); +const types = require('../tokenizer/types.cjs'); +const names = require('../tokenizer/names.cjs'); + +const NOOP = () => {}; +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const SEMICOLON = 0x003B; // U+003B SEMICOLON (;) +const LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({) +const NULL = 0; + +function createParseContext(name) { + return function() { + return this[name](); + }; +} + +function fetchParseValues(dict) { + const result = Object.create(null); + + for (const name of Object.keys(dict)) { + const item = dict[name]; + const fn = item.parse || item; + + if (fn) { + result[name] = fn; + } + } + + return result; +} + +function processConfig(config) { + const parseConfig = { + context: Object.create(null), + features: Object.assign(Object.create(null), config.features), + scope: Object.assign(Object.create(null), config.scope), + atrule: fetchParseValues(config.atrule), + pseudo: fetchParseValues(config.pseudo), + node: fetchParseValues(config.node) + }; + + for (const [name, context] of Object.entries(config.parseContext)) { + switch (typeof context) { + case 'function': + parseConfig.context[name] = context; + break; + + case 'string': + parseConfig.context[name] = createParseContext(context); + break; + } + } + + return { + config: parseConfig, + ...parseConfig, + ...parseConfig.node + }; +} + +function createParser(config) { + let source = ''; + let filename = '<unknown>'; + let needPositions = false; + let onParseError = NOOP; + let onParseErrorThrow = false; + + const locationMap = new OffsetToLocation.OffsetToLocation(); + const parser = Object.assign(new TokenStream.TokenStream(), processConfig(config || {}), { + parseAtrulePrelude: true, + parseRulePrelude: true, + parseValue: true, + parseCustomProperty: false, + + readSequence: sequence.readSequence, + + consumeUntilBalanceEnd: () => 0, + consumeUntilLeftCurlyBracket(code) { + return code === LEFTCURLYBRACKET ? 1 : 0; + }, + consumeUntilLeftCurlyBracketOrSemicolon(code) { + return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0; + }, + consumeUntilExclamationMarkOrSemicolon(code) { + return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0; + }, + consumeUntilSemicolonIncluded(code) { + return code === SEMICOLON ? 2 : 0; + }, + + createList() { + return new List.List(); + }, + createSingleNodeList(node) { + return new List.List().appendData(node); + }, + getFirstListNode(list) { + return list && list.first; + }, + getLastListNode(list) { + return list && list.last; + }, + + parseWithFallback(consumer, fallback) { + const startIndex = this.tokenIndex; + + try { + return consumer.call(this); + } catch (e) { + if (onParseErrorThrow) { + throw e; + } + + this.skip(startIndex - this.tokenIndex); + const fallbackNode = fallback.call(this); + + onParseErrorThrow = true; + onParseError(e, fallbackNode); + onParseErrorThrow = false; + + return fallbackNode; + } + }, + + lookupNonWSType(offset) { + let type; + + do { + type = this.lookupType(offset++); + if (type !== types.WhiteSpace && type !== types.Comment) { + return type; + } + } while (type !== NULL); + + return NULL; + }, + + charCodeAt(offset) { + return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0; + }, + substring(offsetStart, offsetEnd) { + return source.substring(offsetStart, offsetEnd); + }, + substrToCursor(start) { + return this.source.substring(start, this.tokenStart); + }, + + cmpChar(offset, charCode) { + return utils.cmpChar(source, offset, charCode); + }, + cmpStr(offsetStart, offsetEnd, str) { + return utils.cmpStr(source, offsetStart, offsetEnd, str); + }, + + consume(tokenType) { + const start = this.tokenStart; + + this.eat(tokenType); + + return this.substrToCursor(start); + }, + consumeFunctionName() { + const name = source.substring(this.tokenStart, this.tokenEnd - 1); + + this.eat(types.Function); + + return name; + }, + consumeNumber(type) { + const number = source.substring(this.tokenStart, utils.consumeNumber(source, this.tokenStart)); + + this.eat(type); + + return number; + }, + + eat(tokenType) { + if (this.tokenType !== tokenType) { + const tokenName = names[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase()); + let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`; + let offset = this.tokenStart; + + // tweak message and offset + switch (tokenType) { + case types.Ident: + // when identifier is expected but there is a function or url + if (this.tokenType === types.Function || this.tokenType === types.Url) { + offset = this.tokenEnd - 1; + message = 'Identifier is expected but function found'; + } else { + message = 'Identifier is expected'; + } + break; + + case types.Hash: + if (this.isDelim(NUMBERSIGN)) { + this.next(); + offset++; + message = 'Name is expected'; + } + break; + + case types.Percentage: + if (this.tokenType === types.Number) { + offset = this.tokenEnd; + message = 'Percent sign is expected'; + } + break; + } + + this.error(message, offset); + } + + this.next(); + }, + eatIdent(name) { + if (this.tokenType !== types.Ident || this.lookupValue(0, name) === false) { + this.error(`Identifier "${name}" is expected`); + } + + this.next(); + }, + eatDelim(code) { + if (!this.isDelim(code)) { + this.error(`Delim "${String.fromCharCode(code)}" is expected`); + } + + this.next(); + }, + + getLocation(start, end) { + if (needPositions) { + return locationMap.getLocationRange( + start, + end, + filename + ); + } + + return null; + }, + getLocationFromList(list) { + if (needPositions) { + const head = this.getFirstListNode(list); + const tail = this.getLastListNode(list); + return locationMap.getLocationRange( + head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart, + tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart, + filename + ); + } + + return null; + }, + + error(message, offset) { + const location = typeof offset !== 'undefined' && offset < source.length + ? locationMap.getLocation(offset) + : this.eof + ? locationMap.getLocation(utils.findWhiteSpaceStart(source, source.length - 1)) + : locationMap.getLocation(this.tokenStart); + + throw new SyntaxError.SyntaxError( + message || 'Unexpected input', + source, + location.offset, + location.line, + location.column, + locationMap.startLine, + locationMap.startColumn + ); + } + }); + + const parse = function(source_, options) { + source = source_; + options = options || {}; + + parser.setSource(source, index.tokenize); + locationMap.setSource( + source, + options.offset, + options.line, + options.column + ); + + filename = options.filename || '<unknown>'; + needPositions = Boolean(options.positions); + onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP; + onParseErrorThrow = false; + + parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true; + parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true; + parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true; + parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false; + + const { context = 'default', onComment } = options; + + if (context in parser.context === false) { + throw new Error('Unknown context `' + context + '`'); + } + + if (typeof onComment === 'function') { + parser.forEachToken((type, start, end) => { + if (type === types.Comment) { + const loc = parser.getLocation(start, end); + const value = utils.cmpStr(source, end - 2, end, '*/') + ? source.slice(start + 2, end - 2) + : source.slice(start + 2, end); + + onComment(value, loc); + } + }); + } + + const ast = parser.context[context].call(parser, options); + + if (!parser.eof) { + parser.error(); + } + + return ast; + }; + + return Object.assign(parse, { + SyntaxError: SyntaxError.SyntaxError, + config: parser.config + }); +} + +exports.createParser = createParser; diff --git a/vanilla/node_modules/css-tree/cjs/parser/index.cjs b/vanilla/node_modules/css-tree/cjs/parser/index.cjs new file mode 100644 index 0000000..9450cb0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/parser/index.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const parser = require('../syntax/config/parser.cjs'); + +const index = create.createParser(parser); + +module.exports = index; diff --git a/vanilla/node_modules/css-tree/cjs/parser/parse-selector.cjs b/vanilla/node_modules/css-tree/cjs/parser/parse-selector.cjs new file mode 100644 index 0000000..8ea8d0d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/parser/parse-selector.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const parserSelector = require('../syntax/config/parser-selector.cjs'); + +const parseSelector = create.createParser(parserSelector); + +module.exports = parseSelector; diff --git a/vanilla/node_modules/css-tree/cjs/parser/sequence.cjs b/vanilla/node_modules/css-tree/cjs/parser/sequence.cjs new file mode 100644 index 0000000..b7d7d29 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/parser/sequence.cjs @@ -0,0 +1,47 @@ +'use strict'; + +const types = require('../tokenizer/types.cjs'); + +function readSequence(recognizer) { + const children = this.createList(); + let space = false; + const context = { + recognizer + }; + + while (!this.eof) { + switch (this.tokenType) { + case types.Comment: + this.next(); + continue; + + case types.WhiteSpace: + space = true; + this.next(); + continue; + } + + let child = recognizer.getNode.call(this, context); + + if (child === undefined) { + break; + } + + if (space) { + if (recognizer.onWhiteSpace) { + recognizer.onWhiteSpace.call(this, child, children, context); + } + space = false; + } + + children.push(child); + } + + if (space && recognizer.onWhiteSpace) { + recognizer.onWhiteSpace.call(this, null, children, context); + } + + return children; +} + +exports.readSequence = readSequence; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs new file mode 100644 index 0000000..7413f45 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs @@ -0,0 +1,32 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +// https://drafts.csswg.org/css-contain-3/#container-rule +// The keywords `none`, `and`, `not`, and `or` are excluded from the <custom-ident> above. +const nonContainerNameKeywords = new Set(['none', 'and', 'not', 'or']); + +const container = { + parse: { + prelude() { + const children = this.createList(); + + if (this.tokenType === types.Ident) { + const name = this.substring(this.tokenStart, this.tokenEnd); + + if (!nonContainerNameKeywords.has(name.toLowerCase())) { + children.push(this.Identifier()); + } + } + + children.push(this.Condition('container')); + + return children; + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = container; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs new file mode 100644 index 0000000..fc7f64a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs @@ -0,0 +1,12 @@ +'use strict'; + +const fontFace = { + parse: { + prelude: null, + block() { + return this.Block(true); + } + } +}; + +module.exports = fontFace; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs new file mode 100644 index 0000000..09fc11c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs @@ -0,0 +1,101 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function parseWithFallback(parse, fallback) { + return this.parseWithFallback( + () => { + try { + return parse.call(this); + } finally { + this.skipSC(); + if (this.lookupNonWSType(0) !== types.RightParenthesis) { + this.error(); + } + } + }, + fallback || (() => this.Raw(null, true)) + ); +} + +const parseFunctions = { + layer() { + this.skipSC(); + + const children = this.createList(); + const node = parseWithFallback.call(this, this.Layer); + + if (node.type !== 'Raw' || node.value !== '') { + children.push(node); + } + + return children; + }, + supports() { + this.skipSC(); + + const children = this.createList(); + const node = parseWithFallback.call( + this, + this.Declaration, + () => parseWithFallback.call(this, () => this.Condition('supports')) + ); + + if (node.type !== 'Raw' || node.value !== '') { + children.push(node); + } + + return children; + } +}; + +const importAtrule = { + parse: { + prelude() { + const children = this.createList(); + + switch (this.tokenType) { + case types.String: + children.push(this.String()); + break; + + case types.Url: + case types.Function: + children.push(this.Url()); + break; + + default: + this.error('String or url() is expected'); + } + + this.skipSC(); + + if (this.tokenType === types.Ident && + this.cmpStr(this.tokenStart, this.tokenEnd, 'layer')) { + children.push(this.Identifier()); + } else if ( + this.tokenType === types.Function && + this.cmpStr(this.tokenStart, this.tokenEnd, 'layer(') + ) { + children.push(this.Function(null, parseFunctions)); + } + + this.skipSC(); + + if (this.tokenType === types.Function && + this.cmpStr(this.tokenStart, this.tokenEnd, 'supports(')) { + children.push(this.Function(null, parseFunctions)); + } + + if (this.lookupNonWSType(0) === types.Ident || + this.lookupNonWSType(0) === types.LeftParenthesis) { + children.push(this.MediaQueryList()); + } + + return children; + }, + block: null + } +}; + +module.exports = importAtrule; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs new file mode 100644 index 0000000..143f21f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs @@ -0,0 +1,27 @@ +'use strict'; + +const container = require('./container.cjs'); +const fontFace = require('./font-face.cjs'); +const _import = require('./import.cjs'); +const layer = require('./layer.cjs'); +const media = require('./media.cjs'); +const nest = require('./nest.cjs'); +const page = require('./page.cjs'); +const scope = require('./scope.cjs'); +const startingStyle = require('./starting-style.cjs'); +const supports = require('./supports.cjs'); + +const atrule = { + container, + 'font-face': fontFace, + import: _import, + layer, + media, + nest, + page, + scope, + 'starting-style': startingStyle, + supports +}; + +module.exports = atrule; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs new file mode 100644 index 0000000..5a9ac26 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const layer = { + parse: { + prelude() { + return this.createSingleNodeList( + this.LayerList() + ); + }, + block() { + return this.Block(false); + } + } +}; + +module.exports = layer; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs new file mode 100644 index 0000000..5db3439 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const media = { + parse: { + prelude() { + return this.createSingleNodeList( + this.MediaQueryList() + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = media; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs new file mode 100644 index 0000000..5cd6672 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const nest = { + parse: { + prelude() { + return this.createSingleNodeList( + this.SelectorList() + ); + }, + block() { + return this.Block(true); + } + } +}; + +module.exports = nest; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs new file mode 100644 index 0000000..ffef0d1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const page = { + parse: { + prelude() { + return this.createSingleNodeList( + this.SelectorList() + ); + }, + block() { + return this.Block(true); + } + } +}; + +module.exports = page; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs new file mode 100644 index 0000000..e5ffba2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const scope = { + parse: { + prelude() { + return this.createSingleNodeList( + this.Scope() + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = scope; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs new file mode 100644 index 0000000..8c9814d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs @@ -0,0 +1,12 @@ +'use strict'; + +const startingStyle = { + parse: { + prelude: null, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = startingStyle; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs new file mode 100644 index 0000000..b03d864 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const supports = { + parse: { + prelude() { + return this.createSingleNodeList( + this.Condition('supports') + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = supports; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs new file mode 100644 index 0000000..c092458 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs @@ -0,0 +1,9 @@ +'use strict'; + +const indexGenerate = require('../node/index-generate.cjs'); + +const config = { + node: indexGenerate +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs new file mode 100644 index 0000000..9889262 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs @@ -0,0 +1,14 @@ +'use strict'; + +const genericConst = require('../../lexer/generic-const.cjs'); +const data = require('../../data.cjs'); +const index = require('../node/index.cjs'); + +const lexerConfig = { + generic: true, + cssWideKeywords: genericConst.cssWideKeywords, + ...data, + node: index +}; + +module.exports = lexerConfig; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs new file mode 100644 index 0000000..5ecf1bb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs @@ -0,0 +1,127 @@ +'use strict'; + +function appendOrSet(a, b) { + if (typeof b === 'string' && /^\s*\|/.test(b)) { + return typeof a === 'string' + ? a + b + : b.replace(/^\s*\|\s*/, ''); + } + + return b || null; +} + +function sliceProps(obj, props) { + const result = Object.create(null); + + for (const [key, value] of Object.entries(obj)) { + if (value) { + result[key] = {}; + for (const prop of Object.keys(value)) { + if (props.includes(prop)) { + result[key][prop] = value[prop]; + } + } + } + } + + return result; +} + +function mix(dest, src) { + const result = { ...dest }; + + for (const [prop, value] of Object.entries(src)) { + switch (prop) { + case 'generic': + result[prop] = Boolean(value); + break; + + case 'cssWideKeywords': + result[prop] = dest[prop] + ? [...dest[prop], ...value] + : value || []; + break; + + case 'units': + result[prop] = { ...dest[prop] }; + for (const [name, patch] of Object.entries(value)) { + result[prop][name] = Array.isArray(patch) ? patch : []; + } + break; + + case 'atrules': + result[prop] = { ...dest[prop] }; + + for (const [name, atrule] of Object.entries(value)) { + const exists = result[prop][name] || {}; + const current = result[prop][name] = { + prelude: exists.prelude || null, + descriptors: { + ...exists.descriptors + } + }; + + if (!atrule) { + continue; + } + + current.prelude = atrule.prelude + ? appendOrSet(current.prelude, atrule.prelude) + : current.prelude || null; + + for (const [descriptorName, descriptorValue] of Object.entries(atrule.descriptors || {})) { + current.descriptors[descriptorName] = descriptorValue + ? appendOrSet(current.descriptors[descriptorName], descriptorValue) + : null; + } + + if (!Object.keys(current.descriptors).length) { + current.descriptors = null; + } + } + break; + + case 'types': + case 'properties': + result[prop] = { ...dest[prop] }; + for (const [name, syntax] of Object.entries(value)) { + result[prop][name] = appendOrSet(result[prop][name], syntax); + } + break; + + case 'scope': + case 'features': + result[prop] = { ...dest[prop] }; + for (const [name, props] of Object.entries(value)) { + result[prop][name] = { ...result[prop][name], ...props }; + } + break; + + case 'parseContext': + result[prop] = { + ...dest[prop], + ...value + }; + break; + + case 'atrule': + case 'pseudo': + result[prop] = { + ...dest[prop], + ...sliceProps(value, ['parse']) + }; + break; + + case 'node': + result[prop] = { + ...dest[prop], + ...sliceProps(value, ['name', 'structure', 'parse', 'generate', 'walkContext']) + }; + break; + } + } + + return result; +} + +module.exports = mix; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs new file mode 100644 index 0000000..03b1683 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs @@ -0,0 +1,19 @@ +'use strict'; + +const index = require('../pseudo/index.cjs'); +const indexParseSelector = require('../node/index-parse-selector.cjs'); +const selector = require('../scope/selector.cjs'); + +const config = { + parseContext: { + default: 'SelectorList', + selectorList: 'SelectorList', + selector: 'Selector' + }, + scope: { Selector: selector }, + atrule: {}, + pseudo: index, + node: indexParseSelector +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs new file mode 100644 index 0000000..cd7114a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs @@ -0,0 +1,49 @@ +'use strict'; + +const index = require('../scope/index.cjs'); +const index$1 = require('../atrule/index.cjs'); +const index$2 = require('../pseudo/index.cjs'); +const indexParse = require('../node/index-parse.cjs'); + +const config = { + parseContext: { + default: 'StyleSheet', + stylesheet: 'StyleSheet', + atrule: 'Atrule', + atrulePrelude(options) { + return this.AtrulePrelude(options.atrule ? String(options.atrule) : null); + }, + mediaQueryList: 'MediaQueryList', + mediaQuery: 'MediaQuery', + condition(options) { + return this.Condition(options.kind); + }, + rule: 'Rule', + selectorList: 'SelectorList', + selector: 'Selector', + block() { + return this.Block(true); + }, + declarationList: 'DeclarationList', + declaration: 'Declaration', + value: 'Value' + }, + features: { + supports: { + selector() { + return this.Selector(); + } + }, + container: { + style() { + return this.Declaration(); + } + } + }, + scope: index, + atrule: index$1, + pseudo: index$2, + node: indexParse +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs new file mode 100644 index 0000000..95c8f7d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs @@ -0,0 +1,9 @@ +'use strict'; + +const index = require('../node/index.cjs'); + +const config = { + node: index +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/create.cjs b/vanilla/node_modules/css-tree/cjs/syntax/create.cjs new file mode 100644 index 0000000..6ed51ea --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/create.cjs @@ -0,0 +1,58 @@ +'use strict'; + +const index = require('../tokenizer/index.cjs'); +const create = require('../parser/create.cjs'); +const create$2 = require('../generator/create.cjs'); +const create$3 = require('../convertor/create.cjs'); +const create$1 = require('../walker/create.cjs'); +const Lexer = require('../lexer/Lexer.cjs'); +const mix = require('./config/mix.cjs'); + +function createSyntax(config) { + const parse = create.createParser(config); + const walk = create$1.createWalker(config); + const generate = create$2.createGenerator(config); + const { fromPlainObject, toPlainObject } = create$3.createConvertor(walk); + + const syntax = { + lexer: null, + createLexer: config => new Lexer.Lexer(config, syntax, syntax.lexer.structure), + + tokenize: index.tokenize, + parse, + generate, + + walk, + find: walk.find, + findLast: walk.findLast, + findAll: walk.findAll, + + fromPlainObject, + toPlainObject, + + fork(extension) { + const base = mix({}, config); // copy of config + + return createSyntax( + typeof extension === 'function' + ? extension(base) // TODO: remove Object.assign as second parameter + : mix(base, extension) + ); + } + }; + + syntax.lexer = new Lexer.Lexer({ + generic: config.generic, + cssWideKeywords: config.cssWideKeywords, + units: config.units, + types: config.types, + atrules: config.atrules, + properties: config.properties, + node: config.node + }, syntax); + + return syntax; +} +const createSyntax$1 = config => createSyntax(mix({}, config)); + +module.exports = createSyntax$1; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs b/vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs new file mode 100644 index 0000000..5a8967c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs @@ -0,0 +1,11 @@ +'use strict'; + +// legacy IE function +// expression( <any-value> ) +function expressionFn() { + return this.createSingleNodeList( + this.Raw(null, false) + ); +} + +module.exports = expressionFn; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs b/vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs new file mode 100644 index 0000000..f688eab --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs @@ -0,0 +1,43 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +// var( <ident> , <value>? ) +function varFn() { + const children = this.createList(); + + this.skipSC(); + + // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer + children.push(this.Identifier()); + + this.skipSC(); + + if (this.tokenType === types.Comma) { + children.push(this.Operator()); + + const startIndex = this.tokenIndex; + const value = this.parseCustomProperty + ? this.Value(null) + : this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false); + + if (value.type === 'Value' && value.children.isEmpty) { + for (let offset = startIndex - this.tokenIndex; offset <= 0; offset++) { + if (this.lookupType(offset) === types.WhiteSpace) { + value.children.appendData({ + type: 'WhiteSpace', + loc: null, + value: ' ' + }); + break; + } + } + } + + children.push(value); + } + + return children; +} + +module.exports = varFn; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/index.cjs new file mode 100644 index 0000000..24de495 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/index.cjs @@ -0,0 +1,14 @@ +'use strict'; + +const create = require('./create.cjs'); +const lexer = require('./config/lexer.cjs'); +const parser = require('./config/parser.cjs'); +const walker = require('./config/walker.cjs'); + +const syntax = create({ + ...lexer, + ...parser, + ...walker +}); + +module.exports = syntax; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs new file mode 100644 index 0000000..cd59927 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs @@ -0,0 +1,293 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); +const charCodeDefinitions = require('../../tokenizer/char-code-definitions.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const N = 0x006E; // U+006E LATIN SMALL LETTER N (n) +const DISALLOW_SIGN = true; +const ALLOW_SIGN = false; + +function checkInteger(offset, disallowSign) { + let pos = this.tokenStart + offset; + const code = this.charCodeAt(pos); + + if (code === PLUSSIGN || code === HYPHENMINUS) { + if (disallowSign) { + this.error('Number sign is not allowed'); + } + pos++; + } + + for (; pos < this.tokenEnd; pos++) { + if (!charCodeDefinitions.isDigit(this.charCodeAt(pos))) { + this.error('Integer is expected', pos); + } + } +} + +function checkTokenIsInteger(disallowSign) { + return checkInteger.call(this, 0, disallowSign); +} + +function expectCharCode(offset, code) { + if (!this.cmpChar(this.tokenStart + offset, code)) { + let msg = ''; + + switch (code) { + case N: + msg = 'N is expected'; + break; + case HYPHENMINUS: + msg = 'HyphenMinus is expected'; + break; + } + + this.error(msg, this.tokenStart + offset); + } +} + +// ... <signed-integer> +// ... ['+' | '-'] <signless-integer> +function consumeB() { + let offset = 0; + let sign = 0; + let type = this.tokenType; + + while (type === types.WhiteSpace || type === types.Comment) { + type = this.lookupType(++offset); + } + + if (type !== types.Number) { + if (this.isDelim(PLUSSIGN, offset) || + this.isDelim(HYPHENMINUS, offset)) { + sign = this.isDelim(PLUSSIGN, offset) ? PLUSSIGN : HYPHENMINUS; + + do { + type = this.lookupType(++offset); + } while (type === types.WhiteSpace || type === types.Comment); + + if (type !== types.Number) { + this.skip(offset); + checkTokenIsInteger.call(this, DISALLOW_SIGN); + } + } else { + return null; + } + } + + if (offset > 0) { + this.skip(offset); + } + + if (sign === 0) { + type = this.charCodeAt(this.tokenStart); + if (type !== PLUSSIGN && type !== HYPHENMINUS) { + this.error('Number sign is expected'); + } + } + + checkTokenIsInteger.call(this, sign !== 0); + return sign === HYPHENMINUS ? '-' + this.consume(types.Number) : this.consume(types.Number); +} + +// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb +const name = 'AnPlusB'; +const structure = { + a: [String, null], + b: [String, null] +}; + +function parse() { + /* eslint-disable brace-style*/ + const start = this.tokenStart; + let a = null; + let b = null; + + // <integer> + if (this.tokenType === types.Number) { + checkTokenIsInteger.call(this, ALLOW_SIGN); + b = this.consume(types.Number); + } + + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + // -n- <signless-integer> + // <dashndashdigit-ident> + else if (this.tokenType === types.Ident && this.cmpChar(this.tokenStart, HYPHENMINUS)) { + a = '-1'; + + expectCharCode.call(this, 1, N); + + switch (this.tokenEnd - this.tokenStart) { + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + case 2: + this.next(); + b = consumeB.call(this); + break; + + // -n- <signless-integer> + case 3: + expectCharCode.call(this, 2, HYPHENMINUS); + + this.next(); + this.skipSC(); + + checkTokenIsInteger.call(this, DISALLOW_SIGN); + + b = '-' + this.consume(types.Number); + break; + + // <dashndashdigit-ident> + default: + expectCharCode.call(this, 2, HYPHENMINUS); + checkInteger.call(this, 3, DISALLOW_SIGN); + this.next(); + + b = this.substrToCursor(start + 2); + } + } + + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + // '+'? n- <signless-integer> + // '+'? <ndashdigit-ident> + else if (this.tokenType === types.Ident || (this.isDelim(PLUSSIGN) && this.lookupType(1) === types.Ident)) { + let sign = 0; + a = '1'; + + // just ignore a plus + if (this.isDelim(PLUSSIGN)) { + sign = 1; + this.next(); + } + + expectCharCode.call(this, 0, N); + + switch (this.tokenEnd - this.tokenStart) { + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + case 1: + this.next(); + b = consumeB.call(this); + break; + + // '+'? n- <signless-integer> + case 2: + expectCharCode.call(this, 1, HYPHENMINUS); + + this.next(); + this.skipSC(); + + checkTokenIsInteger.call(this, DISALLOW_SIGN); + + b = '-' + this.consume(types.Number); + break; + + // '+'? <ndashdigit-ident> + default: + expectCharCode.call(this, 1, HYPHENMINUS); + checkInteger.call(this, 2, DISALLOW_SIGN); + this.next(); + + b = this.substrToCursor(start + sign + 1); + } + } + + // <ndashdigit-dimension> + // <ndash-dimension> <signless-integer> + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + else if (this.tokenType === types.Dimension) { + const code = this.charCodeAt(this.tokenStart); + const sign = code === PLUSSIGN || code === HYPHENMINUS; + let i = this.tokenStart + sign; + + for (; i < this.tokenEnd; i++) { + if (!charCodeDefinitions.isDigit(this.charCodeAt(i))) { + break; + } + } + + if (i === this.tokenStart + sign) { + this.error('Integer is expected', this.tokenStart + sign); + } + + expectCharCode.call(this, i - this.tokenStart, N); + a = this.substring(start, i); + + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + if (i + 1 === this.tokenEnd) { + this.next(); + b = consumeB.call(this); + } else { + expectCharCode.call(this, i - this.tokenStart + 1, HYPHENMINUS); + + // <ndash-dimension> <signless-integer> + if (i + 2 === this.tokenEnd) { + this.next(); + this.skipSC(); + checkTokenIsInteger.call(this, DISALLOW_SIGN); + b = '-' + this.consume(types.Number); + } + // <ndashdigit-dimension> + else { + checkInteger.call(this, i - this.tokenStart + 2, DISALLOW_SIGN); + this.next(); + b = this.substrToCursor(i + 1); + } + } + } else { + this.error(); + } + + if (a !== null && a.charCodeAt(0) === PLUSSIGN) { + a = a.substr(1); + } + + if (b !== null && b.charCodeAt(0) === PLUSSIGN) { + b = b.substr(1); + } + + return { + type: 'AnPlusB', + loc: this.getLocation(start, this.tokenStart), + a, + b + }; +} + +function generate(node) { + if (node.a) { + const a = + node.a === '+1' && 'n' || + node.a === '1' && 'n' || + node.a === '-1' && '-n' || + node.a + 'n'; + + if (node.b) { + const b = node.b[0] === '-' || node.b[0] === '+' + ? node.b + : '+' + node.b; + this.tokenize(a + b); + } else { + this.tokenize(a); + } + } else { + this.tokenize(node.b); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs new file mode 100644 index 0000000..b2e0598 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function consumeRaw() { + return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon, true); +} + +function isDeclarationBlockAtrule() { + for (let offset = 1, type; type = this.lookupType(offset); offset++) { + if (type === types.RightCurlyBracket) { + return true; + } + + if (type === types.LeftCurlyBracket || + type === types.AtKeyword) { + return false; + } + } + + return false; +} + + +const name = 'Atrule'; +const walkContext = 'atrule'; +const structure = { + name: String, + prelude: ['AtrulePrelude', 'Raw', null], + block: ['Block', null] +}; + +function parse(isDeclaration = false) { + const start = this.tokenStart; + let name; + let nameLowerCase; + let prelude = null; + let block = null; + + this.eat(types.AtKeyword); + + name = this.substrToCursor(start + 1); + nameLowerCase = name.toLowerCase(); + this.skipSC(); + + // parse prelude + if (this.eof === false && + this.tokenType !== types.LeftCurlyBracket && + this.tokenType !== types.Semicolon) { + if (this.parseAtrulePrelude) { + prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name, isDeclaration), consumeRaw); + } else { + prelude = consumeRaw.call(this, this.tokenIndex); + } + + this.skipSC(); + } + + switch (this.tokenType) { + case types.Semicolon: + this.next(); + break; + + case types.LeftCurlyBracket: + if (hasOwnProperty.call(this.atrule, nameLowerCase) && + typeof this.atrule[nameLowerCase].block === 'function') { + block = this.atrule[nameLowerCase].block.call(this, isDeclaration); + } else { + // TODO: should consume block content as Raw? + block = this.Block(isDeclarationBlockAtrule.call(this)); + } + + break; + } + + return { + type: 'Atrule', + loc: this.getLocation(start, this.tokenStart), + name, + prelude, + block + }; +} + +function generate(node) { + this.token(types.AtKeyword, '@' + node.name); + + if (node.prelude !== null) { + this.node(node.prelude); + } + + if (node.block) { + this.node(node.block); + } else { + this.token(types.Semicolon, ';'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs new file mode 100644 index 0000000..0db69b6 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs @@ -0,0 +1,52 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'AtrulePrelude'; +const walkContext = 'atrulePrelude'; +const structure = { + children: [[]] +}; + +function parse(name) { + let children = null; + + if (name !== null) { + name = name.toLowerCase(); + } + + this.skipSC(); + + if (hasOwnProperty.call(this.atrule, name) && + typeof this.atrule[name].prelude === 'function') { + // custom consumer + children = this.atrule[name].prelude.call(this); + } else { + // default consumer + children = this.readSequence(this.scope.AtrulePrelude); + } + + this.skipSC(); + + if (this.eof !== true && + this.tokenType !== types.LeftCurlyBracket && + this.tokenType !== types.Semicolon) { + this.error('Semicolon or block is expected'); + } + + return { + type: 'AtrulePrelude', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs new file mode 100644 index 0000000..757d4eb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs @@ -0,0 +1,148 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=) +const CIRCUMFLEXACCENT = 0x005E; // U+005E (^) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) +const TILDE = 0x007E; // U+007E TILDE (~) + +function getAttributeName() { + if (this.eof) { + this.error('Unexpected end of input'); + } + + const start = this.tokenStart; + let expectIdent = false; + + if (this.isDelim(ASTERISK)) { + expectIdent = true; + this.next(); + } else if (!this.isDelim(VERTICALLINE)) { + this.eat(types.Ident); + } + + if (this.isDelim(VERTICALLINE)) { + if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN) { + this.next(); + this.eat(types.Ident); + } else if (expectIdent) { + this.error('Identifier is expected', this.tokenEnd); + } + } else if (expectIdent) { + this.error('Vertical line is expected'); + } + + return { + type: 'Identifier', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start) + }; +} + +function getOperator() { + const start = this.tokenStart; + const code = this.charCodeAt(start); + + if (code !== EQUALSSIGN && // = + code !== TILDE && // ~= + code !== CIRCUMFLEXACCENT && // ^= + code !== DOLLARSIGN && // $= + code !== ASTERISK && // *= + code !== VERTICALLINE // |= + ) { + this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected'); + } + + this.next(); + + if (code !== EQUALSSIGN) { + if (!this.isDelim(EQUALSSIGN)) { + this.error('Equal sign is expected'); + } + + this.next(); + } + + return this.substrToCursor(start); +} + +// '[' <wq-name> ']' +// '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']' +const name = 'AttributeSelector'; +const structure = { + name: 'Identifier', + matcher: [String, null], + value: ['String', 'Identifier', null], + flags: [String, null] +}; + +function parse() { + const start = this.tokenStart; + let name; + let matcher = null; + let value = null; + let flags = null; + + this.eat(types.LeftSquareBracket); + this.skipSC(); + + name = getAttributeName.call(this); + this.skipSC(); + + if (this.tokenType !== types.RightSquareBracket) { + // avoid case `[name i]` + if (this.tokenType !== types.Ident) { + matcher = getOperator.call(this); + + this.skipSC(); + + value = this.tokenType === types.String + ? this.String() + : this.Identifier(); + + this.skipSC(); + } + + // attribute flags + if (this.tokenType === types.Ident) { + flags = this.consume(types.Ident); + + this.skipSC(); + } + } + + this.eat(types.RightSquareBracket); + + return { + type: 'AttributeSelector', + loc: this.getLocation(start, this.tokenStart), + name, + matcher, + value, + flags + }; +} + +function generate(node) { + this.token(types.Delim, '['); + this.node(node.name); + + if (node.matcher !== null) { + this.tokenize(node.matcher); + this.node(node.value); + } + + if (node.flags !== null) { + this.token(types.Ident, node.flags); + } + + this.token(types.Delim, ']'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs new file mode 100644 index 0000000..0e334f6 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs @@ -0,0 +1,96 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +function consumeRaw() { + return this.Raw(null, true); +} +function consumeRule() { + return this.parseWithFallback(this.Rule, consumeRaw); +} +function consumeRawDeclaration() { + return this.Raw(this.consumeUntilSemicolonIncluded, true); +} +function consumeDeclaration() { + if (this.tokenType === types.Semicolon) { + return consumeRawDeclaration.call(this, this.tokenIndex); + } + + const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration); + + if (this.tokenType === types.Semicolon) { + this.next(); + } + + return node; +} + +const name = 'Block'; +const walkContext = 'block'; +const structure = { + children: [[ + 'Atrule', + 'Rule', + 'Declaration' + ]] +}; + +function parse(isStyleBlock) { + const consumer = isStyleBlock ? consumeDeclaration : consumeRule; + const start = this.tokenStart; + let children = this.createList(); + + this.eat(types.LeftCurlyBracket); + + scan: + while (!this.eof) { + switch (this.tokenType) { + case types.RightCurlyBracket: + break scan; + + case types.WhiteSpace: + case types.Comment: + this.next(); + break; + + case types.AtKeyword: + children.push(this.parseWithFallback(this.Atrule.bind(this, isStyleBlock), consumeRaw)); + break; + + default: + if (isStyleBlock && this.isDelim(AMPERSAND)) { + children.push(consumeRule.call(this)); + } else { + children.push(consumer.call(this)); + } + } + } + + if (!this.eof) { + this.eat(types.RightCurlyBracket); + } + + return { + type: 'Block', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.token(types.LeftCurlyBracket, '{'); + this.children(node, prev => { + if (prev.type === 'Declaration') { + this.token(types.Semicolon, ';'); + } + }); + this.token(types.RightCurlyBracket, '}'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs new file mode 100644 index 0000000..eb18131 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Brackets'; +const structure = { + children: [[]] +}; + +function parse(readSequence, recognizer) { + const start = this.tokenStart; + let children = null; + + this.eat(types.LeftSquareBracket); + + children = readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(types.RightSquareBracket); + } + + return { + type: 'Brackets', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.token(types.Delim, '['); + this.children(node); + this.token(types.Delim, ']'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs new file mode 100644 index 0000000..aadf3ad --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'CDC'; +const structure = []; + +function parse() { + const start = this.tokenStart; + + this.eat(types.CDC); // --> + + return { + type: 'CDC', + loc: this.getLocation(start, this.tokenStart) + }; +} + +function generate() { + this.token(types.CDC, '-->'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs new file mode 100644 index 0000000..0e98217 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'CDO'; +const structure = []; + +function parse() { + const start = this.tokenStart; + + this.eat(types.CDO); // <!-- + + return { + type: 'CDO', + loc: this.getLocation(start, this.tokenStart) + }; +} + +function generate() { + this.token(types.CDO, '<!--'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs new file mode 100644 index 0000000..ff3de5c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs @@ -0,0 +1,31 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +// '.' ident +const name = 'ClassSelector'; +const structure = { + name: String +}; + +function parse() { + this.eatDelim(FULLSTOP); + + return { + type: 'ClassSelector', + loc: this.getLocation(this.tokenStart - 1, this.tokenEnd), + name: this.consume(types.Ident) + }; +} + +function generate(node) { + this.token(types.Delim, '.'); + this.token(types.Ident, node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs new file mode 100644 index 0000000..1a24278 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs @@ -0,0 +1,61 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) +const TILDE = 0x007E; // U+007E TILDE (~) + +const name = 'Combinator'; +const structure = { + name: String +}; + +// + | > | ~ | /deep/ +function parse() { + const start = this.tokenStart; + let name; + + switch (this.tokenType) { + case types.WhiteSpace: + name = ' '; + break; + + case types.Delim: + switch (this.charCodeAt(this.tokenStart)) { + case GREATERTHANSIGN: + case PLUSSIGN: + case TILDE: + this.next(); + break; + + case SOLIDUS: + this.next(); + this.eatIdent('deep'); + this.eatDelim(SOLIDUS); + break; + + default: + this.error('Combinator is expected'); + } + + name = this.substrToCursor(start); + break; + } + + return { + type: 'Combinator', + loc: this.getLocation(start, this.tokenStart), + name + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs new file mode 100644 index 0000000..083e950 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs @@ -0,0 +1,40 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + + +const name = 'Comment'; +const structure = { + value: String +}; + +function parse() { + const start = this.tokenStart; + let end = this.tokenEnd; + + this.eat(types.Comment); + + if ((end - start + 2) >= 2 && + this.charCodeAt(end - 2) === ASTERISK && + this.charCodeAt(end - 1) === SOLIDUS) { + end -= 2; + } + + return { + type: 'Comment', + loc: this.getLocation(start, this.tokenStart), + value: this.substring(start + 2, end) + }; +} + +function generate(node) { + this.token(types.Comment, '/*' + node.value + '*/'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs new file mode 100644 index 0000000..af6a2ec --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs @@ -0,0 +1,120 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const likelyFeatureToken = new Set([types.Colon, types.RightParenthesis, types.EOF]); + +const name = 'Condition'; +const structure = { + kind: String, + children: [[ + 'Identifier', + 'Feature', + 'FeatureFunction', + 'FeatureRange', + 'SupportsDeclaration' + ]] +}; + +function featureOrRange(kind) { + if (this.lookupTypeNonSC(1) === types.Ident && + likelyFeatureToken.has(this.lookupTypeNonSC(2))) { + return this.Feature(kind); + } + + return this.FeatureRange(kind); +} + +const parentheses = { + media: featureOrRange, + container: featureOrRange, + supports() { + return this.SupportsDeclaration(); + } +}; + +function parse(kind = 'media') { + const children = this.createList(); + + scan: while (!this.eof) { + switch (this.tokenType) { + case types.Comment: + case types.WhiteSpace: + this.next(); + continue; + + case types.Ident: + children.push(this.Identifier()); + break; + + case types.LeftParenthesis: { + let term = this.parseWithFallback( + () => parentheses[kind].call(this, kind), + () => null + ); + + if (!term) { + term = this.parseWithFallback( + () => { + this.eat(types.LeftParenthesis); + const res = this.Condition(kind); + this.eat(types.RightParenthesis); + return res; + }, + () => { + return this.GeneralEnclosed(kind); + } + ); + } + + children.push(term); + break; + } + + case types.Function: { + let term = this.parseWithFallback( + () => this.FeatureFunction(kind), + () => null + ); + + if (!term) { + term = this.GeneralEnclosed(kind); + } + + children.push(term); + break; + } + + default: + break scan; + } + } + + if (children.isEmpty) { + this.error('Condition is expected'); + } + + return { + type: 'Condition', + loc: this.getLocationFromList(children), + kind, + children + }; +} + +function generate(node) { + node.children.forEach(child => { + if (child.type === 'Condition') { + this.token(types.LeftParenthesis, '('); + this.node(child); + this.token(types.RightParenthesis, ')'); + } else { + this.node(child); + } + }); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs new file mode 100644 index 0000000..7cf13b1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs @@ -0,0 +1,166 @@ +'use strict'; + +const names = require('../../utils/names.cjs'); +const types = require('../../tokenizer/types.cjs'); + +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +function consumeValueRaw() { + return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, true); +} + +function consumeCustomPropertyRaw() { + return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false); +} + +function consumeValue() { + const startValueToken = this.tokenIndex; + const value = this.Value(); + + if (value.type !== 'Raw' && + this.eof === false && + this.tokenType !== types.Semicolon && + this.isDelim(EXCLAMATIONMARK) === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; +} + +const name = 'Declaration'; +const walkContext = 'declaration'; +const structure = { + important: [Boolean, String], + property: String, + value: ['Value', 'Raw'] +}; + +function parse() { + const start = this.tokenStart; + const startToken = this.tokenIndex; + const property = readProperty.call(this); + const customProperty = names.isCustomProperty(property); + const parseValue = customProperty ? this.parseCustomProperty : this.parseValue; + const consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw; + let important = false; + let value; + + this.skipSC(); + this.eat(types.Colon); + + const valueStart = this.tokenIndex; + + if (!customProperty) { + this.skipSC(); + } + + if (parseValue) { + value = this.parseWithFallback(consumeValue, consumeRaw); + } else { + value = consumeRaw.call(this, this.tokenIndex); + } + + if (customProperty && value.type === 'Value' && value.children.isEmpty) { + for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) { + if (this.lookupType(offset) === types.WhiteSpace) { + value.children.appendData({ + type: 'WhiteSpace', + loc: null, + value: ' ' + }); + break; + } + } + } + + if (this.isDelim(EXCLAMATIONMARK)) { + important = getImportant.call(this); + this.skipSC(); + } + + // Do not include semicolon to range per spec + // https://drafts.csswg.org/css-syntax/#declaration-diagram + + if (this.eof === false && + this.tokenType !== types.Semicolon && + this.isBalanceEdge(startToken) === false) { + this.error(); + } + + return { + type: 'Declaration', + loc: this.getLocation(start, this.tokenStart), + important, + property, + value + }; +} + +function generate(node) { + this.token(types.Ident, node.property); + this.token(types.Colon, ':'); + this.node(node.value); + + if (node.important) { + this.token(types.Delim, '!'); + this.token(types.Ident, node.important === true ? 'important' : node.important); + } +} + +function readProperty() { + const start = this.tokenStart; + + // hacks + if (this.tokenType === types.Delim) { + switch (this.charCodeAt(this.tokenStart)) { + case ASTERISK: + case DOLLARSIGN: + case PLUSSIGN: + case NUMBERSIGN: + case AMPERSAND: + this.next(); + break; + + // TODO: not sure we should support this hack + case SOLIDUS: + this.next(); + if (this.isDelim(SOLIDUS)) { + this.next(); + } + break; + } + } + + if (this.tokenType === types.Hash) { + this.eat(types.Hash); + } else { + this.eat(types.Ident); + } + + return this.substrToCursor(start); +} + +// ! ws* important +function getImportant() { + this.eat(types.Delim); + this.skipSC(); + + const important = this.consume(types.Ident); + + // store original value in case it differ from `important` + // for better original source restoring and hacks like `!ie` support + return important === 'important' ? true : important; +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs new file mode 100644 index 0000000..d3cffad --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs @@ -0,0 +1,62 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +function consumeRaw() { + return this.Raw(this.consumeUntilSemicolonIncluded, true); +} + +const name = 'DeclarationList'; +const structure = { + children: [[ + 'Declaration', + 'Atrule', + 'Rule' + ]] +}; + +function parse() { + const children = this.createList(); + + while (!this.eof) { + switch (this.tokenType) { + case types.WhiteSpace: + case types.Comment: + case types.Semicolon: + this.next(); + break; + + case types.AtKeyword: + children.push(this.parseWithFallback(this.Atrule.bind(this, true), consumeRaw)); + break; + + default: + if (this.isDelim(AMPERSAND)) { + children.push(this.parseWithFallback(this.Rule, consumeRaw)); + } else { + children.push(this.parseWithFallback(this.Declaration, consumeRaw)); + } + } + } + + return { + type: 'DeclarationList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, prev => { + if (prev.type === 'Declaration') { + this.token(types.Semicolon, ';'); + } + }); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs new file mode 100644 index 0000000..227184c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs @@ -0,0 +1,30 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Dimension'; +const structure = { + value: String, + unit: String +}; + +function parse() { + const start = this.tokenStart; + const value = this.consumeNumber(types.Dimension); + + return { + type: 'Dimension', + loc: this.getLocation(start, this.tokenStart), + value, + unit: this.substring(start + value.length, this.tokenStart) + }; +} + +function generate(node) { + this.token(types.Dimension, node.value + node.unit); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs new file mode 100644 index 0000000..a55019b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs @@ -0,0 +1,101 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +const name = 'Feature'; +const structure = { + kind: String, + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null] +}; + +function parse(kind) { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + name = this.consume(types.Ident); + this.skipSC(); + + if (this.tokenType !== types.RightParenthesis) { + this.eat(types.Colon); + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case types.Dimension: + value = this.Dimension(); + break; + + case types.Ident: + value = this.Identifier(); + break; + + case types.Function: + value = this.parseWithFallback( + () => { + const res = this.Function(this.readSequence, this.scope.Value); + + this.skipSC(); + + if (this.isDelim(SOLIDUS)) { + this.error(); + } + + return res; + }, + () => { + return this.Ratio(); + } + ); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'Feature', + loc: this.getLocation(start, this.tokenStart), + kind, + name, + value + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.token(types.Ident, node.name); + + if (node.value !== null) { + this.token(types.Colon, ':'); + this.node(node.value); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs new file mode 100644 index 0000000..1986947 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs @@ -0,0 +1,67 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'FeatureFunction'; +const structure = { + kind: String, + feature: String, + value: ['Declaration', 'Selector'] +}; + +function getFeatureParser(kind, name) { + const featuresOfKind = this.features[kind] || {}; + const parser = featuresOfKind[name]; + + if (typeof parser !== 'function') { + this.error(`Unknown feature ${name}()`); + } + + return parser; +} + +function parse(kind = 'unknown') { + const start = this.tokenStart; + const functionName = this.consumeFunctionName(); + const valueParser = getFeatureParser.call(this, kind, functionName.toLowerCase()); + + this.skipSC(); + + const value = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const value = valueParser.call(this); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; + }, + () => this.Raw(null, false) + ); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'FeatureFunction', + loc: this.getLocation(start, this.tokenStart), + kind, + feature: functionName, + value + }; +} + +function generate(node) { + this.token(types.Function, node.feature + '('); + this.node(node.value); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs new file mode 100644 index 0000000..f6730c2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs @@ -0,0 +1,133 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const LESSTHANSIGN = 0x003C; // U+003C LESS-THAN SIGN (<) +const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) + +const name = 'FeatureRange'; +const structure = { + kind: String, + left: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'], + leftComparison: String, + middle: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'], + rightComparison: [String, null], + right: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null] +}; + +function readTerm() { + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.isDelim(SOLIDUS, this.lookupOffsetNonSC(1))) { + return this.Ratio(); + } else { + return this.Number(); + } + + case types.Dimension: + return this.Dimension(); + + case types.Ident: + return this.Identifier(); + + case types.Function: + return this.parseWithFallback( + () => { + const res = this.Function(this.readSequence, this.scope.Value); + + this.skipSC(); + + if (this.isDelim(SOLIDUS)) { + this.error(); + } + + return res; + }, + () => { + return this.Ratio(); + } + ); + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } +} + +function readComparison(expectColon) { + this.skipSC(); + + if (this.isDelim(LESSTHANSIGN) || + this.isDelim(GREATERTHANSIGN)) { + const value = this.source[this.tokenStart]; + + this.next(); + + if (this.isDelim(EQUALSSIGN)) { + this.next(); + return value + '='; + } + + return value; + } + + if (this.isDelim(EQUALSSIGN)) { + return '='; + } + + this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`); +} + +function parse(kind = 'unknown') { + const start = this.tokenStart; + + this.skipSC(); + this.eat(types.LeftParenthesis); + + const left = readTerm.call(this); + const leftComparison = readComparison.call(this, left.type === 'Identifier'); + const middle = readTerm.call(this); + let rightComparison = null; + let right = null; + + if (this.lookupNonWSType(0) !== types.RightParenthesis) { + rightComparison = readComparison.call(this); + right = readTerm.call(this); + } + + this.skipSC(); + this.eat(types.RightParenthesis); + + return { + type: 'FeatureRange', + loc: this.getLocation(start, this.tokenStart), + kind, + left, + leftComparison, + middle, + rightComparison, + right + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.node(node.left); + this.tokenize(node.leftComparison); + this.node(node.middle); + + if (node.right) { + this.tokenize(node.rightComparison); + this.node(node.right); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs new file mode 100644 index 0000000..b5e3b57 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs @@ -0,0 +1,45 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Function'; +const walkContext = 'function'; +const structure = { + name: String, + children: [[]] +}; + +// <function-token> <sequence> ) +function parse(readSequence, recognizer) { + const start = this.tokenStart; + const name = this.consumeFunctionName(); + const nameLowerCase = name.toLowerCase(); + let children; + + children = recognizer.hasOwnProperty(nameLowerCase) + ? recognizer[nameLowerCase].call(this, recognizer) + : readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'Function', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +function generate(node) { + this.token(types.Function, node.name + '('); + this.children(node); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs new file mode 100644 index 0000000..2a442d0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs @@ -0,0 +1,68 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'GeneralEnclosed'; +const structure = { + kind: String, + function: [String, null], + children: [[]] +}; + +// <function-token> <any-value> ) +// ( <any-value> ) +function parse(kind) { + const start = this.tokenStart; + let functionName = null; + + if (this.tokenType === types.Function) { + functionName = this.consumeFunctionName(); + } else { + this.eat(types.LeftParenthesis); + } + + const children = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const children = this.readSequence(this.scope.Value); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return children; + }, + () => this.createSingleNodeList( + this.Raw(null, false) + ) + ); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'GeneralEnclosed', + loc: this.getLocation(start, this.tokenStart), + kind, + function: functionName, + children + }; +} + +function generate(node) { + if (node.function) { + this.token(types.Function, node.function + '('); + } else { + this.token(types.LeftParenthesis, '('); + } + + this.children(node); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs new file mode 100644 index 0000000..8b5f375 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs @@ -0,0 +1,30 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +// '#' ident +const xxx = 'XXX'; +const name = 'Hash'; +const structure = { + value: String +}; +function parse() { + const start = this.tokenStart; + + this.eat(types.Hash); + + return { + type: 'Hash', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start + 1) + }; +} +function generate(node) { + this.token(types.Hash, '#' + node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.xxx = xxx; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs new file mode 100644 index 0000000..264525d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs @@ -0,0 +1,33 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'IdSelector'; +const structure = { + name: String +}; + +function parse() { + const start = this.tokenStart; + + // TODO: check value is an ident + this.eat(types.Hash); + + return { + type: 'IdSelector', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start + 1) + }; +} + +function generate(node) { + // Using Delim instead of Hash is a hack to avoid for a whitespace between ident and id-selector + // in safe mode (e.g. "a#id"), because IE11 doesn't allow a sequence <ident-token> <hash-token> + // without a whitespace in values (e.g. "1px solid#000") + this.token(types.Delim, '#' + node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs new file mode 100644 index 0000000..8928cf8 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Identifier'; +const structure = { + name: String +}; + +function parse() { + return { + type: 'Identifier', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + name: this.consume(types.Ident) + }; +} + +function generate(node) { + this.token(types.Ident, node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs new file mode 100644 index 0000000..a748046 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs @@ -0,0 +1,35 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +const name = 'Layer'; +const structure = { + name: String +}; + +function parse() { + let tokenStart = this.tokenStart; + let name = this.consume(types.Ident); + + while (this.isDelim(FULLSTOP)) { + this.eat(types.Delim); + name += '.' + this.consume(types.Ident); + } + + return { + type: 'Layer', + loc: this.getLocation(tokenStart, this.tokenStart), + name + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs new file mode 100644 index 0000000..0ce29f5 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs @@ -0,0 +1,43 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'LayerList'; +const structure = { + children: [[ + 'Layer' + ]] +}; + +function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.Layer()); + + if (this.lookupTypeNonSC(0) !== types.Comma) { + break; + } + + this.skipSC(); + this.next(); + this.skipSC(); + } + + return { + type: 'LayerList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs new file mode 100644 index 0000000..97ac9b7 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs @@ -0,0 +1,34 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +const name = 'LayerName'; +const structure = { + name: String +}; + +function parse() { + let name = this.consume(types.Ident); + + while (this.isDelim(FULLSTOP)) { + this.eat(types.Delim); + name += '.' + this.consume(types.Ident); + } + + return { + type: 'LayerName', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + name + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs new file mode 100644 index 0000000..e35140d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs @@ -0,0 +1,42 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'LayerNameList'; +const structure = { + children: [[ + 'MediaQuery' + ]] +}; + +function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.LayerName()); + + if (this.tokenType !== types.Comma) { + break; + } + + this.next(); + this.skipSC(); + } + + return { + type: 'LayerNameList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs new file mode 100644 index 0000000..c98fdc8 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs @@ -0,0 +1,70 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const MediaFeatureToken = new Set([types.Colon, types.RightParenthesis, types.EOF]); + +const name = 'MediaCondition'; +const structure = { + children: [[ + 'Identifier', + 'MediaFeature', + 'MediaFeatureRange' + ]] +}; + +function parse() { + const children = this.createList(); + + scan: while (!this.eof) { + switch (this.tokenType) { + case types.Comment: + case types.WhiteSpace: + this.next(); + continue; + + case types.Ident: + children.push(this.Identifier()); + break; + + case types.LeftParenthesis: + if (this.lookupTypeNonSC(1) === types.Ident && MediaFeatureToken.has(this.lookupTypeNonSC(2))) { + children.push(this.MediaFeature()); + } else if (this.lookupTypeNonSC(1) === types.LeftParenthesis || this.lookupTypeNonSC(2) === types.LeftParenthesis) { + this.next(); + children.push(this.MediaCondition()); + this.eat(types.RightParenthesis); + } else { + children.push(this.MediaFeatureRange()); + } + + break; + + default: + break scan; + } + } + + return { + type: 'MediaCondition', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + node.children.forEach(child => { + if (child.type === 'MediaCondition') { + this.token(types.LeftParenthesis, '('); + this.node(child); + this.token(types.RightParenthesis, ')'); + } else { + this.node(child); + } + }); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs new file mode 100644 index 0000000..90e8d5a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs @@ -0,0 +1,76 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'MediaFeature'; +const structure = { + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', null] +}; + +function parse() { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + name = this.consume(types.Ident); + this.skipSC(); + + if (this.tokenType !== types.RightParenthesis) { + this.eat(types.Colon); + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case types.Dimension: + value = this.Dimension(); + break; + + case types.Ident: + value = this.Identifier(); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + this.eat(types.RightParenthesis); + + return { + type: 'MediaFeature', + loc: this.getLocation(start, this.tokenStart), + name, + value + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.token(types.Ident, node.name); + + if (node.value !== null) { + this.token(types.Colon, ':'); + this.node(node.value); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs new file mode 100644 index 0000000..8be899f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs @@ -0,0 +1,11 @@ +'use strict'; + +const featureRange = require('./common/feature-range.cjs'); + +const name = 'MediaFeatureRange'; +const parse = featureRange.createParse(name); + +exports.generate = featureRange.generate; +exports.structure = featureRange.structure; +exports.name = name; +exports.parse = parse; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs new file mode 100644 index 0000000..776efdd --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs @@ -0,0 +1,100 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'MediaQuery'; +const structure = { + modifier: [String, null], + mediaType: [String, null], + condition: ['Condition', null] +}; + +function parse() { + const start = this.tokenStart; + let modifier = null; + let mediaType = null; + let condition = null; + + this.skipSC(); + + if (this.tokenType === types.Ident && this.lookupTypeNonSC(1) !== types.LeftParenthesis) { + // [ not | only ]? <media-type> + const ident = this.consume(types.Ident); + const identLowerCase = ident.toLowerCase(); + + if (identLowerCase === 'not' || identLowerCase === 'only') { + this.skipSC(); + modifier = identLowerCase; + mediaType = this.consume(types.Ident); + } else { + mediaType = ident; + } + + switch (this.lookupTypeNonSC(0)) { + case types.Ident: { + // and <media-condition-without-or> + this.skipSC(); + this.eatIdent('and'); + condition = this.Condition('media'); + break; + } + + case types.LeftCurlyBracket: + case types.Semicolon: + case types.Comma: + case types.EOF: + break; + + default: + this.error('Identifier or parenthesis is expected'); + } + } else { + switch (this.tokenType) { + case types.Ident: + case types.LeftParenthesis: + case types.Function: { + // <media-condition> + condition = this.Condition('media'); + break; + } + + case types.LeftCurlyBracket: + case types.Semicolon: + case types.EOF: + break; + + default: + this.error('Identifier or parenthesis is expected'); + } + } + + return { + type: 'MediaQuery', + loc: this.getLocation(start, this.tokenStart), + modifier, + mediaType, + condition + }; +} + +function generate(node) { + if (node.mediaType) { + if (node.modifier) { + this.token(types.Ident, node.modifier); + } + + this.token(types.Ident, node.mediaType); + + if (node.condition) { + this.token(types.Ident, 'and'); + this.node(node.condition); + } + } else if (node.condition) { + this.node(node.condition); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs new file mode 100644 index 0000000..3877947 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs @@ -0,0 +1,41 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'MediaQueryList'; +const structure = { + children: [[ + 'MediaQuery' + ]] +}; + +function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.MediaQuery()); + + if (this.tokenType !== types.Comma) { + break; + } + + this.next(); + } + + return { + type: 'MediaQueryList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs new file mode 100644 index 0000000..9850a9c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs @@ -0,0 +1,29 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +const name = 'NestingSelector'; +const structure = { +}; + +function parse() { + const start = this.tokenStart; + + this.eatDelim(AMPERSAND); + + return { + type: 'NestingSelector', + loc: this.getLocation(start, this.tokenStart) + }; +} + +function generate() { + this.token(types.Delim, '&'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs new file mode 100644 index 0000000..709312f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs @@ -0,0 +1,54 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Nth'; +const structure = { + nth: ['AnPlusB', 'Identifier'], + selector: ['SelectorList', null] +}; + +function parse() { + this.skipSC(); + + const start = this.tokenStart; + let end = start; + let selector = null; + let nth; + + if (this.lookupValue(0, 'odd') || this.lookupValue(0, 'even')) { + nth = this.Identifier(); + } else { + nth = this.AnPlusB(); + } + + end = this.tokenStart; + this.skipSC(); + + if (this.lookupValue(0, 'of')) { + this.next(); + + selector = this.SelectorList(); + end = this.tokenStart; + } + + return { + type: 'Nth', + loc: this.getLocation(start, end), + nth, + selector + }; +} + +function generate(node) { + this.node(node.nth); + if (node.selector !== null) { + this.token(types.Ident, 'of'); + this.node(node.selector); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs new file mode 100644 index 0000000..8abd9ae --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Number'; +const structure = { + value: String +}; + +function parse() { + return { + type: 'Number', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: this.consume(types.Number) + }; +} + +function generate(node) { + this.token(types.Number, node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs new file mode 100644 index 0000000..c5a513b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs @@ -0,0 +1,28 @@ +'use strict'; + +// '/' | '*' | ',' | ':' | '+' | '-' +const name = 'Operator'; +const structure = { + value: String +}; + +function parse() { + const start = this.tokenStart; + + this.next(); + + return { + type: 'Operator', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start) + }; +} + +function generate(node) { + this.tokenize(node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs new file mode 100644 index 0000000..7c14bc6 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Parentheses'; +const structure = { + children: [[]] +}; + +function parse(readSequence, recognizer) { + const start = this.tokenStart; + let children = null; + + this.eat(types.LeftParenthesis); + + children = readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'Parentheses', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.children(node); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs new file mode 100644 index 0000000..38cc1d5 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Percentage'; +const structure = { + value: String +}; + +function parse() { + return { + type: 'Percentage', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: this.consumeNumber(types.Percentage) + }; +} + +function generate(node) { + this.token(types.Percentage, node.value + '%'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs new file mode 100644 index 0000000..f5fa0da --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs @@ -0,0 +1,67 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'PseudoClassSelector'; +const walkContext = 'function'; +const structure = { + name: String, + children: [['Raw'], null] +}; + +// : [ <ident> | <function-token> <any-value>? ) ] +function parse() { + const start = this.tokenStart; + let children = null; + let name; + let nameLowerCase; + + this.eat(types.Colon); + + if (this.tokenType === types.Function) { + name = this.consumeFunctionName(); + nameLowerCase = name.toLowerCase(); + + if (this.lookupNonWSType(0) == types.RightParenthesis) { + children = this.createList(); + } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) { + this.skipSC(); + children = this.pseudo[nameLowerCase].call(this); + this.skipSC(); + } else { + children = this.createList(); + children.push( + this.Raw(null, false) + ); + } + + this.eat(types.RightParenthesis); + } else { + name = this.consume(types.Ident); + } + + return { + type: 'PseudoClassSelector', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +function generate(node) { + this.token(types.Colon, ':'); + + if (node.children === null) { + this.token(types.Ident, node.name); + } else { + this.token(types.Function, node.name + '('); + this.children(node); + this.token(types.RightParenthesis, ')'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs new file mode 100644 index 0000000..f998968 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs @@ -0,0 +1,69 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'PseudoElementSelector'; +const walkContext = 'function'; +const structure = { + name: String, + children: [['Raw'], null] +}; + +// :: [ <ident> | <function-token> <any-value>? ) ] +function parse() { + const start = this.tokenStart; + let children = null; + let name; + let nameLowerCase; + + this.eat(types.Colon); + this.eat(types.Colon); + + if (this.tokenType === types.Function) { + name = this.consumeFunctionName(); + nameLowerCase = name.toLowerCase(); + + if (this.lookupNonWSType(0) == types.RightParenthesis) { + children = this.createList(); + } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) { + this.skipSC(); + children = this.pseudo[nameLowerCase].call(this); + this.skipSC(); + } else { + children = this.createList(); + children.push( + this.Raw(null, false) + ); + } + + this.eat(types.RightParenthesis); + } else { + name = this.consume(types.Ident); + } + + return { + type: 'PseudoElementSelector', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +function generate(node) { + this.token(types.Colon, ':'); + this.token(types.Colon, ':'); + + if (node.children === null) { + this.token(types.Ident, node.name); + } else { + this.token(types.Function, node.name + '('); + this.children(node); + this.token(types.RightParenthesis, ')'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs new file mode 100644 index 0000000..69b71ea --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs @@ -0,0 +1,71 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +// Media Queries Level 3 defines terms of <ratio> as a positive (not zero or negative) +// integers (see https://drafts.csswg.org/mediaqueries-3/#values) +// However, Media Queries Level 4 removes any definition of values +// (see https://drafts.csswg.org/mediaqueries-4/#values) and refers to +// CSS Values and Units for detail. In CSS Values and Units Level 4 a <ratio> +// definition was added (see https://drafts.csswg.org/css-values-4/#ratios) which +// defines ratio as "<number [0,∞]> [ / <number [0,∞]> ]?" and based on it +// any constrains on terms were removed. Parser also doesn't test numbers +// in any way to make possible for linting and fixing them by the tools using CSSTree. +// An additional syntax examination may be applied by a lexer. +function consumeTerm() { + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + return this.Number(); + + case types.Function: + return this.Function(this.readSequence, this.scope.Value); + + default: + this.error('Number of function is expected'); + } +} + +const name = 'Ratio'; +const structure = { + left: ['Number', 'Function'], + right: ['Number', 'Function', null] +}; + +// <number [0,∞]> [ / <number [0,∞]> ]? +function parse() { + const start = this.tokenStart; + const left = consumeTerm.call(this); + let right = null; + + this.skipSC(); + if (this.isDelim(SOLIDUS)) { + this.eatDelim(SOLIDUS); + right = consumeTerm.call(this); + } + + return { + type: 'Ratio', + loc: this.getLocation(start, this.tokenStart), + left, + right + }; +} + +function generate(node) { + this.node(node.left); + this.token(types.Delim, '/'); + if (node.right) { + this.node(node.right); + } else { + this.node(types.Number, 1); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs new file mode 100644 index 0000000..5b92f74 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs @@ -0,0 +1,48 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function getOffsetExcludeWS() { + if (this.tokenIndex > 0) { + if (this.lookupType(-1) === types.WhiteSpace) { + return this.tokenIndex > 1 + ? this.getTokenStart(this.tokenIndex - 1) + : this.firstCharOffset; + } + } + + return this.tokenStart; +} + +const name = 'Raw'; +const structure = { + value: String +}; + +function parse(consumeUntil, excludeWhiteSpace) { + const startOffset = this.getTokenStart(this.tokenIndex); + let endOffset; + + this.skipUntilBalanced(this.tokenIndex, consumeUntil || this.consumeUntilBalanceEnd); + + if (excludeWhiteSpace && this.tokenStart > startOffset) { + endOffset = getOffsetExcludeWS.call(this); + } else { + endOffset = this.tokenStart; + } + + return { + type: 'Raw', + loc: this.getLocation(startOffset, endOffset), + value: this.substring(startOffset, endOffset) + }; +} + +function generate(node) { + this.tokenize(node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs new file mode 100644 index 0000000..e03dbe0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs @@ -0,0 +1,58 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function consumeRaw() { + return this.Raw(this.consumeUntilLeftCurlyBracket, true); +} + +function consumePrelude() { + const prelude = this.SelectorList(); + + if (prelude.type !== 'Raw' && + this.eof === false && + this.tokenType !== types.LeftCurlyBracket) { + this.error(); + } + + return prelude; +} + +const name = 'Rule'; +const walkContext = 'rule'; +const structure = { + prelude: ['SelectorList', 'Raw'], + block: ['Block'] +}; + +function parse() { + const startToken = this.tokenIndex; + const startOffset = this.tokenStart; + let prelude; + let block; + + if (this.parseRulePrelude) { + prelude = this.parseWithFallback(consumePrelude, consumeRaw); + } else { + prelude = consumeRaw.call(this, startToken); + } + + block = this.Block(true); + + return { + type: 'Rule', + loc: this.getLocation(startOffset, this.tokenStart), + prelude, + block + }; +} +function generate(node) { + this.node(node.prelude); + this.node(node.block); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs new file mode 100644 index 0000000..1320b04 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs @@ -0,0 +1,69 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Scope'; +const structure = { + root: ['SelectorList', 'Raw', null], + limit: ['SelectorList', 'Raw', null] +}; + +function parse() { + let root = null; + let limit = null; + + this.skipSC(); + + const startOffset = this.tokenStart; + if (this.tokenType === types.LeftParenthesis) { + this.next(); + this.skipSC(); + root = this.parseWithFallback( + this.SelectorList, + () => this.Raw(false, true) + ); + this.skipSC(); + this.eat(types.RightParenthesis); + } + + if (this.lookupNonWSType(0) === types.Ident) { + this.skipSC(); + this.eatIdent('to'); + this.skipSC(); + this.eat(types.LeftParenthesis); + this.skipSC(); + limit = this.parseWithFallback( + this.SelectorList, + () => this.Raw(false, true) + ); + this.skipSC(); + this.eat(types.RightParenthesis); + } + + return { + type: 'Scope', + loc: this.getLocation(startOffset, this.tokenStart), + root, + limit + }; +} + +function generate(node) { + if (node.root) { + this.token(types.LeftParenthesis, '('); + this.node(node.root); + this.token(types.RightParenthesis, ')'); + } + + if (node.limit) { + this.token(types.Ident, 'to'); + this.token(types.LeftParenthesis, '('); + this.node(node.limit); + this.token(types.RightParenthesis, ')'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs new file mode 100644 index 0000000..f836975 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const name = 'Selector'; +const structure = { + children: [[ + 'TypeSelector', + 'IdSelector', + 'ClassSelector', + 'AttributeSelector', + 'PseudoClassSelector', + 'PseudoElementSelector', + 'Combinator' + ]] +}; + +function parse() { + const children = this.readSequence(this.scope.Selector); + + // nothing were consumed + if (this.getFirstListNode(children) === null) { + this.error('Selector is expected'); + } + + return { + type: 'Selector', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs new file mode 100644 index 0000000..7ecf09b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs @@ -0,0 +1,43 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'SelectorList'; +const walkContext = 'selector'; +const structure = { + children: [[ + 'Selector', + 'Raw' + ]] +}; + +function parse() { + const children = this.createList(); + + while (!this.eof) { + children.push(this.Selector()); + + if (this.tokenType === types.Comma) { + this.next(); + continue; + } + + break; + } + + return { + type: 'SelectorList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs new file mode 100644 index 0000000..8a7801e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const string = require('../../utils/string.cjs'); +const types = require('../../tokenizer/types.cjs'); + +const name = 'String'; +const structure = { + value: String +}; + +function parse() { + return { + type: 'String', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: string.decode(this.consume(types.String)) + }; +} + +function generate(node) { + this.token(types.String, string.encode(node.value)); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs new file mode 100644 index 0000000..6e48f05 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs @@ -0,0 +1,83 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) + +function consumeRaw() { + return this.Raw(null, false); +} + +const name = 'StyleSheet'; +const walkContext = 'stylesheet'; +const structure = { + children: [[ + 'Comment', + 'CDO', + 'CDC', + 'Atrule', + 'Rule', + 'Raw' + ]] +}; + +function parse() { + const start = this.tokenStart; + const children = this.createList(); + let child; + + while (!this.eof) { + switch (this.tokenType) { + case types.WhiteSpace: + this.next(); + continue; + + case types.Comment: + // ignore comments except exclamation comments (i.e. /*! .. */) on top level + if (this.charCodeAt(this.tokenStart + 2) !== EXCLAMATIONMARK) { + this.next(); + continue; + } + + child = this.Comment(); + break; + + case types.CDO: // <!-- + child = this.CDO(); + break; + + case types.CDC: // --> + child = this.CDC(); + break; + + // CSS Syntax Module Level 3 + // §2.2 Error handling + // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule. + case types.AtKeyword: + child = this.parseWithFallback(this.Atrule, consumeRaw); + break; + + // Anything else starts a qualified rule ... + default: + child = this.parseWithFallback(this.Rule, consumeRaw); + } + + children.push(child); + } + + return { + type: 'StyleSheet', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs new file mode 100644 index 0000000..fcac089 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'SupportsDeclaration'; +const structure = { + declaration: 'Declaration' +}; + +function parse() { + const start = this.tokenStart; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + const declaration = this.Declaration(); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'SupportsDeclaration', + loc: this.getLocation(start, this.tokenStart), + declaration + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.node(node.declaration); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs new file mode 100644 index 0000000..e569a5c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs @@ -0,0 +1,69 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'SupportsDeclaration'; +const structure = { + feature: String, + value: 'Declaration' +}; + +function parse() { + const start = this.tokenStart; + let featureName = 'declaration'; + let valueParser = this.Declaration; + + if (this.tokenType === types.Function) { + featureName = this.consumeFunctionName(); + valueParser = this.supportsFeature[featureName.toLowerCase()]; + if (!valueParser) { + this.error(`Unknown supports feature ${featureName.toLowerCase()}()`); + } + } else { + this.eat(types.LeftParenthesis); + } + + this.skipSC(); + + const value = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const value = valueParser.call(this); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; + }, + (startToken) => this.Raw(startToken, null, false) + ); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'SupportsDeclaration', + loc: this.getLocation(start, this.tokenStart), + feature: featureName, + value + }; +} + +function generate(node) { + if (node.feature !== 'declaration') { + this.token(types.Function, node.feature + '('); + } else { + this.token(types.LeftParenthesis, '('); + } + + this.node(node.value); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs new file mode 100644 index 0000000..1d15270 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs @@ -0,0 +1,59 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) + +function eatIdentifierOrAsterisk() { + if (this.tokenType !== types.Ident && + this.isDelim(ASTERISK) === false) { + this.error('Identifier or asterisk is expected'); + } + + this.next(); +} + +const name = 'TypeSelector'; +const structure = { + name: String +}; + +// ident +// ident|ident +// ident|* +// * +// *|ident +// *|* +// |ident +// |* +function parse() { + const start = this.tokenStart; + + if (this.isDelim(VERTICALLINE)) { + this.next(); + eatIdentifierOrAsterisk.call(this); + } else { + eatIdentifierOrAsterisk.call(this); + + if (this.isDelim(VERTICALLINE)) { + this.next(); + eatIdentifierOrAsterisk.call(this); + } + } + + return { + type: 'TypeSelector', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start) + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs new file mode 100644 index 0000000..5585e8f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs @@ -0,0 +1,158 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); +const charCodeDefinitions = require('../../tokenizer/char-code-definitions.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?) + +function eatHexSequence(offset, allowDash) { + let len = 0; + + for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) { + const code = this.charCodeAt(pos); + + if (code === HYPHENMINUS && allowDash && len !== 0) { + eatHexSequence.call(this, offset + len + 1, false); + return -1; + } + + if (!charCodeDefinitions.isHexDigit(code)) { + this.error( + allowDash && len !== 0 + ? 'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected' + : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'), + pos + ); + } + + if (++len > 6) { + this.error('Too many hex digits', pos); + } } + + this.next(); + return len; +} + +function eatQuestionMarkSequence(max) { + let count = 0; + + while (this.isDelim(QUESTIONMARK)) { + if (++count > max) { + this.error('Too many question marks'); + } + + this.next(); + } +} + +function startsWith(code) { + if (this.charCodeAt(this.tokenStart) !== code) { + this.error((code === PLUSSIGN ? 'Plus sign' : 'Hyphen minus') + ' is expected'); + } +} + +// https://drafts.csswg.org/css-syntax/#urange +// Informally, the <urange> production has three forms: +// U+0001 +// Defines a range consisting of a single code point, in this case the code point "1". +// U+0001-00ff +// Defines a range of codepoints between the first and the second value, in this case +// the range between "1" and "ff" (255 in decimal) inclusive. +// U+00?? +// Defines a range of codepoints where the "?" characters range over all hex digits, +// in this case defining the same as the value U+0000-00ff. +// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit). +// +// <urange> = +// u '+' <ident-token> '?'* | +// u <dimension-token> '?'* | +// u <number-token> '?'* | +// u <number-token> <dimension-token> | +// u <number-token> <number-token> | +// u '+' '?'+ +function scanUnicodeRange() { + let hexLength = 0; + + switch (this.tokenType) { + case types.Number: + // u <number-token> '?'* + // u <number-token> <dimension-token> + // u <number-token> <number-token> + hexLength = eatHexSequence.call(this, 1, true); + + if (this.isDelim(QUESTIONMARK)) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + break; + } + + if (this.tokenType === types.Dimension || + this.tokenType === types.Number) { + startsWith.call(this, HYPHENMINUS); + eatHexSequence.call(this, 1, false); + break; + } + + break; + + case types.Dimension: + // u <dimension-token> '?'* + hexLength = eatHexSequence.call(this, 1, true); + + if (hexLength > 0) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + } + + break; + + default: + // u '+' <ident-token> '?'* + // u '+' '?'+ + this.eatDelim(PLUSSIGN); + + if (this.tokenType === types.Ident) { + hexLength = eatHexSequence.call(this, 0, true); + if (hexLength > 0) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + } + break; + } + + if (this.isDelim(QUESTIONMARK)) { + this.next(); + eatQuestionMarkSequence.call(this, 5); + break; + } + + this.error('Hex digit or question mark is expected'); + } +} + +const name = 'UnicodeRange'; +const structure = { + value: String +}; + +function parse() { + const start = this.tokenStart; + + // U or u + this.eatIdent('u'); + scanUnicodeRange.call(this); + + return { + type: 'UnicodeRange', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start) + }; +} + +function generate(node) { + this.tokenize(node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs new file mode 100644 index 0000000..6a39457 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs @@ -0,0 +1,54 @@ +'use strict'; + +const url = require('../../utils/url.cjs'); +const string = require('../../utils/string.cjs'); +const types = require('../../tokenizer/types.cjs'); + +const name = 'Url'; +const structure = { + value: String +}; + +// <url-token> | <function-token> <string> ) +function parse() { + const start = this.tokenStart; + let value; + + switch (this.tokenType) { + case types.Url: + value = url.decode(this.consume(types.Url)); + break; + + case types.Function: + if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) { + this.error('Function name must be `url`'); + } + + this.eat(types.Function); + this.skipSC(); + value = string.decode(this.consume(types.String)); + this.skipSC(); + if (!this.eof) { + this.eat(types.RightParenthesis); + } + break; + + default: + this.error('Url or Function is expected'); + } + + return { + type: 'Url', + loc: this.getLocation(start, this.tokenStart), + value + }; +} + +function generate(node) { + this.token(types.Url, url.encode(node.value)); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs new file mode 100644 index 0000000..bdb322e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const name = 'Value'; +const structure = { + children: [[]] +}; + +function parse() { + const start = this.tokenStart; + const children = this.readSequence(this.scope.Value); + + return { + type: 'Value', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs new file mode 100644 index 0000000..50c1982 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs @@ -0,0 +1,34 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SPACE = Object.freeze({ + type: 'WhiteSpace', + loc: null, + value: ' ' +}); + +const name = 'WhiteSpace'; +const structure = { + value: String +}; + +function parse() { + this.eat(types.WhiteSpace); + return SPACE; + + // return { + // type: 'WhiteSpace', + // loc: this.getLocation(this.tokenStart, this.tokenEnd), + // value: this.consume(WHITESPACE) + // }; +} + +function generate(node) { + this.token(types.WhiteSpace, node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs new file mode 100644 index 0000000..7589b56 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs @@ -0,0 +1,112 @@ +'use strict'; + +const types = require('../../../tokenizer/types.cjs'); + +const LESSTHANSIGN = 60; // < +const EQUALSIGN = 61; // = +const GREATERTHANSIGN = 62; // > + +const structure = { + left: ['Identifier', 'Number', 'Dimension', 'Ratio'], + leftComparison: String, + middle: ['Identifier', 'Number', 'Dimension', 'Ratio'], + rightComparison: [String, null], + right: ['Identifier', 'Number', 'Dimension', 'Ratio', null] +}; + +function readTerm() { + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + return this.Ratio(); + } else { + return this.Number(); + } + + case types.Dimension: + return this.Dimension(); + + case types.Ident: + return this.Identifier(); + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } +} + +function readComparison(expectColon) { + this.skipSC(); + + if (this.isDelim(LESSTHANSIGN) || + this.isDelim(GREATERTHANSIGN)) { + const value = this.source[this.tokenStart]; + + this.next(); + + if (this.isDelim(EQUALSIGN)) { + this.next(); + return value + '='; + } + + return value; + } + + if (this.isDelim(EQUALSIGN)) { + return '='; + } + + this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`); +} + +function createParse(type) { + return function parse() { + const start = this.tokenStart; + + this.skipSC(); + this.eat(types.LeftParenthesis); + + const left = readTerm.call(this); + const leftComparison = readComparison.call(this, left.type === 'Identifier'); + const middle = readTerm.call(this); + let rightComparison = null; + let right = null; + + if (this.lookupNonWSType(0) !== types.RightParenthesis) { + rightComparison = readComparison.call(this); + right = readTerm.call(this); + } + + this.skipSC(); + this.eat(types.RightParenthesis); + + return { + type, + loc: this.getLocation(start, this.tokenStart), + left, + leftComparison, + middle, + rightComparison, + right + }; + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.node(node.left); + this.tokenize(node.leftComparison); + this.node(node.middle); + + if (node.right) { + this.tokenize(node.rightComparison); + this.node(node.right); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.createParse = createParse; +exports.generate = generate; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs new file mode 100644 index 0000000..fa5de4e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs @@ -0,0 +1,76 @@ +'use strict'; + +const types = require('../../../tokenizer/types.cjs'); + +const structure = { + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', null] +}; + +function createParse(type) { + return function parse() { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + name = this.consume(types.Ident); + this.skipSC(); + + if (this.tokenType !== types.RightParenthesis) { + this.eat(types.Colon); + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case types.Dimension: + value = this.Dimension(); + break; + + case types.Ident: + value = this.Identifier(); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + this.eat(types.RightParenthesis); + + return { + type, + loc: this.getLocation(start, this.tokenStart), + name, + value + }; + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.token(types.Ident, node.name); + + if (node.value !== null) { + this.token(types.Colon, ':'); + this.node(node.value); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.createParse = createParse; +exports.generate = generate; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs new file mode 100644 index 0000000..41a4ef1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const Atrule = require('./Atrule.cjs'); +const AtrulePrelude = require('./AtrulePrelude.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const Block = require('./Block.cjs'); +const Brackets = require('./Brackets.cjs'); +const CDC = require('./CDC.cjs'); +const CDO = require('./CDO.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Comment = require('./Comment.cjs'); +const Condition = require('./Condition.cjs'); +const Declaration = require('./Declaration.cjs'); +const DeclarationList = require('./DeclarationList.cjs'); +const Dimension = require('./Dimension.cjs'); +const Feature = require('./Feature.cjs'); +const FeatureFunction = require('./FeatureFunction.cjs'); +const FeatureRange = require('./FeatureRange.cjs'); +const Function = require('./Function.cjs'); +const GeneralEnclosed = require('./GeneralEnclosed.cjs'); +const Hash = require('./Hash.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const Layer = require('./Layer.cjs'); +const LayerList = require('./LayerList.cjs'); +const MediaQuery = require('./MediaQuery.cjs'); +const MediaQueryList = require('./MediaQueryList.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Number = require('./Number.cjs'); +const Operator = require('./Operator.cjs'); +const Parentheses = require('./Parentheses.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Ratio = require('./Ratio.cjs'); +const Raw = require('./Raw.cjs'); +const Rule = require('./Rule.cjs'); +const Scope = require('./Scope.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String = require('./String.cjs'); +const StyleSheet = require('./StyleSheet.cjs'); +const SupportsDeclaration = require('./SupportsDeclaration.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); +const UnicodeRange = require('./UnicodeRange.cjs'); +const Url = require('./Url.cjs'); +const Value = require('./Value.cjs'); +const WhiteSpace = require('./WhiteSpace.cjs'); + + + +exports.AnPlusB = AnPlusB.generate; +exports.Atrule = Atrule.generate; +exports.AtrulePrelude = AtrulePrelude.generate; +exports.AttributeSelector = AttributeSelector.generate; +exports.Block = Block.generate; +exports.Brackets = Brackets.generate; +exports.CDC = CDC.generate; +exports.CDO = CDO.generate; +exports.ClassSelector = ClassSelector.generate; +exports.Combinator = Combinator.generate; +exports.Comment = Comment.generate; +exports.Condition = Condition.generate; +exports.Declaration = Declaration.generate; +exports.DeclarationList = DeclarationList.generate; +exports.Dimension = Dimension.generate; +exports.Feature = Feature.generate; +exports.FeatureFunction = FeatureFunction.generate; +exports.FeatureRange = FeatureRange.generate; +exports.Function = Function.generate; +exports.GeneralEnclosed = GeneralEnclosed.generate; +exports.Hash = Hash.generate; +exports.Identifier = Identifier.generate; +exports.IdSelector = IdSelector.generate; +exports.Layer = Layer.generate; +exports.LayerList = LayerList.generate; +exports.MediaQuery = MediaQuery.generate; +exports.MediaQueryList = MediaQueryList.generate; +exports.NestingSelector = NestingSelector.generate; +exports.Nth = Nth.generate; +exports.Number = Number.generate; +exports.Operator = Operator.generate; +exports.Parentheses = Parentheses.generate; +exports.Percentage = Percentage.generate; +exports.PseudoClassSelector = PseudoClassSelector.generate; +exports.PseudoElementSelector = PseudoElementSelector.generate; +exports.Ratio = Ratio.generate; +exports.Raw = Raw.generate; +exports.Rule = Rule.generate; +exports.Scope = Scope.generate; +exports.Selector = Selector.generate; +exports.SelectorList = SelectorList.generate; +exports.String = String.generate; +exports.StyleSheet = StyleSheet.generate; +exports.SupportsDeclaration = SupportsDeclaration.generate; +exports.TypeSelector = TypeSelector.generate; +exports.UnicodeRange = UnicodeRange.generate; +exports.Url = Url.generate; +exports.Value = Value.generate; +exports.WhiteSpace = WhiteSpace.generate; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs new file mode 100644 index 0000000..79caf05 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs @@ -0,0 +1,39 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Operator = require('./Operator.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Raw = require('./Raw.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String = require('./String.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); + + + +exports.AnPlusB = AnPlusB.parse; +exports.AttributeSelector = AttributeSelector.parse; +exports.ClassSelector = ClassSelector.parse; +exports.Combinator = Combinator.parse; +exports.Identifier = Identifier.parse; +exports.IdSelector = IdSelector.parse; +exports.NestingSelector = NestingSelector.parse; +exports.Nth = Nth.parse; +exports.Operator = Operator.parse; +exports.Percentage = Percentage.parse; +exports.PseudoClassSelector = PseudoClassSelector.parse; +exports.PseudoElementSelector = PseudoElementSelector.parse; +exports.Raw = Raw.parse; +exports.Selector = Selector.parse; +exports.SelectorList = SelectorList.parse; +exports.String = String.parse; +exports.TypeSelector = TypeSelector.parse; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs new file mode 100644 index 0000000..050bd17 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const Atrule = require('./Atrule.cjs'); +const AtrulePrelude = require('./AtrulePrelude.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const Block = require('./Block.cjs'); +const Brackets = require('./Brackets.cjs'); +const CDC = require('./CDC.cjs'); +const CDO = require('./CDO.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Comment = require('./Comment.cjs'); +const Condition = require('./Condition.cjs'); +const Declaration = require('./Declaration.cjs'); +const DeclarationList = require('./DeclarationList.cjs'); +const Dimension = require('./Dimension.cjs'); +const Feature = require('./Feature.cjs'); +const FeatureFunction = require('./FeatureFunction.cjs'); +const FeatureRange = require('./FeatureRange.cjs'); +const Function = require('./Function.cjs'); +const GeneralEnclosed = require('./GeneralEnclosed.cjs'); +const Hash = require('./Hash.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const Layer = require('./Layer.cjs'); +const LayerList = require('./LayerList.cjs'); +const MediaQuery = require('./MediaQuery.cjs'); +const MediaQueryList = require('./MediaQueryList.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Number = require('./Number.cjs'); +const Operator = require('./Operator.cjs'); +const Parentheses = require('./Parentheses.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Ratio = require('./Ratio.cjs'); +const Raw = require('./Raw.cjs'); +const Rule = require('./Rule.cjs'); +const Scope = require('./Scope.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String = require('./String.cjs'); +const StyleSheet = require('./StyleSheet.cjs'); +const SupportsDeclaration = require('./SupportsDeclaration.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); +const UnicodeRange = require('./UnicodeRange.cjs'); +const Url = require('./Url.cjs'); +const Value = require('./Value.cjs'); +const WhiteSpace = require('./WhiteSpace.cjs'); + + + +exports.AnPlusB = AnPlusB.parse; +exports.Atrule = Atrule.parse; +exports.AtrulePrelude = AtrulePrelude.parse; +exports.AttributeSelector = AttributeSelector.parse; +exports.Block = Block.parse; +exports.Brackets = Brackets.parse; +exports.CDC = CDC.parse; +exports.CDO = CDO.parse; +exports.ClassSelector = ClassSelector.parse; +exports.Combinator = Combinator.parse; +exports.Comment = Comment.parse; +exports.Condition = Condition.parse; +exports.Declaration = Declaration.parse; +exports.DeclarationList = DeclarationList.parse; +exports.Dimension = Dimension.parse; +exports.Feature = Feature.parse; +exports.FeatureFunction = FeatureFunction.parse; +exports.FeatureRange = FeatureRange.parse; +exports.Function = Function.parse; +exports.GeneralEnclosed = GeneralEnclosed.parse; +exports.Hash = Hash.parse; +exports.Identifier = Identifier.parse; +exports.IdSelector = IdSelector.parse; +exports.Layer = Layer.parse; +exports.LayerList = LayerList.parse; +exports.MediaQuery = MediaQuery.parse; +exports.MediaQueryList = MediaQueryList.parse; +exports.NestingSelector = NestingSelector.parse; +exports.Nth = Nth.parse; +exports.Number = Number.parse; +exports.Operator = Operator.parse; +exports.Parentheses = Parentheses.parse; +exports.Percentage = Percentage.parse; +exports.PseudoClassSelector = PseudoClassSelector.parse; +exports.PseudoElementSelector = PseudoElementSelector.parse; +exports.Ratio = Ratio.parse; +exports.Raw = Raw.parse; +exports.Rule = Rule.parse; +exports.Scope = Scope.parse; +exports.Selector = Selector.parse; +exports.SelectorList = SelectorList.parse; +exports.String = String.parse; +exports.StyleSheet = StyleSheet.parse; +exports.SupportsDeclaration = SupportsDeclaration.parse; +exports.TypeSelector = TypeSelector.parse; +exports.UnicodeRange = UnicodeRange.parse; +exports.Url = Url.parse; +exports.Value = Value.parse; +exports.WhiteSpace = WhiteSpace.parse; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs new file mode 100644 index 0000000..57451f0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const Atrule = require('./Atrule.cjs'); +const AtrulePrelude = require('./AtrulePrelude.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const Block = require('./Block.cjs'); +const Brackets = require('./Brackets.cjs'); +const CDC = require('./CDC.cjs'); +const CDO = require('./CDO.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Comment = require('./Comment.cjs'); +const Condition = require('./Condition.cjs'); +const Declaration = require('./Declaration.cjs'); +const DeclarationList = require('./DeclarationList.cjs'); +const Dimension = require('./Dimension.cjs'); +const Feature = require('./Feature.cjs'); +const FeatureFunction = require('./FeatureFunction.cjs'); +const FeatureRange = require('./FeatureRange.cjs'); +const Function = require('./Function.cjs'); +const GeneralEnclosed = require('./GeneralEnclosed.cjs'); +const Hash = require('./Hash.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const Layer = require('./Layer.cjs'); +const LayerList = require('./LayerList.cjs'); +const MediaQuery = require('./MediaQuery.cjs'); +const MediaQueryList = require('./MediaQueryList.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Number$1 = require('./Number.cjs'); +const Operator = require('./Operator.cjs'); +const Parentheses = require('./Parentheses.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Ratio = require('./Ratio.cjs'); +const Raw = require('./Raw.cjs'); +const Rule = require('./Rule.cjs'); +const Scope = require('./Scope.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String$1 = require('./String.cjs'); +const StyleSheet = require('./StyleSheet.cjs'); +const SupportsDeclaration = require('./SupportsDeclaration.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); +const UnicodeRange = require('./UnicodeRange.cjs'); +const Url = require('./Url.cjs'); +const Value = require('./Value.cjs'); +const WhiteSpace = require('./WhiteSpace.cjs'); + + + +exports.AnPlusB = AnPlusB; +exports.Atrule = Atrule; +exports.AtrulePrelude = AtrulePrelude; +exports.AttributeSelector = AttributeSelector; +exports.Block = Block; +exports.Brackets = Brackets; +exports.CDC = CDC; +exports.CDO = CDO; +exports.ClassSelector = ClassSelector; +exports.Combinator = Combinator; +exports.Comment = Comment; +exports.Condition = Condition; +exports.Declaration = Declaration; +exports.DeclarationList = DeclarationList; +exports.Dimension = Dimension; +exports.Feature = Feature; +exports.FeatureFunction = FeatureFunction; +exports.FeatureRange = FeatureRange; +exports.Function = Function; +exports.GeneralEnclosed = GeneralEnclosed; +exports.Hash = Hash; +exports.Identifier = Identifier; +exports.IdSelector = IdSelector; +exports.Layer = Layer; +exports.LayerList = LayerList; +exports.MediaQuery = MediaQuery; +exports.MediaQueryList = MediaQueryList; +exports.NestingSelector = NestingSelector; +exports.Nth = Nth; +exports.Number = Number$1; +exports.Operator = Operator; +exports.Parentheses = Parentheses; +exports.Percentage = Percentage; +exports.PseudoClassSelector = PseudoClassSelector; +exports.PseudoElementSelector = PseudoElementSelector; +exports.Ratio = Ratio; +exports.Raw = Raw; +exports.Rule = Rule; +exports.Scope = Scope; +exports.Selector = Selector; +exports.SelectorList = SelectorList; +exports.String = String$1; +exports.StyleSheet = StyleSheet; +exports.SupportsDeclaration = SupportsDeclaration; +exports.TypeSelector = TypeSelector; +exports.UnicodeRange = UnicodeRange; +exports.Url = Url; +exports.Value = Value; +exports.WhiteSpace = WhiteSpace; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs new file mode 100644 index 0000000..37ad6b8 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs @@ -0,0 +1,60 @@ +'use strict'; + +const lang = require('./lang.cjs'); + +const selectorList = { + parse() { + return this.createSingleNodeList( + this.SelectorList() + ); + } +}; + +const selector = { + parse() { + return this.createSingleNodeList( + this.Selector() + ); + } +}; + +const identList = { + parse() { + return this.createSingleNodeList( + this.Identifier() + ); + } +}; + +const langList = { + parse: lang.parseLanguageRangeList +}; + +const nth = { + parse() { + return this.createSingleNodeList( + this.Nth() + ); + } +}; + +const pseudo = { + 'dir': identList, + 'has': selectorList, + 'lang': langList, + 'matches': selectorList, + 'is': selectorList, + '-moz-any': selectorList, + '-webkit-any': selectorList, + 'where': selectorList, + 'not': selectorList, + 'nth-child': nth, + 'nth-last-child': nth, + 'nth-last-of-type': nth, + 'nth-of-type': nth, + 'slotted': selector, + 'host': selector, + 'host-context': selector +}; + +module.exports = pseudo; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs new file mode 100644 index 0000000..6b80ee1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs @@ -0,0 +1,37 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function parseLanguageRangeList() { + const children = this.createList(); + + this.skipSC(); + + loop: while (!this.eof) { + switch (this.tokenType) { + case types.Ident: + children.push(this.Identifier()); + break; + + case types.String: + children.push(this.String()); + break; + + case types.Comma: + children.push(this.Operator()); + break; + + case types.RightParenthesis: + break loop; + + default: + this.error('Identifier, string or comma is expected'); + } + + this.skipSC(); + } + + return children; +} + +exports.parseLanguageRangeList = parseLanguageRangeList; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs new file mode 100644 index 0000000..65a1544 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs @@ -0,0 +1,9 @@ +'use strict'; + +const _default = require('./default.cjs'); + +const atrulePrelude = { + getNode: _default +}; + +module.exports = atrulePrelude; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs new file mode 100644 index 0000000..43b5c18 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs @@ -0,0 +1,76 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u) + +function defaultRecognizer(context) { + switch (this.tokenType) { + case types.Hash: + return this.Hash(); + + case types.Comma: + return this.Operator(); + + case types.LeftParenthesis: + return this.Parentheses(this.readSequence, context.recognizer); + + case types.LeftSquareBracket: + return this.Brackets(this.readSequence, context.recognizer); + + case types.String: + return this.String(); + + case types.Dimension: + return this.Dimension(); + + case types.Percentage: + return this.Percentage(); + + case types.Number: + return this.Number(); + + case types.Function: + return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(') + ? this.Url() + : this.Function(this.readSequence, context.recognizer); + + case types.Url: + return this.Url(); + + case types.Ident: + // check for unicode range, it should start with u+ or U+ + if (this.cmpChar(this.tokenStart, U) && + this.cmpChar(this.tokenStart + 1, PLUSSIGN)) { + return this.UnicodeRange(); + } else { + return this.Identifier(); + } + + case types.Delim: { + const code = this.charCodeAt(this.tokenStart); + + if (code === SOLIDUS || + code === ASTERISK || + code === PLUSSIGN || + code === HYPHENMINUS) { + return this.Operator(); // TODO: replace with Delim + } + + // TODO: produce a node with Delim node type + + if (code === NUMBERSIGN) { + this.error('Hex or identifier is expected', this.tokenStart + 1); + } + + break; + } + } +} + +module.exports = defaultRecognizer; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs new file mode 100644 index 0000000..7839128 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs @@ -0,0 +1,11 @@ +'use strict'; + +const atrulePrelude = require('./atrulePrelude.cjs'); +const selector = require('./selector.cjs'); +const value = require('./value.cjs'); + + + +exports.AtrulePrelude = atrulePrelude; +exports.Selector = selector; +exports.Value = value; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs new file mode 100644 index 0000000..6b915ae --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs @@ -0,0 +1,88 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) +const TILDE = 0x007E; // U+007E TILDE (~) + +function onWhiteSpace(next, children) { + if (children.last !== null && children.last.type !== 'Combinator' && + next !== null && next.type !== 'Combinator') { + children.push({ // FIXME: this.Combinator() should be used instead + type: 'Combinator', + loc: null, + name: ' ' + }); + } +} + +function getNode() { + switch (this.tokenType) { + case types.LeftSquareBracket: + return this.AttributeSelector(); + + case types.Hash: + return this.IdSelector(); + + case types.Colon: + if (this.lookupType(1) === types.Colon) { + return this.PseudoElementSelector(); + } else { + return this.PseudoClassSelector(); + } + + case types.Ident: + return this.TypeSelector(); + + case types.Number: + case types.Percentage: + return this.Percentage(); + + case types.Dimension: + // throws when .123ident + if (this.charCodeAt(this.tokenStart) === FULLSTOP) { + this.error('Identifier is expected', this.tokenStart + 1); + } + break; + + case types.Delim: { + const code = this.charCodeAt(this.tokenStart); + + switch (code) { + case PLUSSIGN: + case GREATERTHANSIGN: + case TILDE: + case SOLIDUS: // /deep/ + return this.Combinator(); + + case FULLSTOP: + return this.ClassSelector(); + + case ASTERISK: + case VERTICALLINE: + return this.TypeSelector(); + + case NUMBERSIGN: + return this.IdSelector(); + + case AMPERSAND: + return this.NestingSelector(); + } + + break; + } + } +} +const Selector = { + onWhiteSpace, + getNode +}; + +module.exports = Selector; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs new file mode 100644 index 0000000..a9900a1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs @@ -0,0 +1,29 @@ +'use strict'; + +const _default = require('./default.cjs'); +const expression = require('../function/expression.cjs'); +const _var = require('../function/var.cjs'); + +function isPlusMinusOperator(node) { + return ( + node !== null && + node.type === 'Operator' && + (node.value[node.value.length - 1] === '-' || node.value[node.value.length - 1] === '+') + ); +} + +const value = { + getNode: _default, + onWhiteSpace(next, children) { + if (isPlusMinusOperator(next)) { + next.value = ' ' + next.value; + } + if (isPlusMinusOperator(children.last)) { + children.last.value += ' '; + } + }, + 'expression': expression, + 'var': _var +}; + +module.exports = value; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/OffsetToLocation.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/OffsetToLocation.cjs new file mode 100644 index 0000000..18b7f7c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/OffsetToLocation.cjs @@ -0,0 +1,91 @@ +'use strict'; + +const adoptBuffer = require('./adopt-buffer.cjs'); +const charCodeDefinitions = require('./char-code-definitions.cjs'); + +const N = 10; +const F = 12; +const R = 13; + +function computeLinesAndColumns(host) { + const source = host.source; + const sourceLength = source.length; + const startOffset = source.length > 0 ? charCodeDefinitions.isBOM(source.charCodeAt(0)) : 0; + const lines = adoptBuffer.adoptBuffer(host.lines, sourceLength); + const columns = adoptBuffer.adoptBuffer(host.columns, sourceLength); + let line = host.startLine; + let column = host.startColumn; + + for (let i = startOffset; i < sourceLength; i++) { + const code = source.charCodeAt(i); + + lines[i] = line; + columns[i] = column++; + + if (code === N || code === R || code === F) { + if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N) { + i++; + lines[i] = line; + columns[i] = column; + } + + line++; + column = 1; + } + } + + lines[sourceLength] = line; + columns[sourceLength] = column; + + host.lines = lines; + host.columns = columns; + host.computed = true; +} + +class OffsetToLocation { + constructor(source, startOffset, startLine, startColumn) { + this.setSource(source, startOffset, startLine, startColumn); + this.lines = null; + this.columns = null; + } + setSource(source = '', startOffset = 0, startLine = 1, startColumn = 1) { + this.source = source; + this.startOffset = startOffset; + this.startLine = startLine; + this.startColumn = startColumn; + this.computed = false; + } + getLocation(offset, filename) { + if (!this.computed) { + computeLinesAndColumns(this); + } + + return { + source: filename, + offset: this.startOffset + offset, + line: this.lines[offset], + column: this.columns[offset] + }; + } + getLocationRange(start, end, filename) { + if (!this.computed) { + computeLinesAndColumns(this); + } + + return { + source: filename, + start: { + offset: this.startOffset + start, + line: this.lines[start], + column: this.columns[start] + }, + end: { + offset: this.startOffset + end, + line: this.lines[end], + column: this.columns[end] + } + }; + } +} + +exports.OffsetToLocation = OffsetToLocation; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/TokenStream.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/TokenStream.cjs new file mode 100644 index 0000000..045991f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/TokenStream.cjs @@ -0,0 +1,308 @@ +'use strict'; + +const adoptBuffer = require('./adopt-buffer.cjs'); +const utils = require('./utils.cjs'); +const names = require('./names.cjs'); +const types = require('./types.cjs'); + +const OFFSET_MASK = 0x00FFFFFF; +const TYPE_SHIFT = 24; +const balancePair = new Uint8Array(32); // 32b of memory ought to be enough for anyone (any number of tokens) +balancePair[types.Function] = types.RightParenthesis; +balancePair[types.LeftParenthesis] = types.RightParenthesis; +balancePair[types.LeftSquareBracket] = types.RightSquareBracket; +balancePair[types.LeftCurlyBracket] = types.RightCurlyBracket; + +function isBlockOpenerToken(tokenType) { + return balancePair[tokenType] !== 0; +} + +class TokenStream { + constructor(source, tokenize) { + this.setSource(source, tokenize); + } + reset() { + this.eof = false; + this.tokenIndex = -1; + this.tokenType = 0; + this.tokenStart = this.firstCharOffset; + this.tokenEnd = this.firstCharOffset; + } + setSource(source = '', tokenize = () => {}) { + source = String(source || ''); + + const sourceLength = source.length; + const offsetAndType = adoptBuffer.adoptBuffer(this.offsetAndType, source.length + 1); // +1 because of eof-token + const balance = adoptBuffer.adoptBuffer(this.balance, source.length + 1); + let tokenCount = 0; + let firstCharOffset = -1; + let balanceCloseType = 0; + let balanceStart = source.length; + + // capture buffers + this.offsetAndType = null; + this.balance = null; + balance.fill(0); + + tokenize(source, (type, start, end) => { + const index = tokenCount++; + + // type & offset + offsetAndType[index] = (type << TYPE_SHIFT) | end; + + if (firstCharOffset === -1) { + firstCharOffset = start; + } + + // balance + balance[index] = balanceStart; + + if (type === balanceCloseType) { + const prevBalanceStart = balance[balanceStart]; + + // set reference to balance end for a block opener + balance[balanceStart] = index; + + // pop state + balanceStart = prevBalanceStart; + balanceCloseType = balancePair[offsetAndType[prevBalanceStart] >> TYPE_SHIFT]; + } else if (isBlockOpenerToken(type)) { // check for FunctionToken, <(-token>, <[-token> and <{-token> + // push state + balanceStart = index; + balanceCloseType = balancePair[type]; + } + }); + + // finalize buffers + offsetAndType[tokenCount] = (types.EOF << TYPE_SHIFT) | sourceLength; // <EOF-token> + balance[tokenCount] = tokenCount; // prevents false positive balance match with any token + + // reverse references from balance start to end + // tokens + // token: a ( [ b c ] d e ) { + // index: 0 1 2 3 4 5 6 7 8 9 + // before + // balance: 0 8 5 2 2 2 1 1 1 0 + // - > > < < < < < < - + // after + // balance: 9 8 5 5 5 2 8 8 1 9 + // > > > > > < > > < > + for (let i = 0; i < tokenCount; i++) { + const balanceStart = balance[i]; + + if (balanceStart <= i) { + const balanceEnd = balance[balanceStart]; + + if (balanceEnd !== i) { + balance[i] = balanceEnd; + } + } else if (balanceStart > tokenCount) { + balance[i] = tokenCount; + } + } + + // balance[0] = tokenCount; + + this.source = source; + this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset; + this.tokenCount = tokenCount; + this.offsetAndType = offsetAndType; + this.balance = balance; + + this.reset(); + this.next(); + } + + lookupType(offset) { + offset += this.tokenIndex; + + if (offset < this.tokenCount) { + return this.offsetAndType[offset] >> TYPE_SHIFT; + } + + return types.EOF; + } + lookupTypeNonSC(idx) { + for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) { + const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT; + + if (tokenType !== types.WhiteSpace && tokenType !== types.Comment) { + if (idx-- === 0) { + return tokenType; + } + } + } + + return types.EOF; + } + lookupOffset(offset) { + offset += this.tokenIndex; + + if (offset < this.tokenCount) { + return this.offsetAndType[offset - 1] & OFFSET_MASK; + } + + return this.source.length; + } + lookupOffsetNonSC(idx) { + for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) { + const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT; + + if (tokenType !== types.WhiteSpace && tokenType !== types.Comment) { + if (idx-- === 0) { + return offset - this.tokenIndex; + } + } + } + + return types.EOF; + } + lookupValue(offset, referenceStr) { + offset += this.tokenIndex; + + if (offset < this.tokenCount) { + return utils.cmpStr( + this.source, + this.offsetAndType[offset - 1] & OFFSET_MASK, + this.offsetAndType[offset] & OFFSET_MASK, + referenceStr + ); + } + + return false; + } + getTokenStart(tokenIndex) { + if (tokenIndex === this.tokenIndex) { + return this.tokenStart; + } + + if (tokenIndex > 0) { + return tokenIndex < this.tokenCount + ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK + : this.offsetAndType[this.tokenCount] & OFFSET_MASK; + } + + return this.firstCharOffset; + } + substrToCursor(start) { + return this.source.substring(start, this.tokenStart); + } + + isBalanceEdge(pos) { + return this.balance[this.tokenIndex] < pos; + // return this.balance[this.balance[pos]] !== this.tokenIndex; + } + isDelim(code, offset) { + if (offset) { + return ( + this.lookupType(offset) === types.Delim && + this.source.charCodeAt(this.lookupOffset(offset)) === code + ); + } + + return ( + this.tokenType === types.Delim && + this.source.charCodeAt(this.tokenStart) === code + ); + } + + skip(tokenCount) { + let next = this.tokenIndex + tokenCount; + + if (next < this.tokenCount) { + this.tokenIndex = next; + this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK; + next = this.offsetAndType[next]; + this.tokenType = next >> TYPE_SHIFT; + this.tokenEnd = next & OFFSET_MASK; + } else { + this.tokenIndex = this.tokenCount; + this.next(); + } + } + next() { + let next = this.tokenIndex + 1; + + if (next < this.tokenCount) { + this.tokenIndex = next; + this.tokenStart = this.tokenEnd; + next = this.offsetAndType[next]; + this.tokenType = next >> TYPE_SHIFT; + this.tokenEnd = next & OFFSET_MASK; + } else { + this.eof = true; + this.tokenIndex = this.tokenCount; + this.tokenType = types.EOF; + this.tokenStart = this.tokenEnd = this.source.length; + } + } + skipSC() { + while (this.tokenType === types.WhiteSpace || this.tokenType === types.Comment) { + this.next(); + } + } + skipUntilBalanced(startToken, stopConsume) { + let cursor = startToken; + let balanceEnd = 0; + let offset = 0; + + loop: + for (; cursor < this.tokenCount; cursor++) { + balanceEnd = this.balance[cursor]; + + // stop scanning on balance edge that points to offset before start token + if (balanceEnd < startToken) { + break loop; + } + + offset = cursor > 0 ? this.offsetAndType[cursor - 1] & OFFSET_MASK : this.firstCharOffset; + + // check stop condition + switch (stopConsume(this.source.charCodeAt(offset))) { + case 1: // just stop + break loop; + + case 2: // stop & included + cursor++; + break loop; + + default: + // fast forward to the end of balanced block for an open block tokens + if (isBlockOpenerToken(this.offsetAndType[cursor] >> TYPE_SHIFT)) { + cursor = balanceEnd; + } + } + } + + this.skip(cursor - this.tokenIndex); + } + + forEachToken(fn) { + for (let i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) { + const start = offset; + const item = this.offsetAndType[i]; + const end = item & OFFSET_MASK; + const type = item >> TYPE_SHIFT; + + offset = end; + + fn(type, start, end, i); + } + } + dump() { + const tokens = new Array(this.tokenCount); + + this.forEachToken((type, start, end, index) => { + tokens[index] = { + idx: index, + type: names[type], + chunk: this.source.substring(start, end), + balance: this.balance[index] + }; + }); + + return tokens; + } +} + +exports.TokenStream = TokenStream; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/adopt-buffer.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/adopt-buffer.cjs new file mode 100644 index 0000000..b2956ce --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/adopt-buffer.cjs @@ -0,0 +1,13 @@ +'use strict'; + +const MIN_SIZE = 16 * 1024; + +function adoptBuffer(buffer = null, size) { + if (buffer === null || buffer.length < size) { + return new Uint32Array(Math.max(size + 1024, MIN_SIZE)); + } + + return buffer; +} + +exports.adoptBuffer = adoptBuffer; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/char-code-definitions.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/char-code-definitions.cjs new file mode 100644 index 0000000..ebd4b58 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/char-code-definitions.cjs @@ -0,0 +1,236 @@ +'use strict'; + +const EOF = 0; + +// https://drafts.csswg.org/css-syntax-3/ +// § 4.2. Definitions + +// digit +// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9). +function isDigit(code) { + return code >= 0x0030 && code <= 0x0039; +} + +// hex digit +// A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F), +// or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f). +function isHexDigit(code) { + return ( + isDigit(code) || // 0 .. 9 + (code >= 0x0041 && code <= 0x0046) || // A .. F + (code >= 0x0061 && code <= 0x0066) // a .. f + ); +} + +// uppercase letter +// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z). +function isUppercaseLetter(code) { + return code >= 0x0041 && code <= 0x005A; +} + +// lowercase letter +// A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z). +function isLowercaseLetter(code) { + return code >= 0x0061 && code <= 0x007A; +} + +// letter +// An uppercase letter or a lowercase letter. +function isLetter(code) { + return isUppercaseLetter(code) || isLowercaseLetter(code); +} + +// non-ASCII code point +// A code point with a value equal to or greater than U+0080 <control>. +// +// 2024-09-02: The latest spec narrows the range for non-ASCII characters (see https://github.com/csstree/csstree/issues/188). +// However, all modern browsers support a wider range, and strictly following the latest spec could result +// in some CSS being parsed incorrectly, even though it works in the browser. Therefore, this function adheres +// to the previous, broader definition of non-ASCII characters. +function isNonAscii(code) { + return code >= 0x0080; +} + +// name-start code point +// A letter, a non-ASCII code point, or U+005F LOW LINE (_). +function isNameStart(code) { + return isLetter(code) || isNonAscii(code) || code === 0x005F; +} + +// name code point +// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-). +function isName(code) { + return isNameStart(code) || isDigit(code) || code === 0x002D; +} + +// non-printable code point +// A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION, +// or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE. +function isNonPrintable(code) { + return ( + (code >= 0x0000 && code <= 0x0008) || + (code === 0x000B) || + (code >= 0x000E && code <= 0x001F) || + (code === 0x007F) + ); +} + +// newline +// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition, +// as they are converted to U+000A LINE FEED during preprocessing. +// TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED +function isNewline(code) { + return code === 0x000A || code === 0x000D || code === 0x000C; +} + +// whitespace +// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE. +function isWhiteSpace(code) { + return isNewline(code) || code === 0x0020 || code === 0x0009; +} + +// § 4.3.8. Check if two code points are a valid escape +function isValidEscape(first, second) { + // If the first code point is not U+005C REVERSE SOLIDUS (\), return false. + if (first !== 0x005C) { + return false; + } + + // Otherwise, if the second code point is a newline or EOF, return false. + if (isNewline(second) || second === EOF) { + return false; + } + + // Otherwise, return true. + return true; +} + +// § 4.3.9. Check if three code points would start an identifier +function isIdentifierStart(first, second, third) { + // Look at the first code point: + + // U+002D HYPHEN-MINUS + if (first === 0x002D) { + // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS, + // or the second and third code points are a valid escape, return true. Otherwise, return false. + return ( + isNameStart(second) || + second === 0x002D || + isValidEscape(second, third) + ); + } + + // name-start code point + if (isNameStart(first)) { + // Return true. + return true; + } + + // U+005C REVERSE SOLIDUS (\) + if (first === 0x005C) { + // If the first and second code points are a valid escape, return true. Otherwise, return false. + return isValidEscape(first, second); + } + + // anything else + // Return false. + return false; +} + +// § 4.3.10. Check if three code points would start a number +function isNumberStart(first, second, third) { + // Look at the first code point: + + // U+002B PLUS SIGN (+) + // U+002D HYPHEN-MINUS (-) + if (first === 0x002B || first === 0x002D) { + // If the second code point is a digit, return true. + if (isDigit(second)) { + return 2; + } + + // Otherwise, if the second code point is a U+002E FULL STOP (.) + // and the third code point is a digit, return true. + // Otherwise, return false. + return second === 0x002E && isDigit(third) ? 3 : 0; + } + + // U+002E FULL STOP (.) + if (first === 0x002E) { + // If the second code point is a digit, return true. Otherwise, return false. + return isDigit(second) ? 2 : 0; + } + + // digit + if (isDigit(first)) { + // Return true. + return 1; + } + + // anything else + // Return false. + return 0; +} + +// +// Misc +// + +// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark) +function isBOM(code) { + // UTF-16BE + if (code === 0xFEFF) { + return 1; + } + + // UTF-16LE + if (code === 0xFFFE) { + return 1; + } + + return 0; +} + +// Fast code category +// Only ASCII code points has a special meaning, that's why we define a maps for 0..127 codes only +const CATEGORY = new Array(0x80); +const EofCategory = 0x80; +const WhiteSpaceCategory = 0x82; +const DigitCategory = 0x83; +const NameStartCategory = 0x84; +const NonPrintableCategory = 0x85; + +for (let i = 0; i < CATEGORY.length; i++) { + CATEGORY[i] = + isWhiteSpace(i) && WhiteSpaceCategory || + isDigit(i) && DigitCategory || + isNameStart(i) && NameStartCategory || + isNonPrintable(i) && NonPrintableCategory || + i || EofCategory; +} + +function charCodeCategory(code) { + return code < 0x80 ? CATEGORY[code] : NameStartCategory; +} + +exports.DigitCategory = DigitCategory; +exports.EofCategory = EofCategory; +exports.NameStartCategory = NameStartCategory; +exports.NonPrintableCategory = NonPrintableCategory; +exports.WhiteSpaceCategory = WhiteSpaceCategory; +exports.charCodeCategory = charCodeCategory; +exports.isBOM = isBOM; +exports.isDigit = isDigit; +exports.isHexDigit = isHexDigit; +exports.isIdentifierStart = isIdentifierStart; +exports.isLetter = isLetter; +exports.isLowercaseLetter = isLowercaseLetter; +exports.isName = isName; +exports.isNameStart = isNameStart; +exports.isNewline = isNewline; +exports.isNonAscii = isNonAscii; +exports.isNonPrintable = isNonPrintable; +exports.isNumberStart = isNumberStart; +exports.isUppercaseLetter = isUppercaseLetter; +exports.isValidEscape = isValidEscape; +exports.isWhiteSpace = isWhiteSpace; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/index.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/index.cjs new file mode 100644 index 0000000..bfb73e5 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/index.cjs @@ -0,0 +1,554 @@ +'use strict'; + +const types = require('./types.cjs'); +const charCodeDefinitions = require('./char-code-definitions.cjs'); +const utils = require('./utils.cjs'); +const names = require('./names.cjs'); +const OffsetToLocation = require('./OffsetToLocation.cjs'); +const TokenStream = require('./TokenStream.cjs'); + +function tokenize(source, onToken) { + function getCharCode(offset) { + return offset < sourceLength ? source.charCodeAt(offset) : 0; + } + + // § 4.3.3. Consume a numeric token + function consumeNumericToken() { + // Consume a number and let number be the result. + offset = utils.consumeNumber(source, offset); + + // If the next 3 input code points would start an identifier, then: + if (charCodeDefinitions.isIdentifierStart(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) { + // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string. + // Consume a name. Set the <dimension-token>’s unit to the returned value. + // Return the <dimension-token>. + type = types.Dimension; + offset = utils.consumeName(source, offset); + return; + } + + // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it. + if (getCharCode(offset) === 0x0025) { + // Create a <percentage-token> with the same value as number, and return it. + type = types.Percentage; + offset++; + return; + } + + // Otherwise, create a <number-token> with the same value and type flag as number, and return it. + type = types.Number; + } + + // § 4.3.4. Consume an ident-like token + function consumeIdentLikeToken() { + const nameStartOffset = offset; + + // Consume a name, and let string be the result. + offset = utils.consumeName(source, offset); + + // If string’s value is an ASCII case-insensitive match for "url", + // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it. + if (utils.cmpStr(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) { + // While the next two input code points are whitespace, consume the next input code point. + offset = utils.findWhiteSpaceEnd(source, offset + 1); + + // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('), + // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('), + // then create a <function-token> with its value set to string and return it. + if (getCharCode(offset) === 0x0022 || + getCharCode(offset) === 0x0027) { + type = types.Function; + offset = nameStartOffset + 4; + return; + } + + // Otherwise, consume a url token, and return it. + consumeUrlToken(); + return; + } + + // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it. + // Create a <function-token> with its value set to string and return it. + if (getCharCode(offset) === 0x0028) { + type = types.Function; + offset++; + return; + } + + // Otherwise, create an <ident-token> with its value set to string and return it. + type = types.Ident; + } + + // § 4.3.5. Consume a string token + function consumeStringToken(endingCodePoint) { + // This algorithm may be called with an ending code point, which denotes the code point + // that ends the string. If an ending code point is not specified, + // the current input code point is used. + if (!endingCodePoint) { + endingCodePoint = getCharCode(offset++); + } + + // Initially create a <string-token> with its value set to the empty string. + type = types.String; + + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + switch (charCodeDefinitions.charCodeCategory(code)) { + // ending code point + case endingCodePoint: + // Return the <string-token>. + offset++; + return; + + // EOF + // case EofCategory: + // This is a parse error. Return the <string-token>. + // return; + + // newline + case charCodeDefinitions.WhiteSpaceCategory: + if (charCodeDefinitions.isNewline(code)) { + // This is a parse error. Reconsume the current input code point, + // create a <bad-string-token>, and return it. + offset += utils.getNewlineLength(source, offset, code); + type = types.BadString; + return; + } + break; + + // U+005C REVERSE SOLIDUS (\) + case 0x005C: + // If the next input code point is EOF, do nothing. + if (offset === source.length - 1) { + break; + } + + const nextCode = getCharCode(offset + 1); + + // Otherwise, if the next input code point is a newline, consume it. + if (charCodeDefinitions.isNewline(nextCode)) { + offset += utils.getNewlineLength(source, offset + 1, nextCode); + } else if (charCodeDefinitions.isValidEscape(code, nextCode)) { + // Otherwise, (the stream starts with a valid escape) consume + // an escaped code point and append the returned code point to + // the <string-token>’s value. + offset = utils.consumeEscaped(source, offset) - 1; + } + break; + + // anything else + // Append the current input code point to the <string-token>’s value. + } + } + } + + // § 4.3.6. Consume a url token + // Note: This algorithm assumes that the initial "url(" has already been consumed. + // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo). + // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token + // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise. + function consumeUrlToken() { + // Initially create a <url-token> with its value set to the empty string. + type = types.Url; + + // Consume as much whitespace as possible. + offset = utils.findWhiteSpaceEnd(source, offset); + + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + switch (charCodeDefinitions.charCodeCategory(code)) { + // U+0029 RIGHT PARENTHESIS ()) + case 0x0029: + // Return the <url-token>. + offset++; + return; + + // EOF + // case EofCategory: + // This is a parse error. Return the <url-token>. + // return; + + // whitespace + case charCodeDefinitions.WhiteSpaceCategory: + // Consume as much whitespace as possible. + offset = utils.findWhiteSpaceEnd(source, offset); + + // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF, + // consume it and return the <url-token> + // (if EOF was encountered, this is a parse error); + if (getCharCode(offset) === 0x0029 || offset >= source.length) { + if (offset < source.length) { + offset++; + } + return; + } + + // otherwise, consume the remnants of a bad url, create a <bad-url-token>, + // and return it. + offset = utils.consumeBadUrlRemnants(source, offset); + type = types.BadUrl; + return; + + // U+0022 QUOTATION MARK (") + // U+0027 APOSTROPHE (') + // U+0028 LEFT PARENTHESIS (() + // non-printable code point + case 0x0022: + case 0x0027: + case 0x0028: + case charCodeDefinitions.NonPrintableCategory: + // This is a parse error. Consume the remnants of a bad url, + // create a <bad-url-token>, and return it. + offset = utils.consumeBadUrlRemnants(source, offset); + type = types.BadUrl; + return; + + // U+005C REVERSE SOLIDUS (\) + case 0x005C: + // If the stream starts with a valid escape, consume an escaped code point and + // append the returned code point to the <url-token>’s value. + if (charCodeDefinitions.isValidEscape(code, getCharCode(offset + 1))) { + offset = utils.consumeEscaped(source, offset) - 1; + break; + } + + // Otherwise, this is a parse error. Consume the remnants of a bad url, + // create a <bad-url-token>, and return it. + offset = utils.consumeBadUrlRemnants(source, offset); + type = types.BadUrl; + return; + + // anything else + // Append the current input code point to the <url-token>’s value. + } + } + } + + // ensure source is a string + source = String(source || ''); + + const sourceLength = source.length; + let start = charCodeDefinitions.isBOM(getCharCode(0)); + let offset = start; + let type; + + // https://drafts.csswg.org/css-syntax-3/#consume-token + // § 4.3.1. Consume a token + while (offset < sourceLength) { + const code = source.charCodeAt(offset); + + switch (charCodeDefinitions.charCodeCategory(code)) { + // whitespace + case charCodeDefinitions.WhiteSpaceCategory: + // Consume as much whitespace as possible. Return a <whitespace-token>. + type = types.WhiteSpace; + offset = utils.findWhiteSpaceEnd(source, offset + 1); + break; + + // U+0022 QUOTATION MARK (") + case 0x0022: + // Consume a string token and return it. + consumeStringToken(); + break; + + // U+0023 NUMBER SIGN (#) + case 0x0023: + // If the next input code point is a name code point or the next two input code points are a valid escape, then: + if (charCodeDefinitions.isName(getCharCode(offset + 1)) || charCodeDefinitions.isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) { + // Create a <hash-token>. + type = types.Hash; + + // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id". + // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) { + // // TODO: set id flag + // } + + // Consume a name, and set the <hash-token>’s value to the returned string. + offset = utils.consumeName(source, offset + 1); + + // Return the <hash-token>. + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + + break; + + // U+0027 APOSTROPHE (') + case 0x0027: + // Consume a string token and return it. + consumeStringToken(); + break; + + // U+0028 LEFT PARENTHESIS (() + case 0x0028: + // Return a <(-token>. + type = types.LeftParenthesis; + offset++; + break; + + // U+0029 RIGHT PARENTHESIS ()) + case 0x0029: + // Return a <)-token>. + type = types.RightParenthesis; + offset++; + break; + + // U+002B PLUS SIGN (+) + case 0x002B: + // If the input stream starts with a number, ... + if (charCodeDefinitions.isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + // ... reconsume the current input code point, consume a numeric token, and return it. + consumeNumericToken(); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + break; + + // U+002C COMMA (,) + case 0x002C: + // Return a <comma-token>. + type = types.Comma; + offset++; + break; + + // U+002D HYPHEN-MINUS (-) + case 0x002D: + // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it. + if (charCodeDefinitions.isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + consumeNumericToken(); + } else { + // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>. + if (getCharCode(offset + 1) === 0x002D && + getCharCode(offset + 2) === 0x003E) { + type = types.CDC; + offset = offset + 3; + } else { + // Otherwise, if the input stream starts with an identifier, ... + if (charCodeDefinitions.isIdentifierStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + // ... reconsume the current input code point, consume an ident-like token, and return it. + consumeIdentLikeToken(); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + } + } + break; + + // U+002E FULL STOP (.) + case 0x002E: + // If the input stream starts with a number, ... + if (charCodeDefinitions.isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + // ... reconsume the current input code point, consume a numeric token, and return it. + consumeNumericToken(); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + + break; + + // U+002F SOLIDUS (/) + case 0x002F: + // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*), + if (getCharCode(offset + 1) === 0x002A) { + // ... consume them and all following code points up to and including the first U+002A ASTERISK (*) + // followed by a U+002F SOLIDUS (/), or up to an EOF code point. + type = types.Comment; + offset = source.indexOf('*/', offset + 2); + offset = offset === -1 ? source.length : offset + 2; + } else { + type = types.Delim; + offset++; + } + break; + + // U+003A COLON (:) + case 0x003A: + // Return a <colon-token>. + type = types.Colon; + offset++; + break; + + // U+003B SEMICOLON (;) + case 0x003B: + // Return a <semicolon-token>. + type = types.Semicolon; + offset++; + break; + + // U+003C LESS-THAN SIGN (<) + case 0x003C: + // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ... + if (getCharCode(offset + 1) === 0x0021 && + getCharCode(offset + 2) === 0x002D && + getCharCode(offset + 3) === 0x002D) { + // ... consume them and return a <CDO-token>. + type = types.CDO; + offset = offset + 4; + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + + break; + + // U+0040 COMMERCIAL AT (@) + case 0x0040: + // If the next 3 input code points would start an identifier, ... + if (charCodeDefinitions.isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) { + // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it. + type = types.AtKeyword; + offset = utils.consumeName(source, offset + 1); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + + break; + + // U+005B LEFT SQUARE BRACKET ([) + case 0x005B: + // Return a <[-token>. + type = types.LeftSquareBracket; + offset++; + break; + + // U+005C REVERSE SOLIDUS (\) + case 0x005C: + // If the input stream starts with a valid escape, ... + if (charCodeDefinitions.isValidEscape(code, getCharCode(offset + 1))) { + // ... reconsume the current input code point, consume an ident-like token, and return it. + consumeIdentLikeToken(); + } else { + // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + break; + + // U+005D RIGHT SQUARE BRACKET (]) + case 0x005D: + // Return a <]-token>. + type = types.RightSquareBracket; + offset++; + break; + + // U+007B LEFT CURLY BRACKET ({) + case 0x007B: + // Return a <{-token>. + type = types.LeftCurlyBracket; + offset++; + break; + + // U+007D RIGHT CURLY BRACKET (}) + case 0x007D: + // Return a <}-token>. + type = types.RightCurlyBracket; + offset++; + break; + + // digit + case charCodeDefinitions.DigitCategory: + // Reconsume the current input code point, consume a numeric token, and return it. + consumeNumericToken(); + break; + + // name-start code point + case charCodeDefinitions.NameStartCategory: + // Reconsume the current input code point, consume an ident-like token, and return it. + consumeIdentLikeToken(); + break; + + // EOF + // case EofCategory: + // Return an <EOF-token>. + // break; + + // anything else + default: + // Return a <delim-token> with its value set to the current input code point. + type = types.Delim; + offset++; + } + + // put token to stream + onToken(type, start, start = offset); + } +} + +exports.AtKeyword = types.AtKeyword; +exports.BadString = types.BadString; +exports.BadUrl = types.BadUrl; +exports.CDC = types.CDC; +exports.CDO = types.CDO; +exports.Colon = types.Colon; +exports.Comma = types.Comma; +exports.Comment = types.Comment; +exports.Delim = types.Delim; +exports.Dimension = types.Dimension; +exports.EOF = types.EOF; +exports.Function = types.Function; +exports.Hash = types.Hash; +exports.Ident = types.Ident; +exports.LeftCurlyBracket = types.LeftCurlyBracket; +exports.LeftParenthesis = types.LeftParenthesis; +exports.LeftSquareBracket = types.LeftSquareBracket; +exports.Number = types.Number; +exports.Percentage = types.Percentage; +exports.RightCurlyBracket = types.RightCurlyBracket; +exports.RightParenthesis = types.RightParenthesis; +exports.RightSquareBracket = types.RightSquareBracket; +exports.Semicolon = types.Semicolon; +exports.String = types.String; +exports.Url = types.Url; +exports.WhiteSpace = types.WhiteSpace; +exports.tokenTypes = types; +exports.DigitCategory = charCodeDefinitions.DigitCategory; +exports.EofCategory = charCodeDefinitions.EofCategory; +exports.NameStartCategory = charCodeDefinitions.NameStartCategory; +exports.NonPrintableCategory = charCodeDefinitions.NonPrintableCategory; +exports.WhiteSpaceCategory = charCodeDefinitions.WhiteSpaceCategory; +exports.charCodeCategory = charCodeDefinitions.charCodeCategory; +exports.isBOM = charCodeDefinitions.isBOM; +exports.isDigit = charCodeDefinitions.isDigit; +exports.isHexDigit = charCodeDefinitions.isHexDigit; +exports.isIdentifierStart = charCodeDefinitions.isIdentifierStart; +exports.isLetter = charCodeDefinitions.isLetter; +exports.isLowercaseLetter = charCodeDefinitions.isLowercaseLetter; +exports.isName = charCodeDefinitions.isName; +exports.isNameStart = charCodeDefinitions.isNameStart; +exports.isNewline = charCodeDefinitions.isNewline; +exports.isNonAscii = charCodeDefinitions.isNonAscii; +exports.isNonPrintable = charCodeDefinitions.isNonPrintable; +exports.isNumberStart = charCodeDefinitions.isNumberStart; +exports.isUppercaseLetter = charCodeDefinitions.isUppercaseLetter; +exports.isValidEscape = charCodeDefinitions.isValidEscape; +exports.isWhiteSpace = charCodeDefinitions.isWhiteSpace; +exports.cmpChar = utils.cmpChar; +exports.cmpStr = utils.cmpStr; +exports.consumeBadUrlRemnants = utils.consumeBadUrlRemnants; +exports.consumeEscaped = utils.consumeEscaped; +exports.consumeName = utils.consumeName; +exports.consumeNumber = utils.consumeNumber; +exports.decodeEscaped = utils.decodeEscaped; +exports.findDecimalNumberEnd = utils.findDecimalNumberEnd; +exports.findWhiteSpaceEnd = utils.findWhiteSpaceEnd; +exports.findWhiteSpaceStart = utils.findWhiteSpaceStart; +exports.getNewlineLength = utils.getNewlineLength; +exports.tokenNames = names; +exports.OffsetToLocation = OffsetToLocation.OffsetToLocation; +exports.TokenStream = TokenStream.TokenStream; +exports.tokenize = tokenize; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/names.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/names.cjs new file mode 100644 index 0000000..6900f98 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/names.cjs @@ -0,0 +1,32 @@ +'use strict'; + +const tokenNames = [ + 'EOF-token', + 'ident-token', + 'function-token', + 'at-keyword-token', + 'hash-token', + 'string-token', + 'bad-string-token', + 'url-token', + 'bad-url-token', + 'delim-token', + 'number-token', + 'percentage-token', + 'dimension-token', + 'whitespace-token', + 'CDO-token', + 'CDC-token', + 'colon-token', + 'semicolon-token', + 'comma-token', + '[-token', + ']-token', + '(-token', + ')-token', + '{-token', + '}-token', + 'comment-token' +]; + +module.exports = tokenNames; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/types.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/types.cjs new file mode 100644 index 0000000..a89b810 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/types.cjs @@ -0,0 +1,57 @@ +'use strict'; + +// CSS Syntax Module Level 3 +// https://www.w3.org/TR/css-syntax-3/ +const EOF = 0; // <EOF-token> +const Ident = 1; // <ident-token> +const Function = 2; // <function-token> +const AtKeyword = 3; // <at-keyword-token> +const Hash = 4; // <hash-token> +const String = 5; // <string-token> +const BadString = 6; // <bad-string-token> +const Url = 7; // <url-token> +const BadUrl = 8; // <bad-url-token> +const Delim = 9; // <delim-token> +const Number = 10; // <number-token> +const Percentage = 11; // <percentage-token> +const Dimension = 12; // <dimension-token> +const WhiteSpace = 13; // <whitespace-token> +const CDO = 14; // <CDO-token> +const CDC = 15; // <CDC-token> +const Colon = 16; // <colon-token> : +const Semicolon = 17; // <semicolon-token> ; +const Comma = 18; // <comma-token> , +const LeftSquareBracket = 19; // <[-token> +const RightSquareBracket = 20; // <]-token> +const LeftParenthesis = 21; // <(-token> +const RightParenthesis = 22; // <)-token> +const LeftCurlyBracket = 23; // <{-token> +const RightCurlyBracket = 24; // <}-token> +const Comment = 25; + +exports.AtKeyword = AtKeyword; +exports.BadString = BadString; +exports.BadUrl = BadUrl; +exports.CDC = CDC; +exports.CDO = CDO; +exports.Colon = Colon; +exports.Comma = Comma; +exports.Comment = Comment; +exports.Delim = Delim; +exports.Dimension = Dimension; +exports.EOF = EOF; +exports.Function = Function; +exports.Hash = Hash; +exports.Ident = Ident; +exports.LeftCurlyBracket = LeftCurlyBracket; +exports.LeftParenthesis = LeftParenthesis; +exports.LeftSquareBracket = LeftSquareBracket; +exports.Number = Number; +exports.Percentage = Percentage; +exports.RightCurlyBracket = RightCurlyBracket; +exports.RightParenthesis = RightParenthesis; +exports.RightSquareBracket = RightSquareBracket; +exports.Semicolon = Semicolon; +exports.String = String; +exports.Url = Url; +exports.WhiteSpace = WhiteSpace; diff --git a/vanilla/node_modules/css-tree/cjs/tokenizer/utils.cjs b/vanilla/node_modules/css-tree/cjs/tokenizer/utils.cjs new file mode 100644 index 0000000..c3798e3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/tokenizer/utils.cjs @@ -0,0 +1,261 @@ +'use strict'; + +const charCodeDefinitions = require('./char-code-definitions.cjs'); + +function getCharCode(source, offset) { + return offset < source.length ? source.charCodeAt(offset) : 0; +} + +function getNewlineLength(source, offset, code) { + if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) { + return 2; + } + + return 1; +} + +function cmpChar(testStr, offset, referenceCode) { + let code = testStr.charCodeAt(offset); + + // code.toLowerCase() for A..Z + if (charCodeDefinitions.isUppercaseLetter(code)) { + code = code | 32; + } + + return code === referenceCode; +} + +function cmpStr(testStr, start, end, referenceStr) { + if (end - start !== referenceStr.length) { + return false; + } + + if (start < 0 || end > testStr.length) { + return false; + } + + for (let i = start; i < end; i++) { + const referenceCode = referenceStr.charCodeAt(i - start); + let testCode = testStr.charCodeAt(i); + + // testCode.toLowerCase() for A..Z + if (charCodeDefinitions.isUppercaseLetter(testCode)) { + testCode = testCode | 32; + } + + if (testCode !== referenceCode) { + return false; + } + } + + return true; +} + +function findWhiteSpaceStart(source, offset) { + for (; offset >= 0; offset--) { + if (!charCodeDefinitions.isWhiteSpace(source.charCodeAt(offset))) { + break; + } + } + + return offset + 1; +} + +function findWhiteSpaceEnd(source, offset) { + for (; offset < source.length; offset++) { + if (!charCodeDefinitions.isWhiteSpace(source.charCodeAt(offset))) { + break; + } + } + + return offset; +} + +function findDecimalNumberEnd(source, offset) { + for (; offset < source.length; offset++) { + if (!charCodeDefinitions.isDigit(source.charCodeAt(offset))) { + break; + } + } + + return offset; +} + +// § 4.3.7. Consume an escaped code point +function consumeEscaped(source, offset) { + // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and + // that the next input code point has already been verified to be part of a valid escape. + offset += 2; + + // hex digit + if (charCodeDefinitions.isHexDigit(getCharCode(source, offset - 1))) { + // Consume as many hex digits as possible, but no more than 5. + // Note that this means 1-6 hex digits have been consumed in total. + for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) { + if (!charCodeDefinitions.isHexDigit(getCharCode(source, offset))) { + break; + } + } + + // If the next input code point is whitespace, consume it as well. + const code = getCharCode(source, offset); + if (charCodeDefinitions.isWhiteSpace(code)) { + offset += getNewlineLength(source, offset, code); + } + } + + return offset; +} + +// §4.3.11. Consume a name +// Note: This algorithm does not do the verification of the first few code points that are necessary +// to ensure the returned code points would constitute an <ident-token>. If that is the intended use, +// ensure that the stream starts with an identifier before calling this algorithm. +function consumeName(source, offset) { + // Let result initially be an empty string. + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + // name code point + if (charCodeDefinitions.isName(code)) { + // Append the code point to result. + continue; + } + + // the stream starts with a valid escape + if (charCodeDefinitions.isValidEscape(code, getCharCode(source, offset + 1))) { + // Consume an escaped code point. Append the returned code point to result. + offset = consumeEscaped(source, offset) - 1; + continue; + } + + // anything else + // Reconsume the current input code point. Return result. + break; + } + + return offset; +} + +// §4.3.12. Consume a number +function consumeNumber(source, offset) { + let code = source.charCodeAt(offset); + + // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-), + // consume it and append it to repr. + if (code === 0x002B || code === 0x002D) { + code = source.charCodeAt(offset += 1); + } + + // 3. While the next input code point is a digit, consume it and append it to repr. + if (charCodeDefinitions.isDigit(code)) { + offset = findDecimalNumberEnd(source, offset + 1); + code = source.charCodeAt(offset); + } + + // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then: + if (code === 0x002E && charCodeDefinitions.isDigit(source.charCodeAt(offset + 1))) { + // 4.1 Consume them. + // 4.2 Append them to repr. + offset += 2; + + // 4.3 Set type to "number". + // TODO + + // 4.4 While the next input code point is a digit, consume it and append it to repr. + + offset = findDecimalNumberEnd(source, offset); + } + + // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E) + // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then: + if (cmpChar(source, offset, 101 /* e */)) { + let sign = 0; + code = source.charCodeAt(offset + 1); + + // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ... + if (code === 0x002D || code === 0x002B) { + sign = 1; + code = source.charCodeAt(offset + 2); + } + + // ... followed by a digit + if (charCodeDefinitions.isDigit(code)) { + // 5.1 Consume them. + // 5.2 Append them to repr. + + // 5.3 Set type to "number". + // TODO + + // 5.4 While the next input code point is a digit, consume it and append it to repr. + offset = findDecimalNumberEnd(source, offset + 1 + sign + 1); + } + } + + return offset; +} + +// § 4.3.14. Consume the remnants of a bad url +// ... its sole use is to consume enough of the input stream to reach a recovery point +// where normal tokenizing can resume. +function consumeBadUrlRemnants(source, offset) { + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + // U+0029 RIGHT PARENTHESIS ()) + // EOF + if (code === 0x0029) { + // Return. + offset++; + break; + } + + if (charCodeDefinitions.isValidEscape(code, getCharCode(source, offset + 1))) { + // Consume an escaped code point. + // Note: This allows an escaped right parenthesis ("\)") to be encountered + // without ending the <bad-url-token>. This is otherwise identical to + // the "anything else" clause. + offset = consumeEscaped(source, offset); + } + } + + return offset; +} + +// § 4.3.7. Consume an escaped code point +// Note: This algorithm assumes that escaped is valid without leading U+005C REVERSE SOLIDUS (\) +function decodeEscaped(escaped) { + // Single char escaped that's not a hex digit + if (escaped.length === 1 && !charCodeDefinitions.isHexDigit(escaped.charCodeAt(0))) { + return escaped[0]; + } + + // Interpret the hex digits as a hexadecimal number. + let code = parseInt(escaped, 16); + + if ( + (code === 0) || // If this number is zero, + (code >= 0xD800 && code <= 0xDFFF) || // or is for a surrogate, + (code > 0x10FFFF) // or is greater than the maximum allowed code point + ) { + // ... return U+FFFD REPLACEMENT CHARACTER + code = 0xFFFD; + } + + // Otherwise, return the code point with that value. + return String.fromCodePoint(code); +} + +exports.cmpChar = cmpChar; +exports.cmpStr = cmpStr; +exports.consumeBadUrlRemnants = consumeBadUrlRemnants; +exports.consumeEscaped = consumeEscaped; +exports.consumeName = consumeName; +exports.consumeNumber = consumeNumber; +exports.decodeEscaped = decodeEscaped; +exports.findDecimalNumberEnd = findDecimalNumberEnd; +exports.findWhiteSpaceEnd = findWhiteSpaceEnd; +exports.findWhiteSpaceStart = findWhiteSpaceStart; +exports.getNewlineLength = getNewlineLength; diff --git a/vanilla/node_modules/css-tree/cjs/utils/List.cjs b/vanilla/node_modules/css-tree/cjs/utils/List.cjs new file mode 100644 index 0000000..ec25f46 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/List.cjs @@ -0,0 +1,473 @@ +'use strict'; + +// +// list +// ┌──────┐ +// ┌──────────────┼─head │ +// │ │ tail─┼──────────────┐ +// │ └──────┘ │ +// ▼ ▼ +// item item item item +// ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ +// null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │ +// │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null +// ├──────┤ ├──────┤ ├──────┤ ├──────┤ +// │ data │ │ data │ │ data │ │ data │ +// └──────┘ └──────┘ └──────┘ └──────┘ +// + +let releasedCursors = null; + +class List { + static createItem(data) { + return { + prev: null, + next: null, + data + }; + } + + constructor() { + this.head = null; + this.tail = null; + this.cursor = null; + } + createItem(data) { + return List.createItem(data); + } + + // cursor helpers + allocateCursor(prev, next) { + let cursor; + + if (releasedCursors !== null) { + cursor = releasedCursors; + releasedCursors = releasedCursors.cursor; + cursor.prev = prev; + cursor.next = next; + cursor.cursor = this.cursor; + } else { + cursor = { + prev, + next, + cursor: this.cursor + }; + } + + this.cursor = cursor; + + return cursor; + } + releaseCursor() { + const { cursor } = this; + + this.cursor = cursor.cursor; + cursor.prev = null; + cursor.next = null; + cursor.cursor = releasedCursors; + releasedCursors = cursor; + } + updateCursors(prevOld, prevNew, nextOld, nextNew) { + let { cursor } = this; + + while (cursor !== null) { + if (cursor.prev === prevOld) { + cursor.prev = prevNew; + } + + if (cursor.next === nextOld) { + cursor.next = nextNew; + } + + cursor = cursor.cursor; + } + } + *[Symbol.iterator]() { + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + yield cursor.data; + } + } + + // getters + get size() { + let size = 0; + + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + size++; + } + + return size; + } + get isEmpty() { + return this.head === null; + } + get first() { + return this.head && this.head.data; + } + get last() { + return this.tail && this.tail.data; + } + + // convertors + fromArray(array) { + let cursor = null; + this.head = null; + + for (let data of array) { + const item = List.createItem(data); + + if (cursor !== null) { + cursor.next = item; + } else { + this.head = item; + } + + item.prev = cursor; + cursor = item; + } + + this.tail = cursor; + return this; + } + toArray() { + return [...this]; + } + toJSON() { + return [...this]; + } + + // array-like methods + forEach(fn, thisArg = this) { + // push cursor + const cursor = this.allocateCursor(null, this.head); + + while (cursor.next !== null) { + const item = cursor.next; + cursor.next = item.next; + fn.call(thisArg, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + } + forEachRight(fn, thisArg = this) { + // push cursor + const cursor = this.allocateCursor(this.tail, null); + + while (cursor.prev !== null) { + const item = cursor.prev; + cursor.prev = item.prev; + fn.call(thisArg, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + } + reduce(fn, initialValue, thisArg = this) { + // push cursor + let cursor = this.allocateCursor(null, this.head); + let acc = initialValue; + let item; + + while (cursor.next !== null) { + item = cursor.next; + cursor.next = item.next; + + acc = fn.call(thisArg, acc, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + + return acc; + } + reduceRight(fn, initialValue, thisArg = this) { + // push cursor + let cursor = this.allocateCursor(this.tail, null); + let acc = initialValue; + let item; + + while (cursor.prev !== null) { + item = cursor.prev; + cursor.prev = item.prev; + + acc = fn.call(thisArg, acc, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + + return acc; + } + some(fn, thisArg = this) { + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + if (fn.call(thisArg, cursor.data, cursor, this)) { + return true; + } + } + + return false; + } + map(fn, thisArg = this) { + const result = new List(); + + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + result.appendData(fn.call(thisArg, cursor.data, cursor, this)); + } + + return result; + } + filter(fn, thisArg = this) { + const result = new List(); + + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + if (fn.call(thisArg, cursor.data, cursor, this)) { + result.appendData(cursor.data); + } + } + + return result; + } + + nextUntil(start, fn, thisArg = this) { + if (start === null) { + return; + } + + // push cursor + const cursor = this.allocateCursor(null, start); + + while (cursor.next !== null) { + const item = cursor.next; + cursor.next = item.next; + if (fn.call(thisArg, item.data, item, this)) { + break; + } + } + + // pop cursor + this.releaseCursor(); + } + prevUntil(start, fn, thisArg = this) { + if (start === null) { + return; + } + + // push cursor + const cursor = this.allocateCursor(start, null); + + while (cursor.prev !== null) { + const item = cursor.prev; + cursor.prev = item.prev; + if (fn.call(thisArg, item.data, item, this)) { + break; + } + } + + // pop cursor + this.releaseCursor(); + } + + // mutation + clear() { + this.head = null; + this.tail = null; + } + copy() { + const result = new List(); + + for (let data of this) { + result.appendData(data); + } + + return result; + } + prepend(item) { + // head + // ^ + // item + this.updateCursors(null, item, this.head, item); + + // insert to the beginning of the list + if (this.head !== null) { + // new item <- first item + this.head.prev = item; + // new item -> first item + item.next = this.head; + } else { + // if list has no head, then it also has no tail + // in this case tail points to the new item + this.tail = item; + } + + // head always points to new item + this.head = item; + return this; + } + prependData(data) { + return this.prepend(List.createItem(data)); + } + append(item) { + return this.insert(item); + } + appendData(data) { + return this.insert(List.createItem(data)); + } + insert(item, before = null) { + if (before !== null) { + // prev before + // ^ + // item + this.updateCursors(before.prev, item, before, item); + + if (before.prev === null) { + // insert to the beginning of list + if (this.head !== before) { + throw new Error('before doesn\'t belong to list'); + } + // since head points to before therefore list doesn't empty + // no need to check tail + this.head = item; + before.prev = item; + item.next = before; + this.updateCursors(null, item); + } else { + // insert between two items + before.prev.next = item; + item.prev = before.prev; + before.prev = item; + item.next = before; + } + } else { + // tail + // ^ + // item + this.updateCursors(this.tail, item, null, item); + + // insert to the ending of the list + if (this.tail !== null) { + // last item -> new item + this.tail.next = item; + // last item <- new item + item.prev = this.tail; + } else { + // if list has no tail, then it also has no head + // in this case head points to new item + this.head = item; + } + + // tail always points to new item + this.tail = item; + } + + return this; + } + insertData(data, before) { + return this.insert(List.createItem(data), before); + } + remove(item) { + // item + // ^ + // prev next + this.updateCursors(item, item.prev, item, item.next); + + if (item.prev !== null) { + item.prev.next = item.next; + } else { + if (this.head !== item) { + throw new Error('item doesn\'t belong to list'); + } + + this.head = item.next; + } + + if (item.next !== null) { + item.next.prev = item.prev; + } else { + if (this.tail !== item) { + throw new Error('item doesn\'t belong to list'); + } + + this.tail = item.prev; + } + + item.prev = null; + item.next = null; + + return item; + } + push(data) { + this.insert(List.createItem(data)); + } + pop() { + return this.tail !== null ? this.remove(this.tail) : null; + } + unshift(data) { + this.prepend(List.createItem(data)); + } + shift() { + return this.head !== null ? this.remove(this.head) : null; + } + prependList(list) { + return this.insertList(list, this.head); + } + appendList(list) { + return this.insertList(list); + } + insertList(list, before) { + // ignore empty lists + if (list.head === null) { + return this; + } + + if (before !== undefined && before !== null) { + this.updateCursors(before.prev, list.tail, before, list.head); + + // insert in the middle of dist list + if (before.prev !== null) { + // before.prev <-> list.head + before.prev.next = list.head; + list.head.prev = before.prev; + } else { + this.head = list.head; + } + + before.prev = list.tail; + list.tail.next = before; + } else { + this.updateCursors(this.tail, list.tail, null, list.head); + + // insert to end of the list + if (this.tail !== null) { + // if destination list has a tail, then it also has a head, + // but head doesn't change + // dest tail -> source head + this.tail.next = list.head; + // dest tail <- source head + list.head.prev = this.tail; + } else { + // if list has no a tail, then it also has no a head + // in this case points head to new item + this.head = list.head; + } + + // tail always start point to new item + this.tail = list.tail; + } + + list.head = null; + list.tail = null; + return this; + } + replace(oldItem, newItemOrList) { + if ('head' in newItemOrList) { + this.insertList(newItemOrList, oldItem); + } else { + this.insert(newItemOrList, oldItem); + } + + this.remove(oldItem); + } +} + +exports.List = List; diff --git a/vanilla/node_modules/css-tree/cjs/utils/clone.cjs b/vanilla/node_modules/css-tree/cjs/utils/clone.cjs new file mode 100644 index 0000000..41d5edb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/clone.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const List = require('./List.cjs'); + +function clone(node) { + const result = {}; + + for (const key of Object.keys(node)) { + let value = node[key]; + + if (value) { + if (Array.isArray(value) || value instanceof List.List) { + value = value.map(clone); + } else if (value.constructor === Object) { + value = clone(value); + } + } + + result[key] = value; + } + + return result; +} + +exports.clone = clone; diff --git a/vanilla/node_modules/css-tree/cjs/utils/create-custom-error.cjs b/vanilla/node_modules/css-tree/cjs/utils/create-custom-error.cjs new file mode 100644 index 0000000..d1d3e53 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/create-custom-error.cjs @@ -0,0 +1,18 @@ +'use strict'; + +function createCustomError(name, message) { + // use Object.create(), because some VMs prevent setting line/column otherwise + // (iOS Safari 10 even throws an exception) + const error = Object.create(SyntaxError.prototype); + const errorStack = new Error(); + + return Object.assign(error, { + name, + message, + get stack() { + return (errorStack.stack || '').replace(/^(.+\n){1,3}/, `${name}: ${message}\n`); + } + }); +} + +exports.createCustomError = createCustomError; diff --git a/vanilla/node_modules/css-tree/cjs/utils/ident.cjs b/vanilla/node_modules/css-tree/cjs/utils/ident.cjs new file mode 100644 index 0000000..cd70911 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/ident.cjs @@ -0,0 +1,102 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) + +function decode(str) { + const end = str.length - 1; + let decoded = ''; + + for (let i = 0; i < str.length; i++) { + let code = str.charCodeAt(i); + + if (code === REVERSE_SOLIDUS) { + // special case at the ending + if (i === end) { + // if the next input code point is EOF, do nothing + break; + } + + code = str.charCodeAt(++i); + + // consume escaped + if (charCodeDefinitions.isValidEscape(REVERSE_SOLIDUS, code)) { + const escapeStart = i - 1; + const escapeEnd = utils.consumeEscaped(str, escapeStart); + + i = escapeEnd - 1; + decoded += utils.decodeEscaped(str.substring(escapeStart + 1, escapeEnd)); + } else { + // \r\n + if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) { + i++; + } + } + } else { + decoded += str[i]; + } + } + + return decoded; +} + +// https://drafts.csswg.org/cssom/#serialize-an-identifier +// § 2.1. Common Serializing Idioms +function encode(str) { + let encoded = ''; + + // If the character is the first character and is a "-" (U+002D), + // and there is no second character, then the escaped character. + // Note: That's means a single dash string "-" return as escaped dash, + // so move the condition out of the main loop + if (str.length === 1 && str.charCodeAt(0) === 0x002D) { + return '\\-'; + } + + // To serialize an identifier means to create a string represented + // by the concatenation of, for each character of the identifier: + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (code === 0x0000) { + encoded += '\uFFFD'; + continue; + } + + if ( + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F ... + // Note: Do not compare with 0x0001 since 0x0000 is precessed before + code <= 0x001F || code === 0x007F || + // [or] ... is in the range [0-9] (U+0030 to U+0039), + (code >= 0x0030 && code <= 0x0039 && ( + // If the character is the first character ... + i === 0 || + // If the character is the second character ... and the first character is a "-" (U+002D) + i === 1 && str.charCodeAt(0) === 0x002D + )) + ) { + // ... then the character escaped as code point. + encoded += '\\' + code.toString(16) + ' '; + continue; + } + + // If the character is not handled by one of the above rules and is greater + // than or equal to U+0080, is "-" (U+002D) or "_" (U+005F), or is in one + // of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A), + // or \[a-z] (U+0061 to U+007A), then the character itself. + if (charCodeDefinitions.isName(code)) { + encoded += str.charAt(i); + } else { + // Otherwise, the escaped character. + encoded += '\\' + str.charAt(i); + } + } + + return encoded; +} + +exports.decode = decode; +exports.encode = encode; diff --git a/vanilla/node_modules/css-tree/cjs/utils/index.cjs b/vanilla/node_modules/css-tree/cjs/utils/index.cjs new file mode 100644 index 0000000..cdae621 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/index.cjs @@ -0,0 +1,20 @@ +'use strict'; + +const clone = require('./clone.cjs'); +const ident = require('./ident.cjs'); +const List = require('./List.cjs'); +const names = require('./names.cjs'); +const string = require('./string.cjs'); +const url = require('./url.cjs'); + + + +exports.clone = clone.clone; +exports.ident = ident; +exports.List = List.List; +exports.isCustomProperty = names.isCustomProperty; +exports.keyword = names.keyword; +exports.property = names.property; +exports.vendorPrefix = names.vendorPrefix; +exports.string = string; +exports.url = url; diff --git a/vanilla/node_modules/css-tree/cjs/utils/names.cjs b/vanilla/node_modules/css-tree/cjs/utils/names.cjs new file mode 100644 index 0000000..92c73c7 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/names.cjs @@ -0,0 +1,113 @@ +'use strict'; + +const keywords = new Map(); +const properties = new Map(); +const HYPHENMINUS = 45; // '-'.charCodeAt() + +const keyword = getKeywordDescriptor; +const property = getPropertyDescriptor; +const vendorPrefix = getVendorPrefix; +function isCustomProperty(str, offset) { + offset = offset || 0; + + return str.length - offset >= 2 && + str.charCodeAt(offset) === HYPHENMINUS && + str.charCodeAt(offset + 1) === HYPHENMINUS; +} + +function getVendorPrefix(str, offset) { + offset = offset || 0; + + // verdor prefix should be at least 3 chars length + if (str.length - offset >= 3) { + // vendor prefix starts with hyper minus following non-hyper minus + if (str.charCodeAt(offset) === HYPHENMINUS && + str.charCodeAt(offset + 1) !== HYPHENMINUS) { + // vendor prefix should contain a hyper minus at the ending + const secondDashIndex = str.indexOf('-', offset + 2); + + if (secondDashIndex !== -1) { + return str.substring(offset, secondDashIndex + 1); + } + } + } + + return ''; +} + +function getKeywordDescriptor(keyword) { + if (keywords.has(keyword)) { + return keywords.get(keyword); + } + + const name = keyword.toLowerCase(); + let descriptor = keywords.get(name); + + if (descriptor === undefined) { + const custom = isCustomProperty(name, 0); + const vendor = !custom ? getVendorPrefix(name, 0) : ''; + descriptor = Object.freeze({ + basename: name.substr(vendor.length), + name, + prefix: vendor, + vendor, + custom + }); + } + + keywords.set(keyword, descriptor); + + return descriptor; +} + +function getPropertyDescriptor(property) { + if (properties.has(property)) { + return properties.get(property); + } + + let name = property; + let hack = property[0]; + + if (hack === '/') { + hack = property[1] === '/' ? '//' : '/'; + } else if (hack !== '_' && + hack !== '*' && + hack !== '$' && + hack !== '#' && + hack !== '+' && + hack !== '&') { + hack = ''; + } + + const custom = isCustomProperty(name, hack.length); + + // re-use result when possible (the same as for lower case) + if (!custom) { + name = name.toLowerCase(); + if (properties.has(name)) { + const descriptor = properties.get(name); + properties.set(property, descriptor); + return descriptor; + } + } + + const vendor = !custom ? getVendorPrefix(name, hack.length) : ''; + const prefix = name.substr(0, hack.length + vendor.length); + const descriptor = Object.freeze({ + basename: name.substr(prefix.length), + name: name.substr(hack.length), + hack, + vendor, + prefix, + custom + }); + + properties.set(property, descriptor); + + return descriptor; +} + +exports.isCustomProperty = isCustomProperty; +exports.keyword = keyword; +exports.property = property; +exports.vendorPrefix = vendorPrefix; diff --git a/vanilla/node_modules/css-tree/cjs/utils/string.cjs b/vanilla/node_modules/css-tree/cjs/utils/string.cjs new file mode 100644 index 0000000..d9c5d01 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/string.cjs @@ -0,0 +1,99 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) +const QUOTATION_MARK = 0x0022; // " +const APOSTROPHE = 0x0027; // ' + +function decode(str) { + const len = str.length; + const firstChar = str.charCodeAt(0); + const start = firstChar === QUOTATION_MARK || firstChar === APOSTROPHE ? 1 : 0; + const end = start === 1 && len > 1 && str.charCodeAt(len - 1) === firstChar ? len - 2 : len - 1; + let decoded = ''; + + for (let i = start; i <= end; i++) { + let code = str.charCodeAt(i); + + if (code === REVERSE_SOLIDUS) { + // special case at the ending + if (i === end) { + // if the next input code point is EOF, do nothing + // otherwise include last quote as escaped + if (i !== len - 1) { + decoded = str.substr(i + 1); + } + break; + } + + code = str.charCodeAt(++i); + + // consume escaped + if (charCodeDefinitions.isValidEscape(REVERSE_SOLIDUS, code)) { + const escapeStart = i - 1; + const escapeEnd = utils.consumeEscaped(str, escapeStart); + + i = escapeEnd - 1; + decoded += utils.decodeEscaped(str.substring(escapeStart + 1, escapeEnd)); + } else { + // \r\n + if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) { + i++; + } + } + } else { + decoded += str[i]; + } + } + + return decoded; +} + +// https://drafts.csswg.org/cssom/#serialize-a-string +// § 2.1. Common Serializing Idioms +function encode(str, apostrophe) { + const quote = apostrophe ? '\'' : '"'; + const quoteCode = apostrophe ? APOSTROPHE : QUOTATION_MARK; + let encoded = ''; + let wsBeforeHexIsNeeded = false; + + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (code === 0x0000) { + encoded += '\uFFFD'; + continue; + } + + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, + // the character escaped as code point. + // Note: Do not compare with 0x0001 since 0x0000 is precessed before + if (code <= 0x001f || code === 0x007F) { + encoded += '\\' + code.toString(16); + wsBeforeHexIsNeeded = true; + continue; + } + + // If the character is '"' (U+0022) or "\" (U+005C), the escaped character. + if (code === quoteCode || code === REVERSE_SOLIDUS) { + encoded += '\\' + str.charAt(i); + wsBeforeHexIsNeeded = false; + } else { + if (wsBeforeHexIsNeeded && (charCodeDefinitions.isHexDigit(code) || charCodeDefinitions.isWhiteSpace(code))) { + encoded += ' '; + } + + // Otherwise, the character itself. + encoded += str.charAt(i); + wsBeforeHexIsNeeded = false; + } + } + + return quote + encoded + quote; +} + +exports.decode = decode; +exports.encode = encode; diff --git a/vanilla/node_modules/css-tree/cjs/utils/url.cjs b/vanilla/node_modules/css-tree/cjs/utils/url.cjs new file mode 100644 index 0000000..e0e5c22 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/utils/url.cjs @@ -0,0 +1,108 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const SPACE = 0x0020; // U+0020 SPACE +const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) +const QUOTATION_MARK = 0x0022; // " +const APOSTROPHE = 0x0027; // ' +const LEFTPARENTHESIS = 0x0028; // U+0028 LEFT PARENTHESIS (() +const RIGHTPARENTHESIS = 0x0029; // U+0029 RIGHT PARENTHESIS ()) + +function decode(str) { + const len = str.length; + let start = 4; // length of "url(" + let end = str.charCodeAt(len - 1) === RIGHTPARENTHESIS ? len - 2 : len - 1; + let decoded = ''; + + while (start < end && charCodeDefinitions.isWhiteSpace(str.charCodeAt(start))) { + start++; + } + + while (start < end && charCodeDefinitions.isWhiteSpace(str.charCodeAt(end))) { + end--; + } + + for (let i = start; i <= end; i++) { + let code = str.charCodeAt(i); + + if (code === REVERSE_SOLIDUS) { + // special case at the ending + if (i === end) { + // if the next input code point is EOF, do nothing + // otherwise include last left parenthesis as escaped + if (i !== len - 1) { + decoded = str.substr(i + 1); + } + break; + } + + code = str.charCodeAt(++i); + + // consume escaped + if (charCodeDefinitions.isValidEscape(REVERSE_SOLIDUS, code)) { + const escapeStart = i - 1; + const escapeEnd = utils.consumeEscaped(str, escapeStart); + + i = escapeEnd - 1; + decoded += utils.decodeEscaped(str.substring(escapeStart + 1, escapeEnd)); + } else { + // \r\n + if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) { + i++; + } + } + } else { + decoded += str[i]; + } + } + + return decoded; +} + +function encode(str) { + let encoded = ''; + let wsBeforeHexIsNeeded = false; + + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (code === 0x0000) { + encoded += '\uFFFD'; + continue; + } + + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, + // the character escaped as code point. + // Note: Do not compare with 0x0001 since 0x0000 is precessed before + if (code <= 0x001f || code === 0x007F) { + encoded += '\\' + code.toString(16); + wsBeforeHexIsNeeded = true; + continue; + } + + if (code === SPACE || + code === REVERSE_SOLIDUS || + code === QUOTATION_MARK || + code === APOSTROPHE || + code === LEFTPARENTHESIS || + code === RIGHTPARENTHESIS) { + encoded += '\\' + str.charAt(i); + wsBeforeHexIsNeeded = false; + } else { + if (wsBeforeHexIsNeeded && charCodeDefinitions.isHexDigit(code)) { + encoded += ' '; + } + + encoded += str.charAt(i); + wsBeforeHexIsNeeded = false; + } + } + + return 'url(' + encoded + ')'; +} + +exports.decode = decode; +exports.encode = encode; diff --git a/vanilla/node_modules/css-tree/cjs/version.cjs b/vanilla/node_modules/css-tree/cjs/version.cjs new file mode 100644 index 0000000..eaa2fef --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/version.cjs @@ -0,0 +1,5 @@ +'use strict'; + +const { version } = require('../package.json'); + +exports.version = version; diff --git a/vanilla/node_modules/css-tree/cjs/walker/create.cjs b/vanilla/node_modules/css-tree/cjs/walker/create.cjs new file mode 100644 index 0000000..3938a9f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/walker/create.cjs @@ -0,0 +1,291 @@ +'use strict'; + +const { hasOwnProperty } = Object.prototype; +const noop = function() {}; + +function ensureFunction(value) { + return typeof value === 'function' ? value : noop; +} + +function invokeForType(fn, type) { + return function(node, item, list) { + if (node.type === type) { + fn.call(this, node, item, list); + } + }; +} + +function getWalkersFromStructure(name, nodeType) { + const structure = nodeType.structure; + const walkers = []; + + for (const key in structure) { + if (hasOwnProperty.call(structure, key) === false) { + continue; + } + + let fieldTypes = structure[key]; + const walker = { + name: key, + type: false, + nullable: false + }; + + if (!Array.isArray(fieldTypes)) { + fieldTypes = [fieldTypes]; + } + + for (const fieldType of fieldTypes) { + if (fieldType === null) { + walker.nullable = true; + } else if (typeof fieldType === 'string') { + walker.type = 'node'; + } else if (Array.isArray(fieldType)) { + walker.type = 'list'; + } + } + + if (walker.type) { + walkers.push(walker); + } + } + + if (walkers.length) { + return { + context: nodeType.walkContext, + fields: walkers + }; + } + + return null; +} + +function getTypesFromConfig(config) { + const types = {}; + + for (const name in config.node) { + if (hasOwnProperty.call(config.node, name)) { + const nodeType = config.node[name]; + + if (!nodeType.structure) { + throw new Error('Missed `structure` field in `' + name + '` node type definition'); + } + + types[name] = getWalkersFromStructure(name, nodeType); + } + } + + return types; +} + +function createTypeIterator(config, reverse) { + const fields = config.fields.slice(); + const contextName = config.context; + const useContext = typeof contextName === 'string'; + + if (reverse) { + fields.reverse(); + } + + return function(node, context, walk, walkReducer) { + let prevContextValue; + + if (useContext) { + prevContextValue = context[contextName]; + context[contextName] = node; + } + + for (const field of fields) { + const ref = node[field.name]; + + if (!field.nullable || ref) { + if (field.type === 'list') { + const breakWalk = reverse + ? ref.reduceRight(walkReducer, false) + : ref.reduce(walkReducer, false); + + if (breakWalk) { + return true; + } + } else if (walk(ref)) { + return true; + } + } + } + + if (useContext) { + context[contextName] = prevContextValue; + } + }; +} + +function createFastTraveralMap({ + StyleSheet, + Atrule, + Rule, + Block, + DeclarationList +}) { + return { + Atrule: { + StyleSheet, + Atrule, + Rule, + Block + }, + Rule: { + StyleSheet, + Atrule, + Rule, + Block + }, + Declaration: { + StyleSheet, + Atrule, + Rule, + Block, + DeclarationList + } + }; +} + +function createWalker(config) { + const types = getTypesFromConfig(config); + const iteratorsNatural = {}; + const iteratorsReverse = {}; + const breakWalk = Symbol('break-walk'); + const skipNode = Symbol('skip-node'); + + for (const name in types) { + if (hasOwnProperty.call(types, name) && types[name] !== null) { + iteratorsNatural[name] = createTypeIterator(types[name], false); + iteratorsReverse[name] = createTypeIterator(types[name], true); + } + } + + const fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural); + const fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse); + + const walk = function(root, options) { + function walkNode(node, item, list) { + const enterRet = enter.call(context, node, item, list); + + if (enterRet === breakWalk) { + return true; + } + + if (enterRet === skipNode) { + return false; + } + + if (iterators.hasOwnProperty(node.type)) { + if (iterators[node.type](node, context, walkNode, walkReducer)) { + return true; + } + } + + if (leave.call(context, node, item, list) === breakWalk) { + return true; + } + + return false; + } + + let enter = noop; + let leave = noop; + let iterators = iteratorsNatural; + let walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list); + const context = { + break: breakWalk, + skip: skipNode, + + root, + stylesheet: null, + atrule: null, + atrulePrelude: null, + rule: null, + selector: null, + block: null, + declaration: null, + function: null + }; + + if (typeof options === 'function') { + enter = options; + } else if (options) { + enter = ensureFunction(options.enter); + leave = ensureFunction(options.leave); + + if (options.reverse) { + iterators = iteratorsReverse; + } + + if (options.visit) { + if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) { + iterators = options.reverse + ? fastTraversalIteratorsReverse[options.visit] + : fastTraversalIteratorsNatural[options.visit]; + } else if (!types.hasOwnProperty(options.visit)) { + throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).sort().join(', ') + ')'); + } + + enter = invokeForType(enter, options.visit); + leave = invokeForType(leave, options.visit); + } + } + + if (enter === noop && leave === noop) { + throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function'); + } + + walkNode(root); + }; + + walk.break = breakWalk; + walk.skip = skipNode; + + walk.find = function(ast, fn) { + let found = null; + + walk(ast, function(node, item, list) { + if (fn.call(this, node, item, list)) { + found = node; + return breakWalk; + } + }); + + return found; + }; + + walk.findLast = function(ast, fn) { + let found = null; + + walk(ast, { + reverse: true, + enter(node, item, list) { + if (fn.call(this, node, item, list)) { + found = node; + return breakWalk; + } + } + }); + + return found; + }; + + walk.findAll = function(ast, fn) { + const found = []; + + walk(ast, function(node, item, list) { + if (fn.call(this, node, item, list)) { + found.push(node); + } + }); + + return found; + }; + + return walk; +} + +exports.createWalker = createWalker; diff --git a/vanilla/node_modules/css-tree/cjs/walker/index.cjs b/vanilla/node_modules/css-tree/cjs/walker/index.cjs new file mode 100644 index 0000000..e923c61 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/walker/index.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const walker$1 = require('../syntax/config/walker.cjs'); + +const walker = create.createWalker(walker$1); + +module.exports = walker; diff --git a/vanilla/node_modules/css-tree/data/patch.json b/vanilla/node_modules/css-tree/data/patch.json new file mode 100644 index 0000000..08c59a1 --- /dev/null +++ b/vanilla/node_modules/css-tree/data/patch.json @@ -0,0 +1,982 @@ +{ + "atrules": { + "charset": { + "prelude": "<string>" + }, + "container": { + "prelude": "[ <container-name> ]? <container-condition>" + }, + "font-face": { + "descriptors": { + "unicode-range": { + "comment": "replaces <unicode-range>, an old production name", + "syntax": "<urange>#" + } + } + }, + "nest": { + "prelude": "<complex-selector-list>" + }, + "scope": { + "prelude": "[ ( <scope-start> ) ]? [ to ( <scope-end> ) ]?" + }, + "position-try": { + "comment": "The list of descriptors: https://developer.mozilla.org/en-US/docs/Web/CSS/@position-try", + "descriptors": { + "top": "<'top'>", + "left": "<'left'>", + "bottom": "<'bottom'>", + "right": "<'right'>", + "inset-block-start": "<'inset-block-start'>", + "inset-block-end": "<'inset-block-end'>", + "inset-inline-start": "<'inset-inline-start'>", + "inset-inline-end": "<'inset-inline-end'>", + "inset-block": "<'inset-block'>", + "inset-inline": "<'inset-inline'>", + "inset": "<'inset'>", + "margin-top": "<'margin-top'>", + "margin-left": "<'margin-left'>", + "margin-bottom": "<'margin-bottom'>", + "margin-right": "<'margin-right'>", + "margin-block-start": "<'margin-block-start'>", + "margin-block-end": "<'margin-block-end'>", + "margin-inline-start": "<'margin-inline-start'>", + "margin-inline-end": "<'margin-inline-end'>", + "margin": "<'margin'>", + "margin-block": "<'margin-block'>", + "margin-inline": "<'margin-inline'>", + "width": "<'width'>", + "height": "<'height'>", + "min-width": "<'min-width'>", + "min-height": "<'min-height'>", + "max-width": "<'max-width'>", + "max-height": "<'max-height'>", + "block-size": "<'block-size'>", + "inline-size": "<'inline-size'>", + "min-block-size": "<'min-block-size'>", + "min-inline-size": "<'min-inline-size'>", + "max-block-size": "<'max-block-size'>", + "max-inline-size": "<'max-inline-size'>", + "align-self": "<'align-self'> | anchor-center", + "justify-self": "<'justify-self'> | anchor-center" + } + } + }, + "properties": { + "-moz-background-clip": { + "comment": "deprecated syntax in old Firefox, https://developer.mozilla.org/en/docs/Web/CSS/background-clip", + "syntax": "padding | border" + }, + "-moz-border-radius-bottomleft": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-left-radius", + "syntax": "<'border-bottom-left-radius'>" + }, + "-moz-border-radius-bottomright": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius", + "syntax": "<'border-bottom-right-radius'>" + }, + "-moz-border-radius-topleft": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/border-top-left-radius", + "syntax": "<'border-top-left-radius'>" + }, + "-moz-border-radius-topright": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius", + "syntax": "<'border-bottom-right-radius'>" + }, + "-moz-control-character-visibility": { + "comment": "firefox specific keywords, https://bugzilla.mozilla.org/show_bug.cgi?id=947588", + "syntax": "visible | hidden" + }, + "-moz-osx-font-smoothing": { + "comment": "misssed old syntax https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth", + "syntax": "auto | grayscale" + }, + "-moz-user-select": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/user-select", + "syntax": "none | text | all | -moz-none" + }, + "-ms-flex-align": { + "comment": "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align", + "syntax": "start | end | center | baseline | stretch" + }, + "-ms-flex-item-align": { + "comment": "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align", + "syntax": "auto | start | end | center | baseline | stretch" + }, + "-ms-flex-line-pack": { + "comment": "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-line-pack", + "syntax": "start | end | center | justify | distribute | stretch" + }, + "-ms-flex-negative": { + "comment": "misssed old syntax implemented in IE; TODO: find references for comfirmation", + "syntax": "<'flex-shrink'>" + }, + "-ms-flex-pack": { + "comment": "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-pack", + "syntax": "start | end | center | justify | distribute" + }, + "-ms-flex-order": { + "comment": "misssed old syntax implemented in IE; https://msdn.microsoft.com/en-us/library/jj127303(v=vs.85).aspx", + "syntax": "<integer>" + }, + "-ms-flex-positive": { + "comment": "misssed old syntax implemented in IE; TODO: find references for comfirmation", + "syntax": "<'flex-grow'>" + }, + "-ms-flex-preferred-size": { + "comment": "misssed old syntax implemented in IE; TODO: find references for comfirmation", + "syntax": "<'flex-basis'>" + }, + "-ms-interpolation-mode": { + "comment": "https://msdn.microsoft.com/en-us/library/ff521095(v=vs.85).aspx", + "syntax": "nearest-neighbor | bicubic" + }, + "-ms-grid-column-align": { + "comment": "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466338.aspx", + "syntax": "start | end | center | stretch" + }, + "-ms-grid-row-align": { + "comment": "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466348.aspx", + "syntax": "start | end | center | stretch" + }, + "-ms-hyphenate-limit-last": { + "comment": "misssed old syntax implemented in IE; https://www.w3.org/TR/css-text-4/#hyphenate-line-limits", + "syntax": "none | always | column | page | spread" + }, + "-webkit-appearance": { + "comment": "webkit specific keywords", + "references": [ + "http://css-infos.net/property/-webkit-appearance" + ], + "syntax": "none | button | button-bevel | caps-lock-indicator | caret | checkbox | default-button | inner-spin-button | listbox | listitem | media-controls-background | media-controls-fullscreen-background | media-current-time-display | media-enter-fullscreen-button | media-exit-fullscreen-button | media-fullscreen-button | media-mute-button | media-overlay-play-button | media-play-button | media-seek-back-button | media-seek-forward-button | media-slider | media-sliderthumb | media-time-remaining-display | media-toggle-closed-captions-button | media-volume-slider | media-volume-slider-container | media-volume-sliderthumb | menulist | menulist-button | menulist-text | menulist-textfield | meter | progress-bar | progress-bar-value | push-button | radio | scrollbarbutton-down | scrollbarbutton-left | scrollbarbutton-right | scrollbarbutton-up | scrollbargripper-horizontal | scrollbargripper-vertical | scrollbarthumb-horizontal | scrollbarthumb-vertical | scrollbartrack-horizontal | scrollbartrack-vertical | searchfield | searchfield-cancel-button | searchfield-decoration | searchfield-results-button | searchfield-results-decoration | slider-horizontal | slider-vertical | sliderthumb-horizontal | sliderthumb-vertical | square-button | textarea | textfield | -apple-pay-button" + }, + "-webkit-background-clip": { + "comment": "https://developer.mozilla.org/en/docs/Web/CSS/background-clip", + "syntax": "[ <box> | border | padding | content | text ]#" + }, + "-webkit-column-break-after": { + "comment": "added, http://help.dottoro.com/lcrthhhv.php", + "syntax": "always | auto | avoid" + }, + "-webkit-column-break-before": { + "comment": "added, http://help.dottoro.com/lcxquvkf.php", + "syntax": "always | auto | avoid" + }, + "-webkit-column-break-inside": { + "comment": "added, http://help.dottoro.com/lclhnthl.php", + "syntax": "always | auto | avoid" + }, + "-webkit-font-smoothing": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth", + "syntax": "auto | none | antialiased | subpixel-antialiased" + }, + "-webkit-mask-box-image": { + "comment": "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image", + "syntax": "[ <url> | <gradient> | none ] [ <length-percentage>{4} <-webkit-mask-box-repeat>{2} ]?" + }, + "-webkit-print-color-adjust": { + "comment": "missed", + "references": [ + "https://developer.mozilla.org/en/docs/Web/CSS/-webkit-print-color-adjust" + ], + "syntax": "economy | exact" + }, + "-webkit-text-security": { + "comment": "missed; http://help.dottoro.com/lcbkewgt.php", + "syntax": "none | circle | disc | square" + }, + "-webkit-user-drag": { + "comment": "missed; http://help.dottoro.com/lcbixvwm.php", + "syntax": "none | element | auto" + }, + "-webkit-user-select": { + "comment": "auto is supported by old webkit, https://developer.mozilla.org/en-US/docs/Web/CSS/user-select", + "syntax": "auto | none | text | all" + }, + "alignment-baseline": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/text.html#AlignmentBaselineProperty" + ], + "syntax": "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical" + }, + "background-clip": { + "comment": "used <bg-clip> from CSS Backgrounds and Borders 4 since it adds new values", + "references": [ + "https://github.com/csstree/csstree/issues/190" + ], + "syntax": "<bg-clip>#" + }, + "baseline-shift": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/text.html#BaselineShiftProperty" + ], + "syntax": "baseline | sub | super | <svg-length>" + }, + "behavior": { + "comment": "added old IE property https://msdn.microsoft.com/en-us/library/ms530723(v=vs.85).aspx", + "syntax": "<url>+" + }, + "container-type": { + "comment": "https://www.w3.org/TR/css-contain-3/#propdef-container-type", + "syntax": "normal || [ size | inline-size ]" + }, + "cue": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<'cue-before'> <'cue-after'>?" + }, + "cue-after": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<url> <decibel>? | none" + }, + "cue-before": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<url> <decibel>? | none" + }, + "cursor": { + "comment": "added legacy keywords: hand, -webkit-grab. -webkit-grabbing, -webkit-zoom-in, -webkit-zoom-out, -moz-grab, -moz-grabbing, -moz-zoom-in, -moz-zoom-out", + "references": [ + "https://www.sitepoint.com/css3-cursor-styles/" + ], + "syntax": "[ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing | hand | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out | -moz-grab | -moz-grabbing | -moz-zoom-in | -moz-zoom-out ] ]" + }, + "display": { + "comment": "extended with -ms-flexbox", + "syntax": "| <-non-standard-display>" + }, + "position": { + "comment": "extended with -webkit-sticky", + "syntax": "| -webkit-sticky" + }, + "dominant-baseline": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/text.html#DominantBaselineProperty" + ], + "syntax": "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge" + }, + "image-rendering": { + "comment": "extended with <-non-standard-image-rendering>, added SVG keywords optimizeSpeed and optimizeQuality", + "references": [ + "https://developer.mozilla.org/en/docs/Web/CSS/image-rendering", + "https://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty" + ], + "syntax": "| optimizeSpeed | optimizeQuality | <-non-standard-image-rendering>" + }, + "fill": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#FillProperty" + ], + "syntax": "<paint>" + }, + "fill-opacity": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#FillProperty" + ], + "syntax": "<number-zero-one>" + }, + "filter": { + "comment": "extend with IE legacy syntaxes", + "syntax": "| <-ms-filter-function-list>" + }, + "font": { + "comment": "align with font-4, fix <'font-family'>#, add non standard fonts", + "references": [ + "https://drafts.csswg.org/css-fonts-4/#font-prop", + "https://github.com/w3c/csswg-drafts/pull/10832", + "https://webkit.org/blog/3709/using-the-system-font-in-web-content/" + ], + "syntax": "[ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-width-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'># ] | <system-family-name> | <-non-standard-font>" + }, + "glyph-orientation-horizontal": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/text.html#GlyphOrientationHorizontalProperty" + ], + "syntax": "<angle>" + }, + "glyph-orientation-vertical": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/text.html#GlyphOrientationVerticalProperty" + ], + "syntax": "<angle>" + }, + "kerning": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/text.html#KerningProperty" + ], + "syntax": "auto | <svg-length>" + }, + "letter-spacing": { + "comment": "fix syntax <length> -> <length-percentage>", + "references": [ + "https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/letter-spacing" + ], + "syntax": "normal | <length-percentage>" + }, + "max-width": { + "comment": "extend by non-standard size keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width", + "syntax": "| stretch | <-non-standard-size>" + }, + "max-height": { + "comment": "extend by non-standard size keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width", + "syntax": "| stretch | <-non-standard-size>" + }, + "width": { + "references": [ + "https://developer.mozilla.org/en-US/docs/Web/CSS/width", + "https://github.com/csstree/stylelint-validator/issues/29" + ], + "syntax": "| stretch | <-non-standard-size>" + }, + "height": { + "syntax": "| stretch | <-non-standard-size>" + }, + "min-width": { + "comment": "extend by non-standard width keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width", + "syntax": "| stretch | <-non-standard-size>" + }, + "min-height": { + "syntax": "| stretch | <-non-standard-size>" + }, + "overflow": { + "comment": "extend by vendor keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow", + "syntax": "| <-non-standard-overflow>" + }, + "pause": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<'pause-before'> <'pause-after'>?" + }, + "pause-after": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<time> | none | x-weak | weak | medium | strong | x-strong" + }, + "pause-before": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<time> | none | x-weak | weak | medium | strong | x-strong" + }, + "rest": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<'rest-before'> <'rest-after'>?" + }, + "rest-after": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<time> | none | x-weak | weak | medium | strong | x-strong" + }, + "rest-before": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<time> | none | x-weak | weak | medium | strong | x-strong" + }, + "scroll-timeline": { + "comment": "fix according to spec", + "references": [ + "https://www.w3.org/TR/scroll-animations-1/#scroll-timeline-shorthand" + ], + "syntax": "[ <'scroll-timeline-name'> || <'scroll-timeline-axis'> ]#" + }, + "scroll-timeline-name": { + "comment": "fix according to spec", + "references": [ + "https://w3c.github.io/csswg-drafts/scroll-animations/#propdef-scroll-timeline-name" + ], + "syntax": "[ none | <dashed-ident> ]#" + }, + "src": { + "comment": "added @font-face's src property https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src", + "syntax": "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#" + }, + "speak": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "auto | never | always" + }, + "speak-as": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "normal | spell-out || digits || [ literal-punctuation | no-punctuation ]" + }, + "stroke": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#StrokeProperties" + ], + "syntax": "<paint>" + }, + "stroke-dasharray": { + "comment": "added SVG property; a list of comma and/or white space separated <length>s and <percentage>s", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#StrokeProperties" + ], + "syntax": "none | [ <svg-length>+ ]#" + }, + "stroke-dashoffset": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#StrokeProperties" + ], + "syntax": "<svg-length>" + }, + "stroke-linejoin": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#StrokeProperties" + ], + "syntax": "miter | round | bevel" + }, + "stroke-miterlimit": { + "comment": "added SVG property (<miterlimit> = <number-one-or-greater>) ", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#StrokeProperties" + ], + "syntax": "<number-one-or-greater>" + }, + "stroke-width": { + "comment": "added SVG property", + "references": [ + "https://www.w3.org/TR/SVG/painting.html#StrokeProperties" + ], + "syntax": "<svg-length>" + }, + "text-wrap": { + "comment": "broken in mdn/data", + "syntax": "<'text-wrap-mode'> || <'text-wrap-style'>" + }, + "unicode-bidi": { + "comment": "added prefixed keywords https://developer.mozilla.org/en-US/docs/Web/CSS/unicode-bidi", + "syntax": "| -moz-isolate | -moz-isolate-override | -moz-plaintext | -webkit-isolate | -webkit-isolate-override | -webkit-plaintext" + }, + "unicode-range": { + "comment": "added missed property https://developer.mozilla.org/en-US/docs/Web/CSS/%40font-face/unicode-range", + "syntax": "<urange>#" + }, + "voice-balance": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<number> | left | center | right | leftwards | rightwards" + }, + "voice-duration": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "auto | <time>" + }, + "voice-family": { + "comment": "<name> -> <family-name>, https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "[ [ <family-name> | <generic-voice> ] , ]* [ <family-name> | <generic-voice> ] | preserve" + }, + "voice-pitch": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]" + }, + "voice-range": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]" + }, + "voice-rate": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "[ normal | x-slow | slow | medium | fast | x-fast ] || <percentage>" + }, + "voice-stress": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "normal | strong | moderate | none | reduced" + }, + "voice-volume": { + "comment": "https://www.w3.org/TR/css3-speech/#property-index", + "syntax": "silent | [ [ x-soft | soft | medium | loud | x-loud ] || <decibel> ]" + }, + "writing-mode": { + "comment": "extend with SVG keywords", + "syntax": "| <svg-writing-mode>" + }, + "white-space-trim": { + "syntax": "none | discard-before || discard-after || discard-inner", + "comment": "missed, https://www.w3.org/TR/css-text-4/#white-space-trim" + }, + "word-break": { + "syntax": "normal | break-all | keep-all | break-word | auto-phrase", + "comment": "added in Chrome/Edge 119, not covered by a spec currently (2024-09-02)", + "references": [ + "https://developer.mozilla.org/en-US/docs/Web/CSS/word-break" + ] + } + }, + "types": { + "-legacy-gradient": { + "comment": "added collection of legacy gradient syntaxes", + "syntax": "<-webkit-gradient()> | <-legacy-linear-gradient> | <-legacy-repeating-linear-gradient> | <-legacy-radial-gradient> | <-legacy-repeating-radial-gradient>" + }, + "-legacy-linear-gradient": { + "comment": "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient", + "syntax": "-moz-linear-gradient( <-legacy-linear-gradient-arguments> ) | -webkit-linear-gradient( <-legacy-linear-gradient-arguments> ) | -o-linear-gradient( <-legacy-linear-gradient-arguments> )" + }, + "-legacy-repeating-linear-gradient": { + "comment": "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient", + "syntax": "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> ) | -webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> ) | -o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )" + }, + "-legacy-linear-gradient-arguments": { + "comment": "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient", + "syntax": "[ <angle> | <side-or-corner> ]? , <color-stop-list>" + }, + "-legacy-radial-gradient": { + "comment": "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients", + "syntax": "-moz-radial-gradient( <-legacy-radial-gradient-arguments> ) | -webkit-radial-gradient( <-legacy-radial-gradient-arguments> ) | -o-radial-gradient( <-legacy-radial-gradient-arguments> )" + }, + "-legacy-repeating-radial-gradient": { + "comment": "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients", + "syntax": "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> ) | -webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> ) | -o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )" + }, + "-legacy-radial-gradient-arguments": { + "comment": "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients", + "syntax": "[ <position> , ]? [ [ [ <-legacy-radial-gradient-shape> || <-legacy-radial-gradient-size> ] | [ <length> | <percentage> ]{2} ] , ]? <color-stop-list>" + }, + "-legacy-radial-gradient-size": { + "comment": "before a standard it contains 2 extra keywords (`contain` and `cover`) https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltsize", + "syntax": "closest-side | closest-corner | farthest-side | farthest-corner | contain | cover" + }, + "-legacy-radial-gradient-shape": { + "comment": "define to double sure it doesn't extends in future https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltshape", + "syntax": "circle | ellipse" + }, + "-non-standard-font": { + "comment": "non standard fonts", + "references": [ + "https://webkit.org/blog/3709/using-the-system-font-in-web-content/" + ], + "syntax": "-apple-system-body | -apple-system-headline | -apple-system-subheadline | -apple-system-caption1 | -apple-system-caption2 | -apple-system-footnote | -apple-system-short-body | -apple-system-short-headline | -apple-system-short-subheadline | -apple-system-short-caption1 | -apple-system-short-footnote | -apple-system-tall-body" + }, + "-non-standard-color": { + "comment": "non standard colors", + "references": [ + "http://cssdot.ru/%D0%A1%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA_CSS/color-i305.html", + "https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Mozilla_Color_Preference_Extensions" + ], + "syntax": "-moz-ButtonDefault | -moz-ButtonHoverFace | -moz-ButtonHoverText | -moz-CellHighlight | -moz-CellHighlightText | -moz-Combobox | -moz-ComboboxText | -moz-Dialog | -moz-DialogText | -moz-dragtargetzone | -moz-EvenTreeRow | -moz-Field | -moz-FieldText | -moz-html-CellHighlight | -moz-html-CellHighlightText | -moz-mac-accentdarkestshadow | -moz-mac-accentdarkshadow | -moz-mac-accentface | -moz-mac-accentlightesthighlight | -moz-mac-accentlightshadow | -moz-mac-accentregularhighlight | -moz-mac-accentregularshadow | -moz-mac-chrome-active | -moz-mac-chrome-inactive | -moz-mac-focusring | -moz-mac-menuselect | -moz-mac-menushadow | -moz-mac-menutextselect | -moz-MenuHover | -moz-MenuHoverText | -moz-MenuBarText | -moz-MenuBarHoverText | -moz-nativehyperlinktext | -moz-OddTreeRow | -moz-win-communicationstext | -moz-win-mediatext | -moz-activehyperlinktext | -moz-default-background-color | -moz-default-color | -moz-hyperlinktext | -moz-visitedhyperlinktext | -webkit-activelink | -webkit-focus-ring-color | -webkit-link | -webkit-text" + }, + "-non-standard-image-rendering": { + "comment": "non-standard keywords http://phrogz.net/tmp/canvas_image_zoom.html", + "syntax": "optimize-contrast | -moz-crisp-edges | -o-crisp-edges | -webkit-optimize-contrast" + }, + "-non-standard-overflow": { + "comment": "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow", + "syntax": "overlay | -moz-scrollbars-none | -moz-scrollbars-horizontal | -moz-scrollbars-vertical | -moz-hidden-unscrollable" + }, + "-non-standard-size": { + "comment": "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width", + "syntax": "intrinsic | min-intrinsic | -webkit-fill-available | -webkit-fit-content | -webkit-min-content | -webkit-max-content | -moz-available | -moz-fit-content | -moz-min-content | -moz-max-content" + }, + "-webkit-gradient()": { + "comment": "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/ - TODO: simplify when after match algorithm improvement ( [, point, radius | , point] -> [, radius]? , point )", + "syntax": "-webkit-gradient( <-webkit-gradient-type>, <-webkit-gradient-point> [, <-webkit-gradient-point> | , <-webkit-gradient-radius>, <-webkit-gradient-point> ] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )" + }, + "-webkit-gradient-color-stop": { + "comment": "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/", + "syntax": "from( <color> ) | color-stop( [ <number-zero-one> | <percentage> ] , <color> ) | to( <color> )" + }, + "-webkit-gradient-point": { + "comment": "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/", + "syntax": "[ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]" + }, + "-webkit-gradient-radius": { + "comment": "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/", + "syntax": "<length> | <percentage>" + }, + "-webkit-gradient-type": { + "comment": "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/", + "syntax": "linear | radial" + }, + "-webkit-mask-box-repeat": { + "comment": "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image", + "syntax": "repeat | stretch | round" + }, + "-ms-filter-function-list": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter", + "syntax": "<-ms-filter-function>+" + }, + "-ms-filter-function": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter", + "syntax": "<-ms-filter-function-progid> | <-ms-filter-function-legacy>" + }, + "-ms-filter-function-progid": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter", + "syntax": "'progid:' [ <ident-token> '.' ]* [ <ident-token> | <function-token> <any-value>? ) ]" + }, + "-ms-filter-function-legacy": { + "comment": "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter", + "syntax": "<ident-token> | <function-token> <any-value>? )" + }, + "absolute-color-base": { + "comment": "https://www.w3.org/TR/css-color-4/#color-syntax", + "syntax": "<hex-color> | <absolute-color-function> | <named-color> | transparent" + }, + "absolute-color-function": { + "comment": "https://www.w3.org/TR/css-color-4/#color-syntax", + "syntax": "<rgb()> | <rgba()> | <hsl()> | <hsla()> | <hwb()> | <lab()> | <lch()> | <oklab()> | <oklch()> | <color()>" + }, + "age": { + "comment": "https://www.w3.org/TR/css3-speech/#voice-family", + "syntax": "child | young | old" + }, + "anchor-name": { + "comment": "missed in mdn/data", + "syntax": "<dashed-ident>" + }, + "attr-name": { + "syntax": "<wq-name>" + }, + "attr-fallback": { + "syntax": "<any-value>" + }, + "bg-clip": { + "comment": "missed, https://drafts.csswg.org/css-backgrounds-4/#typedef-bg-clip", + "syntax": "<box> | border | text" + }, + "bottom": { + "comment": "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect", + "syntax": "<length> | auto" + }, + "content-list": { + "comment": "added attr(), see https://github.com/csstree/csstree/issues/201", + "syntax": "[ <string> | contents | <image> | <counter> | <quote> | <target> | <leader()> | <attr()> ]+" + }, + "container-name": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#container-rule", + "syntax": "<custom-ident>" + }, + "container-condition": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#container-rule", + "syntax": "not <query-in-parens> | <query-in-parens> [ [ and <query-in-parens> ]* | [ or <query-in-parens> ]* ]" + }, + "coord-box": { + "syntax": "content-box | padding-box | border-box | fill-box | stroke-box | view-box" + }, + "element()": { + "comment": "https://drafts.csswg.org/css-gcpm/#element-syntax & https://drafts.csswg.org/css-images-4/#element-notation", + "syntax": "element( <custom-ident> , [ first | start | last | first-except ]? ) | element( <id-selector> )" + }, + "generic-voice": { + "comment": "https://www.w3.org/TR/css3-speech/#voice-family", + "syntax": "[ <age>? <gender> <integer>? ]" + }, + "gender": { + "comment": "https://www.w3.org/TR/css3-speech/#voice-family", + "syntax": "male | female | neutral" + }, + "general-enclosed": { + "comment": "remove ident-token, optional any-value, brackets (see https://drafts.csswg.org/mediaqueries-5/#typedef-general-enclosed)", + "syntax": "[ <function-token> <any-value>? ) ] | [ ( <any-value>? ) ]" + }, + "generic-family": { + "comment": "new definition on font-4, https://drafts.csswg.org/css-fonts-4/#typedef-generic-family", + "syntax": "<generic-script-specific>| <generic-complete> | <generic-incomplete> | <-non-standard-generic-family>" + }, + "generic-script-specific": { + "syntax": "generic(kai) | generic(fangsong) | generic(nastaliq)" + }, + "generic-complete": { + "syntax": "serif | sans-serif | system-ui | cursive | fantasy | math | monospace" + }, + "generic-incomplete": { + "syntax": "ui-serif | ui-sans-serif | ui-monospace | ui-rounded" + }, + "-non-standard-generic-family": { + "syntax": "-apple-system | BlinkMacSystemFont", + "references": [ + "https://css-tricks.com/snippets/css/system-font-stack/", + "https://webkit.org/blog/3709/using-the-system-font-in-web-content/" + ] + }, + "gradient": { + "comment": "added legacy syntaxes support", + "syntax": "| <-legacy-gradient>" + }, + "left": { + "comment": "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect", + "syntax": "<length> | auto" + }, + "color": { + "comment": "css-color-5, added non standard color names", + "syntax": "<color-base> | currentColor | <system-color> | <device-cmyk()> | <light-dark()> | <-non-standard-color>" + }, + "color-base": { + "syntax": "<hex-color> | <color-function> | <named-color> | <color-mix()> | transparent" + }, + "color-function": { + "syntax": "<rgb()> | <rgba()> | <hsl()> | <hsla()> | <hwb()> | <lab()> | <lch()> | <oklab()> | <oklch()> | <color()>" + }, + "device-cmyk()": { + "syntax": "<legacy-device-cmyk-syntax> | <modern-device-cmyk-syntax>" + }, + "legacy-device-cmyk-syntax": { + "syntax": "device-cmyk( <number>#{4} )" + }, + "modern-device-cmyk-syntax": { + "syntax": "device-cmyk( <cmyk-component>{4} [ / [ <alpha-value> | none ] ]? )" + }, + "cmyk-component": { + "syntax": "<number> | <percentage> | none" + }, + "color-mix()": { + "syntax": "color-mix( <color-interpolation-method> , [ <color> && <percentage [0,100]>? ]#{2} )" + }, + "color-interpolation-method": { + "syntax": "in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? | <custom-color-space> ]" + }, + "color-space": { + "syntax": "<rectangular-color-space> | <polar-color-space> | <custom-color-space>" + }, + "custom-color-space": { + "syntax": "<dashed-ident>" + }, + "paint": { + "comment": "used by SVG https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint", + "syntax": "none | <color> | <url> [ none | <color> ]? | context-fill | context-stroke" + }, + "palette-identifier": { + "comment": "<palette-identifier> is parsed as a <dashed-ident> (https://drafts.csswg.org/css-fonts/#typedef-font-palette-palette-identifier)", + "syntax": "<dashed-ident>" + }, + "right": { + "comment": "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect", + "syntax": "<length> | auto" + }, + "shape": { + "comment": "missed spaces in function body and add backwards compatible syntax", + "syntax": "rect( <top>, <right>, <bottom>, <left> ) | rect( <top> <right> <bottom> <left> )" + }, + "scope-start": { + "syntax": "<forgiving-selector-list>" + }, + "scope-end": { + "syntax": "<forgiving-selector-list>" + }, + "forgiving-selector-list": { + "syntax": "<complex-real-selector-list>" + }, + "forgiving-relative-selector-list": { + "syntax": "<relative-real-selector-list>" + }, + "selector-list": { + "syntax": "<complex-selector-list>" + }, + "complex-real-selector-list": { + "syntax": "<complex-real-selector>#" + }, + "simple-selector-list": { + "syntax": "<simple-selector>#" + }, + "relative-real-selector-list": { + "syntax": "<relative-real-selector>#" + }, + "complex-selector": { + "syntax": "<complex-selector-unit> [ <combinator>? <complex-selector-unit> ]*" + }, + "complex-selector-unit": { + "syntax": "[ <compound-selector>? <pseudo-compound-selector>* ]!" + }, + "complex-real-selector": { + "syntax": "<compound-selector> [ <combinator>? <compound-selector> ]*" + }, + "relative-real-selector": { + "syntax": "<combinator>? <complex-real-selector>" + }, + "compound-selector": { + "syntax": "[ <type-selector>? <subclass-selector>* ]!" + }, + "pseudo-compound-selector": { + "syntax": " <pseudo-element-selector> <pseudo-class-selector>*" + }, + "simple-selector": { + "syntax": "<type-selector> | <subclass-selector>" + }, + "combinator": { + "syntax": "'>' | '+' | '~' | [ '|' '|' ]" + }, + "pseudo-element-selector": { + "syntax": "':' <pseudo-class-selector> | <legacy-pseudo-element-selector>" + }, + "legacy-pseudo-element-selector": { + "syntax": " ':' [before | after | first-line | first-letter]" + }, + "single-animation-composition": { + "comment": "missed definition", + "references": [ + "https://w3c.github.io/csswg-drafts/css-animations-2/#typedef-single-animation-composition" + ], + "syntax": "replace | add | accumulate" + }, + "svg-length": { + "comment": "All coordinates and lengths in SVG can be specified with or without a unit identifier", + "references": [ + "https://www.w3.org/TR/SVG11/coords.html#Units" + ], + "syntax": "<percentage> | <length> | <number>" + }, + "svg-writing-mode": { + "comment": "SVG specific keywords (deprecated for CSS)", + "references": [ + "https://developer.mozilla.org/en/docs/Web/CSS/writing-mode", + "https://www.w3.org/TR/SVG/text.html#WritingModeProperty" + ], + "syntax": "lr-tb | rl-tb | tb-rl | lr | rl | tb" + }, + "top": { + "comment": "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect", + "syntax": "<length> | auto" + }, + "x": { + "comment": "missed; not sure we should add it, but no others except `cursor` is using it so it's ok for now; https://drafts.csswg.org/css-ui-3/#cursor", + "syntax": "<number>" + }, + "y": { + "comment": "missed; not sure we should add it, but no others except `cursor` is using so it's ok for now; https://drafts.csswg.org/css-ui-3/#cursor", + "syntax": "<number>" + }, + "declaration": { + "comment": "missed, restored by https://drafts.csswg.org/css-syntax", + "syntax": "<ident-token> : <declaration-value>? [ '!' important ]?" + }, + "declaration-list": { + "comment": "missed, restored by https://drafts.csswg.org/css-syntax", + "syntax": "[ <declaration>? ';' ]* <declaration>?" + }, + "url": { + "comment": "https://drafts.csswg.org/css-values-4/#urls", + "syntax": "url( <string> <url-modifier>* ) | <url-token>" + }, + "url-modifier": { + "comment": "https://drafts.csswg.org/css-values-4/#typedef-url-modifier", + "syntax": "<ident> | <function-token> <any-value> )" + }, + "number-zero-one": { + "syntax": "<number [0,1]>" + }, + "number-one-or-greater": { + "syntax": "<number [1,∞]>" + }, + "color()": { + "syntax": "color( <colorspace-params> [ / [ <alpha-value> | none ] ]? )" + }, + "colorspace-params": { + "syntax": "[ <predefined-rgb-params> | <xyz-params>]" + }, + "predefined-rgb-params": { + "syntax": "<predefined-rgb> [ <number> | <percentage> | none ]{3}" + }, + "predefined-rgb": { + "syntax": "srgb | srgb-linear | display-p3 | a98-rgb | prophoto-rgb | rec2020" + }, + "xyz-params": { + "syntax": "<xyz-space> [ <number> | <percentage> | none ]{3}" + }, + "xyz-space": { + "syntax": "xyz | xyz-d50 | xyz-d65" + }, + "oklab()": { + "comment": "https://www.w3.org/TR/css-color-4/#specifying-oklab-oklch", + "syntax": "oklab( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ / [<alpha-value> | none] ]? )" + }, + "oklch()": { + "comment": "https://www.w3.org/TR/css-color-4/#specifying-oklab-oklch", + "syntax": "oklch( [ <percentage> | <number> | none] [ <percentage> | <number> | none] [ <hue> | none] [ / [<alpha-value> | none] ]? )" + }, + "offset-path": { + "syntax": "<ray()> | <url> | <basic-shape>" + }, + "basic-shape": { + "syntax": "<inset()> | <xywh()> | <rect()> | <circle()> | <ellipse()> | <polygon()> | <path()>" + }, + "rect()": { + "comment": "missed, https://drafts.csswg.org/css-shapes/#supported-basic-shapes", + "syntax": "rect( [ <length-percentage> | auto ]{4} [ round <'border-radius'> ]? )" + }, + "xywh()": { + "comment": "missed, https://drafts.csswg.org/css-shapes/#supported-basic-shapes", + "syntax": "xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [ round <'border-radius'> ]? )" + }, + "query-in-parens": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#container-rule", + "syntax": "( <container-condition> ) | ( <size-feature> ) | style( <style-query> ) | <general-enclosed>" + }, + "size-feature": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#typedef-size-feature", + "syntax": "<mf-plain> | <mf-boolean> | <mf-range>" + }, + "style-feature": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#typedef-style-feature", + "syntax": "<declaration>" + }, + "style-query": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#container-rule", + "syntax": "<style-condition> | <style-feature>" + }, + "style-condition": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#container-rule", + "syntax": "not <style-in-parens> | <style-in-parens> [ [ and <style-in-parens> ]* | [ or <style-in-parens> ]* ]" + }, + "style-in-parens": { + "comment": "missed, https://drafts.csswg.org/css-contain-3/#container-rule", + "syntax": "( <style-condition> ) | ( <style-feature> ) | <general-enclosed>" + }, + "-non-standard-display": { + "syntax": "-ms-inline-flexbox | -ms-grid | -ms-inline-grid | -webkit-flex | -webkit-inline-flex | -webkit-box | -webkit-inline-box | -moz-inline-stack | -moz-box | -moz-inline-box" + }, + "inset-area": { + "syntax": "[ [ left | center | right | span-left | span-right | x-start | x-end | span-x-start | span-x-end | x-self-start | x-self-end | span-x-self-start | span-x-self-end | span-all ] || [ top | center | bottom | span-top | span-bottom | y-start | y-end | span-y-start | span-y-end | y-self-start | y-self-end | span-y-self-start | span-y-self-end | span-all ] | [ block-start | center | block-end | span-block-start | span-block-end | span-all ] || [ inline-start | center | inline-end | span-inline-start | span-inline-end | span-all ] | [ self-block-start | self-block-end | span-self-block-start | span-self-block-end | span-all ] || [ self-inline-start | self-inline-end | span-self-inline-start | span-self-inline-end | span-all ] | [ start | center | end | span-start | span-end | span-all ]{1,2} | [ self-start | center | self-end | span-self-start | span-self-end | span-all ]{1,2} ]", + "comment": "initial name for <position-area> before renamed", + "references": [ + "https://www.w3.org/TR/css-anchor-position-1/#inset-area" + ] + }, + "position-area": { + "syntax": "[ [ left | center | right | span-left | span-right | x-start | x-end | span-x-start | span-x-end | x-self-start | x-self-end | span-x-self-start | span-x-self-end | span-all ] || [ top | center | bottom | span-top | span-bottom | y-start | y-end | span-y-start | span-y-end | y-self-start | y-self-end | span-y-self-start | span-y-self-end | span-all ] | [ block-start | center | block-end | span-block-start | span-block-end | span-all ] || [ inline-start | center | inline-end | span-inline-start | span-inline-end | span-all ] | [ self-block-start | center | self-block-end | span-self-block-start | span-self-block-end | span-all ] || [ self-inline-start | center | self-inline-end | span-self-inline-start | span-self-inline-end | span-all ] | [ start | center | end | span-start | span-end | span-all ]{1,2} | [ self-start | center | self-end | span-self-start | span-self-end | span-all ]{1,2} ]", + "comment": "replaced <inset-area>", + "references": [ + "https://drafts.csswg.org/css-anchor-position-1/#typedef-position-area" + ] + }, + "anchor()": { + "syntax": "anchor( <anchor-element>? && <anchor-side>, <length-percentage>? )", + "comment": "missed", + "references": [ + "https://drafts.csswg.org/css-anchor-position-1/#anchor-pos" + ] + }, + "anchor-side": { + "syntax": "inside | outside | top | left | right | bottom | start | end | self-start | self-end | <percentage> | center" + }, + "anchor-size()": { + "syntax": "anchor-size( [ <anchor-element> || <anchor-size> ]? , <length-percentage>? )", + "comment": "missed", + "references": [ + "https://drafts.csswg.org/css-anchor-position-1/#funcdef-anchor-size" + ] + }, + "anchor-size": { + "syntax": "width | height | block | inline | self-block | self-inline" + }, + "anchor-element": { + "syntax": "<dashed-ident>", + "comment": "missed, https://drafts.csswg.org/css-anchor-position-1/#typedef-anchor-element" + }, + "try-size": { + "syntax": "most-width | most-height | most-block-size | most-inline-size", + "comment": "missed, https://drafts.csswg.org/css-anchor-position-1/#typedef-try-size" + }, + "try-tactic": { + "syntax": "flip-block || flip-inline || flip-start", + "comment": "missed, https://drafts.csswg.org/css-anchor-position-1/#typedef-position-try-fallbacks-try-tactic" + }, + "font-variant-css2": { + "syntax": "normal | small-caps", + "comment": "new definition on font-4, https://drafts.csswg.org/css-fonts-4/#font-variant-css21-values" + }, + "font-width-css3": { + "syntax": "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded", + "comment": "new definition on font-4, https://drafts.csswg.org/css-fonts-4/#font-width-css3-values" + }, + "system-family-name": { + "syntax": "caption | icon | menu | message-box | small-caption | status-bar", + "comment": "new definition on font-4, https://drafts.csswg.org/css-fonts-4/#system-family-name-value" + } + } +} diff --git a/vanilla/node_modules/css-tree/dist/csstree.esm.js b/vanilla/node_modules/css-tree/dist/csstree.esm.js new file mode 100644 index 0000000..3a64eec --- /dev/null +++ b/vanilla/node_modules/css-tree/dist/csstree.esm.js @@ -0,0 +1,12 @@ +var Da=Object.create;var nr=Object.defineProperty;var Na=Object.getOwnPropertyDescriptor;var Oa=Object.getOwnPropertyNames;var Fa=Object.getPrototypeOf,Ra=Object.prototype.hasOwnProperty;var Re=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),x=(e,t)=>{for(var r in t)nr(e,r,{get:t[r],enumerable:!0})},Ma=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Oa(t))!Ra.call(e,i)&&i!==r&&nr(e,i,{get:()=>t[i],enumerable:!(n=Na(t,i))||n.enumerable});return e};var Ba=(e,t,r)=>(r=e!=null?Da(Fa(e)):{},Ma(t||!e||!e.__esModule?nr(r,"default",{value:e,enumerable:!0}):r,e));var yo=Re(hr=>{var xo="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");hr.encode=function(e){if(0<=e&&e<xo.length)return xo[e];throw new TypeError("Must be between 0 and 63: "+e)};hr.decode=function(e){var t=65,r=90,n=97,i=122,o=48,a=57,u=43,l=47,s=26,c=52;return t<=e&&e<=r?e-t:n<=e&&e<=i?e-n+s:o<=e&&e<=a?e-o+c:e==u?62:e==l?63:-1}});var Co=Re(fr=>{var ko=yo(),mr=5,wo=1<<mr,vo=wo-1,So=wo;function Qa(e){return e<0?(-e<<1)+1:(e<<1)+0}function Xa(e){var t=(e&1)===1,r=e>>1;return t?-r:r}fr.encode=function(t){var r="",n,i=Qa(t);do n=i&vo,i>>>=mr,i>0&&(n|=So),r+=ko.encode(n);while(i>0);return r};fr.decode=function(t,r,n){var i=t.length,o=0,a=0,u,l;do{if(r>=i)throw new Error("Expected more digits in base 64 VLQ value.");if(l=ko.decode(t.charCodeAt(r++)),l===-1)throw new Error("Invalid base64 digit: "+t.charAt(r-1));u=!!(l&So),l&=vo,o=o+(l<<a),a+=mr}while(u);n.value=Xa(o),n.rest=r}});var Nt=Re(V=>{function $a(e,t,r){if(t in e)return e[t];if(arguments.length===3)return r;throw new Error('"'+t+'" is a required argument.')}V.getArg=$a;var To=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,Za=/^data:.+\,.+$/;function at(e){var t=e.match(To);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}V.urlParse=at;function He(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}V.urlGenerate=He;var Ja=32;function el(e){var t=[];return function(r){for(var n=0;n<t.length;n++)if(t[n].input===r){var i=t[0];return t[0]=t[n],t[n]=i,t[0].result}var o=e(r);return t.unshift({input:r,result:o}),t.length>Ja&&t.pop(),o}}var dr=el(function(t){var r=t,n=at(t);if(n){if(!n.path)return t;r=n.path}for(var i=V.isAbsolute(r),o=[],a=0,u=0;;)if(a=u,u=r.indexOf("/",a),u===-1){o.push(r.slice(a));break}else for(o.push(r.slice(a,u));u<r.length&&r[u]==="/";)u++;for(var l,s=0,u=o.length-1;u>=0;u--)l=o[u],l==="."?o.splice(u,1):l===".."?s++:s>0&&(l===""?(o.splice(u+1,s),s=0):(o.splice(u,2),s--));return r=o.join("/"),r===""&&(r=i?"/":"."),n?(n.path=r,He(n)):r});V.normalize=dr;function Ao(e,t){e===""&&(e="."),t===""&&(t=".");var r=at(t),n=at(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),He(r);if(r||t.match(Za))return t;if(n&&!n.host&&!n.path)return n.host=t,He(n);var i=t.charAt(0)==="/"?t:dr(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=i,He(n)):i}V.join=Ao;V.isAbsolute=function(e){return e.charAt(0)==="/"||To.test(e)};function tl(e,t){e===""&&(e="."),e=e.replace(/\/$/,"");for(var r=0;t.indexOf(e+"/")!==0;){var n=e.lastIndexOf("/");if(n<0||(e=e.slice(0,n),e.match(/^([^\/]+:\/)?\/*$/)))return t;++r}return Array(r+1).join("../")+t.substr(e.length+1)}V.relative=tl;var Lo=function(){var e=Object.create(null);return!("__proto__"in e)}();function Eo(e){return e}function rl(e){return zo(e)?"$"+e:e}V.toSetString=Lo?Eo:rl;function nl(e){return zo(e)?e.slice(1):e}V.fromSetString=Lo?Eo:nl;function zo(e){if(!e)return!1;var t=e.length;if(t<9||e.charCodeAt(t-1)!==95||e.charCodeAt(t-2)!==95||e.charCodeAt(t-3)!==111||e.charCodeAt(t-4)!==116||e.charCodeAt(t-5)!==111||e.charCodeAt(t-6)!==114||e.charCodeAt(t-7)!==112||e.charCodeAt(t-8)!==95||e.charCodeAt(t-9)!==95)return!1;for(var r=t-10;r>=0;r--)if(e.charCodeAt(r)!==36)return!1;return!0}function il(e,t,r){var n=ye(e.source,t.source);return n!==0||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:ye(e.name,t.name)}V.compareByOriginalPositions=il;function ol(e,t,r){var n;return n=e.originalLine-t.originalLine,n!==0||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:ye(e.name,t.name)}V.compareByOriginalPositionsNoSource=ol;function sl(e,t,r){var n=e.generatedLine-t.generatedLine;return n!==0||(n=e.generatedColumn-t.generatedColumn,n!==0||r)||(n=ye(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:ye(e.name,t.name)}V.compareByGeneratedPositionsDeflated=sl;function al(e,t,r){var n=e.generatedColumn-t.generatedColumn;return n!==0||r||(n=ye(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:ye(e.name,t.name)}V.compareByGeneratedPositionsDeflatedNoLine=al;function ye(e,t){return e===t?0:e===null?1:t===null?-1:e>t?1:-1}function ll(e,t){var r=e.generatedLine-t.generatedLine;return r!==0||(r=e.generatedColumn-t.generatedColumn,r!==0)||(r=ye(e.source,t.source),r!==0)||(r=e.originalLine-t.originalLine,r!==0)||(r=e.originalColumn-t.originalColumn,r!==0)?r:ye(e.name,t.name)}V.compareByGeneratedPositionsInflated=ll;function cl(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}V.parseSourceMapInput=cl;function ul(e,t,r){if(t=t||"",e&&(e[e.length-1]!=="/"&&t[0]!=="/"&&(e+="/"),t=e+t),r){var n=at(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var i=n.path.lastIndexOf("/");i>=0&&(n.path=n.path.substring(0,i+1))}t=Ao(He(n),t)}return dr(t)}V.computeSourceURL=ul});var Io=Re(Po=>{var gr=Nt(),br=Object.prototype.hasOwnProperty,De=typeof Map<"u";function ke(){this._array=[],this._set=De?new Map:Object.create(null)}ke.fromArray=function(t,r){for(var n=new ke,i=0,o=t.length;i<o;i++)n.add(t[i],r);return n};ke.prototype.size=function(){return De?this._set.size:Object.getOwnPropertyNames(this._set).length};ke.prototype.add=function(t,r){var n=De?t:gr.toSetString(t),i=De?this.has(t):br.call(this._set,n),o=this._array.length;(!i||r)&&this._array.push(t),i||(De?this._set.set(t,o):this._set[n]=o)};ke.prototype.has=function(t){if(De)return this._set.has(t);var r=gr.toSetString(t);return br.call(this._set,r)};ke.prototype.indexOf=function(t){if(De){var r=this._set.get(t);if(r>=0)return r}else{var n=gr.toSetString(t);if(br.call(this._set,n))return this._set[n]}throw new Error('"'+t+'" is not in the set.')};ke.prototype.at=function(t){if(t>=0&&t<this._array.length)return this._array[t];throw new Error("No element indexed by "+t)};ke.prototype.toArray=function(){return this._array.slice()};Po.ArraySet=ke});var Oo=Re(No=>{var Do=Nt();function pl(e,t){var r=e.generatedLine,n=t.generatedLine,i=e.generatedColumn,o=t.generatedColumn;return n>r||n==r&&o>=i||Do.compareByGeneratedPositionsInflated(e,t)<=0}function Ot(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}Ot.prototype.unsortedForEach=function(t,r){this._array.forEach(t,r)};Ot.prototype.add=function(t){pl(this._last,t)?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t))};Ot.prototype.toArray=function(){return this._sorted||(this._array.sort(Do.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};No.MappingList=Ot});var Ro=Re(Fo=>{var lt=Co(),U=Nt(),Ft=Io().ArraySet,hl=Oo().MappingList;function ie(e){e||(e={}),this._file=U.getArg(e,"file",null),this._sourceRoot=U.getArg(e,"sourceRoot",null),this._skipValidation=U.getArg(e,"skipValidation",!1),this._sources=new Ft,this._names=new Ft,this._mappings=new hl,this._sourcesContents=null}ie.prototype._version=3;ie.fromSourceMap=function(t){var r=t.sourceRoot,n=new ie({file:t.file,sourceRoot:r});return t.eachMapping(function(i){var o={generated:{line:i.generatedLine,column:i.generatedColumn}};i.source!=null&&(o.source=i.source,r!=null&&(o.source=U.relative(r,o.source)),o.original={line:i.originalLine,column:i.originalColumn},i.name!=null&&(o.name=i.name)),n.addMapping(o)}),t.sources.forEach(function(i){var o=i;r!==null&&(o=U.relative(r,i)),n._sources.has(o)||n._sources.add(o);var a=t.sourceContentFor(i);a!=null&&n.setSourceContent(i,a)}),n};ie.prototype.addMapping=function(t){var r=U.getArg(t,"generated"),n=U.getArg(t,"original",null),i=U.getArg(t,"source",null),o=U.getArg(t,"name",null);this._skipValidation||this._validateMapping(r,n,i,o),i!=null&&(i=String(i),this._sources.has(i)||this._sources.add(i)),o!=null&&(o=String(o),this._names.has(o)||this._names.add(o)),this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:i,name:o})};ie.prototype.setSourceContent=function(t,r){var n=t;this._sourceRoot!=null&&(n=U.relative(this._sourceRoot,n)),r!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[U.toSetString(n)]=r):this._sourcesContents&&(delete this._sourcesContents[U.toSetString(n)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))};ie.prototype.applySourceMap=function(t,r,n){var i=r;if(r==null){if(t.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);i=t.file}var o=this._sourceRoot;o!=null&&(i=U.relative(o,i));var a=new Ft,u=new Ft;this._mappings.unsortedForEach(function(l){if(l.source===i&&l.originalLine!=null){var s=t.originalPositionFor({line:l.originalLine,column:l.originalColumn});s.source!=null&&(l.source=s.source,n!=null&&(l.source=U.join(n,l.source)),o!=null&&(l.source=U.relative(o,l.source)),l.originalLine=s.line,l.originalColumn=s.column,s.name!=null&&(l.name=s.name))}var c=l.source;c!=null&&!a.has(c)&&a.add(c);var h=l.name;h!=null&&!u.has(h)&&u.add(h)},this),this._sources=a,this._names=u,t.sources.forEach(function(l){var s=t.sourceContentFor(l);s!=null&&(n!=null&&(l=U.join(n,l)),o!=null&&(l=U.relative(o,l)),this.setSourceContent(l,s))},this)};ie.prototype._validateMapping=function(t,r,n,i){if(r&&typeof r.line!="number"&&typeof r.column!="number")throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!r&&!n&&!i)){if(t&&"line"in t&&"column"in t&&r&&"line"in r&&"column"in r&&t.line>0&&t.column>=0&&r.line>0&&r.column>=0&&n)return;throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:n,original:r,name:i}))}};ie.prototype._serializeMappings=function(){for(var t=0,r=1,n=0,i=0,o=0,a=0,u="",l,s,c,h,m=this._mappings.toArray(),f=0,w=m.length;f<w;f++){if(s=m[f],l="",s.generatedLine!==r)for(t=0;s.generatedLine!==r;)l+=";",r++;else if(f>0){if(!U.compareByGeneratedPositionsInflated(s,m[f-1]))continue;l+=","}l+=lt.encode(s.generatedColumn-t),t=s.generatedColumn,s.source!=null&&(h=this._sources.indexOf(s.source),l+=lt.encode(h-a),a=h,l+=lt.encode(s.originalLine-1-i),i=s.originalLine-1,l+=lt.encode(s.originalColumn-n),n=s.originalColumn,s.name!=null&&(c=this._names.indexOf(s.name),l+=lt.encode(c-o),o=c)),u+=l}return u};ie.prototype._generateSourcesContent=function(t,r){return t.map(function(n){if(!this._sourcesContents)return null;r!=null&&(n=U.relative(r,n));var i=U.toSetString(n);return Object.prototype.hasOwnProperty.call(this._sourcesContents,i)?this._sourcesContents[i]:null},this)};ie.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(t.file=this._file),this._sourceRoot!=null&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t};ie.prototype.toString=function(){return JSON.stringify(this.toJSON())};Fo.SourceMapGenerator=ie});var et={};x(et,{AtKeyword:()=>P,BadString:()=>Ee,BadUrl:()=>Y,CDC:()=>q,CDO:()=>ue,Colon:()=>D,Comma:()=>R,Comment:()=>E,Delim:()=>y,Dimension:()=>k,EOF:()=>ne,Function:()=>g,Hash:()=>T,Ident:()=>p,LeftCurlyBracket:()=>I,LeftParenthesis:()=>v,LeftSquareBracket:()=>W,Number:()=>b,Percentage:()=>L,RightCurlyBracket:()=>H,RightParenthesis:()=>d,RightSquareBracket:()=>K,Semicolon:()=>F,String:()=>_,Url:()=>B,WhiteSpace:()=>S});var ne=0,p=1,g=2,P=3,T=4,_=5,Ee=6,B=7,Y=8,y=9,b=10,L=11,k=12,S=13,ue=14,q=15,D=16,F=17,R=18,W=19,K=20,v=21,d=22,I=23,H=24,E=25;function j(e){return e>=48&&e<=57}function te(e){return j(e)||e>=65&&e<=70||e>=97&&e<=102}function At(e){return e>=65&&e<=90}function _a(e){return e>=97&&e<=122}function Wa(e){return At(e)||_a(e)}function ja(e){return e>=128}function Tt(e){return Wa(e)||ja(e)||e===95}function Me(e){return Tt(e)||j(e)||e===45}function qa(e){return e>=0&&e<=8||e===11||e>=14&&e<=31||e===127}function tt(e){return e===10||e===13||e===12}function pe(e){return tt(e)||e===32||e===9}function $(e,t){return!(e!==92||tt(t)||t===0)}function Be(e,t,r){return e===45?Tt(t)||t===45||$(t,r):Tt(e)?!0:e===92?$(e,t):!1}function Lt(e,t,r){return e===43||e===45?j(t)?2:t===46&&j(r)?3:0:e===46?j(t)?2:0:j(e)?1:0}function Et(e){return e===65279||e===65534?1:0}var ir=new Array(128),Ua=128,rt=130,or=131,zt=132,sr=133;for(let e=0;e<ir.length;e++)ir[e]=pe(e)&&rt||j(e)&&or||Tt(e)&&zt||qa(e)&&sr||e||Ua;function Pt(e){return e<128?ir[e]:zt}function _e(e,t){return t<e.length?e.charCodeAt(t):0}function It(e,t,r){return r===13&&_e(e,t+1)===10?2:1}function be(e,t,r){let n=e.charCodeAt(t);return At(n)&&(n=n|32),n===r}function xe(e,t,r,n){if(r-t!==n.length||t<0||r>e.length)return!1;for(let i=t;i<r;i++){let o=n.charCodeAt(i-t),a=e.charCodeAt(i);if(At(a)&&(a=a|32),a!==o)return!1}return!0}function io(e,t){for(;t>=0&&pe(e.charCodeAt(t));t--);return t+1}function nt(e,t){for(;t<e.length&&pe(e.charCodeAt(t));t++);return t}function ar(e,t){for(;t<e.length&&j(e.charCodeAt(t));t++);return t}function ae(e,t){if(t+=2,te(_e(e,t-1))){for(let n=Math.min(e.length,t+5);t<n&&te(_e(e,t));t++);let r=_e(e,t);pe(r)&&(t+=It(e,t,r))}return t}function it(e,t){for(;t<e.length;t++){let r=e.charCodeAt(t);if(!Me(r)){if($(r,_e(e,t+1))){t=ae(e,t)-1;continue}break}}return t}function ze(e,t){let r=e.charCodeAt(t);if((r===43||r===45)&&(r=e.charCodeAt(t+=1)),j(r)&&(t=ar(e,t+1),r=e.charCodeAt(t)),r===46&&j(e.charCodeAt(t+1))&&(t+=2,t=ar(e,t)),be(e,t,101)){let n=0;r=e.charCodeAt(t+1),(r===45||r===43)&&(n=1,r=e.charCodeAt(t+2)),j(r)&&(t=ar(e,t+1+n+1))}return t}function Dt(e,t){for(;t<e.length;t++){let r=e.charCodeAt(t);if(r===41){t++;break}$(r,_e(e,t+1))&&(t=ae(e,t))}return t}function We(e){if(e.length===1&&!te(e.charCodeAt(0)))return e[0];let t=parseInt(e,16);return(t===0||t>=55296&&t<=57343||t>1114111)&&(t=65533),String.fromCodePoint(t)}var je=["EOF-token","ident-token","function-token","at-keyword-token","hash-token","string-token","bad-string-token","url-token","bad-url-token","delim-token","number-token","percentage-token","dimension-token","whitespace-token","CDO-token","CDC-token","colon-token","semicolon-token","comma-token","[-token","]-token","(-token",")-token","{-token","}-token","comment-token"];function qe(e=null,t){return e===null||e.length<t?new Uint32Array(Math.max(t+1024,16384)):e}var oo=10,Ha=12,so=13;function ao(e){let t=e.source,r=t.length,n=t.length>0?Et(t.charCodeAt(0)):0,i=qe(e.lines,r),o=qe(e.columns,r),a=e.startLine,u=e.startColumn;for(let l=n;l<r;l++){let s=t.charCodeAt(l);i[l]=a,o[l]=u++,(s===oo||s===so||s===Ha)&&(s===so&&l+1<r&&t.charCodeAt(l+1)===oo&&(l++,i[l]=a,o[l]=u),a++,u=1)}i[r]=a,o[r]=u,e.lines=i,e.columns=o,e.computed=!0}var ot=class{constructor(t,r,n,i){this.setSource(t,r,n,i),this.lines=null,this.columns=null}setSource(t="",r=0,n=1,i=1){this.source=t,this.startOffset=r,this.startLine=n,this.startColumn=i,this.computed=!1}getLocation(t,r){return this.computed||ao(this),{source:r,offset:this.startOffset+t,line:this.lines[t],column:this.columns[t]}}getLocationRange(t,r,n){return this.computed||ao(this),{source:n,start:{offset:this.startOffset+t,line:this.lines[t],column:this.columns[t]},end:{offset:this.startOffset+r,line:this.lines[r],column:this.columns[r]}}}};var he=16777215,me=24,Pe=new Uint8Array(32);Pe[2]=22;Pe[21]=22;Pe[19]=20;Pe[23]=24;function lo(e){return Pe[e]!==0}var st=class{constructor(t,r){this.setSource(t,r)}reset(){this.eof=!1,this.tokenIndex=-1,this.tokenType=0,this.tokenStart=this.firstCharOffset,this.tokenEnd=this.firstCharOffset}setSource(t="",r=()=>{}){t=String(t||"");let n=t.length,i=qe(this.offsetAndType,t.length+1),o=qe(this.balance,t.length+1),a=0,u=-1,l=0,s=t.length;this.offsetAndType=null,this.balance=null,o.fill(0),r(t,(c,h,m)=>{let f=a++;if(i[f]=c<<me|m,u===-1&&(u=h),o[f]=s,c===l){let w=o[s];o[s]=f,s=w,l=Pe[i[w]>>me]}else lo(c)&&(s=f,l=Pe[c])}),i[a]=0<<me|n,o[a]=a;for(let c=0;c<a;c++){let h=o[c];if(h<=c){let m=o[h];m!==c&&(o[c]=m)}else h>a&&(o[c]=a)}this.source=t,this.firstCharOffset=u===-1?0:u,this.tokenCount=a,this.offsetAndType=i,this.balance=o,this.reset(),this.next()}lookupType(t){return t+=this.tokenIndex,t<this.tokenCount?this.offsetAndType[t]>>me:0}lookupTypeNonSC(t){for(let r=this.tokenIndex;r<this.tokenCount;r++){let n=this.offsetAndType[r]>>me;if(n!==13&&n!==25&&t--===0)return n}return 0}lookupOffset(t){return t+=this.tokenIndex,t<this.tokenCount?this.offsetAndType[t-1]&he:this.source.length}lookupOffsetNonSC(t){for(let r=this.tokenIndex;r<this.tokenCount;r++){let n=this.offsetAndType[r]>>me;if(n!==13&&n!==25&&t--===0)return r-this.tokenIndex}return 0}lookupValue(t,r){return t+=this.tokenIndex,t<this.tokenCount?xe(this.source,this.offsetAndType[t-1]&he,this.offsetAndType[t]&he,r):!1}getTokenStart(t){return t===this.tokenIndex?this.tokenStart:t>0?t<this.tokenCount?this.offsetAndType[t-1]&he:this.offsetAndType[this.tokenCount]&he:this.firstCharOffset}substrToCursor(t){return this.source.substring(t,this.tokenStart)}isBalanceEdge(t){return this.balance[this.tokenIndex]<t}isDelim(t,r){return r?this.lookupType(r)===9&&this.source.charCodeAt(this.lookupOffset(r))===t:this.tokenType===9&&this.source.charCodeAt(this.tokenStart)===t}skip(t){let r=this.tokenIndex+t;r<this.tokenCount?(this.tokenIndex=r,this.tokenStart=this.offsetAndType[r-1]&he,r=this.offsetAndType[r],this.tokenType=r>>me,this.tokenEnd=r&he):(this.tokenIndex=this.tokenCount,this.next())}next(){let t=this.tokenIndex+1;t<this.tokenCount?(this.tokenIndex=t,this.tokenStart=this.tokenEnd,t=this.offsetAndType[t],this.tokenType=t>>me,this.tokenEnd=t&he):(this.eof=!0,this.tokenIndex=this.tokenCount,this.tokenType=0,this.tokenStart=this.tokenEnd=this.source.length)}skipSC(){for(;this.tokenType===13||this.tokenType===25;)this.next()}skipUntilBalanced(t,r){let n=t,i=0,o=0;e:for(;n<this.tokenCount;n++){if(i=this.balance[n],i<t)break e;switch(o=n>0?this.offsetAndType[n-1]&he:this.firstCharOffset,r(this.source.charCodeAt(o))){case 1:break e;case 2:n++;break e;default:lo(this.offsetAndType[n]>>me)&&(n=i)}}this.skip(n-this.tokenIndex)}forEachToken(t){for(let r=0,n=this.firstCharOffset;r<this.tokenCount;r++){let i=n,o=this.offsetAndType[r],a=o&he,u=o>>me;n=a,t(u,i,a,r)}}dump(){let t=new Array(this.tokenCount);return this.forEachToken((r,n,i,o)=>{t[o]={idx:o,type:je[r],chunk:this.source.substring(n,i),balance:this.balance[o]}}),t}};function Se(e,t){function r(h){return h<u?e.charCodeAt(h):0}function n(){if(s=ze(e,s),Be(r(s),r(s+1),r(s+2))){c=12,s=it(e,s);return}if(r(s)===37){c=11,s++;return}c=10}function i(){let h=s;if(s=it(e,s),xe(e,h,s,"url")&&r(s)===40){if(s=nt(e,s+1),r(s)===34||r(s)===39){c=2,s=h+4;return}a();return}if(r(s)===40){c=2,s++;return}c=1}function o(h){for(h||(h=r(s++)),c=5;s<e.length;s++){let m=e.charCodeAt(s);switch(Pt(m)){case h:s++;return;case rt:if(tt(m)){s+=It(e,s,m),c=6;return}break;case 92:if(s===e.length-1)break;let f=r(s+1);tt(f)?s+=It(e,s+1,f):$(m,f)&&(s=ae(e,s)-1);break}}}function a(){for(c=7,s=nt(e,s);s<e.length;s++){let h=e.charCodeAt(s);switch(Pt(h)){case 41:s++;return;case rt:if(s=nt(e,s),r(s)===41||s>=e.length){s<e.length&&s++;return}s=Dt(e,s),c=8;return;case 34:case 39:case 40:case sr:s=Dt(e,s),c=8;return;case 92:if($(h,r(s+1))){s=ae(e,s)-1;break}s=Dt(e,s),c=8;return}}}e=String(e||"");let u=e.length,l=Et(r(0)),s=l,c;for(;s<u;){let h=e.charCodeAt(s);switch(Pt(h)){case rt:c=13,s=nt(e,s+1);break;case 34:o();break;case 35:Me(r(s+1))||$(r(s+1),r(s+2))?(c=4,s=it(e,s+1)):(c=9,s++);break;case 39:o();break;case 40:c=21,s++;break;case 41:c=22,s++;break;case 43:Lt(h,r(s+1),r(s+2))?n():(c=9,s++);break;case 44:c=18,s++;break;case 45:Lt(h,r(s+1),r(s+2))?n():r(s+1)===45&&r(s+2)===62?(c=15,s=s+3):Be(h,r(s+1),r(s+2))?i():(c=9,s++);break;case 46:Lt(h,r(s+1),r(s+2))?n():(c=9,s++);break;case 47:r(s+1)===42?(c=25,s=e.indexOf("*/",s+2),s=s===-1?e.length:s+2):(c=9,s++);break;case 58:c=16,s++;break;case 59:c=17,s++;break;case 60:r(s+1)===33&&r(s+2)===45&&r(s+3)===45?(c=14,s=s+4):(c=9,s++);break;case 64:Be(r(s+1),r(s+2),r(s+3))?(c=3,s=it(e,s+1)):(c=9,s++);break;case 91:c=19,s++;break;case 92:$(h,r(s+1))?i():(c=9,s++);break;case 93:c=20,s++;break;case 123:c=23,s++;break;case 125:c=24,s++;break;case or:n();break;case zt:i();break;default:c=9,s++}t(c,l,l=s)}}var Ue=null,Z=class e{static createItem(t){return{prev:null,next:null,data:t}}constructor(){this.head=null,this.tail=null,this.cursor=null}createItem(t){return e.createItem(t)}allocateCursor(t,r){let n;return Ue!==null?(n=Ue,Ue=Ue.cursor,n.prev=t,n.next=r,n.cursor=this.cursor):n={prev:t,next:r,cursor:this.cursor},this.cursor=n,n}releaseCursor(){let{cursor:t}=this;this.cursor=t.cursor,t.prev=null,t.next=null,t.cursor=Ue,Ue=t}updateCursors(t,r,n,i){let{cursor:o}=this;for(;o!==null;)o.prev===t&&(o.prev=r),o.next===n&&(o.next=i),o=o.cursor}*[Symbol.iterator](){for(let t=this.head;t!==null;t=t.next)yield t.data}get size(){let t=0;for(let r=this.head;r!==null;r=r.next)t++;return t}get isEmpty(){return this.head===null}get first(){return this.head&&this.head.data}get last(){return this.tail&&this.tail.data}fromArray(t){let r=null;this.head=null;for(let n of t){let i=e.createItem(n);r!==null?r.next=i:this.head=i,i.prev=r,r=i}return this.tail=r,this}toArray(){return[...this]}toJSON(){return[...this]}forEach(t,r=this){let n=this.allocateCursor(null,this.head);for(;n.next!==null;){let i=n.next;n.next=i.next,t.call(r,i.data,i,this)}this.releaseCursor()}forEachRight(t,r=this){let n=this.allocateCursor(this.tail,null);for(;n.prev!==null;){let i=n.prev;n.prev=i.prev,t.call(r,i.data,i,this)}this.releaseCursor()}reduce(t,r,n=this){let i=this.allocateCursor(null,this.head),o=r,a;for(;i.next!==null;)a=i.next,i.next=a.next,o=t.call(n,o,a.data,a,this);return this.releaseCursor(),o}reduceRight(t,r,n=this){let i=this.allocateCursor(this.tail,null),o=r,a;for(;i.prev!==null;)a=i.prev,i.prev=a.prev,o=t.call(n,o,a.data,a,this);return this.releaseCursor(),o}some(t,r=this){for(let n=this.head;n!==null;n=n.next)if(t.call(r,n.data,n,this))return!0;return!1}map(t,r=this){let n=new e;for(let i=this.head;i!==null;i=i.next)n.appendData(t.call(r,i.data,i,this));return n}filter(t,r=this){let n=new e;for(let i=this.head;i!==null;i=i.next)t.call(r,i.data,i,this)&&n.appendData(i.data);return n}nextUntil(t,r,n=this){if(t===null)return;let i=this.allocateCursor(null,t);for(;i.next!==null;){let o=i.next;if(i.next=o.next,r.call(n,o.data,o,this))break}this.releaseCursor()}prevUntil(t,r,n=this){if(t===null)return;let i=this.allocateCursor(t,null);for(;i.prev!==null;){let o=i.prev;if(i.prev=o.prev,r.call(n,o.data,o,this))break}this.releaseCursor()}clear(){this.head=null,this.tail=null}copy(){let t=new e;for(let r of this)t.appendData(r);return t}prepend(t){return this.updateCursors(null,t,this.head,t),this.head!==null?(this.head.prev=t,t.next=this.head):this.tail=t,this.head=t,this}prependData(t){return this.prepend(e.createItem(t))}append(t){return this.insert(t)}appendData(t){return this.insert(e.createItem(t))}insert(t,r=null){if(r!==null)if(this.updateCursors(r.prev,t,r,t),r.prev===null){if(this.head!==r)throw new Error("before doesn't belong to list");this.head=t,r.prev=t,t.next=r,this.updateCursors(null,t)}else r.prev.next=t,t.prev=r.prev,r.prev=t,t.next=r;else this.updateCursors(this.tail,t,null,t),this.tail!==null?(this.tail.next=t,t.prev=this.tail):this.head=t,this.tail=t;return this}insertData(t,r){return this.insert(e.createItem(t),r)}remove(t){if(this.updateCursors(t,t.prev,t,t.next),t.prev!==null)t.prev.next=t.next;else{if(this.head!==t)throw new Error("item doesn't belong to list");this.head=t.next}if(t.next!==null)t.next.prev=t.prev;else{if(this.tail!==t)throw new Error("item doesn't belong to list");this.tail=t.prev}return t.prev=null,t.next=null,t}push(t){this.insert(e.createItem(t))}pop(){return this.tail!==null?this.remove(this.tail):null}unshift(t){this.prepend(e.createItem(t))}shift(){return this.head!==null?this.remove(this.head):null}prependList(t){return this.insertList(t,this.head)}appendList(t){return this.insertList(t)}insertList(t,r){return t.head===null?this:(r!=null?(this.updateCursors(r.prev,t.tail,r,t.head),r.prev!==null?(r.prev.next=t.head,t.head.prev=r.prev):this.head=t.head,r.prev=t.tail,t.tail.next=r):(this.updateCursors(this.tail,t.tail,null,t.head),this.tail!==null?(this.tail.next=t.head,t.head.prev=this.tail):this.head=t.head,this.tail=t.tail),t.head=null,t.tail=null,this)}replace(t,r){"head"in r?this.insertList(r,t):this.insert(r,t),this.remove(t)}};function Ie(e,t){let r=Object.create(SyntaxError.prototype),n=new Error;return Object.assign(r,{name:e,message:t,get stack(){return(n.stack||"").replace(/^(.+\n){1,3}/,`${e}: ${t} +`)}})}var lr=100,co=60,uo=" ";function po({source:e,line:t,column:r,baseLine:n,baseColumn:i},o){function a(w,ee){return s.slice(w,ee).map((G,C)=>String(w+C+1).padStart(m)+" |"+G).join(` +`)}let u=` +`.repeat(Math.max(n-1,0)),l=" ".repeat(Math.max(i-1,0)),s=(u+l+e).split(/\r\n?|\n|\f/),c=Math.max(1,t-o)-1,h=Math.min(t+o,s.length+1),m=Math.max(4,String(h).length)+1,f=0;r+=(uo.length-1)*(s[t-1].substr(0,r-1).match(/\t/g)||[]).length,r>lr&&(f=r-co+3,r=co-2);for(let w=c;w<=h;w++)w>=0&&w<s.length&&(s[w]=s[w].replace(/\t/g,uo),s[w]=(f>0&&s[w].length>f?"\u2026":"")+s[w].substr(f,lr-2)+(s[w].length>f+lr-1?"\u2026":""));return[a(c,t),new Array(r+m+2).join("-")+"^",a(t,h)].filter(Boolean).join(` +`).replace(/^(\s+\d+\s+\|\n)+/,"").replace(/\n(\s+\d+\s+\|)+$/,"")}function cr(e,t,r,n,i,o=1,a=1){return Object.assign(Ie("SyntaxError",e),{source:t,offset:r,line:n,column:i,sourceFragment(l){return po({source:t,line:n,column:i,baseLine:o,baseColumn:a},isNaN(l)?0:l)},get formattedMessage(){return`Parse error: ${e} +`+po({source:t,line:n,column:i,baseLine:o,baseColumn:a},2)}})}function ho(e){let t=this.createList(),r=!1,n={recognizer:e};for(;!this.eof;){switch(this.tokenType){case 25:this.next();continue;case 13:r=!0,this.next();continue}let i=e.getNode.call(this,n);if(i===void 0)break;r&&(e.onWhiteSpace&&e.onWhiteSpace.call(this,i,t,n),r=!1),t.push(i)}return r&&e.onWhiteSpace&&e.onWhiteSpace.call(this,null,t,n),t}var mo=()=>{},Ga=33,Ya=35,ur=59,fo=123,go=0;function Ka(e){return function(){return this[e]()}}function pr(e){let t=Object.create(null);for(let r of Object.keys(e)){let n=e[r],i=n.parse||n;i&&(t[r]=i)}return t}function Va(e){let t={context:Object.create(null),features:Object.assign(Object.create(null),e.features),scope:Object.assign(Object.create(null),e.scope),atrule:pr(e.atrule),pseudo:pr(e.pseudo),node:pr(e.node)};for(let[r,n]of Object.entries(e.parseContext))switch(typeof n){case"function":t.context[r]=n;break;case"string":t.context[r]=Ka(n);break}return{config:t,...t,...t.node}}function bo(e){let t="",r="<unknown>",n=!1,i=mo,o=!1,a=new ot,u=Object.assign(new st,Va(e||{}),{parseAtrulePrelude:!0,parseRulePrelude:!0,parseValue:!0,parseCustomProperty:!1,readSequence:ho,consumeUntilBalanceEnd:()=>0,consumeUntilLeftCurlyBracket(s){return s===fo?1:0},consumeUntilLeftCurlyBracketOrSemicolon(s){return s===fo||s===ur?1:0},consumeUntilExclamationMarkOrSemicolon(s){return s===Ga||s===ur?1:0},consumeUntilSemicolonIncluded(s){return s===ur?2:0},createList(){return new Z},createSingleNodeList(s){return new Z().appendData(s)},getFirstListNode(s){return s&&s.first},getLastListNode(s){return s&&s.last},parseWithFallback(s,c){let h=this.tokenIndex;try{return s.call(this)}catch(m){if(o)throw m;this.skip(h-this.tokenIndex);let f=c.call(this);return o=!0,i(m,f),o=!1,f}},lookupNonWSType(s){let c;do if(c=this.lookupType(s++),c!==13&&c!==25)return c;while(c!==go);return go},charCodeAt(s){return s>=0&&s<t.length?t.charCodeAt(s):0},substring(s,c){return t.substring(s,c)},substrToCursor(s){return this.source.substring(s,this.tokenStart)},cmpChar(s,c){return be(t,s,c)},cmpStr(s,c,h){return xe(t,s,c,h)},consume(s){let c=this.tokenStart;return this.eat(s),this.substrToCursor(c)},consumeFunctionName(){let s=t.substring(this.tokenStart,this.tokenEnd-1);return this.eat(2),s},consumeNumber(s){let c=t.substring(this.tokenStart,ze(t,this.tokenStart));return this.eat(s),c},eat(s){if(this.tokenType!==s){let c=je[s].slice(0,-6).replace(/-/g," ").replace(/^./,f=>f.toUpperCase()),h=`${/[[\](){}]/.test(c)?`"${c}"`:c} is expected`,m=this.tokenStart;switch(s){case 1:this.tokenType===2||this.tokenType===7?(m=this.tokenEnd-1,h="Identifier is expected but function found"):h="Identifier is expected";break;case 4:this.isDelim(Ya)&&(this.next(),m++,h="Name is expected");break;case 11:this.tokenType===10&&(m=this.tokenEnd,h="Percent sign is expected");break}this.error(h,m)}this.next()},eatIdent(s){(this.tokenType!==1||this.lookupValue(0,s)===!1)&&this.error(`Identifier "${s}" is expected`),this.next()},eatDelim(s){this.isDelim(s)||this.error(`Delim "${String.fromCharCode(s)}" is expected`),this.next()},getLocation(s,c){return n?a.getLocationRange(s,c,r):null},getLocationFromList(s){if(n){let c=this.getFirstListNode(s),h=this.getLastListNode(s);return a.getLocationRange(c!==null?c.loc.start.offset-a.startOffset:this.tokenStart,h!==null?h.loc.end.offset-a.startOffset:this.tokenStart,r)}return null},error(s,c){let h=typeof c<"u"&&c<t.length?a.getLocation(c):this.eof?a.getLocation(io(t,t.length-1)):a.getLocation(this.tokenStart);throw new cr(s||"Unexpected input",t,h.offset,h.line,h.column,a.startLine,a.startColumn)}});return Object.assign(function(s,c){t=s,c=c||{},u.setSource(t,Se),a.setSource(t,c.offset,c.line,c.column),r=c.filename||"<unknown>",n=!!c.positions,i=typeof c.onParseError=="function"?c.onParseError:mo,o=!1,u.parseAtrulePrelude="parseAtrulePrelude"in c?!!c.parseAtrulePrelude:!0,u.parseRulePrelude="parseRulePrelude"in c?!!c.parseRulePrelude:!0,u.parseValue="parseValue"in c?!!c.parseValue:!0,u.parseCustomProperty="parseCustomProperty"in c?!!c.parseCustomProperty:!1;let{context:h="default",onComment:m}=c;if(!(h in u.context))throw new Error("Unknown context `"+h+"`");typeof m=="function"&&u.forEachToken((w,ee,G)=>{if(w===25){let C=u.getLocation(ee,G),M=xe(t,G-2,G,"*/")?t.slice(ee+2,G-2):t.slice(ee+2,G);m(M,C)}});let f=u.context[h].call(u,c);return u.eof||u.error(),f},{SyntaxError:cr,config:u.config})}var Bo=Ba(Ro(),1),Mo=new Set(["Atrule","Selector","Declaration"]);function _o(e){let t=new Bo.SourceMapGenerator,r={line:1,column:0},n={line:0,column:0},i={line:1,column:0},o={generated:i},a=1,u=0,l=!1,s=e.node;e.node=function(m){if(m.loc&&m.loc.start&&Mo.has(m.type)){let f=m.loc.start.line,w=m.loc.start.column-1;(n.line!==f||n.column!==w)&&(n.line=f,n.column=w,r.line=a,r.column=u,l&&(l=!1,(r.line!==i.line||r.column!==i.column)&&t.addMapping(o)),l=!0,t.addMapping({source:m.loc.source,original:n,generated:r}))}s.call(this,m),l&&Mo.has(m.type)&&(i.line=a,i.column=u)};let c=e.emit;e.emit=function(m,f,w){for(let ee=0;ee<m.length;ee++)m.charCodeAt(ee)===10?(a++,u=0):u++;c(m,f,w)};let h=e.result;return e.result=function(){return l&&t.addMapping(o),{css:h(),map:t}},e}var Rt={};x(Rt,{safe:()=>yr,spec:()=>gl});var ml=43,fl=45,xr=(e,t)=>{if(e===9&&(e=t),typeof e=="string"){let r=e.charCodeAt(0);return r>127?32768:r<<8}return e},Wo=[[1,1],[1,2],[1,7],[1,8],[1,"-"],[1,10],[1,11],[1,12],[1,15],[1,21],[3,1],[3,2],[3,7],[3,8],[3,"-"],[3,10],[3,11],[3,12],[3,15],[4,1],[4,2],[4,7],[4,8],[4,"-"],[4,10],[4,11],[4,12],[4,15],[12,1],[12,2],[12,7],[12,8],[12,"-"],[12,10],[12,11],[12,12],[12,15],["#",1],["#",2],["#",7],["#",8],["#","-"],["#",10],["#",11],["#",12],["#",15],["-",1],["-",2],["-",7],["-",8],["-","-"],["-",10],["-",11],["-",12],["-",15],[10,1],[10,2],[10,7],[10,8],[10,10],[10,11],[10,12],[10,"%"],[10,15],["@",1],["@",2],["@",7],["@",8],["@","-"],["@",15],[".",10],[".",11],[".",12],["+",10],["+",11],["+",12],["/","*"]],dl=Wo.concat([[1,4],[12,4],[4,4],[3,21],[3,5],[3,16],[11,11],[11,12],[11,2],[11,"-"],[22,1],[22,2],[22,11],[22,12],[22,4],[22,"-"]]);function jo(e){let t=new Set(e.map(([r,n])=>xr(r)<<16|xr(n)));return function(r,n,i){let o=xr(n,i),a=i.charCodeAt(0);return(a===fl&&n!==1&&n!==2&&n!==15||a===ml?t.has(r<<16|a<<8):t.has(r<<16|o))&&this.emit(" ",13,!0),o}}var gl=jo(Wo),yr=jo(dl);var bl=92;function xl(e,t){if(typeof t=="function"){let r=null;e.children.forEach(n=>{r!==null&&t.call(this,r),this.node(n),r=n});return}e.children.forEach(this.node,this)}function yl(e){Se(e,(t,r,n)=>{this.token(t,e.slice(r,n))})}function qo(e){let t=new Map;for(let[r,n]of Object.entries(e.node))typeof(n.generate||n)=="function"&&t.set(r,n.generate||n);return function(r,n){let i="",o=0,a={node(l){if(t.has(l.type))t.get(l.type).call(u,l);else throw new Error("Unknown node type: "+l.type)},tokenBefore:yr,token(l,s){o=this.tokenBefore(o,l,s),this.emit(s,l,!1),l===9&&s.charCodeAt(0)===bl&&this.emit(` +`,13,!0)},emit(l){i+=l},result(){return i}};n&&(typeof n.decorator=="function"&&(a=n.decorator(a)),n.sourceMap&&(a=_o(a)),n.mode in Rt&&(a.tokenBefore=Rt[n.mode]));let u={node:l=>a.node(l),children:xl,token:(l,s)=>a.token(l,s),tokenize:yl};return a.node(r),a.result()}}function Uo(e){return{fromPlainObject(t){return e(t,{enter(r){r.children&&!(r.children instanceof Z)&&(r.children=new Z().fromArray(r.children))}}),t},toPlainObject(t){return e(t,{leave(r){r.children&&r.children instanceof Z&&(r.children=r.children.toArray())}}),t}}}var{hasOwnProperty:kr}=Object.prototype,ct=function(){};function Ho(e){return typeof e=="function"?e:ct}function Go(e,t){return function(r,n,i){r.type===t&&e.call(this,r,n,i)}}function kl(e,t){let r=t.structure,n=[];for(let i in r){if(kr.call(r,i)===!1)continue;let o=r[i],a={name:i,type:!1,nullable:!1};Array.isArray(o)||(o=[o]);for(let u of o)u===null?a.nullable=!0:typeof u=="string"?a.type="node":Array.isArray(u)&&(a.type="list");a.type&&n.push(a)}return n.length?{context:t.walkContext,fields:n}:null}function wl(e){let t={};for(let r in e.node)if(kr.call(e.node,r)){let n=e.node[r];if(!n.structure)throw new Error("Missed `structure` field in `"+r+"` node type definition");t[r]=kl(r,n)}return t}function Yo(e,t){let r=e.fields.slice(),n=e.context,i=typeof n=="string";return t&&r.reverse(),function(o,a,u,l){let s;i&&(s=a[n],a[n]=o);for(let c of r){let h=o[c.name];if(!c.nullable||h){if(c.type==="list"){if(t?h.reduceRight(l,!1):h.reduce(l,!1))return!0}else if(u(h))return!0}}i&&(a[n]=s)}}function Ko({StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:i}){return{Atrule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Rule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Declaration:{StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:i}}}function Vo(e){let t=wl(e),r={},n={},i=Symbol("break-walk"),o=Symbol("skip-node");for(let s in t)kr.call(t,s)&&t[s]!==null&&(r[s]=Yo(t[s],!1),n[s]=Yo(t[s],!0));let a=Ko(r),u=Ko(n),l=function(s,c){function h(C,M,ve){let O=m.call(G,C,M,ve);return O===i?!0:O===o?!1:!!(w.hasOwnProperty(C.type)&&w[C.type](C,G,h,ee)||f.call(G,C,M,ve)===i)}let m=ct,f=ct,w=r,ee=(C,M,ve,O)=>C||h(M,ve,O),G={break:i,skip:o,root:s,stylesheet:null,atrule:null,atrulePrelude:null,rule:null,selector:null,block:null,declaration:null,function:null};if(typeof c=="function")m=c;else if(c&&(m=Ho(c.enter),f=Ho(c.leave),c.reverse&&(w=n),c.visit)){if(a.hasOwnProperty(c.visit))w=c.reverse?u[c.visit]:a[c.visit];else if(!t.hasOwnProperty(c.visit))throw new Error("Bad value `"+c.visit+"` for `visit` option (should be: "+Object.keys(t).sort().join(", ")+")");m=Go(m,c.visit),f=Go(f,c.visit)}if(m===ct&&f===ct)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");h(s)};return l.break=i,l.skip=o,l.find=function(s,c){let h=null;return l(s,function(m,f,w){if(c.call(this,m,f,w))return h=m,i}),h},l.findLast=function(s,c){let h=null;return l(s,{reverse:!0,enter(m,f,w){if(c.call(this,m,f,w))return h=m,i}}),h},l.findAll=function(s,c){let h=[];return l(s,function(m,f,w){c.call(this,m,f,w)&&h.push(m)}),h},l}function vl(e){return e}function Sl(e){let{min:t,max:r,comma:n}=e;return t===0&&r===0?n?"#?":"*":t===0&&r===1?"?":t===1&&r===0?n?"#":"+":t===1&&r===1?"":(n?"#":"")+(t===r?"{"+t+"}":"{"+t+","+(r!==0?r:"")+"}")}function Cl(e){switch(e.type){case"Range":return" ["+(e.min===null?"-\u221E":e.min)+","+(e.max===null?"\u221E":e.max)+"]";default:throw new Error("Unknown node type `"+e.type+"`")}}function Tl(e,t,r,n){let i=e.combinator===" "||n?e.combinator:" "+e.combinator+" ",o=e.terms.map(a=>Mt(a,t,r,n)).join(i);return e.explicit||r?(n||o[0]===","?"[":"[ ")+o+(n?"]":" ]"):o}function Mt(e,t,r,n){let i;switch(e.type){case"Group":i=Tl(e,t,r,n)+(e.disallowEmpty?"!":"");break;case"Multiplier":return Mt(e.term,t,r,n)+t(Sl(e),e);case"Boolean":i="<boolean-expr["+Mt(e.term,t,r,n)+"]>";break;case"Type":i="<"+e.name+(e.opts?t(Cl(e.opts),e.opts):"")+">";break;case"Property":i="<'"+e.name+"'>";break;case"Keyword":i=e.name;break;case"AtKeyword":i="@"+e.name;break;case"Function":i=e.name+"(";break;case"String":case"Token":i=e.value;break;case"Comma":i=",";break;default:throw new Error("Unknown node type `"+e.type+"`")}return t(i,e)}function Ne(e,t){let r=vl,n=!1,i=!1;return typeof t=="function"?r=t:t&&(n=!!t.forceBraces,i=!!t.compact,typeof t.decorate=="function"&&(r=t.decorate)),Mt(e,r,n,i)}var Qo={offset:0,line:1,column:1};function Al(e,t){let r=e.tokens,n=e.longestMatch,i=n<r.length&&r[n].node||null,o=i!==t?i:null,a=0,u=0,l=0,s="",c,h;for(let m=0;m<r.length;m++){let f=r[m].value;m===n&&(u=f.length,a=s.length),o!==null&&r[m].node===o&&(m<=n?l++:l=0),s+=f}return n===r.length||l>1?(c=Bt(o||t,"end")||ut(Qo,s),h=ut(c)):(c=Bt(o,"start")||ut(Bt(t,"start")||Qo,s.slice(0,a)),h=Bt(o,"end")||ut(c,s.substr(a,u))),{css:s,mismatchOffset:a,mismatchLength:u,start:c,end:h}}function Bt(e,t){let r=e&&e.loc&&e.loc[t];return r?"line"in r?ut(r):r:null}function ut({offset:e,line:t,column:r},n){let i={offset:e,line:t,column:r};if(n){let o=n.split(/\n|\r\n?|\f/);i.offset+=n.length,i.line+=o.length-1,i.column=o.length===1?i.column+n.length:o.pop().length+1}return i}var Ge=function(e,t){let r=Ie("SyntaxReferenceError",e+(t?" `"+t+"`":""));return r.reference=t,r},Xo=function(e,t,r,n){let i=Ie("SyntaxMatchError",e),{css:o,mismatchOffset:a,mismatchLength:u,start:l,end:s}=Al(n,r);return i.rawMessage=e,i.syntax=t?Ne(t):"<generic>",i.css=o,i.mismatchOffset=a,i.mismatchLength=u,i.message=e+` + syntax: `+i.syntax+` + value: `+(o||"<empty string>")+` + --------`+new Array(i.mismatchOffset+1).join("-")+"^",Object.assign(i,l),i.loc={source:r&&r.loc&&r.loc.source||"<unknown>",start:l,end:s},i};var _t=new Map,Ye=new Map,Wt=45,jt=Ll,wr=El,Xf=vr;function qt(e,t){return t=t||0,e.length-t>=2&&e.charCodeAt(t)===Wt&&e.charCodeAt(t+1)===Wt}function vr(e,t){if(t=t||0,e.length-t>=3&&e.charCodeAt(t)===Wt&&e.charCodeAt(t+1)!==Wt){let r=e.indexOf("-",t+2);if(r!==-1)return e.substring(t,r+1)}return""}function Ll(e){if(_t.has(e))return _t.get(e);let t=e.toLowerCase(),r=_t.get(t);if(r===void 0){let n=qt(t,0),i=n?"":vr(t,0);r=Object.freeze({basename:t.substr(i.length),name:t,prefix:i,vendor:i,custom:n})}return _t.set(e,r),r}function El(e){if(Ye.has(e))return Ye.get(e);let t=e,r=e[0];r==="/"?r=e[1]==="/"?"//":"/":r!=="_"&&r!=="*"&&r!=="$"&&r!=="#"&&r!=="+"&&r!=="&"&&(r="");let n=qt(t,r.length);if(!n&&(t=t.toLowerCase(),Ye.has(t))){let u=Ye.get(t);return Ye.set(e,u),u}let i=n?"":vr(t,r.length),o=t.substr(0,r.length+i.length),a=Object.freeze({basename:t.substr(o.length),name:t.substr(r.length),hack:r,vendor:i,prefix:o,custom:n});return Ye.set(e,a),a}var Ke=["initial","inherit","unset","revert","revert-layer"];var ht=43,fe=45,Sr=110,Ve=!0,Pl=!1;function Tr(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function pt(e,t,r){for(;e!==null&&(e.type===13||e.type===25);)e=r(++t);return t}function Ce(e,t,r,n){if(!e)return 0;let i=e.value.charCodeAt(t);if(i===ht||i===fe){if(r)return 0;t++}for(;t<e.value.length;t++)if(!j(e.value.charCodeAt(t)))return 0;return n+1}function Cr(e,t,r){let n=!1,i=pt(e,t,r);if(e=r(i),e===null)return t;if(e.type!==10)if(Tr(e,ht)||Tr(e,fe)){if(n=!0,i=pt(r(++i),i,r),e=r(i),e===null||e.type!==10)return 0}else return t;if(!n){let o=e.value.charCodeAt(0);if(o!==ht&&o!==fe)return 0}return Ce(e,n?0:1,n,i)}function Ar(e,t){let r=0;if(!e)return 0;if(e.type===10)return Ce(e,0,Pl,r);if(e.type===1&&e.value.charCodeAt(0)===fe){if(!be(e.value,1,Sr))return 0;switch(e.value.length){case 2:return Cr(t(++r),r,t);case 3:return e.value.charCodeAt(2)!==fe?0:(r=pt(t(++r),r,t),e=t(r),Ce(e,0,Ve,r));default:return e.value.charCodeAt(2)!==fe?0:Ce(e,3,Ve,r)}}else if(e.type===1||Tr(e,ht)&&t(r+1).type===1){if(e.type!==1&&(e=t(++r)),e===null||!be(e.value,0,Sr))return 0;switch(e.value.length){case 1:return Cr(t(++r),r,t);case 2:return e.value.charCodeAt(1)!==fe?0:(r=pt(t(++r),r,t),e=t(r),Ce(e,0,Ve,r));default:return e.value.charCodeAt(1)!==fe?0:Ce(e,2,Ve,r)}}else if(e.type===12){let n=e.value.charCodeAt(0),i=n===ht||n===fe?1:0,o=i;for(;o<e.value.length&&j(e.value.charCodeAt(o));o++);return o===i||!be(e.value,o,Sr)?0:o+1===e.value.length?Cr(t(++r),r,t):e.value.charCodeAt(o+1)!==fe?0:o+2===e.value.length?(r=pt(t(++r),r,t),e=t(r),Ce(e,0,Ve,r)):Ce(e,o+2,Ve,r)}return 0}var Il=43,$o=45,Zo=63,Dl=117;function Lr(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function Nl(e,t){return e.value.charCodeAt(0)===t}function mt(e,t,r){let n=0;for(let i=t;i<e.value.length;i++){let o=e.value.charCodeAt(i);if(o===$o&&r&&n!==0)return mt(e,t+n+1,!1),6;if(!te(o)||++n>6)return 0}return n}function Ut(e,t,r){if(!e)return 0;for(;Lr(r(t),Zo);){if(++e>6)return 0;t++}return t}function Er(e,t){let r=0;if(e===null||e.type!==1||!be(e.value,0,Dl)||(e=t(++r),e===null))return 0;if(Lr(e,Il))return e=t(++r),e===null?0:e.type===1?Ut(mt(e,0,!0),++r,t):Lr(e,Zo)?Ut(1,++r,t):0;if(e.type===10){let n=mt(e,1,!0);return n===0?0:(e=t(++r),e===null?r:e.type===12||e.type===10?!Nl(e,$o)||!mt(e,1,!1)?0:r+1:Ut(n,r,t))}return e.type===12?Ut(mt(e,1,!0),++r,t):0}var Ol=["calc(","-moz-calc(","-webkit-calc("],zr=new Map([[2,22],[21,22],[19,20],[23,24]]);function le(e,t){return t<e.length?e.charCodeAt(t):0}function Jo(e,t){return xe(e,0,e.length,t)}function es(e,t){for(let r=0;r<t.length;r++)if(Jo(e,t[r]))return!0;return!1}function ts(e,t){return t!==e.length-2?!1:le(e,t)===92&&j(le(e,t+1))}function Ht(e,t,r){if(e&&e.type==="Range"){let n=Number(r!==void 0&&r!==t.length?t.substr(0,r):t);if(isNaN(n)||e.min!==null&&n<e.min&&typeof e.min!="string"||e.max!==null&&n>e.max&&typeof e.max!="string")return!0}return!1}function Fl(e,t){let r=0,n=[],i=0;e:do{switch(e.type){case 24:case 22:case 20:if(e.type!==r)break e;if(r=n.pop(),n.length===0){i++;break e}break;case 2:case 21:case 19:case 23:n.push(r),r=zr.get(e.type);break}i++}while(e=t(i));return i}function oe(e){return function(t,r,n){return t===null?0:t.type===2&&es(t.value,Ol)?Fl(t,r):e(t,r,n)}}function N(e){return function(t){return t===null||t.type!==e?0:1}}function Rl(e){if(e===null||e.type!==1)return 0;let t=e.value.toLowerCase();return es(t,Ke)||Jo(t,"default")?0:1}function rs(e){return e===null||e.type!==1||le(e.value,0)!==45||le(e.value,1)!==45?0:1}function Ml(e){return!rs(e)||e.value==="--"?0:1}function Bl(e){if(e===null||e.type!==4)return 0;let t=e.value.length;if(t!==4&&t!==5&&t!==7&&t!==9)return 0;for(let r=1;r<t;r++)if(!te(le(e.value,r)))return 0;return 1}function _l(e){return e===null||e.type!==4||!Be(le(e.value,1),le(e.value,2),le(e.value,3))?0:1}function Wl(e,t){if(!e)return 0;let r=0,n=[],i=0;e:do{switch(e.type){case 6:case 8:break e;case 24:case 22:case 20:if(e.type!==r)break e;r=n.pop();break;case 17:if(r===0)break e;break;case 9:if(r===0&&e.value==="!")break e;break;case 2:case 21:case 19:case 23:n.push(r),r=zr.get(e.type);break}i++}while(e=t(i));return i}function jl(e,t){if(!e)return 0;let r=0,n=[],i=0;e:do{switch(e.type){case 6:case 8:break e;case 24:case 22:case 20:if(e.type!==r)break e;r=n.pop();break;case 2:case 21:case 19:case 23:n.push(r),r=zr.get(e.type);break}i++}while(e=t(i));return i}function we(e){return e&&(e=new Set(e)),function(t,r,n){if(t===null||t.type!==12)return 0;let i=ze(t.value,0);if(e!==null){let o=t.value.indexOf("\\",i),a=o===-1||!ts(t.value,o)?t.value.substr(i):t.value.substring(i,o);if(e.has(a.toLowerCase())===!1)return 0}return Ht(n,t.value,i)?0:1}}function ql(e,t,r){return e===null||e.type!==11||Ht(r,e.value,e.value.length-1)?0:1}function ns(e){return typeof e!="function"&&(e=function(){return 0}),function(t,r,n){return t!==null&&t.type===10&&Number(t.value)===0?1:e(t,r,n)}}function Ul(e,t,r){if(e===null)return 0;let n=ze(e.value,0);return!(n===e.value.length)&&!ts(e.value,n)||Ht(r,e.value,n)?0:1}function Hl(e,t,r){if(e===null||e.type!==10)return 0;let n=le(e.value,0)===43||le(e.value,0)===45?1:0;for(;n<e.value.length;n++)if(!j(le(e.value,n)))return 0;return Ht(r,e.value,n)?0:1}var Gl={"ident-token":N(1),"function-token":N(2),"at-keyword-token":N(3),"hash-token":N(4),"string-token":N(5),"bad-string-token":N(6),"url-token":N(7),"bad-url-token":N(8),"delim-token":N(9),"number-token":N(10),"percentage-token":N(11),"dimension-token":N(12),"whitespace-token":N(13),"CDO-token":N(14),"CDC-token":N(15),"colon-token":N(16),"semicolon-token":N(17),"comma-token":N(18),"[-token":N(19),"]-token":N(20),"(-token":N(21),")-token":N(22),"{-token":N(23),"}-token":N(24)},Yl={string:N(5),ident:N(1),percentage:oe(ql),zero:ns(),number:oe(Ul),integer:oe(Hl),"custom-ident":Rl,"dashed-ident":rs,"custom-property-name":Ml,"hex-color":Bl,"id-selector":_l,"an-plus-b":Ar,urange:Er,"declaration-value":Wl,"any-value":jl};function Kl(e){let{angle:t,decibel:r,frequency:n,flex:i,length:o,resolution:a,semitones:u,time:l}=e||{};return{dimension:oe(we(null)),angle:oe(we(t)),decibel:oe(we(r)),frequency:oe(we(n)),flex:oe(we(i)),length:oe(ns(we(o))),resolution:oe(we(a)),semitones:oe(we(u)),time:oe(we(l))}}function is(e){return{...Gl,...Yl,...Kl(e)}}var Gt={};x(Gt,{angle:()=>Ql,decibel:()=>ec,flex:()=>Jl,frequency:()=>$l,length:()=>Vl,resolution:()=>Zl,semitones:()=>tc,time:()=>Xl});var Vl=["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],Ql=["deg","grad","rad","turn"],Xl=["s","ms"],$l=["hz","khz"],Zl=["dpi","dpcm","dppx","x"],Jl=["fr"],ec=["db"],tc=["st"];var bs={};x(bs,{SyntaxError:()=>Yt,generate:()=>Ne,parse:()=>Qe,walk:()=>Xt});function Yt(e,t,r){return Object.assign(Ie("SyntaxError",e),{input:t,offset:r,rawMessage:e,message:e+` + `+t+` +--`+new Array((r||t.length)+1).join("-")+"^"})}var rc=9,nc=10,ic=12,oc=13,sc=32,os=new Uint8Array(128).map((e,t)=>/[a-zA-Z0-9\-]/.test(String.fromCharCode(t))?1:0),Kt=class{constructor(t){this.str=t,this.pos=0}charCodeAt(t){return t<this.str.length?this.str.charCodeAt(t):0}charCode(){return this.charCodeAt(this.pos)}isNameCharCode(t=this.charCode()){return t<128&&os[t]===1}nextCharCode(){return this.charCodeAt(this.pos+1)}nextNonWsCode(t){return this.charCodeAt(this.findWsEnd(t))}skipWs(){this.pos=this.findWsEnd(this.pos)}findWsEnd(t){for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r!==oc&&r!==nc&&r!==ic&&r!==sc&&r!==rc)break}return t}substringToPos(t){return this.str.substring(this.pos,this.pos=t)}eat(t){this.charCode()!==t&&this.error("Expect `"+String.fromCharCode(t)+"`"),this.pos++}peek(){return this.pos<this.str.length?this.str.charAt(this.pos++):""}error(t){throw new Yt(t,this.str,this.pos)}scanSpaces(){return this.substringToPos(this.findWsEnd(this.pos))}scanWord(){let t=this.pos;for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r>=128||os[r]===0)break}return this.pos===t&&this.error("Expect a keyword"),this.substringToPos(t)}scanNumber(){let t=this.pos;for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r<48||r>57)break}return this.pos===t&&this.error("Expect a number"),this.substringToPos(t)}scanString(){let t=this.str.indexOf("'",this.pos+1);return t===-1&&(this.pos=this.str.length,this.error("Expect an apostrophe")),this.substringToPos(t+1)}};var ac=9,lc=10,cc=12,uc=13,pc=32,ms=33,Nr=35,ss=38,Vt=39,fs=40,hc=41,ds=42,Or=43,Fr=44,as=45,Rr=60,Ir=62,Dr=63,mc=64,ft=91,dt=93,Qt=123,ls=124,cs=125,us=8734,ps={" ":1,"&&":2,"||":3,"|":4};function hs(e){let t=null,r=null;return e.eat(Qt),e.skipWs(),t=e.scanNumber(e),e.skipWs(),e.charCode()===Fr?(e.pos++,e.skipWs(),e.charCode()!==cs&&(r=e.scanNumber(e),e.skipWs())):r=t,e.eat(cs),{min:Number(t),max:r?Number(r):0}}function fc(e){let t=null,r=!1;switch(e.charCode()){case ds:e.pos++,t={min:0,max:0};break;case Or:e.pos++,t={min:1,max:0};break;case Dr:e.pos++,t={min:0,max:1};break;case Nr:e.pos++,r=!0,e.charCode()===Qt?t=hs(e):e.charCode()===Dr?(e.pos++,t={min:0,max:0}):t={min:1,max:0};break;case Qt:t=hs(e);break;default:return null}return{type:"Multiplier",comma:r,min:t.min,max:t.max,term:null}}function Te(e,t){let r=fc(e);return r!==null?(r.term=t,e.charCode()===Nr&&e.charCodeAt(e.pos-1)===Or?Te(e,r):r):t}function Pr(e){let t=e.peek();return t===""?null:Te(e,{type:"Token",value:t})}function dc(e){let t;return e.eat(Rr),e.eat(Vt),t=e.scanWord(),e.eat(Vt),e.eat(Ir),Te(e,{type:"Property",name:t})}function gc(e){let t=null,r=null,n=1;return e.eat(ft),e.charCode()===as&&(e.peek(),n=-1),n==-1&&e.charCode()===us?e.peek():(t=n*Number(e.scanNumber(e)),e.isNameCharCode()&&(t+=e.scanWord())),e.skipWs(),e.eat(Fr),e.skipWs(),e.charCode()===us?e.peek():(n=1,e.charCode()===as&&(e.peek(),n=-1),r=n*Number(e.scanNumber(e)),e.isNameCharCode()&&(r+=e.scanWord())),e.eat(dt),{type:"Range",min:t,max:r}}function bc(e){let t,r=null;if(e.eat(Rr),t=e.scanWord(),t==="boolean-expr"){e.eat(ft);let n=Mr(e,dt);return e.eat(dt),e.eat(Ir),Te(e,{type:"Boolean",term:n.terms.length===1?n.terms[0]:n})}return e.charCode()===fs&&e.nextCharCode()===hc&&(e.pos+=2,t+="()"),e.charCodeAt(e.findWsEnd(e.pos))===ft&&(e.skipWs(),r=gc(e)),e.eat(Ir),Te(e,{type:"Type",name:t,opts:r})}function xc(e){let t=e.scanWord();return e.charCode()===fs?(e.pos++,{type:"Function",name:t}):Te(e,{type:"Keyword",name:t})}function yc(e,t){function r(i,o){return{type:"Group",terms:i,combinator:o,disallowEmpty:!1,explicit:!1}}let n;for(t=Object.keys(t).sort((i,o)=>ps[i]-ps[o]);t.length>0;){n=t.shift();let i=0,o=0;for(;i<e.length;i++){let a=e[i];a.type==="Combinator"&&(a.value===n?(o===-1&&(o=i-1),e.splice(i,1),i--):(o!==-1&&i-o>1&&(e.splice(o,i-o,r(e.slice(o,i),n)),i=o+1),o=-1))}o!==-1&&t.length&&e.splice(o,i-o,r(e.slice(o,i),n))}return n}function Mr(e,t){let r=Object.create(null),n=[],i,o=null,a=e.pos;for(;e.charCode()!==t&&(i=wc(e,t));)i.type!=="Spaces"&&(i.type==="Combinator"?((o===null||o.type==="Combinator")&&(e.pos=a,e.error("Unexpected combinator")),r[i.value]=!0):o!==null&&o.type!=="Combinator"&&(r[" "]=!0,n.push({type:"Combinator",value:" "})),n.push(i),o=i,a=e.pos);return o!==null&&o.type==="Combinator"&&(e.pos-=a,e.error("Unexpected combinator")),{type:"Group",terms:n,combinator:yc(n,r)||" ",disallowEmpty:!1,explicit:!1}}function kc(e,t){let r;return e.eat(ft),r=Mr(e,t),e.eat(dt),r.explicit=!0,e.charCode()===ms&&(e.pos++,r.disallowEmpty=!0),r}function wc(e,t){let r=e.charCode();switch(r){case dt:break;case ft:return Te(e,kc(e,t));case Rr:return e.nextCharCode()===Vt?dc(e):bc(e);case ls:return{type:"Combinator",value:e.substringToPos(e.pos+(e.nextCharCode()===ls?2:1))};case ss:return e.pos++,e.eat(ss),{type:"Combinator",value:"&&"};case Fr:return e.pos++,{type:"Comma"};case Vt:return Te(e,{type:"String",value:e.scanString()});case pc:case ac:case lc:case uc:case cc:return{type:"Spaces",value:e.scanSpaces()};case mc:return r=e.nextCharCode(),e.isNameCharCode(r)?(e.pos++,{type:"AtKeyword",name:e.scanWord()}):Pr(e);case ds:case Or:case Dr:case Nr:case ms:break;case Qt:if(r=e.nextCharCode(),r<48||r>57)return Pr(e);break;default:return e.isNameCharCode(r)?xc(e):Pr(e)}}function Qe(e){let t=new Kt(e),r=Mr(t);return t.pos!==e.length&&t.error("Unexpected input"),r.terms.length===1&&r.terms[0].type==="Group"?r.terms[0]:r}var gt=function(){};function gs(e){return typeof e=="function"?e:gt}function Xt(e,t,r){function n(a){switch(i.call(r,a),a.type){case"Group":a.terms.forEach(n);break;case"Multiplier":case"Boolean":n(a.term);break;case"Type":case"Property":case"Keyword":case"AtKeyword":case"Function":case"String":case"Token":case"Comma":break;default:throw new Error("Unknown type: "+a.type)}o.call(r,a)}let i=gt,o=gt;if(typeof t=="function"?i=t:t&&(i=gs(t.enter),o=gs(t.leave)),i===gt&&o===gt)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");n(e,r)}var vc={decorator(e){let t=[],r=null;return{...e,node(n){let i=r;r=n,e.node.call(this,n),r=i},emit(n,i,o){t.push({type:i,value:n,node:o?null:r})},result(){return t}}}};function Sc(e){let t=[];return Se(e,(r,n,i)=>t.push({type:r,value:e.slice(n,i),node:null})),t}function xs(e,t){return typeof e=="string"?Sc(e):t.generate(e,vc)}var A={type:"Match"},z={type:"Mismatch"},$t={type:"DisallowEmpty"},Cc=40,Tc=41;function J(e,t,r){return t===A&&r===z||e===A&&t===A&&r===A?e:(e.type==="If"&&e.else===z&&t===A&&(t=e.then,e=e.match),{type:"If",match:e,then:t,else:r})}function ks(e){return e.length>2&&e.charCodeAt(e.length-2)===Cc&&e.charCodeAt(e.length-1)===Tc}function ys(e){return e.type==="Keyword"||e.type==="AtKeyword"||e.type==="Function"||e.type==="Type"&&ks(e.name)}function Ae(e,t=" ",r=!1){return{type:"Group",terms:e,combinator:t,disallowEmpty:!1,explicit:r}}function bt(e,t,r=new Set){if(!r.has(e))switch(r.add(e),e.type){case"If":e.match=bt(e.match,t,r),e.then=bt(e.then,t,r),e.else=bt(e.else,t,r);break;case"Type":return t[e.name]||e}return e}function Br(e,t,r){switch(e){case" ":{let n=A;for(let i=t.length-1;i>=0;i--){let o=t[i];n=J(o,n,z)}return n}case"|":{let n=z,i=null;for(let o=t.length-1;o>=0;o--){let a=t[o];if(ys(a)&&(i===null&&o>0&&ys(t[o-1])&&(i=Object.create(null),n=J({type:"Enum",map:i},A,n)),i!==null)){let u=(ks(a.name)?a.name.slice(0,-1):a.name).toLowerCase();if(!(u in i)){i[u]=a;continue}}i=null,n=J(a,A,n)}return n}case"&&":{if(t.length>5)return{type:"MatchOnce",terms:t,all:!0};let n=z;for(let i=t.length-1;i>=0;i--){let o=t[i],a;t.length>1?a=Br(e,t.filter(function(u){return u!==o}),!1):a=A,n=J(o,a,n)}return n}case"||":{if(t.length>5)return{type:"MatchOnce",terms:t,all:!1};let n=r?A:z;for(let i=t.length-1;i>=0;i--){let o=t[i],a;t.length>1?a=Br(e,t.filter(function(u){return u!==o}),!0):a=A,n=J(o,a,n)}return n}}}function Ac(e){let t=A,r=Xe(e.term);if(e.max===0)r=J(r,$t,z),t=J(r,null,z),t.then=J(A,A,t),e.comma&&(t.then.else=J({type:"Comma",syntax:e},t,z));else for(let n=e.min||1;n<=e.max;n++)e.comma&&t!==A&&(t=J({type:"Comma",syntax:e},t,z)),t=J(r,J(A,A,t),z);if(e.min===0)t=J(A,A,t);else for(let n=0;n<e.min-1;n++)e.comma&&t!==A&&(t=J({type:"Comma",syntax:e},t,z)),t=J(r,t,z);return t}function Xe(e){if(typeof e=="function")return{type:"Generic",fn:e};switch(e.type){case"Group":{let t=Br(e.combinator,e.terms.map(Xe),!1);return e.disallowEmpty&&(t=J(t,$t,z)),t}case"Multiplier":return Ac(e);case"Boolean":{let t=Xe(e.term),r=Xe(Ae([Ae([{type:"Keyword",name:"not"},{type:"Type",name:"!boolean-group"}]),Ae([{type:"Type",name:"!boolean-group"},Ae([{type:"Multiplier",comma:!1,min:0,max:0,term:Ae([{type:"Keyword",name:"and"},{type:"Type",name:"!boolean-group"}])},{type:"Multiplier",comma:!1,min:0,max:0,term:Ae([{type:"Keyword",name:"or"},{type:"Type",name:"!boolean-group"}])}],"|")])],"|")),n=Xe(Ae([{type:"Type",name:"!term"},Ae([{type:"Token",value:"("},{type:"Type",name:"!self"},{type:"Token",value:")"}]),{type:"Type",name:"general-enclosed"}],"|"));return bt(n,{"!term":t,"!self":r}),bt(r,{"!boolean-group":n}),r}case"Type":case"Property":return{type:e.type,name:e.name,syntax:e};case"Keyword":return{type:e.type,name:e.name.toLowerCase(),syntax:e};case"AtKeyword":return{type:e.type,name:"@"+e.name.toLowerCase(),syntax:e};case"Function":return{type:e.type,name:e.name.toLowerCase()+"(",syntax:e};case"String":return e.value.length===3?{type:"Token",value:e.value.charAt(1),syntax:e}:{type:e.type,value:e.value.substr(1,e.value.length-2).replace(/\\'/g,"'"),syntax:e};case"Token":return{type:e.type,value:e.value,syntax:e};case"Comma":return{type:e.type,syntax:e};default:throw new Error("Unknown node type:",e.type)}}function xt(e,t){return typeof e=="string"&&(e=Qe(e)),{type:"MatchGraph",match:Xe(e),syntax:t||null,source:e}}var{hasOwnProperty:ws}=Object.prototype,Lc=0,Ec=1,Wr=2,As=3,vs="Match",zc="Mismatch",Pc="Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)",Ss=15e3,Ic=0;function Dc(e){let t=null,r=null,n=e;for(;n!==null;)r=n.prev,n.prev=t,t=n,n=r;return t}function _r(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++){let n=t.charCodeAt(r),i=e.charCodeAt(r);if(i>=65&&i<=90&&(i=i|32),i!==n)return!1}return!0}function Nc(e){return e.type!==9?!1:e.value!=="?"}function Cs(e){return e===null?!0:e.type===18||e.type===2||e.type===21||e.type===19||e.type===23||Nc(e)}function Ts(e){return e===null?!0:e.type===22||e.type===20||e.type===24||e.type===9&&e.value==="/"}function Oc(e,t,r){function n(){do M++,C=M<e.length?e[M]:null;while(C!==null&&(C.type===13||C.type===25))}function i(se){let ge=M+se;return ge<e.length?e[ge]:null}function o(se,ge){return{nextState:se,matchStack:O,syntaxStack:h,thenStack:m,tokenIndex:M,prev:ge}}function a(se){m={nextState:se,matchStack:O,syntaxStack:h,prev:m}}function u(se){f=o(se,f)}function l(){O={type:Ec,syntax:t.syntax,token:C,prev:O},n(),w=null,M>ve&&(ve=M)}function s(){h={syntax:t.syntax,opts:t.syntax.opts||h!==null&&h.opts||null,prev:h},O={type:Wr,syntax:t.syntax,token:O.token,prev:O}}function c(){O.type===Wr?O=O.prev:O={type:As,syntax:h.syntax,token:O.token,prev:O},h=h.prev}let h=null,m=null,f=null,w=null,ee=0,G=null,C=null,M=-1,ve=0,O={type:Lc,syntax:null,token:null,prev:null};for(n();G===null&&++ee<Ss;)switch(t.type){case"Match":if(m===null){if(C!==null&&(M!==e.length-1||C.value!=="\\0"&&C.value!=="\\9")){t=z;break}G=vs;break}if(t=m.nextState,t===$t)if(m.matchStack===O){t=z;break}else t=A;for(;m.syntaxStack!==h;)c();m=m.prev;break;case"Mismatch":if(w!==null&&w!==!1)(f===null||M>f.tokenIndex)&&(f=w,w=!1);else if(f===null){G=zc;break}t=f.nextState,m=f.thenStack,h=f.syntaxStack,O=f.matchStack,M=f.tokenIndex,C=M<e.length?e[M]:null,f=f.prev;break;case"MatchGraph":t=t.match;break;case"If":t.else!==z&&u(t.else),t.then!==A&&a(t.then),t=t.match;break;case"MatchOnce":t={type:"MatchOnceBuffer",syntax:t,index:0,mask:0};break;case"MatchOnceBuffer":{let Q=t.syntax.terms;if(t.index===Q.length){if(t.mask===0||t.syntax.all){t=z;break}t=A;break}if(t.mask===(1<<Q.length)-1){t=A;break}for(;t.index<Q.length;t.index++){let X=1<<t.index;if(!(t.mask&X)){u(t),a({type:"AddMatchOnce",syntax:t.syntax,mask:t.mask|X}),t=Q[t.index++];break}}break}case"AddMatchOnce":t={type:"MatchOnceBuffer",syntax:t.syntax,index:0,mask:t.mask};break;case"Enum":if(C!==null){let Q=C.value.toLowerCase();if(Q.indexOf("\\")!==-1&&(Q=Q.replace(/\\[09].*$/,"")),ws.call(t.map,Q)){t=t.map[Q];break}}t=z;break;case"Generic":{let Q=h!==null?h.opts:null,X=M+Math.floor(t.fn(C,i,Q));if(!isNaN(X)&&X>M){for(;M<X;)l();t=A}else t=z;break}case"Type":case"Property":{let Q=t.type==="Type"?"types":"properties",X=ws.call(r,Q)?r[Q][t.name]:null;if(!X||!X.match)throw new Error("Bad syntax reference: "+(t.type==="Type"?"<"+t.name+">":"<'"+t.name+"'>"));if(w!==!1&&C!==null&&t.type==="Type"&&(t.name==="custom-ident"&&C.type===1||t.name==="length"&&C.value==="0")){w===null&&(w=o(t,f)),t=z;break}s(),t=X.matchRef||X.match;break}case"Keyword":{let Q=t.name;if(C!==null){let X=C.value;if(X.indexOf("\\")!==-1&&(X=X.replace(/\\[09].*$/,"")),_r(X,Q)){l(),t=A;break}}t=z;break}case"AtKeyword":case"Function":if(C!==null&&_r(C.value,t.name)){l(),t=A;break}t=z;break;case"Token":if(C!==null&&C.value===t.value){l(),t=A;break}t=z;break;case"Comma":C!==null&&C.type===18?Cs(O.token)?t=z:(l(),t=Ts(C)?z:A):t=Cs(O.token)||Ts(C)?A:z;break;case"String":let se="",ge=M;for(;ge<e.length&&se.length<t.value.length;ge++)se+=e[ge].value;if(_r(se,t.value)){for(;M<ge;)l();t=A}else t=z;break;default:throw new Error("Unknown node type: "+t.type)}switch(Ic+=ee,G){case null:console.warn("[csstree-match] BREAK after "+Ss+" iterations"),G=Pc,O=null;break;case vs:for(;h!==null;)c();break;default:O=null}return{tokens:e,reason:G,iterations:ee,match:O,longestMatch:ve}}function jr(e,t,r){let n=Oc(e,t,r||{});if(n.match===null)return n;let i=n.match,o=n.match={syntax:t.syntax||null,match:[]},a=[o];for(i=Dc(i).prev;i!==null;){switch(i.type){case Wr:o.match.push(o={syntax:i.syntax,match:[]}),a.push(o);break;case As:a.pop(),o=a[a.length-1];break;default:o.match.push({syntax:i.syntax||null,token:i.token.value,node:i.token.node})}i=i.prev}return n}var Ur={};x(Ur,{getTrace:()=>Ls,isKeyword:()=>Mc,isProperty:()=>Rc,isType:()=>Fc});function Ls(e){function t(i){return i===null?!1:i.type==="Type"||i.type==="Property"||i.type==="Keyword"}function r(i){if(Array.isArray(i.match)){for(let o=0;o<i.match.length;o++)if(r(i.match[o]))return t(i.syntax)&&n.unshift(i.syntax),!0}else if(i.node===e)return n=t(i.syntax)?[i.syntax]:[],!0;return!1}let n=null;return this.matched!==null&&r(this.matched),n}function Fc(e,t){return qr(this,e,r=>r.type==="Type"&&r.name===t)}function Rc(e,t){return qr(this,e,r=>r.type==="Property"&&r.name===t)}function Mc(e){return qr(this,e,t=>t.type==="Keyword")}function qr(e,t,r){let n=Ls.call(e,t);return n===null?!1:n.some(r)}function Es(e){return"node"in e?e.node:Es(e.match[0])}function zs(e){return"node"in e?e.node:zs(e.match[e.match.length-1])}function Hr(e,t,r,n,i){function o(u){if(u.syntax!==null&&u.syntax.type===n&&u.syntax.name===i){let l=Es(u),s=zs(u);e.syntax.walk(t,function(c,h,m){if(c===l){let f=new Z;do{if(f.appendData(h.data),h.data===s)break;h=h.next}while(h!==null);a.push({parent:m,nodes:f})}})}Array.isArray(u.match)&&u.match.forEach(o)}let a=[];return r.matched!==null&&o(r.matched),a}var{hasOwnProperty:yt}=Object.prototype;function Gr(e){return typeof e=="number"&&isFinite(e)&&Math.floor(e)===e&&e>=0}function Ps(e){return!!e&&Gr(e.offset)&&Gr(e.line)&&Gr(e.column)}function Bc(e,t){return function(n,i){if(!n||n.constructor!==Object)return i(n,"Type of node should be an Object");for(let o in n){let a=!0;if(yt.call(n,o)!==!1){if(o==="type")n.type!==e&&i(n,"Wrong node type `"+n.type+"`, expected `"+e+"`");else if(o==="loc"){if(n.loc===null)continue;if(n.loc&&n.loc.constructor===Object)if(typeof n.loc.source!="string")o+=".source";else if(!Ps(n.loc.start))o+=".start";else if(!Ps(n.loc.end))o+=".end";else continue;a=!1}else if(t.hasOwnProperty(o)){a=!1;for(let u=0;!a&&u<t[o].length;u++){let l=t[o][u];switch(l){case String:a=typeof n[o]=="string";break;case Boolean:a=typeof n[o]=="boolean";break;case null:a=n[o]===null;break;default:typeof l=="string"?a=n[o]&&n[o].type===l:Array.isArray(l)&&(a=n[o]instanceof Z)}}}else i(n,"Unknown field `"+o+"` for "+e+" node type");a||i(n,"Bad value for `"+e+"."+o+"`")}}for(let o in t)yt.call(t,o)&&yt.call(n,o)===!1&&i(n,"Field `"+e+"."+o+"` is missed")}}function Is(e,t){let r=[];for(let n=0;n<e.length;n++){let i=e[n];if(i===String||i===Boolean)r.push(i.name.toLowerCase());else if(i===null)r.push("null");else if(typeof i=="string")r.push(i);else if(Array.isArray(i))r.push("List<"+(Is(i,t)||"any")+">");else throw new Error("Wrong value `"+i+"` in `"+t+"` structure definition")}return r.join(" | ")}function _c(e,t){let r=t.structure,n={type:String,loc:!0},i={type:'"'+e+'"'};for(let o in r){if(yt.call(r,o)===!1)continue;let a=n[o]=Array.isArray(r[o])?r[o].slice():[r[o]];i[o]=Is(a,e+"."+o)}return{docs:i,check:Bc(e,n)}}function Ds(e){let t={};if(e.node){for(let r in e.node)if(yt.call(e.node,r)){let n=e.node[r];if(n.structure)t[r]=_c(r,n);else throw new Error("Missed `structure` field in `"+r+"` node type definition")}}return t}function Yr(e,t,r){let n={};for(let i in e)e[i].syntax&&(n[i]=r?e[i].syntax:Ne(e[i].syntax,{compact:t}));return n}function Wc(e,t,r){let n={};for(let[i,o]of Object.entries(e))n[i]={prelude:o.prelude&&(r?o.prelude.syntax:Ne(o.prelude.syntax,{compact:t})),descriptors:o.descriptors&&Yr(o.descriptors,t,r)};return n}function jc(e){for(let t=0;t<e.length;t++)if(e[t].value.toLowerCase()==="var(")return!0;return!1}function qc(e){let t=e.terms[0];return e.explicit===!1&&e.terms.length===1&&t.type==="Multiplier"&&t.comma===!0}function ce(e,t,r){return{matched:e,iterations:r,error:t,...Ur}}function $e(e,t,r,n){let i=xs(r,e.syntax),o;return jc(i)?ce(null,new Error("Matching for a tree with var() is not supported")):(n&&(o=jr(i,e.cssWideKeywordsSyntax,e)),(!n||!o.match)&&(o=jr(i,t.match,e),!o.match)?ce(null,new Xo(o.reason,t.syntax,r,o),o.iterations):ce(o.match,null,o.iterations))}var Ze=class{constructor(t,r,n){if(this.cssWideKeywords=Ke,this.syntax=r,this.generic=!1,this.units={...Gt},this.atrules=Object.create(null),this.properties=Object.create(null),this.types=Object.create(null),this.structure=n||Ds(t),t){if(t.cssWideKeywords&&(this.cssWideKeywords=t.cssWideKeywords),t.units)for(let i of Object.keys(Gt))Array.isArray(t.units[i])&&(this.units[i]=t.units[i]);if(t.types)for(let[i,o]of Object.entries(t.types))this.addType_(i,o);if(t.generic){this.generic=!0;for(let[i,o]of Object.entries(is(this.units)))this.addType_(i,o)}if(t.atrules)for(let[i,o]of Object.entries(t.atrules))this.addAtrule_(i,o);if(t.properties)for(let[i,o]of Object.entries(t.properties))this.addProperty_(i,o)}this.cssWideKeywordsSyntax=xt(this.cssWideKeywords.join(" | "))}checkStructure(t){function r(o,a){i.push({node:o,message:a})}let n=this.structure,i=[];return this.syntax.walk(t,function(o){n.hasOwnProperty(o.type)?n[o.type].check(o,r):r(o,"Unknown node type `"+o.type+"`")}),i.length?i:!1}createDescriptor(t,r,n,i=null){let o={type:r,name:n},a={type:r,name:n,parent:i,serializable:typeof t=="string"||t&&typeof t.type=="string",syntax:null,match:null,matchRef:null};return typeof t=="function"?a.match=xt(t,o):(typeof t=="string"?Object.defineProperty(a,"syntax",{get(){return Object.defineProperty(a,"syntax",{value:Qe(t)}),a.syntax}}):a.syntax=t,Object.defineProperty(a,"match",{get(){return Object.defineProperty(a,"match",{value:xt(a.syntax,o)}),a.match}}),r==="Property"&&Object.defineProperty(a,"matchRef",{get(){let u=a.syntax,l=qc(u)?xt({...u,terms:[u.terms[0].term]},o):null;return Object.defineProperty(a,"matchRef",{value:l}),l}})),a}addAtrule_(t,r){r&&(this.atrules[t]={type:"Atrule",name:t,prelude:r.prelude?this.createDescriptor(r.prelude,"AtrulePrelude",t):null,descriptors:r.descriptors?Object.keys(r.descriptors).reduce((n,i)=>(n[i]=this.createDescriptor(r.descriptors[i],"AtruleDescriptor",i,t),n),Object.create(null)):null})}addProperty_(t,r){r&&(this.properties[t]=this.createDescriptor(r,"Property",t))}addType_(t,r){r&&(this.types[t]=this.createDescriptor(r,"Type",t))}checkAtruleName(t){if(!this.getAtrule(t))return new Ge("Unknown at-rule","@"+t)}checkAtrulePrelude(t,r){let n=this.checkAtruleName(t);if(n)return n;let i=this.getAtrule(t);if(!i.prelude&&r)return new SyntaxError("At-rule `@"+t+"` should not contain a prelude");if(i.prelude&&!r&&!$e(this,i.prelude,"",!1).matched)return new SyntaxError("At-rule `@"+t+"` should contain a prelude")}checkAtruleDescriptorName(t,r){let n=this.checkAtruleName(t);if(n)return n;let i=this.getAtrule(t),o=jt(r);if(!i.descriptors)return new SyntaxError("At-rule `@"+t+"` has no known descriptors");if(!i.descriptors[o.name]&&!i.descriptors[o.basename])return new Ge("Unknown at-rule descriptor",r)}checkPropertyName(t){if(!this.getProperty(t))return new Ge("Unknown property",t)}matchAtrulePrelude(t,r){let n=this.checkAtrulePrelude(t,r);if(n)return ce(null,n);let i=this.getAtrule(t);return i.prelude?$e(this,i.prelude,r||"",!1):ce(null,null)}matchAtruleDescriptor(t,r,n){let i=this.checkAtruleDescriptorName(t,r);if(i)return ce(null,i);let o=this.getAtrule(t),a=jt(r);return $e(this,o.descriptors[a.name]||o.descriptors[a.basename],n,!1)}matchDeclaration(t){return t.type!=="Declaration"?ce(null,new Error("Not a Declaration node")):this.matchProperty(t.property,t.value)}matchProperty(t,r){if(wr(t).custom)return ce(null,new Error("Lexer matching doesn't applicable for custom properties"));let n=this.checkPropertyName(t);return n?ce(null,n):$e(this,this.getProperty(t),r,!0)}matchType(t,r){let n=this.getType(t);return n?$e(this,n,r,!1):ce(null,new Ge("Unknown type",t))}match(t,r){return typeof t!="string"&&(!t||!t.type)?ce(null,new Ge("Bad syntax")):((typeof t=="string"||!t.match)&&(t=this.createDescriptor(t,"Type","anonymous")),$e(this,t,r,!1))}findValueFragments(t,r,n,i){return Hr(this,r,this.matchProperty(t,r),n,i)}findDeclarationValueFragments(t,r,n){return Hr(this,t.value,this.matchDeclaration(t),r,n)}findAllFragments(t,r,n){let i=[];return this.syntax.walk(t,{visit:"Declaration",enter:o=>{i.push.apply(i,this.findDeclarationValueFragments(o,r,n))}}),i}getAtrule(t,r=!0){let n=jt(t);return(n.vendor&&r?this.atrules[n.name]||this.atrules[n.basename]:this.atrules[n.name])||null}getAtrulePrelude(t,r=!0){let n=this.getAtrule(t,r);return n&&n.prelude||null}getAtruleDescriptor(t,r){return this.atrules.hasOwnProperty(t)&&this.atrules.declarators&&this.atrules[t].declarators[r]||null}getProperty(t,r=!0){let n=wr(t);return(n.vendor&&r?this.properties[n.name]||this.properties[n.basename]:this.properties[n.name])||null}getType(t){return hasOwnProperty.call(this.types,t)?this.types[t]:null}validate(){function t(l,s){return s?`<${l}>`:`<'${l}'>`}function r(l,s,c,h){if(c.has(s))return c.get(s);c.set(s,!1),h.syntax!==null&&Xt(h.syntax,function(m){if(m.type!=="Type"&&m.type!=="Property")return;let f=m.type==="Type"?l.types:l.properties,w=m.type==="Type"?i:o;hasOwnProperty.call(f,m.name)?r(l,m.name,w,f[m.name])&&(n.push(`${t(s,c===i)} used broken syntax definition ${t(m.name,m.type==="Type")}`),c.set(s,!0)):(n.push(`${t(s,c===i)} used missed syntax definition ${t(m.name,m.type==="Type")}`),c.set(s,!0))},this)}let n=[],i=new Map,o=new Map;for(let l in this.types)r(this,l,i,this.types[l]);for(let l in this.properties)r(this,l,o,this.properties[l]);let a=[...i.keys()].filter(l=>i.get(l)),u=[...o.keys()].filter(l=>o.get(l));return a.length||u.length?{errors:n,types:a,properties:u}:null}dump(t,r){return{generic:this.generic,cssWideKeywords:this.cssWideKeywords,units:this.units,types:Yr(this.types,!r,t),properties:Yr(this.properties,!r,t),atrules:Wc(this.atrules,!r,t)}}toString(){return JSON.stringify(this.dump())}};function Kr(e,t){return typeof t=="string"&&/^\s*\|/.test(t)?typeof e=="string"?e+t:t.replace(/^\s*\|\s*/,""):t||null}function Ns(e,t){let r=Object.create(null);for(let[n,i]of Object.entries(e))if(i){r[n]={};for(let o of Object.keys(i))t.includes(o)&&(r[n][o]=i[o])}return r}function kt(e,t){let r={...e};for(let[n,i]of Object.entries(t))switch(n){case"generic":r[n]=!!i;break;case"cssWideKeywords":r[n]=e[n]?[...e[n],...i]:i||[];break;case"units":r[n]={...e[n]};for(let[o,a]of Object.entries(i))r[n][o]=Array.isArray(a)?a:[];break;case"atrules":r[n]={...e[n]};for(let[o,a]of Object.entries(i)){let u=r[n][o]||{},l=r[n][o]={prelude:u.prelude||null,descriptors:{...u.descriptors}};if(a){l.prelude=a.prelude?Kr(l.prelude,a.prelude):l.prelude||null;for(let[s,c]of Object.entries(a.descriptors||{}))l.descriptors[s]=c?Kr(l.descriptors[s],c):null;Object.keys(l.descriptors).length||(l.descriptors=null)}}break;case"types":case"properties":r[n]={...e[n]};for(let[o,a]of Object.entries(i))r[n][o]=Kr(r[n][o],a);break;case"scope":case"features":r[n]={...e[n]};for(let[o,a]of Object.entries(i))r[n][o]={...r[n][o],...a};break;case"parseContext":r[n]={...e[n],...i};break;case"atrule":case"pseudo":r[n]={...e[n],...Ns(i,["parse"])};break;case"node":r[n]={...e[n],...Ns(i,["name","structure","parse","generate","walkContext"])};break}return r}function Os(e){let t=bo(e),r=Vo(e),n=qo(e),{fromPlainObject:i,toPlainObject:o}=Uo(r),a={lexer:null,createLexer:u=>new Ze(u,a,a.lexer.structure),tokenize:Se,parse:t,generate:n,walk:r,find:r.find,findLast:r.findLast,findAll:r.findAll,fromPlainObject:i,toPlainObject:o,fork(u){let l=kt({},e);return Os(typeof u=="function"?u(l):kt(l,u))}};return a.lexer=new Ze({generic:e.generic,cssWideKeywords:e.cssWideKeywords,units:e.units,types:e.types,atrules:e.atrules,properties:e.properties,node:e.node},a),a}var Vr=e=>Os(kt({},e));var Fs={generic:!0,cssWideKeywords:["initial","inherit","unset","revert","revert-layer"],units:{angle:["deg","grad","rad","turn"],decibel:["db"],flex:["fr"],frequency:["hz","khz"],length:["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],resolution:["dpi","dpcm","dppx","x"],semitones:["st"],time:["s","ms"]},types:{"abs()":"abs( <calc-sum> )","absolute-size":"xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large","acos()":"acos( <calc-sum> )","alpha-value":"<number>|<percentage>","angle-percentage":"<angle>|<percentage>","angular-color-hint":"<angle-percentage>","angular-color-stop":"<color>&&<color-stop-angle>?","angular-color-stop-list":"[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>","animateable-feature":"scroll-position|contents|<custom-ident>","asin()":"asin( <calc-sum> )","atan()":"atan( <calc-sum> )","atan2()":"atan2( <calc-sum> , <calc-sum> )",attachment:"scroll|fixed|local","attr()":"attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )","attr-matcher":"['~'|'|'|'^'|'$'|'*']? '='","attr-modifier":"i|s","attribute-selector":"'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'","auto-repeat":"repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )","auto-track-list":"[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?",axis:"block|inline|x|y","baseline-position":"[first|last]? baseline","basic-shape":"<inset()>|<xywh()>|<rect()>|<circle()>|<ellipse()>|<polygon()>|<path()>","bg-image":"none|<image>","bg-layer":"<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>","bg-position":"[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]","bg-size":"[<length-percentage>|auto]{1,2}|cover|contain","blur()":"blur( <length> )","blend-mode":"normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",box:"border-box|padding-box|content-box","brightness()":"brightness( <number-percentage> )","calc()":"calc( <calc-sum> )","calc-sum":"<calc-product> [['+'|'-'] <calc-product>]*","calc-product":"<calc-value> ['*' <calc-value>|'/' <number>]*","calc-value":"<number>|<dimension>|<percentage>|<calc-constant>|( <calc-sum> )","calc-constant":"e|pi|infinity|-infinity|NaN","cf-final-image":"<image>|<color>","cf-mixing-image":"<percentage>?&&<image>","circle()":"circle( [<shape-radius>]? [at <position>]? )","clamp()":"clamp( <calc-sum>#{3} )","class-selector":"'.' <ident-token>","clip-source":"<url>",color:"<color-base>|currentColor|<system-color>|<device-cmyk()>|<light-dark()>|<-non-standard-color>","color-stop":"<color-stop-length>|<color-stop-angle>","color-stop-angle":"<angle-percentage>{1,2}","color-stop-length":"<length-percentage>{1,2}","color-stop-list":"[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>","color-interpolation-method":"in [<rectangular-color-space>|<polar-color-space> <hue-interpolation-method>?|<custom-color-space>]",combinator:"'>'|'+'|'~'|['|' '|']","common-lig-values":"[common-ligatures|no-common-ligatures]","compat-auto":"searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button","composite-style":"clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor","compositing-operator":"add|subtract|intersect|exclude","compound-selector":"[<type-selector>? <subclass-selector>*]!","compound-selector-list":"<compound-selector>#","complex-selector":"<complex-selector-unit> [<combinator>? <complex-selector-unit>]*","complex-selector-list":"<complex-selector>#","conic-gradient()":"conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )","contextual-alt-values":"[contextual|no-contextual]","content-distribution":"space-between|space-around|space-evenly|stretch","content-list":"[<string>|contents|<image>|<counter>|<quote>|<target>|<leader()>|<attr()>]+","content-position":"center|start|end|flex-start|flex-end","content-replacement":"<image>","contrast()":"contrast( [<number-percentage>] )","cos()":"cos( <calc-sum> )",counter:"<counter()>|<counters()>","counter()":"counter( <counter-name> , <counter-style>? )","counter-name":"<custom-ident>","counter-style":"<counter-style-name>|symbols( )","counter-style-name":"<custom-ident>","counters()":"counters( <counter-name> , <string> , <counter-style>? )","cross-fade()":"cross-fade( <cf-mixing-image> , <cf-final-image>? )","cubic-bezier-timing-function":"ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )","deprecated-system-color":"ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText","discretionary-lig-values":"[discretionary-ligatures|no-discretionary-ligatures]","display-box":"contents|none","display-inside":"flow|flow-root|table|flex|grid|ruby","display-internal":"table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container","display-legacy":"inline-block|inline-list-item|inline-table|inline-flex|inline-grid","display-listitem":"<display-outside>?&&[flow|flow-root]?&&list-item","display-outside":"block|inline|run-in","drop-shadow()":"drop-shadow( <length>{2,3} <color>? )","east-asian-variant-values":"[jis78|jis83|jis90|jis04|simplified|traditional]","east-asian-width-values":"[full-width|proportional-width]","element()":"element( <custom-ident> , [first|start|last|first-except]? )|element( <id-selector> )","ellipse()":"ellipse( [<shape-radius>{2}]? [at <position>]? )","ending-shape":"circle|ellipse","env()":"env( <custom-ident> , <declaration-value>? )","exp()":"exp( <calc-sum> )","explicit-track-list":"[<line-names>? <track-size>]+ <line-names>?","family-name":"<string>|<custom-ident>+","feature-tag-value":"<string> [<integer>|on|off]?","feature-type":"@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation","feature-value-block":"<feature-type> '{' <feature-value-declaration-list> '}'","feature-value-block-list":"<feature-value-block>+","feature-value-declaration":"<custom-ident> : <integer>+ ;","feature-value-declaration-list":"<feature-value-declaration>","feature-value-name":"<custom-ident>","fill-rule":"nonzero|evenodd","filter-function":"<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>","filter-function-list":"[<filter-function>|<url>]+","final-bg-layer":"<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>","fixed-breadth":"<length-percentage>","fixed-repeat":"repeat( [<integer [1,\u221E]>] , [<line-names>? <fixed-size>]+ <line-names>? )","fixed-size":"<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )","font-stretch-absolute":"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>","font-variant-css21":"[normal|small-caps]","font-weight-absolute":"normal|bold|<number [1,1000]>","frequency-percentage":"<frequency>|<percentage>","general-enclosed":"[<function-token> <any-value>? )]|[( <any-value>? )]","generic-family":"<generic-script-specific>|<generic-complete>|<generic-incomplete>|<-non-standard-generic-family>","generic-name":"serif|sans-serif|cursive|fantasy|monospace","geometry-box":"<shape-box>|fill-box|stroke-box|view-box",gradient:"<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<repeating-conic-gradient()>|<-legacy-gradient>","grayscale()":"grayscale( <number-percentage> )","grid-line":"auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]","historical-lig-values":"[historical-ligatures|no-historical-ligatures]","hsl()":"hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )","hsla()":"hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )",hue:"<number>|<angle>","hue-rotate()":"hue-rotate( <angle> )","hue-interpolation-method":"[shorter|longer|increasing|decreasing] hue","hwb()":"hwb( [<hue>|none] [<percentage>|none] [<percentage>|none] [/ [<alpha-value>|none]]? )","hypot()":"hypot( <calc-sum># )",image:"<url>|<image()>|<image-set()>|<element()>|<paint()>|<cross-fade()>|<gradient>","image()":"image( <image-tags>? [<image-src>? , <color>?]! )","image-set()":"image-set( <image-set-option># )","image-set-option":"[<image>|<string>] [<resolution>||type( <string> )]","image-src":"<url>|<string>","image-tags":"ltr|rtl","inflexible-breadth":"<length-percentage>|min-content|max-content|auto","inset()":"inset( <length-percentage>{1,4} [round <'border-radius'>]? )","invert()":"invert( <number-percentage> )","keyframes-name":"<custom-ident>|<string>","keyframe-block":"<keyframe-selector># { <declaration-list> }","keyframe-block-list":"<keyframe-block>+","keyframe-selector":"from|to|<percentage>|<timeline-range-name> <percentage>","lab()":"lab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )","layer()":"layer( <layer-name> )","layer-name":"<ident> ['.' <ident>]*","lch()":"lch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )","leader()":"leader( <leader-type> )","leader-type":"dotted|solid|space|<string>","length-percentage":"<length>|<percentage>","light-dark()":"light-dark( <color> , <color> )","line-names":"'[' <custom-ident>* ']'","line-name-list":"[<line-names>|<name-repeat>]+","line-style":"none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset","line-width":"<length>|thin|medium|thick","linear-color-hint":"<length-percentage>","linear-color-stop":"<color> <color-stop-length>?","linear-gradient()":"linear-gradient( [[<angle>|to <side-or-corner>]||<color-interpolation-method>]? , <color-stop-list> )","log()":"log( <calc-sum> , <calc-sum>? )","mask-layer":"<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>","mask-position":"[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?","mask-reference":"none|<image>|<mask-source>","mask-source":"<url>","masking-mode":"alpha|luminance|match-source","matrix()":"matrix( <number>#{6} )","matrix3d()":"matrix3d( <number>#{16} )","max()":"max( <calc-sum># )","media-and":"<media-in-parens> [and <media-in-parens>]+","media-condition":"<media-not>|<media-and>|<media-or>|<media-in-parens>","media-condition-without-or":"<media-not>|<media-and>|<media-in-parens>","media-feature":"( [<mf-plain>|<mf-boolean>|<mf-range>] )","media-in-parens":"( <media-condition> )|<media-feature>|<general-enclosed>","media-not":"not <media-in-parens>","media-or":"<media-in-parens> [or <media-in-parens>]+","media-query":"<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?","media-query-list":"<media-query>#","media-type":"<ident>","mf-boolean":"<mf-name>","mf-name":"<ident>","mf-plain":"<mf-name> : <mf-value>","mf-range":"<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>","mf-value":"<number>|<dimension>|<ident>|<ratio>","min()":"min( <calc-sum># )","minmax()":"minmax( [<length-percentage>|min-content|max-content|auto] , [<length-percentage>|<flex>|min-content|max-content|auto] )","mod()":"mod( <calc-sum> , <calc-sum> )","name-repeat":"repeat( [<integer [1,\u221E]>|auto-fill] , <line-names>+ )","named-color":"transparent|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","namespace-prefix":"<ident>","ns-prefix":"[<ident-token>|'*']? '|'","number-percentage":"<number>|<percentage>","numeric-figure-values":"[lining-nums|oldstyle-nums]","numeric-fraction-values":"[diagonal-fractions|stacked-fractions]","numeric-spacing-values":"[proportional-nums|tabular-nums]",nth:"<an-plus-b>|even|odd","opacity()":"opacity( [<number-percentage>] )","overflow-position":"unsafe|safe","outline-radius":"<length>|<percentage>","page-body":"<declaration>? [; <page-body>]?|<page-margin-box> <page-body>","page-margin-box":"<page-margin-box-type> '{' <declaration-list> '}'","page-margin-box-type":"@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom","page-selector-list":"[<page-selector>#]?","page-selector":"<pseudo-page>+|<ident> <pseudo-page>*","page-size":"A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger","path()":"path( [<fill-rule> ,]? <string> )","paint()":"paint( <ident> , <declaration-value>? )","perspective()":"perspective( [<length [0,\u221E]>|none] )","polygon()":"polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )","polar-color-space":"hsl|hwb|lch|oklch",position:"[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]","pow()":"pow( <calc-sum> , <calc-sum> )","pseudo-class-selector":"':' <ident-token>|':' <function-token> <any-value> ')'","pseudo-element-selector":"':' <pseudo-class-selector>|<legacy-pseudo-element-selector>","pseudo-page":": [left|right|first|blank]",quote:"open-quote|close-quote|no-open-quote|no-close-quote","radial-gradient()":"radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",ratio:"<number [0,\u221E]> [/ <number [0,\u221E]>]?","ray()":"ray( <angle>&&<ray-size>?&&contain?&&[at <position>]? )","ray-size":"closest-side|closest-corner|farthest-side|farthest-corner|sides","rectangular-color-space":"srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020|lab|oklab|xyz|xyz-d50|xyz-d65","relative-selector":"<combinator>? <complex-selector>","relative-selector-list":"<relative-selector>#","relative-size":"larger|smaller","rem()":"rem( <calc-sum> , <calc-sum> )","repeat-style":"repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}","repeating-conic-gradient()":"repeating-conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )","repeating-linear-gradient()":"repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )","repeating-radial-gradient()":"repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )","reversed-counter-name":"reversed( <counter-name> )","rgb()":"rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )","rgba()":"rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )","rotate()":"rotate( [<angle>|<zero>] )","rotate3d()":"rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )","rotateX()":"rotateX( [<angle>|<zero>] )","rotateY()":"rotateY( [<angle>|<zero>] )","rotateZ()":"rotateZ( [<angle>|<zero>] )","round()":"round( <rounding-strategy>? , <calc-sum> , <calc-sum> )","rounding-strategy":"nearest|up|down|to-zero","saturate()":"saturate( <number-percentage> )","scale()":"scale( [<number>|<percentage>]#{1,2} )","scale3d()":"scale3d( [<number>|<percentage>]#{3} )","scaleX()":"scaleX( [<number>|<percentage>] )","scaleY()":"scaleY( [<number>|<percentage>] )","scaleZ()":"scaleZ( [<number>|<percentage>] )","scroll()":"scroll( [<axis>||<scroller>]? )",scroller:"root|nearest|self","self-position":"center|start|end|self-start|self-end|flex-start|flex-end","shape-radius":"<length-percentage>|closest-side|farthest-side","sign()":"sign( <calc-sum> )","skew()":"skew( [<angle>|<zero>] , [<angle>|<zero>]? )","skewX()":"skewX( [<angle>|<zero>] )","skewY()":"skewY( [<angle>|<zero>] )","sepia()":"sepia( <number-percentage> )",shadow:"inset?&&<length>{2,4}&&<color>?","shadow-t":"[<length>{2,3}&&<color>?]",shape:"rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )","shape-box":"<box>|margin-box","side-or-corner":"[left|right]||[top|bottom]","sin()":"sin( <calc-sum> )","single-animation":"<'animation-duration'>||<easing-function>||<'animation-delay'>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]||<single-animation-timeline>","single-animation-direction":"normal|reverse|alternate|alternate-reverse","single-animation-fill-mode":"none|forwards|backwards|both","single-animation-iteration-count":"infinite|<number>","single-animation-play-state":"running|paused","single-animation-timeline":"auto|none|<dashed-ident>|<scroll()>|<view()>","single-transition":"[none|<single-transition-property>]||<time>||<easing-function>||<time>||<transition-behavior-value>","single-transition-property":"all|<custom-ident>",size:"closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}","sqrt()":"sqrt( <calc-sum> )","step-position":"jump-start|jump-end|jump-none|jump-both|start|end","step-timing-function":"step-start|step-end|steps( <integer> [, <step-position>]? )","subclass-selector":"<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>","supports-condition":"not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*","supports-in-parens":"( <supports-condition> )|<supports-feature>|<general-enclosed>","supports-feature":"<supports-decl>|<supports-selector-fn>","supports-decl":"( <declaration> )","supports-selector-fn":"selector( <complex-selector> )",symbol:"<string>|<image>|<custom-ident>","system-color":"AccentColor|AccentColorText|ActiveText|ButtonBorder|ButtonFace|ButtonText|Canvas|CanvasText|Field|FieldText|GrayText|Highlight|HighlightText|LinkText|Mark|MarkText|SelectedItem|SelectedItemText|VisitedText","tan()":"tan( <calc-sum> )",target:"<target-counter()>|<target-counters()>|<target-text()>","target-counter()":"target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )","target-counters()":"target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )","target-text()":"target-text( [<string>|<url>] , [content|before|after|first-letter]? )","time-percentage":"<time>|<percentage>","timeline-range-name":"cover|contain|entry|exit|entry-crossing|exit-crossing","easing-function":"linear|<cubic-bezier-timing-function>|<step-timing-function>","track-breadth":"<length-percentage>|<flex>|min-content|max-content|auto","track-list":"[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?","track-repeat":"repeat( [<integer [1,\u221E]>] , [<line-names>? <track-size>]+ <line-names>? )","track-size":"<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( <length-percentage> )","transform-function":"<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>","transform-list":"<transform-function>+","transition-behavior-value":"normal|allow-discrete","translate()":"translate( <length-percentage> , <length-percentage>? )","translate3d()":"translate3d( <length-percentage> , <length-percentage> , <length> )","translateX()":"translateX( <length-percentage> )","translateY()":"translateY( <length-percentage> )","translateZ()":"translateZ( <length> )","type-or-unit":"string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%","type-selector":"<wq-name>|<ns-prefix>? '*'","var()":"var( <custom-property-name> , <declaration-value>? )","view()":"view( [<axis>||<'view-timeline-inset'>]? )","viewport-length":"auto|<length-percentage>","visual-box":"content-box|padding-box|border-box","wq-name":"<ns-prefix>? <ident-token>","-legacy-gradient":"<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>","-legacy-linear-gradient":"-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )","-legacy-repeating-linear-gradient":"-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )","-legacy-linear-gradient-arguments":"[<angle>|<side-or-corner>]? , <color-stop-list>","-legacy-radial-gradient":"-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )","-legacy-repeating-radial-gradient":"-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )","-legacy-radial-gradient-arguments":"[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>","-legacy-radial-gradient-size":"closest-side|closest-corner|farthest-side|farthest-corner|contain|cover","-legacy-radial-gradient-shape":"circle|ellipse","-non-standard-font":"-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body","-non-standard-color":"-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text","-non-standard-image-rendering":"optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast","-non-standard-overflow":"overlay|-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable","-non-standard-size":"intrinsic|min-intrinsic|-webkit-fill-available|-webkit-fit-content|-webkit-min-content|-webkit-max-content|-moz-available|-moz-fit-content|-moz-min-content|-moz-max-content","-webkit-gradient()":"-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )","-webkit-gradient-color-stop":"from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )","-webkit-gradient-point":"[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]","-webkit-gradient-radius":"<length>|<percentage>","-webkit-gradient-type":"linear|radial","-webkit-mask-box-repeat":"repeat|stretch|round","-ms-filter-function-list":"<-ms-filter-function>+","-ms-filter-function":"<-ms-filter-function-progid>|<-ms-filter-function-legacy>","-ms-filter-function-progid":"'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]","-ms-filter-function-legacy":"<ident-token>|<function-token> <any-value>? )","absolute-color-base":"<hex-color>|<absolute-color-function>|<named-color>|transparent","absolute-color-function":"<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>",age:"child|young|old","anchor-name":"<dashed-ident>","attr-name":"<wq-name>","attr-fallback":"<any-value>","bg-clip":"<box>|border|text",bottom:"<length>|auto","container-name":"<custom-ident>","container-condition":"not <query-in-parens>|<query-in-parens> [[and <query-in-parens>]*|[or <query-in-parens>]*]","coord-box":"content-box|padding-box|border-box|fill-box|stroke-box|view-box","generic-voice":"[<age>? <gender> <integer>?]",gender:"male|female|neutral","generic-script-specific":"generic( kai )|generic( fangsong )|generic( nastaliq )","generic-complete":"serif|sans-serif|system-ui|cursive|fantasy|math|monospace","generic-incomplete":"ui-serif|ui-sans-serif|ui-monospace|ui-rounded","-non-standard-generic-family":"-apple-system|BlinkMacSystemFont",left:"<length>|auto","color-base":"<hex-color>|<color-function>|<named-color>|<color-mix()>|transparent","color-function":"<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>","device-cmyk()":"<legacy-device-cmyk-syntax>|<modern-device-cmyk-syntax>","legacy-device-cmyk-syntax":"device-cmyk( <number>#{4} )","modern-device-cmyk-syntax":"device-cmyk( <cmyk-component>{4} [/ [<alpha-value>|none]]? )","cmyk-component":"<number>|<percentage>|none","color-mix()":"color-mix( <color-interpolation-method> , [<color>&&<percentage [0,100]>?]#{2} )","color-space":"<rectangular-color-space>|<polar-color-space>|<custom-color-space>","custom-color-space":"<dashed-ident>",paint:"none|<color>|<url> [none|<color>]?|context-fill|context-stroke","palette-identifier":"<dashed-ident>",right:"<length>|auto","scope-start":"<forgiving-selector-list>","scope-end":"<forgiving-selector-list>","forgiving-selector-list":"<complex-real-selector-list>","forgiving-relative-selector-list":"<relative-real-selector-list>","selector-list":"<complex-selector-list>","complex-real-selector-list":"<complex-real-selector>#","simple-selector-list":"<simple-selector>#","relative-real-selector-list":"<relative-real-selector>#","complex-selector-unit":"[<compound-selector>? <pseudo-compound-selector>*]!","complex-real-selector":"<compound-selector> [<combinator>? <compound-selector>]*","relative-real-selector":"<combinator>? <complex-real-selector>","pseudo-compound-selector":"<pseudo-element-selector> <pseudo-class-selector>*","simple-selector":"<type-selector>|<subclass-selector>","legacy-pseudo-element-selector":"':' [before|after|first-line|first-letter]","single-animation-composition":"replace|add|accumulate","svg-length":"<percentage>|<length>|<number>","svg-writing-mode":"lr-tb|rl-tb|tb-rl|lr|rl|tb",top:"<length>|auto",x:"<number>",y:"<number>",declaration:"<ident-token> : <declaration-value>? ['!' important]?","declaration-list":"[<declaration>? ';']* <declaration>?",url:"url( <string> <url-modifier>* )|<url-token>","url-modifier":"<ident>|<function-token> <any-value> )","number-zero-one":"<number [0,1]>","number-one-or-greater":"<number [1,\u221E]>","color()":"color( <colorspace-params> [/ [<alpha-value>|none]]? )","colorspace-params":"[<predefined-rgb-params>|<xyz-params>]","predefined-rgb-params":"<predefined-rgb> [<number>|<percentage>|none]{3}","predefined-rgb":"srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020","xyz-params":"<xyz-space> [<number>|<percentage>|none]{3}","xyz-space":"xyz|xyz-d50|xyz-d65","oklab()":"oklab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )","oklch()":"oklch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )","offset-path":"<ray()>|<url>|<basic-shape>","rect()":"rect( [<length-percentage>|auto]{4} [round <'border-radius'>]? )","xywh()":"xywh( <length-percentage>{2} <length-percentage [0,\u221E]>{2} [round <'border-radius'>]? )","query-in-parens":"( <container-condition> )|( <size-feature> )|style( <style-query> )|<general-enclosed>","size-feature":"<mf-plain>|<mf-boolean>|<mf-range>","style-feature":"<declaration>","style-query":"<style-condition>|<style-feature>","style-condition":"not <style-in-parens>|<style-in-parens> [[and <style-in-parens>]*|[or <style-in-parens>]*]","style-in-parens":"( <style-condition> )|( <style-feature> )|<general-enclosed>","-non-standard-display":"-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box","inset-area":"[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]","position-area":"[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|center|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|center|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]","anchor()":"anchor( <anchor-element>?&&<anchor-side> , <length-percentage>? )","anchor-side":"inside|outside|top|left|right|bottom|start|end|self-start|self-end|<percentage>|center","anchor-size()":"anchor-size( [<anchor-element>||<anchor-size>]? , <length-percentage>? )","anchor-size":"width|height|block|inline|self-block|self-inline","anchor-element":"<dashed-ident>","try-size":"most-width|most-height|most-block-size|most-inline-size","try-tactic":"flip-block||flip-inline||flip-start","font-variant-css2":"normal|small-caps","font-width-css3":"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded","system-family-name":"caption|icon|menu|message-box|small-caption|status-bar"},properties:{"--*":"<declaration-value>","-ms-accelerator":"false|true","-ms-block-progression":"tb|rl|bt|lr","-ms-content-zoom-chaining":"none|chained","-ms-content-zooming":"none|zoom","-ms-content-zoom-limit":"<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>","-ms-content-zoom-limit-max":"<percentage>","-ms-content-zoom-limit-min":"<percentage>","-ms-content-zoom-snap":"<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>","-ms-content-zoom-snap-points":"snapInterval( <percentage> , <percentage> )|snapList( <percentage># )","-ms-content-zoom-snap-type":"none|proximity|mandatory","-ms-filter":"<string>","-ms-flow-from":"[none|<custom-ident>]#","-ms-flow-into":"[none|<custom-ident>]#","-ms-grid-columns":"none|<track-list>|<auto-track-list>","-ms-grid-rows":"none|<track-list>|<auto-track-list>","-ms-high-contrast-adjust":"auto|none","-ms-hyphenate-limit-chars":"auto|<integer>{1,3}","-ms-hyphenate-limit-lines":"no-limit|<integer>","-ms-hyphenate-limit-zone":"<percentage>|<length>","-ms-ime-align":"auto|after","-ms-overflow-style":"auto|none|scrollbar|-ms-autohiding-scrollbar","-ms-scrollbar-3dlight-color":"<color>","-ms-scrollbar-arrow-color":"<color>","-ms-scrollbar-base-color":"<color>","-ms-scrollbar-darkshadow-color":"<color>","-ms-scrollbar-face-color":"<color>","-ms-scrollbar-highlight-color":"<color>","-ms-scrollbar-shadow-color":"<color>","-ms-scrollbar-track-color":"<color>","-ms-scroll-chaining":"chained|none","-ms-scroll-limit":"<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>","-ms-scroll-limit-x-max":"auto|<length>","-ms-scroll-limit-x-min":"<length>","-ms-scroll-limit-y-max":"auto|<length>","-ms-scroll-limit-y-min":"<length>","-ms-scroll-rails":"none|railed","-ms-scroll-snap-points-x":"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )","-ms-scroll-snap-points-y":"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )","-ms-scroll-snap-type":"none|proximity|mandatory","-ms-scroll-snap-x":"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>","-ms-scroll-snap-y":"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>","-ms-scroll-translation":"none|vertical-to-horizontal","-ms-text-autospace":"none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space","-ms-touch-select":"grippers|none","-ms-user-select":"none|element|text","-ms-wrap-flow":"auto|both|start|end|maximum|clear","-ms-wrap-margin":"<length>","-ms-wrap-through":"wrap|none","-moz-appearance":"none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized","-moz-binding":"<url>|none","-moz-border-bottom-colors":"<color>+|none","-moz-border-left-colors":"<color>+|none","-moz-border-right-colors":"<color>+|none","-moz-border-top-colors":"<color>+|none","-moz-context-properties":"none|[fill|fill-opacity|stroke|stroke-opacity]#","-moz-float-edge":"border-box|content-box|margin-box|padding-box","-moz-force-broken-image-icon":"0|1","-moz-image-region":"<shape>|auto","-moz-orient":"inline|block|horizontal|vertical","-moz-outline-radius":"<outline-radius>{1,4} [/ <outline-radius>{1,4}]?","-moz-outline-radius-bottomleft":"<outline-radius>","-moz-outline-radius-bottomright":"<outline-radius>","-moz-outline-radius-topleft":"<outline-radius>","-moz-outline-radius-topright":"<outline-radius>","-moz-stack-sizing":"ignore|stretch-to-fit","-moz-text-blink":"none|blink","-moz-user-focus":"ignore|normal|select-after|select-before|select-menu|select-same|select-all|none","-moz-user-input":"auto|none|enabled|disabled","-moz-user-modify":"read-only|read-write|write-only","-moz-window-dragging":"drag|no-drag","-moz-window-shadow":"default|menu|tooltip|sheet|none","-webkit-appearance":"none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|inner-spin-button|listbox|listitem|media-controls-background|media-controls-fullscreen-background|media-current-time-display|media-enter-fullscreen-button|media-exit-fullscreen-button|media-fullscreen-button|media-mute-button|media-overlay-play-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|media-time-remaining-display|media-toggle-closed-captions-button|media-volume-slider|media-volume-slider-container|media-volume-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|meter|progress-bar|progress-bar-value|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield|-apple-pay-button","-webkit-border-before":"<'border-width'>||<'border-style'>||<color>","-webkit-border-before-color":"<color>","-webkit-border-before-style":"<'border-style'>","-webkit-border-before-width":"<'border-width'>","-webkit-box-reflect":"[above|below|right|left]? <length>? <image>?","-webkit-line-clamp":"none|<integer>","-webkit-mask":"[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#","-webkit-mask-attachment":"<attachment>#","-webkit-mask-clip":"[<box>|border|padding|content|text]#","-webkit-mask-composite":"<composite-style>#","-webkit-mask-image":"<mask-reference>#","-webkit-mask-origin":"[<box>|border|padding|content]#","-webkit-mask-position":"<position>#","-webkit-mask-position-x":"[<length-percentage>|left|center|right]#","-webkit-mask-position-y":"[<length-percentage>|top|center|bottom]#","-webkit-mask-repeat":"<repeat-style>#","-webkit-mask-repeat-x":"repeat|no-repeat|space|round","-webkit-mask-repeat-y":"repeat|no-repeat|space|round","-webkit-mask-size":"<bg-size>#","-webkit-overflow-scrolling":"auto|touch","-webkit-tap-highlight-color":"<color>","-webkit-text-fill-color":"<color>","-webkit-text-stroke":"<length>||<color>","-webkit-text-stroke-color":"<color>","-webkit-text-stroke-width":"<length>","-webkit-touch-callout":"default|none","-webkit-user-modify":"read-only|read-write|read-write-plaintext-only","accent-color":"auto|<color>","align-content":"normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>","align-items":"normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]","align-self":"auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>","align-tracks":"[normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>]#",all:"initial|inherit|unset|revert|revert-layer","anchor-name":"none|<dashed-ident>#","anchor-scope":"none|all|<dashed-ident>#",animation:"<single-animation>#","animation-composition":"<single-animation-composition>#","animation-delay":"<time>#","animation-direction":"<single-animation-direction>#","animation-duration":"<time>#","animation-fill-mode":"<single-animation-fill-mode>#","animation-iteration-count":"<single-animation-iteration-count>#","animation-name":"[none|<keyframes-name>]#","animation-play-state":"<single-animation-play-state>#","animation-range":"[<'animation-range-start'> <'animation-range-end'>?]#","animation-range-end":"[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#","animation-range-start":"[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#","animation-timing-function":"<easing-function>#","animation-timeline":"<single-animation-timeline>#",appearance:"none|auto|textfield|menulist-button|<compat-auto>","aspect-ratio":"auto||<ratio>",azimuth:"<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards","backdrop-filter":"none|<filter-function-list>","backface-visibility":"visible|hidden",background:"[<bg-layer> ,]* <final-bg-layer>","background-attachment":"<attachment>#","background-blend-mode":"<blend-mode>#","background-clip":"<bg-clip>#","background-color":"<color>","background-image":"<bg-image>#","background-origin":"<box>#","background-position":"<bg-position>#","background-position-x":"[center|[[left|right|x-start|x-end]? <length-percentage>?]!]#","background-position-y":"[center|[[top|bottom|y-start|y-end]? <length-percentage>?]!]#","background-repeat":"<repeat-style>#","background-size":"<bg-size>#","block-size":"<'width'>",border:"<line-width>||<line-style>||<color>","border-block":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-color":"<'border-top-color'>{1,2}","border-block-style":"<'border-top-style'>","border-block-width":"<'border-top-width'>","border-block-end":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-end-color":"<'border-top-color'>","border-block-end-style":"<'border-top-style'>","border-block-end-width":"<'border-top-width'>","border-block-start":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-start-color":"<'border-top-color'>","border-block-start-style":"<'border-top-style'>","border-block-start-width":"<'border-top-width'>","border-bottom":"<line-width>||<line-style>||<color>","border-bottom-color":"<'border-top-color'>","border-bottom-left-radius":"<length-percentage>{1,2}","border-bottom-right-radius":"<length-percentage>{1,2}","border-bottom-style":"<line-style>","border-bottom-width":"<line-width>","border-collapse":"collapse|separate","border-color":"<color>{1,4}","border-end-end-radius":"<length-percentage>{1,2}","border-end-start-radius":"<length-percentage>{1,2}","border-image":"<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>","border-image-outset":"[<length>|<number>]{1,4}","border-image-repeat":"[stretch|repeat|round|space]{1,2}","border-image-slice":"<number-percentage>{1,4}&&fill?","border-image-source":"none|<image>","border-image-width":"[<length-percentage>|<number>|auto]{1,4}","border-inline":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-end":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-color":"<'border-top-color'>{1,2}","border-inline-style":"<'border-top-style'>","border-inline-width":"<'border-top-width'>","border-inline-end-color":"<'border-top-color'>","border-inline-end-style":"<'border-top-style'>","border-inline-end-width":"<'border-top-width'>","border-inline-start":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-start-color":"<'border-top-color'>","border-inline-start-style":"<'border-top-style'>","border-inline-start-width":"<'border-top-width'>","border-left":"<line-width>||<line-style>||<color>","border-left-color":"<color>","border-left-style":"<line-style>","border-left-width":"<line-width>","border-radius":"<length-percentage>{1,4} [/ <length-percentage>{1,4}]?","border-right":"<line-width>||<line-style>||<color>","border-right-color":"<color>","border-right-style":"<line-style>","border-right-width":"<line-width>","border-spacing":"<length> <length>?","border-start-end-radius":"<length-percentage>{1,2}","border-start-start-radius":"<length-percentage>{1,2}","border-style":"<line-style>{1,4}","border-top":"<line-width>||<line-style>||<color>","border-top-color":"<color>","border-top-left-radius":"<length-percentage>{1,2}","border-top-right-radius":"<length-percentage>{1,2}","border-top-style":"<line-style>","border-top-width":"<line-width>","border-width":"<line-width>{1,4}",bottom:"<length>|<percentage>|auto","box-align":"start|center|end|baseline|stretch","box-decoration-break":"slice|clone","box-direction":"normal|reverse|inherit","box-flex":"<number>","box-flex-group":"<integer>","box-lines":"single|multiple","box-ordinal-group":"<integer>","box-orient":"horizontal|vertical|inline-axis|block-axis|inherit","box-pack":"start|center|end|justify","box-shadow":"none|<shadow>#","box-sizing":"content-box|border-box","break-after":"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region","break-before":"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region","break-inside":"auto|avoid|avoid-page|avoid-column|avoid-region","caption-side":"top|bottom|block-start|block-end|inline-start|inline-end",caret:"<'caret-color'>||<'caret-shape'>","caret-color":"auto|<color>","caret-shape":"auto|bar|block|underscore",clear:"none|left|right|both|inline-start|inline-end",clip:"<shape>|auto","clip-path":"<clip-source>|[<basic-shape>||<geometry-box>]|none","clip-rule":"nonzero|evenodd",color:"<color>","color-interpolation-filters":"auto|sRGB|linearRGB","color-scheme":"normal|[light|dark|<custom-ident>]+&&only?","column-count":"<integer>|auto","column-fill":"auto|balance","column-gap":"normal|<length-percentage>","column-rule":"<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>","column-rule-color":"<color>","column-rule-style":"<'border-style'>","column-rule-width":"<'border-width'>","column-span":"none|all","column-width":"<length>|auto",columns:"<'column-width'>||<'column-count'>",contain:"none|strict|content|[[size||inline-size]||layout||style||paint]","contain-intrinsic-size":"[auto? [none|<length>]]{1,2}","contain-intrinsic-block-size":"auto? [none|<length>]","contain-intrinsic-height":"auto? [none|<length>]","contain-intrinsic-inline-size":"auto? [none|<length>]","contain-intrinsic-width":"auto? [none|<length>]",container:"<'container-name'> [/ <'container-type'>]?","container-name":"none|<custom-ident>+","container-type":"normal||[size|inline-size]",content:"normal|none|[<content-replacement>|<content-list>] [/ [<string>|<counter>]+]?","content-visibility":"visible|auto|hidden","counter-increment":"[<counter-name> <integer>?]+|none","counter-reset":"[<counter-name> <integer>?|<reversed-counter-name> <integer>?]+|none","counter-set":"[<counter-name> <integer>?]+|none",cursor:"[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]",d:"none|path( <string> )",cx:"<length>|<percentage>",cy:"<length>|<percentage>",direction:"ltr|rtl",display:"[<display-outside>||<display-inside>]|<display-listitem>|<display-internal>|<display-box>|<display-legacy>|<-non-standard-display>","dominant-baseline":"auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge","empty-cells":"show|hide","field-sizing":"content|fixed",fill:"<paint>","fill-opacity":"<number-zero-one>","fill-rule":"nonzero|evenodd",filter:"none|<filter-function-list>|<-ms-filter-function-list>",flex:"none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]","flex-basis":"content|<'width'>","flex-direction":"row|row-reverse|column|column-reverse","flex-flow":"<'flex-direction'>||<'flex-wrap'>","flex-grow":"<number>","flex-shrink":"<number>","flex-wrap":"nowrap|wrap|wrap-reverse",float:"left|right|none|inline-start|inline-end",font:"[[<'font-style'>||<font-variant-css2>||<'font-weight'>||<font-width-css3>]? <'font-size'> [/ <'line-height'>]? <'font-family'>#]|<system-family-name>|<-non-standard-font>","font-family":"[<family-name>|<generic-family>]#","font-feature-settings":"normal|<feature-tag-value>#","font-kerning":"auto|normal|none","font-language-override":"normal|<string>","font-optical-sizing":"auto|none","font-palette":"normal|light|dark|<palette-identifier>","font-variation-settings":"normal|[<string> <number>]#","font-size":"<absolute-size>|<relative-size>|<length-percentage>","font-size-adjust":"none|[ex-height|cap-height|ch-width|ic-width|ic-height]? [from-font|<number>]","font-smooth":"auto|never|always|<absolute-size>|<length>","font-stretch":"<font-stretch-absolute>","font-style":"normal|italic|oblique <angle>?","font-synthesis":"none|[weight||style||small-caps||position]","font-synthesis-position":"auto|none","font-synthesis-small-caps":"auto|none","font-synthesis-style":"auto|none","font-synthesis-weight":"auto|none","font-variant":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]","font-variant-alternates":"normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]","font-variant-caps":"normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps","font-variant-east-asian":"normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]","font-variant-emoji":"normal|text|emoji|unicode","font-variant-ligatures":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]","font-variant-numeric":"normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]","font-variant-position":"normal|sub|super","font-weight":"<font-weight-absolute>|bolder|lighter","forced-color-adjust":"auto|none|preserve-parent-color",gap:"<'row-gap'> <'column-gap'>?",grid:"<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>","grid-area":"<grid-line> [/ <grid-line>]{0,3}","grid-auto-columns":"<track-size>+","grid-auto-flow":"[row|column]||dense","grid-auto-rows":"<track-size>+","grid-column":"<grid-line> [/ <grid-line>]?","grid-column-end":"<grid-line>","grid-column-gap":"<length-percentage>","grid-column-start":"<grid-line>","grid-gap":"<'grid-row-gap'> <'grid-column-gap'>?","grid-row":"<grid-line> [/ <grid-line>]?","grid-row-end":"<grid-line>","grid-row-gap":"<length-percentage>","grid-row-start":"<grid-line>","grid-template":"none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?","grid-template-areas":"none|<string>+","grid-template-columns":"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?","grid-template-rows":"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?","hanging-punctuation":"none|[first||[force-end|allow-end]||last]",height:"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","hyphenate-character":"auto|<string>","hyphenate-limit-chars":"[auto|<integer>]{1,3}",hyphens:"none|manual|auto","image-orientation":"from-image|<angle>|[<angle>? flip]","image-rendering":"auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>","image-resolution":"[from-image||<resolution>]&&snap?","ime-mode":"auto|normal|active|inactive|disabled","initial-letter":"normal|[<number> <integer>?]","initial-letter-align":"[auto|alphabetic|hanging|ideographic]","inline-size":"<'width'>","input-security":"auto|none",inset:"<'top'>{1,4}","inset-block":"<'top'>{1,2}","inset-block-end":"<'top'>","inset-block-start":"<'top'>","inset-inline":"<'top'>{1,2}","inset-inline-end":"<'top'>","inset-inline-start":"<'top'>","interpolate-size":"numeric-only|allow-keywords",isolation:"auto|isolate","justify-content":"normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]","justify-items":"normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]","justify-self":"auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]","justify-tracks":"[normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]]#",left:"<length>|<percentage>|auto","letter-spacing":"normal|<length-percentage>","line-break":"auto|loose|normal|strict|anywhere","line-clamp":"none|<integer>","line-height":"normal|<number>|<length>|<percentage>","line-height-step":"<length>","list-style":"<'list-style-type'>||<'list-style-position'>||<'list-style-image'>","list-style-image":"<image>|none","list-style-position":"inside|outside","list-style-type":"<counter-style>|<string>|none",margin:"[<length>|<percentage>|auto]{1,4}","margin-block":"<'margin-left'>{1,2}","margin-block-end":"<'margin-left'>","margin-block-start":"<'margin-left'>","margin-bottom":"<length>|<percentage>|auto","margin-inline":"<'margin-left'>{1,2}","margin-inline-end":"<'margin-left'>","margin-inline-start":"<'margin-left'>","margin-left":"<length>|<percentage>|auto","margin-right":"<length>|<percentage>|auto","margin-top":"<length>|<percentage>|auto","margin-trim":"none|in-flow|all",marker:"none|<url>","marker-end":"none|<url>","marker-mid":"none|<url>","marker-start":"none|<url>",mask:"<mask-layer>#","mask-border":"<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>","mask-border-mode":"luminance|alpha","mask-border-outset":"[<length>|<number>]{1,4}","mask-border-repeat":"[stretch|repeat|round|space]{1,2}","mask-border-slice":"<number-percentage>{1,4} fill?","mask-border-source":"none|<image>","mask-border-width":"[<length-percentage>|<number>|auto]{1,4}","mask-clip":"[<geometry-box>|no-clip]#","mask-composite":"<compositing-operator>#","mask-image":"<mask-reference>#","mask-mode":"<masking-mode>#","mask-origin":"<geometry-box>#","mask-position":"<position>#","mask-repeat":"<repeat-style>#","mask-size":"<bg-size>#","mask-type":"luminance|alpha","masonry-auto-flow":"[pack|next]||[definite-first|ordered]","math-depth":"auto-add|add( <integer> )|<integer>","math-shift":"normal|compact","math-style":"normal|compact","max-block-size":"<'max-width'>","max-height":"none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","max-inline-size":"<'max-width'>","max-lines":"none|<integer>","max-width":"none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","min-block-size":"<'min-width'>","min-height":"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","min-inline-size":"<'min-width'>","min-width":"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","mix-blend-mode":"<blend-mode>|plus-lighter","object-fit":"fill|contain|cover|none|scale-down","object-position":"<position>",offset:"[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?","offset-anchor":"auto|<position>","offset-distance":"<length-percentage>","offset-path":"none|<offset-path>||<coord-box>","offset-position":"normal|auto|<position>","offset-rotate":"[auto|reverse]||<angle>",opacity:"<alpha-value>",order:"<integer>",orphans:"<integer>",outline:"[<'outline-width'>||<'outline-style'>||<'outline-color'>]","outline-color":"auto|<color>","outline-offset":"<length>","outline-style":"auto|<'border-style'>","outline-width":"<line-width>",overflow:"[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>","overflow-anchor":"auto|none","overflow-block":"visible|hidden|clip|scroll|auto","overflow-clip-box":"padding-box|content-box","overflow-clip-margin":"<visual-box>||<length [0,\u221E]>","overflow-inline":"visible|hidden|clip|scroll|auto","overflow-wrap":"normal|break-word|anywhere","overflow-x":"visible|hidden|clip|scroll|auto","overflow-y":"visible|hidden|clip|scroll|auto",overlay:"none|auto","overscroll-behavior":"[contain|none|auto]{1,2}","overscroll-behavior-block":"contain|none|auto","overscroll-behavior-inline":"contain|none|auto","overscroll-behavior-x":"contain|none|auto","overscroll-behavior-y":"contain|none|auto",padding:"[<length>|<percentage>]{1,4}","padding-block":"<'padding-left'>{1,2}","padding-block-end":"<'padding-left'>","padding-block-start":"<'padding-left'>","padding-bottom":"<length>|<percentage>","padding-inline":"<'padding-left'>{1,2}","padding-inline-end":"<'padding-left'>","padding-inline-start":"<'padding-left'>","padding-left":"<length>|<percentage>","padding-right":"<length>|<percentage>","padding-top":"<length>|<percentage>",page:"auto|<custom-ident>","page-break-after":"auto|always|avoid|left|right|recto|verso","page-break-before":"auto|always|avoid|left|right|recto|verso","page-break-inside":"auto|avoid","paint-order":"normal|[fill||stroke||markers]",perspective:"none|<length>","perspective-origin":"<position>","place-content":"<'align-content'> <'justify-content'>?","place-items":"<'align-items'> <'justify-items'>?","place-self":"<'align-self'> <'justify-self'>?","pointer-events":"auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit",position:"static|relative|absolute|sticky|fixed|-webkit-sticky","position-anchor":"auto|<anchor-name>","position-area":"none|<position-area>","position-try":"<'position-try-order'>? <'position-try-fallbacks'>","position-try-fallbacks":"none|[[<dashed-ident>||<try-tactic>]|<'position-area'>]#","position-try-order":"normal|<try-size>","position-visibility":"always|[anchors-valid||anchors-visible||no-overflow]","print-color-adjust":"economy|exact",quotes:"none|auto|[<string> <string>]+",r:"<length>|<percentage>",resize:"none|both|horizontal|vertical|block|inline",right:"<length>|<percentage>|auto",rotate:"none|<angle>|[x|y|z|<number>{3}]&&<angle>","row-gap":"normal|<length-percentage>","ruby-align":"start|center|space-between|space-around","ruby-merge":"separate|collapse|auto","ruby-position":"[alternate||[over|under]]|inter-character",rx:"<length>|<percentage>",ry:"<length>|<percentage>",scale:"none|[<number>|<percentage>]{1,3}","scrollbar-color":"auto|<color>{2}","scrollbar-gutter":"auto|stable&&both-edges?","scrollbar-width":"auto|thin|none","scroll-behavior":"auto|smooth","scroll-margin":"<length>{1,4}","scroll-margin-block":"<length>{1,2}","scroll-margin-block-start":"<length>","scroll-margin-block-end":"<length>","scroll-margin-bottom":"<length>","scroll-margin-inline":"<length>{1,2}","scroll-margin-inline-start":"<length>","scroll-margin-inline-end":"<length>","scroll-margin-left":"<length>","scroll-margin-right":"<length>","scroll-margin-top":"<length>","scroll-padding":"[auto|<length-percentage>]{1,4}","scroll-padding-block":"[auto|<length-percentage>]{1,2}","scroll-padding-block-start":"auto|<length-percentage>","scroll-padding-block-end":"auto|<length-percentage>","scroll-padding-bottom":"auto|<length-percentage>","scroll-padding-inline":"[auto|<length-percentage>]{1,2}","scroll-padding-inline-start":"auto|<length-percentage>","scroll-padding-inline-end":"auto|<length-percentage>","scroll-padding-left":"auto|<length-percentage>","scroll-padding-right":"auto|<length-percentage>","scroll-padding-top":"auto|<length-percentage>","scroll-snap-align":"[none|start|end|center]{1,2}","scroll-snap-coordinate":"none|<position>#","scroll-snap-destination":"<position>","scroll-snap-points-x":"none|repeat( <length-percentage> )","scroll-snap-points-y":"none|repeat( <length-percentage> )","scroll-snap-stop":"normal|always","scroll-snap-type":"none|[x|y|block|inline|both] [mandatory|proximity]?","scroll-snap-type-x":"none|mandatory|proximity","scroll-snap-type-y":"none|mandatory|proximity","scroll-timeline":"[<'scroll-timeline-name'>||<'scroll-timeline-axis'>]#","scroll-timeline-axis":"[block|inline|x|y]#","scroll-timeline-name":"[none|<dashed-ident>]#","shape-image-threshold":"<alpha-value>","shape-margin":"<length-percentage>","shape-outside":"none|[<shape-box>||<basic-shape>]|<image>","shape-rendering":"auto|optimizeSpeed|crispEdges|geometricPrecision",stroke:"<paint>","stroke-dasharray":"none|[<svg-length>+]#","stroke-dashoffset":"<svg-length>","stroke-linecap":"butt|round|square","stroke-linejoin":"miter|round|bevel","stroke-miterlimit":"<number-one-or-greater>","stroke-opacity":"<'opacity'>","stroke-width":"<svg-length>","tab-size":"<integer>|<length>","table-layout":"auto|fixed","text-align":"start|end|left|right|center|justify|match-parent","text-align-last":"auto|start|end|left|right|center|justify","text-anchor":"start|middle|end","text-combine-upright":"none|all|[digits <integer>?]","text-decoration":"<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>||<'text-decoration-thickness'>","text-decoration-color":"<color>","text-decoration-line":"none|[underline||overline||line-through||blink]|spelling-error|grammar-error","text-decoration-skip":"none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]","text-decoration-skip-ink":"auto|all|none","text-decoration-style":"solid|double|dotted|dashed|wavy","text-decoration-thickness":"auto|from-font|<length>|<percentage>","text-emphasis":"<'text-emphasis-style'>||<'text-emphasis-color'>","text-emphasis-color":"<color>","text-emphasis-position":"auto|[over|under]&&[right|left]?","text-emphasis-style":"none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>","text-indent":"<length-percentage>&&hanging?&&each-line?","text-justify":"auto|inter-character|inter-word|none","text-orientation":"mixed|upright|sideways","text-overflow":"[clip|ellipsis|<string>]{1,2}","text-rendering":"auto|optimizeSpeed|optimizeLegibility|geometricPrecision","text-shadow":"none|<shadow-t>#","text-size-adjust":"none|auto|<percentage>","text-spacing-trim":"space-all|normal|space-first|trim-start|trim-both|trim-all|auto","text-transform":"none|capitalize|uppercase|lowercase|full-width|full-size-kana","text-underline-offset":"auto|<length>|<percentage>","text-underline-position":"auto|from-font|[under||[left|right]]","text-wrap":"<'text-wrap-mode'>||<'text-wrap-style'>","text-wrap-mode":"auto|wrap|nowrap","text-wrap-style":"auto|balance|stable|pretty","timeline-scope":"none|<dashed-ident>#",top:"<length>|<percentage>|auto","touch-action":"auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation",transform:"none|<transform-list>","transform-box":"content-box|border-box|fill-box|stroke-box|view-box","transform-origin":"[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?","transform-style":"flat|preserve-3d",transition:"<single-transition>#","transition-behavior":"<transition-behavior-value>#","transition-delay":"<time>#","transition-duration":"<time>#","transition-property":"none|<single-transition-property>#","transition-timing-function":"<easing-function>#",translate:"none|<length-percentage> [<length-percentage> <length>?]?","unicode-bidi":"normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate|-webkit-isolate-override|-webkit-plaintext","user-select":"auto|text|none|contain|all","vector-effect":"none|non-scaling-stroke|non-scaling-size|non-rotation|fixed-position","vertical-align":"baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>","view-timeline":"[<'view-timeline-name'> <'view-timeline-axis'>?]#","view-timeline-axis":"[block|inline|x|y]#","view-timeline-inset":"[[auto|<length-percentage>]{1,2}]#","view-timeline-name":"none|<dashed-ident>#","view-transition-name":"none|<custom-ident>",visibility:"visible|hidden|collapse","white-space":"normal|pre|nowrap|pre-wrap|pre-line|break-spaces|[<'white-space-collapse'>||<'text-wrap'>||<'white-space-trim'>]","white-space-collapse":"collapse|discard|preserve|preserve-breaks|preserve-spaces|break-spaces",widows:"<integer>",width:"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","will-change":"auto|<animateable-feature>#","word-break":"normal|break-all|keep-all|break-word|auto-phrase","word-spacing":"normal|<length>","word-wrap":"normal|break-word","writing-mode":"horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>",x:"<length>|<percentage>",y:"<length>|<percentage>","z-index":"auto|<integer>",zoom:"normal|reset|<number>|<percentage>","-moz-background-clip":"padding|border","-moz-border-radius-bottomleft":"<'border-bottom-left-radius'>","-moz-border-radius-bottomright":"<'border-bottom-right-radius'>","-moz-border-radius-topleft":"<'border-top-left-radius'>","-moz-border-radius-topright":"<'border-bottom-right-radius'>","-moz-control-character-visibility":"visible|hidden","-moz-osx-font-smoothing":"auto|grayscale","-moz-user-select":"none|text|all|-moz-none","-ms-flex-align":"start|end|center|baseline|stretch","-ms-flex-item-align":"auto|start|end|center|baseline|stretch","-ms-flex-line-pack":"start|end|center|justify|distribute|stretch","-ms-flex-negative":"<'flex-shrink'>","-ms-flex-pack":"start|end|center|justify|distribute","-ms-flex-order":"<integer>","-ms-flex-positive":"<'flex-grow'>","-ms-flex-preferred-size":"<'flex-basis'>","-ms-interpolation-mode":"nearest-neighbor|bicubic","-ms-grid-column-align":"start|end|center|stretch","-ms-grid-row-align":"start|end|center|stretch","-ms-hyphenate-limit-last":"none|always|column|page|spread","-webkit-background-clip":"[<box>|border|padding|content|text]#","-webkit-column-break-after":"always|auto|avoid","-webkit-column-break-before":"always|auto|avoid","-webkit-column-break-inside":"always|auto|avoid","-webkit-font-smoothing":"auto|none|antialiased|subpixel-antialiased","-webkit-mask-box-image":"[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?","-webkit-print-color-adjust":"economy|exact","-webkit-text-security":"none|circle|disc|square","-webkit-user-drag":"none|element|auto","-webkit-user-select":"auto|none|text|all","alignment-baseline":"auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical","baseline-shift":"baseline|sub|super|<svg-length>",behavior:"<url>+",cue:"<'cue-before'> <'cue-after'>?","cue-after":"<url> <decibel>?|none","cue-before":"<url> <decibel>?|none","glyph-orientation-horizontal":"<angle>","glyph-orientation-vertical":"<angle>",kerning:"auto|<svg-length>",pause:"<'pause-before'> <'pause-after'>?","pause-after":"<time>|none|x-weak|weak|medium|strong|x-strong","pause-before":"<time>|none|x-weak|weak|medium|strong|x-strong",rest:"<'rest-before'> <'rest-after'>?","rest-after":"<time>|none|x-weak|weak|medium|strong|x-strong","rest-before":"<time>|none|x-weak|weak|medium|strong|x-strong",src:"[<url> [format( <string># )]?|local( <family-name> )]#",speak:"auto|never|always","speak-as":"normal|spell-out||digits||[literal-punctuation|no-punctuation]","unicode-range":"<urange>#","voice-balance":"<number>|left|center|right|leftwards|rightwards","voice-duration":"auto|<time>","voice-family":"[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve","voice-pitch":"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]","voice-range":"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]","voice-rate":"[normal|x-slow|slow|medium|fast|x-fast]||<percentage>","voice-stress":"normal|strong|moderate|none|reduced","voice-volume":"silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]","white-space-trim":"none|discard-before||discard-after||discard-inner"},atrules:{charset:{prelude:"<string>",descriptors:null},"counter-style":{prelude:"<counter-style-name>",descriptors:{"additive-symbols":"[<integer>&&<symbol>]#",fallback:"<counter-style-name>",negative:"<symbol> <symbol>?",pad:"<integer>&&<symbol>",prefix:"<symbol>",range:"[[<integer>|infinite]{2}]#|auto","speak-as":"auto|bullets|numbers|words|spell-out|<counter-style-name>",suffix:"<symbol>",symbols:"<symbol>+",system:"cyclic|numeric|alphabetic|symbolic|additive|[fixed <integer>?]|[extends <counter-style-name>]"}},document:{prelude:"[<url>|url-prefix( <string> )|domain( <string> )|media-document( <string> )|regexp( <string> )]#",descriptors:null},"font-palette-values":{prelude:"<dashed-ident>",descriptors:{"base-palette":"light|dark|<integer [0,\u221E]>","font-family":"<family-name>#","override-colors":"[<integer [0,\u221E]> <absolute-color-base>]#"}},"font-face":{prelude:null,descriptors:{"ascent-override":"normal|<percentage>","descent-override":"normal|<percentage>","font-display":"[auto|block|swap|fallback|optional]","font-family":"<family-name>","font-feature-settings":"normal|<feature-tag-value>#","font-variation-settings":"normal|[<string> <number>]#","font-stretch":"<font-stretch-absolute>{1,2}","font-style":"normal|italic|oblique <angle>{0,2}","font-weight":"<font-weight-absolute>{1,2}","line-gap-override":"normal|<percentage>","size-adjust":"<percentage>",src:"[<url> [format( <string># )]?|local( <family-name> )]#","unicode-range":"<urange>#"}},"font-feature-values":{prelude:"<family-name>#",descriptors:null},import:{prelude:"[<string>|<url>] [layer|layer( <layer-name> )]? [supports( [<supports-condition>|<declaration>] )]? <media-query-list>?",descriptors:null},keyframes:{prelude:"<keyframes-name>",descriptors:null},layer:{prelude:"[<layer-name>#|<layer-name>?]",descriptors:null},media:{prelude:"<media-query-list>",descriptors:null},namespace:{prelude:"<namespace-prefix>? [<string>|<url>]",descriptors:null},page:{prelude:"<page-selector-list>",descriptors:{bleed:"auto|<length>",marks:"none|[crop||cross]","page-orientation":"upright|rotate-left|rotate-right",size:"<length>{1,2}|auto|[<page-size>||[portrait|landscape]]"}},"position-try":{prelude:"<dashed-ident>",descriptors:{top:"<'top'>",left:"<'left'>",bottom:"<'bottom'>",right:"<'right'>","inset-block-start":"<'inset-block-start'>","inset-block-end":"<'inset-block-end'>","inset-inline-start":"<'inset-inline-start'>","inset-inline-end":"<'inset-inline-end'>","inset-block":"<'inset-block'>","inset-inline":"<'inset-inline'>",inset:"<'inset'>","margin-top":"<'margin-top'>","margin-left":"<'margin-left'>","margin-bottom":"<'margin-bottom'>","margin-right":"<'margin-right'>","margin-block-start":"<'margin-block-start'>","margin-block-end":"<'margin-block-end'>","margin-inline-start":"<'margin-inline-start'>","margin-inline-end":"<'margin-inline-end'>",margin:"<'margin'>","margin-block":"<'margin-block'>","margin-inline":"<'margin-inline'>",width:"<'width'>",height:"<'height'>","min-width":"<'min-width'>","min-height":"<'min-height'>","max-width":"<'max-width'>","max-height":"<'max-height'>","block-size":"<'block-size'>","inline-size":"<'inline-size'>","min-block-size":"<'min-block-size'>","min-inline-size":"<'min-inline-size'>","max-block-size":"<'max-block-size'>","max-inline-size":"<'max-inline-size'>","align-self":"<'align-self'>|anchor-center","justify-self":"<'justify-self'>|anchor-center"}},property:{prelude:"<custom-property-name>",descriptors:{syntax:"<string>",inherits:"true|false","initial-value":"<declaration-value>?"}},scope:{prelude:"[( <scope-start> )]? [to ( <scope-end> )]?",descriptors:null},"starting-style":{prelude:null,descriptors:null},supports:{prelude:"<supports-condition>",descriptors:null},container:{prelude:"[<container-name>]? <container-condition>",descriptors:null},nest:{prelude:"<complex-selector-list>",descriptors:null}}};var St={};x(St,{AnPlusB:()=>$r,Atrule:()=>Jr,AtrulePrelude:()=>tn,AttributeSelector:()=>on,Block:()=>an,Brackets:()=>cn,CDC:()=>pn,CDO:()=>mn,ClassSelector:()=>dn,Combinator:()=>bn,Comment:()=>yn,Condition:()=>wn,Declaration:()=>Sn,DeclarationList:()=>An,Dimension:()=>En,Feature:()=>Pn,FeatureFunction:()=>Dn,FeatureRange:()=>Fn,Function:()=>Mn,GeneralEnclosed:()=>_n,Hash:()=>jn,IdSelector:()=>Gn,Identifier:()=>Un,Layer:()=>Kn,LayerList:()=>Qn,MediaQuery:()=>$n,MediaQueryList:()=>Jn,NestingSelector:()=>ti,Nth:()=>ni,Number:()=>oi,Operator:()=>ai,Parentheses:()=>ci,Percentage:()=>pi,PseudoClassSelector:()=>mi,PseudoElementSelector:()=>di,Ratio:()=>bi,Raw:()=>yi,Rule:()=>wi,Scope:()=>Si,Selector:()=>Ti,SelectorList:()=>Li,String:()=>Di,StyleSheet:()=>Oi,SupportsDeclaration:()=>Ri,TypeSelector:()=>_i,UnicodeRange:()=>qi,Url:()=>Vi,Value:()=>Xi,WhiteSpace:()=>Zi});var $r={};x($r,{generate:()=>Yc,name:()=>Hc,parse:()=>Xr,structure:()=>Gc});var de=43,re=45,Zt=110,Oe=!0,Uc=!1;function Jt(e,t){let r=this.tokenStart+e,n=this.charCodeAt(r);for((n===de||n===re)&&(t&&this.error("Number sign is not allowed"),r++);r<this.tokenEnd;r++)j(this.charCodeAt(r))||this.error("Integer is expected",r)}function Je(e){return Jt.call(this,0,e)}function Le(e,t){if(!this.cmpChar(this.tokenStart+e,t)){let r="";switch(t){case Zt:r="N is expected";break;case re:r="HyphenMinus is expected";break}this.error(r,this.tokenStart+e)}}function Qr(){let e=0,t=0,r=this.tokenType;for(;r===13||r===25;)r=this.lookupType(++e);if(r!==10)if(this.isDelim(de,e)||this.isDelim(re,e)){t=this.isDelim(de,e)?de:re;do r=this.lookupType(++e);while(r===13||r===25);r!==10&&(this.skip(e),Je.call(this,Oe))}else return null;return e>0&&this.skip(e),t===0&&(r=this.charCodeAt(this.tokenStart),r!==de&&r!==re&&this.error("Number sign is expected")),Je.call(this,t!==0),t===re?"-"+this.consume(10):this.consume(10)}var Hc="AnPlusB",Gc={a:[String,null],b:[String,null]};function Xr(){let e=this.tokenStart,t=null,r=null;if(this.tokenType===10)Je.call(this,Uc),r=this.consume(10);else if(this.tokenType===1&&this.cmpChar(this.tokenStart,re))switch(t="-1",Le.call(this,1,Zt),this.tokenEnd-this.tokenStart){case 2:this.next(),r=Qr.call(this);break;case 3:Le.call(this,2,re),this.next(),this.skipSC(),Je.call(this,Oe),r="-"+this.consume(10);break;default:Le.call(this,2,re),Jt.call(this,3,Oe),this.next(),r=this.substrToCursor(e+2)}else if(this.tokenType===1||this.isDelim(de)&&this.lookupType(1)===1){let n=0;switch(t="1",this.isDelim(de)&&(n=1,this.next()),Le.call(this,0,Zt),this.tokenEnd-this.tokenStart){case 1:this.next(),r=Qr.call(this);break;case 2:Le.call(this,1,re),this.next(),this.skipSC(),Je.call(this,Oe),r="-"+this.consume(10);break;default:Le.call(this,1,re),Jt.call(this,2,Oe),this.next(),r=this.substrToCursor(e+n+1)}}else if(this.tokenType===12){let n=this.charCodeAt(this.tokenStart),i=n===de||n===re,o=this.tokenStart+i;for(;o<this.tokenEnd&&j(this.charCodeAt(o));o++);o===this.tokenStart+i&&this.error("Integer is expected",this.tokenStart+i),Le.call(this,o-this.tokenStart,Zt),t=this.substring(e,o),o+1===this.tokenEnd?(this.next(),r=Qr.call(this)):(Le.call(this,o-this.tokenStart+1,re),o+2===this.tokenEnd?(this.next(),this.skipSC(),Je.call(this,Oe),r="-"+this.consume(10)):(Jt.call(this,o-this.tokenStart+2,Oe),this.next(),r=this.substrToCursor(o+1)))}else this.error();return t!==null&&t.charCodeAt(0)===de&&(t=t.substr(1)),r!==null&&r.charCodeAt(0)===de&&(r=r.substr(1)),{type:"AnPlusB",loc:this.getLocation(e,this.tokenStart),a:t,b:r}}function Yc(e){if(e.a){let t=e.a==="+1"&&"n"||e.a==="1"&&"n"||e.a==="-1"&&"-n"||e.a+"n";if(e.b){let r=e.b[0]==="-"||e.b[0]==="+"?e.b:"+"+e.b;this.tokenize(t+r)}else this.tokenize(t)}else this.tokenize(e.b)}var Jr={};x(Jr,{generate:()=>$c,name:()=>Vc,parse:()=>Zr,structure:()=>Xc,walkContext:()=>Qc});function Rs(){return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon,!0)}function Kc(){for(let e=1,t;t=this.lookupType(e);e++){if(t===24)return!0;if(t===23||t===3)return!1}return!1}var Vc="Atrule",Qc="atrule",Xc={name:String,prelude:["AtrulePrelude","Raw",null],block:["Block",null]};function Zr(e=!1){let t=this.tokenStart,r,n,i=null,o=null;switch(this.eat(3),r=this.substrToCursor(t+1),n=r.toLowerCase(),this.skipSC(),this.eof===!1&&this.tokenType!==23&&this.tokenType!==17&&(this.parseAtrulePrelude?i=this.parseWithFallback(this.AtrulePrelude.bind(this,r,e),Rs):i=Rs.call(this,this.tokenIndex),this.skipSC()),this.tokenType){case 17:this.next();break;case 23:hasOwnProperty.call(this.atrule,n)&&typeof this.atrule[n].block=="function"?o=this.atrule[n].block.call(this,e):o=this.Block(Kc.call(this));break}return{type:"Atrule",loc:this.getLocation(t,this.tokenStart),name:r,prelude:i,block:o}}function $c(e){this.token(3,"@"+e.name),e.prelude!==null&&this.node(e.prelude),e.block?this.node(e.block):this.token(17,";")}var tn={};x(tn,{generate:()=>tu,name:()=>Zc,parse:()=>en,structure:()=>eu,walkContext:()=>Jc});var Zc="AtrulePrelude",Jc="atrulePrelude",eu={children:[[]]};function en(e){let t=null;return e!==null&&(e=e.toLowerCase()),this.skipSC(),hasOwnProperty.call(this.atrule,e)&&typeof this.atrule[e].prelude=="function"?t=this.atrule[e].prelude.call(this):t=this.readSequence(this.scope.AtrulePrelude),this.skipSC(),this.eof!==!0&&this.tokenType!==23&&this.tokenType!==17&&this.error("Semicolon or block is expected"),{type:"AtrulePrelude",loc:this.getLocationFromList(t),children:t}}function tu(e){this.children(e)}var on={};x(on,{generate:()=>cu,name:()=>au,parse:()=>nn,structure:()=>lu});var ru=36,Ms=42,er=61,nu=94,rn=124,iu=126;function ou(){this.eof&&this.error("Unexpected end of input");let e=this.tokenStart,t=!1;return this.isDelim(Ms)?(t=!0,this.next()):this.isDelim(rn)||this.eat(1),this.isDelim(rn)?this.charCodeAt(this.tokenStart+1)!==er?(this.next(),this.eat(1)):t&&this.error("Identifier is expected",this.tokenEnd):t&&this.error("Vertical line is expected"),{type:"Identifier",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e)}}function su(){let e=this.tokenStart,t=this.charCodeAt(e);return t!==er&&t!==iu&&t!==nu&&t!==ru&&t!==Ms&&t!==rn&&this.error("Attribute selector (=, ~=, ^=, $=, *=, |=) is expected"),this.next(),t!==er&&(this.isDelim(er)||this.error("Equal sign is expected"),this.next()),this.substrToCursor(e)}var au="AttributeSelector",lu={name:"Identifier",matcher:[String,null],value:["String","Identifier",null],flags:[String,null]};function nn(){let e=this.tokenStart,t,r=null,n=null,i=null;return this.eat(19),this.skipSC(),t=ou.call(this),this.skipSC(),this.tokenType!==20&&(this.tokenType!==1&&(r=su.call(this),this.skipSC(),n=this.tokenType===5?this.String():this.Identifier(),this.skipSC()),this.tokenType===1&&(i=this.consume(1),this.skipSC())),this.eat(20),{type:"AttributeSelector",loc:this.getLocation(e,this.tokenStart),name:t,matcher:r,value:n,flags:i}}function cu(e){this.token(9,"["),this.node(e.name),e.matcher!==null&&(this.tokenize(e.matcher),this.node(e.value)),e.flags!==null&&this.token(1,e.flags),this.token(9,"]")}var an={};x(an,{generate:()=>du,name:()=>hu,parse:()=>sn,structure:()=>fu,walkContext:()=>mu});var uu=38;function Ws(){return this.Raw(null,!0)}function Bs(){return this.parseWithFallback(this.Rule,Ws)}function _s(){return this.Raw(this.consumeUntilSemicolonIncluded,!0)}function pu(){if(this.tokenType===17)return _s.call(this,this.tokenIndex);let e=this.parseWithFallback(this.Declaration,_s);return this.tokenType===17&&this.next(),e}var hu="Block",mu="block",fu={children:[["Atrule","Rule","Declaration"]]};function sn(e){let t=e?pu:Bs,r=this.tokenStart,n=this.createList();this.eat(23);e:for(;!this.eof;)switch(this.tokenType){case 24:break e;case 13:case 25:this.next();break;case 3:n.push(this.parseWithFallback(this.Atrule.bind(this,e),Ws));break;default:e&&this.isDelim(uu)?n.push(Bs.call(this)):n.push(t.call(this))}return this.eof||this.eat(24),{type:"Block",loc:this.getLocation(r,this.tokenStart),children:n}}function du(e){this.token(23,"{"),this.children(e,t=>{t.type==="Declaration"&&this.token(17,";")}),this.token(24,"}")}var cn={};x(cn,{generate:()=>xu,name:()=>gu,parse:()=>ln,structure:()=>bu});var gu="Brackets",bu={children:[[]]};function ln(e,t){let r=this.tokenStart,n=null;return this.eat(19),n=e.call(this,t),this.eof||this.eat(20),{type:"Brackets",loc:this.getLocation(r,this.tokenStart),children:n}}function xu(e){this.token(9,"["),this.children(e),this.token(9,"]")}var pn={};x(pn,{generate:()=>wu,name:()=>yu,parse:()=>un,structure:()=>ku});var yu="CDC",ku=[];function un(){let e=this.tokenStart;return this.eat(15),{type:"CDC",loc:this.getLocation(e,this.tokenStart)}}function wu(){this.token(15,"-->")}var mn={};x(mn,{generate:()=>Cu,name:()=>vu,parse:()=>hn,structure:()=>Su});var vu="CDO",Su=[];function hn(){let e=this.tokenStart;return this.eat(14),{type:"CDO",loc:this.getLocation(e,this.tokenStart)}}function Cu(){this.token(14,"<!--")}var dn={};x(dn,{generate:()=>Eu,name:()=>Au,parse:()=>fn,structure:()=>Lu});var Tu=46,Au="ClassSelector",Lu={name:String};function fn(){return this.eatDelim(Tu),{type:"ClassSelector",loc:this.getLocation(this.tokenStart-1,this.tokenEnd),name:this.consume(1)}}function Eu(e){this.token(9,"."),this.token(1,e.name)}var bn={};x(bn,{generate:()=>Ou,name:()=>Du,parse:()=>gn,structure:()=>Nu});var zu=43,js=47,Pu=62,Iu=126,Du="Combinator",Nu={name:String};function gn(){let e=this.tokenStart,t;switch(this.tokenType){case 13:t=" ";break;case 9:switch(this.charCodeAt(this.tokenStart)){case Pu:case zu:case Iu:this.next();break;case js:this.next(),this.eatIdent("deep"),this.eatDelim(js);break;default:this.error("Combinator is expected")}t=this.substrToCursor(e);break}return{type:"Combinator",loc:this.getLocation(e,this.tokenStart),name:t}}function Ou(e){this.tokenize(e.name)}var yn={};x(yn,{generate:()=>_u,name:()=>Mu,parse:()=>xn,structure:()=>Bu});var Fu=42,Ru=47,Mu="Comment",Bu={value:String};function xn(){let e=this.tokenStart,t=this.tokenEnd;return this.eat(25),t-e+2>=2&&this.charCodeAt(t-2)===Fu&&this.charCodeAt(t-1)===Ru&&(t-=2),{type:"Comment",loc:this.getLocation(e,this.tokenStart),value:this.substring(e+2,t)}}function _u(e){this.token(25,"/*"+e.value+"*/")}var wn={};x(wn,{generate:()=>Hu,name:()=>ju,parse:()=>kn,structure:()=>qu});var Wu=new Set([16,22,0]),ju="Condition",qu={kind:String,children:[["Identifier","Feature","FeatureFunction","FeatureRange","SupportsDeclaration"]]};function qs(e){return this.lookupTypeNonSC(1)===1&&Wu.has(this.lookupTypeNonSC(2))?this.Feature(e):this.FeatureRange(e)}var Uu={media:qs,container:qs,supports(){return this.SupportsDeclaration()}};function kn(e="media"){let t=this.createList();e:for(;!this.eof;)switch(this.tokenType){case 25:case 13:this.next();continue;case 1:t.push(this.Identifier());break;case 21:{let r=this.parseWithFallback(()=>Uu[e].call(this,e),()=>null);r||(r=this.parseWithFallback(()=>{this.eat(21);let n=this.Condition(e);return this.eat(22),n},()=>this.GeneralEnclosed(e))),t.push(r);break}case 2:{let r=this.parseWithFallback(()=>this.FeatureFunction(e),()=>null);r||(r=this.GeneralEnclosed(e)),t.push(r);break}default:break e}return t.isEmpty&&this.error("Condition is expected"),{type:"Condition",loc:this.getLocationFromList(t),kind:e,children:t}}function Hu(e){e.children.forEach(t=>{t.type==="Condition"?(this.token(21,"("),this.node(t),this.token(22,")")):this.node(t)})}var Sn={};x(Sn,{generate:()=>rp,name:()=>Ju,parse:()=>vn,structure:()=>tp,walkContext:()=>ep});var Hs=33,Gu=35,Yu=36,Ku=38,Vu=42,Qu=43,Us=47;function Xu(){return this.Raw(this.consumeUntilExclamationMarkOrSemicolon,!0)}function $u(){return this.Raw(this.consumeUntilExclamationMarkOrSemicolon,!1)}function Zu(){let e=this.tokenIndex,t=this.Value();return t.type!=="Raw"&&this.eof===!1&&this.tokenType!==17&&this.isDelim(Hs)===!1&&this.isBalanceEdge(e)===!1&&this.error(),t}var Ju="Declaration",ep="declaration",tp={important:[Boolean,String],property:String,value:["Value","Raw"]};function vn(){let e=this.tokenStart,t=this.tokenIndex,r=np.call(this),n=qt(r),i=n?this.parseCustomProperty:this.parseValue,o=n?$u:Xu,a=!1,u;this.skipSC(),this.eat(16);let l=this.tokenIndex;if(n||this.skipSC(),i?u=this.parseWithFallback(Zu,o):u=o.call(this,this.tokenIndex),n&&u.type==="Value"&&u.children.isEmpty){for(let s=l-this.tokenIndex;s<=0;s++)if(this.lookupType(s)===13){u.children.appendData({type:"WhiteSpace",loc:null,value:" "});break}}return this.isDelim(Hs)&&(a=ip.call(this),this.skipSC()),this.eof===!1&&this.tokenType!==17&&this.isBalanceEdge(t)===!1&&this.error(),{type:"Declaration",loc:this.getLocation(e,this.tokenStart),important:a,property:r,value:u}}function rp(e){this.token(1,e.property),this.token(16,":"),this.node(e.value),e.important&&(this.token(9,"!"),this.token(1,e.important===!0?"important":e.important))}function np(){let e=this.tokenStart;if(this.tokenType===9)switch(this.charCodeAt(this.tokenStart)){case Vu:case Yu:case Qu:case Gu:case Ku:this.next();break;case Us:this.next(),this.isDelim(Us)&&this.next();break}return this.tokenType===4?this.eat(4):this.eat(1),this.substrToCursor(e)}function ip(){this.eat(9),this.skipSC();let e=this.consume(1);return e==="important"?!0:e}var An={};x(An,{generate:()=>lp,name:()=>sp,parse:()=>Tn,structure:()=>ap});var op=38;function Cn(){return this.Raw(this.consumeUntilSemicolonIncluded,!0)}var sp="DeclarationList",ap={children:[["Declaration","Atrule","Rule"]]};function Tn(){let e=this.createList();for(;!this.eof;)switch(this.tokenType){case 13:case 25:case 17:this.next();break;case 3:e.push(this.parseWithFallback(this.Atrule.bind(this,!0),Cn));break;default:this.isDelim(op)?e.push(this.parseWithFallback(this.Rule,Cn)):e.push(this.parseWithFallback(this.Declaration,Cn))}return{type:"DeclarationList",loc:this.getLocationFromList(e),children:e}}function lp(e){this.children(e,t=>{t.type==="Declaration"&&this.token(17,";")})}var En={};x(En,{generate:()=>pp,name:()=>cp,parse:()=>Ln,structure:()=>up});var cp="Dimension",up={value:String,unit:String};function Ln(){let e=this.tokenStart,t=this.consumeNumber(12);return{type:"Dimension",loc:this.getLocation(e,this.tokenStart),value:t,unit:this.substring(e+t.length,this.tokenStart)}}function pp(e){this.token(12,e.value+e.unit)}var Pn={};x(Pn,{generate:()=>dp,name:()=>mp,parse:()=>zn,structure:()=>fp});var hp=47,mp="Feature",fp={kind:String,name:String,value:["Identifier","Number","Dimension","Ratio","Function",null]};function zn(e){let t=this.tokenStart,r,n=null;if(this.eat(21),this.skipSC(),r=this.consume(1),this.skipSC(),this.tokenType!==22){switch(this.eat(16),this.skipSC(),this.tokenType){case 10:this.lookupNonWSType(1)===9?n=this.Ratio():n=this.Number();break;case 12:n=this.Dimension();break;case 1:n=this.Identifier();break;case 2:n=this.parseWithFallback(()=>{let i=this.Function(this.readSequence,this.scope.Value);return this.skipSC(),this.isDelim(hp)&&this.error(),i},()=>this.Ratio());break;default:this.error("Number, dimension, ratio or identifier is expected")}this.skipSC()}return this.eof||this.eat(22),{type:"Feature",loc:this.getLocation(t,this.tokenStart),kind:e,name:r,value:n}}function dp(e){this.token(21,"("),this.token(1,e.name),e.value!==null&&(this.token(16,":"),this.node(e.value)),this.token(22,")")}var Dn={};x(Dn,{generate:()=>yp,name:()=>gp,parse:()=>In,structure:()=>bp});var gp="FeatureFunction",bp={kind:String,feature:String,value:["Declaration","Selector"]};function xp(e,t){let n=(this.features[e]||{})[t];return typeof n!="function"&&this.error(`Unknown feature ${t}()`),n}function In(e="unknown"){let t=this.tokenStart,r=this.consumeFunctionName(),n=xp.call(this,e,r.toLowerCase());this.skipSC();let i=this.parseWithFallback(()=>{let o=this.tokenIndex,a=n.call(this);return this.eof===!1&&this.isBalanceEdge(o)===!1&&this.error(),a},()=>this.Raw(null,!1));return this.eof||this.eat(22),{type:"FeatureFunction",loc:this.getLocation(t,this.tokenStart),kind:e,feature:r,value:i}}function yp(e){this.token(2,e.feature+"("),this.node(e.value),this.token(22,")")}var Fn={};x(Fn,{generate:()=>Cp,name:()=>vp,parse:()=>On,structure:()=>Sp});var Gs=47,kp=60,Ys=61,wp=62,vp="FeatureRange",Sp={kind:String,left:["Identifier","Number","Dimension","Ratio","Function"],leftComparison:String,middle:["Identifier","Number","Dimension","Ratio","Function"],rightComparison:[String,null],right:["Identifier","Number","Dimension","Ratio","Function",null]};function Nn(){switch(this.skipSC(),this.tokenType){case 10:return this.isDelim(Gs,this.lookupOffsetNonSC(1))?this.Ratio():this.Number();case 12:return this.Dimension();case 1:return this.Identifier();case 2:return this.parseWithFallback(()=>{let e=this.Function(this.readSequence,this.scope.Value);return this.skipSC(),this.isDelim(Gs)&&this.error(),e},()=>this.Ratio());default:this.error("Number, dimension, ratio or identifier is expected")}}function Ks(e){if(this.skipSC(),this.isDelim(kp)||this.isDelim(wp)){let t=this.source[this.tokenStart];return this.next(),this.isDelim(Ys)?(this.next(),t+"="):t}if(this.isDelim(Ys))return"=";this.error(`Expected ${e?'":", ':""}"<", ">", "=" or ")"`)}function On(e="unknown"){let t=this.tokenStart;this.skipSC(),this.eat(21);let r=Nn.call(this),n=Ks.call(this,r.type==="Identifier"),i=Nn.call(this),o=null,a=null;return this.lookupNonWSType(0)!==22&&(o=Ks.call(this),a=Nn.call(this)),this.skipSC(),this.eat(22),{type:"FeatureRange",loc:this.getLocation(t,this.tokenStart),kind:e,left:r,leftComparison:n,middle:i,rightComparison:o,right:a}}function Cp(e){this.token(21,"("),this.node(e.left),this.tokenize(e.leftComparison),this.node(e.middle),e.right&&(this.tokenize(e.rightComparison),this.node(e.right)),this.token(22,")")}var Mn={};x(Mn,{generate:()=>Ep,name:()=>Tp,parse:()=>Rn,structure:()=>Lp,walkContext:()=>Ap});var Tp="Function",Ap="function",Lp={name:String,children:[[]]};function Rn(e,t){let r=this.tokenStart,n=this.consumeFunctionName(),i=n.toLowerCase(),o;return o=t.hasOwnProperty(i)?t[i].call(this,t):e.call(this,t),this.eof||this.eat(22),{type:"Function",loc:this.getLocation(r,this.tokenStart),name:n,children:o}}function Ep(e){this.token(2,e.name+"("),this.children(e),this.token(22,")")}var _n={};x(_n,{generate:()=>Ip,name:()=>zp,parse:()=>Bn,structure:()=>Pp});var zp="GeneralEnclosed",Pp={kind:String,function:[String,null],children:[[]]};function Bn(e){let t=this.tokenStart,r=null;this.tokenType===2?r=this.consumeFunctionName():this.eat(21);let n=this.parseWithFallback(()=>{let i=this.tokenIndex,o=this.readSequence(this.scope.Value);return this.eof===!1&&this.isBalanceEdge(i)===!1&&this.error(),o},()=>this.createSingleNodeList(this.Raw(null,!1)));return this.eof||this.eat(22),{type:"GeneralEnclosed",loc:this.getLocation(t,this.tokenStart),kind:e,function:r,children:n}}function Ip(e){e.function?this.token(2,e.function+"("):this.token(21,"("),this.children(e),this.token(22,")")}var jn={};x(jn,{generate:()=>Fp,name:()=>Np,parse:()=>Wn,structure:()=>Op,xxx:()=>Dp});var Dp="XXX",Np="Hash",Op={value:String};function Wn(){let e=this.tokenStart;return this.eat(4),{type:"Hash",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e+1)}}function Fp(e){this.token(4,"#"+e.value)}var Un={};x(Un,{generate:()=>Bp,name:()=>Rp,parse:()=>qn,structure:()=>Mp});var Rp="Identifier",Mp={name:String};function qn(){return{type:"Identifier",loc:this.getLocation(this.tokenStart,this.tokenEnd),name:this.consume(1)}}function Bp(e){this.token(1,e.name)}var Gn={};x(Gn,{generate:()=>jp,name:()=>_p,parse:()=>Hn,structure:()=>Wp});var _p="IdSelector",Wp={name:String};function Hn(){let e=this.tokenStart;return this.eat(4),{type:"IdSelector",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e+1)}}function jp(e){this.token(9,"#"+e.name)}var Kn={};x(Kn,{generate:()=>Gp,name:()=>Up,parse:()=>Yn,structure:()=>Hp});var qp=46,Up="Layer",Hp={name:String};function Yn(){let e=this.tokenStart,t=this.consume(1);for(;this.isDelim(qp);)this.eat(9),t+="."+this.consume(1);return{type:"Layer",loc:this.getLocation(e,this.tokenStart),name:t}}function Gp(e){this.tokenize(e.name)}var Qn={};x(Qn,{generate:()=>Vp,name:()=>Yp,parse:()=>Vn,structure:()=>Kp});var Yp="LayerList",Kp={children:[["Layer"]]};function Vn(){let e=this.createList();for(this.skipSC();!this.eof&&(e.push(this.Layer()),this.lookupTypeNonSC(0)===18);)this.skipSC(),this.next(),this.skipSC();return{type:"LayerList",loc:this.getLocationFromList(e),children:e}}function Vp(e){this.children(e,()=>this.token(18,","))}var $n={};x($n,{generate:()=>$p,name:()=>Qp,parse:()=>Xn,structure:()=>Xp});var Qp="MediaQuery",Xp={modifier:[String,null],mediaType:[String,null],condition:["Condition",null]};function Xn(){let e=this.tokenStart,t=null,r=null,n=null;if(this.skipSC(),this.tokenType===1&&this.lookupTypeNonSC(1)!==21){let i=this.consume(1),o=i.toLowerCase();switch(o==="not"||o==="only"?(this.skipSC(),t=o,r=this.consume(1)):r=i,this.lookupTypeNonSC(0)){case 1:{this.skipSC(),this.eatIdent("and"),n=this.Condition("media");break}case 23:case 17:case 18:case 0:break;default:this.error("Identifier or parenthesis is expected")}}else switch(this.tokenType){case 1:case 21:case 2:{n=this.Condition("media");break}case 23:case 17:case 0:break;default:this.error("Identifier or parenthesis is expected")}return{type:"MediaQuery",loc:this.getLocation(e,this.tokenStart),modifier:t,mediaType:r,condition:n}}function $p(e){e.mediaType?(e.modifier&&this.token(1,e.modifier),this.token(1,e.mediaType),e.condition&&(this.token(1,"and"),this.node(e.condition))):e.condition&&this.node(e.condition)}var Jn={};x(Jn,{generate:()=>eh,name:()=>Zp,parse:()=>Zn,structure:()=>Jp});var Zp="MediaQueryList",Jp={children:[["MediaQuery"]]};function Zn(){let e=this.createList();for(this.skipSC();!this.eof&&(e.push(this.MediaQuery()),this.tokenType===18);)this.next();return{type:"MediaQueryList",loc:this.getLocationFromList(e),children:e}}function eh(e){this.children(e,()=>this.token(18,","))}var ti={};x(ti,{generate:()=>ih,name:()=>rh,parse:()=>ei,structure:()=>nh});var th=38,rh="NestingSelector",nh={};function ei(){let e=this.tokenStart;return this.eatDelim(th),{type:"NestingSelector",loc:this.getLocation(e,this.tokenStart)}}function ih(){this.token(9,"&")}var ni={};x(ni,{generate:()=>ah,name:()=>oh,parse:()=>ri,structure:()=>sh});var oh="Nth",sh={nth:["AnPlusB","Identifier"],selector:["SelectorList",null]};function ri(){this.skipSC();let e=this.tokenStart,t=e,r=null,n;return this.lookupValue(0,"odd")||this.lookupValue(0,"even")?n=this.Identifier():n=this.AnPlusB(),t=this.tokenStart,this.skipSC(),this.lookupValue(0,"of")&&(this.next(),r=this.SelectorList(),t=this.tokenStart),{type:"Nth",loc:this.getLocation(e,t),nth:n,selector:r}}function ah(e){this.node(e.nth),e.selector!==null&&(this.token(1,"of"),this.node(e.selector))}var oi={};x(oi,{generate:()=>uh,name:()=>lh,parse:()=>ii,structure:()=>ch});var lh="Number",ch={value:String};function ii(){return{type:"Number",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:this.consume(10)}}function uh(e){this.token(10,e.value)}var ai={};x(ai,{generate:()=>mh,name:()=>ph,parse:()=>si,structure:()=>hh});var ph="Operator",hh={value:String};function si(){let e=this.tokenStart;return this.next(),{type:"Operator",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e)}}function mh(e){this.tokenize(e.value)}var ci={};x(ci,{generate:()=>gh,name:()=>fh,parse:()=>li,structure:()=>dh});var fh="Parentheses",dh={children:[[]]};function li(e,t){let r=this.tokenStart,n=null;return this.eat(21),n=e.call(this,t),this.eof||this.eat(22),{type:"Parentheses",loc:this.getLocation(r,this.tokenStart),children:n}}function gh(e){this.token(21,"("),this.children(e),this.token(22,")")}var pi={};x(pi,{generate:()=>yh,name:()=>bh,parse:()=>ui,structure:()=>xh});var bh="Percentage",xh={value:String};function ui(){return{type:"Percentage",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:this.consumeNumber(11)}}function yh(e){this.token(11,e.value+"%")}var mi={};x(mi,{generate:()=>Sh,name:()=>kh,parse:()=>hi,structure:()=>vh,walkContext:()=>wh});var kh="PseudoClassSelector",wh="function",vh={name:String,children:[["Raw"],null]};function hi(){let e=this.tokenStart,t=null,r,n;return this.eat(16),this.tokenType===2?(r=this.consumeFunctionName(),n=r.toLowerCase(),this.lookupNonWSType(0)==22?t=this.createList():hasOwnProperty.call(this.pseudo,n)?(this.skipSC(),t=this.pseudo[n].call(this),this.skipSC()):(t=this.createList(),t.push(this.Raw(null,!1))),this.eat(22)):r=this.consume(1),{type:"PseudoClassSelector",loc:this.getLocation(e,this.tokenStart),name:r,children:t}}function Sh(e){this.token(16,":"),e.children===null?this.token(1,e.name):(this.token(2,e.name+"("),this.children(e),this.token(22,")"))}var di={};x(di,{generate:()=>Lh,name:()=>Ch,parse:()=>fi,structure:()=>Ah,walkContext:()=>Th});var Ch="PseudoElementSelector",Th="function",Ah={name:String,children:[["Raw"],null]};function fi(){let e=this.tokenStart,t=null,r,n;return this.eat(16),this.eat(16),this.tokenType===2?(r=this.consumeFunctionName(),n=r.toLowerCase(),this.lookupNonWSType(0)==22?t=this.createList():hasOwnProperty.call(this.pseudo,n)?(this.skipSC(),t=this.pseudo[n].call(this),this.skipSC()):(t=this.createList(),t.push(this.Raw(null,!1))),this.eat(22)):r=this.consume(1),{type:"PseudoElementSelector",loc:this.getLocation(e,this.tokenStart),name:r,children:t}}function Lh(e){this.token(16,":"),this.token(16,":"),e.children===null?this.token(1,e.name):(this.token(2,e.name+"("),this.children(e),this.token(22,")"))}var bi={};x(bi,{generate:()=>Ph,name:()=>Eh,parse:()=>gi,structure:()=>zh});var Vs=47;function Qs(){switch(this.skipSC(),this.tokenType){case 10:return this.Number();case 2:return this.Function(this.readSequence,this.scope.Value);default:this.error("Number of function is expected")}}var Eh="Ratio",zh={left:["Number","Function"],right:["Number","Function",null]};function gi(){let e=this.tokenStart,t=Qs.call(this),r=null;return this.skipSC(),this.isDelim(Vs)&&(this.eatDelim(Vs),r=Qs.call(this)),{type:"Ratio",loc:this.getLocation(e,this.tokenStart),left:t,right:r}}function Ph(e){this.node(e.left),this.token(9,"/"),e.right?this.node(e.right):this.node(10,1)}var yi={};x(yi,{generate:()=>Oh,name:()=>Dh,parse:()=>xi,structure:()=>Nh});function Ih(){return this.tokenIndex>0&&this.lookupType(-1)===13?this.tokenIndex>1?this.getTokenStart(this.tokenIndex-1):this.firstCharOffset:this.tokenStart}var Dh="Raw",Nh={value:String};function xi(e,t){let r=this.getTokenStart(this.tokenIndex),n;return this.skipUntilBalanced(this.tokenIndex,e||this.consumeUntilBalanceEnd),t&&this.tokenStart>r?n=Ih.call(this):n=this.tokenStart,{type:"Raw",loc:this.getLocation(r,n),value:this.substring(r,n)}}function Oh(e){this.tokenize(e.value)}var wi={};x(wi,{generate:()=>_h,name:()=>Rh,parse:()=>ki,structure:()=>Bh,walkContext:()=>Mh});function Xs(){return this.Raw(this.consumeUntilLeftCurlyBracket,!0)}function Fh(){let e=this.SelectorList();return e.type!=="Raw"&&this.eof===!1&&this.tokenType!==23&&this.error(),e}var Rh="Rule",Mh="rule",Bh={prelude:["SelectorList","Raw"],block:["Block"]};function ki(){let e=this.tokenIndex,t=this.tokenStart,r,n;return this.parseRulePrelude?r=this.parseWithFallback(Fh,Xs):r=Xs.call(this,e),n=this.Block(!0),{type:"Rule",loc:this.getLocation(t,this.tokenStart),prelude:r,block:n}}function _h(e){this.node(e.prelude),this.node(e.block)}var Si={};x(Si,{generate:()=>qh,name:()=>Wh,parse:()=>vi,structure:()=>jh});var Wh="Scope",jh={root:["SelectorList","Raw",null],limit:["SelectorList","Raw",null]};function vi(){let e=null,t=null;this.skipSC();let r=this.tokenStart;return this.tokenType===21&&(this.next(),this.skipSC(),e=this.parseWithFallback(this.SelectorList,()=>this.Raw(!1,!0)),this.skipSC(),this.eat(22)),this.lookupNonWSType(0)===1&&(this.skipSC(),this.eatIdent("to"),this.skipSC(),this.eat(21),this.skipSC(),t=this.parseWithFallback(this.SelectorList,()=>this.Raw(!1,!0)),this.skipSC(),this.eat(22)),{type:"Scope",loc:this.getLocation(r,this.tokenStart),root:e,limit:t}}function qh(e){e.root&&(this.token(21,"("),this.node(e.root),this.token(22,")")),e.limit&&(this.token(1,"to"),this.token(21,"("),this.node(e.limit),this.token(22,")"))}var Ti={};x(Ti,{generate:()=>Gh,name:()=>Uh,parse:()=>Ci,structure:()=>Hh});var Uh="Selector",Hh={children:[["TypeSelector","IdSelector","ClassSelector","AttributeSelector","PseudoClassSelector","PseudoElementSelector","Combinator"]]};function Ci(){let e=this.readSequence(this.scope.Selector);return this.getFirstListNode(e)===null&&this.error("Selector is expected"),{type:"Selector",loc:this.getLocationFromList(e),children:e}}function Gh(e){this.children(e)}var Li={};x(Li,{generate:()=>Qh,name:()=>Yh,parse:()=>Ai,structure:()=>Vh,walkContext:()=>Kh});var Yh="SelectorList",Kh="selector",Vh={children:[["Selector","Raw"]]};function Ai(){let e=this.createList();for(;!this.eof;){if(e.push(this.Selector()),this.tokenType===18){this.next();continue}break}return{type:"SelectorList",loc:this.getLocationFromList(e),children:e}}function Qh(e){this.children(e,()=>this.token(18,","))}var Di={};x(Di,{generate:()=>Zh,name:()=>Xh,parse:()=>Ii,structure:()=>$h});var Pi={};x(Pi,{decode:()=>wt,encode:()=>zi});var Ei=92,$s=34,Zs=39;function wt(e){let t=e.length,r=e.charCodeAt(0),n=r===$s||r===Zs?1:0,i=n===1&&t>1&&e.charCodeAt(t-1)===r?t-2:t-1,o="";for(let a=n;a<=i;a++){let u=e.charCodeAt(a);if(u===Ei){if(a===i){a!==t-1&&(o=e.substr(a+1));break}if(u=e.charCodeAt(++a),$(Ei,u)){let l=a-1,s=ae(e,l);a=s-1,o+=We(e.substring(l+1,s))}else u===13&&e.charCodeAt(a+1)===10&&a++}else o+=e[a]}return o}function zi(e,t){let r=t?"'":'"',n=t?Zs:$s,i="",o=!1;for(let a=0;a<e.length;a++){let u=e.charCodeAt(a);if(u===0){i+="\uFFFD";continue}if(u<=31||u===127){i+="\\"+u.toString(16),o=!0;continue}u===n||u===Ei?(i+="\\"+e.charAt(a),o=!1):(o&&(te(u)||pe(u))&&(i+=" "),i+=e.charAt(a),o=!1)}return r+i+r}var Xh="String",$h={value:String};function Ii(){return{type:"String",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:wt(this.consume(5))}}function Zh(e){this.token(5,zi(e.value))}var Oi={};x(Oi,{generate:()=>nm,name:()=>em,parse:()=>Ni,structure:()=>rm,walkContext:()=>tm});var Jh=33;function Js(){return this.Raw(null,!1)}var em="StyleSheet",tm="stylesheet",rm={children:[["Comment","CDO","CDC","Atrule","Rule","Raw"]]};function Ni(){let e=this.tokenStart,t=this.createList(),r;for(;!this.eof;){switch(this.tokenType){case 13:this.next();continue;case 25:if(this.charCodeAt(this.tokenStart+2)!==Jh){this.next();continue}r=this.Comment();break;case 14:r=this.CDO();break;case 15:r=this.CDC();break;case 3:r=this.parseWithFallback(this.Atrule,Js);break;default:r=this.parseWithFallback(this.Rule,Js)}t.push(r)}return{type:"StyleSheet",loc:this.getLocation(e,this.tokenStart),children:t}}function nm(e){this.children(e)}var Ri={};x(Ri,{generate:()=>sm,name:()=>im,parse:()=>Fi,structure:()=>om});var im="SupportsDeclaration",om={declaration:"Declaration"};function Fi(){let e=this.tokenStart;this.eat(21),this.skipSC();let t=this.Declaration();return this.eof||this.eat(22),{type:"SupportsDeclaration",loc:this.getLocation(e,this.tokenStart),declaration:t}}function sm(e){this.token(21,"("),this.node(e.declaration),this.token(22,")")}var _i={};x(_i,{generate:()=>um,name:()=>lm,parse:()=>Bi,structure:()=>cm});var am=42,ea=124;function Mi(){this.tokenType!==1&&this.isDelim(am)===!1&&this.error("Identifier or asterisk is expected"),this.next()}var lm="TypeSelector",cm={name:String};function Bi(){let e=this.tokenStart;return this.isDelim(ea)?(this.next(),Mi.call(this)):(Mi.call(this),this.isDelim(ea)&&(this.next(),Mi.call(this))),{type:"TypeSelector",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e)}}function um(e){this.tokenize(e.name)}var qi={};x(qi,{generate:()=>dm,name:()=>mm,parse:()=>ji,structure:()=>fm});var ta=43,ra=45,Wi=63;function vt(e,t){let r=0;for(let n=this.tokenStart+e;n<this.tokenEnd;n++){let i=this.charCodeAt(n);if(i===ra&&t&&r!==0)return vt.call(this,e+r+1,!1),-1;te(i)||this.error(t&&r!==0?"Hyphen minus"+(r<6?" or hex digit":"")+" is expected":r<6?"Hex digit is expected":"Unexpected input",n),++r>6&&this.error("Too many hex digits",n)}return this.next(),r}function tr(e){let t=0;for(;this.isDelim(Wi);)++t>e&&this.error("Too many question marks"),this.next()}function pm(e){this.charCodeAt(this.tokenStart)!==e&&this.error((e===ta?"Plus sign":"Hyphen minus")+" is expected")}function hm(){let e=0;switch(this.tokenType){case 10:if(e=vt.call(this,1,!0),this.isDelim(Wi)){tr.call(this,6-e);break}if(this.tokenType===12||this.tokenType===10){pm.call(this,ra),vt.call(this,1,!1);break}break;case 12:e=vt.call(this,1,!0),e>0&&tr.call(this,6-e);break;default:if(this.eatDelim(ta),this.tokenType===1){e=vt.call(this,0,!0),e>0&&tr.call(this,6-e);break}if(this.isDelim(Wi)){this.next(),tr.call(this,5);break}this.error("Hex digit or question mark is expected")}}var mm="UnicodeRange",fm={value:String};function ji(){let e=this.tokenStart;return this.eatIdent("u"),hm.call(this),{type:"UnicodeRange",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e)}}function dm(e){this.tokenize(e.value)}var Vi={};x(Vi,{generate:()=>vm,name:()=>km,parse:()=>Ki,structure:()=>wm});var Yi={};x(Yi,{decode:()=>Hi,encode:()=>Gi});var gm=32,Ui=92,bm=34,xm=39,ym=40,na=41;function Hi(e){let t=e.length,r=4,n=e.charCodeAt(t-1)===na?t-2:t-1,i="";for(;r<n&&pe(e.charCodeAt(r));)r++;for(;r<n&&pe(e.charCodeAt(n));)n--;for(let o=r;o<=n;o++){let a=e.charCodeAt(o);if(a===Ui){if(o===n){o!==t-1&&(i=e.substr(o+1));break}if(a=e.charCodeAt(++o),$(Ui,a)){let u=o-1,l=ae(e,u);o=l-1,i+=We(e.substring(u+1,l))}else a===13&&e.charCodeAt(o+1)===10&&o++}else i+=e[o]}return i}function Gi(e){let t="",r=!1;for(let n=0;n<e.length;n++){let i=e.charCodeAt(n);if(i===0){t+="\uFFFD";continue}if(i<=31||i===127){t+="\\"+i.toString(16),r=!0;continue}i===gm||i===Ui||i===bm||i===xm||i===ym||i===na?(t+="\\"+e.charAt(n),r=!1):(r&&te(i)&&(t+=" "),t+=e.charAt(n),r=!1)}return"url("+t+")"}var km="Url",wm={value:String};function Ki(){let e=this.tokenStart,t;switch(this.tokenType){case 7:t=Hi(this.consume(7));break;case 2:this.cmpStr(this.tokenStart,this.tokenEnd,"url(")||this.error("Function name must be `url`"),this.eat(2),this.skipSC(),t=wt(this.consume(5)),this.skipSC(),this.eof||this.eat(22);break;default:this.error("Url or Function is expected")}return{type:"Url",loc:this.getLocation(e,this.tokenStart),value:t}}function vm(e){this.token(7,Gi(e.value))}var Xi={};x(Xi,{generate:()=>Tm,name:()=>Sm,parse:()=>Qi,structure:()=>Cm});var Sm="Value",Cm={children:[[]]};function Qi(){let e=this.tokenStart,t=this.readSequence(this.scope.Value);return{type:"Value",loc:this.getLocation(e,this.tokenStart),children:t}}function Tm(e){this.children(e)}var Zi={};x(Zi,{generate:()=>zm,name:()=>Lm,parse:()=>$i,structure:()=>Em});var Am=Object.freeze({type:"WhiteSpace",loc:null,value:" "}),Lm="WhiteSpace",Em={value:String};function $i(){return this.eat(13),Am}function zm(e){this.token(13,e.value)}var ia={generic:!0,cssWideKeywords:Ke,...Fs,node:St};var Ji={};x(Ji,{AtrulePrelude:()=>sa,Selector:()=>la,Value:()=>ha});var Pm=35,Im=42,oa=43,Dm=45,Nm=47,Om=117;function Ct(e){switch(this.tokenType){case 4:return this.Hash();case 18:return this.Operator();case 21:return this.Parentheses(this.readSequence,e.recognizer);case 19:return this.Brackets(this.readSequence,e.recognizer);case 5:return this.String();case 12:return this.Dimension();case 11:return this.Percentage();case 10:return this.Number();case 2:return this.cmpStr(this.tokenStart,this.tokenEnd,"url(")?this.Url():this.Function(this.readSequence,e.recognizer);case 7:return this.Url();case 1:return this.cmpChar(this.tokenStart,Om)&&this.cmpChar(this.tokenStart+1,oa)?this.UnicodeRange():this.Identifier();case 9:{let t=this.charCodeAt(this.tokenStart);if(t===Nm||t===Im||t===oa||t===Dm)return this.Operator();t===Pm&&this.error("Hex or identifier is expected",this.tokenStart+1);break}}}var sa={getNode:Ct};var Fm=35,Rm=38,Mm=42,Bm=43,_m=47,aa=46,Wm=62,jm=124,qm=126;function Um(e,t){t.last!==null&&t.last.type!=="Combinator"&&e!==null&&e.type!=="Combinator"&&t.push({type:"Combinator",loc:null,name:" "})}function Hm(){switch(this.tokenType){case 19:return this.AttributeSelector();case 4:return this.IdSelector();case 16:return this.lookupType(1)===16?this.PseudoElementSelector():this.PseudoClassSelector();case 1:return this.TypeSelector();case 10:case 11:return this.Percentage();case 12:this.charCodeAt(this.tokenStart)===aa&&this.error("Identifier is expected",this.tokenStart+1);break;case 9:{switch(this.charCodeAt(this.tokenStart)){case Bm:case Wm:case qm:case _m:return this.Combinator();case aa:return this.ClassSelector();case Mm:case jm:return this.TypeSelector();case Fm:return this.IdSelector();case Rm:return this.NestingSelector()}break}}}var la={onWhiteSpace:Um,getNode:Hm};function ca(){return this.createSingleNodeList(this.Raw(null,!1))}function ua(){let e=this.createList();if(this.skipSC(),e.push(this.Identifier()),this.skipSC(),this.tokenType===18){e.push(this.Operator());let t=this.tokenIndex,r=this.parseCustomProperty?this.Value(null):this.Raw(this.consumeUntilExclamationMarkOrSemicolon,!1);if(r.type==="Value"&&r.children.isEmpty){for(let n=t-this.tokenIndex;n<=0;n++)if(this.lookupType(n)===13){r.children.appendData({type:"WhiteSpace",loc:null,value:" "});break}}e.push(r)}return e}function pa(e){return e!==null&&e.type==="Operator"&&(e.value[e.value.length-1]==="-"||e.value[e.value.length-1]==="+")}var ha={getNode:Ct,onWhiteSpace(e,t){pa(e)&&(e.value=" "+e.value),pa(t.last)&&(t.last.value+=" ")},expression:ca,var:ua};var Gm=new Set(["none","and","not","or"]),ma={parse:{prelude(){let e=this.createList();if(this.tokenType===1){let t=this.substring(this.tokenStart,this.tokenEnd);Gm.has(t.toLowerCase())||e.push(this.Identifier())}return e.push(this.Condition("container")),e},block(e=!1){return this.Block(e)}}};var fa={parse:{prelude:null,block(){return this.Block(!0)}}};function eo(e,t){return this.parseWithFallback(()=>{try{return e.call(this)}finally{this.skipSC(),this.lookupNonWSType(0)!==22&&this.error()}},t||(()=>this.Raw(null,!0)))}var da={layer(){this.skipSC();let e=this.createList(),t=eo.call(this,this.Layer);return(t.type!=="Raw"||t.value!=="")&&e.push(t),e},supports(){this.skipSC();let e=this.createList(),t=eo.call(this,this.Declaration,()=>eo.call(this,()=>this.Condition("supports")));return(t.type!=="Raw"||t.value!=="")&&e.push(t),e}},ga={parse:{prelude(){let e=this.createList();switch(this.tokenType){case 5:e.push(this.String());break;case 7:case 2:e.push(this.Url());break;default:this.error("String or url() is expected")}return this.skipSC(),this.tokenType===1&&this.cmpStr(this.tokenStart,this.tokenEnd,"layer")?e.push(this.Identifier()):this.tokenType===2&&this.cmpStr(this.tokenStart,this.tokenEnd,"layer(")&&e.push(this.Function(null,da)),this.skipSC(),this.tokenType===2&&this.cmpStr(this.tokenStart,this.tokenEnd,"supports(")&&e.push(this.Function(null,da)),(this.lookupNonWSType(0)===1||this.lookupNonWSType(0)===21)&&e.push(this.MediaQueryList()),e},block:null}};var ba={parse:{prelude(){return this.createSingleNodeList(this.LayerList())},block(){return this.Block(!1)}}};var xa={parse:{prelude(){return this.createSingleNodeList(this.MediaQueryList())},block(e=!1){return this.Block(e)}}};var ya={parse:{prelude(){return this.createSingleNodeList(this.SelectorList())},block(){return this.Block(!0)}}};var ka={parse:{prelude(){return this.createSingleNodeList(this.SelectorList())},block(){return this.Block(!0)}}};var wa={parse:{prelude(){return this.createSingleNodeList(this.Scope())},block(e=!1){return this.Block(e)}}};var va={parse:{prelude:null,block(e=!1){return this.Block(e)}}};var Sa={parse:{prelude(){return this.createSingleNodeList(this.Condition("supports"))},block(e=!1){return this.Block(e)}}};var Ca={container:ma,"font-face":fa,import:ga,layer:ba,media:xa,nest:ya,page:ka,scope:wa,"starting-style":va,supports:Sa};function Ta(){let e=this.createList();this.skipSC();e:for(;!this.eof;){switch(this.tokenType){case 1:e.push(this.Identifier());break;case 5:e.push(this.String());break;case 18:e.push(this.Operator());break;case 22:break e;default:this.error("Identifier, string or comma is expected")}this.skipSC()}return e}var Fe={parse(){return this.createSingleNodeList(this.SelectorList())}},to={parse(){return this.createSingleNodeList(this.Selector())}},Ym={parse(){return this.createSingleNodeList(this.Identifier())}},Km={parse:Ta},rr={parse(){return this.createSingleNodeList(this.Nth())}},Aa={dir:Ym,has:Fe,lang:Km,matches:Fe,is:Fe,"-moz-any":Fe,"-webkit-any":Fe,where:Fe,not:Fe,"nth-child":rr,"nth-last-child":rr,"nth-last-of-type":rr,"nth-of-type":rr,slotted:to,host:to,"host-context":to};var ro={};x(ro,{AnPlusB:()=>Xr,Atrule:()=>Zr,AtrulePrelude:()=>en,AttributeSelector:()=>nn,Block:()=>sn,Brackets:()=>ln,CDC:()=>un,CDO:()=>hn,ClassSelector:()=>fn,Combinator:()=>gn,Comment:()=>xn,Condition:()=>kn,Declaration:()=>vn,DeclarationList:()=>Tn,Dimension:()=>Ln,Feature:()=>zn,FeatureFunction:()=>In,FeatureRange:()=>On,Function:()=>Rn,GeneralEnclosed:()=>Bn,Hash:()=>Wn,IdSelector:()=>Hn,Identifier:()=>qn,Layer:()=>Yn,LayerList:()=>Vn,MediaQuery:()=>Xn,MediaQueryList:()=>Zn,NestingSelector:()=>ei,Nth:()=>ri,Number:()=>ii,Operator:()=>si,Parentheses:()=>li,Percentage:()=>ui,PseudoClassSelector:()=>hi,PseudoElementSelector:()=>fi,Ratio:()=>gi,Raw:()=>xi,Rule:()=>ki,Scope:()=>vi,Selector:()=>Ci,SelectorList:()=>Ai,String:()=>Ii,StyleSheet:()=>Ni,SupportsDeclaration:()=>Fi,TypeSelector:()=>Bi,UnicodeRange:()=>ji,Url:()=>Ki,Value:()=>Qi,WhiteSpace:()=>$i});var La={parseContext:{default:"StyleSheet",stylesheet:"StyleSheet",atrule:"Atrule",atrulePrelude(e){return this.AtrulePrelude(e.atrule?String(e.atrule):null)},mediaQueryList:"MediaQueryList",mediaQuery:"MediaQuery",condition(e){return this.Condition(e.kind)},rule:"Rule",selectorList:"SelectorList",selector:"Selector",block(){return this.Block(!0)},declarationList:"DeclarationList",declaration:"Declaration",value:"Value"},features:{supports:{selector(){return this.Selector()}},container:{style(){return this.Declaration()}}},scope:Ji,atrule:Ca,pseudo:Aa,node:ro};var Ea={node:St};var za=Vr({...ia,...La,...Ea});var Wx="3.0.1";function no(e){let t={};for(let r of Object.keys(e)){let n=e[r];n&&(Array.isArray(n)||n instanceof Z?n=n.map(no):n.constructor===Object&&(n=no(n))),t[r]=n}return t}var Ia={};x(Ia,{decode:()=>Vm,encode:()=>Qm});var Pa=92;function Vm(e){let t=e.length-1,r="";for(let n=0;n<e.length;n++){let i=e.charCodeAt(n);if(i===Pa){if(n===t)break;if(i=e.charCodeAt(++n),$(Pa,i)){let o=n-1,a=ae(e,o);n=a-1,r+=We(e.substring(o+1,a))}else i===13&&e.charCodeAt(n+1)===10&&n++}else r+=e[n]}return r}function Qm(e){let t="";if(e.length===1&&e.charCodeAt(0)===45)return"\\-";for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);if(n===0){t+="\uFFFD";continue}if(n<=31||n===127||n>=48&&n<=57&&(r===0||r===1&&e.charCodeAt(0)===45)){t+="\\"+n.toString(16)+" ";continue}Me(n)?t+=e.charAt(r):t+="\\"+e.charAt(r)}return t}var{tokenize:Yx,parse:Kx,generate:Vx,lexer:Qx,createLexer:Xx,walk:$x,find:Zx,findLast:Jx,findAll:ey,toPlainObject:ty,fromPlainObject:ry,fork:ny}=za;export{Ze as Lexer,Z as List,ot as OffsetToLocation,st as TokenStream,no as clone,Xx as createLexer,Vr as createSyntax,bs as definitionSyntax,Zx as find,ey as findAll,Jx as findLast,ny as fork,ry as fromPlainObject,Vx as generate,Ia as ident,qt as isCustomProperty,jt as keyword,Qx as lexer,Kx as parse,wr as property,Pi as string,ty as toPlainObject,je as tokenNames,et as tokenTypes,Yx as tokenize,Yi as url,Xf as vendorPrefix,Wx as version,$x as walk}; diff --git a/vanilla/node_modules/css-tree/dist/csstree.js b/vanilla/node_modules/css-tree/dist/csstree.js new file mode 100644 index 0000000..e1eeb5c --- /dev/null +++ b/vanilla/node_modules/css-tree/dist/csstree.js @@ -0,0 +1,12 @@ +var csstree=(()=>{var Na=Object.create;var Lt=Object.defineProperty;var Oa=Object.getOwnPropertyDescriptor;var Fa=Object.getOwnPropertyNames;var Ra=Object.getPrototypeOf,Ma=Object.prototype.hasOwnProperty;var Be=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),x=(e,t)=>{for(var r in t)Lt(e,r,{get:t[r],enumerable:!0})},so=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Fa(t))!Ma.call(e,i)&&i!==r&&Lt(e,i,{get:()=>t[i],enumerable:!(n=Oa(t,i))||n.enumerable});return e};var Ba=(e,t,r)=>(r=e!=null?Na(Ra(e)):{},so(t||!e||!e.__esModule?Lt(r,"default",{value:e,enumerable:!0}):r,e)),_a=e=>so(Lt({},"__esModule",{value:!0}),e);var vo=Be(br=>{var wo="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");br.encode=function(e){if(0<=e&&e<wo.length)return wo[e];throw new TypeError("Must be between 0 and 63: "+e)};br.decode=function(e){var t=65,r=90,n=97,i=122,o=48,a=57,u=43,l=47,s=26,c=52;return t<=e&&e<=r?e-t:n<=e&&e<=i?e-n+s:o<=e&&e<=a?e-o+c:e==u?62:e==l?63:-1}});var Lo=Be(yr=>{var So=vo(),xr=5,Co=1<<xr,To=Co-1,Ao=Co;function Xa(e){return e<0?(-e<<1)+1:(e<<1)+0}function $a(e){var t=(e&1)===1,r=e>>1;return t?-r:r}yr.encode=function(t){var r="",n,i=Xa(t);do n=i&To,i>>>=xr,i>0&&(n|=Ao),r+=So.encode(n);while(i>0);return r};yr.decode=function(t,r,n){var i=t.length,o=0,a=0,u,l;do{if(r>=i)throw new Error("Expected more digits in base 64 VLQ value.");if(l=So.decode(t.charCodeAt(r++)),l===-1)throw new Error("Invalid base64 digit: "+t.charAt(r-1));u=!!(l&Ao),l&=To,o=o+(l<<a),a+=xr}while(u);n.value=$a(o),n.rest=r}});var Rt=Be(V=>{function Za(e,t,r){if(t in e)return e[t];if(arguments.length===3)return r;throw new Error('"'+t+'" is a required argument.')}V.getArg=Za;var Eo=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,Ja=/^data:.+\,.+$/;function at(e){var t=e.match(Eo);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}V.urlParse=at;function Ve(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}V.urlGenerate=Ve;var el=32;function tl(e){var t=[];return function(r){for(var n=0;n<t.length;n++)if(t[n].input===r){var i=t[0];return t[0]=t[n],t[n]=i,t[0].result}var o=e(r);return t.unshift({input:r,result:o}),t.length>el&&t.pop(),o}}var kr=tl(function(t){var r=t,n=at(t);if(n){if(!n.path)return t;r=n.path}for(var i=V.isAbsolute(r),o=[],a=0,u=0;;)if(a=u,u=r.indexOf("/",a),u===-1){o.push(r.slice(a));break}else for(o.push(r.slice(a,u));u<r.length&&r[u]==="/";)u++;for(var l,s=0,u=o.length-1;u>=0;u--)l=o[u],l==="."?o.splice(u,1):l===".."?s++:s>0&&(l===""?(o.splice(u+1,s),s=0):(o.splice(u,2),s--));return r=o.join("/"),r===""&&(r=i?"/":"."),n?(n.path=r,Ve(n)):r});V.normalize=kr;function zo(e,t){e===""&&(e="."),t===""&&(t=".");var r=at(t),n=at(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),Ve(r);if(r||t.match(Ja))return t;if(n&&!n.host&&!n.path)return n.host=t,Ve(n);var i=t.charAt(0)==="/"?t:kr(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=i,Ve(n)):i}V.join=zo;V.isAbsolute=function(e){return e.charAt(0)==="/"||Eo.test(e)};function rl(e,t){e===""&&(e="."),e=e.replace(/\/$/,"");for(var r=0;t.indexOf(e+"/")!==0;){var n=e.lastIndexOf("/");if(n<0||(e=e.slice(0,n),e.match(/^([^\/]+:\/)?\/*$/)))return t;++r}return Array(r+1).join("../")+t.substr(e.length+1)}V.relative=rl;var Po=function(){var e=Object.create(null);return!("__proto__"in e)}();function Io(e){return e}function nl(e){return Do(e)?"$"+e:e}V.toSetString=Po?Io:nl;function il(e){return Do(e)?e.slice(1):e}V.fromSetString=Po?Io:il;function Do(e){if(!e)return!1;var t=e.length;if(t<9||e.charCodeAt(t-1)!==95||e.charCodeAt(t-2)!==95||e.charCodeAt(t-3)!==111||e.charCodeAt(t-4)!==116||e.charCodeAt(t-5)!==111||e.charCodeAt(t-6)!==114||e.charCodeAt(t-7)!==112||e.charCodeAt(t-8)!==95||e.charCodeAt(t-9)!==95)return!1;for(var r=t-10;r>=0;r--)if(e.charCodeAt(r)!==36)return!1;return!0}function ol(e,t,r){var n=ye(e.source,t.source);return n!==0||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:ye(e.name,t.name)}V.compareByOriginalPositions=ol;function sl(e,t,r){var n;return n=e.originalLine-t.originalLine,n!==0||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:ye(e.name,t.name)}V.compareByOriginalPositionsNoSource=sl;function al(e,t,r){var n=e.generatedLine-t.generatedLine;return n!==0||(n=e.generatedColumn-t.generatedColumn,n!==0||r)||(n=ye(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:ye(e.name,t.name)}V.compareByGeneratedPositionsDeflated=al;function ll(e,t,r){var n=e.generatedColumn-t.generatedColumn;return n!==0||r||(n=ye(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:ye(e.name,t.name)}V.compareByGeneratedPositionsDeflatedNoLine=ll;function ye(e,t){return e===t?0:e===null?1:t===null?-1:e>t?1:-1}function cl(e,t){var r=e.generatedLine-t.generatedLine;return r!==0||(r=e.generatedColumn-t.generatedColumn,r!==0)||(r=ye(e.source,t.source),r!==0)||(r=e.originalLine-t.originalLine,r!==0)||(r=e.originalColumn-t.originalColumn,r!==0)?r:ye(e.name,t.name)}V.compareByGeneratedPositionsInflated=cl;function ul(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}V.parseSourceMapInput=ul;function pl(e,t,r){if(t=t||"",e&&(e[e.length-1]!=="/"&&t[0]!=="/"&&(e+="/"),t=e+t),r){var n=at(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var i=n.path.lastIndexOf("/");i>=0&&(n.path=n.path.substring(0,i+1))}t=zo(Ve(n),t)}return kr(t)}V.computeSourceURL=pl});var Oo=Be(No=>{var wr=Rt(),vr=Object.prototype.hasOwnProperty,Ne=typeof Map<"u";function ke(){this._array=[],this._set=Ne?new Map:Object.create(null)}ke.fromArray=function(t,r){for(var n=new ke,i=0,o=t.length;i<o;i++)n.add(t[i],r);return n};ke.prototype.size=function(){return Ne?this._set.size:Object.getOwnPropertyNames(this._set).length};ke.prototype.add=function(t,r){var n=Ne?t:wr.toSetString(t),i=Ne?this.has(t):vr.call(this._set,n),o=this._array.length;(!i||r)&&this._array.push(t),i||(Ne?this._set.set(t,o):this._set[n]=o)};ke.prototype.has=function(t){if(Ne)return this._set.has(t);var r=wr.toSetString(t);return vr.call(this._set,r)};ke.prototype.indexOf=function(t){if(Ne){var r=this._set.get(t);if(r>=0)return r}else{var n=wr.toSetString(t);if(vr.call(this._set,n))return this._set[n]}throw new Error('"'+t+'" is not in the set.')};ke.prototype.at=function(t){if(t>=0&&t<this._array.length)return this._array[t];throw new Error("No element indexed by "+t)};ke.prototype.toArray=function(){return this._array.slice()};No.ArraySet=ke});var Mo=Be(Ro=>{var Fo=Rt();function hl(e,t){var r=e.generatedLine,n=t.generatedLine,i=e.generatedColumn,o=t.generatedColumn;return n>r||n==r&&o>=i||Fo.compareByGeneratedPositionsInflated(e,t)<=0}function Mt(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}Mt.prototype.unsortedForEach=function(t,r){this._array.forEach(t,r)};Mt.prototype.add=function(t){hl(this._last,t)?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t))};Mt.prototype.toArray=function(){return this._sorted||(this._array.sort(Fo.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};Ro.MappingList=Mt});var _o=Be(Bo=>{var lt=Lo(),U=Rt(),Bt=Oo().ArraySet,ml=Mo().MappingList;function ie(e){e||(e={}),this._file=U.getArg(e,"file",null),this._sourceRoot=U.getArg(e,"sourceRoot",null),this._skipValidation=U.getArg(e,"skipValidation",!1),this._sources=new Bt,this._names=new Bt,this._mappings=new ml,this._sourcesContents=null}ie.prototype._version=3;ie.fromSourceMap=function(t){var r=t.sourceRoot,n=new ie({file:t.file,sourceRoot:r});return t.eachMapping(function(i){var o={generated:{line:i.generatedLine,column:i.generatedColumn}};i.source!=null&&(o.source=i.source,r!=null&&(o.source=U.relative(r,o.source)),o.original={line:i.originalLine,column:i.originalColumn},i.name!=null&&(o.name=i.name)),n.addMapping(o)}),t.sources.forEach(function(i){var o=i;r!==null&&(o=U.relative(r,i)),n._sources.has(o)||n._sources.add(o);var a=t.sourceContentFor(i);a!=null&&n.setSourceContent(i,a)}),n};ie.prototype.addMapping=function(t){var r=U.getArg(t,"generated"),n=U.getArg(t,"original",null),i=U.getArg(t,"source",null),o=U.getArg(t,"name",null);this._skipValidation||this._validateMapping(r,n,i,o),i!=null&&(i=String(i),this._sources.has(i)||this._sources.add(i)),o!=null&&(o=String(o),this._names.has(o)||this._names.add(o)),this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:i,name:o})};ie.prototype.setSourceContent=function(t,r){var n=t;this._sourceRoot!=null&&(n=U.relative(this._sourceRoot,n)),r!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[U.toSetString(n)]=r):this._sourcesContents&&(delete this._sourcesContents[U.toSetString(n)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))};ie.prototype.applySourceMap=function(t,r,n){var i=r;if(r==null){if(t.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);i=t.file}var o=this._sourceRoot;o!=null&&(i=U.relative(o,i));var a=new Bt,u=new Bt;this._mappings.unsortedForEach(function(l){if(l.source===i&&l.originalLine!=null){var s=t.originalPositionFor({line:l.originalLine,column:l.originalColumn});s.source!=null&&(l.source=s.source,n!=null&&(l.source=U.join(n,l.source)),o!=null&&(l.source=U.relative(o,l.source)),l.originalLine=s.line,l.originalColumn=s.column,s.name!=null&&(l.name=s.name))}var c=l.source;c!=null&&!a.has(c)&&a.add(c);var h=l.name;h!=null&&!u.has(h)&&u.add(h)},this),this._sources=a,this._names=u,t.sources.forEach(function(l){var s=t.sourceContentFor(l);s!=null&&(n!=null&&(l=U.join(n,l)),o!=null&&(l=U.relative(o,l)),this.setSourceContent(l,s))},this)};ie.prototype._validateMapping=function(t,r,n,i){if(r&&typeof r.line!="number"&&typeof r.column!="number")throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!r&&!n&&!i)){if(t&&"line"in t&&"column"in t&&r&&"line"in r&&"column"in r&&t.line>0&&t.column>=0&&r.line>0&&r.column>=0&&n)return;throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:n,original:r,name:i}))}};ie.prototype._serializeMappings=function(){for(var t=0,r=1,n=0,i=0,o=0,a=0,u="",l,s,c,h,m=this._mappings.toArray(),f=0,w=m.length;f<w;f++){if(s=m[f],l="",s.generatedLine!==r)for(t=0;s.generatedLine!==r;)l+=";",r++;else if(f>0){if(!U.compareByGeneratedPositionsInflated(s,m[f-1]))continue;l+=","}l+=lt.encode(s.generatedColumn-t),t=s.generatedColumn,s.source!=null&&(h=this._sources.indexOf(s.source),l+=lt.encode(h-a),a=h,l+=lt.encode(s.originalLine-1-i),i=s.originalLine-1,l+=lt.encode(s.originalColumn-n),n=s.originalColumn,s.name!=null&&(c=this._names.indexOf(s.name),l+=lt.encode(c-o),o=c)),u+=l}return u};ie.prototype._generateSourcesContent=function(t,r){return t.map(function(n){if(!this._sourcesContents)return null;r!=null&&(n=U.relative(r,n));var i=U.toSetString(n);return Object.prototype.hasOwnProperty.call(this._sourcesContents,i)?this._sourcesContents[i]:null},this)};ie.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(t.file=this._file),this._sourceRoot!=null&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t};ie.prototype.toString=function(){return JSON.stringify(this.toJSON())};Bo.SourceMapGenerator=ie});var hf={};x(hf,{Lexer:()=>Fe,List:()=>X,OffsetToLocation:()=>Ge,TokenStream:()=>Ye,clone:()=>lr,createLexer:()=>nf,createSyntax:()=>er,definitionSyntax:()=>qr,find:()=>sf,findAll:()=>lf,findLast:()=>af,fork:()=>pf,fromPlainObject:()=>uf,generate:()=>tf,ident:()=>oo,isCustomProperty:()=>ht,keyword:()=>pt,lexer:()=>rf,parse:()=>ef,property:()=>Ht,string:()=>ir,toPlainObject:()=>cf,tokenNames:()=>Pe,tokenTypes:()=>_e,tokenize:()=>Jm,url:()=>sr,vendorPrefix:()=>El,version:()=>Xm,walk:()=>of});var _e={};x(_e,{AtKeyword:()=>P,BadString:()=>Ee,BadUrl:()=>Y,CDC:()=>q,CDO:()=>ue,Colon:()=>D,Comma:()=>R,Comment:()=>E,Delim:()=>y,Dimension:()=>k,EOF:()=>ne,Function:()=>g,Hash:()=>T,Ident:()=>p,LeftCurlyBracket:()=>I,LeftParenthesis:()=>v,LeftSquareBracket:()=>W,Number:()=>b,Percentage:()=>L,RightCurlyBracket:()=>H,RightParenthesis:()=>d,RightSquareBracket:()=>K,Semicolon:()=>F,String:()=>_,Url:()=>B,WhiteSpace:()=>S});var ne=0,p=1,g=2,P=3,T=4,_=5,Ee=6,B=7,Y=8,y=9,b=10,L=11,k=12,S=13,ue=14,q=15,D=16,F=17,R=18,W=19,K=20,v=21,d=22,I=23,H=24,E=25;function j(e){return e>=48&&e<=57}function te(e){return j(e)||e>=65&&e<=70||e>=97&&e<=102}function zt(e){return e>=65&&e<=90}function Wa(e){return e>=97&&e<=122}function ja(e){return zt(e)||Wa(e)}function qa(e){return e>=128}function Et(e){return ja(e)||qa(e)||e===95}function We(e){return Et(e)||j(e)||e===45}function Ua(e){return e>=0&&e<=8||e===11||e>=14&&e<=31||e===127}function nt(e){return e===10||e===13||e===12}function pe(e){return nt(e)||e===32||e===9}function Z(e,t){return!(e!==92||nt(t)||t===0)}function je(e,t,r){return e===45?Et(t)||t===45||Z(t,r):Et(e)?!0:e===92?Z(e,t):!1}function Pt(e,t,r){return e===43||e===45?j(t)?2:t===46&&j(r)?3:0:e===46?j(t)?2:0:j(e)?1:0}function It(e){return e===65279||e===65534?1:0}var cr=new Array(128),Ha=128,it=130,ur=131,Dt=132,pr=133;for(let e=0;e<cr.length;e++)cr[e]=pe(e)&&it||j(e)&&ur||Et(e)&&Dt||Ua(e)&&pr||e||Ha;function Nt(e){return e<128?cr[e]:Dt}function qe(e,t){return t<e.length?e.charCodeAt(t):0}function Ot(e,t,r){return r===13&&qe(e,t+1)===10?2:1}function be(e,t,r){let n=e.charCodeAt(t);return zt(n)&&(n=n|32),n===r}function xe(e,t,r,n){if(r-t!==n.length||t<0||r>e.length)return!1;for(let i=t;i<r;i++){let o=n.charCodeAt(i-t),a=e.charCodeAt(i);if(zt(a)&&(a=a|32),a!==o)return!1}return!0}function ao(e,t){for(;t>=0&&pe(e.charCodeAt(t));t--);return t+1}function ot(e,t){for(;t<e.length&&pe(e.charCodeAt(t));t++);return t}function hr(e,t){for(;t<e.length&&j(e.charCodeAt(t));t++);return t}function ae(e,t){if(t+=2,te(qe(e,t-1))){for(let n=Math.min(e.length,t+5);t<n&&te(qe(e,t));t++);let r=qe(e,t);pe(r)&&(t+=Ot(e,t,r))}return t}function st(e,t){for(;t<e.length;t++){let r=e.charCodeAt(t);if(!We(r)){if(Z(r,qe(e,t+1))){t=ae(e,t)-1;continue}break}}return t}function ze(e,t){let r=e.charCodeAt(t);if((r===43||r===45)&&(r=e.charCodeAt(t+=1)),j(r)&&(t=hr(e,t+1),r=e.charCodeAt(t)),r===46&&j(e.charCodeAt(t+1))&&(t+=2,t=hr(e,t)),be(e,t,101)){let n=0;r=e.charCodeAt(t+1),(r===45||r===43)&&(n=1,r=e.charCodeAt(t+2)),j(r)&&(t=hr(e,t+1+n+1))}return t}function Ft(e,t){for(;t<e.length;t++){let r=e.charCodeAt(t);if(r===41){t++;break}Z(r,qe(e,t+1))&&(t=ae(e,t))}return t}function Ue(e){if(e.length===1&&!te(e.charCodeAt(0)))return e[0];let t=parseInt(e,16);return(t===0||t>=55296&&t<=57343||t>1114111)&&(t=65533),String.fromCodePoint(t)}var Pe=["EOF-token","ident-token","function-token","at-keyword-token","hash-token","string-token","bad-string-token","url-token","bad-url-token","delim-token","number-token","percentage-token","dimension-token","whitespace-token","CDO-token","CDC-token","colon-token","semicolon-token","comma-token","[-token","]-token","(-token",")-token","{-token","}-token","comment-token"];function He(e=null,t){return e===null||e.length<t?new Uint32Array(Math.max(t+1024,16384)):e}var lo=10,Ga=12,co=13;function uo(e){let t=e.source,r=t.length,n=t.length>0?It(t.charCodeAt(0)):0,i=He(e.lines,r),o=He(e.columns,r),a=e.startLine,u=e.startColumn;for(let l=n;l<r;l++){let s=t.charCodeAt(l);i[l]=a,o[l]=u++,(s===lo||s===co||s===Ga)&&(s===co&&l+1<r&&t.charCodeAt(l+1)===lo&&(l++,i[l]=a,o[l]=u),a++,u=1)}i[r]=a,o[r]=u,e.lines=i,e.columns=o,e.computed=!0}var Ge=class{constructor(t,r,n,i){this.setSource(t,r,n,i),this.lines=null,this.columns=null}setSource(t="",r=0,n=1,i=1){this.source=t,this.startOffset=r,this.startLine=n,this.startColumn=i,this.computed=!1}getLocation(t,r){return this.computed||uo(this),{source:r,offset:this.startOffset+t,line:this.lines[t],column:this.columns[t]}}getLocationRange(t,r,n){return this.computed||uo(this),{source:n,start:{offset:this.startOffset+t,line:this.lines[t],column:this.columns[t]},end:{offset:this.startOffset+r,line:this.lines[r],column:this.columns[r]}}}};var he=16777215,me=24,Ie=new Uint8Array(32);Ie[2]=22;Ie[21]=22;Ie[19]=20;Ie[23]=24;function po(e){return Ie[e]!==0}var Ye=class{constructor(t,r){this.setSource(t,r)}reset(){this.eof=!1,this.tokenIndex=-1,this.tokenType=0,this.tokenStart=this.firstCharOffset,this.tokenEnd=this.firstCharOffset}setSource(t="",r=()=>{}){t=String(t||"");let n=t.length,i=He(this.offsetAndType,t.length+1),o=He(this.balance,t.length+1),a=0,u=-1,l=0,s=t.length;this.offsetAndType=null,this.balance=null,o.fill(0),r(t,(c,h,m)=>{let f=a++;if(i[f]=c<<me|m,u===-1&&(u=h),o[f]=s,c===l){let w=o[s];o[s]=f,s=w,l=Ie[i[w]>>me]}else po(c)&&(s=f,l=Ie[c])}),i[a]=0<<me|n,o[a]=a;for(let c=0;c<a;c++){let h=o[c];if(h<=c){let m=o[h];m!==c&&(o[c]=m)}else h>a&&(o[c]=a)}this.source=t,this.firstCharOffset=u===-1?0:u,this.tokenCount=a,this.offsetAndType=i,this.balance=o,this.reset(),this.next()}lookupType(t){return t+=this.tokenIndex,t<this.tokenCount?this.offsetAndType[t]>>me:0}lookupTypeNonSC(t){for(let r=this.tokenIndex;r<this.tokenCount;r++){let n=this.offsetAndType[r]>>me;if(n!==13&&n!==25&&t--===0)return n}return 0}lookupOffset(t){return t+=this.tokenIndex,t<this.tokenCount?this.offsetAndType[t-1]&he:this.source.length}lookupOffsetNonSC(t){for(let r=this.tokenIndex;r<this.tokenCount;r++){let n=this.offsetAndType[r]>>me;if(n!==13&&n!==25&&t--===0)return r-this.tokenIndex}return 0}lookupValue(t,r){return t+=this.tokenIndex,t<this.tokenCount?xe(this.source,this.offsetAndType[t-1]&he,this.offsetAndType[t]&he,r):!1}getTokenStart(t){return t===this.tokenIndex?this.tokenStart:t>0?t<this.tokenCount?this.offsetAndType[t-1]&he:this.offsetAndType[this.tokenCount]&he:this.firstCharOffset}substrToCursor(t){return this.source.substring(t,this.tokenStart)}isBalanceEdge(t){return this.balance[this.tokenIndex]<t}isDelim(t,r){return r?this.lookupType(r)===9&&this.source.charCodeAt(this.lookupOffset(r))===t:this.tokenType===9&&this.source.charCodeAt(this.tokenStart)===t}skip(t){let r=this.tokenIndex+t;r<this.tokenCount?(this.tokenIndex=r,this.tokenStart=this.offsetAndType[r-1]&he,r=this.offsetAndType[r],this.tokenType=r>>me,this.tokenEnd=r&he):(this.tokenIndex=this.tokenCount,this.next())}next(){let t=this.tokenIndex+1;t<this.tokenCount?(this.tokenIndex=t,this.tokenStart=this.tokenEnd,t=this.offsetAndType[t],this.tokenType=t>>me,this.tokenEnd=t&he):(this.eof=!0,this.tokenIndex=this.tokenCount,this.tokenType=0,this.tokenStart=this.tokenEnd=this.source.length)}skipSC(){for(;this.tokenType===13||this.tokenType===25;)this.next()}skipUntilBalanced(t,r){let n=t,i=0,o=0;e:for(;n<this.tokenCount;n++){if(i=this.balance[n],i<t)break e;switch(o=n>0?this.offsetAndType[n-1]&he:this.firstCharOffset,r(this.source.charCodeAt(o))){case 1:break e;case 2:n++;break e;default:po(this.offsetAndType[n]>>me)&&(n=i)}}this.skip(n-this.tokenIndex)}forEachToken(t){for(let r=0,n=this.firstCharOffset;r<this.tokenCount;r++){let i=n,o=this.offsetAndType[r],a=o&he,u=o>>me;n=a,t(u,i,a,r)}}dump(){let t=new Array(this.tokenCount);return this.forEachToken((r,n,i,o)=>{t[o]={idx:o,type:Pe[r],chunk:this.source.substring(n,i),balance:this.balance[o]}}),t}};function Se(e,t){function r(h){return h<u?e.charCodeAt(h):0}function n(){if(s=ze(e,s),je(r(s),r(s+1),r(s+2))){c=12,s=st(e,s);return}if(r(s)===37){c=11,s++;return}c=10}function i(){let h=s;if(s=st(e,s),xe(e,h,s,"url")&&r(s)===40){if(s=ot(e,s+1),r(s)===34||r(s)===39){c=2,s=h+4;return}a();return}if(r(s)===40){c=2,s++;return}c=1}function o(h){for(h||(h=r(s++)),c=5;s<e.length;s++){let m=e.charCodeAt(s);switch(Nt(m)){case h:s++;return;case it:if(nt(m)){s+=Ot(e,s,m),c=6;return}break;case 92:if(s===e.length-1)break;let f=r(s+1);nt(f)?s+=Ot(e,s+1,f):Z(m,f)&&(s=ae(e,s)-1);break}}}function a(){for(c=7,s=ot(e,s);s<e.length;s++){let h=e.charCodeAt(s);switch(Nt(h)){case 41:s++;return;case it:if(s=ot(e,s),r(s)===41||s>=e.length){s<e.length&&s++;return}s=Ft(e,s),c=8;return;case 34:case 39:case 40:case pr:s=Ft(e,s),c=8;return;case 92:if(Z(h,r(s+1))){s=ae(e,s)-1;break}s=Ft(e,s),c=8;return}}}e=String(e||"");let u=e.length,l=It(r(0)),s=l,c;for(;s<u;){let h=e.charCodeAt(s);switch(Nt(h)){case it:c=13,s=ot(e,s+1);break;case 34:o();break;case 35:We(r(s+1))||Z(r(s+1),r(s+2))?(c=4,s=st(e,s+1)):(c=9,s++);break;case 39:o();break;case 40:c=21,s++;break;case 41:c=22,s++;break;case 43:Pt(h,r(s+1),r(s+2))?n():(c=9,s++);break;case 44:c=18,s++;break;case 45:Pt(h,r(s+1),r(s+2))?n():r(s+1)===45&&r(s+2)===62?(c=15,s=s+3):je(h,r(s+1),r(s+2))?i():(c=9,s++);break;case 46:Pt(h,r(s+1),r(s+2))?n():(c=9,s++);break;case 47:r(s+1)===42?(c=25,s=e.indexOf("*/",s+2),s=s===-1?e.length:s+2):(c=9,s++);break;case 58:c=16,s++;break;case 59:c=17,s++;break;case 60:r(s+1)===33&&r(s+2)===45&&r(s+3)===45?(c=14,s=s+4):(c=9,s++);break;case 64:je(r(s+1),r(s+2),r(s+3))?(c=3,s=st(e,s+1)):(c=9,s++);break;case 91:c=19,s++;break;case 92:Z(h,r(s+1))?i():(c=9,s++);break;case 93:c=20,s++;break;case 123:c=23,s++;break;case 125:c=24,s++;break;case ur:n();break;case Dt:i();break;default:c=9,s++}t(c,l,l=s)}}var Ke=null,X=class e{static createItem(t){return{prev:null,next:null,data:t}}constructor(){this.head=null,this.tail=null,this.cursor=null}createItem(t){return e.createItem(t)}allocateCursor(t,r){let n;return Ke!==null?(n=Ke,Ke=Ke.cursor,n.prev=t,n.next=r,n.cursor=this.cursor):n={prev:t,next:r,cursor:this.cursor},this.cursor=n,n}releaseCursor(){let{cursor:t}=this;this.cursor=t.cursor,t.prev=null,t.next=null,t.cursor=Ke,Ke=t}updateCursors(t,r,n,i){let{cursor:o}=this;for(;o!==null;)o.prev===t&&(o.prev=r),o.next===n&&(o.next=i),o=o.cursor}*[Symbol.iterator](){for(let t=this.head;t!==null;t=t.next)yield t.data}get size(){let t=0;for(let r=this.head;r!==null;r=r.next)t++;return t}get isEmpty(){return this.head===null}get first(){return this.head&&this.head.data}get last(){return this.tail&&this.tail.data}fromArray(t){let r=null;this.head=null;for(let n of t){let i=e.createItem(n);r!==null?r.next=i:this.head=i,i.prev=r,r=i}return this.tail=r,this}toArray(){return[...this]}toJSON(){return[...this]}forEach(t,r=this){let n=this.allocateCursor(null,this.head);for(;n.next!==null;){let i=n.next;n.next=i.next,t.call(r,i.data,i,this)}this.releaseCursor()}forEachRight(t,r=this){let n=this.allocateCursor(this.tail,null);for(;n.prev!==null;){let i=n.prev;n.prev=i.prev,t.call(r,i.data,i,this)}this.releaseCursor()}reduce(t,r,n=this){let i=this.allocateCursor(null,this.head),o=r,a;for(;i.next!==null;)a=i.next,i.next=a.next,o=t.call(n,o,a.data,a,this);return this.releaseCursor(),o}reduceRight(t,r,n=this){let i=this.allocateCursor(this.tail,null),o=r,a;for(;i.prev!==null;)a=i.prev,i.prev=a.prev,o=t.call(n,o,a.data,a,this);return this.releaseCursor(),o}some(t,r=this){for(let n=this.head;n!==null;n=n.next)if(t.call(r,n.data,n,this))return!0;return!1}map(t,r=this){let n=new e;for(let i=this.head;i!==null;i=i.next)n.appendData(t.call(r,i.data,i,this));return n}filter(t,r=this){let n=new e;for(let i=this.head;i!==null;i=i.next)t.call(r,i.data,i,this)&&n.appendData(i.data);return n}nextUntil(t,r,n=this){if(t===null)return;let i=this.allocateCursor(null,t);for(;i.next!==null;){let o=i.next;if(i.next=o.next,r.call(n,o.data,o,this))break}this.releaseCursor()}prevUntil(t,r,n=this){if(t===null)return;let i=this.allocateCursor(t,null);for(;i.prev!==null;){let o=i.prev;if(i.prev=o.prev,r.call(n,o.data,o,this))break}this.releaseCursor()}clear(){this.head=null,this.tail=null}copy(){let t=new e;for(let r of this)t.appendData(r);return t}prepend(t){return this.updateCursors(null,t,this.head,t),this.head!==null?(this.head.prev=t,t.next=this.head):this.tail=t,this.head=t,this}prependData(t){return this.prepend(e.createItem(t))}append(t){return this.insert(t)}appendData(t){return this.insert(e.createItem(t))}insert(t,r=null){if(r!==null)if(this.updateCursors(r.prev,t,r,t),r.prev===null){if(this.head!==r)throw new Error("before doesn't belong to list");this.head=t,r.prev=t,t.next=r,this.updateCursors(null,t)}else r.prev.next=t,t.prev=r.prev,r.prev=t,t.next=r;else this.updateCursors(this.tail,t,null,t),this.tail!==null?(this.tail.next=t,t.prev=this.tail):this.head=t,this.tail=t;return this}insertData(t,r){return this.insert(e.createItem(t),r)}remove(t){if(this.updateCursors(t,t.prev,t,t.next),t.prev!==null)t.prev.next=t.next;else{if(this.head!==t)throw new Error("item doesn't belong to list");this.head=t.next}if(t.next!==null)t.next.prev=t.prev;else{if(this.tail!==t)throw new Error("item doesn't belong to list");this.tail=t.prev}return t.prev=null,t.next=null,t}push(t){this.insert(e.createItem(t))}pop(){return this.tail!==null?this.remove(this.tail):null}unshift(t){this.prepend(e.createItem(t))}shift(){return this.head!==null?this.remove(this.head):null}prependList(t){return this.insertList(t,this.head)}appendList(t){return this.insertList(t)}insertList(t,r){return t.head===null?this:(r!=null?(this.updateCursors(r.prev,t.tail,r,t.head),r.prev!==null?(r.prev.next=t.head,t.head.prev=r.prev):this.head=t.head,r.prev=t.tail,t.tail.next=r):(this.updateCursors(this.tail,t.tail,null,t.head),this.tail!==null?(this.tail.next=t.head,t.head.prev=this.tail):this.head=t.head,this.tail=t.tail),t.head=null,t.tail=null,this)}replace(t,r){"head"in r?this.insertList(r,t):this.insert(r,t),this.remove(t)}};function De(e,t){let r=Object.create(SyntaxError.prototype),n=new Error;return Object.assign(r,{name:e,message:t,get stack(){return(n.stack||"").replace(/^(.+\n){1,3}/,`${e}: ${t} +`)}})}var mr=100,ho=60,mo=" ";function fo({source:e,line:t,column:r,baseLine:n,baseColumn:i},o){function a(w,ee){return s.slice(w,ee).map((G,C)=>String(w+C+1).padStart(m)+" |"+G).join(` +`)}let u=` +`.repeat(Math.max(n-1,0)),l=" ".repeat(Math.max(i-1,0)),s=(u+l+e).split(/\r\n?|\n|\f/),c=Math.max(1,t-o)-1,h=Math.min(t+o,s.length+1),m=Math.max(4,String(h).length)+1,f=0;r+=(mo.length-1)*(s[t-1].substr(0,r-1).match(/\t/g)||[]).length,r>mr&&(f=r-ho+3,r=ho-2);for(let w=c;w<=h;w++)w>=0&&w<s.length&&(s[w]=s[w].replace(/\t/g,mo),s[w]=(f>0&&s[w].length>f?"\u2026":"")+s[w].substr(f,mr-2)+(s[w].length>f+mr-1?"\u2026":""));return[a(c,t),new Array(r+m+2).join("-")+"^",a(t,h)].filter(Boolean).join(` +`).replace(/^(\s+\d+\s+\|\n)+/,"").replace(/\n(\s+\d+\s+\|)+$/,"")}function fr(e,t,r,n,i,o=1,a=1){return Object.assign(De("SyntaxError",e),{source:t,offset:r,line:n,column:i,sourceFragment(l){return fo({source:t,line:n,column:i,baseLine:o,baseColumn:a},isNaN(l)?0:l)},get formattedMessage(){return`Parse error: ${e} +`+fo({source:t,line:n,column:i,baseLine:o,baseColumn:a},2)}})}function go(e){let t=this.createList(),r=!1,n={recognizer:e};for(;!this.eof;){switch(this.tokenType){case 25:this.next();continue;case 13:r=!0,this.next();continue}let i=e.getNode.call(this,n);if(i===void 0)break;r&&(e.onWhiteSpace&&e.onWhiteSpace.call(this,i,t,n),r=!1),t.push(i)}return r&&e.onWhiteSpace&&e.onWhiteSpace.call(this,null,t,n),t}var bo=()=>{},Ya=33,Ka=35,dr=59,xo=123,yo=0;function Va(e){return function(){return this[e]()}}function gr(e){let t=Object.create(null);for(let r of Object.keys(e)){let n=e[r],i=n.parse||n;i&&(t[r]=i)}return t}function Qa(e){let t={context:Object.create(null),features:Object.assign(Object.create(null),e.features),scope:Object.assign(Object.create(null),e.scope),atrule:gr(e.atrule),pseudo:gr(e.pseudo),node:gr(e.node)};for(let[r,n]of Object.entries(e.parseContext))switch(typeof n){case"function":t.context[r]=n;break;case"string":t.context[r]=Va(n);break}return{config:t,...t,...t.node}}function ko(e){let t="",r="<unknown>",n=!1,i=bo,o=!1,a=new Ge,u=Object.assign(new Ye,Qa(e||{}),{parseAtrulePrelude:!0,parseRulePrelude:!0,parseValue:!0,parseCustomProperty:!1,readSequence:go,consumeUntilBalanceEnd:()=>0,consumeUntilLeftCurlyBracket(s){return s===xo?1:0},consumeUntilLeftCurlyBracketOrSemicolon(s){return s===xo||s===dr?1:0},consumeUntilExclamationMarkOrSemicolon(s){return s===Ya||s===dr?1:0},consumeUntilSemicolonIncluded(s){return s===dr?2:0},createList(){return new X},createSingleNodeList(s){return new X().appendData(s)},getFirstListNode(s){return s&&s.first},getLastListNode(s){return s&&s.last},parseWithFallback(s,c){let h=this.tokenIndex;try{return s.call(this)}catch(m){if(o)throw m;this.skip(h-this.tokenIndex);let f=c.call(this);return o=!0,i(m,f),o=!1,f}},lookupNonWSType(s){let c;do if(c=this.lookupType(s++),c!==13&&c!==25)return c;while(c!==yo);return yo},charCodeAt(s){return s>=0&&s<t.length?t.charCodeAt(s):0},substring(s,c){return t.substring(s,c)},substrToCursor(s){return this.source.substring(s,this.tokenStart)},cmpChar(s,c){return be(t,s,c)},cmpStr(s,c,h){return xe(t,s,c,h)},consume(s){let c=this.tokenStart;return this.eat(s),this.substrToCursor(c)},consumeFunctionName(){let s=t.substring(this.tokenStart,this.tokenEnd-1);return this.eat(2),s},consumeNumber(s){let c=t.substring(this.tokenStart,ze(t,this.tokenStart));return this.eat(s),c},eat(s){if(this.tokenType!==s){let c=Pe[s].slice(0,-6).replace(/-/g," ").replace(/^./,f=>f.toUpperCase()),h=`${/[[\](){}]/.test(c)?`"${c}"`:c} is expected`,m=this.tokenStart;switch(s){case 1:this.tokenType===2||this.tokenType===7?(m=this.tokenEnd-1,h="Identifier is expected but function found"):h="Identifier is expected";break;case 4:this.isDelim(Ka)&&(this.next(),m++,h="Name is expected");break;case 11:this.tokenType===10&&(m=this.tokenEnd,h="Percent sign is expected");break}this.error(h,m)}this.next()},eatIdent(s){(this.tokenType!==1||this.lookupValue(0,s)===!1)&&this.error(`Identifier "${s}" is expected`),this.next()},eatDelim(s){this.isDelim(s)||this.error(`Delim "${String.fromCharCode(s)}" is expected`),this.next()},getLocation(s,c){return n?a.getLocationRange(s,c,r):null},getLocationFromList(s){if(n){let c=this.getFirstListNode(s),h=this.getLastListNode(s);return a.getLocationRange(c!==null?c.loc.start.offset-a.startOffset:this.tokenStart,h!==null?h.loc.end.offset-a.startOffset:this.tokenStart,r)}return null},error(s,c){let h=typeof c<"u"&&c<t.length?a.getLocation(c):this.eof?a.getLocation(ao(t,t.length-1)):a.getLocation(this.tokenStart);throw new fr(s||"Unexpected input",t,h.offset,h.line,h.column,a.startLine,a.startColumn)}});return Object.assign(function(s,c){t=s,c=c||{},u.setSource(t,Se),a.setSource(t,c.offset,c.line,c.column),r=c.filename||"<unknown>",n=!!c.positions,i=typeof c.onParseError=="function"?c.onParseError:bo,o=!1,u.parseAtrulePrelude="parseAtrulePrelude"in c?!!c.parseAtrulePrelude:!0,u.parseRulePrelude="parseRulePrelude"in c?!!c.parseRulePrelude:!0,u.parseValue="parseValue"in c?!!c.parseValue:!0,u.parseCustomProperty="parseCustomProperty"in c?!!c.parseCustomProperty:!1;let{context:h="default",onComment:m}=c;if(!(h in u.context))throw new Error("Unknown context `"+h+"`");typeof m=="function"&&u.forEachToken((w,ee,G)=>{if(w===25){let C=u.getLocation(ee,G),M=xe(t,G-2,G,"*/")?t.slice(ee+2,G-2):t.slice(ee+2,G);m(M,C)}});let f=u.context[h].call(u,c);return u.eof||u.error(),f},{SyntaxError:fr,config:u.config})}var jo=Ba(_o(),1),Wo=new Set(["Atrule","Selector","Declaration"]);function qo(e){let t=new jo.SourceMapGenerator,r={line:1,column:0},n={line:0,column:0},i={line:1,column:0},o={generated:i},a=1,u=0,l=!1,s=e.node;e.node=function(m){if(m.loc&&m.loc.start&&Wo.has(m.type)){let f=m.loc.start.line,w=m.loc.start.column-1;(n.line!==f||n.column!==w)&&(n.line=f,n.column=w,r.line=a,r.column=u,l&&(l=!1,(r.line!==i.line||r.column!==i.column)&&t.addMapping(o)),l=!0,t.addMapping({source:m.loc.source,original:n,generated:r}))}s.call(this,m),l&&Wo.has(m.type)&&(i.line=a,i.column=u)};let c=e.emit;e.emit=function(m,f,w){for(let ee=0;ee<m.length;ee++)m.charCodeAt(ee)===10?(a++,u=0):u++;c(m,f,w)};let h=e.result;return e.result=function(){return l&&t.addMapping(o),{css:h(),map:t}},e}var _t={};x(_t,{safe:()=>Cr,spec:()=>bl});var fl=43,dl=45,Sr=(e,t)=>{if(e===9&&(e=t),typeof e=="string"){let r=e.charCodeAt(0);return r>127?32768:r<<8}return e},Uo=[[1,1],[1,2],[1,7],[1,8],[1,"-"],[1,10],[1,11],[1,12],[1,15],[1,21],[3,1],[3,2],[3,7],[3,8],[3,"-"],[3,10],[3,11],[3,12],[3,15],[4,1],[4,2],[4,7],[4,8],[4,"-"],[4,10],[4,11],[4,12],[4,15],[12,1],[12,2],[12,7],[12,8],[12,"-"],[12,10],[12,11],[12,12],[12,15],["#",1],["#",2],["#",7],["#",8],["#","-"],["#",10],["#",11],["#",12],["#",15],["-",1],["-",2],["-",7],["-",8],["-","-"],["-",10],["-",11],["-",12],["-",15],[10,1],[10,2],[10,7],[10,8],[10,10],[10,11],[10,12],[10,"%"],[10,15],["@",1],["@",2],["@",7],["@",8],["@","-"],["@",15],[".",10],[".",11],[".",12],["+",10],["+",11],["+",12],["/","*"]],gl=Uo.concat([[1,4],[12,4],[4,4],[3,21],[3,5],[3,16],[11,11],[11,12],[11,2],[11,"-"],[22,1],[22,2],[22,11],[22,12],[22,4],[22,"-"]]);function Ho(e){let t=new Set(e.map(([r,n])=>Sr(r)<<16|Sr(n)));return function(r,n,i){let o=Sr(n,i),a=i.charCodeAt(0);return(a===dl&&n!==1&&n!==2&&n!==15||a===fl?t.has(r<<16|a<<8):t.has(r<<16|o))&&this.emit(" ",13,!0),o}}var bl=Ho(Uo),Cr=Ho(gl);var xl=92;function yl(e,t){if(typeof t=="function"){let r=null;e.children.forEach(n=>{r!==null&&t.call(this,r),this.node(n),r=n});return}e.children.forEach(this.node,this)}function kl(e){Se(e,(t,r,n)=>{this.token(t,e.slice(r,n))})}function Go(e){let t=new Map;for(let[r,n]of Object.entries(e.node))typeof(n.generate||n)=="function"&&t.set(r,n.generate||n);return function(r,n){let i="",o=0,a={node(l){if(t.has(l.type))t.get(l.type).call(u,l);else throw new Error("Unknown node type: "+l.type)},tokenBefore:Cr,token(l,s){o=this.tokenBefore(o,l,s),this.emit(s,l,!1),l===9&&s.charCodeAt(0)===xl&&this.emit(` +`,13,!0)},emit(l){i+=l},result(){return i}};n&&(typeof n.decorator=="function"&&(a=n.decorator(a)),n.sourceMap&&(a=qo(a)),n.mode in _t&&(a.tokenBefore=_t[n.mode]));let u={node:l=>a.node(l),children:yl,token:(l,s)=>a.token(l,s),tokenize:kl};return a.node(r),a.result()}}function Yo(e){return{fromPlainObject(t){return e(t,{enter(r){r.children&&!(r.children instanceof X)&&(r.children=new X().fromArray(r.children))}}),t},toPlainObject(t){return e(t,{leave(r){r.children&&r.children instanceof X&&(r.children=r.children.toArray())}}),t}}}var{hasOwnProperty:Tr}=Object.prototype,ct=function(){};function Ko(e){return typeof e=="function"?e:ct}function Vo(e,t){return function(r,n,i){r.type===t&&e.call(this,r,n,i)}}function wl(e,t){let r=t.structure,n=[];for(let i in r){if(Tr.call(r,i)===!1)continue;let o=r[i],a={name:i,type:!1,nullable:!1};Array.isArray(o)||(o=[o]);for(let u of o)u===null?a.nullable=!0:typeof u=="string"?a.type="node":Array.isArray(u)&&(a.type="list");a.type&&n.push(a)}return n.length?{context:t.walkContext,fields:n}:null}function vl(e){let t={};for(let r in e.node)if(Tr.call(e.node,r)){let n=e.node[r];if(!n.structure)throw new Error("Missed `structure` field in `"+r+"` node type definition");t[r]=wl(r,n)}return t}function Qo(e,t){let r=e.fields.slice(),n=e.context,i=typeof n=="string";return t&&r.reverse(),function(o,a,u,l){let s;i&&(s=a[n],a[n]=o);for(let c of r){let h=o[c.name];if(!c.nullable||h){if(c.type==="list"){if(t?h.reduceRight(l,!1):h.reduce(l,!1))return!0}else if(u(h))return!0}}i&&(a[n]=s)}}function Xo({StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:i}){return{Atrule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Rule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Declaration:{StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:i}}}function $o(e){let t=vl(e),r={},n={},i=Symbol("break-walk"),o=Symbol("skip-node");for(let s in t)Tr.call(t,s)&&t[s]!==null&&(r[s]=Qo(t[s],!1),n[s]=Qo(t[s],!0));let a=Xo(r),u=Xo(n),l=function(s,c){function h(C,M,ve){let O=m.call(G,C,M,ve);return O===i?!0:O===o?!1:!!(w.hasOwnProperty(C.type)&&w[C.type](C,G,h,ee)||f.call(G,C,M,ve)===i)}let m=ct,f=ct,w=r,ee=(C,M,ve,O)=>C||h(M,ve,O),G={break:i,skip:o,root:s,stylesheet:null,atrule:null,atrulePrelude:null,rule:null,selector:null,block:null,declaration:null,function:null};if(typeof c=="function")m=c;else if(c&&(m=Ko(c.enter),f=Ko(c.leave),c.reverse&&(w=n),c.visit)){if(a.hasOwnProperty(c.visit))w=c.reverse?u[c.visit]:a[c.visit];else if(!t.hasOwnProperty(c.visit))throw new Error("Bad value `"+c.visit+"` for `visit` option (should be: "+Object.keys(t).sort().join(", ")+")");m=Vo(m,c.visit),f=Vo(f,c.visit)}if(m===ct&&f===ct)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");h(s)};return l.break=i,l.skip=o,l.find=function(s,c){let h=null;return l(s,function(m,f,w){if(c.call(this,m,f,w))return h=m,i}),h},l.findLast=function(s,c){let h=null;return l(s,{reverse:!0,enter(m,f,w){if(c.call(this,m,f,w))return h=m,i}}),h},l.findAll=function(s,c){let h=[];return l(s,function(m,f,w){c.call(this,m,f,w)&&h.push(m)}),h},l}function Sl(e){return e}function Cl(e){let{min:t,max:r,comma:n}=e;return t===0&&r===0?n?"#?":"*":t===0&&r===1?"?":t===1&&r===0?n?"#":"+":t===1&&r===1?"":(n?"#":"")+(t===r?"{"+t+"}":"{"+t+","+(r!==0?r:"")+"}")}function Tl(e){switch(e.type){case"Range":return" ["+(e.min===null?"-\u221E":e.min)+","+(e.max===null?"\u221E":e.max)+"]";default:throw new Error("Unknown node type `"+e.type+"`")}}function Al(e,t,r,n){let i=e.combinator===" "||n?e.combinator:" "+e.combinator+" ",o=e.terms.map(a=>Wt(a,t,r,n)).join(i);return e.explicit||r?(n||o[0]===","?"[":"[ ")+o+(n?"]":" ]"):o}function Wt(e,t,r,n){let i;switch(e.type){case"Group":i=Al(e,t,r,n)+(e.disallowEmpty?"!":"");break;case"Multiplier":return Wt(e.term,t,r,n)+t(Cl(e),e);case"Boolean":i="<boolean-expr["+Wt(e.term,t,r,n)+"]>";break;case"Type":i="<"+e.name+(e.opts?t(Tl(e.opts),e.opts):"")+">";break;case"Property":i="<'"+e.name+"'>";break;case"Keyword":i=e.name;break;case"AtKeyword":i="@"+e.name;break;case"Function":i=e.name+"(";break;case"String":case"Token":i=e.value;break;case"Comma":i=",";break;default:throw new Error("Unknown node type `"+e.type+"`")}return t(i,e)}function Oe(e,t){let r=Sl,n=!1,i=!1;return typeof t=="function"?r=t:t&&(n=!!t.forceBraces,i=!!t.compact,typeof t.decorate=="function"&&(r=t.decorate)),Wt(e,r,n,i)}var Zo={offset:0,line:1,column:1};function Ll(e,t){let r=e.tokens,n=e.longestMatch,i=n<r.length&&r[n].node||null,o=i!==t?i:null,a=0,u=0,l=0,s="",c,h;for(let m=0;m<r.length;m++){let f=r[m].value;m===n&&(u=f.length,a=s.length),o!==null&&r[m].node===o&&(m<=n?l++:l=0),s+=f}return n===r.length||l>1?(c=jt(o||t,"end")||ut(Zo,s),h=ut(c)):(c=jt(o,"start")||ut(jt(t,"start")||Zo,s.slice(0,a)),h=jt(o,"end")||ut(c,s.substr(a,u))),{css:s,mismatchOffset:a,mismatchLength:u,start:c,end:h}}function jt(e,t){let r=e&&e.loc&&e.loc[t];return r?"line"in r?ut(r):r:null}function ut({offset:e,line:t,column:r},n){let i={offset:e,line:t,column:r};if(n){let o=n.split(/\n|\r\n?|\f/);i.offset+=n.length,i.line+=o.length-1,i.column=o.length===1?i.column+n.length:o.pop().length+1}return i}var Qe=function(e,t){let r=De("SyntaxReferenceError",e+(t?" `"+t+"`":""));return r.reference=t,r},Jo=function(e,t,r,n){let i=De("SyntaxMatchError",e),{css:o,mismatchOffset:a,mismatchLength:u,start:l,end:s}=Ll(n,r);return i.rawMessage=e,i.syntax=t?Oe(t):"<generic>",i.css=o,i.mismatchOffset=a,i.mismatchLength=u,i.message=e+` + syntax: `+i.syntax+` + value: `+(o||"<empty string>")+` + --------`+new Array(i.mismatchOffset+1).join("-")+"^",Object.assign(i,l),i.loc={source:r&&r.loc&&r.loc.source||"<unknown>",start:l,end:s},i};var qt=new Map,Xe=new Map,Ut=45,pt=zl,Ht=Pl,El=Ar;function ht(e,t){return t=t||0,e.length-t>=2&&e.charCodeAt(t)===Ut&&e.charCodeAt(t+1)===Ut}function Ar(e,t){if(t=t||0,e.length-t>=3&&e.charCodeAt(t)===Ut&&e.charCodeAt(t+1)!==Ut){let r=e.indexOf("-",t+2);if(r!==-1)return e.substring(t,r+1)}return""}function zl(e){if(qt.has(e))return qt.get(e);let t=e.toLowerCase(),r=qt.get(t);if(r===void 0){let n=ht(t,0),i=n?"":Ar(t,0);r=Object.freeze({basename:t.substr(i.length),name:t,prefix:i,vendor:i,custom:n})}return qt.set(e,r),r}function Pl(e){if(Xe.has(e))return Xe.get(e);let t=e,r=e[0];r==="/"?r=e[1]==="/"?"//":"/":r!=="_"&&r!=="*"&&r!=="$"&&r!=="#"&&r!=="+"&&r!=="&"&&(r="");let n=ht(t,r.length);if(!n&&(t=t.toLowerCase(),Xe.has(t))){let u=Xe.get(t);return Xe.set(e,u),u}let i=n?"":Ar(t,r.length),o=t.substr(0,r.length+i.length),a=Object.freeze({basename:t.substr(o.length),name:t.substr(r.length),hack:r,vendor:i,prefix:o,custom:n});return Xe.set(e,a),a}var $e=["initial","inherit","unset","revert","revert-layer"];var ft=43,fe=45,Lr=110,Ze=!0,Dl=!1;function zr(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function mt(e,t,r){for(;e!==null&&(e.type===13||e.type===25);)e=r(++t);return t}function Ce(e,t,r,n){if(!e)return 0;let i=e.value.charCodeAt(t);if(i===ft||i===fe){if(r)return 0;t++}for(;t<e.value.length;t++)if(!j(e.value.charCodeAt(t)))return 0;return n+1}function Er(e,t,r){let n=!1,i=mt(e,t,r);if(e=r(i),e===null)return t;if(e.type!==10)if(zr(e,ft)||zr(e,fe)){if(n=!0,i=mt(r(++i),i,r),e=r(i),e===null||e.type!==10)return 0}else return t;if(!n){let o=e.value.charCodeAt(0);if(o!==ft&&o!==fe)return 0}return Ce(e,n?0:1,n,i)}function Pr(e,t){let r=0;if(!e)return 0;if(e.type===10)return Ce(e,0,Dl,r);if(e.type===1&&e.value.charCodeAt(0)===fe){if(!be(e.value,1,Lr))return 0;switch(e.value.length){case 2:return Er(t(++r),r,t);case 3:return e.value.charCodeAt(2)!==fe?0:(r=mt(t(++r),r,t),e=t(r),Ce(e,0,Ze,r));default:return e.value.charCodeAt(2)!==fe?0:Ce(e,3,Ze,r)}}else if(e.type===1||zr(e,ft)&&t(r+1).type===1){if(e.type!==1&&(e=t(++r)),e===null||!be(e.value,0,Lr))return 0;switch(e.value.length){case 1:return Er(t(++r),r,t);case 2:return e.value.charCodeAt(1)!==fe?0:(r=mt(t(++r),r,t),e=t(r),Ce(e,0,Ze,r));default:return e.value.charCodeAt(1)!==fe?0:Ce(e,2,Ze,r)}}else if(e.type===12){let n=e.value.charCodeAt(0),i=n===ft||n===fe?1:0,o=i;for(;o<e.value.length&&j(e.value.charCodeAt(o));o++);return o===i||!be(e.value,o,Lr)?0:o+1===e.value.length?Er(t(++r),r,t):e.value.charCodeAt(o+1)!==fe?0:o+2===e.value.length?(r=mt(t(++r),r,t),e=t(r),Ce(e,0,Ze,r)):Ce(e,o+2,Ze,r)}return 0}var Nl=43,es=45,ts=63,Ol=117;function Ir(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function Fl(e,t){return e.value.charCodeAt(0)===t}function dt(e,t,r){let n=0;for(let i=t;i<e.value.length;i++){let o=e.value.charCodeAt(i);if(o===es&&r&&n!==0)return dt(e,t+n+1,!1),6;if(!te(o)||++n>6)return 0}return n}function Gt(e,t,r){if(!e)return 0;for(;Ir(r(t),ts);){if(++e>6)return 0;t++}return t}function Dr(e,t){let r=0;if(e===null||e.type!==1||!be(e.value,0,Ol)||(e=t(++r),e===null))return 0;if(Ir(e,Nl))return e=t(++r),e===null?0:e.type===1?Gt(dt(e,0,!0),++r,t):Ir(e,ts)?Gt(1,++r,t):0;if(e.type===10){let n=dt(e,1,!0);return n===0?0:(e=t(++r),e===null?r:e.type===12||e.type===10?!Fl(e,es)||!dt(e,1,!1)?0:r+1:Gt(n,r,t))}return e.type===12?Gt(dt(e,1,!0),++r,t):0}var Rl=["calc(","-moz-calc(","-webkit-calc("],Nr=new Map([[2,22],[21,22],[19,20],[23,24]]);function le(e,t){return t<e.length?e.charCodeAt(t):0}function rs(e,t){return xe(e,0,e.length,t)}function ns(e,t){for(let r=0;r<t.length;r++)if(rs(e,t[r]))return!0;return!1}function is(e,t){return t!==e.length-2?!1:le(e,t)===92&&j(le(e,t+1))}function Yt(e,t,r){if(e&&e.type==="Range"){let n=Number(r!==void 0&&r!==t.length?t.substr(0,r):t);if(isNaN(n)||e.min!==null&&n<e.min&&typeof e.min!="string"||e.max!==null&&n>e.max&&typeof e.max!="string")return!0}return!1}function Ml(e,t){let r=0,n=[],i=0;e:do{switch(e.type){case 24:case 22:case 20:if(e.type!==r)break e;if(r=n.pop(),n.length===0){i++;break e}break;case 2:case 21:case 19:case 23:n.push(r),r=Nr.get(e.type);break}i++}while(e=t(i));return i}function oe(e){return function(t,r,n){return t===null?0:t.type===2&&ns(t.value,Rl)?Ml(t,r):e(t,r,n)}}function N(e){return function(t){return t===null||t.type!==e?0:1}}function Bl(e){if(e===null||e.type!==1)return 0;let t=e.value.toLowerCase();return ns(t,$e)||rs(t,"default")?0:1}function os(e){return e===null||e.type!==1||le(e.value,0)!==45||le(e.value,1)!==45?0:1}function _l(e){return!os(e)||e.value==="--"?0:1}function Wl(e){if(e===null||e.type!==4)return 0;let t=e.value.length;if(t!==4&&t!==5&&t!==7&&t!==9)return 0;for(let r=1;r<t;r++)if(!te(le(e.value,r)))return 0;return 1}function jl(e){return e===null||e.type!==4||!je(le(e.value,1),le(e.value,2),le(e.value,3))?0:1}function ql(e,t){if(!e)return 0;let r=0,n=[],i=0;e:do{switch(e.type){case 6:case 8:break e;case 24:case 22:case 20:if(e.type!==r)break e;r=n.pop();break;case 17:if(r===0)break e;break;case 9:if(r===0&&e.value==="!")break e;break;case 2:case 21:case 19:case 23:n.push(r),r=Nr.get(e.type);break}i++}while(e=t(i));return i}function Ul(e,t){if(!e)return 0;let r=0,n=[],i=0;e:do{switch(e.type){case 6:case 8:break e;case 24:case 22:case 20:if(e.type!==r)break e;r=n.pop();break;case 2:case 21:case 19:case 23:n.push(r),r=Nr.get(e.type);break}i++}while(e=t(i));return i}function we(e){return e&&(e=new Set(e)),function(t,r,n){if(t===null||t.type!==12)return 0;let i=ze(t.value,0);if(e!==null){let o=t.value.indexOf("\\",i),a=o===-1||!is(t.value,o)?t.value.substr(i):t.value.substring(i,o);if(e.has(a.toLowerCase())===!1)return 0}return Yt(n,t.value,i)?0:1}}function Hl(e,t,r){return e===null||e.type!==11||Yt(r,e.value,e.value.length-1)?0:1}function ss(e){return typeof e!="function"&&(e=function(){return 0}),function(t,r,n){return t!==null&&t.type===10&&Number(t.value)===0?1:e(t,r,n)}}function Gl(e,t,r){if(e===null)return 0;let n=ze(e.value,0);return!(n===e.value.length)&&!is(e.value,n)||Yt(r,e.value,n)?0:1}function Yl(e,t,r){if(e===null||e.type!==10)return 0;let n=le(e.value,0)===43||le(e.value,0)===45?1:0;for(;n<e.value.length;n++)if(!j(le(e.value,n)))return 0;return Yt(r,e.value,n)?0:1}var Kl={"ident-token":N(1),"function-token":N(2),"at-keyword-token":N(3),"hash-token":N(4),"string-token":N(5),"bad-string-token":N(6),"url-token":N(7),"bad-url-token":N(8),"delim-token":N(9),"number-token":N(10),"percentage-token":N(11),"dimension-token":N(12),"whitespace-token":N(13),"CDO-token":N(14),"CDC-token":N(15),"colon-token":N(16),"semicolon-token":N(17),"comma-token":N(18),"[-token":N(19),"]-token":N(20),"(-token":N(21),")-token":N(22),"{-token":N(23),"}-token":N(24)},Vl={string:N(5),ident:N(1),percentage:oe(Hl),zero:ss(),number:oe(Gl),integer:oe(Yl),"custom-ident":Bl,"dashed-ident":os,"custom-property-name":_l,"hex-color":Wl,"id-selector":jl,"an-plus-b":Pr,urange:Dr,"declaration-value":ql,"any-value":Ul};function Ql(e){let{angle:t,decibel:r,frequency:n,flex:i,length:o,resolution:a,semitones:u,time:l}=e||{};return{dimension:oe(we(null)),angle:oe(we(t)),decibel:oe(we(r)),frequency:oe(we(n)),flex:oe(we(i)),length:oe(ss(we(o))),resolution:oe(we(a)),semitones:oe(we(u)),time:oe(we(l))}}function as(e){return{...Kl,...Vl,...Ql(e)}}var Kt={};x(Kt,{angle:()=>$l,decibel:()=>rc,flex:()=>tc,frequency:()=>Jl,length:()=>Xl,resolution:()=>ec,semitones:()=>nc,time:()=>Zl});var Xl=["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],$l=["deg","grad","rad","turn"],Zl=["s","ms"],Jl=["hz","khz"],ec=["dpi","dpcm","dppx","x"],tc=["fr"],rc=["db"],nc=["st"];var qr={};x(qr,{SyntaxError:()=>Vt,generate:()=>Oe,parse:()=>Je,walk:()=>Zt});function Vt(e,t,r){return Object.assign(De("SyntaxError",e),{input:t,offset:r,rawMessage:e,message:e+` + `+t+` +--`+new Array((r||t.length)+1).join("-")+"^"})}var ic=9,oc=10,sc=12,ac=13,lc=32,ls=new Uint8Array(128).map((e,t)=>/[a-zA-Z0-9\-]/.test(String.fromCharCode(t))?1:0),Qt=class{constructor(t){this.str=t,this.pos=0}charCodeAt(t){return t<this.str.length?this.str.charCodeAt(t):0}charCode(){return this.charCodeAt(this.pos)}isNameCharCode(t=this.charCode()){return t<128&&ls[t]===1}nextCharCode(){return this.charCodeAt(this.pos+1)}nextNonWsCode(t){return this.charCodeAt(this.findWsEnd(t))}skipWs(){this.pos=this.findWsEnd(this.pos)}findWsEnd(t){for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r!==ac&&r!==oc&&r!==sc&&r!==lc&&r!==ic)break}return t}substringToPos(t){return this.str.substring(this.pos,this.pos=t)}eat(t){this.charCode()!==t&&this.error("Expect `"+String.fromCharCode(t)+"`"),this.pos++}peek(){return this.pos<this.str.length?this.str.charAt(this.pos++):""}error(t){throw new Vt(t,this.str,this.pos)}scanSpaces(){return this.substringToPos(this.findWsEnd(this.pos))}scanWord(){let t=this.pos;for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r>=128||ls[r]===0)break}return this.pos===t&&this.error("Expect a keyword"),this.substringToPos(t)}scanNumber(){let t=this.pos;for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r<48||r>57)break}return this.pos===t&&this.error("Expect a number"),this.substringToPos(t)}scanString(){let t=this.str.indexOf("'",this.pos+1);return t===-1&&(this.pos=this.str.length,this.error("Expect an apostrophe")),this.substringToPos(t+1)}};var cc=9,uc=10,pc=12,hc=13,mc=32,gs=33,Mr=35,cs=38,Xt=39,bs=40,fc=41,xs=42,Br=43,_r=44,us=45,Wr=60,Fr=62,Rr=63,dc=64,gt=91,bt=93,$t=123,ps=124,hs=125,ms=8734,fs={" ":1,"&&":2,"||":3,"|":4};function ds(e){let t=null,r=null;return e.eat($t),e.skipWs(),t=e.scanNumber(e),e.skipWs(),e.charCode()===_r?(e.pos++,e.skipWs(),e.charCode()!==hs&&(r=e.scanNumber(e),e.skipWs())):r=t,e.eat(hs),{min:Number(t),max:r?Number(r):0}}function gc(e){let t=null,r=!1;switch(e.charCode()){case xs:e.pos++,t={min:0,max:0};break;case Br:e.pos++,t={min:1,max:0};break;case Rr:e.pos++,t={min:0,max:1};break;case Mr:e.pos++,r=!0,e.charCode()===$t?t=ds(e):e.charCode()===Rr?(e.pos++,t={min:0,max:0}):t={min:1,max:0};break;case $t:t=ds(e);break;default:return null}return{type:"Multiplier",comma:r,min:t.min,max:t.max,term:null}}function Te(e,t){let r=gc(e);return r!==null?(r.term=t,e.charCode()===Mr&&e.charCodeAt(e.pos-1)===Br?Te(e,r):r):t}function Or(e){let t=e.peek();return t===""?null:Te(e,{type:"Token",value:t})}function bc(e){let t;return e.eat(Wr),e.eat(Xt),t=e.scanWord(),e.eat(Xt),e.eat(Fr),Te(e,{type:"Property",name:t})}function xc(e){let t=null,r=null,n=1;return e.eat(gt),e.charCode()===us&&(e.peek(),n=-1),n==-1&&e.charCode()===ms?e.peek():(t=n*Number(e.scanNumber(e)),e.isNameCharCode()&&(t+=e.scanWord())),e.skipWs(),e.eat(_r),e.skipWs(),e.charCode()===ms?e.peek():(n=1,e.charCode()===us&&(e.peek(),n=-1),r=n*Number(e.scanNumber(e)),e.isNameCharCode()&&(r+=e.scanWord())),e.eat(bt),{type:"Range",min:t,max:r}}function yc(e){let t,r=null;if(e.eat(Wr),t=e.scanWord(),t==="boolean-expr"){e.eat(gt);let n=jr(e,bt);return e.eat(bt),e.eat(Fr),Te(e,{type:"Boolean",term:n.terms.length===1?n.terms[0]:n})}return e.charCode()===bs&&e.nextCharCode()===fc&&(e.pos+=2,t+="()"),e.charCodeAt(e.findWsEnd(e.pos))===gt&&(e.skipWs(),r=xc(e)),e.eat(Fr),Te(e,{type:"Type",name:t,opts:r})}function kc(e){let t=e.scanWord();return e.charCode()===bs?(e.pos++,{type:"Function",name:t}):Te(e,{type:"Keyword",name:t})}function wc(e,t){function r(i,o){return{type:"Group",terms:i,combinator:o,disallowEmpty:!1,explicit:!1}}let n;for(t=Object.keys(t).sort((i,o)=>fs[i]-fs[o]);t.length>0;){n=t.shift();let i=0,o=0;for(;i<e.length;i++){let a=e[i];a.type==="Combinator"&&(a.value===n?(o===-1&&(o=i-1),e.splice(i,1),i--):(o!==-1&&i-o>1&&(e.splice(o,i-o,r(e.slice(o,i),n)),i=o+1),o=-1))}o!==-1&&t.length&&e.splice(o,i-o,r(e.slice(o,i),n))}return n}function jr(e,t){let r=Object.create(null),n=[],i,o=null,a=e.pos;for(;e.charCode()!==t&&(i=Sc(e,t));)i.type!=="Spaces"&&(i.type==="Combinator"?((o===null||o.type==="Combinator")&&(e.pos=a,e.error("Unexpected combinator")),r[i.value]=!0):o!==null&&o.type!=="Combinator"&&(r[" "]=!0,n.push({type:"Combinator",value:" "})),n.push(i),o=i,a=e.pos);return o!==null&&o.type==="Combinator"&&(e.pos-=a,e.error("Unexpected combinator")),{type:"Group",terms:n,combinator:wc(n,r)||" ",disallowEmpty:!1,explicit:!1}}function vc(e,t){let r;return e.eat(gt),r=jr(e,t),e.eat(bt),r.explicit=!0,e.charCode()===gs&&(e.pos++,r.disallowEmpty=!0),r}function Sc(e,t){let r=e.charCode();switch(r){case bt:break;case gt:return Te(e,vc(e,t));case Wr:return e.nextCharCode()===Xt?bc(e):yc(e);case ps:return{type:"Combinator",value:e.substringToPos(e.pos+(e.nextCharCode()===ps?2:1))};case cs:return e.pos++,e.eat(cs),{type:"Combinator",value:"&&"};case _r:return e.pos++,{type:"Comma"};case Xt:return Te(e,{type:"String",value:e.scanString()});case mc:case cc:case uc:case hc:case pc:return{type:"Spaces",value:e.scanSpaces()};case dc:return r=e.nextCharCode(),e.isNameCharCode(r)?(e.pos++,{type:"AtKeyword",name:e.scanWord()}):Or(e);case xs:case Br:case Rr:case Mr:case gs:break;case $t:if(r=e.nextCharCode(),r<48||r>57)return Or(e);break;default:return e.isNameCharCode(r)?kc(e):Or(e)}}function Je(e){let t=new Qt(e),r=jr(t);return t.pos!==e.length&&t.error("Unexpected input"),r.terms.length===1&&r.terms[0].type==="Group"?r.terms[0]:r}var xt=function(){};function ys(e){return typeof e=="function"?e:xt}function Zt(e,t,r){function n(a){switch(i.call(r,a),a.type){case"Group":a.terms.forEach(n);break;case"Multiplier":case"Boolean":n(a.term);break;case"Type":case"Property":case"Keyword":case"AtKeyword":case"Function":case"String":case"Token":case"Comma":break;default:throw new Error("Unknown type: "+a.type)}o.call(r,a)}let i=xt,o=xt;if(typeof t=="function"?i=t:t&&(i=ys(t.enter),o=ys(t.leave)),i===xt&&o===xt)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");n(e,r)}var Cc={decorator(e){let t=[],r=null;return{...e,node(n){let i=r;r=n,e.node.call(this,n),r=i},emit(n,i,o){t.push({type:i,value:n,node:o?null:r})},result(){return t}}}};function Tc(e){let t=[];return Se(e,(r,n,i)=>t.push({type:r,value:e.slice(n,i),node:null})),t}function ks(e,t){return typeof e=="string"?Tc(e):t.generate(e,Cc)}var A={type:"Match"},z={type:"Mismatch"},Jt={type:"DisallowEmpty"},Ac=40,Lc=41;function J(e,t,r){return t===A&&r===z||e===A&&t===A&&r===A?e:(e.type==="If"&&e.else===z&&t===A&&(t=e.then,e=e.match),{type:"If",match:e,then:t,else:r})}function vs(e){return e.length>2&&e.charCodeAt(e.length-2)===Ac&&e.charCodeAt(e.length-1)===Lc}function ws(e){return e.type==="Keyword"||e.type==="AtKeyword"||e.type==="Function"||e.type==="Type"&&vs(e.name)}function Ae(e,t=" ",r=!1){return{type:"Group",terms:e,combinator:t,disallowEmpty:!1,explicit:r}}function yt(e,t,r=new Set){if(!r.has(e))switch(r.add(e),e.type){case"If":e.match=yt(e.match,t,r),e.then=yt(e.then,t,r),e.else=yt(e.else,t,r);break;case"Type":return t[e.name]||e}return e}function Ur(e,t,r){switch(e){case" ":{let n=A;for(let i=t.length-1;i>=0;i--){let o=t[i];n=J(o,n,z)}return n}case"|":{let n=z,i=null;for(let o=t.length-1;o>=0;o--){let a=t[o];if(ws(a)&&(i===null&&o>0&&ws(t[o-1])&&(i=Object.create(null),n=J({type:"Enum",map:i},A,n)),i!==null)){let u=(vs(a.name)?a.name.slice(0,-1):a.name).toLowerCase();if(!(u in i)){i[u]=a;continue}}i=null,n=J(a,A,n)}return n}case"&&":{if(t.length>5)return{type:"MatchOnce",terms:t,all:!0};let n=z;for(let i=t.length-1;i>=0;i--){let o=t[i],a;t.length>1?a=Ur(e,t.filter(function(u){return u!==o}),!1):a=A,n=J(o,a,n)}return n}case"||":{if(t.length>5)return{type:"MatchOnce",terms:t,all:!1};let n=r?A:z;for(let i=t.length-1;i>=0;i--){let o=t[i],a;t.length>1?a=Ur(e,t.filter(function(u){return u!==o}),!0):a=A,n=J(o,a,n)}return n}}}function Ec(e){let t=A,r=et(e.term);if(e.max===0)r=J(r,Jt,z),t=J(r,null,z),t.then=J(A,A,t),e.comma&&(t.then.else=J({type:"Comma",syntax:e},t,z));else for(let n=e.min||1;n<=e.max;n++)e.comma&&t!==A&&(t=J({type:"Comma",syntax:e},t,z)),t=J(r,J(A,A,t),z);if(e.min===0)t=J(A,A,t);else for(let n=0;n<e.min-1;n++)e.comma&&t!==A&&(t=J({type:"Comma",syntax:e},t,z)),t=J(r,t,z);return t}function et(e){if(typeof e=="function")return{type:"Generic",fn:e};switch(e.type){case"Group":{let t=Ur(e.combinator,e.terms.map(et),!1);return e.disallowEmpty&&(t=J(t,Jt,z)),t}case"Multiplier":return Ec(e);case"Boolean":{let t=et(e.term),r=et(Ae([Ae([{type:"Keyword",name:"not"},{type:"Type",name:"!boolean-group"}]),Ae([{type:"Type",name:"!boolean-group"},Ae([{type:"Multiplier",comma:!1,min:0,max:0,term:Ae([{type:"Keyword",name:"and"},{type:"Type",name:"!boolean-group"}])},{type:"Multiplier",comma:!1,min:0,max:0,term:Ae([{type:"Keyword",name:"or"},{type:"Type",name:"!boolean-group"}])}],"|")])],"|")),n=et(Ae([{type:"Type",name:"!term"},Ae([{type:"Token",value:"("},{type:"Type",name:"!self"},{type:"Token",value:")"}]),{type:"Type",name:"general-enclosed"}],"|"));return yt(n,{"!term":t,"!self":r}),yt(r,{"!boolean-group":n}),r}case"Type":case"Property":return{type:e.type,name:e.name,syntax:e};case"Keyword":return{type:e.type,name:e.name.toLowerCase(),syntax:e};case"AtKeyword":return{type:e.type,name:"@"+e.name.toLowerCase(),syntax:e};case"Function":return{type:e.type,name:e.name.toLowerCase()+"(",syntax:e};case"String":return e.value.length===3?{type:"Token",value:e.value.charAt(1),syntax:e}:{type:e.type,value:e.value.substr(1,e.value.length-2).replace(/\\'/g,"'"),syntax:e};case"Token":return{type:e.type,value:e.value,syntax:e};case"Comma":return{type:e.type,syntax:e};default:throw new Error("Unknown node type:",e.type)}}function kt(e,t){return typeof e=="string"&&(e=Je(e)),{type:"MatchGraph",match:et(e),syntax:t||null,source:e}}var{hasOwnProperty:Ss}=Object.prototype,zc=0,Pc=1,Gr=2,Es=3,Cs="Match",Ic="Mismatch",Dc="Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)",Ts=15e3,Nc=0;function Oc(e){let t=null,r=null,n=e;for(;n!==null;)r=n.prev,n.prev=t,t=n,n=r;return t}function Hr(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++){let n=t.charCodeAt(r),i=e.charCodeAt(r);if(i>=65&&i<=90&&(i=i|32),i!==n)return!1}return!0}function Fc(e){return e.type!==9?!1:e.value!=="?"}function As(e){return e===null?!0:e.type===18||e.type===2||e.type===21||e.type===19||e.type===23||Fc(e)}function Ls(e){return e===null?!0:e.type===22||e.type===20||e.type===24||e.type===9&&e.value==="/"}function Rc(e,t,r){function n(){do M++,C=M<e.length?e[M]:null;while(C!==null&&(C.type===13||C.type===25))}function i(se){let ge=M+se;return ge<e.length?e[ge]:null}function o(se,ge){return{nextState:se,matchStack:O,syntaxStack:h,thenStack:m,tokenIndex:M,prev:ge}}function a(se){m={nextState:se,matchStack:O,syntaxStack:h,prev:m}}function u(se){f=o(se,f)}function l(){O={type:Pc,syntax:t.syntax,token:C,prev:O},n(),w=null,M>ve&&(ve=M)}function s(){h={syntax:t.syntax,opts:t.syntax.opts||h!==null&&h.opts||null,prev:h},O={type:Gr,syntax:t.syntax,token:O.token,prev:O}}function c(){O.type===Gr?O=O.prev:O={type:Es,syntax:h.syntax,token:O.token,prev:O},h=h.prev}let h=null,m=null,f=null,w=null,ee=0,G=null,C=null,M=-1,ve=0,O={type:zc,syntax:null,token:null,prev:null};for(n();G===null&&++ee<Ts;)switch(t.type){case"Match":if(m===null){if(C!==null&&(M!==e.length-1||C.value!=="\\0"&&C.value!=="\\9")){t=z;break}G=Cs;break}if(t=m.nextState,t===Jt)if(m.matchStack===O){t=z;break}else t=A;for(;m.syntaxStack!==h;)c();m=m.prev;break;case"Mismatch":if(w!==null&&w!==!1)(f===null||M>f.tokenIndex)&&(f=w,w=!1);else if(f===null){G=Ic;break}t=f.nextState,m=f.thenStack,h=f.syntaxStack,O=f.matchStack,M=f.tokenIndex,C=M<e.length?e[M]:null,f=f.prev;break;case"MatchGraph":t=t.match;break;case"If":t.else!==z&&u(t.else),t.then!==A&&a(t.then),t=t.match;break;case"MatchOnce":t={type:"MatchOnceBuffer",syntax:t,index:0,mask:0};break;case"MatchOnceBuffer":{let Q=t.syntax.terms;if(t.index===Q.length){if(t.mask===0||t.syntax.all){t=z;break}t=A;break}if(t.mask===(1<<Q.length)-1){t=A;break}for(;t.index<Q.length;t.index++){let $=1<<t.index;if(!(t.mask&$)){u(t),a({type:"AddMatchOnce",syntax:t.syntax,mask:t.mask|$}),t=Q[t.index++];break}}break}case"AddMatchOnce":t={type:"MatchOnceBuffer",syntax:t.syntax,index:0,mask:t.mask};break;case"Enum":if(C!==null){let Q=C.value.toLowerCase();if(Q.indexOf("\\")!==-1&&(Q=Q.replace(/\\[09].*$/,"")),Ss.call(t.map,Q)){t=t.map[Q];break}}t=z;break;case"Generic":{let Q=h!==null?h.opts:null,$=M+Math.floor(t.fn(C,i,Q));if(!isNaN($)&&$>M){for(;M<$;)l();t=A}else t=z;break}case"Type":case"Property":{let Q=t.type==="Type"?"types":"properties",$=Ss.call(r,Q)?r[Q][t.name]:null;if(!$||!$.match)throw new Error("Bad syntax reference: "+(t.type==="Type"?"<"+t.name+">":"<'"+t.name+"'>"));if(w!==!1&&C!==null&&t.type==="Type"&&(t.name==="custom-ident"&&C.type===1||t.name==="length"&&C.value==="0")){w===null&&(w=o(t,f)),t=z;break}s(),t=$.matchRef||$.match;break}case"Keyword":{let Q=t.name;if(C!==null){let $=C.value;if($.indexOf("\\")!==-1&&($=$.replace(/\\[09].*$/,"")),Hr($,Q)){l(),t=A;break}}t=z;break}case"AtKeyword":case"Function":if(C!==null&&Hr(C.value,t.name)){l(),t=A;break}t=z;break;case"Token":if(C!==null&&C.value===t.value){l(),t=A;break}t=z;break;case"Comma":C!==null&&C.type===18?As(O.token)?t=z:(l(),t=Ls(C)?z:A):t=As(O.token)||Ls(C)?A:z;break;case"String":let se="",ge=M;for(;ge<e.length&&se.length<t.value.length;ge++)se+=e[ge].value;if(Hr(se,t.value)){for(;M<ge;)l();t=A}else t=z;break;default:throw new Error("Unknown node type: "+t.type)}switch(Nc+=ee,G){case null:console.warn("[csstree-match] BREAK after "+Ts+" iterations"),G=Dc,O=null;break;case Cs:for(;h!==null;)c();break;default:O=null}return{tokens:e,reason:G,iterations:ee,match:O,longestMatch:ve}}function Yr(e,t,r){let n=Rc(e,t,r||{});if(n.match===null)return n;let i=n.match,o=n.match={syntax:t.syntax||null,match:[]},a=[o];for(i=Oc(i).prev;i!==null;){switch(i.type){case Gr:o.match.push(o={syntax:i.syntax,match:[]}),a.push(o);break;case Es:a.pop(),o=a[a.length-1];break;default:o.match.push({syntax:i.syntax||null,token:i.token.value,node:i.token.node})}i=i.prev}return n}var Vr={};x(Vr,{getTrace:()=>zs,isKeyword:()=>_c,isProperty:()=>Bc,isType:()=>Mc});function zs(e){function t(i){return i===null?!1:i.type==="Type"||i.type==="Property"||i.type==="Keyword"}function r(i){if(Array.isArray(i.match)){for(let o=0;o<i.match.length;o++)if(r(i.match[o]))return t(i.syntax)&&n.unshift(i.syntax),!0}else if(i.node===e)return n=t(i.syntax)?[i.syntax]:[],!0;return!1}let n=null;return this.matched!==null&&r(this.matched),n}function Mc(e,t){return Kr(this,e,r=>r.type==="Type"&&r.name===t)}function Bc(e,t){return Kr(this,e,r=>r.type==="Property"&&r.name===t)}function _c(e){return Kr(this,e,t=>t.type==="Keyword")}function Kr(e,t,r){let n=zs.call(e,t);return n===null?!1:n.some(r)}function Ps(e){return"node"in e?e.node:Ps(e.match[0])}function Is(e){return"node"in e?e.node:Is(e.match[e.match.length-1])}function Qr(e,t,r,n,i){function o(u){if(u.syntax!==null&&u.syntax.type===n&&u.syntax.name===i){let l=Ps(u),s=Is(u);e.syntax.walk(t,function(c,h,m){if(c===l){let f=new X;do{if(f.appendData(h.data),h.data===s)break;h=h.next}while(h!==null);a.push({parent:m,nodes:f})}})}Array.isArray(u.match)&&u.match.forEach(o)}let a=[];return r.matched!==null&&o(r.matched),a}var{hasOwnProperty:wt}=Object.prototype;function Xr(e){return typeof e=="number"&&isFinite(e)&&Math.floor(e)===e&&e>=0}function Ds(e){return!!e&&Xr(e.offset)&&Xr(e.line)&&Xr(e.column)}function Wc(e,t){return function(n,i){if(!n||n.constructor!==Object)return i(n,"Type of node should be an Object");for(let o in n){let a=!0;if(wt.call(n,o)!==!1){if(o==="type")n.type!==e&&i(n,"Wrong node type `"+n.type+"`, expected `"+e+"`");else if(o==="loc"){if(n.loc===null)continue;if(n.loc&&n.loc.constructor===Object)if(typeof n.loc.source!="string")o+=".source";else if(!Ds(n.loc.start))o+=".start";else if(!Ds(n.loc.end))o+=".end";else continue;a=!1}else if(t.hasOwnProperty(o)){a=!1;for(let u=0;!a&&u<t[o].length;u++){let l=t[o][u];switch(l){case String:a=typeof n[o]=="string";break;case Boolean:a=typeof n[o]=="boolean";break;case null:a=n[o]===null;break;default:typeof l=="string"?a=n[o]&&n[o].type===l:Array.isArray(l)&&(a=n[o]instanceof X)}}}else i(n,"Unknown field `"+o+"` for "+e+" node type");a||i(n,"Bad value for `"+e+"."+o+"`")}}for(let o in t)wt.call(t,o)&&wt.call(n,o)===!1&&i(n,"Field `"+e+"."+o+"` is missed")}}function Ns(e,t){let r=[];for(let n=0;n<e.length;n++){let i=e[n];if(i===String||i===Boolean)r.push(i.name.toLowerCase());else if(i===null)r.push("null");else if(typeof i=="string")r.push(i);else if(Array.isArray(i))r.push("List<"+(Ns(i,t)||"any")+">");else throw new Error("Wrong value `"+i+"` in `"+t+"` structure definition")}return r.join(" | ")}function jc(e,t){let r=t.structure,n={type:String,loc:!0},i={type:'"'+e+'"'};for(let o in r){if(wt.call(r,o)===!1)continue;let a=n[o]=Array.isArray(r[o])?r[o].slice():[r[o]];i[o]=Ns(a,e+"."+o)}return{docs:i,check:Wc(e,n)}}function Os(e){let t={};if(e.node){for(let r in e.node)if(wt.call(e.node,r)){let n=e.node[r];if(n.structure)t[r]=jc(r,n);else throw new Error("Missed `structure` field in `"+r+"` node type definition")}}return t}function $r(e,t,r){let n={};for(let i in e)e[i].syntax&&(n[i]=r?e[i].syntax:Oe(e[i].syntax,{compact:t}));return n}function qc(e,t,r){let n={};for(let[i,o]of Object.entries(e))n[i]={prelude:o.prelude&&(r?o.prelude.syntax:Oe(o.prelude.syntax,{compact:t})),descriptors:o.descriptors&&$r(o.descriptors,t,r)};return n}function Uc(e){for(let t=0;t<e.length;t++)if(e[t].value.toLowerCase()==="var(")return!0;return!1}function Hc(e){let t=e.terms[0];return e.explicit===!1&&e.terms.length===1&&t.type==="Multiplier"&&t.comma===!0}function ce(e,t,r){return{matched:e,iterations:r,error:t,...Vr}}function tt(e,t,r,n){let i=ks(r,e.syntax),o;return Uc(i)?ce(null,new Error("Matching for a tree with var() is not supported")):(n&&(o=Yr(i,e.cssWideKeywordsSyntax,e)),(!n||!o.match)&&(o=Yr(i,t.match,e),!o.match)?ce(null,new Jo(o.reason,t.syntax,r,o),o.iterations):ce(o.match,null,o.iterations))}var Fe=class{constructor(t,r,n){if(this.cssWideKeywords=$e,this.syntax=r,this.generic=!1,this.units={...Kt},this.atrules=Object.create(null),this.properties=Object.create(null),this.types=Object.create(null),this.structure=n||Os(t),t){if(t.cssWideKeywords&&(this.cssWideKeywords=t.cssWideKeywords),t.units)for(let i of Object.keys(Kt))Array.isArray(t.units[i])&&(this.units[i]=t.units[i]);if(t.types)for(let[i,o]of Object.entries(t.types))this.addType_(i,o);if(t.generic){this.generic=!0;for(let[i,o]of Object.entries(as(this.units)))this.addType_(i,o)}if(t.atrules)for(let[i,o]of Object.entries(t.atrules))this.addAtrule_(i,o);if(t.properties)for(let[i,o]of Object.entries(t.properties))this.addProperty_(i,o)}this.cssWideKeywordsSyntax=kt(this.cssWideKeywords.join(" | "))}checkStructure(t){function r(o,a){i.push({node:o,message:a})}let n=this.structure,i=[];return this.syntax.walk(t,function(o){n.hasOwnProperty(o.type)?n[o.type].check(o,r):r(o,"Unknown node type `"+o.type+"`")}),i.length?i:!1}createDescriptor(t,r,n,i=null){let o={type:r,name:n},a={type:r,name:n,parent:i,serializable:typeof t=="string"||t&&typeof t.type=="string",syntax:null,match:null,matchRef:null};return typeof t=="function"?a.match=kt(t,o):(typeof t=="string"?Object.defineProperty(a,"syntax",{get(){return Object.defineProperty(a,"syntax",{value:Je(t)}),a.syntax}}):a.syntax=t,Object.defineProperty(a,"match",{get(){return Object.defineProperty(a,"match",{value:kt(a.syntax,o)}),a.match}}),r==="Property"&&Object.defineProperty(a,"matchRef",{get(){let u=a.syntax,l=Hc(u)?kt({...u,terms:[u.terms[0].term]},o):null;return Object.defineProperty(a,"matchRef",{value:l}),l}})),a}addAtrule_(t,r){r&&(this.atrules[t]={type:"Atrule",name:t,prelude:r.prelude?this.createDescriptor(r.prelude,"AtrulePrelude",t):null,descriptors:r.descriptors?Object.keys(r.descriptors).reduce((n,i)=>(n[i]=this.createDescriptor(r.descriptors[i],"AtruleDescriptor",i,t),n),Object.create(null)):null})}addProperty_(t,r){r&&(this.properties[t]=this.createDescriptor(r,"Property",t))}addType_(t,r){r&&(this.types[t]=this.createDescriptor(r,"Type",t))}checkAtruleName(t){if(!this.getAtrule(t))return new Qe("Unknown at-rule","@"+t)}checkAtrulePrelude(t,r){let n=this.checkAtruleName(t);if(n)return n;let i=this.getAtrule(t);if(!i.prelude&&r)return new SyntaxError("At-rule `@"+t+"` should not contain a prelude");if(i.prelude&&!r&&!tt(this,i.prelude,"",!1).matched)return new SyntaxError("At-rule `@"+t+"` should contain a prelude")}checkAtruleDescriptorName(t,r){let n=this.checkAtruleName(t);if(n)return n;let i=this.getAtrule(t),o=pt(r);if(!i.descriptors)return new SyntaxError("At-rule `@"+t+"` has no known descriptors");if(!i.descriptors[o.name]&&!i.descriptors[o.basename])return new Qe("Unknown at-rule descriptor",r)}checkPropertyName(t){if(!this.getProperty(t))return new Qe("Unknown property",t)}matchAtrulePrelude(t,r){let n=this.checkAtrulePrelude(t,r);if(n)return ce(null,n);let i=this.getAtrule(t);return i.prelude?tt(this,i.prelude,r||"",!1):ce(null,null)}matchAtruleDescriptor(t,r,n){let i=this.checkAtruleDescriptorName(t,r);if(i)return ce(null,i);let o=this.getAtrule(t),a=pt(r);return tt(this,o.descriptors[a.name]||o.descriptors[a.basename],n,!1)}matchDeclaration(t){return t.type!=="Declaration"?ce(null,new Error("Not a Declaration node")):this.matchProperty(t.property,t.value)}matchProperty(t,r){if(Ht(t).custom)return ce(null,new Error("Lexer matching doesn't applicable for custom properties"));let n=this.checkPropertyName(t);return n?ce(null,n):tt(this,this.getProperty(t),r,!0)}matchType(t,r){let n=this.getType(t);return n?tt(this,n,r,!1):ce(null,new Qe("Unknown type",t))}match(t,r){return typeof t!="string"&&(!t||!t.type)?ce(null,new Qe("Bad syntax")):((typeof t=="string"||!t.match)&&(t=this.createDescriptor(t,"Type","anonymous")),tt(this,t,r,!1))}findValueFragments(t,r,n,i){return Qr(this,r,this.matchProperty(t,r),n,i)}findDeclarationValueFragments(t,r,n){return Qr(this,t.value,this.matchDeclaration(t),r,n)}findAllFragments(t,r,n){let i=[];return this.syntax.walk(t,{visit:"Declaration",enter:o=>{i.push.apply(i,this.findDeclarationValueFragments(o,r,n))}}),i}getAtrule(t,r=!0){let n=pt(t);return(n.vendor&&r?this.atrules[n.name]||this.atrules[n.basename]:this.atrules[n.name])||null}getAtrulePrelude(t,r=!0){let n=this.getAtrule(t,r);return n&&n.prelude||null}getAtruleDescriptor(t,r){return this.atrules.hasOwnProperty(t)&&this.atrules.declarators&&this.atrules[t].declarators[r]||null}getProperty(t,r=!0){let n=Ht(t);return(n.vendor&&r?this.properties[n.name]||this.properties[n.basename]:this.properties[n.name])||null}getType(t){return hasOwnProperty.call(this.types,t)?this.types[t]:null}validate(){function t(l,s){return s?`<${l}>`:`<'${l}'>`}function r(l,s,c,h){if(c.has(s))return c.get(s);c.set(s,!1),h.syntax!==null&&Zt(h.syntax,function(m){if(m.type!=="Type"&&m.type!=="Property")return;let f=m.type==="Type"?l.types:l.properties,w=m.type==="Type"?i:o;hasOwnProperty.call(f,m.name)?r(l,m.name,w,f[m.name])&&(n.push(`${t(s,c===i)} used broken syntax definition ${t(m.name,m.type==="Type")}`),c.set(s,!0)):(n.push(`${t(s,c===i)} used missed syntax definition ${t(m.name,m.type==="Type")}`),c.set(s,!0))},this)}let n=[],i=new Map,o=new Map;for(let l in this.types)r(this,l,i,this.types[l]);for(let l in this.properties)r(this,l,o,this.properties[l]);let a=[...i.keys()].filter(l=>i.get(l)),u=[...o.keys()].filter(l=>o.get(l));return a.length||u.length?{errors:n,types:a,properties:u}:null}dump(t,r){return{generic:this.generic,cssWideKeywords:this.cssWideKeywords,units:this.units,types:$r(this.types,!r,t),properties:$r(this.properties,!r,t),atrules:qc(this.atrules,!r,t)}}toString(){return JSON.stringify(this.dump())}};function Zr(e,t){return typeof t=="string"&&/^\s*\|/.test(t)?typeof e=="string"?e+t:t.replace(/^\s*\|\s*/,""):t||null}function Fs(e,t){let r=Object.create(null);for(let[n,i]of Object.entries(e))if(i){r[n]={};for(let o of Object.keys(i))t.includes(o)&&(r[n][o]=i[o])}return r}function vt(e,t){let r={...e};for(let[n,i]of Object.entries(t))switch(n){case"generic":r[n]=!!i;break;case"cssWideKeywords":r[n]=e[n]?[...e[n],...i]:i||[];break;case"units":r[n]={...e[n]};for(let[o,a]of Object.entries(i))r[n][o]=Array.isArray(a)?a:[];break;case"atrules":r[n]={...e[n]};for(let[o,a]of Object.entries(i)){let u=r[n][o]||{},l=r[n][o]={prelude:u.prelude||null,descriptors:{...u.descriptors}};if(a){l.prelude=a.prelude?Zr(l.prelude,a.prelude):l.prelude||null;for(let[s,c]of Object.entries(a.descriptors||{}))l.descriptors[s]=c?Zr(l.descriptors[s],c):null;Object.keys(l.descriptors).length||(l.descriptors=null)}}break;case"types":case"properties":r[n]={...e[n]};for(let[o,a]of Object.entries(i))r[n][o]=Zr(r[n][o],a);break;case"scope":case"features":r[n]={...e[n]};for(let[o,a]of Object.entries(i))r[n][o]={...r[n][o],...a};break;case"parseContext":r[n]={...e[n],...i};break;case"atrule":case"pseudo":r[n]={...e[n],...Fs(i,["parse"])};break;case"node":r[n]={...e[n],...Fs(i,["name","structure","parse","generate","walkContext"])};break}return r}function Rs(e){let t=ko(e),r=$o(e),n=Go(e),{fromPlainObject:i,toPlainObject:o}=Yo(r),a={lexer:null,createLexer:u=>new Fe(u,a,a.lexer.structure),tokenize:Se,parse:t,generate:n,walk:r,find:r.find,findLast:r.findLast,findAll:r.findAll,fromPlainObject:i,toPlainObject:o,fork(u){let l=vt({},e);return Rs(typeof u=="function"?u(l):vt(l,u))}};return a.lexer=new Fe({generic:e.generic,cssWideKeywords:e.cssWideKeywords,units:e.units,types:e.types,atrules:e.atrules,properties:e.properties,node:e.node},a),a}var er=e=>Rs(vt({},e));var Ms={generic:!0,cssWideKeywords:["initial","inherit","unset","revert","revert-layer"],units:{angle:["deg","grad","rad","turn"],decibel:["db"],flex:["fr"],frequency:["hz","khz"],length:["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],resolution:["dpi","dpcm","dppx","x"],semitones:["st"],time:["s","ms"]},types:{"abs()":"abs( <calc-sum> )","absolute-size":"xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large","acos()":"acos( <calc-sum> )","alpha-value":"<number>|<percentage>","angle-percentage":"<angle>|<percentage>","angular-color-hint":"<angle-percentage>","angular-color-stop":"<color>&&<color-stop-angle>?","angular-color-stop-list":"[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>","animateable-feature":"scroll-position|contents|<custom-ident>","asin()":"asin( <calc-sum> )","atan()":"atan( <calc-sum> )","atan2()":"atan2( <calc-sum> , <calc-sum> )",attachment:"scroll|fixed|local","attr()":"attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )","attr-matcher":"['~'|'|'|'^'|'$'|'*']? '='","attr-modifier":"i|s","attribute-selector":"'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'","auto-repeat":"repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )","auto-track-list":"[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?",axis:"block|inline|x|y","baseline-position":"[first|last]? baseline","basic-shape":"<inset()>|<xywh()>|<rect()>|<circle()>|<ellipse()>|<polygon()>|<path()>","bg-image":"none|<image>","bg-layer":"<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>","bg-position":"[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]","bg-size":"[<length-percentage>|auto]{1,2}|cover|contain","blur()":"blur( <length> )","blend-mode":"normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",box:"border-box|padding-box|content-box","brightness()":"brightness( <number-percentage> )","calc()":"calc( <calc-sum> )","calc-sum":"<calc-product> [['+'|'-'] <calc-product>]*","calc-product":"<calc-value> ['*' <calc-value>|'/' <number>]*","calc-value":"<number>|<dimension>|<percentage>|<calc-constant>|( <calc-sum> )","calc-constant":"e|pi|infinity|-infinity|NaN","cf-final-image":"<image>|<color>","cf-mixing-image":"<percentage>?&&<image>","circle()":"circle( [<shape-radius>]? [at <position>]? )","clamp()":"clamp( <calc-sum>#{3} )","class-selector":"'.' <ident-token>","clip-source":"<url>",color:"<color-base>|currentColor|<system-color>|<device-cmyk()>|<light-dark()>|<-non-standard-color>","color-stop":"<color-stop-length>|<color-stop-angle>","color-stop-angle":"<angle-percentage>{1,2}","color-stop-length":"<length-percentage>{1,2}","color-stop-list":"[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>","color-interpolation-method":"in [<rectangular-color-space>|<polar-color-space> <hue-interpolation-method>?|<custom-color-space>]",combinator:"'>'|'+'|'~'|['|' '|']","common-lig-values":"[common-ligatures|no-common-ligatures]","compat-auto":"searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button","composite-style":"clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor","compositing-operator":"add|subtract|intersect|exclude","compound-selector":"[<type-selector>? <subclass-selector>*]!","compound-selector-list":"<compound-selector>#","complex-selector":"<complex-selector-unit> [<combinator>? <complex-selector-unit>]*","complex-selector-list":"<complex-selector>#","conic-gradient()":"conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )","contextual-alt-values":"[contextual|no-contextual]","content-distribution":"space-between|space-around|space-evenly|stretch","content-list":"[<string>|contents|<image>|<counter>|<quote>|<target>|<leader()>|<attr()>]+","content-position":"center|start|end|flex-start|flex-end","content-replacement":"<image>","contrast()":"contrast( [<number-percentage>] )","cos()":"cos( <calc-sum> )",counter:"<counter()>|<counters()>","counter()":"counter( <counter-name> , <counter-style>? )","counter-name":"<custom-ident>","counter-style":"<counter-style-name>|symbols( )","counter-style-name":"<custom-ident>","counters()":"counters( <counter-name> , <string> , <counter-style>? )","cross-fade()":"cross-fade( <cf-mixing-image> , <cf-final-image>? )","cubic-bezier-timing-function":"ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )","deprecated-system-color":"ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText","discretionary-lig-values":"[discretionary-ligatures|no-discretionary-ligatures]","display-box":"contents|none","display-inside":"flow|flow-root|table|flex|grid|ruby","display-internal":"table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container","display-legacy":"inline-block|inline-list-item|inline-table|inline-flex|inline-grid","display-listitem":"<display-outside>?&&[flow|flow-root]?&&list-item","display-outside":"block|inline|run-in","drop-shadow()":"drop-shadow( <length>{2,3} <color>? )","east-asian-variant-values":"[jis78|jis83|jis90|jis04|simplified|traditional]","east-asian-width-values":"[full-width|proportional-width]","element()":"element( <custom-ident> , [first|start|last|first-except]? )|element( <id-selector> )","ellipse()":"ellipse( [<shape-radius>{2}]? [at <position>]? )","ending-shape":"circle|ellipse","env()":"env( <custom-ident> , <declaration-value>? )","exp()":"exp( <calc-sum> )","explicit-track-list":"[<line-names>? <track-size>]+ <line-names>?","family-name":"<string>|<custom-ident>+","feature-tag-value":"<string> [<integer>|on|off]?","feature-type":"@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation","feature-value-block":"<feature-type> '{' <feature-value-declaration-list> '}'","feature-value-block-list":"<feature-value-block>+","feature-value-declaration":"<custom-ident> : <integer>+ ;","feature-value-declaration-list":"<feature-value-declaration>","feature-value-name":"<custom-ident>","fill-rule":"nonzero|evenodd","filter-function":"<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>","filter-function-list":"[<filter-function>|<url>]+","final-bg-layer":"<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>","fixed-breadth":"<length-percentage>","fixed-repeat":"repeat( [<integer [1,\u221E]>] , [<line-names>? <fixed-size>]+ <line-names>? )","fixed-size":"<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )","font-stretch-absolute":"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>","font-variant-css21":"[normal|small-caps]","font-weight-absolute":"normal|bold|<number [1,1000]>","frequency-percentage":"<frequency>|<percentage>","general-enclosed":"[<function-token> <any-value>? )]|[( <any-value>? )]","generic-family":"<generic-script-specific>|<generic-complete>|<generic-incomplete>|<-non-standard-generic-family>","generic-name":"serif|sans-serif|cursive|fantasy|monospace","geometry-box":"<shape-box>|fill-box|stroke-box|view-box",gradient:"<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<repeating-conic-gradient()>|<-legacy-gradient>","grayscale()":"grayscale( <number-percentage> )","grid-line":"auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]","historical-lig-values":"[historical-ligatures|no-historical-ligatures]","hsl()":"hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )","hsla()":"hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )",hue:"<number>|<angle>","hue-rotate()":"hue-rotate( <angle> )","hue-interpolation-method":"[shorter|longer|increasing|decreasing] hue","hwb()":"hwb( [<hue>|none] [<percentage>|none] [<percentage>|none] [/ [<alpha-value>|none]]? )","hypot()":"hypot( <calc-sum># )",image:"<url>|<image()>|<image-set()>|<element()>|<paint()>|<cross-fade()>|<gradient>","image()":"image( <image-tags>? [<image-src>? , <color>?]! )","image-set()":"image-set( <image-set-option># )","image-set-option":"[<image>|<string>] [<resolution>||type( <string> )]","image-src":"<url>|<string>","image-tags":"ltr|rtl","inflexible-breadth":"<length-percentage>|min-content|max-content|auto","inset()":"inset( <length-percentage>{1,4} [round <'border-radius'>]? )","invert()":"invert( <number-percentage> )","keyframes-name":"<custom-ident>|<string>","keyframe-block":"<keyframe-selector># { <declaration-list> }","keyframe-block-list":"<keyframe-block>+","keyframe-selector":"from|to|<percentage>|<timeline-range-name> <percentage>","lab()":"lab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )","layer()":"layer( <layer-name> )","layer-name":"<ident> ['.' <ident>]*","lch()":"lch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )","leader()":"leader( <leader-type> )","leader-type":"dotted|solid|space|<string>","length-percentage":"<length>|<percentage>","light-dark()":"light-dark( <color> , <color> )","line-names":"'[' <custom-ident>* ']'","line-name-list":"[<line-names>|<name-repeat>]+","line-style":"none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset","line-width":"<length>|thin|medium|thick","linear-color-hint":"<length-percentage>","linear-color-stop":"<color> <color-stop-length>?","linear-gradient()":"linear-gradient( [[<angle>|to <side-or-corner>]||<color-interpolation-method>]? , <color-stop-list> )","log()":"log( <calc-sum> , <calc-sum>? )","mask-layer":"<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>","mask-position":"[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?","mask-reference":"none|<image>|<mask-source>","mask-source":"<url>","masking-mode":"alpha|luminance|match-source","matrix()":"matrix( <number>#{6} )","matrix3d()":"matrix3d( <number>#{16} )","max()":"max( <calc-sum># )","media-and":"<media-in-parens> [and <media-in-parens>]+","media-condition":"<media-not>|<media-and>|<media-or>|<media-in-parens>","media-condition-without-or":"<media-not>|<media-and>|<media-in-parens>","media-feature":"( [<mf-plain>|<mf-boolean>|<mf-range>] )","media-in-parens":"( <media-condition> )|<media-feature>|<general-enclosed>","media-not":"not <media-in-parens>","media-or":"<media-in-parens> [or <media-in-parens>]+","media-query":"<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?","media-query-list":"<media-query>#","media-type":"<ident>","mf-boolean":"<mf-name>","mf-name":"<ident>","mf-plain":"<mf-name> : <mf-value>","mf-range":"<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>","mf-value":"<number>|<dimension>|<ident>|<ratio>","min()":"min( <calc-sum># )","minmax()":"minmax( [<length-percentage>|min-content|max-content|auto] , [<length-percentage>|<flex>|min-content|max-content|auto] )","mod()":"mod( <calc-sum> , <calc-sum> )","name-repeat":"repeat( [<integer [1,\u221E]>|auto-fill] , <line-names>+ )","named-color":"transparent|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","namespace-prefix":"<ident>","ns-prefix":"[<ident-token>|'*']? '|'","number-percentage":"<number>|<percentage>","numeric-figure-values":"[lining-nums|oldstyle-nums]","numeric-fraction-values":"[diagonal-fractions|stacked-fractions]","numeric-spacing-values":"[proportional-nums|tabular-nums]",nth:"<an-plus-b>|even|odd","opacity()":"opacity( [<number-percentage>] )","overflow-position":"unsafe|safe","outline-radius":"<length>|<percentage>","page-body":"<declaration>? [; <page-body>]?|<page-margin-box> <page-body>","page-margin-box":"<page-margin-box-type> '{' <declaration-list> '}'","page-margin-box-type":"@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom","page-selector-list":"[<page-selector>#]?","page-selector":"<pseudo-page>+|<ident> <pseudo-page>*","page-size":"A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger","path()":"path( [<fill-rule> ,]? <string> )","paint()":"paint( <ident> , <declaration-value>? )","perspective()":"perspective( [<length [0,\u221E]>|none] )","polygon()":"polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )","polar-color-space":"hsl|hwb|lch|oklch",position:"[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]","pow()":"pow( <calc-sum> , <calc-sum> )","pseudo-class-selector":"':' <ident-token>|':' <function-token> <any-value> ')'","pseudo-element-selector":"':' <pseudo-class-selector>|<legacy-pseudo-element-selector>","pseudo-page":": [left|right|first|blank]",quote:"open-quote|close-quote|no-open-quote|no-close-quote","radial-gradient()":"radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",ratio:"<number [0,\u221E]> [/ <number [0,\u221E]>]?","ray()":"ray( <angle>&&<ray-size>?&&contain?&&[at <position>]? )","ray-size":"closest-side|closest-corner|farthest-side|farthest-corner|sides","rectangular-color-space":"srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020|lab|oklab|xyz|xyz-d50|xyz-d65","relative-selector":"<combinator>? <complex-selector>","relative-selector-list":"<relative-selector>#","relative-size":"larger|smaller","rem()":"rem( <calc-sum> , <calc-sum> )","repeat-style":"repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}","repeating-conic-gradient()":"repeating-conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )","repeating-linear-gradient()":"repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )","repeating-radial-gradient()":"repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )","reversed-counter-name":"reversed( <counter-name> )","rgb()":"rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )","rgba()":"rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )","rotate()":"rotate( [<angle>|<zero>] )","rotate3d()":"rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )","rotateX()":"rotateX( [<angle>|<zero>] )","rotateY()":"rotateY( [<angle>|<zero>] )","rotateZ()":"rotateZ( [<angle>|<zero>] )","round()":"round( <rounding-strategy>? , <calc-sum> , <calc-sum> )","rounding-strategy":"nearest|up|down|to-zero","saturate()":"saturate( <number-percentage> )","scale()":"scale( [<number>|<percentage>]#{1,2} )","scale3d()":"scale3d( [<number>|<percentage>]#{3} )","scaleX()":"scaleX( [<number>|<percentage>] )","scaleY()":"scaleY( [<number>|<percentage>] )","scaleZ()":"scaleZ( [<number>|<percentage>] )","scroll()":"scroll( [<axis>||<scroller>]? )",scroller:"root|nearest|self","self-position":"center|start|end|self-start|self-end|flex-start|flex-end","shape-radius":"<length-percentage>|closest-side|farthest-side","sign()":"sign( <calc-sum> )","skew()":"skew( [<angle>|<zero>] , [<angle>|<zero>]? )","skewX()":"skewX( [<angle>|<zero>] )","skewY()":"skewY( [<angle>|<zero>] )","sepia()":"sepia( <number-percentage> )",shadow:"inset?&&<length>{2,4}&&<color>?","shadow-t":"[<length>{2,3}&&<color>?]",shape:"rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )","shape-box":"<box>|margin-box","side-or-corner":"[left|right]||[top|bottom]","sin()":"sin( <calc-sum> )","single-animation":"<'animation-duration'>||<easing-function>||<'animation-delay'>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]||<single-animation-timeline>","single-animation-direction":"normal|reverse|alternate|alternate-reverse","single-animation-fill-mode":"none|forwards|backwards|both","single-animation-iteration-count":"infinite|<number>","single-animation-play-state":"running|paused","single-animation-timeline":"auto|none|<dashed-ident>|<scroll()>|<view()>","single-transition":"[none|<single-transition-property>]||<time>||<easing-function>||<time>||<transition-behavior-value>","single-transition-property":"all|<custom-ident>",size:"closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}","sqrt()":"sqrt( <calc-sum> )","step-position":"jump-start|jump-end|jump-none|jump-both|start|end","step-timing-function":"step-start|step-end|steps( <integer> [, <step-position>]? )","subclass-selector":"<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>","supports-condition":"not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*","supports-in-parens":"( <supports-condition> )|<supports-feature>|<general-enclosed>","supports-feature":"<supports-decl>|<supports-selector-fn>","supports-decl":"( <declaration> )","supports-selector-fn":"selector( <complex-selector> )",symbol:"<string>|<image>|<custom-ident>","system-color":"AccentColor|AccentColorText|ActiveText|ButtonBorder|ButtonFace|ButtonText|Canvas|CanvasText|Field|FieldText|GrayText|Highlight|HighlightText|LinkText|Mark|MarkText|SelectedItem|SelectedItemText|VisitedText","tan()":"tan( <calc-sum> )",target:"<target-counter()>|<target-counters()>|<target-text()>","target-counter()":"target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )","target-counters()":"target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )","target-text()":"target-text( [<string>|<url>] , [content|before|after|first-letter]? )","time-percentage":"<time>|<percentage>","timeline-range-name":"cover|contain|entry|exit|entry-crossing|exit-crossing","easing-function":"linear|<cubic-bezier-timing-function>|<step-timing-function>","track-breadth":"<length-percentage>|<flex>|min-content|max-content|auto","track-list":"[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?","track-repeat":"repeat( [<integer [1,\u221E]>] , [<line-names>? <track-size>]+ <line-names>? )","track-size":"<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( <length-percentage> )","transform-function":"<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>","transform-list":"<transform-function>+","transition-behavior-value":"normal|allow-discrete","translate()":"translate( <length-percentage> , <length-percentage>? )","translate3d()":"translate3d( <length-percentage> , <length-percentage> , <length> )","translateX()":"translateX( <length-percentage> )","translateY()":"translateY( <length-percentage> )","translateZ()":"translateZ( <length> )","type-or-unit":"string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%","type-selector":"<wq-name>|<ns-prefix>? '*'","var()":"var( <custom-property-name> , <declaration-value>? )","view()":"view( [<axis>||<'view-timeline-inset'>]? )","viewport-length":"auto|<length-percentage>","visual-box":"content-box|padding-box|border-box","wq-name":"<ns-prefix>? <ident-token>","-legacy-gradient":"<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>","-legacy-linear-gradient":"-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )","-legacy-repeating-linear-gradient":"-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )","-legacy-linear-gradient-arguments":"[<angle>|<side-or-corner>]? , <color-stop-list>","-legacy-radial-gradient":"-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )","-legacy-repeating-radial-gradient":"-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )","-legacy-radial-gradient-arguments":"[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>","-legacy-radial-gradient-size":"closest-side|closest-corner|farthest-side|farthest-corner|contain|cover","-legacy-radial-gradient-shape":"circle|ellipse","-non-standard-font":"-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body","-non-standard-color":"-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text","-non-standard-image-rendering":"optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast","-non-standard-overflow":"overlay|-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable","-non-standard-size":"intrinsic|min-intrinsic|-webkit-fill-available|-webkit-fit-content|-webkit-min-content|-webkit-max-content|-moz-available|-moz-fit-content|-moz-min-content|-moz-max-content","-webkit-gradient()":"-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )","-webkit-gradient-color-stop":"from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )","-webkit-gradient-point":"[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]","-webkit-gradient-radius":"<length>|<percentage>","-webkit-gradient-type":"linear|radial","-webkit-mask-box-repeat":"repeat|stretch|round","-ms-filter-function-list":"<-ms-filter-function>+","-ms-filter-function":"<-ms-filter-function-progid>|<-ms-filter-function-legacy>","-ms-filter-function-progid":"'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]","-ms-filter-function-legacy":"<ident-token>|<function-token> <any-value>? )","absolute-color-base":"<hex-color>|<absolute-color-function>|<named-color>|transparent","absolute-color-function":"<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>",age:"child|young|old","anchor-name":"<dashed-ident>","attr-name":"<wq-name>","attr-fallback":"<any-value>","bg-clip":"<box>|border|text",bottom:"<length>|auto","container-name":"<custom-ident>","container-condition":"not <query-in-parens>|<query-in-parens> [[and <query-in-parens>]*|[or <query-in-parens>]*]","coord-box":"content-box|padding-box|border-box|fill-box|stroke-box|view-box","generic-voice":"[<age>? <gender> <integer>?]",gender:"male|female|neutral","generic-script-specific":"generic( kai )|generic( fangsong )|generic( nastaliq )","generic-complete":"serif|sans-serif|system-ui|cursive|fantasy|math|monospace","generic-incomplete":"ui-serif|ui-sans-serif|ui-monospace|ui-rounded","-non-standard-generic-family":"-apple-system|BlinkMacSystemFont",left:"<length>|auto","color-base":"<hex-color>|<color-function>|<named-color>|<color-mix()>|transparent","color-function":"<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>","device-cmyk()":"<legacy-device-cmyk-syntax>|<modern-device-cmyk-syntax>","legacy-device-cmyk-syntax":"device-cmyk( <number>#{4} )","modern-device-cmyk-syntax":"device-cmyk( <cmyk-component>{4} [/ [<alpha-value>|none]]? )","cmyk-component":"<number>|<percentage>|none","color-mix()":"color-mix( <color-interpolation-method> , [<color>&&<percentage [0,100]>?]#{2} )","color-space":"<rectangular-color-space>|<polar-color-space>|<custom-color-space>","custom-color-space":"<dashed-ident>",paint:"none|<color>|<url> [none|<color>]?|context-fill|context-stroke","palette-identifier":"<dashed-ident>",right:"<length>|auto","scope-start":"<forgiving-selector-list>","scope-end":"<forgiving-selector-list>","forgiving-selector-list":"<complex-real-selector-list>","forgiving-relative-selector-list":"<relative-real-selector-list>","selector-list":"<complex-selector-list>","complex-real-selector-list":"<complex-real-selector>#","simple-selector-list":"<simple-selector>#","relative-real-selector-list":"<relative-real-selector>#","complex-selector-unit":"[<compound-selector>? <pseudo-compound-selector>*]!","complex-real-selector":"<compound-selector> [<combinator>? <compound-selector>]*","relative-real-selector":"<combinator>? <complex-real-selector>","pseudo-compound-selector":"<pseudo-element-selector> <pseudo-class-selector>*","simple-selector":"<type-selector>|<subclass-selector>","legacy-pseudo-element-selector":"':' [before|after|first-line|first-letter]","single-animation-composition":"replace|add|accumulate","svg-length":"<percentage>|<length>|<number>","svg-writing-mode":"lr-tb|rl-tb|tb-rl|lr|rl|tb",top:"<length>|auto",x:"<number>",y:"<number>",declaration:"<ident-token> : <declaration-value>? ['!' important]?","declaration-list":"[<declaration>? ';']* <declaration>?",url:"url( <string> <url-modifier>* )|<url-token>","url-modifier":"<ident>|<function-token> <any-value> )","number-zero-one":"<number [0,1]>","number-one-or-greater":"<number [1,\u221E]>","color()":"color( <colorspace-params> [/ [<alpha-value>|none]]? )","colorspace-params":"[<predefined-rgb-params>|<xyz-params>]","predefined-rgb-params":"<predefined-rgb> [<number>|<percentage>|none]{3}","predefined-rgb":"srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020","xyz-params":"<xyz-space> [<number>|<percentage>|none]{3}","xyz-space":"xyz|xyz-d50|xyz-d65","oklab()":"oklab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )","oklch()":"oklch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )","offset-path":"<ray()>|<url>|<basic-shape>","rect()":"rect( [<length-percentage>|auto]{4} [round <'border-radius'>]? )","xywh()":"xywh( <length-percentage>{2} <length-percentage [0,\u221E]>{2} [round <'border-radius'>]? )","query-in-parens":"( <container-condition> )|( <size-feature> )|style( <style-query> )|<general-enclosed>","size-feature":"<mf-plain>|<mf-boolean>|<mf-range>","style-feature":"<declaration>","style-query":"<style-condition>|<style-feature>","style-condition":"not <style-in-parens>|<style-in-parens> [[and <style-in-parens>]*|[or <style-in-parens>]*]","style-in-parens":"( <style-condition> )|( <style-feature> )|<general-enclosed>","-non-standard-display":"-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box","inset-area":"[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]","position-area":"[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|center|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|center|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]","anchor()":"anchor( <anchor-element>?&&<anchor-side> , <length-percentage>? )","anchor-side":"inside|outside|top|left|right|bottom|start|end|self-start|self-end|<percentage>|center","anchor-size()":"anchor-size( [<anchor-element>||<anchor-size>]? , <length-percentage>? )","anchor-size":"width|height|block|inline|self-block|self-inline","anchor-element":"<dashed-ident>","try-size":"most-width|most-height|most-block-size|most-inline-size","try-tactic":"flip-block||flip-inline||flip-start","font-variant-css2":"normal|small-caps","font-width-css3":"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded","system-family-name":"caption|icon|menu|message-box|small-caption|status-bar"},properties:{"--*":"<declaration-value>","-ms-accelerator":"false|true","-ms-block-progression":"tb|rl|bt|lr","-ms-content-zoom-chaining":"none|chained","-ms-content-zooming":"none|zoom","-ms-content-zoom-limit":"<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>","-ms-content-zoom-limit-max":"<percentage>","-ms-content-zoom-limit-min":"<percentage>","-ms-content-zoom-snap":"<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>","-ms-content-zoom-snap-points":"snapInterval( <percentage> , <percentage> )|snapList( <percentage># )","-ms-content-zoom-snap-type":"none|proximity|mandatory","-ms-filter":"<string>","-ms-flow-from":"[none|<custom-ident>]#","-ms-flow-into":"[none|<custom-ident>]#","-ms-grid-columns":"none|<track-list>|<auto-track-list>","-ms-grid-rows":"none|<track-list>|<auto-track-list>","-ms-high-contrast-adjust":"auto|none","-ms-hyphenate-limit-chars":"auto|<integer>{1,3}","-ms-hyphenate-limit-lines":"no-limit|<integer>","-ms-hyphenate-limit-zone":"<percentage>|<length>","-ms-ime-align":"auto|after","-ms-overflow-style":"auto|none|scrollbar|-ms-autohiding-scrollbar","-ms-scrollbar-3dlight-color":"<color>","-ms-scrollbar-arrow-color":"<color>","-ms-scrollbar-base-color":"<color>","-ms-scrollbar-darkshadow-color":"<color>","-ms-scrollbar-face-color":"<color>","-ms-scrollbar-highlight-color":"<color>","-ms-scrollbar-shadow-color":"<color>","-ms-scrollbar-track-color":"<color>","-ms-scroll-chaining":"chained|none","-ms-scroll-limit":"<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>","-ms-scroll-limit-x-max":"auto|<length>","-ms-scroll-limit-x-min":"<length>","-ms-scroll-limit-y-max":"auto|<length>","-ms-scroll-limit-y-min":"<length>","-ms-scroll-rails":"none|railed","-ms-scroll-snap-points-x":"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )","-ms-scroll-snap-points-y":"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )","-ms-scroll-snap-type":"none|proximity|mandatory","-ms-scroll-snap-x":"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>","-ms-scroll-snap-y":"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>","-ms-scroll-translation":"none|vertical-to-horizontal","-ms-text-autospace":"none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space","-ms-touch-select":"grippers|none","-ms-user-select":"none|element|text","-ms-wrap-flow":"auto|both|start|end|maximum|clear","-ms-wrap-margin":"<length>","-ms-wrap-through":"wrap|none","-moz-appearance":"none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized","-moz-binding":"<url>|none","-moz-border-bottom-colors":"<color>+|none","-moz-border-left-colors":"<color>+|none","-moz-border-right-colors":"<color>+|none","-moz-border-top-colors":"<color>+|none","-moz-context-properties":"none|[fill|fill-opacity|stroke|stroke-opacity]#","-moz-float-edge":"border-box|content-box|margin-box|padding-box","-moz-force-broken-image-icon":"0|1","-moz-image-region":"<shape>|auto","-moz-orient":"inline|block|horizontal|vertical","-moz-outline-radius":"<outline-radius>{1,4} [/ <outline-radius>{1,4}]?","-moz-outline-radius-bottomleft":"<outline-radius>","-moz-outline-radius-bottomright":"<outline-radius>","-moz-outline-radius-topleft":"<outline-radius>","-moz-outline-radius-topright":"<outline-radius>","-moz-stack-sizing":"ignore|stretch-to-fit","-moz-text-blink":"none|blink","-moz-user-focus":"ignore|normal|select-after|select-before|select-menu|select-same|select-all|none","-moz-user-input":"auto|none|enabled|disabled","-moz-user-modify":"read-only|read-write|write-only","-moz-window-dragging":"drag|no-drag","-moz-window-shadow":"default|menu|tooltip|sheet|none","-webkit-appearance":"none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|inner-spin-button|listbox|listitem|media-controls-background|media-controls-fullscreen-background|media-current-time-display|media-enter-fullscreen-button|media-exit-fullscreen-button|media-fullscreen-button|media-mute-button|media-overlay-play-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|media-time-remaining-display|media-toggle-closed-captions-button|media-volume-slider|media-volume-slider-container|media-volume-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|meter|progress-bar|progress-bar-value|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield|-apple-pay-button","-webkit-border-before":"<'border-width'>||<'border-style'>||<color>","-webkit-border-before-color":"<color>","-webkit-border-before-style":"<'border-style'>","-webkit-border-before-width":"<'border-width'>","-webkit-box-reflect":"[above|below|right|left]? <length>? <image>?","-webkit-line-clamp":"none|<integer>","-webkit-mask":"[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#","-webkit-mask-attachment":"<attachment>#","-webkit-mask-clip":"[<box>|border|padding|content|text]#","-webkit-mask-composite":"<composite-style>#","-webkit-mask-image":"<mask-reference>#","-webkit-mask-origin":"[<box>|border|padding|content]#","-webkit-mask-position":"<position>#","-webkit-mask-position-x":"[<length-percentage>|left|center|right]#","-webkit-mask-position-y":"[<length-percentage>|top|center|bottom]#","-webkit-mask-repeat":"<repeat-style>#","-webkit-mask-repeat-x":"repeat|no-repeat|space|round","-webkit-mask-repeat-y":"repeat|no-repeat|space|round","-webkit-mask-size":"<bg-size>#","-webkit-overflow-scrolling":"auto|touch","-webkit-tap-highlight-color":"<color>","-webkit-text-fill-color":"<color>","-webkit-text-stroke":"<length>||<color>","-webkit-text-stroke-color":"<color>","-webkit-text-stroke-width":"<length>","-webkit-touch-callout":"default|none","-webkit-user-modify":"read-only|read-write|read-write-plaintext-only","accent-color":"auto|<color>","align-content":"normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>","align-items":"normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]","align-self":"auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>","align-tracks":"[normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>]#",all:"initial|inherit|unset|revert|revert-layer","anchor-name":"none|<dashed-ident>#","anchor-scope":"none|all|<dashed-ident>#",animation:"<single-animation>#","animation-composition":"<single-animation-composition>#","animation-delay":"<time>#","animation-direction":"<single-animation-direction>#","animation-duration":"<time>#","animation-fill-mode":"<single-animation-fill-mode>#","animation-iteration-count":"<single-animation-iteration-count>#","animation-name":"[none|<keyframes-name>]#","animation-play-state":"<single-animation-play-state>#","animation-range":"[<'animation-range-start'> <'animation-range-end'>?]#","animation-range-end":"[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#","animation-range-start":"[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#","animation-timing-function":"<easing-function>#","animation-timeline":"<single-animation-timeline>#",appearance:"none|auto|textfield|menulist-button|<compat-auto>","aspect-ratio":"auto||<ratio>",azimuth:"<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards","backdrop-filter":"none|<filter-function-list>","backface-visibility":"visible|hidden",background:"[<bg-layer> ,]* <final-bg-layer>","background-attachment":"<attachment>#","background-blend-mode":"<blend-mode>#","background-clip":"<bg-clip>#","background-color":"<color>","background-image":"<bg-image>#","background-origin":"<box>#","background-position":"<bg-position>#","background-position-x":"[center|[[left|right|x-start|x-end]? <length-percentage>?]!]#","background-position-y":"[center|[[top|bottom|y-start|y-end]? <length-percentage>?]!]#","background-repeat":"<repeat-style>#","background-size":"<bg-size>#","block-size":"<'width'>",border:"<line-width>||<line-style>||<color>","border-block":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-color":"<'border-top-color'>{1,2}","border-block-style":"<'border-top-style'>","border-block-width":"<'border-top-width'>","border-block-end":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-end-color":"<'border-top-color'>","border-block-end-style":"<'border-top-style'>","border-block-end-width":"<'border-top-width'>","border-block-start":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-start-color":"<'border-top-color'>","border-block-start-style":"<'border-top-style'>","border-block-start-width":"<'border-top-width'>","border-bottom":"<line-width>||<line-style>||<color>","border-bottom-color":"<'border-top-color'>","border-bottom-left-radius":"<length-percentage>{1,2}","border-bottom-right-radius":"<length-percentage>{1,2}","border-bottom-style":"<line-style>","border-bottom-width":"<line-width>","border-collapse":"collapse|separate","border-color":"<color>{1,4}","border-end-end-radius":"<length-percentage>{1,2}","border-end-start-radius":"<length-percentage>{1,2}","border-image":"<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>","border-image-outset":"[<length>|<number>]{1,4}","border-image-repeat":"[stretch|repeat|round|space]{1,2}","border-image-slice":"<number-percentage>{1,4}&&fill?","border-image-source":"none|<image>","border-image-width":"[<length-percentage>|<number>|auto]{1,4}","border-inline":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-end":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-color":"<'border-top-color'>{1,2}","border-inline-style":"<'border-top-style'>","border-inline-width":"<'border-top-width'>","border-inline-end-color":"<'border-top-color'>","border-inline-end-style":"<'border-top-style'>","border-inline-end-width":"<'border-top-width'>","border-inline-start":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-start-color":"<'border-top-color'>","border-inline-start-style":"<'border-top-style'>","border-inline-start-width":"<'border-top-width'>","border-left":"<line-width>||<line-style>||<color>","border-left-color":"<color>","border-left-style":"<line-style>","border-left-width":"<line-width>","border-radius":"<length-percentage>{1,4} [/ <length-percentage>{1,4}]?","border-right":"<line-width>||<line-style>||<color>","border-right-color":"<color>","border-right-style":"<line-style>","border-right-width":"<line-width>","border-spacing":"<length> <length>?","border-start-end-radius":"<length-percentage>{1,2}","border-start-start-radius":"<length-percentage>{1,2}","border-style":"<line-style>{1,4}","border-top":"<line-width>||<line-style>||<color>","border-top-color":"<color>","border-top-left-radius":"<length-percentage>{1,2}","border-top-right-radius":"<length-percentage>{1,2}","border-top-style":"<line-style>","border-top-width":"<line-width>","border-width":"<line-width>{1,4}",bottom:"<length>|<percentage>|auto","box-align":"start|center|end|baseline|stretch","box-decoration-break":"slice|clone","box-direction":"normal|reverse|inherit","box-flex":"<number>","box-flex-group":"<integer>","box-lines":"single|multiple","box-ordinal-group":"<integer>","box-orient":"horizontal|vertical|inline-axis|block-axis|inherit","box-pack":"start|center|end|justify","box-shadow":"none|<shadow>#","box-sizing":"content-box|border-box","break-after":"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region","break-before":"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region","break-inside":"auto|avoid|avoid-page|avoid-column|avoid-region","caption-side":"top|bottom|block-start|block-end|inline-start|inline-end",caret:"<'caret-color'>||<'caret-shape'>","caret-color":"auto|<color>","caret-shape":"auto|bar|block|underscore",clear:"none|left|right|both|inline-start|inline-end",clip:"<shape>|auto","clip-path":"<clip-source>|[<basic-shape>||<geometry-box>]|none","clip-rule":"nonzero|evenodd",color:"<color>","color-interpolation-filters":"auto|sRGB|linearRGB","color-scheme":"normal|[light|dark|<custom-ident>]+&&only?","column-count":"<integer>|auto","column-fill":"auto|balance","column-gap":"normal|<length-percentage>","column-rule":"<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>","column-rule-color":"<color>","column-rule-style":"<'border-style'>","column-rule-width":"<'border-width'>","column-span":"none|all","column-width":"<length>|auto",columns:"<'column-width'>||<'column-count'>",contain:"none|strict|content|[[size||inline-size]||layout||style||paint]","contain-intrinsic-size":"[auto? [none|<length>]]{1,2}","contain-intrinsic-block-size":"auto? [none|<length>]","contain-intrinsic-height":"auto? [none|<length>]","contain-intrinsic-inline-size":"auto? [none|<length>]","contain-intrinsic-width":"auto? [none|<length>]",container:"<'container-name'> [/ <'container-type'>]?","container-name":"none|<custom-ident>+","container-type":"normal||[size|inline-size]",content:"normal|none|[<content-replacement>|<content-list>] [/ [<string>|<counter>]+]?","content-visibility":"visible|auto|hidden","counter-increment":"[<counter-name> <integer>?]+|none","counter-reset":"[<counter-name> <integer>?|<reversed-counter-name> <integer>?]+|none","counter-set":"[<counter-name> <integer>?]+|none",cursor:"[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]",d:"none|path( <string> )",cx:"<length>|<percentage>",cy:"<length>|<percentage>",direction:"ltr|rtl",display:"[<display-outside>||<display-inside>]|<display-listitem>|<display-internal>|<display-box>|<display-legacy>|<-non-standard-display>","dominant-baseline":"auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge","empty-cells":"show|hide","field-sizing":"content|fixed",fill:"<paint>","fill-opacity":"<number-zero-one>","fill-rule":"nonzero|evenodd",filter:"none|<filter-function-list>|<-ms-filter-function-list>",flex:"none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]","flex-basis":"content|<'width'>","flex-direction":"row|row-reverse|column|column-reverse","flex-flow":"<'flex-direction'>||<'flex-wrap'>","flex-grow":"<number>","flex-shrink":"<number>","flex-wrap":"nowrap|wrap|wrap-reverse",float:"left|right|none|inline-start|inline-end",font:"[[<'font-style'>||<font-variant-css2>||<'font-weight'>||<font-width-css3>]? <'font-size'> [/ <'line-height'>]? <'font-family'>#]|<system-family-name>|<-non-standard-font>","font-family":"[<family-name>|<generic-family>]#","font-feature-settings":"normal|<feature-tag-value>#","font-kerning":"auto|normal|none","font-language-override":"normal|<string>","font-optical-sizing":"auto|none","font-palette":"normal|light|dark|<palette-identifier>","font-variation-settings":"normal|[<string> <number>]#","font-size":"<absolute-size>|<relative-size>|<length-percentage>","font-size-adjust":"none|[ex-height|cap-height|ch-width|ic-width|ic-height]? [from-font|<number>]","font-smooth":"auto|never|always|<absolute-size>|<length>","font-stretch":"<font-stretch-absolute>","font-style":"normal|italic|oblique <angle>?","font-synthesis":"none|[weight||style||small-caps||position]","font-synthesis-position":"auto|none","font-synthesis-small-caps":"auto|none","font-synthesis-style":"auto|none","font-synthesis-weight":"auto|none","font-variant":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]","font-variant-alternates":"normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]","font-variant-caps":"normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps","font-variant-east-asian":"normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]","font-variant-emoji":"normal|text|emoji|unicode","font-variant-ligatures":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]","font-variant-numeric":"normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]","font-variant-position":"normal|sub|super","font-weight":"<font-weight-absolute>|bolder|lighter","forced-color-adjust":"auto|none|preserve-parent-color",gap:"<'row-gap'> <'column-gap'>?",grid:"<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>","grid-area":"<grid-line> [/ <grid-line>]{0,3}","grid-auto-columns":"<track-size>+","grid-auto-flow":"[row|column]||dense","grid-auto-rows":"<track-size>+","grid-column":"<grid-line> [/ <grid-line>]?","grid-column-end":"<grid-line>","grid-column-gap":"<length-percentage>","grid-column-start":"<grid-line>","grid-gap":"<'grid-row-gap'> <'grid-column-gap'>?","grid-row":"<grid-line> [/ <grid-line>]?","grid-row-end":"<grid-line>","grid-row-gap":"<length-percentage>","grid-row-start":"<grid-line>","grid-template":"none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?","grid-template-areas":"none|<string>+","grid-template-columns":"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?","grid-template-rows":"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?","hanging-punctuation":"none|[first||[force-end|allow-end]||last]",height:"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","hyphenate-character":"auto|<string>","hyphenate-limit-chars":"[auto|<integer>]{1,3}",hyphens:"none|manual|auto","image-orientation":"from-image|<angle>|[<angle>? flip]","image-rendering":"auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>","image-resolution":"[from-image||<resolution>]&&snap?","ime-mode":"auto|normal|active|inactive|disabled","initial-letter":"normal|[<number> <integer>?]","initial-letter-align":"[auto|alphabetic|hanging|ideographic]","inline-size":"<'width'>","input-security":"auto|none",inset:"<'top'>{1,4}","inset-block":"<'top'>{1,2}","inset-block-end":"<'top'>","inset-block-start":"<'top'>","inset-inline":"<'top'>{1,2}","inset-inline-end":"<'top'>","inset-inline-start":"<'top'>","interpolate-size":"numeric-only|allow-keywords",isolation:"auto|isolate","justify-content":"normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]","justify-items":"normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]","justify-self":"auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]","justify-tracks":"[normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]]#",left:"<length>|<percentage>|auto","letter-spacing":"normal|<length-percentage>","line-break":"auto|loose|normal|strict|anywhere","line-clamp":"none|<integer>","line-height":"normal|<number>|<length>|<percentage>","line-height-step":"<length>","list-style":"<'list-style-type'>||<'list-style-position'>||<'list-style-image'>","list-style-image":"<image>|none","list-style-position":"inside|outside","list-style-type":"<counter-style>|<string>|none",margin:"[<length>|<percentage>|auto]{1,4}","margin-block":"<'margin-left'>{1,2}","margin-block-end":"<'margin-left'>","margin-block-start":"<'margin-left'>","margin-bottom":"<length>|<percentage>|auto","margin-inline":"<'margin-left'>{1,2}","margin-inline-end":"<'margin-left'>","margin-inline-start":"<'margin-left'>","margin-left":"<length>|<percentage>|auto","margin-right":"<length>|<percentage>|auto","margin-top":"<length>|<percentage>|auto","margin-trim":"none|in-flow|all",marker:"none|<url>","marker-end":"none|<url>","marker-mid":"none|<url>","marker-start":"none|<url>",mask:"<mask-layer>#","mask-border":"<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>","mask-border-mode":"luminance|alpha","mask-border-outset":"[<length>|<number>]{1,4}","mask-border-repeat":"[stretch|repeat|round|space]{1,2}","mask-border-slice":"<number-percentage>{1,4} fill?","mask-border-source":"none|<image>","mask-border-width":"[<length-percentage>|<number>|auto]{1,4}","mask-clip":"[<geometry-box>|no-clip]#","mask-composite":"<compositing-operator>#","mask-image":"<mask-reference>#","mask-mode":"<masking-mode>#","mask-origin":"<geometry-box>#","mask-position":"<position>#","mask-repeat":"<repeat-style>#","mask-size":"<bg-size>#","mask-type":"luminance|alpha","masonry-auto-flow":"[pack|next]||[definite-first|ordered]","math-depth":"auto-add|add( <integer> )|<integer>","math-shift":"normal|compact","math-style":"normal|compact","max-block-size":"<'max-width'>","max-height":"none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","max-inline-size":"<'max-width'>","max-lines":"none|<integer>","max-width":"none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","min-block-size":"<'min-width'>","min-height":"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","min-inline-size":"<'min-width'>","min-width":"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","mix-blend-mode":"<blend-mode>|plus-lighter","object-fit":"fill|contain|cover|none|scale-down","object-position":"<position>",offset:"[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?","offset-anchor":"auto|<position>","offset-distance":"<length-percentage>","offset-path":"none|<offset-path>||<coord-box>","offset-position":"normal|auto|<position>","offset-rotate":"[auto|reverse]||<angle>",opacity:"<alpha-value>",order:"<integer>",orphans:"<integer>",outline:"[<'outline-width'>||<'outline-style'>||<'outline-color'>]","outline-color":"auto|<color>","outline-offset":"<length>","outline-style":"auto|<'border-style'>","outline-width":"<line-width>",overflow:"[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>","overflow-anchor":"auto|none","overflow-block":"visible|hidden|clip|scroll|auto","overflow-clip-box":"padding-box|content-box","overflow-clip-margin":"<visual-box>||<length [0,\u221E]>","overflow-inline":"visible|hidden|clip|scroll|auto","overflow-wrap":"normal|break-word|anywhere","overflow-x":"visible|hidden|clip|scroll|auto","overflow-y":"visible|hidden|clip|scroll|auto",overlay:"none|auto","overscroll-behavior":"[contain|none|auto]{1,2}","overscroll-behavior-block":"contain|none|auto","overscroll-behavior-inline":"contain|none|auto","overscroll-behavior-x":"contain|none|auto","overscroll-behavior-y":"contain|none|auto",padding:"[<length>|<percentage>]{1,4}","padding-block":"<'padding-left'>{1,2}","padding-block-end":"<'padding-left'>","padding-block-start":"<'padding-left'>","padding-bottom":"<length>|<percentage>","padding-inline":"<'padding-left'>{1,2}","padding-inline-end":"<'padding-left'>","padding-inline-start":"<'padding-left'>","padding-left":"<length>|<percentage>","padding-right":"<length>|<percentage>","padding-top":"<length>|<percentage>",page:"auto|<custom-ident>","page-break-after":"auto|always|avoid|left|right|recto|verso","page-break-before":"auto|always|avoid|left|right|recto|verso","page-break-inside":"auto|avoid","paint-order":"normal|[fill||stroke||markers]",perspective:"none|<length>","perspective-origin":"<position>","place-content":"<'align-content'> <'justify-content'>?","place-items":"<'align-items'> <'justify-items'>?","place-self":"<'align-self'> <'justify-self'>?","pointer-events":"auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit",position:"static|relative|absolute|sticky|fixed|-webkit-sticky","position-anchor":"auto|<anchor-name>","position-area":"none|<position-area>","position-try":"<'position-try-order'>? <'position-try-fallbacks'>","position-try-fallbacks":"none|[[<dashed-ident>||<try-tactic>]|<'position-area'>]#","position-try-order":"normal|<try-size>","position-visibility":"always|[anchors-valid||anchors-visible||no-overflow]","print-color-adjust":"economy|exact",quotes:"none|auto|[<string> <string>]+",r:"<length>|<percentage>",resize:"none|both|horizontal|vertical|block|inline",right:"<length>|<percentage>|auto",rotate:"none|<angle>|[x|y|z|<number>{3}]&&<angle>","row-gap":"normal|<length-percentage>","ruby-align":"start|center|space-between|space-around","ruby-merge":"separate|collapse|auto","ruby-position":"[alternate||[over|under]]|inter-character",rx:"<length>|<percentage>",ry:"<length>|<percentage>",scale:"none|[<number>|<percentage>]{1,3}","scrollbar-color":"auto|<color>{2}","scrollbar-gutter":"auto|stable&&both-edges?","scrollbar-width":"auto|thin|none","scroll-behavior":"auto|smooth","scroll-margin":"<length>{1,4}","scroll-margin-block":"<length>{1,2}","scroll-margin-block-start":"<length>","scroll-margin-block-end":"<length>","scroll-margin-bottom":"<length>","scroll-margin-inline":"<length>{1,2}","scroll-margin-inline-start":"<length>","scroll-margin-inline-end":"<length>","scroll-margin-left":"<length>","scroll-margin-right":"<length>","scroll-margin-top":"<length>","scroll-padding":"[auto|<length-percentage>]{1,4}","scroll-padding-block":"[auto|<length-percentage>]{1,2}","scroll-padding-block-start":"auto|<length-percentage>","scroll-padding-block-end":"auto|<length-percentage>","scroll-padding-bottom":"auto|<length-percentage>","scroll-padding-inline":"[auto|<length-percentage>]{1,2}","scroll-padding-inline-start":"auto|<length-percentage>","scroll-padding-inline-end":"auto|<length-percentage>","scroll-padding-left":"auto|<length-percentage>","scroll-padding-right":"auto|<length-percentage>","scroll-padding-top":"auto|<length-percentage>","scroll-snap-align":"[none|start|end|center]{1,2}","scroll-snap-coordinate":"none|<position>#","scroll-snap-destination":"<position>","scroll-snap-points-x":"none|repeat( <length-percentage> )","scroll-snap-points-y":"none|repeat( <length-percentage> )","scroll-snap-stop":"normal|always","scroll-snap-type":"none|[x|y|block|inline|both] [mandatory|proximity]?","scroll-snap-type-x":"none|mandatory|proximity","scroll-snap-type-y":"none|mandatory|proximity","scroll-timeline":"[<'scroll-timeline-name'>||<'scroll-timeline-axis'>]#","scroll-timeline-axis":"[block|inline|x|y]#","scroll-timeline-name":"[none|<dashed-ident>]#","shape-image-threshold":"<alpha-value>","shape-margin":"<length-percentage>","shape-outside":"none|[<shape-box>||<basic-shape>]|<image>","shape-rendering":"auto|optimizeSpeed|crispEdges|geometricPrecision",stroke:"<paint>","stroke-dasharray":"none|[<svg-length>+]#","stroke-dashoffset":"<svg-length>","stroke-linecap":"butt|round|square","stroke-linejoin":"miter|round|bevel","stroke-miterlimit":"<number-one-or-greater>","stroke-opacity":"<'opacity'>","stroke-width":"<svg-length>","tab-size":"<integer>|<length>","table-layout":"auto|fixed","text-align":"start|end|left|right|center|justify|match-parent","text-align-last":"auto|start|end|left|right|center|justify","text-anchor":"start|middle|end","text-combine-upright":"none|all|[digits <integer>?]","text-decoration":"<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>||<'text-decoration-thickness'>","text-decoration-color":"<color>","text-decoration-line":"none|[underline||overline||line-through||blink]|spelling-error|grammar-error","text-decoration-skip":"none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]","text-decoration-skip-ink":"auto|all|none","text-decoration-style":"solid|double|dotted|dashed|wavy","text-decoration-thickness":"auto|from-font|<length>|<percentage>","text-emphasis":"<'text-emphasis-style'>||<'text-emphasis-color'>","text-emphasis-color":"<color>","text-emphasis-position":"auto|[over|under]&&[right|left]?","text-emphasis-style":"none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>","text-indent":"<length-percentage>&&hanging?&&each-line?","text-justify":"auto|inter-character|inter-word|none","text-orientation":"mixed|upright|sideways","text-overflow":"[clip|ellipsis|<string>]{1,2}","text-rendering":"auto|optimizeSpeed|optimizeLegibility|geometricPrecision","text-shadow":"none|<shadow-t>#","text-size-adjust":"none|auto|<percentage>","text-spacing-trim":"space-all|normal|space-first|trim-start|trim-both|trim-all|auto","text-transform":"none|capitalize|uppercase|lowercase|full-width|full-size-kana","text-underline-offset":"auto|<length>|<percentage>","text-underline-position":"auto|from-font|[under||[left|right]]","text-wrap":"<'text-wrap-mode'>||<'text-wrap-style'>","text-wrap-mode":"auto|wrap|nowrap","text-wrap-style":"auto|balance|stable|pretty","timeline-scope":"none|<dashed-ident>#",top:"<length>|<percentage>|auto","touch-action":"auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation",transform:"none|<transform-list>","transform-box":"content-box|border-box|fill-box|stroke-box|view-box","transform-origin":"[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?","transform-style":"flat|preserve-3d",transition:"<single-transition>#","transition-behavior":"<transition-behavior-value>#","transition-delay":"<time>#","transition-duration":"<time>#","transition-property":"none|<single-transition-property>#","transition-timing-function":"<easing-function>#",translate:"none|<length-percentage> [<length-percentage> <length>?]?","unicode-bidi":"normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate|-webkit-isolate-override|-webkit-plaintext","user-select":"auto|text|none|contain|all","vector-effect":"none|non-scaling-stroke|non-scaling-size|non-rotation|fixed-position","vertical-align":"baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>","view-timeline":"[<'view-timeline-name'> <'view-timeline-axis'>?]#","view-timeline-axis":"[block|inline|x|y]#","view-timeline-inset":"[[auto|<length-percentage>]{1,2}]#","view-timeline-name":"none|<dashed-ident>#","view-transition-name":"none|<custom-ident>",visibility:"visible|hidden|collapse","white-space":"normal|pre|nowrap|pre-wrap|pre-line|break-spaces|[<'white-space-collapse'>||<'text-wrap'>||<'white-space-trim'>]","white-space-collapse":"collapse|discard|preserve|preserve-breaks|preserve-spaces|break-spaces",widows:"<integer>",width:"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>","will-change":"auto|<animateable-feature>#","word-break":"normal|break-all|keep-all|break-word|auto-phrase","word-spacing":"normal|<length>","word-wrap":"normal|break-word","writing-mode":"horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>",x:"<length>|<percentage>",y:"<length>|<percentage>","z-index":"auto|<integer>",zoom:"normal|reset|<number>|<percentage>","-moz-background-clip":"padding|border","-moz-border-radius-bottomleft":"<'border-bottom-left-radius'>","-moz-border-radius-bottomright":"<'border-bottom-right-radius'>","-moz-border-radius-topleft":"<'border-top-left-radius'>","-moz-border-radius-topright":"<'border-bottom-right-radius'>","-moz-control-character-visibility":"visible|hidden","-moz-osx-font-smoothing":"auto|grayscale","-moz-user-select":"none|text|all|-moz-none","-ms-flex-align":"start|end|center|baseline|stretch","-ms-flex-item-align":"auto|start|end|center|baseline|stretch","-ms-flex-line-pack":"start|end|center|justify|distribute|stretch","-ms-flex-negative":"<'flex-shrink'>","-ms-flex-pack":"start|end|center|justify|distribute","-ms-flex-order":"<integer>","-ms-flex-positive":"<'flex-grow'>","-ms-flex-preferred-size":"<'flex-basis'>","-ms-interpolation-mode":"nearest-neighbor|bicubic","-ms-grid-column-align":"start|end|center|stretch","-ms-grid-row-align":"start|end|center|stretch","-ms-hyphenate-limit-last":"none|always|column|page|spread","-webkit-background-clip":"[<box>|border|padding|content|text]#","-webkit-column-break-after":"always|auto|avoid","-webkit-column-break-before":"always|auto|avoid","-webkit-column-break-inside":"always|auto|avoid","-webkit-font-smoothing":"auto|none|antialiased|subpixel-antialiased","-webkit-mask-box-image":"[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?","-webkit-print-color-adjust":"economy|exact","-webkit-text-security":"none|circle|disc|square","-webkit-user-drag":"none|element|auto","-webkit-user-select":"auto|none|text|all","alignment-baseline":"auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical","baseline-shift":"baseline|sub|super|<svg-length>",behavior:"<url>+",cue:"<'cue-before'> <'cue-after'>?","cue-after":"<url> <decibel>?|none","cue-before":"<url> <decibel>?|none","glyph-orientation-horizontal":"<angle>","glyph-orientation-vertical":"<angle>",kerning:"auto|<svg-length>",pause:"<'pause-before'> <'pause-after'>?","pause-after":"<time>|none|x-weak|weak|medium|strong|x-strong","pause-before":"<time>|none|x-weak|weak|medium|strong|x-strong",rest:"<'rest-before'> <'rest-after'>?","rest-after":"<time>|none|x-weak|weak|medium|strong|x-strong","rest-before":"<time>|none|x-weak|weak|medium|strong|x-strong",src:"[<url> [format( <string># )]?|local( <family-name> )]#",speak:"auto|never|always","speak-as":"normal|spell-out||digits||[literal-punctuation|no-punctuation]","unicode-range":"<urange>#","voice-balance":"<number>|left|center|right|leftwards|rightwards","voice-duration":"auto|<time>","voice-family":"[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve","voice-pitch":"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]","voice-range":"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]","voice-rate":"[normal|x-slow|slow|medium|fast|x-fast]||<percentage>","voice-stress":"normal|strong|moderate|none|reduced","voice-volume":"silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]","white-space-trim":"none|discard-before||discard-after||discard-inner"},atrules:{charset:{prelude:"<string>",descriptors:null},"counter-style":{prelude:"<counter-style-name>",descriptors:{"additive-symbols":"[<integer>&&<symbol>]#",fallback:"<counter-style-name>",negative:"<symbol> <symbol>?",pad:"<integer>&&<symbol>",prefix:"<symbol>",range:"[[<integer>|infinite]{2}]#|auto","speak-as":"auto|bullets|numbers|words|spell-out|<counter-style-name>",suffix:"<symbol>",symbols:"<symbol>+",system:"cyclic|numeric|alphabetic|symbolic|additive|[fixed <integer>?]|[extends <counter-style-name>]"}},document:{prelude:"[<url>|url-prefix( <string> )|domain( <string> )|media-document( <string> )|regexp( <string> )]#",descriptors:null},"font-palette-values":{prelude:"<dashed-ident>",descriptors:{"base-palette":"light|dark|<integer [0,\u221E]>","font-family":"<family-name>#","override-colors":"[<integer [0,\u221E]> <absolute-color-base>]#"}},"font-face":{prelude:null,descriptors:{"ascent-override":"normal|<percentage>","descent-override":"normal|<percentage>","font-display":"[auto|block|swap|fallback|optional]","font-family":"<family-name>","font-feature-settings":"normal|<feature-tag-value>#","font-variation-settings":"normal|[<string> <number>]#","font-stretch":"<font-stretch-absolute>{1,2}","font-style":"normal|italic|oblique <angle>{0,2}","font-weight":"<font-weight-absolute>{1,2}","line-gap-override":"normal|<percentage>","size-adjust":"<percentage>",src:"[<url> [format( <string># )]?|local( <family-name> )]#","unicode-range":"<urange>#"}},"font-feature-values":{prelude:"<family-name>#",descriptors:null},import:{prelude:"[<string>|<url>] [layer|layer( <layer-name> )]? [supports( [<supports-condition>|<declaration>] )]? <media-query-list>?",descriptors:null},keyframes:{prelude:"<keyframes-name>",descriptors:null},layer:{prelude:"[<layer-name>#|<layer-name>?]",descriptors:null},media:{prelude:"<media-query-list>",descriptors:null},namespace:{prelude:"<namespace-prefix>? [<string>|<url>]",descriptors:null},page:{prelude:"<page-selector-list>",descriptors:{bleed:"auto|<length>",marks:"none|[crop||cross]","page-orientation":"upright|rotate-left|rotate-right",size:"<length>{1,2}|auto|[<page-size>||[portrait|landscape]]"}},"position-try":{prelude:"<dashed-ident>",descriptors:{top:"<'top'>",left:"<'left'>",bottom:"<'bottom'>",right:"<'right'>","inset-block-start":"<'inset-block-start'>","inset-block-end":"<'inset-block-end'>","inset-inline-start":"<'inset-inline-start'>","inset-inline-end":"<'inset-inline-end'>","inset-block":"<'inset-block'>","inset-inline":"<'inset-inline'>",inset:"<'inset'>","margin-top":"<'margin-top'>","margin-left":"<'margin-left'>","margin-bottom":"<'margin-bottom'>","margin-right":"<'margin-right'>","margin-block-start":"<'margin-block-start'>","margin-block-end":"<'margin-block-end'>","margin-inline-start":"<'margin-inline-start'>","margin-inline-end":"<'margin-inline-end'>",margin:"<'margin'>","margin-block":"<'margin-block'>","margin-inline":"<'margin-inline'>",width:"<'width'>",height:"<'height'>","min-width":"<'min-width'>","min-height":"<'min-height'>","max-width":"<'max-width'>","max-height":"<'max-height'>","block-size":"<'block-size'>","inline-size":"<'inline-size'>","min-block-size":"<'min-block-size'>","min-inline-size":"<'min-inline-size'>","max-block-size":"<'max-block-size'>","max-inline-size":"<'max-inline-size'>","align-self":"<'align-self'>|anchor-center","justify-self":"<'justify-self'>|anchor-center"}},property:{prelude:"<custom-property-name>",descriptors:{syntax:"<string>",inherits:"true|false","initial-value":"<declaration-value>?"}},scope:{prelude:"[( <scope-start> )]? [to ( <scope-end> )]?",descriptors:null},"starting-style":{prelude:null,descriptors:null},supports:{prelude:"<supports-condition>",descriptors:null},container:{prelude:"[<container-name>]? <container-condition>",descriptors:null},nest:{prelude:"<complex-selector-list>",descriptors:null}}};var Tt={};x(Tt,{AnPlusB:()=>tn,Atrule:()=>nn,AtrulePrelude:()=>sn,AttributeSelector:()=>cn,Block:()=>pn,Brackets:()=>mn,CDC:()=>dn,CDO:()=>bn,ClassSelector:()=>yn,Combinator:()=>wn,Comment:()=>Sn,Condition:()=>Tn,Declaration:()=>Ln,DeclarationList:()=>Pn,Dimension:()=>Dn,Feature:()=>On,FeatureFunction:()=>Rn,FeatureRange:()=>_n,Function:()=>jn,GeneralEnclosed:()=>Un,Hash:()=>Gn,IdSelector:()=>Qn,Identifier:()=>Kn,Layer:()=>$n,LayerList:()=>Jn,MediaQuery:()=>ti,MediaQueryList:()=>ni,NestingSelector:()=>oi,Nth:()=>ai,Number:()=>ci,Operator:()=>pi,Parentheses:()=>mi,Percentage:()=>di,PseudoClassSelector:()=>bi,PseudoElementSelector:()=>yi,Ratio:()=>wi,Raw:()=>Si,Rule:()=>Ti,Scope:()=>Li,Selector:()=>zi,SelectorList:()=>Ii,String:()=>Fi,StyleSheet:()=>Mi,SupportsDeclaration:()=>_i,TypeSelector:()=>qi,UnicodeRange:()=>Gi,Url:()=>Xi,Value:()=>Zi,WhiteSpace:()=>eo});var tn={};x(tn,{generate:()=>Vc,name:()=>Yc,parse:()=>en,structure:()=>Kc});var de=43,re=45,tr=110,Re=!0,Gc=!1;function rr(e,t){let r=this.tokenStart+e,n=this.charCodeAt(r);for((n===de||n===re)&&(t&&this.error("Number sign is not allowed"),r++);r<this.tokenEnd;r++)j(this.charCodeAt(r))||this.error("Integer is expected",r)}function rt(e){return rr.call(this,0,e)}function Le(e,t){if(!this.cmpChar(this.tokenStart+e,t)){let r="";switch(t){case tr:r="N is expected";break;case re:r="HyphenMinus is expected";break}this.error(r,this.tokenStart+e)}}function Jr(){let e=0,t=0,r=this.tokenType;for(;r===13||r===25;)r=this.lookupType(++e);if(r!==10)if(this.isDelim(de,e)||this.isDelim(re,e)){t=this.isDelim(de,e)?de:re;do r=this.lookupType(++e);while(r===13||r===25);r!==10&&(this.skip(e),rt.call(this,Re))}else return null;return e>0&&this.skip(e),t===0&&(r=this.charCodeAt(this.tokenStart),r!==de&&r!==re&&this.error("Number sign is expected")),rt.call(this,t!==0),t===re?"-"+this.consume(10):this.consume(10)}var Yc="AnPlusB",Kc={a:[String,null],b:[String,null]};function en(){let e=this.tokenStart,t=null,r=null;if(this.tokenType===10)rt.call(this,Gc),r=this.consume(10);else if(this.tokenType===1&&this.cmpChar(this.tokenStart,re))switch(t="-1",Le.call(this,1,tr),this.tokenEnd-this.tokenStart){case 2:this.next(),r=Jr.call(this);break;case 3:Le.call(this,2,re),this.next(),this.skipSC(),rt.call(this,Re),r="-"+this.consume(10);break;default:Le.call(this,2,re),rr.call(this,3,Re),this.next(),r=this.substrToCursor(e+2)}else if(this.tokenType===1||this.isDelim(de)&&this.lookupType(1)===1){let n=0;switch(t="1",this.isDelim(de)&&(n=1,this.next()),Le.call(this,0,tr),this.tokenEnd-this.tokenStart){case 1:this.next(),r=Jr.call(this);break;case 2:Le.call(this,1,re),this.next(),this.skipSC(),rt.call(this,Re),r="-"+this.consume(10);break;default:Le.call(this,1,re),rr.call(this,2,Re),this.next(),r=this.substrToCursor(e+n+1)}}else if(this.tokenType===12){let n=this.charCodeAt(this.tokenStart),i=n===de||n===re,o=this.tokenStart+i;for(;o<this.tokenEnd&&j(this.charCodeAt(o));o++);o===this.tokenStart+i&&this.error("Integer is expected",this.tokenStart+i),Le.call(this,o-this.tokenStart,tr),t=this.substring(e,o),o+1===this.tokenEnd?(this.next(),r=Jr.call(this)):(Le.call(this,o-this.tokenStart+1,re),o+2===this.tokenEnd?(this.next(),this.skipSC(),rt.call(this,Re),r="-"+this.consume(10)):(rr.call(this,o-this.tokenStart+2,Re),this.next(),r=this.substrToCursor(o+1)))}else this.error();return t!==null&&t.charCodeAt(0)===de&&(t=t.substr(1)),r!==null&&r.charCodeAt(0)===de&&(r=r.substr(1)),{type:"AnPlusB",loc:this.getLocation(e,this.tokenStart),a:t,b:r}}function Vc(e){if(e.a){let t=e.a==="+1"&&"n"||e.a==="1"&&"n"||e.a==="-1"&&"-n"||e.a+"n";if(e.b){let r=e.b[0]==="-"||e.b[0]==="+"?e.b:"+"+e.b;this.tokenize(t+r)}else this.tokenize(t)}else this.tokenize(e.b)}var nn={};x(nn,{generate:()=>Jc,name:()=>Xc,parse:()=>rn,structure:()=>Zc,walkContext:()=>$c});function Bs(){return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon,!0)}function Qc(){for(let e=1,t;t=this.lookupType(e);e++){if(t===24)return!0;if(t===23||t===3)return!1}return!1}var Xc="Atrule",$c="atrule",Zc={name:String,prelude:["AtrulePrelude","Raw",null],block:["Block",null]};function rn(e=!1){let t=this.tokenStart,r,n,i=null,o=null;switch(this.eat(3),r=this.substrToCursor(t+1),n=r.toLowerCase(),this.skipSC(),this.eof===!1&&this.tokenType!==23&&this.tokenType!==17&&(this.parseAtrulePrelude?i=this.parseWithFallback(this.AtrulePrelude.bind(this,r,e),Bs):i=Bs.call(this,this.tokenIndex),this.skipSC()),this.tokenType){case 17:this.next();break;case 23:hasOwnProperty.call(this.atrule,n)&&typeof this.atrule[n].block=="function"?o=this.atrule[n].block.call(this,e):o=this.Block(Qc.call(this));break}return{type:"Atrule",loc:this.getLocation(t,this.tokenStart),name:r,prelude:i,block:o}}function Jc(e){this.token(3,"@"+e.name),e.prelude!==null&&this.node(e.prelude),e.block?this.node(e.block):this.token(17,";")}var sn={};x(sn,{generate:()=>nu,name:()=>eu,parse:()=>on,structure:()=>ru,walkContext:()=>tu});var eu="AtrulePrelude",tu="atrulePrelude",ru={children:[[]]};function on(e){let t=null;return e!==null&&(e=e.toLowerCase()),this.skipSC(),hasOwnProperty.call(this.atrule,e)&&typeof this.atrule[e].prelude=="function"?t=this.atrule[e].prelude.call(this):t=this.readSequence(this.scope.AtrulePrelude),this.skipSC(),this.eof!==!0&&this.tokenType!==23&&this.tokenType!==17&&this.error("Semicolon or block is expected"),{type:"AtrulePrelude",loc:this.getLocationFromList(t),children:t}}function nu(e){this.children(e)}var cn={};x(cn,{generate:()=>pu,name:()=>cu,parse:()=>ln,structure:()=>uu});var iu=36,_s=42,nr=61,ou=94,an=124,su=126;function au(){this.eof&&this.error("Unexpected end of input");let e=this.tokenStart,t=!1;return this.isDelim(_s)?(t=!0,this.next()):this.isDelim(an)||this.eat(1),this.isDelim(an)?this.charCodeAt(this.tokenStart+1)!==nr?(this.next(),this.eat(1)):t&&this.error("Identifier is expected",this.tokenEnd):t&&this.error("Vertical line is expected"),{type:"Identifier",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e)}}function lu(){let e=this.tokenStart,t=this.charCodeAt(e);return t!==nr&&t!==su&&t!==ou&&t!==iu&&t!==_s&&t!==an&&this.error("Attribute selector (=, ~=, ^=, $=, *=, |=) is expected"),this.next(),t!==nr&&(this.isDelim(nr)||this.error("Equal sign is expected"),this.next()),this.substrToCursor(e)}var cu="AttributeSelector",uu={name:"Identifier",matcher:[String,null],value:["String","Identifier",null],flags:[String,null]};function ln(){let e=this.tokenStart,t,r=null,n=null,i=null;return this.eat(19),this.skipSC(),t=au.call(this),this.skipSC(),this.tokenType!==20&&(this.tokenType!==1&&(r=lu.call(this),this.skipSC(),n=this.tokenType===5?this.String():this.Identifier(),this.skipSC()),this.tokenType===1&&(i=this.consume(1),this.skipSC())),this.eat(20),{type:"AttributeSelector",loc:this.getLocation(e,this.tokenStart),name:t,matcher:r,value:n,flags:i}}function pu(e){this.token(9,"["),this.node(e.name),e.matcher!==null&&(this.tokenize(e.matcher),this.node(e.value)),e.flags!==null&&this.token(1,e.flags),this.token(9,"]")}var pn={};x(pn,{generate:()=>bu,name:()=>fu,parse:()=>un,structure:()=>gu,walkContext:()=>du});var hu=38;function qs(){return this.Raw(null,!0)}function Ws(){return this.parseWithFallback(this.Rule,qs)}function js(){return this.Raw(this.consumeUntilSemicolonIncluded,!0)}function mu(){if(this.tokenType===17)return js.call(this,this.tokenIndex);let e=this.parseWithFallback(this.Declaration,js);return this.tokenType===17&&this.next(),e}var fu="Block",du="block",gu={children:[["Atrule","Rule","Declaration"]]};function un(e){let t=e?mu:Ws,r=this.tokenStart,n=this.createList();this.eat(23);e:for(;!this.eof;)switch(this.tokenType){case 24:break e;case 13:case 25:this.next();break;case 3:n.push(this.parseWithFallback(this.Atrule.bind(this,e),qs));break;default:e&&this.isDelim(hu)?n.push(Ws.call(this)):n.push(t.call(this))}return this.eof||this.eat(24),{type:"Block",loc:this.getLocation(r,this.tokenStart),children:n}}function bu(e){this.token(23,"{"),this.children(e,t=>{t.type==="Declaration"&&this.token(17,";")}),this.token(24,"}")}var mn={};x(mn,{generate:()=>ku,name:()=>xu,parse:()=>hn,structure:()=>yu});var xu="Brackets",yu={children:[[]]};function hn(e,t){let r=this.tokenStart,n=null;return this.eat(19),n=e.call(this,t),this.eof||this.eat(20),{type:"Brackets",loc:this.getLocation(r,this.tokenStart),children:n}}function ku(e){this.token(9,"["),this.children(e),this.token(9,"]")}var dn={};x(dn,{generate:()=>Su,name:()=>wu,parse:()=>fn,structure:()=>vu});var wu="CDC",vu=[];function fn(){let e=this.tokenStart;return this.eat(15),{type:"CDC",loc:this.getLocation(e,this.tokenStart)}}function Su(){this.token(15,"-->")}var bn={};x(bn,{generate:()=>Au,name:()=>Cu,parse:()=>gn,structure:()=>Tu});var Cu="CDO",Tu=[];function gn(){let e=this.tokenStart;return this.eat(14),{type:"CDO",loc:this.getLocation(e,this.tokenStart)}}function Au(){this.token(14,"<!--")}var yn={};x(yn,{generate:()=>Pu,name:()=>Eu,parse:()=>xn,structure:()=>zu});var Lu=46,Eu="ClassSelector",zu={name:String};function xn(){return this.eatDelim(Lu),{type:"ClassSelector",loc:this.getLocation(this.tokenStart-1,this.tokenEnd),name:this.consume(1)}}function Pu(e){this.token(9,"."),this.token(1,e.name)}var wn={};x(wn,{generate:()=>Ru,name:()=>Ou,parse:()=>kn,structure:()=>Fu});var Iu=43,Us=47,Du=62,Nu=126,Ou="Combinator",Fu={name:String};function kn(){let e=this.tokenStart,t;switch(this.tokenType){case 13:t=" ";break;case 9:switch(this.charCodeAt(this.tokenStart)){case Du:case Iu:case Nu:this.next();break;case Us:this.next(),this.eatIdent("deep"),this.eatDelim(Us);break;default:this.error("Combinator is expected")}t=this.substrToCursor(e);break}return{type:"Combinator",loc:this.getLocation(e,this.tokenStart),name:t}}function Ru(e){this.tokenize(e.name)}var Sn={};x(Sn,{generate:()=>ju,name:()=>_u,parse:()=>vn,structure:()=>Wu});var Mu=42,Bu=47,_u="Comment",Wu={value:String};function vn(){let e=this.tokenStart,t=this.tokenEnd;return this.eat(25),t-e+2>=2&&this.charCodeAt(t-2)===Mu&&this.charCodeAt(t-1)===Bu&&(t-=2),{type:"Comment",loc:this.getLocation(e,this.tokenStart),value:this.substring(e+2,t)}}function ju(e){this.token(25,"/*"+e.value+"*/")}var Tn={};x(Tn,{generate:()=>Yu,name:()=>Uu,parse:()=>Cn,structure:()=>Hu});var qu=new Set([16,22,0]),Uu="Condition",Hu={kind:String,children:[["Identifier","Feature","FeatureFunction","FeatureRange","SupportsDeclaration"]]};function Hs(e){return this.lookupTypeNonSC(1)===1&&qu.has(this.lookupTypeNonSC(2))?this.Feature(e):this.FeatureRange(e)}var Gu={media:Hs,container:Hs,supports(){return this.SupportsDeclaration()}};function Cn(e="media"){let t=this.createList();e:for(;!this.eof;)switch(this.tokenType){case 25:case 13:this.next();continue;case 1:t.push(this.Identifier());break;case 21:{let r=this.parseWithFallback(()=>Gu[e].call(this,e),()=>null);r||(r=this.parseWithFallback(()=>{this.eat(21);let n=this.Condition(e);return this.eat(22),n},()=>this.GeneralEnclosed(e))),t.push(r);break}case 2:{let r=this.parseWithFallback(()=>this.FeatureFunction(e),()=>null);r||(r=this.GeneralEnclosed(e)),t.push(r);break}default:break e}return t.isEmpty&&this.error("Condition is expected"),{type:"Condition",loc:this.getLocationFromList(t),kind:e,children:t}}function Yu(e){e.children.forEach(t=>{t.type==="Condition"?(this.token(21,"("),this.node(t),this.token(22,")")):this.node(t)})}var Ln={};x(Ln,{generate:()=>ip,name:()=>tp,parse:()=>An,structure:()=>np,walkContext:()=>rp});var Ys=33,Ku=35,Vu=36,Qu=38,Xu=42,$u=43,Gs=47;function Zu(){return this.Raw(this.consumeUntilExclamationMarkOrSemicolon,!0)}function Ju(){return this.Raw(this.consumeUntilExclamationMarkOrSemicolon,!1)}function ep(){let e=this.tokenIndex,t=this.Value();return t.type!=="Raw"&&this.eof===!1&&this.tokenType!==17&&this.isDelim(Ys)===!1&&this.isBalanceEdge(e)===!1&&this.error(),t}var tp="Declaration",rp="declaration",np={important:[Boolean,String],property:String,value:["Value","Raw"]};function An(){let e=this.tokenStart,t=this.tokenIndex,r=op.call(this),n=ht(r),i=n?this.parseCustomProperty:this.parseValue,o=n?Ju:Zu,a=!1,u;this.skipSC(),this.eat(16);let l=this.tokenIndex;if(n||this.skipSC(),i?u=this.parseWithFallback(ep,o):u=o.call(this,this.tokenIndex),n&&u.type==="Value"&&u.children.isEmpty){for(let s=l-this.tokenIndex;s<=0;s++)if(this.lookupType(s)===13){u.children.appendData({type:"WhiteSpace",loc:null,value:" "});break}}return this.isDelim(Ys)&&(a=sp.call(this),this.skipSC()),this.eof===!1&&this.tokenType!==17&&this.isBalanceEdge(t)===!1&&this.error(),{type:"Declaration",loc:this.getLocation(e,this.tokenStart),important:a,property:r,value:u}}function ip(e){this.token(1,e.property),this.token(16,":"),this.node(e.value),e.important&&(this.token(9,"!"),this.token(1,e.important===!0?"important":e.important))}function op(){let e=this.tokenStart;if(this.tokenType===9)switch(this.charCodeAt(this.tokenStart)){case Xu:case Vu:case $u:case Ku:case Qu:this.next();break;case Gs:this.next(),this.isDelim(Gs)&&this.next();break}return this.tokenType===4?this.eat(4):this.eat(1),this.substrToCursor(e)}function sp(){this.eat(9),this.skipSC();let e=this.consume(1);return e==="important"?!0:e}var Pn={};x(Pn,{generate:()=>up,name:()=>lp,parse:()=>zn,structure:()=>cp});var ap=38;function En(){return this.Raw(this.consumeUntilSemicolonIncluded,!0)}var lp="DeclarationList",cp={children:[["Declaration","Atrule","Rule"]]};function zn(){let e=this.createList();for(;!this.eof;)switch(this.tokenType){case 13:case 25:case 17:this.next();break;case 3:e.push(this.parseWithFallback(this.Atrule.bind(this,!0),En));break;default:this.isDelim(ap)?e.push(this.parseWithFallback(this.Rule,En)):e.push(this.parseWithFallback(this.Declaration,En))}return{type:"DeclarationList",loc:this.getLocationFromList(e),children:e}}function up(e){this.children(e,t=>{t.type==="Declaration"&&this.token(17,";")})}var Dn={};x(Dn,{generate:()=>mp,name:()=>pp,parse:()=>In,structure:()=>hp});var pp="Dimension",hp={value:String,unit:String};function In(){let e=this.tokenStart,t=this.consumeNumber(12);return{type:"Dimension",loc:this.getLocation(e,this.tokenStart),value:t,unit:this.substring(e+t.length,this.tokenStart)}}function mp(e){this.token(12,e.value+e.unit)}var On={};x(On,{generate:()=>bp,name:()=>dp,parse:()=>Nn,structure:()=>gp});var fp=47,dp="Feature",gp={kind:String,name:String,value:["Identifier","Number","Dimension","Ratio","Function",null]};function Nn(e){let t=this.tokenStart,r,n=null;if(this.eat(21),this.skipSC(),r=this.consume(1),this.skipSC(),this.tokenType!==22){switch(this.eat(16),this.skipSC(),this.tokenType){case 10:this.lookupNonWSType(1)===9?n=this.Ratio():n=this.Number();break;case 12:n=this.Dimension();break;case 1:n=this.Identifier();break;case 2:n=this.parseWithFallback(()=>{let i=this.Function(this.readSequence,this.scope.Value);return this.skipSC(),this.isDelim(fp)&&this.error(),i},()=>this.Ratio());break;default:this.error("Number, dimension, ratio or identifier is expected")}this.skipSC()}return this.eof||this.eat(22),{type:"Feature",loc:this.getLocation(t,this.tokenStart),kind:e,name:r,value:n}}function bp(e){this.token(21,"("),this.token(1,e.name),e.value!==null&&(this.token(16,":"),this.node(e.value)),this.token(22,")")}var Rn={};x(Rn,{generate:()=>wp,name:()=>xp,parse:()=>Fn,structure:()=>yp});var xp="FeatureFunction",yp={kind:String,feature:String,value:["Declaration","Selector"]};function kp(e,t){let n=(this.features[e]||{})[t];return typeof n!="function"&&this.error(`Unknown feature ${t}()`),n}function Fn(e="unknown"){let t=this.tokenStart,r=this.consumeFunctionName(),n=kp.call(this,e,r.toLowerCase());this.skipSC();let i=this.parseWithFallback(()=>{let o=this.tokenIndex,a=n.call(this);return this.eof===!1&&this.isBalanceEdge(o)===!1&&this.error(),a},()=>this.Raw(null,!1));return this.eof||this.eat(22),{type:"FeatureFunction",loc:this.getLocation(t,this.tokenStart),kind:e,feature:r,value:i}}function wp(e){this.token(2,e.feature+"("),this.node(e.value),this.token(22,")")}var _n={};x(_n,{generate:()=>Ap,name:()=>Cp,parse:()=>Bn,structure:()=>Tp});var Ks=47,vp=60,Vs=61,Sp=62,Cp="FeatureRange",Tp={kind:String,left:["Identifier","Number","Dimension","Ratio","Function"],leftComparison:String,middle:["Identifier","Number","Dimension","Ratio","Function"],rightComparison:[String,null],right:["Identifier","Number","Dimension","Ratio","Function",null]};function Mn(){switch(this.skipSC(),this.tokenType){case 10:return this.isDelim(Ks,this.lookupOffsetNonSC(1))?this.Ratio():this.Number();case 12:return this.Dimension();case 1:return this.Identifier();case 2:return this.parseWithFallback(()=>{let e=this.Function(this.readSequence,this.scope.Value);return this.skipSC(),this.isDelim(Ks)&&this.error(),e},()=>this.Ratio());default:this.error("Number, dimension, ratio or identifier is expected")}}function Qs(e){if(this.skipSC(),this.isDelim(vp)||this.isDelim(Sp)){let t=this.source[this.tokenStart];return this.next(),this.isDelim(Vs)?(this.next(),t+"="):t}if(this.isDelim(Vs))return"=";this.error(`Expected ${e?'":", ':""}"<", ">", "=" or ")"`)}function Bn(e="unknown"){let t=this.tokenStart;this.skipSC(),this.eat(21);let r=Mn.call(this),n=Qs.call(this,r.type==="Identifier"),i=Mn.call(this),o=null,a=null;return this.lookupNonWSType(0)!==22&&(o=Qs.call(this),a=Mn.call(this)),this.skipSC(),this.eat(22),{type:"FeatureRange",loc:this.getLocation(t,this.tokenStart),kind:e,left:r,leftComparison:n,middle:i,rightComparison:o,right:a}}function Ap(e){this.token(21,"("),this.node(e.left),this.tokenize(e.leftComparison),this.node(e.middle),e.right&&(this.tokenize(e.rightComparison),this.node(e.right)),this.token(22,")")}var jn={};x(jn,{generate:()=>Pp,name:()=>Lp,parse:()=>Wn,structure:()=>zp,walkContext:()=>Ep});var Lp="Function",Ep="function",zp={name:String,children:[[]]};function Wn(e,t){let r=this.tokenStart,n=this.consumeFunctionName(),i=n.toLowerCase(),o;return o=t.hasOwnProperty(i)?t[i].call(this,t):e.call(this,t),this.eof||this.eat(22),{type:"Function",loc:this.getLocation(r,this.tokenStart),name:n,children:o}}function Pp(e){this.token(2,e.name+"("),this.children(e),this.token(22,")")}var Un={};x(Un,{generate:()=>Np,name:()=>Ip,parse:()=>qn,structure:()=>Dp});var Ip="GeneralEnclosed",Dp={kind:String,function:[String,null],children:[[]]};function qn(e){let t=this.tokenStart,r=null;this.tokenType===2?r=this.consumeFunctionName():this.eat(21);let n=this.parseWithFallback(()=>{let i=this.tokenIndex,o=this.readSequence(this.scope.Value);return this.eof===!1&&this.isBalanceEdge(i)===!1&&this.error(),o},()=>this.createSingleNodeList(this.Raw(null,!1)));return this.eof||this.eat(22),{type:"GeneralEnclosed",loc:this.getLocation(t,this.tokenStart),kind:e,function:r,children:n}}function Np(e){e.function?this.token(2,e.function+"("):this.token(21,"("),this.children(e),this.token(22,")")}var Gn={};x(Gn,{generate:()=>Mp,name:()=>Fp,parse:()=>Hn,structure:()=>Rp,xxx:()=>Op});var Op="XXX",Fp="Hash",Rp={value:String};function Hn(){let e=this.tokenStart;return this.eat(4),{type:"Hash",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e+1)}}function Mp(e){this.token(4,"#"+e.value)}var Kn={};x(Kn,{generate:()=>Wp,name:()=>Bp,parse:()=>Yn,structure:()=>_p});var Bp="Identifier",_p={name:String};function Yn(){return{type:"Identifier",loc:this.getLocation(this.tokenStart,this.tokenEnd),name:this.consume(1)}}function Wp(e){this.token(1,e.name)}var Qn={};x(Qn,{generate:()=>Up,name:()=>jp,parse:()=>Vn,structure:()=>qp});var jp="IdSelector",qp={name:String};function Vn(){let e=this.tokenStart;return this.eat(4),{type:"IdSelector",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e+1)}}function Up(e){this.token(9,"#"+e.name)}var $n={};x($n,{generate:()=>Kp,name:()=>Gp,parse:()=>Xn,structure:()=>Yp});var Hp=46,Gp="Layer",Yp={name:String};function Xn(){let e=this.tokenStart,t=this.consume(1);for(;this.isDelim(Hp);)this.eat(9),t+="."+this.consume(1);return{type:"Layer",loc:this.getLocation(e,this.tokenStart),name:t}}function Kp(e){this.tokenize(e.name)}var Jn={};x(Jn,{generate:()=>Xp,name:()=>Vp,parse:()=>Zn,structure:()=>Qp});var Vp="LayerList",Qp={children:[["Layer"]]};function Zn(){let e=this.createList();for(this.skipSC();!this.eof&&(e.push(this.Layer()),this.lookupTypeNonSC(0)===18);)this.skipSC(),this.next(),this.skipSC();return{type:"LayerList",loc:this.getLocationFromList(e),children:e}}function Xp(e){this.children(e,()=>this.token(18,","))}var ti={};x(ti,{generate:()=>Jp,name:()=>$p,parse:()=>ei,structure:()=>Zp});var $p="MediaQuery",Zp={modifier:[String,null],mediaType:[String,null],condition:["Condition",null]};function ei(){let e=this.tokenStart,t=null,r=null,n=null;if(this.skipSC(),this.tokenType===1&&this.lookupTypeNonSC(1)!==21){let i=this.consume(1),o=i.toLowerCase();switch(o==="not"||o==="only"?(this.skipSC(),t=o,r=this.consume(1)):r=i,this.lookupTypeNonSC(0)){case 1:{this.skipSC(),this.eatIdent("and"),n=this.Condition("media");break}case 23:case 17:case 18:case 0:break;default:this.error("Identifier or parenthesis is expected")}}else switch(this.tokenType){case 1:case 21:case 2:{n=this.Condition("media");break}case 23:case 17:case 0:break;default:this.error("Identifier or parenthesis is expected")}return{type:"MediaQuery",loc:this.getLocation(e,this.tokenStart),modifier:t,mediaType:r,condition:n}}function Jp(e){e.mediaType?(e.modifier&&this.token(1,e.modifier),this.token(1,e.mediaType),e.condition&&(this.token(1,"and"),this.node(e.condition))):e.condition&&this.node(e.condition)}var ni={};x(ni,{generate:()=>rh,name:()=>eh,parse:()=>ri,structure:()=>th});var eh="MediaQueryList",th={children:[["MediaQuery"]]};function ri(){let e=this.createList();for(this.skipSC();!this.eof&&(e.push(this.MediaQuery()),this.tokenType===18);)this.next();return{type:"MediaQueryList",loc:this.getLocationFromList(e),children:e}}function rh(e){this.children(e,()=>this.token(18,","))}var oi={};x(oi,{generate:()=>sh,name:()=>ih,parse:()=>ii,structure:()=>oh});var nh=38,ih="NestingSelector",oh={};function ii(){let e=this.tokenStart;return this.eatDelim(nh),{type:"NestingSelector",loc:this.getLocation(e,this.tokenStart)}}function sh(){this.token(9,"&")}var ai={};x(ai,{generate:()=>ch,name:()=>ah,parse:()=>si,structure:()=>lh});var ah="Nth",lh={nth:["AnPlusB","Identifier"],selector:["SelectorList",null]};function si(){this.skipSC();let e=this.tokenStart,t=e,r=null,n;return this.lookupValue(0,"odd")||this.lookupValue(0,"even")?n=this.Identifier():n=this.AnPlusB(),t=this.tokenStart,this.skipSC(),this.lookupValue(0,"of")&&(this.next(),r=this.SelectorList(),t=this.tokenStart),{type:"Nth",loc:this.getLocation(e,t),nth:n,selector:r}}function ch(e){this.node(e.nth),e.selector!==null&&(this.token(1,"of"),this.node(e.selector))}var ci={};x(ci,{generate:()=>hh,name:()=>uh,parse:()=>li,structure:()=>ph});var uh="Number",ph={value:String};function li(){return{type:"Number",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:this.consume(10)}}function hh(e){this.token(10,e.value)}var pi={};x(pi,{generate:()=>dh,name:()=>mh,parse:()=>ui,structure:()=>fh});var mh="Operator",fh={value:String};function ui(){let e=this.tokenStart;return this.next(),{type:"Operator",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e)}}function dh(e){this.tokenize(e.value)}var mi={};x(mi,{generate:()=>xh,name:()=>gh,parse:()=>hi,structure:()=>bh});var gh="Parentheses",bh={children:[[]]};function hi(e,t){let r=this.tokenStart,n=null;return this.eat(21),n=e.call(this,t),this.eof||this.eat(22),{type:"Parentheses",loc:this.getLocation(r,this.tokenStart),children:n}}function xh(e){this.token(21,"("),this.children(e),this.token(22,")")}var di={};x(di,{generate:()=>wh,name:()=>yh,parse:()=>fi,structure:()=>kh});var yh="Percentage",kh={value:String};function fi(){return{type:"Percentage",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:this.consumeNumber(11)}}function wh(e){this.token(11,e.value+"%")}var bi={};x(bi,{generate:()=>Th,name:()=>vh,parse:()=>gi,structure:()=>Ch,walkContext:()=>Sh});var vh="PseudoClassSelector",Sh="function",Ch={name:String,children:[["Raw"],null]};function gi(){let e=this.tokenStart,t=null,r,n;return this.eat(16),this.tokenType===2?(r=this.consumeFunctionName(),n=r.toLowerCase(),this.lookupNonWSType(0)==22?t=this.createList():hasOwnProperty.call(this.pseudo,n)?(this.skipSC(),t=this.pseudo[n].call(this),this.skipSC()):(t=this.createList(),t.push(this.Raw(null,!1))),this.eat(22)):r=this.consume(1),{type:"PseudoClassSelector",loc:this.getLocation(e,this.tokenStart),name:r,children:t}}function Th(e){this.token(16,":"),e.children===null?this.token(1,e.name):(this.token(2,e.name+"("),this.children(e),this.token(22,")"))}var yi={};x(yi,{generate:()=>zh,name:()=>Ah,parse:()=>xi,structure:()=>Eh,walkContext:()=>Lh});var Ah="PseudoElementSelector",Lh="function",Eh={name:String,children:[["Raw"],null]};function xi(){let e=this.tokenStart,t=null,r,n;return this.eat(16),this.eat(16),this.tokenType===2?(r=this.consumeFunctionName(),n=r.toLowerCase(),this.lookupNonWSType(0)==22?t=this.createList():hasOwnProperty.call(this.pseudo,n)?(this.skipSC(),t=this.pseudo[n].call(this),this.skipSC()):(t=this.createList(),t.push(this.Raw(null,!1))),this.eat(22)):r=this.consume(1),{type:"PseudoElementSelector",loc:this.getLocation(e,this.tokenStart),name:r,children:t}}function zh(e){this.token(16,":"),this.token(16,":"),e.children===null?this.token(1,e.name):(this.token(2,e.name+"("),this.children(e),this.token(22,")"))}var wi={};x(wi,{generate:()=>Dh,name:()=>Ph,parse:()=>ki,structure:()=>Ih});var Xs=47;function $s(){switch(this.skipSC(),this.tokenType){case 10:return this.Number();case 2:return this.Function(this.readSequence,this.scope.Value);default:this.error("Number of function is expected")}}var Ph="Ratio",Ih={left:["Number","Function"],right:["Number","Function",null]};function ki(){let e=this.tokenStart,t=$s.call(this),r=null;return this.skipSC(),this.isDelim(Xs)&&(this.eatDelim(Xs),r=$s.call(this)),{type:"Ratio",loc:this.getLocation(e,this.tokenStart),left:t,right:r}}function Dh(e){this.node(e.left),this.token(9,"/"),e.right?this.node(e.right):this.node(10,1)}var Si={};x(Si,{generate:()=>Rh,name:()=>Oh,parse:()=>vi,structure:()=>Fh});function Nh(){return this.tokenIndex>0&&this.lookupType(-1)===13?this.tokenIndex>1?this.getTokenStart(this.tokenIndex-1):this.firstCharOffset:this.tokenStart}var Oh="Raw",Fh={value:String};function vi(e,t){let r=this.getTokenStart(this.tokenIndex),n;return this.skipUntilBalanced(this.tokenIndex,e||this.consumeUntilBalanceEnd),t&&this.tokenStart>r?n=Nh.call(this):n=this.tokenStart,{type:"Raw",loc:this.getLocation(r,n),value:this.substring(r,n)}}function Rh(e){this.tokenize(e.value)}var Ti={};x(Ti,{generate:()=>jh,name:()=>Bh,parse:()=>Ci,structure:()=>Wh,walkContext:()=>_h});function Zs(){return this.Raw(this.consumeUntilLeftCurlyBracket,!0)}function Mh(){let e=this.SelectorList();return e.type!=="Raw"&&this.eof===!1&&this.tokenType!==23&&this.error(),e}var Bh="Rule",_h="rule",Wh={prelude:["SelectorList","Raw"],block:["Block"]};function Ci(){let e=this.tokenIndex,t=this.tokenStart,r,n;return this.parseRulePrelude?r=this.parseWithFallback(Mh,Zs):r=Zs.call(this,e),n=this.Block(!0),{type:"Rule",loc:this.getLocation(t,this.tokenStart),prelude:r,block:n}}function jh(e){this.node(e.prelude),this.node(e.block)}var Li={};x(Li,{generate:()=>Hh,name:()=>qh,parse:()=>Ai,structure:()=>Uh});var qh="Scope",Uh={root:["SelectorList","Raw",null],limit:["SelectorList","Raw",null]};function Ai(){let e=null,t=null;this.skipSC();let r=this.tokenStart;return this.tokenType===21&&(this.next(),this.skipSC(),e=this.parseWithFallback(this.SelectorList,()=>this.Raw(!1,!0)),this.skipSC(),this.eat(22)),this.lookupNonWSType(0)===1&&(this.skipSC(),this.eatIdent("to"),this.skipSC(),this.eat(21),this.skipSC(),t=this.parseWithFallback(this.SelectorList,()=>this.Raw(!1,!0)),this.skipSC(),this.eat(22)),{type:"Scope",loc:this.getLocation(r,this.tokenStart),root:e,limit:t}}function Hh(e){e.root&&(this.token(21,"("),this.node(e.root),this.token(22,")")),e.limit&&(this.token(1,"to"),this.token(21,"("),this.node(e.limit),this.token(22,")"))}var zi={};x(zi,{generate:()=>Kh,name:()=>Gh,parse:()=>Ei,structure:()=>Yh});var Gh="Selector",Yh={children:[["TypeSelector","IdSelector","ClassSelector","AttributeSelector","PseudoClassSelector","PseudoElementSelector","Combinator"]]};function Ei(){let e=this.readSequence(this.scope.Selector);return this.getFirstListNode(e)===null&&this.error("Selector is expected"),{type:"Selector",loc:this.getLocationFromList(e),children:e}}function Kh(e){this.children(e)}var Ii={};x(Ii,{generate:()=>$h,name:()=>Vh,parse:()=>Pi,structure:()=>Xh,walkContext:()=>Qh});var Vh="SelectorList",Qh="selector",Xh={children:[["Selector","Raw"]]};function Pi(){let e=this.createList();for(;!this.eof;){if(e.push(this.Selector()),this.tokenType===18){this.next();continue}break}return{type:"SelectorList",loc:this.getLocationFromList(e),children:e}}function $h(e){this.children(e,()=>this.token(18,","))}var Fi={};x(Fi,{generate:()=>em,name:()=>Zh,parse:()=>Oi,structure:()=>Jh});var ir={};x(ir,{decode:()=>St,encode:()=>Ni});var Di=92,Js=34,ea=39;function St(e){let t=e.length,r=e.charCodeAt(0),n=r===Js||r===ea?1:0,i=n===1&&t>1&&e.charCodeAt(t-1)===r?t-2:t-1,o="";for(let a=n;a<=i;a++){let u=e.charCodeAt(a);if(u===Di){if(a===i){a!==t-1&&(o=e.substr(a+1));break}if(u=e.charCodeAt(++a),Z(Di,u)){let l=a-1,s=ae(e,l);a=s-1,o+=Ue(e.substring(l+1,s))}else u===13&&e.charCodeAt(a+1)===10&&a++}else o+=e[a]}return o}function Ni(e,t){let r=t?"'":'"',n=t?ea:Js,i="",o=!1;for(let a=0;a<e.length;a++){let u=e.charCodeAt(a);if(u===0){i+="\uFFFD";continue}if(u<=31||u===127){i+="\\"+u.toString(16),o=!0;continue}u===n||u===Di?(i+="\\"+e.charAt(a),o=!1):(o&&(te(u)||pe(u))&&(i+=" "),i+=e.charAt(a),o=!1)}return r+i+r}var Zh="String",Jh={value:String};function Oi(){return{type:"String",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:St(this.consume(5))}}function em(e){this.token(5,Ni(e.value))}var Mi={};x(Mi,{generate:()=>om,name:()=>rm,parse:()=>Ri,structure:()=>im,walkContext:()=>nm});var tm=33;function ta(){return this.Raw(null,!1)}var rm="StyleSheet",nm="stylesheet",im={children:[["Comment","CDO","CDC","Atrule","Rule","Raw"]]};function Ri(){let e=this.tokenStart,t=this.createList(),r;for(;!this.eof;){switch(this.tokenType){case 13:this.next();continue;case 25:if(this.charCodeAt(this.tokenStart+2)!==tm){this.next();continue}r=this.Comment();break;case 14:r=this.CDO();break;case 15:r=this.CDC();break;case 3:r=this.parseWithFallback(this.Atrule,ta);break;default:r=this.parseWithFallback(this.Rule,ta)}t.push(r)}return{type:"StyleSheet",loc:this.getLocation(e,this.tokenStart),children:t}}function om(e){this.children(e)}var _i={};x(_i,{generate:()=>lm,name:()=>sm,parse:()=>Bi,structure:()=>am});var sm="SupportsDeclaration",am={declaration:"Declaration"};function Bi(){let e=this.tokenStart;this.eat(21),this.skipSC();let t=this.Declaration();return this.eof||this.eat(22),{type:"SupportsDeclaration",loc:this.getLocation(e,this.tokenStart),declaration:t}}function lm(e){this.token(21,"("),this.node(e.declaration),this.token(22,")")}var qi={};x(qi,{generate:()=>hm,name:()=>um,parse:()=>ji,structure:()=>pm});var cm=42,ra=124;function Wi(){this.tokenType!==1&&this.isDelim(cm)===!1&&this.error("Identifier or asterisk is expected"),this.next()}var um="TypeSelector",pm={name:String};function ji(){let e=this.tokenStart;return this.isDelim(ra)?(this.next(),Wi.call(this)):(Wi.call(this),this.isDelim(ra)&&(this.next(),Wi.call(this))),{type:"TypeSelector",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e)}}function hm(e){this.tokenize(e.name)}var Gi={};x(Gi,{generate:()=>bm,name:()=>dm,parse:()=>Hi,structure:()=>gm});var na=43,ia=45,Ui=63;function Ct(e,t){let r=0;for(let n=this.tokenStart+e;n<this.tokenEnd;n++){let i=this.charCodeAt(n);if(i===ia&&t&&r!==0)return Ct.call(this,e+r+1,!1),-1;te(i)||this.error(t&&r!==0?"Hyphen minus"+(r<6?" or hex digit":"")+" is expected":r<6?"Hex digit is expected":"Unexpected input",n),++r>6&&this.error("Too many hex digits",n)}return this.next(),r}function or(e){let t=0;for(;this.isDelim(Ui);)++t>e&&this.error("Too many question marks"),this.next()}function mm(e){this.charCodeAt(this.tokenStart)!==e&&this.error((e===na?"Plus sign":"Hyphen minus")+" is expected")}function fm(){let e=0;switch(this.tokenType){case 10:if(e=Ct.call(this,1,!0),this.isDelim(Ui)){or.call(this,6-e);break}if(this.tokenType===12||this.tokenType===10){mm.call(this,ia),Ct.call(this,1,!1);break}break;case 12:e=Ct.call(this,1,!0),e>0&&or.call(this,6-e);break;default:if(this.eatDelim(na),this.tokenType===1){e=Ct.call(this,0,!0),e>0&&or.call(this,6-e);break}if(this.isDelim(Ui)){this.next(),or.call(this,5);break}this.error("Hex digit or question mark is expected")}}var dm="UnicodeRange",gm={value:String};function Hi(){let e=this.tokenStart;return this.eatIdent("u"),fm.call(this),{type:"UnicodeRange",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e)}}function bm(e){this.tokenize(e.value)}var Xi={};x(Xi,{generate:()=>Cm,name:()=>vm,parse:()=>Qi,structure:()=>Sm});var sr={};x(sr,{decode:()=>Ki,encode:()=>Vi});var xm=32,Yi=92,ym=34,km=39,wm=40,oa=41;function Ki(e){let t=e.length,r=4,n=e.charCodeAt(t-1)===oa?t-2:t-1,i="";for(;r<n&&pe(e.charCodeAt(r));)r++;for(;r<n&&pe(e.charCodeAt(n));)n--;for(let o=r;o<=n;o++){let a=e.charCodeAt(o);if(a===Yi){if(o===n){o!==t-1&&(i=e.substr(o+1));break}if(a=e.charCodeAt(++o),Z(Yi,a)){let u=o-1,l=ae(e,u);o=l-1,i+=Ue(e.substring(u+1,l))}else a===13&&e.charCodeAt(o+1)===10&&o++}else i+=e[o]}return i}function Vi(e){let t="",r=!1;for(let n=0;n<e.length;n++){let i=e.charCodeAt(n);if(i===0){t+="\uFFFD";continue}if(i<=31||i===127){t+="\\"+i.toString(16),r=!0;continue}i===xm||i===Yi||i===ym||i===km||i===wm||i===oa?(t+="\\"+e.charAt(n),r=!1):(r&&te(i)&&(t+=" "),t+=e.charAt(n),r=!1)}return"url("+t+")"}var vm="Url",Sm={value:String};function Qi(){let e=this.tokenStart,t;switch(this.tokenType){case 7:t=Ki(this.consume(7));break;case 2:this.cmpStr(this.tokenStart,this.tokenEnd,"url(")||this.error("Function name must be `url`"),this.eat(2),this.skipSC(),t=St(this.consume(5)),this.skipSC(),this.eof||this.eat(22);break;default:this.error("Url or Function is expected")}return{type:"Url",loc:this.getLocation(e,this.tokenStart),value:t}}function Cm(e){this.token(7,Vi(e.value))}var Zi={};x(Zi,{generate:()=>Lm,name:()=>Tm,parse:()=>$i,structure:()=>Am});var Tm="Value",Am={children:[[]]};function $i(){let e=this.tokenStart,t=this.readSequence(this.scope.Value);return{type:"Value",loc:this.getLocation(e,this.tokenStart),children:t}}function Lm(e){this.children(e)}var eo={};x(eo,{generate:()=>Im,name:()=>zm,parse:()=>Ji,structure:()=>Pm});var Em=Object.freeze({type:"WhiteSpace",loc:null,value:" "}),zm="WhiteSpace",Pm={value:String};function Ji(){return this.eat(13),Em}function Im(e){this.token(13,e.value)}var sa={generic:!0,cssWideKeywords:$e,...Ms,node:Tt};var to={};x(to,{AtrulePrelude:()=>la,Selector:()=>ua,Value:()=>fa});var Dm=35,Nm=42,aa=43,Om=45,Fm=47,Rm=117;function At(e){switch(this.tokenType){case 4:return this.Hash();case 18:return this.Operator();case 21:return this.Parentheses(this.readSequence,e.recognizer);case 19:return this.Brackets(this.readSequence,e.recognizer);case 5:return this.String();case 12:return this.Dimension();case 11:return this.Percentage();case 10:return this.Number();case 2:return this.cmpStr(this.tokenStart,this.tokenEnd,"url(")?this.Url():this.Function(this.readSequence,e.recognizer);case 7:return this.Url();case 1:return this.cmpChar(this.tokenStart,Rm)&&this.cmpChar(this.tokenStart+1,aa)?this.UnicodeRange():this.Identifier();case 9:{let t=this.charCodeAt(this.tokenStart);if(t===Fm||t===Nm||t===aa||t===Om)return this.Operator();t===Dm&&this.error("Hex or identifier is expected",this.tokenStart+1);break}}}var la={getNode:At};var Mm=35,Bm=38,_m=42,Wm=43,jm=47,ca=46,qm=62,Um=124,Hm=126;function Gm(e,t){t.last!==null&&t.last.type!=="Combinator"&&e!==null&&e.type!=="Combinator"&&t.push({type:"Combinator",loc:null,name:" "})}function Ym(){switch(this.tokenType){case 19:return this.AttributeSelector();case 4:return this.IdSelector();case 16:return this.lookupType(1)===16?this.PseudoElementSelector():this.PseudoClassSelector();case 1:return this.TypeSelector();case 10:case 11:return this.Percentage();case 12:this.charCodeAt(this.tokenStart)===ca&&this.error("Identifier is expected",this.tokenStart+1);break;case 9:{switch(this.charCodeAt(this.tokenStart)){case Wm:case qm:case Hm:case jm:return this.Combinator();case ca:return this.ClassSelector();case _m:case Um:return this.TypeSelector();case Mm:return this.IdSelector();case Bm:return this.NestingSelector()}break}}}var ua={onWhiteSpace:Gm,getNode:Ym};function pa(){return this.createSingleNodeList(this.Raw(null,!1))}function ha(){let e=this.createList();if(this.skipSC(),e.push(this.Identifier()),this.skipSC(),this.tokenType===18){e.push(this.Operator());let t=this.tokenIndex,r=this.parseCustomProperty?this.Value(null):this.Raw(this.consumeUntilExclamationMarkOrSemicolon,!1);if(r.type==="Value"&&r.children.isEmpty){for(let n=t-this.tokenIndex;n<=0;n++)if(this.lookupType(n)===13){r.children.appendData({type:"WhiteSpace",loc:null,value:" "});break}}e.push(r)}return e}function ma(e){return e!==null&&e.type==="Operator"&&(e.value[e.value.length-1]==="-"||e.value[e.value.length-1]==="+")}var fa={getNode:At,onWhiteSpace(e,t){ma(e)&&(e.value=" "+e.value),ma(t.last)&&(t.last.value+=" ")},expression:pa,var:ha};var Km=new Set(["none","and","not","or"]),da={parse:{prelude(){let e=this.createList();if(this.tokenType===1){let t=this.substring(this.tokenStart,this.tokenEnd);Km.has(t.toLowerCase())||e.push(this.Identifier())}return e.push(this.Condition("container")),e},block(e=!1){return this.Block(e)}}};var ga={parse:{prelude:null,block(){return this.Block(!0)}}};function ro(e,t){return this.parseWithFallback(()=>{try{return e.call(this)}finally{this.skipSC(),this.lookupNonWSType(0)!==22&&this.error()}},t||(()=>this.Raw(null,!0)))}var ba={layer(){this.skipSC();let e=this.createList(),t=ro.call(this,this.Layer);return(t.type!=="Raw"||t.value!=="")&&e.push(t),e},supports(){this.skipSC();let e=this.createList(),t=ro.call(this,this.Declaration,()=>ro.call(this,()=>this.Condition("supports")));return(t.type!=="Raw"||t.value!=="")&&e.push(t),e}},xa={parse:{prelude(){let e=this.createList();switch(this.tokenType){case 5:e.push(this.String());break;case 7:case 2:e.push(this.Url());break;default:this.error("String or url() is expected")}return this.skipSC(),this.tokenType===1&&this.cmpStr(this.tokenStart,this.tokenEnd,"layer")?e.push(this.Identifier()):this.tokenType===2&&this.cmpStr(this.tokenStart,this.tokenEnd,"layer(")&&e.push(this.Function(null,ba)),this.skipSC(),this.tokenType===2&&this.cmpStr(this.tokenStart,this.tokenEnd,"supports(")&&e.push(this.Function(null,ba)),(this.lookupNonWSType(0)===1||this.lookupNonWSType(0)===21)&&e.push(this.MediaQueryList()),e},block:null}};var ya={parse:{prelude(){return this.createSingleNodeList(this.LayerList())},block(){return this.Block(!1)}}};var ka={parse:{prelude(){return this.createSingleNodeList(this.MediaQueryList())},block(e=!1){return this.Block(e)}}};var wa={parse:{prelude(){return this.createSingleNodeList(this.SelectorList())},block(){return this.Block(!0)}}};var va={parse:{prelude(){return this.createSingleNodeList(this.SelectorList())},block(){return this.Block(!0)}}};var Sa={parse:{prelude(){return this.createSingleNodeList(this.Scope())},block(e=!1){return this.Block(e)}}};var Ca={parse:{prelude:null,block(e=!1){return this.Block(e)}}};var Ta={parse:{prelude(){return this.createSingleNodeList(this.Condition("supports"))},block(e=!1){return this.Block(e)}}};var Aa={container:da,"font-face":ga,import:xa,layer:ya,media:ka,nest:wa,page:va,scope:Sa,"starting-style":Ca,supports:Ta};function La(){let e=this.createList();this.skipSC();e:for(;!this.eof;){switch(this.tokenType){case 1:e.push(this.Identifier());break;case 5:e.push(this.String());break;case 18:e.push(this.Operator());break;case 22:break e;default:this.error("Identifier, string or comma is expected")}this.skipSC()}return e}var Me={parse(){return this.createSingleNodeList(this.SelectorList())}},no={parse(){return this.createSingleNodeList(this.Selector())}},Vm={parse(){return this.createSingleNodeList(this.Identifier())}},Qm={parse:La},ar={parse(){return this.createSingleNodeList(this.Nth())}},Ea={dir:Vm,has:Me,lang:Qm,matches:Me,is:Me,"-moz-any":Me,"-webkit-any":Me,where:Me,not:Me,"nth-child":ar,"nth-last-child":ar,"nth-last-of-type":ar,"nth-of-type":ar,slotted:no,host:no,"host-context":no};var io={};x(io,{AnPlusB:()=>en,Atrule:()=>rn,AtrulePrelude:()=>on,AttributeSelector:()=>ln,Block:()=>un,Brackets:()=>hn,CDC:()=>fn,CDO:()=>gn,ClassSelector:()=>xn,Combinator:()=>kn,Comment:()=>vn,Condition:()=>Cn,Declaration:()=>An,DeclarationList:()=>zn,Dimension:()=>In,Feature:()=>Nn,FeatureFunction:()=>Fn,FeatureRange:()=>Bn,Function:()=>Wn,GeneralEnclosed:()=>qn,Hash:()=>Hn,IdSelector:()=>Vn,Identifier:()=>Yn,Layer:()=>Xn,LayerList:()=>Zn,MediaQuery:()=>ei,MediaQueryList:()=>ri,NestingSelector:()=>ii,Nth:()=>si,Number:()=>li,Operator:()=>ui,Parentheses:()=>hi,Percentage:()=>fi,PseudoClassSelector:()=>gi,PseudoElementSelector:()=>xi,Ratio:()=>ki,Raw:()=>vi,Rule:()=>Ci,Scope:()=>Ai,Selector:()=>Ei,SelectorList:()=>Pi,String:()=>Oi,StyleSheet:()=>Ri,SupportsDeclaration:()=>Bi,TypeSelector:()=>ji,UnicodeRange:()=>Hi,Url:()=>Qi,Value:()=>$i,WhiteSpace:()=>Ji});var za={parseContext:{default:"StyleSheet",stylesheet:"StyleSheet",atrule:"Atrule",atrulePrelude(e){return this.AtrulePrelude(e.atrule?String(e.atrule):null)},mediaQueryList:"MediaQueryList",mediaQuery:"MediaQuery",condition(e){return this.Condition(e.kind)},rule:"Rule",selectorList:"SelectorList",selector:"Selector",block(){return this.Block(!0)},declarationList:"DeclarationList",declaration:"Declaration",value:"Value"},features:{supports:{selector(){return this.Selector()}},container:{style(){return this.Declaration()}}},scope:to,atrule:Aa,pseudo:Ea,node:io};var Pa={node:Tt};var Ia=er({...sa,...za,...Pa});var Xm="3.0.1";function lr(e){let t={};for(let r of Object.keys(e)){let n=e[r];n&&(Array.isArray(n)||n instanceof X?n=n.map(lr):n.constructor===Object&&(n=lr(n))),t[r]=n}return t}var oo={};x(oo,{decode:()=>$m,encode:()=>Zm});var Da=92;function $m(e){let t=e.length-1,r="";for(let n=0;n<e.length;n++){let i=e.charCodeAt(n);if(i===Da){if(n===t)break;if(i=e.charCodeAt(++n),Z(Da,i)){let o=n-1,a=ae(e,o);n=a-1,r+=Ue(e.substring(o+1,a))}else i===13&&e.charCodeAt(n+1)===10&&n++}else r+=e[n]}return r}function Zm(e){let t="";if(e.length===1&&e.charCodeAt(0)===45)return"\\-";for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);if(n===0){t+="\uFFFD";continue}if(n<=31||n===127||n>=48&&n<=57&&(r===0||r===1&&e.charCodeAt(0)===45)){t+="\\"+n.toString(16)+" ";continue}We(n)?t+=e.charAt(r):t+="\\"+e.charAt(r)}return t}var{tokenize:Jm,parse:ef,generate:tf,lexer:rf,createLexer:nf,walk:of,find:sf,findLast:af,findAll:lf,toPlainObject:cf,fromPlainObject:uf,fork:pf}=Ia;return _a(hf);})(); diff --git a/vanilla/node_modules/css-tree/dist/data.cjs b/vanilla/node_modules/css-tree/dist/data.cjs new file mode 100644 index 0000000..4a5538c --- /dev/null +++ b/vanilla/node_modules/css-tree/dist/data.cjs @@ -0,0 +1,1308 @@ +module.exports = { + "generic": true, + "cssWideKeywords": [ + "initial", + "inherit", + "unset", + "revert", + "revert-layer" + ], + "units": { + "angle": [ + "deg", + "grad", + "rad", + "turn" + ], + "decibel": [ + "db" + ], + "flex": [ + "fr" + ], + "frequency": [ + "hz", + "khz" + ], + "length": [ + "cm", + "mm", + "q", + "in", + "pt", + "pc", + "px", + "em", + "rem", + "ex", + "rex", + "cap", + "rcap", + "ch", + "rch", + "ic", + "ric", + "lh", + "rlh", + "vw", + "svw", + "lvw", + "dvw", + "vh", + "svh", + "lvh", + "dvh", + "vi", + "svi", + "lvi", + "dvi", + "vb", + "svb", + "lvb", + "dvb", + "vmin", + "svmin", + "lvmin", + "dvmin", + "vmax", + "svmax", + "lvmax", + "dvmax", + "cqw", + "cqh", + "cqi", + "cqb", + "cqmin", + "cqmax" + ], + "resolution": [ + "dpi", + "dpcm", + "dppx", + "x" + ], + "semitones": [ + "st" + ], + "time": [ + "s", + "ms" + ] + }, + "types": { + "abs()": "abs( <calc-sum> )", + "absolute-size": "xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large", + "acos()": "acos( <calc-sum> )", + "alpha-value": "<number>|<percentage>", + "angle-percentage": "<angle>|<percentage>", + "angular-color-hint": "<angle-percentage>", + "angular-color-stop": "<color>&&<color-stop-angle>?", + "angular-color-stop-list": "[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>", + "animateable-feature": "scroll-position|contents|<custom-ident>", + "asin()": "asin( <calc-sum> )", + "atan()": "atan( <calc-sum> )", + "atan2()": "atan2( <calc-sum> , <calc-sum> )", + "attachment": "scroll|fixed|local", + "attr()": "attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )", + "attr-matcher": "['~'|'|'|'^'|'$'|'*']? '='", + "attr-modifier": "i|s", + "attribute-selector": "'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'", + "auto-repeat": "repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )", + "auto-track-list": "[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?", + "axis": "block|inline|x|y", + "baseline-position": "[first|last]? baseline", + "basic-shape": "<inset()>|<xywh()>|<rect()>|<circle()>|<ellipse()>|<polygon()>|<path()>", + "bg-image": "none|<image>", + "bg-layer": "<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>", + "bg-position": "[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]", + "bg-size": "[<length-percentage>|auto]{1,2}|cover|contain", + "blur()": "blur( <length> )", + "blend-mode": "normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity", + "box": "border-box|padding-box|content-box", + "brightness()": "brightness( <number-percentage> )", + "calc()": "calc( <calc-sum> )", + "calc-sum": "<calc-product> [['+'|'-'] <calc-product>]*", + "calc-product": "<calc-value> ['*' <calc-value>|'/' <number>]*", + "calc-value": "<number>|<dimension>|<percentage>|<calc-constant>|( <calc-sum> )", + "calc-constant": "e|pi|infinity|-infinity|NaN", + "cf-final-image": "<image>|<color>", + "cf-mixing-image": "<percentage>?&&<image>", + "circle()": "circle( [<shape-radius>]? [at <position>]? )", + "clamp()": "clamp( <calc-sum>#{3} )", + "class-selector": "'.' <ident-token>", + "clip-source": "<url>", + "color": "<color-base>|currentColor|<system-color>|<device-cmyk()>|<light-dark()>|<-non-standard-color>", + "color-stop": "<color-stop-length>|<color-stop-angle>", + "color-stop-angle": "<angle-percentage>{1,2}", + "color-stop-length": "<length-percentage>{1,2}", + "color-stop-list": "[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>", + "color-interpolation-method": "in [<rectangular-color-space>|<polar-color-space> <hue-interpolation-method>?|<custom-color-space>]", + "combinator": "'>'|'+'|'~'|['|' '|']", + "common-lig-values": "[common-ligatures|no-common-ligatures]", + "compat-auto": "searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button", + "composite-style": "clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor", + "compositing-operator": "add|subtract|intersect|exclude", + "compound-selector": "[<type-selector>? <subclass-selector>*]!", + "compound-selector-list": "<compound-selector>#", + "complex-selector": "<complex-selector-unit> [<combinator>? <complex-selector-unit>]*", + "complex-selector-list": "<complex-selector>#", + "conic-gradient()": "conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )", + "contextual-alt-values": "[contextual|no-contextual]", + "content-distribution": "space-between|space-around|space-evenly|stretch", + "content-list": "[<string>|contents|<image>|<counter>|<quote>|<target>|<leader()>|<attr()>]+", + "content-position": "center|start|end|flex-start|flex-end", + "content-replacement": "<image>", + "contrast()": "contrast( [<number-percentage>] )", + "cos()": "cos( <calc-sum> )", + "counter": "<counter()>|<counters()>", + "counter()": "counter( <counter-name> , <counter-style>? )", + "counter-name": "<custom-ident>", + "counter-style": "<counter-style-name>|symbols( )", + "counter-style-name": "<custom-ident>", + "counters()": "counters( <counter-name> , <string> , <counter-style>? )", + "cross-fade()": "cross-fade( <cf-mixing-image> , <cf-final-image>? )", + "cubic-bezier-timing-function": "ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )", + "deprecated-system-color": "ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText", + "discretionary-lig-values": "[discretionary-ligatures|no-discretionary-ligatures]", + "display-box": "contents|none", + "display-inside": "flow|flow-root|table|flex|grid|ruby", + "display-internal": "table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container", + "display-legacy": "inline-block|inline-list-item|inline-table|inline-flex|inline-grid", + "display-listitem": "<display-outside>?&&[flow|flow-root]?&&list-item", + "display-outside": "block|inline|run-in", + "drop-shadow()": "drop-shadow( <length>{2,3} <color>? )", + "east-asian-variant-values": "[jis78|jis83|jis90|jis04|simplified|traditional]", + "east-asian-width-values": "[full-width|proportional-width]", + "element()": "element( <custom-ident> , [first|start|last|first-except]? )|element( <id-selector> )", + "ellipse()": "ellipse( [<shape-radius>{2}]? [at <position>]? )", + "ending-shape": "circle|ellipse", + "env()": "env( <custom-ident> , <declaration-value>? )", + "exp()": "exp( <calc-sum> )", + "explicit-track-list": "[<line-names>? <track-size>]+ <line-names>?", + "family-name": "<string>|<custom-ident>+", + "feature-tag-value": "<string> [<integer>|on|off]?", + "feature-type": "@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation", + "feature-value-block": "<feature-type> '{' <feature-value-declaration-list> '}'", + "feature-value-block-list": "<feature-value-block>+", + "feature-value-declaration": "<custom-ident> : <integer>+ ;", + "feature-value-declaration-list": "<feature-value-declaration>", + "feature-value-name": "<custom-ident>", + "fill-rule": "nonzero|evenodd", + "filter-function": "<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>", + "filter-function-list": "[<filter-function>|<url>]+", + "final-bg-layer": "<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>", + "fixed-breadth": "<length-percentage>", + "fixed-repeat": "repeat( [<integer [1,∞]>] , [<line-names>? <fixed-size>]+ <line-names>? )", + "fixed-size": "<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )", + "font-stretch-absolute": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>", + "font-variant-css21": "[normal|small-caps]", + "font-weight-absolute": "normal|bold|<number [1,1000]>", + "frequency-percentage": "<frequency>|<percentage>", + "general-enclosed": "[<function-token> <any-value>? )]|[( <any-value>? )]", + "generic-family": "<generic-script-specific>|<generic-complete>|<generic-incomplete>|<-non-standard-generic-family>", + "generic-name": "serif|sans-serif|cursive|fantasy|monospace", + "geometry-box": "<shape-box>|fill-box|stroke-box|view-box", + "gradient": "<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<repeating-conic-gradient()>|<-legacy-gradient>", + "grayscale()": "grayscale( <number-percentage> )", + "grid-line": "auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]", + "historical-lig-values": "[historical-ligatures|no-historical-ligatures]", + "hsl()": "hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )", + "hsla()": "hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )", + "hue": "<number>|<angle>", + "hue-rotate()": "hue-rotate( <angle> )", + "hue-interpolation-method": "[shorter|longer|increasing|decreasing] hue", + "hwb()": "hwb( [<hue>|none] [<percentage>|none] [<percentage>|none] [/ [<alpha-value>|none]]? )", + "hypot()": "hypot( <calc-sum># )", + "image": "<url>|<image()>|<image-set()>|<element()>|<paint()>|<cross-fade()>|<gradient>", + "image()": "image( <image-tags>? [<image-src>? , <color>?]! )", + "image-set()": "image-set( <image-set-option># )", + "image-set-option": "[<image>|<string>] [<resolution>||type( <string> )]", + "image-src": "<url>|<string>", + "image-tags": "ltr|rtl", + "inflexible-breadth": "<length-percentage>|min-content|max-content|auto", + "inset()": "inset( <length-percentage>{1,4} [round <'border-radius'>]? )", + "invert()": "invert( <number-percentage> )", + "keyframes-name": "<custom-ident>|<string>", + "keyframe-block": "<keyframe-selector># { <declaration-list> }", + "keyframe-block-list": "<keyframe-block>+", + "keyframe-selector": "from|to|<percentage>|<timeline-range-name> <percentage>", + "lab()": "lab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )", + "layer()": "layer( <layer-name> )", + "layer-name": "<ident> ['.' <ident>]*", + "lch()": "lch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )", + "leader()": "leader( <leader-type> )", + "leader-type": "dotted|solid|space|<string>", + "length-percentage": "<length>|<percentage>", + "light-dark()": "light-dark( <color> , <color> )", + "line-names": "'[' <custom-ident>* ']'", + "line-name-list": "[<line-names>|<name-repeat>]+", + "line-style": "none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset", + "line-width": "<length>|thin|medium|thick", + "linear-color-hint": "<length-percentage>", + "linear-color-stop": "<color> <color-stop-length>?", + "linear-gradient()": "linear-gradient( [[<angle>|to <side-or-corner>]||<color-interpolation-method>]? , <color-stop-list> )", + "log()": "log( <calc-sum> , <calc-sum>? )", + "mask-layer": "<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>", + "mask-position": "[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?", + "mask-reference": "none|<image>|<mask-source>", + "mask-source": "<url>", + "masking-mode": "alpha|luminance|match-source", + "matrix()": "matrix( <number>#{6} )", + "matrix3d()": "matrix3d( <number>#{16} )", + "max()": "max( <calc-sum># )", + "media-and": "<media-in-parens> [and <media-in-parens>]+", + "media-condition": "<media-not>|<media-and>|<media-or>|<media-in-parens>", + "media-condition-without-or": "<media-not>|<media-and>|<media-in-parens>", + "media-feature": "( [<mf-plain>|<mf-boolean>|<mf-range>] )", + "media-in-parens": "( <media-condition> )|<media-feature>|<general-enclosed>", + "media-not": "not <media-in-parens>", + "media-or": "<media-in-parens> [or <media-in-parens>]+", + "media-query": "<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?", + "media-query-list": "<media-query>#", + "media-type": "<ident>", + "mf-boolean": "<mf-name>", + "mf-name": "<ident>", + "mf-plain": "<mf-name> : <mf-value>", + "mf-range": "<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>", + "mf-value": "<number>|<dimension>|<ident>|<ratio>", + "min()": "min( <calc-sum># )", + "minmax()": "minmax( [<length-percentage>|min-content|max-content|auto] , [<length-percentage>|<flex>|min-content|max-content|auto] )", + "mod()": "mod( <calc-sum> , <calc-sum> )", + "name-repeat": "repeat( [<integer [1,∞]>|auto-fill] , <line-names>+ )", + "named-color": "transparent|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", + "namespace-prefix": "<ident>", + "ns-prefix": "[<ident-token>|'*']? '|'", + "number-percentage": "<number>|<percentage>", + "numeric-figure-values": "[lining-nums|oldstyle-nums]", + "numeric-fraction-values": "[diagonal-fractions|stacked-fractions]", + "numeric-spacing-values": "[proportional-nums|tabular-nums]", + "nth": "<an-plus-b>|even|odd", + "opacity()": "opacity( [<number-percentage>] )", + "overflow-position": "unsafe|safe", + "outline-radius": "<length>|<percentage>", + "page-body": "<declaration>? [; <page-body>]?|<page-margin-box> <page-body>", + "page-margin-box": "<page-margin-box-type> '{' <declaration-list> '}'", + "page-margin-box-type": "@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom", + "page-selector-list": "[<page-selector>#]?", + "page-selector": "<pseudo-page>+|<ident> <pseudo-page>*", + "page-size": "A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger", + "path()": "path( [<fill-rule> ,]? <string> )", + "paint()": "paint( <ident> , <declaration-value>? )", + "perspective()": "perspective( [<length [0,∞]>|none] )", + "polygon()": "polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )", + "polar-color-space": "hsl|hwb|lch|oklch", + "position": "[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]", + "pow()": "pow( <calc-sum> , <calc-sum> )", + "pseudo-class-selector": "':' <ident-token>|':' <function-token> <any-value> ')'", + "pseudo-element-selector": "':' <pseudo-class-selector>|<legacy-pseudo-element-selector>", + "pseudo-page": ": [left|right|first|blank]", + "quote": "open-quote|close-quote|no-open-quote|no-close-quote", + "radial-gradient()": "radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )", + "ratio": "<number [0,∞]> [/ <number [0,∞]>]?", + "ray()": "ray( <angle>&&<ray-size>?&&contain?&&[at <position>]? )", + "ray-size": "closest-side|closest-corner|farthest-side|farthest-corner|sides", + "rectangular-color-space": "srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020|lab|oklab|xyz|xyz-d50|xyz-d65", + "relative-selector": "<combinator>? <complex-selector>", + "relative-selector-list": "<relative-selector>#", + "relative-size": "larger|smaller", + "rem()": "rem( <calc-sum> , <calc-sum> )", + "repeat-style": "repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}", + "repeating-conic-gradient()": "repeating-conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )", + "repeating-linear-gradient()": "repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )", + "repeating-radial-gradient()": "repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )", + "reversed-counter-name": "reversed( <counter-name> )", + "rgb()": "rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )", + "rgba()": "rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )", + "rotate()": "rotate( [<angle>|<zero>] )", + "rotate3d()": "rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )", + "rotateX()": "rotateX( [<angle>|<zero>] )", + "rotateY()": "rotateY( [<angle>|<zero>] )", + "rotateZ()": "rotateZ( [<angle>|<zero>] )", + "round()": "round( <rounding-strategy>? , <calc-sum> , <calc-sum> )", + "rounding-strategy": "nearest|up|down|to-zero", + "saturate()": "saturate( <number-percentage> )", + "scale()": "scale( [<number>|<percentage>]#{1,2} )", + "scale3d()": "scale3d( [<number>|<percentage>]#{3} )", + "scaleX()": "scaleX( [<number>|<percentage>] )", + "scaleY()": "scaleY( [<number>|<percentage>] )", + "scaleZ()": "scaleZ( [<number>|<percentage>] )", + "scroll()": "scroll( [<axis>||<scroller>]? )", + "scroller": "root|nearest|self", + "self-position": "center|start|end|self-start|self-end|flex-start|flex-end", + "shape-radius": "<length-percentage>|closest-side|farthest-side", + "sign()": "sign( <calc-sum> )", + "skew()": "skew( [<angle>|<zero>] , [<angle>|<zero>]? )", + "skewX()": "skewX( [<angle>|<zero>] )", + "skewY()": "skewY( [<angle>|<zero>] )", + "sepia()": "sepia( <number-percentage> )", + "shadow": "inset?&&<length>{2,4}&&<color>?", + "shadow-t": "[<length>{2,3}&&<color>?]", + "shape": "rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )", + "shape-box": "<box>|margin-box", + "side-or-corner": "[left|right]||[top|bottom]", + "sin()": "sin( <calc-sum> )", + "single-animation": "<'animation-duration'>||<easing-function>||<'animation-delay'>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]||<single-animation-timeline>", + "single-animation-direction": "normal|reverse|alternate|alternate-reverse", + "single-animation-fill-mode": "none|forwards|backwards|both", + "single-animation-iteration-count": "infinite|<number>", + "single-animation-play-state": "running|paused", + "single-animation-timeline": "auto|none|<dashed-ident>|<scroll()>|<view()>", + "single-transition": "[none|<single-transition-property>]||<time>||<easing-function>||<time>||<transition-behavior-value>", + "single-transition-property": "all|<custom-ident>", + "size": "closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}", + "sqrt()": "sqrt( <calc-sum> )", + "step-position": "jump-start|jump-end|jump-none|jump-both|start|end", + "step-timing-function": "step-start|step-end|steps( <integer> [, <step-position>]? )", + "subclass-selector": "<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>", + "supports-condition": "not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*", + "supports-in-parens": "( <supports-condition> )|<supports-feature>|<general-enclosed>", + "supports-feature": "<supports-decl>|<supports-selector-fn>", + "supports-decl": "( <declaration> )", + "supports-selector-fn": "selector( <complex-selector> )", + "symbol": "<string>|<image>|<custom-ident>", + "system-color": "AccentColor|AccentColorText|ActiveText|ButtonBorder|ButtonFace|ButtonText|Canvas|CanvasText|Field|FieldText|GrayText|Highlight|HighlightText|LinkText|Mark|MarkText|SelectedItem|SelectedItemText|VisitedText", + "tan()": "tan( <calc-sum> )", + "target": "<target-counter()>|<target-counters()>|<target-text()>", + "target-counter()": "target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )", + "target-counters()": "target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )", + "target-text()": "target-text( [<string>|<url>] , [content|before|after|first-letter]? )", + "time-percentage": "<time>|<percentage>", + "timeline-range-name": "cover|contain|entry|exit|entry-crossing|exit-crossing", + "easing-function": "linear|<cubic-bezier-timing-function>|<step-timing-function>", + "track-breadth": "<length-percentage>|<flex>|min-content|max-content|auto", + "track-list": "[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?", + "track-repeat": "repeat( [<integer [1,∞]>] , [<line-names>? <track-size>]+ <line-names>? )", + "track-size": "<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( <length-percentage> )", + "transform-function": "<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>", + "transform-list": "<transform-function>+", + "transition-behavior-value": "normal|allow-discrete", + "translate()": "translate( <length-percentage> , <length-percentage>? )", + "translate3d()": "translate3d( <length-percentage> , <length-percentage> , <length> )", + "translateX()": "translateX( <length-percentage> )", + "translateY()": "translateY( <length-percentage> )", + "translateZ()": "translateZ( <length> )", + "type-or-unit": "string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%", + "type-selector": "<wq-name>|<ns-prefix>? '*'", + "var()": "var( <custom-property-name> , <declaration-value>? )", + "view()": "view( [<axis>||<'view-timeline-inset'>]? )", + "viewport-length": "auto|<length-percentage>", + "visual-box": "content-box|padding-box|border-box", + "wq-name": "<ns-prefix>? <ident-token>", + "-legacy-gradient": "<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>", + "-legacy-linear-gradient": "-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )", + "-legacy-repeating-linear-gradient": "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )", + "-legacy-linear-gradient-arguments": "[<angle>|<side-or-corner>]? , <color-stop-list>", + "-legacy-radial-gradient": "-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )", + "-legacy-repeating-radial-gradient": "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )", + "-legacy-radial-gradient-arguments": "[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>", + "-legacy-radial-gradient-size": "closest-side|closest-corner|farthest-side|farthest-corner|contain|cover", + "-legacy-radial-gradient-shape": "circle|ellipse", + "-non-standard-font": "-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body", + "-non-standard-color": "-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text", + "-non-standard-image-rendering": "optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast", + "-non-standard-overflow": "overlay|-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable", + "-non-standard-size": "intrinsic|min-intrinsic|-webkit-fill-available|-webkit-fit-content|-webkit-min-content|-webkit-max-content|-moz-available|-moz-fit-content|-moz-min-content|-moz-max-content", + "-webkit-gradient()": "-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )", + "-webkit-gradient-color-stop": "from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )", + "-webkit-gradient-point": "[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]", + "-webkit-gradient-radius": "<length>|<percentage>", + "-webkit-gradient-type": "linear|radial", + "-webkit-mask-box-repeat": "repeat|stretch|round", + "-ms-filter-function-list": "<-ms-filter-function>+", + "-ms-filter-function": "<-ms-filter-function-progid>|<-ms-filter-function-legacy>", + "-ms-filter-function-progid": "'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]", + "-ms-filter-function-legacy": "<ident-token>|<function-token> <any-value>? )", + "absolute-color-base": "<hex-color>|<absolute-color-function>|<named-color>|transparent", + "absolute-color-function": "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>", + "age": "child|young|old", + "anchor-name": "<dashed-ident>", + "attr-name": "<wq-name>", + "attr-fallback": "<any-value>", + "bg-clip": "<box>|border|text", + "bottom": "<length>|auto", + "container-name": "<custom-ident>", + "container-condition": "not <query-in-parens>|<query-in-parens> [[and <query-in-parens>]*|[or <query-in-parens>]*]", + "coord-box": "content-box|padding-box|border-box|fill-box|stroke-box|view-box", + "generic-voice": "[<age>? <gender> <integer>?]", + "gender": "male|female|neutral", + "generic-script-specific": "generic( kai )|generic( fangsong )|generic( nastaliq )", + "generic-complete": "serif|sans-serif|system-ui|cursive|fantasy|math|monospace", + "generic-incomplete": "ui-serif|ui-sans-serif|ui-monospace|ui-rounded", + "-non-standard-generic-family": "-apple-system|BlinkMacSystemFont", + "left": "<length>|auto", + "color-base": "<hex-color>|<color-function>|<named-color>|<color-mix()>|transparent", + "color-function": "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>", + "device-cmyk()": "<legacy-device-cmyk-syntax>|<modern-device-cmyk-syntax>", + "legacy-device-cmyk-syntax": "device-cmyk( <number>#{4} )", + "modern-device-cmyk-syntax": "device-cmyk( <cmyk-component>{4} [/ [<alpha-value>|none]]? )", + "cmyk-component": "<number>|<percentage>|none", + "color-mix()": "color-mix( <color-interpolation-method> , [<color>&&<percentage [0,100]>?]#{2} )", + "color-space": "<rectangular-color-space>|<polar-color-space>|<custom-color-space>", + "custom-color-space": "<dashed-ident>", + "paint": "none|<color>|<url> [none|<color>]?|context-fill|context-stroke", + "palette-identifier": "<dashed-ident>", + "right": "<length>|auto", + "scope-start": "<forgiving-selector-list>", + "scope-end": "<forgiving-selector-list>", + "forgiving-selector-list": "<complex-real-selector-list>", + "forgiving-relative-selector-list": "<relative-real-selector-list>", + "selector-list": "<complex-selector-list>", + "complex-real-selector-list": "<complex-real-selector>#", + "simple-selector-list": "<simple-selector>#", + "relative-real-selector-list": "<relative-real-selector>#", + "complex-selector-unit": "[<compound-selector>? <pseudo-compound-selector>*]!", + "complex-real-selector": "<compound-selector> [<combinator>? <compound-selector>]*", + "relative-real-selector": "<combinator>? <complex-real-selector>", + "pseudo-compound-selector": "<pseudo-element-selector> <pseudo-class-selector>*", + "simple-selector": "<type-selector>|<subclass-selector>", + "legacy-pseudo-element-selector": "':' [before|after|first-line|first-letter]", + "single-animation-composition": "replace|add|accumulate", + "svg-length": "<percentage>|<length>|<number>", + "svg-writing-mode": "lr-tb|rl-tb|tb-rl|lr|rl|tb", + "top": "<length>|auto", + "x": "<number>", + "y": "<number>", + "declaration": "<ident-token> : <declaration-value>? ['!' important]?", + "declaration-list": "[<declaration>? ';']* <declaration>?", + "url": "url( <string> <url-modifier>* )|<url-token>", + "url-modifier": "<ident>|<function-token> <any-value> )", + "number-zero-one": "<number [0,1]>", + "number-one-or-greater": "<number [1,∞]>", + "color()": "color( <colorspace-params> [/ [<alpha-value>|none]]? )", + "colorspace-params": "[<predefined-rgb-params>|<xyz-params>]", + "predefined-rgb-params": "<predefined-rgb> [<number>|<percentage>|none]{3}", + "predefined-rgb": "srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020", + "xyz-params": "<xyz-space> [<number>|<percentage>|none]{3}", + "xyz-space": "xyz|xyz-d50|xyz-d65", + "oklab()": "oklab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )", + "oklch()": "oklch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )", + "offset-path": "<ray()>|<url>|<basic-shape>", + "rect()": "rect( [<length-percentage>|auto]{4} [round <'border-radius'>]? )", + "xywh()": "xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [round <'border-radius'>]? )", + "query-in-parens": "( <container-condition> )|( <size-feature> )|style( <style-query> )|<general-enclosed>", + "size-feature": "<mf-plain>|<mf-boolean>|<mf-range>", + "style-feature": "<declaration>", + "style-query": "<style-condition>|<style-feature>", + "style-condition": "not <style-in-parens>|<style-in-parens> [[and <style-in-parens>]*|[or <style-in-parens>]*]", + "style-in-parens": "( <style-condition> )|( <style-feature> )|<general-enclosed>", + "-non-standard-display": "-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box", + "inset-area": "[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]", + "position-area": "[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|center|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|center|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]", + "anchor()": "anchor( <anchor-element>?&&<anchor-side> , <length-percentage>? )", + "anchor-side": "inside|outside|top|left|right|bottom|start|end|self-start|self-end|<percentage>|center", + "anchor-size()": "anchor-size( [<anchor-element>||<anchor-size>]? , <length-percentage>? )", + "anchor-size": "width|height|block|inline|self-block|self-inline", + "anchor-element": "<dashed-ident>", + "try-size": "most-width|most-height|most-block-size|most-inline-size", + "try-tactic": "flip-block||flip-inline||flip-start", + "font-variant-css2": "normal|small-caps", + "font-width-css3": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded", + "system-family-name": "caption|icon|menu|message-box|small-caption|status-bar" + }, + "properties": { + "--*": "<declaration-value>", + "-ms-accelerator": "false|true", + "-ms-block-progression": "tb|rl|bt|lr", + "-ms-content-zoom-chaining": "none|chained", + "-ms-content-zooming": "none|zoom", + "-ms-content-zoom-limit": "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>", + "-ms-content-zoom-limit-max": "<percentage>", + "-ms-content-zoom-limit-min": "<percentage>", + "-ms-content-zoom-snap": "<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>", + "-ms-content-zoom-snap-points": "snapInterval( <percentage> , <percentage> )|snapList( <percentage># )", + "-ms-content-zoom-snap-type": "none|proximity|mandatory", + "-ms-filter": "<string>", + "-ms-flow-from": "[none|<custom-ident>]#", + "-ms-flow-into": "[none|<custom-ident>]#", + "-ms-grid-columns": "none|<track-list>|<auto-track-list>", + "-ms-grid-rows": "none|<track-list>|<auto-track-list>", + "-ms-high-contrast-adjust": "auto|none", + "-ms-hyphenate-limit-chars": "auto|<integer>{1,3}", + "-ms-hyphenate-limit-lines": "no-limit|<integer>", + "-ms-hyphenate-limit-zone": "<percentage>|<length>", + "-ms-ime-align": "auto|after", + "-ms-overflow-style": "auto|none|scrollbar|-ms-autohiding-scrollbar", + "-ms-scrollbar-3dlight-color": "<color>", + "-ms-scrollbar-arrow-color": "<color>", + "-ms-scrollbar-base-color": "<color>", + "-ms-scrollbar-darkshadow-color": "<color>", + "-ms-scrollbar-face-color": "<color>", + "-ms-scrollbar-highlight-color": "<color>", + "-ms-scrollbar-shadow-color": "<color>", + "-ms-scrollbar-track-color": "<color>", + "-ms-scroll-chaining": "chained|none", + "-ms-scroll-limit": "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>", + "-ms-scroll-limit-x-max": "auto|<length>", + "-ms-scroll-limit-x-min": "<length>", + "-ms-scroll-limit-y-max": "auto|<length>", + "-ms-scroll-limit-y-min": "<length>", + "-ms-scroll-rails": "none|railed", + "-ms-scroll-snap-points-x": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )", + "-ms-scroll-snap-points-y": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )", + "-ms-scroll-snap-type": "none|proximity|mandatory", + "-ms-scroll-snap-x": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>", + "-ms-scroll-snap-y": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>", + "-ms-scroll-translation": "none|vertical-to-horizontal", + "-ms-text-autospace": "none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space", + "-ms-touch-select": "grippers|none", + "-ms-user-select": "none|element|text", + "-ms-wrap-flow": "auto|both|start|end|maximum|clear", + "-ms-wrap-margin": "<length>", + "-ms-wrap-through": "wrap|none", + "-moz-appearance": "none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized", + "-moz-binding": "<url>|none", + "-moz-border-bottom-colors": "<color>+|none", + "-moz-border-left-colors": "<color>+|none", + "-moz-border-right-colors": "<color>+|none", + "-moz-border-top-colors": "<color>+|none", + "-moz-context-properties": "none|[fill|fill-opacity|stroke|stroke-opacity]#", + "-moz-float-edge": "border-box|content-box|margin-box|padding-box", + "-moz-force-broken-image-icon": "0|1", + "-moz-image-region": "<shape>|auto", + "-moz-orient": "inline|block|horizontal|vertical", + "-moz-outline-radius": "<outline-radius>{1,4} [/ <outline-radius>{1,4}]?", + "-moz-outline-radius-bottomleft": "<outline-radius>", + "-moz-outline-radius-bottomright": "<outline-radius>", + "-moz-outline-radius-topleft": "<outline-radius>", + "-moz-outline-radius-topright": "<outline-radius>", + "-moz-stack-sizing": "ignore|stretch-to-fit", + "-moz-text-blink": "none|blink", + "-moz-user-focus": "ignore|normal|select-after|select-before|select-menu|select-same|select-all|none", + "-moz-user-input": "auto|none|enabled|disabled", + "-moz-user-modify": "read-only|read-write|write-only", + "-moz-window-dragging": "drag|no-drag", + "-moz-window-shadow": "default|menu|tooltip|sheet|none", + "-webkit-appearance": "none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|inner-spin-button|listbox|listitem|media-controls-background|media-controls-fullscreen-background|media-current-time-display|media-enter-fullscreen-button|media-exit-fullscreen-button|media-fullscreen-button|media-mute-button|media-overlay-play-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|media-time-remaining-display|media-toggle-closed-captions-button|media-volume-slider|media-volume-slider-container|media-volume-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|meter|progress-bar|progress-bar-value|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield|-apple-pay-button", + "-webkit-border-before": "<'border-width'>||<'border-style'>||<color>", + "-webkit-border-before-color": "<color>", + "-webkit-border-before-style": "<'border-style'>", + "-webkit-border-before-width": "<'border-width'>", + "-webkit-box-reflect": "[above|below|right|left]? <length>? <image>?", + "-webkit-line-clamp": "none|<integer>", + "-webkit-mask": "[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#", + "-webkit-mask-attachment": "<attachment>#", + "-webkit-mask-clip": "[<box>|border|padding|content|text]#", + "-webkit-mask-composite": "<composite-style>#", + "-webkit-mask-image": "<mask-reference>#", + "-webkit-mask-origin": "[<box>|border|padding|content]#", + "-webkit-mask-position": "<position>#", + "-webkit-mask-position-x": "[<length-percentage>|left|center|right]#", + "-webkit-mask-position-y": "[<length-percentage>|top|center|bottom]#", + "-webkit-mask-repeat": "<repeat-style>#", + "-webkit-mask-repeat-x": "repeat|no-repeat|space|round", + "-webkit-mask-repeat-y": "repeat|no-repeat|space|round", + "-webkit-mask-size": "<bg-size>#", + "-webkit-overflow-scrolling": "auto|touch", + "-webkit-tap-highlight-color": "<color>", + "-webkit-text-fill-color": "<color>", + "-webkit-text-stroke": "<length>||<color>", + "-webkit-text-stroke-color": "<color>", + "-webkit-text-stroke-width": "<length>", + "-webkit-touch-callout": "default|none", + "-webkit-user-modify": "read-only|read-write|read-write-plaintext-only", + "accent-color": "auto|<color>", + "align-content": "normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>", + "align-items": "normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]", + "align-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>", + "align-tracks": "[normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>]#", + "all": "initial|inherit|unset|revert|revert-layer", + "anchor-name": "none|<dashed-ident>#", + "anchor-scope": "none|all|<dashed-ident>#", + "animation": "<single-animation>#", + "animation-composition": "<single-animation-composition>#", + "animation-delay": "<time>#", + "animation-direction": "<single-animation-direction>#", + "animation-duration": "<time>#", + "animation-fill-mode": "<single-animation-fill-mode>#", + "animation-iteration-count": "<single-animation-iteration-count>#", + "animation-name": "[none|<keyframes-name>]#", + "animation-play-state": "<single-animation-play-state>#", + "animation-range": "[<'animation-range-start'> <'animation-range-end'>?]#", + "animation-range-end": "[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#", + "animation-range-start": "[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#", + "animation-timing-function": "<easing-function>#", + "animation-timeline": "<single-animation-timeline>#", + "appearance": "none|auto|textfield|menulist-button|<compat-auto>", + "aspect-ratio": "auto||<ratio>", + "azimuth": "<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards", + "backdrop-filter": "none|<filter-function-list>", + "backface-visibility": "visible|hidden", + "background": "[<bg-layer> ,]* <final-bg-layer>", + "background-attachment": "<attachment>#", + "background-blend-mode": "<blend-mode>#", + "background-clip": "<bg-clip>#", + "background-color": "<color>", + "background-image": "<bg-image>#", + "background-origin": "<box>#", + "background-position": "<bg-position>#", + "background-position-x": "[center|[[left|right|x-start|x-end]? <length-percentage>?]!]#", + "background-position-y": "[center|[[top|bottom|y-start|y-end]? <length-percentage>?]!]#", + "background-repeat": "<repeat-style>#", + "background-size": "<bg-size>#", + "block-size": "<'width'>", + "border": "<line-width>||<line-style>||<color>", + "border-block": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-block-color": "<'border-top-color'>{1,2}", + "border-block-style": "<'border-top-style'>", + "border-block-width": "<'border-top-width'>", + "border-block-end": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-block-end-color": "<'border-top-color'>", + "border-block-end-style": "<'border-top-style'>", + "border-block-end-width": "<'border-top-width'>", + "border-block-start": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-block-start-color": "<'border-top-color'>", + "border-block-start-style": "<'border-top-style'>", + "border-block-start-width": "<'border-top-width'>", + "border-bottom": "<line-width>||<line-style>||<color>", + "border-bottom-color": "<'border-top-color'>", + "border-bottom-left-radius": "<length-percentage>{1,2}", + "border-bottom-right-radius": "<length-percentage>{1,2}", + "border-bottom-style": "<line-style>", + "border-bottom-width": "<line-width>", + "border-collapse": "collapse|separate", + "border-color": "<color>{1,4}", + "border-end-end-radius": "<length-percentage>{1,2}", + "border-end-start-radius": "<length-percentage>{1,2}", + "border-image": "<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>", + "border-image-outset": "[<length>|<number>]{1,4}", + "border-image-repeat": "[stretch|repeat|round|space]{1,2}", + "border-image-slice": "<number-percentage>{1,4}&&fill?", + "border-image-source": "none|<image>", + "border-image-width": "[<length-percentage>|<number>|auto]{1,4}", + "border-inline": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-inline-end": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-inline-color": "<'border-top-color'>{1,2}", + "border-inline-style": "<'border-top-style'>", + "border-inline-width": "<'border-top-width'>", + "border-inline-end-color": "<'border-top-color'>", + "border-inline-end-style": "<'border-top-style'>", + "border-inline-end-width": "<'border-top-width'>", + "border-inline-start": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-inline-start-color": "<'border-top-color'>", + "border-inline-start-style": "<'border-top-style'>", + "border-inline-start-width": "<'border-top-width'>", + "border-left": "<line-width>||<line-style>||<color>", + "border-left-color": "<color>", + "border-left-style": "<line-style>", + "border-left-width": "<line-width>", + "border-radius": "<length-percentage>{1,4} [/ <length-percentage>{1,4}]?", + "border-right": "<line-width>||<line-style>||<color>", + "border-right-color": "<color>", + "border-right-style": "<line-style>", + "border-right-width": "<line-width>", + "border-spacing": "<length> <length>?", + "border-start-end-radius": "<length-percentage>{1,2}", + "border-start-start-radius": "<length-percentage>{1,2}", + "border-style": "<line-style>{1,4}", + "border-top": "<line-width>||<line-style>||<color>", + "border-top-color": "<color>", + "border-top-left-radius": "<length-percentage>{1,2}", + "border-top-right-radius": "<length-percentage>{1,2}", + "border-top-style": "<line-style>", + "border-top-width": "<line-width>", + "border-width": "<line-width>{1,4}", + "bottom": "<length>|<percentage>|auto", + "box-align": "start|center|end|baseline|stretch", + "box-decoration-break": "slice|clone", + "box-direction": "normal|reverse|inherit", + "box-flex": "<number>", + "box-flex-group": "<integer>", + "box-lines": "single|multiple", + "box-ordinal-group": "<integer>", + "box-orient": "horizontal|vertical|inline-axis|block-axis|inherit", + "box-pack": "start|center|end|justify", + "box-shadow": "none|<shadow>#", + "box-sizing": "content-box|border-box", + "break-after": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region", + "break-before": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region", + "break-inside": "auto|avoid|avoid-page|avoid-column|avoid-region", + "caption-side": "top|bottom|block-start|block-end|inline-start|inline-end", + "caret": "<'caret-color'>||<'caret-shape'>", + "caret-color": "auto|<color>", + "caret-shape": "auto|bar|block|underscore", + "clear": "none|left|right|both|inline-start|inline-end", + "clip": "<shape>|auto", + "clip-path": "<clip-source>|[<basic-shape>||<geometry-box>]|none", + "clip-rule": "nonzero|evenodd", + "color": "<color>", + "color-interpolation-filters": "auto|sRGB|linearRGB", + "color-scheme": "normal|[light|dark|<custom-ident>]+&&only?", + "column-count": "<integer>|auto", + "column-fill": "auto|balance", + "column-gap": "normal|<length-percentage>", + "column-rule": "<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>", + "column-rule-color": "<color>", + "column-rule-style": "<'border-style'>", + "column-rule-width": "<'border-width'>", + "column-span": "none|all", + "column-width": "<length>|auto", + "columns": "<'column-width'>||<'column-count'>", + "contain": "none|strict|content|[[size||inline-size]||layout||style||paint]", + "contain-intrinsic-size": "[auto? [none|<length>]]{1,2}", + "contain-intrinsic-block-size": "auto? [none|<length>]", + "contain-intrinsic-height": "auto? [none|<length>]", + "contain-intrinsic-inline-size": "auto? [none|<length>]", + "contain-intrinsic-width": "auto? [none|<length>]", + "container": "<'container-name'> [/ <'container-type'>]?", + "container-name": "none|<custom-ident>+", + "container-type": "normal||[size|inline-size]", + "content": "normal|none|[<content-replacement>|<content-list>] [/ [<string>|<counter>]+]?", + "content-visibility": "visible|auto|hidden", + "counter-increment": "[<counter-name> <integer>?]+|none", + "counter-reset": "[<counter-name> <integer>?|<reversed-counter-name> <integer>?]+|none", + "counter-set": "[<counter-name> <integer>?]+|none", + "cursor": "[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]", + "d": "none|path( <string> )", + "cx": "<length>|<percentage>", + "cy": "<length>|<percentage>", + "direction": "ltr|rtl", + "display": "[<display-outside>||<display-inside>]|<display-listitem>|<display-internal>|<display-box>|<display-legacy>|<-non-standard-display>", + "dominant-baseline": "auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge", + "empty-cells": "show|hide", + "field-sizing": "content|fixed", + "fill": "<paint>", + "fill-opacity": "<number-zero-one>", + "fill-rule": "nonzero|evenodd", + "filter": "none|<filter-function-list>|<-ms-filter-function-list>", + "flex": "none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]", + "flex-basis": "content|<'width'>", + "flex-direction": "row|row-reverse|column|column-reverse", + "flex-flow": "<'flex-direction'>||<'flex-wrap'>", + "flex-grow": "<number>", + "flex-shrink": "<number>", + "flex-wrap": "nowrap|wrap|wrap-reverse", + "float": "left|right|none|inline-start|inline-end", + "font": "[[<'font-style'>||<font-variant-css2>||<'font-weight'>||<font-width-css3>]? <'font-size'> [/ <'line-height'>]? <'font-family'>#]|<system-family-name>|<-non-standard-font>", + "font-family": "[<family-name>|<generic-family>]#", + "font-feature-settings": "normal|<feature-tag-value>#", + "font-kerning": "auto|normal|none", + "font-language-override": "normal|<string>", + "font-optical-sizing": "auto|none", + "font-palette": "normal|light|dark|<palette-identifier>", + "font-variation-settings": "normal|[<string> <number>]#", + "font-size": "<absolute-size>|<relative-size>|<length-percentage>", + "font-size-adjust": "none|[ex-height|cap-height|ch-width|ic-width|ic-height]? [from-font|<number>]", + "font-smooth": "auto|never|always|<absolute-size>|<length>", + "font-stretch": "<font-stretch-absolute>", + "font-style": "normal|italic|oblique <angle>?", + "font-synthesis": "none|[weight||style||small-caps||position]", + "font-synthesis-position": "auto|none", + "font-synthesis-small-caps": "auto|none", + "font-synthesis-style": "auto|none", + "font-synthesis-weight": "auto|none", + "font-variant": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]", + "font-variant-alternates": "normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]", + "font-variant-caps": "normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps", + "font-variant-east-asian": "normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]", + "font-variant-emoji": "normal|text|emoji|unicode", + "font-variant-ligatures": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]", + "font-variant-numeric": "normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]", + "font-variant-position": "normal|sub|super", + "font-weight": "<font-weight-absolute>|bolder|lighter", + "forced-color-adjust": "auto|none|preserve-parent-color", + "gap": "<'row-gap'> <'column-gap'>?", + "grid": "<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>", + "grid-area": "<grid-line> [/ <grid-line>]{0,3}", + "grid-auto-columns": "<track-size>+", + "grid-auto-flow": "[row|column]||dense", + "grid-auto-rows": "<track-size>+", + "grid-column": "<grid-line> [/ <grid-line>]?", + "grid-column-end": "<grid-line>", + "grid-column-gap": "<length-percentage>", + "grid-column-start": "<grid-line>", + "grid-gap": "<'grid-row-gap'> <'grid-column-gap'>?", + "grid-row": "<grid-line> [/ <grid-line>]?", + "grid-row-end": "<grid-line>", + "grid-row-gap": "<length-percentage>", + "grid-row-start": "<grid-line>", + "grid-template": "none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?", + "grid-template-areas": "none|<string>+", + "grid-template-columns": "none|<track-list>|<auto-track-list>|subgrid <line-name-list>?", + "grid-template-rows": "none|<track-list>|<auto-track-list>|subgrid <line-name-list>?", + "hanging-punctuation": "none|[first||[force-end|allow-end]||last]", + "height": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "hyphenate-character": "auto|<string>", + "hyphenate-limit-chars": "[auto|<integer>]{1,3}", + "hyphens": "none|manual|auto", + "image-orientation": "from-image|<angle>|[<angle>? flip]", + "image-rendering": "auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>", + "image-resolution": "[from-image||<resolution>]&&snap?", + "ime-mode": "auto|normal|active|inactive|disabled", + "initial-letter": "normal|[<number> <integer>?]", + "initial-letter-align": "[auto|alphabetic|hanging|ideographic]", + "inline-size": "<'width'>", + "input-security": "auto|none", + "inset": "<'top'>{1,4}", + "inset-block": "<'top'>{1,2}", + "inset-block-end": "<'top'>", + "inset-block-start": "<'top'>", + "inset-inline": "<'top'>{1,2}", + "inset-inline-end": "<'top'>", + "inset-inline-start": "<'top'>", + "interpolate-size": "numeric-only|allow-keywords", + "isolation": "auto|isolate", + "justify-content": "normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]", + "justify-items": "normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]", + "justify-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]", + "justify-tracks": "[normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]]#", + "left": "<length>|<percentage>|auto", + "letter-spacing": "normal|<length-percentage>", + "line-break": "auto|loose|normal|strict|anywhere", + "line-clamp": "none|<integer>", + "line-height": "normal|<number>|<length>|<percentage>", + "line-height-step": "<length>", + "list-style": "<'list-style-type'>||<'list-style-position'>||<'list-style-image'>", + "list-style-image": "<image>|none", + "list-style-position": "inside|outside", + "list-style-type": "<counter-style>|<string>|none", + "margin": "[<length>|<percentage>|auto]{1,4}", + "margin-block": "<'margin-left'>{1,2}", + "margin-block-end": "<'margin-left'>", + "margin-block-start": "<'margin-left'>", + "margin-bottom": "<length>|<percentage>|auto", + "margin-inline": "<'margin-left'>{1,2}", + "margin-inline-end": "<'margin-left'>", + "margin-inline-start": "<'margin-left'>", + "margin-left": "<length>|<percentage>|auto", + "margin-right": "<length>|<percentage>|auto", + "margin-top": "<length>|<percentage>|auto", + "margin-trim": "none|in-flow|all", + "marker": "none|<url>", + "marker-end": "none|<url>", + "marker-mid": "none|<url>", + "marker-start": "none|<url>", + "mask": "<mask-layer>#", + "mask-border": "<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>", + "mask-border-mode": "luminance|alpha", + "mask-border-outset": "[<length>|<number>]{1,4}", + "mask-border-repeat": "[stretch|repeat|round|space]{1,2}", + "mask-border-slice": "<number-percentage>{1,4} fill?", + "mask-border-source": "none|<image>", + "mask-border-width": "[<length-percentage>|<number>|auto]{1,4}", + "mask-clip": "[<geometry-box>|no-clip]#", + "mask-composite": "<compositing-operator>#", + "mask-image": "<mask-reference>#", + "mask-mode": "<masking-mode>#", + "mask-origin": "<geometry-box>#", + "mask-position": "<position>#", + "mask-repeat": "<repeat-style>#", + "mask-size": "<bg-size>#", + "mask-type": "luminance|alpha", + "masonry-auto-flow": "[pack|next]||[definite-first|ordered]", + "math-depth": "auto-add|add( <integer> )|<integer>", + "math-shift": "normal|compact", + "math-style": "normal|compact", + "max-block-size": "<'max-width'>", + "max-height": "none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "max-inline-size": "<'max-width'>", + "max-lines": "none|<integer>", + "max-width": "none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "min-block-size": "<'min-width'>", + "min-height": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "min-inline-size": "<'min-width'>", + "min-width": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "mix-blend-mode": "<blend-mode>|plus-lighter", + "object-fit": "fill|contain|cover|none|scale-down", + "object-position": "<position>", + "offset": "[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?", + "offset-anchor": "auto|<position>", + "offset-distance": "<length-percentage>", + "offset-path": "none|<offset-path>||<coord-box>", + "offset-position": "normal|auto|<position>", + "offset-rotate": "[auto|reverse]||<angle>", + "opacity": "<alpha-value>", + "order": "<integer>", + "orphans": "<integer>", + "outline": "[<'outline-width'>||<'outline-style'>||<'outline-color'>]", + "outline-color": "auto|<color>", + "outline-offset": "<length>", + "outline-style": "auto|<'border-style'>", + "outline-width": "<line-width>", + "overflow": "[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>", + "overflow-anchor": "auto|none", + "overflow-block": "visible|hidden|clip|scroll|auto", + "overflow-clip-box": "padding-box|content-box", + "overflow-clip-margin": "<visual-box>||<length [0,∞]>", + "overflow-inline": "visible|hidden|clip|scroll|auto", + "overflow-wrap": "normal|break-word|anywhere", + "overflow-x": "visible|hidden|clip|scroll|auto", + "overflow-y": "visible|hidden|clip|scroll|auto", + "overlay": "none|auto", + "overscroll-behavior": "[contain|none|auto]{1,2}", + "overscroll-behavior-block": "contain|none|auto", + "overscroll-behavior-inline": "contain|none|auto", + "overscroll-behavior-x": "contain|none|auto", + "overscroll-behavior-y": "contain|none|auto", + "padding": "[<length>|<percentage>]{1,4}", + "padding-block": "<'padding-left'>{1,2}", + "padding-block-end": "<'padding-left'>", + "padding-block-start": "<'padding-left'>", + "padding-bottom": "<length>|<percentage>", + "padding-inline": "<'padding-left'>{1,2}", + "padding-inline-end": "<'padding-left'>", + "padding-inline-start": "<'padding-left'>", + "padding-left": "<length>|<percentage>", + "padding-right": "<length>|<percentage>", + "padding-top": "<length>|<percentage>", + "page": "auto|<custom-ident>", + "page-break-after": "auto|always|avoid|left|right|recto|verso", + "page-break-before": "auto|always|avoid|left|right|recto|verso", + "page-break-inside": "auto|avoid", + "paint-order": "normal|[fill||stroke||markers]", + "perspective": "none|<length>", + "perspective-origin": "<position>", + "place-content": "<'align-content'> <'justify-content'>?", + "place-items": "<'align-items'> <'justify-items'>?", + "place-self": "<'align-self'> <'justify-self'>?", + "pointer-events": "auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit", + "position": "static|relative|absolute|sticky|fixed|-webkit-sticky", + "position-anchor": "auto|<anchor-name>", + "position-area": "none|<position-area>", + "position-try": "<'position-try-order'>? <'position-try-fallbacks'>", + "position-try-fallbacks": "none|[[<dashed-ident>||<try-tactic>]|<'position-area'>]#", + "position-try-order": "normal|<try-size>", + "position-visibility": "always|[anchors-valid||anchors-visible||no-overflow]", + "print-color-adjust": "economy|exact", + "quotes": "none|auto|[<string> <string>]+", + "r": "<length>|<percentage>", + "resize": "none|both|horizontal|vertical|block|inline", + "right": "<length>|<percentage>|auto", + "rotate": "none|<angle>|[x|y|z|<number>{3}]&&<angle>", + "row-gap": "normal|<length-percentage>", + "ruby-align": "start|center|space-between|space-around", + "ruby-merge": "separate|collapse|auto", + "ruby-position": "[alternate||[over|under]]|inter-character", + "rx": "<length>|<percentage>", + "ry": "<length>|<percentage>", + "scale": "none|[<number>|<percentage>]{1,3}", + "scrollbar-color": "auto|<color>{2}", + "scrollbar-gutter": "auto|stable&&both-edges?", + "scrollbar-width": "auto|thin|none", + "scroll-behavior": "auto|smooth", + "scroll-margin": "<length>{1,4}", + "scroll-margin-block": "<length>{1,2}", + "scroll-margin-block-start": "<length>", + "scroll-margin-block-end": "<length>", + "scroll-margin-bottom": "<length>", + "scroll-margin-inline": "<length>{1,2}", + "scroll-margin-inline-start": "<length>", + "scroll-margin-inline-end": "<length>", + "scroll-margin-left": "<length>", + "scroll-margin-right": "<length>", + "scroll-margin-top": "<length>", + "scroll-padding": "[auto|<length-percentage>]{1,4}", + "scroll-padding-block": "[auto|<length-percentage>]{1,2}", + "scroll-padding-block-start": "auto|<length-percentage>", + "scroll-padding-block-end": "auto|<length-percentage>", + "scroll-padding-bottom": "auto|<length-percentage>", + "scroll-padding-inline": "[auto|<length-percentage>]{1,2}", + "scroll-padding-inline-start": "auto|<length-percentage>", + "scroll-padding-inline-end": "auto|<length-percentage>", + "scroll-padding-left": "auto|<length-percentage>", + "scroll-padding-right": "auto|<length-percentage>", + "scroll-padding-top": "auto|<length-percentage>", + "scroll-snap-align": "[none|start|end|center]{1,2}", + "scroll-snap-coordinate": "none|<position>#", + "scroll-snap-destination": "<position>", + "scroll-snap-points-x": "none|repeat( <length-percentage> )", + "scroll-snap-points-y": "none|repeat( <length-percentage> )", + "scroll-snap-stop": "normal|always", + "scroll-snap-type": "none|[x|y|block|inline|both] [mandatory|proximity]?", + "scroll-snap-type-x": "none|mandatory|proximity", + "scroll-snap-type-y": "none|mandatory|proximity", + "scroll-timeline": "[<'scroll-timeline-name'>||<'scroll-timeline-axis'>]#", + "scroll-timeline-axis": "[block|inline|x|y]#", + "scroll-timeline-name": "[none|<dashed-ident>]#", + "shape-image-threshold": "<alpha-value>", + "shape-margin": "<length-percentage>", + "shape-outside": "none|[<shape-box>||<basic-shape>]|<image>", + "shape-rendering": "auto|optimizeSpeed|crispEdges|geometricPrecision", + "stroke": "<paint>", + "stroke-dasharray": "none|[<svg-length>+]#", + "stroke-dashoffset": "<svg-length>", + "stroke-linecap": "butt|round|square", + "stroke-linejoin": "miter|round|bevel", + "stroke-miterlimit": "<number-one-or-greater>", + "stroke-opacity": "<'opacity'>", + "stroke-width": "<svg-length>", + "tab-size": "<integer>|<length>", + "table-layout": "auto|fixed", + "text-align": "start|end|left|right|center|justify|match-parent", + "text-align-last": "auto|start|end|left|right|center|justify", + "text-anchor": "start|middle|end", + "text-combine-upright": "none|all|[digits <integer>?]", + "text-decoration": "<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>||<'text-decoration-thickness'>", + "text-decoration-color": "<color>", + "text-decoration-line": "none|[underline||overline||line-through||blink]|spelling-error|grammar-error", + "text-decoration-skip": "none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]", + "text-decoration-skip-ink": "auto|all|none", + "text-decoration-style": "solid|double|dotted|dashed|wavy", + "text-decoration-thickness": "auto|from-font|<length>|<percentage>", + "text-emphasis": "<'text-emphasis-style'>||<'text-emphasis-color'>", + "text-emphasis-color": "<color>", + "text-emphasis-position": "auto|[over|under]&&[right|left]?", + "text-emphasis-style": "none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>", + "text-indent": "<length-percentage>&&hanging?&&each-line?", + "text-justify": "auto|inter-character|inter-word|none", + "text-orientation": "mixed|upright|sideways", + "text-overflow": "[clip|ellipsis|<string>]{1,2}", + "text-rendering": "auto|optimizeSpeed|optimizeLegibility|geometricPrecision", + "text-shadow": "none|<shadow-t>#", + "text-size-adjust": "none|auto|<percentage>", + "text-spacing-trim": "space-all|normal|space-first|trim-start|trim-both|trim-all|auto", + "text-transform": "none|capitalize|uppercase|lowercase|full-width|full-size-kana", + "text-underline-offset": "auto|<length>|<percentage>", + "text-underline-position": "auto|from-font|[under||[left|right]]", + "text-wrap": "<'text-wrap-mode'>||<'text-wrap-style'>", + "text-wrap-mode": "auto|wrap|nowrap", + "text-wrap-style": "auto|balance|stable|pretty", + "timeline-scope": "none|<dashed-ident>#", + "top": "<length>|<percentage>|auto", + "touch-action": "auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation", + "transform": "none|<transform-list>", + "transform-box": "content-box|border-box|fill-box|stroke-box|view-box", + "transform-origin": "[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?", + "transform-style": "flat|preserve-3d", + "transition": "<single-transition>#", + "transition-behavior": "<transition-behavior-value>#", + "transition-delay": "<time>#", + "transition-duration": "<time>#", + "transition-property": "none|<single-transition-property>#", + "transition-timing-function": "<easing-function>#", + "translate": "none|<length-percentage> [<length-percentage> <length>?]?", + "unicode-bidi": "normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate|-webkit-isolate-override|-webkit-plaintext", + "user-select": "auto|text|none|contain|all", + "vector-effect": "none|non-scaling-stroke|non-scaling-size|non-rotation|fixed-position", + "vertical-align": "baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>", + "view-timeline": "[<'view-timeline-name'> <'view-timeline-axis'>?]#", + "view-timeline-axis": "[block|inline|x|y]#", + "view-timeline-inset": "[[auto|<length-percentage>]{1,2}]#", + "view-timeline-name": "none|<dashed-ident>#", + "view-transition-name": "none|<custom-ident>", + "visibility": "visible|hidden|collapse", + "white-space": "normal|pre|nowrap|pre-wrap|pre-line|break-spaces|[<'white-space-collapse'>||<'text-wrap'>||<'white-space-trim'>]", + "white-space-collapse": "collapse|discard|preserve|preserve-breaks|preserve-spaces|break-spaces", + "widows": "<integer>", + "width": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "will-change": "auto|<animateable-feature>#", + "word-break": "normal|break-all|keep-all|break-word|auto-phrase", + "word-spacing": "normal|<length>", + "word-wrap": "normal|break-word", + "writing-mode": "horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>", + "x": "<length>|<percentage>", + "y": "<length>|<percentage>", + "z-index": "auto|<integer>", + "zoom": "normal|reset|<number>|<percentage>", + "-moz-background-clip": "padding|border", + "-moz-border-radius-bottomleft": "<'border-bottom-left-radius'>", + "-moz-border-radius-bottomright": "<'border-bottom-right-radius'>", + "-moz-border-radius-topleft": "<'border-top-left-radius'>", + "-moz-border-radius-topright": "<'border-bottom-right-radius'>", + "-moz-control-character-visibility": "visible|hidden", + "-moz-osx-font-smoothing": "auto|grayscale", + "-moz-user-select": "none|text|all|-moz-none", + "-ms-flex-align": "start|end|center|baseline|stretch", + "-ms-flex-item-align": "auto|start|end|center|baseline|stretch", + "-ms-flex-line-pack": "start|end|center|justify|distribute|stretch", + "-ms-flex-negative": "<'flex-shrink'>", + "-ms-flex-pack": "start|end|center|justify|distribute", + "-ms-flex-order": "<integer>", + "-ms-flex-positive": "<'flex-grow'>", + "-ms-flex-preferred-size": "<'flex-basis'>", + "-ms-interpolation-mode": "nearest-neighbor|bicubic", + "-ms-grid-column-align": "start|end|center|stretch", + "-ms-grid-row-align": "start|end|center|stretch", + "-ms-hyphenate-limit-last": "none|always|column|page|spread", + "-webkit-background-clip": "[<box>|border|padding|content|text]#", + "-webkit-column-break-after": "always|auto|avoid", + "-webkit-column-break-before": "always|auto|avoid", + "-webkit-column-break-inside": "always|auto|avoid", + "-webkit-font-smoothing": "auto|none|antialiased|subpixel-antialiased", + "-webkit-mask-box-image": "[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?", + "-webkit-print-color-adjust": "economy|exact", + "-webkit-text-security": "none|circle|disc|square", + "-webkit-user-drag": "none|element|auto", + "-webkit-user-select": "auto|none|text|all", + "alignment-baseline": "auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical", + "baseline-shift": "baseline|sub|super|<svg-length>", + "behavior": "<url>+", + "cue": "<'cue-before'> <'cue-after'>?", + "cue-after": "<url> <decibel>?|none", + "cue-before": "<url> <decibel>?|none", + "glyph-orientation-horizontal": "<angle>", + "glyph-orientation-vertical": "<angle>", + "kerning": "auto|<svg-length>", + "pause": "<'pause-before'> <'pause-after'>?", + "pause-after": "<time>|none|x-weak|weak|medium|strong|x-strong", + "pause-before": "<time>|none|x-weak|weak|medium|strong|x-strong", + "rest": "<'rest-before'> <'rest-after'>?", + "rest-after": "<time>|none|x-weak|weak|medium|strong|x-strong", + "rest-before": "<time>|none|x-weak|weak|medium|strong|x-strong", + "src": "[<url> [format( <string># )]?|local( <family-name> )]#", + "speak": "auto|never|always", + "speak-as": "normal|spell-out||digits||[literal-punctuation|no-punctuation]", + "unicode-range": "<urange>#", + "voice-balance": "<number>|left|center|right|leftwards|rightwards", + "voice-duration": "auto|<time>", + "voice-family": "[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve", + "voice-pitch": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]", + "voice-range": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]", + "voice-rate": "[normal|x-slow|slow|medium|fast|x-fast]||<percentage>", + "voice-stress": "normal|strong|moderate|none|reduced", + "voice-volume": "silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]", + "white-space-trim": "none|discard-before||discard-after||discard-inner" + }, + "atrules": { + "charset": { + "prelude": "<string>", + "descriptors": null + }, + "counter-style": { + "prelude": "<counter-style-name>", + "descriptors": { + "additive-symbols": "[<integer>&&<symbol>]#", + "fallback": "<counter-style-name>", + "negative": "<symbol> <symbol>?", + "pad": "<integer>&&<symbol>", + "prefix": "<symbol>", + "range": "[[<integer>|infinite]{2}]#|auto", + "speak-as": "auto|bullets|numbers|words|spell-out|<counter-style-name>", + "suffix": "<symbol>", + "symbols": "<symbol>+", + "system": "cyclic|numeric|alphabetic|symbolic|additive|[fixed <integer>?]|[extends <counter-style-name>]" + } + }, + "document": { + "prelude": "[<url>|url-prefix( <string> )|domain( <string> )|media-document( <string> )|regexp( <string> )]#", + "descriptors": null + }, + "font-palette-values": { + "prelude": "<dashed-ident>", + "descriptors": { + "base-palette": "light|dark|<integer [0,∞]>", + "font-family": "<family-name>#", + "override-colors": "[<integer [0,∞]> <absolute-color-base>]#" + } + }, + "font-face": { + "prelude": null, + "descriptors": { + "ascent-override": "normal|<percentage>", + "descent-override": "normal|<percentage>", + "font-display": "[auto|block|swap|fallback|optional]", + "font-family": "<family-name>", + "font-feature-settings": "normal|<feature-tag-value>#", + "font-variation-settings": "normal|[<string> <number>]#", + "font-stretch": "<font-stretch-absolute>{1,2}", + "font-style": "normal|italic|oblique <angle>{0,2}", + "font-weight": "<font-weight-absolute>{1,2}", + "line-gap-override": "normal|<percentage>", + "size-adjust": "<percentage>", + "src": "[<url> [format( <string># )]?|local( <family-name> )]#", + "unicode-range": "<urange>#" + } + }, + "font-feature-values": { + "prelude": "<family-name>#", + "descriptors": null + }, + "import": { + "prelude": "[<string>|<url>] [layer|layer( <layer-name> )]? [supports( [<supports-condition>|<declaration>] )]? <media-query-list>?", + "descriptors": null + }, + "keyframes": { + "prelude": "<keyframes-name>", + "descriptors": null + }, + "layer": { + "prelude": "[<layer-name>#|<layer-name>?]", + "descriptors": null + }, + "media": { + "prelude": "<media-query-list>", + "descriptors": null + }, + "namespace": { + "prelude": "<namespace-prefix>? [<string>|<url>]", + "descriptors": null + }, + "page": { + "prelude": "<page-selector-list>", + "descriptors": { + "bleed": "auto|<length>", + "marks": "none|[crop||cross]", + "page-orientation": "upright|rotate-left|rotate-right", + "size": "<length>{1,2}|auto|[<page-size>||[portrait|landscape]]" + } + }, + "position-try": { + "prelude": "<dashed-ident>", + "descriptors": { + "top": "<'top'>", + "left": "<'left'>", + "bottom": "<'bottom'>", + "right": "<'right'>", + "inset-block-start": "<'inset-block-start'>", + "inset-block-end": "<'inset-block-end'>", + "inset-inline-start": "<'inset-inline-start'>", + "inset-inline-end": "<'inset-inline-end'>", + "inset-block": "<'inset-block'>", + "inset-inline": "<'inset-inline'>", + "inset": "<'inset'>", + "margin-top": "<'margin-top'>", + "margin-left": "<'margin-left'>", + "margin-bottom": "<'margin-bottom'>", + "margin-right": "<'margin-right'>", + "margin-block-start": "<'margin-block-start'>", + "margin-block-end": "<'margin-block-end'>", + "margin-inline-start": "<'margin-inline-start'>", + "margin-inline-end": "<'margin-inline-end'>", + "margin": "<'margin'>", + "margin-block": "<'margin-block'>", + "margin-inline": "<'margin-inline'>", + "width": "<'width'>", + "height": "<'height'>", + "min-width": "<'min-width'>", + "min-height": "<'min-height'>", + "max-width": "<'max-width'>", + "max-height": "<'max-height'>", + "block-size": "<'block-size'>", + "inline-size": "<'inline-size'>", + "min-block-size": "<'min-block-size'>", + "min-inline-size": "<'min-inline-size'>", + "max-block-size": "<'max-block-size'>", + "max-inline-size": "<'max-inline-size'>", + "align-self": "<'align-self'>|anchor-center", + "justify-self": "<'justify-self'>|anchor-center" + } + }, + "property": { + "prelude": "<custom-property-name>", + "descriptors": { + "syntax": "<string>", + "inherits": "true|false", + "initial-value": "<declaration-value>?" + } + }, + "scope": { + "prelude": "[( <scope-start> )]? [to ( <scope-end> )]?", + "descriptors": null + }, + "starting-style": { + "prelude": null, + "descriptors": null + }, + "supports": { + "prelude": "<supports-condition>", + "descriptors": null + }, + "container": { + "prelude": "[<container-name>]? <container-condition>", + "descriptors": null + }, + "nest": { + "prelude": "<complex-selector-list>", + "descriptors": null + } + } +};
\ No newline at end of file diff --git a/vanilla/node_modules/css-tree/dist/data.js b/vanilla/node_modules/css-tree/dist/data.js new file mode 100644 index 0000000..7b711ec --- /dev/null +++ b/vanilla/node_modules/css-tree/dist/data.js @@ -0,0 +1,1308 @@ +export default { + "generic": true, + "cssWideKeywords": [ + "initial", + "inherit", + "unset", + "revert", + "revert-layer" + ], + "units": { + "angle": [ + "deg", + "grad", + "rad", + "turn" + ], + "decibel": [ + "db" + ], + "flex": [ + "fr" + ], + "frequency": [ + "hz", + "khz" + ], + "length": [ + "cm", + "mm", + "q", + "in", + "pt", + "pc", + "px", + "em", + "rem", + "ex", + "rex", + "cap", + "rcap", + "ch", + "rch", + "ic", + "ric", + "lh", + "rlh", + "vw", + "svw", + "lvw", + "dvw", + "vh", + "svh", + "lvh", + "dvh", + "vi", + "svi", + "lvi", + "dvi", + "vb", + "svb", + "lvb", + "dvb", + "vmin", + "svmin", + "lvmin", + "dvmin", + "vmax", + "svmax", + "lvmax", + "dvmax", + "cqw", + "cqh", + "cqi", + "cqb", + "cqmin", + "cqmax" + ], + "resolution": [ + "dpi", + "dpcm", + "dppx", + "x" + ], + "semitones": [ + "st" + ], + "time": [ + "s", + "ms" + ] + }, + "types": { + "abs()": "abs( <calc-sum> )", + "absolute-size": "xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large", + "acos()": "acos( <calc-sum> )", + "alpha-value": "<number>|<percentage>", + "angle-percentage": "<angle>|<percentage>", + "angular-color-hint": "<angle-percentage>", + "angular-color-stop": "<color>&&<color-stop-angle>?", + "angular-color-stop-list": "[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>", + "animateable-feature": "scroll-position|contents|<custom-ident>", + "asin()": "asin( <calc-sum> )", + "atan()": "atan( <calc-sum> )", + "atan2()": "atan2( <calc-sum> , <calc-sum> )", + "attachment": "scroll|fixed|local", + "attr()": "attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )", + "attr-matcher": "['~'|'|'|'^'|'$'|'*']? '='", + "attr-modifier": "i|s", + "attribute-selector": "'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'", + "auto-repeat": "repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )", + "auto-track-list": "[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?", + "axis": "block|inline|x|y", + "baseline-position": "[first|last]? baseline", + "basic-shape": "<inset()>|<xywh()>|<rect()>|<circle()>|<ellipse()>|<polygon()>|<path()>", + "bg-image": "none|<image>", + "bg-layer": "<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>", + "bg-position": "[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]", + "bg-size": "[<length-percentage>|auto]{1,2}|cover|contain", + "blur()": "blur( <length> )", + "blend-mode": "normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity", + "box": "border-box|padding-box|content-box", + "brightness()": "brightness( <number-percentage> )", + "calc()": "calc( <calc-sum> )", + "calc-sum": "<calc-product> [['+'|'-'] <calc-product>]*", + "calc-product": "<calc-value> ['*' <calc-value>|'/' <number>]*", + "calc-value": "<number>|<dimension>|<percentage>|<calc-constant>|( <calc-sum> )", + "calc-constant": "e|pi|infinity|-infinity|NaN", + "cf-final-image": "<image>|<color>", + "cf-mixing-image": "<percentage>?&&<image>", + "circle()": "circle( [<shape-radius>]? [at <position>]? )", + "clamp()": "clamp( <calc-sum>#{3} )", + "class-selector": "'.' <ident-token>", + "clip-source": "<url>", + "color": "<color-base>|currentColor|<system-color>|<device-cmyk()>|<light-dark()>|<-non-standard-color>", + "color-stop": "<color-stop-length>|<color-stop-angle>", + "color-stop-angle": "<angle-percentage>{1,2}", + "color-stop-length": "<length-percentage>{1,2}", + "color-stop-list": "[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>", + "color-interpolation-method": "in [<rectangular-color-space>|<polar-color-space> <hue-interpolation-method>?|<custom-color-space>]", + "combinator": "'>'|'+'|'~'|['|' '|']", + "common-lig-values": "[common-ligatures|no-common-ligatures]", + "compat-auto": "searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button", + "composite-style": "clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor", + "compositing-operator": "add|subtract|intersect|exclude", + "compound-selector": "[<type-selector>? <subclass-selector>*]!", + "compound-selector-list": "<compound-selector>#", + "complex-selector": "<complex-selector-unit> [<combinator>? <complex-selector-unit>]*", + "complex-selector-list": "<complex-selector>#", + "conic-gradient()": "conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )", + "contextual-alt-values": "[contextual|no-contextual]", + "content-distribution": "space-between|space-around|space-evenly|stretch", + "content-list": "[<string>|contents|<image>|<counter>|<quote>|<target>|<leader()>|<attr()>]+", + "content-position": "center|start|end|flex-start|flex-end", + "content-replacement": "<image>", + "contrast()": "contrast( [<number-percentage>] )", + "cos()": "cos( <calc-sum> )", + "counter": "<counter()>|<counters()>", + "counter()": "counter( <counter-name> , <counter-style>? )", + "counter-name": "<custom-ident>", + "counter-style": "<counter-style-name>|symbols( )", + "counter-style-name": "<custom-ident>", + "counters()": "counters( <counter-name> , <string> , <counter-style>? )", + "cross-fade()": "cross-fade( <cf-mixing-image> , <cf-final-image>? )", + "cubic-bezier-timing-function": "ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )", + "deprecated-system-color": "ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText", + "discretionary-lig-values": "[discretionary-ligatures|no-discretionary-ligatures]", + "display-box": "contents|none", + "display-inside": "flow|flow-root|table|flex|grid|ruby", + "display-internal": "table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container", + "display-legacy": "inline-block|inline-list-item|inline-table|inline-flex|inline-grid", + "display-listitem": "<display-outside>?&&[flow|flow-root]?&&list-item", + "display-outside": "block|inline|run-in", + "drop-shadow()": "drop-shadow( <length>{2,3} <color>? )", + "east-asian-variant-values": "[jis78|jis83|jis90|jis04|simplified|traditional]", + "east-asian-width-values": "[full-width|proportional-width]", + "element()": "element( <custom-ident> , [first|start|last|first-except]? )|element( <id-selector> )", + "ellipse()": "ellipse( [<shape-radius>{2}]? [at <position>]? )", + "ending-shape": "circle|ellipse", + "env()": "env( <custom-ident> , <declaration-value>? )", + "exp()": "exp( <calc-sum> )", + "explicit-track-list": "[<line-names>? <track-size>]+ <line-names>?", + "family-name": "<string>|<custom-ident>+", + "feature-tag-value": "<string> [<integer>|on|off]?", + "feature-type": "@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation", + "feature-value-block": "<feature-type> '{' <feature-value-declaration-list> '}'", + "feature-value-block-list": "<feature-value-block>+", + "feature-value-declaration": "<custom-ident> : <integer>+ ;", + "feature-value-declaration-list": "<feature-value-declaration>", + "feature-value-name": "<custom-ident>", + "fill-rule": "nonzero|evenodd", + "filter-function": "<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>", + "filter-function-list": "[<filter-function>|<url>]+", + "final-bg-layer": "<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>", + "fixed-breadth": "<length-percentage>", + "fixed-repeat": "repeat( [<integer [1,∞]>] , [<line-names>? <fixed-size>]+ <line-names>? )", + "fixed-size": "<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )", + "font-stretch-absolute": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>", + "font-variant-css21": "[normal|small-caps]", + "font-weight-absolute": "normal|bold|<number [1,1000]>", + "frequency-percentage": "<frequency>|<percentage>", + "general-enclosed": "[<function-token> <any-value>? )]|[( <any-value>? )]", + "generic-family": "<generic-script-specific>|<generic-complete>|<generic-incomplete>|<-non-standard-generic-family>", + "generic-name": "serif|sans-serif|cursive|fantasy|monospace", + "geometry-box": "<shape-box>|fill-box|stroke-box|view-box", + "gradient": "<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<repeating-conic-gradient()>|<-legacy-gradient>", + "grayscale()": "grayscale( <number-percentage> )", + "grid-line": "auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]", + "historical-lig-values": "[historical-ligatures|no-historical-ligatures]", + "hsl()": "hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )", + "hsla()": "hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )", + "hue": "<number>|<angle>", + "hue-rotate()": "hue-rotate( <angle> )", + "hue-interpolation-method": "[shorter|longer|increasing|decreasing] hue", + "hwb()": "hwb( [<hue>|none] [<percentage>|none] [<percentage>|none] [/ [<alpha-value>|none]]? )", + "hypot()": "hypot( <calc-sum># )", + "image": "<url>|<image()>|<image-set()>|<element()>|<paint()>|<cross-fade()>|<gradient>", + "image()": "image( <image-tags>? [<image-src>? , <color>?]! )", + "image-set()": "image-set( <image-set-option># )", + "image-set-option": "[<image>|<string>] [<resolution>||type( <string> )]", + "image-src": "<url>|<string>", + "image-tags": "ltr|rtl", + "inflexible-breadth": "<length-percentage>|min-content|max-content|auto", + "inset()": "inset( <length-percentage>{1,4} [round <'border-radius'>]? )", + "invert()": "invert( <number-percentage> )", + "keyframes-name": "<custom-ident>|<string>", + "keyframe-block": "<keyframe-selector># { <declaration-list> }", + "keyframe-block-list": "<keyframe-block>+", + "keyframe-selector": "from|to|<percentage>|<timeline-range-name> <percentage>", + "lab()": "lab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )", + "layer()": "layer( <layer-name> )", + "layer-name": "<ident> ['.' <ident>]*", + "lch()": "lch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )", + "leader()": "leader( <leader-type> )", + "leader-type": "dotted|solid|space|<string>", + "length-percentage": "<length>|<percentage>", + "light-dark()": "light-dark( <color> , <color> )", + "line-names": "'[' <custom-ident>* ']'", + "line-name-list": "[<line-names>|<name-repeat>]+", + "line-style": "none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset", + "line-width": "<length>|thin|medium|thick", + "linear-color-hint": "<length-percentage>", + "linear-color-stop": "<color> <color-stop-length>?", + "linear-gradient()": "linear-gradient( [[<angle>|to <side-or-corner>]||<color-interpolation-method>]? , <color-stop-list> )", + "log()": "log( <calc-sum> , <calc-sum>? )", + "mask-layer": "<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>", + "mask-position": "[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?", + "mask-reference": "none|<image>|<mask-source>", + "mask-source": "<url>", + "masking-mode": "alpha|luminance|match-source", + "matrix()": "matrix( <number>#{6} )", + "matrix3d()": "matrix3d( <number>#{16} )", + "max()": "max( <calc-sum># )", + "media-and": "<media-in-parens> [and <media-in-parens>]+", + "media-condition": "<media-not>|<media-and>|<media-or>|<media-in-parens>", + "media-condition-without-or": "<media-not>|<media-and>|<media-in-parens>", + "media-feature": "( [<mf-plain>|<mf-boolean>|<mf-range>] )", + "media-in-parens": "( <media-condition> )|<media-feature>|<general-enclosed>", + "media-not": "not <media-in-parens>", + "media-or": "<media-in-parens> [or <media-in-parens>]+", + "media-query": "<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?", + "media-query-list": "<media-query>#", + "media-type": "<ident>", + "mf-boolean": "<mf-name>", + "mf-name": "<ident>", + "mf-plain": "<mf-name> : <mf-value>", + "mf-range": "<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>", + "mf-value": "<number>|<dimension>|<ident>|<ratio>", + "min()": "min( <calc-sum># )", + "minmax()": "minmax( [<length-percentage>|min-content|max-content|auto] , [<length-percentage>|<flex>|min-content|max-content|auto] )", + "mod()": "mod( <calc-sum> , <calc-sum> )", + "name-repeat": "repeat( [<integer [1,∞]>|auto-fill] , <line-names>+ )", + "named-color": "transparent|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", + "namespace-prefix": "<ident>", + "ns-prefix": "[<ident-token>|'*']? '|'", + "number-percentage": "<number>|<percentage>", + "numeric-figure-values": "[lining-nums|oldstyle-nums]", + "numeric-fraction-values": "[diagonal-fractions|stacked-fractions]", + "numeric-spacing-values": "[proportional-nums|tabular-nums]", + "nth": "<an-plus-b>|even|odd", + "opacity()": "opacity( [<number-percentage>] )", + "overflow-position": "unsafe|safe", + "outline-radius": "<length>|<percentage>", + "page-body": "<declaration>? [; <page-body>]?|<page-margin-box> <page-body>", + "page-margin-box": "<page-margin-box-type> '{' <declaration-list> '}'", + "page-margin-box-type": "@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom", + "page-selector-list": "[<page-selector>#]?", + "page-selector": "<pseudo-page>+|<ident> <pseudo-page>*", + "page-size": "A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger", + "path()": "path( [<fill-rule> ,]? <string> )", + "paint()": "paint( <ident> , <declaration-value>? )", + "perspective()": "perspective( [<length [0,∞]>|none] )", + "polygon()": "polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )", + "polar-color-space": "hsl|hwb|lch|oklch", + "position": "[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]", + "pow()": "pow( <calc-sum> , <calc-sum> )", + "pseudo-class-selector": "':' <ident-token>|':' <function-token> <any-value> ')'", + "pseudo-element-selector": "':' <pseudo-class-selector>|<legacy-pseudo-element-selector>", + "pseudo-page": ": [left|right|first|blank]", + "quote": "open-quote|close-quote|no-open-quote|no-close-quote", + "radial-gradient()": "radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )", + "ratio": "<number [0,∞]> [/ <number [0,∞]>]?", + "ray()": "ray( <angle>&&<ray-size>?&&contain?&&[at <position>]? )", + "ray-size": "closest-side|closest-corner|farthest-side|farthest-corner|sides", + "rectangular-color-space": "srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020|lab|oklab|xyz|xyz-d50|xyz-d65", + "relative-selector": "<combinator>? <complex-selector>", + "relative-selector-list": "<relative-selector>#", + "relative-size": "larger|smaller", + "rem()": "rem( <calc-sum> , <calc-sum> )", + "repeat-style": "repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}", + "repeating-conic-gradient()": "repeating-conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )", + "repeating-linear-gradient()": "repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )", + "repeating-radial-gradient()": "repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )", + "reversed-counter-name": "reversed( <counter-name> )", + "rgb()": "rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )", + "rgba()": "rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )", + "rotate()": "rotate( [<angle>|<zero>] )", + "rotate3d()": "rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )", + "rotateX()": "rotateX( [<angle>|<zero>] )", + "rotateY()": "rotateY( [<angle>|<zero>] )", + "rotateZ()": "rotateZ( [<angle>|<zero>] )", + "round()": "round( <rounding-strategy>? , <calc-sum> , <calc-sum> )", + "rounding-strategy": "nearest|up|down|to-zero", + "saturate()": "saturate( <number-percentage> )", + "scale()": "scale( [<number>|<percentage>]#{1,2} )", + "scale3d()": "scale3d( [<number>|<percentage>]#{3} )", + "scaleX()": "scaleX( [<number>|<percentage>] )", + "scaleY()": "scaleY( [<number>|<percentage>] )", + "scaleZ()": "scaleZ( [<number>|<percentage>] )", + "scroll()": "scroll( [<axis>||<scroller>]? )", + "scroller": "root|nearest|self", + "self-position": "center|start|end|self-start|self-end|flex-start|flex-end", + "shape-radius": "<length-percentage>|closest-side|farthest-side", + "sign()": "sign( <calc-sum> )", + "skew()": "skew( [<angle>|<zero>] , [<angle>|<zero>]? )", + "skewX()": "skewX( [<angle>|<zero>] )", + "skewY()": "skewY( [<angle>|<zero>] )", + "sepia()": "sepia( <number-percentage> )", + "shadow": "inset?&&<length>{2,4}&&<color>?", + "shadow-t": "[<length>{2,3}&&<color>?]", + "shape": "rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )", + "shape-box": "<box>|margin-box", + "side-or-corner": "[left|right]||[top|bottom]", + "sin()": "sin( <calc-sum> )", + "single-animation": "<'animation-duration'>||<easing-function>||<'animation-delay'>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]||<single-animation-timeline>", + "single-animation-direction": "normal|reverse|alternate|alternate-reverse", + "single-animation-fill-mode": "none|forwards|backwards|both", + "single-animation-iteration-count": "infinite|<number>", + "single-animation-play-state": "running|paused", + "single-animation-timeline": "auto|none|<dashed-ident>|<scroll()>|<view()>", + "single-transition": "[none|<single-transition-property>]||<time>||<easing-function>||<time>||<transition-behavior-value>", + "single-transition-property": "all|<custom-ident>", + "size": "closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}", + "sqrt()": "sqrt( <calc-sum> )", + "step-position": "jump-start|jump-end|jump-none|jump-both|start|end", + "step-timing-function": "step-start|step-end|steps( <integer> [, <step-position>]? )", + "subclass-selector": "<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>", + "supports-condition": "not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*", + "supports-in-parens": "( <supports-condition> )|<supports-feature>|<general-enclosed>", + "supports-feature": "<supports-decl>|<supports-selector-fn>", + "supports-decl": "( <declaration> )", + "supports-selector-fn": "selector( <complex-selector> )", + "symbol": "<string>|<image>|<custom-ident>", + "system-color": "AccentColor|AccentColorText|ActiveText|ButtonBorder|ButtonFace|ButtonText|Canvas|CanvasText|Field|FieldText|GrayText|Highlight|HighlightText|LinkText|Mark|MarkText|SelectedItem|SelectedItemText|VisitedText", + "tan()": "tan( <calc-sum> )", + "target": "<target-counter()>|<target-counters()>|<target-text()>", + "target-counter()": "target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )", + "target-counters()": "target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )", + "target-text()": "target-text( [<string>|<url>] , [content|before|after|first-letter]? )", + "time-percentage": "<time>|<percentage>", + "timeline-range-name": "cover|contain|entry|exit|entry-crossing|exit-crossing", + "easing-function": "linear|<cubic-bezier-timing-function>|<step-timing-function>", + "track-breadth": "<length-percentage>|<flex>|min-content|max-content|auto", + "track-list": "[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?", + "track-repeat": "repeat( [<integer [1,∞]>] , [<line-names>? <track-size>]+ <line-names>? )", + "track-size": "<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( <length-percentage> )", + "transform-function": "<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>", + "transform-list": "<transform-function>+", + "transition-behavior-value": "normal|allow-discrete", + "translate()": "translate( <length-percentage> , <length-percentage>? )", + "translate3d()": "translate3d( <length-percentage> , <length-percentage> , <length> )", + "translateX()": "translateX( <length-percentage> )", + "translateY()": "translateY( <length-percentage> )", + "translateZ()": "translateZ( <length> )", + "type-or-unit": "string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%", + "type-selector": "<wq-name>|<ns-prefix>? '*'", + "var()": "var( <custom-property-name> , <declaration-value>? )", + "view()": "view( [<axis>||<'view-timeline-inset'>]? )", + "viewport-length": "auto|<length-percentage>", + "visual-box": "content-box|padding-box|border-box", + "wq-name": "<ns-prefix>? <ident-token>", + "-legacy-gradient": "<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>", + "-legacy-linear-gradient": "-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )", + "-legacy-repeating-linear-gradient": "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )", + "-legacy-linear-gradient-arguments": "[<angle>|<side-or-corner>]? , <color-stop-list>", + "-legacy-radial-gradient": "-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )", + "-legacy-repeating-radial-gradient": "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )", + "-legacy-radial-gradient-arguments": "[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>", + "-legacy-radial-gradient-size": "closest-side|closest-corner|farthest-side|farthest-corner|contain|cover", + "-legacy-radial-gradient-shape": "circle|ellipse", + "-non-standard-font": "-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body", + "-non-standard-color": "-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text", + "-non-standard-image-rendering": "optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast", + "-non-standard-overflow": "overlay|-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable", + "-non-standard-size": "intrinsic|min-intrinsic|-webkit-fill-available|-webkit-fit-content|-webkit-min-content|-webkit-max-content|-moz-available|-moz-fit-content|-moz-min-content|-moz-max-content", + "-webkit-gradient()": "-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )", + "-webkit-gradient-color-stop": "from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )", + "-webkit-gradient-point": "[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]", + "-webkit-gradient-radius": "<length>|<percentage>", + "-webkit-gradient-type": "linear|radial", + "-webkit-mask-box-repeat": "repeat|stretch|round", + "-ms-filter-function-list": "<-ms-filter-function>+", + "-ms-filter-function": "<-ms-filter-function-progid>|<-ms-filter-function-legacy>", + "-ms-filter-function-progid": "'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]", + "-ms-filter-function-legacy": "<ident-token>|<function-token> <any-value>? )", + "absolute-color-base": "<hex-color>|<absolute-color-function>|<named-color>|transparent", + "absolute-color-function": "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>", + "age": "child|young|old", + "anchor-name": "<dashed-ident>", + "attr-name": "<wq-name>", + "attr-fallback": "<any-value>", + "bg-clip": "<box>|border|text", + "bottom": "<length>|auto", + "container-name": "<custom-ident>", + "container-condition": "not <query-in-parens>|<query-in-parens> [[and <query-in-parens>]*|[or <query-in-parens>]*]", + "coord-box": "content-box|padding-box|border-box|fill-box|stroke-box|view-box", + "generic-voice": "[<age>? <gender> <integer>?]", + "gender": "male|female|neutral", + "generic-script-specific": "generic( kai )|generic( fangsong )|generic( nastaliq )", + "generic-complete": "serif|sans-serif|system-ui|cursive|fantasy|math|monospace", + "generic-incomplete": "ui-serif|ui-sans-serif|ui-monospace|ui-rounded", + "-non-standard-generic-family": "-apple-system|BlinkMacSystemFont", + "left": "<length>|auto", + "color-base": "<hex-color>|<color-function>|<named-color>|<color-mix()>|transparent", + "color-function": "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>", + "device-cmyk()": "<legacy-device-cmyk-syntax>|<modern-device-cmyk-syntax>", + "legacy-device-cmyk-syntax": "device-cmyk( <number>#{4} )", + "modern-device-cmyk-syntax": "device-cmyk( <cmyk-component>{4} [/ [<alpha-value>|none]]? )", + "cmyk-component": "<number>|<percentage>|none", + "color-mix()": "color-mix( <color-interpolation-method> , [<color>&&<percentage [0,100]>?]#{2} )", + "color-space": "<rectangular-color-space>|<polar-color-space>|<custom-color-space>", + "custom-color-space": "<dashed-ident>", + "paint": "none|<color>|<url> [none|<color>]?|context-fill|context-stroke", + "palette-identifier": "<dashed-ident>", + "right": "<length>|auto", + "scope-start": "<forgiving-selector-list>", + "scope-end": "<forgiving-selector-list>", + "forgiving-selector-list": "<complex-real-selector-list>", + "forgiving-relative-selector-list": "<relative-real-selector-list>", + "selector-list": "<complex-selector-list>", + "complex-real-selector-list": "<complex-real-selector>#", + "simple-selector-list": "<simple-selector>#", + "relative-real-selector-list": "<relative-real-selector>#", + "complex-selector-unit": "[<compound-selector>? <pseudo-compound-selector>*]!", + "complex-real-selector": "<compound-selector> [<combinator>? <compound-selector>]*", + "relative-real-selector": "<combinator>? <complex-real-selector>", + "pseudo-compound-selector": "<pseudo-element-selector> <pseudo-class-selector>*", + "simple-selector": "<type-selector>|<subclass-selector>", + "legacy-pseudo-element-selector": "':' [before|after|first-line|first-letter]", + "single-animation-composition": "replace|add|accumulate", + "svg-length": "<percentage>|<length>|<number>", + "svg-writing-mode": "lr-tb|rl-tb|tb-rl|lr|rl|tb", + "top": "<length>|auto", + "x": "<number>", + "y": "<number>", + "declaration": "<ident-token> : <declaration-value>? ['!' important]?", + "declaration-list": "[<declaration>? ';']* <declaration>?", + "url": "url( <string> <url-modifier>* )|<url-token>", + "url-modifier": "<ident>|<function-token> <any-value> )", + "number-zero-one": "<number [0,1]>", + "number-one-or-greater": "<number [1,∞]>", + "color()": "color( <colorspace-params> [/ [<alpha-value>|none]]? )", + "colorspace-params": "[<predefined-rgb-params>|<xyz-params>]", + "predefined-rgb-params": "<predefined-rgb> [<number>|<percentage>|none]{3}", + "predefined-rgb": "srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020", + "xyz-params": "<xyz-space> [<number>|<percentage>|none]{3}", + "xyz-space": "xyz|xyz-d50|xyz-d65", + "oklab()": "oklab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )", + "oklch()": "oklch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )", + "offset-path": "<ray()>|<url>|<basic-shape>", + "rect()": "rect( [<length-percentage>|auto]{4} [round <'border-radius'>]? )", + "xywh()": "xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [round <'border-radius'>]? )", + "query-in-parens": "( <container-condition> )|( <size-feature> )|style( <style-query> )|<general-enclosed>", + "size-feature": "<mf-plain>|<mf-boolean>|<mf-range>", + "style-feature": "<declaration>", + "style-query": "<style-condition>|<style-feature>", + "style-condition": "not <style-in-parens>|<style-in-parens> [[and <style-in-parens>]*|[or <style-in-parens>]*]", + "style-in-parens": "( <style-condition> )|( <style-feature> )|<general-enclosed>", + "-non-standard-display": "-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box", + "inset-area": "[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]", + "position-area": "[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|center|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|center|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]", + "anchor()": "anchor( <anchor-element>?&&<anchor-side> , <length-percentage>? )", + "anchor-side": "inside|outside|top|left|right|bottom|start|end|self-start|self-end|<percentage>|center", + "anchor-size()": "anchor-size( [<anchor-element>||<anchor-size>]? , <length-percentage>? )", + "anchor-size": "width|height|block|inline|self-block|self-inline", + "anchor-element": "<dashed-ident>", + "try-size": "most-width|most-height|most-block-size|most-inline-size", + "try-tactic": "flip-block||flip-inline||flip-start", + "font-variant-css2": "normal|small-caps", + "font-width-css3": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded", + "system-family-name": "caption|icon|menu|message-box|small-caption|status-bar" + }, + "properties": { + "--*": "<declaration-value>", + "-ms-accelerator": "false|true", + "-ms-block-progression": "tb|rl|bt|lr", + "-ms-content-zoom-chaining": "none|chained", + "-ms-content-zooming": "none|zoom", + "-ms-content-zoom-limit": "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>", + "-ms-content-zoom-limit-max": "<percentage>", + "-ms-content-zoom-limit-min": "<percentage>", + "-ms-content-zoom-snap": "<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>", + "-ms-content-zoom-snap-points": "snapInterval( <percentage> , <percentage> )|snapList( <percentage># )", + "-ms-content-zoom-snap-type": "none|proximity|mandatory", + "-ms-filter": "<string>", + "-ms-flow-from": "[none|<custom-ident>]#", + "-ms-flow-into": "[none|<custom-ident>]#", + "-ms-grid-columns": "none|<track-list>|<auto-track-list>", + "-ms-grid-rows": "none|<track-list>|<auto-track-list>", + "-ms-high-contrast-adjust": "auto|none", + "-ms-hyphenate-limit-chars": "auto|<integer>{1,3}", + "-ms-hyphenate-limit-lines": "no-limit|<integer>", + "-ms-hyphenate-limit-zone": "<percentage>|<length>", + "-ms-ime-align": "auto|after", + "-ms-overflow-style": "auto|none|scrollbar|-ms-autohiding-scrollbar", + "-ms-scrollbar-3dlight-color": "<color>", + "-ms-scrollbar-arrow-color": "<color>", + "-ms-scrollbar-base-color": "<color>", + "-ms-scrollbar-darkshadow-color": "<color>", + "-ms-scrollbar-face-color": "<color>", + "-ms-scrollbar-highlight-color": "<color>", + "-ms-scrollbar-shadow-color": "<color>", + "-ms-scrollbar-track-color": "<color>", + "-ms-scroll-chaining": "chained|none", + "-ms-scroll-limit": "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>", + "-ms-scroll-limit-x-max": "auto|<length>", + "-ms-scroll-limit-x-min": "<length>", + "-ms-scroll-limit-y-max": "auto|<length>", + "-ms-scroll-limit-y-min": "<length>", + "-ms-scroll-rails": "none|railed", + "-ms-scroll-snap-points-x": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )", + "-ms-scroll-snap-points-y": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )", + "-ms-scroll-snap-type": "none|proximity|mandatory", + "-ms-scroll-snap-x": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>", + "-ms-scroll-snap-y": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>", + "-ms-scroll-translation": "none|vertical-to-horizontal", + "-ms-text-autospace": "none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space", + "-ms-touch-select": "grippers|none", + "-ms-user-select": "none|element|text", + "-ms-wrap-flow": "auto|both|start|end|maximum|clear", + "-ms-wrap-margin": "<length>", + "-ms-wrap-through": "wrap|none", + "-moz-appearance": "none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized", + "-moz-binding": "<url>|none", + "-moz-border-bottom-colors": "<color>+|none", + "-moz-border-left-colors": "<color>+|none", + "-moz-border-right-colors": "<color>+|none", + "-moz-border-top-colors": "<color>+|none", + "-moz-context-properties": "none|[fill|fill-opacity|stroke|stroke-opacity]#", + "-moz-float-edge": "border-box|content-box|margin-box|padding-box", + "-moz-force-broken-image-icon": "0|1", + "-moz-image-region": "<shape>|auto", + "-moz-orient": "inline|block|horizontal|vertical", + "-moz-outline-radius": "<outline-radius>{1,4} [/ <outline-radius>{1,4}]?", + "-moz-outline-radius-bottomleft": "<outline-radius>", + "-moz-outline-radius-bottomright": "<outline-radius>", + "-moz-outline-radius-topleft": "<outline-radius>", + "-moz-outline-radius-topright": "<outline-radius>", + "-moz-stack-sizing": "ignore|stretch-to-fit", + "-moz-text-blink": "none|blink", + "-moz-user-focus": "ignore|normal|select-after|select-before|select-menu|select-same|select-all|none", + "-moz-user-input": "auto|none|enabled|disabled", + "-moz-user-modify": "read-only|read-write|write-only", + "-moz-window-dragging": "drag|no-drag", + "-moz-window-shadow": "default|menu|tooltip|sheet|none", + "-webkit-appearance": "none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|inner-spin-button|listbox|listitem|media-controls-background|media-controls-fullscreen-background|media-current-time-display|media-enter-fullscreen-button|media-exit-fullscreen-button|media-fullscreen-button|media-mute-button|media-overlay-play-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|media-time-remaining-display|media-toggle-closed-captions-button|media-volume-slider|media-volume-slider-container|media-volume-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|meter|progress-bar|progress-bar-value|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield|-apple-pay-button", + "-webkit-border-before": "<'border-width'>||<'border-style'>||<color>", + "-webkit-border-before-color": "<color>", + "-webkit-border-before-style": "<'border-style'>", + "-webkit-border-before-width": "<'border-width'>", + "-webkit-box-reflect": "[above|below|right|left]? <length>? <image>?", + "-webkit-line-clamp": "none|<integer>", + "-webkit-mask": "[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#", + "-webkit-mask-attachment": "<attachment>#", + "-webkit-mask-clip": "[<box>|border|padding|content|text]#", + "-webkit-mask-composite": "<composite-style>#", + "-webkit-mask-image": "<mask-reference>#", + "-webkit-mask-origin": "[<box>|border|padding|content]#", + "-webkit-mask-position": "<position>#", + "-webkit-mask-position-x": "[<length-percentage>|left|center|right]#", + "-webkit-mask-position-y": "[<length-percentage>|top|center|bottom]#", + "-webkit-mask-repeat": "<repeat-style>#", + "-webkit-mask-repeat-x": "repeat|no-repeat|space|round", + "-webkit-mask-repeat-y": "repeat|no-repeat|space|round", + "-webkit-mask-size": "<bg-size>#", + "-webkit-overflow-scrolling": "auto|touch", + "-webkit-tap-highlight-color": "<color>", + "-webkit-text-fill-color": "<color>", + "-webkit-text-stroke": "<length>||<color>", + "-webkit-text-stroke-color": "<color>", + "-webkit-text-stroke-width": "<length>", + "-webkit-touch-callout": "default|none", + "-webkit-user-modify": "read-only|read-write|read-write-plaintext-only", + "accent-color": "auto|<color>", + "align-content": "normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>", + "align-items": "normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]", + "align-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>", + "align-tracks": "[normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>]#", + "all": "initial|inherit|unset|revert|revert-layer", + "anchor-name": "none|<dashed-ident>#", + "anchor-scope": "none|all|<dashed-ident>#", + "animation": "<single-animation>#", + "animation-composition": "<single-animation-composition>#", + "animation-delay": "<time>#", + "animation-direction": "<single-animation-direction>#", + "animation-duration": "<time>#", + "animation-fill-mode": "<single-animation-fill-mode>#", + "animation-iteration-count": "<single-animation-iteration-count>#", + "animation-name": "[none|<keyframes-name>]#", + "animation-play-state": "<single-animation-play-state>#", + "animation-range": "[<'animation-range-start'> <'animation-range-end'>?]#", + "animation-range-end": "[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#", + "animation-range-start": "[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#", + "animation-timing-function": "<easing-function>#", + "animation-timeline": "<single-animation-timeline>#", + "appearance": "none|auto|textfield|menulist-button|<compat-auto>", + "aspect-ratio": "auto||<ratio>", + "azimuth": "<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards", + "backdrop-filter": "none|<filter-function-list>", + "backface-visibility": "visible|hidden", + "background": "[<bg-layer> ,]* <final-bg-layer>", + "background-attachment": "<attachment>#", + "background-blend-mode": "<blend-mode>#", + "background-clip": "<bg-clip>#", + "background-color": "<color>", + "background-image": "<bg-image>#", + "background-origin": "<box>#", + "background-position": "<bg-position>#", + "background-position-x": "[center|[[left|right|x-start|x-end]? <length-percentage>?]!]#", + "background-position-y": "[center|[[top|bottom|y-start|y-end]? <length-percentage>?]!]#", + "background-repeat": "<repeat-style>#", + "background-size": "<bg-size>#", + "block-size": "<'width'>", + "border": "<line-width>||<line-style>||<color>", + "border-block": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-block-color": "<'border-top-color'>{1,2}", + "border-block-style": "<'border-top-style'>", + "border-block-width": "<'border-top-width'>", + "border-block-end": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-block-end-color": "<'border-top-color'>", + "border-block-end-style": "<'border-top-style'>", + "border-block-end-width": "<'border-top-width'>", + "border-block-start": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-block-start-color": "<'border-top-color'>", + "border-block-start-style": "<'border-top-style'>", + "border-block-start-width": "<'border-top-width'>", + "border-bottom": "<line-width>||<line-style>||<color>", + "border-bottom-color": "<'border-top-color'>", + "border-bottom-left-radius": "<length-percentage>{1,2}", + "border-bottom-right-radius": "<length-percentage>{1,2}", + "border-bottom-style": "<line-style>", + "border-bottom-width": "<line-width>", + "border-collapse": "collapse|separate", + "border-color": "<color>{1,4}", + "border-end-end-radius": "<length-percentage>{1,2}", + "border-end-start-radius": "<length-percentage>{1,2}", + "border-image": "<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>", + "border-image-outset": "[<length>|<number>]{1,4}", + "border-image-repeat": "[stretch|repeat|round|space]{1,2}", + "border-image-slice": "<number-percentage>{1,4}&&fill?", + "border-image-source": "none|<image>", + "border-image-width": "[<length-percentage>|<number>|auto]{1,4}", + "border-inline": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-inline-end": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-inline-color": "<'border-top-color'>{1,2}", + "border-inline-style": "<'border-top-style'>", + "border-inline-width": "<'border-top-width'>", + "border-inline-end-color": "<'border-top-color'>", + "border-inline-end-style": "<'border-top-style'>", + "border-inline-end-width": "<'border-top-width'>", + "border-inline-start": "<'border-top-width'>||<'border-top-style'>||<color>", + "border-inline-start-color": "<'border-top-color'>", + "border-inline-start-style": "<'border-top-style'>", + "border-inline-start-width": "<'border-top-width'>", + "border-left": "<line-width>||<line-style>||<color>", + "border-left-color": "<color>", + "border-left-style": "<line-style>", + "border-left-width": "<line-width>", + "border-radius": "<length-percentage>{1,4} [/ <length-percentage>{1,4}]?", + "border-right": "<line-width>||<line-style>||<color>", + "border-right-color": "<color>", + "border-right-style": "<line-style>", + "border-right-width": "<line-width>", + "border-spacing": "<length> <length>?", + "border-start-end-radius": "<length-percentage>{1,2}", + "border-start-start-radius": "<length-percentage>{1,2}", + "border-style": "<line-style>{1,4}", + "border-top": "<line-width>||<line-style>||<color>", + "border-top-color": "<color>", + "border-top-left-radius": "<length-percentage>{1,2}", + "border-top-right-radius": "<length-percentage>{1,2}", + "border-top-style": "<line-style>", + "border-top-width": "<line-width>", + "border-width": "<line-width>{1,4}", + "bottom": "<length>|<percentage>|auto", + "box-align": "start|center|end|baseline|stretch", + "box-decoration-break": "slice|clone", + "box-direction": "normal|reverse|inherit", + "box-flex": "<number>", + "box-flex-group": "<integer>", + "box-lines": "single|multiple", + "box-ordinal-group": "<integer>", + "box-orient": "horizontal|vertical|inline-axis|block-axis|inherit", + "box-pack": "start|center|end|justify", + "box-shadow": "none|<shadow>#", + "box-sizing": "content-box|border-box", + "break-after": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region", + "break-before": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region", + "break-inside": "auto|avoid|avoid-page|avoid-column|avoid-region", + "caption-side": "top|bottom|block-start|block-end|inline-start|inline-end", + "caret": "<'caret-color'>||<'caret-shape'>", + "caret-color": "auto|<color>", + "caret-shape": "auto|bar|block|underscore", + "clear": "none|left|right|both|inline-start|inline-end", + "clip": "<shape>|auto", + "clip-path": "<clip-source>|[<basic-shape>||<geometry-box>]|none", + "clip-rule": "nonzero|evenodd", + "color": "<color>", + "color-interpolation-filters": "auto|sRGB|linearRGB", + "color-scheme": "normal|[light|dark|<custom-ident>]+&&only?", + "column-count": "<integer>|auto", + "column-fill": "auto|balance", + "column-gap": "normal|<length-percentage>", + "column-rule": "<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>", + "column-rule-color": "<color>", + "column-rule-style": "<'border-style'>", + "column-rule-width": "<'border-width'>", + "column-span": "none|all", + "column-width": "<length>|auto", + "columns": "<'column-width'>||<'column-count'>", + "contain": "none|strict|content|[[size||inline-size]||layout||style||paint]", + "contain-intrinsic-size": "[auto? [none|<length>]]{1,2}", + "contain-intrinsic-block-size": "auto? [none|<length>]", + "contain-intrinsic-height": "auto? [none|<length>]", + "contain-intrinsic-inline-size": "auto? [none|<length>]", + "contain-intrinsic-width": "auto? [none|<length>]", + "container": "<'container-name'> [/ <'container-type'>]?", + "container-name": "none|<custom-ident>+", + "container-type": "normal||[size|inline-size]", + "content": "normal|none|[<content-replacement>|<content-list>] [/ [<string>|<counter>]+]?", + "content-visibility": "visible|auto|hidden", + "counter-increment": "[<counter-name> <integer>?]+|none", + "counter-reset": "[<counter-name> <integer>?|<reversed-counter-name> <integer>?]+|none", + "counter-set": "[<counter-name> <integer>?]+|none", + "cursor": "[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]", + "d": "none|path( <string> )", + "cx": "<length>|<percentage>", + "cy": "<length>|<percentage>", + "direction": "ltr|rtl", + "display": "[<display-outside>||<display-inside>]|<display-listitem>|<display-internal>|<display-box>|<display-legacy>|<-non-standard-display>", + "dominant-baseline": "auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge", + "empty-cells": "show|hide", + "field-sizing": "content|fixed", + "fill": "<paint>", + "fill-opacity": "<number-zero-one>", + "fill-rule": "nonzero|evenodd", + "filter": "none|<filter-function-list>|<-ms-filter-function-list>", + "flex": "none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]", + "flex-basis": "content|<'width'>", + "flex-direction": "row|row-reverse|column|column-reverse", + "flex-flow": "<'flex-direction'>||<'flex-wrap'>", + "flex-grow": "<number>", + "flex-shrink": "<number>", + "flex-wrap": "nowrap|wrap|wrap-reverse", + "float": "left|right|none|inline-start|inline-end", + "font": "[[<'font-style'>||<font-variant-css2>||<'font-weight'>||<font-width-css3>]? <'font-size'> [/ <'line-height'>]? <'font-family'>#]|<system-family-name>|<-non-standard-font>", + "font-family": "[<family-name>|<generic-family>]#", + "font-feature-settings": "normal|<feature-tag-value>#", + "font-kerning": "auto|normal|none", + "font-language-override": "normal|<string>", + "font-optical-sizing": "auto|none", + "font-palette": "normal|light|dark|<palette-identifier>", + "font-variation-settings": "normal|[<string> <number>]#", + "font-size": "<absolute-size>|<relative-size>|<length-percentage>", + "font-size-adjust": "none|[ex-height|cap-height|ch-width|ic-width|ic-height]? [from-font|<number>]", + "font-smooth": "auto|never|always|<absolute-size>|<length>", + "font-stretch": "<font-stretch-absolute>", + "font-style": "normal|italic|oblique <angle>?", + "font-synthesis": "none|[weight||style||small-caps||position]", + "font-synthesis-position": "auto|none", + "font-synthesis-small-caps": "auto|none", + "font-synthesis-style": "auto|none", + "font-synthesis-weight": "auto|none", + "font-variant": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]", + "font-variant-alternates": "normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]", + "font-variant-caps": "normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps", + "font-variant-east-asian": "normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]", + "font-variant-emoji": "normal|text|emoji|unicode", + "font-variant-ligatures": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]", + "font-variant-numeric": "normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]", + "font-variant-position": "normal|sub|super", + "font-weight": "<font-weight-absolute>|bolder|lighter", + "forced-color-adjust": "auto|none|preserve-parent-color", + "gap": "<'row-gap'> <'column-gap'>?", + "grid": "<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>", + "grid-area": "<grid-line> [/ <grid-line>]{0,3}", + "grid-auto-columns": "<track-size>+", + "grid-auto-flow": "[row|column]||dense", + "grid-auto-rows": "<track-size>+", + "grid-column": "<grid-line> [/ <grid-line>]?", + "grid-column-end": "<grid-line>", + "grid-column-gap": "<length-percentage>", + "grid-column-start": "<grid-line>", + "grid-gap": "<'grid-row-gap'> <'grid-column-gap'>?", + "grid-row": "<grid-line> [/ <grid-line>]?", + "grid-row-end": "<grid-line>", + "grid-row-gap": "<length-percentage>", + "grid-row-start": "<grid-line>", + "grid-template": "none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?", + "grid-template-areas": "none|<string>+", + "grid-template-columns": "none|<track-list>|<auto-track-list>|subgrid <line-name-list>?", + "grid-template-rows": "none|<track-list>|<auto-track-list>|subgrid <line-name-list>?", + "hanging-punctuation": "none|[first||[force-end|allow-end]||last]", + "height": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "hyphenate-character": "auto|<string>", + "hyphenate-limit-chars": "[auto|<integer>]{1,3}", + "hyphens": "none|manual|auto", + "image-orientation": "from-image|<angle>|[<angle>? flip]", + "image-rendering": "auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>", + "image-resolution": "[from-image||<resolution>]&&snap?", + "ime-mode": "auto|normal|active|inactive|disabled", + "initial-letter": "normal|[<number> <integer>?]", + "initial-letter-align": "[auto|alphabetic|hanging|ideographic]", + "inline-size": "<'width'>", + "input-security": "auto|none", + "inset": "<'top'>{1,4}", + "inset-block": "<'top'>{1,2}", + "inset-block-end": "<'top'>", + "inset-block-start": "<'top'>", + "inset-inline": "<'top'>{1,2}", + "inset-inline-end": "<'top'>", + "inset-inline-start": "<'top'>", + "interpolate-size": "numeric-only|allow-keywords", + "isolation": "auto|isolate", + "justify-content": "normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]", + "justify-items": "normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]", + "justify-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]", + "justify-tracks": "[normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]]#", + "left": "<length>|<percentage>|auto", + "letter-spacing": "normal|<length-percentage>", + "line-break": "auto|loose|normal|strict|anywhere", + "line-clamp": "none|<integer>", + "line-height": "normal|<number>|<length>|<percentage>", + "line-height-step": "<length>", + "list-style": "<'list-style-type'>||<'list-style-position'>||<'list-style-image'>", + "list-style-image": "<image>|none", + "list-style-position": "inside|outside", + "list-style-type": "<counter-style>|<string>|none", + "margin": "[<length>|<percentage>|auto]{1,4}", + "margin-block": "<'margin-left'>{1,2}", + "margin-block-end": "<'margin-left'>", + "margin-block-start": "<'margin-left'>", + "margin-bottom": "<length>|<percentage>|auto", + "margin-inline": "<'margin-left'>{1,2}", + "margin-inline-end": "<'margin-left'>", + "margin-inline-start": "<'margin-left'>", + "margin-left": "<length>|<percentage>|auto", + "margin-right": "<length>|<percentage>|auto", + "margin-top": "<length>|<percentage>|auto", + "margin-trim": "none|in-flow|all", + "marker": "none|<url>", + "marker-end": "none|<url>", + "marker-mid": "none|<url>", + "marker-start": "none|<url>", + "mask": "<mask-layer>#", + "mask-border": "<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>", + "mask-border-mode": "luminance|alpha", + "mask-border-outset": "[<length>|<number>]{1,4}", + "mask-border-repeat": "[stretch|repeat|round|space]{1,2}", + "mask-border-slice": "<number-percentage>{1,4} fill?", + "mask-border-source": "none|<image>", + "mask-border-width": "[<length-percentage>|<number>|auto]{1,4}", + "mask-clip": "[<geometry-box>|no-clip]#", + "mask-composite": "<compositing-operator>#", + "mask-image": "<mask-reference>#", + "mask-mode": "<masking-mode>#", + "mask-origin": "<geometry-box>#", + "mask-position": "<position>#", + "mask-repeat": "<repeat-style>#", + "mask-size": "<bg-size>#", + "mask-type": "luminance|alpha", + "masonry-auto-flow": "[pack|next]||[definite-first|ordered]", + "math-depth": "auto-add|add( <integer> )|<integer>", + "math-shift": "normal|compact", + "math-style": "normal|compact", + "max-block-size": "<'max-width'>", + "max-height": "none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "max-inline-size": "<'max-width'>", + "max-lines": "none|<integer>", + "max-width": "none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "min-block-size": "<'min-width'>", + "min-height": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "min-inline-size": "<'min-width'>", + "min-width": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "mix-blend-mode": "<blend-mode>|plus-lighter", + "object-fit": "fill|contain|cover|none|scale-down", + "object-position": "<position>", + "offset": "[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?", + "offset-anchor": "auto|<position>", + "offset-distance": "<length-percentage>", + "offset-path": "none|<offset-path>||<coord-box>", + "offset-position": "normal|auto|<position>", + "offset-rotate": "[auto|reverse]||<angle>", + "opacity": "<alpha-value>", + "order": "<integer>", + "orphans": "<integer>", + "outline": "[<'outline-width'>||<'outline-style'>||<'outline-color'>]", + "outline-color": "auto|<color>", + "outline-offset": "<length>", + "outline-style": "auto|<'border-style'>", + "outline-width": "<line-width>", + "overflow": "[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>", + "overflow-anchor": "auto|none", + "overflow-block": "visible|hidden|clip|scroll|auto", + "overflow-clip-box": "padding-box|content-box", + "overflow-clip-margin": "<visual-box>||<length [0,∞]>", + "overflow-inline": "visible|hidden|clip|scroll|auto", + "overflow-wrap": "normal|break-word|anywhere", + "overflow-x": "visible|hidden|clip|scroll|auto", + "overflow-y": "visible|hidden|clip|scroll|auto", + "overlay": "none|auto", + "overscroll-behavior": "[contain|none|auto]{1,2}", + "overscroll-behavior-block": "contain|none|auto", + "overscroll-behavior-inline": "contain|none|auto", + "overscroll-behavior-x": "contain|none|auto", + "overscroll-behavior-y": "contain|none|auto", + "padding": "[<length>|<percentage>]{1,4}", + "padding-block": "<'padding-left'>{1,2}", + "padding-block-end": "<'padding-left'>", + "padding-block-start": "<'padding-left'>", + "padding-bottom": "<length>|<percentage>", + "padding-inline": "<'padding-left'>{1,2}", + "padding-inline-end": "<'padding-left'>", + "padding-inline-start": "<'padding-left'>", + "padding-left": "<length>|<percentage>", + "padding-right": "<length>|<percentage>", + "padding-top": "<length>|<percentage>", + "page": "auto|<custom-ident>", + "page-break-after": "auto|always|avoid|left|right|recto|verso", + "page-break-before": "auto|always|avoid|left|right|recto|verso", + "page-break-inside": "auto|avoid", + "paint-order": "normal|[fill||stroke||markers]", + "perspective": "none|<length>", + "perspective-origin": "<position>", + "place-content": "<'align-content'> <'justify-content'>?", + "place-items": "<'align-items'> <'justify-items'>?", + "place-self": "<'align-self'> <'justify-self'>?", + "pointer-events": "auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit", + "position": "static|relative|absolute|sticky|fixed|-webkit-sticky", + "position-anchor": "auto|<anchor-name>", + "position-area": "none|<position-area>", + "position-try": "<'position-try-order'>? <'position-try-fallbacks'>", + "position-try-fallbacks": "none|[[<dashed-ident>||<try-tactic>]|<'position-area'>]#", + "position-try-order": "normal|<try-size>", + "position-visibility": "always|[anchors-valid||anchors-visible||no-overflow]", + "print-color-adjust": "economy|exact", + "quotes": "none|auto|[<string> <string>]+", + "r": "<length>|<percentage>", + "resize": "none|both|horizontal|vertical|block|inline", + "right": "<length>|<percentage>|auto", + "rotate": "none|<angle>|[x|y|z|<number>{3}]&&<angle>", + "row-gap": "normal|<length-percentage>", + "ruby-align": "start|center|space-between|space-around", + "ruby-merge": "separate|collapse|auto", + "ruby-position": "[alternate||[over|under]]|inter-character", + "rx": "<length>|<percentage>", + "ry": "<length>|<percentage>", + "scale": "none|[<number>|<percentage>]{1,3}", + "scrollbar-color": "auto|<color>{2}", + "scrollbar-gutter": "auto|stable&&both-edges?", + "scrollbar-width": "auto|thin|none", + "scroll-behavior": "auto|smooth", + "scroll-margin": "<length>{1,4}", + "scroll-margin-block": "<length>{1,2}", + "scroll-margin-block-start": "<length>", + "scroll-margin-block-end": "<length>", + "scroll-margin-bottom": "<length>", + "scroll-margin-inline": "<length>{1,2}", + "scroll-margin-inline-start": "<length>", + "scroll-margin-inline-end": "<length>", + "scroll-margin-left": "<length>", + "scroll-margin-right": "<length>", + "scroll-margin-top": "<length>", + "scroll-padding": "[auto|<length-percentage>]{1,4}", + "scroll-padding-block": "[auto|<length-percentage>]{1,2}", + "scroll-padding-block-start": "auto|<length-percentage>", + "scroll-padding-block-end": "auto|<length-percentage>", + "scroll-padding-bottom": "auto|<length-percentage>", + "scroll-padding-inline": "[auto|<length-percentage>]{1,2}", + "scroll-padding-inline-start": "auto|<length-percentage>", + "scroll-padding-inline-end": "auto|<length-percentage>", + "scroll-padding-left": "auto|<length-percentage>", + "scroll-padding-right": "auto|<length-percentage>", + "scroll-padding-top": "auto|<length-percentage>", + "scroll-snap-align": "[none|start|end|center]{1,2}", + "scroll-snap-coordinate": "none|<position>#", + "scroll-snap-destination": "<position>", + "scroll-snap-points-x": "none|repeat( <length-percentage> )", + "scroll-snap-points-y": "none|repeat( <length-percentage> )", + "scroll-snap-stop": "normal|always", + "scroll-snap-type": "none|[x|y|block|inline|both] [mandatory|proximity]?", + "scroll-snap-type-x": "none|mandatory|proximity", + "scroll-snap-type-y": "none|mandatory|proximity", + "scroll-timeline": "[<'scroll-timeline-name'>||<'scroll-timeline-axis'>]#", + "scroll-timeline-axis": "[block|inline|x|y]#", + "scroll-timeline-name": "[none|<dashed-ident>]#", + "shape-image-threshold": "<alpha-value>", + "shape-margin": "<length-percentage>", + "shape-outside": "none|[<shape-box>||<basic-shape>]|<image>", + "shape-rendering": "auto|optimizeSpeed|crispEdges|geometricPrecision", + "stroke": "<paint>", + "stroke-dasharray": "none|[<svg-length>+]#", + "stroke-dashoffset": "<svg-length>", + "stroke-linecap": "butt|round|square", + "stroke-linejoin": "miter|round|bevel", + "stroke-miterlimit": "<number-one-or-greater>", + "stroke-opacity": "<'opacity'>", + "stroke-width": "<svg-length>", + "tab-size": "<integer>|<length>", + "table-layout": "auto|fixed", + "text-align": "start|end|left|right|center|justify|match-parent", + "text-align-last": "auto|start|end|left|right|center|justify", + "text-anchor": "start|middle|end", + "text-combine-upright": "none|all|[digits <integer>?]", + "text-decoration": "<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>||<'text-decoration-thickness'>", + "text-decoration-color": "<color>", + "text-decoration-line": "none|[underline||overline||line-through||blink]|spelling-error|grammar-error", + "text-decoration-skip": "none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]", + "text-decoration-skip-ink": "auto|all|none", + "text-decoration-style": "solid|double|dotted|dashed|wavy", + "text-decoration-thickness": "auto|from-font|<length>|<percentage>", + "text-emphasis": "<'text-emphasis-style'>||<'text-emphasis-color'>", + "text-emphasis-color": "<color>", + "text-emphasis-position": "auto|[over|under]&&[right|left]?", + "text-emphasis-style": "none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>", + "text-indent": "<length-percentage>&&hanging?&&each-line?", + "text-justify": "auto|inter-character|inter-word|none", + "text-orientation": "mixed|upright|sideways", + "text-overflow": "[clip|ellipsis|<string>]{1,2}", + "text-rendering": "auto|optimizeSpeed|optimizeLegibility|geometricPrecision", + "text-shadow": "none|<shadow-t>#", + "text-size-adjust": "none|auto|<percentage>", + "text-spacing-trim": "space-all|normal|space-first|trim-start|trim-both|trim-all|auto", + "text-transform": "none|capitalize|uppercase|lowercase|full-width|full-size-kana", + "text-underline-offset": "auto|<length>|<percentage>", + "text-underline-position": "auto|from-font|[under||[left|right]]", + "text-wrap": "<'text-wrap-mode'>||<'text-wrap-style'>", + "text-wrap-mode": "auto|wrap|nowrap", + "text-wrap-style": "auto|balance|stable|pretty", + "timeline-scope": "none|<dashed-ident>#", + "top": "<length>|<percentage>|auto", + "touch-action": "auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation", + "transform": "none|<transform-list>", + "transform-box": "content-box|border-box|fill-box|stroke-box|view-box", + "transform-origin": "[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?", + "transform-style": "flat|preserve-3d", + "transition": "<single-transition>#", + "transition-behavior": "<transition-behavior-value>#", + "transition-delay": "<time>#", + "transition-duration": "<time>#", + "transition-property": "none|<single-transition-property>#", + "transition-timing-function": "<easing-function>#", + "translate": "none|<length-percentage> [<length-percentage> <length>?]?", + "unicode-bidi": "normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate|-webkit-isolate-override|-webkit-plaintext", + "user-select": "auto|text|none|contain|all", + "vector-effect": "none|non-scaling-stroke|non-scaling-size|non-rotation|fixed-position", + "vertical-align": "baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>", + "view-timeline": "[<'view-timeline-name'> <'view-timeline-axis'>?]#", + "view-timeline-axis": "[block|inline|x|y]#", + "view-timeline-inset": "[[auto|<length-percentage>]{1,2}]#", + "view-timeline-name": "none|<dashed-ident>#", + "view-transition-name": "none|<custom-ident>", + "visibility": "visible|hidden|collapse", + "white-space": "normal|pre|nowrap|pre-wrap|pre-line|break-spaces|[<'white-space-collapse'>||<'text-wrap'>||<'white-space-trim'>]", + "white-space-collapse": "collapse|discard|preserve|preserve-breaks|preserve-spaces|break-spaces", + "widows": "<integer>", + "width": "auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|stretch|<-non-standard-size>", + "will-change": "auto|<animateable-feature>#", + "word-break": "normal|break-all|keep-all|break-word|auto-phrase", + "word-spacing": "normal|<length>", + "word-wrap": "normal|break-word", + "writing-mode": "horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>", + "x": "<length>|<percentage>", + "y": "<length>|<percentage>", + "z-index": "auto|<integer>", + "zoom": "normal|reset|<number>|<percentage>", + "-moz-background-clip": "padding|border", + "-moz-border-radius-bottomleft": "<'border-bottom-left-radius'>", + "-moz-border-radius-bottomright": "<'border-bottom-right-radius'>", + "-moz-border-radius-topleft": "<'border-top-left-radius'>", + "-moz-border-radius-topright": "<'border-bottom-right-radius'>", + "-moz-control-character-visibility": "visible|hidden", + "-moz-osx-font-smoothing": "auto|grayscale", + "-moz-user-select": "none|text|all|-moz-none", + "-ms-flex-align": "start|end|center|baseline|stretch", + "-ms-flex-item-align": "auto|start|end|center|baseline|stretch", + "-ms-flex-line-pack": "start|end|center|justify|distribute|stretch", + "-ms-flex-negative": "<'flex-shrink'>", + "-ms-flex-pack": "start|end|center|justify|distribute", + "-ms-flex-order": "<integer>", + "-ms-flex-positive": "<'flex-grow'>", + "-ms-flex-preferred-size": "<'flex-basis'>", + "-ms-interpolation-mode": "nearest-neighbor|bicubic", + "-ms-grid-column-align": "start|end|center|stretch", + "-ms-grid-row-align": "start|end|center|stretch", + "-ms-hyphenate-limit-last": "none|always|column|page|spread", + "-webkit-background-clip": "[<box>|border|padding|content|text]#", + "-webkit-column-break-after": "always|auto|avoid", + "-webkit-column-break-before": "always|auto|avoid", + "-webkit-column-break-inside": "always|auto|avoid", + "-webkit-font-smoothing": "auto|none|antialiased|subpixel-antialiased", + "-webkit-mask-box-image": "[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?", + "-webkit-print-color-adjust": "economy|exact", + "-webkit-text-security": "none|circle|disc|square", + "-webkit-user-drag": "none|element|auto", + "-webkit-user-select": "auto|none|text|all", + "alignment-baseline": "auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical", + "baseline-shift": "baseline|sub|super|<svg-length>", + "behavior": "<url>+", + "cue": "<'cue-before'> <'cue-after'>?", + "cue-after": "<url> <decibel>?|none", + "cue-before": "<url> <decibel>?|none", + "glyph-orientation-horizontal": "<angle>", + "glyph-orientation-vertical": "<angle>", + "kerning": "auto|<svg-length>", + "pause": "<'pause-before'> <'pause-after'>?", + "pause-after": "<time>|none|x-weak|weak|medium|strong|x-strong", + "pause-before": "<time>|none|x-weak|weak|medium|strong|x-strong", + "rest": "<'rest-before'> <'rest-after'>?", + "rest-after": "<time>|none|x-weak|weak|medium|strong|x-strong", + "rest-before": "<time>|none|x-weak|weak|medium|strong|x-strong", + "src": "[<url> [format( <string># )]?|local( <family-name> )]#", + "speak": "auto|never|always", + "speak-as": "normal|spell-out||digits||[literal-punctuation|no-punctuation]", + "unicode-range": "<urange>#", + "voice-balance": "<number>|left|center|right|leftwards|rightwards", + "voice-duration": "auto|<time>", + "voice-family": "[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve", + "voice-pitch": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]", + "voice-range": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]", + "voice-rate": "[normal|x-slow|slow|medium|fast|x-fast]||<percentage>", + "voice-stress": "normal|strong|moderate|none|reduced", + "voice-volume": "silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]", + "white-space-trim": "none|discard-before||discard-after||discard-inner" + }, + "atrules": { + "charset": { + "prelude": "<string>", + "descriptors": null + }, + "counter-style": { + "prelude": "<counter-style-name>", + "descriptors": { + "additive-symbols": "[<integer>&&<symbol>]#", + "fallback": "<counter-style-name>", + "negative": "<symbol> <symbol>?", + "pad": "<integer>&&<symbol>", + "prefix": "<symbol>", + "range": "[[<integer>|infinite]{2}]#|auto", + "speak-as": "auto|bullets|numbers|words|spell-out|<counter-style-name>", + "suffix": "<symbol>", + "symbols": "<symbol>+", + "system": "cyclic|numeric|alphabetic|symbolic|additive|[fixed <integer>?]|[extends <counter-style-name>]" + } + }, + "document": { + "prelude": "[<url>|url-prefix( <string> )|domain( <string> )|media-document( <string> )|regexp( <string> )]#", + "descriptors": null + }, + "font-palette-values": { + "prelude": "<dashed-ident>", + "descriptors": { + "base-palette": "light|dark|<integer [0,∞]>", + "font-family": "<family-name>#", + "override-colors": "[<integer [0,∞]> <absolute-color-base>]#" + } + }, + "font-face": { + "prelude": null, + "descriptors": { + "ascent-override": "normal|<percentage>", + "descent-override": "normal|<percentage>", + "font-display": "[auto|block|swap|fallback|optional]", + "font-family": "<family-name>", + "font-feature-settings": "normal|<feature-tag-value>#", + "font-variation-settings": "normal|[<string> <number>]#", + "font-stretch": "<font-stretch-absolute>{1,2}", + "font-style": "normal|italic|oblique <angle>{0,2}", + "font-weight": "<font-weight-absolute>{1,2}", + "line-gap-override": "normal|<percentage>", + "size-adjust": "<percentage>", + "src": "[<url> [format( <string># )]?|local( <family-name> )]#", + "unicode-range": "<urange>#" + } + }, + "font-feature-values": { + "prelude": "<family-name>#", + "descriptors": null + }, + "import": { + "prelude": "[<string>|<url>] [layer|layer( <layer-name> )]? [supports( [<supports-condition>|<declaration>] )]? <media-query-list>?", + "descriptors": null + }, + "keyframes": { + "prelude": "<keyframes-name>", + "descriptors": null + }, + "layer": { + "prelude": "[<layer-name>#|<layer-name>?]", + "descriptors": null + }, + "media": { + "prelude": "<media-query-list>", + "descriptors": null + }, + "namespace": { + "prelude": "<namespace-prefix>? [<string>|<url>]", + "descriptors": null + }, + "page": { + "prelude": "<page-selector-list>", + "descriptors": { + "bleed": "auto|<length>", + "marks": "none|[crop||cross]", + "page-orientation": "upright|rotate-left|rotate-right", + "size": "<length>{1,2}|auto|[<page-size>||[portrait|landscape]]" + } + }, + "position-try": { + "prelude": "<dashed-ident>", + "descriptors": { + "top": "<'top'>", + "left": "<'left'>", + "bottom": "<'bottom'>", + "right": "<'right'>", + "inset-block-start": "<'inset-block-start'>", + "inset-block-end": "<'inset-block-end'>", + "inset-inline-start": "<'inset-inline-start'>", + "inset-inline-end": "<'inset-inline-end'>", + "inset-block": "<'inset-block'>", + "inset-inline": "<'inset-inline'>", + "inset": "<'inset'>", + "margin-top": "<'margin-top'>", + "margin-left": "<'margin-left'>", + "margin-bottom": "<'margin-bottom'>", + "margin-right": "<'margin-right'>", + "margin-block-start": "<'margin-block-start'>", + "margin-block-end": "<'margin-block-end'>", + "margin-inline-start": "<'margin-inline-start'>", + "margin-inline-end": "<'margin-inline-end'>", + "margin": "<'margin'>", + "margin-block": "<'margin-block'>", + "margin-inline": "<'margin-inline'>", + "width": "<'width'>", + "height": "<'height'>", + "min-width": "<'min-width'>", + "min-height": "<'min-height'>", + "max-width": "<'max-width'>", + "max-height": "<'max-height'>", + "block-size": "<'block-size'>", + "inline-size": "<'inline-size'>", + "min-block-size": "<'min-block-size'>", + "min-inline-size": "<'min-inline-size'>", + "max-block-size": "<'max-block-size'>", + "max-inline-size": "<'max-inline-size'>", + "align-self": "<'align-self'>|anchor-center", + "justify-self": "<'justify-self'>|anchor-center" + } + }, + "property": { + "prelude": "<custom-property-name>", + "descriptors": { + "syntax": "<string>", + "inherits": "true|false", + "initial-value": "<declaration-value>?" + } + }, + "scope": { + "prelude": "[( <scope-start> )]? [to ( <scope-end> )]?", + "descriptors": null + }, + "starting-style": { + "prelude": null, + "descriptors": null + }, + "supports": { + "prelude": "<supports-condition>", + "descriptors": null + }, + "container": { + "prelude": "[<container-name>]? <container-condition>", + "descriptors": null + }, + "nest": { + "prelude": "<complex-selector-list>", + "descriptors": null + } + } +};
\ No newline at end of file diff --git a/vanilla/node_modules/css-tree/dist/version.cjs b/vanilla/node_modules/css-tree/dist/version.cjs new file mode 100644 index 0000000..cdac846 --- /dev/null +++ b/vanilla/node_modules/css-tree/dist/version.cjs @@ -0,0 +1 @@ +module.exports = "3.1.0";
\ No newline at end of file diff --git a/vanilla/node_modules/css-tree/dist/version.js b/vanilla/node_modules/css-tree/dist/version.js new file mode 100644 index 0000000..175d49a --- /dev/null +++ b/vanilla/node_modules/css-tree/dist/version.js @@ -0,0 +1 @@ +export const version = "3.1.0";
\ No newline at end of file diff --git a/vanilla/node_modules/css-tree/lib/convertor/create.js b/vanilla/node_modules/css-tree/lib/convertor/create.js new file mode 100644 index 0000000..56e4333 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/convertor/create.js @@ -0,0 +1,28 @@ +import { List } from '../utils/List.js'; + +export function createConvertor(walk) { + return { + fromPlainObject(ast) { + walk(ast, { + enter(node) { + if (node.children && node.children instanceof List === false) { + node.children = new List().fromArray(node.children); + } + } + }); + + return ast; + }, + toPlainObject(ast) { + walk(ast, { + leave(node) { + if (node.children && node.children instanceof List) { + node.children = node.children.toArray(); + } + } + }); + + return ast; + } + }; +}; diff --git a/vanilla/node_modules/css-tree/lib/convertor/index.js b/vanilla/node_modules/css-tree/lib/convertor/index.js new file mode 100644 index 0000000..0f8d4af --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/convertor/index.js @@ -0,0 +1,4 @@ +import { createConvertor } from './create.js'; +import walker from '../walker/index.js'; + +export default createConvertor(walker); diff --git a/vanilla/node_modules/css-tree/lib/data-patch.js b/vanilla/node_modules/css-tree/lib/data-patch.js new file mode 100644 index 0000000..cd49cbe --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/data-patch.js @@ -0,0 +1,6 @@ +import { createRequire } from 'module'; + +const require = createRequire(import.meta.url); +const patch = require('../data/patch.json'); + +export default patch; diff --git a/vanilla/node_modules/css-tree/lib/data.js b/vanilla/node_modules/css-tree/lib/data.js new file mode 100755 index 0000000..162fa20 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/data.js @@ -0,0 +1,118 @@ +import { createRequire } from 'module'; +import patch from './data-patch.js'; + +const require = createRequire(import.meta.url); +const mdnAtrules = require('mdn-data/css/at-rules.json'); +const mdnProperties = require('mdn-data/css/properties.json'); +const mdnSyntaxes = require('mdn-data/css/syntaxes.json'); + +const hasOwn = Object.hasOwn || ((object, property) => Object.prototype.hasOwnProperty.call(object, property)); +const extendSyntax = /^\s*\|\s*/; + +function preprocessAtrules(dict) { + const result = Object.create(null); + + for (const [atruleName, atrule] of Object.entries(dict)) { + let descriptors = null; + + if (atrule.descriptors) { + descriptors = Object.create(null); + + for (const [name, descriptor] of Object.entries(atrule.descriptors)) { + descriptors[name] = descriptor.syntax; + } + } + + result[atruleName.substr(1)] = { + prelude: atrule.syntax.trim().replace(/\{(.|\s)+\}/, '').match(/^@\S+\s+([^;\{]*)/)[1].trim() || null, + descriptors + }; + } + + return result; +} + +function patchDictionary(dict, patchDict) { + const result = Object.create(null); + + // copy all syntaxes for an original dict + for (const [key, value] of Object.entries(dict)) { + if (value) { + result[key] = value.syntax || value; + } + } + + // apply a patch + for (const key of Object.keys(patchDict)) { + if (hasOwn(dict, key)) { + if (patchDict[key].syntax) { + result[key] = extendSyntax.test(patchDict[key].syntax) + ? result[key] + ' ' + patchDict[key].syntax.trim() + : patchDict[key].syntax; + } else { + delete result[key]; + } + } else { + if (patchDict[key].syntax) { + result[key] = patchDict[key].syntax.replace(extendSyntax, ''); + } + } + } + + return result; +} + +function preprocessPatchAtrulesDescritors(declarations) { + const result = {}; + + for (const [key, value] of Object.entries(declarations || {})) { + result[key] = typeof value === 'string' + ? { syntax: value } + : value; + } + + return result; +} + +function patchAtrules(dict, patchDict) { + const result = {}; + + // copy all syntaxes for an original dict + for (const key in dict) { + if (patchDict[key] === null) { + continue; + } + + const atrulePatch = patchDict[key] || {}; + + result[key] = { + prelude: key in patchDict && 'prelude' in atrulePatch + ? atrulePatch.prelude + : dict[key].prelude || null, + descriptors: patchDictionary( + dict[key].descriptors || {}, + preprocessPatchAtrulesDescritors(atrulePatch.descriptors) + ) + }; + } + + // apply a patch + for (const [key, atrulePatch] of Object.entries(patchDict)) { + if (atrulePatch && !hasOwn(dict, key)) { + result[key] = { + prelude: atrulePatch.prelude || null, + descriptors: atrulePatch.descriptors + ? patchDictionary({}, preprocessPatchAtrulesDescritors(atrulePatch.descriptors)) + : null + }; + } + } + + return result; +} + +export default { + types: patchDictionary(mdnSyntaxes, patch.types), + atrules: patchAtrules(preprocessAtrules(mdnAtrules), patch.atrules), + properties: patchDictionary(mdnProperties, patch.properties) +}; diff --git a/vanilla/node_modules/css-tree/lib/definition-syntax/SyntaxError.js b/vanilla/node_modules/css-tree/lib/definition-syntax/SyntaxError.js new file mode 100644 index 0000000..5f63138 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/definition-syntax/SyntaxError.js @@ -0,0 +1,12 @@ +import { createCustomError } from '../utils/create-custom-error.js'; + +export function SyntaxError(message, input, offset) { + return Object.assign(createCustomError('SyntaxError', message), { + input, + offset, + rawMessage: message, + message: message + '\n' + + ' ' + input + '\n' + + '--' + new Array((offset || input.length) + 1).join('-') + '^' + }); +}; diff --git a/vanilla/node_modules/css-tree/lib/definition-syntax/generate.js b/vanilla/node_modules/css-tree/lib/definition-syntax/generate.js new file mode 100644 index 0000000..b2636d1 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/definition-syntax/generate.js @@ -0,0 +1,135 @@ +function noop(value) { + return value; +} + +function generateMultiplier(multiplier) { + const { min, max, comma } = multiplier; + + if (min === 0 && max === 0) { + return comma ? '#?' : '*'; + } + + if (min === 0 && max === 1) { + return '?'; + } + + if (min === 1 && max === 0) { + return comma ? '#' : '+'; + } + + if (min === 1 && max === 1) { + return ''; + } + + return ( + (comma ? '#' : '') + + (min === max + ? '{' + min + '}' + : '{' + min + ',' + (max !== 0 ? max : '') + '}' + ) + ); +} + +function generateTypeOpts(node) { + switch (node.type) { + case 'Range': + return ( + ' [' + + (node.min === null ? '-∞' : node.min) + + ',' + + (node.max === null ? '∞' : node.max) + + ']' + ); + + default: + throw new Error('Unknown node type `' + node.type + '`'); + } +} + +function generateSequence(node, decorate, forceBraces, compact) { + const combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' '; + const result = node.terms + .map(term => internalGenerate(term, decorate, forceBraces, compact)) + .join(combinator); + + if (node.explicit || forceBraces) { + return (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]'); + } + + return result; +} + +function internalGenerate(node, decorate, forceBraces, compact) { + let result; + + switch (node.type) { + case 'Group': + result = + generateSequence(node, decorate, forceBraces, compact) + + (node.disallowEmpty ? '!' : ''); + break; + + case 'Multiplier': + // return since node is a composition + return ( + internalGenerate(node.term, decorate, forceBraces, compact) + + decorate(generateMultiplier(node), node) + ); + + case 'Boolean': + result = '<boolean-expr[' + internalGenerate(node.term, decorate, forceBraces, compact) + ']>'; + break; + + case 'Type': + result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>'; + break; + + case 'Property': + result = '<\'' + node.name + '\'>'; + break; + + case 'Keyword': + result = node.name; + break; + + case 'AtKeyword': + result = '@' + node.name; + break; + + case 'Function': + result = node.name + '('; + break; + + case 'String': + case 'Token': + result = node.value; + break; + + case 'Comma': + result = ','; + break; + + default: + throw new Error('Unknown node type `' + node.type + '`'); + } + + return decorate(result, node); +} + +export function generate(node, options) { + let decorate = noop; + let forceBraces = false; + let compact = false; + + if (typeof options === 'function') { + decorate = options; + } else if (options) { + forceBraces = Boolean(options.forceBraces); + compact = Boolean(options.compact); + if (typeof options.decorate === 'function') { + decorate = options.decorate; + } + } + + return internalGenerate(node, decorate, forceBraces, compact); +}; diff --git a/vanilla/node_modules/css-tree/lib/definition-syntax/index.js b/vanilla/node_modules/css-tree/lib/definition-syntax/index.js new file mode 100644 index 0000000..0c24dbd --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/definition-syntax/index.js @@ -0,0 +1,4 @@ +export { SyntaxError } from './SyntaxError.js'; +export { generate } from './generate.js'; +export { parse } from './parse.js'; +export { walk } from './walk.js'; diff --git a/vanilla/node_modules/css-tree/lib/definition-syntax/parse.js b/vanilla/node_modules/css-tree/lib/definition-syntax/parse.js new file mode 100644 index 0000000..4e13ad8 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/definition-syntax/parse.js @@ -0,0 +1,552 @@ +import { Scanner } from './scanner.js'; + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; +const EXCLAMATIONMARK = 33; // ! +const NUMBERSIGN = 35; // # +const AMPERSAND = 38; // & +const APOSTROPHE = 39; // ' +const LEFTPARENTHESIS = 40; // ( +const RIGHTPARENTHESIS = 41; // ) +const ASTERISK = 42; // * +const PLUSSIGN = 43; // + +const COMMA = 44; // , +const HYPERMINUS = 45; // - +const LESSTHANSIGN = 60; // < +const GREATERTHANSIGN = 62; // > +const QUESTIONMARK = 63; // ? +const COMMERCIALAT = 64; // @ +const LEFTSQUAREBRACKET = 91; // [ +const RIGHTSQUAREBRACKET = 93; // ] +const LEFTCURLYBRACKET = 123; // { +const VERTICALLINE = 124; // | +const RIGHTCURLYBRACKET = 125; // } +const INFINITY = 8734; // ∞ +const COMBINATOR_PRECEDENCE = { + ' ': 1, + '&&': 2, + '||': 3, + '|': 4 +}; + +function readMultiplierRange(scanner) { + let min = null; + let max = null; + + scanner.eat(LEFTCURLYBRACKET); + scanner.skipWs(); + + min = scanner.scanNumber(scanner); + scanner.skipWs(); + + if (scanner.charCode() === COMMA) { + scanner.pos++; + scanner.skipWs(); + + if (scanner.charCode() !== RIGHTCURLYBRACKET) { + max = scanner.scanNumber(scanner); + scanner.skipWs(); + } + } else { + max = min; + } + + scanner.eat(RIGHTCURLYBRACKET); + + return { + min: Number(min), + max: max ? Number(max) : 0 + }; +} + +function readMultiplier(scanner) { + let range = null; + let comma = false; + + switch (scanner.charCode()) { + case ASTERISK: + scanner.pos++; + + range = { + min: 0, + max: 0 + }; + + break; + + case PLUSSIGN: + scanner.pos++; + + range = { + min: 1, + max: 0 + }; + + break; + + case QUESTIONMARK: + scanner.pos++; + + range = { + min: 0, + max: 1 + }; + + break; + + case NUMBERSIGN: + scanner.pos++; + + comma = true; + + if (scanner.charCode() === LEFTCURLYBRACKET) { + range = readMultiplierRange(scanner); + } else if (scanner.charCode() === QUESTIONMARK) { + // https://www.w3.org/TR/css-values-4/#component-multipliers + // > the # and ? multipliers may be stacked as #? + // In this case just treat "#?" as a single multiplier + // { min: 0, max: 0, comma: true } + scanner.pos++; + range = { + min: 0, + max: 0 + }; + } else { + range = { + min: 1, + max: 0 + }; + } + + break; + + case LEFTCURLYBRACKET: + range = readMultiplierRange(scanner); + break; + + default: + return null; + } + + return { + type: 'Multiplier', + comma, + min: range.min, + max: range.max, + term: null + }; +} + +function maybeMultiplied(scanner, node) { + const multiplier = readMultiplier(scanner); + + if (multiplier !== null) { + multiplier.term = node; + + // https://www.w3.org/TR/css-values-4/#component-multipliers + // > The + and # multipliers may be stacked as +#; + // Represent "+#" as nested multipliers: + // { ...<multiplier #>, + // term: { + // ...<multipler +>, + // term: node + // } + // } + if (scanner.charCode() === NUMBERSIGN && + scanner.charCodeAt(scanner.pos - 1) === PLUSSIGN) { + return maybeMultiplied(scanner, multiplier); + } + + return multiplier; + } + + return node; +} + +function maybeToken(scanner) { + const ch = scanner.peek(); + + if (ch === '') { + return null; + } + + return maybeMultiplied(scanner, { + type: 'Token', + value: ch + }); +} + +function readProperty(scanner) { + let name; + + scanner.eat(LESSTHANSIGN); + scanner.eat(APOSTROPHE); + + name = scanner.scanWord(); + + scanner.eat(APOSTROPHE); + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Property', + name + }); +} + +// https://drafts.csswg.org/css-values-3/#numeric-ranges +// 4.1. Range Restrictions and Range Definition Notation +// +// Range restrictions can be annotated in the numeric type notation using CSS bracketed +// range notation—[min,max]—within the angle brackets, after the identifying keyword, +// indicating a closed range between (and including) min and max. +// For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive. +function readTypeRange(scanner) { + // use null for Infinity to make AST format JSON serializable/deserializable + let min = null; // -Infinity + let max = null; // Infinity + let sign = 1; + + scanner.eat(LEFTSQUAREBRACKET); + + if (scanner.charCode() === HYPERMINUS) { + scanner.peek(); + sign = -1; + } + + if (sign == -1 && scanner.charCode() === INFINITY) { + scanner.peek(); + } else { + min = sign * Number(scanner.scanNumber(scanner)); + + if (scanner.isNameCharCode()) { + min += scanner.scanWord(); + } + } + + scanner.skipWs(); + scanner.eat(COMMA); + scanner.skipWs(); + + if (scanner.charCode() === INFINITY) { + scanner.peek(); + } else { + sign = 1; + + if (scanner.charCode() === HYPERMINUS) { + scanner.peek(); + sign = -1; + } + + max = sign * Number(scanner.scanNumber(scanner)); + + if (scanner.isNameCharCode()) { + max += scanner.scanWord(); + } + } + + scanner.eat(RIGHTSQUAREBRACKET); + + return { + type: 'Range', + min, + max + }; +} + +function readType(scanner) { + let name; + let opts = null; + + scanner.eat(LESSTHANSIGN); + name = scanner.scanWord(); + + // https://drafts.csswg.org/css-values-5/#boolean + if (name === 'boolean-expr') { + scanner.eat(LEFTSQUAREBRACKET); + + const implicitGroup = readImplicitGroup(scanner, RIGHTSQUAREBRACKET); + + scanner.eat(RIGHTSQUAREBRACKET); + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Boolean', + term: implicitGroup.terms.length === 1 + ? implicitGroup.terms[0] + : implicitGroup + }); + } + + if (scanner.charCode() === LEFTPARENTHESIS && + scanner.nextCharCode() === RIGHTPARENTHESIS) { + scanner.pos += 2; + name += '()'; + } + + if (scanner.charCodeAt(scanner.findWsEnd(scanner.pos)) === LEFTSQUAREBRACKET) { + scanner.skipWs(); + opts = readTypeRange(scanner); + } + + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Type', + name, + opts + }); +} + +function readKeywordOrFunction(scanner) { + const name = scanner.scanWord(); + + if (scanner.charCode() === LEFTPARENTHESIS) { + scanner.pos++; + + return { + type: 'Function', + name + }; + } + + return maybeMultiplied(scanner, { + type: 'Keyword', + name + }); +} + +function regroupTerms(terms, combinators) { + function createGroup(terms, combinator) { + return { + type: 'Group', + terms, + combinator, + disallowEmpty: false, + explicit: false + }; + } + + let combinator; + + combinators = Object.keys(combinators) + .sort((a, b) => COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b]); + + while (combinators.length > 0) { + combinator = combinators.shift(); + + let i = 0; + let subgroupStart = 0; + + for (; i < terms.length; i++) { + const term = terms[i]; + + if (term.type === 'Combinator') { + if (term.value === combinator) { + if (subgroupStart === -1) { + subgroupStart = i - 1; + } + terms.splice(i, 1); + i--; + } else { + if (subgroupStart !== -1 && i - subgroupStart > 1) { + terms.splice( + subgroupStart, + i - subgroupStart, + createGroup(terms.slice(subgroupStart, i), combinator) + ); + i = subgroupStart + 1; + } + subgroupStart = -1; + } + } + } + + if (subgroupStart !== -1 && combinators.length) { + terms.splice( + subgroupStart, + i - subgroupStart, + createGroup(terms.slice(subgroupStart, i), combinator) + ); + } + } + + return combinator; +} + +function readImplicitGroup(scanner, stopCharCode) { + const combinators = Object.create(null); + const terms = []; + let token; + let prevToken = null; + let prevTokenPos = scanner.pos; + + while (scanner.charCode() !== stopCharCode && (token = peek(scanner, stopCharCode))) { + if (token.type !== 'Spaces') { + if (token.type === 'Combinator') { + // check for combinator in group beginning and double combinator sequence + if (prevToken === null || prevToken.type === 'Combinator') { + scanner.pos = prevTokenPos; + scanner.error('Unexpected combinator'); + } + + combinators[token.value] = true; + } else if (prevToken !== null && prevToken.type !== 'Combinator') { + combinators[' '] = true; // a b + terms.push({ + type: 'Combinator', + value: ' ' + }); + } + + terms.push(token); + prevToken = token; + prevTokenPos = scanner.pos; + } + } + + // check for combinator in group ending + if (prevToken !== null && prevToken.type === 'Combinator') { + scanner.pos -= prevTokenPos; + scanner.error('Unexpected combinator'); + } + + return { + type: 'Group', + terms, + combinator: regroupTerms(terms, combinators) || ' ', + disallowEmpty: false, + explicit: false + }; +} + +function readGroup(scanner, stopCharCode) { + let result; + + scanner.eat(LEFTSQUAREBRACKET); + result = readImplicitGroup(scanner, stopCharCode); + scanner.eat(RIGHTSQUAREBRACKET); + + result.explicit = true; + + if (scanner.charCode() === EXCLAMATIONMARK) { + scanner.pos++; + result.disallowEmpty = true; + } + + return result; +} + +function peek(scanner, stopCharCode) { + let code = scanner.charCode(); + + switch (code) { + case RIGHTSQUAREBRACKET: + // don't eat, stop scan a group + break; + + case LEFTSQUAREBRACKET: + return maybeMultiplied(scanner, readGroup(scanner, stopCharCode)); + + case LESSTHANSIGN: + return scanner.nextCharCode() === APOSTROPHE + ? readProperty(scanner) + : readType(scanner); + + case VERTICALLINE: + return { + type: 'Combinator', + value: scanner.substringToPos( + scanner.pos + (scanner.nextCharCode() === VERTICALLINE ? 2 : 1) + ) + }; + + case AMPERSAND: + scanner.pos++; + scanner.eat(AMPERSAND); + + return { + type: 'Combinator', + value: '&&' + }; + + case COMMA: + scanner.pos++; + return { + type: 'Comma' + }; + + case APOSTROPHE: + return maybeMultiplied(scanner, { + type: 'String', + value: scanner.scanString() + }); + + case SPACE: + case TAB: + case N: + case R: + case F: + return { + type: 'Spaces', + value: scanner.scanSpaces() + }; + + case COMMERCIALAT: + code = scanner.nextCharCode(); + + if (scanner.isNameCharCode(code)) { + scanner.pos++; + return { + type: 'AtKeyword', + name: scanner.scanWord() + }; + } + + return maybeToken(scanner); + + case ASTERISK: + case PLUSSIGN: + case QUESTIONMARK: + case NUMBERSIGN: + case EXCLAMATIONMARK: + // prohibited tokens (used as a multiplier start) + break; + + case LEFTCURLYBRACKET: + // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting + // check next char isn't a number, because it's likely a disjoined multiplier + code = scanner.nextCharCode(); + + if (code < 48 || code > 57) { + return maybeToken(scanner); + } + + break; + + default: + if (scanner.isNameCharCode(code)) { + return readKeywordOrFunction(scanner); + } + + return maybeToken(scanner); + } +} + +export function parse(source) { + const scanner = new Scanner(source); + const result = readImplicitGroup(scanner); + + if (scanner.pos !== source.length) { + scanner.error('Unexpected input'); + } + + // reduce redundant groups with single group term + if (result.terms.length === 1 && result.terms[0].type === 'Group') { + return result.terms[0]; + } + + return result; +}; diff --git a/vanilla/node_modules/css-tree/lib/definition-syntax/scanner.js b/vanilla/node_modules/css-tree/lib/definition-syntax/scanner.js new file mode 100644 index 0000000..d0b1895 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/definition-syntax/scanner.js @@ -0,0 +1,109 @@ +import { SyntaxError } from './SyntaxError.js'; + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; +const NAME_CHAR = new Uint8Array(128).map((_, idx) => + /[a-zA-Z0-9\-]/.test(String.fromCharCode(idx)) ? 1 : 0 +); + +export class Scanner { + constructor(str) { + this.str = str; + this.pos = 0; + } + + charCodeAt(pos) { + return pos < this.str.length ? this.str.charCodeAt(pos) : 0; + } + charCode() { + return this.charCodeAt(this.pos); + } + isNameCharCode(code = this.charCode()) { + return code < 128 && NAME_CHAR[code] === 1; + } + nextCharCode() { + return this.charCodeAt(this.pos + 1); + } + nextNonWsCode(pos) { + return this.charCodeAt(this.findWsEnd(pos)); + } + skipWs() { + this.pos = this.findWsEnd(this.pos); + } + findWsEnd(pos) { + for (; pos < this.str.length; pos++) { + const code = this.str.charCodeAt(pos); + if (code !== R && code !== N && code !== F && code !== SPACE && code !== TAB) { + break; + } + } + + return pos; + } + substringToPos(end) { + return this.str.substring(this.pos, this.pos = end); + } + eat(code) { + if (this.charCode() !== code) { + this.error('Expect `' + String.fromCharCode(code) + '`'); + } + + this.pos++; + } + peek() { + return this.pos < this.str.length ? this.str.charAt(this.pos++) : ''; + } + error(message) { + throw new SyntaxError(message, this.str, this.pos); + } + + scanSpaces() { + return this.substringToPos(this.findWsEnd(this.pos)); + } + scanWord() { + let end = this.pos; + + for (; end < this.str.length; end++) { + const code = this.str.charCodeAt(end); + if (code >= 128 || NAME_CHAR[code] === 0) { + break; + } + } + + if (this.pos === end) { + this.error('Expect a keyword'); + } + + return this.substringToPos(end); + } + scanNumber() { + let end = this.pos; + + for (; end < this.str.length; end++) { + const code = this.str.charCodeAt(end); + + if (code < 48 || code > 57) { + break; + } + } + + if (this.pos === end) { + this.error('Expect a number'); + } + + return this.substringToPos(end); + } + scanString() { + const end = this.str.indexOf('\'', this.pos + 1); + + if (end === -1) { + this.pos = this.str.length; + this.error('Expect an apostrophe'); + } + + return this.substringToPos(end + 1); + } +}; diff --git a/vanilla/node_modules/css-tree/lib/definition-syntax/walk.js b/vanilla/node_modules/css-tree/lib/definition-syntax/walk.js new file mode 100644 index 0000000..b8c7957 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/definition-syntax/walk.js @@ -0,0 +1,53 @@ +const noop = function() {}; + +function ensureFunction(value) { + return typeof value === 'function' ? value : noop; +} + +export function walk(node, options, context) { + function walk(node) { + enter.call(context, node); + + switch (node.type) { + case 'Group': + node.terms.forEach(walk); + break; + + case 'Multiplier': + case 'Boolean': + walk(node.term); + break; + + case 'Type': + case 'Property': + case 'Keyword': + case 'AtKeyword': + case 'Function': + case 'String': + case 'Token': + case 'Comma': + break; + + default: + throw new Error('Unknown type: ' + node.type); + } + + leave.call(context, node); + } + + let enter = noop; + let leave = noop; + + if (typeof options === 'function') { + enter = options; + } else if (options) { + enter = ensureFunction(options.enter); + leave = ensureFunction(options.leave); + } + + if (enter === noop && leave === noop) { + throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function'); + } + + walk(node, context); +}; diff --git a/vanilla/node_modules/css-tree/lib/generator/create.js b/vanilla/node_modules/css-tree/lib/generator/create.js new file mode 100644 index 0000000..c542f4f --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/generator/create.js @@ -0,0 +1,97 @@ +import { tokenize, Delim, WhiteSpace } from '../tokenizer/index.js'; +import { generateSourceMap } from './sourceMap.js'; +import * as tokenBefore from './token-before.js'; + +const REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) + +function processChildren(node, delimeter) { + if (typeof delimeter === 'function') { + let prev = null; + + node.children.forEach(node => { + if (prev !== null) { + delimeter.call(this, prev); + } + + this.node(node); + prev = node; + }); + + return; + } + + node.children.forEach(this.node, this); +} + +function processChunk(chunk) { + tokenize(chunk, (type, start, end) => { + this.token(type, chunk.slice(start, end)); + }); +} + +export function createGenerator(config) { + const types = new Map(); + + for (let [name, item] of Object.entries(config.node)) { + const fn = item.generate || item; + + if (typeof fn === 'function') { + types.set(name, item.generate || item); + } + } + + return function(node, options) { + let buffer = ''; + let prevCode = 0; + let handlers = { + node(node) { + if (types.has(node.type)) { + types.get(node.type).call(publicApi, node); + } else { + throw new Error('Unknown node type: ' + node.type); + } + }, + tokenBefore: tokenBefore.safe, + token(type, value) { + prevCode = this.tokenBefore(prevCode, type, value); + + this.emit(value, type, false); + + if (type === Delim && value.charCodeAt(0) === REVERSESOLIDUS) { + this.emit('\n', WhiteSpace, true); + } + }, + emit(value) { + buffer += value; + }, + result() { + return buffer; + } + }; + + if (options) { + if (typeof options.decorator === 'function') { + handlers = options.decorator(handlers); + } + + if (options.sourceMap) { + handlers = generateSourceMap(handlers); + } + + if (options.mode in tokenBefore) { + handlers.tokenBefore = tokenBefore[options.mode]; + } + } + + const publicApi = { + node: (node) => handlers.node(node), + children: processChildren, + token: (type, value) => handlers.token(type, value), + tokenize: processChunk + }; + + handlers.node(node); + + return handlers.result(); + }; +}; diff --git a/vanilla/node_modules/css-tree/lib/generator/index.js b/vanilla/node_modules/css-tree/lib/generator/index.js new file mode 100644 index 0000000..dc05116 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/generator/index.js @@ -0,0 +1,4 @@ +import { createGenerator } from './create.js'; +import config from '../syntax/config/generator.js'; + +export default createGenerator(config); diff --git a/vanilla/node_modules/css-tree/lib/generator/sourceMap.js b/vanilla/node_modules/css-tree/lib/generator/sourceMap.js new file mode 100644 index 0000000..0c5ff27 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/generator/sourceMap.js @@ -0,0 +1,92 @@ +import { SourceMapGenerator } from 'source-map-js/lib/source-map-generator.js'; + +const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']); + +export function generateSourceMap(handlers) { + const map = new SourceMapGenerator(); + const generated = { + line: 1, + column: 0 + }; + const original = { + line: 0, // should be zero to add first mapping + column: 0 + }; + const activatedGenerated = { + line: 1, + column: 0 + }; + const activatedMapping = { + generated: activatedGenerated + }; + let line = 1; + let column = 0; + let sourceMappingActive = false; + + const origHandlersNode = handlers.node; + handlers.node = function(node) { + if (node.loc && node.loc.start && trackNodes.has(node.type)) { + const nodeLine = node.loc.start.line; + const nodeColumn = node.loc.start.column - 1; + + if (original.line !== nodeLine || + original.column !== nodeColumn) { + original.line = nodeLine; + original.column = nodeColumn; + + generated.line = line; + generated.column = column; + + if (sourceMappingActive) { + sourceMappingActive = false; + if (generated.line !== activatedGenerated.line || + generated.column !== activatedGenerated.column) { + map.addMapping(activatedMapping); + } + } + + sourceMappingActive = true; + map.addMapping({ + source: node.loc.source, + original, + generated + }); + } + } + + origHandlersNode.call(this, node); + + if (sourceMappingActive && trackNodes.has(node.type)) { + activatedGenerated.line = line; + activatedGenerated.column = column; + } + }; + + const origHandlersEmit = handlers.emit; + handlers.emit = function(value, type, auto) { + for (let i = 0; i < value.length; i++) { + if (value.charCodeAt(i) === 10) { // \n + line++; + column = 0; + } else { + column++; + } + } + + origHandlersEmit(value, type, auto); + }; + + const origHandlersResult = handlers.result; + handlers.result = function() { + if (sourceMappingActive) { + map.addMapping(activatedMapping); + } + + return { + css: origHandlersResult(), + map + }; + }; + + return handlers; +}; diff --git a/vanilla/node_modules/css-tree/lib/generator/token-before.js b/vanilla/node_modules/css-tree/lib/generator/token-before.js new file mode 100644 index 0000000..da3fed0 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/generator/token-before.js @@ -0,0 +1,182 @@ +import { + WhiteSpace, + Delim, + Ident, + Function as FunctionToken, + Url, + BadUrl, + AtKeyword, + Hash, + Percentage, + Dimension, + Number as NumberToken, + String as StringToken, + Colon, + LeftParenthesis, + RightParenthesis, + CDC +} from '../tokenizer/index.js'; + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) + +const code = (type, value) => { + if (type === Delim) { + type = value; + } + + if (typeof type === 'string') { + const charCode = type.charCodeAt(0); + return charCode > 0x7F ? 0x8000 : charCode << 8; + } + + return type; +}; + +// https://www.w3.org/TR/css-syntax-3/#serialization +// The only requirement for serialization is that it must "round-trip" with parsing, +// that is, parsing the stylesheet must produce the same data structures as parsing, +// serializing, and parsing again, except for consecutive <whitespace-token>s, +// which may be collapsed into a single token. + +const specPairs = [ + [Ident, Ident], + [Ident, FunctionToken], + [Ident, Url], + [Ident, BadUrl], + [Ident, '-'], + [Ident, NumberToken], + [Ident, Percentage], + [Ident, Dimension], + [Ident, CDC], + [Ident, LeftParenthesis], + + [AtKeyword, Ident], + [AtKeyword, FunctionToken], + [AtKeyword, Url], + [AtKeyword, BadUrl], + [AtKeyword, '-'], + [AtKeyword, NumberToken], + [AtKeyword, Percentage], + [AtKeyword, Dimension], + [AtKeyword, CDC], + + [Hash, Ident], + [Hash, FunctionToken], + [Hash, Url], + [Hash, BadUrl], + [Hash, '-'], + [Hash, NumberToken], + [Hash, Percentage], + [Hash, Dimension], + [Hash, CDC], + + [Dimension, Ident], + [Dimension, FunctionToken], + [Dimension, Url], + [Dimension, BadUrl], + [Dimension, '-'], + [Dimension, NumberToken], + [Dimension, Percentage], + [Dimension, Dimension], + [Dimension, CDC], + + ['#', Ident], + ['#', FunctionToken], + ['#', Url], + ['#', BadUrl], + ['#', '-'], + ['#', NumberToken], + ['#', Percentage], + ['#', Dimension], + ['#', CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['-', Ident], + ['-', FunctionToken], + ['-', Url], + ['-', BadUrl], + ['-', '-'], + ['-', NumberToken], + ['-', Percentage], + ['-', Dimension], + ['-', CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + [NumberToken, Ident], + [NumberToken, FunctionToken], + [NumberToken, Url], + [NumberToken, BadUrl], + [NumberToken, NumberToken], + [NumberToken, Percentage], + [NumberToken, Dimension], + [NumberToken, '%'], + [NumberToken, CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['@', Ident], + ['@', FunctionToken], + ['@', Url], + ['@', BadUrl], + ['@', '-'], + ['@', CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['.', NumberToken], + ['.', Percentage], + ['.', Dimension], + + ['+', NumberToken], + ['+', Percentage], + ['+', Dimension], + + ['/', '*'] +]; +// validate with scripts/generate-safe +const safePairs = specPairs.concat([ + [Ident, Hash], + + [Dimension, Hash], + + [Hash, Hash], + + [AtKeyword, LeftParenthesis], + [AtKeyword, StringToken], + [AtKeyword, Colon], + + [Percentage, Percentage], + [Percentage, Dimension], + [Percentage, FunctionToken], + [Percentage, '-'], + + [RightParenthesis, Ident], + [RightParenthesis, FunctionToken], + [RightParenthesis, Percentage], + [RightParenthesis, Dimension], + [RightParenthesis, Hash], + [RightParenthesis, '-'] +]); + +function createMap(pairs) { + const isWhiteSpaceRequired = new Set( + pairs.map(([prev, next]) => (code(prev) << 16 | code(next))) + ); + + return function(prevCode, type, value) { + const nextCode = code(type, value); + const nextCharCode = value.charCodeAt(0); + const emitWs = + (nextCharCode === HYPHENMINUS && + type !== Ident && + type !== FunctionToken && + type !== CDC) || + (nextCharCode === PLUSSIGN) + ? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8) + : isWhiteSpaceRequired.has(prevCode << 16 | nextCode); + + if (emitWs) { + this.emit(' ', WhiteSpace, true); + } + + return nextCode; + }; +} + +export const spec = createMap(specPairs); +export const safe = createMap(safePairs); diff --git a/vanilla/node_modules/css-tree/lib/index.js b/vanilla/node_modules/css-tree/lib/index.js new file mode 100644 index 0000000..22cf491 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/index.js @@ -0,0 +1,30 @@ +import syntax from './syntax/index.js'; + +export * from './version.js'; +export { default as createSyntax } from './syntax/create.js'; +export { List } from './utils/List.js'; +export { Lexer } from './lexer/Lexer.js'; +export { tokenTypes, tokenNames, TokenStream, OffsetToLocation } from './tokenizer/index.js'; +export * as definitionSyntax from './definition-syntax/index.js'; +export { clone } from './utils/clone.js'; +export * from './utils/names.js'; +export * as ident from './utils/ident.js'; +export * as string from './utils/string.js'; +export * as url from './utils/url.js'; +export const { + tokenize, + parse, + generate, + lexer, + createLexer, + + walk, + find, + findLast, + findAll, + + toPlainObject, + fromPlainObject, + + fork +} = syntax; diff --git a/vanilla/node_modules/css-tree/lib/lexer/Lexer.js b/vanilla/node_modules/css-tree/lib/lexer/Lexer.js new file mode 100644 index 0000000..d09f574 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/Lexer.js @@ -0,0 +1,511 @@ +import { SyntaxReferenceError, SyntaxMatchError } from './error.js'; +import * as names from '../utils/names.js'; +import { cssWideKeywords } from './generic-const.js'; +import { createGenericTypes } from './generic.js'; +import * as units from './units.js'; +import { parse, generate, walk } from '../definition-syntax/index.js'; +import prepareTokens from './prepare-tokens.js'; +import { buildMatchGraph } from './match-graph.js'; +import { matchAsTree } from './match.js'; +import * as trace from './trace.js'; +import { matchFragments } from './search.js'; +import { getStructureFromConfig } from './structure.js'; + +function dumpMapSyntax(map, compact, syntaxAsAst) { + const result = {}; + + for (const name in map) { + if (map[name].syntax) { + result[name] = syntaxAsAst + ? map[name].syntax + : generate(map[name].syntax, { compact }); + } + } + + return result; +} + +function dumpAtruleMapSyntax(map, compact, syntaxAsAst) { + const result = {}; + + for (const [name, atrule] of Object.entries(map)) { + result[name] = { + prelude: atrule.prelude && ( + syntaxAsAst + ? atrule.prelude.syntax + : generate(atrule.prelude.syntax, { compact }) + ), + descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst) + }; + } + + return result; +} + +function valueHasVar(tokens) { + for (let i = 0; i < tokens.length; i++) { + if (tokens[i].value.toLowerCase() === 'var(') { + return true; + } + } + + return false; +} + +function syntaxHasTopLevelCommaMultiplier(syntax) { + const singleTerm = syntax.terms[0]; + + return ( + syntax.explicit === false && + syntax.terms.length === 1 && + singleTerm.type === 'Multiplier' && + singleTerm.comma === true + ); +} + +function buildMatchResult(matched, error, iterations) { + return { + matched, + iterations, + error, + ...trace + }; +} + +function matchSyntax(lexer, syntax, value, useCssWideKeywords) { + const tokens = prepareTokens(value, lexer.syntax); + let result; + + if (valueHasVar(tokens)) { + return buildMatchResult(null, new Error('Matching for a tree with var() is not supported')); + } + + if (useCssWideKeywords) { + result = matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer); + } + + if (!useCssWideKeywords || !result.match) { + result = matchAsTree(tokens, syntax.match, lexer); + if (!result.match) { + return buildMatchResult( + null, + new SyntaxMatchError(result.reason, syntax.syntax, value, result), + result.iterations + ); + } + } + + return buildMatchResult(result.match, null, result.iterations); +} + +export class Lexer { + constructor(config, syntax, structure) { + this.cssWideKeywords = cssWideKeywords; + this.syntax = syntax; + this.generic = false; + this.units = { ...units }; + this.atrules = Object.create(null); + this.properties = Object.create(null); + this.types = Object.create(null); + this.structure = structure || getStructureFromConfig(config); + + if (config) { + if (config.cssWideKeywords) { + this.cssWideKeywords = config.cssWideKeywords; + } + + if (config.units) { + for (const group of Object.keys(units)) { + if (Array.isArray(config.units[group])) { + this.units[group] = config.units[group]; + } + } + } + + if (config.types) { + for (const [name, type] of Object.entries(config.types)) { + this.addType_(name, type); + } + } + + if (config.generic) { + this.generic = true; + for (const [name, value] of Object.entries(createGenericTypes(this.units))) { + this.addType_(name, value); + } + } + + if (config.atrules) { + for (const [name, atrule] of Object.entries(config.atrules)) { + this.addAtrule_(name, atrule); + } + } + + if (config.properties) { + for (const [name, property] of Object.entries(config.properties)) { + this.addProperty_(name, property); + } + } + } + + this.cssWideKeywordsSyntax = buildMatchGraph(this.cssWideKeywords.join(' | ')); + } + + checkStructure(ast) { + function collectWarning(node, message) { + warns.push({ node, message }); + } + + const structure = this.structure; + const warns = []; + + this.syntax.walk(ast, function(node) { + if (structure.hasOwnProperty(node.type)) { + structure[node.type].check(node, collectWarning); + } else { + collectWarning(node, 'Unknown node type `' + node.type + '`'); + } + }); + + return warns.length ? warns : false; + } + + createDescriptor(syntax, type, name, parent = null) { + const ref = { + type, + name + }; + const descriptor = { + type, + name, + parent, + serializable: typeof syntax === 'string' || (syntax && typeof syntax.type === 'string'), + syntax: null, + match: null, + matchRef: null // used for properties when a syntax referenced as <'property'> in other syntax definitions + }; + + if (typeof syntax === 'function') { + descriptor.match = buildMatchGraph(syntax, ref); + } else { + if (typeof syntax === 'string') { + // lazy parsing on first access + Object.defineProperty(descriptor, 'syntax', { + get() { + Object.defineProperty(descriptor, 'syntax', { + value: parse(syntax) + }); + + return descriptor.syntax; + } + }); + } else { + descriptor.syntax = syntax; + } + + // lazy graph build on first access + Object.defineProperty(descriptor, 'match', { + get() { + Object.defineProperty(descriptor, 'match', { + value: buildMatchGraph(descriptor.syntax, ref) + }); + + return descriptor.match; + } + }); + + if (type === 'Property') { + Object.defineProperty(descriptor, 'matchRef', { + get() { + const syntax = descriptor.syntax; + const value = syntaxHasTopLevelCommaMultiplier(syntax) + ? buildMatchGraph({ + ...syntax, + terms: [syntax.terms[0].term] + }, ref) + : null; + + Object.defineProperty(descriptor, 'matchRef', { + value + }); + + return value; + } + }); + } + } + + return descriptor; + } + addAtrule_(name, syntax) { + if (!syntax) { + return; + } + + this.atrules[name] = { + type: 'Atrule', + name: name, + prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null, + descriptors: syntax.descriptors + ? Object.keys(syntax.descriptors).reduce( + (map, descName) => { + map[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name); + return map; + }, + Object.create(null) + ) + : null + }; + } + addProperty_(name, syntax) { + if (!syntax) { + return; + } + + this.properties[name] = this.createDescriptor(syntax, 'Property', name); + } + addType_(name, syntax) { + if (!syntax) { + return; + } + + this.types[name] = this.createDescriptor(syntax, 'Type', name); + } + + checkAtruleName(atruleName) { + if (!this.getAtrule(atruleName)) { + return new SyntaxReferenceError('Unknown at-rule', '@' + atruleName); + } + } + checkAtrulePrelude(atruleName, prelude) { + const error = this.checkAtruleName(atruleName); + + if (error) { + return error; + } + + const atrule = this.getAtrule(atruleName); + + if (!atrule.prelude && prelude) { + return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude'); + } + + if (atrule.prelude && !prelude) { + if (!matchSyntax(this, atrule.prelude, '', false).matched) { + return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude'); + } + } + } + checkAtruleDescriptorName(atruleName, descriptorName) { + const error = this.checkAtruleName(atruleName); + + if (error) { + return error; + } + + const atrule = this.getAtrule(atruleName); + const descriptor = names.keyword(descriptorName); + + if (!atrule.descriptors) { + return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors'); + } + + if (!atrule.descriptors[descriptor.name] && + !atrule.descriptors[descriptor.basename]) { + return new SyntaxReferenceError('Unknown at-rule descriptor', descriptorName); + } + } + checkPropertyName(propertyName) { + if (!this.getProperty(propertyName)) { + return new SyntaxReferenceError('Unknown property', propertyName); + } + } + + matchAtrulePrelude(atruleName, prelude) { + const error = this.checkAtrulePrelude(atruleName, prelude); + + if (error) { + return buildMatchResult(null, error); + } + + const atrule = this.getAtrule(atruleName); + + if (!atrule.prelude) { + return buildMatchResult(null, null); + } + + return matchSyntax(this, atrule.prelude, prelude || '', false); + } + matchAtruleDescriptor(atruleName, descriptorName, value) { + const error = this.checkAtruleDescriptorName(atruleName, descriptorName); + + if (error) { + return buildMatchResult(null, error); + } + + const atrule = this.getAtrule(atruleName); + const descriptor = names.keyword(descriptorName); + + return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false); + } + matchDeclaration(node) { + if (node.type !== 'Declaration') { + return buildMatchResult(null, new Error('Not a Declaration node')); + } + + return this.matchProperty(node.property, node.value); + } + matchProperty(propertyName, value) { + // don't match syntax for a custom property at the moment + if (names.property(propertyName).custom) { + return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties')); + } + + const error = this.checkPropertyName(propertyName); + + if (error) { + return buildMatchResult(null, error); + } + + return matchSyntax(this, this.getProperty(propertyName), value, true); + } + matchType(typeName, value) { + const typeSyntax = this.getType(typeName); + + if (!typeSyntax) { + return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName)); + } + + return matchSyntax(this, typeSyntax, value, false); + } + match(syntax, value) { + if (typeof syntax !== 'string' && (!syntax || !syntax.type)) { + return buildMatchResult(null, new SyntaxReferenceError('Bad syntax')); + } + + if (typeof syntax === 'string' || !syntax.match) { + syntax = this.createDescriptor(syntax, 'Type', 'anonymous'); + } + + return matchSyntax(this, syntax, value, false); + } + + findValueFragments(propertyName, value, type, name) { + return matchFragments(this, value, this.matchProperty(propertyName, value), type, name); + } + findDeclarationValueFragments(declaration, type, name) { + return matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name); + } + findAllFragments(ast, type, name) { + const result = []; + + this.syntax.walk(ast, { + visit: 'Declaration', + enter: (declaration) => { + result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name)); + } + }); + + return result; + } + + getAtrule(atruleName, fallbackBasename = true) { + const atrule = names.keyword(atruleName); + const atruleEntry = atrule.vendor && fallbackBasename + ? this.atrules[atrule.name] || this.atrules[atrule.basename] + : this.atrules[atrule.name]; + + return atruleEntry || null; + } + getAtrulePrelude(atruleName, fallbackBasename = true) { + const atrule = this.getAtrule(atruleName, fallbackBasename); + + return atrule && atrule.prelude || null; + } + getAtruleDescriptor(atruleName, name) { + return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators + ? this.atrules[atruleName].declarators[name] || null + : null; + } + getProperty(propertyName, fallbackBasename = true) { + const property = names.property(propertyName); + const propertyEntry = property.vendor && fallbackBasename + ? this.properties[property.name] || this.properties[property.basename] + : this.properties[property.name]; + + return propertyEntry || null; + } + getType(name) { + return hasOwnProperty.call(this.types, name) ? this.types[name] : null; + } + + validate() { + function syntaxRef(name, isType) { + return isType ? `<${name}>` : `<'${name}'>`; + } + + function validate(syntax, name, broken, descriptor) { + if (broken.has(name)) { + return broken.get(name); + } + + broken.set(name, false); + if (descriptor.syntax !== null) { + walk(descriptor.syntax, function(node) { + if (node.type !== 'Type' && node.type !== 'Property') { + return; + } + + const map = node.type === 'Type' ? syntax.types : syntax.properties; + const brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties; + + if (!hasOwnProperty.call(map, node.name)) { + errors.push(`${syntaxRef(name, broken === brokenTypes)} used missed syntax definition ${syntaxRef(node.name, node.type === 'Type')}`); + broken.set(name, true); + } else if (validate(syntax, node.name, brokenMap, map[node.name])) { + errors.push(`${syntaxRef(name, broken === brokenTypes)} used broken syntax definition ${syntaxRef(node.name, node.type === 'Type')}`); + broken.set(name, true); + } + }, this); + } + } + + const errors = []; + let brokenTypes = new Map(); + let brokenProperties = new Map(); + + for (const key in this.types) { + validate(this, key, brokenTypes, this.types[key]); + } + + for (const key in this.properties) { + validate(this, key, brokenProperties, this.properties[key]); + } + + const brokenTypesArray = [...brokenTypes.keys()].filter(name => brokenTypes.get(name)); + const brokenPropertiesArray = [...brokenProperties.keys()].filter(name => brokenProperties.get(name)); + + if (brokenTypesArray.length || brokenPropertiesArray.length) { + return { + errors, + types: brokenTypesArray, + properties: brokenPropertiesArray + }; + } + + return null; + } + dump(syntaxAsAst, pretty) { + return { + generic: this.generic, + cssWideKeywords: this.cssWideKeywords, + units: this.units, + types: dumpMapSyntax(this.types, !pretty, syntaxAsAst), + properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst), + atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst) + }; + } + toString() { + return JSON.stringify(this.dump()); + } +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/error.js b/vanilla/node_modules/css-tree/lib/lexer/error.js new file mode 100644 index 0000000..89a5400 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/error.js @@ -0,0 +1,123 @@ +import { createCustomError } from '../utils/create-custom-error.js'; +import { generate } from '../definition-syntax/generate.js'; + +const defaultLoc = { offset: 0, line: 1, column: 1 }; + +function locateMismatch(matchResult, node) { + const tokens = matchResult.tokens; + const longestMatch = matchResult.longestMatch; + const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null; + const badNode = mismatchNode !== node ? mismatchNode : null; + let mismatchOffset = 0; + let mismatchLength = 0; + let entries = 0; + let css = ''; + let start; + let end; + + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i].value; + + if (i === longestMatch) { + mismatchLength = token.length; + mismatchOffset = css.length; + } + + if (badNode !== null && tokens[i].node === badNode) { + if (i <= longestMatch) { + entries++; + } else { + entries = 0; + } + } + + css += token; + } + + if (longestMatch === tokens.length || entries > 1) { // last + start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css); + end = buildLoc(start); + } else { + start = fromLoc(badNode, 'start') || + buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset)); + end = fromLoc(badNode, 'end') || + buildLoc(start, css.substr(mismatchOffset, mismatchLength)); + } + + return { + css, + mismatchOffset, + mismatchLength, + start, + end + }; +} + +function fromLoc(node, point) { + const value = node && node.loc && node.loc[point]; + + if (value) { + return 'line' in value ? buildLoc(value) : value; + } + + return null; +} + +function buildLoc({ offset, line, column }, extra) { + const loc = { + offset, + line, + column + }; + + if (extra) { + const lines = extra.split(/\n|\r\n?|\f/); + + loc.offset += extra.length; + loc.line += lines.length - 1; + loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1; + } + + return loc; +} + +export const SyntaxReferenceError = function(type, referenceName) { + const error = createCustomError( + 'SyntaxReferenceError', + type + (referenceName ? ' `' + referenceName + '`' : '') + ); + + error.reference = referenceName; + + return error; +}; + +export const SyntaxMatchError = function(message, syntax, node, matchResult) { + const error = createCustomError('SyntaxMatchError', message); + const { + css, + mismatchOffset, + mismatchLength, + start, + end + } = locateMismatch(matchResult, node); + + error.rawMessage = message; + error.syntax = syntax ? generate(syntax) : '<generic>'; + error.css = css; + error.mismatchOffset = mismatchOffset; + error.mismatchLength = mismatchLength; + error.message = message + '\n' + + ' syntax: ' + error.syntax + '\n' + + ' value: ' + (css || '<empty string>') + '\n' + + ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^'; + + Object.assign(error, start); + error.loc = { + source: (node && node.loc && node.loc.source) || '<unknown>', + start, + end + }; + + return error; +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/generic-an-plus-b.js b/vanilla/node_modules/css-tree/lib/lexer/generic-an-plus-b.js new file mode 100644 index 0000000..347715c --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/generic-an-plus-b.js @@ -0,0 +1,238 @@ +import { + isDigit, + cmpChar, + Delim, + WhiteSpace, + Comment, + Ident, + Number as NumberToken, + Dimension +} from '../tokenizer/index.js'; + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const N = 0x006E; // U+006E LATIN SMALL LETTER N (n) +const DISALLOW_SIGN = true; +const ALLOW_SIGN = false; + +function isDelim(token, code) { + return token !== null && token.type === Delim && token.value.charCodeAt(0) === code; +} + +function skipSC(token, offset, getNextToken) { + while (token !== null && (token.type === WhiteSpace || token.type === Comment)) { + token = getNextToken(++offset); + } + + return offset; +} + +function checkInteger(token, valueOffset, disallowSign, offset) { + if (!token) { + return 0; + } + + const code = token.value.charCodeAt(valueOffset); + + if (code === PLUSSIGN || code === HYPHENMINUS) { + if (disallowSign) { + // Number sign is not allowed + return 0; + } + valueOffset++; + } + + for (; valueOffset < token.value.length; valueOffset++) { + if (!isDigit(token.value.charCodeAt(valueOffset))) { + // Integer is expected + return 0; + } + } + + return offset + 1; +} + +// ... <signed-integer> +// ... ['+' | '-'] <signless-integer> +function consumeB(token, offset_, getNextToken) { + let sign = false; + let offset = skipSC(token, offset_, getNextToken); + + token = getNextToken(offset); + + if (token === null) { + return offset_; + } + + if (token.type !== NumberToken) { + if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS)) { + sign = true; + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + if (token === null || token.type !== NumberToken) { + return 0; + } + } else { + return offset_; + } + } + + if (!sign) { + const code = token.value.charCodeAt(0); + if (code !== PLUSSIGN && code !== HYPHENMINUS) { + // Number sign is expected + return 0; + } + } + + return checkInteger(token, sign ? 0 : 1, sign, offset); +} + +// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb +export default function anPlusB(token, getNextToken) { + /* eslint-disable brace-style*/ + let offset = 0; + + if (!token) { + return 0; + } + + // <integer> + if (token.type === NumberToken) { + return checkInteger(token, 0, ALLOW_SIGN, offset); // b + } + + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + // -n- <signless-integer> + // <dashndashdigit-ident> + else if (token.type === Ident && token.value.charCodeAt(0) === HYPHENMINUS) { + // expect 1st char is N + if (!cmpChar(token.value, 1, N)) { + return 0; + } + + switch (token.value.length) { + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + case 2: + return consumeB(getNextToken(++offset), offset, getNextToken); + + // -n- <signless-integer> + case 3: + if (token.value.charCodeAt(2) !== HYPHENMINUS) { + return 0; + } + + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + + // <dashndashdigit-ident> + default: + if (token.value.charCodeAt(2) !== HYPHENMINUS) { + return 0; + } + + return checkInteger(token, 3, DISALLOW_SIGN, offset); + } + } + + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + // '+'? n- <signless-integer> + // '+'? <ndashdigit-ident> + else if (token.type === Ident || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === Ident)) { + // just ignore a plus + if (token.type !== Ident) { + token = getNextToken(++offset); + } + + if (token === null || !cmpChar(token.value, 0, N)) { + return 0; + } + + switch (token.value.length) { + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + case 1: + return consumeB(getNextToken(++offset), offset, getNextToken); + + // '+'? n- <signless-integer> + case 2: + if (token.value.charCodeAt(1) !== HYPHENMINUS) { + return 0; + } + + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + + // '+'? <ndashdigit-ident> + default: + if (token.value.charCodeAt(1) !== HYPHENMINUS) { + return 0; + } + + return checkInteger(token, 2, DISALLOW_SIGN, offset); + } + } + + // <ndashdigit-dimension> + // <ndash-dimension> <signless-integer> + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + else if (token.type === Dimension) { + let code = token.value.charCodeAt(0); + let sign = code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0; + let i = sign; + + for (; i < token.value.length; i++) { + if (!isDigit(token.value.charCodeAt(i))) { + break; + } + } + + if (i === sign) { + // Integer is expected + return 0; + } + + if (!cmpChar(token.value, i, N)) { + return 0; + } + + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + if (i + 1 === token.value.length) { + return consumeB(getNextToken(++offset), offset, getNextToken); + } else { + if (token.value.charCodeAt(i + 1) !== HYPHENMINUS) { + return 0; + } + + // <ndash-dimension> <signless-integer> + if (i + 2 === token.value.length) { + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + } + // <ndashdigit-dimension> + else { + return checkInteger(token, i + 2, DISALLOW_SIGN, offset); + } + } + } + + return 0; +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/generic-const.js b/vanilla/node_modules/css-tree/lib/lexer/generic-const.js new file mode 100644 index 0000000..8efe6ae --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/generic-const.js @@ -0,0 +1,8 @@ +// https://drafts.csswg.org/css-cascade-5/ +export const cssWideKeywords = [ + 'initial', + 'inherit', + 'unset', + 'revert', + 'revert-layer' +]; diff --git a/vanilla/node_modules/css-tree/lib/lexer/generic-urange.js b/vanilla/node_modules/css-tree/lib/lexer/generic-urange.js new file mode 100644 index 0000000..d878409 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/generic-urange.js @@ -0,0 +1,151 @@ +import { + isHexDigit, + cmpChar, + Ident, + Delim, + Number as NumberToken, + Dimension +} from '../tokenizer/index.js'; + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?) +const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u) + +function isDelim(token, code) { + return token !== null && token.type === Delim && token.value.charCodeAt(0) === code; +} + +function startsWith(token, code) { + return token.value.charCodeAt(0) === code; +} + +function hexSequence(token, offset, allowDash) { + let hexlen = 0; + + for (let pos = offset; pos < token.value.length; pos++) { + const code = token.value.charCodeAt(pos); + + if (code === HYPHENMINUS && allowDash && hexlen !== 0) { + hexSequence(token, offset + hexlen + 1, false); + return 6; // dissallow following question marks + } + + if (!isHexDigit(code)) { + return 0; // not a hex digit + } + + if (++hexlen > 6) { + return 0; // too many hex digits + }; + } + + return hexlen; +} + +function withQuestionMarkSequence(consumed, length, getNextToken) { + if (!consumed) { + return 0; // nothing consumed + } + + while (isDelim(getNextToken(length), QUESTIONMARK)) { + if (++consumed > 6) { + return 0; // too many question marks + } + + length++; + } + + return length; +} + +// https://drafts.csswg.org/css-syntax/#urange +// Informally, the <urange> production has three forms: +// U+0001 +// Defines a range consisting of a single code point, in this case the code point "1". +// U+0001-00ff +// Defines a range of codepoints between the first and the second value, in this case +// the range between "1" and "ff" (255 in decimal) inclusive. +// U+00?? +// Defines a range of codepoints where the "?" characters range over all hex digits, +// in this case defining the same as the value U+0000-00ff. +// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit). +// +// <urange> = +// u '+' <ident-token> '?'* | +// u <dimension-token> '?'* | +// u <number-token> '?'* | +// u <number-token> <dimension-token> | +// u <number-token> <number-token> | +// u '+' '?'+ +export default function urange(token, getNextToken) { + let length = 0; + + // should start with `u` or `U` + if (token === null || token.type !== Ident || !cmpChar(token.value, 0, U)) { + return 0; + } + + token = getNextToken(++length); + if (token === null) { + return 0; + } + + // u '+' <ident-token> '?'* + // u '+' '?'+ + if (isDelim(token, PLUSSIGN)) { + token = getNextToken(++length); + if (token === null) { + return 0; + } + + if (token.type === Ident) { + // u '+' <ident-token> '?'* + return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken); + } + + if (isDelim(token, QUESTIONMARK)) { + // u '+' '?'+ + return withQuestionMarkSequence(1, ++length, getNextToken); + } + + // Hex digit or question mark is expected + return 0; + } + + // u <number-token> '?'* + // u <number-token> <dimension-token> + // u <number-token> <number-token> + if (token.type === NumberToken) { + const consumedHexLength = hexSequence(token, 1, true); + if (consumedHexLength === 0) { + return 0; + } + + token = getNextToken(++length); + if (token === null) { + // u <number-token> <eof> + return length; + } + + if (token.type === Dimension || token.type === NumberToken) { + // u <number-token> <dimension-token> + // u <number-token> <number-token> + if (!startsWith(token, HYPHENMINUS) || !hexSequence(token, 1, false)) { + return 0; + } + + return length + 1; + } + + // u <number-token> '?'* + return withQuestionMarkSequence(consumedHexLength, length, getNextToken); + } + + // u <dimension-token> '?'* + if (token.type === Dimension) { + return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken); + } + + return 0; +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/generic.js b/vanilla/node_modules/css-tree/lib/lexer/generic.js new file mode 100644 index 0000000..422e130 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/generic.js @@ -0,0 +1,622 @@ +import { cssWideKeywords } from './generic-const.js'; +import anPlusB from './generic-an-plus-b.js'; +import urange from './generic-urange.js'; +import { + isIdentifierStart, + isHexDigit, + isDigit, + cmpStr, + consumeNumber, + + Ident, + Function as FunctionToken, + AtKeyword, + Hash, + String as StringToken, + BadString, + Url, + BadUrl, + Delim, + Number as NumberToken, + Percentage, + Dimension, + WhiteSpace, + CDO, + CDC, + Colon, + Semicolon, + Comma, + LeftSquareBracket, + RightSquareBracket, + LeftParenthesis, + RightParenthesis, + LeftCurlyBracket, + RightCurlyBracket +} from '../tokenizer/index.js'; + +const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc(']; +const balancePair = new Map([ + [FunctionToken, RightParenthesis], + [LeftParenthesis, RightParenthesis], + [LeftSquareBracket, RightSquareBracket], + [LeftCurlyBracket, RightCurlyBracket] +]); + +// safe char code getter +function charCodeAt(str, index) { + return index < str.length ? str.charCodeAt(index) : 0; +} + +function eqStr(actual, expected) { + return cmpStr(actual, 0, actual.length, expected); +} + +function eqStrAny(actual, expected) { + for (let i = 0; i < expected.length; i++) { + if (eqStr(actual, expected[i])) { + return true; + } + } + + return false; +} + +// IE postfix hack, i.e. 123\0 or 123px\9 +function isPostfixIeHack(str, offset) { + if (offset !== str.length - 2) { + return false; + } + + return ( + charCodeAt(str, offset) === 0x005C && // U+005C REVERSE SOLIDUS (\) + isDigit(charCodeAt(str, offset + 1)) + ); +} + +function outOfRange(opts, value, numEnd) { + if (opts && opts.type === 'Range') { + const num = Number( + numEnd !== undefined && numEnd !== value.length + ? value.substr(0, numEnd) + : value + ); + + if (isNaN(num)) { + return true; + } + + // FIXME: when opts.min is a string it's a dimension, skip a range validation + // for now since it requires a type covertation which is not implmented yet + if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') { + return true; + } + + // FIXME: when opts.max is a string it's a dimension, skip a range validation + // for now since it requires a type covertation which is not implmented yet + if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') { + return true; + } + } + + return false; +} + +function consumeFunction(token, getNextToken) { + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // balanced token consuming + scan: + do { + switch (token.type) { + case RightCurlyBracket: + case RightParenthesis: + case RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + + if (balanceStash.length === 0) { + length++; + break scan; + } + + break; + + case FunctionToken: + case LeftParenthesis: + case LeftSquareBracket: + case LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// TODO: implement +// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed +// https://drafts.csswg.org/css-values/#calc-notation +function calc(next) { + return function(token, getNextToken, opts) { + if (token === null) { + return 0; + } + + if (token.type === FunctionToken && eqStrAny(token.value, calcFunctionNames)) { + return consumeFunction(token, getNextToken); + } + + return next(token, getNextToken, opts); + }; +} + +function tokenType(expectedTokenType) { + return function(token) { + if (token === null || token.type !== expectedTokenType) { + return 0; + } + + return 1; + }; +} + +// ========================= +// Complex types +// + +// https://drafts.csswg.org/css-values-4/#custom-idents +// 4.2. Author-defined Identifiers: the <custom-ident> type +// Some properties accept arbitrary author-defined identifiers as a component value. +// This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier +// that would not be misinterpreted as a pre-defined keyword in that property’s value definition. +// +// See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident +function customIdent(token) { + if (token === null || token.type !== Ident) { + return 0; + } + + const name = token.value.toLowerCase(); + + // The CSS-wide keywords are not valid <custom-ident>s + if (eqStrAny(name, cssWideKeywords)) { + return 0; + } + + // The default keyword is reserved and is also not a valid <custom-ident> + if (eqStr(name, 'default')) { + return 0; + } + + // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident) + // Specifications using <custom-ident> must specify clearly what other keywords + // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords + // in that property’s value definition are excluded. Excluded keywords are excluded + // in all ASCII case permutations. + + return 1; +} + +// https://drafts.csswg.org/css-values-4/#dashed-idents +// The <dashed-ident> production is a <custom-ident>, with all the case-sensitivity that implies, +// with the additional restriction that it must start with two dashes (U+002D HYPHEN-MINUS). +function dashedIdent(token) { + if (token === null || token.type !== Ident) { + return 0; + } + + // ... must start with two dashes (U+002D HYPHEN-MINUS) + if (charCodeAt(token.value, 0) !== 0x002D || charCodeAt(token.value, 1) !== 0x002D) { + return 0; + } + + return 1; +} + +// https://drafts.csswg.org/css-variables/#typedef-custom-property-name +// A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo. +// The <custom-property-name> production corresponds to this: it’s defined as any <dashed-ident> +// (a valid identifier that starts with two dashes), except -- itself, which is reserved for future use by CSS. +function customPropertyName(token) { + // ... it’s defined as any <dashed-ident> + if (!dashedIdent(token)) { + return 0; + } + + // ... except -- itself, which is reserved for future use by CSS + if (token.value === '--') { + return 0; + } + + return 1; +} + +// https://drafts.csswg.org/css-color-4/#hex-notation +// The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits. +// In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or +// letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00). +function hexColor(token) { + if (token === null || token.type !== Hash) { + return 0; + } + + const length = token.value.length; + + // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9) + if (length !== 4 && length !== 5 && length !== 7 && length !== 9) { + return 0; + } + + for (let i = 1; i < length; i++) { + if (!isHexDigit(charCodeAt(token.value, i))) { + return 0; + } + } + + return 1; +} + +function idSelector(token) { + if (token === null || token.type !== Hash) { + return 0; + } + + if (!isIdentifierStart(charCodeAt(token.value, 1), charCodeAt(token.value, 2), charCodeAt(token.value, 3))) { + return 0; + } + + return 1; +} + +// https://drafts.csswg.org/css-syntax/#any-value +// It represents the entirety of what a valid declaration can have as its value. +function declarationValue(token, getNextToken) { + if (!token) { + return 0; + } + + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // The <declaration-value> production matches any sequence of one or more tokens, + // so long as the sequence does not contain ... + scan: + do { + switch (token.type) { + // ... <bad-string-token>, <bad-url-token>, + case BadString: + case BadUrl: + break scan; + + // ... unmatched <)-token>, <]-token>, or <}-token>, + case RightCurlyBracket: + case RightParenthesis: + case RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + break; + + // ... or top-level <semicolon-token> tokens + case Semicolon: + if (balanceCloseType === 0) { + break scan; + } + + break; + + // ... or <delim-token> tokens with a value of "!" + case Delim: + if (balanceCloseType === 0 && token.value === '!') { + break scan; + } + + break; + + case FunctionToken: + case LeftParenthesis: + case LeftSquareBracket: + case LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// https://drafts.csswg.org/css-syntax/#any-value +// The <any-value> production is identical to <declaration-value>, but also +// allows top-level <semicolon-token> tokens and <delim-token> tokens +// with a value of "!". It represents the entirety of what valid CSS can be in any context. +function anyValue(token, getNextToken) { + if (!token) { + return 0; + } + + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // The <any-value> production matches any sequence of one or more tokens, + // so long as the sequence ... + scan: + do { + switch (token.type) { + // ... does not contain <bad-string-token>, <bad-url-token>, + case BadString: + case BadUrl: + break scan; + + // ... unmatched <)-token>, <]-token>, or <}-token>, + case RightCurlyBracket: + case RightParenthesis: + case RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + break; + + case FunctionToken: + case LeftParenthesis: + case LeftSquareBracket: + case LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// ========================= +// Dimensions +// + +function dimension(type) { + if (type) { + type = new Set(type); + } + + return function(token, getNextToken, opts) { + if (token === null || token.type !== Dimension) { + return 0; + } + + const numberEnd = consumeNumber(token.value, 0); + + // check unit + if (type !== null) { + // check for IE postfix hack, i.e. 123px\0 or 123px\9 + const reverseSolidusOffset = token.value.indexOf('\\', numberEnd); + const unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset) + ? token.value.substr(numberEnd) + : token.value.substring(numberEnd, reverseSolidusOffset); + + if (type.has(unit.toLowerCase()) === false) { + return 0; + } + } + + // check range if specified + if (outOfRange(opts, token.value, numberEnd)) { + return 0; + } + + return 1; + }; +} + +// ========================= +// Percentage +// + +// §5.5. Percentages: the <percentage> type +// https://drafts.csswg.org/css-values-4/#percentages +function percentage(token, getNextToken, opts) { + // ... corresponds to the <percentage-token> production + if (token === null || token.type !== Percentage) { + return 0; + } + + // check range if specified + if (outOfRange(opts, token.value, token.value.length - 1)) { + return 0; + } + + return 1; +} + +// ========================= +// Numeric +// + +// https://drafts.csswg.org/css-values-4/#numbers +// The value <zero> represents a literal number with the value 0. Expressions that merely +// evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>; +// only literal <number-token>s do. +function zero(next) { + if (typeof next !== 'function') { + next = function() { + return 0; + }; + } + + return function(token, getNextToken, opts) { + if (token !== null && token.type === NumberToken) { + if (Number(token.value) === 0) { + return 1; + } + } + + return next(token, getNextToken, opts); + }; +} + +// § 5.3. Real Numbers: the <number> type +// https://drafts.csswg.org/css-values-4/#numbers +// Number values are denoted by <number>, and represent real numbers, possibly with a fractional component. +// ... It corresponds to the <number-token> production +function number(token, getNextToken, opts) { + if (token === null) { + return 0; + } + + const numberEnd = consumeNumber(token.value, 0); + const isNumber = numberEnd === token.value.length; + if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) { + return 0; + } + + // check range if specified + if (outOfRange(opts, token.value, numberEnd)) { + return 0; + } + + return 1; +} + +// §5.2. Integers: the <integer> type +// https://drafts.csswg.org/css-values-4/#integers +function integer(token, getNextToken, opts) { + // ... corresponds to a subset of the <number-token> production + if (token === null || token.type !== NumberToken) { + return 0; + } + + // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign. + let i = charCodeAt(token.value, 0) === 0x002B || // U+002B PLUS SIGN (+) + charCodeAt(token.value, 0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-) + + // When written literally, an integer is one or more decimal digits 0 through 9 ... + for (; i < token.value.length; i++) { + if (!isDigit(charCodeAt(token.value, i))) { + return 0; + } + } + + // check range if specified + if (outOfRange(opts, token.value, i)) { + return 0; + } + + return 1; +} + +// token types +export const tokenTypes = { + 'ident-token': tokenType(Ident), + 'function-token': tokenType(FunctionToken), + 'at-keyword-token': tokenType(AtKeyword), + 'hash-token': tokenType(Hash), + 'string-token': tokenType(StringToken), + 'bad-string-token': tokenType(BadString), + 'url-token': tokenType(Url), + 'bad-url-token': tokenType(BadUrl), + 'delim-token': tokenType(Delim), + 'number-token': tokenType(NumberToken), + 'percentage-token': tokenType(Percentage), + 'dimension-token': tokenType(Dimension), + 'whitespace-token': tokenType(WhiteSpace), + 'CDO-token': tokenType(CDO), + 'CDC-token': tokenType(CDC), + 'colon-token': tokenType(Colon), + 'semicolon-token': tokenType(Semicolon), + 'comma-token': tokenType(Comma), + '[-token': tokenType(LeftSquareBracket), + ']-token': tokenType(RightSquareBracket), + '(-token': tokenType(LeftParenthesis), + ')-token': tokenType(RightParenthesis), + '{-token': tokenType(LeftCurlyBracket), + '}-token': tokenType(RightCurlyBracket) +}; + +// token production types +export const productionTypes = { + // token type aliases + 'string': tokenType(StringToken), + 'ident': tokenType(Ident), + + // percentage + 'percentage': calc(percentage), + + // numeric + 'zero': zero(), + 'number': calc(number), + 'integer': calc(integer), + + // complex types + 'custom-ident': customIdent, + 'dashed-ident': dashedIdent, + 'custom-property-name': customPropertyName, + 'hex-color': hexColor, + 'id-selector': idSelector, // element( <id-selector> ) + 'an-plus-b': anPlusB, + 'urange': urange, + 'declaration-value': declarationValue, + 'any-value': anyValue +}; + +export const unitGroups = [ + 'length', + 'angle', + 'time', + 'frequency', + 'resolution', + 'flex', + 'decibel', + 'semitones' +]; + +// dimensions types depend on units set +export function createDemensionTypes(units) { + const { + angle, + decibel, + frequency, + flex, + length, + resolution, + semitones, + time + } = units || {}; + + return { + 'dimension': calc(dimension(null)), + 'angle': calc(dimension(angle)), + 'decibel': calc(dimension(decibel)), + 'frequency': calc(dimension(frequency)), + 'flex': calc(dimension(flex)), + 'length': calc(zero(dimension(length))), + 'resolution': calc(dimension(resolution)), + 'semitones': calc(dimension(semitones)), + 'time': calc(dimension(time)) + }; +} + +export function createGenericTypes(units) { + return { + ...tokenTypes, + ...productionTypes, + ...createDemensionTypes(units) + }; +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/index.js b/vanilla/node_modules/css-tree/lib/lexer/index.js new file mode 100644 index 0000000..1661b76 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/index.js @@ -0,0 +1 @@ +export { Lexer } from './Lexer.js'; diff --git a/vanilla/node_modules/css-tree/lib/lexer/match-graph.js b/vanilla/node_modules/css-tree/lib/lexer/match-graph.js new file mode 100644 index 0000000..5d3d800 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/match-graph.js @@ -0,0 +1,527 @@ +import { parse } from '../definition-syntax/parse.js'; + +export const MATCH = { type: 'Match' }; +export const MISMATCH = { type: 'Mismatch' }; +export const DISALLOW_EMPTY = { type: 'DisallowEmpty' }; + +const LEFTPARENTHESIS = 40; // ( +const RIGHTPARENTHESIS = 41; // ) + +function createCondition(match, thenBranch, elseBranch) { + // reduce node count + if (thenBranch === MATCH && elseBranch === MISMATCH) { + return match; + } + + if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) { + return match; + } + + if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) { + thenBranch = match.then; + match = match.match; + } + + return { + type: 'If', + match, + then: thenBranch, + else: elseBranch + }; +} + +function isFunctionType(name) { + return ( + name.length > 2 && + name.charCodeAt(name.length - 2) === LEFTPARENTHESIS && + name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS + ); +} + +function isEnumCapatible(term) { + return ( + term.type === 'Keyword' || + term.type === 'AtKeyword' || + term.type === 'Function' || + term.type === 'Type' && isFunctionType(term.name) + ); +} + +function groupNode(terms, combinator = ' ', explicit = false) { + return { + type: 'Group', + terms, + combinator, + disallowEmpty: false, + explicit + }; +} + +function replaceTypeInGraph(node, replacements, visited = new Set()) { + if (!visited.has(node)) { + visited.add(node); + + switch (node.type) { + case 'If': + node.match = replaceTypeInGraph(node.match, replacements, visited); + node.then = replaceTypeInGraph(node.then, replacements, visited); + node.else = replaceTypeInGraph(node.else, replacements, visited); + break; + + case 'Type': + return replacements[node.name] || node; + } + } + + return node; +} + +function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) { + switch (combinator) { + case ' ': { + // Juxtaposing components means that all of them must occur, in the given order. + // + // a b c + // = + // match a + // then match b + // then match c + // then MATCH + // else MISMATCH + // else MISMATCH + // else MISMATCH + let result = MATCH; + + for (let i = terms.length - 1; i >= 0; i--) { + const term = terms[i]; + + result = createCondition( + term, + result, + MISMATCH + ); + }; + + return result; + } + + case '|': { + // A bar (|) separates two or more alternatives: exactly one of them must occur. + // + // a | b | c + // = + // match a + // then MATCH + // else match b + // then MATCH + // else match c + // then MATCH + // else MISMATCH + + let result = MISMATCH; + let map = null; + + for (let i = terms.length - 1; i >= 0; i--) { + let term = terms[i]; + + // reduce sequence of keywords into a Enum + if (isEnumCapatible(term)) { + if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) { + map = Object.create(null); + result = createCondition( + { + type: 'Enum', + map + }, + MATCH, + result + ); + } + + if (map !== null) { + const key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase(); + if (key in map === false) { + map[key] = term; + continue; + } + } + } + + map = null; + + // create a new conditonal node + result = createCondition( + term, + MATCH, + result + ); + }; + + return result; + } + + case '&&': { + // A double ampersand (&&) separates two or more components, + // all of which must occur, in any order. + + // Use MatchOnce for groups with a large number of terms, + // since &&-groups produces at least N!-node trees + if (terms.length > 5) { + return { + type: 'MatchOnce', + terms, + all: true + }; + } + + // Use a combination tree for groups with small number of terms + // + // a && b && c + // = + // match a + // then [b && c] + // else match b + // then [a && c] + // else match c + // then [a && b] + // else MISMATCH + // + // a && b + // = + // match a + // then match b + // then MATCH + // else MISMATCH + // else match b + // then match a + // then MATCH + // else MISMATCH + // else MISMATCH + let result = MISMATCH; + + for (let i = terms.length - 1; i >= 0; i--) { + const term = terms[i]; + let thenClause; + + if (terms.length > 1) { + thenClause = buildGroupMatchGraph( + combinator, + terms.filter(function(newGroupTerm) { + return newGroupTerm !== term; + }), + false + ); + } else { + thenClause = MATCH; + } + + result = createCondition( + term, + thenClause, + result + ); + }; + + return result; + } + + case '||': { + // A double bar (||) separates two or more options: + // one or more of them must occur, in any order. + + // Use MatchOnce for groups with a large number of terms, + // since ||-groups produces at least N!-node trees + if (terms.length > 5) { + return { + type: 'MatchOnce', + terms, + all: false + }; + } + + // Use a combination tree for groups with small number of terms + // + // a || b || c + // = + // match a + // then [b || c] + // else match b + // then [a || c] + // else match c + // then [a || b] + // else MISMATCH + // + // a || b + // = + // match a + // then match b + // then MATCH + // else MATCH + // else match b + // then match a + // then MATCH + // else MATCH + // else MISMATCH + let result = atLeastOneTermMatched ? MATCH : MISMATCH; + + for (let i = terms.length - 1; i >= 0; i--) { + const term = terms[i]; + let thenClause; + + if (terms.length > 1) { + thenClause = buildGroupMatchGraph( + combinator, + terms.filter(function(newGroupTerm) { + return newGroupTerm !== term; + }), + true + ); + } else { + thenClause = MATCH; + } + + result = createCondition( + term, + thenClause, + result + ); + }; + + return result; + } + } +} + +function buildMultiplierMatchGraph(node) { + let result = MATCH; + let matchTerm = buildMatchGraphInternal(node.term); + + if (node.max === 0) { + // disable repeating of empty match to prevent infinite loop + matchTerm = createCondition( + matchTerm, + DISALLOW_EMPTY, + MISMATCH + ); + + // an occurrence count is not limited, make a cycle; + // to collect more terms on each following matching mismatch + result = createCondition( + matchTerm, + null, // will be a loop + MISMATCH + ); + + result.then = createCondition( + MATCH, + MATCH, + result // make a loop + ); + + if (node.comma) { + result.then.else = createCondition( + { type: 'Comma', syntax: node }, + result, + MISMATCH + ); + } + } else { + // create a match node chain for [min .. max] interval with optional matches + for (let i = node.min || 1; i <= node.max; i++) { + if (node.comma && result !== MATCH) { + result = createCondition( + { type: 'Comma', syntax: node }, + result, + MISMATCH + ); + } + + result = createCondition( + matchTerm, + createCondition( + MATCH, + MATCH, + result + ), + MISMATCH + ); + } + } + + if (node.min === 0) { + // allow zero match + result = createCondition( + MATCH, + MATCH, + result + ); + } else { + // create a match node chain to collect [0 ... min - 1] required matches + for (let i = 0; i < node.min - 1; i++) { + if (node.comma && result !== MATCH) { + result = createCondition( + { type: 'Comma', syntax: node }, + result, + MISMATCH + ); + } + + result = createCondition( + matchTerm, + result, + MISMATCH + ); + } + } + + return result; +} + +function buildMatchGraphInternal(node) { + if (typeof node === 'function') { + return { + type: 'Generic', + fn: node + }; + } + + switch (node.type) { + case 'Group': { + let result = buildGroupMatchGraph( + node.combinator, + node.terms.map(buildMatchGraphInternal), + false + ); + + if (node.disallowEmpty) { + result = createCondition( + result, + DISALLOW_EMPTY, + MISMATCH + ); + } + + return result; + } + + case 'Multiplier': + return buildMultiplierMatchGraph(node); + + // https://drafts.csswg.org/css-values-5/#boolean + case 'Boolean': { + const term = buildMatchGraphInternal(node.term); + // <boolean-expr[ <test> ]> = not <boolean-expr-group> | <boolean-expr-group> [ [ and <boolean-expr-group> ]* | [ or <boolean-expr-group> ]* ] + const matchNode = buildMatchGraphInternal(groupNode([ + groupNode([ + { type: 'Keyword', name: 'not' }, + { type: 'Type', name: '!boolean-group' } + ]), + groupNode([ + { type: 'Type', name: '!boolean-group' }, + groupNode([ + { type: 'Multiplier', comma: false, min: 0, max: 0, term: groupNode([ + { type: 'Keyword', name: 'and' }, + { type: 'Type', name: '!boolean-group' } + ]) }, + { type: 'Multiplier', comma: false, min: 0, max: 0, term: groupNode([ + { type: 'Keyword', name: 'or' }, + { type: 'Type', name: '!boolean-group' } + ]) } + ], '|') + ]) + ], '|')); + // <boolean-expr-group> = <test> | ( <boolean-expr[ <test> ]> ) | <general-enclosed> + const booleanGroup = buildMatchGraphInternal( + groupNode([ + { type: 'Type', name: '!term' }, + groupNode([ + { type: 'Token', value: '(' }, + { type: 'Type', name: '!self' }, + { type: 'Token', value: ')' } + ]), + { type: 'Type', name: 'general-enclosed' } + ], '|') + ); + + replaceTypeInGraph(booleanGroup, { '!term': term, '!self': matchNode }); + replaceTypeInGraph(matchNode, { '!boolean-group': booleanGroup }); + + return matchNode; + } + + case 'Type': + case 'Property': + return { + type: node.type, + name: node.name, + syntax: node + }; + + case 'Keyword': + return { + type: node.type, + name: node.name.toLowerCase(), + syntax: node + }; + + case 'AtKeyword': + return { + type: node.type, + name: '@' + node.name.toLowerCase(), + syntax: node + }; + + case 'Function': + return { + type: node.type, + name: node.name.toLowerCase() + '(', + syntax: node + }; + + case 'String': + // convert a one char length String to a Token + if (node.value.length === 3) { + return { + type: 'Token', + value: node.value.charAt(1), + syntax: node + }; + } + + // otherwise use it as is + return { + type: node.type, + value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''), + syntax: node + }; + + case 'Token': + return { + type: node.type, + value: node.value, + syntax: node + }; + + case 'Comma': + return { + type: node.type, + syntax: node + }; + + default: + throw new Error('Unknown node type:', node.type); + } +} + +export function buildMatchGraph(syntaxTree, ref) { + if (typeof syntaxTree === 'string') { + syntaxTree = parse(syntaxTree); + } + + return { + type: 'MatchGraph', + match: buildMatchGraphInternal(syntaxTree), + syntax: ref || null, + source: syntaxTree + }; +} diff --git a/vanilla/node_modules/css-tree/lib/lexer/match.js b/vanilla/node_modules/css-tree/lib/lexer/match.js new file mode 100644 index 0000000..5ac9c48 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/match.js @@ -0,0 +1,630 @@ +import { MATCH, MISMATCH, DISALLOW_EMPTY } from './match-graph.js'; +import * as TYPE from '../tokenizer/types.js'; + +const { hasOwnProperty } = Object.prototype; +const STUB = 0; +const TOKEN = 1; +const OPEN_SYNTAX = 2; +const CLOSE_SYNTAX = 3; + +const EXIT_REASON_MATCH = 'Match'; +const EXIT_REASON_MISMATCH = 'Mismatch'; +const EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)'; + +const ITERATION_LIMIT = 15000; +export let totalIterationCount = 0; + +function reverseList(list) { + let prev = null; + let next = null; + let item = list; + + while (item !== null) { + next = item.prev; + item.prev = prev; + prev = item; + item = next; + } + + return prev; +} + +function areStringsEqualCaseInsensitive(testStr, referenceStr) { + if (testStr.length !== referenceStr.length) { + return false; + } + + for (let i = 0; i < testStr.length; i++) { + const referenceCode = referenceStr.charCodeAt(i); + let testCode = testStr.charCodeAt(i); + + // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z). + if (testCode >= 0x0041 && testCode <= 0x005A) { + testCode = testCode | 32; + } + + if (testCode !== referenceCode) { + return false; + } + } + + return true; +} + +function isContextEdgeDelim(token) { + if (token.type !== TYPE.Delim) { + return false; + } + + // Fix matching for unicode-range: U+30??, U+FF00-FF9F + // Probably we need to check out previous match instead + return token.value !== '?'; +} + +function isCommaContextStart(token) { + if (token === null) { + return true; + } + + return ( + token.type === TYPE.Comma || + token.type === TYPE.Function || + token.type === TYPE.LeftParenthesis || + token.type === TYPE.LeftSquareBracket || + token.type === TYPE.LeftCurlyBracket || + isContextEdgeDelim(token) + ); +} + +function isCommaContextEnd(token) { + if (token === null) { + return true; + } + + return ( + token.type === TYPE.RightParenthesis || + token.type === TYPE.RightSquareBracket || + token.type === TYPE.RightCurlyBracket || + (token.type === TYPE.Delim && token.value === '/') + ); +} + +function internalMatch(tokens, state, syntaxes) { + function moveToNextToken() { + do { + tokenIndex++; + token = tokenIndex < tokens.length ? tokens[tokenIndex] : null; + } while (token !== null && (token.type === TYPE.WhiteSpace || token.type === TYPE.Comment)); + } + + function getNextToken(offset) { + const nextIndex = tokenIndex + offset; + + return nextIndex < tokens.length ? tokens[nextIndex] : null; + } + + function stateSnapshotFromSyntax(nextState, prev) { + return { + nextState, + matchStack, + syntaxStack, + thenStack, + tokenIndex, + prev + }; + } + + function pushThenStack(nextState) { + thenStack = { + nextState, + matchStack, + syntaxStack, + prev: thenStack + }; + } + + function pushElseStack(nextState) { + elseStack = stateSnapshotFromSyntax(nextState, elseStack); + } + + function addTokenToMatch() { + matchStack = { + type: TOKEN, + syntax: state.syntax, + token, + prev: matchStack + }; + + moveToNextToken(); + syntaxStash = null; + + if (tokenIndex > longestMatch) { + longestMatch = tokenIndex; + } + } + + function openSyntax() { + syntaxStack = { + syntax: state.syntax, + opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null, + prev: syntaxStack + }; + + matchStack = { + type: OPEN_SYNTAX, + syntax: state.syntax, + token: matchStack.token, + prev: matchStack + }; + } + + function closeSyntax() { + if (matchStack.type === OPEN_SYNTAX) { + matchStack = matchStack.prev; + } else { + matchStack = { + type: CLOSE_SYNTAX, + syntax: syntaxStack.syntax, + token: matchStack.token, + prev: matchStack + }; + } + + syntaxStack = syntaxStack.prev; + } + + let syntaxStack = null; + let thenStack = null; + let elseStack = null; + + // null – stashing allowed, nothing stashed + // false – stashing disabled, nothing stashed + // anithing else – fail stashable syntaxes, some syntax stashed + let syntaxStash = null; + + let iterationCount = 0; // count iterations and prevent infinite loop + let exitReason = null; + + let token = null; + let tokenIndex = -1; + let longestMatch = 0; + let matchStack = { + type: STUB, + syntax: null, + token: null, + prev: null + }; + + moveToNextToken(); + + while (exitReason === null && ++iterationCount < ITERATION_LIMIT) { + // function mapList(list, fn) { + // const result = []; + // while (list) { + // result.unshift(fn(list)); + // list = list.prev; + // } + // return result; + // } + // console.log('--\n', + // '#' + iterationCount, + // require('util').inspect({ + // match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null), + // token: token && token.value, + // tokenIndex, + // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '') + // }, { depth: null }) + // ); + switch (state.type) { + case 'Match': + if (thenStack === null) { + // turn to MISMATCH when some tokens left unmatched + if (token !== null) { + // doesn't mismatch if just one token left and it's an IE hack + if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) { + state = MISMATCH; + break; + } + } + + // break the main loop, return a result - MATCH + exitReason = EXIT_REASON_MATCH; + break; + } + + // go to next syntax (`then` branch) + state = thenStack.nextState; + + // check match is not empty + if (state === DISALLOW_EMPTY) { + if (thenStack.matchStack === matchStack) { + state = MISMATCH; + break; + } else { + state = MATCH; + } + } + + // close syntax if needed + while (thenStack.syntaxStack !== syntaxStack) { + closeSyntax(); + } + + // pop stack + thenStack = thenStack.prev; + break; + + case 'Mismatch': + // when some syntax is stashed + if (syntaxStash !== null && syntaxStash !== false) { + // there is no else branches or a branch reduce match stack + if (elseStack === null || tokenIndex > elseStack.tokenIndex) { + // restore state from the stash + elseStack = syntaxStash; + syntaxStash = false; // disable stashing + } + } else if (elseStack === null) { + // no else branches -> break the main loop + // return a result - MISMATCH + exitReason = EXIT_REASON_MISMATCH; + break; + } + + // go to next syntax (`else` branch) + state = elseStack.nextState; + + // restore all the rest stack states + thenStack = elseStack.thenStack; + syntaxStack = elseStack.syntaxStack; + matchStack = elseStack.matchStack; + tokenIndex = elseStack.tokenIndex; + token = tokenIndex < tokens.length ? tokens[tokenIndex] : null; + + // pop stack + elseStack = elseStack.prev; + break; + + case 'MatchGraph': + state = state.match; + break; + + case 'If': + // IMPORTANT: else stack push must go first, + // since it stores the state of thenStack before changes + if (state.else !== MISMATCH) { + pushElseStack(state.else); + } + + if (state.then !== MATCH) { + pushThenStack(state.then); + } + + state = state.match; + break; + + case 'MatchOnce': + state = { + type: 'MatchOnceBuffer', + syntax: state, + index: 0, + mask: 0 + }; + break; + + case 'MatchOnceBuffer': { + const terms = state.syntax.terms; + + if (state.index === terms.length) { + // no matches at all or it's required all terms to be matched + if (state.mask === 0 || state.syntax.all) { + state = MISMATCH; + break; + } + + // a partial match is ok + state = MATCH; + break; + } + + // all terms are matched + if (state.mask === (1 << terms.length) - 1) { + state = MATCH; + break; + } + + for (; state.index < terms.length; state.index++) { + const matchFlag = 1 << state.index; + + if ((state.mask & matchFlag) === 0) { + // IMPORTANT: else stack push must go first, + // since it stores the state of thenStack before changes + pushElseStack(state); + pushThenStack({ + type: 'AddMatchOnce', + syntax: state.syntax, + mask: state.mask | matchFlag + }); + + // match + state = terms[state.index++]; + break; + } + } + break; + } + + case 'AddMatchOnce': + state = { + type: 'MatchOnceBuffer', + syntax: state.syntax, + index: 0, + mask: state.mask + }; + break; + + case 'Enum': + if (token !== null) { + let name = token.value.toLowerCase(); + + // drop \0 and \9 hack from keyword name + if (name.indexOf('\\') !== -1) { + name = name.replace(/\\[09].*$/, ''); + } + + if (hasOwnProperty.call(state.map, name)) { + state = state.map[name]; + break; + } + } + + state = MISMATCH; + break; + + case 'Generic': { + const opts = syntaxStack !== null ? syntaxStack.opts : null; + const lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts)); + + if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) { + while (tokenIndex < lastTokenIndex) { + addTokenToMatch(); + } + + state = MATCH; + } else { + state = MISMATCH; + } + + break; + } + + case 'Type': + case 'Property': { + const syntaxDict = state.type === 'Type' ? 'types' : 'properties'; + const dictSyntax = hasOwnProperty.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null; + + if (!dictSyntax || !dictSyntax.match) { + throw new Error( + 'Bad syntax reference: ' + + (state.type === 'Type' + ? '<' + state.name + '>' + : '<\'' + state.name + '\'>') + ); + } + + // stash a syntax for types with low priority + if (syntaxStash !== false && token !== null && state.type === 'Type') { + const lowPriorityMatching = + // https://drafts.csswg.org/css-values-4/#custom-idents + // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production + // can only claim the keyword if no other unfulfilled production can claim it. + (state.name === 'custom-ident' && token.type === TYPE.Ident) || + + // https://drafts.csswg.org/css-values-4/#lengths + // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height), + // it must parse as a <number> + (state.name === 'length' && token.value === '0'); + + if (lowPriorityMatching) { + if (syntaxStash === null) { + syntaxStash = stateSnapshotFromSyntax(state, elseStack); + } + + state = MISMATCH; + break; + } + } + + openSyntax(); + state = dictSyntax.matchRef || dictSyntax.match; + break; + } + + case 'Keyword': { + const name = state.name; + + if (token !== null) { + let keywordName = token.value; + + // drop \0 and \9 hack from keyword name + if (keywordName.indexOf('\\') !== -1) { + keywordName = keywordName.replace(/\\[09].*$/, ''); + } + + if (areStringsEqualCaseInsensitive(keywordName, name)) { + addTokenToMatch(); + state = MATCH; + break; + } + } + + state = MISMATCH; + break; + } + + case 'AtKeyword': + case 'Function': + if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) { + addTokenToMatch(); + state = MATCH; + break; + } + + state = MISMATCH; + break; + + case 'Token': + if (token !== null && token.value === state.value) { + addTokenToMatch(); + state = MATCH; + break; + } + + state = MISMATCH; + break; + + case 'Comma': + if (token !== null && token.type === TYPE.Comma) { + if (isCommaContextStart(matchStack.token)) { + state = MISMATCH; + } else { + addTokenToMatch(); + state = isCommaContextEnd(token) ? MISMATCH : MATCH; + } + } else { + state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH : MISMATCH; + } + + break; + + case 'String': + let string = ''; + let lastTokenIndex = tokenIndex; + + for (; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) { + string += tokens[lastTokenIndex].value; + } + + if (areStringsEqualCaseInsensitive(string, state.value)) { + while (tokenIndex < lastTokenIndex) { + addTokenToMatch(); + } + + state = MATCH; + } else { + state = MISMATCH; + } + + break; + + default: + throw new Error('Unknown node type: ' + state.type); + } + } + + totalIterationCount += iterationCount; + + switch (exitReason) { + case null: + console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations'); + exitReason = EXIT_REASON_ITERATION_LIMIT; + matchStack = null; + break; + + case EXIT_REASON_MATCH: + while (syntaxStack !== null) { + closeSyntax(); + } + break; + + default: + matchStack = null; + } + + return { + tokens, + reason: exitReason, + iterations: iterationCount, + match: matchStack, + longestMatch + }; +} + +export function matchAsList(tokens, matchGraph, syntaxes) { + const matchResult = internalMatch(tokens, matchGraph, syntaxes || {}); + + if (matchResult.match !== null) { + let item = reverseList(matchResult.match).prev; + + matchResult.match = []; + + while (item !== null) { + switch (item.type) { + case OPEN_SYNTAX: + case CLOSE_SYNTAX: + matchResult.match.push({ + type: item.type, + syntax: item.syntax + }); + break; + + default: + matchResult.match.push({ + token: item.token.value, + node: item.token.node + }); + break; + } + + item = item.prev; + } + } + + return matchResult; +} + +export function matchAsTree(tokens, matchGraph, syntaxes) { + const matchResult = internalMatch(tokens, matchGraph, syntaxes || {}); + + if (matchResult.match === null) { + return matchResult; + } + + let item = matchResult.match; + let host = matchResult.match = { + syntax: matchGraph.syntax || null, + match: [] + }; + const hostStack = [host]; + + // revert a list and start with 2nd item since 1st is a stub item + item = reverseList(item).prev; + + // build a tree + while (item !== null) { + switch (item.type) { + case OPEN_SYNTAX: + host.match.push(host = { + syntax: item.syntax, + match: [] + }); + hostStack.push(host); + break; + + case CLOSE_SYNTAX: + hostStack.pop(); + host = hostStack[hostStack.length - 1]; + break; + + default: + host.match.push({ + syntax: item.syntax || null, + token: item.token.value, + node: item.token.node + }); + } + + item = item.prev; + } + + return matchResult; +} diff --git a/vanilla/node_modules/css-tree/lib/lexer/prepare-tokens.js b/vanilla/node_modules/css-tree/lib/lexer/prepare-tokens.js new file mode 100644 index 0000000..4243fa8 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/prepare-tokens.js @@ -0,0 +1,50 @@ +import { tokenize } from '../tokenizer/index.js'; + +const astToTokens = { + decorator(handlers) { + const tokens = []; + let curNode = null; + + return { + ...handlers, + node(node) { + const tmp = curNode; + curNode = node; + handlers.node.call(this, node); + curNode = tmp; + }, + emit(value, type, auto) { + tokens.push({ + type, + value, + node: auto ? null : curNode + }); + }, + result() { + return tokens; + } + }; + } +}; + +function stringToTokens(str) { + const tokens = []; + + tokenize(str, (type, start, end) => + tokens.push({ + type, + value: str.slice(start, end), + node: null + }) + ); + + return tokens; +} + +export default function(value, syntax) { + if (typeof value === 'string') { + return stringToTokens(value); + } + + return syntax.generate(value, astToTokens); +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/search.js b/vanilla/node_modules/css-tree/lib/lexer/search.js new file mode 100644 index 0000000..ee68e2d --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/search.js @@ -0,0 +1,61 @@ +import { List } from '../utils/List.js'; + +function getFirstMatchNode(matchNode) { + if ('node' in matchNode) { + return matchNode.node; + } + + return getFirstMatchNode(matchNode.match[0]); +} + +function getLastMatchNode(matchNode) { + if ('node' in matchNode) { + return matchNode.node; + } + + return getLastMatchNode(matchNode.match[matchNode.match.length - 1]); +} + +export function matchFragments(lexer, ast, match, type, name) { + function findFragments(matchNode) { + if (matchNode.syntax !== null && + matchNode.syntax.type === type && + matchNode.syntax.name === name) { + const start = getFirstMatchNode(matchNode); + const end = getLastMatchNode(matchNode); + + lexer.syntax.walk(ast, function(node, item, list) { + if (node === start) { + const nodes = new List(); + + do { + nodes.appendData(item.data); + + if (item.data === end) { + break; + } + + item = item.next; + } while (item !== null); + + fragments.push({ + parent: list, + nodes + }); + } + }); + } + + if (Array.isArray(matchNode.match)) { + matchNode.match.forEach(findFragments); + } + } + + const fragments = []; + + if (match.matched !== null) { + findFragments(match.matched); + } + + return fragments; +} diff --git a/vanilla/node_modules/css-tree/lib/lexer/structure.js b/vanilla/node_modules/css-tree/lib/lexer/structure.js new file mode 100644 index 0000000..3bf4ced --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/structure.js @@ -0,0 +1,169 @@ +import { List } from '../utils/List.js'; + +const { hasOwnProperty } = Object.prototype; + +function isValidNumber(value) { + // Number.isInteger(value) && value >= 0 + return ( + typeof value === 'number' && + isFinite(value) && + Math.floor(value) === value && + value >= 0 + ); +} + +function isValidLocation(loc) { + return ( + Boolean(loc) && + isValidNumber(loc.offset) && + isValidNumber(loc.line) && + isValidNumber(loc.column) + ); +} + +function createNodeStructureChecker(type, fields) { + return function checkNode(node, warn) { + if (!node || node.constructor !== Object) { + return warn(node, 'Type of node should be an Object'); + } + + for (let key in node) { + let valid = true; + + if (hasOwnProperty.call(node, key) === false) { + continue; + } + + if (key === 'type') { + if (node.type !== type) { + warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`'); + } + } else if (key === 'loc') { + if (node.loc === null) { + continue; + } else if (node.loc && node.loc.constructor === Object) { + if (typeof node.loc.source !== 'string') { + key += '.source'; + } else if (!isValidLocation(node.loc.start)) { + key += '.start'; + } else if (!isValidLocation(node.loc.end)) { + key += '.end'; + } else { + continue; + } + } + + valid = false; + } else if (fields.hasOwnProperty(key)) { + valid = false; + + for (let i = 0; !valid && i < fields[key].length; i++) { + const fieldType = fields[key][i]; + + switch (fieldType) { + case String: + valid = typeof node[key] === 'string'; + break; + + case Boolean: + valid = typeof node[key] === 'boolean'; + break; + + case null: + valid = node[key] === null; + break; + + default: + if (typeof fieldType === 'string') { + valid = node[key] && node[key].type === fieldType; + } else if (Array.isArray(fieldType)) { + valid = node[key] instanceof List; + } + } + } + } else { + warn(node, 'Unknown field `' + key + '` for ' + type + ' node type'); + } + + if (!valid) { + warn(node, 'Bad value for `' + type + '.' + key + '`'); + } + } + + for (const key in fields) { + if (hasOwnProperty.call(fields, key) && + hasOwnProperty.call(node, key) === false) { + warn(node, 'Field `' + type + '.' + key + '` is missed'); + } + } + }; +} + +function genTypesList(fieldTypes, path) { + const docsTypes = []; + + for (let i = 0; i < fieldTypes.length; i++) { + const fieldType = fieldTypes[i]; + if (fieldType === String || fieldType === Boolean) { + docsTypes.push(fieldType.name.toLowerCase()); + } else if (fieldType === null) { + docsTypes.push('null'); + } else if (typeof fieldType === 'string') { + docsTypes.push(fieldType); + } else if (Array.isArray(fieldType)) { + docsTypes.push('List<' + (genTypesList(fieldType, path) || 'any') + '>'); // TODO: use type enum + } else { + throw new Error('Wrong value `' + fieldType + '` in `' + path + '` structure definition'); + } + } + + return docsTypes.join(' | '); +} + +function processStructure(name, nodeType) { + const structure = nodeType.structure; + const fields = { + type: String, + loc: true + }; + const docs = { + type: '"' + name + '"' + }; + + for (const key in structure) { + if (hasOwnProperty.call(structure, key) === false) { + continue; + } + + const fieldTypes = fields[key] = Array.isArray(structure[key]) + ? structure[key].slice() + : [structure[key]]; + + docs[key] = genTypesList(fieldTypes, name + '.' + key); + } + + return { + docs, + check: createNodeStructureChecker(name, fields) + }; +} + +export function getStructureFromConfig(config) { + const structure = {}; + + if (config.node) { + for (const name in config.node) { + if (hasOwnProperty.call(config.node, name)) { + const nodeType = config.node[name]; + + if (nodeType.structure) { + structure[name] = processStructure(name, nodeType); + } else { + throw new Error('Missed `structure` field in `' + name + '` node type definition'); + } + } + } + } + + return structure; +}; diff --git a/vanilla/node_modules/css-tree/lib/lexer/trace.js b/vanilla/node_modules/css-tree/lib/lexer/trace.js new file mode 100644 index 0000000..959813c --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/trace.js @@ -0,0 +1,66 @@ +export function getTrace(node) { + function shouldPutToTrace(syntax) { + if (syntax === null) { + return false; + } + + return ( + syntax.type === 'Type' || + syntax.type === 'Property' || + syntax.type === 'Keyword' + ); + } + + function hasMatch(matchNode) { + if (Array.isArray(matchNode.match)) { + // use for-loop for better perfomance + for (let i = 0; i < matchNode.match.length; i++) { + if (hasMatch(matchNode.match[i])) { + if (shouldPutToTrace(matchNode.syntax)) { + result.unshift(matchNode.syntax); + } + + return true; + } + } + } else if (matchNode.node === node) { + result = shouldPutToTrace(matchNode.syntax) + ? [matchNode.syntax] + : []; + + return true; + } + + return false; + } + + let result = null; + + if (this.matched !== null) { + hasMatch(this.matched); + } + + return result; +} + +export function isType(node, type) { + return testNode(this, node, match => match.type === 'Type' && match.name === type); +} + +export function isProperty(node, property) { + return testNode(this, node, match => match.type === 'Property' && match.name === property); +} + +export function isKeyword(node) { + return testNode(this, node, match => match.type === 'Keyword'); +} + +function testNode(match, node, fn) { + const trace = getTrace.call(match, node); + + if (trace === null) { + return false; + } + + return trace.some(fn); +} diff --git a/vanilla/node_modules/css-tree/lib/lexer/units.js b/vanilla/node_modules/css-tree/lib/lexer/units.js new file mode 100644 index 0000000..88b1f69 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/lexer/units.js @@ -0,0 +1,27 @@ +export const length = [ + // absolute length units https://www.w3.org/TR/css-values-3/#lengths + 'cm', 'mm', 'q', 'in', 'pt', 'pc', 'px', + // font-relative length units https://drafts.csswg.org/css-values-4/#font-relative-lengths + 'em', 'rem', + 'ex', 'rex', + 'cap', 'rcap', + 'ch', 'rch', + 'ic', 'ric', + 'lh', 'rlh', + // viewport-percentage lengths https://drafts.csswg.org/css-values-4/#viewport-relative-lengths + 'vw', 'svw', 'lvw', 'dvw', + 'vh', 'svh', 'lvh', 'dvh', + 'vi', 'svi', 'lvi', 'dvi', + 'vb', 'svb', 'lvb', 'dvb', + 'vmin', 'svmin', 'lvmin', 'dvmin', + 'vmax', 'svmax', 'lvmax', 'dvmax', + // container relative lengths https://drafts.csswg.org/css-contain-3/#container-lengths + 'cqw', 'cqh', 'cqi', 'cqb', 'cqmin', 'cqmax' +]; +export const angle = ['deg', 'grad', 'rad', 'turn']; // https://www.w3.org/TR/css-values-3/#angles +export const time = ['s', 'ms']; // https://www.w3.org/TR/css-values-3/#time +export const frequency = ['hz', 'khz']; // https://www.w3.org/TR/css-values-3/#frequency +export const resolution = ['dpi', 'dpcm', 'dppx', 'x']; // https://www.w3.org/TR/css-values-3/#resolution +export const flex = ['fr']; // https://drafts.csswg.org/css-grid/#fr-unit +export const decibel = ['db']; // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume +export const semitones = ['st']; // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch diff --git a/vanilla/node_modules/css-tree/lib/parser/SyntaxError.js b/vanilla/node_modules/css-tree/lib/parser/SyntaxError.js new file mode 100644 index 0000000..55e01c1 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/parser/SyntaxError.js @@ -0,0 +1,70 @@ +import { createCustomError } from '../utils/create-custom-error.js'; + +const MAX_LINE_LENGTH = 100; +const OFFSET_CORRECTION = 60; +const TAB_REPLACEMENT = ' '; + +function sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) { + function processLines(start, end) { + return lines + .slice(start, end) + .map((line, idx) => + String(start + idx + 1).padStart(maxNumLength) + ' |' + line + ).join('\n'); + } + + const prelines = '\n'.repeat(Math.max(baseLine - 1, 0)); + const precolumns = ' '.repeat(Math.max(baseColumn - 1, 0)); + const lines = (prelines + precolumns + source).split(/\r\n?|\n|\f/); + const startLine = Math.max(1, line - extraLines) - 1; + const endLine = Math.min(line + extraLines, lines.length + 1); + const maxNumLength = Math.max(4, String(endLine).length) + 1; + let cutLeft = 0; + + // column correction according to replaced tab before column + column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length; + + if (column > MAX_LINE_LENGTH) { + cutLeft = column - OFFSET_CORRECTION + 3; + column = OFFSET_CORRECTION - 2; + } + + for (let i = startLine; i <= endLine; i++) { + if (i >= 0 && i < lines.length) { + lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT); + lines[i] = + (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') + + lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) + + (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : ''); + } + } + + return [ + processLines(startLine, line), + new Array(column + maxNumLength + 2).join('-') + '^', + processLines(line, endLine) + ].filter(Boolean) + .join('\n') + .replace(/^(\s+\d+\s+\|\n)+/, '') + .replace(/\n(\s+\d+\s+\|)+$/, ''); +} + +export function SyntaxError(message, source, offset, line, column, baseLine = 1, baseColumn = 1) { + const error = Object.assign(createCustomError('SyntaxError', message), { + source, + offset, + line, + column, + sourceFragment(extraLines) { + return sourceFragment({ source, line, column, baseLine, baseColumn }, isNaN(extraLines) ? 0 : extraLines); + }, + get formattedMessage() { + return ( + `Parse error: ${message}\n` + + sourceFragment({ source, line, column, baseLine, baseColumn }, 2) + ); + } + }); + + return error; +} diff --git a/vanilla/node_modules/css-tree/lib/parser/create.js b/vanilla/node_modules/css-tree/lib/parser/create.js new file mode 100644 index 0000000..8c08d81 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/parser/create.js @@ -0,0 +1,350 @@ +import { List } from '../utils/List.js'; +import { SyntaxError } from './SyntaxError.js'; +import { + tokenize, + OffsetToLocation, + TokenStream, + tokenNames, + + consumeNumber, + findWhiteSpaceStart, + cmpChar, + cmpStr, + + WhiteSpace, + Comment, + Ident, + Function as FunctionToken, + Url, + Hash, + Percentage, + Number as NumberToken +} from '../tokenizer/index.js'; +import { readSequence } from './sequence.js'; + +const NOOP = () => {}; +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const SEMICOLON = 0x003B; // U+003B SEMICOLON (;) +const LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({) +const NULL = 0; + +function createParseContext(name) { + return function() { + return this[name](); + }; +} + +function fetchParseValues(dict) { + const result = Object.create(null); + + for (const name of Object.keys(dict)) { + const item = dict[name]; + const fn = item.parse || item; + + if (fn) { + result[name] = fn; + } + } + + return result; +} + +function processConfig(config) { + const parseConfig = { + context: Object.create(null), + features: Object.assign(Object.create(null), config.features), + scope: Object.assign(Object.create(null), config.scope), + atrule: fetchParseValues(config.atrule), + pseudo: fetchParseValues(config.pseudo), + node: fetchParseValues(config.node) + }; + + for (const [name, context] of Object.entries(config.parseContext)) { + switch (typeof context) { + case 'function': + parseConfig.context[name] = context; + break; + + case 'string': + parseConfig.context[name] = createParseContext(context); + break; + } + } + + return { + config: parseConfig, + ...parseConfig, + ...parseConfig.node + }; +} + +export function createParser(config) { + let source = ''; + let filename = '<unknown>'; + let needPositions = false; + let onParseError = NOOP; + let onParseErrorThrow = false; + + const locationMap = new OffsetToLocation(); + const parser = Object.assign(new TokenStream(), processConfig(config || {}), { + parseAtrulePrelude: true, + parseRulePrelude: true, + parseValue: true, + parseCustomProperty: false, + + readSequence, + + consumeUntilBalanceEnd: () => 0, + consumeUntilLeftCurlyBracket(code) { + return code === LEFTCURLYBRACKET ? 1 : 0; + }, + consumeUntilLeftCurlyBracketOrSemicolon(code) { + return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0; + }, + consumeUntilExclamationMarkOrSemicolon(code) { + return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0; + }, + consumeUntilSemicolonIncluded(code) { + return code === SEMICOLON ? 2 : 0; + }, + + createList() { + return new List(); + }, + createSingleNodeList(node) { + return new List().appendData(node); + }, + getFirstListNode(list) { + return list && list.first; + }, + getLastListNode(list) { + return list && list.last; + }, + + parseWithFallback(consumer, fallback) { + const startIndex = this.tokenIndex; + + try { + return consumer.call(this); + } catch (e) { + if (onParseErrorThrow) { + throw e; + } + + this.skip(startIndex - this.tokenIndex); + const fallbackNode = fallback.call(this); + + onParseErrorThrow = true; + onParseError(e, fallbackNode); + onParseErrorThrow = false; + + return fallbackNode; + } + }, + + lookupNonWSType(offset) { + let type; + + do { + type = this.lookupType(offset++); + if (type !== WhiteSpace && type !== Comment) { + return type; + } + } while (type !== NULL); + + return NULL; + }, + + charCodeAt(offset) { + return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0; + }, + substring(offsetStart, offsetEnd) { + return source.substring(offsetStart, offsetEnd); + }, + substrToCursor(start) { + return this.source.substring(start, this.tokenStart); + }, + + cmpChar(offset, charCode) { + return cmpChar(source, offset, charCode); + }, + cmpStr(offsetStart, offsetEnd, str) { + return cmpStr(source, offsetStart, offsetEnd, str); + }, + + consume(tokenType) { + const start = this.tokenStart; + + this.eat(tokenType); + + return this.substrToCursor(start); + }, + consumeFunctionName() { + const name = source.substring(this.tokenStart, this.tokenEnd - 1); + + this.eat(FunctionToken); + + return name; + }, + consumeNumber(type) { + const number = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart)); + + this.eat(type); + + return number; + }, + + eat(tokenType) { + if (this.tokenType !== tokenType) { + const tokenName = tokenNames[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase()); + let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`; + let offset = this.tokenStart; + + // tweak message and offset + switch (tokenType) { + case Ident: + // when identifier is expected but there is a function or url + if (this.tokenType === FunctionToken || this.tokenType === Url) { + offset = this.tokenEnd - 1; + message = 'Identifier is expected but function found'; + } else { + message = 'Identifier is expected'; + } + break; + + case Hash: + if (this.isDelim(NUMBERSIGN)) { + this.next(); + offset++; + message = 'Name is expected'; + } + break; + + case Percentage: + if (this.tokenType === NumberToken) { + offset = this.tokenEnd; + message = 'Percent sign is expected'; + } + break; + } + + this.error(message, offset); + } + + this.next(); + }, + eatIdent(name) { + if (this.tokenType !== Ident || this.lookupValue(0, name) === false) { + this.error(`Identifier "${name}" is expected`); + } + + this.next(); + }, + eatDelim(code) { + if (!this.isDelim(code)) { + this.error(`Delim "${String.fromCharCode(code)}" is expected`); + } + + this.next(); + }, + + getLocation(start, end) { + if (needPositions) { + return locationMap.getLocationRange( + start, + end, + filename + ); + } + + return null; + }, + getLocationFromList(list) { + if (needPositions) { + const head = this.getFirstListNode(list); + const tail = this.getLastListNode(list); + return locationMap.getLocationRange( + head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart, + tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart, + filename + ); + } + + return null; + }, + + error(message, offset) { + const location = typeof offset !== 'undefined' && offset < source.length + ? locationMap.getLocation(offset) + : this.eof + ? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1)) + : locationMap.getLocation(this.tokenStart); + + throw new SyntaxError( + message || 'Unexpected input', + source, + location.offset, + location.line, + location.column, + locationMap.startLine, + locationMap.startColumn + ); + } + }); + + const parse = function(source_, options) { + source = source_; + options = options || {}; + + parser.setSource(source, tokenize); + locationMap.setSource( + source, + options.offset, + options.line, + options.column + ); + + filename = options.filename || '<unknown>'; + needPositions = Boolean(options.positions); + onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP; + onParseErrorThrow = false; + + parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true; + parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true; + parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true; + parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false; + + const { context = 'default', onComment } = options; + + if (context in parser.context === false) { + throw new Error('Unknown context `' + context + '`'); + } + + if (typeof onComment === 'function') { + parser.forEachToken((type, start, end) => { + if (type === Comment) { + const loc = parser.getLocation(start, end); + const value = cmpStr(source, end - 2, end, '*/') + ? source.slice(start + 2, end - 2) + : source.slice(start + 2, end); + + onComment(value, loc); + } + }); + } + + const ast = parser.context[context].call(parser, options); + + if (!parser.eof) { + parser.error(); + } + + return ast; + }; + + return Object.assign(parse, { + SyntaxError, + config: parser.config + }); +}; diff --git a/vanilla/node_modules/css-tree/lib/parser/index.js b/vanilla/node_modules/css-tree/lib/parser/index.js new file mode 100644 index 0000000..7cee62e --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/parser/index.js @@ -0,0 +1,4 @@ +import { createParser } from './create.js'; +import config from '../syntax/config/parser.js'; + +export default createParser(config); diff --git a/vanilla/node_modules/css-tree/lib/parser/parse-selector.js b/vanilla/node_modules/css-tree/lib/parser/parse-selector.js new file mode 100644 index 0000000..05b539a --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/parser/parse-selector.js @@ -0,0 +1,4 @@ +import { createParser } from './create.js'; +import config from '../syntax/config/parser-selector.js'; + +export default createParser(config); diff --git a/vanilla/node_modules/css-tree/lib/parser/sequence.js b/vanilla/node_modules/css-tree/lib/parser/sequence.js new file mode 100644 index 0000000..47d1ccd --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/parser/sequence.js @@ -0,0 +1,43 @@ +import { WhiteSpace, Comment } from '../tokenizer/index.js'; + +export function readSequence(recognizer) { + const children = this.createList(); + let space = false; + const context = { + recognizer + }; + + while (!this.eof) { + switch (this.tokenType) { + case Comment: + this.next(); + continue; + + case WhiteSpace: + space = true; + this.next(); + continue; + } + + let child = recognizer.getNode.call(this, context); + + if (child === undefined) { + break; + } + + if (space) { + if (recognizer.onWhiteSpace) { + recognizer.onWhiteSpace.call(this, child, children, context); + } + space = false; + } + + children.push(child); + } + + if (space && recognizer.onWhiteSpace) { + recognizer.onWhiteSpace.call(this, null, children, context); + } + + return children; +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/container.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/container.js new file mode 100644 index 0000000..aa550de --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/container.js @@ -0,0 +1,28 @@ +import { Ident } from '../../tokenizer/index.js'; + +// https://drafts.csswg.org/css-contain-3/#container-rule +// The keywords `none`, `and`, `not`, and `or` are excluded from the <custom-ident> above. +const nonContainerNameKeywords = new Set(['none', 'and', 'not', 'or']); + +export default { + parse: { + prelude() { + const children = this.createList(); + + if (this.tokenType === Ident) { + const name = this.substring(this.tokenStart, this.tokenEnd); + + if (!nonContainerNameKeywords.has(name.toLowerCase())) { + children.push(this.Identifier()); + } + } + + children.push(this.Condition('container')); + + return children; + }, + block(nested = false) { + return this.Block(nested); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/font-face.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/font-face.js new file mode 100644 index 0000000..48a0570 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/font-face.js @@ -0,0 +1,8 @@ +export default { + parse: { + prelude: null, + block() { + return this.Block(true); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/import.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/import.js new file mode 100644 index 0000000..4e5a637 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/import.js @@ -0,0 +1,104 @@ +import { + String as StringToken, + Ident, + Url, + Function as FunctionToken, + LeftParenthesis, + RightParenthesis +} from '../../tokenizer/index.js'; + +function parseWithFallback(parse, fallback) { + return this.parseWithFallback( + () => { + try { + return parse.call(this); + } finally { + this.skipSC(); + if (this.lookupNonWSType(0) !== RightParenthesis) { + this.error(); + } + } + }, + fallback || (() => this.Raw(null, true)) + ); +} + +const parseFunctions = { + layer() { + this.skipSC(); + + const children = this.createList(); + const node = parseWithFallback.call(this, this.Layer); + + if (node.type !== 'Raw' || node.value !== '') { + children.push(node); + } + + return children; + }, + supports() { + this.skipSC(); + + const children = this.createList(); + const node = parseWithFallback.call( + this, + this.Declaration, + () => parseWithFallback.call(this, () => this.Condition('supports')) + ); + + if (node.type !== 'Raw' || node.value !== '') { + children.push(node); + } + + return children; + } +}; + +export default { + parse: { + prelude() { + const children = this.createList(); + + switch (this.tokenType) { + case StringToken: + children.push(this.String()); + break; + + case Url: + case FunctionToken: + children.push(this.Url()); + break; + + default: + this.error('String or url() is expected'); + } + + this.skipSC(); + + if (this.tokenType === Ident && + this.cmpStr(this.tokenStart, this.tokenEnd, 'layer')) { + children.push(this.Identifier()); + } else if ( + this.tokenType === FunctionToken && + this.cmpStr(this.tokenStart, this.tokenEnd, 'layer(') + ) { + children.push(this.Function(null, parseFunctions)); + } + + this.skipSC(); + + if (this.tokenType === FunctionToken && + this.cmpStr(this.tokenStart, this.tokenEnd, 'supports(')) { + children.push(this.Function(null, parseFunctions)); + } + + if (this.lookupNonWSType(0) === Ident || + this.lookupNonWSType(0) === LeftParenthesis) { + children.push(this.MediaQueryList()); + } + + return children; + }, + block: null + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/index.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/index.js new file mode 100644 index 0000000..46ac7f8 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/index.js @@ -0,0 +1,23 @@ +import container from './container.js'; +import fontFace from './font-face.js'; +import importAtrule from './import.js'; +import layer from './layer.js'; +import media from './media.js'; +import nest from './nest.js'; +import page from './page.js'; +import scope from './scope.js'; +import startingStyle from './starting-style.js'; +import supports from './supports.js'; + +export default { + container, + 'font-face': fontFace, + import: importAtrule, + layer, + media, + nest, + page, + scope, + 'starting-style': startingStyle, + supports +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/layer.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/layer.js new file mode 100644 index 0000000..232eb29 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/layer.js @@ -0,0 +1,12 @@ +export default { + parse: { + prelude() { + return this.createSingleNodeList( + this.LayerList() + ); + }, + block() { + return this.Block(false); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/media.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/media.js new file mode 100644 index 0000000..24d4608 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/media.js @@ -0,0 +1,12 @@ +export default { + parse: { + prelude() { + return this.createSingleNodeList( + this.MediaQueryList() + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/nest.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/nest.js new file mode 100644 index 0000000..99fc15e --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/nest.js @@ -0,0 +1,12 @@ +export default { + parse: { + prelude() { + return this.createSingleNodeList( + this.SelectorList() + ); + }, + block() { + return this.Block(true); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/page.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/page.js new file mode 100644 index 0000000..99fc15e --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/page.js @@ -0,0 +1,12 @@ +export default { + parse: { + prelude() { + return this.createSingleNodeList( + this.SelectorList() + ); + }, + block() { + return this.Block(true); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/scope.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/scope.js new file mode 100644 index 0000000..7185ca1 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/scope.js @@ -0,0 +1,12 @@ +export default { + parse: { + prelude() { + return this.createSingleNodeList( + this.Scope() + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/starting-style.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/starting-style.js new file mode 100644 index 0000000..b964704 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/starting-style.js @@ -0,0 +1,8 @@ +export default { + parse: { + prelude: null, + block(nested = false) { + return this.Block(nested); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/atrule/supports.js b/vanilla/node_modules/css-tree/lib/syntax/atrule/supports.js new file mode 100644 index 0000000..bdfffce --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/atrule/supports.js @@ -0,0 +1,12 @@ +export default { + parse: { + prelude() { + return this.createSingleNodeList( + this.Condition('supports') + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/config/generator.js b/vanilla/node_modules/css-tree/lib/syntax/config/generator.js new file mode 100644 index 0000000..82e874c --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/config/generator.js @@ -0,0 +1,5 @@ +import * as node from '../node/index-generate.js'; + +export default { + node +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/config/lexer.js b/vanilla/node_modules/css-tree/lib/syntax/config/lexer.js new file mode 100644 index 0000000..b479ac5 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/config/lexer.js @@ -0,0 +1,10 @@ +import { cssWideKeywords } from '../../lexer/generic-const.js'; +import definitions from '../../data.js'; +import * as node from '../node/index.js'; + +export default { + generic: true, + cssWideKeywords, + ...definitions, + node +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/config/mix.js b/vanilla/node_modules/css-tree/lib/syntax/config/mix.js new file mode 100644 index 0000000..f722ceb --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/config/mix.js @@ -0,0 +1,123 @@ +function appendOrSet(a, b) { + if (typeof b === 'string' && /^\s*\|/.test(b)) { + return typeof a === 'string' + ? a + b + : b.replace(/^\s*\|\s*/, ''); + } + + return b || null; +} + +function sliceProps(obj, props) { + const result = Object.create(null); + + for (const [key, value] of Object.entries(obj)) { + if (value) { + result[key] = {}; + for (const prop of Object.keys(value)) { + if (props.includes(prop)) { + result[key][prop] = value[prop]; + } + } + } + } + + return result; +} + +export default function mix(dest, src) { + const result = { ...dest }; + + for (const [prop, value] of Object.entries(src)) { + switch (prop) { + case 'generic': + result[prop] = Boolean(value); + break; + + case 'cssWideKeywords': + result[prop] = dest[prop] + ? [...dest[prop], ...value] + : value || []; + break; + + case 'units': + result[prop] = { ...dest[prop] }; + for (const [name, patch] of Object.entries(value)) { + result[prop][name] = Array.isArray(patch) ? patch : []; + } + break; + + case 'atrules': + result[prop] = { ...dest[prop] }; + + for (const [name, atrule] of Object.entries(value)) { + const exists = result[prop][name] || {}; + const current = result[prop][name] = { + prelude: exists.prelude || null, + descriptors: { + ...exists.descriptors + } + }; + + if (!atrule) { + continue; + } + + current.prelude = atrule.prelude + ? appendOrSet(current.prelude, atrule.prelude) + : current.prelude || null; + + for (const [descriptorName, descriptorValue] of Object.entries(atrule.descriptors || {})) { + current.descriptors[descriptorName] = descriptorValue + ? appendOrSet(current.descriptors[descriptorName], descriptorValue) + : null; + } + + if (!Object.keys(current.descriptors).length) { + current.descriptors = null; + } + } + break; + + case 'types': + case 'properties': + result[prop] = { ...dest[prop] }; + for (const [name, syntax] of Object.entries(value)) { + result[prop][name] = appendOrSet(result[prop][name], syntax); + } + break; + + case 'scope': + case 'features': + result[prop] = { ...dest[prop] }; + for (const [name, props] of Object.entries(value)) { + result[prop][name] = { ...result[prop][name], ...props }; + } + break; + + case 'parseContext': + result[prop] = { + ...dest[prop], + ...value + }; + break; + + case 'atrule': + case 'pseudo': + result[prop] = { + ...dest[prop], + ...sliceProps(value, ['parse']) + }; + break; + + case 'node': + result[prop] = { + ...dest[prop], + ...sliceProps(value, ['name', 'structure', 'parse', 'generate', 'walkContext']) + }; + break; + } + } + + return result; +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/config/parser-selector.js b/vanilla/node_modules/css-tree/lib/syntax/config/parser-selector.js new file mode 100644 index 0000000..c9e0ee2 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/config/parser-selector.js @@ -0,0 +1,15 @@ +import { Selector } from '../scope/index.js'; +import pseudo from '../pseudo/index.js'; +import * as node from '../node/index-parse-selector.js'; + +export default { + parseContext: { + default: 'SelectorList', + selectorList: 'SelectorList', + selector: 'Selector' + }, + scope: { Selector }, + atrule: {}, + pseudo, + node +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/config/parser.js b/vanilla/node_modules/css-tree/lib/syntax/config/parser.js new file mode 100644 index 0000000..0b455aa --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/config/parser.js @@ -0,0 +1,45 @@ +import * as scope from '../scope/index.js'; +import atrule from '../atrule/index.js'; +import pseudo from '../pseudo/index.js'; +import * as node from '../node/index-parse.js'; + +export default { + parseContext: { + default: 'StyleSheet', + stylesheet: 'StyleSheet', + atrule: 'Atrule', + atrulePrelude(options) { + return this.AtrulePrelude(options.atrule ? String(options.atrule) : null); + }, + mediaQueryList: 'MediaQueryList', + mediaQuery: 'MediaQuery', + condition(options) { + return this.Condition(options.kind); + }, + rule: 'Rule', + selectorList: 'SelectorList', + selector: 'Selector', + block() { + return this.Block(true); + }, + declarationList: 'DeclarationList', + declaration: 'Declaration', + value: 'Value' + }, + features: { + supports: { + selector() { + return this.Selector(); + } + }, + container: { + style() { + return this.Declaration(); + } + } + }, + scope, + atrule, + pseudo, + node +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/config/walker.js b/vanilla/node_modules/css-tree/lib/syntax/config/walker.js new file mode 100644 index 0000000..215d024 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/config/walker.js @@ -0,0 +1,5 @@ +import * as node from '../node/index.js'; + +export default { + node +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/create.js b/vanilla/node_modules/css-tree/lib/syntax/create.js new file mode 100644 index 0000000..9bb32c5 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/create.js @@ -0,0 +1,55 @@ +import { tokenize } from '../tokenizer/index.js'; +import { createParser } from '../parser/create.js'; +import { createGenerator } from '../generator/create.js'; +import { createConvertor } from '../convertor/create.js'; +import { createWalker } from '../walker/create.js'; +import { Lexer } from '../lexer/Lexer.js'; +import mix from './config/mix.js'; + +function createSyntax(config) { + const parse = createParser(config); + const walk = createWalker(config); + const generate = createGenerator(config); + const { fromPlainObject, toPlainObject } = createConvertor(walk); + + const syntax = { + lexer: null, + createLexer: config => new Lexer(config, syntax, syntax.lexer.structure), + + tokenize, + parse, + generate, + + walk, + find: walk.find, + findLast: walk.findLast, + findAll: walk.findAll, + + fromPlainObject, + toPlainObject, + + fork(extension) { + const base = mix({}, config); // copy of config + + return createSyntax( + typeof extension === 'function' + ? extension(base) // TODO: remove Object.assign as second parameter + : mix(base, extension) + ); + } + }; + + syntax.lexer = new Lexer({ + generic: config.generic, + cssWideKeywords: config.cssWideKeywords, + units: config.units, + types: config.types, + atrules: config.atrules, + properties: config.properties, + node: config.node + }, syntax); + + return syntax; +}; + +export default config => createSyntax(mix({}, config)); diff --git a/vanilla/node_modules/css-tree/lib/syntax/function/expression.js b/vanilla/node_modules/css-tree/lib/syntax/function/expression.js new file mode 100644 index 0000000..040f826 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/function/expression.js @@ -0,0 +1,7 @@ +// legacy IE function +// expression( <any-value> ) +export default function() { + return this.createSingleNodeList( + this.Raw(null, false) + ); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/function/var.js b/vanilla/node_modules/css-tree/lib/syntax/function/var.js new file mode 100644 index 0000000..010dc0a --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/function/var.js @@ -0,0 +1,39 @@ +import { Comma, WhiteSpace } from '../../tokenizer/index.js'; + +// var( <ident> , <value>? ) +export default function() { + const children = this.createList(); + + this.skipSC(); + + // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer + children.push(this.Identifier()); + + this.skipSC(); + + if (this.tokenType === Comma) { + children.push(this.Operator()); + + const startIndex = this.tokenIndex; + const value = this.parseCustomProperty + ? this.Value(null) + : this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false); + + if (value.type === 'Value' && value.children.isEmpty) { + for (let offset = startIndex - this.tokenIndex; offset <= 0; offset++) { + if (this.lookupType(offset) === WhiteSpace) { + value.children.appendData({ + type: 'WhiteSpace', + loc: null, + value: ' ' + }); + break; + } + } + } + + children.push(value); + } + + return children; +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/index.js b/vanilla/node_modules/css-tree/lib/syntax/index.js new file mode 100644 index 0000000..c8c9152 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/index.js @@ -0,0 +1,10 @@ +import createSyntax from './create.js'; +import lexerConfig from './config/lexer.js'; +import parserConfig from './config/parser.js'; +import walkerConfig from './config/walker.js'; + +export default createSyntax({ + ...lexerConfig, + ...parserConfig, + ...walkerConfig +}); diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/AnPlusB.js b/vanilla/node_modules/css-tree/lib/syntax/node/AnPlusB.js new file mode 100644 index 0000000..05c7e44 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/AnPlusB.js @@ -0,0 +1,292 @@ +import { + isDigit, + WhiteSpace, + Comment, + Ident, + Number, + Dimension +} from '../../tokenizer/index.js'; + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const N = 0x006E; // U+006E LATIN SMALL LETTER N (n) +const DISALLOW_SIGN = true; +const ALLOW_SIGN = false; + +function checkInteger(offset, disallowSign) { + let pos = this.tokenStart + offset; + const code = this.charCodeAt(pos); + + if (code === PLUSSIGN || code === HYPHENMINUS) { + if (disallowSign) { + this.error('Number sign is not allowed'); + } + pos++; + } + + for (; pos < this.tokenEnd; pos++) { + if (!isDigit(this.charCodeAt(pos))) { + this.error('Integer is expected', pos); + } + } +} + +function checkTokenIsInteger(disallowSign) { + return checkInteger.call(this, 0, disallowSign); +} + +function expectCharCode(offset, code) { + if (!this.cmpChar(this.tokenStart + offset, code)) { + let msg = ''; + + switch (code) { + case N: + msg = 'N is expected'; + break; + case HYPHENMINUS: + msg = 'HyphenMinus is expected'; + break; + } + + this.error(msg, this.tokenStart + offset); + } +} + +// ... <signed-integer> +// ... ['+' | '-'] <signless-integer> +function consumeB() { + let offset = 0; + let sign = 0; + let type = this.tokenType; + + while (type === WhiteSpace || type === Comment) { + type = this.lookupType(++offset); + } + + if (type !== Number) { + if (this.isDelim(PLUSSIGN, offset) || + this.isDelim(HYPHENMINUS, offset)) { + sign = this.isDelim(PLUSSIGN, offset) ? PLUSSIGN : HYPHENMINUS; + + do { + type = this.lookupType(++offset); + } while (type === WhiteSpace || type === Comment); + + if (type !== Number) { + this.skip(offset); + checkTokenIsInteger.call(this, DISALLOW_SIGN); + } + } else { + return null; + } + } + + if (offset > 0) { + this.skip(offset); + } + + if (sign === 0) { + type = this.charCodeAt(this.tokenStart); + if (type !== PLUSSIGN && type !== HYPHENMINUS) { + this.error('Number sign is expected'); + } + } + + checkTokenIsInteger.call(this, sign !== 0); + return sign === HYPHENMINUS ? '-' + this.consume(Number) : this.consume(Number); +} + +// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb +export const name = 'AnPlusB'; +export const structure = { + a: [String, null], + b: [String, null] +}; + +export function parse() { + /* eslint-disable brace-style*/ + const start = this.tokenStart; + let a = null; + let b = null; + + // <integer> + if (this.tokenType === Number) { + checkTokenIsInteger.call(this, ALLOW_SIGN); + b = this.consume(Number); + } + + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + // -n- <signless-integer> + // <dashndashdigit-ident> + else if (this.tokenType === Ident && this.cmpChar(this.tokenStart, HYPHENMINUS)) { + a = '-1'; + + expectCharCode.call(this, 1, N); + + switch (this.tokenEnd - this.tokenStart) { + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + case 2: + this.next(); + b = consumeB.call(this); + break; + + // -n- <signless-integer> + case 3: + expectCharCode.call(this, 2, HYPHENMINUS); + + this.next(); + this.skipSC(); + + checkTokenIsInteger.call(this, DISALLOW_SIGN); + + b = '-' + this.consume(Number); + break; + + // <dashndashdigit-ident> + default: + expectCharCode.call(this, 2, HYPHENMINUS); + checkInteger.call(this, 3, DISALLOW_SIGN); + this.next(); + + b = this.substrToCursor(start + 2); + } + } + + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + // '+'? n- <signless-integer> + // '+'? <ndashdigit-ident> + else if (this.tokenType === Ident || (this.isDelim(PLUSSIGN) && this.lookupType(1) === Ident)) { + let sign = 0; + a = '1'; + + // just ignore a plus + if (this.isDelim(PLUSSIGN)) { + sign = 1; + this.next(); + } + + expectCharCode.call(this, 0, N); + + switch (this.tokenEnd - this.tokenStart) { + // '+'? n + // '+'? n <signed-integer> + // '+'? n ['+' | '-'] <signless-integer> + case 1: + this.next(); + b = consumeB.call(this); + break; + + // '+'? n- <signless-integer> + case 2: + expectCharCode.call(this, 1, HYPHENMINUS); + + this.next(); + this.skipSC(); + + checkTokenIsInteger.call(this, DISALLOW_SIGN); + + b = '-' + this.consume(Number); + break; + + // '+'? <ndashdigit-ident> + default: + expectCharCode.call(this, 1, HYPHENMINUS); + checkInteger.call(this, 2, DISALLOW_SIGN); + this.next(); + + b = this.substrToCursor(start + sign + 1); + } + } + + // <ndashdigit-dimension> + // <ndash-dimension> <signless-integer> + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + else if (this.tokenType === Dimension) { + const code = this.charCodeAt(this.tokenStart); + const sign = code === PLUSSIGN || code === HYPHENMINUS; + let i = this.tokenStart + sign; + + for (; i < this.tokenEnd; i++) { + if (!isDigit(this.charCodeAt(i))) { + break; + } + } + + if (i === this.tokenStart + sign) { + this.error('Integer is expected', this.tokenStart + sign); + } + + expectCharCode.call(this, i - this.tokenStart, N); + a = this.substring(start, i); + + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + if (i + 1 === this.tokenEnd) { + this.next(); + b = consumeB.call(this); + } else { + expectCharCode.call(this, i - this.tokenStart + 1, HYPHENMINUS); + + // <ndash-dimension> <signless-integer> + if (i + 2 === this.tokenEnd) { + this.next(); + this.skipSC(); + checkTokenIsInteger.call(this, DISALLOW_SIGN); + b = '-' + this.consume(Number); + } + // <ndashdigit-dimension> + else { + checkInteger.call(this, i - this.tokenStart + 2, DISALLOW_SIGN); + this.next(); + b = this.substrToCursor(i + 1); + } + } + } else { + this.error(); + } + + if (a !== null && a.charCodeAt(0) === PLUSSIGN) { + a = a.substr(1); + } + + if (b !== null && b.charCodeAt(0) === PLUSSIGN) { + b = b.substr(1); + } + + return { + type: 'AnPlusB', + loc: this.getLocation(start, this.tokenStart), + a, + b + }; +} + +export function generate(node) { + if (node.a) { + const a = + node.a === '+1' && 'n' || + node.a === '1' && 'n' || + node.a === '-1' && '-n' || + node.a + 'n'; + + if (node.b) { + const b = node.b[0] === '-' || node.b[0] === '+' + ? node.b + : '+' + node.b; + this.tokenize(a + b); + } else { + this.tokenize(a); + } + } else { + this.tokenize(node.b); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Atrule.js b/vanilla/node_modules/css-tree/lib/syntax/node/Atrule.js new file mode 100644 index 0000000..99d1284 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Atrule.js @@ -0,0 +1,100 @@ +import { + AtKeyword, + Semicolon, + LeftCurlyBracket, + RightCurlyBracket +} from '../../tokenizer/index.js'; + +function consumeRaw() { + return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon, true); +} + +function isDeclarationBlockAtrule() { + for (let offset = 1, type; type = this.lookupType(offset); offset++) { + if (type === RightCurlyBracket) { + return true; + } + + if (type === LeftCurlyBracket || + type === AtKeyword) { + return false; + } + } + + return false; +} + + +export const name = 'Atrule'; +export const walkContext = 'atrule'; +export const structure = { + name: String, + prelude: ['AtrulePrelude', 'Raw', null], + block: ['Block', null] +}; + +export function parse(isDeclaration = false) { + const start = this.tokenStart; + let name; + let nameLowerCase; + let prelude = null; + let block = null; + + this.eat(AtKeyword); + + name = this.substrToCursor(start + 1); + nameLowerCase = name.toLowerCase(); + this.skipSC(); + + // parse prelude + if (this.eof === false && + this.tokenType !== LeftCurlyBracket && + this.tokenType !== Semicolon) { + if (this.parseAtrulePrelude) { + prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name, isDeclaration), consumeRaw); + } else { + prelude = consumeRaw.call(this, this.tokenIndex); + } + + this.skipSC(); + } + + switch (this.tokenType) { + case Semicolon: + this.next(); + break; + + case LeftCurlyBracket: + if (hasOwnProperty.call(this.atrule, nameLowerCase) && + typeof this.atrule[nameLowerCase].block === 'function') { + block = this.atrule[nameLowerCase].block.call(this, isDeclaration); + } else { + // TODO: should consume block content as Raw? + block = this.Block(isDeclarationBlockAtrule.call(this)); + } + + break; + } + + return { + type: 'Atrule', + loc: this.getLocation(start, this.tokenStart), + name, + prelude, + block + }; +} + +export function generate(node) { + this.token(AtKeyword, '@' + node.name); + + if (node.prelude !== null) { + this.node(node.prelude); + } + + if (node.block) { + this.node(node.block); + } else { + this.token(Semicolon, ';'); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/AtrulePrelude.js b/vanilla/node_modules/css-tree/lib/syntax/node/AtrulePrelude.js new file mode 100644 index 0000000..5b5645a --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/AtrulePrelude.js @@ -0,0 +1,47 @@ +import { + Semicolon, + LeftCurlyBracket +} from '../../tokenizer/index.js'; + +export const name = 'AtrulePrelude'; +export const walkContext = 'atrulePrelude'; +export const structure = { + children: [[]] +}; + +export function parse(name) { + let children = null; + + if (name !== null) { + name = name.toLowerCase(); + } + + this.skipSC(); + + if (hasOwnProperty.call(this.atrule, name) && + typeof this.atrule[name].prelude === 'function') { + // custom consumer + children = this.atrule[name].prelude.call(this); + } else { + // default consumer + children = this.readSequence(this.scope.AtrulePrelude); + } + + this.skipSC(); + + if (this.eof !== true && + this.tokenType !== LeftCurlyBracket && + this.tokenType !== Semicolon) { + this.error('Semicolon or block is expected'); + } + + return { + type: 'AtrulePrelude', + loc: this.getLocationFromList(children), + children + }; +} + +export function generate(node) { + this.children(node); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/AttributeSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/AttributeSelector.js new file mode 100644 index 0000000..8578dad --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/AttributeSelector.js @@ -0,0 +1,147 @@ +import { + Ident, + String as StringToken, + Delim, + LeftSquareBracket, + RightSquareBracket +} from '../../tokenizer/index.js'; + +const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=) +const CIRCUMFLEXACCENT = 0x005E; // U+005E (^) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) +const TILDE = 0x007E; // U+007E TILDE (~) + +function getAttributeName() { + if (this.eof) { + this.error('Unexpected end of input'); + } + + const start = this.tokenStart; + let expectIdent = false; + + if (this.isDelim(ASTERISK)) { + expectIdent = true; + this.next(); + } else if (!this.isDelim(VERTICALLINE)) { + this.eat(Ident); + } + + if (this.isDelim(VERTICALLINE)) { + if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN) { + this.next(); + this.eat(Ident); + } else if (expectIdent) { + this.error('Identifier is expected', this.tokenEnd); + } + } else if (expectIdent) { + this.error('Vertical line is expected'); + } + + return { + type: 'Identifier', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start) + }; +} + +function getOperator() { + const start = this.tokenStart; + const code = this.charCodeAt(start); + + if (code !== EQUALSSIGN && // = + code !== TILDE && // ~= + code !== CIRCUMFLEXACCENT && // ^= + code !== DOLLARSIGN && // $= + code !== ASTERISK && // *= + code !== VERTICALLINE // |= + ) { + this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected'); + } + + this.next(); + + if (code !== EQUALSSIGN) { + if (!this.isDelim(EQUALSSIGN)) { + this.error('Equal sign is expected'); + } + + this.next(); + } + + return this.substrToCursor(start); +} + +// '[' <wq-name> ']' +// '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']' +export const name = 'AttributeSelector'; +export const structure = { + name: 'Identifier', + matcher: [String, null], + value: ['String', 'Identifier', null], + flags: [String, null] +}; + +export function parse() { + const start = this.tokenStart; + let name; + let matcher = null; + let value = null; + let flags = null; + + this.eat(LeftSquareBracket); + this.skipSC(); + + name = getAttributeName.call(this); + this.skipSC(); + + if (this.tokenType !== RightSquareBracket) { + // avoid case `[name i]` + if (this.tokenType !== Ident) { + matcher = getOperator.call(this); + + this.skipSC(); + + value = this.tokenType === StringToken + ? this.String() + : this.Identifier(); + + this.skipSC(); + } + + // attribute flags + if (this.tokenType === Ident) { + flags = this.consume(Ident); + + this.skipSC(); + } + } + + this.eat(RightSquareBracket); + + return { + type: 'AttributeSelector', + loc: this.getLocation(start, this.tokenStart), + name, + matcher, + value, + flags + }; +} + +export function generate(node) { + this.token(Delim, '['); + this.node(node.name); + + if (node.matcher !== null) { + this.tokenize(node.matcher); + this.node(node.value); + } + + if (node.flags !== null) { + this.token(Ident, node.flags); + } + + this.token(Delim, ']'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Block.js b/vanilla/node_modules/css-tree/lib/syntax/node/Block.js new file mode 100644 index 0000000..10bf6fc --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Block.js @@ -0,0 +1,95 @@ +import { + WhiteSpace, + Comment, + Semicolon, + AtKeyword, + LeftCurlyBracket, + RightCurlyBracket +} from '../../tokenizer/index.js'; + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +function consumeRaw() { + return this.Raw(null, true); +} +function consumeRule() { + return this.parseWithFallback(this.Rule, consumeRaw); +} +function consumeRawDeclaration() { + return this.Raw(this.consumeUntilSemicolonIncluded, true); +} +function consumeDeclaration() { + if (this.tokenType === Semicolon) { + return consumeRawDeclaration.call(this, this.tokenIndex); + } + + const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration); + + if (this.tokenType === Semicolon) { + this.next(); + } + + return node; +} + +export const name = 'Block'; +export const walkContext = 'block'; +export const structure = { + children: [[ + 'Atrule', + 'Rule', + 'Declaration' + ]] +}; + +export function parse(isStyleBlock) { + const consumer = isStyleBlock ? consumeDeclaration : consumeRule; + const start = this.tokenStart; + let children = this.createList(); + + this.eat(LeftCurlyBracket); + + scan: + while (!this.eof) { + switch (this.tokenType) { + case RightCurlyBracket: + break scan; + + case WhiteSpace: + case Comment: + this.next(); + break; + + case AtKeyword: + children.push(this.parseWithFallback(this.Atrule.bind(this, isStyleBlock), consumeRaw)); + break; + + default: + if (isStyleBlock && this.isDelim(AMPERSAND)) { + children.push(consumeRule.call(this)); + } else { + children.push(consumer.call(this)); + } + } + } + + if (!this.eof) { + this.eat(RightCurlyBracket); + } + + return { + type: 'Block', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +export function generate(node) { + this.token(LeftCurlyBracket, '{'); + this.children(node, prev => { + if (prev.type === 'Declaration') { + this.token(Semicolon, ';'); + } + }); + this.token(RightCurlyBracket, '}'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Brackets.js b/vanilla/node_modules/css-tree/lib/syntax/node/Brackets.js new file mode 100644 index 0000000..1d97a4c --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Brackets.js @@ -0,0 +1,35 @@ +import { + Delim, + LeftSquareBracket, + RightSquareBracket +} from '../../tokenizer/index.js'; + +export const name = 'Brackets'; +export const structure = { + children: [[]] +}; + +export function parse(readSequence, recognizer) { + const start = this.tokenStart; + let children = null; + + this.eat(LeftSquareBracket); + + children = readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(RightSquareBracket); + } + + return { + type: 'Brackets', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +export function generate(node) { + this.token(Delim, '['); + this.children(node); + this.token(Delim, ']'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/CDC.js b/vanilla/node_modules/css-tree/lib/syntax/node/CDC.js new file mode 100644 index 0000000..efed4a6 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/CDC.js @@ -0,0 +1,19 @@ +import { CDC } from '../../tokenizer/index.js'; + +export const name = 'CDC'; +export const structure = []; + +export function parse() { + const start = this.tokenStart; + + this.eat(CDC); // --> + + return { + type: 'CDC', + loc: this.getLocation(start, this.tokenStart) + }; +} + +export function generate() { + this.token(CDC, '-->'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/CDO.js b/vanilla/node_modules/css-tree/lib/syntax/node/CDO.js new file mode 100644 index 0000000..3a9de89 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/CDO.js @@ -0,0 +1,19 @@ +import { CDO } from '../../tokenizer/index.js'; + +export const name = 'CDO'; +export const structure = []; + +export function parse() { + const start = this.tokenStart; + + this.eat(CDO); // <!-- + + return { + type: 'CDO', + loc: this.getLocation(start, this.tokenStart) + }; +} + +export function generate() { + this.token(CDO, '<!--'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/ClassSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/ClassSelector.js new file mode 100644 index 0000000..febb0d9 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/ClassSelector.js @@ -0,0 +1,24 @@ +import { Delim, Ident } from '../../tokenizer/index.js'; + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +// '.' ident +export const name = 'ClassSelector'; +export const structure = { + name: String +}; + +export function parse() { + this.eatDelim(FULLSTOP); + + return { + type: 'ClassSelector', + loc: this.getLocation(this.tokenStart - 1, this.tokenEnd), + name: this.consume(Ident) + }; +} + +export function generate(node) { + this.token(Delim, '.'); + this.token(Ident, node.name); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Combinator.js b/vanilla/node_modules/css-tree/lib/syntax/node/Combinator.js new file mode 100644 index 0000000..2e5bb1f --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Combinator.js @@ -0,0 +1,54 @@ +import { WhiteSpace, Delim } from '../../tokenizer/index.js'; + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) +const TILDE = 0x007E; // U+007E TILDE (~) + +export const name = 'Combinator'; +export const structure = { + name: String +}; + +// + | > | ~ | /deep/ +export function parse() { + const start = this.tokenStart; + let name; + + switch (this.tokenType) { + case WhiteSpace: + name = ' '; + break; + + case Delim: + switch (this.charCodeAt(this.tokenStart)) { + case GREATERTHANSIGN: + case PLUSSIGN: + case TILDE: + this.next(); + break; + + case SOLIDUS: + this.next(); + this.eatIdent('deep'); + this.eatDelim(SOLIDUS); + break; + + default: + this.error('Combinator is expected'); + } + + name = this.substrToCursor(start); + break; + } + + return { + type: 'Combinator', + loc: this.getLocation(start, this.tokenStart), + name + }; +} + +export function generate(node) { + this.tokenize(node.name); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Comment.js b/vanilla/node_modules/css-tree/lib/syntax/node/Comment.js new file mode 100644 index 0000000..8a9d291 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Comment.js @@ -0,0 +1,33 @@ +import { Comment } from '../../tokenizer/index.js'; + +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + + +export const name = 'Comment'; +export const structure = { + value: String +}; + +export function parse() { + const start = this.tokenStart; + let end = this.tokenEnd; + + this.eat(Comment); + + if ((end - start + 2) >= 2 && + this.charCodeAt(end - 2) === ASTERISK && + this.charCodeAt(end - 1) === SOLIDUS) { + end -= 2; + } + + return { + type: 'Comment', + loc: this.getLocation(start, this.tokenStart), + value: this.substring(start + 2, end) + }; +} + +export function generate(node) { + this.token(Comment, '/*' + node.value + '*/'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Condition.js b/vanilla/node_modules/css-tree/lib/syntax/node/Condition.js new file mode 100644 index 0000000..e4b1e0d --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Condition.js @@ -0,0 +1,123 @@ +import { + WhiteSpace, + Comment, + Ident, + LeftParenthesis, + RightParenthesis, + Function as FunctionToken, + Colon, + EOF +} from '../../tokenizer/index.js'; + +const likelyFeatureToken = new Set([Colon, RightParenthesis, EOF]); + +export const name = 'Condition'; +export const structure = { + kind: String, + children: [[ + 'Identifier', + 'Feature', + 'FeatureFunction', + 'FeatureRange', + 'SupportsDeclaration' + ]] +}; + +function featureOrRange(kind) { + if (this.lookupTypeNonSC(1) === Ident && + likelyFeatureToken.has(this.lookupTypeNonSC(2))) { + return this.Feature(kind); + } + + return this.FeatureRange(kind); +} + +const parentheses = { + media: featureOrRange, + container: featureOrRange, + supports() { + return this.SupportsDeclaration(); + } +}; + +export function parse(kind = 'media') { + const children = this.createList(); + + scan: while (!this.eof) { + switch (this.tokenType) { + case Comment: + case WhiteSpace: + this.next(); + continue; + + case Ident: + children.push(this.Identifier()); + break; + + case LeftParenthesis: { + let term = this.parseWithFallback( + () => parentheses[kind].call(this, kind), + () => null + ); + + if (!term) { + term = this.parseWithFallback( + () => { + this.eat(LeftParenthesis); + const res = this.Condition(kind); + this.eat(RightParenthesis); + return res; + }, + () => { + return this.GeneralEnclosed(kind); + } + ); + } + + children.push(term); + break; + } + + case FunctionToken: { + let term = this.parseWithFallback( + () => this.FeatureFunction(kind), + () => null + ); + + if (!term) { + term = this.GeneralEnclosed(kind); + } + + children.push(term); + break; + } + + default: + break scan; + } + } + + if (children.isEmpty) { + this.error('Condition is expected'); + } + + return { + type: 'Condition', + loc: this.getLocationFromList(children), + kind, + children + }; +} + +export function generate(node) { + node.children.forEach(child => { + if (child.type === 'Condition') { + this.token(LeftParenthesis, '('); + this.node(child); + this.token(RightParenthesis, ')'); + } else { + this.node(child); + } + }); +} + diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Declaration.js b/vanilla/node_modules/css-tree/lib/syntax/node/Declaration.js new file mode 100644 index 0000000..af3ea60 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Declaration.js @@ -0,0 +1,165 @@ +import { isCustomProperty } from '../../utils/names.js'; +import { + Ident, + Hash, + Colon, + Semicolon, + Delim, + WhiteSpace +} from '../../tokenizer/index.js'; + +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +function consumeValueRaw() { + return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, true); +} + +function consumeCustomPropertyRaw() { + return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false); +} + +function consumeValue() { + const startValueToken = this.tokenIndex; + const value = this.Value(); + + if (value.type !== 'Raw' && + this.eof === false && + this.tokenType !== Semicolon && + this.isDelim(EXCLAMATIONMARK) === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; +} + +export const name = 'Declaration'; +export const walkContext = 'declaration'; +export const structure = { + important: [Boolean, String], + property: String, + value: ['Value', 'Raw'] +}; + +export function parse() { + const start = this.tokenStart; + const startToken = this.tokenIndex; + const property = readProperty.call(this); + const customProperty = isCustomProperty(property); + const parseValue = customProperty ? this.parseCustomProperty : this.parseValue; + const consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw; + let important = false; + let value; + + this.skipSC(); + this.eat(Colon); + + const valueStart = this.tokenIndex; + + if (!customProperty) { + this.skipSC(); + } + + if (parseValue) { + value = this.parseWithFallback(consumeValue, consumeRaw); + } else { + value = consumeRaw.call(this, this.tokenIndex); + } + + if (customProperty && value.type === 'Value' && value.children.isEmpty) { + for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) { + if (this.lookupType(offset) === WhiteSpace) { + value.children.appendData({ + type: 'WhiteSpace', + loc: null, + value: ' ' + }); + break; + } + } + } + + if (this.isDelim(EXCLAMATIONMARK)) { + important = getImportant.call(this); + this.skipSC(); + } + + // Do not include semicolon to range per spec + // https://drafts.csswg.org/css-syntax/#declaration-diagram + + if (this.eof === false && + this.tokenType !== Semicolon && + this.isBalanceEdge(startToken) === false) { + this.error(); + } + + return { + type: 'Declaration', + loc: this.getLocation(start, this.tokenStart), + important, + property, + value + }; +} + +export function generate(node) { + this.token(Ident, node.property); + this.token(Colon, ':'); + this.node(node.value); + + if (node.important) { + this.token(Delim, '!'); + this.token(Ident, node.important === true ? 'important' : node.important); + } +} + +function readProperty() { + const start = this.tokenStart; + + // hacks + if (this.tokenType === Delim) { + switch (this.charCodeAt(this.tokenStart)) { + case ASTERISK: + case DOLLARSIGN: + case PLUSSIGN: + case NUMBERSIGN: + case AMPERSAND: + this.next(); + break; + + // TODO: not sure we should support this hack + case SOLIDUS: + this.next(); + if (this.isDelim(SOLIDUS)) { + this.next(); + } + break; + } + } + + if (this.tokenType === Hash) { + this.eat(Hash); + } else { + this.eat(Ident); + } + + return this.substrToCursor(start); +} + +// ! ws* important +function getImportant() { + this.eat(Delim); + this.skipSC(); + + const important = this.consume(Ident); + + // store original value in case it differ from `important` + // for better original source restoring and hacks like `!ie` support + return important === 'important' ? true : important; +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/DeclarationList.js b/vanilla/node_modules/css-tree/lib/syntax/node/DeclarationList.js new file mode 100644 index 0000000..2b40c99 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/DeclarationList.js @@ -0,0 +1,62 @@ +import { + WhiteSpace, + Comment, + Semicolon, + AtKeyword +} from '../../tokenizer/index.js'; + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +function consumeRaw() { + return this.Raw(this.consumeUntilSemicolonIncluded, true); +} + +export const name = 'DeclarationList'; +export const structure = { + children: [[ + 'Declaration', + 'Atrule', + 'Rule' + ]] +}; + +export function parse() { + const children = this.createList(); + + scan: + while (!this.eof) { + switch (this.tokenType) { + case WhiteSpace: + case Comment: + case Semicolon: + this.next(); + break; + + case AtKeyword: + children.push(this.parseWithFallback(this.Atrule.bind(this, true), consumeRaw)); + break; + + default: + if (this.isDelim(AMPERSAND)) { + children.push(this.parseWithFallback(this.Rule, consumeRaw)); + } else { + children.push(this.parseWithFallback(this.Declaration, consumeRaw)); + } + } + } + + return { + type: 'DeclarationList', + loc: this.getLocationFromList(children), + children + }; +} + +export function generate(node) { + this.children(node, prev => { + if (prev.type === 'Declaration') { + this.token(Semicolon, ';'); + } + }); +} + diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Dimension.js b/vanilla/node_modules/css-tree/lib/syntax/node/Dimension.js new file mode 100644 index 0000000..4b9bffc --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Dimension.js @@ -0,0 +1,23 @@ +import { Dimension } from '../../tokenizer/index.js'; + +export const name = 'Dimension'; +export const structure = { + value: String, + unit: String +}; + +export function parse() { + const start = this.tokenStart; + const value = this.consumeNumber(Dimension); + + return { + type: 'Dimension', + loc: this.getLocation(start, this.tokenStart), + value, + unit: this.substring(start + value.length, this.tokenStart) + }; +} + +export function generate(node) { + this.token(Dimension, node.value + node.unit); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Feature.js b/vanilla/node_modules/css-tree/lib/syntax/node/Feature.js new file mode 100644 index 0000000..2f2dc3d --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Feature.js @@ -0,0 +1,103 @@ +import { + Ident, + Number, + Dimension, + Function as FunctionToken, + LeftParenthesis, + RightParenthesis, + Colon, + Delim +} from '../../tokenizer/index.js'; + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +export const name = 'Feature'; +export const structure = { + kind: String, + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null] +}; + +export function parse(kind) { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(LeftParenthesis); + this.skipSC(); + + name = this.consume(Ident); + this.skipSC(); + + if (this.tokenType !== RightParenthesis) { + this.eat(Colon); + this.skipSC(); + + switch (this.tokenType) { + case Number: + if (this.lookupNonWSType(1) === Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case Dimension: + value = this.Dimension(); + break; + + case Ident: + value = this.Identifier(); + break; + + case FunctionToken: + value = this.parseWithFallback( + () => { + const res = this.Function(this.readSequence, this.scope.Value); + + this.skipSC(); + + if (this.isDelim(SOLIDUS)) { + this.error(); + } + + return res; + }, + () => { + return this.Ratio(); + } + ); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + if (!this.eof) { + this.eat(RightParenthesis); + } + + return { + type: 'Feature', + loc: this.getLocation(start, this.tokenStart), + kind, + name, + value + }; +} + +export function generate(node) { + this.token(LeftParenthesis, '('); + this.token(Ident, node.name); + + if (node.value !== null) { + this.token(Colon, ':'); + this.node(node.value); + } + + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/FeatureFunction.js b/vanilla/node_modules/css-tree/lib/syntax/node/FeatureFunction.js new file mode 100644 index 0000000..5869479 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/FeatureFunction.js @@ -0,0 +1,63 @@ +import { + Function as FunctionToken, + RightParenthesis +} from '../../tokenizer/index.js'; + +export const name = 'FeatureFunction'; +export const structure = { + kind: String, + feature: String, + value: ['Declaration', 'Selector'] +}; + +function getFeatureParser(kind, name) { + const featuresOfKind = this.features[kind] || {}; + const parser = featuresOfKind[name]; + + if (typeof parser !== 'function') { + this.error(`Unknown feature ${name}()`); + } + + return parser; +} + +export function parse(kind = 'unknown') { + const start = this.tokenStart; + const functionName = this.consumeFunctionName(); + const valueParser = getFeatureParser.call(this, kind, functionName.toLowerCase()); + + this.skipSC(); + + const value = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const value = valueParser.call(this); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; + }, + () => this.Raw(null, false) + ); + + if (!this.eof) { + this.eat(RightParenthesis); + } + + return { + type: 'FeatureFunction', + loc: this.getLocation(start, this.tokenStart), + kind, + feature: functionName, + value + }; +} + +export function generate(node) { + this.token(FunctionToken, node.feature + '('); + this.node(node.value); + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/FeatureRange.js b/vanilla/node_modules/css-tree/lib/syntax/node/FeatureRange.js new file mode 100644 index 0000000..a83e479 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/FeatureRange.js @@ -0,0 +1,133 @@ +import { + Ident, + Number, + Dimension, + Function as FunctionToken, + LeftParenthesis, + RightParenthesis +} from '../../tokenizer/index.js'; + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const LESSTHANSIGN = 0x003C; // U+003C LESS-THAN SIGN (<) +const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) + +export const name = 'FeatureRange'; +export const structure = { + kind: String, + left: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'], + leftComparison: String, + middle: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'], + rightComparison: [String, null], + right: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null] +}; + +function readTerm() { + this.skipSC(); + + switch (this.tokenType) { + case Number: + if (this.isDelim(SOLIDUS, this.lookupOffsetNonSC(1))) { + return this.Ratio(); + } else { + return this.Number(); + } + + case Dimension: + return this.Dimension(); + + case Ident: + return this.Identifier(); + + case FunctionToken: + return this.parseWithFallback( + () => { + const res = this.Function(this.readSequence, this.scope.Value); + + this.skipSC(); + + if (this.isDelim(SOLIDUS)) { + this.error(); + } + + return res; + }, + () => { + return this.Ratio(); + } + ); + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } +} + +function readComparison(expectColon) { + this.skipSC(); + + if (this.isDelim(LESSTHANSIGN) || + this.isDelim(GREATERTHANSIGN)) { + const value = this.source[this.tokenStart]; + + this.next(); + + if (this.isDelim(EQUALSSIGN)) { + this.next(); + return value + '='; + } + + return value; + } + + if (this.isDelim(EQUALSSIGN)) { + return '='; + } + + this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`); +} + +export function parse(kind = 'unknown') { + const start = this.tokenStart; + + this.skipSC(); + this.eat(LeftParenthesis); + + const left = readTerm.call(this); + const leftComparison = readComparison.call(this, left.type === 'Identifier'); + const middle = readTerm.call(this); + let rightComparison = null; + let right = null; + + if (this.lookupNonWSType(0) !== RightParenthesis) { + rightComparison = readComparison.call(this); + right = readTerm.call(this); + } + + this.skipSC(); + this.eat(RightParenthesis); + + return { + type: 'FeatureRange', + loc: this.getLocation(start, this.tokenStart), + kind, + left, + leftComparison, + middle, + rightComparison, + right + }; +} + +export function generate(node) { + this.token(LeftParenthesis, '('); + this.node(node.left); + this.tokenize(node.leftComparison); + this.node(node.middle); + + if (node.right) { + this.tokenize(node.rightComparison); + this.node(node.right); + } + + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Function.js b/vanilla/node_modules/css-tree/lib/syntax/node/Function.js new file mode 100644 index 0000000..1fdc414 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Function.js @@ -0,0 +1,41 @@ +import { + Function as FunctionToken, + RightParenthesis +} from '../../tokenizer/index.js'; + + +export const name = 'Function'; +export const walkContext = 'function'; +export const structure = { + name: String, + children: [[]] +}; + +// <function-token> <sequence> ) +export function parse(readSequence, recognizer) { + const start = this.tokenStart; + const name = this.consumeFunctionName(); + const nameLowerCase = name.toLowerCase(); + let children; + + children = recognizer.hasOwnProperty(nameLowerCase) + ? recognizer[nameLowerCase].call(this, recognizer) + : readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(RightParenthesis); + } + + return { + type: 'Function', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +export function generate(node) { + this.token(FunctionToken, node.name + '('); + this.children(node); + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/GeneralEnclosed.js b/vanilla/node_modules/css-tree/lib/syntax/node/GeneralEnclosed.js new file mode 100644 index 0000000..8ac8cae --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/GeneralEnclosed.js @@ -0,0 +1,66 @@ +import { + Function as FunctionToken, + LeftParenthesis, + RightParenthesis +} from '../../tokenizer/index.js'; + + +export const name = 'GeneralEnclosed'; +export const structure = { + kind: String, + function: [String, null], + children: [[]] +}; + +// <function-token> <any-value> ) +// ( <any-value> ) +export function parse(kind) { + const start = this.tokenStart; + let functionName = null; + + if (this.tokenType === FunctionToken) { + functionName = this.consumeFunctionName(); + } else { + this.eat(LeftParenthesis); + } + + const children = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const children = this.readSequence(this.scope.Value); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return children; + }, + () => this.createSingleNodeList( + this.Raw(null, false) + ) + ); + + if (!this.eof) { + this.eat(RightParenthesis); + } + + return { + type: 'GeneralEnclosed', + loc: this.getLocation(start, this.tokenStart), + kind, + function: functionName, + children + }; +} + +export function generate(node) { + if (node.function) { + this.token(FunctionToken, node.function + '('); + } else { + this.token(LeftParenthesis, '('); + } + + this.children(node); + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Hash.js b/vanilla/node_modules/css-tree/lib/syntax/node/Hash.js new file mode 100644 index 0000000..b752752 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Hash.js @@ -0,0 +1,23 @@ +import { Hash } from '../../tokenizer/index.js'; + +// '#' ident +export const xxx = 'XXX'; +export const name = 'Hash'; +export const structure = { + value: String +}; +export function parse() { + const start = this.tokenStart; + + this.eat(Hash); + + return { + type: 'Hash', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start + 1) + }; +} +export function generate(node) { + this.token(Hash, '#' + node.value); +} + diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/IdSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/IdSelector.js new file mode 100644 index 0000000..c85c1b2 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/IdSelector.js @@ -0,0 +1,26 @@ +import { Hash, Delim } from '../../tokenizer/index.js'; + +export const name = 'IdSelector'; +export const structure = { + name: String +}; + +export function parse() { + const start = this.tokenStart; + + // TODO: check value is an ident + this.eat(Hash); + + return { + type: 'IdSelector', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start + 1) + }; +} + +export function generate(node) { + // Using Delim instead of Hash is a hack to avoid for a whitespace between ident and id-selector + // in safe mode (e.g. "a#id"), because IE11 doesn't allow a sequence <ident-token> <hash-token> + // without a whitespace in values (e.g. "1px solid#000") + this.token(Delim, '#' + node.name); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Identifier.js b/vanilla/node_modules/css-tree/lib/syntax/node/Identifier.js new file mode 100644 index 0000000..067c2d0 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Identifier.js @@ -0,0 +1,18 @@ +import { Ident } from '../../tokenizer/index.js'; + +export const name = 'Identifier'; +export const structure = { + name: String +}; + +export function parse() { + return { + type: 'Identifier', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + name: this.consume(Ident) + }; +} + +export function generate(node) { + this.token(Ident, node.name); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Layer.js b/vanilla/node_modules/css-tree/lib/syntax/node/Layer.js new file mode 100644 index 0000000..d170dcb --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Layer.js @@ -0,0 +1,28 @@ +import { Ident, Delim } from '../../tokenizer/index.js'; + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +export const name = 'Layer'; +export const structure = { + name: String +}; + +export function parse() { + let tokenStart = this.tokenStart; + let name = this.consume(Ident); + + while (this.isDelim(FULLSTOP)) { + this.eat(Delim); + name += '.' + this.consume(Ident); + } + + return { + type: 'Layer', + loc: this.getLocation(tokenStart, this.tokenStart), + name + }; +} + +export function generate(node) { + this.tokenize(node.name); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/LayerList.js b/vanilla/node_modules/css-tree/lib/syntax/node/LayerList.js new file mode 100644 index 0000000..e8a05cd --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/LayerList.js @@ -0,0 +1,36 @@ +import { Comma } from '../../tokenizer/index.js'; + +export const name = 'LayerList'; +export const structure = { + children: [[ + 'Layer' + ]] +}; + +export function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.Layer()); + + if (this.lookupTypeNonSC(0) !== Comma) { + break; + } + + this.skipSC(); + this.next(); + this.skipSC(); + } + + return { + type: 'LayerList', + loc: this.getLocationFromList(children), + children + }; +} + +export function generate(node) { + this.children(node, () => this.token(Comma, ',')); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/MediaQuery.js b/vanilla/node_modules/css-tree/lib/syntax/node/MediaQuery.js new file mode 100644 index 0000000..f569c75 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/MediaQuery.js @@ -0,0 +1,102 @@ +import { + Comma, + EOF, + Ident, + LeftCurlyBracket, + LeftParenthesis, + Function as FunctionToken, + Semicolon +} from '../../tokenizer/index.js'; + +export const name = 'MediaQuery'; +export const structure = { + modifier: [String, null], + mediaType: [String, null], + condition: ['Condition', null] +}; + +export function parse() { + const start = this.tokenStart; + let modifier = null; + let mediaType = null; + let condition = null; + + this.skipSC(); + + if (this.tokenType === Ident && this.lookupTypeNonSC(1) !== LeftParenthesis) { + // [ not | only ]? <media-type> + const ident = this.consume(Ident); + const identLowerCase = ident.toLowerCase(); + + if (identLowerCase === 'not' || identLowerCase === 'only') { + this.skipSC(); + modifier = identLowerCase; + mediaType = this.consume(Ident); + } else { + mediaType = ident; + } + + switch (this.lookupTypeNonSC(0)) { + case Ident: { + // and <media-condition-without-or> + this.skipSC(); + this.eatIdent('and'); + condition = this.Condition('media'); + break; + } + + case LeftCurlyBracket: + case Semicolon: + case Comma: + case EOF: + break; + + default: + this.error('Identifier or parenthesis is expected'); + } + } else { + switch (this.tokenType) { + case Ident: + case LeftParenthesis: + case FunctionToken: { + // <media-condition> + condition = this.Condition('media'); + break; + } + + case LeftCurlyBracket: + case Semicolon: + case EOF: + break; + + default: + this.error('Identifier or parenthesis is expected'); + } + } + + return { + type: 'MediaQuery', + loc: this.getLocation(start, this.tokenStart), + modifier, + mediaType, + condition + }; +} + +export function generate(node) { + if (node.mediaType) { + if (node.modifier) { + this.token(Ident, node.modifier); + } + + this.token(Ident, node.mediaType); + + if (node.condition) { + this.token(Ident, 'and'); + this.node(node.condition); + } + } else if (node.condition) { + this.node(node.condition); + } +} + diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/MediaQueryList.js b/vanilla/node_modules/css-tree/lib/syntax/node/MediaQueryList.js new file mode 100644 index 0000000..1c16bcd --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/MediaQueryList.js @@ -0,0 +1,34 @@ +import { Comma } from '../../tokenizer/index.js'; + +export const name = 'MediaQueryList'; +export const structure = { + children: [[ + 'MediaQuery' + ]] +}; + +export function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.MediaQuery()); + + if (this.tokenType !== Comma) { + break; + } + + this.next(); + } + + return { + type: 'MediaQueryList', + loc: this.getLocationFromList(children), + children + }; +} + +export function generate(node) { + this.children(node, () => this.token(Comma, ',')); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/NestingSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/NestingSelector.js new file mode 100644 index 0000000..33c8b6a --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/NestingSelector.js @@ -0,0 +1,22 @@ +import { Delim } from '../../tokenizer/index.js'; + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +export const name = 'NestingSelector'; +export const structure = { +}; + +export function parse() { + const start = this.tokenStart; + + this.eatDelim(AMPERSAND); + + return { + type: 'NestingSelector', + loc: this.getLocation(start, this.tokenStart) + }; +} + +export function generate() { + this.token(Delim, '&'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Nth.js b/vanilla/node_modules/css-tree/lib/syntax/node/Nth.js new file mode 100644 index 0000000..bfd74a1 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Nth.js @@ -0,0 +1,47 @@ +import { Ident } from '../../tokenizer/index.js'; + +export const name = 'Nth'; +export const structure = { + nth: ['AnPlusB', 'Identifier'], + selector: ['SelectorList', null] +}; + +export function parse() { + this.skipSC(); + + const start = this.tokenStart; + let end = start; + let selector = null; + let nth; + + if (this.lookupValue(0, 'odd') || this.lookupValue(0, 'even')) { + nth = this.Identifier(); + } else { + nth = this.AnPlusB(); + } + + end = this.tokenStart; + this.skipSC(); + + if (this.lookupValue(0, 'of')) { + this.next(); + + selector = this.SelectorList(); + end = this.tokenStart; + } + + return { + type: 'Nth', + loc: this.getLocation(start, end), + nth, + selector + }; +} + +export function generate(node) { + this.node(node.nth); + if (node.selector !== null) { + this.token(Ident, 'of'); + this.node(node.selector); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Number.js b/vanilla/node_modules/css-tree/lib/syntax/node/Number.js new file mode 100644 index 0000000..a9d8f0a --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Number.js @@ -0,0 +1,18 @@ +import { Number as NumberToken } from '../../tokenizer/index.js'; + +export const name = 'Number'; +export const structure = { + value: String +}; + +export function parse() { + return { + type: 'Number', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: this.consume(NumberToken) + }; +} + +export function generate(node) { + this.token(NumberToken, node.value); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Operator.js b/vanilla/node_modules/css-tree/lib/syntax/node/Operator.js new file mode 100644 index 0000000..4f1238b --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Operator.js @@ -0,0 +1,21 @@ +// '/' | '*' | ',' | ':' | '+' | '-' +export const name = 'Operator'; +export const structure = { + value: String +}; + +export function parse() { + const start = this.tokenStart; + + this.next(); + + return { + type: 'Operator', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start) + }; +} + +export function generate(node) { + this.tokenize(node.value); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Parentheses.js b/vanilla/node_modules/css-tree/lib/syntax/node/Parentheses.js new file mode 100644 index 0000000..8c6cdb5 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Parentheses.js @@ -0,0 +1,34 @@ +import { + LeftParenthesis, + RightParenthesis +} from '../../tokenizer/index.js'; + +export const name = 'Parentheses'; +export const structure = { + children: [[]] +}; + +export function parse(readSequence, recognizer) { + const start = this.tokenStart; + let children = null; + + this.eat(LeftParenthesis); + + children = readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(RightParenthesis); + } + + return { + type: 'Parentheses', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +export function generate(node) { + this.token(LeftParenthesis, '('); + this.children(node); + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Percentage.js b/vanilla/node_modules/css-tree/lib/syntax/node/Percentage.js new file mode 100644 index 0000000..3c8b628 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Percentage.js @@ -0,0 +1,18 @@ +import { Percentage } from '../../tokenizer/index.js'; + +export const name = 'Percentage'; +export const structure = { + value: String +}; + +export function parse() { + return { + type: 'Percentage', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: this.consumeNumber(Percentage) + }; +} + +export function generate(node) { + this.token(Percentage, node.value + '%'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/PseudoClassSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/PseudoClassSelector.js new file mode 100644 index 0000000..584546c --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/PseudoClassSelector.js @@ -0,0 +1,65 @@ +import { + Ident, + Function as FunctionToken, + Colon, + RightParenthesis +} from '../../tokenizer/index.js'; + + +export const name = 'PseudoClassSelector'; +export const walkContext = 'function'; +export const structure = { + name: String, + children: [['Raw'], null] +}; + +// : [ <ident> | <function-token> <any-value>? ) ] +export function parse() { + const start = this.tokenStart; + let children = null; + let name; + let nameLowerCase; + + this.eat(Colon); + + if (this.tokenType === FunctionToken) { + name = this.consumeFunctionName(); + nameLowerCase = name.toLowerCase(); + + if (this.lookupNonWSType(0) == RightParenthesis) { + children = this.createList(); + } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) { + this.skipSC(); + children = this.pseudo[nameLowerCase].call(this); + this.skipSC(); + } else { + children = this.createList(); + children.push( + this.Raw(null, false) + ); + } + + this.eat(RightParenthesis); + } else { + name = this.consume(Ident); + } + + return { + type: 'PseudoClassSelector', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +export function generate(node) { + this.token(Colon, ':'); + + if (node.children === null) { + this.token(Ident, node.name); + } else { + this.token(FunctionToken, node.name + '('); + this.children(node); + this.token(RightParenthesis, ')'); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/PseudoElementSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/PseudoElementSelector.js new file mode 100644 index 0000000..b23b9a0 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/PseudoElementSelector.js @@ -0,0 +1,66 @@ +import { + Ident, + Function as FunctionToken, + Colon, + RightParenthesis +} from '../../tokenizer/index.js'; + +export const name = 'PseudoElementSelector'; +export const walkContext = 'function'; +export const structure = { + name: String, + children: [['Raw'], null] +}; + +// :: [ <ident> | <function-token> <any-value>? ) ] +export function parse() { + const start = this.tokenStart; + let children = null; + let name; + let nameLowerCase; + + this.eat(Colon); + this.eat(Colon); + + if (this.tokenType === FunctionToken) { + name = this.consumeFunctionName(); + nameLowerCase = name.toLowerCase(); + + if (this.lookupNonWSType(0) == RightParenthesis) { + children = this.createList(); + } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) { + this.skipSC(); + children = this.pseudo[nameLowerCase].call(this); + this.skipSC(); + } else { + children = this.createList(); + children.push( + this.Raw(null, false) + ); + } + + this.eat(RightParenthesis); + } else { + name = this.consume(Ident); + } + + return { + type: 'PseudoElementSelector', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +export function generate(node) { + this.token(Colon, ':'); + this.token(Colon, ':'); + + if (node.children === null) { + this.token(Ident, node.name); + } else { + this.token(FunctionToken, node.name + '('); + this.children(node); + this.token(RightParenthesis, ')'); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Ratio.js b/vanilla/node_modules/css-tree/lib/syntax/node/Ratio.js new file mode 100644 index 0000000..c26cf10 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Ratio.js @@ -0,0 +1,68 @@ +import { + Delim, + Number as NumberToken, + Function as FunctionToken +} from '../../tokenizer/index.js'; + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +// Media Queries Level 3 defines terms of <ratio> as a positive (not zero or negative) +// integers (see https://drafts.csswg.org/mediaqueries-3/#values) +// However, Media Queries Level 4 removes any definition of values +// (see https://drafts.csswg.org/mediaqueries-4/#values) and refers to +// CSS Values and Units for detail. In CSS Values and Units Level 4 a <ratio> +// definition was added (see https://drafts.csswg.org/css-values-4/#ratios) which +// defines ratio as "<number [0,∞]> [ / <number [0,∞]> ]?" and based on it +// any constrains on terms were removed. Parser also doesn't test numbers +// in any way to make possible for linting and fixing them by the tools using CSSTree. +// An additional syntax examination may be applied by a lexer. +function consumeTerm() { + this.skipSC(); + + switch (this.tokenType) { + case NumberToken: + return this.Number(); + + case FunctionToken: + return this.Function(this.readSequence, this.scope.Value); + + default: + this.error('Number of function is expected'); + } +} + +export const name = 'Ratio'; +export const structure = { + left: ['Number', 'Function'], + right: ['Number', 'Function', null] +}; + +// <number [0,∞]> [ / <number [0,∞]> ]? +export function parse() { + const start = this.tokenStart; + const left = consumeTerm.call(this); + let right = null; + + this.skipSC(); + if (this.isDelim(SOLIDUS)) { + this.eatDelim(SOLIDUS); + right = consumeTerm.call(this); + } + + return { + type: 'Ratio', + loc: this.getLocation(start, this.tokenStart), + left, + right + }; +} + +export function generate(node) { + this.node(node.left); + this.token(Delim, '/'); + if (node.right) { + this.node(node.right); + } else { + this.node(NumberToken, 1); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Raw.js b/vanilla/node_modules/css-tree/lib/syntax/node/Raw.js new file mode 100644 index 0000000..0c2ea69 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Raw.js @@ -0,0 +1,41 @@ +import { WhiteSpace } from '../../tokenizer/index.js'; + +function getOffsetExcludeWS() { + if (this.tokenIndex > 0) { + if (this.lookupType(-1) === WhiteSpace) { + return this.tokenIndex > 1 + ? this.getTokenStart(this.tokenIndex - 1) + : this.firstCharOffset; + } + } + + return this.tokenStart; +} + +export const name = 'Raw'; +export const structure = { + value: String +}; + +export function parse(consumeUntil, excludeWhiteSpace) { + const startOffset = this.getTokenStart(this.tokenIndex); + let endOffset; + + this.skipUntilBalanced(this.tokenIndex, consumeUntil || this.consumeUntilBalanceEnd); + + if (excludeWhiteSpace && this.tokenStart > startOffset) { + endOffset = getOffsetExcludeWS.call(this); + } else { + endOffset = this.tokenStart; + } + + return { + type: 'Raw', + loc: this.getLocation(startOffset, endOffset), + value: this.substring(startOffset, endOffset) + }; +} + +export function generate(node) { + this.tokenize(node.value); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Rule.js b/vanilla/node_modules/css-tree/lib/syntax/node/Rule.js new file mode 100644 index 0000000..89745cf --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Rule.js @@ -0,0 +1,51 @@ +import { LeftCurlyBracket } from '../../tokenizer/index.js'; + +function consumeRaw() { + return this.Raw(this.consumeUntilLeftCurlyBracket, true); +} + +function consumePrelude() { + const prelude = this.SelectorList(); + + if (prelude.type !== 'Raw' && + this.eof === false && + this.tokenType !== LeftCurlyBracket) { + this.error(); + } + + return prelude; +} + +export const name = 'Rule'; +export const walkContext = 'rule'; +export const structure = { + prelude: ['SelectorList', 'Raw'], + block: ['Block'] +}; + +export function parse() { + const startToken = this.tokenIndex; + const startOffset = this.tokenStart; + let prelude; + let block; + + if (this.parseRulePrelude) { + prelude = this.parseWithFallback(consumePrelude, consumeRaw); + } else { + prelude = consumeRaw.call(this, startToken); + } + + block = this.Block(true); + + return { + type: 'Rule', + loc: this.getLocation(startOffset, this.tokenStart), + prelude, + block + }; +} +export function generate(node) { + this.node(node.prelude); + this.node(node.block); +} + diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Scope.js b/vanilla/node_modules/css-tree/lib/syntax/node/Scope.js new file mode 100644 index 0000000..650b035 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Scope.js @@ -0,0 +1,66 @@ +import { + Ident, + LeftParenthesis, + RightParenthesis +} from '../../tokenizer/index.js'; + +export const name = 'Scope'; +export const structure = { + root: ['SelectorList', 'Raw', null], + limit: ['SelectorList', 'Raw', null] +}; + +export function parse() { + let root = null; + let limit = null; + + this.skipSC(); + + const startOffset = this.tokenStart; + if (this.tokenType === LeftParenthesis) { + this.next(); + this.skipSC(); + root = this.parseWithFallback( + this.SelectorList, + () => this.Raw(false, true) + ); + this.skipSC(); + this.eat(RightParenthesis); + } + + if (this.lookupNonWSType(0) === Ident) { + this.skipSC(); + this.eatIdent('to'); + this.skipSC(); + this.eat(LeftParenthesis); + this.skipSC(); + limit = this.parseWithFallback( + this.SelectorList, + () => this.Raw(false, true) + ); + this.skipSC(); + this.eat(RightParenthesis); + } + + return { + type: 'Scope', + loc: this.getLocation(startOffset, this.tokenStart), + root, + limit + }; +} + +export function generate(node) { + if (node.root) { + this.token(LeftParenthesis, '('); + this.node(node.root); + this.token(RightParenthesis, ')'); + } + + if (node.limit) { + this.token(Ident, 'to'); + this.token(LeftParenthesis, '('); + this.node(node.limit); + this.token(RightParenthesis, ')'); + } +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Selector.js b/vanilla/node_modules/css-tree/lib/syntax/node/Selector.js new file mode 100644 index 0000000..36028e0 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Selector.js @@ -0,0 +1,31 @@ +export const name = 'Selector'; +export const structure = { + children: [[ + 'TypeSelector', + 'IdSelector', + 'ClassSelector', + 'AttributeSelector', + 'PseudoClassSelector', + 'PseudoElementSelector', + 'Combinator' + ]] +}; + +export function parse() { + const children = this.readSequence(this.scope.Selector); + + // nothing were consumed + if (this.getFirstListNode(children) === null) { + this.error('Selector is expected'); + } + + return { + type: 'Selector', + loc: this.getLocationFromList(children), + children + }; +} + +export function generate(node) { + this.children(node); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/SelectorList.js b/vanilla/node_modules/css-tree/lib/syntax/node/SelectorList.js new file mode 100644 index 0000000..ebba3cd --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/SelectorList.js @@ -0,0 +1,35 @@ +import { Comma } from '../../tokenizer/index.js'; + +export const name = 'SelectorList'; +export const walkContext = 'selector'; +export const structure = { + children: [[ + 'Selector', + 'Raw' + ]] +}; + +export function parse() { + const children = this.createList(); + + while (!this.eof) { + children.push(this.Selector()); + + if (this.tokenType === Comma) { + this.next(); + continue; + } + + break; + } + + return { + type: 'SelectorList', + loc: this.getLocationFromList(children), + children + }; +} + +export function generate(node) { + this.children(node, () => this.token(Comma, ',')); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/String.js b/vanilla/node_modules/css-tree/lib/syntax/node/String.js new file mode 100644 index 0000000..95e1aaa --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/String.js @@ -0,0 +1,19 @@ +import { String as StringToken } from '../../tokenizer/index.js'; +import { decode, encode } from '../../utils/string.js'; + +export const name = 'String'; +export const structure = { + value: String +}; + +export function parse() { + return { + type: 'String', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: decode(this.consume(StringToken)) + }; +} + +export function generate(node) { + this.token(StringToken, encode(node.value)); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/StyleSheet.js b/vanilla/node_modules/css-tree/lib/syntax/node/StyleSheet.js new file mode 100644 index 0000000..3bc5347 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/StyleSheet.js @@ -0,0 +1,82 @@ +import { + WhiteSpace, + Comment, + AtKeyword, + CDO, + CDC +} from '../../tokenizer/index.js'; + +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) + +function consumeRaw() { + return this.Raw(null, false); +} + +export const name = 'StyleSheet'; +export const walkContext = 'stylesheet'; +export const structure = { + children: [[ + 'Comment', + 'CDO', + 'CDC', + 'Atrule', + 'Rule', + 'Raw' + ]] +}; + +export function parse() { + const start = this.tokenStart; + const children = this.createList(); + let child; + + scan: + while (!this.eof) { + switch (this.tokenType) { + case WhiteSpace: + this.next(); + continue; + + case Comment: + // ignore comments except exclamation comments (i.e. /*! .. */) on top level + if (this.charCodeAt(this.tokenStart + 2) !== EXCLAMATIONMARK) { + this.next(); + continue; + } + + child = this.Comment(); + break; + + case CDO: // <!-- + child = this.CDO(); + break; + + case CDC: // --> + child = this.CDC(); + break; + + // CSS Syntax Module Level 3 + // §2.2 Error handling + // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule. + case AtKeyword: + child = this.parseWithFallback(this.Atrule, consumeRaw); + break; + + // Anything else starts a qualified rule ... + default: + child = this.parseWithFallback(this.Rule, consumeRaw); + } + + children.push(child); + } + + return { + type: 'StyleSheet', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +export function generate(node) { + this.children(node); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/SupportsDeclaration.js b/vanilla/node_modules/css-tree/lib/syntax/node/SupportsDeclaration.js new file mode 100644 index 0000000..ee816e5 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/SupportsDeclaration.js @@ -0,0 +1,34 @@ +import { + LeftParenthesis, + RightParenthesis +} from '../../tokenizer/index.js'; + +export const name = 'SupportsDeclaration'; +export const structure = { + declaration: 'Declaration' +}; + +export function parse() { + const start = this.tokenStart; + + this.eat(LeftParenthesis); + this.skipSC(); + + const declaration = this.Declaration(); + + if (!this.eof) { + this.eat(RightParenthesis); + } + + return { + type: 'SupportsDeclaration', + loc: this.getLocation(start, this.tokenStart), + declaration + }; +} + +export function generate(node) { + this.token(LeftParenthesis, '('); + this.node(node.declaration); + this.token(RightParenthesis, ')'); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/TypeSelector.js b/vanilla/node_modules/css-tree/lib/syntax/node/TypeSelector.js new file mode 100644 index 0000000..272e195 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/TypeSelector.js @@ -0,0 +1,52 @@ +import { Ident } from '../../tokenizer/index.js'; + +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) + +function eatIdentifierOrAsterisk() { + if (this.tokenType !== Ident && + this.isDelim(ASTERISK) === false) { + this.error('Identifier or asterisk is expected'); + } + + this.next(); +} + +export const name = 'TypeSelector'; +export const structure = { + name: String +}; + +// ident +// ident|ident +// ident|* +// * +// *|ident +// *|* +// |ident +// |* +export function parse() { + const start = this.tokenStart; + + if (this.isDelim(VERTICALLINE)) { + this.next(); + eatIdentifierOrAsterisk.call(this); + } else { + eatIdentifierOrAsterisk.call(this); + + if (this.isDelim(VERTICALLINE)) { + this.next(); + eatIdentifierOrAsterisk.call(this); + } + } + + return { + type: 'TypeSelector', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start) + }; +} + +export function generate(node) { + this.tokenize(node.name); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/UnicodeRange.js b/vanilla/node_modules/css-tree/lib/syntax/node/UnicodeRange.js new file mode 100644 index 0000000..95ee8b9 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/UnicodeRange.js @@ -0,0 +1,156 @@ +import { + isHexDigit, + Ident, + Number, + Dimension +} from '../../tokenizer/index.js'; + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?) + +function eatHexSequence(offset, allowDash) { + let len = 0; + + for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) { + const code = this.charCodeAt(pos); + + if (code === HYPHENMINUS && allowDash && len !== 0) { + eatHexSequence.call(this, offset + len + 1, false); + return -1; + } + + if (!isHexDigit(code)) { + this.error( + allowDash && len !== 0 + ? 'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected' + : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'), + pos + ); + } + + if (++len > 6) { + this.error('Too many hex digits', pos); + }; + } + + this.next(); + return len; +} + +function eatQuestionMarkSequence(max) { + let count = 0; + + while (this.isDelim(QUESTIONMARK)) { + if (++count > max) { + this.error('Too many question marks'); + } + + this.next(); + } +} + +function startsWith(code) { + if (this.charCodeAt(this.tokenStart) !== code) { + this.error((code === PLUSSIGN ? 'Plus sign' : 'Hyphen minus') + ' is expected'); + } +} + +// https://drafts.csswg.org/css-syntax/#urange +// Informally, the <urange> production has three forms: +// U+0001 +// Defines a range consisting of a single code point, in this case the code point "1". +// U+0001-00ff +// Defines a range of codepoints between the first and the second value, in this case +// the range between "1" and "ff" (255 in decimal) inclusive. +// U+00?? +// Defines a range of codepoints where the "?" characters range over all hex digits, +// in this case defining the same as the value U+0000-00ff. +// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit). +// +// <urange> = +// u '+' <ident-token> '?'* | +// u <dimension-token> '?'* | +// u <number-token> '?'* | +// u <number-token> <dimension-token> | +// u <number-token> <number-token> | +// u '+' '?'+ +function scanUnicodeRange() { + let hexLength = 0; + + switch (this.tokenType) { + case Number: + // u <number-token> '?'* + // u <number-token> <dimension-token> + // u <number-token> <number-token> + hexLength = eatHexSequence.call(this, 1, true); + + if (this.isDelim(QUESTIONMARK)) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + break; + } + + if (this.tokenType === Dimension || + this.tokenType === Number) { + startsWith.call(this, HYPHENMINUS); + eatHexSequence.call(this, 1, false); + break; + } + + break; + + case Dimension: + // u <dimension-token> '?'* + hexLength = eatHexSequence.call(this, 1, true); + + if (hexLength > 0) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + } + + break; + + default: + // u '+' <ident-token> '?'* + // u '+' '?'+ + this.eatDelim(PLUSSIGN); + + if (this.tokenType === Ident) { + hexLength = eatHexSequence.call(this, 0, true); + if (hexLength > 0) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + } + break; + } + + if (this.isDelim(QUESTIONMARK)) { + this.next(); + eatQuestionMarkSequence.call(this, 5); + break; + } + + this.error('Hex digit or question mark is expected'); + } +} + +export const name = 'UnicodeRange'; +export const structure = { + value: String +}; + +export function parse() { + const start = this.tokenStart; + + // U or u + this.eatIdent('u'); + scanUnicodeRange.call(this); + + return { + type: 'UnicodeRange', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start) + }; +} + +export function generate(node) { + this.tokenize(node.value); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Url.js b/vanilla/node_modules/css-tree/lib/syntax/node/Url.js new file mode 100644 index 0000000..ac52c9d --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Url.js @@ -0,0 +1,52 @@ +import * as url from '../../utils/url.js'; +import * as string from '../../utils/string.js'; +import { + Function as FunctionToken, + String as StringToken, + Url, + RightParenthesis +} from '../../tokenizer/index.js'; + +export const name = 'Url'; +export const structure = { + value: String +}; + +// <url-token> | <function-token> <string> ) +export function parse() { + const start = this.tokenStart; + let value; + + switch (this.tokenType) { + case Url: + value = url.decode(this.consume(Url)); + break; + + case FunctionToken: + if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) { + this.error('Function name must be `url`'); + } + + this.eat(FunctionToken); + this.skipSC(); + value = string.decode(this.consume(StringToken)); + this.skipSC(); + if (!this.eof) { + this.eat(RightParenthesis); + } + break; + + default: + this.error('Url or Function is expected'); + } + + return { + type: 'Url', + loc: this.getLocation(start, this.tokenStart), + value + }; +} + +export function generate(node) { + this.token(Url, url.encode(node.value)); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/Value.js b/vanilla/node_modules/css-tree/lib/syntax/node/Value.js new file mode 100644 index 0000000..ba465bc --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/Value.js @@ -0,0 +1,19 @@ +export const name = 'Value'; +export const structure = { + children: [[]] +}; + +export function parse() { + const start = this.tokenStart; + const children = this.readSequence(this.scope.Value); + + return { + type: 'Value', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +export function generate(node) { + this.children(node); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/WhiteSpace.js b/vanilla/node_modules/css-tree/lib/syntax/node/WhiteSpace.js new file mode 100644 index 0000000..df34e6f --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/WhiteSpace.js @@ -0,0 +1,27 @@ +import { WhiteSpace } from '../../tokenizer/index.js'; + +const SPACE = Object.freeze({ + type: 'WhiteSpace', + loc: null, + value: ' ' +}); + +export const name = 'WhiteSpace'; +export const structure = { + value: String +}; + +export function parse() { + this.eat(WhiteSpace); + return SPACE; + + // return { + // type: 'WhiteSpace', + // loc: this.getLocation(this.tokenStart, this.tokenEnd), + // value: this.consume(WHITESPACE) + // }; +} + +export function generate(node) { + this.token(WhiteSpace, node.value); +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/index-generate.js b/vanilla/node_modules/css-tree/lib/syntax/node/index-generate.js new file mode 100644 index 0000000..568736f --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/index-generate.js @@ -0,0 +1,49 @@ +export { generate as AnPlusB } from './AnPlusB.js'; +export { generate as Atrule } from './Atrule.js'; +export { generate as AtrulePrelude } from './AtrulePrelude.js'; +export { generate as AttributeSelector } from './AttributeSelector.js'; +export { generate as Block } from './Block.js'; +export { generate as Brackets } from './Brackets.js'; +export { generate as CDC } from './CDC.js'; +export { generate as CDO } from './CDO.js'; +export { generate as ClassSelector } from './ClassSelector.js'; +export { generate as Combinator } from './Combinator.js'; +export { generate as Comment } from './Comment.js'; +export { generate as Condition } from './Condition.js'; +export { generate as Declaration } from './Declaration.js'; +export { generate as DeclarationList } from './DeclarationList.js'; +export { generate as Dimension } from './Dimension.js'; +export { generate as Feature } from './Feature.js'; +export { generate as FeatureFunction } from './FeatureFunction.js'; +export { generate as FeatureRange } from './FeatureRange.js'; +export { generate as Function } from './Function.js'; +export { generate as GeneralEnclosed } from './GeneralEnclosed.js'; +export { generate as Hash } from './Hash.js'; +export { generate as Identifier } from './Identifier.js'; +export { generate as IdSelector } from './IdSelector.js'; +export { generate as Layer } from './Layer.js'; +export { generate as LayerList } from './LayerList.js'; +export { generate as MediaQuery } from './MediaQuery.js'; +export { generate as MediaQueryList } from './MediaQueryList.js'; +export { generate as NestingSelector } from './NestingSelector.js'; +export { generate as Nth } from './Nth.js'; +export { generate as Number } from './Number.js'; +export { generate as Operator } from './Operator.js'; +export { generate as Parentheses } from './Parentheses.js'; +export { generate as Percentage } from './Percentage.js'; +export { generate as PseudoClassSelector } from './PseudoClassSelector.js'; +export { generate as PseudoElementSelector } from './PseudoElementSelector.js'; +export { generate as Ratio } from './Ratio.js'; +export { generate as Raw } from './Raw.js'; +export { generate as Rule } from './Rule.js'; +export { generate as Scope } from './Scope.js'; +export { generate as Selector } from './Selector.js'; +export { generate as SelectorList } from './SelectorList.js'; +export { generate as String } from './String.js'; +export { generate as StyleSheet } from './StyleSheet.js'; +export { generate as SupportsDeclaration } from './SupportsDeclaration.js'; +export { generate as TypeSelector } from './TypeSelector.js'; +export { generate as UnicodeRange } from './UnicodeRange.js'; +export { generate as Url } from './Url.js'; +export { generate as Value } from './Value.js'; +export { generate as WhiteSpace } from './WhiteSpace.js'; diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/index-parse-selector.js b/vanilla/node_modules/css-tree/lib/syntax/node/index-parse-selector.js new file mode 100644 index 0000000..3a0a2a3 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/index-parse-selector.js @@ -0,0 +1,17 @@ +export { parse as AnPlusB } from './AnPlusB.js'; +export { parse as AttributeSelector } from './AttributeSelector.js'; +export { parse as ClassSelector } from './ClassSelector.js'; +export { parse as Combinator } from './Combinator.js'; +export { parse as Identifier } from './Identifier.js'; +export { parse as IdSelector } from './IdSelector.js'; +export { parse as NestingSelector } from './NestingSelector.js'; +export { parse as Nth } from './Nth.js'; +export { parse as Operator } from './Operator.js'; +export { parse as Percentage } from './Percentage.js'; +export { parse as PseudoClassSelector } from './PseudoClassSelector.js'; +export { parse as PseudoElementSelector } from './PseudoElementSelector.js'; +export { parse as Raw } from './Raw.js'; +export { parse as Selector } from './Selector.js'; +export { parse as SelectorList } from './SelectorList.js'; +export { parse as String } from './String.js'; +export { parse as TypeSelector } from './TypeSelector.js'; diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/index-parse.js b/vanilla/node_modules/css-tree/lib/syntax/node/index-parse.js new file mode 100644 index 0000000..80136d3 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/index-parse.js @@ -0,0 +1,49 @@ +export { parse as AnPlusB } from './AnPlusB.js'; +export { parse as Atrule } from './Atrule.js'; +export { parse as AtrulePrelude } from './AtrulePrelude.js'; +export { parse as AttributeSelector } from './AttributeSelector.js'; +export { parse as Block } from './Block.js'; +export { parse as Brackets } from './Brackets.js'; +export { parse as CDC } from './CDC.js'; +export { parse as CDO } from './CDO.js'; +export { parse as ClassSelector } from './ClassSelector.js'; +export { parse as Combinator } from './Combinator.js'; +export { parse as Comment } from './Comment.js'; +export { parse as Condition } from './Condition.js'; +export { parse as Declaration } from './Declaration.js'; +export { parse as DeclarationList } from './DeclarationList.js'; +export { parse as Dimension } from './Dimension.js'; +export { parse as Feature } from './Feature.js'; +export { parse as FeatureFunction } from './FeatureFunction.js'; +export { parse as FeatureRange } from './FeatureRange.js'; +export { parse as Function } from './Function.js'; +export { parse as GeneralEnclosed } from './GeneralEnclosed.js'; +export { parse as Hash } from './Hash.js'; +export { parse as Identifier } from './Identifier.js'; +export { parse as IdSelector } from './IdSelector.js'; +export { parse as Layer } from './Layer.js'; +export { parse as LayerList } from './LayerList.js'; +export { parse as MediaQuery } from './MediaQuery.js'; +export { parse as MediaQueryList } from './MediaQueryList.js'; +export { parse as NestingSelector } from './NestingSelector.js'; +export { parse as Nth } from './Nth.js'; +export { parse as Number } from './Number.js'; +export { parse as Operator } from './Operator.js'; +export { parse as Parentheses } from './Parentheses.js'; +export { parse as Percentage } from './Percentage.js'; +export { parse as PseudoClassSelector } from './PseudoClassSelector.js'; +export { parse as PseudoElementSelector } from './PseudoElementSelector.js'; +export { parse as Ratio } from './Ratio.js'; +export { parse as Raw } from './Raw.js'; +export { parse as Rule } from './Rule.js'; +export { parse as Scope } from './Scope.js'; +export { parse as Selector } from './Selector.js'; +export { parse as SelectorList } from './SelectorList.js'; +export { parse as String } from './String.js'; +export { parse as StyleSheet } from './StyleSheet.js'; +export { parse as SupportsDeclaration } from './SupportsDeclaration.js'; +export { parse as TypeSelector } from './TypeSelector.js'; +export { parse as UnicodeRange } from './UnicodeRange.js'; +export { parse as Url } from './Url.js'; +export { parse as Value } from './Value.js'; +export { parse as WhiteSpace } from './WhiteSpace.js'; diff --git a/vanilla/node_modules/css-tree/lib/syntax/node/index.js b/vanilla/node_modules/css-tree/lib/syntax/node/index.js new file mode 100644 index 0000000..4aa2dea --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/node/index.js @@ -0,0 +1,49 @@ +export * as AnPlusB from './AnPlusB.js'; +export * as Atrule from './Atrule.js'; +export * as AtrulePrelude from './AtrulePrelude.js'; +export * as AttributeSelector from './AttributeSelector.js'; +export * as Block from './Block.js'; +export * as Brackets from './Brackets.js'; +export * as CDC from './CDC.js'; +export * as CDO from './CDO.js'; +export * as ClassSelector from './ClassSelector.js'; +export * as Combinator from './Combinator.js'; +export * as Comment from './Comment.js'; +export * as Condition from './Condition.js'; +export * as Declaration from './Declaration.js'; +export * as DeclarationList from './DeclarationList.js'; +export * as Dimension from './Dimension.js'; +export * as Feature from './Feature.js'; +export * as FeatureFunction from './FeatureFunction.js'; +export * as FeatureRange from './FeatureRange.js'; +export * as Function from './Function.js'; +export * as GeneralEnclosed from './GeneralEnclosed.js'; +export * as Hash from './Hash.js'; +export * as Identifier from './Identifier.js'; +export * as IdSelector from './IdSelector.js'; +export * as Layer from './Layer.js'; +export * as LayerList from './LayerList.js'; +export * as MediaQuery from './MediaQuery.js'; +export * as MediaQueryList from './MediaQueryList.js'; +export * as NestingSelector from './NestingSelector.js'; +export * as Nth from './Nth.js'; +export * as Number from './Number.js'; +export * as Operator from './Operator.js'; +export * as Parentheses from './Parentheses.js'; +export * as Percentage from './Percentage.js'; +export * as PseudoClassSelector from './PseudoClassSelector.js'; +export * as PseudoElementSelector from './PseudoElementSelector.js'; +export * as Ratio from './Ratio.js'; +export * as Raw from './Raw.js'; +export * as Rule from './Rule.js'; +export * as Scope from './Scope.js'; +export * as Selector from './Selector.js'; +export * as SelectorList from './SelectorList.js'; +export * as String from './String.js'; +export * as StyleSheet from './StyleSheet.js'; +export * as SupportsDeclaration from './SupportsDeclaration.js'; +export * as TypeSelector from './TypeSelector.js'; +export * as UnicodeRange from './UnicodeRange.js'; +export * as Url from './Url.js'; +export * as Value from './Value.js'; +export * as WhiteSpace from './WhiteSpace.js'; diff --git a/vanilla/node_modules/css-tree/lib/syntax/pseudo/index.js b/vanilla/node_modules/css-tree/lib/syntax/pseudo/index.js new file mode 100644 index 0000000..7d75fe1 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/pseudo/index.js @@ -0,0 +1,56 @@ +import { parseLanguageRangeList } from './lang.js'; + +const selectorList = { + parse() { + return this.createSingleNodeList( + this.SelectorList() + ); + } +}; + +const selector = { + parse() { + return this.createSingleNodeList( + this.Selector() + ); + } +}; + +const identList = { + parse() { + return this.createSingleNodeList( + this.Identifier() + ); + } +}; + +const langList = { + parse: parseLanguageRangeList +}; + +const nth = { + parse() { + return this.createSingleNodeList( + this.Nth() + ); + } +}; + +export default { + 'dir': identList, + 'has': selectorList, + 'lang': langList, + 'matches': selectorList, + 'is': selectorList, + '-moz-any': selectorList, + '-webkit-any': selectorList, + 'where': selectorList, + 'not': selectorList, + 'nth-child': nth, + 'nth-last-child': nth, + 'nth-last-of-type': nth, + 'nth-of-type': nth, + 'slotted': selector, + 'host': selector, + 'host-context': selector +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/pseudo/lang.js b/vanilla/node_modules/css-tree/lib/syntax/pseudo/lang.js new file mode 100644 index 0000000..3adfdb8 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/pseudo/lang.js @@ -0,0 +1,33 @@ +import { Comma, String as StringToken, Ident, RightParenthesis } from '../../tokenizer/index.js'; + +export function parseLanguageRangeList() { + const children = this.createList(); + + this.skipSC(); + + loop: while (!this.eof) { + switch (this.tokenType) { + case Ident: + children.push(this.Identifier()); + break; + + case StringToken: + children.push(this.String()); + break; + + case Comma: + children.push(this.Operator()); + break; + + case RightParenthesis: + break loop; + + default: + this.error('Identifier, string or comma is expected'); + } + + this.skipSC(); + } + + return children; +} diff --git a/vanilla/node_modules/css-tree/lib/syntax/scope/atrulePrelude.js b/vanilla/node_modules/css-tree/lib/syntax/scope/atrulePrelude.js new file mode 100644 index 0000000..c903555 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/scope/atrulePrelude.js @@ -0,0 +1,5 @@ +import getNode from './default.js'; + +export default { + getNode +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/scope/default.js b/vanilla/node_modules/css-tree/lib/syntax/scope/default.js new file mode 100644 index 0000000..8f14035 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/scope/default.js @@ -0,0 +1,85 @@ +import { + Ident, + String as StringToken, + Number as NumberToken, + Function as FunctionToken, + Url, + Hash, + Dimension, + Percentage, + LeftParenthesis, + LeftSquareBracket, + Comma, + Delim +} from '../../tokenizer/index.js'; + +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u) + +export default function defaultRecognizer(context) { + switch (this.tokenType) { + case Hash: + return this.Hash(); + + case Comma: + return this.Operator(); + + case LeftParenthesis: + return this.Parentheses(this.readSequence, context.recognizer); + + case LeftSquareBracket: + return this.Brackets(this.readSequence, context.recognizer); + + case StringToken: + return this.String(); + + case Dimension: + return this.Dimension(); + + case Percentage: + return this.Percentage(); + + case NumberToken: + return this.Number(); + + case FunctionToken: + return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(') + ? this.Url() + : this.Function(this.readSequence, context.recognizer); + + case Url: + return this.Url(); + + case Ident: + // check for unicode range, it should start with u+ or U+ + if (this.cmpChar(this.tokenStart, U) && + this.cmpChar(this.tokenStart + 1, PLUSSIGN)) { + return this.UnicodeRange(); + } else { + return this.Identifier(); + } + + case Delim: { + const code = this.charCodeAt(this.tokenStart); + + if (code === SOLIDUS || + code === ASTERISK || + code === PLUSSIGN || + code === HYPHENMINUS) { + return this.Operator(); // TODO: replace with Delim + } + + // TODO: produce a node with Delim node type + + if (code === NUMBERSIGN) { + this.error('Hex or identifier is expected', this.tokenStart + 1); + } + + break; + } + } +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/scope/index.js b/vanilla/node_modules/css-tree/lib/syntax/scope/index.js new file mode 100644 index 0000000..6dabbbe --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/scope/index.js @@ -0,0 +1,3 @@ +export { default as AtrulePrelude } from './atrulePrelude.js'; +export { default as Selector } from './selector.js'; +export { default as Value } from './value.js'; diff --git a/vanilla/node_modules/css-tree/lib/syntax/scope/selector.js b/vanilla/node_modules/css-tree/lib/syntax/scope/selector.js new file mode 100644 index 0000000..a8efcd5 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/scope/selector.js @@ -0,0 +1,94 @@ +import { + Delim, + Ident, + Dimension, + Percentage, + Number as NumberToken, + Hash, + Colon, + LeftSquareBracket +} from '../../tokenizer/index.js'; + +const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) +const TILDE = 0x007E; // U+007E TILDE (~) + +function onWhiteSpace(next, children) { + if (children.last !== null && children.last.type !== 'Combinator' && + next !== null && next.type !== 'Combinator') { + children.push({ // FIXME: this.Combinator() should be used instead + type: 'Combinator', + loc: null, + name: ' ' + }); + } +} + +function getNode() { + switch (this.tokenType) { + case LeftSquareBracket: + return this.AttributeSelector(); + + case Hash: + return this.IdSelector(); + + case Colon: + if (this.lookupType(1) === Colon) { + return this.PseudoElementSelector(); + } else { + return this.PseudoClassSelector(); + } + + case Ident: + return this.TypeSelector(); + + case NumberToken: + case Percentage: + return this.Percentage(); + + case Dimension: + // throws when .123ident + if (this.charCodeAt(this.tokenStart) === FULLSTOP) { + this.error('Identifier is expected', this.tokenStart + 1); + } + break; + + case Delim: { + const code = this.charCodeAt(this.tokenStart); + + switch (code) { + case PLUSSIGN: + case GREATERTHANSIGN: + case TILDE: + case SOLIDUS: // /deep/ + return this.Combinator(); + + case FULLSTOP: + return this.ClassSelector(); + + case ASTERISK: + case VERTICALLINE: + return this.TypeSelector(); + + case NUMBERSIGN: + return this.IdSelector(); + + case AMPERSAND: + return this.NestingSelector(); + } + + break; + } + } +}; + +export default { + onWhiteSpace, + getNode +}; diff --git a/vanilla/node_modules/css-tree/lib/syntax/scope/value.js b/vanilla/node_modules/css-tree/lib/syntax/scope/value.js new file mode 100644 index 0000000..dc94219 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/syntax/scope/value.js @@ -0,0 +1,25 @@ +import getNode from './default.js'; +import expressionFn from '../function/expression.js'; +import varFn from '../function/var.js'; + +function isPlusMinusOperator(node) { + return ( + node !== null && + node.type === 'Operator' && + (node.value[node.value.length - 1] === '-' || node.value[node.value.length - 1] === '+') + ); +} + +export default { + getNode, + onWhiteSpace(next, children) { + if (isPlusMinusOperator(next)) { + next.value = ' ' + next.value; + } + if (isPlusMinusOperator(children.last)) { + children.last.value += ' '; + } + }, + 'expression': expressionFn, + 'var': varFn +}; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/OffsetToLocation.js b/vanilla/node_modules/css-tree/lib/tokenizer/OffsetToLocation.js new file mode 100644 index 0000000..cc584c0 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/OffsetToLocation.js @@ -0,0 +1,87 @@ +import { adoptBuffer } from './adopt-buffer.js'; +import { isBOM } from './char-code-definitions.js'; + +const N = 10; +const F = 12; +const R = 13; + +function computeLinesAndColumns(host) { + const source = host.source; + const sourceLength = source.length; + const startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0; + const lines = adoptBuffer(host.lines, sourceLength); + const columns = adoptBuffer(host.columns, sourceLength); + let line = host.startLine; + let column = host.startColumn; + + for (let i = startOffset; i < sourceLength; i++) { + const code = source.charCodeAt(i); + + lines[i] = line; + columns[i] = column++; + + if (code === N || code === R || code === F) { + if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N) { + i++; + lines[i] = line; + columns[i] = column; + } + + line++; + column = 1; + } + } + + lines[sourceLength] = line; + columns[sourceLength] = column; + + host.lines = lines; + host.columns = columns; + host.computed = true; +} + +export class OffsetToLocation { + constructor(source, startOffset, startLine, startColumn) { + this.setSource(source, startOffset, startLine, startColumn); + this.lines = null; + this.columns = null; + } + setSource(source = '', startOffset = 0, startLine = 1, startColumn = 1) { + this.source = source; + this.startOffset = startOffset; + this.startLine = startLine; + this.startColumn = startColumn; + this.computed = false; + } + getLocation(offset, filename) { + if (!this.computed) { + computeLinesAndColumns(this); + } + + return { + source: filename, + offset: this.startOffset + offset, + line: this.lines[offset], + column: this.columns[offset] + }; + } + getLocationRange(start, end, filename) { + if (!this.computed) { + computeLinesAndColumns(this); + } + + return { + source: filename, + start: { + offset: this.startOffset + start, + line: this.lines[start], + column: this.columns[start] + }, + end: { + offset: this.startOffset + end, + line: this.lines[end], + column: this.columns[end] + } + }; + } +}; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/TokenStream.js b/vanilla/node_modules/css-tree/lib/tokenizer/TokenStream.js new file mode 100644 index 0000000..96d48b7 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/TokenStream.js @@ -0,0 +1,316 @@ +import { adoptBuffer } from './adopt-buffer.js'; +import { cmpStr } from './utils.js'; +import tokenNames from './names.js'; +import { + WhiteSpace, + Comment, + Delim, + EOF, + Function as FunctionToken, + LeftParenthesis, + RightParenthesis, + LeftSquareBracket, + RightSquareBracket, + LeftCurlyBracket, + RightCurlyBracket +} from './types.js'; + +const OFFSET_MASK = 0x00FFFFFF; +const TYPE_SHIFT = 24; +const balancePair = new Uint8Array(32); // 32b of memory ought to be enough for anyone (any number of tokens) +balancePair[FunctionToken] = RightParenthesis; +balancePair[LeftParenthesis] = RightParenthesis; +balancePair[LeftSquareBracket] = RightSquareBracket; +balancePair[LeftCurlyBracket] = RightCurlyBracket; + +function isBlockOpenerToken(tokenType) { + return balancePair[tokenType] !== 0; +} + +export class TokenStream { + constructor(source, tokenize) { + this.setSource(source, tokenize); + } + reset() { + this.eof = false; + this.tokenIndex = -1; + this.tokenType = 0; + this.tokenStart = this.firstCharOffset; + this.tokenEnd = this.firstCharOffset; + } + setSource(source = '', tokenize = () => {}) { + source = String(source || ''); + + const sourceLength = source.length; + const offsetAndType = adoptBuffer(this.offsetAndType, source.length + 1); // +1 because of eof-token + const balance = adoptBuffer(this.balance, source.length + 1); + let tokenCount = 0; + let firstCharOffset = -1; + let balanceCloseType = 0; + let balanceStart = source.length; + + // capture buffers + this.offsetAndType = null; + this.balance = null; + balance.fill(0); + + tokenize(source, (type, start, end) => { + const index = tokenCount++; + + // type & offset + offsetAndType[index] = (type << TYPE_SHIFT) | end; + + if (firstCharOffset === -1) { + firstCharOffset = start; + } + + // balance + balance[index] = balanceStart; + + if (type === balanceCloseType) { + const prevBalanceStart = balance[balanceStart]; + + // set reference to balance end for a block opener + balance[balanceStart] = index; + + // pop state + balanceStart = prevBalanceStart; + balanceCloseType = balancePair[offsetAndType[prevBalanceStart] >> TYPE_SHIFT]; + } else if (isBlockOpenerToken(type)) { // check for FunctionToken, <(-token>, <[-token> and <{-token> + // push state + balanceStart = index; + balanceCloseType = balancePair[type]; + } + }); + + // finalize buffers + offsetAndType[tokenCount] = (EOF << TYPE_SHIFT) | sourceLength; // <EOF-token> + balance[tokenCount] = tokenCount; // prevents false positive balance match with any token + + // reverse references from balance start to end + // tokens + // token: a ( [ b c ] d e ) { + // index: 0 1 2 3 4 5 6 7 8 9 + // before + // balance: 0 8 5 2 2 2 1 1 1 0 + // - > > < < < < < < - + // after + // balance: 9 8 5 5 5 2 8 8 1 9 + // > > > > > < > > < > + for (let i = 0; i < tokenCount; i++) { + const balanceStart = balance[i]; + + if (balanceStart <= i) { + const balanceEnd = balance[balanceStart]; + + if (balanceEnd !== i) { + balance[i] = balanceEnd; + } + } else if (balanceStart > tokenCount) { + balance[i] = tokenCount; + } + } + + // balance[0] = tokenCount; + + this.source = source; + this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset; + this.tokenCount = tokenCount; + this.offsetAndType = offsetAndType; + this.balance = balance; + + this.reset(); + this.next(); + } + + lookupType(offset) { + offset += this.tokenIndex; + + if (offset < this.tokenCount) { + return this.offsetAndType[offset] >> TYPE_SHIFT; + } + + return EOF; + } + lookupTypeNonSC(idx) { + for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) { + const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT; + + if (tokenType !== WhiteSpace && tokenType !== Comment) { + if (idx-- === 0) { + return tokenType; + } + } + } + + return EOF; + } + lookupOffset(offset) { + offset += this.tokenIndex; + + if (offset < this.tokenCount) { + return this.offsetAndType[offset - 1] & OFFSET_MASK; + } + + return this.source.length; + } + lookupOffsetNonSC(idx) { + for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) { + const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT; + + if (tokenType !== WhiteSpace && tokenType !== Comment) { + if (idx-- === 0) { + return offset - this.tokenIndex; + } + } + } + + return EOF; + } + lookupValue(offset, referenceStr) { + offset += this.tokenIndex; + + if (offset < this.tokenCount) { + return cmpStr( + this.source, + this.offsetAndType[offset - 1] & OFFSET_MASK, + this.offsetAndType[offset] & OFFSET_MASK, + referenceStr + ); + } + + return false; + } + getTokenStart(tokenIndex) { + if (tokenIndex === this.tokenIndex) { + return this.tokenStart; + } + + if (tokenIndex > 0) { + return tokenIndex < this.tokenCount + ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK + : this.offsetAndType[this.tokenCount] & OFFSET_MASK; + } + + return this.firstCharOffset; + } + substrToCursor(start) { + return this.source.substring(start, this.tokenStart); + } + + isBalanceEdge(pos) { + return this.balance[this.tokenIndex] < pos; + // return this.balance[this.balance[pos]] !== this.tokenIndex; + } + isDelim(code, offset) { + if (offset) { + return ( + this.lookupType(offset) === Delim && + this.source.charCodeAt(this.lookupOffset(offset)) === code + ); + } + + return ( + this.tokenType === Delim && + this.source.charCodeAt(this.tokenStart) === code + ); + } + + skip(tokenCount) { + let next = this.tokenIndex + tokenCount; + + if (next < this.tokenCount) { + this.tokenIndex = next; + this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK; + next = this.offsetAndType[next]; + this.tokenType = next >> TYPE_SHIFT; + this.tokenEnd = next & OFFSET_MASK; + } else { + this.tokenIndex = this.tokenCount; + this.next(); + } + } + next() { + let next = this.tokenIndex + 1; + + if (next < this.tokenCount) { + this.tokenIndex = next; + this.tokenStart = this.tokenEnd; + next = this.offsetAndType[next]; + this.tokenType = next >> TYPE_SHIFT; + this.tokenEnd = next & OFFSET_MASK; + } else { + this.eof = true; + this.tokenIndex = this.tokenCount; + this.tokenType = EOF; + this.tokenStart = this.tokenEnd = this.source.length; + } + } + skipSC() { + while (this.tokenType === WhiteSpace || this.tokenType === Comment) { + this.next(); + } + } + skipUntilBalanced(startToken, stopConsume) { + let cursor = startToken; + let balanceEnd = 0; + let offset = 0; + + loop: + for (; cursor < this.tokenCount; cursor++) { + balanceEnd = this.balance[cursor]; + + // stop scanning on balance edge that points to offset before start token + if (balanceEnd < startToken) { + break loop; + } + + offset = cursor > 0 ? this.offsetAndType[cursor - 1] & OFFSET_MASK : this.firstCharOffset; + + // check stop condition + switch (stopConsume(this.source.charCodeAt(offset))) { + case 1: // just stop + break loop; + + case 2: // stop & included + cursor++; + break loop; + + default: + // fast forward to the end of balanced block for an open block tokens + if (isBlockOpenerToken(this.offsetAndType[cursor] >> TYPE_SHIFT)) { + cursor = balanceEnd; + } + } + } + + this.skip(cursor - this.tokenIndex); + } + + forEachToken(fn) { + for (let i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) { + const start = offset; + const item = this.offsetAndType[i]; + const end = item & OFFSET_MASK; + const type = item >> TYPE_SHIFT; + + offset = end; + + fn(type, start, end, i); + } + } + dump() { + const tokens = new Array(this.tokenCount); + + this.forEachToken((type, start, end, index) => { + tokens[index] = { + idx: index, + type: tokenNames[type], + chunk: this.source.substring(start, end), + balance: this.balance[index] + }; + }); + + return tokens; + } +}; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/adopt-buffer.js b/vanilla/node_modules/css-tree/lib/tokenizer/adopt-buffer.js new file mode 100644 index 0000000..ab4566d --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/adopt-buffer.js @@ -0,0 +1,9 @@ +const MIN_SIZE = 16 * 1024; + +export function adoptBuffer(buffer = null, size) { + if (buffer === null || buffer.length < size) { + return new Uint32Array(Math.max(size + 1024, MIN_SIZE)); + } + + return buffer; +}; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/char-code-definitions.js b/vanilla/node_modules/css-tree/lib/tokenizer/char-code-definitions.js new file mode 100644 index 0000000..715572a --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/char-code-definitions.js @@ -0,0 +1,212 @@ +const EOF = 0; + +// https://drafts.csswg.org/css-syntax-3/ +// § 4.2. Definitions + +// digit +// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9). +export function isDigit(code) { + return code >= 0x0030 && code <= 0x0039; +} + +// hex digit +// A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F), +// or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f). +export function isHexDigit(code) { + return ( + isDigit(code) || // 0 .. 9 + (code >= 0x0041 && code <= 0x0046) || // A .. F + (code >= 0x0061 && code <= 0x0066) // a .. f + ); +} + +// uppercase letter +// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z). +export function isUppercaseLetter(code) { + return code >= 0x0041 && code <= 0x005A; +} + +// lowercase letter +// A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z). +export function isLowercaseLetter(code) { + return code >= 0x0061 && code <= 0x007A; +} + +// letter +// An uppercase letter or a lowercase letter. +export function isLetter(code) { + return isUppercaseLetter(code) || isLowercaseLetter(code); +} + +// non-ASCII code point +// A code point with a value equal to or greater than U+0080 <control>. +// +// 2024-09-02: The latest spec narrows the range for non-ASCII characters (see https://github.com/csstree/csstree/issues/188). +// However, all modern browsers support a wider range, and strictly following the latest spec could result +// in some CSS being parsed incorrectly, even though it works in the browser. Therefore, this function adheres +// to the previous, broader definition of non-ASCII characters. +export function isNonAscii(code) { + return code >= 0x0080; +} + +// name-start code point +// A letter, a non-ASCII code point, or U+005F LOW LINE (_). +export function isNameStart(code) { + return isLetter(code) || isNonAscii(code) || code === 0x005F; +} + +// name code point +// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-). +export function isName(code) { + return isNameStart(code) || isDigit(code) || code === 0x002D; +} + +// non-printable code point +// A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION, +// or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE. +export function isNonPrintable(code) { + return ( + (code >= 0x0000 && code <= 0x0008) || + (code === 0x000B) || + (code >= 0x000E && code <= 0x001F) || + (code === 0x007F) + ); +} + +// newline +// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition, +// as they are converted to U+000A LINE FEED during preprocessing. +// TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED +export function isNewline(code) { + return code === 0x000A || code === 0x000D || code === 0x000C; +} + +// whitespace +// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE. +export function isWhiteSpace(code) { + return isNewline(code) || code === 0x0020 || code === 0x0009; +} + +// § 4.3.8. Check if two code points are a valid escape +export function isValidEscape(first, second) { + // If the first code point is not U+005C REVERSE SOLIDUS (\), return false. + if (first !== 0x005C) { + return false; + } + + // Otherwise, if the second code point is a newline or EOF, return false. + if (isNewline(second) || second === EOF) { + return false; + } + + // Otherwise, return true. + return true; +} + +// § 4.3.9. Check if three code points would start an identifier +export function isIdentifierStart(first, second, third) { + // Look at the first code point: + + // U+002D HYPHEN-MINUS + if (first === 0x002D) { + // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS, + // or the second and third code points are a valid escape, return true. Otherwise, return false. + return ( + isNameStart(second) || + second === 0x002D || + isValidEscape(second, third) + ); + } + + // name-start code point + if (isNameStart(first)) { + // Return true. + return true; + } + + // U+005C REVERSE SOLIDUS (\) + if (first === 0x005C) { + // If the first and second code points are a valid escape, return true. Otherwise, return false. + return isValidEscape(first, second); + } + + // anything else + // Return false. + return false; +} + +// § 4.3.10. Check if three code points would start a number +export function isNumberStart(first, second, third) { + // Look at the first code point: + + // U+002B PLUS SIGN (+) + // U+002D HYPHEN-MINUS (-) + if (first === 0x002B || first === 0x002D) { + // If the second code point is a digit, return true. + if (isDigit(second)) { + return 2; + } + + // Otherwise, if the second code point is a U+002E FULL STOP (.) + // and the third code point is a digit, return true. + // Otherwise, return false. + return second === 0x002E && isDigit(third) ? 3 : 0; + } + + // U+002E FULL STOP (.) + if (first === 0x002E) { + // If the second code point is a digit, return true. Otherwise, return false. + return isDigit(second) ? 2 : 0; + } + + // digit + if (isDigit(first)) { + // Return true. + return 1; + } + + // anything else + // Return false. + return 0; +} + +// +// Misc +// + +// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark) +export function isBOM(code) { + // UTF-16BE + if (code === 0xFEFF) { + return 1; + } + + // UTF-16LE + if (code === 0xFFFE) { + return 1; + } + + return 0; +} + +// Fast code category +// Only ASCII code points has a special meaning, that's why we define a maps for 0..127 codes only +const CATEGORY = new Array(0x80); +export const EofCategory = 0x80; +export const WhiteSpaceCategory = 0x82; +export const DigitCategory = 0x83; +export const NameStartCategory = 0x84; +export const NonPrintableCategory = 0x85; + +for (let i = 0; i < CATEGORY.length; i++) { + CATEGORY[i] = + isWhiteSpace(i) && WhiteSpaceCategory || + isDigit(i) && DigitCategory || + isNameStart(i) && NameStartCategory || + isNonPrintable(i) && NonPrintableCategory || + i || EofCategory; +} + +export function charCodeCategory(code) { + return code < 0x80 ? CATEGORY[code] : NameStartCategory; +} diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/index.js b/vanilla/node_modules/css-tree/lib/tokenizer/index.js new file mode 100644 index 0000000..16df44c --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/index.js @@ -0,0 +1,513 @@ +import * as TYPE from './types.js'; +import { + isNewline, + isName, + isValidEscape, + isNumberStart, + isIdentifierStart, + isBOM, + charCodeCategory, + WhiteSpaceCategory, + DigitCategory, + NameStartCategory, + NonPrintableCategory +} from './char-code-definitions.js'; +import { + cmpStr, + getNewlineLength, + findWhiteSpaceEnd, + consumeEscaped, + consumeName, + consumeNumber, + consumeBadUrlRemnants +} from './utils.js'; + +export function tokenize(source, onToken) { + function getCharCode(offset) { + return offset < sourceLength ? source.charCodeAt(offset) : 0; + } + + // § 4.3.3. Consume a numeric token + function consumeNumericToken() { + // Consume a number and let number be the result. + offset = consumeNumber(source, offset); + + // If the next 3 input code points would start an identifier, then: + if (isIdentifierStart(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) { + // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string. + // Consume a name. Set the <dimension-token>’s unit to the returned value. + // Return the <dimension-token>. + type = TYPE.Dimension; + offset = consumeName(source, offset); + return; + } + + // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it. + if (getCharCode(offset) === 0x0025) { + // Create a <percentage-token> with the same value as number, and return it. + type = TYPE.Percentage; + offset++; + return; + } + + // Otherwise, create a <number-token> with the same value and type flag as number, and return it. + type = TYPE.Number; + } + + // § 4.3.4. Consume an ident-like token + function consumeIdentLikeToken() { + const nameStartOffset = offset; + + // Consume a name, and let string be the result. + offset = consumeName(source, offset); + + // If string’s value is an ASCII case-insensitive match for "url", + // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it. + if (cmpStr(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) { + // While the next two input code points are whitespace, consume the next input code point. + offset = findWhiteSpaceEnd(source, offset + 1); + + // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('), + // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('), + // then create a <function-token> with its value set to string and return it. + if (getCharCode(offset) === 0x0022 || + getCharCode(offset) === 0x0027) { + type = TYPE.Function; + offset = nameStartOffset + 4; + return; + } + + // Otherwise, consume a url token, and return it. + consumeUrlToken(); + return; + } + + // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it. + // Create a <function-token> with its value set to string and return it. + if (getCharCode(offset) === 0x0028) { + type = TYPE.Function; + offset++; + return; + } + + // Otherwise, create an <ident-token> with its value set to string and return it. + type = TYPE.Ident; + } + + // § 4.3.5. Consume a string token + function consumeStringToken(endingCodePoint) { + // This algorithm may be called with an ending code point, which denotes the code point + // that ends the string. If an ending code point is not specified, + // the current input code point is used. + if (!endingCodePoint) { + endingCodePoint = getCharCode(offset++); + } + + // Initially create a <string-token> with its value set to the empty string. + type = TYPE.String; + + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + switch (charCodeCategory(code)) { + // ending code point + case endingCodePoint: + // Return the <string-token>. + offset++; + return; + + // EOF + // case EofCategory: + // This is a parse error. Return the <string-token>. + // return; + + // newline + case WhiteSpaceCategory: + if (isNewline(code)) { + // This is a parse error. Reconsume the current input code point, + // create a <bad-string-token>, and return it. + offset += getNewlineLength(source, offset, code); + type = TYPE.BadString; + return; + } + break; + + // U+005C REVERSE SOLIDUS (\) + case 0x005C: + // If the next input code point is EOF, do nothing. + if (offset === source.length - 1) { + break; + } + + const nextCode = getCharCode(offset + 1); + + // Otherwise, if the next input code point is a newline, consume it. + if (isNewline(nextCode)) { + offset += getNewlineLength(source, offset + 1, nextCode); + } else if (isValidEscape(code, nextCode)) { + // Otherwise, (the stream starts with a valid escape) consume + // an escaped code point and append the returned code point to + // the <string-token>’s value. + offset = consumeEscaped(source, offset) - 1; + } + break; + + // anything else + // Append the current input code point to the <string-token>’s value. + } + } + } + + // § 4.3.6. Consume a url token + // Note: This algorithm assumes that the initial "url(" has already been consumed. + // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo). + // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token + // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise. + function consumeUrlToken() { + // Initially create a <url-token> with its value set to the empty string. + type = TYPE.Url; + + // Consume as much whitespace as possible. + offset = findWhiteSpaceEnd(source, offset); + + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + switch (charCodeCategory(code)) { + // U+0029 RIGHT PARENTHESIS ()) + case 0x0029: + // Return the <url-token>. + offset++; + return; + + // EOF + // case EofCategory: + // This is a parse error. Return the <url-token>. + // return; + + // whitespace + case WhiteSpaceCategory: + // Consume as much whitespace as possible. + offset = findWhiteSpaceEnd(source, offset); + + // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF, + // consume it and return the <url-token> + // (if EOF was encountered, this is a parse error); + if (getCharCode(offset) === 0x0029 || offset >= source.length) { + if (offset < source.length) { + offset++; + } + return; + } + + // otherwise, consume the remnants of a bad url, create a <bad-url-token>, + // and return it. + offset = consumeBadUrlRemnants(source, offset); + type = TYPE.BadUrl; + return; + + // U+0022 QUOTATION MARK (") + // U+0027 APOSTROPHE (') + // U+0028 LEFT PARENTHESIS (() + // non-printable code point + case 0x0022: + case 0x0027: + case 0x0028: + case NonPrintableCategory: + // This is a parse error. Consume the remnants of a bad url, + // create a <bad-url-token>, and return it. + offset = consumeBadUrlRemnants(source, offset); + type = TYPE.BadUrl; + return; + + // U+005C REVERSE SOLIDUS (\) + case 0x005C: + // If the stream starts with a valid escape, consume an escaped code point and + // append the returned code point to the <url-token>’s value. + if (isValidEscape(code, getCharCode(offset + 1))) { + offset = consumeEscaped(source, offset) - 1; + break; + } + + // Otherwise, this is a parse error. Consume the remnants of a bad url, + // create a <bad-url-token>, and return it. + offset = consumeBadUrlRemnants(source, offset); + type = TYPE.BadUrl; + return; + + // anything else + // Append the current input code point to the <url-token>’s value. + } + } + } + + // ensure source is a string + source = String(source || ''); + + const sourceLength = source.length; + let start = isBOM(getCharCode(0)); + let offset = start; + let type; + + // https://drafts.csswg.org/css-syntax-3/#consume-token + // § 4.3.1. Consume a token + while (offset < sourceLength) { + const code = source.charCodeAt(offset); + + switch (charCodeCategory(code)) { + // whitespace + case WhiteSpaceCategory: + // Consume as much whitespace as possible. Return a <whitespace-token>. + type = TYPE.WhiteSpace; + offset = findWhiteSpaceEnd(source, offset + 1); + break; + + // U+0022 QUOTATION MARK (") + case 0x0022: + // Consume a string token and return it. + consumeStringToken(); + break; + + // U+0023 NUMBER SIGN (#) + case 0x0023: + // If the next input code point is a name code point or the next two input code points are a valid escape, then: + if (isName(getCharCode(offset + 1)) || isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) { + // Create a <hash-token>. + type = TYPE.Hash; + + // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id". + // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) { + // // TODO: set id flag + // } + + // Consume a name, and set the <hash-token>’s value to the returned string. + offset = consumeName(source, offset + 1); + + // Return the <hash-token>. + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + + break; + + // U+0027 APOSTROPHE (') + case 0x0027: + // Consume a string token and return it. + consumeStringToken(); + break; + + // U+0028 LEFT PARENTHESIS (() + case 0x0028: + // Return a <(-token>. + type = TYPE.LeftParenthesis; + offset++; + break; + + // U+0029 RIGHT PARENTHESIS ()) + case 0x0029: + // Return a <)-token>. + type = TYPE.RightParenthesis; + offset++; + break; + + // U+002B PLUS SIGN (+) + case 0x002B: + // If the input stream starts with a number, ... + if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + // ... reconsume the current input code point, consume a numeric token, and return it. + consumeNumericToken(); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + break; + + // U+002C COMMA (,) + case 0x002C: + // Return a <comma-token>. + type = TYPE.Comma; + offset++; + break; + + // U+002D HYPHEN-MINUS (-) + case 0x002D: + // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it. + if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + consumeNumericToken(); + } else { + // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>. + if (getCharCode(offset + 1) === 0x002D && + getCharCode(offset + 2) === 0x003E) { + type = TYPE.CDC; + offset = offset + 3; + } else { + // Otherwise, if the input stream starts with an identifier, ... + if (isIdentifierStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + // ... reconsume the current input code point, consume an ident-like token, and return it. + consumeIdentLikeToken(); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + } + } + break; + + // U+002E FULL STOP (.) + case 0x002E: + // If the input stream starts with a number, ... + if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) { + // ... reconsume the current input code point, consume a numeric token, and return it. + consumeNumericToken(); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + + break; + + // U+002F SOLIDUS (/) + case 0x002F: + // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*), + if (getCharCode(offset + 1) === 0x002A) { + // ... consume them and all following code points up to and including the first U+002A ASTERISK (*) + // followed by a U+002F SOLIDUS (/), or up to an EOF code point. + type = TYPE.Comment; + offset = source.indexOf('*/', offset + 2); + offset = offset === -1 ? source.length : offset + 2; + } else { + type = TYPE.Delim; + offset++; + } + break; + + // U+003A COLON (:) + case 0x003A: + // Return a <colon-token>. + type = TYPE.Colon; + offset++; + break; + + // U+003B SEMICOLON (;) + case 0x003B: + // Return a <semicolon-token>. + type = TYPE.Semicolon; + offset++; + break; + + // U+003C LESS-THAN SIGN (<) + case 0x003C: + // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ... + if (getCharCode(offset + 1) === 0x0021 && + getCharCode(offset + 2) === 0x002D && + getCharCode(offset + 3) === 0x002D) { + // ... consume them and return a <CDO-token>. + type = TYPE.CDO; + offset = offset + 4; + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + + break; + + // U+0040 COMMERCIAL AT (@) + case 0x0040: + // If the next 3 input code points would start an identifier, ... + if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) { + // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it. + type = TYPE.AtKeyword; + offset = consumeName(source, offset + 1); + } else { + // Otherwise, return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + + break; + + // U+005B LEFT SQUARE BRACKET ([) + case 0x005B: + // Return a <[-token>. + type = TYPE.LeftSquareBracket; + offset++; + break; + + // U+005C REVERSE SOLIDUS (\) + case 0x005C: + // If the input stream starts with a valid escape, ... + if (isValidEscape(code, getCharCode(offset + 1))) { + // ... reconsume the current input code point, consume an ident-like token, and return it. + consumeIdentLikeToken(); + } else { + // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + break; + + // U+005D RIGHT SQUARE BRACKET (]) + case 0x005D: + // Return a <]-token>. + type = TYPE.RightSquareBracket; + offset++; + break; + + // U+007B LEFT CURLY BRACKET ({) + case 0x007B: + // Return a <{-token>. + type = TYPE.LeftCurlyBracket; + offset++; + break; + + // U+007D RIGHT CURLY BRACKET (}) + case 0x007D: + // Return a <}-token>. + type = TYPE.RightCurlyBracket; + offset++; + break; + + // digit + case DigitCategory: + // Reconsume the current input code point, consume a numeric token, and return it. + consumeNumericToken(); + break; + + // name-start code point + case NameStartCategory: + // Reconsume the current input code point, consume an ident-like token, and return it. + consumeIdentLikeToken(); + break; + + // EOF + // case EofCategory: + // Return an <EOF-token>. + // break; + + // anything else + default: + // Return a <delim-token> with its value set to the current input code point. + type = TYPE.Delim; + offset++; + } + + // put token to stream + onToken(type, start, start = offset); + } +} + +export * from './types.js'; +export * as tokenTypes from './types.js'; +export { default as tokenNames } from './names.js'; +export * from './char-code-definitions.js'; +export * from './utils.js'; +export * from './OffsetToLocation.js'; +export * from './TokenStream.js'; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/names.js b/vanilla/node_modules/css-tree/lib/tokenizer/names.js new file mode 100644 index 0000000..54831bd --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/names.js @@ -0,0 +1,28 @@ +export default [ + 'EOF-token', + 'ident-token', + 'function-token', + 'at-keyword-token', + 'hash-token', + 'string-token', + 'bad-string-token', + 'url-token', + 'bad-url-token', + 'delim-token', + 'number-token', + 'percentage-token', + 'dimension-token', + 'whitespace-token', + 'CDO-token', + 'CDC-token', + 'colon-token', + 'semicolon-token', + 'comma-token', + '[-token', + ']-token', + '(-token', + ')-token', + '{-token', + '}-token', + 'comment-token' +]; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/types.js b/vanilla/node_modules/css-tree/lib/tokenizer/types.js new file mode 100644 index 0000000..5018569 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/types.js @@ -0,0 +1,28 @@ +// CSS Syntax Module Level 3 +// https://www.w3.org/TR/css-syntax-3/ +export const EOF = 0; // <EOF-token> +export const Ident = 1; // <ident-token> +export const Function = 2; // <function-token> +export const AtKeyword = 3; // <at-keyword-token> +export const Hash = 4; // <hash-token> +export const String = 5; // <string-token> +export const BadString = 6; // <bad-string-token> +export const Url = 7; // <url-token> +export const BadUrl = 8; // <bad-url-token> +export const Delim = 9; // <delim-token> +export const Number = 10; // <number-token> +export const Percentage = 11; // <percentage-token> +export const Dimension = 12; // <dimension-token> +export const WhiteSpace = 13; // <whitespace-token> +export const CDO = 14; // <CDO-token> +export const CDC = 15; // <CDC-token> +export const Colon = 16; // <colon-token> : +export const Semicolon = 17; // <semicolon-token> ; +export const Comma = 18; // <comma-token> , +export const LeftSquareBracket = 19; // <[-token> +export const RightSquareBracket = 20; // <]-token> +export const LeftParenthesis = 21; // <(-token> +export const RightParenthesis = 22; // <)-token> +export const LeftCurlyBracket = 23; // <{-token> +export const RightCurlyBracket = 24; // <}-token> +export const Comment = 25; diff --git a/vanilla/node_modules/css-tree/lib/tokenizer/utils.js b/vanilla/node_modules/css-tree/lib/tokenizer/utils.js new file mode 100644 index 0000000..c131ec5 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/tokenizer/utils.js @@ -0,0 +1,254 @@ +import { + isDigit, + isHexDigit, + isUppercaseLetter, + isName, + isWhiteSpace, + isValidEscape +} from './char-code-definitions.js'; + +function getCharCode(source, offset) { + return offset < source.length ? source.charCodeAt(offset) : 0; +} + +export function getNewlineLength(source, offset, code) { + if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) { + return 2; + } + + return 1; +} + +export function cmpChar(testStr, offset, referenceCode) { + let code = testStr.charCodeAt(offset); + + // code.toLowerCase() for A..Z + if (isUppercaseLetter(code)) { + code = code | 32; + } + + return code === referenceCode; +} + +export function cmpStr(testStr, start, end, referenceStr) { + if (end - start !== referenceStr.length) { + return false; + } + + if (start < 0 || end > testStr.length) { + return false; + } + + for (let i = start; i < end; i++) { + const referenceCode = referenceStr.charCodeAt(i - start); + let testCode = testStr.charCodeAt(i); + + // testCode.toLowerCase() for A..Z + if (isUppercaseLetter(testCode)) { + testCode = testCode | 32; + } + + if (testCode !== referenceCode) { + return false; + } + } + + return true; +} + +export function findWhiteSpaceStart(source, offset) { + for (; offset >= 0; offset--) { + if (!isWhiteSpace(source.charCodeAt(offset))) { + break; + } + } + + return offset + 1; +} + +export function findWhiteSpaceEnd(source, offset) { + for (; offset < source.length; offset++) { + if (!isWhiteSpace(source.charCodeAt(offset))) { + break; + } + } + + return offset; +} + +export function findDecimalNumberEnd(source, offset) { + for (; offset < source.length; offset++) { + if (!isDigit(source.charCodeAt(offset))) { + break; + } + } + + return offset; +} + +// § 4.3.7. Consume an escaped code point +export function consumeEscaped(source, offset) { + // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and + // that the next input code point has already been verified to be part of a valid escape. + offset += 2; + + // hex digit + if (isHexDigit(getCharCode(source, offset - 1))) { + // Consume as many hex digits as possible, but no more than 5. + // Note that this means 1-6 hex digits have been consumed in total. + for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) { + if (!isHexDigit(getCharCode(source, offset))) { + break; + } + } + + // If the next input code point is whitespace, consume it as well. + const code = getCharCode(source, offset); + if (isWhiteSpace(code)) { + offset += getNewlineLength(source, offset, code); + } + } + + return offset; +} + +// §4.3.11. Consume a name +// Note: This algorithm does not do the verification of the first few code points that are necessary +// to ensure the returned code points would constitute an <ident-token>. If that is the intended use, +// ensure that the stream starts with an identifier before calling this algorithm. +export function consumeName(source, offset) { + // Let result initially be an empty string. + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + // name code point + if (isName(code)) { + // Append the code point to result. + continue; + } + + // the stream starts with a valid escape + if (isValidEscape(code, getCharCode(source, offset + 1))) { + // Consume an escaped code point. Append the returned code point to result. + offset = consumeEscaped(source, offset) - 1; + continue; + } + + // anything else + // Reconsume the current input code point. Return result. + break; + } + + return offset; +} + +// §4.3.12. Consume a number +export function consumeNumber(source, offset) { + let code = source.charCodeAt(offset); + + // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-), + // consume it and append it to repr. + if (code === 0x002B || code === 0x002D) { + code = source.charCodeAt(offset += 1); + } + + // 3. While the next input code point is a digit, consume it and append it to repr. + if (isDigit(code)) { + offset = findDecimalNumberEnd(source, offset + 1); + code = source.charCodeAt(offset); + } + + // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then: + if (code === 0x002E && isDigit(source.charCodeAt(offset + 1))) { + // 4.1 Consume them. + // 4.2 Append them to repr. + offset += 2; + + // 4.3 Set type to "number". + // TODO + + // 4.4 While the next input code point is a digit, consume it and append it to repr. + + offset = findDecimalNumberEnd(source, offset); + } + + // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E) + // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then: + if (cmpChar(source, offset, 101 /* e */)) { + let sign = 0; + code = source.charCodeAt(offset + 1); + + // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ... + if (code === 0x002D || code === 0x002B) { + sign = 1; + code = source.charCodeAt(offset + 2); + } + + // ... followed by a digit + if (isDigit(code)) { + // 5.1 Consume them. + // 5.2 Append them to repr. + + // 5.3 Set type to "number". + // TODO + + // 5.4 While the next input code point is a digit, consume it and append it to repr. + offset = findDecimalNumberEnd(source, offset + 1 + sign + 1); + } + } + + return offset; +} + +// § 4.3.14. Consume the remnants of a bad url +// ... its sole use is to consume enough of the input stream to reach a recovery point +// where normal tokenizing can resume. +export function consumeBadUrlRemnants(source, offset) { + // Repeatedly consume the next input code point from the stream: + for (; offset < source.length; offset++) { + const code = source.charCodeAt(offset); + + // U+0029 RIGHT PARENTHESIS ()) + // EOF + if (code === 0x0029) { + // Return. + offset++; + break; + } + + if (isValidEscape(code, getCharCode(source, offset + 1))) { + // Consume an escaped code point. + // Note: This allows an escaped right parenthesis ("\)") to be encountered + // without ending the <bad-url-token>. This is otherwise identical to + // the "anything else" clause. + offset = consumeEscaped(source, offset); + } + } + + return offset; +} + +// § 4.3.7. Consume an escaped code point +// Note: This algorithm assumes that escaped is valid without leading U+005C REVERSE SOLIDUS (\) +export function decodeEscaped(escaped) { + // Single char escaped that's not a hex digit + if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) { + return escaped[0]; + } + + // Interpret the hex digits as a hexadecimal number. + let code = parseInt(escaped, 16); + + if ( + (code === 0) || // If this number is zero, + (code >= 0xD800 && code <= 0xDFFF) || // or is for a surrogate, + (code > 0x10FFFF) // or is greater than the maximum allowed code point + ) { + // ... return U+FFFD REPLACEMENT CHARACTER + code = 0xFFFD; + } + + // Otherwise, return the code point with that value. + return String.fromCodePoint(code); +} diff --git a/vanilla/node_modules/css-tree/lib/utils/List.js b/vanilla/node_modules/css-tree/lib/utils/List.js new file mode 100644 index 0000000..8953264 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/List.js @@ -0,0 +1,469 @@ +// +// list +// ┌──────┐ +// ┌──────────────┼─head │ +// │ │ tail─┼──────────────┐ +// │ └──────┘ │ +// ▼ ▼ +// item item item item +// ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ +// null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │ +// │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null +// ├──────┤ ├──────┤ ├──────┤ ├──────┤ +// │ data │ │ data │ │ data │ │ data │ +// └──────┘ └──────┘ └──────┘ └──────┘ +// + +let releasedCursors = null; + +export class List { + static createItem(data) { + return { + prev: null, + next: null, + data + }; + } + + constructor() { + this.head = null; + this.tail = null; + this.cursor = null; + } + createItem(data) { + return List.createItem(data); + } + + // cursor helpers + allocateCursor(prev, next) { + let cursor; + + if (releasedCursors !== null) { + cursor = releasedCursors; + releasedCursors = releasedCursors.cursor; + cursor.prev = prev; + cursor.next = next; + cursor.cursor = this.cursor; + } else { + cursor = { + prev, + next, + cursor: this.cursor + }; + } + + this.cursor = cursor; + + return cursor; + } + releaseCursor() { + const { cursor } = this; + + this.cursor = cursor.cursor; + cursor.prev = null; + cursor.next = null; + cursor.cursor = releasedCursors; + releasedCursors = cursor; + } + updateCursors(prevOld, prevNew, nextOld, nextNew) { + let { cursor } = this; + + while (cursor !== null) { + if (cursor.prev === prevOld) { + cursor.prev = prevNew; + } + + if (cursor.next === nextOld) { + cursor.next = nextNew; + } + + cursor = cursor.cursor; + } + } + *[Symbol.iterator]() { + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + yield cursor.data; + } + } + + // getters + get size() { + let size = 0; + + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + size++; + } + + return size; + } + get isEmpty() { + return this.head === null; + } + get first() { + return this.head && this.head.data; + } + get last() { + return this.tail && this.tail.data; + } + + // convertors + fromArray(array) { + let cursor = null; + this.head = null; + + for (let data of array) { + const item = List.createItem(data); + + if (cursor !== null) { + cursor.next = item; + } else { + this.head = item; + } + + item.prev = cursor; + cursor = item; + } + + this.tail = cursor; + return this; + } + toArray() { + return [...this]; + } + toJSON() { + return [...this]; + } + + // array-like methods + forEach(fn, thisArg = this) { + // push cursor + const cursor = this.allocateCursor(null, this.head); + + while (cursor.next !== null) { + const item = cursor.next; + cursor.next = item.next; + fn.call(thisArg, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + } + forEachRight(fn, thisArg = this) { + // push cursor + const cursor = this.allocateCursor(this.tail, null); + + while (cursor.prev !== null) { + const item = cursor.prev; + cursor.prev = item.prev; + fn.call(thisArg, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + } + reduce(fn, initialValue, thisArg = this) { + // push cursor + let cursor = this.allocateCursor(null, this.head); + let acc = initialValue; + let item; + + while (cursor.next !== null) { + item = cursor.next; + cursor.next = item.next; + + acc = fn.call(thisArg, acc, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + + return acc; + } + reduceRight(fn, initialValue, thisArg = this) { + // push cursor + let cursor = this.allocateCursor(this.tail, null); + let acc = initialValue; + let item; + + while (cursor.prev !== null) { + item = cursor.prev; + cursor.prev = item.prev; + + acc = fn.call(thisArg, acc, item.data, item, this); + } + + // pop cursor + this.releaseCursor(); + + return acc; + } + some(fn, thisArg = this) { + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + if (fn.call(thisArg, cursor.data, cursor, this)) { + return true; + } + } + + return false; + } + map(fn, thisArg = this) { + const result = new List(); + + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + result.appendData(fn.call(thisArg, cursor.data, cursor, this)); + } + + return result; + } + filter(fn, thisArg = this) { + const result = new List(); + + for (let cursor = this.head; cursor !== null; cursor = cursor.next) { + if (fn.call(thisArg, cursor.data, cursor, this)) { + result.appendData(cursor.data); + } + } + + return result; + } + + nextUntil(start, fn, thisArg = this) { + if (start === null) { + return; + } + + // push cursor + const cursor = this.allocateCursor(null, start); + + while (cursor.next !== null) { + const item = cursor.next; + cursor.next = item.next; + if (fn.call(thisArg, item.data, item, this)) { + break; + } + } + + // pop cursor + this.releaseCursor(); + } + prevUntil(start, fn, thisArg = this) { + if (start === null) { + return; + } + + // push cursor + const cursor = this.allocateCursor(start, null); + + while (cursor.prev !== null) { + const item = cursor.prev; + cursor.prev = item.prev; + if (fn.call(thisArg, item.data, item, this)) { + break; + } + } + + // pop cursor + this.releaseCursor(); + } + + // mutation + clear() { + this.head = null; + this.tail = null; + } + copy() { + const result = new List(); + + for (let data of this) { + result.appendData(data); + } + + return result; + } + prepend(item) { + // head + // ^ + // item + this.updateCursors(null, item, this.head, item); + + // insert to the beginning of the list + if (this.head !== null) { + // new item <- first item + this.head.prev = item; + // new item -> first item + item.next = this.head; + } else { + // if list has no head, then it also has no tail + // in this case tail points to the new item + this.tail = item; + } + + // head always points to new item + this.head = item; + return this; + } + prependData(data) { + return this.prepend(List.createItem(data)); + } + append(item) { + return this.insert(item); + } + appendData(data) { + return this.insert(List.createItem(data)); + } + insert(item, before = null) { + if (before !== null) { + // prev before + // ^ + // item + this.updateCursors(before.prev, item, before, item); + + if (before.prev === null) { + // insert to the beginning of list + if (this.head !== before) { + throw new Error('before doesn\'t belong to list'); + } + // since head points to before therefore list doesn't empty + // no need to check tail + this.head = item; + before.prev = item; + item.next = before; + this.updateCursors(null, item); + } else { + // insert between two items + before.prev.next = item; + item.prev = before.prev; + before.prev = item; + item.next = before; + } + } else { + // tail + // ^ + // item + this.updateCursors(this.tail, item, null, item); + + // insert to the ending of the list + if (this.tail !== null) { + // last item -> new item + this.tail.next = item; + // last item <- new item + item.prev = this.tail; + } else { + // if list has no tail, then it also has no head + // in this case head points to new item + this.head = item; + } + + // tail always points to new item + this.tail = item; + } + + return this; + } + insertData(data, before) { + return this.insert(List.createItem(data), before); + } + remove(item) { + // item + // ^ + // prev next + this.updateCursors(item, item.prev, item, item.next); + + if (item.prev !== null) { + item.prev.next = item.next; + } else { + if (this.head !== item) { + throw new Error('item doesn\'t belong to list'); + } + + this.head = item.next; + } + + if (item.next !== null) { + item.next.prev = item.prev; + } else { + if (this.tail !== item) { + throw new Error('item doesn\'t belong to list'); + } + + this.tail = item.prev; + } + + item.prev = null; + item.next = null; + + return item; + } + push(data) { + this.insert(List.createItem(data)); + } + pop() { + return this.tail !== null ? this.remove(this.tail) : null; + } + unshift(data) { + this.prepend(List.createItem(data)); + } + shift() { + return this.head !== null ? this.remove(this.head) : null; + } + prependList(list) { + return this.insertList(list, this.head); + } + appendList(list) { + return this.insertList(list); + } + insertList(list, before) { + // ignore empty lists + if (list.head === null) { + return this; + } + + if (before !== undefined && before !== null) { + this.updateCursors(before.prev, list.tail, before, list.head); + + // insert in the middle of dist list + if (before.prev !== null) { + // before.prev <-> list.head + before.prev.next = list.head; + list.head.prev = before.prev; + } else { + this.head = list.head; + } + + before.prev = list.tail; + list.tail.next = before; + } else { + this.updateCursors(this.tail, list.tail, null, list.head); + + // insert to end of the list + if (this.tail !== null) { + // if destination list has a tail, then it also has a head, + // but head doesn't change + // dest tail -> source head + this.tail.next = list.head; + // dest tail <- source head + list.head.prev = this.tail; + } else { + // if list has no a tail, then it also has no a head + // in this case points head to new item + this.head = list.head; + } + + // tail always start point to new item + this.tail = list.tail; + } + + list.head = null; + list.tail = null; + return this; + } + replace(oldItem, newItemOrList) { + if ('head' in newItemOrList) { + this.insertList(newItemOrList, oldItem); + } else { + this.insert(newItemOrList, oldItem); + } + + this.remove(oldItem); + } +} diff --git a/vanilla/node_modules/css-tree/lib/utils/clone.js b/vanilla/node_modules/css-tree/lib/utils/clone.js new file mode 100644 index 0000000..84819c0 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/clone.js @@ -0,0 +1,21 @@ +import { List } from './List.js'; + +export function clone(node) { + const result = {}; + + for (const key of Object.keys(node)) { + let value = node[key]; + + if (value) { + if (Array.isArray(value) || value instanceof List) { + value = value.map(clone); + } else if (value.constructor === Object) { + value = clone(value); + } + } + + result[key] = value; + } + + return result; +} diff --git a/vanilla/node_modules/css-tree/lib/utils/create-custom-error.js b/vanilla/node_modules/css-tree/lib/utils/create-custom-error.js new file mode 100644 index 0000000..dba122f --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/create-custom-error.js @@ -0,0 +1,14 @@ +export function createCustomError(name, message) { + // use Object.create(), because some VMs prevent setting line/column otherwise + // (iOS Safari 10 even throws an exception) + const error = Object.create(SyntaxError.prototype); + const errorStack = new Error(); + + return Object.assign(error, { + name, + message, + get stack() { + return (errorStack.stack || '').replace(/^(.+\n){1,3}/, `${name}: ${message}\n`); + } + }); +}; diff --git a/vanilla/node_modules/css-tree/lib/utils/ident.js b/vanilla/node_modules/css-tree/lib/utils/ident.js new file mode 100644 index 0000000..9cbe0f8 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/ident.js @@ -0,0 +1,101 @@ +import { + isName, + isValidEscape, + consumeEscaped, + decodeEscaped +} from '../tokenizer/index.js'; + +const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) + +export function decode(str) { + const end = str.length - 1; + let decoded = ''; + + for (let i = 0; i < str.length; i++) { + let code = str.charCodeAt(i); + + if (code === REVERSE_SOLIDUS) { + // special case at the ending + if (i === end) { + // if the next input code point is EOF, do nothing + break; + } + + code = str.charCodeAt(++i); + + // consume escaped + if (isValidEscape(REVERSE_SOLIDUS, code)) { + const escapeStart = i - 1; + const escapeEnd = consumeEscaped(str, escapeStart); + + i = escapeEnd - 1; + decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd)); + } else { + // \r\n + if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) { + i++; + } + } + } else { + decoded += str[i]; + } + } + + return decoded; +} + +// https://drafts.csswg.org/cssom/#serialize-an-identifier +// § 2.1. Common Serializing Idioms +export function encode(str) { + let encoded = ''; + + // If the character is the first character and is a "-" (U+002D), + // and there is no second character, then the escaped character. + // Note: That's means a single dash string "-" return as escaped dash, + // so move the condition out of the main loop + if (str.length === 1 && str.charCodeAt(0) === 0x002D) { + return '\\-'; + } + + // To serialize an identifier means to create a string represented + // by the concatenation of, for each character of the identifier: + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (code === 0x0000) { + encoded += '\uFFFD'; + continue; + } + + if ( + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F ... + // Note: Do not compare with 0x0001 since 0x0000 is precessed before + code <= 0x001F || code === 0x007F || + // [or] ... is in the range [0-9] (U+0030 to U+0039), + (code >= 0x0030 && code <= 0x0039 && ( + // If the character is the first character ... + i === 0 || + // If the character is the second character ... and the first character is a "-" (U+002D) + i === 1 && str.charCodeAt(0) === 0x002D + )) + ) { + // ... then the character escaped as code point. + encoded += '\\' + code.toString(16) + ' '; + continue; + } + + // If the character is not handled by one of the above rules and is greater + // than or equal to U+0080, is "-" (U+002D) or "_" (U+005F), or is in one + // of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A), + // or \[a-z] (U+0061 to U+007A), then the character itself. + if (isName(code)) { + encoded += str.charAt(i); + } else { + // Otherwise, the escaped character. + encoded += '\\' + str.charAt(i); + } + } + + return encoded; +} diff --git a/vanilla/node_modules/css-tree/lib/utils/index.js b/vanilla/node_modules/css-tree/lib/utils/index.js new file mode 100644 index 0000000..07bf0f9 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/index.js @@ -0,0 +1,6 @@ +export * from './clone.js'; +export * as ident from './ident.js'; +export * from './List.js'; +export * from './names.js'; +export * as string from './string.js'; +export * as url from './url.js'; diff --git a/vanilla/node_modules/css-tree/lib/utils/names.js b/vanilla/node_modules/css-tree/lib/utils/names.js new file mode 100644 index 0000000..b4f74b9 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/names.js @@ -0,0 +1,106 @@ +const keywords = new Map(); +const properties = new Map(); +const HYPHENMINUS = 45; // '-'.charCodeAt() + +export const keyword = getKeywordDescriptor; +export const property = getPropertyDescriptor; +export const vendorPrefix = getVendorPrefix; +export function isCustomProperty(str, offset) { + offset = offset || 0; + + return str.length - offset >= 2 && + str.charCodeAt(offset) === HYPHENMINUS && + str.charCodeAt(offset + 1) === HYPHENMINUS; +} + +function getVendorPrefix(str, offset) { + offset = offset || 0; + + // verdor prefix should be at least 3 chars length + if (str.length - offset >= 3) { + // vendor prefix starts with hyper minus following non-hyper minus + if (str.charCodeAt(offset) === HYPHENMINUS && + str.charCodeAt(offset + 1) !== HYPHENMINUS) { + // vendor prefix should contain a hyper minus at the ending + const secondDashIndex = str.indexOf('-', offset + 2); + + if (secondDashIndex !== -1) { + return str.substring(offset, secondDashIndex + 1); + } + } + } + + return ''; +} + +function getKeywordDescriptor(keyword) { + if (keywords.has(keyword)) { + return keywords.get(keyword); + } + + const name = keyword.toLowerCase(); + let descriptor = keywords.get(name); + + if (descriptor === undefined) { + const custom = isCustomProperty(name, 0); + const vendor = !custom ? getVendorPrefix(name, 0) : ''; + descriptor = Object.freeze({ + basename: name.substr(vendor.length), + name, + prefix: vendor, + vendor, + custom + }); + } + + keywords.set(keyword, descriptor); + + return descriptor; +} + +function getPropertyDescriptor(property) { + if (properties.has(property)) { + return properties.get(property); + } + + let name = property; + let hack = property[0]; + + if (hack === '/') { + hack = property[1] === '/' ? '//' : '/'; + } else if (hack !== '_' && + hack !== '*' && + hack !== '$' && + hack !== '#' && + hack !== '+' && + hack !== '&') { + hack = ''; + } + + const custom = isCustomProperty(name, hack.length); + + // re-use result when possible (the same as for lower case) + if (!custom) { + name = name.toLowerCase(); + if (properties.has(name)) { + const descriptor = properties.get(name); + properties.set(property, descriptor); + return descriptor; + } + } + + const vendor = !custom ? getVendorPrefix(name, hack.length) : ''; + const prefix = name.substr(0, hack.length + vendor.length); + const descriptor = Object.freeze({ + basename: name.substr(prefix.length), + name: name.substr(hack.length), + hack, + vendor, + prefix, + custom + }); + + properties.set(property, descriptor); + + return descriptor; +} diff --git a/vanilla/node_modules/css-tree/lib/utils/string.js b/vanilla/node_modules/css-tree/lib/utils/string.js new file mode 100644 index 0000000..928a85b --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/string.js @@ -0,0 +1,99 @@ +import { + isHexDigit, + isWhiteSpace, + isValidEscape, + consumeEscaped, + decodeEscaped +} from '../tokenizer/index.js'; + +const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) +const QUOTATION_MARK = 0x0022; // " +const APOSTROPHE = 0x0027; // ' + +export function decode(str) { + const len = str.length; + const firstChar = str.charCodeAt(0); + const start = firstChar === QUOTATION_MARK || firstChar === APOSTROPHE ? 1 : 0; + const end = start === 1 && len > 1 && str.charCodeAt(len - 1) === firstChar ? len - 2 : len - 1; + let decoded = ''; + + for (let i = start; i <= end; i++) { + let code = str.charCodeAt(i); + + if (code === REVERSE_SOLIDUS) { + // special case at the ending + if (i === end) { + // if the next input code point is EOF, do nothing + // otherwise include last quote as escaped + if (i !== len - 1) { + decoded = str.substr(i + 1); + } + break; + } + + code = str.charCodeAt(++i); + + // consume escaped + if (isValidEscape(REVERSE_SOLIDUS, code)) { + const escapeStart = i - 1; + const escapeEnd = consumeEscaped(str, escapeStart); + + i = escapeEnd - 1; + decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd)); + } else { + // \r\n + if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) { + i++; + } + } + } else { + decoded += str[i]; + } + } + + return decoded; +} + +// https://drafts.csswg.org/cssom/#serialize-a-string +// § 2.1. Common Serializing Idioms +export function encode(str, apostrophe) { + const quote = apostrophe ? '\'' : '"'; + const quoteCode = apostrophe ? APOSTROPHE : QUOTATION_MARK; + let encoded = ''; + let wsBeforeHexIsNeeded = false; + + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (code === 0x0000) { + encoded += '\uFFFD'; + continue; + } + + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, + // the character escaped as code point. + // Note: Do not compare with 0x0001 since 0x0000 is precessed before + if (code <= 0x001f || code === 0x007F) { + encoded += '\\' + code.toString(16); + wsBeforeHexIsNeeded = true; + continue; + } + + // If the character is '"' (U+0022) or "\" (U+005C), the escaped character. + if (code === quoteCode || code === REVERSE_SOLIDUS) { + encoded += '\\' + str.charAt(i); + wsBeforeHexIsNeeded = false; + } else { + if (wsBeforeHexIsNeeded && (isHexDigit(code) || isWhiteSpace(code))) { + encoded += ' '; + } + + // Otherwise, the character itself. + encoded += str.charAt(i); + wsBeforeHexIsNeeded = false; + } + } + + return quote + encoded + quote; +} diff --git a/vanilla/node_modules/css-tree/lib/utils/url.js b/vanilla/node_modules/css-tree/lib/utils/url.js new file mode 100644 index 0000000..cce5709 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/utils/url.js @@ -0,0 +1,108 @@ +import { + isHexDigit, + isWhiteSpace, + isValidEscape, + consumeEscaped, + decodeEscaped +} from '../tokenizer/index.js'; + +const SPACE = 0x0020; // U+0020 SPACE +const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) +const QUOTATION_MARK = 0x0022; // " +const APOSTROPHE = 0x0027; // ' +const LEFTPARENTHESIS = 0x0028; // U+0028 LEFT PARENTHESIS (() +const RIGHTPARENTHESIS = 0x0029; // U+0029 RIGHT PARENTHESIS ()) + +export function decode(str) { + const len = str.length; + let start = 4; // length of "url(" + let end = str.charCodeAt(len - 1) === RIGHTPARENTHESIS ? len - 2 : len - 1; + let decoded = ''; + + while (start < end && isWhiteSpace(str.charCodeAt(start))) { + start++; + } + + while (start < end && isWhiteSpace(str.charCodeAt(end))) { + end--; + } + + for (let i = start; i <= end; i++) { + let code = str.charCodeAt(i); + + if (code === REVERSE_SOLIDUS) { + // special case at the ending + if (i === end) { + // if the next input code point is EOF, do nothing + // otherwise include last left parenthesis as escaped + if (i !== len - 1) { + decoded = str.substr(i + 1); + } + break; + } + + code = str.charCodeAt(++i); + + // consume escaped + if (isValidEscape(REVERSE_SOLIDUS, code)) { + const escapeStart = i - 1; + const escapeEnd = consumeEscaped(str, escapeStart); + + i = escapeEnd - 1; + decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd)); + } else { + // \r\n + if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) { + i++; + } + } + } else { + decoded += str[i]; + } + } + + return decoded; +} + +export function encode(str) { + let encoded = ''; + let wsBeforeHexIsNeeded = false; + + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (code === 0x0000) { + encoded += '\uFFFD'; + continue; + } + + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, + // the character escaped as code point. + // Note: Do not compare with 0x0001 since 0x0000 is precessed before + if (code <= 0x001f || code === 0x007F) { + encoded += '\\' + code.toString(16); + wsBeforeHexIsNeeded = true; + continue; + } + + if (code === SPACE || + code === REVERSE_SOLIDUS || + code === QUOTATION_MARK || + code === APOSTROPHE || + code === LEFTPARENTHESIS || + code === RIGHTPARENTHESIS) { + encoded += '\\' + str.charAt(i); + wsBeforeHexIsNeeded = false; + } else { + if (wsBeforeHexIsNeeded && isHexDigit(code)) { + encoded += ' '; + } + + encoded += str.charAt(i); + wsBeforeHexIsNeeded = false; + } + } + + return 'url(' + encoded + ')'; +} diff --git a/vanilla/node_modules/css-tree/lib/version.js b/vanilla/node_modules/css-tree/lib/version.js new file mode 100644 index 0000000..dde3a83 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/version.js @@ -0,0 +1,5 @@ +import { createRequire } from 'module'; + +const require = createRequire(import.meta.url); + +export const { version } = require('../package.json'); diff --git a/vanilla/node_modules/css-tree/lib/walker/create.js b/vanilla/node_modules/css-tree/lib/walker/create.js new file mode 100644 index 0000000..ca76e03 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/walker/create.js @@ -0,0 +1,287 @@ +const { hasOwnProperty } = Object.prototype; +const noop = function() {}; + +function ensureFunction(value) { + return typeof value === 'function' ? value : noop; +} + +function invokeForType(fn, type) { + return function(node, item, list) { + if (node.type === type) { + fn.call(this, node, item, list); + } + }; +} + +function getWalkersFromStructure(name, nodeType) { + const structure = nodeType.structure; + const walkers = []; + + for (const key in structure) { + if (hasOwnProperty.call(structure, key) === false) { + continue; + } + + let fieldTypes = structure[key]; + const walker = { + name: key, + type: false, + nullable: false + }; + + if (!Array.isArray(fieldTypes)) { + fieldTypes = [fieldTypes]; + } + + for (const fieldType of fieldTypes) { + if (fieldType === null) { + walker.nullable = true; + } else if (typeof fieldType === 'string') { + walker.type = 'node'; + } else if (Array.isArray(fieldType)) { + walker.type = 'list'; + } + } + + if (walker.type) { + walkers.push(walker); + } + } + + if (walkers.length) { + return { + context: nodeType.walkContext, + fields: walkers + }; + } + + return null; +} + +function getTypesFromConfig(config) { + const types = {}; + + for (const name in config.node) { + if (hasOwnProperty.call(config.node, name)) { + const nodeType = config.node[name]; + + if (!nodeType.structure) { + throw new Error('Missed `structure` field in `' + name + '` node type definition'); + } + + types[name] = getWalkersFromStructure(name, nodeType); + } + } + + return types; +} + +function createTypeIterator(config, reverse) { + const fields = config.fields.slice(); + const contextName = config.context; + const useContext = typeof contextName === 'string'; + + if (reverse) { + fields.reverse(); + } + + return function(node, context, walk, walkReducer) { + let prevContextValue; + + if (useContext) { + prevContextValue = context[contextName]; + context[contextName] = node; + } + + for (const field of fields) { + const ref = node[field.name]; + + if (!field.nullable || ref) { + if (field.type === 'list') { + const breakWalk = reverse + ? ref.reduceRight(walkReducer, false) + : ref.reduce(walkReducer, false); + + if (breakWalk) { + return true; + } + } else if (walk(ref)) { + return true; + } + } + } + + if (useContext) { + context[contextName] = prevContextValue; + } + }; +} + +function createFastTraveralMap({ + StyleSheet, + Atrule, + Rule, + Block, + DeclarationList +}) { + return { + Atrule: { + StyleSheet, + Atrule, + Rule, + Block + }, + Rule: { + StyleSheet, + Atrule, + Rule, + Block + }, + Declaration: { + StyleSheet, + Atrule, + Rule, + Block, + DeclarationList + } + }; +} + +export function createWalker(config) { + const types = getTypesFromConfig(config); + const iteratorsNatural = {}; + const iteratorsReverse = {}; + const breakWalk = Symbol('break-walk'); + const skipNode = Symbol('skip-node'); + + for (const name in types) { + if (hasOwnProperty.call(types, name) && types[name] !== null) { + iteratorsNatural[name] = createTypeIterator(types[name], false); + iteratorsReverse[name] = createTypeIterator(types[name], true); + } + } + + const fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural); + const fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse); + + const walk = function(root, options) { + function walkNode(node, item, list) { + const enterRet = enter.call(context, node, item, list); + + if (enterRet === breakWalk) { + return true; + } + + if (enterRet === skipNode) { + return false; + } + + if (iterators.hasOwnProperty(node.type)) { + if (iterators[node.type](node, context, walkNode, walkReducer)) { + return true; + } + } + + if (leave.call(context, node, item, list) === breakWalk) { + return true; + } + + return false; + } + + let enter = noop; + let leave = noop; + let iterators = iteratorsNatural; + let walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list); + const context = { + break: breakWalk, + skip: skipNode, + + root, + stylesheet: null, + atrule: null, + atrulePrelude: null, + rule: null, + selector: null, + block: null, + declaration: null, + function: null + }; + + if (typeof options === 'function') { + enter = options; + } else if (options) { + enter = ensureFunction(options.enter); + leave = ensureFunction(options.leave); + + if (options.reverse) { + iterators = iteratorsReverse; + } + + if (options.visit) { + if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) { + iterators = options.reverse + ? fastTraversalIteratorsReverse[options.visit] + : fastTraversalIteratorsNatural[options.visit]; + } else if (!types.hasOwnProperty(options.visit)) { + throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).sort().join(', ') + ')'); + } + + enter = invokeForType(enter, options.visit); + leave = invokeForType(leave, options.visit); + } + } + + if (enter === noop && leave === noop) { + throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function'); + } + + walkNode(root); + }; + + walk.break = breakWalk; + walk.skip = skipNode; + + walk.find = function(ast, fn) { + let found = null; + + walk(ast, function(node, item, list) { + if (fn.call(this, node, item, list)) { + found = node; + return breakWalk; + } + }); + + return found; + }; + + walk.findLast = function(ast, fn) { + let found = null; + + walk(ast, { + reverse: true, + enter(node, item, list) { + if (fn.call(this, node, item, list)) { + found = node; + return breakWalk; + } + } + }); + + return found; + }; + + walk.findAll = function(ast, fn) { + const found = []; + + walk(ast, function(node, item, list) { + if (fn.call(this, node, item, list)) { + found.push(node); + } + }); + + return found; + }; + + return walk; +}; diff --git a/vanilla/node_modules/css-tree/lib/walker/index.js b/vanilla/node_modules/css-tree/lib/walker/index.js new file mode 100644 index 0000000..24cb477 --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/walker/index.js @@ -0,0 +1,4 @@ +import { createWalker } from './create.js'; +import config from '../syntax/config/walker.js'; + +export default createWalker(config); diff --git a/vanilla/node_modules/css-tree/package.json b/vanilla/node_modules/css-tree/package.json new file mode 100644 index 0000000..26e78dc --- /dev/null +++ b/vanilla/node_modules/css-tree/package.json @@ -0,0 +1,125 @@ +{ + "name": "css-tree", + "version": "3.1.0", + "description": "A tool set for CSS: fast detailed parser (CSS → AST), walker (AST traversal), generator (AST → CSS) and lexer (validation and matching) based on specs and browser implementations", + "author": "Roman Dvornov <rdvornov@gmail.com> (https://github.com/lahmatiy)", + "license": "MIT", + "repository": "csstree/csstree", + "keywords": [ + "css", + "ast", + "tokenizer", + "parser", + "walker", + "lexer", + "generator", + "utils", + "syntax", + "validation" + ], + "type": "module", + "module": "./lib/index.js", + "main": "./cjs/index.cjs", + "exports": { + ".": { + "import": "./lib/index.js", + "require": "./cjs/index.cjs" + }, + "./dist/*": "./dist/*.js", + "./package.json": "./package.json", + "./tokenizer": { + "import": "./lib/tokenizer/index.js", + "require": "./cjs/tokenizer/index.cjs" + }, + "./parser": { + "import": "./lib/parser/index.js", + "require": "./cjs/parser/index.cjs" + }, + "./selector-parser": { + "import": "./lib/parser/parse-selector.js", + "require": "./cjs/parser/parse-selector.cjs" + }, + "./generator": { + "import": "./lib/generator/index.js", + "require": "./cjs/generator/index.cjs" + }, + "./walker": { + "import": "./lib/walker/index.js", + "require": "./cjs/walker/index.cjs" + }, + "./convertor": { + "import": "./lib/convertor/index.js", + "require": "./cjs/convertor/index.cjs" + }, + "./lexer": { + "import": "./lib/lexer/index.js", + "require": "./cjs/lexer/index.cjs" + }, + "./definition-syntax": { + "import": "./lib/definition-syntax/index.js", + "require": "./cjs/definition-syntax/index.cjs" + }, + "./definition-syntax-data": { + "import": "./lib/data.js", + "require": "./cjs/data.cjs" + }, + "./definition-syntax-data-patch": { + "import": "./lib/data-patch.js", + "require": "./cjs/data-patch.cjs" + }, + "./utils": { + "import": "./lib/utils/index.js", + "require": "./cjs/utils/index.cjs" + } + }, + "browser": { + "./cjs/data.cjs": "./dist/data.cjs", + "./cjs/version.cjs": "./dist/version.cjs", + "./lib/data.js": "./dist/data.js", + "./lib/version.js": "./dist/version.js" + }, + "unpkg": "dist/csstree.esm.js", + "jsdelivr": "dist/csstree.esm.js", + "scripts": { + "watch": "npm run build -- --watch", + "build": "npm run bundle && npm run esm-to-cjs --", + "build-and-test": "npm run build && npm run test:dist && npm run test:cjs", + "bundle": "node scripts/bundle", + "bundle-and-test": "npm run bundle && npm run test:dist", + "esm-to-cjs": "node scripts/esm-to-cjs.cjs", + "esm-to-cjs-and-test": "npm run esm-to-cjs && npm run test:cjs", + "lint": "eslint lib scripts && node scripts/review-syntax-patch --lint && node scripts/update-docs --lint", + "lint-and-test": "npm run lint && npm test", + "update:docs": "node scripts/update-docs", + "review:syntax-patch": "node scripts/review-syntax-patch", + "test": "mocha lib/__tests --require lib/__tests/helpers/setup.js --reporter progress", + "test:cjs": "mocha cjs/__tests --require lib/__tests/helpers/setup.js --reporter progress", + "test:dist": "mocha dist/__tests --reporter progress", + "coverage": "c8 --exclude lib/__tests --reporter=lcovonly npm test", + "prepublishOnly": "npm run lint-and-test && npm run build-and-test" + }, + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "devDependencies": { + "c8": "^7.12.0", + "clap": "^2.0.1", + "esbuild": "^0.24.0", + "eslint": "^8.4.1", + "json-to-ast": "^2.1.0", + "mocha": "^9.2.2", + "rollup": "^2.79.2" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + }, + "files": [ + "data", + "dist", + "cjs", + "!cjs/__tests", + "lib", + "!lib/__tests" + ] +} |
