Best JavaScript code snippet using playwright-internal
highlight.js
Source:highlight.js  
1/*!2  Highlight.js v11.0.1 (git: 1cf31f015d)3  (c) 2006-2021 Ivan Sagalaev and other contributors4  License: BSD-3-Clause5 */6var hljs = (function () {7    'use strict';8    var deepFreezeEs6 = {exports: {}};9    function deepFreeze(obj) {10        if (obj instanceof Map) {11            obj.clear = obj.delete = obj.set = function () {12                throw new Error('map is read-only');13            };14        } else if (obj instanceof Set) {15            obj.add = obj.clear = obj.delete = function () {16                throw new Error('set is read-only');17            };18        }19        // Freeze self20        Object.freeze(obj);21        Object.getOwnPropertyNames(obj).forEach(function (name) {22            var prop = obj[name];23            // Freeze prop if it is an object24            if (typeof prop == 'object' && !Object.isFrozen(prop)) {25                deepFreeze(prop);26            }27        });28        return obj;29    }30    deepFreezeEs6.exports = deepFreeze;31    deepFreezeEs6.exports.default = deepFreeze;32    var deepFreeze$1 = deepFreezeEs6.exports;33    34    /** @typedef {import('highlight.js').CompiledMode} CompiledMode */35    /** @implements CallbackResponse */36    class Response {37      /**38       * @param {CompiledMode} mode39       */40      constructor(mode) {41        // eslint-disable-next-line no-undefined42        if (mode.data === undefined) mode.data = {};43        this.data = mode.data;44        this.isMatchIgnored = false;45      }46      ignoreMatch() {47        this.isMatchIgnored = true;48      }49    }50    /**51     * @param {string} value52     * @returns {string}53     */54    function escapeHTML(value) {55      return value56        .replace(/&/g, '&')57        .replace(/</g, '<')58        .replace(/>/g, '>')59        .replace(/"/g, '"')60        .replace(/'/g, ''');61    }62    /**63     * performs a shallow merge of multiple objects into one64     *65     * @template T66     * @param {T} original67     * @param {Record<string,any>[]} objects68     * @returns {T} a single new object69     */70    function inherit$1(original, ...objects) {71      /** @type Record<string,any> */72      const result = Object.create(null);73      for (const key in original) {74        result[key] = original[key];75      }76      objects.forEach(function(obj) {77        for (const key in obj) {78          result[key] = obj[key];79        }80      });81      return /** @type {T} */ (result);82    }83    /**84     * @typedef {object} Renderer85     * @property {(text: string) => void} addText86     * @property {(node: Node) => void} openNode87     * @property {(node: Node) => void} closeNode88     * @property {() => string} value89     */90    /** @typedef {{kind?: string, sublanguage?: boolean}} Node */91    /** @typedef {{walk: (r: Renderer) => void}} Tree */92    /** */93    const SPAN_CLOSE = '</span>';94    /**95     * Determines if a node needs to be wrapped in <span>96     *97     * @param {Node} node */98    const emitsWrappingTags = (node) => {99      return !!node.kind;100    };101    /**102     *103     * @param {string} name104     * @param {{prefix:string}} options105     */106    const expandScopeName = (name, { prefix }) => {107      if (name.includes(".")) {108        const pieces = name.split(".");109        return [110          `${prefix}${pieces.shift()}`,111          ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`))112        ].join(" ");113      }114      return `${prefix}${name}`;115    };116    /** @type {Renderer} */117    class HTMLRenderer {118      /**119       * Creates a new HTMLRenderer120       *121       * @param {Tree} parseTree - the parse tree (must support `walk` API)122       * @param {{classPrefix: string}} options123       */124      constructor(parseTree, options) {125        this.buffer = "";126        this.classPrefix = options.classPrefix;127        parseTree.walk(this);128      }129      /**130       * Adds texts to the output stream131       *132       * @param {string} text */133      addText(text) {134        this.buffer += escapeHTML(text);135      }136      /**137       * Adds a node open to the output stream (if needed)138       *139       * @param {Node} node */140      openNode(node) {141        if (!emitsWrappingTags(node)) return;142        let scope = node.kind;143        if (node.sublanguage) {144          scope = `language-${scope}`;145        } else {146          scope = expandScopeName(scope, { prefix: this.classPrefix });147        }148        this.span(scope);149      }150      /**151       * Adds a node close to the output stream (if needed)152       *153       * @param {Node} node */154      closeNode(node) {155        if (!emitsWrappingTags(node)) return;156        this.buffer += SPAN_CLOSE;157      }158      /**159       * returns the accumulated buffer160      */161      value() {162        return this.buffer;163      }164      // helpers165      /**166       * Builds a span element167       *168       * @param {string} className */169      span(className) {170        this.buffer += `<span class="${className}">`;171      }172    }173    /** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} | string} Node */174    /** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} } DataNode */175    /** @typedef {import('highlight.js').Emitter} Emitter */176    /**  */177    class TokenTree {178      constructor() {179        /** @type DataNode */180        this.rootNode = { children: [] };181        this.stack = [this.rootNode];182      }183      get top() {184        return this.stack[this.stack.length - 1];185      }186      get root() { return this.rootNode; }187      /** @param {Node} node */188      add(node) {189        this.top.children.push(node);190      }191      /** @param {string} kind */192      openNode(kind) {193        /** @type Node */194        const node = { kind, children: [] };195        this.add(node);196        this.stack.push(node);197      }198      closeNode() {199        if (this.stack.length > 1) {200          return this.stack.pop();201        }202        // eslint-disable-next-line no-undefined203        return undefined;204      }205      closeAllNodes() {206        while (this.closeNode());207      }208      toJSON() {209        return JSON.stringify(this.rootNode, null, 4);210      }211      /**212       * @typedef { import("./html_renderer").Renderer } Renderer213       * @param {Renderer} builder214       */215      walk(builder) {216        // this does not217        return this.constructor._walk(builder, this.rootNode);218        // this works219        // return TokenTree._walk(builder, this.rootNode);220      }221      /**222       * @param {Renderer} builder223       * @param {Node} node224       */225      static _walk(builder, node) {226        if (typeof node === "string") {227          builder.addText(node);228        } else if (node.children) {229          builder.openNode(node);230          node.children.forEach((child) => this._walk(builder, child));231          builder.closeNode(node);232        }233        return builder;234      }235      /**236       * @param {Node} node237       */238      static _collapse(node) {239        if (typeof node === "string") return;240        if (!node.children) return;241        if (node.children.every(el => typeof el === "string")) {242          // node.text = node.children.join("");243          // delete node.children;244          node.children = [node.children.join("")];245        } else {246          node.children.forEach((child) => {247            TokenTree._collapse(child);248          });249        }250      }251    }252    /**253      Currently this is all private API, but this is the minimal API necessary254      that an Emitter must implement to fully support the parser.255      Minimal interface:256      - addKeyword(text, kind)257      - addText(text)258      - addSublanguage(emitter, subLanguageName)259      - finalize()260      - openNode(kind)261      - closeNode()262      - closeAllNodes()263      - toHTML()264    */265    /**266     * @implements {Emitter}267     */268    class TokenTreeEmitter extends TokenTree {269      /**270       * @param {*} options271       */272      constructor(options) {273        super();274        this.options = options;275      }276      /**277       * @param {string} text278       * @param {string} kind279       */280      addKeyword(text, kind) {281        if (text === "") { return; }282        this.openNode(kind);283        this.addText(text);284        this.closeNode();285      }286      /**287       * @param {string} text288       */289      addText(text) {290        if (text === "") { return; }291        this.add(text);292      }293      /**294       * @param {Emitter & {root: DataNode}} emitter295       * @param {string} name296       */297      addSublanguage(emitter, name) {298        /** @type DataNode */299        const node = emitter.root;300        node.kind = name;301        node.sublanguage = true;302        this.add(node);303      }304      toHTML() {305        const renderer = new HTMLRenderer(this, this.options);306        return renderer.value();307      }308      finalize() {309        return true;310      }311    }312    /**313     * @param {string} value314     * @returns {RegExp}315     * */316    /**317     * @param {RegExp | string } re318     * @returns {string}319     */320    function source(re) {321      if (!re) return null;322      if (typeof re === "string") return re;323      return re.source;324    }325    /**326     * @param {RegExp | string } re327     * @returns {string}328     */329    function lookahead(re) {330      return concat('(?=', re, ')');331    }332    /**333     * @param {...(RegExp | string) } args334     * @returns {string}335     */336    function concat(...args) {337      const joined = args.map((x) => source(x)).join("");338      return joined;339    }340    function stripOptionsFromArgs(args) {341      const opts = args[args.length - 1];342      if (typeof opts === 'object' && opts.constructor === Object) {343        args.splice(args.length - 1, 1);344        return opts;345      } else {346        return {};347      }348    }349    /**350     * Any of the passed expresssions may match351     *352     * Creates a huge this | this | that | that match353     * @param {(RegExp | string)[] } args354     * @returns {string}355     */356    function either(...args) {357      const opts = stripOptionsFromArgs(args);358      const joined = '(' +359        (opts.capture ? "" : "?:") +360        args.map((x) => source(x)).join("|") + ")";361      return joined;362    }363    /**364     * @param {RegExp} re365     * @returns {number}366     */367    function countMatchGroups(re) {368      return (new RegExp(re.toString() + '|')).exec('').length - 1;369    }370    /**371     * Does lexeme start with a regular expression match at the beginning372     * @param {RegExp} re373     * @param {string} lexeme374     */375    function startsWith(re, lexeme) {376      const match = re && re.exec(lexeme);377      return match && match.index === 0;378    }379    // BACKREF_RE matches an open parenthesis or backreference. To avoid380    // an incorrect parse, it additionally matches the following:381    // - [...] elements, where the meaning of parentheses and escapes change382    // - other escape sequences, so we do not misparse escape sequences as383    //   interesting elements384    // - non-matching or lookahead parentheses, which do not capture. These385    //   follow the '(' with a '?'.386    const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;387    // **INTERNAL** Not intended for outside usage388    // join logically computes regexps.join(separator), but fixes the389    // backreferences so they continue to match.390    // it also places each individual regular expression into it's own391    // match group, keeping track of the sequencing of those match groups392    // is currently an exercise for the caller. :-)393    /**394     * @param {(string | RegExp)[]} regexps395     * @param {{joinWith: string}} opts396     * @returns {string}397     */398    function _rewriteBackreferences(regexps, { joinWith }) {399      let numCaptures = 0;400      return regexps.map((regex) => {401        numCaptures += 1;402        const offset = numCaptures;403        let re = source(regex);404        let out = '';405        while (re.length > 0) {406          const match = BACKREF_RE.exec(re);407          if (!match) {408            out += re;409            break;410          }411          out += re.substring(0, match.index);412          re = re.substring(match.index + match[0].length);413          if (match[0][0] === '\\' && match[1]) {414            // Adjust the backreference.415            out += '\\' + String(Number(match[1]) + offset);416          } else {417            out += match[0];418            if (match[0] === '(') {419              numCaptures++;420            }421          }422        }423        return out;424      }).map(re => `(${re})`).join(joinWith);425    }426    /** @typedef {import('highlight.js').Mode} Mode */427    /** @typedef {import('highlight.js').ModeCallback} ModeCallback */428    // Common regexps429    const MATCH_NOTHING_RE = /\b\B/;430    const IDENT_RE = '[a-zA-Z]\\w*';431    const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*';432    const NUMBER_RE = '\\b\\d+(\\.\\d+)?';433    const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float434    const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...435    const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';436    /**437    * @param { Partial<Mode> & {binary?: string | RegExp} } opts438    */439    const SHEBANG = (opts = {}) => {440      const beginShebang = /^#![ ]*\//;441      if (opts.binary) {442        opts.begin = concat(443          beginShebang,444          /.*\b/,445          opts.binary,446          /\b.*/);447      }448      return inherit$1({449        scope: 'meta',450        begin: beginShebang,451        end: /$/,452        relevance: 0,453        /** @type {ModeCallback} */454        "on:begin": (m, resp) => {455          if (m.index !== 0) resp.ignoreMatch();456        }457      }, opts);458    };459    // Common modes460    const BACKSLASH_ESCAPE = {461      begin: '\\\\[\\s\\S]', relevance: 0462    };463    const APOS_STRING_MODE = {464      scope: 'string',465      begin: '\'',466      end: '\'',467      illegal: '\\n',468      contains: [BACKSLASH_ESCAPE]469    };470    const QUOTE_STRING_MODE = {471      scope: 'string',472      begin: '"',473      end: '"',474      illegal: '\\n',475      contains: [BACKSLASH_ESCAPE]476    };477    const PHRASAL_WORDS_MODE = {478      begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/479    };480    /**481     * Creates a comment mode482     *483     * @param {string | RegExp} begin484     * @param {string | RegExp} end485     * @param {Mode | {}} [modeOptions]486     * @returns {Partial<Mode>}487     */488    const COMMENT = function(begin, end, modeOptions = {}) {489      const mode = inherit$1(490        {491          scope: 'comment',492          begin,493          end,494          contains: []495        },496        modeOptions497      );498      mode.contains.push({499        scope: 'doctag',500        // hack to avoid the space from being included. the space is necessary to501        // match here to prevent the plain text rule below from gobbling up doctags502        begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',503        end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,504        excludeBegin: true,505        relevance: 0506      });507      const ENGLISH_WORD = either(508        // list of common 1 and 2 letter words in English509        "I",510        "a",511        "is",512        "so",513        "us",514        "to",515        "at",516        "if",517        "in",518        "it",519        "on",520        // note: this is not an exhaustive list of contractions, just popular ones521        /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc522        /[A-Za-z]+[-][a-z]+/, // `no-way`, etc.523        /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences524      );525      // looking like plain text, more likely to be a comment526      mode.contains.push(527        {528          // TODO: how to include ", (, ) without breaking grammars that use these for529          // comment delimiters?530          // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/531          // ---532          // this tries to find sequences of 3 english words in a row (without any533          // "programming" type syntax) this gives us a strong signal that we've534          // TRULY found a comment - vs perhaps scanning with the wrong language.535          // It's possible to find something that LOOKS like the start of the536          // comment - but then if there is no readable text - good chance it is a537          // false match and not a comment.538          //539          // for a visual example please see:540          // https://github.com/highlightjs/highlight.js/issues/2827541          begin: concat(542            /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */543            '(',544            ENGLISH_WORD,545            /[.]?[:]?([.][ ]|[ ])/,546            '){3}') // look for 3 words in a row547        }548      );549      return mode;550    };551    const C_LINE_COMMENT_MODE = COMMENT('//', '$');552    const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/');553    const HASH_COMMENT_MODE = COMMENT('#', '$');554    const NUMBER_MODE = {555      scope: 'number',556      begin: NUMBER_RE,557      relevance: 0558    };559    const C_NUMBER_MODE = {560      scope: 'number',561      begin: C_NUMBER_RE,562      relevance: 0563    };564    const BINARY_NUMBER_MODE = {565      scope: 'number',566      begin: BINARY_NUMBER_RE,567      relevance: 0568    };569    const REGEXP_MODE = {570      // this outer rule makes sure we actually have a WHOLE regex and not simply571      // an expression such as:572      //573      //     3 / something574      //575      // (which will then blow up when regex's `illegal` sees the newline)576      begin: /(?=\/[^/\n]*\/)/,577      contains: [{578        scope: 'regexp',579        begin: /\//,580        end: /\/[gimuy]*/,581        illegal: /\n/,582        contains: [583          BACKSLASH_ESCAPE,584          {585            begin: /\[/,586            end: /\]/,587            relevance: 0,588            contains: [BACKSLASH_ESCAPE]589          }590        ]591      }]592    };593    const TITLE_MODE = {594      scope: 'title',595      begin: IDENT_RE,596      relevance: 0597    };598    const UNDERSCORE_TITLE_MODE = {599      scope: 'title',600      begin: UNDERSCORE_IDENT_RE,601      relevance: 0602    };603    const METHOD_GUARD = {604      // excludes method names from keyword processing605      begin: '\\.\\s*' + UNDERSCORE_IDENT_RE,606      relevance: 0607    };608    /**609     * Adds end same as begin mechanics to a mode610     *611     * Your mode must include at least a single () match group as that first match612     * group is what is used for comparison613     * @param {Partial<Mode>} mode614     */615    const END_SAME_AS_BEGIN = function(mode) {616      return Object.assign(mode,617        {618          /** @type {ModeCallback} */619          'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },620          /** @type {ModeCallback} */621          'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }622        });623    };624    var MODES = /*#__PURE__*/Object.freeze({625        __proto__: null,626        MATCH_NOTHING_RE: MATCH_NOTHING_RE,627        IDENT_RE: IDENT_RE,628        UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,629        NUMBER_RE: NUMBER_RE,630        C_NUMBER_RE: C_NUMBER_RE,631        BINARY_NUMBER_RE: BINARY_NUMBER_RE,632        RE_STARTERS_RE: RE_STARTERS_RE,633        SHEBANG: SHEBANG,634        BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,635        APOS_STRING_MODE: APOS_STRING_MODE,636        QUOTE_STRING_MODE: QUOTE_STRING_MODE,637        PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,638        COMMENT: COMMENT,639        C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,640        C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,641        HASH_COMMENT_MODE: HASH_COMMENT_MODE,642        NUMBER_MODE: NUMBER_MODE,643        C_NUMBER_MODE: C_NUMBER_MODE,644        BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,645        REGEXP_MODE: REGEXP_MODE,646        TITLE_MODE: TITLE_MODE,647        UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,648        METHOD_GUARD: METHOD_GUARD,649        END_SAME_AS_BEGIN: END_SAME_AS_BEGIN650    });651    /**652    @typedef {import('highlight.js').CallbackResponse} CallbackResponse653    @typedef {import('highlight.js').CompilerExt} CompilerExt654    */655    // Grammar extensions / plugins656    // See: https://github.com/highlightjs/highlight.js/issues/2833657    // Grammar extensions allow "syntactic sugar" to be added to the grammar modes658    // without requiring any underlying changes to the compiler internals.659    // `compileMatch` being the perfect small example of now allowing a grammar660    // author to write `match` when they desire to match a single expression rather661    // than being forced to use `begin`.  The extension then just moves `match` into662    // `begin` when it runs.  Ie, no features have been added, but we've just made663    // the experience of writing (and reading grammars) a little bit nicer.664    // ------665    // TODO: We need negative look-behind support to do this properly666    /**667     * Skip a match if it has a preceding dot668     *669     * This is used for `beginKeywords` to prevent matching expressions such as670     * `bob.keyword.do()`. The mode compiler automatically wires this up as a671     * special _internal_ 'on:begin' callback for modes with `beginKeywords`672     * @param {RegExpMatchArray} match673     * @param {CallbackResponse} response674     */675    function skipIfHasPrecedingDot(match, response) {676      const before = match.input[match.index - 1];677      if (before === ".") {678        response.ignoreMatch();679      }680    }681    /**682     *683     * @type {CompilerExt}684     */685    function scopeClassName(mode, _parent) {686      // eslint-disable-next-line no-undefined687      if (mode.className !== undefined) {688        mode.scope = mode.className;689        delete mode.className;690      }691    }692    /**693     * `beginKeywords` syntactic sugar694     * @type {CompilerExt}695     */696    function beginKeywords(mode, parent) {697      if (!parent) return;698      if (!mode.beginKeywords) return;699      // for languages with keywords that include non-word characters checking for700      // a word boundary is not sufficient, so instead we check for a word boundary701      // or whitespace - this does no harm in any case since our keyword engine702      // doesn't allow spaces in keywords anyways and we still check for the boundary703      // first704      mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)';705      mode.__beforeBegin = skipIfHasPrecedingDot;706      mode.keywords = mode.keywords || mode.beginKeywords;707      delete mode.beginKeywords;708      // prevents double relevance, the keywords themselves provide709      // relevance, the mode doesn't need to double it710      // eslint-disable-next-line no-undefined711      if (mode.relevance === undefined) mode.relevance = 0;712    }713    /**714     * Allow `illegal` to contain an array of illegal values715     * @type {CompilerExt}716     */717    function compileIllegal(mode, _parent) {718      if (!Array.isArray(mode.illegal)) return;719      mode.illegal = either(...mode.illegal);720    }721    /**722     * `match` to match a single expression for readability723     * @type {CompilerExt}724     */725    function compileMatch(mode, _parent) {726      if (!mode.match) return;727      if (mode.begin || mode.end) throw new Error("begin & end are not supported with match");728      mode.begin = mode.match;729      delete mode.match;730    }731    /**732     * provides the default 1 relevance to all modes733     * @type {CompilerExt}734     */735    function compileRelevance(mode, _parent) {736      // eslint-disable-next-line no-undefined737      if (mode.relevance === undefined) mode.relevance = 1;738    }739    // allow beforeMatch to act as a "qualifier" for the match740    // the full match begin must be [beforeMatch][begin]741    const beforeMatchExt = (mode, parent) => {742      if (!mode.beforeMatch) return;743      // starts conflicts with endsParent which we need to make sure the child744      // rule is not matched multiple times745      if (mode.starts) throw new Error("beforeMatch cannot be used with starts");746      const originalMode = Object.assign({}, mode);747      Object.keys(mode).forEach((key) => { delete mode[key]; });748      mode.keywords = originalMode.keywords;749      mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));750      mode.starts = {751        relevance: 0,752        contains: [753          Object.assign(originalMode, { endsParent: true })754        ]755      };756      mode.relevance = 0;757      delete originalMode.beforeMatch;758    };759    // keywords that should have no default relevance value760    const COMMON_KEYWORDS = [761      'of',762      'and',763      'for',764      'in',765      'not',766      'or',767      'if',768      'then',769      'parent', // common variable name770      'list', // common variable name771      'value' // common variable name772    ];773    const DEFAULT_KEYWORD_SCOPE = "keyword";774    /**775     * Given raw keywords from a language definition, compile them.776     *777     * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords778     * @param {boolean} caseInsensitive779     */780    function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {781      /** @type KeywordDict */782      const compiledKeywords = Object.create(null);783      // input can be a string of keywords, an array of keywords, or a object with784      // named keys representing scopeName (which can then point to a string or array)785      if (typeof rawKeywords === 'string') {786        compileList(scopeName, rawKeywords.split(" "));787      } else if (Array.isArray(rawKeywords)) {788        compileList(scopeName, rawKeywords);789      } else {790        Object.keys(rawKeywords).forEach(function(scopeName) {791          // collapse all our objects back into the parent object792          Object.assign(793            compiledKeywords,794            compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)795          );796        });797      }798      return compiledKeywords;799      // ---800      /**801       * Compiles an individual list of keywords802       *803       * Ex: "for if when while|5"804       *805       * @param {string} scopeName806       * @param {Array<string>} keywordList807       */808      function compileList(scopeName, keywordList) {809        if (caseInsensitive) {810          keywordList = keywordList.map(x => x.toLowerCase());811        }812        keywordList.forEach(function(keyword) {813          const pair = keyword.split('|');814          compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];815        });816      }817    }818    /**819     * Returns the proper score for a given keyword820     *821     * Also takes into account comment keywords, which will be scored 0 UNLESS822     * another score has been manually assigned.823     * @param {string} keyword824     * @param {string} [providedScore]825     */826    function scoreForKeyword(keyword, providedScore) {827      // manual scores always win over common keywords828      // so you can force a score of 1 if you really insist829      if (providedScore) {830        return Number(providedScore);831      }832      return commonKeyword(keyword) ? 0 : 1;833    }834    /**835     * Determines if a given keyword is common or not836     *837     * @param {string} keyword */838    function commonKeyword(keyword) {839      return COMMON_KEYWORDS.includes(keyword.toLowerCase());840    }841    /*842    For the reasoning behind this please see:843    https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419844    */845    /**846     * @type {Record<string, boolean>}847     */848    const seenDeprecations = {};849    /**850     * @param {string} message851     */852    const error = (message) => {853      console.error(message);854    };855    /**856     * @param {string} message857     * @param {any} args858     */859    const warn = (message, ...args) => {860      console.log(`WARN: ${message}`, ...args);861    };862    /**863     * @param {string} version864     * @param {string} message865     */866    const deprecated = (version, message) => {867      if (seenDeprecations[`${version}/${message}`]) return;868      console.log(`Deprecated as of ${version}. ${message}`);869      seenDeprecations[`${version}/${message}`] = true;870    };871    /* eslint-disable no-throw-literal */872    /**873    @typedef {import('highlight.js').CompiledMode} CompiledMode874    */875    const MultiClassError = new Error();876    /**877     * Renumbers labeled scope names to account for additional inner match878     * groups that otherwise would break everything.879     *880     * Lets say we 3 match scopes:881     *882     *   { 1 => ..., 2 => ..., 3 => ... }883     *884     * So what we need is a clean match like this:885     *886     *   (a)(b)(c) => [ "a", "b", "c" ]887     *888     * But this falls apart with inner match groups:889     *890     * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ]891     *892     * Our scopes are now "out of alignment" and we're repeating `b` 3 times.893     * What needs to happen is the numbers are remapped:894     *895     *   { 1 => ..., 2 => ..., 5 => ... }896     *897     * We also need to know that the ONLY groups that should be output898     * are 1, 2, and 5.  This function handles this behavior.899     *900     * @param {CompiledMode} mode901     * @param {Array<RegExp>} regexes902     * @param {{key: "beginScope"|"endScope"}} opts903     */904    function remapScopeNames(mode, regexes, { key }) {905      let offset = 0;906      const scopeNames = mode[key];907      /** @type Record<number,boolean> */908      const emit = {};909      /** @type Record<number,string> */910      const positions = {};911      for (let i = 1; i <= regexes.length; i++) {912        positions[i + offset] = scopeNames[i];913        emit[i + offset] = true;914        offset += countMatchGroups(regexes[i - 1]);915      }916      // we use _emit to keep track of which match groups are "top-level" to avoid double917      // output from inside match groups918      mode[key] = positions;919      mode[key]._emit = emit;920      mode[key]._multi = true;921    }922    /**923     * @param {CompiledMode} mode924     */925    function beginMultiClass(mode) {926      if (!Array.isArray(mode.begin)) return;927      if (mode.skip || mode.excludeBegin || mode.returnBegin) {928        error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");929        throw MultiClassError;930      }931      if (typeof mode.beginScope !== "object" || mode.beginScope === null) {932        error("beginScope must be object");933        throw MultiClassError;934      }935      remapScopeNames(mode, mode.begin, {key: "beginScope"});936      mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" });937    }938    /**939     * @param {CompiledMode} mode940     */941    function endMultiClass(mode) {942      if (!Array.isArray(mode.end)) return;943      if (mode.skip || mode.excludeEnd || mode.returnEnd) {944        error("skip, excludeEnd, returnEnd not compatible with endScope: {}");945        throw MultiClassError;946      }947      if (typeof mode.endScope !== "object" || mode.endScope === null) {948        error("endScope must be object");949        throw MultiClassError;950      }951      remapScopeNames(mode, mode.end, {key: "endScope"});952      mode.end = _rewriteBackreferences(mode.end, { joinWith: "" });953    }954    /**955     * this exists only to allow `scope: {}` to be used beside `match:`956     * Otherwise `beginScope` would necessary and that would look weird957      {958        match: [ /def/, /\w+/ ]959        scope: { 1: "keyword" , 2: "title" }960      }961     * @param {CompiledMode} mode962     */963    function scopeSugar(mode) {964      if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {965        mode.beginScope = mode.scope;966        delete mode.scope;967      }968    }969    /**970     * @param {CompiledMode} mode971     */972    function MultiClass(mode) {973      scopeSugar(mode);974      if (typeof mode.beginScope === "string") {975        mode.beginScope = { _wrap: mode.beginScope };976      }977      if (typeof mode.endScope === "string") {978        mode.endScope = { _wrap: mode.endScope };979      }980      beginMultiClass(mode);981      endMultiClass(mode);982    }983    /**984    @typedef {import('highlight.js').Mode} Mode985    @typedef {import('highlight.js').CompiledMode} CompiledMode986    @typedef {import('highlight.js').Language} Language987    @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin988    @typedef {import('highlight.js').CompiledLanguage} CompiledLanguage989    */990    // compilation991    /**992     * Compiles a language definition result993     *994     * Given the raw result of a language definition (Language), compiles this so995     * that it is ready for highlighting code.996     * @param {Language} language997     * @returns {CompiledLanguage}998     */999    function compileLanguage(language) {1000      /**1001       * Builds a regex with the case sensitivity of the current language1002       *1003       * @param {RegExp | string} value1004       * @param {boolean} [global]1005       */1006      function langRe(value, global) {1007        return new RegExp(1008          source(value),1009          'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')1010        );1011      }1012      /**1013        Stores multiple regular expressions and allows you to quickly search for1014        them all in a string simultaneously - returning the first match.  It does1015        this by creating a huge (a|b|c) regex - each individual item wrapped with ()1016        and joined by `|` - using match groups to track position.  When a match is1017        found checking which position in the array has content allows us to figure1018        out which of the original regexes / match groups triggered the match.1019        The match object itself (the result of `Regex.exec`) is returned but also1020        enhanced by merging in any meta-data that was registered with the regex.1021        This is how we keep track of which mode matched, and what type of rule1022        (`illegal`, `begin`, end, etc).1023      */1024      class MultiRegex {1025        constructor() {1026          this.matchIndexes = {};1027          // @ts-ignore1028          this.regexes = [];1029          this.matchAt = 1;1030          this.position = 0;1031        }1032        // @ts-ignore1033        addRule(re, opts) {1034          opts.position = this.position++;1035          // @ts-ignore1036          this.matchIndexes[this.matchAt] = opts;1037          this.regexes.push([opts, re]);1038          this.matchAt += countMatchGroups(re) + 1;1039        }1040        compile() {1041          if (this.regexes.length === 0) {1042            // avoids the need to check length every time exec is called1043            // @ts-ignore1044            this.exec = () => null;1045          }1046          const terminators = this.regexes.map(el => el[1]);1047          this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true);1048          this.lastIndex = 0;1049        }1050        /** @param {string} s */1051        exec(s) {1052          this.matcherRe.lastIndex = this.lastIndex;1053          const match = this.matcherRe.exec(s);1054          if (!match) { return null; }1055          // eslint-disable-next-line no-undefined1056          const i = match.findIndex((el, i) => i > 0 && el !== undefined);1057          // @ts-ignore1058          const matchData = this.matchIndexes[i];1059          // trim off any earlier non-relevant match groups (ie, the other regex1060          // match groups that make up the multi-matcher)1061          match.splice(0, i);1062          return Object.assign(match, matchData);1063        }1064      }1065      /*1066        Created to solve the key deficiently with MultiRegex - there is no way to1067        test for multiple matches at a single location.  Why would we need to do1068        that?  In the future a more dynamic engine will allow certain matches to be1069        ignored.  An example: if we matched say the 3rd regex in a large group but1070        decided to ignore it - we'd need to started testing again at the 4th1071        regex... but MultiRegex itself gives us no real way to do that.1072        So what this class creates MultiRegexs on the fly for whatever search1073        position they are needed.1074        NOTE: These additional MultiRegex objects are created dynamically.  For most1075        grammars most of the time we will never actually need anything more than the1076        first MultiRegex - so this shouldn't have too much overhead.1077        Say this is our search group, and we match regex3, but wish to ignore it.1078          regex1 | regex2 | regex3 | regex4 | regex5    ' ie, startAt = 01079        What we need is a new MultiRegex that only includes the remaining1080        possibilities:1081          regex4 | regex5                               ' ie, startAt = 31082        This class wraps all that complexity up in a simple API... `startAt` decides1083        where in the array of expressions to start doing the matching. It1084        auto-increments, so if a match is found at position 2, then startAt will be1085        set to 3.  If the end is reached startAt will return to 0.1086        MOST of the time the parser will be setting startAt manually to 0.1087      */1088      class ResumableMultiRegex {1089        constructor() {1090          // @ts-ignore1091          this.rules = [];1092          // @ts-ignore1093          this.multiRegexes = [];1094          this.count = 0;1095          this.lastIndex = 0;1096          this.regexIndex = 0;1097        }1098        // @ts-ignore1099        getMatcher(index) {1100          if (this.multiRegexes[index]) return this.multiRegexes[index];1101          const matcher = new MultiRegex();1102          this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));1103          matcher.compile();1104          this.multiRegexes[index] = matcher;1105          return matcher;1106        }1107        resumingScanAtSamePosition() {1108          return this.regexIndex !== 0;1109        }1110        considerAll() {1111          this.regexIndex = 0;1112        }1113        // @ts-ignore1114        addRule(re, opts) {1115          this.rules.push([re, opts]);1116          if (opts.type === "begin") this.count++;1117        }1118        /** @param {string} s */1119        exec(s) {1120          const m = this.getMatcher(this.regexIndex);1121          m.lastIndex = this.lastIndex;1122          let result = m.exec(s);1123          // The following is because we have no easy way to say "resume scanning at the1124          // existing position but also skip the current rule ONLY". What happens is1125          // all prior rules are also skipped which can result in matching the wrong1126          // thing. Example of matching "booger":1127          // our matcher is [string, "booger", number]1128          //1129          // ....booger....1130          // if "booger" is ignored then we'd really need a regex to scan from the1131          // SAME position for only: [string, number] but ignoring "booger" (if it1132          // was the first match), a simple resume would scan ahead who knows how1133          // far looking only for "number", ignoring potential string matches (or1134          // future "booger" matches that might be valid.)1135          // So what we do: We execute two matchers, one resuming at the same1136          // position, but the second full matcher starting at the position after:1137          //     /--- resume first regex match here (for [number])1138          //     |/---- full match here for [string, "booger", number]1139          //     vv1140          // ....booger....1141          // Which ever results in a match first is then used. So this 3-4 step1142          // process essentially allows us to say "match at this position, excluding1143          // a prior rule that was ignored".1144          //1145          // 1. Match "booger" first, ignore. Also proves that [string] does non match.1146          // 2. Resume matching for [number]1147          // 3. Match at index + 1 for [string, "booger", number]1148          // 4. If #2 and #3 result in matches, which came first?1149          if (this.resumingScanAtSamePosition()) {1150            if (result && result.index === this.lastIndex) ; else { // use the second matcher result1151              const m2 = this.getMatcher(0);1152              m2.lastIndex = this.lastIndex + 1;1153              result = m2.exec(s);1154            }1155          }1156          if (result) {1157            this.regexIndex += result.position + 1;1158            if (this.regexIndex === this.count) {1159              // wrap-around to considering all matches again1160              this.considerAll();1161            }1162          }1163          return result;1164        }1165      }1166      /**1167       * Given a mode, builds a huge ResumableMultiRegex that can be used to walk1168       * the content and find matches.1169       *1170       * @param {CompiledMode} mode1171       * @returns {ResumableMultiRegex}1172       */1173      function buildModeRegex(mode) {1174        const mm = new ResumableMultiRegex();1175        mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" }));1176        if (mode.terminatorEnd) {1177          mm.addRule(mode.terminatorEnd, { type: "end" });1178        }1179        if (mode.illegal) {1180          mm.addRule(mode.illegal, { type: "illegal" });1181        }1182        return mm;1183      }1184      /** skip vs abort vs ignore1185       *1186       * @skip   - The mode is still entered and exited normally (and contains rules apply),1187       *           but all content is held and added to the parent buffer rather than being1188       *           output when the mode ends.  Mostly used with `sublanguage` to build up1189       *           a single large buffer than can be parsed by sublanguage.1190       *1191       *             - The mode begin ands ends normally.1192       *             - Content matched is added to the parent mode buffer.1193       *             - The parser cursor is moved forward normally.1194       *1195       * @abort  - A hack placeholder until we have ignore.  Aborts the mode (as if it1196       *           never matched) but DOES NOT continue to match subsequent `contains`1197       *           modes.  Abort is bad/suboptimal because it can result in modes1198       *           farther down not getting applied because an earlier rule eats the1199       *           content but then aborts.1200       *1201       *             - The mode does not begin.1202       *             - Content matched by `begin` is added to the mode buffer.1203       *             - The parser cursor is moved forward accordingly.1204       *1205       * @ignore - Ignores the mode (as if it never matched) and continues to match any1206       *           subsequent `contains` modes.  Ignore isn't technically possible with1207       *           the current parser implementation.1208       *1209       *             - The mode does not begin.1210       *             - Content matched by `begin` is ignored.1211       *             - The parser cursor is not moved forward.1212       */1213      /**1214       * Compiles an individual mode1215       *1216       * This can raise an error if the mode contains certain detectable known logic1217       * issues.1218       * @param {Mode} mode1219       * @param {CompiledMode | null} [parent]1220       * @returns {CompiledMode | never}1221       */1222      function compileMode(mode, parent) {1223        const cmode = /** @type CompiledMode */ (mode);1224        if (mode.isCompiled) return cmode;1225        [1226          scopeClassName,1227          // do this early so compiler extensions generally don't have to worry about1228          // the distinction between match/begin1229          compileMatch,1230          MultiClass,1231          beforeMatchExt1232        ].forEach(ext => ext(mode, parent));1233        language.compilerExtensions.forEach(ext => ext(mode, parent));1234        // __beforeBegin is considered private API, internal use only1235        mode.__beforeBegin = null;1236        [1237          beginKeywords,1238          // do this later so compiler extensions that come earlier have access to the1239          // raw array if they wanted to perhaps manipulate it, etc.1240          compileIllegal,1241          // default to 1 relevance if not specified1242          compileRelevance1243        ].forEach(ext => ext(mode, parent));1244        mode.isCompiled = true;1245        let keywordPattern = null;1246        if (typeof mode.keywords === "object" && mode.keywords.$pattern) {1247          // we need a copy because keywords might be compiled multiple times1248          // so we can't go deleting $pattern from the original on the first1249          // pass1250          mode.keywords = Object.assign({}, mode.keywords);1251          keywordPattern = mode.keywords.$pattern;1252          delete mode.keywords.$pattern;1253        }1254        keywordPattern = keywordPattern || /\w+/;1255        if (mode.keywords) {1256          mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);1257        }1258        cmode.keywordPatternRe = langRe(keywordPattern, true);1259        if (parent) {1260          if (!mode.begin) mode.begin = /\B|\b/;1261          cmode.beginRe = langRe(mode.begin);1262          if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/;1263          if (mode.end) cmode.endRe = langRe(mode.end);1264          cmode.terminatorEnd = source(mode.end) || '';1265          if (mode.endsWithParent && parent.terminatorEnd) {1266            cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;1267          }1268        }1269        if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));1270        if (!mode.contains) mode.contains = [];1271        mode.contains = [].concat(...mode.contains.map(function(c) {1272          return expandOrCloneMode(c === 'self' ? mode : c);1273        }));1274        mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });1275        if (mode.starts) {1276          compileMode(mode.starts, parent);1277        }1278        cmode.matcher = buildModeRegex(cmode);1279        return cmode;1280      }1281      if (!language.compilerExtensions) language.compilerExtensions = [];1282      // self is not valid at the top-level1283      if (language.contains && language.contains.includes('self')) {1284        throw new Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.");1285      }1286      // we need a null object, which inherit will guarantee1287      language.classNameAliases = inherit$1(language.classNameAliases || {});1288      return compileMode(/** @type Mode */ (language));1289    }1290    /**1291     * Determines if a mode has a dependency on it's parent or not1292     *1293     * If a mode does have a parent dependency then often we need to clone it if1294     * it's used in multiple places so that each copy points to the correct parent,1295     * where-as modes without a parent can often safely be re-used at the bottom of1296     * a mode chain.1297     *1298     * @param {Mode | null} mode1299     * @returns {boolean} - is there a dependency on the parent?1300     * */1301    function dependencyOnParent(mode) {1302      if (!mode) return false;1303      return mode.endsWithParent || dependencyOnParent(mode.starts);1304    }1305    /**1306     * Expands a mode or clones it if necessary1307     *1308     * This is necessary for modes with parental dependenceis (see notes on1309     * `dependencyOnParent`) and for nodes that have `variants` - which must then be1310     * exploded into their own individual modes at compile time.1311     *1312     * @param {Mode} mode1313     * @returns {Mode | Mode[]}1314     * */1315    function expandOrCloneMode(mode) {1316      if (mode.variants && !mode.cachedVariants) {1317        mode.cachedVariants = mode.variants.map(function(variant) {1318          return inherit$1(mode, { variants: null }, variant);1319        });1320      }1321      // EXPAND1322      // if we have variants then essentially "replace" the mode with the variants1323      // this happens in compileMode, where this function is called from1324      if (mode.cachedVariants) {1325        return mode.cachedVariants;1326      }1327      // CLONE1328      // if we have dependencies on parents then we need a unique1329      // instance of ourselves, so we can be reused with many1330      // different parents without issue1331      if (dependencyOnParent(mode)) {1332        return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null });1333      }1334      if (Object.isFrozen(mode)) {1335        return inherit$1(mode);1336      }1337      // no special dependency issues, just return ourselves1338      return mode;1339    }1340    var version = "11.0.1";1341    /*1342    Syntax highlighting with language autodetection.1343    https://highlightjs.org/1344    */1345    /**1346    @typedef {import('highlight.js').Mode} Mode1347    @typedef {import('highlight.js').CompiledMode} CompiledMode1348    @typedef {import('highlight.js').Language} Language1349    @typedef {import('highlight.js').HLJSApi} HLJSApi1350    @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin1351    @typedef {import('highlight.js').PluginEvent} PluginEvent1352    @typedef {import('highlight.js').HLJSOptions} HLJSOptions1353    @typedef {import('highlight.js').LanguageFn} LanguageFn1354    @typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement1355    @typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext1356    @typedef {import('highlight.js/private').MatchType} MatchType1357    @typedef {import('highlight.js/private').KeywordData} KeywordData1358    @typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch1359    @typedef {import('highlight.js/private').AnnotatedError} AnnotatedError1360    @typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult1361    @typedef {import('highlight.js').HighlightOptions} HighlightOptions1362    @typedef {import('highlight.js').HighlightResult} HighlightResult1363    */1364    const escape = escapeHTML;1365    const inherit = inherit$1;1366    const NO_MATCH = Symbol("nomatch");1367    const MAX_KEYWORD_HITS = 7;1368    /**1369     * @param {any} hljs - object that is extended (legacy)1370     * @returns {HLJSApi}1371     */1372    const HLJS = function(hljs) {1373      // Global internal variables used within the highlight.js library.1374      /** @type {Record<string, Language>} */1375      const languages = Object.create(null);1376      /** @type {Record<string, string>} */1377      const aliases = Object.create(null);1378      /** @type {HLJSPlugin[]} */1379      const plugins = [];1380      // safe/production mode - swallows more errors, tries to keep running1381      // even if a single syntax or parse hits a fatal error1382      let SAFE_MODE = true;1383      const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?";1384      /** @type {Language} */1385      const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };1386      // Global options used when within external APIs. This is modified when1387      // calling the `hljs.configure` function.1388      /** @type HLJSOptions */1389      let options = {1390        ignoreUnescapedHTML: false,1391        noHighlightRe: /^(no-?highlight)$/i,1392        languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,1393        classPrefix: 'hljs-',1394        cssSelector: 'pre code',1395        languages: null,1396        // beta configuration options, subject to change, welcome to discuss1397        // https://github.com/highlightjs/highlight.js/issues/10861398        __emitter: TokenTreeEmitter1399      };1400      /* Utility functions */1401      /**1402       * Tests a language name to see if highlighting should be skipped1403       * @param {string} languageName1404       */1405      function shouldNotHighlight(languageName) {1406        return options.noHighlightRe.test(languageName);1407      }1408      /**1409       * @param {HighlightedHTMLElement} block - the HTML element to determine language for1410       */1411      function blockLanguage(block) {1412        let classes = block.className + ' ';1413        classes += block.parentNode ? block.parentNode.className : '';1414        // language-* takes precedence over non-prefixed class names.1415        const match = options.languageDetectRe.exec(classes);1416        if (match) {1417          const language = getLanguage(match[1]);1418          if (!language) {1419            warn(LANGUAGE_NOT_FOUND.replace("{}", match[1]));1420            warn("Falling back to no-highlight mode for this block.", block);1421          }1422          return language ? match[1] : 'no-highlight';1423        }1424        return classes1425          .split(/\s+/)1426          .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));1427      }1428      /**1429       * Core highlighting function.1430       *1431       * OLD API1432       * highlight(lang, code, ignoreIllegals, continuation)1433       *1434       * NEW API1435       * highlight(code, {lang, ignoreIllegals})1436       *1437       * @param {string} codeOrLanguageName - the language to use for highlighting1438       * @param {string | HighlightOptions} optionsOrCode - the code to highlight1439       * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail1440       * @param {CompiledMode} [continuation] - current continuation mode, if any1441       *1442       * @returns {HighlightResult} Result - an object that represents the result1443       * @property {string} language - the language name1444       * @property {number} relevance - the relevance score1445       * @property {string} value - the highlighted HTML code1446       * @property {string} code - the original raw code1447       * @property {CompiledMode} top - top of the current mode stack1448       * @property {boolean} illegal - indicates whether any illegal matches were found1449      */1450      function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals, continuation) {1451        let code = "";1452        let languageName = "";1453        if (typeof optionsOrCode === "object") {1454          code = codeOrLanguageName;1455          ignoreIllegals = optionsOrCode.ignoreIllegals;1456          languageName = optionsOrCode.language;1457          // continuation not supported at all via the new API1458          // eslint-disable-next-line no-undefined1459          continuation = undefined;1460        } else {1461          // old API1462          deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated.");1463          deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277");1464          languageName = codeOrLanguageName;1465          code = optionsOrCode;1466        }1467        // https://github.com/highlightjs/highlight.js/issues/31491468        // eslint-disable-next-line no-undefined1469        if (ignoreIllegals === undefined) { ignoreIllegals = true; }1470        /** @type {BeforeHighlightContext} */1471        const context = {1472          code,1473          language: languageName1474        };1475        // the plugin can change the desired language or the code to be highlighted1476        // just be changing the object it was passed1477        fire("before:highlight", context);1478        // a before plugin can usurp the result completely by providing it's own1479        // in which case we don't even need to call highlight1480        const result = context.result1481          ? context.result1482          : _highlight(context.language, context.code, ignoreIllegals, continuation);1483        result.code = context.code;1484        // the plugin can change anything in result to suite it1485        fire("after:highlight", result);1486        return result;1487      }1488      /**1489       * private highlight that's used internally and does not fire callbacks1490       *1491       * @param {string} languageName - the language to use for highlighting1492       * @param {string} codeToHighlight - the code to highlight1493       * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail1494       * @param {CompiledMode?} [continuation] - current continuation mode, if any1495       * @returns {HighlightResult} - result of the highlight operation1496      */1497      function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {1498        const keywordHits = Object.create(null);1499        /**1500         * Return keyword data if a match is a keyword1501         * @param {CompiledMode} mode - current mode1502         * @param {string} matchText - the textual match1503         * @returns {KeywordData | false}1504         */1505        function keywordData(mode, matchText) {1506          return mode.keywords[matchText];1507        }1508        function processKeywords() {1509          if (!top.keywords) {1510            emitter.addText(modeBuffer);1511            return;1512          }1513          let lastIndex = 0;1514          top.keywordPatternRe.lastIndex = 0;1515          let match = top.keywordPatternRe.exec(modeBuffer);1516          let buf = "";1517          while (match) {1518            buf += modeBuffer.substring(lastIndex, match.index);1519            const word = language.case_insensitive ? match[0].toLowerCase() : match[0];1520            const data = keywordData(top, word);1521            if (data) {1522              const [kind, keywordRelevance] = data;1523              emitter.addText(buf);1524              buf = "";1525              keywordHits[word] = (keywordHits[word] || 0) + 1;1526              if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance;1527              if (kind.startsWith("_")) {1528                // _ implied for relevance only, do not highlight1529                // by applying a class name1530                buf += match[0];1531              } else {1532                const cssClass = language.classNameAliases[kind] || kind;1533                emitter.addKeyword(match[0], cssClass);1534              }1535            } else {1536              buf += match[0];1537            }1538            lastIndex = top.keywordPatternRe.lastIndex;1539            match = top.keywordPatternRe.exec(modeBuffer);1540          }1541          buf += modeBuffer.substr(lastIndex);1542          emitter.addText(buf);1543        }1544        function processSubLanguage() {1545          if (modeBuffer === "") return;1546          /** @type HighlightResult */1547          let result = null;1548          if (typeof top.subLanguage === 'string') {1549            if (!languages[top.subLanguage]) {1550              emitter.addText(modeBuffer);1551              return;1552            }1553            result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);1554            continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top);1555          } else {1556            result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);1557          }1558          // Counting embedded language score towards the host language may be disabled1559          // with zeroing the containing mode relevance. Use case in point is Markdown that1560          // allows XML everywhere and makes every XML snippet to have a much larger Markdown1561          // score.1562          if (top.relevance > 0) {1563            relevance += result.relevance;1564          }1565          emitter.addSublanguage(result._emitter, result.language);1566        }1567        function processBuffer() {1568          if (top.subLanguage != null) {1569            processSubLanguage();1570          } else {1571            processKeywords();1572          }1573          modeBuffer = '';1574        }1575        /**1576         * @param {CompiledMode} mode1577         * @param {RegExpMatchArray} match1578         */1579        function emitMultiClass(scope, match) {1580          let i = 1;1581          // eslint-disable-next-line no-undefined1582          while (match[i] !== undefined) {1583            if (!scope._emit[i]) { i++; continue; }1584            const klass = language.classNameAliases[scope[i]] || scope[i];1585            const text = match[i];1586            if (klass) {1587              emitter.addKeyword(text, klass);1588            } else {1589              modeBuffer = text;1590              processKeywords();1591              modeBuffer = "";1592            }1593            i++;1594          }1595        }1596        /**1597         * @param {CompiledMode} mode - new mode to start1598         * @param {RegExpMatchArray} match1599         */1600        function startNewMode(mode, match) {1601          if (mode.scope && typeof mode.scope === "string") {1602            emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);1603          }1604          if (mode.beginScope) {1605            // beginScope just wraps the begin match itself in a scope1606            if (mode.beginScope._wrap) {1607              emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);1608              modeBuffer = "";1609            } else if (mode.beginScope._multi) {1610              // at this point modeBuffer should just be the match1611              emitMultiClass(mode.beginScope, match);1612              modeBuffer = "";1613            }1614          }1615          top = Object.create(mode, { parent: { value: top } });1616          return top;1617        }1618        /**1619         * @param {CompiledMode } mode - the mode to potentially end1620         * @param {RegExpMatchArray} match - the latest match1621         * @param {string} matchPlusRemainder - match plus remainder of content1622         * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode1623         */1624        function endOfMode(mode, match, matchPlusRemainder) {1625          let matched = startsWith(mode.endRe, matchPlusRemainder);1626          if (matched) {1627            if (mode["on:end"]) {1628              const resp = new Response(mode);1629              mode["on:end"](match, resp);1630              if (resp.isMatchIgnored) matched = false;1631            }1632            if (matched) {1633              while (mode.endsParent && mode.parent) {1634                mode = mode.parent;1635              }1636              return mode;1637            }1638          }1639          // even if on:end fires an `ignore` it's still possible1640          // that we might trigger the end node because of a parent mode1641          if (mode.endsWithParent) {1642            return endOfMode(mode.parent, match, matchPlusRemainder);1643          }1644        }1645        /**1646         * Handle matching but then ignoring a sequence of text1647         *1648         * @param {string} lexeme - string containing full match text1649         */1650        function doIgnore(lexeme) {1651          if (top.matcher.regexIndex === 0) {1652            // no more regexes to potentially match here, so we move the cursor forward one1653            // space1654            modeBuffer += lexeme[0];1655            return 1;1656          } else {1657            // no need to move the cursor, we still have additional regexes to try and1658            // match at this very spot1659            resumeScanAtSamePosition = true;1660            return 0;1661          }1662        }1663        /**1664         * Handle the start of a new potential mode match1665         *1666         * @param {EnhancedMatch} match - the current match1667         * @returns {number} how far to advance the parse cursor1668         */1669        function doBeginMatch(match) {1670          const lexeme = match[0];1671          const newMode = match.rule;1672          const resp = new Response(newMode);1673          // first internal before callbacks, then the public ones1674          const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]];1675          for (const cb of beforeCallbacks) {1676            if (!cb) continue;1677            cb(match, resp);1678            if (resp.isMatchIgnored) return doIgnore(lexeme);1679          }1680          if (newMode.skip) {1681            modeBuffer += lexeme;1682          } else {1683            if (newMode.excludeBegin) {1684              modeBuffer += lexeme;1685            }1686            processBuffer();1687            if (!newMode.returnBegin && !newMode.excludeBegin) {1688              modeBuffer = lexeme;1689            }1690          }1691          startNewMode(newMode, match);1692          return newMode.returnBegin ? 0 : lexeme.length;1693        }1694        /**1695         * Handle the potential end of mode1696         *1697         * @param {RegExpMatchArray} match - the current match1698         */1699        function doEndMatch(match) {1700          const lexeme = match[0];1701          const matchPlusRemainder = codeToHighlight.substr(match.index);1702          const endMode = endOfMode(top, match, matchPlusRemainder);1703          if (!endMode) { return NO_MATCH; }1704          const origin = top;1705          if (top.endScope && top.endScope._wrap) {1706            processBuffer();1707            emitter.addKeyword(lexeme, top.endScope._wrap);1708          } else if (top.endScope && top.endScope._multi) {1709            processBuffer();1710            emitMultiClass(top.endScope, match);1711          } else if (origin.skip) {1712            modeBuffer += lexeme;1713          } else {1714            if (!(origin.returnEnd || origin.excludeEnd)) {1715              modeBuffer += lexeme;1716            }1717            processBuffer();1718            if (origin.excludeEnd) {1719              modeBuffer = lexeme;1720            }1721          }1722          do {1723            if (top.scope && !top.isMultiClass) {1724              emitter.closeNode();1725            }1726            if (!top.skip && !top.subLanguage) {1727              relevance += top.relevance;1728            }1729            top = top.parent;1730          } while (top !== endMode.parent);1731          if (endMode.starts) {1732            startNewMode(endMode.starts, match);1733          }1734          return origin.returnEnd ? 0 : lexeme.length;1735        }1736        function processContinuations() {1737          const list = [];1738          for (let current = top; current !== language; current = current.parent) {1739            if (current.scope) {1740              list.unshift(current.scope);1741            }1742          }1743          list.forEach(item => emitter.openNode(item));1744        }1745        /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */1746        let lastMatch = {};1747        /**1748         *  Process an individual match1749         *1750         * @param {string} textBeforeMatch - text preceding the match (since the last match)1751         * @param {EnhancedMatch} [match] - the match itself1752         */1753        function processLexeme(textBeforeMatch, match) {1754          const lexeme = match && match[0];1755          // add non-matched text to the current mode buffer1756          modeBuffer += textBeforeMatch;1757          if (lexeme == null) {1758            processBuffer();1759            return 0;1760          }1761          // we've found a 0 width match and we're stuck, so we need to advance1762          // this happens when we have badly behaved rules that have optional matchers to the degree that1763          // sometimes they can end up matching nothing at all1764          // Ref: https://github.com/highlightjs/highlight.js/issues/21401765          if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") {1766            // spit the "skipped" character that our regex choked on back into the output sequence1767            modeBuffer += codeToHighlight.slice(match.index, match.index + 1);1768            if (!SAFE_MODE) {1769              /** @type {AnnotatedError} */1770              const err = new Error(`0 width match regex (${languageName})`);1771              err.languageName = languageName;1772              err.badRule = lastMatch.rule;1773              throw err;1774            }1775            return 1;1776          }1777          lastMatch = match;1778          if (match.type === "begin") {1779            return doBeginMatch(match);1780          } else if (match.type === "illegal" && !ignoreIllegals) {1781            // illegal match, we do not continue processing1782            /** @type {AnnotatedError} */1783            const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '<unnamed>') + '"');1784            err.mode = top;1785            throw err;1786          } else if (match.type === "end") {1787            const processed = doEndMatch(match);1788            if (processed !== NO_MATCH) {1789              return processed;1790            }1791          }1792          // edge case for when illegal matches $ (end of line) which is technically1793          // a 0 width match but not a begin/end match so it's not caught by the1794          // first handler (when ignoreIllegals is true)1795          if (match.type === "illegal" && lexeme === "") {1796            // advance so we aren't stuck in an infinite loop1797            return 1;1798          }1799          // infinite loops are BAD, this is a last ditch catch all. if we have a1800          // decent number of iterations yet our index (cursor position in our1801          // parsing) still 3x behind our index then something is very wrong1802          // so we bail1803          if (iterations > 100000 && iterations > match.index * 3) {1804            const err = new Error('potential infinite loop, way more iterations than matches');1805            throw err;1806          }1807          /*1808          Why might be find ourselves here?  An potential end match that was1809          triggered but could not be completed.  IE, `doEndMatch` returned NO_MATCH.1810          (this could be because a callback requests the match be ignored, etc)1811          This causes no real harm other than stopping a few times too many.1812          */1813          modeBuffer += lexeme;1814          return lexeme.length;1815        }1816        const language = getLanguage(languageName);1817        if (!language) {1818          error(LANGUAGE_NOT_FOUND.replace("{}", languageName));1819          throw new Error('Unknown language: "' + languageName + '"');1820        }1821        const md = compileLanguage(language);1822        let result = '';1823        /** @type {CompiledMode} */1824        let top = continuation || md;1825        /** @type Record<string,CompiledMode> */1826        const continuations = {}; // keep continuations for sub-languages1827        const emitter = new options.__emitter(options);1828        processContinuations();1829        let modeBuffer = '';1830        let relevance = 0;1831        let index = 0;1832        let iterations = 0;1833        let resumeScanAtSamePosition = false;1834        try {1835          top.matcher.considerAll();1836          for (;;) {1837            iterations++;1838            if (resumeScanAtSamePosition) {1839              // only regexes not matched previously will now be1840              // considered for a potential match1841              resumeScanAtSamePosition = false;1842            } else {1843              top.matcher.considerAll();1844            }1845            top.matcher.lastIndex = index;1846            const match = top.matcher.exec(codeToHighlight);1847            // console.log("match", match[0], match.rule && match.rule.begin)1848            if (!match) break;1849            const beforeMatch = codeToHighlight.substring(index, match.index);1850            const processedCount = processLexeme(beforeMatch, match);1851            index = match.index + processedCount;1852          }1853          processLexeme(codeToHighlight.substr(index));1854          emitter.closeAllNodes();1855          emitter.finalize();1856          result = emitter.toHTML();1857          return {1858            language: languageName,1859            value: result,1860            relevance: relevance,1861            illegal: false,1862            _emitter: emitter,1863            _top: top1864          };1865        } catch (err) {1866          if (err.message && err.message.includes('Illegal')) {1867            return {1868              language: languageName,1869              value: escape(codeToHighlight),1870              illegal: true,1871              relevance: 0,1872              _illegalBy: {1873                message: err.message,1874                index: index,1875                context: codeToHighlight.slice(index - 100, index + 100),1876                mode: err.mode,1877                resultSoFar: result1878              },1879              _emitter: emitter1880            };1881          } else if (SAFE_MODE) {1882            return {1883              language: languageName,1884              value: escape(codeToHighlight),1885              illegal: false,1886              relevance: 0,1887              errorRaised: err,1888              _emitter: emitter,1889              _top: top1890            };1891          } else {1892            throw err;1893          }1894        }1895      }1896      /**1897       * returns a valid highlight result, without actually doing any actual work,1898       * auto highlight starts with this and it's possible for small snippets that1899       * auto-detection may not find a better match1900       * @param {string} code1901       * @returns {HighlightResult}1902       */1903      function justTextHighlightResult(code) {1904        const result = {1905          value: escape(code),1906          illegal: false,1907          relevance: 0,1908          _top: PLAINTEXT_LANGUAGE,1909          _emitter: new options.__emitter(options)1910        };1911        result._emitter.addText(code);1912        return result;1913      }1914      /**1915      Highlighting with language detection. Accepts a string with the code to1916      highlight. Returns an object with the following properties:1917      - language (detected language)1918      - relevance (int)1919      - value (an HTML string with highlighting markup)1920      - secondBest (object with the same structure for second-best heuristically1921        detected language, may be absent)1922        @param {string} code1923        @param {Array<string>} [languageSubset]1924        @returns {AutoHighlightResult}1925      */1926      function highlightAuto(code, languageSubset) {1927        languageSubset = languageSubset || options.languages || Object.keys(languages);1928        const plaintext = justTextHighlightResult(code);1929        const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>1930          _highlight(name, code, false)1931        );1932        results.unshift(plaintext); // plaintext is always an option1933        const sorted = results.sort((a, b) => {1934          // sort base on relevance1935          if (a.relevance !== b.relevance) return b.relevance - a.relevance;1936          // always award the tie to the base language1937          // ie if C++ and Arduino are tied, it's more likely to be C++1938          if (a.language && b.language) {1939            if (getLanguage(a.language).supersetOf === b.language) {1940              return 1;1941            } else if (getLanguage(b.language).supersetOf === a.language) {1942              return -1;1943            }1944          }1945          // otherwise say they are equal, which has the effect of sorting on1946          // relevance while preserving the original ordering - which is how ties1947          // have historically been settled, ie the language that comes first always1948          // wins in the case of a tie1949          return 0;1950        });1951        const [best, secondBest] = sorted;1952        /** @type {AutoHighlightResult} */1953        const result = best;1954        result.secondBest = secondBest;1955        return result;1956      }1957      /**1958       * Builds new class name for block given the language name1959       *1960       * @param {HTMLElement} element1961       * @param {string} [currentLang]1962       * @param {string} [resultLang]1963       */1964      function updateClassName(element, currentLang, resultLang) {1965        const language = (currentLang && aliases[currentLang]) || resultLang;1966        element.classList.add("hljs");1967        element.classList.add(`language-${language}`);1968      }1969      /**1970       * Applies highlighting to a DOM node containing code.1971       *1972       * @param {HighlightedHTMLElement} element - the HTML element to highlight1973      */1974      function highlightElement(element) {1975        /** @type HTMLElement */1976        let node = null;1977        const language = blockLanguage(element);1978        if (shouldNotHighlight(language)) return;1979        fire("before:highlightElement",1980          { el: element, language: language });1981        // we should be all text, no child nodes1982        if (!options.ignoreUnescapedHTML && element.children.length > 0) {1983          console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk.");1984          console.warn("https://github.com/highlightjs/highlight.js/issues/2886");1985          console.warn(element);1986        }1987        node = element;1988        const text = node.textContent;1989        const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);1990        element.innerHTML = result.value;1991        updateClassName(element, language, result.language);1992        element.result = {1993          language: result.language,1994          // TODO: remove with version 11.01995          re: result.relevance,1996          relevance: result.relevance1997        };1998        if (result.secondBest) {1999          element.secondBest = {2000            language: result.secondBest.language,2001            relevance: result.secondBest.relevance2002          };2003        }2004        fire("after:highlightElement", { el: element, result, text });2005      }2006      /**2007       * Updates highlight.js global options with the passed options2008       *2009       * @param {Partial<HLJSOptions>} userOptions2010       */2011      function configure(userOptions) {2012        options = inherit(options, userOptions);2013      }2014      // TODO: remove v12, deprecated2015      const initHighlighting = () => {2016        highlightAll();2017        deprecated("10.6.0", "initHighlighting() deprecated.  Use highlightAll() now.");2018      };2019      // TODO: remove v12, deprecated2020      function initHighlightingOnLoad() {2021        highlightAll();2022        deprecated("10.6.0", "initHighlightingOnLoad() deprecated.  Use highlightAll() now.");2023      }2024      let wantsHighlight = false;2025      /**2026       * auto-highlights all pre>code elements on the page2027       */2028      function highlightAll() {2029        // if we are called too early in the loading process2030        if (document.readyState === "loading") {2031          wantsHighlight = true;2032          return;2033        }2034        const blocks = document.querySelectorAll(options.cssSelector);2035        blocks.forEach(highlightElement);2036      }2037      function boot() {2038        // if a highlight was requested before DOM was loaded, do now2039        if (wantsHighlight) highlightAll();2040      }2041      // make sure we are in the browser environment2042      if (typeof window !== 'undefined' && window.addEventListener) {2043        window.addEventListener('DOMContentLoaded', boot, false);2044      }2045      /**2046       * Register a language grammar module2047       *2048       * @param {string} languageName2049       * @param {LanguageFn} languageDefinition2050       */2051      function registerLanguage(languageName, languageDefinition) {2052        let lang = null;2053        try {2054          lang = languageDefinition(hljs);2055        } catch (error$1) {2056          error("Language definition for '{}' could not be registered.".replace("{}", languageName));2057          // hard or soft error2058          if (!SAFE_MODE) { throw error$1; } else { error(error$1); }2059          // languages that have serious errors are replaced with essentially a2060          // "plaintext" stand-in so that the code blocks will still get normal2061          // css classes applied to them - and one bad language won't break the2062          // entire highlighter2063          lang = PLAINTEXT_LANGUAGE;2064        }2065        // give it a temporary name if it doesn't have one in the meta-data2066        if (!lang.name) lang.name = languageName;2067        languages[languageName] = lang;2068        lang.rawDefinition = languageDefinition.bind(null, hljs);2069        if (lang.aliases) {2070          registerAliases(lang.aliases, { languageName });2071        }2072      }2073      /**2074       * Remove a language grammar module2075       *2076       * @param {string} languageName2077       */2078      function unregisterLanguage(languageName) {2079        delete languages[languageName];2080        for (const alias of Object.keys(aliases)) {2081          if (aliases[alias] === languageName) {2082            delete aliases[alias];2083          }2084        }2085      }2086      /**2087       * @returns {string[]} List of language internal names2088       */2089      function listLanguages() {2090        return Object.keys(languages);2091      }2092      /**2093       * @param {string} name - name of the language to retrieve2094       * @returns {Language | undefined}2095       */2096      function getLanguage(name) {2097        name = (name || '').toLowerCase();2098        return languages[name] || languages[aliases[name]];2099      }2100      /**2101       *2102       * @param {string|string[]} aliasList - single alias or list of aliases2103       * @param {{languageName: string}} opts2104       */2105      function registerAliases(aliasList, { languageName }) {2106        if (typeof aliasList === 'string') {2107          aliasList = [aliasList];2108        }2109        aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });2110      }2111      /**2112       * Determines if a given language has auto-detection enabled2113       * @param {string} name - name of the language2114       */2115      function autoDetection(name) {2116        const lang = getLanguage(name);2117        return lang && !lang.disableAutodetect;2118      }2119      /**2120       * Upgrades the old highlightBlock plugins to the new2121       * highlightElement API2122       * @param {HLJSPlugin} plugin2123       */2124      function upgradePluginAPI(plugin) {2125        // TODO: remove with v122126        if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) {2127          plugin["before:highlightElement"] = (data) => {2128            plugin["before:highlightBlock"](2129              Object.assign({ block: data.el }, data)2130            );2131          };2132        }2133        if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) {2134          plugin["after:highlightElement"] = (data) => {2135            plugin["after:highlightBlock"](2136              Object.assign({ block: data.el }, data)2137            );2138          };2139        }2140      }2141      /**2142       * @param {HLJSPlugin} plugin2143       */2144      function addPlugin(plugin) {2145        upgradePluginAPI(plugin);2146        plugins.push(plugin);2147      }2148      /**2149       *2150       * @param {PluginEvent} event2151       * @param {any} args2152       */2153      function fire(event, args) {2154        const cb = event;2155        plugins.forEach(function(plugin) {2156          if (plugin[cb]) {2157            plugin[cb](args);2158          }2159        });2160      }2161      /**2162       *2163       * @param {HighlightedHTMLElement} el2164       */2165      function deprecateHighlightBlock(el) {2166        deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0");2167        deprecated("10.7.0", "Please use highlightElement now.");2168        return highlightElement(el);2169      }2170      /* Interface definition */2171      Object.assign(hljs, {2172        highlight,2173        highlightAuto,2174        highlightAll,2175        highlightElement,2176        // TODO: Remove with v12 API2177        highlightBlock: deprecateHighlightBlock,2178        configure,2179        initHighlighting,2180        initHighlightingOnLoad,2181        registerLanguage,2182        unregisterLanguage,2183        listLanguages,2184        getLanguage,2185        registerAliases,2186        autoDetection,2187        inherit,2188        addPlugin2189      });2190      hljs.debugMode = function() { SAFE_MODE = false; };2191      hljs.safeMode = function() { SAFE_MODE = true; };2192      hljs.versionString = version;2193      for (const key in MODES) {2194        // @ts-ignore2195        if (typeof MODES[key] === "object") {2196          // @ts-ignore2197          deepFreeze$1(MODES[key]);2198        }2199      }2200      // merge all the modes/regexes into our main object2201      Object.assign(hljs, MODES);2202      return hljs;2203    };2204    // export an "instance" of the highlighter2205    var HighlightJS = HLJS({});2206    var builtIns = /*#__PURE__*/Object.freeze({2207        __proto__: null2208    });2209    const hljs = HighlightJS;2210    for (const key of Object.keys(builtIns)) {2211      const languageName = key.replace("grmr_", "");2212      hljs.registerLanguage(languageName, builtIns[key]);2213    }2214    return hljs;2215}());...highlight.js_v11.3.1-0C5csJSkMVgQyOMzmIlU_dist_es2020_mode_imports_optimized_common_core-da5e7eef_1b12fcb113193245855a.js
Source:highlight.js_v11.3.1-0C5csJSkMVgQyOMzmIlU_dist_es2020_mode_imports_optimized_common_core-da5e7eef_1b12fcb113193245855a.js  
1var deepFreezeEs6 = {exports: {}};2function deepFreeze(obj) {3  if (obj instanceof Map) {4    obj.clear = obj.delete = obj.set = function() {5      throw new Error("map is read-only");6    };7  } else if (obj instanceof Set) {8    obj.add = obj.clear = obj.delete = function() {9      throw new Error("set is read-only");10    };11  }12  Object.freeze(obj);13  Object.getOwnPropertyNames(obj).forEach(function(name) {14    var prop = obj[name];15    if (typeof prop == "object" && !Object.isFrozen(prop)) {16      deepFreeze(prop);17    }18  });19  return obj;20}21deepFreezeEs6.exports = deepFreeze;22deepFreezeEs6.exports.default = deepFreeze;23var deepFreeze$1 = deepFreezeEs6.exports;24class Response {25  constructor(mode) {26    if (mode.data === void 0)27      mode.data = {};28    this.data = mode.data;29    this.isMatchIgnored = false;30  }31  ignoreMatch() {32    this.isMatchIgnored = true;33  }34}35function escapeHTML(value) {36  return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");37}38function inherit$1(original, ...objects) {39  const result = Object.create(null);40  for (const key in original) {41    result[key] = original[key];42  }43  objects.forEach(function(obj) {44    for (const key in obj) {45      result[key] = obj[key];46    }47  });48  return result;49}50const SPAN_CLOSE = "</span>";51const emitsWrappingTags = (node) => {52  return !!node.kind;53};54const expandScopeName = (name, {prefix}) => {55  if (name.includes(".")) {56    const pieces = name.split(".");57    return [58      `${prefix}${pieces.shift()}`,59      ...pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`)60    ].join(" ");61  }62  return `${prefix}${name}`;63};64class HTMLRenderer {65  constructor(parseTree, options) {66    this.buffer = "";67    this.classPrefix = options.classPrefix;68    parseTree.walk(this);69  }70  addText(text) {71    this.buffer += escapeHTML(text);72  }73  openNode(node) {74    if (!emitsWrappingTags(node))75      return;76    let scope = node.kind;77    if (node.sublanguage) {78      scope = `language-${scope}`;79    } else {80      scope = expandScopeName(scope, {prefix: this.classPrefix});81    }82    this.span(scope);83  }84  closeNode(node) {85    if (!emitsWrappingTags(node))86      return;87    this.buffer += SPAN_CLOSE;88  }89  value() {90    return this.buffer;91  }92  span(className) {93    this.buffer += `<span class="${className}">`;94  }95}96class TokenTree {97  constructor() {98    this.rootNode = {children: []};99    this.stack = [this.rootNode];100  }101  get top() {102    return this.stack[this.stack.length - 1];103  }104  get root() {105    return this.rootNode;106  }107  add(node) {108    this.top.children.push(node);109  }110  openNode(kind) {111    const node = {kind, children: []};112    this.add(node);113    this.stack.push(node);114  }115  closeNode() {116    if (this.stack.length > 1) {117      return this.stack.pop();118    }119    return void 0;120  }121  closeAllNodes() {122    while (this.closeNode())123      ;124  }125  toJSON() {126    return JSON.stringify(this.rootNode, null, 4);127  }128  walk(builder) {129    return this.constructor._walk(builder, this.rootNode);130  }131  static _walk(builder, node) {132    if (typeof node === "string") {133      builder.addText(node);134    } else if (node.children) {135      builder.openNode(node);136      node.children.forEach((child) => this._walk(builder, child));137      builder.closeNode(node);138    }139    return builder;140  }141  static _collapse(node) {142    if (typeof node === "string")143      return;144    if (!node.children)145      return;146    if (node.children.every((el) => typeof el === "string")) {147      node.children = [node.children.join("")];148    } else {149      node.children.forEach((child) => {150        TokenTree._collapse(child);151      });152    }153  }154}155class TokenTreeEmitter extends TokenTree {156  constructor(options) {157    super();158    this.options = options;159  }160  addKeyword(text, kind) {161    if (text === "") {162      return;163    }164    this.openNode(kind);165    this.addText(text);166    this.closeNode();167  }168  addText(text) {169    if (text === "") {170      return;171    }172    this.add(text);173  }174  addSublanguage(emitter, name) {175    const node = emitter.root;176    node.kind = name;177    node.sublanguage = true;178    this.add(node);179  }180  toHTML() {181    const renderer = new HTMLRenderer(this, this.options);182    return renderer.value();183  }184  finalize() {185    return true;186  }187}188function source(re) {189  if (!re)190    return null;191  if (typeof re === "string")192    return re;193  return re.source;194}195function lookahead(re) {196  return concat("(?=", re, ")");197}198function anyNumberOfTimes(re) {199  return concat("(?:", re, ")*");200}201function optional(re) {202  return concat("(?:", re, ")?");203}204function concat(...args) {205  const joined = args.map((x) => source(x)).join("");206  return joined;207}208function stripOptionsFromArgs(args) {209  const opts = args[args.length - 1];210  if (typeof opts === "object" && opts.constructor === Object) {211    args.splice(args.length - 1, 1);212    return opts;213  } else {214    return {};215  }216}217function either(...args) {218  const opts = stripOptionsFromArgs(args);219  const joined = "(" + (opts.capture ? "" : "?:") + args.map((x) => source(x)).join("|") + ")";220  return joined;221}222function countMatchGroups(re) {223  return new RegExp(re.toString() + "|").exec("").length - 1;224}225function startsWith(re, lexeme) {226  const match = re && re.exec(lexeme);227  return match && match.index === 0;228}229const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;230function _rewriteBackreferences(regexps, {joinWith}) {231  let numCaptures = 0;232  return regexps.map((regex) => {233    numCaptures += 1;234    const offset = numCaptures;235    let re = source(regex);236    let out = "";237    while (re.length > 0) {238      const match = BACKREF_RE.exec(re);239      if (!match) {240        out += re;241        break;242      }243      out += re.substring(0, match.index);244      re = re.substring(match.index + match[0].length);245      if (match[0][0] === "\\" && match[1]) {246        out += "\\" + String(Number(match[1]) + offset);247      } else {248        out += match[0];249        if (match[0] === "(") {250          numCaptures++;251        }252      }253    }254    return out;255  }).map((re) => `(${re})`).join(joinWith);256}257const MATCH_NOTHING_RE = /\b\B/;258const IDENT_RE = "[a-zA-Z]\\w*";259const UNDERSCORE_IDENT_RE = "[a-zA-Z_]\\w*";260const NUMBER_RE = "\\b\\d+(\\.\\d+)?";261const C_NUMBER_RE = "(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";262const BINARY_NUMBER_RE = "\\b(0b[01]+)";263const RE_STARTERS_RE = "!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";264const SHEBANG = (opts = {}) => {265  const beginShebang = /^#![ ]*\//;266  if (opts.binary) {267    opts.begin = concat(beginShebang, /.*\b/, opts.binary, /\b.*/);268  }269  return inherit$1({270    scope: "meta",271    begin: beginShebang,272    end: /$/,273    relevance: 0,274    "on:begin": (m, resp) => {275      if (m.index !== 0)276        resp.ignoreMatch();277    }278  }, opts);279};280const BACKSLASH_ESCAPE = {281  begin: "\\\\[\\s\\S]",282  relevance: 0283};284const APOS_STRING_MODE = {285  scope: "string",286  begin: "'",287  end: "'",288  illegal: "\\n",289  contains: [BACKSLASH_ESCAPE]290};291const QUOTE_STRING_MODE = {292  scope: "string",293  begin: '"',294  end: '"',295  illegal: "\\n",296  contains: [BACKSLASH_ESCAPE]297};298const PHRASAL_WORDS_MODE = {299  begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/300};301const COMMENT = function(begin, end, modeOptions = {}) {302  const mode = inherit$1({303    scope: "comment",304    begin,305    end,306    contains: []307  }, modeOptions);308  mode.contains.push({309    scope: "doctag",310    begin: "[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",311    end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,312    excludeBegin: true,313    relevance: 0314  });315  const ENGLISH_WORD = either("I", "a", "is", "so", "us", "to", "at", "if", "in", "it", "on", /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, /[A-Za-z]+[-][a-z]+/, /[A-Za-z][a-z]{2,}/);316  mode.contains.push({317    begin: concat(/[ ]+/, "(", ENGLISH_WORD, /[.]?[:]?([.][ ]|[ ])/, "){3}")318  });319  return mode;320};321const C_LINE_COMMENT_MODE = COMMENT("//", "$");322const C_BLOCK_COMMENT_MODE = COMMENT("/\\*", "\\*/");323const HASH_COMMENT_MODE = COMMENT("#", "$");324const NUMBER_MODE = {325  scope: "number",326  begin: NUMBER_RE,327  relevance: 0328};329const C_NUMBER_MODE = {330  scope: "number",331  begin: C_NUMBER_RE,332  relevance: 0333};334const BINARY_NUMBER_MODE = {335  scope: "number",336  begin: BINARY_NUMBER_RE,337  relevance: 0338};339const REGEXP_MODE = {340  begin: /(?=\/[^/\n]*\/)/,341  contains: [{342    scope: "regexp",343    begin: /\//,344    end: /\/[gimuy]*/,345    illegal: /\n/,346    contains: [347      BACKSLASH_ESCAPE,348      {349        begin: /\[/,350        end: /\]/,351        relevance: 0,352        contains: [BACKSLASH_ESCAPE]353      }354    ]355  }]356};357const TITLE_MODE = {358  scope: "title",359  begin: IDENT_RE,360  relevance: 0361};362const UNDERSCORE_TITLE_MODE = {363  scope: "title",364  begin: UNDERSCORE_IDENT_RE,365  relevance: 0366};367const METHOD_GUARD = {368  begin: "\\.\\s*" + UNDERSCORE_IDENT_RE,369  relevance: 0370};371const END_SAME_AS_BEGIN = function(mode) {372  return Object.assign(mode, {373    "on:begin": (m, resp) => {374      resp.data._beginMatch = m[1];375    },376    "on:end": (m, resp) => {377      if (resp.data._beginMatch !== m[1])378        resp.ignoreMatch();379    }380  });381};382var MODES = /* @__PURE__ */ Object.freeze({383  __proto__: null,384  MATCH_NOTHING_RE,385  IDENT_RE,386  UNDERSCORE_IDENT_RE,387  NUMBER_RE,388  C_NUMBER_RE,389  BINARY_NUMBER_RE,390  RE_STARTERS_RE,391  SHEBANG,392  BACKSLASH_ESCAPE,393  APOS_STRING_MODE,394  QUOTE_STRING_MODE,395  PHRASAL_WORDS_MODE,396  COMMENT,397  C_LINE_COMMENT_MODE,398  C_BLOCK_COMMENT_MODE,399  HASH_COMMENT_MODE,400  NUMBER_MODE,401  C_NUMBER_MODE,402  BINARY_NUMBER_MODE,403  REGEXP_MODE,404  TITLE_MODE,405  UNDERSCORE_TITLE_MODE,406  METHOD_GUARD,407  END_SAME_AS_BEGIN408});409function skipIfHasPrecedingDot(match, response) {410  const before = match.input[match.index - 1];411  if (before === ".") {412    response.ignoreMatch();413  }414}415function scopeClassName(mode, _parent) {416  if (mode.className !== void 0) {417    mode.scope = mode.className;418    delete mode.className;419  }420}421function beginKeywords(mode, parent) {422  if (!parent)423    return;424  if (!mode.beginKeywords)425    return;426  mode.begin = "\\b(" + mode.beginKeywords.split(" ").join("|") + ")(?!\\.)(?=\\b|\\s)";427  mode.__beforeBegin = skipIfHasPrecedingDot;428  mode.keywords = mode.keywords || mode.beginKeywords;429  delete mode.beginKeywords;430  if (mode.relevance === void 0)431    mode.relevance = 0;432}433function compileIllegal(mode, _parent) {434  if (!Array.isArray(mode.illegal))435    return;436  mode.illegal = either(...mode.illegal);437}438function compileMatch(mode, _parent) {439  if (!mode.match)440    return;441  if (mode.begin || mode.end)442    throw new Error("begin & end are not supported with match");443  mode.begin = mode.match;444  delete mode.match;445}446function compileRelevance(mode, _parent) {447  if (mode.relevance === void 0)448    mode.relevance = 1;449}450const beforeMatchExt = (mode, parent) => {451  if (!mode.beforeMatch)452    return;453  if (mode.starts)454    throw new Error("beforeMatch cannot be used with starts");455  const originalMode = Object.assign({}, mode);456  Object.keys(mode).forEach((key) => {457    delete mode[key];458  });459  mode.keywords = originalMode.keywords;460  mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));461  mode.starts = {462    relevance: 0,463    contains: [464      Object.assign(originalMode, {endsParent: true})465    ]466  };467  mode.relevance = 0;468  delete originalMode.beforeMatch;469};470const COMMON_KEYWORDS = [471  "of",472  "and",473  "for",474  "in",475  "not",476  "or",477  "if",478  "then",479  "parent",480  "list",481  "value"482];483const DEFAULT_KEYWORD_SCOPE = "keyword";484function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {485  const compiledKeywords = Object.create(null);486  if (typeof rawKeywords === "string") {487    compileList(scopeName, rawKeywords.split(" "));488  } else if (Array.isArray(rawKeywords)) {489    compileList(scopeName, rawKeywords);490  } else {491    Object.keys(rawKeywords).forEach(function(scopeName2) {492      Object.assign(compiledKeywords, compileKeywords(rawKeywords[scopeName2], caseInsensitive, scopeName2));493    });494  }495  return compiledKeywords;496  function compileList(scopeName2, keywordList) {497    if (caseInsensitive) {498      keywordList = keywordList.map((x) => x.toLowerCase());499    }500    keywordList.forEach(function(keyword) {501      const pair = keyword.split("|");502      compiledKeywords[pair[0]] = [scopeName2, scoreForKeyword(pair[0], pair[1])];503    });504  }505}506function scoreForKeyword(keyword, providedScore) {507  if (providedScore) {508    return Number(providedScore);509  }510  return commonKeyword(keyword) ? 0 : 1;511}512function commonKeyword(keyword) {513  return COMMON_KEYWORDS.includes(keyword.toLowerCase());514}515const seenDeprecations = {};516const error = (message) => {517  console.error(message);518};519const warn = (message, ...args) => {520  console.log(`WARN: ${message}`, ...args);521};522const deprecated = (version2, message) => {523  if (seenDeprecations[`${version2}/${message}`])524    return;525  console.log(`Deprecated as of ${version2}. ${message}`);526  seenDeprecations[`${version2}/${message}`] = true;527};528const MultiClassError = new Error();529function remapScopeNames(mode, regexes, {key}) {530  let offset = 0;531  const scopeNames = mode[key];532  const emit = {};533  const positions = {};534  for (let i = 1; i <= regexes.length; i++) {535    positions[i + offset] = scopeNames[i];536    emit[i + offset] = true;537    offset += countMatchGroups(regexes[i - 1]);538  }539  mode[key] = positions;540  mode[key]._emit = emit;541  mode[key]._multi = true;542}543function beginMultiClass(mode) {544  if (!Array.isArray(mode.begin))545    return;546  if (mode.skip || mode.excludeBegin || mode.returnBegin) {547    error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");548    throw MultiClassError;549  }550  if (typeof mode.beginScope !== "object" || mode.beginScope === null) {551    error("beginScope must be object");552    throw MultiClassError;553  }554  remapScopeNames(mode, mode.begin, {key: "beginScope"});555  mode.begin = _rewriteBackreferences(mode.begin, {joinWith: ""});556}557function endMultiClass(mode) {558  if (!Array.isArray(mode.end))559    return;560  if (mode.skip || mode.excludeEnd || mode.returnEnd) {561    error("skip, excludeEnd, returnEnd not compatible with endScope: {}");562    throw MultiClassError;563  }564  if (typeof mode.endScope !== "object" || mode.endScope === null) {565    error("endScope must be object");566    throw MultiClassError;567  }568  remapScopeNames(mode, mode.end, {key: "endScope"});569  mode.end = _rewriteBackreferences(mode.end, {joinWith: ""});570}571function scopeSugar(mode) {572  if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {573    mode.beginScope = mode.scope;574    delete mode.scope;575  }576}577function MultiClass(mode) {578  scopeSugar(mode);579  if (typeof mode.beginScope === "string") {580    mode.beginScope = {_wrap: mode.beginScope};581  }582  if (typeof mode.endScope === "string") {583    mode.endScope = {_wrap: mode.endScope};584  }585  beginMultiClass(mode);586  endMultiClass(mode);587}588function compileLanguage(language) {589  function langRe(value, global) {590    return new RegExp(source(value), "m" + (language.case_insensitive ? "i" : "") + (language.unicodeRegex ? "u" : "") + (global ? "g" : ""));591  }592  class MultiRegex {593    constructor() {594      this.matchIndexes = {};595      this.regexes = [];596      this.matchAt = 1;597      this.position = 0;598    }599    addRule(re, opts) {600      opts.position = this.position++;601      this.matchIndexes[this.matchAt] = opts;602      this.regexes.push([opts, re]);603      this.matchAt += countMatchGroups(re) + 1;604    }605    compile() {606      if (this.regexes.length === 0) {607        this.exec = () => null;608      }609      const terminators = this.regexes.map((el) => el[1]);610      this.matcherRe = langRe(_rewriteBackreferences(terminators, {joinWith: "|"}), true);611      this.lastIndex = 0;612    }613    exec(s) {614      this.matcherRe.lastIndex = this.lastIndex;615      const match = this.matcherRe.exec(s);616      if (!match) {617        return null;618      }619      const i = match.findIndex((el, i2) => i2 > 0 && el !== void 0);620      const matchData = this.matchIndexes[i];621      match.splice(0, i);622      return Object.assign(match, matchData);623    }624  }625  class ResumableMultiRegex {626    constructor() {627      this.rules = [];628      this.multiRegexes = [];629      this.count = 0;630      this.lastIndex = 0;631      this.regexIndex = 0;632    }633    getMatcher(index) {634      if (this.multiRegexes[index])635        return this.multiRegexes[index];636      const matcher = new MultiRegex();637      this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));638      matcher.compile();639      this.multiRegexes[index] = matcher;640      return matcher;641    }642    resumingScanAtSamePosition() {643      return this.regexIndex !== 0;644    }645    considerAll() {646      this.regexIndex = 0;647    }648    addRule(re, opts) {649      this.rules.push([re, opts]);650      if (opts.type === "begin")651        this.count++;652    }653    exec(s) {654      const m = this.getMatcher(this.regexIndex);655      m.lastIndex = this.lastIndex;656      let result = m.exec(s);657      if (this.resumingScanAtSamePosition()) {658        if (result && result.index === this.lastIndex)659          ;660        else {661          const m2 = this.getMatcher(0);662          m2.lastIndex = this.lastIndex + 1;663          result = m2.exec(s);664        }665      }666      if (result) {667        this.regexIndex += result.position + 1;668        if (this.regexIndex === this.count) {669          this.considerAll();670        }671      }672      return result;673    }674  }675  function buildModeRegex(mode) {676    const mm = new ResumableMultiRegex();677    mode.contains.forEach((term) => mm.addRule(term.begin, {rule: term, type: "begin"}));678    if (mode.terminatorEnd) {679      mm.addRule(mode.terminatorEnd, {type: "end"});680    }681    if (mode.illegal) {682      mm.addRule(mode.illegal, {type: "illegal"});683    }684    return mm;685  }686  function compileMode(mode, parent) {687    const cmode = mode;688    if (mode.isCompiled)689      return cmode;690    [691      scopeClassName,692      compileMatch,693      MultiClass,694      beforeMatchExt695    ].forEach((ext) => ext(mode, parent));696    language.compilerExtensions.forEach((ext) => ext(mode, parent));697    mode.__beforeBegin = null;698    [699      beginKeywords,700      compileIllegal,701      compileRelevance702    ].forEach((ext) => ext(mode, parent));703    mode.isCompiled = true;704    let keywordPattern = null;705    if (typeof mode.keywords === "object" && mode.keywords.$pattern) {706      mode.keywords = Object.assign({}, mode.keywords);707      keywordPattern = mode.keywords.$pattern;708      delete mode.keywords.$pattern;709    }710    keywordPattern = keywordPattern || /\w+/;711    if (mode.keywords) {712      mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);713    }714    cmode.keywordPatternRe = langRe(keywordPattern, true);715    if (parent) {716      if (!mode.begin)717        mode.begin = /\B|\b/;718      cmode.beginRe = langRe(cmode.begin);719      if (!mode.end && !mode.endsWithParent)720        mode.end = /\B|\b/;721      if (mode.end)722        cmode.endRe = langRe(cmode.end);723      cmode.terminatorEnd = source(cmode.end) || "";724      if (mode.endsWithParent && parent.terminatorEnd) {725        cmode.terminatorEnd += (mode.end ? "|" : "") + parent.terminatorEnd;726      }727    }728    if (mode.illegal)729      cmode.illegalRe = langRe(mode.illegal);730    if (!mode.contains)731      mode.contains = [];732    mode.contains = [].concat(...mode.contains.map(function(c) {733      return expandOrCloneMode(c === "self" ? mode : c);734    }));735    mode.contains.forEach(function(c) {736      compileMode(c, cmode);737    });738    if (mode.starts) {739      compileMode(mode.starts, parent);740    }741    cmode.matcher = buildModeRegex(cmode);742    return cmode;743  }744  if (!language.compilerExtensions)745    language.compilerExtensions = [];746  if (language.contains && language.contains.includes("self")) {747    throw new Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.");748  }749  language.classNameAliases = inherit$1(language.classNameAliases || {});750  return compileMode(language);751}752function dependencyOnParent(mode) {753  if (!mode)754    return false;755  return mode.endsWithParent || dependencyOnParent(mode.starts);756}757function expandOrCloneMode(mode) {758  if (mode.variants && !mode.cachedVariants) {759    mode.cachedVariants = mode.variants.map(function(variant) {760      return inherit$1(mode, {variants: null}, variant);761    });762  }763  if (mode.cachedVariants) {764    return mode.cachedVariants;765  }766  if (dependencyOnParent(mode)) {767    return inherit$1(mode, {starts: mode.starts ? inherit$1(mode.starts) : null});768  }769  if (Object.isFrozen(mode)) {770    return inherit$1(mode);771  }772  return mode;773}774var version = "11.3.1";775class HTMLInjectionError extends Error {776  constructor(reason, html) {777    super(reason);778    this.name = "HTMLInjectionError";779    this.html = html;780  }781}782const escape = escapeHTML;783const inherit = inherit$1;784const NO_MATCH = Symbol("nomatch");785const MAX_KEYWORD_HITS = 7;786const HLJS = function(hljs) {787  const languages = Object.create(null);788  const aliases = Object.create(null);789  const plugins = [];790  let SAFE_MODE = true;791  const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?";792  const PLAINTEXT_LANGUAGE = {disableAutodetect: true, name: "Plain text", contains: []};793  let options = {794    ignoreUnescapedHTML: false,795    throwUnescapedHTML: false,796    noHighlightRe: /^(no-?highlight)$/i,797    languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,798    classPrefix: "hljs-",799    cssSelector: "pre code",800    languages: null,801    __emitter: TokenTreeEmitter802  };803  function shouldNotHighlight(languageName) {804    return options.noHighlightRe.test(languageName);805  }806  function blockLanguage(block) {807    let classes = block.className + " ";808    classes += block.parentNode ? block.parentNode.className : "";809    const match = options.languageDetectRe.exec(classes);810    if (match) {811      const language = getLanguage(match[1]);812      if (!language) {813        warn(LANGUAGE_NOT_FOUND.replace("{}", match[1]));814        warn("Falling back to no-highlight mode for this block.", block);815      }816      return language ? match[1] : "no-highlight";817    }818    return classes.split(/\s+/).find((_class) => shouldNotHighlight(_class) || getLanguage(_class));819  }820  function highlight2(codeOrLanguageName, optionsOrCode, ignoreIllegals) {821    let code = "";822    let languageName = "";823    if (typeof optionsOrCode === "object") {824      code = codeOrLanguageName;825      ignoreIllegals = optionsOrCode.ignoreIllegals;826      languageName = optionsOrCode.language;827    } else {828      deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated.");829      deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277");830      languageName = codeOrLanguageName;831      code = optionsOrCode;832    }833    if (ignoreIllegals === void 0) {834      ignoreIllegals = true;835    }836    const context = {837      code,838      language: languageName839    };840    fire("before:highlight", context);841    const result = context.result ? context.result : _highlight(context.language, context.code, ignoreIllegals);842    result.code = context.code;843    fire("after:highlight", result);844    return result;845  }846  function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {847    const keywordHits = Object.create(null);848    function keywordData(mode, matchText) {849      return mode.keywords[matchText];850    }851    function processKeywords() {852      if (!top.keywords) {853        emitter.addText(modeBuffer);854        return;855      }856      let lastIndex = 0;857      top.keywordPatternRe.lastIndex = 0;858      let match = top.keywordPatternRe.exec(modeBuffer);859      let buf = "";860      while (match) {861        buf += modeBuffer.substring(lastIndex, match.index);862        const word = language.case_insensitive ? match[0].toLowerCase() : match[0];863        const data = keywordData(top, word);864        if (data) {865          const [kind, keywordRelevance] = data;866          emitter.addText(buf);867          buf = "";868          keywordHits[word] = (keywordHits[word] || 0) + 1;869          if (keywordHits[word] <= MAX_KEYWORD_HITS)870            relevance += keywordRelevance;871          if (kind.startsWith("_")) {872            buf += match[0];873          } else {874            const cssClass = language.classNameAliases[kind] || kind;875            emitter.addKeyword(match[0], cssClass);876          }877        } else {878          buf += match[0];879        }880        lastIndex = top.keywordPatternRe.lastIndex;881        match = top.keywordPatternRe.exec(modeBuffer);882      }883      buf += modeBuffer.substr(lastIndex);884      emitter.addText(buf);885    }886    function processSubLanguage() {887      if (modeBuffer === "")888        return;889      let result2 = null;890      if (typeof top.subLanguage === "string") {891        if (!languages[top.subLanguage]) {892          emitter.addText(modeBuffer);893          return;894        }895        result2 = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);896        continuations[top.subLanguage] = result2._top;897      } else {898        result2 = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);899      }900      if (top.relevance > 0) {901        relevance += result2.relevance;902      }903      emitter.addSublanguage(result2._emitter, result2.language);904    }905    function processBuffer() {906      if (top.subLanguage != null) {907        processSubLanguage();908      } else {909        processKeywords();910      }911      modeBuffer = "";912    }913    function emitMultiClass(scope, match) {914      let i = 1;915      while (match[i] !== void 0) {916        if (!scope._emit[i]) {917          i++;918          continue;919        }920        const klass = language.classNameAliases[scope[i]] || scope[i];921        const text = match[i];922        if (klass) {923          emitter.addKeyword(text, klass);924        } else {925          modeBuffer = text;926          processKeywords();927          modeBuffer = "";928        }929        i++;930      }931    }932    function startNewMode(mode, match) {933      if (mode.scope && typeof mode.scope === "string") {934        emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);935      }936      if (mode.beginScope) {937        if (mode.beginScope._wrap) {938          emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);939          modeBuffer = "";940        } else if (mode.beginScope._multi) {941          emitMultiClass(mode.beginScope, match);942          modeBuffer = "";943        }944      }945      top = Object.create(mode, {parent: {value: top}});946      return top;947    }948    function endOfMode(mode, match, matchPlusRemainder) {949      let matched = startsWith(mode.endRe, matchPlusRemainder);950      if (matched) {951        if (mode["on:end"]) {952          const resp = new Response(mode);953          mode["on:end"](match, resp);954          if (resp.isMatchIgnored)955            matched = false;956        }957        if (matched) {958          while (mode.endsParent && mode.parent) {959            mode = mode.parent;960          }961          return mode;962        }963      }964      if (mode.endsWithParent) {965        return endOfMode(mode.parent, match, matchPlusRemainder);966      }967    }968    function doIgnore(lexeme) {969      if (top.matcher.regexIndex === 0) {970        modeBuffer += lexeme[0];971        return 1;972      } else {973        resumeScanAtSamePosition = true;974        return 0;975      }976    }977    function doBeginMatch(match) {978      const lexeme = match[0];979      const newMode = match.rule;980      const resp = new Response(newMode);981      const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]];982      for (const cb of beforeCallbacks) {983        if (!cb)984          continue;985        cb(match, resp);986        if (resp.isMatchIgnored)987          return doIgnore(lexeme);988      }989      if (newMode.skip) {990        modeBuffer += lexeme;991      } else {992        if (newMode.excludeBegin) {993          modeBuffer += lexeme;994        }995        processBuffer();996        if (!newMode.returnBegin && !newMode.excludeBegin) {997          modeBuffer = lexeme;998        }999      }1000      startNewMode(newMode, match);1001      return newMode.returnBegin ? 0 : lexeme.length;1002    }1003    function doEndMatch(match) {1004      const lexeme = match[0];1005      const matchPlusRemainder = codeToHighlight.substr(match.index);1006      const endMode = endOfMode(top, match, matchPlusRemainder);1007      if (!endMode) {1008        return NO_MATCH;1009      }1010      const origin = top;1011      if (top.endScope && top.endScope._wrap) {1012        processBuffer();1013        emitter.addKeyword(lexeme, top.endScope._wrap);1014      } else if (top.endScope && top.endScope._multi) {1015        processBuffer();1016        emitMultiClass(top.endScope, match);1017      } else if (origin.skip) {1018        modeBuffer += lexeme;1019      } else {1020        if (!(origin.returnEnd || origin.excludeEnd)) {1021          modeBuffer += lexeme;1022        }1023        processBuffer();1024        if (origin.excludeEnd) {1025          modeBuffer = lexeme;1026        }1027      }1028      do {1029        if (top.scope) {1030          emitter.closeNode();1031        }1032        if (!top.skip && !top.subLanguage) {1033          relevance += top.relevance;1034        }1035        top = top.parent;1036      } while (top !== endMode.parent);1037      if (endMode.starts) {1038        startNewMode(endMode.starts, match);1039      }1040      return origin.returnEnd ? 0 : lexeme.length;1041    }1042    function processContinuations() {1043      const list = [];1044      for (let current = top; current !== language; current = current.parent) {1045        if (current.scope) {1046          list.unshift(current.scope);1047        }1048      }1049      list.forEach((item) => emitter.openNode(item));1050    }1051    let lastMatch = {};1052    function processLexeme(textBeforeMatch, match) {1053      const lexeme = match && match[0];1054      modeBuffer += textBeforeMatch;1055      if (lexeme == null) {1056        processBuffer();1057        return 0;1058      }1059      if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") {1060        modeBuffer += codeToHighlight.slice(match.index, match.index + 1);1061        if (!SAFE_MODE) {1062          const err = new Error(`0 width match regex (${languageName})`);1063          err.languageName = languageName;1064          err.badRule = lastMatch.rule;1065          throw err;1066        }1067        return 1;1068      }1069      lastMatch = match;1070      if (match.type === "begin") {1071        return doBeginMatch(match);1072      } else if (match.type === "illegal" && !ignoreIllegals) {1073        const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || "<unnamed>") + '"');1074        err.mode = top;1075        throw err;1076      } else if (match.type === "end") {1077        const processed = doEndMatch(match);1078        if (processed !== NO_MATCH) {1079          return processed;1080        }1081      }1082      if (match.type === "illegal" && lexeme === "") {1083        return 1;1084      }1085      if (iterations > 1e5 && iterations > match.index * 3) {1086        const err = new Error("potential infinite loop, way more iterations than matches");1087        throw err;1088      }1089      modeBuffer += lexeme;1090      return lexeme.length;1091    }1092    const language = getLanguage(languageName);1093    if (!language) {1094      error(LANGUAGE_NOT_FOUND.replace("{}", languageName));1095      throw new Error('Unknown language: "' + languageName + '"');1096    }1097    const md = compileLanguage(language);1098    let result = "";1099    let top = continuation || md;1100    const continuations = {};1101    const emitter = new options.__emitter(options);1102    processContinuations();1103    let modeBuffer = "";1104    let relevance = 0;1105    let index = 0;1106    let iterations = 0;1107    let resumeScanAtSamePosition = false;1108    try {1109      top.matcher.considerAll();1110      for (; ; ) {1111        iterations++;1112        if (resumeScanAtSamePosition) {1113          resumeScanAtSamePosition = false;1114        } else {1115          top.matcher.considerAll();1116        }1117        top.matcher.lastIndex = index;1118        const match = top.matcher.exec(codeToHighlight);1119        if (!match)1120          break;1121        const beforeMatch = codeToHighlight.substring(index, match.index);1122        const processedCount = processLexeme(beforeMatch, match);1123        index = match.index + processedCount;1124      }1125      processLexeme(codeToHighlight.substr(index));1126      emitter.closeAllNodes();1127      emitter.finalize();1128      result = emitter.toHTML();1129      return {1130        language: languageName,1131        value: result,1132        relevance,1133        illegal: false,1134        _emitter: emitter,1135        _top: top1136      };1137    } catch (err) {1138      if (err.message && err.message.includes("Illegal")) {1139        return {1140          language: languageName,1141          value: escape(codeToHighlight),1142          illegal: true,1143          relevance: 0,1144          _illegalBy: {1145            message: err.message,1146            index,1147            context: codeToHighlight.slice(index - 100, index + 100),1148            mode: err.mode,1149            resultSoFar: result1150          },1151          _emitter: emitter1152        };1153      } else if (SAFE_MODE) {1154        return {1155          language: languageName,1156          value: escape(codeToHighlight),1157          illegal: false,1158          relevance: 0,1159          errorRaised: err,1160          _emitter: emitter,1161          _top: top1162        };1163      } else {1164        throw err;1165      }1166    }1167  }1168  function justTextHighlightResult(code) {1169    const result = {1170      value: escape(code),1171      illegal: false,1172      relevance: 0,1173      _top: PLAINTEXT_LANGUAGE,1174      _emitter: new options.__emitter(options)1175    };1176    result._emitter.addText(code);1177    return result;1178  }1179  function highlightAuto(code, languageSubset) {1180    languageSubset = languageSubset || options.languages || Object.keys(languages);1181    const plaintext = justTextHighlightResult(code);1182    const results = languageSubset.filter(getLanguage).filter(autoDetection).map((name) => _highlight(name, code, false));1183    results.unshift(plaintext);1184    const sorted = results.sort((a, b) => {1185      if (a.relevance !== b.relevance)1186        return b.relevance - a.relevance;1187      if (a.language && b.language) {1188        if (getLanguage(a.language).supersetOf === b.language) {1189          return 1;1190        } else if (getLanguage(b.language).supersetOf === a.language) {1191          return -1;1192        }1193      }1194      return 0;1195    });1196    const [best, secondBest] = sorted;1197    const result = best;1198    result.secondBest = secondBest;1199    return result;1200  }1201  function updateClassName(element, currentLang, resultLang) {1202    const language = currentLang && aliases[currentLang] || resultLang;1203    element.classList.add("hljs");1204    element.classList.add(`language-${language}`);1205  }1206  function highlightElement(element) {1207    let node = null;1208    const language = blockLanguage(element);1209    if (shouldNotHighlight(language))1210      return;1211    fire("before:highlightElement", {el: element, language});1212    if (element.children.length > 0) {1213      if (!options.ignoreUnescapedHTML) {1214        console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk.");1215        console.warn("https://github.com/highlightjs/highlight.js/issues/2886");1216        console.warn(element);1217      }1218      if (options.throwUnescapedHTML) {1219        const err = new HTMLInjectionError("One of your code blocks includes unescaped HTML.", element.innerHTML);1220        throw err;1221      }1222    }1223    node = element;1224    const text = node.textContent;1225    const result = language ? highlight2(text, {language, ignoreIllegals: true}) : highlightAuto(text);1226    element.innerHTML = result.value;1227    updateClassName(element, language, result.language);1228    element.result = {1229      language: result.language,1230      re: result.relevance,1231      relevance: result.relevance1232    };1233    if (result.secondBest) {1234      element.secondBest = {1235        language: result.secondBest.language,1236        relevance: result.secondBest.relevance1237      };1238    }1239    fire("after:highlightElement", {el: element, result, text});1240  }1241  function configure(userOptions) {1242    options = inherit(options, userOptions);1243  }1244  const initHighlighting = () => {1245    highlightAll();1246    deprecated("10.6.0", "initHighlighting() deprecated.  Use highlightAll() now.");1247  };1248  function initHighlightingOnLoad() {1249    highlightAll();1250    deprecated("10.6.0", "initHighlightingOnLoad() deprecated.  Use highlightAll() now.");1251  }1252  let wantsHighlight = false;1253  function highlightAll() {1254    if (document.readyState === "loading") {1255      wantsHighlight = true;1256      return;1257    }1258    const blocks = document.querySelectorAll(options.cssSelector);1259    blocks.forEach(highlightElement);1260  }1261  function boot() {1262    if (wantsHighlight)1263      highlightAll();1264  }1265  if (typeof window !== "undefined" && window.addEventListener) {1266    window.addEventListener("DOMContentLoaded", boot, false);1267  }1268  function registerLanguage(languageName, languageDefinition) {1269    let lang = null;1270    try {1271      lang = languageDefinition(hljs);1272    } catch (error$1) {1273      error("Language definition for '{}' could not be registered.".replace("{}", languageName));1274      if (!SAFE_MODE) {1275        throw error$1;1276      } else {1277        error(error$1);1278      }1279      lang = PLAINTEXT_LANGUAGE;1280    }1281    if (!lang.name)1282      lang.name = languageName;1283    languages[languageName] = lang;1284    lang.rawDefinition = languageDefinition.bind(null, hljs);1285    if (lang.aliases) {1286      registerAliases(lang.aliases, {languageName});1287    }1288  }1289  function unregisterLanguage(languageName) {1290    delete languages[languageName];1291    for (const alias of Object.keys(aliases)) {1292      if (aliases[alias] === languageName) {1293        delete aliases[alias];1294      }1295    }1296  }1297  function listLanguages() {1298    return Object.keys(languages);1299  }1300  function getLanguage(name) {1301    name = (name || "").toLowerCase();1302    return languages[name] || languages[aliases[name]];1303  }1304  function registerAliases(aliasList, {languageName}) {1305    if (typeof aliasList === "string") {1306      aliasList = [aliasList];1307    }1308    aliasList.forEach((alias) => {1309      aliases[alias.toLowerCase()] = languageName;1310    });1311  }1312  function autoDetection(name) {1313    const lang = getLanguage(name);1314    return lang && !lang.disableAutodetect;1315  }1316  function upgradePluginAPI(plugin) {1317    if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) {1318      plugin["before:highlightElement"] = (data) => {1319        plugin["before:highlightBlock"](Object.assign({block: data.el}, data));1320      };1321    }1322    if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) {1323      plugin["after:highlightElement"] = (data) => {1324        plugin["after:highlightBlock"](Object.assign({block: data.el}, data));1325      };1326    }1327  }1328  function addPlugin(plugin) {1329    upgradePluginAPI(plugin);1330    plugins.push(plugin);1331  }1332  function fire(event, args) {1333    const cb = event;1334    plugins.forEach(function(plugin) {1335      if (plugin[cb]) {1336        plugin[cb](args);1337      }1338    });1339  }1340  function deprecateHighlightBlock(el) {1341    deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0");1342    deprecated("10.7.0", "Please use highlightElement now.");1343    return highlightElement(el);1344  }1345  Object.assign(hljs, {1346    highlight: highlight2,1347    highlightAuto,1348    highlightAll,1349    highlightElement,1350    highlightBlock: deprecateHighlightBlock,1351    configure,1352    initHighlighting,1353    initHighlightingOnLoad,1354    registerLanguage,1355    unregisterLanguage,1356    listLanguages,1357    getLanguage,1358    registerAliases,1359    autoDetection,1360    inherit,1361    addPlugin1362  });1363  hljs.debugMode = function() {1364    SAFE_MODE = false;1365  };1366  hljs.safeMode = function() {1367    SAFE_MODE = true;1368  };1369  hljs.versionString = version;1370  hljs.regex = {1371    concat,1372    lookahead,1373    either,1374    optional,1375    anyNumberOfTimes1376  };1377  for (const key in MODES) {1378    if (typeof MODES[key] === "object") {1379      deepFreeze$1(MODES[key]);1380    }1381  }1382  Object.assign(hljs, MODES);1383  return hljs;1384};1385var highlight = HLJS({});1386var core = highlight;1387highlight.HighlightJS = highlight;1388highlight.default = highlight;1389export {core as c};...coder.js
Source:coder.js  
...413  UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,414  METHOD_GUARD: METHOD_GUARD,415  END_SAME_AS_BEGIN: END_SAME_AS_BEGIN416});417function skipIfhasPrecedingDot(match, response) {418  const before = match.input[match.MySQL - 1];419  if (before === ".") {420    response.ignoreMatch();421  }422}423/**424 * `beginKeywords` syntactic sugar425 * @type {CompilerExt}426 */427function beginKeywords(mode, parent) {428  if (!parent) return;429  if (!mode.beginKeywords) return;430  431  mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)';...core.js
Source:core.js  
1function deepFreeze(obj) {2    if (obj instanceof Map) {3        obj.clear = obj.delete = obj.set = function () {4            throw new Error('map is read-only');5        };6    } else if (obj instanceof Set) {7        obj.add = obj.clear = obj.delete = function () {8            throw new Error('set is read-only');9        };10    }11    Object.freeze(obj);12    Object.getOwnPropertyNames(obj).forEach(function (name) {13        var prop = obj[name];14        if (typeof prop == 'object' && !Object.isFrozen(prop)) {15            deepFreeze(prop);16        }17    });18    return obj;19}20class Response {21  constructor(mode) {22    // eslint-disable-next-line no-undefined23    if (mode.data === undefined) mode.data = {};24    this.data = mode.data;25    this.isMatchIgnored = false;26  }27  ignoreMatch() {28    this.isMatchIgnored = true;29  }30}31function escapeHTML(value) {32  return value33    .replace(/&/g, '&')34    .replace(/</g, '<')35    .replace(/>/g, '>')36    .replace(/"/g, '"')37    .replace(/'/g, ''');38}39function inherit$1(original, ...objects) {40  const result = Object.create(null);41  for (const key in original) {42    result[key] = original[key];43  }44  objects.forEach(function(obj) {45    for (const key in obj) {46      result[key] = obj[key];47    }48  });49  return result;50}51const SPAN_CLOSE = '</span>';52const emitsWrappingTags = (node) => {53  return !!node.kind;54};55const expandScopeName = (name, { prefix }) => {56  if (name.includes(".")) {57    const pieces = name.split(".");58    return [59      `${prefix}${pieces.shift()}`,60      ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`))61    ].join(" ");62  }63  return `${prefix}${name}`;64};65class HTMLRenderer {66  constructor(parseTree, options) {67    this.buffer = "";68    this.classPrefix = options.classPrefix;69    parseTree.walk(this);70  }71  addText(text) {72    this.buffer += escapeHTML(text);73  }74  openNode(node) {75    if (!emitsWrappingTags(node)) return;76    let scope = node.kind;77    if (node.sublanguage) {78      scope = `language-${scope}`;79    } else {80      scope = expandScopeName(scope, { prefix: this.classPrefix });81    }82    this.span(scope);83  }84  closeNode(node) {85    if (!emitsWrappingTags(node)) return;86    this.buffer += SPAN_CLOSE;87  }88  value() {89    return this.buffer;90  }91  span(className) {92    this.buffer += `<span class="${className}">`;93  }94}95class TokenTree {96  constructor() {97    this.rootNode = { children: [] };98    this.stack = [this.rootNode];99  }100  get top() {101    return this.stack[this.stack.length - 1];102  }103  get root() { return this.rootNode; }104  add(node) {105    this.top.children.push(node);106  }107  openNode(kind) {108    const node = { kind, children: [] };109    this.add(node);110    this.stack.push(node);111  }112  closeNode() {113    if (this.stack.length > 1) {114      return this.stack.pop();115    }116    // eslint-disable-next-line no-undefined117    return undefined;118  }119  closeAllNodes() {120    while (this.closeNode());121  }122  toJSON() {123    return JSON.stringify(this.rootNode, null, 4);124  }125  walk(builder) {126    return this.constructor._walk(builder, this.rootNode);127  }128  static _walk(builder, node) {129    if (typeof node === "string") {130      builder.addText(node);131    } else if (node.children) {132      builder.openNode(node);133      node.children.forEach((child) => this._walk(builder, child));134      builder.closeNode(node);135    }136    return builder;137  }138  static _collapse(node) {139    if (typeof node === "string") return;140    if (!node.children) return;141    if (node.children.every(el => typeof el === "string")) {142      node.children = [node.children.join("")];143    } else {144      node.children.forEach((child) => {145        TokenTree._collapse(child);146      });147    }148  }149}150class TokenTreeEmitter extends TokenTree {151  constructor(options) {152    super();153    this.options = options;154  }155  addKeyword(text, kind) {156    if (text === "") { return; }157    this.openNode(kind);158    this.addText(text);159    this.closeNode();160  }161  addText(text) {162    if (text === "") { return; }163    this.add(text);164  }165  addSublanguage(emitter, name) {166    const node = emitter.root;167    node.kind = name;168    node.sublanguage = true;169    this.add(node);170  }171  toHTML() {172    const renderer = new HTMLRenderer(this, this.options);173    return renderer.value();174  }175  finalize() {176    return true;177  }178}179function source(re) {180  if (!re) return null;181  if (typeof re === "string") return re;182  return re.source;183}184function lookahead(re) {185  return concat('(?=', re, ')');186}187function concat(...args) {188  const joined = args.map((x) => source(x)).join("");189  return joined;190}191function stripOptionsFromArgs(args) {192  const opts = args[args.length - 1];193  if (typeof opts === 'object' && opts.constructor === Object) {194    args.splice(args.length - 1, 1);195    return opts;196  } else {197    return {};198  }199}200function either(...args) {201  const opts = stripOptionsFromArgs(args);202  const joined = '(' +203    (opts.capture ? "" : "?:") +204    args.map((x) => source(x)).join("|") + ")";205  return joined;206}207function countMatchGroups(re) {208  return (new RegExp(re.toString() + '|')).exec('').length - 1;209}210function startsWith(re, lexeme) {211  const match = re && re.exec(lexeme);212  return match && match.index === 0;213}214const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;215function _rewriteBackreferences(regexps, { joinWith }) {216  let numCaptures = 0;217  return regexps.map((regex) => {218    numCaptures += 1;219    const offset = numCaptures;220    let re = source(regex);221    let out = '';222    while (re.length > 0) {223      const match = BACKREF_RE.exec(re);224      if (!match) {225        out += re;226        break;227      }228      out += re.substring(0, match.index);229      re = re.substring(match.index + match[0].length);230      if (match[0][0] === '\\' && match[1]) {231        // Adjust the backreference.232        out += '\\' + String(Number(match[1]) + offset);233      } else {234        out += match[0];235        if (match[0] === '(') {236          numCaptures++;237        }238      }239    }240    return out;241  }).map(re => `(${re})`).join(joinWith);242}243const MATCH_NOTHING_RE = /\b\B/;244const IDENT_RE = '[a-zA-Z]\\w*';245const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*';246const NUMBER_RE = '\\b\\d+(\\.\\d+)?';247const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)';248const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...249const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';250const SHEBANG = (opts = {}) => {251  const beginShebang = /^#![ ]*\//;252  if (opts.binary) {253    opts.begin = concat(254      beginShebang,255      /.*\b/,256      opts.binary,257      /\b.*/);258  }259  return inherit$1({260    scope: 'meta',261    begin: beginShebang,262    end: /$/,263    relevance: 0,264    /** @type {ModeCallback} */265    "on:begin": (m, resp) => {266      if (m.index !== 0) resp.ignoreMatch();267    }268  }, opts);269};270// Common modes271const BACKSLASH_ESCAPE = {272  begin: '\\\\[\\s\\S]', relevance: 0273};274const APOS_STRING_MODE = {275  scope: 'string',276  begin: '\'',277  end: '\'',278  illegal: '\\n',279  contains: [BACKSLASH_ESCAPE]280};281const QUOTE_STRING_MODE = {282  scope: 'string',283  begin: '"',284  end: '"',285  illegal: '\\n',286  contains: [BACKSLASH_ESCAPE]287};288const PHRASAL_WORDS_MODE = {289  begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/290};291const COMMENT = function(begin, end, modeOptions = {}) {292  const mode = inherit$1(293    {294      scope: 'comment',295      begin,296      end,297      contains: []298    },299    modeOptions300  );301  mode.contains.push({302    scope: 'doctag',303    // hack to avoid the space from being included. the space is necessary to304    // match here to prevent the plain text rule below from gobbling up doctags305    begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',306    end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,307    excludeBegin: true,308    relevance: 0309  });310  const ENGLISH_WORD = either(311    // list of common 1 and 2 letter words in English312    "I",313    "a",314    "is",315    "so",316    "us",317    "to",318    "at",319    "if",320    "in",321    "it",322    "on",323    /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc324    /[A-Za-z]+[-][a-z]+/, // `no-way`, etc.325    /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences326  );327  mode.contains.push(328    {329      begin: concat(330        /[ ]+/,331        '(',332        ENGLISH_WORD,333        /[.]?[:]?([.][ ]|[ ])/,334        '){3}')335    }336  );337  return mode;338};339const C_LINE_COMMENT_MODE = COMMENT('//', '$');340const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/');341const HASH_COMMENT_MODE = COMMENT('#', '$');342const NUMBER_MODE = {343  scope: 'number',344  begin: NUMBER_RE,345  relevance: 0346};347const C_NUMBER_MODE = {348  scope: 'number',349  begin: C_NUMBER_RE,350  relevance: 0351};352const BINARY_NUMBER_MODE = {353  scope: 'number',354  begin: BINARY_NUMBER_RE,355  relevance: 0356};357const REGEXP_MODE = {358  begin: /(?=\/[^/\n]*\/)/,359  contains: [{360    scope: 'regexp',361    begin: /\//,362    end: /\/[gimuy]*/,363    illegal: /\n/,364    contains: [365      BACKSLASH_ESCAPE,366      {367        begin: /\[/,368        end: /\]/,369        relevance: 0,370        contains: [BACKSLASH_ESCAPE]371      }372    ]373  }]374};375const TITLE_MODE = {376  scope: 'title',377  begin: IDENT_RE,378  relevance: 0379};380const UNDERSCORE_TITLE_MODE = {381  scope: 'title',382  begin: UNDERSCORE_IDENT_RE,383  relevance: 0384};385const METHOD_GUARD = {386  // excludes method names from keyword processing387  begin: '\\.\\s*' + UNDERSCORE_IDENT_RE,388  relevance: 0389};390const END_SAME_AS_BEGIN = function(mode) {391  return Object.assign(mode,392    {393      /** @type {ModeCallback} */394      'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },395      /** @type {ModeCallback} */396      'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }397    });398};399var MODES = /*#__PURE__*/Object.freeze({400    __proto__: null,401    MATCH_NOTHING_RE: MATCH_NOTHING_RE,402    IDENT_RE: IDENT_RE,403    UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,404    NUMBER_RE: NUMBER_RE,405    C_NUMBER_RE: C_NUMBER_RE,406    BINARY_NUMBER_RE: BINARY_NUMBER_RE,407    RE_STARTERS_RE: RE_STARTERS_RE,408    SHEBANG: SHEBANG,409    BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,410    APOS_STRING_MODE: APOS_STRING_MODE,411    QUOTE_STRING_MODE: QUOTE_STRING_MODE,412    PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,413    COMMENT: COMMENT,414    C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,415    C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,416    HASH_COMMENT_MODE: HASH_COMMENT_MODE,417    NUMBER_MODE: NUMBER_MODE,418    C_NUMBER_MODE: C_NUMBER_MODE,419    BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,420    REGEXP_MODE: REGEXP_MODE,421    TITLE_MODE: TITLE_MODE,422    UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,423    METHOD_GUARD: METHOD_GUARD,424    END_SAME_AS_BEGIN: END_SAME_AS_BEGIN425});426function skipIfHasPrecedingDot(match, response) {427  const before = match.input[match.index - 1];428  if (before === ".") {429    response.ignoreMatch();430  }431}432function scopeClassName(mode, _parent) {433  // eslint-disable-next-line no-undefined434  if (mode.className !== undefined) {435    mode.scope = mode.className;436    delete mode.className;437  }438}439function beginKeywords(mode, parent) {440  if (!parent) return;441  if (!mode.beginKeywords) return;442  mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)';443  mode.__beforeBegin = skipIfHasPrecedingDot;444  mode.keywords = mode.keywords || mode.beginKeywords;445  delete mode.beginKeywords;446  if (mode.relevance === undefined) mode.relevance = 0;447}448function compileIllegal(mode, _parent) {449  if (!Array.isArray(mode.illegal)) return;450  mode.illegal = either(...mode.illegal);451}452function compileMatch(mode, _parent) {453  if (!mode.match) return;454  if (mode.begin || mode.end) throw new Error("begin & end are not supported with match");455  mode.begin = mode.match;456  delete mode.match;457}458function compileRelevance(mode, _parent) {459  // eslint-disable-next-line no-undefined460  if (mode.relevance === undefined) mode.relevance = 1;461}462const beforeMatchExt = (mode, parent) => {463  if (!mode.beforeMatch) return;464  if (mode.starts) throw new Error("beforeMatch cannot be used with starts");465  const originalMode = Object.assign({}, mode);466  Object.keys(mode).forEach((key) => { delete mode[key]; });467  mode.keywords = originalMode.keywords;468  mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));469  mode.starts = {470    relevance: 0,471    contains: [472      Object.assign(originalMode, { endsParent: true })473    ]474  };475  mode.relevance = 0;476  delete originalMode.beforeMatch;477};478const COMMON_KEYWORDS = [479  'of',480  'and',481  'for',482  'in',483  'not',484  'or',485  'if',486  'then',487  'parent', // common variable name488  'list', // common variable name489  'value' // common variable name490];491const DEFAULT_KEYWORD_SCOPE = "keyword";492function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {493    const compileList = (scopeName, keywordList) => {494        if (caseInsensitive) {495            keywordList = keywordList.map(x => x.toLowerCase());496        }497        keywordList.forEach(function(keyword) {498            const pair = keyword.split('|');499            compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];500        });501    }502    const compiledKeywords = Object.create(null);503    if (typeof rawKeywords === 'string') {504        compileList(scopeName, rawKeywords.split(" "));505    } else if (Array.isArray(rawKeywords)) {506        compileList(scopeName, rawKeywords);507    } else {508        Object.keys(rawKeywords).forEach(function(scopeName) {509        Object.assign(510            compiledKeywords,511            compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)512        );513        });514    }515    return compiledKeywords;516}517function scoreForKeyword(keyword, providedScore) {518  if (providedScore) {519    return Number(providedScore);520  }521  return commonKeyword(keyword) ? 0 : 1;522}523function commonKeyword(keyword) {524  return COMMON_KEYWORDS.includes(keyword.toLowerCase());525}526const seenDeprecations = {};527const error = (message) => {528  console.error(message);529};530const warn = (message, ...args) => {531  console.log(`WARN: ${message}`, ...args);532};533const deprecated = (version, message) => {534  if (seenDeprecations[`${version}/${message}`]) return;535  console.log(`Deprecated as of ${version}. ${message}`);536  seenDeprecations[`${version}/${message}`] = true;537};538const MultiClassError = new Error();539function remapScopeNames(mode, regexes, { key }) {540  let offset = 0;541  const scopeNames = mode[key];542  const emit = {};543  const positions = {};544  for (let i = 1; i <= regexes.length; i++) {545    positions[i + offset] = scopeNames[i];546    emit[i + offset] = true;547    offset += countMatchGroups(regexes[i - 1]);548  }549  mode[key] = positions;550  mode[key]._emit = emit;551  mode[key]._multi = true;552}553function beginMultiClass(mode) {554  if (!Array.isArray(mode.begin)) return;555  if (mode.skip || mode.excludeBegin || mode.returnBegin) {556    error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");557    throw MultiClassError;558  }559  if (typeof mode.beginScope !== "object" || mode.beginScope === null) {560    error("beginScope must be object");561    throw MultiClassError;562  }563  remapScopeNames(mode, mode.begin, {key: "beginScope"});564  mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" });565}566function endMultiClass(mode) {567  if (!Array.isArray(mode.end)) return;568  if (mode.skip || mode.excludeEnd || mode.returnEnd) {569    error("skip, excludeEnd, returnEnd not compatible with endScope: {}");570    throw MultiClassError;571  }572  if (typeof mode.endScope !== "object" || mode.endScope === null) {573    error("endScope must be object");574    throw MultiClassError;575  }576  remapScopeNames(mode, mode.end, {key: "endScope"});577  mode.end = _rewriteBackreferences(mode.end, { joinWith: "" });578}579function scopeSugar(mode) {580  if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {581    mode.beginScope = mode.scope;582    delete mode.scope;583  }584}585function MultiClass(mode) {586  scopeSugar(mode);587  if (typeof mode.beginScope === "string") {588    mode.beginScope = { _wrap: mode.beginScope };589  }590  if (typeof mode.endScope === "string") {591    mode.endScope = { _wrap: mode.endScope };592  }593  beginMultiClass(mode);594  endMultiClass(mode);595}596function compileLanguage(language) {597  function langRe(value, global) {598    return new RegExp(599      source(value),600      'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')601    );602  }603  class MultiRegex {604    constructor() {605      this.matchIndexes = {};606      this.regexes = [];607      this.matchAt = 1;608      this.position = 0;609    }610    addRule(re, opts) {611      opts.position = this.position++;612      this.matchIndexes[this.matchAt] = opts;613      this.regexes.push([opts, re]);614      this.matchAt += countMatchGroups(re) + 1;615    }616    compile() {617      if (this.regexes.length === 0) {618        this.exec = () => null;619      }620      const terminators = this.regexes.map(el => el[1]);621      this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true);622      this.lastIndex = 0;623    }624    exec(s) {625      this.matcherRe.lastIndex = this.lastIndex;626      const match = this.matcherRe.exec(s);627      if (!match) { return null; }628      // eslint-disable-next-line no-undefined629      const i = match.findIndex((el, i) => i > 0 && el !== undefined);630      const matchData = this.matchIndexes[i];631      match.splice(0, i);632      return Object.assign(match, matchData);633    }634  }635  class ResumableMultiRegex {636    constructor() {637      this.rules = [];638      this.multiRegexes = [];639      this.count = 0;640      this.lastIndex = 0;641      this.regexIndex = 0;642    }643    getMatcher(index) {644      if (this.multiRegexes[index]) return this.multiRegexes[index];645      const matcher = new MultiRegex();646      this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));647      matcher.compile();648      this.multiRegexes[index] = matcher;649      return matcher;650    }651    resumingScanAtSamePosition() {652      return this.regexIndex !== 0;653    }654    considerAll() {655      this.regexIndex = 0;656    }657    addRule(re, opts) {658      this.rules.push([re, opts]);659      if (opts.type === "begin") this.count++;660    }661    exec(s) {662      const m = this.getMatcher(this.regexIndex);663      m.lastIndex = this.lastIndex;664      let result = m.exec(s);665      if (this.resumingScanAtSamePosition()) {666        if (result && result.index === this.lastIndex) ; else {667          const m2 = this.getMatcher(0);668          m2.lastIndex = this.lastIndex + 1;669          result = m2.exec(s);670        }671      }672      if (result) {673        this.regexIndex += result.position + 1;674        if (this.regexIndex === this.count) {675          this.considerAll();676        }677      }678      return result;679    }680  }681  function buildModeRegex(mode) {682    const mm = new ResumableMultiRegex();683    mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" }));684    if (mode.terminatorEnd) {685      mm.addRule(mode.terminatorEnd, { type: "end" });686    }687    if (mode.illegal) {688      mm.addRule(mode.illegal, { type: "illegal" });689    }690    return mm;691  }692  function compileMode(mode, parent) {693    const cmode = /** @type CompiledMode */ (mode);694    if (mode.isCompiled) return cmode;695    [696      scopeClassName,697      // do this early so compiler extensions generally don't have to worry about698      // the distinction between match/begin699      compileMatch,700      MultiClass,701      beforeMatchExt702    ].forEach(ext => ext(mode, parent));703    language.compilerExtensions.forEach(ext => ext(mode, parent));704    mode.__beforeBegin = null;705    [706      beginKeywords,707      compileIllegal,708      compileRelevance709    ].forEach(ext => ext(mode, parent));710    mode.isCompiled = true;711    let keywordPattern = null;712    if (typeof mode.keywords === "object" && mode.keywords.$pattern) {713      mode.keywords = Object.assign({}, mode.keywords);714      keywordPattern = mode.keywords.$pattern;715      delete mode.keywords.$pattern;716    }717    keywordPattern = keywordPattern || /\w+/;718    if (mode.keywords) {719      mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);720    }721    cmode.keywordPatternRe = langRe(keywordPattern, true);722    if (parent) {723      if (!mode.begin) mode.begin = /\B|\b/;724      cmode.beginRe = langRe(mode.begin);725      if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/;726      if (mode.end) cmode.endRe = langRe(mode.end);727      cmode.terminatorEnd = source(mode.end) || '';728      if (mode.endsWithParent && parent.terminatorEnd) {729        cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;730      }731    }732    if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));733    if (!mode.contains) mode.contains = [];734    mode.contains = [].concat(...mode.contains.map(function(c) {735      return expandOrCloneMode(c === 'self' ? mode : c);736    }));737    mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });738    if (mode.starts) {739      compileMode(mode.starts, parent);740    }741    cmode.matcher = buildModeRegex(cmode);742    return cmode;743  }744  if (!language.compilerExtensions) language.compilerExtensions = [];745  if (language.contains && language.contains.includes('self')) {746    throw new Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.");747  }748  language.classNameAliases = inherit$1(language.classNameAliases || {});749  return compileMode(language);750}751function dependencyOnParent(mode) {752  if (!mode) return false;753  return mode.endsWithParent || dependencyOnParent(mode.starts);754}755function expandOrCloneMode(mode) {756  if (mode.variants && !mode.cachedVariants) {757    mode.cachedVariants = mode.variants.map(function(variant) {758      return inherit$1(mode, { variants: null }, variant);759    });760  }761  if (mode.cachedVariants) {762    return mode.cachedVariants;763  }764  if (dependencyOnParent(mode)) {765    return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null });766  }767  if (Object.isFrozen(mode)) {768    return inherit$1(mode);769  }770  return mode;771}772const escape = escapeHTML;773const inherit = inherit$1;774const NO_MATCH = Symbol("nomatch");775const MAX_KEYWORD_HITS = 7;776const HLJS = function(hljs) {777  const languages = Object.create(null);778  const aliases = Object.create(null);779  const plugins = [];780  let SAFE_MODE = true;781  const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?";782  const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };783  let options = {784    ignoreUnescapedHTML: false,785    noHighlightRe: /^(no-?highlight)$/i,786    languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,787    classPrefix: '',788    cssSelector: 'pre code',789    languages: null,790    __emitter: TokenTreeEmitter791  };792  function shouldNotHighlight(languageName) {793    return options.noHighlightRe.test(languageName);794  }795  function blockLanguage(block) {796    let classes = block.className + ' ';797    classes += block.parentNode ? block.parentNode.className : '';798    const match = options.languageDetectRe.exec(classes);799    if (match) {800      const language = getLanguage(match[1]);801      if (!language) {802        warn(LANGUAGE_NOT_FOUND.replace("{}", match[1]));803        warn("Falling back to no-highlight mode for this block.", block);804      }805      return language ? match[1] : 'no-highlight';806    }807    return classes808      .split(/\s+/)809      .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));810  }811  function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) {812    let code = "";813    let languageName = "";814    if (typeof optionsOrCode === "object") {815      code = codeOrLanguageName;816      ignoreIllegals = optionsOrCode.ignoreIllegals;817      languageName = optionsOrCode.language;818    } else {819      // old API820      deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated.");821      deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277");822      languageName = codeOrLanguageName;823      code = optionsOrCode;824    }825    if (ignoreIllegals === undefined) { ignoreIllegals = true; }826    /** @type {BeforeHighlightContext} */827    const context = {828      code,829      language: languageName830    };831    fire("before:highlight", context);832    const result = context.result833      ? context.result834      : _highlight(context.language, context.code, ignoreIllegals);835    result.code = context.code;836    fire("after:highlight", result);837    return result;838  }839  function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {840    const keywordHits = Object.create(null);841    function keywordData(mode, matchText) {842      return mode.keywords[matchText];843    }844    function processKeywords() {845      if (!top.keywords) {846        emitter.addText(modeBuffer);847        return;848      }849      let lastIndex = 0;850      top.keywordPatternRe.lastIndex = 0;851      let match = top.keywordPatternRe.exec(modeBuffer);852      let buf = "";853      while (match) {854        buf += modeBuffer.substring(lastIndex, match.index);855        const word = language.case_insensitive ? match[0].toLowerCase() : match[0];856        const data = keywordData(top, word);857        if (data) {858          const [kind, keywordRelevance] = data;859          emitter.addText(buf);860          buf = "";861          keywordHits[word] = (keywordHits[word] || 0) + 1;862          if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance;863          if (kind.startsWith("_")) {864            buf += match[0];865          } else {866            const cssClass = language.classNameAliases[kind] || kind;867            emitter.addKeyword(match[0], cssClass);868          }869        } else {870          buf += match[0];871        }872        lastIndex = top.keywordPatternRe.lastIndex;873        match = top.keywordPatternRe.exec(modeBuffer);874      }875      buf += modeBuffer.substr(lastIndex);876      emitter.addText(buf);877    }878    function processSubLanguage() {879      if (modeBuffer === "") return;880      /** @type HighlightResult */881      let result = null;882      if (typeof top.subLanguage === 'string') {883        if (!languages[top.subLanguage]) {884          emitter.addText(modeBuffer);885          return;886        }887        result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);888        continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top);889      } else {890        result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);891      }892      if (top.relevance > 0) {893        relevance += result.relevance;894      }895      emitter.addSublanguage(result._emitter, result.language);896    }897    function processBuffer() {898      if (top.subLanguage != null) {899        processSubLanguage();900      } else {901        processKeywords();902      }903      modeBuffer = '';904    }905    function emitMultiClass(scope, match) {906      let i = 1;907      // eslint-disable-next-line no-undefined908      while (match[i] !== undefined) {909        if (!scope._emit[i]) { i++; continue; }910        const klass = language.classNameAliases[scope[i]] || scope[i];911        const text = match[i];912        if (klass) {913          emitter.addKeyword(text, klass);914        } else {915          modeBuffer = text;916          processKeywords();917          modeBuffer = "";918        }919        i++;920      }921    }922    function startNewMode(mode, match) {923      if (mode.scope && typeof mode.scope === "string") {924        emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);925      }926      if (mode.beginScope) {927        if (mode.beginScope._wrap) {928          emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);929          modeBuffer = "";930        } else if (mode.beginScope._multi) {931          emitMultiClass(mode.beginScope, match);932          modeBuffer = "";933        }934      }935      top = Object.create(mode, { parent: { value: top } });936      return top;937    }938    function endOfMode(mode, match, matchPlusRemainder) {939      let matched = startsWith(mode.endRe, matchPlusRemainder);940      if (matched) {941        if (mode["on:end"]) {942          const resp = new Response(mode);943          mode["on:end"](match, resp);944          if (resp.isMatchIgnored) matched = false;945        }946        if (matched) {947          while (mode.endsParent && mode.parent) {948            mode = mode.parent;949          }950          return mode;951        }952      }953      if (mode.endsWithParent) {954        return endOfMode(mode.parent, match, matchPlusRemainder);955      }956    }957    function doIgnore(lexeme) {958      if (top.matcher.regexIndex === 0) {959        modeBuffer += lexeme[0];960        return 1;961      } else {962        resumeScanAtSamePosition = true;963        return 0;964      }965    }966    function doBeginMatch(match) {967      const lexeme = match[0];968      const newMode = match.rule;969      const resp = new Response(newMode);970      const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]];971      for (const cb of beforeCallbacks) {972        if (!cb) continue;973        cb(match, resp);974        if (resp.isMatchIgnored) return doIgnore(lexeme);975      }976      if (newMode.skip) {977        modeBuffer += lexeme;978      } else {979        if (newMode.excludeBegin) {980          modeBuffer += lexeme;981        }982        processBuffer();983        if (!newMode.returnBegin && !newMode.excludeBegin) {984          modeBuffer = lexeme;985        }986      }987      startNewMode(newMode, match);988      return newMode.returnBegin ? 0 : lexeme.length;989    }990    function doEndMatch(match) {991      const lexeme = match[0];992      const matchPlusRemainder = codeToHighlight.substr(match.index);993      const endMode = endOfMode(top, match, matchPlusRemainder);994      if (!endMode) { return NO_MATCH; }995      const origin = top;996      if (top.endScope && top.endScope._wrap) {997        processBuffer();998        emitter.addKeyword(lexeme, top.endScope._wrap);999      } else if (top.endScope && top.endScope._multi) {1000        processBuffer();1001        emitMultiClass(top.endScope, match);1002      } else if (origin.skip) {1003        modeBuffer += lexeme;1004      } else {1005        if (!(origin.returnEnd || origin.excludeEnd)) {1006          modeBuffer += lexeme;1007        }1008        processBuffer();1009        if (origin.excludeEnd) {1010          modeBuffer = lexeme;1011        }1012      }1013      do {1014        if (top.scope) {1015          emitter.closeNode();1016        }1017        if (!top.skip && !top.subLanguage) {1018          relevance += top.relevance;1019        }1020        top = top.parent;1021      } while (top !== endMode.parent);1022      if (endMode.starts) {1023        startNewMode(endMode.starts, match);1024      }1025      return origin.returnEnd ? 0 : lexeme.length;1026    }1027    function processContinuations() {1028      const list = [];1029      for (let current = top; current !== language; current = current.parent) {1030        if (current.scope) {1031          list.unshift(current.scope);1032        }1033      }1034      list.forEach(item => emitter.openNode(item));1035    }1036    let lastMatch = {};1037    function processLexeme(textBeforeMatch, match) {1038      const lexeme = match && match[0];1039      modeBuffer += textBeforeMatch;1040      if (lexeme == null) {1041        processBuffer();1042        return 0;1043      }1044      if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") {1045        modeBuffer += codeToHighlight.slice(match.index, match.index + 1);1046        if (!SAFE_MODE) {1047          const err = new Error(`0 width match regex (${languageName})`);1048          err.languageName = languageName;1049          err.badRule = lastMatch.rule;1050          throw err;1051        }1052        return 1;1053      }1054      lastMatch = match;1055      if (match.type === "begin") {1056        return doBeginMatch(match);1057      } else if (match.type === "illegal" && !ignoreIllegals) {1058        const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '<unnamed>') + '"');1059        err.mode = top;1060        throw err;1061      } else if (match.type === "end") {1062        const processed = doEndMatch(match);1063        if (processed !== NO_MATCH) {1064          return processed;1065        }1066      }1067      if (match.type === "illegal" && lexeme === "") {1068        return 1;1069      }1070      if (iterations > 100000 && iterations > match.index * 3) {1071        const err = new Error('potential infinite loop, way more iterations than matches');1072        throw err;1073      }1074      modeBuffer += lexeme;1075      return lexeme.length;1076    }1077    const language = getLanguage(languageName);1078    if (!language) {1079      error(LANGUAGE_NOT_FOUND.replace("{}", languageName));1080      throw new Error('Unknown language: "' + languageName + '"');1081    }1082    const md = compileLanguage(language);1083    let result = '';1084    let top = continuation || md;1085    const continuations = {};1086    const emitter = new options.__emitter(options);1087    processContinuations();1088    let modeBuffer = '';1089    let relevance = 0;1090    let index = 0;1091    let iterations = 0;1092    let resumeScanAtSamePosition = false;1093    try {1094      top.matcher.considerAll();1095      for (;;) {1096        iterations++;1097        if (resumeScanAtSamePosition) {1098          resumeScanAtSamePosition = false;1099        } else {1100          top.matcher.considerAll();1101        }1102        top.matcher.lastIndex = index;1103        const match = top.matcher.exec(codeToHighlight);1104        if (!match) break;1105        const beforeMatch = codeToHighlight.substring(index, match.index);1106        const processedCount = processLexeme(beforeMatch, match);1107        index = match.index + processedCount;1108      }1109      processLexeme(codeToHighlight.substr(index));1110      emitter.closeAllNodes();1111      emitter.finalize();1112      result = emitter.toHTML();1113      return {1114        language: languageName,1115        value: result,1116        relevance: relevance,1117        illegal: false,1118        _emitter: emitter,1119        _top: top1120      };1121    } catch (err) {1122      if (err.message && err.message.includes('Illegal')) {1123        return {1124          language: languageName,1125          value: escape(codeToHighlight),1126          illegal: true,1127          relevance: 0,1128          _illegalBy: {1129            message: err.message,1130            index: index,1131            context: codeToHighlight.slice(index - 100, index + 100),1132            mode: err.mode,1133            resultSoFar: result1134          },1135          _emitter: emitter1136        };1137      } else if (SAFE_MODE) {1138        return {1139          language: languageName,1140          value: escape(codeToHighlight),1141          illegal: false,1142          relevance: 0,1143          errorRaised: err,1144          _emitter: emitter,1145          _top: top1146        };1147      } else {1148        throw err;1149      }1150    }1151  }1152  function justTextHighlightResult(code) {1153    const result = {1154      value: escape(code),1155      illegal: false,1156      relevance: 0,1157      _top: PLAINTEXT_LANGUAGE,1158      _emitter: new options.__emitter(options)1159    };1160    result._emitter.addText(code);1161    return result;1162  }1163  function highlightAuto(code, languageSubset) {1164    languageSubset = languageSubset || options.languages || Object.keys(languages);1165    const plaintext = justTextHighlightResult(code);1166    const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>1167      _highlight(name, code, false)1168    );1169    results.unshift(plaintext); // plaintext is always an option1170    const sorted = results.sort((a, b) => {1171      // sort base on relevance1172      if (a.relevance !== b.relevance) return b.relevance - a.relevance;1173      // always award the tie to the base language1174      // ie if C++ and Arduino are tied, it's more likely to be C++1175      if (a.language && b.language) {1176        if (getLanguage(a.language).supersetOf === b.language) {1177          return 1;1178        } else if (getLanguage(b.language).supersetOf === a.language) {1179          return -1;1180        }1181      }1182      return 0;1183    });1184    const [best, secondBest] = sorted;1185    const result = best;1186    result.secondBest = secondBest;1187    return result;1188  }1189  function updateClassName(element, currentLang, resultLang) {1190    const language = (currentLang && aliases[currentLang]) || resultLang;1191    element.classList.add("hljs");1192    element.classList.add(`language-${language}`);1193  }1194  function highlightElement(element) {1195    let node = null;1196    const language = blockLanguage(element);1197    if (shouldNotHighlight(language)) return;1198    fire("before:highlightElement",1199      { el: element, language: language });1200    if (!options.ignoreUnescapedHTML && element.children.length > 0) {1201      console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk.");1202      console.warn("https://github.com/highlightjs/highlight.js/issues/2886");1203      console.warn(element);1204    }1205    node = element;1206    const text = node.textContent;1207    const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);1208    element.innerHTML = result.value;1209    updateClassName(element, language, result.language);1210    element.result = {1211      language: result.language,1212      re: result.relevance,1213      relevance: result.relevance1214    };1215    if (result.secondBest) {1216      element.secondBest = {1217        language: result.secondBest.language,1218        relevance: result.secondBest.relevance1219      };1220    }1221    fire("after:highlightElement", { el: element, result, text });1222  }1223  let wantsHighlight = false;1224  function highlightAll() {1225    if (document.readyState === "loading") {1226      wantsHighlight = true;1227      return;1228    }1229    const blocks = document.querySelectorAll(options.cssSelector);1230    blocks.forEach(highlightElement);1231  }1232  function boot() {1233    if (wantsHighlight) highlightAll();1234  }1235  if (typeof window !== 'undefined' && window.addEventListener) {1236    window.addEventListener('DOMContentLoaded', boot, false);1237  }1238  function registerLanguage(languageName, languageDefinition) {1239    let lang = null;1240    try {1241      lang = languageDefinition(hljs);1242    } catch (error$1) {1243      error("Language definition for '{}' could not be registered.".replace("{}", languageName));1244      if (!SAFE_MODE) { throw error$1; } else { error(error$1); }1245      lang = PLAINTEXT_LANGUAGE;1246    }1247    if (!lang.name) lang.name = languageName;1248    languages[languageName] = lang;1249    lang.rawDefinition = languageDefinition.bind(null, hljs);1250    if (lang.aliases) {1251      registerAliases(lang.aliases, { languageName });1252    }1253  }1254  function unregisterLanguage(languageName) {1255    delete languages[languageName];1256    for (const alias of Object.keys(aliases)) {1257      if (aliases[alias] === languageName) {1258        delete aliases[alias];1259      }1260    }1261  }1262  function listLanguages() {1263    return Object.keys(languages);1264  }1265  function getLanguage(name) {1266    name = (name || '').toLowerCase();1267    return languages[name] || languages[aliases[name]];1268  }1269  function registerAliases(aliasList, { languageName }) {1270    if (typeof aliasList === 'string') {1271      aliasList = [aliasList];1272    }1273    aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });1274  }1275  function autoDetection(name) {1276    const lang = getLanguage(name);1277    return lang && !lang.disableAutodetect;1278  }1279  function fire(event, args) {1280    const cb = event;1281    plugins.forEach(function(plugin) {1282      if (plugin[cb]) {1283        plugin[cb](args);1284      }1285    });1286  }1287  Object.assign(hljs, {1288    highlight,1289    inherit,1290    registerLanguage,1291    getLanguage1292  });1293  for (const key in MODES) {1294    if (typeof MODES[key] === "object") {1295        deepFreeze(MODES[key]);1296    }1297  }1298  Object.assign(hljs, MODES);1299  return hljs;1300};...mode_compiler.js
Source:mode_compiler.js  
...220   * special _internal_ 'on:begin' callback for modes with `beginKeywords`221   * @param {RegExpMatchArray} match222   * @param {CallbackResponse} response223   */224  function skipIfhasPrecedingDot(match, response) {225    const before = match.input[match.index - 1];226    if (before === ".") {227      response.ignoreMatch();228    }229  }230  /** skip vs abort vs ignore231   *232   * @skip   - The mode is still entered and exited normally (and contains rules apply),233   *           but all content is held and added to the parent buffer rather than being234   *           output when the mode ends.  Mostly used with `sublanguage` to build up235   *           a single large buffer than can be parsed by sublanguage.236   *237   *             - The mode begin ands ends normally.238   *             - Content matched is added to the parent mode buffer....compiler_extensions.js
Source:compiler_extensions.js  
...18 * special _internal_ 'on:begin' callback for modes with `beginKeywords`19 * @param {RegExpMatchArray} match20 * @param {CallbackResponse} response21 */22function skipIfhasPrecedingDot(match, response) {23  const before = match.input[match.index - 1];24  if (before === ".") {25    response.ignoreMatch();26  }27}28/**29 * `beginKeywords` syntactic sugar30 * @type {CompilerExt}31 */32export function beginKeywords(mode, parent) {33  if (!parent) return;34  if (!mode.beginKeywords) return;35  // for languages with keywords that include non-word characters checking for36  // a word boundary is not sufficient, so instead we check for a word boundary...Using AI Code Generation
1const {chromium} = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  const frame = page.mainFrame();7  const element = await frame.$('button');8  console.log(await element.evaluate(element => element.skipIfhasPrecedingDot()));9  await browser.close();10})();Using AI Code Generation
1const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');2const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');3const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');4const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');5const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');6const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');7const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');8const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');9const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');10const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');11const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');12const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');13const { skipIfhasPrecedingDot } = require('playwright/lib/internal/utils');14const { skipIfhasPrecedingDot } = require('playwright/libUsing AI Code Generation
1const { skipIfhasPrecedingDot } = require('@playwright/test');2const { test, expect } = require('@playwright/test');3test('should pass', async ({ page }) => {4  expect(await skipIfhasPrecedingDot(page, '.test')).toBe(true);5});6test('should fail', async ({ page }) => {7  expect(await skipIfhasPrecedingDot(page, 'test')).toBe(true);8});Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('test', async ({ page }) => {3  const skipIfhasPrecedingDot = page._delegate.skipIfhasPrecedingDot;4  expect(skipIfhasPrecedingDot('.test')).toBe(true);5  expect(skipIfhasPrecedingDot('test')).toBe(false);6});Using AI Code Generation
1const { skipIfhasPrecedingDot } = require('playwright/lib/utils/utils');2const { expect } = require('chai');3describe('test', () => {4  it('test', () => {5    expect(skipIfhasPrecedingDot('.someClass')).to.be.true;6    expect(skipIfhasPrecedingDot('someClass')).to.be.false;7  });8});9  1 passing (5ms)Using AI Code Generation
1const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');2skipIfhasPrecedingDot('test.js')3const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');4skipIfhasPrecedingDot('.\test.js')5const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');6skipIfhasPrecedingDot('.\test')7const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');8skipIfhasPrecedingDot('test')9const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');10skipIfhasPrecedingDot('test')11const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');12skipIfhasPrecedingDot('test')13const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');14skipIfhasPrecedingDot('test')15const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');16skipIfhasPrecedingDot('test')17const { skipIfhasPrecedingDot } = require('@playwright/test/lib/utils/pathUtils');18skipIfhasPrecedingDot('test')19const {Using AI Code Generation
1const { skipIfhasPrecedingDot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');2const { skipIfhasPrecedingDot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');3const { skipIfhasPrecedingDot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');4const { skipIfhasPrecedingDot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');5const { skipIfhasPrecedingDot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');6const { skipIfhasPrecedingDot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');7const { skipIfhasUsing AI Code Generation
1const { test, expect } = require('@playwright/test');2const { skipIfhasPrecedingDot } = require('@playwright/test/lib/runner/params');3test('Playwright Internal API', async ({page}) => {4  const skip = skipIfhasPrecedingDot('test');5  if (skip) {6    return skip;7  }8  expect(await page.textContent('.navbar__inner')).toContain('Docs');9});Using AI Code Generation
1const { skipIfhasPrecedingDot } = require('playwright/lib/utils/utils');2const result = skipIfhasPrecedingDot('test.js');3console.log(result);4browser.newContext()5browser.newIncognitoBrowserContext()6browser.newBrowserCDPSession()7browser.newBrowserContext()8const context = await browser.newContext({9});10const context = await browser.newContext({11  viewport: {12  }13});Using AI Code Generation
1const {test, expect} = require('@playwright/test');2test('should not throw error when using skipIfhasPrecedingDot method of Playwright Internal API', async ({ page }) => {3    await page.waitForSelector('text=Get started');4    await page.click('text=Get started');5});6test.js:10:5 › [chromium] should not throw error when using skipIfhasPrecedingDot method of Playwright Internal API (1s)7✓ should not throw error when using skipIfhasPrecedingDot method of Playwright Internal API (1s)81 test passed (1s)LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
