| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 | /** * @param {string} value * @returns {RegExp} * *//** * @param {RegExp | string } re * @returns {string} */function source(re) {  if (!re) return null;  if (typeof re === "string") return re;  return re.source;}/** * @param {RegExp | string } re * @returns {string} */function anyNumberOfTimes(re) {  return concat('(', re, ')*');}/** * @param {RegExp | string } re * @returns {string} */function optional(re) {  return concat('(', re, ')?');}/** * @param {...(RegExp | string) } args * @returns {string} */function concat(...args) {  const joined = args.map((x) => source(x)).join("");  return joined;}/** * Any of the passed expresssions may match * * Creates a huge this | this | that | that match * @param {(RegExp | string)[] } args * @returns {string} */function either(...args) {  const joined = '(' + args.map((x) => source(x)).join("|") + ")";  return joined;}/*Language: HandlebarsRequires: xml.jsAuthor: Robin Ward <robin.ward@gmail.com>Description: Matcher for Handlebars as well as EmberJS additions.Website: https://handlebarsjs.comCategory: template*/function handlebars(hljs) {  const BUILT_INS = {    'builtin-name': [      'action',      'bindattr',      'collection',      'component',      'concat',      'debugger',      'each',      'each-in',      'get',      'hash',      'if',      'in',      'input',      'link-to',      'loc',      'log',      'lookup',      'mut',      'outlet',      'partial',      'query-params',      'render',      'template',      'textarea',      'unbound',      'unless',      'view',      'with',      'yield'    ]  };  const LITERALS = {    literal: [      'true',      'false',      'undefined',      'null'    ]  };  // as defined in https://handlebarsjs.com/guide/expressions.html#literal-segments  // this regex matches literal segments like ' abc ' or [ abc ] as well as helpers and paths  // like a/b, ./abc/cde, and abc.bcd  const DOUBLE_QUOTED_ID_REGEX = /""|"[^"]+"/;  const SINGLE_QUOTED_ID_REGEX = /''|'[^']+'/;  const BRACKET_QUOTED_ID_REGEX = /\[\]|\[[^\]]+\]/;  const PLAIN_ID_REGEX = /[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/;  const PATH_DELIMITER_REGEX = /(\.|\/)/;  const ANY_ID = either(    DOUBLE_QUOTED_ID_REGEX,    SINGLE_QUOTED_ID_REGEX,    BRACKET_QUOTED_ID_REGEX,    PLAIN_ID_REGEX    );  const IDENTIFIER_REGEX = concat(    optional(/\.|\.\/|\//), // relative or absolute path    ANY_ID,    anyNumberOfTimes(concat(      PATH_DELIMITER_REGEX,      ANY_ID    ))  );  // identifier followed by a equal-sign (without the equal sign)  const HASH_PARAM_REGEX = concat(    '(',    BRACKET_QUOTED_ID_REGEX, '|',    PLAIN_ID_REGEX,    ')(?==)'  );  const HELPER_NAME_OR_PATH_EXPRESSION = {    begin: IDENTIFIER_REGEX,    lexemes: /[\w.\/]+/  };  const HELPER_PARAMETER = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {    keywords: LITERALS  });  const SUB_EXPRESSION = {    begin: /\(/,    end: /\)/    // the "contains" is added below when all necessary sub-modes are defined  };  const HASH = {    // fka "attribute-assignment", parameters of the form 'key=value'    className: 'attr',    begin: HASH_PARAM_REGEX,    relevance: 0,    starts: {      begin: /=/,      end: /=/,      starts: {        contains: [          hljs.NUMBER_MODE,          hljs.QUOTE_STRING_MODE,          hljs.APOS_STRING_MODE,          HELPER_PARAMETER,          SUB_EXPRESSION        ]      }    }  };  const BLOCK_PARAMS = {    // parameters of the form '{{#with x as | y |}}...{{/with}}'    begin: /as\s+\|/,    keywords: {      keyword: 'as'    },    end: /\|/,    contains: [      {        // define sub-mode in order to prevent highlighting of block-parameter named "as"        begin: /\w+/      }    ]  };  const HELPER_PARAMETERS = {    contains: [      hljs.NUMBER_MODE,      hljs.QUOTE_STRING_MODE,      hljs.APOS_STRING_MODE,      BLOCK_PARAMS,      HASH,      HELPER_PARAMETER,      SUB_EXPRESSION    ],    returnEnd: true    // the property "end" is defined through inheritance when the mode is used. If depends    // on the surrounding mode, but "endsWithParent" does not work here (i.e. it includes the    // end-token of the surrounding mode)  };  const SUB_EXPRESSION_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {    className: 'name',    keywords: BUILT_INS,    starts: hljs.inherit(HELPER_PARAMETERS, {      end: /\)/    })  });  SUB_EXPRESSION.contains = [SUB_EXPRESSION_CONTENTS];  const OPENING_BLOCK_MUSTACHE_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {    keywords: BUILT_INS,    className: 'name',    starts: hljs.inherit(HELPER_PARAMETERS, {      end: /\}\}/    })  });  const CLOSING_BLOCK_MUSTACHE_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {    keywords: BUILT_INS,    className: 'name'  });  const BASIC_MUSTACHE_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {    className: 'name',    keywords: BUILT_INS,    starts: hljs.inherit(HELPER_PARAMETERS, {      end: /\}\}/    })  });  const ESCAPE_MUSTACHE_WITH_PRECEEDING_BACKSLASH = {    begin: /\\\{\{/,    skip: true  };  const PREVENT_ESCAPE_WITH_ANOTHER_PRECEEDING_BACKSLASH = {    begin: /\\\\(?=\{\{)/,    skip: true  };  return {    name: 'Handlebars',    aliases: [      'hbs',      'html.hbs',      'html.handlebars',      'htmlbars'    ],    case_insensitive: true,    subLanguage: 'xml',    contains: [      ESCAPE_MUSTACHE_WITH_PRECEEDING_BACKSLASH,      PREVENT_ESCAPE_WITH_ANOTHER_PRECEEDING_BACKSLASH,      hljs.COMMENT(/\{\{!--/, /--\}\}/),      hljs.COMMENT(/\{\{!/, /\}\}/),      {        // open raw block "{{{{raw}}}} content not evaluated {{{{/raw}}}}"        className: 'template-tag',        begin: /\{\{\{\{(?!\/)/,        end: /\}\}\}\}/,        contains: [OPENING_BLOCK_MUSTACHE_CONTENTS],        starts: {          end: /\{\{\{\{\//,          returnEnd: true,          subLanguage: 'xml'        }      },      {        // close raw block        className: 'template-tag',        begin: /\{\{\{\{\//,        end: /\}\}\}\}/,        contains: [CLOSING_BLOCK_MUSTACHE_CONTENTS]      },      {        // open block statement        className: 'template-tag',        begin: /\{\{#/,        end: /\}\}/,        contains: [OPENING_BLOCK_MUSTACHE_CONTENTS]      },      {        className: 'template-tag',        begin: /\{\{(?=else\}\})/,        end: /\}\}/,        keywords: 'else'      },      {        className: 'template-tag',        begin: /\{\{(?=else if)/,        end: /\}\}/,        keywords: 'else if'      },      {        // closing block statement        className: 'template-tag',        begin: /\{\{\//,        end: /\}\}/,        contains: [CLOSING_BLOCK_MUSTACHE_CONTENTS]      },      {        // template variable or helper-call that is NOT html-escaped        className: 'template-variable',        begin: /\{\{\{/,        end: /\}\}\}/,        contains: [BASIC_MUSTACHE_CONTENTS]      },      {        // template variable or helper-call that is html-escaped        className: 'template-variable',        begin: /\{\{/,        end: /\}\}/,        contains: [BASIC_MUSTACHE_CONTENTS]      }    ]  };}/* Language: HTMLBars (legacy) Requires: xml.js Description: Matcher for Handlebars as well as EmberJS additions. Website: https://github.com/tildeio/htmlbars Category: template */function htmlbars(hljs) {  const definition = handlebars(hljs);  definition.name = "HTMLbars";  // HACK: This lets handlebars do the auto-detection if it's been loaded (by  // default the build script will load in alphabetical order) and if not (perhaps  // an install is only using `htmlbars`, not `handlebars`) then this will still  // allow HTMLBars to participate in the auto-detection  // worse case someone will have HTMLbars and handlebars competing for the same  // content and will need to change their setup to only require handlebars, but  // I don't consider this a breaking change  if (hljs.getLanguage("handlebars")) {    definition.disableAutodetect = true;  }  return definition;}module.exports = htmlbars;
 |