MindMap/frontend/node_modules/markmap-html-parser/dist/index.js

6001 lines
210 KiB
JavaScript
Raw Normal View History

"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const markmapCommon = require("markmap-common");
const defaultOpts$1 = {
_useHtmlParser2: false
};
function flattenOptions(options, baseOptions) {
if (!options) {
return baseOptions !== null && baseOptions !== void 0 ? baseOptions : defaultOpts$1;
}
const opts = {
_useHtmlParser2: !!options.xmlMode,
...baseOptions,
...options
};
if (options.xml) {
opts._useHtmlParser2 = true;
opts.xmlMode = true;
if (options.xml !== true) {
Object.assign(opts, options.xml);
}
} else if (options.xmlMode) {
opts._useHtmlParser2 = true;
}
return opts;
}
var ElementType;
(function(ElementType2) {
ElementType2["Root"] = "root";
ElementType2["Text"] = "text";
ElementType2["Directive"] = "directive";
ElementType2["Comment"] = "comment";
ElementType2["Script"] = "script";
ElementType2["Style"] = "style";
ElementType2["Tag"] = "tag";
ElementType2["CDATA"] = "cdata";
ElementType2["Doctype"] = "doctype";
})(ElementType || (ElementType = {}));
function isTag$1(elem) {
return elem.type === ElementType.Tag || elem.type === ElementType.Script || elem.type === ElementType.Style;
}
const Root = ElementType.Root;
const Text$1 = ElementType.Text;
const Directive = ElementType.Directive;
const Comment$1 = ElementType.Comment;
const Script = ElementType.Script;
const Style = ElementType.Style;
const Tag = ElementType.Tag;
const CDATA$1 = ElementType.CDATA;
const Doctype = ElementType.Doctype;
class Node {
constructor() {
this.parent = null;
this.prev = null;
this.next = null;
this.startIndex = null;
this.endIndex = null;
}
// Read-write aliases for properties
/**
* Same as {@link parent}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get parentNode() {
return this.parent;
}
set parentNode(parent2) {
this.parent = parent2;
}
/**
* Same as {@link prev}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get previousSibling() {
return this.prev;
}
set previousSibling(prev2) {
this.prev = prev2;
}
/**
* Same as {@link next}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get nextSibling() {
return this.next;
}
set nextSibling(next2) {
this.next = next2;
}
/**
* Clone this node, and optionally its children.
*
* @param recursive Clone child nodes as well.
* @returns A clone of the node.
*/
cloneNode(recursive = false) {
return cloneNode(this, recursive);
}
}
class DataNode extends Node {
/**
* @param data The content of the data node
*/
constructor(data2) {
super();
this.data = data2;
}
/**
* Same as {@link data}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get nodeValue() {
return this.data;
}
set nodeValue(data2) {
this.data = data2;
}
}
class Text extends DataNode {
constructor() {
super(...arguments);
this.type = ElementType.Text;
}
get nodeType() {
return 3;
}
}
class Comment extends DataNode {
constructor() {
super(...arguments);
this.type = ElementType.Comment;
}
get nodeType() {
return 8;
}
}
class ProcessingInstruction extends DataNode {
constructor(name, data2) {
super(data2);
this.name = name;
this.type = ElementType.Directive;
}
get nodeType() {
return 1;
}
}
class NodeWithChildren extends Node {
/**
* @param children Children of the node. Only certain node types can have children.
*/
constructor(children2) {
super();
this.children = children2;
}
// Aliases
/** First child of the node. */
get firstChild() {
var _a2;
return (_a2 = this.children[0]) !== null && _a2 !== void 0 ? _a2 : null;
}
/** Last child of the node. */
get lastChild() {
return this.children.length > 0 ? this.children[this.children.length - 1] : null;
}
/**
* Same as {@link children}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get childNodes() {
return this.children;
}
set childNodes(children2) {
this.children = children2;
}
}
class CDATA extends NodeWithChildren {
constructor() {
super(...arguments);
this.type = ElementType.CDATA;
}
get nodeType() {
return 4;
}
}
class Document extends NodeWithChildren {
constructor() {
super(...arguments);
this.type = ElementType.Root;
}
get nodeType() {
return 9;
}
}
class Element extends NodeWithChildren {
/**
* @param name Name of the tag, eg. `div`, `span`.
* @param attribs Object mapping attribute names to attribute values.
* @param children Children of the node.
*/
constructor(name, attribs, children2 = [], type = name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag) {
super(children2);
this.name = name;
this.attribs = attribs;
this.type = type;
}
get nodeType() {
return 1;
}
// DOM Level 1 aliases
/**
* Same as {@link name}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get tagName() {
return this.name;
}
set tagName(name) {
this.name = name;
}
get attributes() {
return Object.keys(this.attribs).map((name) => {
var _a2, _b;
return {
name,
value: this.attribs[name],
namespace: (_a2 = this["x-attribsNamespace"]) === null || _a2 === void 0 ? void 0 : _a2[name],
prefix: (_b = this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name]
};
});
}
}
function isTag(node) {
return isTag$1(node);
}
function isCDATA(node) {
return node.type === ElementType.CDATA;
}
function isText(node) {
return node.type === ElementType.Text;
}
function isComment(node) {
return node.type === ElementType.Comment;
}
function isDirective(node) {
return node.type === ElementType.Directive;
}
function isDocument(node) {
return node.type === ElementType.Root;
}
function hasChildren(node) {
return Object.prototype.hasOwnProperty.call(node, "children");
}
function cloneNode(node, recursive = false) {
let result;
if (isText(node)) {
result = new Text(node.data);
} else if (isComment(node)) {
result = new Comment(node.data);
} else if (isTag(node)) {
const children2 = recursive ? cloneChildren(node.children) : [];
const clone2 = new Element(node.name, { ...node.attribs }, children2);
children2.forEach((child) => child.parent = clone2);
if (node.namespace != null) {
clone2.namespace = node.namespace;
}
if (node["x-attribsNamespace"]) {
clone2["x-attribsNamespace"] = { ...node["x-attribsNamespace"] };
}
if (node["x-attribsPrefix"]) {
clone2["x-attribsPrefix"] = { ...node["x-attribsPrefix"] };
}
result = clone2;
} else if (isCDATA(node)) {
const children2 = recursive ? cloneChildren(node.children) : [];
const clone2 = new CDATA(children2);
children2.forEach((child) => child.parent = clone2);
result = clone2;
} else if (isDocument(node)) {
const children2 = recursive ? cloneChildren(node.children) : [];
const clone2 = new Document(children2);
children2.forEach((child) => child.parent = clone2);
if (node["x-mode"]) {
clone2["x-mode"] = node["x-mode"];
}
result = clone2;
} else if (isDirective(node)) {
const instruction = new ProcessingInstruction(node.name, node.data);
if (node["x-name"] != null) {
instruction["x-name"] = node["x-name"];
instruction["x-publicId"] = node["x-publicId"];
instruction["x-systemId"] = node["x-systemId"];
}
result = instruction;
} else {
throw new Error(`Not implemented yet: ${node.type}`);
}
result.startIndex = node.startIndex;
result.endIndex = node.endIndex;
if (node.sourceCodeLocation != null) {
result.sourceCodeLocation = node.sourceCodeLocation;
}
return result;
}
function cloneChildren(childs) {
const children2 = childs.map((child) => cloneNode(child, true));
for (let i = 1; i < children2.length; i++) {
children2[i].prev = children2[i - 1];
children2[i - 1].next = children2[i];
}
return children2;
}
const defaultOpts = {
withStartIndices: false,
withEndIndices: false,
xmlMode: false
};
class DomHandler {
/**
* @param callback Called once parsing has completed.
* @param options Settings for the handler.
* @param elementCB Callback whenever a tag is closed.
*/
constructor(callback, options, elementCB) {
this.dom = [];
this.root = new Document(this.dom);
this.done = false;
this.tagStack = [this.root];
this.lastNode = null;
this.parser = null;
if (typeof options === "function") {
elementCB = options;
options = defaultOpts;
}
if (typeof callback === "object") {
options = callback;
callback = void 0;
}
this.callback = callback !== null && callback !== void 0 ? callback : null;
this.options = options !== null && options !== void 0 ? options : defaultOpts;
this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;
}
onparserinit(parser) {
this.parser = parser;
}
// Resets the handler back to starting state
onreset() {
this.dom = [];
this.root = new Document(this.dom);
this.done = false;
this.tagStack = [this.root];
this.lastNode = null;
this.parser = null;
}
// Signals the handler that parsing is done
onend() {
if (this.done)
return;
this.done = true;
this.parser = null;
this.handleCallback(null);
}
onerror(error) {
this.handleCallback(error);
}
onclosetag() {
this.lastNode = null;
const elem = this.tagStack.pop();
if (this.options.withEndIndices) {
elem.endIndex = this.parser.endIndex;
}
if (this.elementCB)
this.elementCB(elem);
}
onopentag(name, attribs) {
const type = this.options.xmlMode ? ElementType.Tag : void 0;
const element = new Element(name, attribs, void 0, type);
this.addNode(element);
this.tagStack.push(element);
}
ontext(data2) {
const { lastNode } = this;
if (lastNode && lastNode.type === ElementType.Text) {
lastNode.data += data2;
if (this.options.withEndIndices) {
lastNode.endIndex = this.parser.endIndex;
}
} else {
const node = new Text(data2);
this.addNode(node);
this.lastNode = node;
}
}
oncomment(data2) {
if (this.lastNode && this.lastNode.type === ElementType.Comment) {
this.lastNode.data += data2;
return;
}
const node = new Comment(data2);
this.addNode(node);
this.lastNode = node;
}
oncommentend() {
this.lastNode = null;
}
oncdatastart() {
const text2 = new Text("");
const node = new CDATA([text2]);
this.addNode(node);
text2.parent = node;
this.lastNode = text2;
}
oncdataend() {
this.lastNode = null;
}
onprocessinginstruction(name, data2) {
const node = new ProcessingInstruction(name, data2);
this.addNode(node);
}
handleCallback(error) {
if (typeof this.callback === "function") {
this.callback(error, this.dom);
} else if (error) {
throw error;
}
}
addNode(node) {
const parent2 = this.tagStack[this.tagStack.length - 1];
const previousSibling = parent2.children[parent2.children.length - 1];
if (this.options.withStartIndices) {
node.startIndex = this.parser.startIndex;
}
if (this.options.withEndIndices) {
node.endIndex = this.parser.endIndex;
}
parent2.children.push(node);
if (previousSibling) {
node.prev = previousSibling;
previousSibling.next = node;
}
node.parent = parent2;
this.lastNode = null;
}
}
const htmlDecodeTree = new Uint16Array(
// prettier-ignore
'<Õıʊҝջאٵ۞ޢߖࠏઑඡረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒ㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms„‹•˜¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲ΂ϏϢϸontourIntegraìȹoɴ͹\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՗՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲ׌y;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱cò׋؀JTabcdfgorstר׬ׯ׺؀ؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d׷׸;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;܀EJOacdfgmnostuۺ۾܃܇܎ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ޷޼߂ߐĀiyޱ޵rc;;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;΀HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶߻dil;;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࡐࡣcy;䐉耻<䀼ʀcmnprࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗࡡron;䄽dil;;䐛ĀfsࡨtԀACDFRTUVarࡾࢩࢱयज़ΐ४ĀnrࢃgleBracket;柨rowƀ;BR憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0eeVector;楡ectorĀ;B懃ar;楙loor;挊ightĀAVrrow;憔ector;楎Āerगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषownVector;楑eeVector;楠ectorĀ;B憿ar;楘ectorĀ;B憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽ拘ftarrow;懚idot;䄿ƀnpwਖਛgȀLRlrਐeftĀAR৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtòࡌ;憰rok;;扪Ѐacefiosuਗ਼અઋp;椅y;䐜Ādl੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;
);
const xmlDecodeTree = new Uint16Array(
// prettier-ignore
"Ȁaglq \x1Bɭ\0\0p;䀦os;䀧t;䀾t;䀼uot;䀢".split("").map((c) => c.charCodeAt(0))
);
var _a;
const decodeMap = /* @__PURE__ */ new Map([
[0, 65533],
// C1 Unicode control character reference replacements
[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]
]);
const fromCodePoint = (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins
(_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function(codePoint) {
let output = "";
if (codePoint > 65535) {
codePoint -= 65536;
output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296);
codePoint = 56320 | codePoint & 1023;
}
output += String.fromCharCode(codePoint);
return output;
}
);
function replaceCodePoint(codePoint) {
var _a2;
if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) {
return 65533;
}
return (_a2 = decodeMap.get(codePoint)) !== null && _a2 !== void 0 ? _a2 : codePoint;
}
var CharCodes$1;
(function(CharCodes2) {
CharCodes2[CharCodes2["NUM"] = 35] = "NUM";
CharCodes2[CharCodes2["SEMI"] = 59] = "SEMI";
CharCodes2[CharCodes2["EQUALS"] = 61] = "EQUALS";
CharCodes2[CharCodes2["ZERO"] = 48] = "ZERO";
CharCodes2[CharCodes2["NINE"] = 57] = "NINE";
CharCodes2[CharCodes2["LOWER_A"] = 97] = "LOWER_A";
CharCodes2[CharCodes2["LOWER_F"] = 102] = "LOWER_F";
CharCodes2[CharCodes2["LOWER_X"] = 120] = "LOWER_X";
CharCodes2[CharCodes2["LOWER_Z"] = 122] = "LOWER_Z";
CharCodes2[CharCodes2["UPPER_A"] = 65] = "UPPER_A";
CharCodes2[CharCodes2["UPPER_F"] = 70] = "UPPER_F";
CharCodes2[CharCodes2["UPPER_Z"] = 90] = "UPPER_Z";
})(CharCodes$1 || (CharCodes$1 = {}));
const TO_LOWER_BIT = 32;
var BinTrieFlags;
(function(BinTrieFlags2) {
BinTrieFlags2[BinTrieFlags2["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
BinTrieFlags2[BinTrieFlags2["BRANCH_LENGTH"] = 16256] = "BRANCH_LENGTH";
BinTrieFlags2[BinTrieFlags2["JUMP_TABLE"] = 127] = "JUMP_TABLE";
})(BinTrieFlags || (BinTrieFlags = {}));
function isNumber(code) {
return code >= CharCodes$1.ZERO && code <= CharCodes$1.NINE;
}
function isHexadecimalCharacter(code) {
return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_F || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_F;
}
function isAsciiAlphaNumeric(code) {
return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_Z || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_Z || isNumber(code);
}
function isEntityInAttributeInvalidEnd(code) {
return code === CharCodes$1.EQUALS || isAsciiAlphaNumeric(code);
}
var EntityDecoderState;
(function(EntityDecoderState2) {
EntityDecoderState2[EntityDecoderState2["EntityStart"] = 0] = "EntityStart";
EntityDecoderState2[EntityDecoderState2["NumericStart"] = 1] = "NumericStart";
EntityDecoderState2[EntityDecoderState2["NumericDecimal"] = 2] = "NumericDecimal";
EntityDecoderState2[EntityDecoderState2["NumericHex"] = 3] = "NumericHex";
EntityDecoderState2[EntityDecoderState2["NamedEntity"] = 4] = "NamedEntity";
})(EntityDecoderState || (EntityDecoderState = {}));
var DecodingMode;
(function(DecodingMode2) {
DecodingMode2[DecodingMode2["Legacy"] = 0] = "Legacy";
DecodingMode2[DecodingMode2["Strict"] = 1] = "Strict";
DecodingMode2[DecodingMode2["Attribute"] = 2] = "Attribute";
})(DecodingMode || (DecodingMode = {}));
class EntityDecoder {
constructor(decodeTree, emitCodePoint, errors) {
this.decodeTree = decodeTree;
this.emitCodePoint = emitCodePoint;
this.errors = errors;
this.state = EntityDecoderState.EntityStart;
this.consumed = 1;
this.result = 0;
this.treeIndex = 0;
this.excess = 1;
this.decodeMode = DecodingMode.Strict;
}
/** Resets the instance to make it reusable. */
startEntity(decodeMode) {
this.decodeMode = decodeMode;
this.state = EntityDecoderState.EntityStart;
this.result = 0;
this.treeIndex = 0;
this.excess = 1;
this.consumed = 1;
}
/**
* Write an entity to the decoder. This can be called multiple times with partial entities.
* If the entity is incomplete, the decoder will return -1.
*
* Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
* entity is incomplete, and resume when the next string is written.
*
* @param string The string containing the entity (or a continuation of the entity).
* @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
write(str, offset) {
switch (this.state) {
case EntityDecoderState.EntityStart: {
if (str.charCodeAt(offset) === CharCodes$1.NUM) {
this.state = EntityDecoderState.NumericStart;
this.consumed += 1;
return this.stateNumericStart(str, offset + 1);
}
this.state = EntityDecoderState.NamedEntity;
return this.stateNamedEntity(str, offset);
}
case EntityDecoderState.NumericStart: {
return this.stateNumericStart(str, offset);
}
case EntityDecoderState.NumericDecimal: {
return this.stateNumericDecimal(str, offset);
}
case EntityDecoderState.NumericHex: {
return this.stateNumericHex(str, offset);
}
case EntityDecoderState.NamedEntity: {
return this.stateNamedEntity(str, offset);
}
}
}
/**
* Switches between the numeric decimal and hexadecimal states.
*
* Equivalent to the `Numeric character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNumericStart(str, offset) {
if (offset >= str.length) {
return -1;
}
if ((str.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes$1.LOWER_X) {
this.state = EntityDecoderState.NumericHex;
this.consumed += 1;
return this.stateNumericHex(str, offset + 1);
}
this.state = EntityDecoderState.NumericDecimal;
return this.stateNumericDecimal(str, offset);
}
addToNumericResult(str, start, end2, base) {
if (start !== end2) {
const digitCount = end2 - start;
this.result = this.result * Math.pow(base, digitCount) + parseInt(str.substr(start, digitCount), base);
this.consumed += digitCount;
}
}
/**
* Parses a hexadecimal numeric entity.
*
* Equivalent to the `Hexademical character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNumericHex(str, offset) {
const startIdx = offset;
while (offset < str.length) {
const char = str.charCodeAt(offset);
if (isNumber(char) || isHexadecimalCharacter(char)) {
offset += 1;
} else {
this.addToNumericResult(str, startIdx, offset, 16);
return this.emitNumericEntity(char, 3);
}
}
this.addToNumericResult(str, startIdx, offset, 16);
return -1;
}
/**
* Parses a decimal numeric entity.
*
* Equivalent to the `Decimal character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNumericDecimal(str, offset) {
const startIdx = offset;
while (offset < str.length) {
const char = str.charCodeAt(offset);
if (isNumber(char)) {
offset += 1;
} else {
this.addToNumericResult(str, startIdx, offset, 10);
return this.emitNumericEntity(char, 2);
}
}
this.addToNumericResult(str, startIdx, offset, 10);
return -1;
}
/**
* Validate and emit a numeric entity.
*
* Implements the logic from the `Hexademical character reference start
* state` and `Numeric character reference end state` in the HTML spec.
*
* @param lastCp The last code point of the entity. Used to see if the
* entity was terminated with a semicolon.
* @param expectedLength The minimum number of characters that should be
* consumed. Used to validate that at least one digit
* was consumed.
* @returns The number of characters that were consumed.
*/
emitNumericEntity(lastCp, expectedLength) {
var _a2;
if (this.consumed <= expectedLength) {
(_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
return 0;
}
if (lastCp === CharCodes$1.SEMI) {
this.consumed += 1;
} else if (this.decodeMode === DecodingMode.Strict) {
return 0;
}
this.emitCodePoint(replaceCodePoint(this.result), this.consumed);
if (this.errors) {
if (lastCp !== CharCodes$1.SEMI) {
this.errors.missingSemicolonAfterCharacterReference();
}
this.errors.validateNumericCharacterReference(this.result);
}
return this.consumed;
}
/**
* Parses a named entity.
*
* Equivalent to the `Named character reference state` in the HTML spec.
*
* @param str The string containing the entity (or a continuation of the entity).
* @param offset The current offset.
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
*/
stateNamedEntity(str, offset) {
const { decodeTree } = this;
let current = decodeTree[this.treeIndex];
let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
for (; offset < str.length; offset++, this.excess++) {
const char = str.charCodeAt(offset);
this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
if (this.treeIndex < 0) {
return this.result === 0 || // If we are parsing an attribute
this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity,
(valueLength === 0 || // And there should be no invalid characters.
isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
}
current = decodeTree[this.treeIndex];
valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
if (valueLength !== 0) {
if (char === CharCodes$1.SEMI) {
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
}
if (this.decodeMode !== DecodingMode.Strict) {
this.result = this.treeIndex;
this.consumed += this.excess;
this.excess = 0;
}
}
}
return -1;
}
/**
* Emit a named entity that was not terminated with a semicolon.
*
* @returns The number of characters consumed.
*/
emitNotTerminatedNamedEntity() {
var _a2;
const { result, decodeTree } = this;
const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;
this.emitNamedEntityData(result, valueLength, this.consumed);
(_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.missingSemicolonAfterCharacterReference();
return this.consumed;
}
/**
* Emit a named entity.
*
* @param result The index of the entity in the decode tree.
* @param valueLength The number of bytes in the entity.
* @param consumed The number of characters consumed.
*
* @returns The number of characters consumed.
*/
emitNamedEntityData(result, valueLength, consumed) {
const { decodeTree } = this;
this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH : decodeTree[result + 1], consumed);
if (valueLength === 3) {
this.emitCodePoint(decodeTree[result + 2], consumed);
}
return consumed;
}
/**
* Signal to the parser that the end of the input was reached.
*
* Remaining data will be emitted and relevant errors will be produced.
*
* @returns The number of characters consumed.
*/
end() {
var _a2;
switch (this.state) {
case EntityDecoderState.NamedEntity: {
return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
}
// Otherwise, emit a numeric entity if we have one.
case EntityDecoderState.NumericDecimal: {
return this.emitNumericEntity(0, 2);
}
case EntityDecoderState.NumericHex: {
return this.emitNumericEntity(0, 3);
}
case EntityDecoderState.NumericStart: {
(_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
return 0;
}
case EntityDecoderState.EntityStart: {
return 0;
}
}
}
}
function getDecoder(decodeTree) {
let ret = "";
const decoder = new EntityDecoder(decodeTree, (str) => ret += fromCodePoint(str));
return function decodeWithTrie(str, decodeMode) {
let lastIndex = 0;
let offset = 0;
while ((offset = str.indexOf("&", offset)) >= 0) {
ret += str.slice(lastIndex, offset);
decoder.startEntity(decodeMode);
const len = decoder.write(
str,
// Skip the "&"
offset + 1
);
if (len < 0) {
lastIndex = offset + decoder.end();
break;
}
lastIndex = offset + len;
offset = len === 0 ? lastIndex + 1 : lastIndex;
}
const result = ret + str.slice(lastIndex);
ret = "";
return result;
};
}
function determineBranch(decodeTree, current, nodeIdx, char) {
const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
const jumpOffset = current & BinTrieFlags.JUMP_TABLE;
if (branchCount === 0) {
return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1;
}
if (jumpOffset) {
const value = char - jumpOffset;
return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1;
}
let lo = nodeIdx;
let hi = lo + branchCount - 1;
while (lo <= hi) {
const mid = lo + hi >>> 1;
const midVal = decodeTree[mid];
if (midVal < char) {
lo = mid + 1;
} else if (midVal > char) {
hi = mid - 1;
} else {
return decodeTree[mid + branchCount];
}
}
return -1;
}
getDecoder(htmlDecodeTree);
getDecoder(xmlDecodeTree);
const xmlReplacer = /["&'<>$\x80-\uFFFF]/g;
const xmlCodeMap = /* @__PURE__ */ new Map([
[34, "&quot;"],
[38, "&amp;"],
[39, "&apos;"],
[60, "&lt;"],
[62, "&gt;"]
]);
const getCodePoint = (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
String.prototype.codePointAt != null ? (str, index2) => str.codePointAt(index2) : (
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
(c, index2) => (c.charCodeAt(index2) & 64512) === 55296 ? (c.charCodeAt(index2) - 55296) * 1024 + c.charCodeAt(index2 + 1) - 56320 + 65536 : c.charCodeAt(index2)
)
);
function encodeXML(str) {
let ret = "";
let lastIdx = 0;
let match;
while ((match = xmlReplacer.exec(str)) !== null) {
const i = match.index;
const char = str.charCodeAt(i);
const next2 = xmlCodeMap.get(char);
if (next2 !== void 0) {
ret += str.substring(lastIdx, i) + next2;
lastIdx = i + 1;
} else {
ret += `${str.substring(lastIdx, i)}&#x${getCodePoint(str, i).toString(16)};`;
lastIdx = xmlReplacer.lastIndex += Number((char & 64512) === 55296);
}
}
return ret + str.substr(lastIdx);
}
function getEscaper(regex, map2) {
return function escape(data2) {
let match;
let lastIdx = 0;
let result = "";
while (match = regex.exec(data2)) {
if (lastIdx !== match.index) {
result += data2.substring(lastIdx, match.index);
}
result += map2.get(match[0].charCodeAt(0));
lastIdx = match.index + 1;
}
return result + data2.substring(lastIdx);
};
}
const escapeAttribute = getEscaper(/["&\u00A0]/g, /* @__PURE__ */ new Map([
[34, "&quot;"],
[38, "&amp;"],
[160, "&nbsp;"]
]));
const escapeText = getEscaper(/[&<>\u00A0]/g, /* @__PURE__ */ new Map([
[38, "&amp;"],
[60, "&lt;"],
[62, "&gt;"],
[160, "&nbsp;"]
]));
const elementNames = new Map([
"altGlyph",
"altGlyphDef",
"altGlyphItem",
"animateColor",
"animateMotion",
"animateTransform",
"clipPath",
"feBlend",
"feColorMatrix",
"feComponentTransfer",
"feComposite",
"feConvolveMatrix",
"feDiffuseLighting",
"feDisplacementMap",
"feDistantLight",
"feDropShadow",
"feFlood",
"feFuncA",
"feFuncB",
"feFuncG",
"feFuncR",
"feGaussianBlur",
"feImage",
"feMerge",
"feMergeNode",
"feMorphology",
"feOffset",
"fePointLight",
"feSpecularLighting",
"feSpotLight",
"feTile",
"feTurbulence",
"foreignObject",
"glyphRef",
"linearGradient",
"radialGradient",
"textPath"
].map((val2) => [val2.toLowerCase(), val2]));
const attributeNames = new Map([
"definitionURL",
"attributeName",
"attributeType",
"baseFrequency",
"baseProfile",
"calcMode",
"clipPathUnits",
"diffuseConstant",
"edgeMode",
"filterUnits",
"glyphRef",
"gradientTransform",
"gradientUnits",
"kernelMatrix",
"kernelUnitLength",
"keyPoints",
"keySplines",
"keyTimes",
"lengthAdjust",
"limitingConeAngle",
"markerHeight",
"markerUnits",
"markerWidth",
"maskContentUnits",
"maskUnits",
"numOctaves",
"pathLength",
"patternContentUnits",
"patternTransform",
"patternUnits",
"pointsAtX",
"pointsAtY",
"pointsAtZ",
"preserveAlpha",
"preserveAspectRatio",
"primitiveUnits",
"refX",
"refY",
"repeatCount",
"repeatDur",
"requiredExtensions",
"requiredFeatures",
"specularConstant",
"specularExponent",
"spreadMethod",
"startOffset",
"stdDeviation",
"stitchTiles",
"surfaceScale",
"systemLanguage",
"tableValues",
"targetX",
"targetY",
"textLength",
"viewBox",
"viewTarget",
"xChannelSelector",
"yChannelSelector",
"zoomAndPan"
].map((val2) => [val2.toLowerCase(), val2]));
const unencodedElements = /* @__PURE__ */ new Set([
"style",
"script",
"xmp",
"iframe",
"noembed",
"noframes",
"plaintext",
"noscript"
]);
function replaceQuotes(value) {
return value.replace(/"/g, "&quot;");
}
function formatAttributes(attributes2, opts) {
var _a2;
if (!attributes2)
return;
const encode = ((_a2 = opts.encodeEntities) !== null && _a2 !== void 0 ? _a2 : opts.decodeEntities) === false ? replaceQuotes : opts.xmlMode || opts.encodeEntities !== "utf8" ? encodeXML : escapeAttribute;
return Object.keys(attributes2).map((key) => {
var _a3, _b;
const value = (_a3 = attributes2[key]) !== null && _a3 !== void 0 ? _a3 : "";
if (opts.xmlMode === "foreign") {
key = (_b = attributeNames.get(key)) !== null && _b !== void 0 ? _b : key;
}
if (!opts.emptyAttrs && !opts.xmlMode && value === "") {
return key;
}
return `${key}="${encode(value)}"`;
}).join(" ");
}
const singleTag = /* @__PURE__ */ new Set([
"area",
"base",
"basefont",
"br",
"col",
"command",
"embed",
"frame",
"hr",
"img",
"input",
"isindex",
"keygen",
"link",
"meta",
"param",
"source",
"track",
"wbr"
]);
function render$1(node, options = {}) {
const nodes = "length" in node ? node : [node];
let output = "";
for (let i = 0; i < nodes.length; i++) {
output += renderNode(nodes[i], options);
}
return output;
}
function renderNode(node, options) {
switch (node.type) {
case Root:
return render$1(node.children, options);
// @ts-expect-error We don't use `Doctype` yet
case Doctype:
case Directive:
return renderDirective(node);
case Comment$1:
return renderComment(node);
case CDATA$1:
return renderCdata(node);
case Script:
case Style:
case Tag:
return renderTag(node, options);
case Text$1:
return renderText(node, options);
}
}
const foreignModeIntegrationPoints = /* @__PURE__ */ new Set([
"mi",
"mo",
"mn",
"ms",
"mtext",
"annotation-xml",
"foreignObject",
"desc",
"title"
]);
const foreignElements = /* @__PURE__ */ new Set(["svg", "math"]);
function renderTag(elem, opts) {
var _a2;
if (opts.xmlMode === "foreign") {
elem.name = (_a2 = elementNames.get(elem.name)) !== null && _a2 !== void 0 ? _a2 : elem.name;
if (elem.parent && foreignModeIntegrationPoints.has(elem.parent.name)) {
opts = { ...opts, xmlMode: false };
}
}
if (!opts.xmlMode && foreignElements.has(elem.name)) {
opts = { ...opts, xmlMode: "foreign" };
}
let tag = `<${elem.name}`;
const attribs = formatAttributes(elem.attribs, opts);
if (attribs) {
tag += ` ${attribs}`;
}
if (elem.children.length === 0 && (opts.xmlMode ? (
// In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags
opts.selfClosingTags !== false
) : (
// User explicitly asked for self-closing tags, even in HTML mode
opts.selfClosingTags && singleTag.has(elem.name)
))) {
if (!opts.xmlMode)
tag += " ";
tag += "/>";
} else {
tag += ">";
if (elem.children.length > 0) {
tag += render$1(elem.children, opts);
}
if (opts.xmlMode || !singleTag.has(elem.name)) {
tag += `</${elem.name}>`;
}
}
return tag;
}
function renderDirective(elem) {
return `<${elem.data}>`;
}
function renderText(elem, opts) {
var _a2;
let data2 = elem.data || "";
if (((_a2 = opts.encodeEntities) !== null && _a2 !== void 0 ? _a2 : opts.decodeEntities) !== false && !(!opts.xmlMode && elem.parent && unencodedElements.has(elem.parent.name))) {
data2 = opts.xmlMode || opts.encodeEntities !== "utf8" ? encodeXML(data2) : escapeText(data2);
}
return data2;
}
function renderCdata(elem) {
return `<![CDATA[${elem.children[0].data}]]>`;
}
function renderComment(elem) {
return `<!--${elem.data}-->`;
}
function getOuterHTML(node, options) {
return render$1(node, options);
}
function getInnerHTML(node, options) {
return hasChildren(node) ? node.children.map((node2) => getOuterHTML(node2, options)).join("") : "";
}
function getText(node) {
if (Array.isArray(node))
return node.map(getText).join("");
if (isTag(node))
return node.name === "br" ? "\n" : getText(node.children);
if (isCDATA(node))
return getText(node.children);
if (isText(node))
return node.data;
return "";
}
function textContent(node) {
if (Array.isArray(node))
return node.map(textContent).join("");
if (hasChildren(node) && !isComment(node)) {
return textContent(node.children);
}
if (isText(node))
return node.data;
return "";
}
function innerText(node) {
if (Array.isArray(node))
return node.map(innerText).join("");
if (hasChildren(node) && (node.type === ElementType.Tag || isCDATA(node))) {
return innerText(node.children);
}
if (isText(node))
return node.data;
return "";
}
function getChildren(elem) {
return hasChildren(elem) ? elem.children : [];
}
function getParent(elem) {
return elem.parent || null;
}
function getSiblings(elem) {
const parent2 = getParent(elem);
if (parent2 != null)
return getChildren(parent2);
const siblings2 = [elem];
let { prev: prev2, next: next2 } = elem;
while (prev2 != null) {
siblings2.unshift(prev2);
({ prev: prev2 } = prev2);
}
while (next2 != null) {
siblings2.push(next2);
({ next: next2 } = next2);
}
return siblings2;
}
function getAttributeValue(elem, name) {
var _a2;
return (_a2 = elem.attribs) === null || _a2 === void 0 ? void 0 : _a2[name];
}
function hasAttrib(elem, name) {
return elem.attribs != null && Object.prototype.hasOwnProperty.call(elem.attribs, name) && elem.attribs[name] != null;
}
function getName(elem) {
return elem.name;
}
function nextElementSibling(elem) {
let { next: next2 } = elem;
while (next2 !== null && !isTag(next2))
({ next: next2 } = next2);
return next2;
}
function prevElementSibling(elem) {
let { prev: prev2 } = elem;
while (prev2 !== null && !isTag(prev2))
({ prev: prev2 } = prev2);
return prev2;
}
function removeElement(elem) {
if (elem.prev)
elem.prev.next = elem.next;
if (elem.next)
elem.next.prev = elem.prev;
if (elem.parent) {
const childs = elem.parent.children;
const childsIndex = childs.lastIndexOf(elem);
if (childsIndex >= 0) {
childs.splice(childsIndex, 1);
}
}
elem.next = null;
elem.prev = null;
elem.parent = null;
}
function replaceElement(elem, replacement) {
const prev2 = replacement.prev = elem.prev;
if (prev2) {
prev2.next = replacement;
}
const next2 = replacement.next = elem.next;
if (next2) {
next2.prev = replacement;
}
const parent2 = replacement.parent = elem.parent;
if (parent2) {
const childs = parent2.children;
childs[childs.lastIndexOf(elem)] = replacement;
elem.parent = null;
}
}
function appendChild(parent2, child) {
removeElement(child);
child.next = null;
child.parent = parent2;
if (parent2.children.push(child) > 1) {
const sibling = parent2.children[parent2.children.length - 2];
sibling.next = child;
child.prev = sibling;
} else {
child.prev = null;
}
}
function append$1(elem, next2) {
removeElement(next2);
const { parent: parent2 } = elem;
const currNext = elem.next;
next2.next = currNext;
next2.prev = elem;
elem.next = next2;
next2.parent = parent2;
if (currNext) {
currNext.prev = next2;
if (parent2) {
const childs = parent2.children;
childs.splice(childs.lastIndexOf(currNext), 0, next2);
}
} else if (parent2) {
parent2.children.push(next2);
}
}
function prependChild(parent2, child) {
removeElement(child);
child.parent = parent2;
child.prev = null;
if (parent2.children.unshift(child) !== 1) {
const sibling = parent2.children[1];
sibling.prev = child;
child.next = sibling;
} else {
child.next = null;
}
}
function prepend$1(elem, prev2) {
removeElement(prev2);
const { parent: parent2 } = elem;
if (parent2) {
const childs = parent2.children;
childs.splice(childs.indexOf(elem), 0, prev2);
}
if (elem.prev) {
elem.prev.next = prev2;
}
prev2.parent = parent2;
prev2.prev = elem.prev;
prev2.next = elem;
elem.prev = prev2;
}
function filter$2(test, node, recurse = true, limit = Infinity) {
return find$2(test, Array.isArray(node) ? node : [node], recurse, limit);
}
function find$2(test, nodes, recurse, limit) {
const result = [];
const nodeStack = [nodes];
const indexStack = [0];
for (; ; ) {
if (indexStack[0] >= nodeStack[0].length) {
if (indexStack.length === 1) {
return result;
}
nodeStack.shift();
indexStack.shift();
continue;
}
const elem = nodeStack[0][indexStack[0]++];
if (test(elem)) {
result.push(elem);
if (--limit <= 0)
return result;
}
if (recurse && hasChildren(elem) && elem.children.length > 0) {
indexStack.unshift(0);
nodeStack.unshift(elem.children);
}
}
}
function findOneChild(test, nodes) {
return nodes.find(test);
}
function findOne(test, nodes, recurse = true) {
let elem = null;
for (let i = 0; i < nodes.length && !elem; i++) {
const node = nodes[i];
if (!isTag(node)) {
continue;
} else if (test(node)) {
elem = node;
} else if (recurse && node.children.length > 0) {
elem = findOne(test, node.children, true);
}
}
return elem;
}
function existsOne(test, nodes) {
return nodes.some((checked) => isTag(checked) && (test(checked) || existsOne(test, checked.children)));
}
function findAll(test, nodes) {
const result = [];
const nodeStack = [nodes];
const indexStack = [0];
for (; ; ) {
if (indexStack[0] >= nodeStack[0].length) {
if (nodeStack.length === 1) {
return result;
}
nodeStack.shift();
indexStack.shift();
continue;
}
const elem = nodeStack[0][indexStack[0]++];
if (!isTag(elem))
continue;
if (test(elem))
result.push(elem);
if (elem.children.length > 0) {
indexStack.unshift(0);
nodeStack.unshift(elem.children);
}
}
}
const Checks = {
tag_name(name) {
if (typeof name === "function") {
return (elem) => isTag(elem) && name(elem.name);
} else if (name === "*") {
return isTag;
}
return (elem) => isTag(elem) && elem.name === name;
},
tag_type(type) {
if (typeof type === "function") {
return (elem) => type(elem.type);
}
return (elem) => elem.type === type;
},
tag_contains(data2) {
if (typeof data2 === "function") {
return (elem) => isText(elem) && data2(elem.data);
}
return (elem) => isText(elem) && elem.data === data2;
}
};
function getAttribCheck(attrib, value) {
if (typeof value === "function") {
return (elem) => isTag(elem) && value(elem.attribs[attrib]);
}
return (elem) => isTag(elem) && elem.attribs[attrib] === value;
}
function combineFuncs(a, b) {
return (elem) => a(elem) || b(elem);
}
function compileTest(options) {
const funcs = Object.keys(options).map((key) => {
const value = options[key];
return Object.prototype.hasOwnProperty.call(Checks, key) ? Checks[key](value) : getAttribCheck(key, value);
});
return funcs.length === 0 ? null : funcs.reduce(combineFuncs);
}
function testElement(options, node) {
const test = compileTest(options);
return test ? test(node) : true;
}
function getElements(options, nodes, recurse, limit = Infinity) {
const test = compileTest(options);
return test ? filter$2(test, nodes, recurse, limit) : [];
}
function getElementById(id, nodes, recurse = true) {
if (!Array.isArray(nodes))
nodes = [nodes];
return findOne(getAttribCheck("id", id), nodes, recurse);
}
function getElementsByTagName(tagName, nodes, recurse = true, limit = Infinity) {
return filter$2(Checks["tag_name"](tagName), nodes, recurse, limit);
}
function getElementsByTagType(type, nodes, recurse = true, limit = Infinity) {
return filter$2(Checks["tag_type"](type), nodes, recurse, limit);
}
function removeSubsets(nodes) {
let idx = nodes.length;
while (--idx >= 0) {
const node = nodes[idx];
if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) {
nodes.splice(idx, 1);
continue;
}
for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
if (nodes.includes(ancestor)) {
nodes.splice(idx, 1);
break;
}
}
}
return nodes;
}
var DocumentPosition;
(function(DocumentPosition2) {
DocumentPosition2[DocumentPosition2["DISCONNECTED"] = 1] = "DISCONNECTED";
DocumentPosition2[DocumentPosition2["PRECEDING"] = 2] = "PRECEDING";
DocumentPosition2[DocumentPosition2["FOLLOWING"] = 4] = "FOLLOWING";
DocumentPosition2[DocumentPosition2["CONTAINS"] = 8] = "CONTAINS";
DocumentPosition2[DocumentPosition2["CONTAINED_BY"] = 16] = "CONTAINED_BY";
})(DocumentPosition || (DocumentPosition = {}));
function compareDocumentPosition(nodeA, nodeB) {
const aParents = [];
const bParents = [];
if (nodeA === nodeB) {
return 0;
}
let current = hasChildren(nodeA) ? nodeA : nodeA.parent;
while (current) {
aParents.unshift(current);
current = current.parent;
}
current = hasChildren(nodeB) ? nodeB : nodeB.parent;
while (current) {
bParents.unshift(current);
current = current.parent;
}
const maxIdx = Math.min(aParents.length, bParents.length);
let idx = 0;
while (idx < maxIdx && aParents[idx] === bParents[idx]) {
idx++;
}
if (idx === 0) {
return DocumentPosition.DISCONNECTED;
}
const sharedParent = aParents[idx - 1];
const siblings2 = sharedParent.children;
const aSibling = aParents[idx];
const bSibling = bParents[idx];
if (siblings2.indexOf(aSibling) > siblings2.indexOf(bSibling)) {
if (sharedParent === nodeB) {
return DocumentPosition.FOLLOWING | DocumentPosition.CONTAINED_BY;
}
return DocumentPosition.FOLLOWING;
}
if (sharedParent === nodeA) {
return DocumentPosition.PRECEDING | DocumentPosition.CONTAINS;
}
return DocumentPosition.PRECEDING;
}
function uniqueSort(nodes) {
nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
nodes.sort((a, b) => {
const relative = compareDocumentPosition(a, b);
if (relative & DocumentPosition.PRECEDING) {
return -1;
} else if (relative & DocumentPosition.FOLLOWING) {
return 1;
}
return 0;
});
return nodes;
}
function getFeed(doc) {
const feedRoot = getOneElement(isValidFeed, doc);
return !feedRoot ? null : feedRoot.name === "feed" ? getAtomFeed(feedRoot) : getRssFeed(feedRoot);
}
function getAtomFeed(feedRoot) {
var _a2;
const childs = feedRoot.children;
const feed = {
type: "atom",
items: getElementsByTagName("entry", childs).map((item) => {
var _a3;
const { children: children2 } = item;
const entry = { media: getMediaElements(children2) };
addConditionally(entry, "id", "id", children2);
addConditionally(entry, "title", "title", children2);
const href2 = (_a3 = getOneElement("link", children2)) === null || _a3 === void 0 ? void 0 : _a3.attribs["href"];
if (href2) {
entry.link = href2;
}
const description = fetch("summary", children2) || fetch("content", children2);
if (description) {
entry.description = description;
}
const pubDate = fetch("updated", children2);
if (pubDate) {
entry.pubDate = new Date(pubDate);
}
return entry;
})
};
addConditionally(feed, "id", "id", childs);
addConditionally(feed, "title", "title", childs);
const href = (_a2 = getOneElement("link", childs)) === null || _a2 === void 0 ? void 0 : _a2.attribs["href"];
if (href) {
feed.link = href;
}
addConditionally(feed, "description", "subtitle", childs);
const updated = fetch("updated", childs);
if (updated) {
feed.updated = new Date(updated);
}
addConditionally(feed, "author", "email", childs, true);
return feed;
}
function getRssFeed(feedRoot) {
var _a2, _b;
const childs = (_b = (_a2 = getOneElement("channel", feedRoot.children)) === null || _a2 === void 0 ? void 0 : _a2.children) !== null && _b !== void 0 ? _b : [];
const feed = {
type: feedRoot.name.substr(0, 3),
id: "",
items: getElementsByTagName("item", feedRoot.children).map((item) => {
const { children: children2 } = item;
const entry = { media: getMediaElements(children2) };
addConditionally(entry, "id", "guid", children2);
addConditionally(entry, "title", "title", children2);
addConditionally(entry, "link", "link", children2);
addConditionally(entry, "description", "description", children2);
const pubDate = fetch("pubDate", children2) || fetch("dc:date", children2);
if (pubDate)
entry.pubDate = new Date(pubDate);
return entry;
})
};
addConditionally(feed, "title", "title", childs);
addConditionally(feed, "link", "link", childs);
addConditionally(feed, "description", "description", childs);
const updated = fetch("lastBuildDate", childs);
if (updated) {
feed.updated = new Date(updated);
}
addConditionally(feed, "author", "managingEditor", childs, true);
return feed;
}
const MEDIA_KEYS_STRING = ["url", "type", "lang"];
const MEDIA_KEYS_INT = [
"fileSize",
"bitrate",
"framerate",
"samplingrate",
"channels",
"duration",
"height",
"width"
];
function getMediaElements(where) {
return getElementsByTagName("media:content", where).map((elem) => {
const { attribs } = elem;
const media = {
medium: attribs["medium"],
isDefault: !!attribs["isDefault"]
};
for (const attrib of MEDIA_KEYS_STRING) {
if (attribs[attrib]) {
media[attrib] = attribs[attrib];
}
}
for (const attrib of MEDIA_KEYS_INT) {
if (attribs[attrib]) {
media[attrib] = parseInt(attribs[attrib], 10);
}
}
if (attribs["expression"]) {
media.expression = attribs["expression"];
}
return media;
});
}
function getOneElement(tagName, node) {
return getElementsByTagName(tagName, node, true, 1)[0];
}
function fetch(tagName, where, recurse = false) {
return textContent(getElementsByTagName(tagName, where, recurse, 1)).trim();
}
function addConditionally(obj, prop2, tagName, where, recurse = false) {
const val2 = fetch(tagName, where, recurse);
if (val2)
obj[prop2] = val2;
}
function isValidFeed(value) {
return value === "rss" || value === "feed" || value === "rdf:RDF";
}
const DomUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
get DocumentPosition() {
return DocumentPosition;
},
append: append$1,
appendChild,
compareDocumentPosition,
existsOne,
filter: filter$2,
find: find$2,
findAll,
findOne,
findOneChild,
getAttributeValue,
getChildren,
getElementById,
getElements,
getElementsByTagName,
getElementsByTagType,
getFeed,
getInnerHTML,
getName,
getOuterHTML,
getParent,
getSiblings,
getText,
hasAttrib,
hasChildren,
innerText,
isCDATA,
isComment,
isDocument,
isTag,
isText,
nextElementSibling,
prepend: prepend$1,
prependChild,
prevElementSibling,
removeElement,
removeSubsets,
replaceElement,
testElement,
textContent,
uniqueSort
}, Symbol.toStringTag, { value: "Module" }));
function render(that, dom, options) {
if (!that)
return "";
return that(dom !== null && dom !== void 0 ? dom : that._root.children, null, void 0, options).toString();
}
function isOptions(dom, options) {
return typeof dom === "object" && dom != null && !("length" in dom) && !("type" in dom);
}
function html$1(dom, options) {
const toRender = isOptions(dom) ? (options = dom, void 0) : dom;
const opts = {
...this === null || this === void 0 ? void 0 : this._options,
...flattenOptions(options)
};
return render(this, toRender, opts);
}
function xml(dom) {
const options = { ...this._options, xmlMode: true };
return render(this, dom, options);
}
function text$1(elements) {
const elems = elements !== null && elements !== void 0 ? elements : this ? this.root() : [];
let ret = "";
for (let i = 0; i < elems.length; i++) {
ret += textContent(elems[i]);
}
return ret;
}
function parseHTML(data2, context, keepScripts = typeof context === "boolean" ? context : false) {
if (!data2 || typeof data2 !== "string") {
return null;
}
if (typeof context === "boolean") {
keepScripts = context;
}
const parsed = this.load(data2, this._options, false);
if (!keepScripts) {
parsed("script").remove();
}
return [...parsed.root()[0].children];
}
function root() {
return this(this._root);
}
function contains(container, contained) {
if (contained === container) {
return false;
}
let next2 = contained;
while (next2 && next2 !== next2.parent) {
next2 = next2.parent;
if (next2 === container) {
return true;
}
}
return false;
}
function extract$1(map2) {
return this.root().extract(map2);
}
function merge(arr1, arr2) {
if (!isArrayLike(arr1) || !isArrayLike(arr2)) {
return;
}
let newLength = arr1.length;
const len = +arr2.length;
for (let i = 0; i < len; i++) {
arr1[newLength++] = arr2[i];
}
arr1.length = newLength;
return arr1;
}
function isArrayLike(item) {
if (Array.isArray(item)) {
return true;
}
if (typeof item !== "object" || item === null || !("length" in item) || typeof item.length !== "number" || item.length < 0) {
return false;
}
for (let i = 0; i < item.length; i++) {
if (!(i in item)) {
return false;
}
}
return true;
}
const staticMethods = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
contains,
extract: extract$1,
html: html$1,
merge,
parseHTML,
root,
text: text$1,
xml
}, Symbol.toStringTag, { value: "Module" }));
function isCheerio(maybeCheerio) {
return maybeCheerio.cheerio != null;
}
function camelCase(str) {
return str.replace(/[._-](\w|$)/g, (_, x) => x.toUpperCase());
}
function cssCase(str) {
return str.replace(/[A-Z]/g, "-$&").toLowerCase();
}
function domEach(array, fn) {
const len = array.length;
for (let i = 0; i < len; i++)
fn(array[i], i);
return array;
}
var CharacterCodes;
(function(CharacterCodes2) {
CharacterCodes2[CharacterCodes2["LowerA"] = 97] = "LowerA";
CharacterCodes2[CharacterCodes2["LowerZ"] = 122] = "LowerZ";
CharacterCodes2[CharacterCodes2["UpperA"] = 65] = "UpperA";
CharacterCodes2[CharacterCodes2["UpperZ"] = 90] = "UpperZ";
CharacterCodes2[CharacterCodes2["Exclamation"] = 33] = "Exclamation";
})(CharacterCodes || (CharacterCodes = {}));
function isHtml(str) {
const tagStart = str.indexOf("<");
if (tagStart < 0 || tagStart > str.length - 3)
return false;
const tagChar = str.charCodeAt(tagStart + 1);
return (tagChar >= CharacterCodes.LowerA && tagChar <= CharacterCodes.LowerZ || tagChar >= CharacterCodes.UpperA && tagChar <= CharacterCodes.UpperZ || tagChar === CharacterCodes.Exclamation) && str.includes(">", tagStart + 2);
}
const hasOwn = Object.prototype.hasOwnProperty;
const rspace = /\s+/;
const dataAttrPrefix = "data-";
const rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i;
const rbrace = /^{[^]*}$|^\[[^]*]$/;
function getAttr(elem, name, xmlMode) {
var _a2;
if (!elem || !isTag(elem))
return void 0;
(_a2 = elem.attribs) !== null && _a2 !== void 0 ? _a2 : elem.attribs = {};
if (!name) {
return elem.attribs;
}
if (hasOwn.call(elem.attribs, name)) {
return !xmlMode && rboolean.test(name) ? name : elem.attribs[name];
}
if (elem.name === "option" && name === "value") {
return text$1(elem.children);
}
if (elem.name === "input" && (elem.attribs["type"] === "radio" || elem.attribs["type"] === "checkbox") && name === "value") {
return "on";
}
return void 0;
}
function setAttr(el, name, value) {
if (value === null) {
removeAttribute(el, name);
} else {
el.attribs[name] = `${value}`;
}
}
function attr(name, value) {
if (typeof name === "object" || value !== void 0) {
if (typeof value === "function") {
if (typeof name !== "string") {
{
throw new Error("Bad combination of arguments.");
}
}
return domEach(this, (el, i) => {
if (isTag(el))
setAttr(el, name, value.call(el, i, el.attribs[name]));
});
}
return domEach(this, (el) => {
if (!isTag(el))
return;
if (typeof name === "object") {
for (const objName of Object.keys(name)) {
const objValue = name[objName];
setAttr(el, objName, objValue);
}
} else {
setAttr(el, name, value);
}
});
}
return arguments.length > 1 ? this : getAttr(this[0], name, this.options.xmlMode);
}
function getProp(el, name, xmlMode) {
return name in el ? (
// @ts-expect-error TS doesn't like us accessing the value directly here.
el[name]
) : !xmlMode && rboolean.test(name) ? getAttr(el, name, false) !== void 0 : getAttr(el, name, xmlMode);
}
function setProp(el, name, value, xmlMode) {
if (name in el) {
el[name] = value;
} else {
setAttr(el, name, !xmlMode && rboolean.test(name) ? value ? "" : null : `${value}`);
}
}
function prop(name, value) {
var _a2;
if (typeof name === "string" && value === void 0) {
const el = this[0];
if (!el || !isTag(el))
return void 0;
switch (name) {
case "style": {
const property = this.css();
const keys = Object.keys(property);
for (let i = 0; i < keys.length; i++) {
property[i] = keys[i];
}
property.length = keys.length;
return property;
}
case "tagName":
case "nodeName": {
return el.name.toUpperCase();
}
case "href":
case "src": {
const prop2 = (_a2 = el.attribs) === null || _a2 === void 0 ? void 0 : _a2[name];
if (typeof URL !== "undefined" && (name === "href" && (el.tagName === "a" || el.tagName === "link") || name === "src" && (el.tagName === "img" || el.tagName === "iframe" || el.tagName === "audio" || el.tagName === "video" || el.tagName === "source")) && prop2 !== void 0 && this.options.baseURI) {
return new URL(prop2, this.options.baseURI).href;
}
return prop2;
}
case "innerText": {
return innerText(el);
}
case "textContent": {
return textContent(el);
}
case "outerHTML": {
return this.clone().wrap("<container />").parent().html();
}
case "innerHTML": {
return this.html();
}
default: {
return getProp(el, name, this.options.xmlMode);
}
}
}
if (typeof name === "object" || value !== void 0) {
if (typeof value === "function") {
if (typeof name === "object") {
throw new TypeError("Bad combination of arguments.");
}
return domEach(this, (el, i) => {
if (isTag(el)) {
setProp(el, name, value.call(el, i, getProp(el, name, this.options.xmlMode)), this.options.xmlMode);
}
});
}
return domEach(this, (el) => {
if (!isTag(el))
return;
if (typeof name === "object") {
for (const key of Object.keys(name)) {
const val2 = name[key];
setProp(el, key, val2, this.options.xmlMode);
}
} else {
setProp(el, name, value, this.options.xmlMode);
}
});
}
return void 0;
}
function setData(elem, name, value) {
var _a2;
(_a2 = elem.data) !== null && _a2 !== void 0 ? _a2 : elem.data = {};
if (typeof name === "object")
Object.assign(elem.data, name);
else if (typeof name === "string" && value !== void 0) {
elem.data[name] = value;
}
}
function readAllData(el) {
for (const domName of Object.keys(el.attribs)) {
if (!domName.startsWith(dataAttrPrefix)) {
continue;
}
const jsName = camelCase(domName.slice(dataAttrPrefix.length));
if (!hasOwn.call(el.data, jsName)) {
el.data[jsName] = parseDataValue(el.attribs[domName]);
}
}
return el.data;
}
function readData(el, name) {
const domName = dataAttrPrefix + cssCase(name);
const data2 = el.data;
if (hasOwn.call(data2, name)) {
return data2[name];
}
if (hasOwn.call(el.attribs, domName)) {
return data2[name] = parseDataValue(el.attribs[domName]);
}
return void 0;
}
function parseDataValue(value) {
if (value === "null")
return null;
if (value === "true")
return true;
if (value === "false")
return false;
const num = Number(value);
if (value === String(num))
return num;
if (rbrace.test(value)) {
try {
return JSON.parse(value);
} catch {
}
}
return value;
}
function data(name, value) {
var _a2;
const elem = this[0];
if (!elem || !isTag(elem))
return;
const dataEl = elem;
(_a2 = dataEl.data) !== null && _a2 !== void 0 ? _a2 : dataEl.data = {};
if (name == null) {
return readAllData(dataEl);
}
if (typeof name === "object" || value !== void 0) {
domEach(this, (el) => {
if (isTag(el)) {
if (typeof name === "object")
setData(el, name);
else
setData(el, name, value);
}
});
return this;
}
return readData(dataEl, name);
}
function val(value) {
const querying = arguments.length === 0;
const element = this[0];
if (!element || !isTag(element))
return querying ? void 0 : this;
switch (element.name) {
case "textarea": {
return this.text(value);
}
case "select": {
const option = this.find("option:selected");
if (!querying) {
if (this.attr("multiple") == null && typeof value === "object") {
return this;
}
this.find("option").removeAttr("selected");
const values = typeof value === "object" ? value : [value];
for (const val2 of values) {
this.find(`option[value="${val2}"]`).attr("selected", "");
}
return this;
}
return this.attr("multiple") ? option.toArray().map((el) => text$1(el.children)) : option.attr("value");
}
case "input":
case "option": {
return querying ? this.attr("value") : this.attr("value", value);
}
}
return void 0;
}
function removeAttribute(elem, name) {
if (!elem.attribs || !hasOwn.call(elem.attribs, name))
return;
delete elem.attribs[name];
}
function splitNames(names) {
return names ? names.trim().split(rspace) : [];
}
function removeAttr(name) {
const attrNames = splitNames(name);
for (const attrName of attrNames) {
domEach(this, (elem) => {
if (isTag(elem))
removeAttribute(elem, attrName);
});
}
return this;
}
function hasClass(className) {
return this.toArray().some((elem) => {
const clazz = isTag(elem) && elem.attribs["class"];
let idx = -1;
if (clazz && className.length > 0) {
while ((idx = clazz.indexOf(className, idx + 1)) > -1) {
const end2 = idx + className.length;
if ((idx === 0 || rspace.test(clazz[idx - 1])) && (end2 === clazz.length || rspace.test(clazz[end2]))) {
return true;
}
}
}
return false;
});
}
function addClass(value) {
if (typeof value === "function") {
return domEach(this, (el, i) => {
if (isTag(el)) {
const className = el.attribs["class"] || "";
addClass.call([el], value.call(el, i, className));
}
});
}
if (!value || typeof value !== "string")
return this;
const classNames = value.split(rspace);
const numElements = this.length;
for (let i = 0; i < numElements; i++) {
const el = this[i];
if (!isTag(el))
continue;
const className = getAttr(el, "class", false);
if (className) {
let setClass = ` ${className} `;
for (const cn of classNames) {
const appendClass = `${cn} `;
if (!setClass.includes(` ${appendClass}`))
setClass += appendClass;
}
setAttr(el, "class", setClass.trim());
} else {
setAttr(el, "class", classNames.join(" ").trim());
}
}
return this;
}
function removeClass(name) {
if (typeof name === "function") {
return domEach(this, (el, i) => {
if (isTag(el)) {
removeClass.call([el], name.call(el, i, el.attribs["class"] || ""));
}
});
}
const classes = splitNames(name);
const numClasses = classes.length;
const removeAll = arguments.length === 0;
return domEach(this, (el) => {
if (!isTag(el))
return;
if (removeAll) {
el.attribs["class"] = "";
} else {
const elClasses = splitNames(el.attribs["class"]);
let changed = false;
for (let j = 0; j < numClasses; j++) {
const index2 = elClasses.indexOf(classes[j]);
if (index2 >= 0) {
elClasses.splice(index2, 1);
changed = true;
j--;
}
}
if (changed) {
el.attribs["class"] = elClasses.join(" ");
}
}
});
}
function toggleClass(value, stateVal) {
if (typeof value === "function") {
return domEach(this, (el, i) => {
if (isTag(el)) {
toggleClass.call([el], value.call(el, i, el.attribs["class"] || "", stateVal), stateVal);
}
});
}
if (!value || typeof value !== "string")
return this;
const classNames = value.split(rspace);
const numClasses = classNames.length;
const state = typeof stateVal === "boolean" ? stateVal ? 1 : -1 : 0;
const numElements = this.length;
for (let i = 0; i < numElements; i++) {
const el = this[i];
if (!isTag(el))
continue;
const elementClasses = splitNames(el.attribs["class"]);
for (let j = 0; j < numClasses; j++) {
const index2 = elementClasses.indexOf(classNames[j]);
if (state >= 0 && index2 < 0) {
elementClasses.push(classNames[j]);
} else if (state <= 0 && index2 >= 0) {
elementClasses.splice(index2, 1);
}
}
el.attribs["class"] = elementClasses.join(" ");
}
return this;
}
const Attributes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
addClass,
attr,
data,
hasClass,
prop,
removeAttr,
removeClass,
toggleClass,
val
}, Symbol.toStringTag, { value: "Module" }));
var SelectorType;
(function(SelectorType2) {
SelectorType2["Attribute"] = "attribute";
SelectorType2["Pseudo"] = "pseudo";
SelectorType2["PseudoElement"] = "pseudo-element";
SelectorType2["Tag"] = "tag";
SelectorType2["Universal"] = "universal";
SelectorType2["Adjacent"] = "adjacent";
SelectorType2["Child"] = "child";
SelectorType2["Descendant"] = "descendant";
SelectorType2["Parent"] = "parent";
SelectorType2["Sibling"] = "sibling";
SelectorType2["ColumnCombinator"] = "column-combinator";
})(SelectorType || (SelectorType = {}));
var AttributeAction;
(function(AttributeAction2) {
AttributeAction2["Any"] = "any";
AttributeAction2["Element"] = "element";
AttributeAction2["End"] = "end";
AttributeAction2["Equals"] = "equals";
AttributeAction2["Exists"] = "exists";
AttributeAction2["Hyphen"] = "hyphen";
AttributeAction2["Not"] = "not";
AttributeAction2["Start"] = "start";
})(AttributeAction || (AttributeAction = {}));
const reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;
const reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;
const actionTypes = /* @__PURE__ */ new Map([
[126, AttributeAction.Element],
[94, AttributeAction.Start],
[36, AttributeAction.End],
[42, AttributeAction.Any],
[33, AttributeAction.Not],
[124, AttributeAction.Hyphen]
]);
const unpackPseudos = /* @__PURE__ */ new Set([
"has",
"not",
"matches",
"is",
"where",
"host",
"host-context"
]);
function isTraversal$1(selector) {
switch (selector.type) {
case SelectorType.Adjacent:
case SelectorType.Child:
case SelectorType.Descendant:
case SelectorType.Parent:
case SelectorType.Sibling:
case SelectorType.ColumnCombinator:
return true;
default:
return false;
}
}
const stripQuotesFromPseudos = /* @__PURE__ */ new Set(["contains", "icontains"]);
function funescape(_, escaped, escapedWhitespace) {
const high = parseInt(escaped, 16) - 65536;
return high !== high || escapedWhitespace ? escaped : high < 0 ? (
// BMP codepoint
String.fromCharCode(high + 65536)
) : (
// Supplemental Plane codepoint (surrogate pair)
String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320)
);
}
function unescapeCSS(str) {
return str.replace(reEscape, funescape);
}
function isQuote(c) {
return c === 39 || c === 34;
}
function isWhitespace$1(c) {
return c === 32 || c === 9 || c === 10 || c === 12 || c === 13;
}
function parse$2(selector) {
const subselects2 = [];
const endIndex = parseSelector(subselects2, `${selector}`, 0);
if (endIndex < selector.length) {
throw new Error(`Unmatched selector: ${selector.slice(endIndex)}`);
}
return subselects2;
}
function parseSelector(subselects2, selector, selectorIndex) {
let tokens = [];
function getName2(offset) {
const match = selector.slice(selectorIndex + offset).match(reName);
if (!match) {
throw new Error(`Expected name, found ${selector.slice(selectorIndex)}`);
}
const [name] = match;
selectorIndex += offset + name.length;
return unescapeCSS(name);
}
function stripWhitespace(offset) {
selectorIndex += offset;
while (selectorIndex < selector.length && isWhitespace$1(selector.charCodeAt(selectorIndex))) {
selectorIndex++;
}
}
function readValueWithParenthesis() {
selectorIndex += 1;
const start = selectorIndex;
let counter = 1;
for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) {
if (selector.charCodeAt(selectorIndex) === 40 && !isEscaped(selectorIndex)) {
counter++;
} else if (selector.charCodeAt(selectorIndex) === 41 && !isEscaped(selectorIndex)) {
counter--;
}
}
if (counter) {
throw new Error("Parenthesis not matched");
}
return unescapeCSS(selector.slice(start, selectorIndex - 1));
}
function isEscaped(pos) {
let slashCount = 0;
while (selector.charCodeAt(--pos) === 92)
slashCount++;
return (slashCount & 1) === 1;
}
function ensureNotTraversal() {
if (tokens.length > 0 && isTraversal$1(tokens[tokens.length - 1])) {
throw new Error("Did not expect successive traversals.");
}
}
function addTraversal(type) {
if (tokens.length > 0 && tokens[tokens.length - 1].type === SelectorType.Descendant) {
tokens[tokens.length - 1].type = type;
return;
}
ensureNotTraversal();
tokens.push({ type });
}
function addSpecialAttribute(name, action) {
tokens.push({
type: SelectorType.Attribute,
name,
action,
value: getName2(1),
namespace: null,
ignoreCase: "quirks"
});
}
function finalizeSubselector() {
if (tokens.length && tokens[tokens.length - 1].type === SelectorType.Descendant) {
tokens.pop();
}
if (tokens.length === 0) {
throw new Error("Empty sub-selector");
}
subselects2.push(tokens);
}
stripWhitespace(0);
if (selector.length === selectorIndex) {
return selectorIndex;
}
loop: while (selectorIndex < selector.length) {
const firstChar = selector.charCodeAt(selectorIndex);
switch (firstChar) {
// Whitespace
case 32:
case 9:
case 10:
case 12:
case 13: {
if (tokens.length === 0 || tokens[0].type !== SelectorType.Descendant) {
ensureNotTraversal();
tokens.push({ type: SelectorType.Descendant });
}
stripWhitespace(1);
break;
}
// Traversals
case 62: {
addTraversal(SelectorType.Child);
stripWhitespace(1);
break;
}
case 60: {
addTraversal(SelectorType.Parent);
stripWhitespace(1);
break;
}
case 126: {
addTraversal(SelectorType.Sibling);
stripWhitespace(1);
break;
}
case 43: {
addTraversal(SelectorType.Adjacent);
stripWhitespace(1);
break;
}
// Special attribute selectors: .class, #id
case 46: {
addSpecialAttribute("class", AttributeAction.Element);
break;
}
case 35: {
addSpecialAttribute("id", AttributeAction.Equals);
break;
}
case 91: {
stripWhitespace(1);
let name;
let namespace = null;
if (selector.charCodeAt(selectorIndex) === 124) {
name = getName2(1);
} else if (selector.startsWith("*|", selectorIndex)) {
namespace = "*";
name = getName2(2);
} else {
name = getName2(0);
if (selector.charCodeAt(selectorIndex) === 124 && selector.charCodeAt(selectorIndex + 1) !== 61) {
namespace = name;
name = getName2(1);
}
}
stripWhitespace(0);
let action = AttributeAction.Exists;
const possibleAction = actionTypes.get(selector.charCodeAt(selectorIndex));
if (possibleAction) {
action = possibleAction;
if (selector.charCodeAt(selectorIndex + 1) !== 61) {
throw new Error("Expected `=`");
}
stripWhitespace(2);
} else if (selector.charCodeAt(selectorIndex) === 61) {
action = AttributeAction.Equals;
stripWhitespace(1);
}
let value = "";
let ignoreCase = null;
if (action !== "exists") {
if (isQuote(selector.charCodeAt(selectorIndex))) {
const quote = selector.charCodeAt(selectorIndex);
let sectionEnd = selectorIndex + 1;
while (sectionEnd < selector.length && (selector.charCodeAt(sectionEnd) !== quote || isEscaped(sectionEnd))) {
sectionEnd += 1;
}
if (selector.charCodeAt(sectionEnd) !== quote) {
throw new Error("Attribute value didn't end");
}
value = unescapeCSS(selector.slice(selectorIndex + 1, sectionEnd));
selectorIndex = sectionEnd + 1;
} else {
const valueStart = selectorIndex;
while (selectorIndex < selector.length && (!isWhitespace$1(selector.charCodeAt(selectorIndex)) && selector.charCodeAt(selectorIndex) !== 93 || isEscaped(selectorIndex))) {
selectorIndex += 1;
}
value = unescapeCSS(selector.slice(valueStart, selectorIndex));
}
stripWhitespace(0);
const forceIgnore = selector.charCodeAt(selectorIndex) | 32;
if (forceIgnore === 115) {
ignoreCase = false;
stripWhitespace(1);
} else if (forceIgnore === 105) {
ignoreCase = true;
stripWhitespace(1);
}
}
if (selector.charCodeAt(selectorIndex) !== 93) {
throw new Error("Attribute selector didn't terminate");
}
selectorIndex += 1;
const attributeSelector = {
type: SelectorType.Attribute,
name,
action,
value,
namespace,
ignoreCase
};
tokens.push(attributeSelector);
break;
}
case 58: {
if (selector.charCodeAt(selectorIndex + 1) === 58) {
tokens.push({
type: SelectorType.PseudoElement,
name: getName2(2).toLowerCase(),
data: selector.charCodeAt(selectorIndex) === 40 ? readValueWithParenthesis() : null
});
continue;
}
const name = getName2(1).toLowerCase();
let data2 = null;
if (selector.charCodeAt(selectorIndex) === 40) {
if (unpackPseudos.has(name)) {
if (isQuote(selector.charCodeAt(selectorIndex + 1))) {
throw new Error(`Pseudo-selector ${name} cannot be quoted`);
}
data2 = [];
selectorIndex = parseSelector(data2, selector, selectorIndex + 1);
if (selector.charCodeAt(selectorIndex) !== 41) {
throw new Error(`Missing closing parenthesis in :${name} (${selector})`);
}
selectorIndex += 1;
} else {
data2 = readValueWithParenthesis();
if (stripQuotesFromPseudos.has(name)) {
const quot = data2.charCodeAt(0);
if (quot === data2.charCodeAt(data2.length - 1) && isQuote(quot)) {
data2 = data2.slice(1, -1);
}
}
data2 = unescapeCSS(data2);
}
}
tokens.push({ type: SelectorType.Pseudo, name, data: data2 });
break;
}
case 44: {
finalizeSubselector();
tokens = [];
stripWhitespace(1);
break;
}
default: {
if (selector.startsWith("/*", selectorIndex)) {
const endIndex = selector.indexOf("*/", selectorIndex + 2);
if (endIndex < 0) {
throw new Error("Comment was not terminated");
}
selectorIndex = endIndex + 2;
if (tokens.length === 0) {
stripWhitespace(0);
}
break;
}
let namespace = null;
let name;
if (firstChar === 42) {
selectorIndex += 1;
name = "*";
} else if (firstChar === 124) {
name = "";
if (selector.charCodeAt(selectorIndex + 1) === 124) {
addTraversal(SelectorType.ColumnCombinator);
stripWhitespace(2);
break;
}
} else if (reName.test(selector.slice(selectorIndex))) {
name = getName2(0);
} else {
break loop;
}
if (selector.charCodeAt(selectorIndex) === 124 && selector.charCodeAt(selectorIndex + 1) !== 124) {
namespace = name;
if (selector.charCodeAt(selectorIndex + 1) === 42) {
name = "*";
selectorIndex += 2;
} else {
name = getName2(1);
}
}
tokens.push(name === "*" ? { type: SelectorType.Universal, namespace } : { type: SelectorType.Tag, name, namespace });
}
}
}
finalizeSubselector();
return selectorIndex;
}
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
var boolbase$1;
var hasRequiredBoolbase;
function requireBoolbase() {
if (hasRequiredBoolbase) return boolbase$1;
hasRequiredBoolbase = 1;
boolbase$1 = {
trueFunc: function trueFunc() {
return true;
},
falseFunc: function falseFunc() {
return false;
}
};
return boolbase$1;
}
var boolbaseExports = requireBoolbase();
const boolbase = /* @__PURE__ */ getDefaultExportFromCjs(boolbaseExports);
const procedure = /* @__PURE__ */ new Map([
[SelectorType.Universal, 50],
[SelectorType.Tag, 30],
[SelectorType.Attribute, 1],
[SelectorType.Pseudo, 0]
]);
function isTraversal(token) {
return !procedure.has(token.type);
}
const attributes = /* @__PURE__ */ new Map([
[AttributeAction.Exists, 10],
[AttributeAction.Equals, 8],
[AttributeAction.Not, 7],
[AttributeAction.Start, 6],
[AttributeAction.End, 6],
[AttributeAction.Any, 5]
]);
function sortByProcedure(arr) {
const procs = arr.map(getProcedure);
for (let i = 1; i < arr.length; i++) {
const procNew = procs[i];
if (procNew < 0)
continue;
for (let j = i - 1; j >= 0 && procNew < procs[j]; j--) {
const token = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = token;
procs[j + 1] = procs[j];
procs[j] = procNew;
}
}
}
function getProcedure(token) {
var _a2, _b;
let proc = (_a2 = procedure.get(token.type)) !== null && _a2 !== void 0 ? _a2 : -1;
if (token.type === SelectorType.Attribute) {
proc = (_b = attributes.get(token.action)) !== null && _b !== void 0 ? _b : 4;
if (token.action === AttributeAction.Equals && token.name === "id") {
proc = 9;
}
if (token.ignoreCase) {
proc >>= 1;
}
} else if (token.type === SelectorType.Pseudo) {
if (!token.data) {
proc = 3;
} else if (token.name === "has" || token.name === "contains") {
proc = 0;
} else if (Array.isArray(token.data)) {
proc = Math.min(...token.data.map((d) => Math.min(...d.map(getProcedure))));
if (proc < 0) {
proc = 0;
}
} else {
proc = 2;
}
}
return proc;
}
const reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
function escapeRegex(value) {
return value.replace(reChars, "\\$&");
}
const caseInsensitiveAttributes = /* @__PURE__ */ new Set([
"accept",
"accept-charset",
"align",
"alink",
"axis",
"bgcolor",
"charset",
"checked",
"clear",
"codetype",
"color",
"compact",
"declare",
"defer",
"dir",
"direction",
"disabled",
"enctype",
"face",
"frame",
"hreflang",
"http-equiv",
"lang",
"language",
"link",
"media",
"method",
"multiple",
"nohref",
"noresize",
"noshade",
"nowrap",
"readonly",
"rel",
"rev",
"rules",
"scope",
"scrolling",
"selected",
"shape",
"target",
"text",
"type",
"valign",
"valuetype",
"vlink"
]);
function shouldIgnoreCase(selector, options) {
return typeof selector.ignoreCase === "boolean" ? selector.ignoreCase : selector.ignoreCase === "quirks" ? !!options.quirksMode : !options.xmlMode && caseInsensitiveAttributes.has(selector.name);
}
const attributeRules = {
equals(next2, data2, options) {
const { adapter } = options;
const { name } = data2;
let { value } = data2;
if (shouldIgnoreCase(data2, options)) {
value = value.toLowerCase();
return (elem) => {
const attr2 = adapter.getAttributeValue(elem, name);
return attr2 != null && attr2.length === value.length && attr2.toLowerCase() === value && next2(elem);
};
}
return (elem) => adapter.getAttributeValue(elem, name) === value && next2(elem);
},
hyphen(next2, data2, options) {
const { adapter } = options;
const { name } = data2;
let { value } = data2;
const len = value.length;
if (shouldIgnoreCase(data2, options)) {
value = value.toLowerCase();
return function hyphenIC(elem) {
const attr2 = adapter.getAttributeValue(elem, name);
return attr2 != null && (attr2.length === len || attr2.charAt(len) === "-") && attr2.substr(0, len).toLowerCase() === value && next2(elem);
};
}
return function hyphen(elem) {
const attr2 = adapter.getAttributeValue(elem, name);
return attr2 != null && (attr2.length === len || attr2.charAt(len) === "-") && attr2.substr(0, len) === value && next2(elem);
};
},
element(next2, data2, options) {
const { adapter } = options;
const { name, value } = data2;
if (/\s/.test(value)) {
return boolbase.falseFunc;
}
const regex = new RegExp(`(?:^|\\s)${escapeRegex(value)}(?:$|\\s)`, shouldIgnoreCase(data2, options) ? "i" : "");
return function element(elem) {
const attr2 = adapter.getAttributeValue(elem, name);
return attr2 != null && attr2.length >= value.length && regex.test(attr2) && next2(elem);
};
},
exists(next2, { name }, { adapter }) {
return (elem) => adapter.hasAttrib(elem, name) && next2(elem);
},
start(next2, data2, options) {
const { adapter } = options;
const { name } = data2;
let { value } = data2;
const len = value.length;
if (len === 0) {
return boolbase.falseFunc;
}
if (shouldIgnoreCase(data2, options)) {
value = value.toLowerCase();
return (elem) => {
const attr2 = adapter.getAttributeValue(elem, name);
return attr2 != null && attr2.length >= len && attr2.substr(0, len).toLowerCase() === value && next2(elem);
};
}
return (elem) => {
var _a2;
return !!((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.startsWith(value)) && next2(elem);
};
},
end(next2, data2, options) {
const { adapter } = options;
const { name } = data2;
let { value } = data2;
const len = -value.length;
if (len === 0) {
return boolbase.falseFunc;
}
if (shouldIgnoreCase(data2, options)) {
value = value.toLowerCase();
return (elem) => {
var _a2;
return ((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.substr(len).toLowerCase()) === value && next2(elem);
};
}
return (elem) => {
var _a2;
return !!((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.endsWith(value)) && next2(elem);
};
},
any(next2, data2, options) {
const { adapter } = options;
const { name, value } = data2;
if (value === "") {
return boolbase.falseFunc;
}
if (shouldIgnoreCase(data2, options)) {
const regex = new RegExp(escapeRegex(value), "i");
return function anyIC(elem) {
const attr2 = adapter.getAttributeValue(elem, name);
return attr2 != null && attr2.length >= value.length && regex.test(attr2) && next2(elem);
};
}
return (elem) => {
var _a2;
return !!((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.includes(value)) && next2(elem);
};
},
not(next2, data2, options) {
const { adapter } = options;
const { name } = data2;
let { value } = data2;
if (value === "") {
return (elem) => !!adapter.getAttributeValue(elem, name) && next2(elem);
} else if (shouldIgnoreCase(data2, options)) {
value = value.toLowerCase();
return (elem) => {
const attr2 = adapter.getAttributeValue(elem, name);
return (attr2 == null || attr2.length !== value.length || attr2.toLowerCase() !== value) && next2(elem);
};
}
return (elem) => adapter.getAttributeValue(elem, name) !== value && next2(elem);
}
};
const whitespace = /* @__PURE__ */ new Set([9, 10, 12, 13, 32]);
const ZERO = "0".charCodeAt(0);
const NINE = "9".charCodeAt(0);
function parse$1(formula) {
formula = formula.trim().toLowerCase();
if (formula === "even") {
return [2, 0];
} else if (formula === "odd") {
return [2, 1];
}
let idx = 0;
let a = 0;
let sign = readSign();
let number = readNumber();
if (idx < formula.length && formula.charAt(idx) === "n") {
idx++;
a = sign * (number !== null && number !== void 0 ? number : 1);
skipWhitespace();
if (idx < formula.length) {
sign = readSign();
skipWhitespace();
number = readNumber();
} else {
sign = number = 0;
}
}
if (number === null || idx < formula.length) {
throw new Error(`n-th rule couldn't be parsed ('${formula}')`);
}
return [a, sign * number];
function readSign() {
if (formula.charAt(idx) === "-") {
idx++;
return -1;
}
if (formula.charAt(idx) === "+") {
idx++;
}
return 1;
}
function readNumber() {
const start = idx;
let value = 0;
while (idx < formula.length && formula.charCodeAt(idx) >= ZERO && formula.charCodeAt(idx) <= NINE) {
value = value * 10 + (formula.charCodeAt(idx) - ZERO);
idx++;
}
return idx === start ? null : value;
}
function skipWhitespace() {
while (idx < formula.length && whitespace.has(formula.charCodeAt(idx))) {
idx++;
}
}
}
function compile(parsed) {
const a = parsed[0];
const b = parsed[1] - 1;
if (b < 0 && a <= 0)
return boolbase.falseFunc;
if (a === -1)
return (index2) => index2 <= b;
if (a === 0)
return (index2) => index2 === b;
if (a === 1)
return b < 0 ? boolbase.trueFunc : (index2) => index2 >= b;
const absA = Math.abs(a);
const bMod = (b % absA + absA) % absA;
return a > 1 ? (index2) => index2 >= b && index2 % absA === bMod : (index2) => index2 <= b && index2 % absA === bMod;
}
function nthCheck(formula) {
return compile(parse$1(formula));
}
function getChildFunc(next2, adapter) {
return (elem) => {
const parent2 = adapter.getParent(elem);
return parent2 != null && adapter.isTag(parent2) && next2(elem);
};
}
const filters = {
contains(next2, text2, { adapter }) {
return function contains2(elem) {
return next2(elem) && adapter.getText(elem).includes(text2);
};
},
icontains(next2, text2, { adapter }) {
const itext = text2.toLowerCase();
return function icontains(elem) {
return next2(elem) && adapter.getText(elem).toLowerCase().includes(itext);
};
},
// Location specific methods
"nth-child"(next2, rule, { adapter, equals }) {
const func = nthCheck(rule);
if (func === boolbase.falseFunc)
return boolbase.falseFunc;
if (func === boolbase.trueFunc)
return getChildFunc(next2, adapter);
return function nthChild(elem) {
const siblings2 = adapter.getSiblings(elem);
let pos = 0;
for (let i = 0; i < siblings2.length; i++) {
if (equals(elem, siblings2[i]))
break;
if (adapter.isTag(siblings2[i])) {
pos++;
}
}
return func(pos) && next2(elem);
};
},
"nth-last-child"(next2, rule, { adapter, equals }) {
const func = nthCheck(rule);
if (func === boolbase.falseFunc)
return boolbase.falseFunc;
if (func === boolbase.trueFunc)
return getChildFunc(next2, adapter);
return function nthLastChild(elem) {
const siblings2 = adapter.getSiblings(elem);
let pos = 0;
for (let i = siblings2.length - 1; i >= 0; i--) {
if (equals(elem, siblings2[i]))
break;
if (adapter.isTag(siblings2[i])) {
pos++;
}
}
return func(pos) && next2(elem);
};
},
"nth-of-type"(next2, rule, { adapter, equals }) {
const func = nthCheck(rule);
if (func === boolbase.falseFunc)
return boolbase.falseFunc;
if (func === boolbase.trueFunc)
return getChildFunc(next2, adapter);
return function nthOfType(elem) {
const siblings2 = adapter.getSiblings(elem);
let pos = 0;
for (let i = 0; i < siblings2.length; i++) {
const currentSibling = siblings2[i];
if (equals(elem, currentSibling))
break;
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === adapter.getName(elem)) {
pos++;
}
}
return func(pos) && next2(elem);
};
},
"nth-last-of-type"(next2, rule, { adapter, equals }) {
const func = nthCheck(rule);
if (func === boolbase.falseFunc)
return boolbase.falseFunc;
if (func === boolbase.trueFunc)
return getChildFunc(next2, adapter);
return function nthLastOfType(elem) {
const siblings2 = adapter.getSiblings(elem);
let pos = 0;
for (let i = siblings2.length - 1; i >= 0; i--) {
const currentSibling = siblings2[i];
if (equals(elem, currentSibling))
break;
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === adapter.getName(elem)) {
pos++;
}
}
return func(pos) && next2(elem);
};
},
// TODO determine the actual root element
root(next2, _rule, { adapter }) {
return (elem) => {
const parent2 = adapter.getParent(elem);
return (parent2 == null || !adapter.isTag(parent2)) && next2(elem);
};
},
scope(next2, rule, options, context) {
const { equals } = options;
if (!context || context.length === 0) {
return filters["root"](next2, rule, options);
}
if (context.length === 1) {
return (elem) => equals(context[0], elem) && next2(elem);
}
return (elem) => context.includes(elem) && next2(elem);
},
hover: dynamicStatePseudo("isHovered"),
visited: dynamicStatePseudo("isVisited"),
active: dynamicStatePseudo("isActive")
};
function dynamicStatePseudo(name) {
return function dynamicPseudo(next2, _rule, { adapter }) {
const func = adapter[name];
if (typeof func !== "function") {
return boolbase.falseFunc;
}
return function active(elem) {
return func(elem) && next2(elem);
};
};
}
const pseudos = {
empty(elem, { adapter }) {
return !adapter.getChildren(elem).some((elem2) => (
// FIXME: `getText` call is potentially expensive.
adapter.isTag(elem2) || adapter.getText(elem2) !== ""
));
},
"first-child"(elem, { adapter, equals }) {
if (adapter.prevElementSibling) {
return adapter.prevElementSibling(elem) == null;
}
const firstChild = adapter.getSiblings(elem).find((elem2) => adapter.isTag(elem2));
return firstChild != null && equals(elem, firstChild);
},
"last-child"(elem, { adapter, equals }) {
const siblings2 = adapter.getSiblings(elem);
for (let i = siblings2.length - 1; i >= 0; i--) {
if (equals(elem, siblings2[i]))
return true;
if (adapter.isTag(siblings2[i]))
break;
}
return false;
},
"first-of-type"(elem, { adapter, equals }) {
const siblings2 = adapter.getSiblings(elem);
const elemName = adapter.getName(elem);
for (let i = 0; i < siblings2.length; i++) {
const currentSibling = siblings2[i];
if (equals(elem, currentSibling))
return true;
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === elemName) {
break;
}
}
return false;
},
"last-of-type"(elem, { adapter, equals }) {
const siblings2 = adapter.getSiblings(elem);
const elemName = adapter.getName(elem);
for (let i = siblings2.length - 1; i >= 0; i--) {
const currentSibling = siblings2[i];
if (equals(elem, currentSibling))
return true;
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === elemName) {
break;
}
}
return false;
},
"only-of-type"(elem, { adapter, equals }) {
const elemName = adapter.getName(elem);
return adapter.getSiblings(elem).every((sibling) => equals(elem, sibling) || !adapter.isTag(sibling) || adapter.getName(sibling) !== elemName);
},
"only-child"(elem, { adapter, equals }) {
return adapter.getSiblings(elem).every((sibling) => equals(elem, sibling) || !adapter.isTag(sibling));
}
};
function verifyPseudoArgs(func, name, subselect, argIndex) {
if (subselect === null) {
if (func.length > argIndex) {
throw new Error(`Pseudo-class :${name} requires an argument`);
}
} else if (func.length === argIndex) {
throw new Error(`Pseudo-class :${name} doesn't have any arguments`);
}
}
const aliases = {
// Links
"any-link": ":is(a, area, link)[href]",
link: ":any-link:not(:visited)",
// Forms
// https://html.spec.whatwg.org/multipage/scripting.html#disabled-elements
disabled: `:is(
:is(button, input, select, textarea, optgroup, option)[disabled],
optgroup[disabled] > option,
fieldset[disabled]:not(fieldset[disabled] legend:first-of-type *)
)`,
enabled: ":not(:disabled)",
checked: ":is(:is(input[type=radio], input[type=checkbox])[checked], option:selected)",
required: ":is(input, select, textarea)[required]",
optional: ":is(input, select, textarea):not([required])",
// JQuery extensions
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-option-selectedness
selected: "option:is([selected], select:not([multiple]):not(:has(> option[selected])) > :first-of-type)",
checkbox: "[type=checkbox]",
file: "[type=file]",
password: "[type=password]",
radio: "[type=radio]",
reset: "[type=reset]",
image: "[type=image]",
submit: "[type=submit]",
parent: ":not(:empty)",
header: ":is(h1, h2, h3, h4, h5, h6)",
button: ":is(button, input[type=button])",
input: ":is(input, textarea, select, button)",
text: "input:is(:not([type!='']), [type=text])"
};
const PLACEHOLDER_ELEMENT = {};
function ensureIsTag(next2, adapter) {
if (next2 === boolbase.falseFunc)
return boolbase.falseFunc;
return (elem) => adapter.isTag(elem) && next2(elem);
}
function getNextSiblings(elem, adapter) {
const siblings2 = adapter.getSiblings(elem);
if (siblings2.length <= 1)
return [];
const elemIndex = siblings2.indexOf(elem);
if (elemIndex < 0 || elemIndex === siblings2.length - 1)
return [];
return siblings2.slice(elemIndex + 1).filter(adapter.isTag);
}
function copyOptions(options) {
return {
xmlMode: !!options.xmlMode,
lowerCaseAttributeNames: !!options.lowerCaseAttributeNames,
lowerCaseTags: !!options.lowerCaseTags,
quirksMode: !!options.quirksMode,
cacheResults: !!options.cacheResults,
pseudos: options.pseudos,
adapter: options.adapter,
equals: options.equals
};
}
const is$2 = (next2, token, options, context, compileToken2) => {
const func = compileToken2(token, copyOptions(options), context);
return func === boolbase.trueFunc ? next2 : func === boolbase.falseFunc ? boolbase.falseFunc : (elem) => func(elem) && next2(elem);
};
const subselects = {
is: is$2,
/**
* `:matches` and `:where` are aliases for `:is`.
*/
matches: is$2,
where: is$2,
not(next2, token, options, context, compileToken2) {
const func = compileToken2(token, copyOptions(options), context);
return func === boolbase.falseFunc ? next2 : func === boolbase.trueFunc ? boolbase.falseFunc : (elem) => !func(elem) && next2(elem);
},
has(next2, subselect, options, _context, compileToken2) {
const { adapter } = options;
const opts = copyOptions(options);
opts.relativeSelector = true;
const context = subselect.some((s) => s.some(isTraversal)) ? (
// Used as a placeholder. Will be replaced with the actual element.
[PLACEHOLDER_ELEMENT]
) : void 0;
const compiled = compileToken2(subselect, opts, context);
if (compiled === boolbase.falseFunc)
return boolbase.falseFunc;
const hasElement = ensureIsTag(compiled, adapter);
if (context && compiled !== boolbase.trueFunc) {
const { shouldTestNextSiblings = false } = compiled;
return (elem) => {
if (!next2(elem))
return false;
context[0] = elem;
const childs = adapter.getChildren(elem);
const nextElements = shouldTestNextSiblings ? [...childs, ...getNextSiblings(elem, adapter)] : childs;
return adapter.existsOne(hasElement, nextElements);
};
}
return (elem) => next2(elem) && adapter.existsOne(hasElement, adapter.getChildren(elem));
}
};
function compilePseudoSelector(next2, selector, options, context, compileToken2) {
var _a2;
const { name, data: data2 } = selector;
if (Array.isArray(data2)) {
if (!(name in subselects)) {
throw new Error(`Unknown pseudo-class :${name}(${data2})`);
}
return subselects[name](next2, data2, options, context, compileToken2);
}
const userPseudo = (_a2 = options.pseudos) === null || _a2 === void 0 ? void 0 : _a2[name];
const stringPseudo = typeof userPseudo === "string" ? userPseudo : aliases[name];
if (typeof stringPseudo === "string") {
if (data2 != null) {
throw new Error(`Pseudo ${name} doesn't have any arguments`);
}
const alias = parse$2(stringPseudo);
return subselects["is"](next2, alias, options, context, compileToken2);
}
if (typeof userPseudo === "function") {
verifyPseudoArgs(userPseudo, name, data2, 1);
return (elem) => userPseudo(elem, data2) && next2(elem);
}
if (name in filters) {
return filters[name](next2, data2, options, context);
}
if (name in pseudos) {
const pseudo = pseudos[name];
verifyPseudoArgs(pseudo, name, data2, 2);
return (elem) => pseudo(elem, options, data2) && next2(elem);
}
throw new Error(`Unknown pseudo-class :${name}`);
}
function getElementParent(node, adapter) {
const parent2 = adapter.getParent(node);
if (parent2 && adapter.isTag(parent2)) {
return parent2;
}
return null;
}
function compileGeneralSelector(next2, selector, options, context, compileToken2) {
const { adapter, equals } = options;
switch (selector.type) {
case SelectorType.PseudoElement: {
throw new Error("Pseudo-elements are not supported by css-select");
}
case SelectorType.ColumnCombinator: {
throw new Error("Column combinators are not yet supported by css-select");
}
case SelectorType.Attribute: {
if (selector.namespace != null) {
throw new Error("Namespaced attributes are not yet supported by css-select");
}
if (!options.xmlMode || options.lowerCaseAttributeNames) {
selector.name = selector.name.toLowerCase();
}
return attributeRules[selector.action](next2, selector, options);
}
case SelectorType.Pseudo: {
return compilePseudoSelector(next2, selector, options, context, compileToken2);
}
// Tags
case SelectorType.Tag: {
if (selector.namespace != null) {
throw new Error("Namespaced tag names are not yet supported by css-select");
}
let { name } = selector;
if (!options.xmlMode || options.lowerCaseTags) {
name = name.toLowerCase();
}
return function tag(elem) {
return adapter.getName(elem) === name && next2(elem);
};
}
// Traversal
case SelectorType.Descendant: {
if (options.cacheResults === false || typeof WeakSet === "undefined") {
return function descendant(elem) {
let current = elem;
while (current = getElementParent(current, adapter)) {
if (next2(current)) {
return true;
}
}
return false;
};
}
const isFalseCache = /* @__PURE__ */ new WeakSet();
return function cachedDescendant(elem) {
let current = elem;
while (current = getElementParent(current, adapter)) {
if (!isFalseCache.has(current)) {
if (adapter.isTag(current) && next2(current)) {
return true;
}
isFalseCache.add(current);
}
}
return false;
};
}
case "_flexibleDescendant": {
return function flexibleDescendant(elem) {
let current = elem;
do {
if (next2(current))
return true;
} while (current = getElementParent(current, adapter));
return false;
};
}
case SelectorType.Parent: {
return function parent2(elem) {
return adapter.getChildren(elem).some((elem2) => adapter.isTag(elem2) && next2(elem2));
};
}
case SelectorType.Child: {
return function child(elem) {
const parent2 = adapter.getParent(elem);
return parent2 != null && adapter.isTag(parent2) && next2(parent2);
};
}
case SelectorType.Sibling: {
return function sibling(elem) {
const siblings2 = adapter.getSiblings(elem);
for (let i = 0; i < siblings2.length; i++) {
const currentSibling = siblings2[i];
if (equals(elem, currentSibling))
break;
if (adapter.isTag(currentSibling) && next2(currentSibling)) {
return true;
}
}
return false;
};
}
case SelectorType.Adjacent: {
if (adapter.prevElementSibling) {
return function adjacent(elem) {
const previous = adapter.prevElementSibling(elem);
return previous != null && next2(previous);
};
}
return function adjacent(elem) {
const siblings2 = adapter.getSiblings(elem);
let lastElement;
for (let i = 0; i < siblings2.length; i++) {
const currentSibling = siblings2[i];
if (equals(elem, currentSibling))
break;
if (adapter.isTag(currentSibling)) {
lastElement = currentSibling;
}
}
return !!lastElement && next2(lastElement);
};
}
case SelectorType.Universal: {
if (selector.namespace != null && selector.namespace !== "*") {
throw new Error("Namespaced universal selectors are not yet supported by css-select");
}
return next2;
}
}
}
function includesScopePseudo(t) {
return t.type === SelectorType.Pseudo && (t.name === "scope" || Array.isArray(t.data) && t.data.some((data2) => data2.some(includesScopePseudo)));
}
const DESCENDANT_TOKEN = { type: SelectorType.Descendant };
const FLEXIBLE_DESCENDANT_TOKEN = {
type: "_flexibleDescendant"
};
const SCOPE_TOKEN = {
type: SelectorType.Pseudo,
name: "scope",
data: null
};
function absolutize(token, { adapter }, context) {
const hasContext = !!(context === null || context === void 0 ? void 0 : context.every((e) => {
const parent2 = adapter.isTag(e) && adapter.getParent(e);
return e === PLACEHOLDER_ELEMENT || parent2 && adapter.isTag(parent2);
}));
for (const t of token) {
if (t.length > 0 && isTraversal(t[0]) && t[0].type !== SelectorType.Descendant) ;
else if (hasContext && !t.some(includesScopePseudo)) {
t.unshift(DESCENDANT_TOKEN);
} else {
continue;
}
t.unshift(SCOPE_TOKEN);
}
}
function compileToken(token, options, context) {
var _a2;
token.forEach(sortByProcedure);
context = (_a2 = options.context) !== null && _a2 !== void 0 ? _a2 : context;
const isArrayContext = Array.isArray(context);
const finalContext = context && (Array.isArray(context) ? context : [context]);
if (options.relativeSelector !== false) {
absolutize(token, options, finalContext);
} else if (token.some((t) => t.length > 0 && isTraversal(t[0]))) {
throw new Error("Relative selectors are not allowed when the `relativeSelector` option is disabled");
}
let shouldTestNextSiblings = false;
const query = token.map((rules) => {
if (rules.length >= 2) {
const [first2, second] = rules;
if (first2.type !== SelectorType.Pseudo || first2.name !== "scope") ;
else if (isArrayContext && second.type === SelectorType.Descendant) {
rules[1] = FLEXIBLE_DESCENDANT_TOKEN;
} else if (second.type === SelectorType.Adjacent || second.type === SelectorType.Sibling) {
shouldTestNextSiblings = true;
}
}
return compileRules(rules, options, finalContext);
}).reduce(reduceRules, boolbase.falseFunc);
query.shouldTestNextSiblings = shouldTestNextSiblings;
return query;
}
function compileRules(rules, options, context) {
var _a2;
return rules.reduce((previous, rule) => previous === boolbase.falseFunc ? boolbase.falseFunc : compileGeneralSelector(previous, rule, options, context, compileToken), (_a2 = options.rootFunc) !== null && _a2 !== void 0 ? _a2 : boolbase.trueFunc);
}
function reduceRules(a, b) {
if (b === boolbase.falseFunc || a === boolbase.trueFunc) {
return a;
}
if (a === boolbase.falseFunc || b === boolbase.trueFunc) {
return b;
}
return function combine(elem) {
return a(elem) || b(elem);
};
}
const defaultEquals = (a, b) => a === b;
const defaultOptions$1 = {
adapter: DomUtils,
equals: defaultEquals
};
function convertOptionFormats(options) {
var _a2, _b, _c, _d;
const opts = options !== null && options !== void 0 ? options : defaultOptions$1;
(_a2 = opts.adapter) !== null && _a2 !== void 0 ? _a2 : opts.adapter = DomUtils;
(_b = opts.equals) !== null && _b !== void 0 ? _b : opts.equals = (_d = (_c = opts.adapter) === null || _c === void 0 ? void 0 : _c.equals) !== null && _d !== void 0 ? _d : defaultEquals;
return opts;
}
function wrapCompile(func) {
return function addAdapter(selector, options, context) {
const opts = convertOptionFormats(options);
return func(selector, opts, context);
};
}
const _compileToken = wrapCompile(compileToken);
function prepareContext(elems, adapter, shouldTestNextSiblings = false) {
if (shouldTestNextSiblings) {
elems = appendNextSiblings(elems, adapter);
}
return Array.isArray(elems) ? adapter.removeSubsets(elems) : adapter.getChildren(elems);
}
function appendNextSiblings(elem, adapter) {
const elems = Array.isArray(elem) ? elem.slice(0) : [elem];
const elemsLength = elems.length;
for (let i = 0; i < elemsLength; i++) {
const nextSiblings = getNextSiblings(elems[i], adapter);
elems.push(...nextSiblings);
}
return elems;
}
const filterNames = /* @__PURE__ */ new Set([
"first",
"last",
"eq",
"gt",
"nth",
"lt",
"even",
"odd"
]);
function isFilter(s) {
if (s.type !== "pseudo")
return false;
if (filterNames.has(s.name))
return true;
if (s.name === "not" && Array.isArray(s.data)) {
return s.data.some((s2) => s2.some(isFilter));
}
return false;
}
function getLimit(filter2, data2, partLimit) {
const num = data2 != null ? parseInt(data2, 10) : NaN;
switch (filter2) {
case "first":
return 1;
case "nth":
case "eq":
return isFinite(num) ? num >= 0 ? num + 1 : Infinity : 0;
case "lt":
return isFinite(num) ? num >= 0 ? Math.min(num, partLimit) : Infinity : 0;
case "gt":
return isFinite(num) ? Infinity : 0;
case "odd":
return 2 * partLimit;
case "even":
return 2 * partLimit - 1;
case "last":
case "not":
return Infinity;
}
}
function getDocumentRoot(node) {
while (node.parent)
node = node.parent;
return node;
}
function groupSelectors(selectors) {
const filteredSelectors = [];
const plainSelectors = [];
for (const selector of selectors) {
if (selector.some(isFilter)) {
filteredSelectors.push(selector);
} else {
plainSelectors.push(selector);
}
}
return [plainSelectors, filteredSelectors];
}
const UNIVERSAL_SELECTOR = {
type: SelectorType.Universal,
namespace: null
};
const SCOPE_PSEUDO = {
type: SelectorType.Pseudo,
name: "scope",
data: null
};
function is$1(element, selector, options = {}) {
return some([element], selector, options);
}
function some(elements, selector, options = {}) {
if (typeof selector === "function")
return elements.some(selector);
const [plain, filtered] = groupSelectors(parse$2(selector));
return plain.length > 0 && elements.some(_compileToken(plain, options)) || filtered.some((sel) => filterBySelector(sel, elements, options).length > 0);
}
function filterByPosition(filter2, elems, data2, options) {
const num = typeof data2 === "string" ? parseInt(data2, 10) : NaN;
switch (filter2) {
case "first":
case "lt":
return elems;
case "last":
return elems.length > 0 ? [elems[elems.length - 1]] : elems;
case "nth":
case "eq":
return isFinite(num) && Math.abs(num) < elems.length ? [num < 0 ? elems[elems.length + num] : elems[num]] : [];
case "gt":
return isFinite(num) ? elems.slice(num + 1) : [];
case "even":
return elems.filter((_, i) => i % 2 === 0);
case "odd":
return elems.filter((_, i) => i % 2 === 1);
case "not": {
const filtered = new Set(filterParsed(data2, elems, options));
return elems.filter((e) => !filtered.has(e));
}
}
}
function filter$1(selector, elements, options = {}) {
return filterParsed(parse$2(selector), elements, options);
}
function filterParsed(selector, elements, options) {
if (elements.length === 0)
return [];
const [plainSelectors, filteredSelectors] = groupSelectors(selector);
let found;
if (plainSelectors.length) {
const filtered = filterElements(elements, plainSelectors, options);
if (filteredSelectors.length === 0) {
return filtered;
}
if (filtered.length) {
found = new Set(filtered);
}
}
for (let i = 0; i < filteredSelectors.length && (found === null || found === void 0 ? void 0 : found.size) !== elements.length; i++) {
const filteredSelector = filteredSelectors[i];
const missing = found ? elements.filter((e) => isTag(e) && !found.has(e)) : elements;
if (missing.length === 0)
break;
const filtered = filterBySelector(filteredSelector, elements, options);
if (filtered.length) {
if (!found) {
if (i === filteredSelectors.length - 1) {
return filtered;
}
found = new Set(filtered);
} else {
filtered.forEach((el) => found.add(el));
}
}
}
return typeof found !== "undefined" ? found.size === elements.length ? elements : (
// Filter elements to preserve order
elements.filter((el) => found.has(el))
) : [];
}
function filterBySelector(selector, elements, options) {
var _a2;
if (selector.some(isTraversal$1)) {
const root2 = (_a2 = options.root) !== null && _a2 !== void 0 ? _a2 : getDocumentRoot(elements[0]);
const opts = { ...options, context: elements, relativeSelector: false };
selector.push(SCOPE_PSEUDO);
return findFilterElements(root2, selector, opts, true, elements.length);
}
return findFilterElements(elements, selector, options, false, elements.length);
}
function select(selector, root2, options = {}, limit = Infinity) {
if (typeof selector === "function") {
return find$1(root2, selector);
}
const [plain, filtered] = groupSelectors(parse$2(selector));
const results = filtered.map((sel) => findFilterElements(root2, sel, options, true, limit));
if (plain.length) {
results.push(findElements(root2, plain, options, limit));
}
if (results.length === 0) {
return [];
}
if (results.length === 1) {
return results[0];
}
return uniqueSort(results.reduce((a, b) => [...a, ...b]));
}
function findFilterElements(root2, selector, options, queryForSelector, totalLimit) {
const filterIndex = selector.findIndex(isFilter);
const sub = selector.slice(0, filterIndex);
const filter2 = selector[filterIndex];
const partLimit = selector.length - 1 === filterIndex ? totalLimit : Infinity;
const limit = getLimit(filter2.name, filter2.data, partLimit);
if (limit === 0)
return [];
const elemsNoLimit = sub.length === 0 && !Array.isArray(root2) ? getChildren(root2).filter(isTag) : sub.length === 0 ? (Array.isArray(root2) ? root2 : [root2]).filter(isTag) : queryForSelector || sub.some(isTraversal$1) ? findElements(root2, [sub], options, limit) : filterElements(root2, [sub], options);
const elems = elemsNoLimit.slice(0, limit);
let result = filterByPosition(filter2.name, elems, filter2.data, options);
if (result.length === 0 || selector.length === filterIndex + 1) {
return result;
}
const remainingSelector = selector.slice(filterIndex + 1);
const remainingHasTraversal = remainingSelector.some(isTraversal$1);
if (remainingHasTraversal) {
if (isTraversal$1(remainingSelector[0])) {
const { type } = remainingSelector[0];
if (type === SelectorType.Sibling || type === SelectorType.Adjacent) {
result = prepareContext(result, DomUtils, true);
}
remainingSelector.unshift(UNIVERSAL_SELECTOR);
}
options = {
...options,
// Avoid absolutizing the selector
relativeSelector: false,
/*
* Add a custom root func, to make sure traversals don't match elements
* that aren't a part of the considered tree.
*/
rootFunc: (el) => result.includes(el)
};
} else if (options.rootFunc && options.rootFunc !== boolbaseExports.trueFunc) {
options = { ...options, rootFunc: boolbaseExports.trueFunc };
}
return remainingSelector.some(isFilter) ? findFilterElements(result, remainingSelector, options, false, totalLimit) : remainingHasTraversal ? (
// Query existing elements to resolve traversal.
findElements(result, [remainingSelector], options, totalLimit)
) : (
// If we don't have any more traversals, simply filter elements.
filterElements(result, [remainingSelector], options)
);
}
function findElements(root2, sel, options, limit) {
const query = _compileToken(sel, options, root2);
return find$1(root2, query, limit);
}
function find$1(root2, query, limit = Infinity) {
const elems = prepareContext(root2, DomUtils, query.shouldTestNextSiblings);
return find$2((node) => isTag(node) && query(node), elems, true, limit);
}
function filterElements(elements, sel, options) {
const els = (Array.isArray(elements) ? elements : [elements]).filter(isTag);
if (els.length === 0)
return els;
const query = _compileToken(sel, options);
return query === boolbaseExports.trueFunc ? els : els.filter(query);
}
const reSiblingSelector = /^\s*[+~]/;
function find(selectorOrHaystack) {
if (!selectorOrHaystack) {
return this._make([]);
}
if (typeof selectorOrHaystack !== "string") {
const haystack = isCheerio(selectorOrHaystack) ? selectorOrHaystack.toArray() : [selectorOrHaystack];
const context = this.toArray();
return this._make(haystack.filter((elem) => context.some((node) => contains(node, elem))));
}
return this._findBySelector(selectorOrHaystack, Number.POSITIVE_INFINITY);
}
function _findBySelector(selector, limit) {
var _a2;
const context = this.toArray();
const elems = reSiblingSelector.test(selector) ? context : this.children().toArray();
const options = {
context,
root: (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0],
// Pass options that are recognized by `cheerio-select`
xmlMode: this.options.xmlMode,
lowerCaseTags: this.options.lowerCaseTags,
lowerCaseAttributeNames: this.options.lowerCaseAttributeNames,
pseudos: this.options.pseudos,
quirksMode: this.options.quirksMode
};
return this._make(select(selector, elems, options, limit));
}
function _getMatcher(matchMap) {
return function(fn, ...postFns) {
return function(selector) {
var _a2;
let matched = matchMap(fn, this);
if (selector) {
matched = filterArray(matched, selector, this.options.xmlMode, (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0]);
}
return this._make(
// Post processing is only necessary if there is more than one element.
this.length > 1 && matched.length > 1 ? postFns.reduce((elems, fn2) => fn2(elems), matched) : matched
);
};
};
}
const _matcher = _getMatcher((fn, elems) => {
let ret = [];
for (let i = 0; i < elems.length; i++) {
const value = fn(elems[i]);
if (value.length > 0)
ret = ret.concat(value);
}
return ret;
});
const _singleMatcher = _getMatcher((fn, elems) => {
const ret = [];
for (let i = 0; i < elems.length; i++) {
const value = fn(elems[i]);
if (value !== null) {
ret.push(value);
}
}
return ret;
});
function _matchUntil(nextElem, ...postFns) {
let matches = null;
const innerMatcher = _getMatcher((nextElem2, elems) => {
const matched = [];
domEach(elems, (elem) => {
for (let next2; next2 = nextElem2(elem); elem = next2) {
if (matches === null || matches === void 0 ? void 0 : matches(next2, matched.length))
break;
matched.push(next2);
}
});
return matched;
})(nextElem, ...postFns);
return function(selector, filterSelector) {
matches = typeof selector === "string" ? (elem) => is$1(elem, selector, this.options) : selector ? getFilterFn(selector) : null;
const ret = innerMatcher.call(this, filterSelector);
matches = null;
return ret;
};
}
function _removeDuplicates(elems) {
return elems.length > 1 ? Array.from(new Set(elems)) : elems;
}
const parent = _singleMatcher(({ parent: parent2 }) => parent2 && !isDocument(parent2) ? parent2 : null, _removeDuplicates);
const parents = _matcher((elem) => {
const matched = [];
while (elem.parent && !isDocument(elem.parent)) {
matched.push(elem.parent);
elem = elem.parent;
}
return matched;
}, uniqueSort, (elems) => elems.reverse());
const parentsUntil = _matchUntil(({ parent: parent2 }) => parent2 && !isDocument(parent2) ? parent2 : null, uniqueSort, (elems) => elems.reverse());
function closest(selector) {
var _a2;
const set = [];
if (!selector) {
return this._make(set);
}
const selectOpts = {
xmlMode: this.options.xmlMode,
root: (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0]
};
const selectFn = typeof selector === "string" ? (elem) => is$1(elem, selector, selectOpts) : getFilterFn(selector);
domEach(this, (elem) => {
if (elem && !isDocument(elem) && !isTag(elem)) {
elem = elem.parent;
}
while (elem && isTag(elem)) {
if (selectFn(elem, 0)) {
if (!set.includes(elem)) {
set.push(elem);
}
break;
}
elem = elem.parent;
}
});
return this._make(set);
}
const next = _singleMatcher((elem) => nextElementSibling(elem));
const nextAll = _matcher((elem) => {
const matched = [];
while (elem.next) {
elem = elem.next;
if (isTag(elem))
matched.push(elem);
}
return matched;
}, _removeDuplicates);
const nextUntil = _matchUntil((el) => nextElementSibling(el), _removeDuplicates);
const prev = _singleMatcher((elem) => prevElementSibling(elem));
const prevAll = _matcher((elem) => {
const matched = [];
while (elem.prev) {
elem = elem.prev;
if (isTag(elem))
matched.push(elem);
}
return matched;
}, _removeDuplicates);
const prevUntil = _matchUntil((el) => prevElementSibling(el), _removeDuplicates);
const siblings = _matcher((elem) => getSiblings(elem).filter((el) => isTag(el) && el !== elem), uniqueSort);
const children = _matcher((elem) => getChildren(elem).filter(isTag), _removeDuplicates);
function contents() {
const elems = this.toArray().reduce((newElems, elem) => hasChildren(elem) ? newElems.concat(elem.children) : newElems, []);
return this._make(elems);
}
function each(fn) {
let i = 0;
const len = this.length;
while (i < len && fn.call(this[i], i, this[i]) !== false)
++i;
return this;
}
function map(fn) {
let elems = [];
for (let i = 0; i < this.length; i++) {
const el = this[i];
const val2 = fn.call(el, i, el);
if (val2 != null) {
elems = elems.concat(val2);
}
}
return this._make(elems);
}
function getFilterFn(match) {
if (typeof match === "function") {
return (el, i) => match.call(el, i, el);
}
if (isCheerio(match)) {
return (el) => Array.prototype.includes.call(match, el);
}
return function(el) {
return match === el;
};
}
function filter(match) {
var _a2;
return this._make(filterArray(this.toArray(), match, this.options.xmlMode, (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0]));
}
function filterArray(nodes, match, xmlMode, root2) {
return typeof match === "string" ? filter$1(match, nodes, { xmlMode, root: root2 }) : nodes.filter(getFilterFn(match));
}
function is(selector) {
const nodes = this.toArray();
return typeof selector === "string" ? some(nodes.filter(isTag), selector, this.options) : selector ? nodes.some(getFilterFn(selector)) : false;
}
function not(match) {
let nodes = this.toArray();
if (typeof match === "string") {
const matches = new Set(filter$1(match, nodes, this.options));
nodes = nodes.filter((el) => !matches.has(el));
} else {
const filterFn = getFilterFn(match);
nodes = nodes.filter((el, i) => !filterFn(el, i));
}
return this._make(nodes);
}
function has(selectorOrHaystack) {
return this.filter(typeof selectorOrHaystack === "string" ? (
// Using the `:has` selector here short-circuits searches.
`:has(${selectorOrHaystack})`
) : (_, el) => this._make(el).find(selectorOrHaystack).length > 0);
}
function first() {
return this.length > 1 ? this._make(this[0]) : this;
}
function last() {
return this.length > 0 ? this._make(this[this.length - 1]) : this;
}
function eq(i) {
var _a2;
i = +i;
if (i === 0 && this.length <= 1)
return this;
if (i < 0)
i = this.length + i;
return this._make((_a2 = this[i]) !== null && _a2 !== void 0 ? _a2 : []);
}
function get(i) {
if (i == null) {
return this.toArray();
}
return this[i < 0 ? this.length + i : i];
}
function toArray() {
return Array.prototype.slice.call(this);
}
function index(selectorOrNeedle) {
let $haystack;
let needle;
if (selectorOrNeedle == null) {
$haystack = this.parent().children();
needle = this[0];
} else if (typeof selectorOrNeedle === "string") {
$haystack = this._make(selectorOrNeedle);
needle = this[0];
} else {
$haystack = this;
needle = isCheerio(selectorOrNeedle) ? selectorOrNeedle[0] : selectorOrNeedle;
}
return Array.prototype.indexOf.call($haystack, needle);
}
function slice(start, end2) {
return this._make(Array.prototype.slice.call(this, start, end2));
}
function end() {
var _a2;
return (_a2 = this.prevObject) !== null && _a2 !== void 0 ? _a2 : this._make([]);
}
function add(other, context) {
const selection = this._make(other, context);
const contents2 = uniqueSort([...this.get(), ...selection.get()]);
return this._make(contents2);
}
function addBack(selector) {
return this.prevObject ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject) : this;
}
const Traversing = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
_findBySelector,
add,
addBack,
children,
closest,
contents,
each,
end,
eq,
filter,
filterArray,
find,
first,
get,
has,
index,
is,
last,
map,
next,
nextAll,
nextUntil,
not,
parent,
parents,
parentsUntil,
prev,
prevAll,
prevUntil,
siblings,
slice,
toArray
}, Symbol.toStringTag, { value: "Module" }));
function getParse(parser) {
return function parse2(content, options, isDocument$1, context) {
if (typeof Buffer !== "undefined" && Buffer.isBuffer(content)) {
content = content.toString();
}
if (typeof content === "string") {
return parser(content, options, isDocument$1, context);
}
const doc = content;
if (!Array.isArray(doc) && isDocument(doc)) {
return doc;
}
const root2 = new Document([]);
update(doc, root2);
return root2;
};
}
function update(newChilds, parent2) {
const arr = Array.isArray(newChilds) ? newChilds : [newChilds];
if (parent2) {
parent2.children = arr;
} else {
parent2 = null;
}
for (let i = 0; i < arr.length; i++) {
const node = arr[i];
if (node.parent && node.parent.children !== arr) {
removeElement(node);
}
if (parent2) {
node.prev = arr[i - 1] || null;
node.next = arr[i + 1] || null;
} else {
node.prev = node.next = null;
}
node.parent = parent2;
}
return parent2;
}
function _makeDomArray(elem, clone2) {
if (elem == null) {
return [];
}
if (typeof elem === "string") {
return this._parse(elem, this.options, false, null).children.slice(0);
}
if ("length" in elem) {
if (elem.length === 1) {
return this._makeDomArray(elem[0], clone2);
}
const result = [];
for (let i = 0; i < elem.length; i++) {
const el = elem[i];
if (typeof el === "object") {
if (el == null) {
continue;
}
if (!("length" in el)) {
result.push(clone2 ? cloneNode(el, true) : el);
continue;
}
}
result.push(...this._makeDomArray(el, clone2));
}
return result;
}
return [clone2 ? cloneNode(elem, true) : elem];
}
function _insert(concatenator) {
return function(...elems) {
const lastIdx = this.length - 1;
return domEach(this, (el, i) => {
if (!hasChildren(el))
return;
const domSrc = typeof elems[0] === "function" ? elems[0].call(el, i, this._render(el.children)) : elems;
const dom = this._makeDomArray(domSrc, i < lastIdx);
concatenator(dom, el.children, el);
});
};
}
function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent2) {
var _a2, _b;
const spliceArgs = [
spliceIdx,
spliceCount,
...newElems
];
const prev2 = spliceIdx === 0 ? null : array[spliceIdx - 1];
const next2 = spliceIdx + spliceCount >= array.length ? null : array[spliceIdx + spliceCount];
for (let idx = 0; idx < newElems.length; ++idx) {
const node = newElems[idx];
const oldParent = node.parent;
if (oldParent) {
const oldSiblings = oldParent.children;
const prevIdx = oldSiblings.indexOf(node);
if (prevIdx > -1) {
oldParent.children.splice(prevIdx, 1);
if (parent2 === oldParent && spliceIdx > prevIdx) {
spliceArgs[0]--;
}
}
}
node.parent = parent2;
if (node.prev) {
node.prev.next = (_a2 = node.next) !== null && _a2 !== void 0 ? _a2 : null;
}
if (node.next) {
node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null;
}
node.prev = idx === 0 ? prev2 : newElems[idx - 1];
node.next = idx === newElems.length - 1 ? next2 : newElems[idx + 1];
}
if (prev2) {
prev2.next = newElems[0];
}
if (next2) {
next2.prev = newElems[newElems.length - 1];
}
return array.splice(...spliceArgs);
}
function appendTo(target) {
const appendTarget = isCheerio(target) ? target : this._make(target);
appendTarget.append(this);
return this;
}
function prependTo(target) {
const prependTarget = isCheerio(target) ? target : this._make(target);
prependTarget.prepend(this);
return this;
}
const append = _insert((dom, children2, parent2) => {
uniqueSplice(children2, children2.length, 0, dom, parent2);
});
const prepend = _insert((dom, children2, parent2) => {
uniqueSplice(children2, 0, 0, dom, parent2);
});
function _wrap(insert) {
return function(wrapper) {
const lastIdx = this.length - 1;
const lastParent = this.parents().last();
for (let i = 0; i < this.length; i++) {
const el = this[i];
const wrap2 = typeof wrapper === "function" ? wrapper.call(el, i, el) : typeof wrapper === "string" && !isHtml(wrapper) ? lastParent.find(wrapper).clone() : wrapper;
const [wrapperDom] = this._makeDomArray(wrap2, i < lastIdx);
if (!wrapperDom || !hasChildren(wrapperDom))
continue;
let elInsertLocation = wrapperDom;
let j = 0;
while (j < elInsertLocation.children.length) {
const child = elInsertLocation.children[j];
if (isTag(child)) {
elInsertLocation = child;
j = 0;
} else {
j++;
}
}
insert(el, elInsertLocation, [wrapperDom]);
}
return this;
};
}
const wrap = _wrap((el, elInsertLocation, wrapperDom) => {
const { parent: parent2 } = el;
if (!parent2)
return;
const siblings2 = parent2.children;
const index2 = siblings2.indexOf(el);
update([el], elInsertLocation);
uniqueSplice(siblings2, index2, 0, wrapperDom, parent2);
});
const wrapInner = _wrap((el, elInsertLocation, wrapperDom) => {
if (!hasChildren(el))
return;
update(el.children, elInsertLocation);
update(wrapperDom, el);
});
function unwrap(selector) {
this.parent(selector).not("body").each((_, el) => {
this._make(el).replaceWith(el.children);
});
return this;
}
function wrapAll(wrapper) {
const el = this[0];
if (el) {
const wrap2 = this._make(typeof wrapper === "function" ? wrapper.call(el, 0, el) : wrapper).insertBefore(el);
let elInsertLocation;
for (let i = 0; i < wrap2.length; i++) {
if (wrap2[i].type === "tag")
elInsertLocation = wrap2[i];
}
let j = 0;
while (elInsertLocation && j < elInsertLocation.children.length) {
const child = elInsertLocation.children[j];
if (child.type === "tag") {
elInsertLocation = child;
j = 0;
} else {
j++;
}
}
if (elInsertLocation)
this._make(elInsertLocation).append(this);
}
return this;
}
function after(...elems) {
const lastIdx = this.length - 1;
return domEach(this, (el, i) => {
if (!hasChildren(el) || !el.parent) {
return;
}
const siblings2 = el.parent.children;
const index2 = siblings2.indexOf(el);
if (index2 < 0)
return;
const domSrc = typeof elems[0] === "function" ? elems[0].call(el, i, this._render(el.children)) : elems;
const dom = this._makeDomArray(domSrc, i < lastIdx);
uniqueSplice(siblings2, index2 + 1, 0, dom, el.parent);
});
}
function insertAfter(target) {
if (typeof target === "string") {
target = this._make(target);
}
this.remove();
const clones = [];
for (const el of this._makeDomArray(target)) {
const clonedSelf = this.clone().toArray();
const { parent: parent2 } = el;
if (!parent2) {
continue;
}
const siblings2 = parent2.children;
const index2 = siblings2.indexOf(el);
if (index2 < 0)
continue;
uniqueSplice(siblings2, index2 + 1, 0, clonedSelf, parent2);
clones.push(...clonedSelf);
}
return this._make(clones);
}
function before(...elems) {
const lastIdx = this.length - 1;
return domEach(this, (el, i) => {
if (!hasChildren(el) || !el.parent) {
return;
}
const siblings2 = el.parent.children;
const index2 = siblings2.indexOf(el);
if (index2 < 0)
return;
const domSrc = typeof elems[0] === "function" ? elems[0].call(el, i, this._render(el.children)) : elems;
const dom = this._makeDomArray(domSrc, i < lastIdx);
uniqueSplice(siblings2, index2, 0, dom, el.parent);
});
}
function insertBefore(target) {
const targetArr = this._make(target);
this.remove();
const clones = [];
domEach(targetArr, (el) => {
const clonedSelf = this.clone().toArray();
const { parent: parent2 } = el;
if (!parent2) {
return;
}
const siblings2 = parent2.children;
const index2 = siblings2.indexOf(el);
if (index2 < 0)
return;
uniqueSplice(siblings2, index2, 0, clonedSelf, parent2);
clones.push(...clonedSelf);
});
return this._make(clones);
}
function remove(selector) {
const elems = selector ? this.filter(selector) : this;
domEach(elems, (el) => {
removeElement(el);
el.prev = el.next = el.parent = null;
});
return this;
}
function replaceWith(content) {
return domEach(this, (el, i) => {
const { parent: parent2 } = el;
if (!parent2) {
return;
}
const siblings2 = parent2.children;
const cont = typeof content === "function" ? content.call(el, i, el) : content;
const dom = this._makeDomArray(cont);
update(dom, null);
const index2 = siblings2.indexOf(el);
uniqueSplice(siblings2, index2, 1, dom, parent2);
if (!dom.includes(el)) {
el.parent = el.prev = el.next = null;
}
});
}
function empty() {
return domEach(this, (el) => {
if (!hasChildren(el))
return;
for (const child of el.children) {
child.next = child.prev = child.parent = null;
}
el.children.length = 0;
});
}
function html(str) {
if (str === void 0) {
const el = this[0];
if (!el || !hasChildren(el))
return null;
return this._render(el.children);
}
return domEach(this, (el) => {
if (!hasChildren(el))
return;
for (const child of el.children) {
child.next = child.prev = child.parent = null;
}
const content = isCheerio(str) ? str.toArray() : this._parse(`${str}`, this.options, false, el).children;
update(content, el);
});
}
function toString() {
return this._render(this);
}
function text(str) {
if (str === void 0) {
return text$1(this);
}
if (typeof str === "function") {
return domEach(this, (el, i) => this._make(el).text(str.call(el, i, text$1([el]))));
}
return domEach(this, (el) => {
if (!hasChildren(el))
return;
for (const child of el.children) {
child.next = child.prev = child.parent = null;
}
const textNode = new Text(`${str}`);
update(textNode, el);
});
}
function clone() {
const clone2 = Array.prototype.map.call(this.get(), (el) => cloneNode(el, true));
const root2 = new Document(clone2);
for (const node of clone2) {
node.parent = root2;
}
return this._make(clone2);
}
const Manipulation = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
_makeDomArray,
after,
append,
appendTo,
before,
clone,
empty,
html,
insertAfter,
insertBefore,
prepend,
prependTo,
remove,
replaceWith,
text,
toString,
unwrap,
wrap,
wrapAll,
wrapInner
}, Symbol.toStringTag, { value: "Module" }));
function css(prop2, val2) {
if (prop2 != null && val2 != null || // When `prop` is a "plain" object
typeof prop2 === "object" && !Array.isArray(prop2)) {
return domEach(this, (el, i) => {
if (isTag(el)) {
setCss(el, prop2, val2, i);
}
});
}
if (this.length === 0) {
return void 0;
}
return getCss(this[0], prop2);
}
function setCss(el, prop2, value, idx) {
if (typeof prop2 === "string") {
const styles = getCss(el);
const val2 = typeof value === "function" ? value.call(el, idx, styles[prop2]) : value;
if (val2 === "") {
delete styles[prop2];
} else if (val2 != null) {
styles[prop2] = val2;
}
el.attribs["style"] = stringify(styles);
} else if (typeof prop2 === "object") {
const keys = Object.keys(prop2);
for (let i = 0; i < keys.length; i++) {
const k = keys[i];
setCss(el, k, prop2[k], i);
}
}
}
function getCss(el, prop2) {
if (!el || !isTag(el))
return;
const styles = parse(el.attribs["style"]);
if (typeof prop2 === "string") {
return styles[prop2];
}
if (Array.isArray(prop2)) {
const newStyles = {};
for (const item of prop2) {
if (styles[item] != null) {
newStyles[item] = styles[item];
}
}
return newStyles;
}
return styles;
}
function stringify(obj) {
return Object.keys(obj).reduce((str, prop2) => `${str}${str ? " " : ""}${prop2}: ${obj[prop2]};`, "");
}
function parse(styles) {
styles = (styles || "").trim();
if (!styles)
return {};
const obj = {};
let key;
for (const str of styles.split(";")) {
const n = str.indexOf(":");
if (n < 1 || n === str.length - 1) {
const trimmed = str.trimEnd();
if (trimmed.length > 0 && key !== void 0) {
obj[key] += `;${trimmed}`;
}
} else {
key = str.slice(0, n).trim();
obj[key] = str.slice(n + 1).trim();
}
}
return obj;
}
const Css = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
css
}, Symbol.toStringTag, { value: "Module" }));
const submittableSelector = "input,select,textarea,keygen";
const r20 = /%20/g;
const rCRLF = /\r?\n/g;
function serialize() {
const arr = this.serializeArray();
const retArr = arr.map((data2) => `${encodeURIComponent(data2.name)}=${encodeURIComponent(data2.value)}`);
return retArr.join("&").replace(r20, "+");
}
function serializeArray() {
return this.map((_, elem) => {
const $elem = this._make(elem);
if (isTag(elem) && elem.name === "form") {
return $elem.find(submittableSelector).toArray();
}
return $elem.filter(submittableSelector).toArray();
}).filter(
// Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
'[name!=""]:enabled:not(:submit, :button, :image, :reset, :file):matches([checked], :not(:checkbox, :radio))'
).map((_, elem) => {
var _a2;
const $elem = this._make(elem);
const name = $elem.attr("name");
const value = (_a2 = $elem.val()) !== null && _a2 !== void 0 ? _a2 : "";
if (Array.isArray(value)) {
return value.map((val2) => (
/*
* We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms
* These can occur inside of `<textarea>'s`
*/
{ name, value: val2.replace(rCRLF, "\r\n") }
));
}
return { name, value: value.replace(rCRLF, "\r\n") };
}).toArray();
}
const Forms = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
serialize,
serializeArray
}, Symbol.toStringTag, { value: "Module" }));
function getExtractDescr(descr) {
var _a2;
if (typeof descr === "string") {
return { selector: descr, value: "textContent" };
}
return {
selector: descr.selector,
value: (_a2 = descr.value) !== null && _a2 !== void 0 ? _a2 : "textContent"
};
}
function extract(map2) {
const ret = {};
for (const key in map2) {
const descr = map2[key];
const isArray = Array.isArray(descr);
const { selector, value } = getExtractDescr(isArray ? descr[0] : descr);
const fn = typeof value === "function" ? value : typeof value === "string" ? (el) => this._make(el).prop(value) : (el) => this._make(el).extract(value);
if (isArray) {
ret[key] = this._findBySelector(selector, Number.POSITIVE_INFINITY).map((_, el) => fn(el, key, ret)).get();
} else {
const $ = this._findBySelector(selector, 1);
ret[key] = $.length > 0 ? fn($[0], key, ret) : void 0;
}
}
return ret;
}
const Extract = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
extract
}, Symbol.toStringTag, { value: "Module" }));
class Cheerio {
/**
* Instance of cheerio. Methods are specified in the modules. Usage of this
* constructor is not recommended. Please use `$.load` instead.
*
* @private
* @param elements - The new selection.
* @param root - Sets the root node.
* @param options - Options for the instance.
*/
constructor(elements, root2, options) {
this.length = 0;
this.options = options;
this._root = root2;
if (elements) {
for (let idx = 0; idx < elements.length; idx++) {
this[idx] = elements[idx];
}
this.length = elements.length;
}
}
}
Cheerio.prototype.cheerio = "[cheerio object]";
Cheerio.prototype.splice = Array.prototype.splice;
Cheerio.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Object.assign(Cheerio.prototype, Attributes, Traversing, Manipulation, Css, Forms, Extract);
function getLoad(parse2, render2) {
return function load2(content, options, isDocument2 = true) {
if (content == null) {
throw new Error("cheerio.load() expects a string");
}
const internalOpts = flattenOptions(options);
const initialRoot = parse2(content, internalOpts, isDocument2, null);
class LoadedCheerio extends Cheerio {
_make(selector, context) {
const cheerio = initialize(selector, context);
cheerio.prevObject = this;
return cheerio;
}
_parse(content2, options2, isDocument3, context) {
return parse2(content2, options2, isDocument3, context);
}
_render(dom) {
return render2(dom, this.options);
}
}
function initialize(selector, context, root2 = initialRoot, opts) {
if (selector && isCheerio(selector))
return selector;
const options2 = flattenOptions(opts, internalOpts);
const r = typeof root2 === "string" ? [parse2(root2, options2, false, null)] : "length" in root2 ? root2 : [root2];
const rootInstance = isCheerio(r) ? r : new LoadedCheerio(r, null, options2);
rootInstance._root = rootInstance;
if (!selector) {
return new LoadedCheerio(void 0, rootInstance, options2);
}
const elements = typeof selector === "string" && isHtml(selector) ? (
// $(<html>)
parse2(selector, options2, false, null).children
) : isNode(selector) ? (
// $(dom)
[selector]
) : Array.isArray(selector) ? (
// $([dom])
selector
) : void 0;
const instance = new LoadedCheerio(elements, rootInstance, options2);
if (elements) {
return instance;
}
if (typeof selector !== "string") {
throw new TypeError("Unexpected type of selector");
}
let search = selector;
const searchContext = context ? (
// If we don't have a context, maybe we have a root, from loading
typeof context === "string" ? isHtml(context) ? (
// $('li', '<ul>...</ul>')
new LoadedCheerio([parse2(context, options2, false, null)], rootInstance, options2)
) : (
// $('li', 'ul')
(search = `${context} ${search}`, rootInstance)
) : isCheerio(context) ? (
// $('li', $)
context
) : (
// $('li', node), $('li', [nodes])
new LoadedCheerio(Array.isArray(context) ? context : [context], rootInstance, options2)
)
) : rootInstance;
if (!searchContext)
return instance;
return searchContext.find(search);
}
Object.assign(initialize, staticMethods, {
load: load2,
// `_root` and `_options` are used in static methods.
_root: initialRoot,
_options: internalOpts,
// Add `fn` for plugins
fn: LoadedCheerio.prototype,
// Add the prototype here to maintain `instanceof` behavior.
prototype: LoadedCheerio.prototype
});
return initialize;
};
}
function isNode(obj) {
return !!obj.name || obj.type === "root" || obj.type === "text" || obj.type === "comment";
}
var CharCodes;
(function(CharCodes2) {
CharCodes2[CharCodes2["Tab"] = 9] = "Tab";
CharCodes2[CharCodes2["NewLine"] = 10] = "NewLine";
CharCodes2[CharCodes2["FormFeed"] = 12] = "FormFeed";
CharCodes2[CharCodes2["CarriageReturn"] = 13] = "CarriageReturn";
CharCodes2[CharCodes2["Space"] = 32] = "Space";
CharCodes2[CharCodes2["ExclamationMark"] = 33] = "ExclamationMark";
CharCodes2[CharCodes2["Number"] = 35] = "Number";
CharCodes2[CharCodes2["Amp"] = 38] = "Amp";
CharCodes2[CharCodes2["SingleQuote"] = 39] = "SingleQuote";
CharCodes2[CharCodes2["DoubleQuote"] = 34] = "DoubleQuote";
CharCodes2[CharCodes2["Dash"] = 45] = "Dash";
CharCodes2[CharCodes2["Slash"] = 47] = "Slash";
CharCodes2[CharCodes2["Zero"] = 48] = "Zero";
CharCodes2[CharCodes2["Nine"] = 57] = "Nine";
CharCodes2[CharCodes2["Semi"] = 59] = "Semi";
CharCodes2[CharCodes2["Lt"] = 60] = "Lt";
CharCodes2[CharCodes2["Eq"] = 61] = "Eq";
CharCodes2[CharCodes2["Gt"] = 62] = "Gt";
CharCodes2[CharCodes2["Questionmark"] = 63] = "Questionmark";
CharCodes2[CharCodes2["UpperA"] = 65] = "UpperA";
CharCodes2[CharCodes2["LowerA"] = 97] = "LowerA";
CharCodes2[CharCodes2["UpperF"] = 70] = "UpperF";
CharCodes2[CharCodes2["LowerF"] = 102] = "LowerF";
CharCodes2[CharCodes2["UpperZ"] = 90] = "UpperZ";
CharCodes2[CharCodes2["LowerZ"] = 122] = "LowerZ";
CharCodes2[CharCodes2["LowerX"] = 120] = "LowerX";
CharCodes2[CharCodes2["OpeningSquareBracket"] = 91] = "OpeningSquareBracket";
})(CharCodes || (CharCodes = {}));
var State;
(function(State2) {
State2[State2["Text"] = 1] = "Text";
State2[State2["BeforeTagName"] = 2] = "BeforeTagName";
State2[State2["InTagName"] = 3] = "InTagName";
State2[State2["InSelfClosingTag"] = 4] = "InSelfClosingTag";
State2[State2["BeforeClosingTagName"] = 5] = "BeforeClosingTagName";
State2[State2["InClosingTagName"] = 6] = "InClosingTagName";
State2[State2["AfterClosingTagName"] = 7] = "AfterClosingTagName";
State2[State2["BeforeAttributeName"] = 8] = "BeforeAttributeName";
State2[State2["InAttributeName"] = 9] = "InAttributeName";
State2[State2["AfterAttributeName"] = 10] = "AfterAttributeName";
State2[State2["BeforeAttributeValue"] = 11] = "BeforeAttributeValue";
State2[State2["InAttributeValueDq"] = 12] = "InAttributeValueDq";
State2[State2["InAttributeValueSq"] = 13] = "InAttributeValueSq";
State2[State2["InAttributeValueNq"] = 14] = "InAttributeValueNq";
State2[State2["BeforeDeclaration"] = 15] = "BeforeDeclaration";
State2[State2["InDeclaration"] = 16] = "InDeclaration";
State2[State2["InProcessingInstruction"] = 17] = "InProcessingInstruction";
State2[State2["BeforeComment"] = 18] = "BeforeComment";
State2[State2["CDATASequence"] = 19] = "CDATASequence";
State2[State2["InSpecialComment"] = 20] = "InSpecialComment";
State2[State2["InCommentLike"] = 21] = "InCommentLike";
State2[State2["BeforeSpecialS"] = 22] = "BeforeSpecialS";
State2[State2["BeforeSpecialT"] = 23] = "BeforeSpecialT";
State2[State2["SpecialStartSequence"] = 24] = "SpecialStartSequence";
State2[State2["InSpecialTag"] = 25] = "InSpecialTag";
State2[State2["InEntity"] = 26] = "InEntity";
})(State || (State = {}));
function isWhitespace(c) {
return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn;
}
function isEndOfTagSection(c) {
return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);
}
function isASCIIAlpha(c) {
return c >= CharCodes.LowerA && c <= CharCodes.LowerZ || c >= CharCodes.UpperA && c <= CharCodes.UpperZ;
}
var QuoteType;
(function(QuoteType2) {
QuoteType2[QuoteType2["NoValue"] = 0] = "NoValue";
QuoteType2[QuoteType2["Unquoted"] = 1] = "Unquoted";
QuoteType2[QuoteType2["Single"] = 2] = "Single";
QuoteType2[QuoteType2["Double"] = 3] = "Double";
})(QuoteType || (QuoteType = {}));
const Sequences = {
Cdata: new Uint8Array([67, 68, 65, 84, 65, 91]),
// CDATA[
CdataEnd: new Uint8Array([93, 93, 62]),
// ]]>
CommentEnd: new Uint8Array([45, 45, 62]),
// `-->`
ScriptEnd: new Uint8Array([60, 47, 115, 99, 114, 105, 112, 116]),
// `<\/script`
StyleEnd: new Uint8Array([60, 47, 115, 116, 121, 108, 101]),
// `</style`
TitleEnd: new Uint8Array([60, 47, 116, 105, 116, 108, 101]),
// `</title`
TextareaEnd: new Uint8Array([
60,
47,
116,
101,
120,
116,
97,
114,
101,
97
])
// `</textarea`
};
class Tokenizer {
constructor({ xmlMode = false, decodeEntities = true }, cbs) {
this.cbs = cbs;
this.state = State.Text;
this.buffer = "";
this.sectionStart = 0;
this.index = 0;
this.entityStart = 0;
this.baseState = State.Text;
this.isSpecial = false;
this.running = true;
this.offset = 0;
this.currentSequence = void 0;
this.sequenceIndex = 0;
this.xmlMode = xmlMode;
this.decodeEntities = decodeEntities;
this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));
}
reset() {
this.state = State.Text;
this.buffer = "";
this.sectionStart = 0;
this.index = 0;
this.baseState = State.Text;
this.currentSequence = void 0;
this.running = true;
this.offset = 0;
}
write(chunk) {
this.offset += this.buffer.length;
this.buffer = chunk;
this.parse();
}
end() {
if (this.running)
this.finish();
}
pause() {
this.running = false;
}
resume() {
this.running = true;
if (this.index < this.buffer.length + this.offset) {
this.parse();
}
}
stateText(c) {
if (c === CharCodes.Lt || !this.decodeEntities && this.fastForwardTo(CharCodes.Lt)) {
if (this.index > this.sectionStart) {
this.cbs.ontext(this.sectionStart, this.index);
}
this.state = State.BeforeTagName;
this.sectionStart = this.index;
} else if (this.decodeEntities && c === CharCodes.Amp) {
this.startEntity();
}
}
stateSpecialStartSequence(c) {
const isEnd = this.sequenceIndex === this.currentSequence.length;
const isMatch = isEnd ? (
// If we are at the end of the sequence, make sure the tag name has ended
isEndOfTagSection(c)
) : (
// Otherwise, do a case-insensitive comparison
(c | 32) === this.currentSequence[this.sequenceIndex]
);
if (!isMatch) {
this.isSpecial = false;
} else if (!isEnd) {
this.sequenceIndex++;
return;
}
this.sequenceIndex = 0;
this.state = State.InTagName;
this.stateInTagName(c);
}
/** Look for an end tag. For <title> tags, also decode entities. */
stateInSpecialTag(c) {
if (this.sequenceIndex === this.currentSequence.length) {
if (c === CharCodes.Gt || isWhitespace(c)) {
const endOfText = this.index - this.currentSequence.length;
if (this.sectionStart < endOfText) {
const actualIndex = this.index;
this.index = endOfText;
this.cbs.ontext(this.sectionStart, endOfText);
this.index = actualIndex;
}
this.isSpecial = false;
this.sectionStart = endOfText + 2;
this.stateInClosingTagName(c);
return;
}
this.sequenceIndex = 0;
}
if ((c | 32) === this.currentSequence[this.sequenceIndex]) {
this.sequenceIndex += 1;
} else if (this.sequenceIndex === 0) {
if (this.currentSequence === Sequences.TitleEnd) {
if (this.decodeEntities && c === CharCodes.Amp) {
this.startEntity();
}
} else if (this.fastForwardTo(CharCodes.Lt)) {
this.sequenceIndex = 1;
}
} else {
this.sequenceIndex = Number(c === CharCodes.Lt);
}
}
stateCDATASequence(c) {
if (c === Sequences.Cdata[this.sequenceIndex]) {
if (++this.sequenceIndex === Sequences.Cdata.length) {
this.state = State.InCommentLike;
this.currentSequence = Sequences.CdataEnd;
this.sequenceIndex = 0;
this.sectionStart = this.index + 1;
}
} else {
this.sequenceIndex = 0;
this.state = State.InDeclaration;
this.stateInDeclaration(c);
}
}
/**
* When we wait for one specific character, we can speed things up
* by skipping through the buffer until we find it.
*
* @returns Whether the character was found.
*/
fastForwardTo(c) {
while (++this.index < this.buffer.length + this.offset) {
if (this.buffer.charCodeAt(this.index - this.offset) === c) {
return true;
}
}
this.index = this.buffer.length + this.offset - 1;
return false;
}
/**
* Comments and CDATA end with `-->` and `]]>`.
*
* Their common qualities are:
* - Their end sequences have a distinct character they start with.
* - That character is then repeated, so we have to check multiple repeats.
* - All characters but the start character of the sequence can be skipped.
*/
stateInCommentLike(c) {
if (c === this.currentSequence[this.sequenceIndex]) {
if (++this.sequenceIndex === this.currentSequence.length) {
if (this.currentSequence === Sequences.CdataEnd) {
this.cbs.oncdata(this.sectionStart, this.index, 2);
} else {
this.cbs.oncomment(this.sectionStart, this.index, 2);
}
this.sequenceIndex = 0;
this.sectionStart = this.index + 1;
this.state = State.Text;
}
} else if (this.sequenceIndex === 0) {
if (this.fastForwardTo(this.currentSequence[0])) {
this.sequenceIndex = 1;
}
} else if (c !== this.currentSequence[this.sequenceIndex - 1]) {
this.sequenceIndex = 0;
}
}
/**
* HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
*
* XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
* We allow anything that wouldn't end the tag.
*/
isTagStartChar(c) {
return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
}
startSpecial(sequence, offset) {
this.isSpecial = true;
this.currentSequence = sequence;
this.sequenceIndex = offset;
this.state = State.SpecialStartSequence;
}
stateBeforeTagName(c) {
if (c === CharCodes.ExclamationMark) {
this.state = State.BeforeDeclaration;
this.sectionStart = this.index + 1;
} else if (c === CharCodes.Questionmark) {
this.state = State.InProcessingInstruction;
this.sectionStart = this.index + 1;
} else if (this.isTagStartChar(c)) {
const lower = c | 32;
this.sectionStart = this.index;
if (this.xmlMode) {
this.state = State.InTagName;
} else if (lower === Sequences.ScriptEnd[2]) {
this.state = State.BeforeSpecialS;
} else if (lower === Sequences.TitleEnd[2]) {
this.state = State.BeforeSpecialT;
} else {
this.state = State.InTagName;
}
} else if (c === CharCodes.Slash) {
this.state = State.BeforeClosingTagName;
} else {
this.state = State.Text;
this.stateText(c);
}
}
stateInTagName(c) {
if (isEndOfTagSection(c)) {
this.cbs.onopentagname(this.sectionStart, this.index);
this.sectionStart = -1;
this.state = State.BeforeAttributeName;
this.stateBeforeAttributeName(c);
}
}
stateBeforeClosingTagName(c) {
if (isWhitespace(c)) ;
else if (c === CharCodes.Gt) {
this.state = State.Text;
} else {
this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment;
this.sectionStart = this.index;
}
}
stateInClosingTagName(c) {
if (c === CharCodes.Gt || isWhitespace(c)) {
this.cbs.onclosetag(this.sectionStart, this.index);
this.sectionStart = -1;
this.state = State.AfterClosingTagName;
this.stateAfterClosingTagName(c);
}
}
stateAfterClosingTagName(c) {
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
this.state = State.Text;
this.sectionStart = this.index + 1;
}
}
stateBeforeAttributeName(c) {
if (c === CharCodes.Gt) {
this.cbs.onopentagend(this.index);
if (this.isSpecial) {
this.state = State.InSpecialTag;
this.sequenceIndex = 0;
} else {
this.state = State.Text;
}
this.sectionStart = this.index + 1;
} else if (c === CharCodes.Slash) {
this.state = State.InSelfClosingTag;
} else if (!isWhitespace(c)) {
this.state = State.InAttributeName;
this.sectionStart = this.index;
}
}
stateInSelfClosingTag(c) {
if (c === CharCodes.Gt) {
this.cbs.onselfclosingtag(this.index);
this.state = State.Text;
this.sectionStart = this.index + 1;
this.isSpecial = false;
} else if (!isWhitespace(c)) {
this.state = State.BeforeAttributeName;
this.stateBeforeAttributeName(c);
}
}
stateInAttributeName(c) {
if (c === CharCodes.Eq || isEndOfTagSection(c)) {
this.cbs.onattribname(this.sectionStart, this.index);
this.sectionStart = this.index;
this.state = State.AfterAttributeName;
this.stateAfterAttributeName(c);
}
}
stateAfterAttributeName(c) {
if (c === CharCodes.Eq) {
this.state = State.BeforeAttributeValue;
} else if (c === CharCodes.Slash || c === CharCodes.Gt) {
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
this.sectionStart = -1;
this.state = State.BeforeAttributeName;
this.stateBeforeAttributeName(c);
} else if (!isWhitespace(c)) {
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
this.state = State.InAttributeName;
this.sectionStart = this.index;
}
}
stateBeforeAttributeValue(c) {
if (c === CharCodes.DoubleQuote) {
this.state = State.InAttributeValueDq;
this.sectionStart = this.index + 1;
} else if (c === CharCodes.SingleQuote) {
this.state = State.InAttributeValueSq;
this.sectionStart = this.index + 1;
} else if (!isWhitespace(c)) {
this.sectionStart = this.index;
this.state = State.InAttributeValueNq;
this.stateInAttributeValueNoQuotes(c);
}
}
handleInAttributeValue(c, quote) {
if (c === quote || !this.decodeEntities && this.fastForwardTo(quote)) {
this.cbs.onattribdata(this.sectionStart, this.index);
this.sectionStart = -1;
this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1);
this.state = State.BeforeAttributeName;
} else if (this.decodeEntities && c === CharCodes.Amp) {
this.startEntity();
}
}
stateInAttributeValueDoubleQuotes(c) {
this.handleInAttributeValue(c, CharCodes.DoubleQuote);
}
stateInAttributeValueSingleQuotes(c) {
this.handleInAttributeValue(c, CharCodes.SingleQuote);
}
stateInAttributeValueNoQuotes(c) {
if (isWhitespace(c) || c === CharCodes.Gt) {
this.cbs.onattribdata(this.sectionStart, this.index);
this.sectionStart = -1;
this.cbs.onattribend(QuoteType.Unquoted, this.index);
this.state = State.BeforeAttributeName;
this.stateBeforeAttributeName(c);
} else if (this.decodeEntities && c === CharCodes.Amp) {
this.startEntity();
}
}
stateBeforeDeclaration(c) {
if (c === CharCodes.OpeningSquareBracket) {
this.state = State.CDATASequence;
this.sequenceIndex = 0;
} else {
this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration;
}
}
stateInDeclaration(c) {
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
this.cbs.ondeclaration(this.sectionStart, this.index);
this.state = State.Text;
this.sectionStart = this.index + 1;
}
}
stateInProcessingInstruction(c) {
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
this.cbs.onprocessinginstruction(this.sectionStart, this.index);
this.state = State.Text;
this.sectionStart = this.index + 1;
}
}
stateBeforeComment(c) {
if (c === CharCodes.Dash) {
this.state = State.InCommentLike;
this.currentSequence = Sequences.CommentEnd;
this.sequenceIndex = 2;
this.sectionStart = this.index + 1;
} else {
this.state = State.InDeclaration;
}
}
stateInSpecialComment(c) {
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
this.cbs.oncomment(this.sectionStart, this.index, 0);
this.state = State.Text;
this.sectionStart = this.index + 1;
}
}
stateBeforeSpecialS(c) {
const lower = c | 32;
if (lower === Sequences.ScriptEnd[3]) {
this.startSpecial(Sequences.ScriptEnd, 4);
} else if (lower === Sequences.StyleEnd[3]) {
this.startSpecial(Sequences.StyleEnd, 4);
} else {
this.state = State.InTagName;
this.stateInTagName(c);
}
}
stateBeforeSpecialT(c) {
const lower = c | 32;
if (lower === Sequences.TitleEnd[3]) {
this.startSpecial(Sequences.TitleEnd, 4);
} else if (lower === Sequences.TextareaEnd[3]) {
this.startSpecial(Sequences.TextareaEnd, 4);
} else {
this.state = State.InTagName;
this.stateInTagName(c);
}
}
startEntity() {
this.baseState = this.state;
this.state = State.InEntity;
this.entityStart = this.index;
this.entityDecoder.startEntity(this.xmlMode ? DecodingMode.Strict : this.baseState === State.Text || this.baseState === State.InSpecialTag ? DecodingMode.Legacy : DecodingMode.Attribute);
}
stateInEntity() {
const length = this.entityDecoder.write(this.buffer, this.index - this.offset);
if (length >= 0) {
this.state = this.baseState;
if (length === 0) {
this.index = this.entityStart;
}
} else {
this.index = this.offset + this.buffer.length - 1;
}
}
/**
* Remove data that has already been consumed from the buffer.
*/
cleanup() {
if (this.running && this.sectionStart !== this.index) {
if (this.state === State.Text || this.state === State.InSpecialTag && this.sequenceIndex === 0) {
this.cbs.ontext(this.sectionStart, this.index);
this.sectionStart = this.index;
} else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) {
this.cbs.onattribdata(this.sectionStart, this.index);
this.sectionStart = this.index;
}
}
}
shouldContinue() {
return this.index < this.buffer.length + this.offset && this.running;
}
/**
* Iterates through the buffer, calling the function corresponding to the current state.
*
* States that are more likely to be hit are higher up, as a performance improvement.
*/
parse() {
while (this.shouldContinue()) {
const c = this.buffer.charCodeAt(this.index - this.offset);
switch (this.state) {
case State.Text: {
this.stateText(c);
break;
}
case State.SpecialStartSequence: {
this.stateSpecialStartSequence(c);
break;
}
case State.InSpecialTag: {
this.stateInSpecialTag(c);
break;
}
case State.CDATASequence: {
this.stateCDATASequence(c);
break;
}
case State.InAttributeValueDq: {
this.stateInAttributeValueDoubleQuotes(c);
break;
}
case State.InAttributeName: {
this.stateInAttributeName(c);
break;
}
case State.InCommentLike: {
this.stateInCommentLike(c);
break;
}
case State.InSpecialComment: {
this.stateInSpecialComment(c);
break;
}
case State.BeforeAttributeName: {
this.stateBeforeAttributeName(c);
break;
}
case State.InTagName: {
this.stateInTagName(c);
break;
}
case State.InClosingTagName: {
this.stateInClosingTagName(c);
break;
}
case State.BeforeTagName: {
this.stateBeforeTagName(c);
break;
}
case State.AfterAttributeName: {
this.stateAfterAttributeName(c);
break;
}
case State.InAttributeValueSq: {
this.stateInAttributeValueSingleQuotes(c);
break;
}
case State.BeforeAttributeValue: {
this.stateBeforeAttributeValue(c);
break;
}
case State.BeforeClosingTagName: {
this.stateBeforeClosingTagName(c);
break;
}
case State.AfterClosingTagName: {
this.stateAfterClosingTagName(c);
break;
}
case State.BeforeSpecialS: {
this.stateBeforeSpecialS(c);
break;
}
case State.BeforeSpecialT: {
this.stateBeforeSpecialT(c);
break;
}
case State.InAttributeValueNq: {
this.stateInAttributeValueNoQuotes(c);
break;
}
case State.InSelfClosingTag: {
this.stateInSelfClosingTag(c);
break;
}
case State.InDeclaration: {
this.stateInDeclaration(c);
break;
}
case State.BeforeDeclaration: {
this.stateBeforeDeclaration(c);
break;
}
case State.BeforeComment: {
this.stateBeforeComment(c);
break;
}
case State.InProcessingInstruction: {
this.stateInProcessingInstruction(c);
break;
}
case State.InEntity: {
this.stateInEntity();
break;
}
}
this.index++;
}
this.cleanup();
}
finish() {
if (this.state === State.InEntity) {
this.entityDecoder.end();
this.state = this.baseState;
}
this.handleTrailingData();
this.cbs.onend();
}
/** Handle any trailing data. */
handleTrailingData() {
const endIndex = this.buffer.length + this.offset;
if (this.sectionStart >= endIndex) {
return;
}
if (this.state === State.InCommentLike) {
if (this.currentSequence === Sequences.CdataEnd) {
this.cbs.oncdata(this.sectionStart, endIndex, 0);
} else {
this.cbs.oncomment(this.sectionStart, endIndex, 0);
}
} else if (this.state === State.InTagName || this.state === State.BeforeAttributeName || this.state === State.BeforeAttributeValue || this.state === State.AfterAttributeName || this.state === State.InAttributeName || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueDq || this.state === State.InAttributeValueNq || this.state === State.InClosingTagName) ;
else {
this.cbs.ontext(this.sectionStart, endIndex);
}
}
emitCodePoint(cp, consumed) {
if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) {
if (this.sectionStart < this.entityStart) {
this.cbs.onattribdata(this.sectionStart, this.entityStart);
}
this.sectionStart = this.entityStart + consumed;
this.index = this.sectionStart - 1;
this.cbs.onattribentity(cp);
} else {
if (this.sectionStart < this.entityStart) {
this.cbs.ontext(this.sectionStart, this.entityStart);
}
this.sectionStart = this.entityStart + consumed;
this.index = this.sectionStart - 1;
this.cbs.ontextentity(cp, this.sectionStart);
}
}
}
const formTags = /* @__PURE__ */ new Set([
"input",
"option",
"optgroup",
"select",
"button",
"datalist",
"textarea"
]);
const pTag = /* @__PURE__ */ new Set(["p"]);
const tableSectionTags = /* @__PURE__ */ new Set(["thead", "tbody"]);
const ddtTags = /* @__PURE__ */ new Set(["dd", "dt"]);
const rtpTags = /* @__PURE__ */ new Set(["rt", "rp"]);
const openImpliesClose = /* @__PURE__ */ new Map([
["tr", /* @__PURE__ */ new Set(["tr", "th", "td"])],
["th", /* @__PURE__ */ new Set(["th"])],
["td", /* @__PURE__ */ new Set(["thead", "th", "td"])],
["body", /* @__PURE__ */ new Set(["head", "link", "script"])],
["li", /* @__PURE__ */ new Set(["li"])],
["p", pTag],
["h1", pTag],
["h2", pTag],
["h3", pTag],
["h4", pTag],
["h5", pTag],
["h6", pTag],
["select", formTags],
["input", formTags],
["output", formTags],
["button", formTags],
["datalist", formTags],
["textarea", formTags],
["option", /* @__PURE__ */ new Set(["option"])],
["optgroup", /* @__PURE__ */ new Set(["optgroup", "option"])],
["dd", ddtTags],
["dt", ddtTags],
["address", pTag],
["article", pTag],
["aside", pTag],
["blockquote", pTag],
["details", pTag],
["div", pTag],
["dl", pTag],
["fieldset", pTag],
["figcaption", pTag],
["figure", pTag],
["footer", pTag],
["form", pTag],
["header", pTag],
["hr", pTag],
["main", pTag],
["nav", pTag],
["ol", pTag],
["pre", pTag],
["section", pTag],
["table", pTag],
["ul", pTag],
["rt", rtpTags],
["rp", rtpTags],
["tbody", tableSectionTags],
["tfoot", tableSectionTags]
]);
const voidElements = /* @__PURE__ */ new Set([
"area",
"base",
"basefont",
"br",
"col",
"command",
"embed",
"frame",
"hr",
"img",
"input",
"isindex",
"keygen",
"link",
"meta",
"param",
"source",
"track",
"wbr"
]);
const foreignContextElements = /* @__PURE__ */ new Set(["math", "svg"]);
const htmlIntegrationElements = /* @__PURE__ */ new Set([
"mi",
"mo",
"mn",
"ms",
"mtext",
"annotation-xml",
"foreignobject",
"desc",
"title"
]);
const reNameEnd = /\s|\//;
class Parser {
constructor(cbs, options = {}) {
var _a2, _b, _c, _d, _e, _f;
this.options = options;
this.startIndex = 0;
this.endIndex = 0;
this.openTagStart = 0;
this.tagname = "";
this.attribname = "";
this.attribvalue = "";
this.attribs = null;
this.stack = [];
this.buffers = [];
this.bufferOffset = 0;
this.writeIndex = 0;
this.ended = false;
this.cbs = cbs !== null && cbs !== void 0 ? cbs : {};
this.htmlMode = !this.options.xmlMode;
this.lowerCaseTagNames = (_a2 = options.lowerCaseTags) !== null && _a2 !== void 0 ? _a2 : this.htmlMode;
this.lowerCaseAttributeNames = (_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : this.htmlMode;
this.recognizeSelfClosing = (_c = options.recognizeSelfClosing) !== null && _c !== void 0 ? _c : !this.htmlMode;
this.tokenizer = new ((_d = options.Tokenizer) !== null && _d !== void 0 ? _d : Tokenizer)(this.options, this);
this.foreignContext = [!this.htmlMode];
(_f = (_e = this.cbs).onparserinit) === null || _f === void 0 ? void 0 : _f.call(_e, this);
}
// Tokenizer event handlers
/** @internal */
ontext(start, endIndex) {
var _a2, _b;
const data2 = this.getSlice(start, endIndex);
this.endIndex = endIndex - 1;
(_b = (_a2 = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a2, data2);
this.startIndex = endIndex;
}
/** @internal */
ontextentity(cp, endIndex) {
var _a2, _b;
this.endIndex = endIndex - 1;
(_b = (_a2 = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a2, fromCodePoint(cp));
this.startIndex = endIndex;
}
/**
* Checks if the current tag is a void element. Override this if you want
* to specify your own additional void elements.
*/
isVoidElement(name) {
return this.htmlMode && voidElements.has(name);
}
/** @internal */
onopentagname(start, endIndex) {
this.endIndex = endIndex;
let name = this.getSlice(start, endIndex);
if (this.lowerCaseTagNames) {
name = name.toLowerCase();
}
this.emitOpenTag(name);
}
emitOpenTag(name) {
var _a2, _b, _c, _d;
this.openTagStart = this.startIndex;
this.tagname = name;
const impliesClose = this.htmlMode && openImpliesClose.get(name);
if (impliesClose) {
while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {
const element = this.stack.shift();
(_b = (_a2 = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a2, element, true);
}
}
if (!this.isVoidElement(name)) {
this.stack.unshift(name);
if (this.htmlMode) {
if (foreignContextElements.has(name)) {
this.foreignContext.unshift(true);
} else if (htmlIntegrationElements.has(name)) {
this.foreignContext.unshift(false);
}
}
}
(_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, name);
if (this.cbs.onopentag)
this.attribs = {};
}
endOpenTag(isImplied) {
var _a2, _b;
this.startIndex = this.openTagStart;
if (this.attribs) {
(_b = (_a2 = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a2, this.tagname, this.attribs, isImplied);
this.attribs = null;
}
if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {
this.cbs.onclosetag(this.tagname, true);
}
this.tagname = "";
}
/** @internal */
onopentagend(endIndex) {
this.endIndex = endIndex;
this.endOpenTag(false);
this.startIndex = endIndex + 1;
}
/** @internal */
onclosetag(start, endIndex) {
var _a2, _b, _c, _d, _e, _f, _g, _h;
this.endIndex = endIndex;
let name = this.getSlice(start, endIndex);
if (this.lowerCaseTagNames) {
name = name.toLowerCase();
}
if (this.htmlMode && (foreignContextElements.has(name) || htmlIntegrationElements.has(name))) {
this.foreignContext.shift();
}
if (!this.isVoidElement(name)) {
const pos = this.stack.indexOf(name);
if (pos !== -1) {
for (let index2 = 0; index2 <= pos; index2++) {
const element = this.stack.shift();
(_b = (_a2 = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a2, element, index2 !== pos);
}
} else if (this.htmlMode && name === "p") {
this.emitOpenTag("p");
this.closeCurrentTag(true);
}
} else if (this.htmlMode && name === "br") {
(_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, "br");
(_f = (_e = this.cbs).onopentag) === null || _f === void 0 ? void 0 : _f.call(_e, "br", {}, true);
(_h = (_g = this.cbs).onclosetag) === null || _h === void 0 ? void 0 : _h.call(_g, "br", false);
}
this.startIndex = endIndex + 1;
}
/** @internal */
onselfclosingtag(endIndex) {
this.endIndex = endIndex;
if (this.recognizeSelfClosing || this.foreignContext[0]) {
this.closeCurrentTag(false);
this.startIndex = endIndex + 1;
} else {
this.onopentagend(endIndex);
}
}
closeCurrentTag(isOpenImplied) {
var _a2, _b;
const name = this.tagname;
this.endOpenTag(isOpenImplied);
if (this.stack[0] === name) {
(_b = (_a2 = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a2, name, !isOpenImplied);
this.stack.shift();
}
}
/** @internal */
onattribname(start, endIndex) {
this.startIndex = start;
const name = this.getSlice(start, endIndex);
this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name;
}
/** @internal */
onattribdata(start, endIndex) {
this.attribvalue += this.getSlice(start, endIndex);
}
/** @internal */
onattribentity(cp) {
this.attribvalue += fromCodePoint(cp);
}
/** @internal */
onattribend(quote, endIndex) {
var _a2, _b;
this.endIndex = endIndex;
(_b = (_a2 = this.cbs).onattribute) === null || _b === void 0 ? void 0 : _b.call(_a2, this.attribname, this.attribvalue, quote === QuoteType.Double ? '"' : quote === QuoteType.Single ? "'" : quote === QuoteType.NoValue ? void 0 : null);
if (this.attribs && !Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) {
this.attribs[this.attribname] = this.attribvalue;
}
this.attribvalue = "";
}
getInstructionName(value) {
const index2 = value.search(reNameEnd);
let name = index2 < 0 ? value : value.substr(0, index2);
if (this.lowerCaseTagNames) {
name = name.toLowerCase();
}
return name;
}
/** @internal */
ondeclaration(start, endIndex) {
this.endIndex = endIndex;
const value = this.getSlice(start, endIndex);
if (this.cbs.onprocessinginstruction) {
const name = this.getInstructionName(value);
this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);
}
this.startIndex = endIndex + 1;
}
/** @internal */
onprocessinginstruction(start, endIndex) {
this.endIndex = endIndex;
const value = this.getSlice(start, endIndex);
if (this.cbs.onprocessinginstruction) {
const name = this.getInstructionName(value);
this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);
}
this.startIndex = endIndex + 1;
}
/** @internal */
oncomment(start, endIndex, offset) {
var _a2, _b, _c, _d;
this.endIndex = endIndex;
(_b = (_a2 = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a2, this.getSlice(start, endIndex - offset));
(_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c);
this.startIndex = endIndex + 1;
}
/** @internal */
oncdata(start, endIndex, offset) {
var _a2, _b, _c, _d, _e, _f, _g, _h, _j, _k;
this.endIndex = endIndex;
const value = this.getSlice(start, endIndex - offset);
if (!this.htmlMode || this.options.recognizeCDATA) {
(_b = (_a2 = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a2);
(_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value);
(_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e);
} else {
(_h = (_g = this.cbs).oncomment) === null || _h === void 0 ? void 0 : _h.call(_g, `[CDATA[${value}]]`);
(_k = (_j = this.cbs).oncommentend) === null || _k === void 0 ? void 0 : _k.call(_j);
}
this.startIndex = endIndex + 1;
}
/** @internal */
onend() {
var _a2, _b;
if (this.cbs.onclosetag) {
this.endIndex = this.startIndex;
for (let index2 = 0; index2 < this.stack.length; index2++) {
this.cbs.onclosetag(this.stack[index2], true);
}
}
(_b = (_a2 = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a2);
}
/**
* Resets the parser to a blank state, ready to parse a new HTML document
*/
reset() {
var _a2, _b, _c, _d;
(_b = (_a2 = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a2);
this.tokenizer.reset();
this.tagname = "";
this.attribname = "";
this.attribs = null;
this.stack.length = 0;
this.startIndex = 0;
this.endIndex = 0;
(_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this);
this.buffers.length = 0;
this.foreignContext.length = 0;
this.foreignContext.unshift(!this.htmlMode);
this.bufferOffset = 0;
this.writeIndex = 0;
this.ended = false;
}
/**
* Resets the parser, then parses a complete document and
* pushes it to the handler.
*
* @param data Document to parse.
*/
parseComplete(data2) {
this.reset();
this.end(data2);
}
getSlice(start, end2) {
while (start - this.bufferOffset >= this.buffers[0].length) {
this.shiftBuffer();
}
let slice2 = this.buffers[0].slice(start - this.bufferOffset, end2 - this.bufferOffset);
while (end2 - this.bufferOffset > this.buffers[0].length) {
this.shiftBuffer();
slice2 += this.buffers[0].slice(0, end2 - this.bufferOffset);
}
return slice2;
}
shiftBuffer() {
this.bufferOffset += this.buffers[0].length;
this.writeIndex--;
this.buffers.shift();
}
/**
* Parses a chunk of data and calls the corresponding callbacks.
*
* @param chunk Chunk to parse.
*/
write(chunk) {
var _a2, _b;
if (this.ended) {
(_b = (_a2 = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a2, new Error(".write() after done!"));
return;
}
this.buffers.push(chunk);
if (this.tokenizer.running) {
this.tokenizer.write(chunk);
this.writeIndex++;
}
}
/**
* Parses the end of the buffer and clears the stack, calls onend.
*
* @param chunk Optional final chunk to parse.
*/
end(chunk) {
var _a2, _b;
if (this.ended) {
(_b = (_a2 = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a2, new Error(".end() after done!"));
return;
}
if (chunk)
this.write(chunk);
this.ended = true;
this.tokenizer.end();
}
/**
* Pauses parsing. The parser won't emit events until `resume` is called.
*/
pause() {
this.tokenizer.pause();
}
/**
* Resumes parsing after `pause` was called.
*/
resume() {
this.tokenizer.resume();
while (this.tokenizer.running && this.writeIndex < this.buffers.length) {
this.tokenizer.write(this.buffers[this.writeIndex++]);
}
if (this.ended)
this.tokenizer.end();
}
/**
* Alias of `write`, for backwards compatibility.
*
* @param chunk Chunk to parse.
* @deprecated
*/
parseChunk(chunk) {
this.write(chunk);
}
/**
* Alias of `end`, for backwards compatibility.
*
* @param chunk Optional final chunk to parse.
* @deprecated
*/
done(chunk) {
this.end(chunk);
}
}
function parseDocument(data2, options) {
const handler = new DomHandler(void 0, options);
new Parser(handler, options).end(data2);
return handler.root;
}
const load = getLoad(getParse(parseDocument), render$1);
var Levels = /* @__PURE__ */ ((Levels2) => {
Levels2[Levels2["None"] = 0] = "None";
Levels2[Levels2["H1"] = 1] = "H1";
Levels2[Levels2["H2"] = 2] = "H2";
Levels2[Levels2["H3"] = 3] = "H3";
Levels2[Levels2["H4"] = 4] = "H4";
Levels2[Levels2["H5"] = 5] = "H5";
Levels2[Levels2["H6"] = 6] = "H6";
Levels2[Levels2["Block"] = 7] = "Block";
Levels2[Levels2["List"] = 8] = "List";
Levels2[Levels2["ListItem"] = 9] = "ListItem";
return Levels2;
})(Levels || {});
const defaultSelectorRules = {
"div,p": ({ $node }) => ({
queue: $node.children()
}),
"h1,h2,h3,h4,h5,h6": ({ $node, getContent }) => ({
...getContent($node.contents())
}),
"ul,ol": ({ $node }) => ({
queue: $node.children(),
nesting: true
}),
li: ({ $node, getContent }) => {
const queue = $node.children().filter("ul,ol");
let content;
if ($node.contents().first().is("div,p")) {
content = getContent($node.children().first());
} else {
let $contents = $node.contents();
const i = $contents.index(queue);
if (i >= 0) $contents = $contents.slice(0, i);
content = getContent($contents);
}
return {
queue,
nesting: true,
...content
};
},
"table,pre,p>img:only-child": ({ $node, getContent }) => ({
...getContent($node)
})
};
const defaultOptions = {
selector: "h1,h2,h3,h4,h5,h6,ul,ol,li,table,pre,p>img:only-child",
selectorRules: defaultSelectorRules
};
const MARKMAP_COMMENT_PREFIX = "markmap: ";
const SELECTOR_HEADING = /^h[1-6]$/;
const SELECTOR_LIST = /^[uo]l$/;
const SELECTOR_LIST_ITEM = /^li$/;
function getLevel(tagName) {
if (SELECTOR_HEADING.test(tagName)) return +tagName[1];
if (SELECTOR_LIST.test(tagName)) return 8;
if (SELECTOR_LIST_ITEM.test(tagName)) return 9;
return 7;
}
function parseHtml(html2, opts) {
const options = {
...defaultOptions,
...opts
};
const $ = load(html2);
let $root = $("body");
if (!$root.length) $root = $.root();
let id = 0;
const rootNode = {
id,
tag: "",
html: "",
level: 0,
parent: 0,
childrenLevel: 0,
children: []
};
const headingStack = [];
let skippingHeading = 0;
checkNodes($root.children());
return rootNode;
function addChild(props) {
var _a2;
const { parent: parent2 } = props;
const node = {
id: ++id,
tag: props.tagName,
level: props.level,
html: props.html,
childrenLevel: 0,
children: props.nesting ? [] : void 0,
parent: parent2.id
};
if ((_a2 = props.comments) == null ? void 0 : _a2.length) {
node.comments = props.comments;
}
if (Object.keys(props.data || {}).length) {
node.data = props.data;
}
if (parent2.children) {
if (parent2.childrenLevel === 0 || parent2.childrenLevel > node.level) {
parent2.children = [];
parent2.childrenLevel = node.level;
}
if (parent2.childrenLevel === node.level) {
parent2.children.push(node);
}
}
return node;
}
function getCurrentHeading(level) {
let heading;
while ((heading = headingStack[headingStack.length - 1]) && heading.level >= level) {
headingStack.pop();
}
return heading || rootNode;
}
function getContent($node) {
var _a2;
const result = extractMagicComments($node);
const html22 = (_a2 = $.html(result.$node)) == null ? void 0 : _a2.trimEnd();
return { comments: result.comments, html: html22 };
}
function extractMagicComments($node) {
const comments = [];
$node = $node.filter((_, child) => {
if (child.type === "comment") {
const data2 = child.data.trim();
if (data2.startsWith(MARKMAP_COMMENT_PREFIX)) {
comments.push(data2.slice(MARKMAP_COMMENT_PREFIX.length).trim());
return false;
}
}
return true;
});
return { $node, comments };
}
function checkNodes($els, node) {
$els.each((_, child) => {
var _a2;
const $child = $(child);
const rule = (_a2 = Object.entries(options.selectorRules).find(
([selector]) => $child.is(selector)
)) == null ? void 0 : _a2[1];
const result = rule == null ? void 0 : rule({ $node: $child, $, getContent });
if ((result == null ? void 0 : result.queue) && !result.nesting) {
checkNodes(result.queue, node);
return;
}
const level = getLevel(child.tagName);
if (!result) {
if (level <= 6) {
skippingHeading = level;
}
return;
}
if (skippingHeading > 0 && level > skippingHeading) return;
if (!$child.is(options.selector)) return;
skippingHeading = 0;
const isHeading = level <= 6;
let data2 = {
// If the child is an inline element and expected to be a separate node,
// data from the closest `<p>` should be included, e.g. `<p data-lines><img /></p>`
...$child.closest("p").data(),
...$child.data()
};
let html22 = result.html || "";
if ($child.is("ol>li") && (node == null ? void 0 : node.children)) {
const start = +($child.parent().attr("start") || 1);
const listIndex = start + node.children.length;
html22 = `${listIndex}. ${html22}`;
data2 = {
...data2,
listIndex
};
}
const childNode = addChild({
parent: node || getCurrentHeading(level),
nesting: !!result.queue || isHeading,
tagName: child.tagName,
level,
html: html22,
comments: result.comments,
data: data2
});
if (isHeading) headingStack.push(childNode);
if (result.queue) checkNodes(result.queue, childNode);
});
}
}
function convertNode(htmlRoot) {
return markmapCommon.walkTree(htmlRoot, (htmlNode, next2) => {
const node = {
content: htmlNode.html,
children: next2() || []
};
if (htmlNode.data) {
node.payload = {
tag: htmlNode.tag,
...htmlNode.data
};
}
if (htmlNode.comments) {
if (htmlNode.comments.includes("foldAll")) {
node.payload = { ...node.payload, fold: 2 };
} else if (htmlNode.comments.includes("fold")) {
node.payload = { ...node.payload, fold: 1 };
}
}
return node;
});
}
function buildTree(html2, opts) {
const htmlRoot = parseHtml(html2, opts);
return convertNode(htmlRoot);
}
exports.Levels = Levels;
exports.buildTree = buildTree;
exports.convertNode = convertNode;
exports.defaultOptions = defaultOptions;
exports.parseHtml = parseHtml;