text: /**!
   * @author obedm503
   * @git https://github.com/obedm503/showdown-katex.git
   * @examples https://obedm503.github.io/showdown-katex/
   * @license MIT
   */
  'use strict';
  
  function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  
  var katex = _interopDefault(require('katex'));
  var renderMathInElement = _interopDefault(require('katex/dist/contrib/auto-render'));
  var showdown = _interopDefault(require('showdown'));
  
  function _extends() {
    _extends = Object.assign || function (target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];
  
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }
  
      return target;
    };
  
    return _extends.apply(this, arguments);
  }
  
  function _toConsumableArray(arr) {
    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
  }
  
  function _arrayWithoutHoles(arr) {
    if (Array.isArray(arr)) {
      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  
      return arr2;
    }
  }
  
  function _iterableToArray(iter) {
    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
  }
  
  function _nonIterableSpread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance");
  }
  
  /**!
   * @preserve
  Based on ASCIIMathTeXImg.js but now part of https://github.com/obedm503/showdown-katex
  
  Based on ASCIIMathML, Version 1.4.7 Aug 30, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen
  Modified with TeX conversion for IMG rendering Sept 6, 2006 (c) David Lippman http://www.pierce.ctc.edu/dlippman
    Updated to match ver 2.2 Mar 3, 2014
    Latest at https://github.com/mathjax/asciimathml
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the 'Software'), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  
  THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  */
  // @ts-check
  // token types
  var tokens = {
    CONST: 0,
    UNARY: 1,
    BINARY: 2,
    INFIX: 3,
    LEFTBRACKET: 4,
    RIGHTBRACKET: 5,
    SPACE: 6,
    UNDEROVER: 7,
    DEFINITION: 8,
    LEFTRIGHT: 9,
    TEXT: 10
  };
  /**
   * @typedef Symbol
   * @property {string} input
   * @property {string} tag
   * @property {string} [output]
   * @property {string} [tex]
   * @property {number} [tType]
   * @property {boolean} [val]
   * @property {boolean} [noTexCopy]
   * @property {boolean} [invisible]
   * @property {boolean} [func]
   * @property {string[]} [rewriteLeftRight]
   * @property {boolean} [acc]
   * @property {string} [atName]
   * @property {string} [atVal]
   */
  
  /** @type {Symbol} */
  
  var quoteSymbol = {
    input: "'",
    tag: 'mtext',
    output: 'mbox',
    tex: null,
    tType: tokens.TEXT
  };
  /** @type {Array<Symbol>} */
  
  var symbols = [// some greek symbols
  {
    input: 'alpha',
    tag: 'mi',
    output: "\u03B1",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'beta',
    tag: 'mi',
    output: "\u03B2",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'chi',
    tag: 'mi',
    output: "\u03C7",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'delta',
    tag: 'mi',
    output: "\u03B4",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Delta',
    tag: 'mo',
    output: "\u0394",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'epsi',
    tag: 'mi',
    output: "\u03B5",
    tex: 'epsilon',
    tType: tokens.CONST
  }, {
    input: 'varepsilon',
    tag: 'mi',
    output: "\u025B",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'eta',
    tag: 'mi',
    output: "\u03B7",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'gamma',
    tag: 'mi',
    output: "\u03B3",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Gamma',
    tag: 'mo',
    output: "\u0393",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'iota',
    tag: 'mi',
    output: "\u03B9",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'kappa',
    tag: 'mi',
    output: "\u03BA",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'lambda',
    tag: 'mi',
    output: "\u03BB",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Lambda',
    tag: 'mo',
    output: "\u039B",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'lamda',
    tag: 'mi',
    output: 'lambda',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'Lamda',
    tag: 'mi',
    output: 'Lambda',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'mu',
    tag: 'mi',
    output: "\u03BC",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'nu',
    tag: 'mi',
    output: "\u03BD",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'omega',
    tag: 'mi',
    output: "\u03C9",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Omega',
    tag: 'mo',
    output: "\u03A9",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'phi',
    tag: 'mi',
    output: "\u03C6",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'varphi',
    tag: 'mi',
    output: "\u03D5",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Phi',
    tag: 'mo',
    output: "\u03A6",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'pi',
    tag: 'mi',
    output: "\u03C0",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Pi',
    tag: 'mo',
    output: "\u03A0",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'psi',
    tag: 'mi',
    output: "\u03C8",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Psi',
    tag: 'mi',
    output: "\u03A8",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'rho',
    tag: 'mi',
    output: "\u03C1",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'sigma',
    tag: 'mi',
    output: "\u03C3",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Sigma',
    tag: 'mo',
    output: "\u03A3",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'tau',
    tag: 'mi',
    output: "\u03C4",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'theta',
    tag: 'mi',
    output: "\u03B8",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'vartheta',
    tag: 'mi',
    output: "\u03D1",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Theta',
    tag: 'mo',
    output: "\u0398",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'upsilon',
    tag: 'mi',
    output: "\u03C5",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'xi',
    tag: 'mi',
    output: "\u03BE",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'Xi',
    tag: 'mo',
    output: "\u039E",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'zeta',
    tag: 'mi',
    output: "\u03B6",
    tex: null,
    tType: tokens.CONST
  }, // binary operation symbols
  {
    input: '*',
    tag: 'mo',
    output: "\u22C5",
    tex: 'cdot',
    tType: tokens.CONST
  }, {
    input: '**',
    tag: 'mo',
    output: "\u2217",
    tex: 'ast',
    tType: tokens.CONST
  }, {
    input: '***',
    tag: 'mo',
    output: "\u22C6",
    tex: 'star',
    tType: tokens.CONST
  }, {
    input: '// ',
    tag: 'mo',
    output: '/',
    tex: '/',
    tType: tokens.CONST,
    val: true,
    noTexCopy: true
  }, {
    input: '\\\\',
    tag: 'mo',
    output: '\\',
    tex: 'backslash',
    tType: tokens.CONST
  }, {
    input: 'setminus',
    tag: 'mo',
    output: '\\',
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'xx',
    tag: 'mo',
    output: "\xD7",
    tex: 'times',
    tType: tokens.CONST
  }, {
    input: '|><',
    tag: 'mo',
    output: "\u22C9",
    tex: 'ltimes',
    tType: tokens.CONST
  }, {
    input: '><|',
    tag: 'mo',
    output: "\u22CA",
    tex: 'rtimes',
    tType: tokens.CONST
  }, {
    input: '|><|',
    tag: 'mo',
    output: "\u22C8",
    tex: 'bowtie',
    tType: tokens.CONST
  }, {
    input: '-:',
    tag: 'mo',
    output: "\xF7",
    tex: 'div',
    tType: tokens.CONST
  }, {
    input: 'divide',
    tag: 'mo',
    output: '-:',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: '@',
    tag: 'mo',
    output: "\u2218",
    tex: 'circ',
    tType: tokens.CONST
  }, {
    input: 'o+',
    tag: 'mo',
    output: "\u2295",
    tex: 'oplus',
    tType: tokens.CONST
  }, {
    input: 'ox',
    tag: 'mo',
    output: "\u2297",
    tex: 'otimes',
    tType: tokens.CONST
  }, {
    input: 'o.',
    tag: 'mo',
    output: "\u2299",
    tex: 'odot',
    tType: tokens.CONST
  }, {
    input: 'sum',
    tag: 'mo',
    output: "\u2211",
    tex: null,
    tType: tokens.UNDEROVER
  }, {
    input: 'prod',
    tag: 'mo',
    output: "\u220F",
    tex: null,
    tType: tokens.UNDEROVER
  }, {
    input: '^^',
    tag: 'mo',
    output: "\u2227",
    tex: 'wedge',
    tType: tokens.CONST
  }, {
    input: '^^^',
    tag: 'mo',
    output: "\u22C0",
    tex: 'bigwedge',
    tType: tokens.UNDEROVER
  }, {
    input: 'vv',
    tag: 'mo',
    output: "\u2228",
    tex: 'vee',
    tType: tokens.CONST
  }, {
    input: 'vvv',
    tag: 'mo',
    output: "\u22C1",
    tex: 'bigvee',
    tType: tokens.UNDEROVER
  }, {
    input: 'nn',
    tag: 'mo',
    output: "\u2229",
    tex: 'cap',
    tType: tokens.CONST
  }, {
    input: 'nnn',
    tag: 'mo',
    output: "\u22C2",
    tex: 'bigcap',
    tType: tokens.UNDEROVER
  }, {
    input: 'uu',
    tag: 'mo',
    output: "\u222A",
    tex: 'cup',
    tType: tokens.CONST
  }, {
    input: 'uuu',
    tag: 'mo',
    output: "\u22C3",
    tex: 'bigcup',
    tType: tokens.UNDEROVER
  }, {
    input: 'overset',
    tag: 'mover',
    output: 'stackrel',
    tex: null,
    tType: tokens.BINARY
  }, {
    input: 'underset',
    tag: 'munder',
    output: 'stackrel',
    tex: null,
    tType: tokens.BINARY
  }, // binary relation symbols
  {
    input: '!=',
    tag: 'mo',
    output: "\u2260",
    tex: 'ne',
    tType: tokens.CONST
  }, {
    input: ':=',
    tag: 'mo',
    output: ':=',
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'lt',
    tag: 'mo',
    output: '<',
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'gt',
    tag: 'mo',
    output: '>',
    tex: null,
    tType: tokens.CONST
  }, {
    input: '<=',
    tag: 'mo',
    output: "\u2264",
    tex: 'le',
    tType: tokens.CONST
  }, {
    input: 'lt=',
    tag: 'mo',
    output: "\u2264",
    tex: 'leq',
    tType: tokens.CONST
  }, {
    input: 'gt=',
    tag: 'mo',
    output: "\u2265",
    tex: 'geq',
    tType: tokens.CONST
  }, {
    input: '>=',
    tag: 'mo',
    output: "\u2265",
    tex: 'ge',
    tType: tokens.CONST
  }, {
    input: '-<',
    tag: 'mo',
    output: "\u227A",
    tex: 'prec',
    tType: tokens.CONST
  }, {
    input: '-lt',
    tag: 'mo',
    output: "\u227A",
    tex: null,
    tType: tokens.CONST
  }, {
    input: '>-',
    tag: 'mo',
    output: "\u227B",
    tex: 'succ',
    tType: tokens.CONST
  }, {
    input: '-<=',
    tag: 'mo',
    output: "\u2AAF",
    tex: 'preceq',
    tType: tokens.CONST
  }, {
    input: '>-=',
    tag: 'mo',
    output: "\u2AB0",
    tex: 'succeq',
    tType: tokens.CONST
  }, {
    input: 'in',
    tag: 'mo',
    output: "\u2208",
    tex: null,
    tType: tokens.CONST
  }, {
    input: '!in',
    tag: 'mo',
    output: "\u2209",
    tex: 'notin',
    tType: tokens.CONST
  }, {
    input: 'sub',
    tag: 'mo',
    output: "\u2282",
    tex: 'subset',
    tType: tokens.CONST
  }, {
    input: 'sup',
    tag: 'mo',
    output: "\u2283",
    tex: 'supset',
    tType: tokens.CONST
  }, {
    input: 'sube',
    tag: 'mo',
    output: "\u2286",
    tex: 'subseteq',
    tType: tokens.CONST
  }, {
    input: 'supe',
    tag: 'mo',
    output: "\u2287",
    tex: 'supseteq',
    tType: tokens.CONST
  }, {
    input: '-=',
    tag: 'mo',
    output: "\u2261",
    tex: 'equiv',
    tType: tokens.CONST
  }, {
    input: '~=',
    tag: 'mo',
    output: "\u2245",
    tex: 'stackrel{\\sim}{=}',
    tType: tokens.CONST
  }, // back hack b/c mimetex doesn't support /cong
  {
    input: 'cong',
    tag: 'mo',
    output: '~=',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: '~~',
    tag: 'mo',
    output: "\u2248",
    tex: 'approx',
    tType: tokens.CONST
  }, {
    input: 'prop',
    tag: 'mo',
    output: "\u221D",
    tex: 'propto',
    tType: tokens.CONST
  }, // logical symbols
  {
    input: 'and',
    tag: 'mtext',
    output: 'and',
    tex: null,
    tType: tokens.SPACE
  }, {
    input: 'or',
    tag: 'mtext',
    output: 'or',
    tex: null,
    tType: tokens.SPACE
  }, {
    input: 'not',
    tag: 'mo',
    output: "\xAC",
    tex: 'neg',
    tType: tokens.CONST
  }, {
    input: '=>',
    tag: 'mo',
    output: "\u21D2",
    tex: 'Rightarrow',
    tType: tokens.CONST
  }, {
    input: 'implies',
    tag: 'mo',
    output: '=>',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'if',
    tag: 'mo',
    output: 'if',
    tex: null,
    tType: tokens.SPACE
  }, {
    input: '<=>',
    tag: 'mo',
    output: "\u21D4",
    tex: 'Leftrightarrow',
    tType: tokens.CONST
  }, {
    input: 'iff',
    tag: 'mo',
    output: '<=>',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'AA',
    tag: 'mo',
    output: "\u2200",
    tex: 'forall',
    tType: tokens.CONST
  }, {
    input: 'EE',
    tag: 'mo',
    output: "\u2203",
    tex: 'exists',
    tType: tokens.CONST
  }, {
    input: '_|_',
    tag: 'mo',
    output: "\u22A5",
    tex: 'bot',
    tType: tokens.CONST
  }, {
    input: 'TT',
    tag: 'mo',
    output: "\u22A4",
    tex: 'top',
    tType: tokens.CONST
  }, {
    input: '|--',
    tag: 'mo',
    output: "\u22A2",
    tex: 'vdash',
    tType: tokens.CONST
  }, {
    input: '|==',
    tag: 'mo',
    output: "\u22A8",
    tex: 'models',
    tType: tokens.CONST
  }, // mimetex doesn't support
  // grouping brackets
  {
    input: '(',
    tag: 'mo',
    output: '(',
    tex: null,
    tType: tokens.LEFTBRACKET,
    val: true
  }, {
    input: ')',
    tag: 'mo',
    output: ')',
    tex: null,
    tType: tokens.RIGHTBRACKET,
    val: true
  }, {
    input: '[',
    tag: 'mo',
    output: '[',
    tex: null,
    tType: tokens.LEFTBRACKET,
    val: true
  }, {
    input: ']',
    tag: 'mo',
    output: ']',
    tex: null,
    tType: tokens.RIGHTBRACKET,
    val: true
  }, {
    input: '{',
    tag: 'mo',
    output: '{',
    tex: 'lbrace',
    tType: tokens.LEFTBRACKET
  }, {
    input: '}',
    tag: 'mo',
    output: '}',
    tex: 'rbrace',
    tType: tokens.RIGHTBRACKET
  }, {
    input: '|',
    tag: 'mo',
    output: '|',
    tex: null,
    tType: tokens.LEFTRIGHT,
    val: true
  }, // {input:'||', tag:'mo', output:'||', tex:null, ttype:LEFTRIGHT},
  {
    input: '(:',
    tag: 'mo',
    output: "\u2329",
    tex: 'langle',
    tType: tokens.LEFTBRACKET
  }, {
    input: ':)',
    tag: 'mo',
    output: "\u232A",
    tex: 'rangle',
    tType: tokens.RIGHTBRACKET
  }, {
    input: '<<',
    tag: 'mo',
    output: "\u2329",
    tex: 'langle',
    tType: tokens.LEFTBRACKET
  }, {
    input: '>>',
    tag: 'mo',
    output: "\u232A",
    tex: 'rangle',
    tType: tokens.RIGHTBRACKET
  }, {
    input: '{:',
    tag: 'mo',
    output: '{:',
    tex: null,
    tType: tokens.LEFTBRACKET,
    invisible: true
  }, {
    input: ':}',
    tag: 'mo',
    output: ':}',
    tex: null,
    tType: tokens.RIGHTBRACKET,
    invisible: true
  }, // miscellaneous symbols
  {
    input: 'int',
    tag: 'mo',
    output: "\u222B",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'dx',
    tag: 'mi',
    output: '{:d x:}',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'dy',
    tag: 'mi',
    output: '{:d y:}',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'dz',
    tag: 'mi',
    output: '{:d z:}',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'dt',
    tag: 'mi',
    output: '{:d t:}',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'oint',
    tag: 'mo',
    output: "\u222E",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'del',
    tag: 'mo',
    output: "\u2202",
    tex: 'partial',
    tType: tokens.CONST
  }, {
    input: 'grad',
    tag: 'mo',
    output: "\u2207",
    tex: 'nabla',
    tType: tokens.CONST
  }, {
    input: '+-',
    tag: 'mo',
    output: "\xB1",
    tex: 'pm',
    tType: tokens.CONST
  }, {
    input: 'O/',
    tag: 'mo',
    output: "\u2205",
    tex: 'emptyset',
    tType: tokens.CONST
  }, {
    input: 'oo',
    tag: 'mo',
    output: "\u221E",
    tex: 'infty',
    tType: tokens.CONST
  }, {
    input: 'aleph',
    tag: 'mo',
    output: "\u2135",
    tex: null,
    tType: tokens.CONST
  }, {
    input: '...',
    tag: 'mo',
    output: '...',
    tex: 'ldots',
    tType: tokens.CONST
  }, {
    input: ':.',
    tag: 'mo',
    output: "\u2234",
    tex: 'therefore',
    tType: tokens.CONST
  }, {
    input: ":'",
    tag: 'mo',
    output: "\u2235",
    tex: 'because',
    tType: tokens.CONST
  }, {
    input: '/_',
    tag: 'mo',
    output: "\u2220",
    tex: 'angle',
    tType: tokens.CONST
  }, {
    input: '/_\\',
    tag: 'mo',
    output: "\u25B3",
    tex: 'triangle',
    tType: tokens.CONST
  }, {
    input: '\\ ',
    tag: 'mo',
    output: "\xA0",
    tex: null,
    tType: tokens.CONST,
    val: true
  }, {
    input: 'frown',
    tag: 'mo',
    output: "\u2322",
    tex: null,
    tType: tokens.CONST
  }, {
    input: '%',
    tag: 'mo',
    output: '%',
    tex: '%',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'quad',
    tag: 'mo',
    output: "\xA0\xA0",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'qquad',
    tag: 'mo',
    output: "\xA0\xA0\xA0\xA0",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'cdots',
    tag: 'mo',
    output: "\u22EF",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'vdots',
    tag: 'mo',
    output: "\u22EE",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'ddots',
    tag: 'mo',
    output: "\u22F1",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'diamond',
    tag: 'mo',
    output: "\u22C4",
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'square',
    tag: 'mo',
    output: "\u25A1",
    tex: 'boxempty',
    tType: tokens.CONST
  }, {
    input: '|__',
    tag: 'mo',
    output: "\u230A",
    tex: 'lfloor',
    tType: tokens.CONST
  }, {
    input: '__|',
    tag: 'mo',
    output: "\u230B",
    tex: 'rfloor',
    tType: tokens.CONST
  }, {
    input: '|~',
    tag: 'mo',
    output: "\u2308",
    tex: 'lceil',
    tType: tokens.CONST
  }, {
    input: 'lceiling',
    tag: 'mo',
    output: '|~',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: '~|',
    tag: 'mo',
    output: "\u2309",
    tex: 'rceil',
    tType: tokens.CONST
  }, {
    input: 'rceiling',
    tag: 'mo',
    output: '~|',
    tex: null,
    tType: tokens.DEFINITION
  }, {
    input: 'CC',
    tag: 'mo',
    output: "\u2102",
    tex: 'mathbb{C}',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'NN',
    tag: 'mo',
    output: "\u2115",
    tex: 'mathbb{N}',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'QQ',
    tag: 'mo',
    output: "\u211A",
    tex: 'mathbb{Q}',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'RR',
    tag: 'mo',
    output: "\u211D",
    tex: 'mathbb{R}',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'ZZ',
    tag: 'mo',
    output: "\u2124",
    tex: 'mathbb{Z}',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'f',
    tag: 'mi',
    output: 'f',
    tex: null,
    tType: tokens.UNARY,
    func: true,
    val: true
  }, {
    input: 'g',
    tag: 'mi',
    output: 'g',
    tex: null,
    tType: tokens.UNARY,
    func: true,
    val: true
  }, {
    input: "''",
    tag: 'mo',
    output: "''",
    tex: null,
    val: true
  }, {
    input: "'''",
    tag: 'mo',
    output: "'''",
    tex: null,
    val: true
  }, {
    input: "''''",
    tag: 'mo',
    output: "''''",
    tex: null,
    val: true
  }, // standard functions
  {
    input: 'lim',
    tag: 'mo',
    output: 'lim',
    tex: null,
    tType: tokens.UNDEROVER
  }, {
    input: 'Lim',
    tag: 'mo',
    output: 'Lim',
    tex: null,
    tType: tokens.UNDEROVER
  }, {
    input: 'sin',
    tag: 'mo',
    output: 'sin',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'cos',
    tag: 'mo',
    output: 'cos',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'tan',
    tag: 'mo',
    output: 'tan',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'arcsin',
    tag: 'mo',
    output: 'arcsin',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'arccos',
    tag: 'mo',
    output: 'arccos',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'arctan',
    tag: 'mo',
    output: 'arctan',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'sinh',
    tag: 'mo',
    output: 'sinh',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'cosh',
    tag: 'mo',
    output: 'cosh',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'tanh',
    tag: 'mo',
    output: 'tanh',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'cot',
    tag: 'mo',
    output: 'cot',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'coth',
    tag: 'mo',
    output: 'coth',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'sech',
    tag: 'mo',
    output: 'sech',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'csch',
    tag: 'mo',
    output: 'csch',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'sec',
    tag: 'mo',
    output: 'sec',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'csc',
    tag: 'mo',
    output: 'csc',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'log',
    tag: 'mo',
    output: 'log',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'ln',
    tag: 'mo',
    output: 'ln',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'abs',
    tag: 'mo',
    output: 'abs',
    tex: null,
    tType: tokens.UNARY,
    noTexCopy: true,
    rewriteLeftRight: ['|', '|']
  }, {
    input: 'norm',
    tag: 'mo',
    output: 'norm',
    tex: null,
    tType: tokens.UNARY,
    noTexCopy: true,
    rewriteLeftRight: ['\\|', '\\|']
  }, {
    input: 'floor',
    tag: 'mo',
    output: 'floor',
    tex: null,
    tType: tokens.UNARY,
    noTexCopy: true,
    rewriteLeftRight: ['\\lfloor', '\\rfloor']
  }, {
    input: 'ceil',
    tag: 'mo',
    output: 'ceil',
    tex: null,
    tType: tokens.UNARY,
    noTexCopy: true,
    rewriteLeftRight: ['\\lceil', '\\rceil']
  }, {
    input: 'Sin',
    tag: 'mo',
    output: 'sin',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Cos',
    tag: 'mo',
    output: 'cos',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Tan',
    tag: 'mo',
    output: 'tan',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Arcsin',
    tag: 'mo',
    output: 'arcsin',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Arccos',
    tag: 'mo',
    output: 'arccos',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Arctan',
    tag: 'mo',
    output: 'arctan',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Sinh',
    tag: 'mo',
    output: 'sinh',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Sosh',
    tag: 'mo',
    output: 'cosh',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Tanh',
    tag: 'mo',
    output: 'tanh',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Cot',
    tag: 'mo',
    output: 'cot',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Sec',
    tag: 'mo',
    output: 'sec',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Csc',
    tag: 'mo',
    output: 'csc',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Log',
    tag: 'mo',
    output: 'log',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Ln',
    tag: 'mo',
    output: 'ln',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'Abs',
    tag: 'mo',
    output: 'abs',
    tex: null,
    tType: tokens.UNARY,
    noTexCopy: true,
    rewriteLeftRight: ['|', '|']
  }, {
    input: 'det',
    tag: 'mo',
    output: 'det',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'exp',
    tag: 'mo',
    output: 'exp',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'dim',
    tag: 'mo',
    output: 'dim',
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'mod',
    tag: 'mo',
    output: 'mod',
    tex: 'text{mod}',
    tType: tokens.CONST,
    noTexCopy: true
  }, {
    input: 'gcd',
    tag: 'mo',
    output: 'gcd',
    tex: null,
    tType: tokens.UNARY,
    func: true
  }, {
    input: 'lcm',
    tag: 'mo',
    output: 'lcm',
    tex: 'text{lcm}',
    tType: tokens.UNARY,
    func: true,
    noTexCopy: true
  }, {
    input: 'lub',
    tag: 'mo',
    output: 'lub',
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'glb',
    tag: 'mo',
    output: 'glb',
    tex: null,
    tType: tokens.CONST
  }, {
    input: 'min',
    tag: 'mo',
    output: 'min',
    tex: null,
    tType: tokens.UNDEROVER
  }, {
    input: 'max',
    tag: 'mo',
    output: 'max',
    tex: null,
    tType: tokens.UNDEROVER
  }, // arrows
  {
    input: 'uarr',
    tag: 'mo',
    output: "\u2191",
    tex: 'uparrow',
    tType: tokens.CONST
  }, {
    input: 'darr',
    tag: 'mo',
    output: "\u2193",
    tex: 'downarrow',
    tType: tokens.CONST
  }, {
    input: 'rarr',
    tag: 'mo',
    output: "\u2192",
    tex: 'rightarrow',
    tType: tokens.CONST
  }, {
    input: '->',
    tag: 'mo',
    output: "\u2192",
    tex: 'to',
    tType: tokens.CONST
  }, {
    input: '>->',
    tag: 'mo',
    output: "\u21A3",
    tex: 'rightarrowtail',
    tType: tokens.CONST
  }, {
    input: '->>',
    tag: 'mo',
    output: "\u21A0",
    tex: 'twoheadrightarrow',
    tType: tokens.CONST
  }, {
    input: '>->>',
    tag: 'mo',
    output: "\u2916",
    tex: 'twoheadrightarrowtail',
    tType: tokens.CONST
  }, {
    input: '|->',
    tag: 'mo',
    output: "\u21A6",
    tex: 'mapsto',
    tType: tokens.CONST
  }, {
    input: 'larr',
    tag: 'mo',
    output: "\u2190",
    tex: 'leftarrow',
    tType: tokens.CONST
  }, {
    input: 'harr',
    tag: 'mo',
    output: "\u2194",
    tex: 'leftrightarrow',
    tType: tokens.CONST
  }, {
    input: 'rArr',
    tag: 'mo',
    output: "\u21D2",
    tex: 'Rightarrow',
    tType: tokens.CONST
  }, {
    input: 'lArr',
    tag: 'mo',
    output: "\u21D0",
    tex: 'Leftarrow',
    tType: tokens.CONST
  }, {
    input: 'hArr',
    tag: 'mo',
    output: "\u21D4",
    tex: 'Leftrightarrow',
    tType: tokens.CONST
  }, // commands with argument
  {
    input: 'sqrt',
    tag: 'msqrt',
    output: 'sqrt',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'root',
    tag: 'mroot',
    output: 'root',
    tex: null,
    tType: tokens.BINARY
  }, {
    input: 'frac',
    tag: 'mfrac',
    output: '/',
    tex: null,
    tType: tokens.BINARY
  }, {
    input: '/',
    tag: 'mfrac',
    output: '/',
    tex: null,
    tType: tokens.INFIX
  }, {
    input: 'stackrel',
    tag: 'mover',
    output: 'stackrel',
    tex: null,
    tType: tokens.BINARY
  }, {
    input: '_',
    tag: 'msub',
    output: '_',
    tex: null,
    tType: tokens.INFIX
  }, {
    input: '^',
    tag: 'msup',
    output: '^',
    tex: null,
    tType: tokens.INFIX
  }, {
    input: 'cancel',
    tag: 'menclose',
    output: 'cancel',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'Sqrt',
    tag: 'msqrt',
    output: 'sqrt',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'hat',
    tag: 'mover',
    output: "^",
    tex: null,
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'bar',
    tag: 'mover',
    output: "\xAF",
    tex: 'overline',
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'vec',
    tag: 'mover',
    output: "\u2192",
    tex: null,
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'tilde',
    tag: 'mover',
    output: '~',
    tex: null,
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'dot',
    tag: 'mover',
    output: '.',
    tex: null,
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'ddot',
    tag: 'mover',
    output: '..',
    tex: null,
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'ul',
    tag: 'munder',
    output: "\u0332",
    tex: 'underline',
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'ubrace',
    tag: 'munder',
    output: "\u23DF",
    tex: 'underbrace',
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'obrace',
    tag: 'mover',
    output: "\u23DE",
    tex: 'overbrace',
    tType: tokens.UNARY,
    acc: true
  }, {
    input: 'text',
    tag: 'mtext',
    output: 'text',
    tex: null,
    tType: tokens.TEXT
  }, {
    input: 'mbox',
    tag: 'mtext',
    output: 'mbox',
    tex: null,
    tType: tokens.TEXT
  }, quoteSymbol, // { input: 'var', tag: 'mstyle', atname: 'fontstyle', atval: 'italic', output: 'var', tex: null, ttype: tokens.UNARY },
  {
    input: 'color',
    tag: 'mstyle',
    tType: tokens.BINARY
  }, {
    input: 'bb',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'bold',
    output: 'bb',
    tex: 'mathbf',
    tType: tokens.UNARY,
    noTexCopy: true
  }, {
    input: 'mathbf',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'bold',
    output: 'mathbf',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'sf',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'sans-serif',
    output: 'sf',
    tex: 'mathsf',
    tType: tokens.UNARY,
    noTexCopy: true
  }, {
    input: 'mathsf',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'sans-serif',
    output: 'mathsf',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'bbb',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'double-struck',
    output: 'bbb',
    tex: 'mathbb',
    tType: tokens.UNARY,
    noTexCopy: true
  }, {
    input: 'mathbb',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'double-struck',
    output: 'mathbb',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'cc',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'script',
    output: 'cc',
    tex: 'mathcal',
    tType: tokens.UNARY,
    noTexCopy: true
  }, {
    input: 'mathcal',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'script',
    output: 'mathcal',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'tt',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'monospace',
    output: 'tt',
    tex: 'mathtt',
    tType: tokens.UNARY,
    noTexCopy: true
  }, {
    input: 'mathtt',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'monospace',
    output: 'mathtt',
    tex: null,
    tType: tokens.UNARY
  }, {
    input: 'fr',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'fraktur',
    output: 'fr',
    tex: 'mathfrak',
    tType: tokens.UNARY,
    noTexCopy: true
  }, {
    input: 'mathfrak',
    tag: 'mstyle',
    atName: 'mathvariant',
    atVal: 'fraktur',
    output: 'mathfrak',
    tex: null,
    tType: tokens.UNARY
  }];
  /** @type {Array<string>} */
  
  var inputSymbols = [];
  {
    /** @type {Array<Symbol>} */
    var otherSymbols = symbols.filter(function (item) {
      return item.tex && item.noTexCopy !== true;
    }).map(function (item) {
      return {
        input: item.tex,
        tag: item.tag,
        output: item.output,
        tType: item.tType,
        acc: item.acc || false
      };
    });
    symbols.push.apply(symbols, _toConsumableArray(otherSymbols));
    symbols.sort(function (s1, s2) {
      return s1.input > s2.input ? 1 : -1;
    });
    inputSymbols = symbols.map(function (item) {
      return item.input;
    });
  }
  /**
   * @param {string} str
   * @param {number} n
   * @returns {string}
   */
  
  function removeCharsAndBlanks(str, n) {
    // remove n characters and any following blanks
    var st;
  
    if (str.charAt(n) === '\\' && str.charAt(n + 1) !== '\\' && str.charAt(n + 1) !== ' ') {
      st = str.slice(n + 1);
    } else {
      st = str.slice(n);
    }
  
    var i = 0;
  
    while (i < st.length && st.charCodeAt(i) <= 32) {
      i++;
    }
  
    return st.slice(i);
  }
  /**
   * @param {string[]} arr
   * @param {string} str
   * @param {number} n
   * @returns {number}
   */
  
  
  function position(arr, str, n) {
    // return position >=n where str appears or would be inserted
    // assumes arr is sorted
    if (n === 0) {
      var len = arr.length;
      n = -1;
  
      while (n + 1 < len) {
        var m = n + len >> 1;
  
        if (arr[m] < str) {
          n = m;
        } else {
          len = m;
        }
      }
  
      return len;
    }
  
    var i = n;
  
    while (i < arr.length && arr[i] < str) {
      i++;
    }
  
    return i; // i=arr.length || arr[i]>=str
  }
  /**
   * @param {string} str
   * @returns {Symbol}
   */
  
  
  function getSymbol(str) {
    var previousSymbol;
    var currentSymbol; // return maximal initial substring of str that appears in names
    // return null if there is none
  
    var newPos = 0; // new pos
  
    var oldPos = 0; // old pos
  
    var matchPos; // match pos
  
    var st;
    var tagst;
    var match = '';
    var more = true;
  
    for (var i = 1; i <= str.length && more; i++) {
      st = str.slice(0, i); // initial substring of length i
  
      oldPos = newPos;
      newPos = position(inputSymbols, st, oldPos);
  
      if (newPos < inputSymbols.length && str.slice(0, inputSymbols[newPos].length) === inputSymbols[newPos]) {
        match = inputSymbols[newPos];
        matchPos = newPos;
        i = match.length;
      }
  
      more = newPos < inputSymbols.length && str.slice(0, inputSymbols[newPos].length) >= inputSymbols[newPos];
    }
  
    previousSymbol = currentSymbol;
  
    if (match !== '') {
      currentSymbol = symbols[matchPos].tType;
      return symbols[matchPos];
    } // if str[0] is a digit or - return maxsubstring of digits.digits
  
  
    currentSymbol = tokens.CONST;
    newPos = 1;
    st = str.slice(0, 1);
    var integ = true;
  
    while ('0' <= st && st <= '9' && newPos <= str.length) {
      st = str.slice(newPos, newPos + 1);
      newPos++;
    }
  
    if (st === '.') {
      st = str.slice(newPos, newPos + 1);
  
      if ('0' <= st && st <= '9') {
        integ = false;
        newPos++;
  
        while ('0' <= st && st <= '9' && newPos <= str.length) {
          st = str.slice(newPos, newPos + 1);
          newPos++;
        }
      }
    }
  
    if (integ && newPos > 1 || newPos > 2) {
      st = str.slice(0, newPos - 1);
      tagst = 'mn';
    } else {
      newPos = 2;
      st = str.slice(0, 1); // take 1 character
  
      tagst = ('A' > st || st > 'Z') && ('a' > st || st > 'z') ? 'mo' : 'mi';
    }
  
    if (st === '-' && previousSymbol === tokens.INFIX) {
      currentSymbol = tokens.INFIX;
      return {
        input: st,
        tag: tagst,
        output: st,
        tType: tokens.UNARY,
        func: true,
        val: true
      };
    } // added val bit
  
  
    return {
      input: st,
      tag: tagst,
      output: st,
      tType: tokens.CONST,
      val: true
    };
  }
  /**
   * @param {string} node
   * @returns {string}
   */
  
  
  function removeBrackets(node) {
    if (node.charAt(0) === '{' && node.charAt(node.length - 1) === '}') {
      var leftchop = 0;
      var st = node.substr(1, 5);
  
      if (st === '\\left') {
        st = node.charAt(6);
  
        if (st === '(' || st === '[' || st === '{') {
          leftchop = 7;
        } else {
          st = node.substr(6, 7);
  
          if (st === '\\lbrace') {
            leftchop = 13;
          }
        }
      } else {
        st = node.charAt(1);
  
        if (st === '(' || st === '[') {
          leftchop = 2;
        }
      }
  
      if (leftchop > 0) {
        // st = node.charAt(node.length-7);
        st = node.substr(node.length - 8);
  
        if (st === '\\right)}' || st === '\\right]}' || st === '\\right.}') {
          node = '{' + node.substr(leftchop);
          node = node.substr(0, node.length - 8) + '}';
        } else if (st === '\\rbrace}') {
          node = '{' + node.substr(leftchop);
          node = node.substr(0, node.length - 14) + '}';
        }
      }
    }
  
    return node;
  }
  /*
    Parsing ASCII math expressions with the following grammar
    v ::= [A-Za-z] | greek letters | numbers | other constant symbols
    u ::= sqrt | text | bb | other unary symbols for font commands
    b ::= frac | root | stackrel         binary symbols
    l ::= ( | [ | { | (: | {:            left brackets
    r ::= ) | ] | } | :) | :}            right brackets
    S ::= v | lEr | uS | bSS             Simple expression
    I ::= S_S | S^S | S_S^S | S          Intermediate expression
    E ::= IE | I/I                       Expression
    Each terminal symbol is translated into a corresponding mathml node.
  */
  
  /**
   * @param {Symbol} symb
   * @returns {string}
   */
  
  
  function getTeXsymbol(symb) {
    var pre = '';
  
    if (typeof symb.val === 'boolean' && symb.val) {
      pre = '';
    } else {
      pre = '\\';
    }
  
    if (!symb.tex) {
      // can't remember why this was here.  Breaks /delta /Delta to removed
      // return (pre + (pre == '' ? symb.input : symb.input.toLowerCase()));
      return pre + symb.input;
    } else {
      return pre + symb.tex;
    }
  }
  /**
   * @param {string} str
   * @param {number} depth
   * @returns {[string, string]}
   */
  
  
  function parseSexpr(str, depth) {
    // parses str and returns [node,tailstr]
    // const rightvert = false,
    str = removeCharsAndBlanks(str, 0);
    var symbol = getSymbol(str); // either a token or a bracket or empty
  
    if (!symbol || symbol.tType === tokens.RIGHTBRACKET && depth > 0) {
      return [null, str];
    }
  
    if (symbol.tType === tokens.DEFINITION) {
      str = symbol.output + removeCharsAndBlanks(str, symbol.input.length);
      symbol = getSymbol(str);
    }
  
    switch (symbol.tType) {
      case tokens.UNDEROVER:
      case tokens.CONST:
        str = removeCharsAndBlanks(str, symbol.input.length);
        var texsymbol = getTeXsymbol(symbol);
  
        if (texsymbol.charAt(0) === '\\' || symbol.tag === 'mo') {
          return [texsymbol, str];
        } else {
          return ["{".concat(texsymbol, "}"), str];
        }
  
      case tokens.LEFTBRACKET:
        {
          // read (expr+)
          depth++;
          str = removeCharsAndBlanks(str, symbol.input.length);
          var result = parseExpr(str, true, depth);
          depth--;
          var leftchop = 0;
  
          if (result[0].substr(0, 6) === '\\right') {
            st = result[0].charAt(6);
  
            if (st === ')' || st === ']' || st === '}') {
              leftchop = 6;
            } else if (st === '.') {
              leftchop = 7;
            } else {
              st = result[0].substr(6, 7);
  
              if (st === '\\rbrace') {
                leftchop = 13;
              }
            }
          }
  
          var node = '';
  
          if (leftchop > 0) {
            result[0] = result[0].substr(leftchop);
  
            if (symbol.invisible) {
              node = "{".concat(result[0], "}");
            } else {
              node = "{".concat(getTeXsymbol(symbol)).concat(result[0], "}");
            }
          } else {
            if (symbol.invisible) {
              node = "{\\left.".concat(result[0], "}");
            } else {
              node = "{\\left".concat(getTeXsymbol(symbol)).concat(result[0], "}");
            }
          }
  
          return [node, result[1]];
        }
  
      case tokens.TEXT:
        {
          if (symbol !== quoteSymbol) {
            str = removeCharsAndBlanks(str, symbol.input.length);
          }
          /** @type {number} */
  
  
          var i;
  
          if (str.charAt(0) === '{') {
            i = str.indexOf('}');
          } else if (str.charAt(0) === '(') {
            i = str.indexOf(')');
          } else if (str.charAt(0) === '[') {
            i = str.indexOf(']');
          } else if (symbol === quoteSymbol) {
            i = str.slice(1).indexOf("'") + 1;
          } else {
            i = 0;
          }
  
          if (i === -1) {
            i = str.length;
          }
  
          st = str.slice(1, i);
          var newFrag = '';
  
          if (st.charAt(0) === ' ') {
            newFrag = '\\ ';
          }
  
          newFrag += "\\text{".concat(st, "}");
  
          if (st.charAt(st.length - 1) === ' ') {
            newFrag += '\\ ';
          }
  
          str = removeCharsAndBlanks(str, i + 1);
          return [newFrag, str];
        }
  
      case tokens.UNARY:
        {
          str = removeCharsAndBlanks(str, symbol.input.length);
  
          var _result = parseSexpr(str, depth);
  
          if (_result[0] === null) {
            return ["{".concat(getTeXsymbol(symbol), "}"), str];
          }
  
          if (symbol.func === true) {
            // functions hack
            st = str.charAt(0);
  
            if (st === '^' || st === '_' || st === '/' || st === '|' || st === ',' || symbol.input.length === 1 && symbol.input.match(/\w/) && st !== '(') {
              return ["{".concat(getTeXsymbol(symbol), "}"), str];
            } else {
              var _node = "{".concat(getTeXsymbol(symbol), "{").concat(_result[0], "}}");
  
              return [_node, _result[1]];
            }
          }
  
          _result[0] = removeBrackets(_result[0]);
  
          if (symbol.input === 'sqrt') {
            // sqrt
            return ["\\sqrt{".concat(_result[0], "}"), _result[1]];
          } else if (symbol.input === 'cancel') {
            // cancel
            return ["\\cancel{".concat(_result[0], "}"), _result[1]];
          } else if (typeof symbol.rewriteLeftRight !== 'undefined') {
            // abs, floor, ceil
            return ["{\\left".concat(symbol.rewriteLeftRight[0]).concat(_result[0], "\\right").concat(symbol.rewriteLeftRight[1], "}"), _result[1]];
          } else if (symbol.acc === true) {
            // accent
            // return ['{'+getTeXsymbol(symbol)+'{'+result[0]+'}}',result[1]];
            return ["".concat(getTeXsymbol(symbol), "{").concat(_result[0], "}"), _result[1]];
          } else {
            // font change command
            return ["{".concat(getTeXsymbol(symbol), "{").concat(_result[0], "}}"), _result[1]];
          }
        }
  
      case tokens.BINARY:
        {
          str = removeCharsAndBlanks(str, symbol.input.length);
  
          var _result2 = parseSexpr(str, depth);
  
          if (_result2[0] === null) {
            return ["{".concat(getTeXsymbol(symbol), "}"), str];
          }
  
          _result2[0] = removeBrackets(_result2[0]);
          var result2 = parseSexpr(_result2[1], depth);
  
          if (result2[0] === null) {
            return ["{".concat(getTeXsymbol(symbol), "}"), str];
          }
  
          result2[0] = removeBrackets(result2[0]);
          var _newFrag = '';
  
          if (symbol.input === 'color') {
            _newFrag = "{\\color{".concat(_result2[0].replace(/[{}]/g, ''), "}").concat(result2[0], "}");
          } else if (symbol.input === 'root') {
            _newFrag = "{\\sqrt[".concat(_result2[0], "]{").concat(result2[0], "}}");
          } else {
            _newFrag = "{".concat(getTeXsymbol(symbol), "{").concat(_result2[0], "}{").concat(result2[0], "}}");
          }
  
          return [_newFrag, result2[1]];
        }
  
      case tokens.INFIX:
        str = removeCharsAndBlanks(str, symbol.input.length);
        return [symbol.output, str];
  
      case tokens.SPACE:
        str = removeCharsAndBlanks(str, symbol.input.length);
        return ["{\\quad\\text{".concat(symbol.input, "}\\quad}"), str];
  
      case tokens.LEFTRIGHT:
        {
          //    if (rightvert) return [null,str]; else rightvert = true;
          depth++;
          str = removeCharsAndBlanks(str, symbol.input.length);
  
          var _result3 = parseExpr(str, false, depth);
  
          depth--;
          var st = '';
          st = _result3[0].charAt(_result3[0].length - 1); // alert(result[0].lastChild+'***'+st);
  
          if (st === '|') {
            // its an absolute value subterm
            var _node2 = "{\\left|".concat(_result3[0], "}");
  
            return [_node2, _result3[1]];
          } else {
            // the '|' is a \mid
            var _node3 = '{\\mid}';
            return [_node3, str];
          }
        }
  
      default:
        // alert('default');
        str = removeCharsAndBlanks(str, symbol.input.length);
        return ["{".concat(getTeXsymbol(symbol), "}"), str];
    }
  }
  /**
   * @param {string} str
   * @param {number} depth
   * @returns {[string, string]}
   */
  
  
  function parseIexpr(str, depth) {
    var sym2;
    str = removeCharsAndBlanks(str, 0);
    var sym1 = getSymbol(str);
    var result = parseSexpr(str, depth);
    var node = result[0];
    str = result[1];
    var symbol = getSymbol(str);
  
    if (!(symbol.tType === tokens.INFIX && symbol.input !== '/')) {
      return [node, str];
    }
  
    str = removeCharsAndBlanks(str, symbol.input.length); // if (symbol.input === '/') result = parseIexpr(str); else
  
    result = parseSexpr(str, depth); // show box in place of missing argument
  
    if (result[0] === null) {
      result[0] = '{}';
    } else {
      result[0] = removeBrackets(result[0]);
    }
  
    str = result[1]; //    if (symbol.input === '/') removeBrackets(node);
  
    if (symbol.input === '_') {
      sym2 = getSymbol(str);
  
      if (sym2.input === '^') {
        str = removeCharsAndBlanks(str, sym2.input.length);
        var res2 = parseSexpr(str, depth);
        res2[0] = removeBrackets(res2[0]);
        str = res2[1];
        node = "{".concat(node);
        node += "_{".concat(result[0], "}");
        node += "^{".concat(res2[0], "}");
        node += '}';
      } else {
        node += "_{".concat(result[0], "}");
      }
    } else {
      // must be ^
      // node = '{'+node+'}^{'+result[0]+'}';
      node = "".concat(node, "^{").concat(result[0], "}");
    }
  
    if (typeof sym1.func !== 'undefined' && sym1.func) {
      sym2 = getSymbol(str);
  
      if (sym2.tType !== tokens.INFIX && sym2.tType !== tokens.RIGHTBRACKET) {
        result = parseIexpr(str, depth);
        node = "{".concat(node).concat(result[0], "}");
        str = result[1];
      }
    }
  
    return [node, str];
  }
  /**
   * @param {string} str
   * @param {boolean} rightbracket
   * @param {number} depth
   * @returns {[string, string]}
   */
  
  
  function parseExpr(str, rightbracket, depth) {
    var symbol;
    var node;
    var result;
    var i; // const nodeList = [];
  
    var newFrag = '';
    var addedright = false;
  
    do {
      str = removeCharsAndBlanks(str, 0);
      result = parseIexpr(str, depth);
      node = result[0];
      str = result[1];
      symbol = getSymbol(str);
  
      if (symbol.tType === tokens.INFIX && symbol.input === '/') {
        str = removeCharsAndBlanks(str, symbol.input.length);
        result = parseIexpr(str, depth); // show box in place of missing argument
  
        if (result[0] === null) {
          result[0] = '{}';
        } else {
          result[0] = removeBrackets(result[0]);
        }
  
        str = result[1];
        node = removeBrackets(node);
        node = "".concat('\\frac' + '{').concat(node, "}");
        node += "{".concat(result[0], "}");
        newFrag += node;
        symbol = getSymbol(str);
      } else if (node) {
        newFrag += node;
      }
    } while ((symbol.tType !== tokens.RIGHTBRACKET && (symbol.tType !== tokens.LEFTRIGHT || rightbracket) || depth === 0) && symbol && symbol.output);
  
    if (symbol.tType === tokens.RIGHTBRACKET || symbol.tType === tokens.LEFTRIGHT) {
      //    if (depth > 0) depth--;
      var len = newFrag.length;
  
      if (len > 2 && newFrag.charAt(0) === '{' && newFrag.indexOf(',') > 0) {
        // could be matrix (total rewrite from .js)
        var right = newFrag.charAt(len - 2);
  
        if (right === ')' || right === ']') {
          var left = newFrag.charAt(6);
  
          if (left === '(' && right === ')' && symbol.output !== '}' || left === '[' && right === ']') {
            var mxout = '\\matrix{';
            var pos = new Array(); // position of commas
  
            pos.push(0);
            var matrix = true;
            var mxnestingd = 0;
            var subpos = [];
            subpos[0] = [0];
            var lastsubposstart = 0;
            var mxanynestingd = 0;
  
            for (i = 1; i < len - 1; i++) {
              if (newFrag.charAt(i) === left) {
                mxnestingd++;
              }
  
              if (newFrag.charAt(i) === right) {
                mxnestingd--;
  
                if (mxnestingd === 0 && newFrag.charAt(i + 2) === ',' && newFrag.charAt(i + 3) === '{') {
                  pos.push(i + 2);
                  lastsubposstart = i + 2;
                  subpos[lastsubposstart] = [i + 2];
                }
              }
  
              if (newFrag.charAt(i) === '[' || newFrag.charAt(i) === '(' || newFrag.charAt(i) === '{') {
                mxanynestingd++;
              }
  
              if (newFrag.charAt(i) === ']' || newFrag.charAt(i) === ')' || newFrag.charAt(i) === '}') {
                mxanynestingd--;
              }
  
              if (newFrag.charAt(i) === ',' && mxanynestingd === 1) {
                subpos[lastsubposstart].push(i);
              }
  
              if (mxanynestingd < 0) {
                // happens at the end of the row
                if (lastsubposstart === i + 1) {
                  // if at end of row, skip to next row
                  i++;
                } else {
                  // misformed something - abandon treating as a matrix
                  matrix = false;
                }
              }
            }
  
            pos.push(len);
            var lastmxsubcnt = -1;
  
            if (mxnestingd === 0 && pos.length > 0 && matrix) {
              for (i = 0; i < pos.length - 1; i++) {
                if (i > 0) {
                  mxout += '\\\\';
                }
  
                var subarr = void 0;
  
                if (i === 0) {
                  // subarr = newFrag.substr(pos[i]+7,pos[i+1]-pos[i]-15).split(',');
                  if (subpos[pos[i]].length === 1) {
                    subarr = [newFrag.substr(pos[i] + 7, pos[i + 1] - pos[i] - 15)];
                  } else {
                    var _subarr = [newFrag.substring(pos[i] + 7, subpos[pos[i]][1])];
  
                    for (var j = 2; j < subpos[pos[i]].length; j++) {
                      _subarr.push(newFrag.substring(subpos[pos[i]][j - 1] + 1, subpos[pos[i]][j]));
                    }
  
                    _subarr.push(newFrag.substring(subpos[pos[i]][subpos[pos[i]].length - 1] + 1, pos[i + 1] - 8));
                  }
                } else {
                  // const subarr = newFrag.substr(pos[i]+8,pos[i+1]-pos[i]-16).split(',');
                  if (subpos[pos[i]].length === 1) {
                    subarr = [newFrag.substr(pos[i] + 8, pos[i + 1] - pos[i] - 16)];
                  } else {
                    subarr = [newFrag.substring(pos[i] + 8, subpos[pos[i]][1])];
  
                    for (var _j = 2; _j < subpos[pos[i]].length; _j++) {
                      subarr.push(newFrag.substring(subpos[pos[i]][_j - 1] + 1, subpos[pos[i]][_j]));
                    }
  
                    subarr.push(newFrag.substring(subpos[pos[i]][subpos[pos[i]].length - 1] + 1, pos[i + 1] - 8));
                  }
                }
  
                if (lastmxsubcnt > 0 && subarr.length !== lastmxsubcnt) {
                  matrix = false;
                } else if (lastmxsubcnt === -1) {
                  lastmxsubcnt = subarr.length;
                }
  
                mxout += subarr.join('&');
              }
            }
  
            mxout += '}';
  
            if (matrix) {
              newFrag = mxout;
            }
          }
        }
      }
  
      str = removeCharsAndBlanks(str, symbol.input.length);
  
      if (typeof symbol.invisible !== 'boolean' || !symbol.invisible) {
        node = "\\right".concat(getTeXsymbol(symbol)); // AMcreateMmlNode('mo',document.createTextNode(symbol.output));
  
        newFrag += node;
        addedright = true;
      } else {
        newFrag += '\\right.';
        addedright = true;
      }
    }
  
    if (depth > 0 && !addedright) {
      newFrag += '\\right.'; // adjust for non-matching left brackets
      // todo: adjust for non-matching right brackets
    }
  
    return [newFrag, str];
  }
  /**
   * @param {string} str
   * @returns {string}
   */
  
  
  function asciimathToTex(str) {
    str = str.replace(/(&nbsp;|\u00a0|&#160;)/g, '').replace(/&gt;/g, '>').replace(/&lt;/g, '<');
  
    if (!str.match(/\S/)) {
      return '';
    }
  
    return parseExpr(str.replace(/^\s+/g, ''), false, 0)[0];
  }
  
  {
    var _require = require('jsdom'),
        JSDOM = _require.JSDOM;
  
    var jsdom = new JSDOM();
    global.DOMParser = jsdom.window.DOMParser;
    global.document = jsdom.window.document;
  }
  /**
   * @param {object} opts
   * @param {NodeListOf<Element>} opts.elements
   * @param opts.config
   * @param {boolean} opts.isAsciimath
   */
  
  
  function renderBlockElements(_ref) {
    var elements = _ref.elements,
        config = _ref.config,
        isAsciimath = _ref.isAsciimath;
  
    if (!elements.length) {
      return;
    }
  
    elements.forEach(function (element) {
      var input = element.textContent;
      var latex = isAsciimath ? asciimathToTex(input) : input;
      var html = katex.renderToString(latex, config);
      element.parentNode.outerHTML = "<span title=\"".concat(input.trim(), "\">").concat(html, "</span>");
    });
  }
  /**
   * https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
   * @param {string} str
   * @returns {string} regexp escaped string
   */
  
  
  function escapeRegExp(str) {
    return str.replace(/[-[\]/{}()*+?.\\$^|]/g, '\\$&');
  } // katex config
  
  
  var getConfig = function getConfig() {
    var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    return _extends({
      displayMode: true,
      throwOnError: false,
      // fail silently
      errorColor: '#ff0000'
    }, config, {
      delimiters: (config.delimiters || []).concat([{
        left: '$$',
        right: '$$',
        display: false
      }, {
        left: '~',
        right: '~',
        display: false,
        asciimath: true
      }])
    });
  };
  
  var showdownKatex = function showdownKatex(userConfig) {
    return function () {
      var parser = new DOMParser();
      var config = getConfig(userConfig);
      var asciimathDelimiters = config.delimiters.filter(function (item) {
        return item.asciimath;
      }).map(function (_ref2) {
        var left = _ref2.left,
            right = _ref2.right;
        var test = new RegExp("".concat(escapeRegExp(left), "(.*?)").concat(escapeRegExp(right)), 'g');
  
        var replacer = function replacer(match, asciimath) {
          return "".concat(left).concat(asciimathToTex(asciimath)).concat(right);
        };
  
        return {
          test: test,
          replacer: replacer
        };
      });
      return [{
        type: 'output',
        filter: function filter() {
          var html = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
          // parse html
          var wrapper = parser.parseFromString(html, 'text/html').body;
  
          if (asciimathDelimiters.length) {
            // convert inline asciimath to inline latex
            // ignore anything in code and pre elements
            wrapper.querySelectorAll(':not(code):not(pre)').forEach(function (el) {
              /** @type Text[] */
              var textNodes = _toConsumableArray(el.childNodes).filter( // skip "empty" text nodes
              function (node) {
                return node.nodeName === '#text' && node.nodeValue.trim();
              });
  
              textNodes.forEach(function (node) {
                var newText = asciimathDelimiters.reduce(function (acc, _ref3) {
                  var test = _ref3.test,
                      replacer = _ref3.replacer;
                  return acc.replace(test, replacer);
                }, node.nodeValue);
                node.nodeValue = newText;
              });
            });
          } // find the math in code blocks
  
  
          var latex = wrapper.querySelectorAll('code.latex.language-latex');
          var asciimath = wrapper.querySelectorAll('code.asciimath.language-asciimath');
          renderBlockElements({
            elements: latex,
            config: config
          });
          renderBlockElements({
            elements: asciimath,
            config: config,
            isAsciimath: true
          });
          renderMathInElement(wrapper, config); // return html without the wrapper
  
          return wrapper.innerHTML;
        }
      }];
    };
  }; // register extension with default config
  
  
  showdown.extension('showdown-katex', showdownKatex());
  
  module.exports = showdownKatex;
  //# sourceMappingURL=showdown-katex.js.map
  