2 * @author Toru Nagashima <https://github.com/mysticatea>
3 * See LICENSE file in root directory for full license.
7 Object.defineProperty(exports, '__esModule', { value: true });
9 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
11 var path = require('path');
12 var path__default = _interopDefault(path);
13 var Evk = _interopDefault(require('eslint-visitor-keys'));
14 var sortedLastIndex = _interopDefault(require('lodash/sortedLastIndex'));
15 var assert = _interopDefault(require('assert'));
16 var last = _interopDefault(require('lodash/last'));
17 var findLastIndex = _interopDefault(require('lodash/findLastIndex'));
18 var debugFactory = _interopDefault(require('debug'));
19 var sortedIndexBy = _interopDefault(require('lodash/sortedIndexBy'));
20 var sortedLastIndexBy = _interopDefault(require('lodash/sortedLastIndexBy'));
21 var first = _interopDefault(require('lodash/first'));
22 var escope = _interopDefault(require('eslint-scope'));
23 var Module = _interopDefault(require('module'));
24 var EventEmitter = _interopDefault(require('events'));
25 var esquery = _interopDefault(require('esquery'));
26 var union = _interopDefault(require('lodash/union'));
27 var intersection = _interopDefault(require('lodash/intersection'));
28 var memoize = _interopDefault(require('lodash/memoize'));
30 function isAcornStyleParseError(x) {
31 return (typeof x.message === "string" &&
32 typeof x.pos === "number" &&
33 typeof x.loc === "object" &&
35 typeof x.loc.line === "number" &&
36 typeof x.loc.column === "number");
38 class ParseError extends SyntaxError {
39 static fromCode(code, offset, line, column) {
40 return new ParseError(code, code, offset, line, column);
43 if (ParseError.isParseError(x)) {
46 if (isAcornStyleParseError(x)) {
47 return new ParseError(x.message, undefined, x.pos, x.loc.line, x.loc.column);
51 constructor(message, code, offset, line, column) {
55 this.lineNumber = line;
58 static isParseError(x) {
59 return (x instanceof ParseError ||
60 (typeof x.message === "string" &&
61 typeof x.index === "number" &&
62 typeof x.lineNumber === "number" &&
63 typeof x.column === "number"));
67 const NS = Object.freeze({
68 HTML: "http://www.w3.org/1999/xhtml",
69 MathML: "http://www.w3.org/1998/Math/MathML",
70 SVG: "http://www.w3.org/2000/svg",
71 XLink: "http://www.w3.org/1999/xlink",
72 XML: "http://www.w3.org/XML/1998/namespace",
73 XMLNS: "http://www.w3.org/2000/xmlns/",
76 const KEYS = Evk.unionWith({
77 VAttribute: ["key", "value"],
78 VDirectiveKey: ["name", "argument", "modifiers"],
79 VDocumentFragment: ["children"],
80 VElement: ["startTag", "children", "endTag"],
82 VExpressionContainer: ["expression"],
83 VFilter: ["callee", "arguments"],
84 VFilterSequenceExpression: ["expression", "filters"],
85 VForExpression: ["left", "right"],
88 VOnExpression: ["body"],
89 VSlotScopeExpression: ["params"],
90 VStartTag: ["attributes"],
93 function fallbackKeysFilter(key) {
95 return (key !== "comments" &&
96 key !== "leadingComments" &&
101 key !== "trailingComments" &&
102 (value = this[key]) !== null &&
103 typeof value === "object" &&
104 (typeof value.type === "string" || Array.isArray(value)));
106 function getFallbackKeys(node) {
107 return Object.keys(node).filter(fallbackKeysFilter, node);
110 return x !== null && typeof x === "object" && typeof x.type === "string";
112 function traverse(node, parent, visitor) {
115 visitor.enterNode(node, parent);
116 const keys = (visitor.visitorKeys || KEYS)[node.type] || getFallbackKeys(node);
117 for (i = 0; i < keys.length; ++i) {
118 const child = node[keys[i]];
119 if (Array.isArray(child)) {
120 for (j = 0; j < child.length; ++j) {
121 if (isNode(child[j])) {
122 traverse(child[j], node, visitor);
126 else if (isNode(child)) {
127 traverse(child, node, visitor);
130 visitor.leaveNode(node, parent);
132 function traverseNodes(node, visitor) {
133 traverse(node, null, visitor);
138 var index = /*#__PURE__*/Object.freeze({
140 ParseError: ParseError,
142 traverseNodes: traverseNodes,
143 getFallbackKeys: getFallbackKeys
146 class LocationCalculator {
147 constructor(gapOffsets, ltOffsets, baseOffset) {
148 this.gapOffsets = gapOffsets;
149 this.ltOffsets = ltOffsets;
150 this.baseOffset = baseOffset || 0;
151 this.baseIndexOfGap =
152 this.baseOffset === 0
154 : sortedLastIndex(gapOffsets, this.baseOffset);
156 getSubCalculatorAfter(offset) {
157 return new LocationCalculator(this.gapOffsets, this.ltOffsets, this.baseOffset + offset);
159 _getLocation(offset) {
160 const line = sortedLastIndex(this.ltOffsets, offset) + 1;
161 const column = offset - (line === 1 ? 0 : this.ltOffsets[line - 2]);
162 return { line, column };
165 const offsets = this.gapOffsets;
166 let g0 = sortedLastIndex(offsets, index + this.baseOffset);
167 let pos = index + this.baseOffset + g0 - this.baseIndexOfGap;
168 while (g0 < offsets.length && offsets[g0] <= pos) {
172 return g0 - this.baseIndexOfGap;
175 return this._getLocation(this.baseOffset + index);
177 getOffsetWithGap(index) {
178 return this.baseOffset + index + this._getGap(index);
181 const range = node.range;
182 const loc = node.loc;
183 const gap0 = this._getGap(range[0]);
184 const gap1 = this._getGap(range[1]);
185 const d0 = this.baseOffset + Math.max(0, gap0);
186 const d1 = this.baseOffset + Math.max(0, gap1);
189 if (node.start != null) {
192 loc.start = this._getLocation(range[0]);
196 if (node.end != null) {
199 loc.end = this._getLocation(range[1]);
203 fixErrorLocation(error) {
204 const gap = this._getGap(error.index);
205 const diff = this.baseOffset + Math.max(0, gap);
207 const loc = this._getLocation(error.index);
208 error.lineNumber = loc.line;
209 error.column = loc.column;
213 const debug = debugFactory("vue-eslint-parser");
215 function isUnique(reference, index, references) {
216 return (index === 0 || reference.identifier !== references[index - 1].identifier);
218 function hasDefinition(variable) {
219 return variable.defs.length >= 1;
221 function transformReference(reference) {
223 id: reference.identifier,
224 mode: reference.isReadOnly()
226 : reference.isWriteOnly()
231 Object.defineProperty(ret, "variable", { enumerable: false });
234 function transformVariable(variable) {
236 id: variable.defs[0].name,
237 kind: variable.scope.type === "for" ? "v-for" : "scope",
240 Object.defineProperty(ret, "references", { enumerable: false });
243 function getForScope(scope) {
244 const child = scope.childScopes[0];
245 return child.block === scope.block ? child.childScopes[0] : child;
247 function analyze(ast, parserOptions) {
248 const ecmaVersion = parserOptions.ecmaVersion || 2017;
249 const ecmaFeatures = parserOptions.ecmaFeatures || {};
250 const sourceType = parserOptions.sourceType || "script";
251 const result = escope.analyze(ast, {
254 impliedStrict: ecmaFeatures.impliedStrict,
257 fallback: getFallbackKeys,
259 return result.globalScope;
261 function analyzeExternalReferences(ast, parserOptions) {
262 const scope = analyze(ast, parserOptions);
263 return scope.through.filter(isUnique).map(transformReference);
265 function analyzeVariablesAndExternalReferences(ast, parserOptions) {
266 const scope = analyze(ast, parserOptions);
268 variables: getForScope(scope)
269 .variables.filter(hasDefinition)
270 .map(transformVariable),
271 references: scope.through.filter(isUnique).map(transformReference),
275 const createRequire = Module.createRequire ||
276 Module.createRequireFromPath ||
278 const mod = new Module(filename);
279 mod.filename = filename;
280 mod.paths = Module._nodeModulePaths(path__default.dirname(filename));
281 mod._compile("module.exports = require;", filename);
284 let espreeCache = null;
285 function isLinterPath(p) {
286 return (p.includes(`eslint${path__default.sep}lib${path__default.sep}linter${path__default.sep}linter.js`) ||
287 p.includes(`eslint${path__default.sep}lib${path__default.sep}linter.js`));
289 function getEspree() {
291 const linterPath = Object.keys(require.cache).find(isLinterPath);
294 espreeCache = createRequire(linterPath)("espree");
300 espreeCache = require("espree");
306 const ALIAS_PARENS = /^(\s*)\(([\s\S]+)\)(\s*(?:in|of)\b[\s\S]+)$/u;
307 const DUMMY_PARENT = {};
308 const IS_FUNCTION_EXPRESSION = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/u;
309 const IS_SIMPLE_PATH = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?'\]|\["[^"]*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/u;
310 function postprocess(result, locationCalculator) {
311 const traversed = new Set();
312 traverseNodes(result.ast, {
313 visitorKeys: result.visitorKeys,
314 enterNode(node, parent) {
315 if (!traversed.has(node)) {
317 node.parent = parent;
318 if (!traversed.has(node.range)) {
319 traversed.add(node.range);
320 locationCalculator.fixLocation(node);
327 for (const token of result.ast.tokens || []) {
328 locationCalculator.fixLocation(token);
330 for (const comment of result.ast.comments || []) {
331 locationCalculator.fixLocation(comment);
334 function replaceAliasParens(code) {
335 const match = ALIAS_PARENS.exec(code);
337 return `${match[1]}[${match[2]}]${match[3]}`;
341 function normalizeLeft(left, replaced) {
342 if (left.type !== "VariableDeclaration") {
343 throw new Error("unreachable");
345 const id = left.declarations[0].id;
351 function getCommaTokenBeforeNode(tokens, node) {
352 let tokenIndex = sortedIndexBy(tokens, { range: node.range }, t => t.range[0]);
353 while (tokenIndex >= 0) {
354 const token = tokens[tokenIndex];
355 if (token.type === "Punctuator" && token.value === ",") {
362 function throwEmptyError(locationCalculator, expected) {
363 const loc = locationCalculator.getLocation(0);
364 const err = new ParseError(`Expected to be ${expected}, but got empty.`, undefined, 0, loc.line, loc.column);
365 locationCalculator.fixErrorLocation(err);
368 function throwUnexpectedTokenError(name, token) {
369 const err = new ParseError(`Unexpected token '${name}'.`, undefined, token.range[0], token.loc.start.line, token.loc.start.column);
372 function throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator) {
373 if (ParseError.isParseError(err)) {
374 const endOffset = locationCalculator.getOffsetWithGap(code.length);
375 if (err.index >= endOffset) {
376 err.message = "Unexpected end of expression.";
381 function parseScriptFragment(code, locationCalculator, parserOptions) {
383 const result = parseScript(code, parserOptions);
384 postprocess(result, locationCalculator);
388 const perr = ParseError.normalize(err);
390 locationCalculator.fixErrorLocation(perr);
396 const validDivisionCharRE = /[\w).+\-_$\]]/u;
397 function splitFilters(exp) {
399 let inSingle = false;
400 let inDouble = false;
401 let inTemplateString = false;
406 let lastFilterIndex = 0;
409 for (let i = 0; i < exp.length; i++) {
411 c = exp.charCodeAt(i);
413 if (c === 0x27 && prev !== 0x5c) {
418 if (c === 0x22 && prev !== 0x5c) {
422 else if (inTemplateString) {
423 if (c === 0x60 && prev !== 0x5c) {
424 inTemplateString = false;
428 if (c === 0x2f && prev !== 0x5c) {
432 else if (c === 0x7c &&
433 exp.charCodeAt(i + 1) !== 0x7c &&
434 exp.charCodeAt(i - 1) !== 0x7c &&
438 result.push(exp.slice(lastFilterIndex, i));
439 lastFilterIndex = i + 1;
450 inTemplateString = true;
474 for (; j >= 0; j--) {
480 if (!p || !validDivisionCharRE.test(p)) {
486 result.push(exp.slice(lastFilterIndex));
489 function parseExpressionBody(code, locationCalculator, parserOptions, allowEmpty = false) {
490 debug('[script] parse expression: "0(%s)"', code);
492 const ast = parseScriptFragment(`0(${code})`, locationCalculator.getSubCalculatorAfter(-2), parserOptions).ast;
493 const tokens = ast.tokens || [];
494 const comments = ast.comments || [];
495 const references = analyzeExternalReferences(ast, parserOptions);
496 const statement = ast.body[0];
497 const callExpression = statement.expression;
498 const expression = callExpression.arguments[0];
499 if (!allowEmpty && !expression) {
500 return throwEmptyError(locationCalculator, "an expression");
502 if (expression && expression.type === "SpreadElement") {
503 return throwUnexpectedTokenError("...", expression);
505 if (callExpression.arguments[1]) {
506 const node = callExpression.arguments[1];
507 return throwUnexpectedTokenError(",", getCommaTokenBeforeNode(tokens, node) || node);
512 return { expression, tokens, comments, references, variables: [] };
515 return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
518 function parseFilter(code, locationCalculator, parserOptions) {
519 debug('[script] parse filter: "%s"', code);
531 const references = [];
532 const paren = code.indexOf("(");
533 const calleeCode = paren === -1 ? code : code.slice(0, paren);
534 const argsCode = paren === -1 ? null : code.slice(paren);
535 if (calleeCode.trim()) {
536 const spaces = /^\s*/u.exec(calleeCode)[0];
537 const { ast } = parseScriptFragment(`${spaces}"${calleeCode.trim()}"`, locationCalculator, parserOptions);
538 const statement = ast.body[0];
539 const callee = statement.expression;
540 if (callee.type !== "Literal") {
541 const { loc, range } = ast.tokens[0];
542 return throwUnexpectedTokenError('"', {
543 range: [range[1] - 1, range[1]],
547 column: loc.end.column - 1,
553 expression.callee = {
556 range: [callee.range[0], callee.range[1] - 2],
558 start: callee.loc.start,
559 end: locationCalculator.getLocation(callee.range[1] - callee.range[0] - 1),
561 name: String(callee.value),
565 value: calleeCode.trim(),
566 range: expression.callee.range,
567 loc: expression.callee.loc,
571 return throwEmptyError(locationCalculator, "a filter name");
573 if (argsCode != null) {
574 const { ast } = parseScriptFragment(`0${argsCode}`, locationCalculator.getSubCalculatorAfter(paren - 1), parserOptions);
575 const statement = ast.body[0];
576 const callExpression = statement.expression;
578 if (callExpression.type !== "CallExpression" ||
579 callExpression.callee.type !== "Literal") {
581 for (const token of ast.tokens.slice(1)) {
582 if (nestCount === 0) {
583 return throwUnexpectedTokenError(token.value, token);
585 if (token.type === "Punctuator" && token.value === "(") {
588 if (token.type === "Punctuator" && token.value === ")") {
592 const token = last(ast.tokens);
593 return throwUnexpectedTokenError(token.value, token);
595 for (const argument of callExpression.arguments) {
596 argument.parent = expression;
597 expression.arguments.push(argument);
599 tokens.push(...ast.tokens);
600 comments.push(...ast.comments);
601 references.push(...analyzeExternalReferences(ast, parserOptions));
603 const firstToken = tokens[0];
604 const lastToken = last(tokens);
605 expression.range = [firstToken.range[0], lastToken.range[1]];
606 expression.loc = { start: firstToken.loc.start, end: lastToken.loc.end };
607 return { expression, tokens, comments, references, variables: [] };
610 return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
613 function parseScript(code, parserOptions) {
614 const parser = typeof parserOptions.parser === "string"
616 require(parserOptions.parser)
618 const result = typeof parser.parseForESLint === "function"
619 ? parser.parseForESLint(code, parserOptions)
620 : parser.parse(code, parserOptions);
621 if (result.ast != null) {
624 return { ast: result };
626 function parseScriptElement(node, globalLocationCalculator, parserOptions) {
627 const text = node.children[0];
628 const offset = text != null && text.type === "VText"
630 : node.startTag.range[1];
631 const code = text != null && text.type === "VText" ? text.value : "";
632 const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(offset);
633 const result = parseScriptFragment(code, locationCalculator, parserOptions);
634 if (result.ast.tokens != null) {
635 const startTag = node.startTag;
636 const endTag = node.endTag;
637 if (startTag != null) {
638 result.ast.tokens.unshift({
640 range: startTag.range,
645 if (endTag != null) {
646 result.ast.tokens.push({
656 function parseExpression(code, locationCalculator, parserOptions, { allowEmpty = false, allowFilters = false } = {}) {
657 debug('[script] parse expression: "%s"', code);
658 const [mainCode, ...filterCodes] = allowFilters
661 if (filterCodes.length === 0) {
662 return parseExpressionBody(code, locationCalculator, parserOptions, allowEmpty);
664 const retB = parseExpressionBody(mainCode, locationCalculator, parserOptions);
665 if (!retB.expression) {
670 type: "VFilterSequenceExpression",
672 expression: retB.expression,
674 range: retB.expression.range.slice(0),
675 loc: Object.assign({}, retB.expression.loc),
677 ret.expression.expression.parent = ret.expression;
678 let prevLoc = mainCode.length;
679 for (const filterCode of filterCodes) {
680 ret.tokens.push(locationCalculator.fixLocation({
683 range: [prevLoc, prevLoc + 1],
686 const retF = parseFilter(filterCode, locationCalculator.getSubCalculatorAfter(prevLoc + 1), parserOptions);
688 if (retF.expression) {
689 ret.expression.filters.push(retF.expression);
690 retF.expression.parent = ret.expression;
692 ret.tokens.push(...retF.tokens);
693 ret.comments.push(...retF.comments);
694 ret.references.push(...retF.references);
696 prevLoc += 1 + filterCode.length;
698 const lastToken = last(ret.tokens);
699 ret.expression.range[1] = lastToken.range[1];
700 ret.expression.loc.end = lastToken.loc.end;
703 function parseVForExpression(code, locationCalculator, parserOptions) {
704 const processedCode = replaceAliasParens(code);
705 debug('[script] parse v-for expression: "for(%s);"', processedCode);
706 if (code.trim() === "") {
707 throwEmptyError(locationCalculator, "'<alias> in <expression>'");
710 const replaced = processedCode !== code;
711 const ast = parseScriptFragment(`for(let ${processedCode});`, locationCalculator.getSubCalculatorAfter(-8), parserOptions).ast;
712 const tokens = ast.tokens || [];
713 const comments = ast.comments || [];
714 const scope = analyzeVariablesAndExternalReferences(ast, parserOptions);
715 const references = scope.references;
716 const variables = scope.variables;
717 const statement = ast.body[0];
718 const left = normalizeLeft(statement.left, replaced);
719 const right = statement.right;
720 const firstToken = tokens[3] || statement.left;
721 const lastToken = tokens[tokens.length - 3] || statement.right;
723 type: "VForExpression",
724 range: [firstToken.range[0], lastToken.range[1]],
725 loc: { start: firstToken.loc.start, end: lastToken.loc.end },
726 parent: DUMMY_PARENT,
730 for (const l of left) {
732 l.parent = expression;
735 right.parent = expression;
742 const closeOffset = statement.left.range[1] - 1;
743 const open = tokens[0];
744 const close = tokens.find(t => t.range[0] === closeOffset);
752 return { expression, tokens, comments, references, variables };
755 return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
758 function parseVOnExpression(code, locationCalculator, parserOptions) {
759 if (IS_FUNCTION_EXPRESSION.test(code) || IS_SIMPLE_PATH.test(code)) {
760 return parseExpressionBody(code, locationCalculator, parserOptions);
762 return parseVOnExpressionBody(code, locationCalculator, parserOptions);
764 function parseVOnExpressionBody(code, locationCalculator, parserOptions) {
765 debug('[script] parse v-on expression: "void function($event){%s}"', code);
766 if (code.trim() === "") {
767 throwEmptyError(locationCalculator, "statements");
770 const ast = parseScriptFragment(`void function($event){${code}}`, locationCalculator.getSubCalculatorAfter(-22), parserOptions).ast;
771 const references = analyzeExternalReferences(ast, parserOptions);
772 const outermostStatement = ast.body[0];
773 const functionDecl = outermostStatement.expression
775 const block = functionDecl.body;
776 const body = block.body;
777 const firstStatement = first(body);
778 const lastStatement = last(body);
780 type: "VOnExpression",
782 firstStatement != null
783 ? firstStatement.range[0]
784 : block.range[0] + 1,
785 lastStatement != null
786 ? lastStatement.range[1]
787 : block.range[1] - 1,
790 start: firstStatement != null
791 ? firstStatement.loc.start
792 : locationCalculator.getLocation(1),
793 end: lastStatement != null
794 ? lastStatement.loc.end
795 : locationCalculator.getLocation(code.length + 1),
797 parent: DUMMY_PARENT,
800 const tokens = ast.tokens || [];
801 const comments = ast.comments || [];
802 for (const b of body) {
803 b.parent = expression;
807 return { expression, tokens, comments, references, variables: [] };
810 return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
813 function parseSlotScopeExpression(code, locationCalculator, parserOptions) {
814 debug('[script] parse slot-scope expression: "void function(%s) {}"', code);
815 if (code.trim() === "") {
816 throwEmptyError(locationCalculator, "an identifier or an array/object pattern");
819 const ast = parseScriptFragment(`void function(${code}) {}`, locationCalculator.getSubCalculatorAfter(-14), parserOptions).ast;
820 const statement = ast.body[0];
821 const rawExpression = statement.expression;
822 const functionDecl = rawExpression.argument;
823 const params = functionDecl.params;
824 if (params.length === 0) {
833 const tokens = ast.tokens || [];
834 const comments = ast.comments || [];
835 const scope = analyzeVariablesAndExternalReferences(ast, parserOptions);
836 const references = scope.references;
837 const variables = scope.variables;
838 const firstParam = first(params);
839 const lastParam = last(params);
841 type: "VSlotScopeExpression",
842 range: [firstParam.range[0], lastParam.range[1]],
843 loc: { start: firstParam.loc.start, end: lastParam.loc.end },
844 parent: DUMMY_PARENT,
845 params: functionDecl.params,
847 for (const param of params) {
848 param.parent = expression;
856 return { expression, tokens, comments, references, variables };
859 return throwErrorAsAdjustingOutsideOfCode(err, code, locationCalculator);
863 const shorthandSign = /^[.:@#]/u;
864 const shorthandNameMap = { ":": "bind", ".": "bind", "@": "on", "#": "slot" };
865 const invalidDynamicArgumentNextChar = /^[\s\r\n=/>]$/u;
866 function getOwnerDocument(leafNode) {
868 while (node != null && node.type !== "VDocumentFragment") {
873 function createSimpleToken(type, start, end, value, globalLocationCalculator) {
878 start: globalLocationCalculator.getLocation(start),
879 end: globalLocationCalculator.getLocation(end),
884 function parseDirectiveKeyStatically(node, document) {
885 const { name: text, rawName: rawText, range: [offset], loc: { start: { column, line }, }, } = node;
886 const directiveKey = {
887 type: "VDirectiveKey",
896 function createIdentifier(start, end, name) {
899 parent: directiveKey,
900 range: [offset + start, offset + end],
902 start: { column: column + start, line },
903 end: { column: column + end, line },
905 name: name || text.slice(start, end),
906 rawName: rawText.slice(start, end),
909 if (shorthandSign.test(text)) {
910 const sign = text[0];
911 directiveKey.name = createIdentifier(0, 1, shorthandNameMap[sign]);
915 const colon = text.indexOf(":");
917 directiveKey.name = createIdentifier(0, colon);
921 if (directiveKey.name != null && text[i] === "[") {
922 const len = text.slice(i).lastIndexOf("]");
924 directiveKey.argument = createIdentifier(i, i + len + 1);
925 i = i + len + 1 + (text[i + len + 1] === "." ? 1 : 0);
928 const modifiers = text
931 .map(modifierName => {
932 const modifier = createIdentifier(i, i + modifierName.length);
933 if (modifierName === "" && i < text.length) {
934 insertError(document, new ParseError(`Unexpected token '${text[i]}'`, undefined, offset + i, line, column + i));
936 i += modifierName.length + 1;
939 if (directiveKey.name == null) {
940 directiveKey.name = modifiers.shift();
942 else if (directiveKey.argument == null && modifiers[0].name !== "") {
943 directiveKey.argument = modifiers.shift() || null;
945 directiveKey.modifiers = modifiers.filter(isNotEmptyModifier);
946 if (directiveKey.name.name === "v-") {
947 insertError(document, new ParseError(`Unexpected token '${text[directiveKey.name.range[1] - offset]}'`, undefined, directiveKey.name.range[1], directiveKey.name.loc.end.line, directiveKey.name.loc.end.column));
949 if (directiveKey.name.rawName === "." &&
950 !directiveKey.modifiers.some(isPropModifier)) {
951 const pos = (directiveKey.argument || directiveKey.name).range[1] - offset;
952 const propModifier = createIdentifier(pos, pos, "prop");
953 directiveKey.modifiers.unshift(propModifier);
957 function isPropModifier(node) {
958 return node.name === "prop";
960 function isNotEmptyModifier(node) {
961 return node.name !== "";
963 function parseDirectiveKeyTokens(node) {
964 const { name, argument, modifiers } = node;
965 const shorthand = name.range[1] - name.range[0] === 1;
977 type: "HTMLIdentifier",
985 range: [name.range[1], argument.range[0]],
986 loc: { start: name.loc.end, end: argument.loc.start },
993 type: "HTMLIdentifier",
994 range: argument.range,
996 value: argument.rawName,
999 let lastNode = argument || name;
1000 for (const modifier of modifiers) {
1001 if (modifier.rawName === "") {
1006 range: [lastNode.range[1], modifier.range[0]],
1007 loc: { start: lastNode.loc.end, end: modifier.loc.start },
1010 type: "HTMLIdentifier",
1011 range: modifier.range,
1013 value: modifier.rawName,
1015 lastNode = modifier;
1019 function convertDynamicArgument(node, document, parserOptions, locationCalculator) {
1020 const { argument } = node;
1021 if (!(argument != null &&
1022 argument.type === "VIdentifier" &&
1023 argument.name.startsWith("[") &&
1024 argument.name.endsWith("]"))) {
1027 const { rawName, range, loc } = argument;
1029 const { comments, expression, references, tokens } = parseExpression(rawName.slice(1, -1), locationCalculator.getSubCalculatorAfter(range[0] + 1), parserOptions);
1031 type: "VExpressionContainer",
1038 if (expression != null) {
1039 expression.parent = node.argument;
1041 tokens.unshift(createSimpleToken("Punctuator", range[0], range[0] + 1, "[", locationCalculator));
1042 tokens.push(createSimpleToken("Punctuator", range[1] - 1, range[1], "]", locationCalculator));
1043 replaceTokens(document, node.argument, tokens);
1044 insertComments(document, comments);
1047 debug("[template] Parse error: %s", error);
1048 if (ParseError.isParseError(error)) {
1050 type: "VExpressionContainer",
1057 insertError(document, error);
1064 function createDirectiveKey(node, document, parserOptions, locationCalculator) {
1065 const directiveKey = parseDirectiveKeyStatically(node, document);
1066 const tokens = parseDirectiveKeyTokens(directiveKey);
1067 replaceTokens(document, directiveKey, tokens);
1068 if (directiveKey.name.name.startsWith("v-")) {
1069 directiveKey.name.name = directiveKey.name.name.slice(2);
1071 if (directiveKey.name.rawName.startsWith("v-")) {
1072 directiveKey.name.rawName = directiveKey.name.rawName.slice(2);
1074 convertDynamicArgument(directiveKey, document, parserOptions, locationCalculator);
1075 return directiveKey;
1077 function byRange0(x) {
1080 function byRange1(x) {
1083 function byIndex(x) {
1086 function replaceTokens(document, node, newTokens) {
1087 if (document == null) {
1090 const index = sortedIndexBy(document.tokens, node, byRange0);
1091 const count = sortedLastIndexBy(document.tokens, node, byRange1) - index;
1092 document.tokens.splice(index, count, ...newTokens);
1094 function insertComments(document, newComments) {
1095 if (document == null || newComments.length === 0) {
1098 const index = sortedIndexBy(document.comments, newComments[0], byRange0);
1099 document.comments.splice(index, 0, ...newComments);
1101 function insertError(document, error) {
1102 if (document == null) {
1105 const index = sortedIndexBy(document.errors, error, byIndex);
1106 document.errors.splice(index, 0, error);
1108 function parseAttributeValue(code, parserOptions, globalLocationCalculator, node, tagName, directiveKey) {
1109 const firstChar = code[node.range[0]];
1110 const quoted = firstChar === '"' || firstChar === "'";
1111 const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(node.range[0] + (quoted ? 1 : 0));
1112 const directiveName = directiveKey.name.name;
1114 if (quoted && node.value === "") {
1123 else if (directiveName === "for") {
1124 result = parseVForExpression(node.value, locationCalculator, parserOptions);
1126 else if (directiveName === "on" && directiveKey.argument != null) {
1127 result = parseVOnExpression(node.value, locationCalculator, parserOptions);
1129 else if (directiveName === "slot" ||
1130 directiveName === "slot-scope" ||
1131 (tagName === "template" && directiveName === "scope")) {
1132 result = parseSlotScopeExpression(node.value, locationCalculator, parserOptions);
1134 else if (directiveName === "bind") {
1135 result = parseExpression(node.value, locationCalculator, parserOptions, { allowFilters: true });
1138 result = parseExpression(node.value, locationCalculator, parserOptions);
1141 result.tokens.unshift(createSimpleToken("Punctuator", node.range[0], node.range[0] + 1, firstChar, globalLocationCalculator));
1142 result.tokens.push(createSimpleToken("Punctuator", node.range[1] - 1, node.range[1], firstChar, globalLocationCalculator));
1146 function resolveReference(referene, element) {
1148 while (node != null && node.type === "VElement") {
1149 for (const variable of node.variables) {
1150 if (variable.id.name === referene.id.name) {
1151 referene.variable = variable;
1152 variable.references.push(referene);
1159 function convertToDirective(code, parserOptions, locationCalculator, node) {
1160 debug('[template] convert to directive: %s="%s" %j', node.key.name, node.value && node.value.value, node.range);
1161 const document = getOwnerDocument(node);
1162 const directive = node;
1163 directive.directive = true;
1164 directive.key = createDirectiveKey(node.key, document, parserOptions, locationCalculator);
1165 const { argument } = directive.key;
1167 argument.type === "VIdentifier" &&
1168 argument.name.startsWith("[")) {
1169 const nextChar = code[argument.range[1]];
1170 if (nextChar == null || invalidDynamicArgumentNextChar.test(nextChar)) {
1171 const char = nextChar == null ? "EOF" : JSON.stringify(nextChar).slice(1, -1);
1172 insertError(document, new ParseError(`Dynamic argument cannot contain the '${char}' character.`, undefined, argument.range[1], argument.loc.end.line, argument.loc.end.column));
1175 if (node.value == null) {
1179 const ret = parseAttributeValue(code, parserOptions, locationCalculator, node.value, node.parent.parent.name, directive.key);
1181 type: "VExpressionContainer",
1182 range: node.value.range,
1183 loc: node.value.loc,
1185 expression: ret.expression,
1186 references: ret.references,
1188 if (ret.expression != null) {
1189 ret.expression.parent = directive.value;
1191 for (const variable of ret.variables) {
1192 node.parent.parent.variables.push(variable);
1194 replaceTokens(document, node.value, ret.tokens);
1195 insertComments(document, ret.comments);
1198 debug("[template] Parse error: %s", err);
1199 if (ParseError.isParseError(err)) {
1201 type: "VExpressionContainer",
1202 range: node.value.range,
1203 loc: node.value.loc,
1208 insertError(document, err);
1215 function processMustache(parserOptions, globalLocationCalculator, node, mustache) {
1217 mustache.startToken.range[1],
1218 mustache.endToken.range[0],
1220 debug("[template] convert mustache {{%s}} %j", mustache.value, range);
1221 const document = getOwnerDocument(node);
1223 const locationCalculator = globalLocationCalculator.getSubCalculatorAfter(range[0]);
1224 const ret = parseExpression(mustache.value, locationCalculator, parserOptions, { allowEmpty: true, allowFilters: true });
1225 node.expression = ret.expression || null;
1226 node.references = ret.references;
1227 if (ret.expression != null) {
1228 ret.expression.parent = node;
1230 replaceTokens(document, { range }, ret.tokens);
1231 insertComments(document, ret.comments);
1234 debug("[template] Parse error: %s", err);
1235 if (ParseError.isParseError(err)) {
1236 insertError(document, err);
1243 function resolveReferences(container) {
1244 let element = container.parent;
1245 while (element != null && element.type !== "VElement") {
1246 element = element.parent;
1248 if (element != null) {
1249 for (const reference of container.references) {
1250 resolveReference(reference, element);
1255 const SVG_ATTRIBUTE_NAME_MAP = new Map([
1256 ["attributename", "attributeName"],
1257 ["attributetype", "attributeType"],
1258 ["basefrequency", "baseFrequency"],
1259 ["baseprofile", "baseProfile"],
1260 ["calcmode", "calcMode"],
1261 ["clippathunits", "clipPathUnits"],
1262 ["diffuseconstant", "diffuseConstant"],
1263 ["edgemode", "edgeMode"],
1264 ["filterunits", "filterUnits"],
1265 ["glyphref", "glyphRef"],
1266 ["gradienttransform", "gradientTransform"],
1267 ["gradientunits", "gradientUnits"],
1268 ["kernelmatrix", "kernelMatrix"],
1269 ["kernelunitlength", "kernelUnitLength"],
1270 ["keypoints", "keyPoints"],
1271 ["keysplines", "keySplines"],
1272 ["keytimes", "keyTimes"],
1273 ["lengthadjust", "lengthAdjust"],
1274 ["limitingconeangle", "limitingConeAngle"],
1275 ["markerheight", "markerHeight"],
1276 ["markerunits", "markerUnits"],
1277 ["markerwidth", "markerWidth"],
1278 ["maskcontentunits", "maskContentUnits"],
1279 ["maskunits", "maskUnits"],
1280 ["numoctaves", "numOctaves"],
1281 ["pathlength", "pathLength"],
1282 ["patterncontentunits", "patternContentUnits"],
1283 ["patterntransform", "patternTransform"],
1284 ["patternunits", "patternUnits"],
1285 ["pointsatx", "pointsAtX"],
1286 ["pointsaty", "pointsAtY"],
1287 ["pointsatz", "pointsAtZ"],
1288 ["preservealpha", "preserveAlpha"],
1289 ["preserveaspectratio", "preserveAspectRatio"],
1290 ["primitiveunits", "primitiveUnits"],
1293 ["repeatcount", "repeatCount"],
1294 ["repeatdur", "repeatDur"],
1295 ["requiredextensions", "requiredExtensions"],
1296 ["requiredfeatures", "requiredFeatures"],
1297 ["specularconstant", "specularConstant"],
1298 ["specularexponent", "specularExponent"],
1299 ["spreadmethod", "spreadMethod"],
1300 ["startoffset", "startOffset"],
1301 ["stddeviation", "stdDeviation"],
1302 ["stitchtiles", "stitchTiles"],
1303 ["surfacescale", "surfaceScale"],
1304 ["systemlanguage", "systemLanguage"],
1305 ["tablevalues", "tableValues"],
1306 ["targetx", "targetX"],
1307 ["targety", "targetY"],
1308 ["textlength", "textLength"],
1309 ["viewbox", "viewBox"],
1310 ["viewtarget", "viewTarget"],
1311 ["xchannelselector", "xChannelSelector"],
1312 ["ychannelselector", "yChannelSelector"],
1313 ["zoomandpan", "zoomAndPan"],
1315 const MATHML_ATTRIBUTE_NAME_MAP = new Map([
1316 ["definitionurl", "definitionUrl"]
1319 const HTML_VOID_ELEMENT_TAGS = new Set([
1320 "area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta",
1321 "param", "source", "track", "wbr",
1323 const HTML_CAN_BE_LEFT_OPEN_TAGS = new Set([
1324 "colgroup", "li", "options", "p", "td", "tfoot", "th", "thead",
1327 const HTML_NON_FHRASING_TAGS = new Set([
1328 "address", "article", "aside", "base", "blockquote", "body", "caption",
1329 "col", "colgroup", "dd", "details", "dialog", "div", "dl", "dt", "fieldset",
1330 "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5",
1331 "h6", "head", "header", "hgroup", "hr", "html", "legend", "li", "menuitem",
1332 "meta", "optgroup", "option", "param", "rp", "rt", "source", "style",
1333 "summary", "tbody", "td", "tfoot", "th", "thead", "title", "tr", "track",
1335 const HTML_RCDATA_TAGS = new Set([
1336 "title", "textarea",
1338 const HTML_RAWTEXT_TAGS = new Set([
1339 "style", "xmp", "iframe", "noembed", "noframes", "noscript", "script",
1341 const SVG_TAGS = new Set([
1342 "a", "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor",
1343 "animateMotion", "animateTransform", "animation", "audio", "canvas",
1344 "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "discard",
1345 "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite",
1346 "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap",
1347 "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB",
1348 "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode",
1349 "feMorphology", "feOffset", "fePointLight", "feSpecularLighting",
1350 "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face",
1351 "font-face-format", "font-face-name", "font-face-src", "font-face-uri",
1352 "foreignObject", "g", "glyph", "glyphRef", "handler", "hatch", "hatchpath",
1353 "hkern", "iframe", "image", "line", "linearGradient", "listener", "marker",
1354 "mask", "mesh", "meshgradient", "meshpatch", "meshrow", "metadata",
1355 "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline",
1356 "prefetch", "radialGradient", "rect", "script", "set", "solidColor",
1357 "solidcolor", "stop", "style", "svg", "switch", "symbol", "tbreak", "text",
1358 "textArea", "textPath", "title", "tref", "tspan", "unknown", "use", "video",
1361 const SVG_ELEMENT_NAME_MAP = new Map();
1362 for (const name of SVG_TAGS) {
1363 if (/[A-Z]/.test(name)) {
1364 SVG_ELEMENT_NAME_MAP.set(name.toLowerCase(), name);
1368 const DUMMY_PARENT$1 = Object.freeze({});
1369 function concat(text, token) {
1370 return text + token.value;
1372 class IntermediateTokenizer {
1374 return this.tokenizer.text;
1377 return this.tokenizer.errors;
1380 return this.tokenizer.state;
1383 this.tokenizer.state = value;
1386 return this.tokenizer.namespace;
1388 set namespace(value) {
1389 this.tokenizer.namespace = value;
1391 get expressionEnabled() {
1392 return this.tokenizer.expressionEnabled;
1394 set expressionEnabled(value) {
1395 this.tokenizer.expressionEnabled = value;
1397 constructor(tokenizer) {
1398 this.tokenizer = tokenizer;
1399 this.currentToken = null;
1400 this.attribute = null;
1401 this.attributeNames = new Set();
1402 this.expressionStartToken = null;
1403 this.expressionTokens = [];
1410 while (result == null && (token = this.tokenizer.nextToken()) != null) {
1411 result = this[token.type](token);
1413 if (result == null && token == null && this.currentToken != null) {
1414 result = this.commit();
1419 assert(this.currentToken != null || this.expressionStartToken != null);
1420 let token = this.currentToken;
1421 this.currentToken = null;
1422 this.attribute = null;
1423 if (this.expressionStartToken != null) {
1424 const start = this.expressionStartToken;
1425 const end = last(this.expressionTokens) || start;
1426 const value = this.expressionTokens.reduce(concat, start.value);
1427 this.expressionStartToken = null;
1428 this.expressionTokens = [];
1429 if (token == null) {
1432 range: [start.range[0], end.range[1]],
1433 loc: { start: start.loc.start, end: end.loc.end },
1437 else if (token.type === "Text") {
1438 token.range[1] = end.range[1];
1439 token.loc.end = end.loc.end;
1440 token.value += value;
1443 throw new Error("unreachable");
1448 reportParseError(token, code) {
1449 const error = ParseError.fromCode(code, token.range[0], token.loc.start.line, token.loc.start.column);
1450 this.errors.push(error);
1451 debug("[html] syntax error:", error.message);
1453 processComment(token) {
1454 this.comments.push(token);
1455 if (this.currentToken != null && this.currentToken.type === "Text") {
1456 return this.commit();
1460 processText(token) {
1461 this.tokens.push(token);
1463 if (this.expressionStartToken != null) {
1464 const lastToken = last(this.expressionTokens) || this.expressionStartToken;
1465 if (lastToken.range[1] === token.range[0]) {
1466 this.expressionTokens.push(token);
1469 result = this.commit();
1471 else if (this.currentToken != null) {
1472 if (this.currentToken.type === "Text" &&
1473 this.currentToken.range[1] === token.range[0]) {
1474 this.currentToken.value += token.value;
1475 this.currentToken.range[1] = token.range[1];
1476 this.currentToken.loc.end = token.loc.end;
1479 result = this.commit();
1481 assert(this.currentToken == null);
1482 this.currentToken = {
1484 range: [token.range[0], token.range[1]],
1485 loc: { start: token.loc.start, end: token.loc.end },
1490 HTMLAssociation(token) {
1491 this.tokens.push(token);
1492 if (this.attribute != null) {
1493 this.attribute.range[1] = token.range[1];
1494 this.attribute.loc.end = token.loc.end;
1495 if (this.currentToken == null ||
1496 this.currentToken.type !== "StartTag") {
1497 throw new Error("unreachable");
1499 this.currentToken.range[1] = token.range[1];
1500 this.currentToken.loc.end = token.loc.end;
1504 HTMLBogusComment(token) {
1505 return this.processComment(token);
1507 HTMLCDataText(token) {
1508 return this.processText(token);
1510 HTMLComment(token) {
1511 return this.processComment(token);
1513 HTMLEndTagOpen(token) {
1514 this.tokens.push(token);
1516 if (this.currentToken != null || this.expressionStartToken != null) {
1517 result = this.commit();
1519 this.currentToken = {
1521 range: [token.range[0], token.range[1]],
1522 loc: { start: token.loc.start, end: token.loc.end },
1527 HTMLIdentifier(token) {
1528 this.tokens.push(token);
1529 if (this.currentToken == null ||
1530 this.currentToken.type === "Text" ||
1531 this.currentToken.type === "Mustache") {
1532 throw new Error("unreachable");
1534 if (this.currentToken.type === "EndTag") {
1535 this.reportParseError(token, "end-tag-with-attributes");
1538 if (this.attributeNames.has(token.value)) {
1539 this.reportParseError(token, "duplicate-attribute");
1541 this.attributeNames.add(token.value);
1544 range: [token.range[0], token.range[1]],
1545 loc: { start: token.loc.start, end: token.loc.end },
1546 parent: DUMMY_PARENT$1,
1549 type: "VIdentifier",
1550 range: [token.range[0], token.range[1]],
1551 loc: { start: token.loc.start, end: token.loc.end },
1552 parent: DUMMY_PARENT$1,
1554 rawName: this.text.slice(token.range[0], token.range[1]),
1558 this.attribute.key.parent = this.attribute;
1559 this.currentToken.range[1] = token.range[1];
1560 this.currentToken.loc.end = token.loc.end;
1561 this.currentToken.attributes.push(this.attribute);
1564 HTMLLiteral(token) {
1565 this.tokens.push(token);
1566 if (this.attribute != null) {
1567 this.attribute.range[1] = token.range[1];
1568 this.attribute.loc.end = token.loc.end;
1569 this.attribute.value = {
1571 range: [token.range[0], token.range[1]],
1572 loc: { start: token.loc.start, end: token.loc.end },
1573 parent: this.attribute,
1576 if (this.currentToken == null ||
1577 this.currentToken.type !== "StartTag") {
1578 throw new Error("unreachable");
1580 this.currentToken.range[1] = token.range[1];
1581 this.currentToken.loc.end = token.loc.end;
1585 HTMLRCDataText(token) {
1586 return this.processText(token);
1588 HTMLRawText(token) {
1589 return this.processText(token);
1591 HTMLSelfClosingTagClose(token) {
1592 this.tokens.push(token);
1593 if (this.currentToken == null || this.currentToken.type === "Text") {
1594 throw new Error("unreachable");
1596 if (this.currentToken.type === "StartTag") {
1597 this.currentToken.selfClosing = true;
1600 this.reportParseError(token, "end-tag-with-trailing-solidus");
1602 this.currentToken.range[1] = token.range[1];
1603 this.currentToken.loc.end = token.loc.end;
1604 return this.commit();
1606 HTMLTagClose(token) {
1607 this.tokens.push(token);
1608 if (this.currentToken == null || this.currentToken.type === "Text") {
1609 throw new Error("unreachable");
1611 this.currentToken.range[1] = token.range[1];
1612 this.currentToken.loc.end = token.loc.end;
1613 return this.commit();
1615 HTMLTagOpen(token) {
1616 this.tokens.push(token);
1618 if (this.currentToken != null || this.expressionStartToken != null) {
1619 result = this.commit();
1621 this.currentToken = {
1623 range: [token.range[0], token.range[1]],
1624 loc: { start: token.loc.start, end: token.loc.end },
1626 rawName: this.text.slice(token.range[0] + 1, token.range[1]),
1630 this.attribute = null;
1631 this.attributeNames.clear();
1635 return this.processText(token);
1637 HTMLWhitespace(token) {
1638 return this.processText(token);
1640 VExpressionStart(token) {
1641 if (this.expressionStartToken != null) {
1642 return this.processText(token);
1644 const separated = this.currentToken != null &&
1645 this.currentToken.range[1] !== token.range[0];
1646 const result = separated ? this.commit() : null;
1647 this.tokens.push(token);
1648 this.expressionStartToken = token;
1651 VExpressionEnd(token) {
1652 if (this.expressionStartToken == null) {
1653 return this.processText(token);
1655 const start = this.expressionStartToken;
1656 const end = last(this.expressionTokens) || start;
1657 if (token.range[0] === start.range[1]) {
1659 this.expressionStartToken = null;
1660 const result = this.processText(start);
1661 this.processText(token);
1664 if (end.range[1] !== token.range[0]) {
1665 const result = this.commit();
1666 this.processText(token);
1669 const value = this.expressionTokens.reduce(concat, "");
1670 this.tokens.push(token);
1671 this.expressionStartToken = null;
1672 this.expressionTokens = [];
1673 const result = this.currentToken != null ? this.commit() : null;
1674 this.currentToken = {
1676 range: [start.range[0], token.range[1]],
1677 loc: { start: start.loc.start, end: token.loc.end },
1682 return result || this.commit();
1686 const DIRECTIVE_NAME = /^(?:v-|[.:@#]).*[^.:@#]$/u;
1687 const DT_DD = /^d[dt]$/u;
1688 const DUMMY_PARENT$2 = Object.freeze({});
1689 function isMathMLIntegrationPoint(element) {
1690 if (element.namespace === NS.MathML) {
1691 const name = element.name;
1692 return (name === "mi" ||
1700 function isHTMLIntegrationPoint(element) {
1701 if (element.namespace === NS.MathML) {
1702 return (element.name === "annotation-xml" &&
1703 element.startTag.attributes.some(a => a.directive === false &&
1704 a.key.name === "encoding" &&
1706 (a.value.value === "text/html" ||
1707 a.value.value === "application/xhtml+xml")));
1709 if (element.namespace === NS.SVG) {
1710 const name = element.name;
1711 return name === "foreignObject" || name === "desc" || name === "title";
1715 function adjustElementName(name, namespace) {
1716 if (namespace === NS.SVG) {
1717 return SVG_ELEMENT_NAME_MAP.get(name) || name;
1721 function adjustAttributeName(name, namespace) {
1722 if (namespace === NS.SVG) {
1723 return SVG_ATTRIBUTE_NAME_MAP.get(name) || name;
1725 if (namespace === NS.MathML) {
1726 return MATHML_ATTRIBUTE_NAME_MAP.get(name) || name;
1730 function propagateEndLocation(node) {
1731 const lastChild = (node.type === "VElement" ? node.endTag : null) || last(node.children);
1732 if (lastChild != null) {
1733 node.range[1] = lastChild.range[1];
1734 node.loc.end = lastChild.loc.end;
1739 return this.tokenizer.text;
1742 return this.tokenizer.tokens;
1745 return this.tokenizer.comments;
1748 return this.tokenizer.errors;
1751 return this.tokenizer.namespace;
1753 set namespace(value) {
1754 this.tokenizer.namespace = value;
1756 get expressionEnabled() {
1757 return this.tokenizer.expressionEnabled;
1759 set expressionEnabled(value) {
1760 this.tokenizer.expressionEnabled = value;
1763 return last(this.elementStack) || this.document;
1765 get isInVPreElement() {
1766 return this.vPreElement != null;
1768 constructor(tokenizer, parserOptions) {
1769 this.tokenizer = new IntermediateTokenizer(tokenizer);
1770 this.locationCalculator = new LocationCalculator(tokenizer.gaps, tokenizer.lineTerminators);
1771 this.parserOptions = parserOptions;
1773 type: "VDocumentFragment",
1776 start: { line: 1, column: 0 },
1777 end: { line: 1, column: 0 },
1781 tokens: this.tokens,
1782 comments: this.comments,
1783 errors: this.errors,
1785 this.elementStack = [];
1786 this.vPreElement = null;
1790 while ((token = this.tokenizer.nextToken()) != null) {
1791 this[token.type](token);
1793 this.popElementStackUntil(0);
1794 propagateEndLocation(this.document);
1795 return this.document;
1797 reportParseError(token, code) {
1798 const error = ParseError.fromCode(code, token.range[0], token.loc.start.line, token.loc.start.column);
1799 this.errors.push(error);
1800 debug("[html] syntax error:", error.message);
1803 assert(this.elementStack.length >= 1);
1804 const element = this.elementStack.pop();
1805 propagateEndLocation(element);
1806 const current = this.currentNode;
1808 current.type === "VElement" ? current.namespace : NS.HTML;
1809 if (this.vPreElement === element) {
1810 this.vPreElement = null;
1811 this.expressionEnabled = true;
1813 if (this.elementStack.length === 0) {
1814 this.expressionEnabled = false;
1817 popElementStackUntil(index) {
1818 while (this.elementStack.length > index) {
1819 this.popElementStack();
1822 detectNamespace(token) {
1823 const name = token.name;
1824 let ns = this.namespace;
1825 if (ns === NS.MathML || ns === NS.SVG) {
1826 const element = this.currentNode;
1827 if (element.type === "VElement") {
1828 if (element.namespace === NS.MathML &&
1829 element.name === "annotation-xml" &&
1833 if (isHTMLIntegrationPoint(element) ||
1834 (isMathMLIntegrationPoint(element) &&
1835 name !== "mglyph" &&
1836 name !== "malignmark")) {
1841 if (ns === NS.HTML) {
1842 if (name === "svg") {
1845 if (name === "math") {
1849 if (name === "template") {
1850 const xmlns = token.attributes.find(a => a.key.name === "xmlns");
1851 const value = xmlns && xmlns.value && xmlns.value.value;
1852 if (value === NS.HTML || value === NS.MathML || value === NS.SVG) {
1858 closeCurrentElementIfNecessary(name) {
1859 const element = this.currentNode;
1860 if (element.type !== "VElement") {
1863 if (element.name === "p" && HTML_NON_FHRASING_TAGS.has(name)) {
1864 this.popElementStack();
1866 if (element.name === name && HTML_CAN_BE_LEFT_OPEN_TAGS.has(name)) {
1867 this.popElementStack();
1869 if (DT_DD.test(element.name) && DT_DD.test(name)) {
1870 this.popElementStack();
1873 processAttribute(node, namespace) {
1874 const tagName = node.parent.parent.name;
1875 const attrName = node.key.name;
1876 if ((this.expressionEnabled ||
1877 (attrName === "v-pre" && !this.isInVPreElement)) &&
1878 (DIRECTIVE_NAME.test(attrName) ||
1879 attrName === "slot-scope" ||
1880 (tagName === "template" && attrName === "scope"))) {
1881 convertToDirective(this.text, this.parserOptions, this.locationCalculator, node);
1884 const key = (node.key.name = adjustAttributeName(node.key.name, namespace));
1885 const value = node.value && node.value.value;
1886 if (key === "xmlns" && value !== namespace) {
1887 this.reportParseError(node, "x-invalid-namespace");
1889 else if (key === "xmlns:xlink" && value !== NS.XLink) {
1890 this.reportParseError(node, "x-invalid-namespace");
1894 debug("[html] StartTag %j", token);
1895 this.closeCurrentElementIfNecessary(token.name);
1896 const parent = this.currentNode;
1897 const namespace = this.detectNamespace(token);
1900 range: [token.range[0], token.range[1]],
1901 loc: { start: token.loc.start, end: token.loc.end },
1903 name: adjustElementName(token.name, namespace),
1904 rawName: token.rawName,
1910 parent: DUMMY_PARENT$2,
1911 selfClosing: token.selfClosing,
1912 attributes: token.attributes,
1918 const hasVPre = !this.isInVPreElement &&
1919 token.attributes.some(a => a.key.name === "v-pre");
1921 this.expressionEnabled = false;
1923 parent.children.push(element);
1924 element.startTag.parent = element;
1925 for (const attribute of token.attributes) {
1926 attribute.parent = element.startTag;
1927 this.processAttribute(attribute, namespace);
1929 for (const attribute of element.startTag.attributes) {
1930 if (attribute.directive) {
1931 if (attribute.key.argument != null &&
1932 attribute.key.argument.type === "VExpressionContainer") {
1933 resolveReferences(attribute.key.argument);
1935 if (attribute.value != null) {
1936 resolveReferences(attribute.value);
1940 const isVoid = namespace === NS.HTML && HTML_VOID_ELEMENT_TAGS.has(element.name);
1941 if (token.selfClosing && !isVoid && namespace === NS.HTML) {
1942 this.reportParseError(token, "non-void-html-element-start-tag-with-trailing-solidus");
1944 if (token.selfClosing || isVoid) {
1945 this.expressionEnabled = !this.isInVPreElement;
1948 this.elementStack.push(element);
1950 assert(this.vPreElement === null);
1951 this.vPreElement = element;
1953 this.namespace = namespace;
1954 if (namespace === NS.HTML) {
1955 if (element.name === "template" &&
1956 element.parent.type === "VDocumentFragment") {
1957 const langAttr = element.startTag.attributes.find(a => !a.directive && a.key.name === "lang");
1958 const lang = (langAttr && langAttr.value && langAttr.value.value) ||
1960 if (lang !== "html") {
1961 this.tokenizer.state = "RAWTEXT";
1963 this.expressionEnabled = true;
1965 if (HTML_RCDATA_TAGS.has(element.name)) {
1966 this.tokenizer.state = "RCDATA";
1968 if (HTML_RAWTEXT_TAGS.has(element.name)) {
1969 this.tokenizer.state = "RAWTEXT";
1974 debug("[html] EndTag %j", token);
1975 const i = findLastIndex(this.elementStack, el => el.name.toLowerCase() === token.name);
1977 this.reportParseError(token, "x-invalid-end-tag");
1980 const element = this.elementStack[i];
1987 this.popElementStackUntil(i);
1990 debug("[html] Text %j", token);
1991 const parent = this.currentNode;
1992 parent.children.push({
2001 debug("[html] Mustache %j", token);
2002 const parent = this.currentNode;
2004 type: "VExpressionContainer",
2011 processMustache(this.parserOptions, this.locationCalculator, container, token);
2012 parent.children.push(container);
2013 resolveReferences(container);
2017 const alternativeCR = new Map([[128, 8364], [130, 8218], [131, 402], [132, 8222], [133, 8230], [134, 8224], [135, 8225], [136, 710], [137, 8240], [138, 352], [139, 8249], [140, 338], [142, 381], [145, 8216], [146, 8217], [147, 8220], [148, 8221], [149, 8226], [150, 8211], [151, 8212], [152, 732], [153, 8482], [154, 353], [155, 8250], [156, 339], [158, 382], [159, 376]]);
2019 const entitySets = [{ "length": 32, "entities": { "CounterClockwiseContourIntegral;": [8755] } }, { "length": 25, "entities": { "ClockwiseContourIntegral;": [8754], "DoubleLongLeftRightArrow;": [10234] } }, { "length": 24, "entities": { "NotNestedGreaterGreater;": [10914, 824] } }, { "length": 23, "entities": { "DiacriticalDoubleAcute;": [733], "NotSquareSupersetEqual;": [8931] } }, { "length": 22, "entities": { "CloseCurlyDoubleQuote;": [8221], "DoubleContourIntegral;": [8751], "FilledVerySmallSquare;": [9642], "NegativeVeryThinSpace;": [8203], "NotPrecedesSlantEqual;": [8928], "NotRightTriangleEqual;": [8941], "NotSucceedsSlantEqual;": [8929] } }, { "length": 21, "entities": { "CapitalDifferentialD;": [8517], "DoubleLeftRightArrow;": [8660], "DoubleLongRightArrow;": [10233], "EmptyVerySmallSquare;": [9643], "NestedGreaterGreater;": [8811], "NotDoubleVerticalBar;": [8742], "NotGreaterSlantEqual;": [10878, 824], "NotLeftTriangleEqual;": [8940], "NotSquareSubsetEqual;": [8930], "OpenCurlyDoubleQuote;": [8220], "ReverseUpEquilibrium;": [10607] } }, { "length": 20, "entities": { "DoubleLongLeftArrow;": [10232], "DownLeftRightVector;": [10576], "LeftArrowRightArrow;": [8646], "NegativeMediumSpace;": [8203], "NotGreaterFullEqual;": [8807, 824], "NotRightTriangleBar;": [10704, 824], "RightArrowLeftArrow;": [8644], "SquareSupersetEqual;": [8850], "leftrightsquigarrow;": [8621] } }, { "length": 19, "entities": { "DownRightTeeVector;": [10591], "DownRightVectorBar;": [10583], "LongLeftRightArrow;": [10231], "Longleftrightarrow;": [10234], "NegativeThickSpace;": [8203], "NotLeftTriangleBar;": [10703, 824], "PrecedesSlantEqual;": [8828], "ReverseEquilibrium;": [8651], "RightDoubleBracket;": [10215], "RightDownTeeVector;": [10589], "RightDownVectorBar;": [10581], "RightTriangleEqual;": [8885], "SquareIntersection;": [8851], "SucceedsSlantEqual;": [8829], "blacktriangleright;": [9656], "longleftrightarrow;": [10231] } }, { "length": 18, "entities": { "DoubleUpDownArrow;": [8661], "DoubleVerticalBar;": [8741], "DownLeftTeeVector;": [10590], "DownLeftVectorBar;": [10582], "FilledSmallSquare;": [9724], "GreaterSlantEqual;": [10878], "LeftDoubleBracket;": [10214], "LeftDownTeeVector;": [10593], "LeftDownVectorBar;": [10585], "LeftTriangleEqual;": [8884], "NegativeThinSpace;": [8203], "NotGreaterGreater;": [8811, 824], "NotLessSlantEqual;": [10877, 824], "NotNestedLessLess;": [10913, 824], "NotReverseElement;": [8716], "NotSquareSuperset;": [8848, 824], "NotTildeFullEqual;": [8775], "RightAngleBracket;": [10217], "RightUpDownVector;": [10575], "SquareSubsetEqual;": [8849], "VerticalSeparator;": [10072], "blacktriangledown;": [9662], "blacktriangleleft;": [9666], "leftrightharpoons;": [8651], "rightleftharpoons;": [8652], "twoheadrightarrow;": [8608] } }, { "length": 17, "entities": { "DiacriticalAcute;": [180], "DiacriticalGrave;": [96], "DiacriticalTilde;": [732], "DoubleRightArrow;": [8658], "DownArrowUpArrow;": [8693], "EmptySmallSquare;": [9723], "GreaterEqualLess;": [8923], "GreaterFullEqual;": [8807], "LeftAngleBracket;": [10216], "LeftUpDownVector;": [10577], "LessEqualGreater;": [8922], "NonBreakingSpace;": [160], "NotPrecedesEqual;": [10927, 824], "NotRightTriangle;": [8939], "NotSucceedsEqual;": [10928, 824], "NotSucceedsTilde;": [8831, 824], "NotSupersetEqual;": [8841], "RightTriangleBar;": [10704], "RightUpTeeVector;": [10588], "RightUpVectorBar;": [10580], "UnderParenthesis;": [9181], "UpArrowDownArrow;": [8645], "circlearrowright;": [8635], "downharpoonright;": [8642], "ntrianglerighteq;": [8941], "rightharpoondown;": [8641], "rightrightarrows;": [8649], "twoheadleftarrow;": [8606], "vartriangleright;": [8883] } }, { "length": 16, "entities": { "CloseCurlyQuote;": [8217], "ContourIntegral;": [8750], "DoubleDownArrow;": [8659], "DoubleLeftArrow;": [8656], "DownRightVector;": [8641], "LeftRightVector;": [10574], "LeftTriangleBar;": [10703], "LeftUpTeeVector;": [10592], "LeftUpVectorBar;": [10584], "LowerRightArrow;": [8600], "NotGreaterEqual;": [8817], "NotGreaterTilde;": [8821], "NotHumpDownHump;": [8782, 824], "NotLeftTriangle;": [8938], "NotSquareSubset;": [8847, 824], "OverParenthesis;": [9180], "RightDownVector;": [8642], "ShortRightArrow;": [8594], "UpperRightArrow;": [8599], "bigtriangledown;": [9661], "circlearrowleft;": [8634], "curvearrowright;": [8631], "downharpoonleft;": [8643], "leftharpoondown;": [8637], "leftrightarrows;": [8646], "nLeftrightarrow;": [8654], "nleftrightarrow;": [8622], "ntrianglelefteq;": [8940], "rightleftarrows;": [8644], "rightsquigarrow;": [8605], "rightthreetimes;": [8908], "straightepsilon;": [1013], "trianglerighteq;": [8885], "vartriangleleft;": [8882] } }, { "length": 15, "entities": { "DiacriticalDot;": [729], "DoubleRightTee;": [8872], "DownLeftVector;": [8637], "GreaterGreater;": [10914], "HorizontalLine;": [9472], "InvisibleComma;": [8291], "InvisibleTimes;": [8290], "LeftDownVector;": [8643], "LeftRightArrow;": [8596], "Leftrightarrow;": [8660], "LessSlantEqual;": [10877], "LongRightArrow;": [10230], "Longrightarrow;": [10233], "LowerLeftArrow;": [8601], "NestedLessLess;": [8810], "NotGreaterLess;": [8825], "NotLessGreater;": [8824], "NotSubsetEqual;": [8840], "NotVerticalBar;": [8740], "OpenCurlyQuote;": [8216], "ReverseElement;": [8715], "RightTeeVector;": [10587], "RightVectorBar;": [10579], "ShortDownArrow;": [8595], "ShortLeftArrow;": [8592], "SquareSuperset;": [8848], "TildeFullEqual;": [8773], "UpperLeftArrow;": [8598], "ZeroWidthSpace;": [8203], "curvearrowleft;": [8630], "doublebarwedge;": [8966], "downdownarrows;": [8650], "hookrightarrow;": [8618], "leftleftarrows;": [8647], "leftrightarrow;": [8596], "leftthreetimes;": [8907], "longrightarrow;": [10230], "looparrowright;": [8620], "nshortparallel;": [8742], "ntriangleright;": [8939], "rightarrowtail;": [8611], "rightharpoonup;": [8640], "trianglelefteq;": [8884], "upharpoonright;": [8638] } }, { "length": 14, "entities": { "ApplyFunction;": [8289], "DifferentialD;": [8518], "DoubleLeftTee;": [10980], "DoubleUpArrow;": [8657], "LeftTeeVector;": [10586], "LeftVectorBar;": [10578], "LessFullEqual;": [8806], "LongLeftArrow;": [10229], "Longleftarrow;": [10232], "NotEqualTilde;": [8770, 824], "NotTildeEqual;": [8772], "NotTildeTilde;": [8777], "Poincareplane;": [8460], "PrecedesEqual;": [10927], "PrecedesTilde;": [8830], "RightArrowBar;": [8677], "RightTeeArrow;": [8614], "RightTriangle;": [8883], "RightUpVector;": [8638], "SucceedsEqual;": [10928], "SucceedsTilde;": [8831], "SupersetEqual;": [8839], "UpEquilibrium;": [10606], "VerticalTilde;": [8768], "VeryThinSpace;": [8202], "bigtriangleup;": [9651], "blacktriangle;": [9652], "divideontimes;": [8903], "fallingdotseq;": [8786], "hookleftarrow;": [8617], "leftarrowtail;": [8610], "leftharpoonup;": [8636], "longleftarrow;": [10229], "looparrowleft;": [8619], "measuredangle;": [8737], "ntriangleleft;": [8938], "shortparallel;": [8741], "smallsetminus;": [8726], "triangleright;": [9657], "upharpoonleft;": [8639], "varsubsetneqq;": [10955, 65024], "varsupsetneqq;": [10956, 65024] } }, { "length": 13, "entities": { "DownArrowBar;": [10515], "DownTeeArrow;": [8615], "ExponentialE;": [8519], "GreaterEqual;": [8805], "GreaterTilde;": [8819], "HilbertSpace;": [8459], "HumpDownHump;": [8782], "Intersection;": [8898], "LeftArrowBar;": [8676], "LeftTeeArrow;": [8612], "LeftTriangle;": [8882], "LeftUpVector;": [8639], "NotCongruent;": [8802], "NotHumpEqual;": [8783, 824], "NotLessEqual;": [8816], "NotLessTilde;": [8820], "Proportional;": [8733], "RightCeiling;": [8969], "RoundImplies;": [10608], "ShortUpArrow;": [8593], "SquareSubset;": [8847], "UnderBracket;": [9141], "VerticalLine;": [124], "blacklozenge;": [10731], "exponentiale;": [8519], "risingdotseq;": [8787], "triangledown;": [9663], "triangleleft;": [9667], "varsubsetneq;": [8842, 65024], "varsupsetneq;": [8843, 65024] } }, { "length": 12, "entities": { "CircleMinus;": [8854], "CircleTimes;": [8855], "Equilibrium;": [8652], "GreaterLess;": [8823], "LeftCeiling;": [8968], "LessGreater;": [8822], "MediumSpace;": [8287], "NotLessLess;": [8810, 824], "NotPrecedes;": [8832], "NotSucceeds;": [8833], "NotSuperset;": [8835, 8402], "OverBracket;": [9140], "RightVector;": [8640], "Rrightarrow;": [8667], "RuleDelayed;": [10740], "SmallCircle;": [8728], "SquareUnion;": [8852], "SubsetEqual;": [8838], "UpDownArrow;": [8597], "Updownarrow;": [8661], "VerticalBar;": [8739], "backepsilon;": [1014], "blacksquare;": [9642], "circledcirc;": [8858], "circleddash;": [8861], "curlyeqprec;": [8926], "curlyeqsucc;": [8927], "diamondsuit;": [9830], "eqslantless;": [10901], "expectation;": [8496], "nRightarrow;": [8655], "nrightarrow;": [8603], "preccurlyeq;": [8828], "precnapprox;": [10937], "quaternions;": [8461], "straightphi;": [981], "succcurlyeq;": [8829], "succnapprox;": [10938], "thickapprox;": [8776], "updownarrow;": [8597] } }, { "length": 11, "entities": { "Bernoullis;": [8492], "CirclePlus;": [8853], "EqualTilde;": [8770], "Fouriertrf;": [8497], "ImaginaryI;": [8520], "Laplacetrf;": [8466], "LeftVector;": [8636], "Lleftarrow;": [8666], "NotElement;": [8713], "NotGreater;": [8815], "Proportion;": [8759], "RightArrow;": [8594], "RightFloor;": [8971], "Rightarrow;": [8658], "ThickSpace;": [8287, 8202], "TildeEqual;": [8771], "TildeTilde;": [8776], "UnderBrace;": [9183], "UpArrowBar;": [10514], "UpTeeArrow;": [8613], "circledast;": [8859], "complement;": [8705], "curlywedge;": [8911], "eqslantgtr;": [10902], "gtreqqless;": [10892], "lessapprox;": [10885], "lesseqqgtr;": [10891], "lmoustache;": [9136], "longmapsto;": [10236], "mapstodown;": [8615], "mapstoleft;": [8612], "nLeftarrow;": [8653], "nleftarrow;": [8602], "nsubseteqq;": [10949, 824], "nsupseteqq;": [10950, 824], "precapprox;": [10935], "rightarrow;": [8594], "rmoustache;": [9137], "sqsubseteq;": [8849], "sqsupseteq;": [8850], "subsetneqq;": [10955], "succapprox;": [10936], "supsetneqq;": [10956], "upuparrows;": [8648], "varepsilon;": [1013], "varnothing;": [8709] } }, { "length": 10, "entities": { "Backslash;": [8726], "CenterDot;": [183], "CircleDot;": [8857], "Congruent;": [8801], "Coproduct;": [8720], "DoubleDot;": [168], "DownArrow;": [8595], "DownBreve;": [785], "Downarrow;": [8659], "HumpEqual;": [8783], "LeftArrow;": [8592], "LeftFloor;": [8970], "Leftarrow;": [8656], "LessTilde;": [8818], "Mellintrf;": [8499], "MinusPlus;": [8723], "NotCupCap;": [8813], "NotExists;": [8708], "NotSubset;": [8834, 8402], "OverBrace;": [9182], "PlusMinus;": [177], "Therefore;": [8756], "ThinSpace;": [8201], "TripleDot;": [8411], "UnionPlus;": [8846], "backprime;": [8245], "backsimeq;": [8909], "bigotimes;": [10754], "centerdot;": [183], "checkmark;": [10003], "complexes;": [8450], "dotsquare;": [8865], "downarrow;": [8595], "gtrapprox;": [10886], "gtreqless;": [8923], "gvertneqq;": [8809, 65024], "heartsuit;": [9829], "leftarrow;": [8592], "lesseqgtr;": [8922], "lvertneqq;": [8808, 65024], "ngeqslant;": [10878, 824], "nleqslant;": [10877, 824], "nparallel;": [8742], "nshortmid;": [8740], "nsubseteq;": [8840], "nsupseteq;": [8841], "pitchfork;": [8916], "rationals;": [8474], "spadesuit;": [9824], "subseteqq;": [10949], "subsetneq;": [8842], "supseteqq;": [10950], "supsetneq;": [8843], "therefore;": [8756], "triangleq;": [8796], "varpropto;": [8733] } }, { "length": 9, "entities": { "DDotrahd;": [10513], "DotEqual;": [8784], "Integral;": [8747], "LessLess;": [10913], "NotEqual;": [8800], "NotTilde;": [8769], "PartialD;": [8706], "Precedes;": [8826], "RightTee;": [8866], "Succeeds;": [8827], "SuchThat;": [8715], "Superset;": [8835], "Uarrocir;": [10569], "UnderBar;": [95], "andslope;": [10840], "angmsdaa;": [10664], "angmsdab;": [10665], "angmsdac;": [10666], "angmsdad;": [10667], "angmsdae;": [10668], "angmsdaf;": [10669], "angmsdag;": [10670], "angmsdah;": [10671], "angrtvbd;": [10653], "approxeq;": [8778], "awconint;": [8755], "backcong;": [8780], "barwedge;": [8965], "bbrktbrk;": [9142], "bigoplus;": [10753], "bigsqcup;": [10758], "biguplus;": [10756], "bigwedge;": [8896], "boxminus;": [8863], "boxtimes;": [8864], "bsolhsub;": [10184], "capbrcup;": [10825], "circledR;": [174], "circledS;": [9416], "cirfnint;": [10768], "clubsuit;": [9827], "cupbrcap;": [10824], "curlyvee;": [8910], "cwconint;": [8754], "doteqdot;": [8785], "dotminus;": [8760], "drbkarow;": [10512], "dzigrarr;": [10239], "elinters;": [9191], "emptyset;": [8709], "eqvparsl;": [10725], "fpartint;": [10765], "geqslant;": [10878], "gesdotol;": [10884], "gnapprox;": [10890], "hksearow;": [10533], "hkswarow;": [10534], "imagline;": [8464], "imagpart;": [8465], "infintie;": [10717], "integers;": [8484], "intercal;": [8890], "intlarhk;": [10775], "laemptyv;": [10676], "ldrushar;": [10571], "leqslant;": [10877], "lesdotor;": [10883], "llcorner;": [8990], "lnapprox;": [10889], "lrcorner;": [8991], "lurdshar;": [10570], "mapstoup;": [8613], "multimap;": [8888], "naturals;": [8469], "ncongdot;": [10861, 824], "notindot;": [8949, 824], "otimesas;": [10806], "parallel;": [8741], "plusacir;": [10787], "pointint;": [10773], "precneqq;": [10933], "precnsim;": [8936], "profalar;": [9006], "profline;": [8978], "profsurf;": [8979], "raemptyv;": [10675], "realpart;": [8476], "rppolint;": [10770], "rtriltri;": [10702], "scpolint;": [10771], "setminus;": [8726], "shortmid;": [8739], "smeparsl;": [10724], "sqsubset;": [8847], "sqsupset;": [8848], "subseteq;": [8838], "succneqq;": [10934], "succnsim;": [8937], "supseteq;": [8839], "thetasym;": [977], "thicksim;": [8764], "timesbar;": [10801], "triangle;": [9653], "triminus;": [10810], "trpezium;": [9186], "ulcorner;": [8988], "urcorner;": [8989], "varkappa;": [1008], "varsigma;": [962], "vartheta;": [977] } }, { "length": 8, "entities": { "Because;": [8757], "Cayleys;": [8493], "Cconint;": [8752], "Cedilla;": [184], "Diamond;": [8900], "DownTee;": [8868], "Element;": [8712], "Epsilon;": [917], "Implies;": [8658], "LeftTee;": [8867], "NewLine;": [10], "NoBreak;": [8288], "NotLess;": [8814], "Omicron;": [927], "OverBar;": [8254], "Product;": [8719], "UpArrow;": [8593], "Uparrow;": [8657], "Upsilon;": [933], "alefsym;": [8501], "angrtvb;": [8894], "angzarr;": [9084], "asympeq;": [8781], "backsim;": [8765], "because;": [8757], "bemptyv;": [10672], "between;": [8812], "bigcirc;": [9711], "bigodot;": [10752], "bigstar;": [9733], "bnequiv;": [8801, 8421], "boxplus;": [8862], "ccupssm;": [10832], "cemptyv;": [10674], "cirscir;": [10690], "coloneq;": [8788], "congdot;": [10861], "cudarrl;": [10552], "cudarrr;": [10549], "cularrp;": [10557], "curarrm;": [10556], "dbkarow;": [10511], "ddagger;": [8225], "ddotseq;": [10871], "demptyv;": [10673], "diamond;": [8900], "digamma;": [989], "dotplus;": [8724], "dwangle;": [10662], "epsilon;": [949], "eqcolon;": [8789], "equivDD;": [10872], "gesdoto;": [10882], "gtquest;": [10876], "gtrless;": [8823], "harrcir;": [10568], "intprod;": [10812], "isindot;": [8949], "larrbfs;": [10527], "larrsim;": [10611], "lbrksld;": [10639], "lbrkslu;": [10637], "ldrdhar;": [10599], "lesdoto;": [10881], "lessdot;": [8918], "lessgtr;": [8822], "lesssim;": [8818], "lotimes;": [10804], "lozenge;": [9674], "ltquest;": [10875], "luruhar;": [10598], "maltese;": [10016], "minusdu;": [10794], "napprox;": [8777], "natural;": [9838], "nearrow;": [8599], "nexists;": [8708], "notinva;": [8713], "notinvb;": [8951], "notinvc;": [8950], "notniva;": [8716], "notnivb;": [8958], "notnivc;": [8957], "npolint;": [10772], "npreceq;": [10927, 824], "nsqsube;": [8930], "nsqsupe;": [8931], "nsubset;": [8834, 8402], "nsucceq;": [10928, 824], "nsupset;": [8835, 8402], "nvinfin;": [10718], "nvltrie;": [8884, 8402], "nvrtrie;": [8885, 8402], "nwarrow;": [8598], "olcross;": [10683], "omicron;": [959], "orderof;": [8500], "orslope;": [10839], "pertenk;": [8241], "planckh;": [8462], "pluscir;": [10786], "plussim;": [10790], "plustwo;": [10791], "precsim;": [8830], "quatint;": [10774], "questeq;": [8799], "rarrbfs;": [10528], "rarrsim;": [10612], "rbrksld;": [10638], "rbrkslu;": [10640], "rdldhar;": [10601], "realine;": [8475], "rotimes;": [10805], "ruluhar;": [10600], "searrow;": [8600], "simplus;": [10788], "simrarr;": [10610], "subedot;": [10947], "submult;": [10945], "subplus;": [10943], "subrarr;": [10617], "succsim;": [8831], "supdsub;": [10968], "supedot;": [10948], "suphsol;": [10185], "suphsub;": [10967], "suplarr;": [10619], "supmult;": [10946], "supplus;": [10944], "swarrow;": [8601], "topfork;": [10970], "triplus;": [10809], "tritime;": [10811], "uparrow;": [8593], "upsilon;": [965], "uwangle;": [10663], "vzigzag;": [10650], "zigrarr;": [8669] } }, { "length": 7, "entities": { "Aacute;": [193], "Abreve;": [258], "Agrave;": [192], "Assign;": [8788], "Atilde;": [195], "Barwed;": [8966], "Bumpeq;": [8782], "Cacute;": [262], "Ccaron;": [268], "Ccedil;": [199], "Colone;": [10868], "Conint;": [8751], "CupCap;": [8781], "Dagger;": [8225], "Dcaron;": [270], "DotDot;": [8412], "Dstrok;": [272], "Eacute;": [201], "Ecaron;": [282], "Egrave;": [200], "Exists;": [8707], "ForAll;": [8704], "Gammad;": [988], "Gbreve;": [286], "Gcedil;": [290], "HARDcy;": [1066], "Hstrok;": [294], "Iacute;": [205], "Igrave;": [204], "Itilde;": [296], "Jsercy;": [1032], "Kcedil;": [310], "Lacute;": [313], "Lambda;": [923], "Lcaron;": [317], "Lcedil;": [315], "Lmidot;": [319], "Lstrok;": [321], "Nacute;": [323], "Ncaron;": [327], "Ncedil;": [325], "Ntilde;": [209], "Oacute;": [211], "Odblac;": [336], "Ograve;": [210], "Oslash;": [216], "Otilde;": [213], "Otimes;": [10807], "Racute;": [340], "Rarrtl;": [10518], "Rcaron;": [344], "Rcedil;": [342], "SHCHcy;": [1065], "SOFTcy;": [1068], "Sacute;": [346], "Scaron;": [352], "Scedil;": [350], "Square;": [9633], "Subset;": [8912], "Supset;": [8913], "Tcaron;": [356], "Tcedil;": [354], "Tstrok;": [358], "Uacute;": [218], "Ubreve;": [364], "Udblac;": [368], "Ugrave;": [217], "Utilde;": [360], "Vdashl;": [10982], "Verbar;": [8214], "Vvdash;": [8874], "Yacute;": [221], "Zacute;": [377], "Zcaron;": [381], "aacute;": [225], "abreve;": [259], "agrave;": [224], "andand;": [10837], "angmsd;": [8737], "angsph;": [8738], "apacir;": [10863], "approx;": [8776], "atilde;": [227], "barvee;": [8893], "barwed;": [8965], "becaus;": [8757], "bernou;": [8492], "bigcap;": [8898], "bigcup;": [8899], "bigvee;": [8897], "bkarow;": [10509], "bottom;": [8869], "bowtie;": [8904], "boxbox;": [10697], "bprime;": [8245], "brvbar;": [166], "bullet;": [8226], "bumpeq;": [8783], "cacute;": [263], "capand;": [10820], "capcap;": [10827], "capcup;": [10823], "capdot;": [10816], "ccaron;": [269], "ccedil;": [231], "circeq;": [8791], "cirmid;": [10991], "colone;": [8788], "commat;": [64], "compfn;": [8728], "conint;": [8750], "coprod;": [8720], "copysr;": [8471], "cularr;": [8630], "cupcap;": [10822], "cupcup;": [10826], "cupdot;": [8845], "curarr;": [8631], "curren;": [164], "cylcty;": [9005], "dagger;": [8224], "daleth;": [8504], "dcaron;": [271], "dfisht;": [10623], "divide;": [247], "divonx;": [8903], "dlcorn;": [8990], "dlcrop;": [8973], "dollar;": [36], "drcorn;": [8991], "drcrop;": [8972], "dstrok;": [273], "eacute;": [233], "easter;": [10862], "ecaron;": [283], "ecolon;": [8789], "egrave;": [232], "egsdot;": [10904], "elsdot;": [10903], "emptyv;": [8709], "emsp13;": [8196], "emsp14;": [8197], "eparsl;": [10723], "eqcirc;": [8790], "equals;": [61], "equest;": [8799], "female;": [9792], "ffilig;": [64259], "ffllig;": [64260], "forall;": [8704], "frac12;": [189], "frac13;": [8531], "frac14;": [188], "frac15;": [8533], "frac16;": [8537], "frac18;": [8539], "frac23;": [8532], "frac25;": [8534], "frac34;": [190], "frac35;": [8535], "frac38;": [8540], "frac45;": [8536], "frac56;": [8538], "frac58;": [8541], "frac78;": [8542], "gacute;": [501], "gammad;": [989], "gbreve;": [287], "gesdot;": [10880], "gesles;": [10900], "gtlPar;": [10645], "gtrarr;": [10616], "gtrdot;": [8919], "gtrsim;": [8819], "hairsp;": [8202], "hamilt;": [8459], "hardcy;": [1098], "hearts;": [9829], "hellip;": [8230], "hercon;": [8889], "homtht;": [8763], "horbar;": [8213], "hslash;": [8463], "hstrok;": [295], "hybull;": [8259], "hyphen;": [8208], "iacute;": [237], "igrave;": [236], "iiiint;": [10764], "iinfin;": [10716], "incare;": [8453], "inodot;": [305], "intcal;": [8890], "iquest;": [191], "isinsv;": [8947], "itilde;": [297], "jsercy;": [1112], "kappav;": [1008], "kcedil;": [311], "kgreen;": [312], "lAtail;": [10523], "lacute;": [314], "lagran;": [8466], "lambda;": [955], "langle;": [10216], "larrfs;": [10525], "larrhk;": [8617], "larrlp;": [8619], "larrpl;": [10553], "larrtl;": [8610], "latail;": [10521], "lbrace;": [123], "lbrack;": [91], "lcaron;": [318], "lcedil;": [316], "ldquor;": [8222], "lesdot;": [10879], "lesges;": [10899], "lfisht;": [10620], "lfloor;": [8970], "lharul;": [10602], "llhard;": [10603], "lmidot;": [320], "lmoust;": [9136], "loplus;": [10797], "lowast;": [8727], "lowbar;": [95], "lparlt;": [10643], "lrhard;": [10605], "lsaquo;": [8249], "lsquor;": [8218], "lstrok;": [322], "lthree;": [8907], "ltimes;": [8905], "ltlarr;": [10614], "ltrPar;": [10646], "mapsto;": [8614], "marker;": [9646], "mcomma;": [10793], "midast;": [42], "midcir;": [10992], "middot;": [183], "minusb;": [8863], "minusd;": [8760], "mnplus;": [8723], "models;": [8871], "mstpos;": [8766], "nVDash;": [8879], "nVdash;": [8878], "nacute;": [324], "nbumpe;": [8783, 824], "ncaron;": [328], "ncedil;": [326], "nearhk;": [10532], "nequiv;": [8802], "nesear;": [10536], "nexist;": [8708], "nltrie;": [8940], "notinE;": [8953, 824], "nparsl;": [11005, 8421], "nprcue;": [8928], "nrarrc;": [10547, 824], "nrarrw;": [8605, 824], "nrtrie;": [8941], "nsccue;": [8929], "nsimeq;": [8772], "ntilde;": [241], "numero;": [8470], "nvDash;": [8877], "nvHarr;": [10500], "nvdash;": [8876], "nvlArr;": [10498], "nvrArr;": [10499], "nwarhk;": [10531], "nwnear;": [10535], "oacute;": [243], "odblac;": [337], "odsold;": [10684], "ograve;": [242], "ominus;": [8854], "origof;": [8886], "oslash;": [248], "otilde;": [245], "otimes;": [8855], "parsim;": [10995], "percnt;": [37], "period;": [46], "permil;": [8240], "phmmat;": [8499], "planck;": [8463], "plankv;": [8463], "plusdo;": [8724], "plusdu;": [10789], "plusmn;": [177], "preceq;": [10927], "primes;": [8473], "prnsim;": [8936], "propto;": [8733], "prurel;": [8880], "puncsp;": [8200], "qprime;": [8279], "rAtail;": [10524], "racute;": [341], "rangle;": [10217], "rarrap;": [10613], "rarrfs;": [10526], "rarrhk;": [8618], "rarrlp;": [8620], "rarrpl;": [10565], "rarrtl;": [8611], "ratail;": [10522], "rbrace;": [125], "rbrack;": [93], "rcaron;": [345], "rcedil;": [343], "rdquor;": [8221], "rfisht;": [10621], "rfloor;": [8971], "rharul;": [10604], "rmoust;": [9137], "roplus;": [10798], "rpargt;": [10644], "rsaquo;": [8250], "rsquor;": [8217], "rthree;": [8908], "rtimes;": [8906], "sacute;": [347], "scaron;": [353], "scedil;": [351], "scnsim;": [8937], "searhk;": [10533], "seswar;": [10537], "sfrown;": [8994], "shchcy;": [1097], "sigmaf;": [962], "sigmav;": [962], "simdot;": [10858], "smashp;": [10803], "softcy;": [1100], "solbar;": [9023], "spades;": [9824], "sqcaps;": [8851, 65024], "sqcups;": [8852, 65024], "sqsube;": [8849], "sqsupe;": [8850], "square;": [9633], "squarf;": [9642], "ssetmn;": [8726], "ssmile;": [8995], "sstarf;": [8902], "subdot;": [10941], "subset;": [8834], "subsim;": [10951], "subsub;": [10965], "subsup;": [10963], "succeq;": [10928], "supdot;": [10942], "supset;": [8835], "supsim;": [10952], "supsub;": [10964], "supsup;": [10966], "swarhk;": [10534], "swnwar;": [10538], "target;": [8982], "tcaron;": [357], "tcedil;": [355], "telrec;": [8981], "there4;": [8756], "thetav;": [977], "thinsp;": [8201], "thksim;": [8764], "timesb;": [8864], "timesd;": [10800], "topbot;": [9014], "topcir;": [10993], "tprime;": [8244], "tridot;": [9708], "tstrok;": [359], "uacute;": [250], "ubreve;": [365], "udblac;": [369], "ufisht;": [10622], "ugrave;": [249], "ulcorn;": [8988], "ulcrop;": [8975], "urcorn;": [8989], "urcrop;": [8974], "utilde;": [361], "vangrt;": [10652], "varphi;": [981], "varrho;": [1009], "veebar;": [8891], "vellip;": [8942], "verbar;": [124], "vsubnE;": [10955, 65024], "vsubne;": [8842, 65024], "vsupnE;": [10956, 65024], "vsupne;": [8843, 65024], "wedbar;": [10847], "wedgeq;": [8793], "weierp;": [8472], "wreath;": [8768], "xoplus;": [10753], "xotime;": [10754], "xsqcup;": [10758], "xuplus;": [10756], "xwedge;": [8896], "yacute;": [253], "zacute;": [378], "zcaron;": [382], "zeetrf;": [8488] } }, { "length": 6, "entities": { "AElig;": [198], "Aacute": [193], "Acirc;": [194], "Agrave": [192], "Alpha;": [913], "Amacr;": [256], "Aogon;": [260], "Aring;": [197], "Atilde": [195], "Breve;": [728], "Ccedil": [199], "Ccirc;": [264], "Colon;": [8759], "Cross;": [10799], "Dashv;": [10980], "Delta;": [916], "Eacute": [201], "Ecirc;": [202], "Egrave": [200], "Emacr;": [274], "Eogon;": [280], "Equal;": [10869], "Gamma;": [915], "Gcirc;": [284], "Hacek;": [711], "Hcirc;": [292], "IJlig;": [306], "Iacute": [205], "Icirc;": [206], "Igrave": [204], "Imacr;": [298], "Iogon;": [302], "Iukcy;": [1030], "Jcirc;": [308], "Jukcy;": [1028], "Kappa;": [922], "Ntilde": [209], "OElig;": [338], "Oacute": [211], "Ocirc;": [212], "Ograve": [210], "Omacr;": [332], "Omega;": [937], "Oslash": [216], "Otilde": [213], "Prime;": [8243], "RBarr;": [10512], "Scirc;": [348], "Sigma;": [931], "THORN;": [222], "TRADE;": [8482], "TSHcy;": [1035], "Theta;": [920], "Tilde;": [8764], "Uacute": [218], "Ubrcy;": [1038], "Ucirc;": [219], "Ugrave": [217], "Umacr;": [362], "Union;": [8899], "Uogon;": [370], "UpTee;": [8869], "Uring;": [366], "VDash;": [8875], "Vdash;": [8873], "Wcirc;": [372], "Wedge;": [8896], "Yacute": [221], "Ycirc;": [374], "aacute": [225], "acirc;": [226], "acute;": [180], "aelig;": [230], "agrave": [224], "aleph;": [8501], "alpha;": [945], "amacr;": [257], "amalg;": [10815], "angle;": [8736], "angrt;": [8735], "angst;": [197], "aogon;": [261], "aring;": [229], "asymp;": [8776], "atilde": [227], "awint;": [10769], "bcong;": [8780], "bdquo;": [8222], "bepsi;": [1014], "blank;": [9251], "blk12;": [9618], "blk14;": [9617], "blk34;": [9619], "block;": [9608], "boxDL;": [9559], "boxDR;": [9556], "boxDl;": [9558], "boxDr;": [9555], "boxHD;": [9574], "boxHU;": [9577], "boxHd;": [9572], "boxHu;": [9575], "boxUL;": [9565], "boxUR;": [9562], "boxUl;": [9564], "boxUr;": [9561], "boxVH;": [9580], "boxVL;": [9571], "boxVR;": [9568], "boxVh;": [9579], "boxVl;": [9570], "boxVr;": [9567], "boxdL;": [9557], "boxdR;": [9554], "boxdl;": [9488], "boxdr;": [9484], "boxhD;": [9573], "boxhU;": [9576], "boxhd;": [9516], "boxhu;": [9524], "boxuL;": [9563], "boxuR;": [9560], "boxul;": [9496], "boxur;": [9492], "boxvH;": [9578], "boxvL;": [9569], "boxvR;": [9566], "boxvh;": [9532], "boxvl;": [9508], "boxvr;": [9500], "breve;": [728], "brvbar": [166], "bsemi;": [8271], "bsime;": [8909], "bsolb;": [10693], "bumpE;": [10926], "bumpe;": [8783], "caret;": [8257], "caron;": [711], "ccaps;": [10829], "ccedil": [231], "ccirc;": [265], "ccups;": [10828], "cedil;": [184], "check;": [10003], "clubs;": [9827], "colon;": [58], "comma;": [44], "crarr;": [8629], "cross;": [10007], "csube;": [10961], "csupe;": [10962], "ctdot;": [8943], "cuepr;": [8926], "cuesc;": [8927], "cupor;": [10821], "curren": [164], "cuvee;": [8910], "cuwed;": [8911], "cwint;": [8753], "dashv;": [8867], "dblac;": [733], "ddarr;": [8650], "delta;": [948], "dharl;": [8643], "dharr;": [8642], "diams;": [9830], "disin;": [8946], "divide": [247], "doteq;": [8784], "dtdot;": [8945], "dtrif;": [9662], "duarr;": [8693], "duhar;": [10607], "eDDot;": [10871], "eacute": [233], "ecirc;": [234], "efDot;": [8786], "egrave": [232], "emacr;": [275], "empty;": [8709], "eogon;": [281], "eplus;": [10865], "epsiv;": [1013], "eqsim;": [8770], "equiv;": [8801], "erDot;": [8787], "erarr;": [10609], "esdot;": [8784], "exist;": [8707], "fflig;": [64256], "filig;": [64257], "fjlig;": [102, 106], "fllig;": [64258], "fltns;": [9649], "forkv;": [10969], "frac12": [189], "frac14": [188], "frac34": [190], "frasl;": [8260], "frown;": [8994], "gamma;": [947], "gcirc;": [285], "gescc;": [10921], "gimel;": [8503], "gneqq;": [8809], "gnsim;": [8935], "grave;": [96], "gsime;": [10894], "gsiml;": [10896], "gtcir;": [10874], "gtdot;": [8919], "harrw;": [8621], "hcirc;": [293], "hoarr;": [8703], "iacute": [237], "icirc;": [238], "iexcl;": [161], "igrave": [236], "iiint;": [8749], "iiota;": [8489], "ijlig;": [307], "imacr;": [299], "image;": [8465], "imath;": [305], "imped;": [437], "infin;": [8734], "iogon;": [303], "iprod;": [10812], "iquest": [191], "isinE;": [8953], "isins;": [8948], "isinv;": [8712], "iukcy;": [1110], "jcirc;": [309], "jmath;": [567], "jukcy;": [1108], "kappa;": [954], "lAarr;": [8666], "lBarr;": [10510], "langd;": [10641], "laquo;": [171], "larrb;": [8676], "lates;": [10925, 65024], "lbarr;": [10508], "lbbrk;": [10098], "lbrke;": [10635], "lceil;": [8968], "ldquo;": [8220], "lescc;": [10920], "lhard;": [8637], "lharu;": [8636], "lhblk;": [9604], "llarr;": [8647], "lltri;": [9722], "lneqq;": [8808], "lnsim;": [8934], "loang;": [10220], "loarr;": [8701], "lobrk;": [10214], "lopar;": [10629], "lrarr;": [8646], "lrhar;": [8651], "lrtri;": [8895], "lsime;": [10893], "lsimg;": [10895], "lsquo;": [8216], "ltcir;": [10873], "ltdot;": [8918], "ltrie;": [8884], "ltrif;": [9666], "mDDot;": [8762], "mdash;": [8212], "micro;": [181], "middot": [183], "minus;": [8722], "mumap;": [8888], "nabla;": [8711], "napid;": [8779, 824], "napos;": [329], "natur;": [9838], "nbump;": [8782, 824], "ncong;": [8775], "ndash;": [8211], "neArr;": [8663], "nearr;": [8599], "nedot;": [8784, 824], "nesim;": [8770, 824], "ngeqq;": [8807, 824], "ngsim;": [8821], "nhArr;": [8654], "nharr;": [8622], "nhpar;": [10994], "nlArr;": [8653], "nlarr;": [8602], "nleqq;": [8806, 824], "nless;": [8814], "nlsim;": [8820], "nltri;": [8938], "notin;": [8713], "notni;": [8716], "npart;": [8706, 824], "nprec;": [8832], "nrArr;": [8655], "nrarr;": [8603], "nrtri;": [8939], "nsime;": [8772], "nsmid;": [8740], "nspar;": [8742], "nsubE;": [10949, 824], "nsube;": [8840], "nsucc;": [8833], "nsupE;": [10950, 824], "nsupe;": [8841], "ntilde": [241], "numsp;": [8199], "nvsim;": [8764, 8402], "nwArr;": [8662], "nwarr;": [8598], "oacute": [243], "ocirc;": [244], "odash;": [8861], "oelig;": [339], "ofcir;": [10687], "ograve": [242], "ohbar;": [10677], "olarr;": [8634], "olcir;": [10686], "oline;": [8254], "omacr;": [333], "omega;": [969], "operp;": [10681], "oplus;": [8853], "orarr;": [8635], "order;": [8500], "oslash": [248], "otilde": [245], "ovbar;": [9021], "parsl;": [11005], "phone;": [9742], "plusb;": [8862], "pluse;": [10866], "plusmn": [177], "pound;": [163], "prcue;": [8828], "prime;": [8242], "prnap;": [10937], "prsim;": [8830], "quest;": [63], "rAarr;": [8667], "rBarr;": [10511], "radic;": [8730], "rangd;": [10642], "range;": [10661], "raquo;": [187], "rarrb;": [8677], "rarrc;": [10547], "rarrw;": [8605], "ratio;": [8758], "rbarr;": [10509], "rbbrk;": [10099], "rbrke;": [10636], "rceil;": [8969], "rdquo;": [8221], "reals;": [8477], "rhard;": [8641], "rharu;": [8640], "rlarr;": [8644], "rlhar;": [8652], "rnmid;": [10990], "roang;": [10221], "roarr;": [8702], "robrk;": [10215], "ropar;": [10630], "rrarr;": [8649], "rsquo;": [8217], "rtrie;": [8885], "rtrif;": [9656], "sbquo;": [8218], "sccue;": [8829], "scirc;": [349], "scnap;": [10938], "scsim;": [8831], "sdotb;": [8865], "sdote;": [10854], "seArr;": [8664], "searr;": [8600], "setmn;": [8726], "sharp;": [9839], "sigma;": [963], "simeq;": [8771], "simgE;": [10912], "simlE;": [10911], "simne;": [8774], "slarr;": [8592], "smile;": [8995], "smtes;": [10924, 65024], "sqcap;": [8851], "sqcup;": [8852], "sqsub;": [8847], "sqsup;": [8848], "srarr;": [8594], "starf;": [9733], "strns;": [175], "subnE;": [10955], "subne;": [8842], "supnE;": [10956], "supne;": [8843], "swArr;": [8665], "swarr;": [8601], "szlig;": [223], "theta;": [952], "thkap;": [8776], "thorn;": [254], "tilde;": [732], "times;": [215], "trade;": [8482], "trisb;": [10701], "tshcy;": [1115], "twixt;": [8812], "uacute": [250], "ubrcy;": [1118], "ucirc;": [251], "udarr;": [8645], "udhar;": [10606], "ugrave": [249], "uharl;": [8639], "uharr;": [8638], "uhblk;": [9600], "ultri;": [9720], "umacr;": [363], "uogon;": [371], "uplus;": [8846], "upsih;": [978], "uring;": [367], "urtri;": [9721], "utdot;": [8944], "utrif;": [9652], "uuarr;": [8648], "vBarv;": [10985], "vDash;": [8872], "varpi;": [982], "vdash;": [8866], "veeeq;": [8794], "vltri;": [8882], "vnsub;": [8834, 8402], "vnsup;": [8835, 8402], "vprop;": [8733], "vrtri;": [8883], "wcirc;": [373], "wedge;": [8743], "xcirc;": [9711], "xdtri;": [9661], "xhArr;": [10234], "xharr;": [10231], "xlArr;": [10232], "xlarr;": [10229], "xodot;": [10752], "xrArr;": [10233], "xrarr;": [10230], "xutri;": [9651], "yacute": [253], "ycirc;": [375] } }, { "length": 5, "entities": { "AElig": [198], "Acirc": [194], "Aopf;": [120120], "Aring": [197], "Ascr;": [119964], "Auml;": [196], "Barv;": [10983], "Beta;": [914], "Bopf;": [120121], "Bscr;": [8492], "CHcy;": [1063], "COPY;": [169], "Cdot;": [266], "Copf;": [8450], "Cscr;": [119966], "DJcy;": [1026], "DScy;": [1029], "DZcy;": [1039], "Darr;": [8609], "Dopf;": [120123], "Dscr;": [119967], "Ecirc": [202], "Edot;": [278], "Eopf;": [120124], "Escr;": [8496], "Esim;": [10867], "Euml;": [203], "Fopf;": [120125], "Fscr;": [8497], "GJcy;": [1027], "Gdot;": [288], "Gopf;": [120126], "Gscr;": [119970], "Hopf;": [8461], "Hscr;": [8459], "IEcy;": [1045], "IOcy;": [1025], "Icirc": [206], "Idot;": [304], "Iopf;": [120128], "Iota;": [921], "Iscr;": [8464], "Iuml;": [207], "Jopf;": [120129], "Jscr;": [119973], "KHcy;": [1061], "KJcy;": [1036], "Kopf;": [120130], "Kscr;": [119974], "LJcy;": [1033], "Lang;": [10218], "Larr;": [8606], "Lopf;": [120131], "Lscr;": [8466], "Mopf;": [120132], "Mscr;": [8499], "NJcy;": [1034], "Nopf;": [8469], "Nscr;": [119977], "Ocirc": [212], "Oopf;": [120134], "Oscr;": [119978], "Ouml;": [214], "Popf;": [8473], "Pscr;": [119979], "QUOT;": [34], "Qopf;": [8474], "Qscr;": [119980], "Rang;": [10219], "Rarr;": [8608], "Ropf;": [8477], "Rscr;": [8475], "SHcy;": [1064], "Sopf;": [120138], "Sqrt;": [8730], "Sscr;": [119982], "Star;": [8902], "THORN": [222], "TScy;": [1062], "Topf;": [120139], "Tscr;": [119983], "Uarr;": [8607], "Ucirc": [219], "Uopf;": [120140], "Upsi;": [978], "Uscr;": [119984], "Uuml;": [220], "Vbar;": [10987], "Vert;": [8214], "Vopf;": [120141], "Vscr;": [119985], "Wopf;": [120142], "Wscr;": [119986], "Xopf;": [120143], "Xscr;": [119987], "YAcy;": [1071], "YIcy;": [1031], "YUcy;": [1070], "Yopf;": [120144], "Yscr;": [119988], "Yuml;": [376], "ZHcy;": [1046], "Zdot;": [379], "Zeta;": [918], "Zopf;": [8484], "Zscr;": [119989], "acirc": [226], "acute": [180], "aelig": [230], "andd;": [10844], "andv;": [10842], "ange;": [10660], "aopf;": [120146], "apid;": [8779], "apos;": [39], "aring": [229], "ascr;": [119990], "auml;": [228], "bNot;": [10989], "bbrk;": [9141], "beta;": [946], "beth;": [8502], "bnot;": [8976], "bopf;": [120147], "boxH;": [9552], "boxV;": [9553], "boxh;": [9472], "boxv;": [9474], "bscr;": [119991], "bsim;": [8765], "bsol;": [92], "bull;": [8226], "bump;": [8782], "caps;": [8745, 65024], "cdot;": [267], "cedil": [184], "cent;": [162], "chcy;": [1095], "cirE;": [10691], "circ;": [710], "cire;": [8791], "comp;": [8705], "cong;": [8773], "copf;": [120148], "copy;": [169], "cscr;": [119992], "csub;": [10959], "csup;": [10960], "cups;": [8746, 65024], "dArr;": [8659], "dHar;": [10597], "darr;": [8595], "dash;": [8208], "diam;": [8900], "djcy;": [1106], "dopf;": [120149], "dscr;": [119993], "dscy;": [1109], "dsol;": [10742], "dtri;": [9663], "dzcy;": [1119], "eDot;": [8785], "ecir;": [8790], "ecirc": [234], "edot;": [279], "emsp;": [8195], "ensp;": [8194], "eopf;": [120150], "epar;": [8917], "epsi;": [949], "escr;": [8495], "esim;": [8770], "euml;": [235], "euro;": [8364], "excl;": [33], "flat;": [9837], "fnof;": [402], "fopf;": [120151], "fork;": [8916], "fscr;": [119995], "gdot;": [289], "geqq;": [8807], "gesl;": [8923, 65024], "gjcy;": [1107], "gnap;": [10890], "gneq;": [10888], "gopf;": [120152], "gscr;": [8458], "gsim;": [8819], "gtcc;": [10919], "gvnE;": [8809, 65024], "hArr;": [8660], "half;": [189], "harr;": [8596], "hbar;": [8463], "hopf;": [120153], "hscr;": [119997], "icirc": [238], "iecy;": [1077], "iexcl": [161], "imof;": [8887], "iocy;": [1105], "iopf;": [120154], "iota;": [953], "iscr;": [119998], "isin;": [8712], "iuml;": [239], "jopf;": [120155], "jscr;": [119999], "khcy;": [1093], "kjcy;": [1116], "kopf;": [120156], "kscr;": [120000], "lArr;": [8656], "lHar;": [10594], "lang;": [10216], "laquo": [171], "larr;": [8592], "late;": [10925], "lcub;": [123], "ldca;": [10550], "ldsh;": [8626], "leqq;": [8806], "lesg;": [8922, 65024], "ljcy;": [1113], "lnap;": [10889], "lneq;": [10887], "lopf;": [120157], "lozf;": [10731], "lpar;": [40], "lscr;": [120001], "lsim;": [8818], "lsqb;": [91], "ltcc;": [10918], "ltri;": [9667], "lvnE;": [8808, 65024], "macr;": [175], "male;": [9794], "malt;": [10016], "micro": [181], "mlcp;": [10971], "mldr;": [8230], "mopf;": [120158], "mscr;": [120002], "nGtv;": [8811, 824], "nLtv;": [8810, 824], "nang;": [8736, 8402], "napE;": [10864, 824], "nbsp;": [160], "ncap;": [10819], "ncup;": [10818], "ngeq;": [8817], "nges;": [10878, 824], "ngtr;": [8815], "nisd;": [8954], "njcy;": [1114], "nldr;": [8229], "nleq;": [8816], "nles;": [10877, 824], "nmid;": [8740], "nopf;": [120159], "npar;": [8742], "npre;": [10927, 824], "nsce;": [10928, 824], "nscr;": [120003], "nsim;": [8769], "nsub;": [8836], "nsup;": [8837], "ntgl;": [8825], "ntlg;": [8824], "nvap;": [8781, 8402], "nvge;": [8805, 8402], "nvgt;": [62, 8402], "nvle;": [8804, 8402], "nvlt;": [60, 8402], "oast;": [8859], "ocir;": [8858], "ocirc": [244], "odiv;": [10808], "odot;": [8857], "ogon;": [731], "oint;": [8750], "omid;": [10678], "oopf;": [120160], "opar;": [10679], "ordf;": [170], "ordm;": [186], "oror;": [10838], "oscr;": [8500], "osol;": [8856], "ouml;": [246], "para;": [182], "part;": [8706], "perp;": [8869], "phiv;": [981], "plus;": [43], "popf;": [120161], "pound": [163], "prap;": [10935], "prec;": [8826], "prnE;": [10933], "prod;": [8719], "prop;": [8733], "pscr;": [120005], "qint;": [10764], "qopf;": [120162], "qscr;": [120006], "quot;": [34], "rArr;": [8658], "rHar;": [10596], "race;": [8765, 817], "rang;": [10217], "raquo": [187], "rarr;": [8594], "rcub;": [125], "rdca;": [10551], "rdsh;": [8627], "real;": [8476], "rect;": [9645], "rhov;": [1009], "ring;": [730], "ropf;": [120163], "rpar;": [41], "rscr;": [120007], "rsqb;": [93], "rtri;": [9657], "scap;": [10936], "scnE;": [10934], "sdot;": [8901], "sect;": [167], "semi;": [59], "sext;": [10038], "shcy;": [1096], "sime;": [8771], "simg;": [10910], "siml;": [10909], "smid;": [8739], "smte;": [10924], "solb;": [10692], "sopf;": [120164], "spar;": [8741], "squf;": [9642], "sscr;": [120008], "star;": [9734], "subE;": [10949], "sube;": [8838], "succ;": [8827], "sung;": [9834], "sup1;": [185], "sup2;": [178], "sup3;": [179], "supE;": [10950], "supe;": [8839], "szlig": [223], "tbrk;": [9140], "tdot;": [8411], "thorn": [254], "times": [215], "tint;": [8749], "toea;": [10536], "topf;": [120165], "tosa;": [10537], "trie;": [8796], "tscr;": [120009], "tscy;": [1094], "uArr;": [8657], "uHar;": [10595], "uarr;": [8593], "ucirc": [251], "uopf;": [120166], "upsi;": [965], "uscr;": [120010], "utri;": [9653], "uuml;": [252], "vArr;": [8661], "vBar;": [10984], "varr;": [8597], "vert;": [124], "vopf;": [120167], "vscr;": [120011], "wopf;": [120168], "wscr;": [120012], "xcap;": [8898], "xcup;": [8899], "xmap;": [10236], "xnis;": [8955], "xopf;": [120169], "xscr;": [120013], "xvee;": [8897], "yacy;": [1103], "yicy;": [1111], "yopf;": [120170], "yscr;": [120014], "yucy;": [1102], "yuml;": [255], "zdot;": [380], "zeta;": [950], "zhcy;": [1078], "zopf;": [120171], "zscr;": [120015], "zwnj;": [8204] } }, { "length": 4, "entities": { "AMP;": [38], "Acy;": [1040], "Afr;": [120068], "And;": [10835], "Auml": [196], "Bcy;": [1041], "Bfr;": [120069], "COPY": [169], "Cap;": [8914], "Cfr;": [8493], "Chi;": [935], "Cup;": [8915], "Dcy;": [1044], "Del;": [8711], "Dfr;": [120071], "Dot;": [168], "ENG;": [330], "ETH;": [208], "Ecy;": [1069], "Efr;": [120072], "Eta;": [919], "Euml": [203], "Fcy;": [1060], "Ffr;": [120073], "Gcy;": [1043], "Gfr;": [120074], "Hat;": [94], "Hfr;": [8460], "Icy;": [1048], "Ifr;": [8465], "Int;": [8748], "Iuml": [207], "Jcy;": [1049], "Jfr;": [120077], "Kcy;": [1050], "Kfr;": [120078], "Lcy;": [1051], "Lfr;": [120079], "Lsh;": [8624], "Map;": [10501], "Mcy;": [1052], "Mfr;": [120080], "Ncy;": [1053], "Nfr;": [120081], "Not;": [10988], "Ocy;": [1054], "Ofr;": [120082], "Ouml": [214], "Pcy;": [1055], "Pfr;": [120083], "Phi;": [934], "Psi;": [936], "QUOT": [34], "Qfr;": [120084], "REG;": [174], "Rcy;": [1056], "Rfr;": [8476], "Rho;": [929], "Rsh;": [8625], "Scy;": [1057], "Sfr;": [120086], "Sub;": [8912], "Sum;": [8721], "Sup;": [8913], "Tab;": [9], "Tau;": [932], "Tcy;": [1058], "Tfr;": [120087], "Ucy;": [1059], "Ufr;": [120088], "Uuml": [220], "Vcy;": [1042], "Vee;": [8897], "Vfr;": [120089], "Wfr;": [120090], "Xfr;": [120091], "Ycy;": [1067], "Yfr;": [120092], "Zcy;": [1047], "Zfr;": [8488], "acE;": [8766, 819], "acd;": [8767], "acy;": [1072], "afr;": [120094], "amp;": [38], "and;": [8743], "ang;": [8736], "apE;": [10864], "ape;": [8778], "ast;": [42], "auml": [228], "bcy;": [1073], "bfr;": [120095], "bne;": [61, 8421], "bot;": [8869], "cap;": [8745], "cent": [162], "cfr;": [120096], "chi;": [967], "cir;": [9675], "copy": [169], "cup;": [8746], "dcy;": [1076], "deg;": [176], "dfr;": [120097], "die;": [168], "div;": [247], "dot;": [729], "ecy;": [1101], "efr;": [120098], "egs;": [10902], "ell;": [8467], "els;": [10901], "eng;": [331], "eta;": [951], "eth;": [240], "euml": [235], "fcy;": [1092], "ffr;": [120099], "gEl;": [10892], "gap;": [10886], "gcy;": [1075], "gel;": [8923], "geq;": [8805], "ges;": [10878], "gfr;": [120100], "ggg;": [8921], "glE;": [10898], "gla;": [10917], "glj;": [10916], "gnE;": [8809], "gne;": [10888], "hfr;": [120101], "icy;": [1080], "iff;": [8660], "ifr;": [120102], "int;": [8747], "iuml": [239], "jcy;": [1081], "jfr;": [120103], "kcy;": [1082], "kfr;": [120104], "lEg;": [10891], "lap;": [10885], "lat;": [10923], "lcy;": [1083], "leg;": [8922], "leq;": [8804], "les;": [10877], "lfr;": [120105], "lgE;": [10897], "lnE;": [8808], "lne;": [10887], "loz;": [9674], "lrm;": [8206], "lsh;": [8624], "macr": [175], "map;": [8614], "mcy;": [1084], "mfr;": [120106], "mho;": [8487], "mid;": [8739], "nGg;": [8921, 824], "nGt;": [8811, 8402], "nLl;": [8920, 824], "nLt;": [8810, 8402], "nap;": [8777], "nbsp": [160], "ncy;": [1085], "nfr;": [120107], "ngE;": [8807, 824], "nge;": [8817], "ngt;": [8815], "nis;": [8956], "niv;": [8715], "nlE;": [8806, 824], "nle;": [8816], "nlt;": [8814], "not;": [172], "npr;": [8832], "nsc;": [8833], "num;": [35], "ocy;": [1086], "ofr;": [120108], "ogt;": [10689], "ohm;": [937], "olt;": [10688], "ord;": [10845], "ordf": [170], "ordm": [186], "orv;": [10843], "ouml": [246], "par;": [8741], "para": [182], "pcy;": [1087], "pfr;": [120109], "phi;": [966], "piv;": [982], "prE;": [10931], "pre;": [10927], "psi;": [968], "qfr;": [120110], "quot": [34], "rcy;": [1088], "reg;": [174], "rfr;": [120111], "rho;": [961], "rlm;": [8207], "rsh;": [8625], "scE;": [10932], "sce;": [10928], "scy;": [1089], "sect": [167], "sfr;": [120112], "shy;": [173], "sim;": [8764], "smt;": [10922], "sol;": [47], "squ;": [9633], "sub;": [8834], "sum;": [8721], "sup1": [185], "sup2": [178], "sup3": [179], "sup;": [8835], "tau;": [964], "tcy;": [1090], "tfr;": [120113], "top;": [8868], "ucy;": [1091], "ufr;": [120114], "uml;": [168], "uuml": [252], "vcy;": [1074], "vee;": [8744], "vfr;": [120115], "wfr;": [120116], "xfr;": [120117], "ycy;": [1099], "yen;": [165], "yfr;": [120118], "yuml": [255], "zcy;": [1079], "zfr;": [120119], "zwj;": [8205] } }, { "length": 3, "entities": { "AMP": [38], "DD;": [8517], "ETH": [208], "GT;": [62], "Gg;": [8921], "Gt;": [8811], "Im;": [8465], "LT;": [60], "Ll;": [8920], "Lt;": [8810], "Mu;": [924], "Nu;": [925], "Or;": [10836], "Pi;": [928], "Pr;": [10939], "REG": [174], "Re;": [8476], "Sc;": [10940], "Xi;": [926], "ac;": [8766], "af;": [8289], "amp": [38], "ap;": [8776], "dd;": [8518], "deg": [176], "ee;": [8519], "eg;": [10906], "el;": [10905], "eth": [240], "gE;": [8807], "ge;": [8805], "gg;": [8811], "gl;": [8823], "gt;": [62], "ic;": [8291], "ii;": [8520], "in;": [8712], "it;": [8290], "lE;": [8806], "le;": [8804], "lg;": [8822], "ll;": [8810], "lt;": [60], "mp;": [8723], "mu;": [956], "ne;": [8800], "ni;": [8715], "not": [172], "nu;": [957], "oS;": [9416], "or;": [8744], "pi;": [960], "pm;": [177], "pr;": [8826], "reg": [174], "rx;": [8478], "sc;": [8827], "shy": [173], "uml": [168], "wp;": [8472], "wr;": [8768], "xi;": [958], "yen": [165] } }, { "length": 2, "entities": { "GT": [62], "LT": [60], "gt": [62], "lt": [60] } }];
2023 const TABULATION = 0x09;
2024 const CARRIAGE_RETURN = 0x0D;
2025 const LINE_FEED = 0x0A;
2026 const FORM_FEED = 0x0C;
2028 const EXCLAMATION_MARK = 0x21;
2029 const QUOTATION_MARK = 0x22;
2030 const NUMBER_SIGN = 0x23;
2031 const AMPERSAND = 0x26;
2032 const APOSTROPHE = 0x27;
2033 const HYPHEN_MINUS = 0x2D;
2034 const SOLIDUS = 0x2F;
2035 const DIGIT_0 = 0x30;
2036 const DIGIT_9 = 0x39;
2037 const SEMICOLON = 0x3B;
2038 const LESS_THAN_SIGN = 0x3C;
2039 const EQUALS_SIGN = 0x3D;
2040 const GREATER_THAN_SIGN = 0x3E;
2041 const QUESTION_MARK = 0x3F;
2042 const LATIN_CAPITAL_A = 0x41;
2043 const LATIN_CAPITAL_D = 0x44;
2044 const LATIN_CAPITAL_F = 0x46;
2045 const LATIN_CAPITAL_X = 0x58;
2046 const LATIN_CAPITAL_Z = 0x5A;
2047 const LEFT_SQUARE_BRACKET = 0x5B;
2048 const RIGHT_SQUARE_BRACKET = 0x5D;
2049 const GRAVE_ACCENT = 0x60;
2050 const LATIN_SMALL_A = 0x61;
2051 const LATIN_SMALL_F = 0x66;
2052 const LATIN_SMALL_X = 0x78;
2053 const LATIN_SMALL_Z = 0x7A;
2054 const LEFT_CURLY_BRACKET = 0x7B;
2055 const RIGHT_CURLY_BRACKET = 0x7D;
2056 const NULL_REPLACEMENT = 0xFFFD;
2057 function isWhitespace(cp) {
2058 return cp === TABULATION || cp === LINE_FEED || cp === FORM_FEED || cp === CARRIAGE_RETURN || cp === SPACE;
2060 function isUpperLetter(cp) {
2061 return cp >= LATIN_CAPITAL_A && cp <= LATIN_CAPITAL_Z;
2063 function isLowerLetter(cp) {
2064 return cp >= LATIN_SMALL_A && cp <= LATIN_SMALL_Z;
2066 function isLetter(cp) {
2067 return isLowerLetter(cp) || isUpperLetter(cp);
2069 function isDigit(cp) {
2070 return cp >= DIGIT_0 && cp <= DIGIT_9;
2072 function isUpperHexDigit(cp) {
2073 return cp >= LATIN_CAPITAL_A && cp <= LATIN_CAPITAL_F;
2075 function isLowerHexDigit(cp) {
2076 return cp >= LATIN_SMALL_A && cp <= LATIN_SMALL_F;
2078 function isHexDigit(cp) {
2079 return isDigit(cp) || isUpperHexDigit(cp) || isLowerHexDigit(cp);
2081 function isControl(cp) {
2082 return (cp >= 0 && cp <= 0x1F) || (cp >= 0x7F && cp <= 0x9F);
2084 function isSurrogate(cp) {
2085 return cp >= 0xD800 && cp <= 0xDFFF;
2087 function isSurrogatePair(cp) {
2088 return cp >= 0xDC00 && cp <= 0xDFFF;
2090 function isNonCharacter(cp) {
2091 return ((cp >= 0xFDD0 && cp <= 0xFDEF) ||
2092 ((cp & 0xFFFE) === 0xFFFE && cp <= 0x10FFFF));
2094 function toLowerCodePoint(cp) {
2100 debug("[html] the source code length: %d", text.length);
2103 this.lineTerminators = [];
2104 this.lastCodePoint = NULL;
2108 this.state = "DATA";
2109 this.returnState = "DATA";
2110 this.reconsuming = false;
2112 this.crStartOffset = -1;
2115 this.committedToken = null;
2116 this.provisionalToken = null;
2117 this.currentToken = null;
2118 this.lastTagOpenToken = null;
2119 this.tokenStartOffset = -1;
2120 this.tokenStartColumn = -1;
2121 this.tokenStartLine = 1;
2122 this.namespace = NS.HTML;
2123 this.expressionEnabled = false;
2126 let cp = this.lastCodePoint;
2127 while (this.committedToken == null &&
2128 (cp !== EOF || this.reconsuming)) {
2129 if (this.provisionalToken != null && !this.isProvisionalState()) {
2130 this.commitProvisionalToken();
2131 if (this.committedToken != null) {
2135 if (this.reconsuming) {
2136 this.reconsuming = false;
2137 cp = this.lastCodePoint;
2140 cp = this.consumeNextCodePoint();
2142 debug("[html] parse", cp, this.state);
2143 this.state = this[this.state](cp);
2146 const token = this.consumeCommittedToken();
2147 if (token != null) {
2152 if (this.currentToken != null) {
2154 const token = this.consumeCommittedToken();
2155 if (token != null) {
2159 return this.currentToken;
2161 consumeCommittedToken() {
2162 const token = this.committedToken;
2163 this.committedToken = null;
2166 consumeNextCodePoint() {
2167 if (this.offset >= this.text.length) {
2168 this.lastCodePoint = EOF;
2171 this.offset += this.lastCodePoint >= 0x10000 ? 2 : 1;
2172 if (this.offset >= this.text.length) {
2173 this.advanceLocation();
2174 this.lastCodePoint = EOF;
2177 const cp = this.text.codePointAt(this.offset);
2178 if (isSurrogate(this.text.charCodeAt(this.offset)) &&
2179 !isSurrogatePair(this.text.charCodeAt(this.offset + 1))) {
2180 this.reportParseError("surrogate-in-input-stream");
2182 if (isNonCharacter(cp)) {
2183 this.reportParseError("noncharacter-in-input-stream");
2185 if (isControl(cp) && !isWhitespace(cp) && cp !== NULL) {
2186 this.reportParseError("control-character-in-input-stream");
2188 if (this.lastCodePoint === CARRIAGE_RETURN && cp === LINE_FEED) {
2189 this.lastCodePoint = LINE_FEED;
2190 this.gaps.push(this.offset);
2191 return this.consumeNextCodePoint();
2193 this.advanceLocation();
2194 this.lastCodePoint = cp;
2195 if (cp === CARRIAGE_RETURN) {
2201 if (this.lastCodePoint === LINE_FEED) {
2202 this.lineTerminators.push(this.offset);
2207 this.column += this.lastCodePoint >= 0x10000 ? 2 : 1;
2210 reconsumeAs(state) {
2211 this.reconsuming = true;
2214 reportParseError(code) {
2215 const error = ParseError.fromCode(code, this.offset, this.line, this.column);
2216 this.errors.push(error);
2217 debug("[html] syntax error:", error.message);
2219 setStartTokenMark() {
2220 this.tokenStartOffset = this.offset;
2221 this.tokenStartLine = this.line;
2222 this.tokenStartColumn = this.column;
2224 clearStartTokenMark() {
2225 this.tokenStartOffset = -1;
2228 if (this.tokenStartOffset === -1) {
2229 this.setStartTokenMark();
2231 const offset = this.tokenStartOffset;
2232 const line = this.tokenStartLine;
2233 const column = this.tokenStartColumn;
2234 if (this.currentToken != null) {
2237 this.tokenStartOffset = -1;
2238 const token = (this.currentToken = {
2240 range: [offset, -1],
2242 start: { line, column },
2243 end: { line: -1, column: -1 },
2247 debug("[html] start token: %d %s", offset, token.type);
2248 return this.currentToken;
2251 if (this.currentToken == null) {
2252 throw new Error("Invalid state");
2254 if (this.tokenStartOffset === -1) {
2255 this.setStartTokenMark();
2257 const token = this.currentToken;
2258 const offset = this.tokenStartOffset;
2259 const line = this.tokenStartLine;
2260 const column = this.tokenStartColumn;
2261 const provisional = this.isProvisionalState();
2262 this.currentToken = null;
2263 this.tokenStartOffset = -1;
2264 token.range[1] = offset;
2265 token.loc.end.line = line;
2266 token.loc.end.column = column;
2267 if (token.range[0] === offset && !provisional) {
2268 debug("[html] abandon token: %j %s %j", token.range, token.type, token.value);
2272 if (this.provisionalToken != null) {
2273 this.commitProvisionalToken();
2275 this.provisionalToken = token;
2276 debug("[html] provisional-commit token: %j %s %j", token.range, token.type, token.value);
2279 this.commitToken(token);
2283 commitToken(token) {
2284 assert(this.committedToken == null, "Invalid state: the commited token existed already.");
2285 debug("[html] commit token: %j %j %s %j", token.range, token.loc, token.type, token.value);
2286 this.committedToken = token;
2287 if (token.type === "HTMLTagOpen") {
2288 this.lastTagOpenToken = token;
2291 isProvisionalState() {
2292 return (this.state.startsWith("RCDATA_") ||
2293 this.state.startsWith("RAWTEXT_"));
2295 commitProvisionalToken() {
2296 assert(this.provisionalToken != null, "Invalid state: the provisional token was not found.");
2297 const token = this.provisionalToken;
2298 this.provisionalToken = null;
2299 if (token.range[0] < token.range[1]) {
2300 this.commitToken(token);
2303 rollbackProvisionalToken() {
2304 assert(this.currentToken != null);
2305 assert(this.provisionalToken != null);
2306 const token = this.currentToken;
2307 debug("[html] rollback token: %d %s", token.range[0], token.type);
2308 this.currentToken = this.provisionalToken;
2309 this.provisionalToken = null;
2311 appendTokenValue(cp, expected) {
2312 const token = this.currentToken;
2313 if (token == null || (expected != null && token.type !== expected)) {
2314 const msg1 = expected ? `"${expected}" type` : "any token";
2315 const msg2 = token ? `"${token.type}" type` : "no token";
2316 throw new Error(`Tokenizer: Invalid state. Expected ${msg1}, but got ${msg2}.`);
2318 token.value += String.fromCodePoint(cp);
2320 isAppropriateEndTagOpen() {
2321 return (this.currentToken != null &&
2322 this.lastTagOpenToken != null &&
2323 this.currentToken.type === "HTMLEndTagOpen" &&
2324 this.currentToken.value === this.lastTagOpenToken.value);
2327 this.clearStartTokenMark();
2329 const type = isWhitespace(cp) ? "HTMLWhitespace" : "HTMLText";
2330 if (this.currentToken != null && this.currentToken.type !== type) {
2332 return this.reconsumeAs(this.state);
2334 if (this.currentToken == null) {
2335 this.startToken(type);
2337 if (cp === AMPERSAND) {
2338 this.returnState = "DATA";
2339 return "CHARACTER_REFERENCE";
2341 if (cp === LESS_THAN_SIGN) {
2342 this.setStartTokenMark();
2345 if (cp === LEFT_CURLY_BRACKET && this.expressionEnabled) {
2346 this.setStartTokenMark();
2347 this.returnState = "DATA";
2348 return "V_EXPRESSION_START";
2350 if (cp === RIGHT_CURLY_BRACKET && this.expressionEnabled) {
2351 this.setStartTokenMark();
2352 this.returnState = "DATA";
2353 return "V_EXPRESSION_END";
2359 this.reportParseError("unexpected-null-character");
2361 this.appendTokenValue(cp, type);
2362 cp = this.consumeNextCodePoint();
2366 this.clearStartTokenMark();
2368 const type = isWhitespace(cp) ? "HTMLWhitespace" : "HTMLRCDataText";
2369 if (this.currentToken != null && this.currentToken.type !== type) {
2371 return this.reconsumeAs(this.state);
2373 if (this.currentToken == null) {
2374 this.startToken(type);
2376 if (cp === AMPERSAND) {
2377 this.returnState = "RCDATA";
2378 return "CHARACTER_REFERENCE";
2380 if (cp === LESS_THAN_SIGN) {
2381 this.setStartTokenMark();
2382 return "RCDATA_LESS_THAN_SIGN";
2384 if (cp === LEFT_CURLY_BRACKET && this.expressionEnabled) {
2385 this.setStartTokenMark();
2386 this.returnState = "RCDATA";
2387 return "V_EXPRESSION_START";
2389 if (cp === RIGHT_CURLY_BRACKET && this.expressionEnabled) {
2390 this.setStartTokenMark();
2391 this.returnState = "RCDATA";
2392 return "V_EXPRESSION_END";
2398 this.reportParseError("unexpected-null-character");
2399 cp = NULL_REPLACEMENT;
2401 this.appendTokenValue(cp, type);
2402 cp = this.consumeNextCodePoint();
2406 this.clearStartTokenMark();
2408 const type = isWhitespace(cp) ? "HTMLWhitespace" : "HTMLRawText";
2409 if (this.currentToken != null && this.currentToken.type !== type) {
2411 return this.reconsumeAs(this.state);
2413 if (this.currentToken == null) {
2414 this.startToken(type);
2416 if (cp === LESS_THAN_SIGN) {
2417 this.setStartTokenMark();
2418 return "RAWTEXT_LESS_THAN_SIGN";
2420 if (cp === LEFT_CURLY_BRACKET && this.expressionEnabled) {
2421 this.setStartTokenMark();
2422 this.returnState = "RAWTEXT";
2423 return "V_EXPRESSION_START";
2425 if (cp === RIGHT_CURLY_BRACKET && this.expressionEnabled) {
2426 this.setStartTokenMark();
2427 this.returnState = "RAWTEXT";
2428 return "V_EXPRESSION_END";
2434 this.reportParseError("unexpected-null-character");
2435 cp = NULL_REPLACEMENT;
2437 this.appendTokenValue(cp, type);
2438 cp = this.consumeNextCodePoint();
2442 if (cp === EXCLAMATION_MARK) {
2443 return "MARKUP_DECLARATION_OPEN";
2445 if (cp === SOLIDUS) {
2446 return "END_TAG_OPEN";
2449 this.startToken("HTMLTagOpen");
2450 return this.reconsumeAs("TAG_NAME");
2452 if (cp === QUESTION_MARK) {
2453 this.reportParseError("unexpected-question-mark-instead-of-tag-name");
2454 this.startToken("HTMLBogusComment");
2455 return this.reconsumeAs("BOGUS_COMMENT");
2458 this.clearStartTokenMark();
2459 this.reportParseError("eof-before-tag-name");
2460 this.appendTokenValue(LESS_THAN_SIGN, "HTMLText");
2463 this.reportParseError("invalid-first-character-of-tag-name");
2464 this.appendTokenValue(LESS_THAN_SIGN, "HTMLText");
2465 return this.reconsumeAs("DATA");
2469 this.startToken("HTMLEndTagOpen");
2470 return this.reconsumeAs("TAG_NAME");
2472 if (cp === GREATER_THAN_SIGN) {
2474 this.reportParseError("missing-end-tag-name");
2478 this.clearStartTokenMark();
2479 this.reportParseError("eof-before-tag-name");
2480 this.appendTokenValue(LESS_THAN_SIGN, "HTMLText");
2481 this.appendTokenValue(SOLIDUS, "HTMLText");
2484 this.reportParseError("invalid-first-character-of-tag-name");
2485 this.startToken("HTMLBogusComment");
2486 return this.reconsumeAs("BOGUS_COMMENT");
2490 if (isWhitespace(cp)) {
2492 return "BEFORE_ATTRIBUTE_NAME";
2494 if (cp === SOLIDUS) {
2496 this.setStartTokenMark();
2497 return "SELF_CLOSING_START_TAG";
2499 if (cp === GREATER_THAN_SIGN) {
2500 this.startToken("HTMLTagClose");
2504 this.reportParseError("eof-in-tag");
2508 this.reportParseError("unexpected-null-character");
2509 cp = NULL_REPLACEMENT;
2511 this.appendTokenValue(isUpperLetter(cp) ? toLowerCodePoint(cp) : cp, null);
2512 cp = this.consumeNextCodePoint();
2515 RCDATA_LESS_THAN_SIGN(cp) {
2516 if (cp === SOLIDUS) {
2518 return "RCDATA_END_TAG_OPEN";
2520 this.appendTokenValue(LESS_THAN_SIGN, "HTMLRCDataText");
2521 return this.reconsumeAs("RCDATA");
2523 RCDATA_END_TAG_OPEN(cp) {
2525 this.startToken("HTMLEndTagOpen");
2526 return this.reconsumeAs("RCDATA_END_TAG_NAME");
2528 this.appendTokenValue(LESS_THAN_SIGN, "HTMLRCDataText");
2529 this.appendTokenValue(SOLIDUS, "HTMLRCDataText");
2530 return this.reconsumeAs("RCDATA");
2532 RCDATA_END_TAG_NAME(cp) {
2534 if (isWhitespace(cp) && this.isAppropriateEndTagOpen()) {
2536 return "BEFORE_ATTRIBUTE_NAME";
2538 if (cp === SOLIDUS && this.isAppropriateEndTagOpen()) {
2540 this.setStartTokenMark();
2541 return "SELF_CLOSING_START_TAG";
2543 if (cp === GREATER_THAN_SIGN && this.isAppropriateEndTagOpen()) {
2544 this.startToken("HTMLTagClose");
2547 if (!isLetter(cp)) {
2548 this.rollbackProvisionalToken();
2549 this.appendTokenValue(LESS_THAN_SIGN, "HTMLRCDataText");
2550 this.appendTokenValue(SOLIDUS, "HTMLRCDataText");
2551 for (const cp1 of this.buffer) {
2552 this.appendTokenValue(cp1, "HTMLRCDataText");
2554 return this.reconsumeAs("RCDATA");
2556 this.appendTokenValue(isUpperLetter(cp) ? toLowerCodePoint(cp) : cp, "HTMLEndTagOpen");
2557 this.buffer.push(cp);
2558 cp = this.consumeNextCodePoint();
2561 RAWTEXT_LESS_THAN_SIGN(cp) {
2562 if (cp === SOLIDUS) {
2564 return "RAWTEXT_END_TAG_OPEN";
2566 this.appendTokenValue(LESS_THAN_SIGN, "HTMLRawText");
2567 return this.reconsumeAs("RAWTEXT");
2569 RAWTEXT_END_TAG_OPEN(cp) {
2571 this.startToken("HTMLEndTagOpen");
2572 return this.reconsumeAs("RAWTEXT_END_TAG_NAME");
2574 this.appendTokenValue(LESS_THAN_SIGN, "HTMLRawText");
2575 this.appendTokenValue(SOLIDUS, "HTMLRawText");
2576 return this.reconsumeAs("RAWTEXT");
2578 RAWTEXT_END_TAG_NAME(cp) {
2580 if (cp === SOLIDUS && this.isAppropriateEndTagOpen()) {
2582 this.setStartTokenMark();
2583 return "SELF_CLOSING_START_TAG";
2585 if (cp === GREATER_THAN_SIGN && this.isAppropriateEndTagOpen()) {
2586 this.startToken("HTMLTagClose");
2589 if (isWhitespace(cp) && this.isAppropriateEndTagOpen()) {
2591 return "BEFORE_ATTRIBUTE_NAME";
2593 if (!isLetter(cp)) {
2594 this.rollbackProvisionalToken();
2595 this.appendTokenValue(LESS_THAN_SIGN, "HTMLRawText");
2596 this.appendTokenValue(SOLIDUS, "HTMLRawText");
2597 for (const cp1 of this.buffer) {
2598 this.appendTokenValue(cp1, "HTMLRawText");
2600 return this.reconsumeAs("RAWTEXT");
2602 this.appendTokenValue(isUpperLetter(cp) ? toLowerCodePoint(cp) : cp, "HTMLEndTagOpen");
2603 this.buffer.push(cp);
2604 cp = this.consumeNextCodePoint();
2607 BEFORE_ATTRIBUTE_NAME(cp) {
2608 while (isWhitespace(cp)) {
2609 cp = this.consumeNextCodePoint();
2611 if (cp === SOLIDUS || cp === GREATER_THAN_SIGN || cp === EOF) {
2612 return this.reconsumeAs("AFTER_ATTRIBUTE_NAME");
2614 if (cp === EQUALS_SIGN) {
2615 this.reportParseError("unexpected-equals-sign-before-attribute-name");
2616 this.startToken("HTMLIdentifier");
2617 this.appendTokenValue(cp, "HTMLIdentifier");
2618 return "ATTRIBUTE_NAME";
2620 this.startToken("HTMLIdentifier");
2621 return this.reconsumeAs("ATTRIBUTE_NAME");
2623 ATTRIBUTE_NAME(cp) {
2625 if (isWhitespace(cp) ||
2627 cp === GREATER_THAN_SIGN ||
2630 return this.reconsumeAs("AFTER_ATTRIBUTE_NAME");
2632 if (cp === EQUALS_SIGN) {
2633 this.startToken("HTMLAssociation");
2634 return "BEFORE_ATTRIBUTE_VALUE";
2637 this.reportParseError("unexpected-null-character");
2638 cp = NULL_REPLACEMENT;
2640 if (cp === QUOTATION_MARK ||
2641 cp === APOSTROPHE ||
2642 cp === LESS_THAN_SIGN) {
2643 this.reportParseError("unexpected-character-in-attribute-name");
2645 this.appendTokenValue(isUpperLetter(cp) ? toLowerCodePoint(cp) : cp, "HTMLIdentifier");
2646 cp = this.consumeNextCodePoint();
2649 AFTER_ATTRIBUTE_NAME(cp) {
2650 while (isWhitespace(cp)) {
2651 cp = this.consumeNextCodePoint();
2653 if (cp === SOLIDUS) {
2654 this.setStartTokenMark();
2655 return "SELF_CLOSING_START_TAG";
2657 if (cp === EQUALS_SIGN) {
2658 this.startToken("HTMLAssociation");
2659 return "BEFORE_ATTRIBUTE_VALUE";
2661 if (cp === GREATER_THAN_SIGN) {
2662 this.startToken("HTMLTagClose");
2666 this.reportParseError("eof-in-tag");
2669 this.startToken("HTMLIdentifier");
2670 return this.reconsumeAs("ATTRIBUTE_NAME");
2672 BEFORE_ATTRIBUTE_VALUE(cp) {
2674 while (isWhitespace(cp)) {
2675 cp = this.consumeNextCodePoint();
2677 if (cp === GREATER_THAN_SIGN) {
2678 this.reportParseError("missing-attribute-value");
2679 this.startToken("HTMLTagClose");
2682 this.startToken("HTMLLiteral");
2683 if (cp === QUOTATION_MARK) {
2684 return "ATTRIBUTE_VALUE_DOUBLE_QUOTED";
2686 if (cp === APOSTROPHE) {
2687 return "ATTRIBUTE_VALUE_SINGLE_QUOTED";
2689 return this.reconsumeAs("ATTRIBUTE_VALUE_UNQUOTED");
2691 ATTRIBUTE_VALUE_DOUBLE_QUOTED(cp) {
2693 if (cp === QUOTATION_MARK) {
2694 return "AFTER_ATTRIBUTE_VALUE_QUOTED";
2696 if (cp === AMPERSAND) {
2697 this.returnState = "ATTRIBUTE_VALUE_DOUBLE_QUOTED";
2698 return "CHARACTER_REFERENCE";
2701 this.reportParseError("unexpected-null-character");
2702 cp = NULL_REPLACEMENT;
2705 this.reportParseError("eof-in-tag");
2708 this.appendTokenValue(cp, "HTMLLiteral");
2709 cp = this.consumeNextCodePoint();
2712 ATTRIBUTE_VALUE_SINGLE_QUOTED(cp) {
2714 if (cp === APOSTROPHE) {
2715 return "AFTER_ATTRIBUTE_VALUE_QUOTED";
2717 if (cp === AMPERSAND) {
2718 this.returnState = "ATTRIBUTE_VALUE_SINGLE_QUOTED";
2719 return "CHARACTER_REFERENCE";
2722 this.reportParseError("unexpected-null-character");
2723 cp = NULL_REPLACEMENT;
2726 this.reportParseError("eof-in-tag");
2729 this.appendTokenValue(cp, "HTMLLiteral");
2730 cp = this.consumeNextCodePoint();
2733 ATTRIBUTE_VALUE_UNQUOTED(cp) {
2735 if (isWhitespace(cp)) {
2737 return "BEFORE_ATTRIBUTE_NAME";
2739 if (cp === AMPERSAND) {
2740 this.returnState = "ATTRIBUTE_VALUE_UNQUOTED";
2741 return "CHARACTER_REFERENCE";
2743 if (cp === GREATER_THAN_SIGN) {
2744 this.startToken("HTMLTagClose");
2748 this.reportParseError("unexpected-null-character");
2749 cp = NULL_REPLACEMENT;
2751 if (cp === QUOTATION_MARK ||
2752 cp === APOSTROPHE ||
2753 cp === LESS_THAN_SIGN ||
2754 cp === EQUALS_SIGN ||
2755 cp === GRAVE_ACCENT) {
2756 this.reportParseError("unexpected-character-in-unquoted-attribute-value");
2759 this.reportParseError("eof-in-tag");
2762 this.appendTokenValue(cp, "HTMLLiteral");
2763 cp = this.consumeNextCodePoint();
2766 AFTER_ATTRIBUTE_VALUE_QUOTED(cp) {
2768 if (isWhitespace(cp)) {
2769 return "BEFORE_ATTRIBUTE_NAME";
2771 if (cp === SOLIDUS) {
2772 this.setStartTokenMark();
2773 return "SELF_CLOSING_START_TAG";
2775 if (cp === GREATER_THAN_SIGN) {
2776 this.startToken("HTMLTagClose");
2780 this.reportParseError("eof-in-tag");
2783 this.reportParseError("missing-whitespace-between-attributes");
2784 return this.reconsumeAs("BEFORE_ATTRIBUTE_NAME");
2786 SELF_CLOSING_START_TAG(cp) {
2787 if (cp === GREATER_THAN_SIGN) {
2788 this.startToken("HTMLSelfClosingTagClose");
2792 this.reportParseError("eof-in-tag");
2795 this.reportParseError("unexpected-solidus-in-tag");
2796 this.clearStartTokenMark();
2797 return this.reconsumeAs("BEFORE_ATTRIBUTE_NAME");
2801 if (cp === GREATER_THAN_SIGN) {
2808 cp = NULL_REPLACEMENT;
2810 this.appendTokenValue(cp, null);
2811 cp = this.consumeNextCodePoint();
2814 MARKUP_DECLARATION_OPEN(cp) {
2815 if (cp === HYPHEN_MINUS && this.text[this.offset + 1] === "-") {
2818 this.startToken("HTMLComment");
2819 return "COMMENT_START";
2821 if (cp === LATIN_CAPITAL_D &&
2822 this.text.slice(this.offset + 1, this.offset + 7) === "OCTYPE") {
2823 this.startToken("HTMLBogusComment");
2824 this.appendTokenValue(cp, "HTMLBogusComment");
2825 return "BOGUS_COMMENT";
2827 if (cp === LEFT_SQUARE_BRACKET &&
2828 this.text.slice(this.offset + 1, this.offset + 7) === "CDATA[") {
2831 if (this.namespace === NS.HTML) {
2832 this.reportParseError("cdata-in-html-content");
2833 this.startToken("HTMLBogusComment").value = "[CDATA[";
2834 return "BOGUS_COMMENT";
2836 this.startToken("HTMLCDataText");
2837 return "CDATA_SECTION";
2839 this.reportParseError("incorrectly-opened-comment");
2840 this.startToken("HTMLBogusComment");
2841 return this.reconsumeAs("BOGUS_COMMENT");
2844 if (cp === HYPHEN_MINUS) {
2845 return "COMMENT_START_DASH";
2847 if (cp === GREATER_THAN_SIGN) {
2848 this.reportParseError("abrupt-closing-of-empty-comment");
2851 return this.reconsumeAs("COMMENT");
2853 COMMENT_START_DASH(cp) {
2854 if (cp === HYPHEN_MINUS) {
2855 return "COMMENT_END";
2857 if (cp === GREATER_THAN_SIGN) {
2858 this.reportParseError("abrupt-closing-of-empty-comment");
2862 this.reportParseError("eof-in-comment");
2865 this.appendTokenValue(HYPHEN_MINUS, "HTMLComment");
2866 return this.reconsumeAs("COMMENT");
2870 if (cp === LESS_THAN_SIGN) {
2871 this.appendTokenValue(LESS_THAN_SIGN, "HTMLComment");
2872 return "COMMENT_LESS_THAN_SIGN";
2874 if (cp === HYPHEN_MINUS) {
2875 return "COMMENT_END_DASH";
2878 this.reportParseError("unexpected-null-character");
2879 cp = NULL_REPLACEMENT;
2882 this.reportParseError("eof-in-comment");
2885 this.appendTokenValue(cp, "HTMLComment");
2886 cp = this.consumeNextCodePoint();
2889 COMMENT_LESS_THAN_SIGN(cp) {
2891 if (cp === EXCLAMATION_MARK) {
2892 this.appendTokenValue(cp, "HTMLComment");
2893 return "COMMENT_LESS_THAN_SIGN_BANG";
2895 if (cp !== LESS_THAN_SIGN) {
2896 return this.reconsumeAs("COMMENT");
2898 this.appendTokenValue(cp, "HTMLComment");
2899 cp = this.consumeNextCodePoint();
2902 COMMENT_LESS_THAN_SIGN_BANG(cp) {
2903 if (cp === HYPHEN_MINUS) {
2904 return "COMMENT_LESS_THAN_SIGN_BANG_DASH";
2906 return this.reconsumeAs("COMMENT");
2908 COMMENT_LESS_THAN_SIGN_BANG_DASH(cp) {
2909 if (cp === HYPHEN_MINUS) {
2910 return "COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH";
2912 return this.reconsumeAs("COMMENT_END_DASH");
2914 COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH(cp) {
2915 if (cp !== GREATER_THAN_SIGN && cp !== EOF) {
2916 this.reportParseError("nested-comment");
2918 return this.reconsumeAs("COMMENT_END");
2920 COMMENT_END_DASH(cp) {
2921 if (cp === HYPHEN_MINUS) {
2922 return "COMMENT_END";
2925 this.reportParseError("eof-in-comment");
2928 this.appendTokenValue(HYPHEN_MINUS, "HTMLComment");
2929 return this.reconsumeAs("COMMENT");
2933 if (cp === GREATER_THAN_SIGN) {
2936 if (cp === EXCLAMATION_MARK) {
2937 return "COMMENT_END_BANG";
2940 this.reportParseError("eof-in-comment");
2943 this.appendTokenValue(HYPHEN_MINUS, "HTMLComment");
2944 if (cp !== HYPHEN_MINUS) {
2945 this.appendTokenValue(HYPHEN_MINUS, "HTMLComment");
2946 return this.reconsumeAs("COMMENT");
2948 cp = this.consumeNextCodePoint();
2951 COMMENT_END_BANG(cp) {
2952 if (cp === HYPHEN_MINUS) {
2953 this.appendTokenValue(HYPHEN_MINUS, "HTMLComment");
2954 this.appendTokenValue(EXCLAMATION_MARK, "HTMLComment");
2955 return "COMMENT_END_DASH";
2957 if (cp === GREATER_THAN_SIGN) {
2958 this.reportParseError("incorrectly-closed-comment");
2962 this.reportParseError("eof-in-comment");
2965 this.appendTokenValue(HYPHEN_MINUS, "HTMLComment");
2966 this.appendTokenValue(EXCLAMATION_MARK, "HTMLComment");
2967 return this.reconsumeAs("COMMENT");
2971 if (cp === RIGHT_SQUARE_BRACKET) {
2972 return "CDATA_SECTION_BRACKET";
2975 this.reportParseError("eof-in-cdata");
2978 this.appendTokenValue(cp, "HTMLCDataText");
2979 cp = this.consumeNextCodePoint();
2982 CDATA_SECTION_BRACKET(cp) {
2983 if (cp === RIGHT_SQUARE_BRACKET) {
2984 return "CDATA_SECTION_END";
2986 this.appendTokenValue(RIGHT_SQUARE_BRACKET, "HTMLCDataText");
2987 return this.reconsumeAs("CDATA_SECTION");
2989 CDATA_SECTION_END(cp) {
2991 if (cp === GREATER_THAN_SIGN) {
2994 if (cp !== RIGHT_SQUARE_BRACKET) {
2995 this.appendTokenValue(RIGHT_SQUARE_BRACKET, "HTMLCDataText");
2996 this.appendTokenValue(RIGHT_SQUARE_BRACKET, "HTMLCDataText");
2997 return this.reconsumeAs("CDATA_SECTION");
2999 this.appendTokenValue(RIGHT_SQUARE_BRACKET, "HTMLCDataText");
3000 cp = this.consumeNextCodePoint();
3003 CHARACTER_REFERENCE(cp) {
3004 this.crStartOffset = this.offset - 1;
3005 this.buffer = [AMPERSAND];
3006 if (isWhitespace(cp) || cp === LESS_THAN_SIGN || cp === EOF) {
3007 return this.reconsumeAs("CHARACTER_REFERENCE_END");
3009 if (cp === NUMBER_SIGN) {
3010 this.buffer.push(cp);
3011 return "NUMERIC_CHARACTER_REFERENCE";
3013 return this.reconsumeAs("NAMED_CHARACTER_REFERENCE");
3015 NAMED_CHARACTER_REFERENCE(cp) {
3016 for (const entitySet of entitySets) {
3017 const length = entitySet.length;
3018 const entities = entitySet.entities;
3019 const text = this.text.slice(this.offset, this.offset + length);
3020 const codepoints = entities[text];
3021 if (codepoints == null) {
3024 const semi = text.endsWith(";");
3025 const next = this.text.codePointAt(this.offset + 1);
3026 this.offset += length - 1;
3027 this.column += length - 1;
3028 if (this.returnState.startsWith("ATTR") &&
3031 (next === EQUALS_SIGN || isLetter(next) || isDigit(next))) {
3032 for (const cp1 of text) {
3033 this.buffer.push(cp1.codePointAt(0));
3038 this.reportParseError("missing-semicolon-after-character-reference");
3040 this.buffer = codepoints;
3042 return "CHARACTER_REFERENCE_END";
3044 for (const cp0 of this.buffer) {
3045 this.appendTokenValue(cp0, null);
3047 this.appendTokenValue(cp, null);
3048 return "AMBIGUOUS_AMPERSAND";
3050 AMBIGUOUS_AMPERSAND(cp) {
3051 while (isDigit(cp) || isLetter(cp)) {
3052 this.appendTokenValue(cp, null);
3053 cp = this.consumeNextCodePoint();
3055 if (cp === SEMICOLON) {
3056 this.reportParseError("unknown-named-character-reference");
3058 return this.reconsumeAs(this.returnState);
3060 NUMERIC_CHARACTER_REFERENCE(cp) {
3062 if (cp === LATIN_SMALL_X || cp === LATIN_CAPITAL_X) {
3063 this.buffer.push(cp);
3064 return "HEXADEMICAL_CHARACTER_REFERENCE_START";
3066 return this.reconsumeAs("DECIMAL_CHARACTER_REFERENCE_START");
3068 HEXADEMICAL_CHARACTER_REFERENCE_START(cp) {
3069 if (isHexDigit(cp)) {
3070 return this.reconsumeAs("HEXADEMICAL_CHARACTER_REFERENCE");
3072 this.reportParseError("absence-of-digits-in-numeric-character-reference");
3073 return this.reconsumeAs("CHARACTER_REFERENCE_END");
3075 DECIMAL_CHARACTER_REFERENCE_START(cp) {
3077 return this.reconsumeAs("DECIMAL_CHARACTER_REFERENCE");
3079 this.reportParseError("absence-of-digits-in-numeric-character-reference");
3080 return this.reconsumeAs("CHARACTER_REFERENCE_END");
3082 HEXADEMICAL_CHARACTER_REFERENCE(cp) {
3085 this.crCode = 16 * this.crCode + (cp - 0x30);
3087 else if (isUpperHexDigit(cp)) {
3088 this.crCode = 16 * this.crCode + (cp - 0x37);
3090 else if (isLowerHexDigit(cp)) {
3091 this.crCode = 16 * this.crCode + (cp - 0x57);
3094 if (cp === SEMICOLON) {
3095 return "NUMERIC_CHARACTER_REFERENCE_END";
3097 this.reportParseError("missing-semicolon-after-character-reference");
3098 return this.reconsumeAs("NUMERIC_CHARACTER_REFERENCE_END");
3100 cp = this.consumeNextCodePoint();
3103 DECIMAL_CHARACTER_REFERENCE(cp) {
3106 this.crCode = 10 * this.crCode + (cp - 0x30);
3109 if (cp === SEMICOLON) {
3110 return "NUMERIC_CHARACTER_REFERENCE_END";
3112 this.reportParseError("missing-semicolon-after-character-reference");
3113 return this.reconsumeAs("NUMERIC_CHARACTER_REFERENCE_END");
3115 cp = this.consumeNextCodePoint();
3118 NUMERIC_CHARACTER_REFERENCE_END(_cp) {
3119 let code = this.crCode;
3121 this.reportParseError("null-character-reference");
3122 code = NULL_REPLACEMENT;
3124 else if (code > 0x10ffff) {
3125 this.reportParseError("character-reference-outside-unicode-range");
3126 code = NULL_REPLACEMENT;
3128 else if (isSurrogate(code)) {
3129 this.reportParseError("surrogate-character-reference");
3130 code = NULL_REPLACEMENT;
3132 else if (isNonCharacter(code)) {
3133 this.reportParseError("noncharacter-character-reference");
3135 else if (code === 0x0d || (isControl(code) && !isWhitespace(code))) {
3136 this.reportParseError("control-character-reference");
3137 code = alternativeCR.get(code) || code;
3139 this.buffer = [code];
3140 return this.reconsumeAs("CHARACTER_REFERENCE_END");
3142 CHARACTER_REFERENCE_END(_cp) {
3143 assert(this.currentToken != null);
3144 const token = this.currentToken;
3145 const len0 = token.value.length;
3146 for (const cp1 of this.buffer) {
3147 this.appendTokenValue(cp1, null);
3149 const newLength = token.value.length - len0;
3150 for (let i = this.crStartOffset + newLength; i < this.offset; ++i) {
3153 return this.reconsumeAs(this.returnState);
3155 V_EXPRESSION_START(cp) {
3156 if (cp === LEFT_CURLY_BRACKET) {
3157 this.startToken("VExpressionStart");
3158 this.appendTokenValue(LEFT_CURLY_BRACKET, null);
3159 this.appendTokenValue(LEFT_CURLY_BRACKET, null);
3160 return this.returnState;
3162 this.appendTokenValue(LEFT_CURLY_BRACKET, null);
3163 return this.reconsumeAs(this.returnState);
3165 V_EXPRESSION_END(cp) {
3166 if (cp === RIGHT_CURLY_BRACKET) {
3167 this.startToken("VExpressionEnd");
3168 this.appendTokenValue(RIGHT_CURLY_BRACKET, null);
3169 this.appendTokenValue(RIGHT_CURLY_BRACKET, null);
3170 return this.returnState;
3172 this.appendTokenValue(RIGHT_CURLY_BRACKET, null);
3173 return this.reconsumeAs(this.returnState);
3177 function getPossibleTypes(parsedSelector) {
3178 switch (parsedSelector.type) {
3180 return [parsedSelector.value];
3182 const typesForComponents = parsedSelector.selectors.map(getPossibleTypes);
3183 if (typesForComponents.every(Boolean)) {
3184 return union(...typesForComponents);
3189 const typesForComponents = parsedSelector.selectors.map(getPossibleTypes).filter(Boolean);
3190 if (!typesForComponents.length) {
3193 return intersection(...typesForComponents);
3199 return getPossibleTypes(parsedSelector.right);
3204 function countClassAttributes(parsedSelector) {
3205 switch (parsedSelector.type) {
3210 return countClassAttributes(parsedSelector.left) + countClassAttributes(parsedSelector.right);
3214 return parsedSelector.selectors.reduce((sum, childSelector) => sum + countClassAttributes(childSelector), 0);
3218 case "nth-last-child":
3224 function countIdentifiers(parsedSelector) {
3225 switch (parsedSelector.type) {
3230 return countIdentifiers(parsedSelector.left) + countIdentifiers(parsedSelector.right);
3234 return parsedSelector.selectors.reduce((sum, childSelector) => sum + countIdentifiers(childSelector), 0);
3241 function compareSpecificity(selectorA, selectorB) {
3242 return selectorA.attributeCount - selectorB.attributeCount ||
3243 selectorA.identifierCount - selectorB.identifierCount ||
3244 (selectorA.rawSelector <= selectorB.rawSelector ? -1 : 1);
3246 function tryParseSelector(rawSelector) {
3248 return esquery.parse(rawSelector.replace(/:exit$/, ""));
3251 if (typeof err.offset === "number") {
3252 throw new Error(`Syntax error in selector "${rawSelector}" at position ${err.offset}: ${err.message}`);
3257 const parseSelector = memoize(rawSelector => {
3258 const parsedSelector = tryParseSelector(rawSelector);
3261 isExit: rawSelector.endsWith(":exit"),
3263 listenerTypes: getPossibleTypes(parsedSelector),
3264 attributeCount: countClassAttributes(parsedSelector),
3265 identifierCount: countIdentifiers(parsedSelector),
3268 class NodeEventGenerator {
3269 constructor(emitter) {
3270 this.emitter = emitter;
3271 this.currentAncestry = [];
3272 this.enterSelectorsByNodeType = new Map();
3273 this.exitSelectorsByNodeType = new Map();
3274 this.anyTypeEnterSelectors = [];
3275 this.anyTypeExitSelectors = [];
3276 const eventNames = typeof emitter.eventNames === "function"
3277 ? emitter.eventNames()
3278 : Object.keys(emitter._events);
3279 for (const rawSelector of eventNames) {
3280 if (typeof rawSelector === "symbol") {
3283 const selector = parseSelector(rawSelector);
3284 if (selector.listenerTypes) {
3285 for (const nodeType of selector.listenerTypes) {
3286 const typeMap = selector.isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType;
3287 let selectors = typeMap.get(nodeType);
3288 if (selectors == null) {
3289 typeMap.set(nodeType, (selectors = []));
3291 selectors.push(selector);
3295 (selector.isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors).push(selector);
3298 this.anyTypeEnterSelectors.sort(compareSpecificity);
3299 this.anyTypeExitSelectors.sort(compareSpecificity);
3300 for (const selectorList of this.enterSelectorsByNodeType.values()) {
3301 selectorList.sort(compareSpecificity);
3303 for (const selectorList of this.exitSelectorsByNodeType.values()) {
3304 selectorList.sort(compareSpecificity);
3307 applySelector(node, selector) {
3308 if (esquery.matches(node, selector.parsedSelector, this.currentAncestry)) {
3309 this.emitter.emit(selector.rawSelector, node);
3312 applySelectors(node, isExit) {
3313 const selectorsByNodeType = (isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType).get(node.type) || [];
3314 const anyTypeSelectors = isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors;
3315 let selectorsByTypeIndex = 0;
3316 let anyTypeSelectorsIndex = 0;
3317 while (selectorsByTypeIndex < selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length) {
3318 if (selectorsByTypeIndex >= selectorsByNodeType.length ||
3319 (anyTypeSelectorsIndex < anyTypeSelectors.length && compareSpecificity(anyTypeSelectors[anyTypeSelectorsIndex], selectorsByNodeType[selectorsByTypeIndex]) < 0)) {
3320 this.applySelector(node, anyTypeSelectors[anyTypeSelectorsIndex++]);
3323 this.applySelector(node, selectorsByNodeType[selectorsByTypeIndex++]);
3329 this.currentAncestry.unshift(node.parent);
3331 this.applySelectors(node, false);
3334 this.applySelectors(node, true);
3335 this.currentAncestry.shift();
3339 function getStartLocation(token) {
3340 return token.range[0];
3342 function search(tokens, location) {
3343 return sortedIndexBy(tokens, { range: [location] }, getStartLocation);
3345 function getFirstIndex(tokens, indexMap, startLoc) {
3346 if (startLoc in indexMap) {
3347 return indexMap[startLoc];
3349 if ((startLoc - 1) in indexMap) {
3350 const index = indexMap[startLoc - 1];
3351 const token = (index >= 0 && index < tokens.length) ? tokens[index] : null;
3352 if (token && token.range[0] >= startLoc) {
3359 function getLastIndex(tokens, indexMap, endLoc) {
3360 if (endLoc in indexMap) {
3361 return indexMap[endLoc] - 1;
3363 if ((endLoc - 1) in indexMap) {
3364 const index = indexMap[endLoc - 1];
3365 const token = (index >= 0 && index < tokens.length) ? tokens[index] : null;
3366 if (token && token.range[1] > endLoc) {
3371 return tokens.length - 1;
3376 this.current = null;
3379 return this.moveNext() ? this.current : null;
3383 while (this.moveNext()) {
3384 tokens.push(this.current);
3390 class BackwardTokenCommentCursor extends Cursor {
3391 constructor(tokens, comments, indexMap, startLoc, endLoc) {
3393 this.tokens = tokens;
3394 this.comments = comments;
3395 this.tokenIndex = getLastIndex(tokens, indexMap, endLoc);
3396 this.commentIndex = search(comments, endLoc) - 1;
3397 this.border = startLoc;
3400 const token = (this.tokenIndex >= 0) ? this.tokens[this.tokenIndex] : null;
3401 const comment = (this.commentIndex >= 0) ? this.comments[this.commentIndex] : null;
3402 if (token && (!comment || token.range[1] > comment.range[1])) {
3403 this.current = token;
3404 this.tokenIndex -= 1;
3407 this.current = comment;
3408 this.commentIndex -= 1;
3411 this.current = null;
3413 return this.current != null && (this.border === -1 || this.current.range[0] >= this.border);
3417 class BackwardTokenCursor extends Cursor {
3418 constructor(tokens, _comments, indexMap, startLoc, endLoc) {
3420 this.tokens = tokens;
3421 this.index = getLastIndex(tokens, indexMap, endLoc);
3422 this.indexEnd = getFirstIndex(tokens, indexMap, startLoc);
3425 if (this.index >= this.indexEnd) {
3426 this.current = this.tokens[this.index];
3433 return (this.index >= this.indexEnd) ? this.tokens[this.index] : null;
3437 class DecorativeCursor extends Cursor {
3438 constructor(cursor) {
3440 this.cursor = cursor;
3443 const retv = this.cursor.moveNext();
3444 this.current = this.cursor.current;
3449 class FilterCursor extends DecorativeCursor {
3450 constructor(cursor, predicate) {
3452 this.predicate = predicate;
3455 const predicate = this.predicate;
3456 while (super.moveNext()) {
3457 if (predicate(this.current)) {
3465 class ForwardTokenCommentCursor extends Cursor {
3466 constructor(tokens, comments, indexMap, startLoc, endLoc) {
3468 this.tokens = tokens;
3469 this.comments = comments;
3470 this.tokenIndex = getFirstIndex(tokens, indexMap, startLoc);
3471 this.commentIndex = search(comments, startLoc);
3472 this.border = endLoc;
3475 const token = (this.tokenIndex < this.tokens.length) ? this.tokens[this.tokenIndex] : null;
3476 const comment = (this.commentIndex < this.comments.length) ? this.comments[this.commentIndex] : null;
3477 if (token && (!comment || token.range[0] < comment.range[0])) {
3478 this.current = token;
3479 this.tokenIndex += 1;
3482 this.current = comment;
3483 this.commentIndex += 1;
3486 this.current = null;
3488 return this.current != null && (this.border === -1 || this.current.range[1] <= this.border);
3492 class ForwardTokenCursor extends Cursor {
3493 constructor(tokens, _comments, indexMap, startLoc, endLoc) {
3495 this.tokens = tokens;
3496 this.index = getFirstIndex(tokens, indexMap, startLoc);
3497 this.indexEnd = getLastIndex(tokens, indexMap, endLoc);
3500 if (this.index <= this.indexEnd) {
3501 this.current = this.tokens[this.index];
3508 return (this.index <= this.indexEnd) ? this.tokens[this.index] : null;
3511 return this.tokens.slice(this.index, this.indexEnd + 1);
3515 class LimitCursor extends DecorativeCursor {
3516 constructor(cursor, count) {
3521 if (this.count > 0) {
3523 return super.moveNext();
3529 class SkipCursor extends DecorativeCursor {
3530 constructor(cursor, count) {
3535 while (this.count > 0) {
3537 if (!super.moveNext()) {
3541 return super.moveNext();
3545 class CursorFactory {
3546 constructor(TokenCursor, TokenCommentCursor) {
3547 this.TokenCursor = TokenCursor;
3548 this.TokenCommentCursor = TokenCommentCursor;
3550 createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments) {
3551 const TokenCursor = includeComments ? this.TokenCommentCursor : this.TokenCursor;
3552 return new TokenCursor(tokens, comments, indexMap, startLoc, endLoc);
3554 createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, count) {
3555 let cursor = this.createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments);
3557 cursor = new FilterCursor(cursor, filter);
3560 cursor = new SkipCursor(cursor, skip);
3563 cursor = new LimitCursor(cursor, count);
3568 const forward = new CursorFactory(ForwardTokenCursor, ForwardTokenCommentCursor);
3569 const backward = new CursorFactory(BackwardTokenCursor, BackwardTokenCommentCursor);
3571 class PaddedTokenCursor extends ForwardTokenCursor {
3572 constructor(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) {
3573 super(tokens, comments, indexMap, startLoc, endLoc);
3574 this.index = Math.max(0, this.index - beforeCount);
3575 this.indexEnd = Math.min(tokens.length - 1, this.indexEnd + afterCount);
3579 function isCommentToken(token) {
3580 return token.type === "Line" || token.type === "Block" || token.type === "Shebang";
3582 function createIndexMap(tokens, comments) {
3583 const map = Object.create(null);
3585 let commentIndex = 0;
3588 while (tokenIndex < tokens.length || commentIndex < comments.length) {
3589 nextStart = (commentIndex < comments.length) ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER;
3590 while (tokenIndex < tokens.length && (range = tokens[tokenIndex].range)[0] < nextStart) {
3591 map[range[0]] = tokenIndex;
3592 map[range[1] - 1] = tokenIndex;
3595 nextStart = (tokenIndex < tokens.length) ? tokens[tokenIndex].range[0] : Number.MAX_SAFE_INTEGER;
3596 while (commentIndex < comments.length && (range = comments[commentIndex].range)[0] < nextStart) {
3597 map[range[0]] = tokenIndex;
3598 map[range[1] - 1] = tokenIndex;
3604 function createCursorWithSkip(factory, tokens, comments, indexMap, startLoc, endLoc, opts) {
3605 let includeComments = false;
3608 if (typeof opts === "number") {
3611 else if (typeof opts === "function") {
3615 includeComments = Boolean(opts.includeComments);
3616 skip = opts.skip || 0;
3617 filter = opts.filter || null;
3619 assert(skip >= 0, "options.skip should be zero or a positive integer.");
3620 assert(!filter || typeof filter === "function", "options.filter should be a function.");
3621 return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, -1);
3623 function createCursorWithCount(factory, tokens, comments, indexMap, startLoc, endLoc, opts) {
3624 let includeComments = false;
3626 let countExists = false;
3628 if (typeof opts === "number") {
3632 else if (typeof opts === "function") {
3636 includeComments = Boolean(opts.includeComments);
3637 count = opts.count || 0;
3638 countExists = typeof opts.count === "number";
3639 filter = opts.filter || null;
3641 assert(count >= 0, "options.count should be zero or a positive integer.");
3642 assert(!filter || typeof filter === "function", "options.filter should be a function.");
3643 return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, 0, countExists ? count : -1);
3645 function createCursorWithPadding(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) {
3646 if (typeof beforeCount === "undefined" && typeof afterCount === "undefined") {
3647 return new ForwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc);
3649 if (typeof beforeCount === "number" || typeof beforeCount === "undefined") {
3650 return new PaddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount || 0, afterCount || 0);
3652 return createCursorWithCount(forward, tokens, comments, indexMap, startLoc, endLoc, beforeCount);
3654 function getAdjacentCommentTokensFromCursor(cursor) {
3656 let currentToken = cursor.getOneToken();
3657 while (currentToken && isCommentToken(currentToken)) {
3658 tokens.push(currentToken);
3659 currentToken = cursor.getOneToken();
3664 constructor(tokens, comments) {
3665 this._tokens = tokens;
3666 this._comments = comments;
3667 this._indexMap = createIndexMap(tokens, comments);
3669 getTokenByRangeStart(offset, options) {
3670 const includeComments = Boolean(options && options.includeComments);
3671 const token = forward.createBaseCursor(this._tokens, this._comments, this._indexMap, offset, -1, includeComments).getOneToken();
3672 if (token && token.range[0] === offset) {
3677 getFirstToken(node, options) {
3678 return createCursorWithSkip(forward, this._tokens, this._comments, this._indexMap, node.range[0], node.range[1], options).getOneToken();
3680 getLastToken(node, options) {
3681 return createCursorWithSkip(backward, this._tokens, this._comments, this._indexMap, node.range[0], node.range[1], options).getOneToken();
3683 getTokenBefore(node, options) {
3684 return createCursorWithSkip(backward, this._tokens, this._comments, this._indexMap, -1, node.range[0], options).getOneToken();
3686 getTokenAfter(node, options) {
3687 return createCursorWithSkip(forward, this._tokens, this._comments, this._indexMap, node.range[1], -1, options).getOneToken();
3689 getFirstTokenBetween(left, right, options) {
3690 return createCursorWithSkip(forward, this._tokens, this._comments, this._indexMap, left.range[1], right.range[0], options).getOneToken();
3692 getLastTokenBetween(left, right, options) {
3693 return createCursorWithSkip(backward, this._tokens, this._comments, this._indexMap, left.range[1], right.range[0], options).getOneToken();
3695 getTokenOrCommentBefore(node, skip) {
3696 return this.getTokenBefore(node, { includeComments: true, skip });
3698 getTokenOrCommentAfter(node, skip) {
3699 return this.getTokenAfter(node, { includeComments: true, skip });
3701 getFirstTokens(node, options) {
3702 return createCursorWithCount(forward, this._tokens, this._comments, this._indexMap, node.range[0], node.range[1], options).getAllTokens();
3704 getLastTokens(node, options) {
3705 return createCursorWithCount(backward, this._tokens, this._comments, this._indexMap, node.range[0], node.range[1], options).getAllTokens().reverse();
3707 getTokensBefore(node, options) {
3708 return createCursorWithCount(backward, this._tokens, this._comments, this._indexMap, -1, node.range[0], options).getAllTokens().reverse();
3710 getTokensAfter(node, options) {
3711 return createCursorWithCount(forward, this._tokens, this._comments, this._indexMap, node.range[1], -1, options).getAllTokens();
3713 getFirstTokensBetween(left, right, options) {
3714 return createCursorWithCount(forward, this._tokens, this._comments, this._indexMap, left.range[1], right.range[0], options).getAllTokens();
3716 getLastTokensBetween(left, right, options) {
3717 return createCursorWithCount(backward, this._tokens, this._comments, this._indexMap, left.range[1], right.range[0], options).getAllTokens().reverse();
3719 getTokens(node, beforeCount, afterCount) {
3720 return createCursorWithPadding(this._tokens, this._comments, this._indexMap, node.range[0], node.range[1], beforeCount, afterCount).getAllTokens();
3722 getTokensBetween(left, right, padding) {
3723 return createCursorWithPadding(this._tokens, this._comments, this._indexMap, left.range[1], right.range[0], padding, typeof padding === "number" ? padding : undefined).getAllTokens();
3725 commentsExistBetween(left, right) {
3726 const index = search(this._comments, left.range[1]);
3727 return (index < this._comments.length &&
3728 this._comments[index].range[1] <= right.range[0]);
3730 getCommentsBefore(nodeOrToken) {
3731 const cursor = createCursorWithCount(backward, this._tokens, this._comments, this._indexMap, -1, nodeOrToken.range[0], { includeComments: true });
3732 return getAdjacentCommentTokensFromCursor(cursor).reverse();
3734 getCommentsAfter(nodeOrToken) {
3735 const cursor = createCursorWithCount(forward, this._tokens, this._comments, this._indexMap, nodeOrToken.range[1], -1, { includeComments: true });
3736 return getAdjacentCommentTokensFromCursor(cursor);
3738 getCommentsInside(node) {
3739 return this.getTokens(node, {
3740 includeComments: true,
3741 filter: isCommentToken,
3746 const emitters = new WeakMap();
3747 const stores = new WeakMap();
3748 function define(rootAST, document) {
3750 defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor) {
3751 if (scriptVisitor == null) {
3754 if (rootAST.templateBody == null) {
3755 return scriptVisitor;
3757 let emitter = emitters.get(rootAST);
3758 if (emitter == null) {
3759 emitter = new EventEmitter();
3760 emitter.setMaxListeners(0);
3761 emitters.set(rootAST, emitter);
3762 const programExitHandler = scriptVisitor["Program:exit"];
3763 scriptVisitor["Program:exit"] = node => {
3765 if (typeof programExitHandler === "function") {
3766 programExitHandler(node);
3768 const generator = new NodeEventGenerator(emitter);
3769 traverseNodes(rootAST.templateBody, generator);
3772 scriptVisitor["Program:exit"] = programExitHandler;
3773 emitters.delete(rootAST);
3777 for (const selector of Object.keys(templateBodyVisitor)) {
3778 emitter.on(selector, templateBodyVisitor[selector]);
3780 return scriptVisitor;
3782 getTemplateBodyTokenStore() {
3783 const ast = rootAST.templateBody;
3784 const key = ast || stores;
3785 let store = stores.get(key);
3789 ? new TokenStore(ast.tokens, ast.comments)
3790 : new TokenStore([], []);
3791 stores.set(key, store);
3795 getDocumentFragment() {
3801 const STARTS_WITH_LT = /^\s*</u;
3802 function isVueFile(code, options) {
3803 const filePath = options.filePath || "unknown.js";
3804 return path.extname(filePath) === ".vue" || STARTS_WITH_LT.test(code);
3806 function isTemplateElement(node) {
3807 return node.type === "VElement" && node.name === "template";
3809 function isScriptElement(node) {
3810 return node.type === "VElement" && node.name === "script";
3812 function isLang(attribute) {
3813 return attribute.directive === false && attribute.key.name === "lang";
3815 function getLang(element, defaultLang) {
3816 const langAttr = element && element.startTag.attributes.find(isLang);
3817 const lang = langAttr && langAttr.value && langAttr.value.value;
3818 return lang || defaultLang;
3820 function parseForESLint(code, options) {
3821 options = Object.assign({
3830 if (!isVueFile(code, options)) {
3831 result = parseScript(code, options);
3835 const skipParsingScript = options.parser === false;
3836 const tokenizer = new Tokenizer(code);
3837 const rootAST = new Parser(tokenizer, options).parse();
3838 const locationCalcurator = new LocationCalculator(tokenizer.gaps, tokenizer.lineTerminators);
3839 const script = rootAST.children.find(isScriptElement);
3840 const template = rootAST.children.find(isTemplateElement);
3841 const templateLang = getLang(template, "html");
3842 const concreteInfo = {
3843 tokens: rootAST.tokens,
3844 comments: rootAST.comments,
3845 errors: rootAST.errors,
3847 const templateBody = template != null && templateLang === "html"
3848 ? Object.assign(template, concreteInfo)
3850 if (skipParsingScript || script == null) {
3851 result = parseScript("", options);
3854 result = parseScriptElement(script, locationCalcurator, options);
3856 result.ast.templateBody = templateBody;
3859 result.services = Object.assign(result.services || {}, define(result.ast, document));
3862 function parse(code, options) {
3863 return parseForESLint(code, options).ast;
3866 exports.AST = index;
3867 exports.parse = parse;
3868 exports.parseForESLint = parseForESLint;
3869 //# sourceMappingURL=index.js.map