3241 lines
		
	
	
		
			79 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			3241 lines
		
	
	
		
			79 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| ![mergify[bot]](/assets/img/avatar_default.png)  | (function webpackUniversalModuleDefinition(root, factory) { | ||
|  | 	if(typeof exports === 'object' && typeof module === 'object') | ||
|  | 		module.exports = factory(require("katex")); | ||
|  | 	else if(typeof define === 'function' && define.amd) | ||
|  | 		define(["katex"], factory); | ||
|  | 	else { | ||
|  | 		var a = typeof exports === 'object' ? factory(require("katex")) : factory(root["katex"]); | ||
|  | 		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; | ||
|  | 	} | ||
|  | })((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__0__) { | ||
|  | return /******/ (function(modules) { // webpackBootstrap
 | ||
|  | /******/ 	// The module cache
 | ||
|  | /******/ 	var installedModules = {}; | ||
|  | /******/ | ||
|  | /******/ 	// The require function
 | ||
|  | /******/ 	function __webpack_require__(moduleId) { | ||
|  | /******/ | ||
|  | /******/ 		// Check if module is in cache
 | ||
|  | /******/ 		if(installedModules[moduleId]) { | ||
|  | /******/ 			return installedModules[moduleId].exports; | ||
|  | /******/ 		} | ||
|  | /******/ 		// Create a new module (and put it into the cache)
 | ||
|  | /******/ 		var module = installedModules[moduleId] = { | ||
|  | /******/ 			i: moduleId, | ||
|  | /******/ 			l: false, | ||
|  | /******/ 			exports: {} | ||
|  | /******/ 		}; | ||
|  | /******/ | ||
|  | /******/ 		// Execute the module function
 | ||
|  | /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
|  | /******/ | ||
|  | /******/ 		// Flag the module as loaded
 | ||
|  | /******/ 		module.l = true; | ||
|  | /******/ | ||
|  | /******/ 		// Return the exports of the module
 | ||
|  | /******/ 		return module.exports; | ||
|  | /******/ 	} | ||
|  | /******/ | ||
|  | /******/ | ||
|  | /******/ 	// expose the modules object (__webpack_modules__)
 | ||
|  | /******/ 	__webpack_require__.m = modules; | ||
|  | /******/ | ||
|  | /******/ 	// expose the module cache
 | ||
|  | /******/ 	__webpack_require__.c = installedModules; | ||
|  | /******/ | ||
|  | /******/ 	// define getter function for harmony exports
 | ||
|  | /******/ 	__webpack_require__.d = function(exports, name, getter) { | ||
|  | /******/ 		if(!__webpack_require__.o(exports, name)) { | ||
|  | /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter }); | ||
|  | /******/ 		} | ||
|  | /******/ 	}; | ||
|  | /******/ | ||
|  | /******/ 	// define __esModule on exports
 | ||
|  | /******/ 	__webpack_require__.r = function(exports) { | ||
|  | /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | ||
|  | /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | ||
|  | /******/ 		} | ||
|  | /******/ 		Object.defineProperty(exports, '__esModule', { value: true }); | ||
|  | /******/ 	}; | ||
|  | /******/ | ||
|  | /******/ 	// create a fake namespace object
 | ||
|  | /******/ 	// mode & 1: value is a module id, require it
 | ||
|  | /******/ 	// mode & 2: merge all properties of value into the ns
 | ||
|  | /******/ 	// mode & 4: return value when already ns object
 | ||
|  | /******/ 	// mode & 8|1: behave like require
 | ||
|  | /******/ 	__webpack_require__.t = function(value, mode) { | ||
|  | /******/ 		if(mode & 1) value = __webpack_require__(value); | ||
|  | /******/ 		if(mode & 8) return value; | ||
|  | /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | ||
|  | /******/ 		var ns = Object.create(null); | ||
|  | /******/ 		__webpack_require__.r(ns); | ||
|  | /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | ||
|  | /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | ||
|  | /******/ 		return ns; | ||
|  | /******/ 	}; | ||
|  | /******/ | ||
|  | /******/ 	// getDefaultExport function for compatibility with non-harmony modules
 | ||
|  | /******/ 	__webpack_require__.n = function(module) { | ||
|  | /******/ 		var getter = module && module.__esModule ? | ||
|  | /******/ 			function getDefault() { return module['default']; } : | ||
|  | /******/ 			function getModuleExports() { return module; }; | ||
|  | /******/ 		__webpack_require__.d(getter, 'a', getter); | ||
|  | /******/ 		return getter; | ||
|  | /******/ 	}; | ||
|  | /******/ | ||
|  | /******/ 	// Object.prototype.hasOwnProperty.call
 | ||
|  | /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
|  | /******/ | ||
|  | /******/ 	// __webpack_public_path__
 | ||
|  | /******/ 	__webpack_require__.p = ""; | ||
|  | /******/ | ||
|  | /******/ | ||
|  | /******/ 	// Load entry module and return exports
 | ||
|  | /******/ 	return __webpack_require__(__webpack_require__.s = 1); | ||
|  | /******/ }) | ||
|  | /************************************************************************/ | ||
|  | /******/ ([ | ||
|  | /* 0 */ | ||
|  | /***/ (function(module, exports) { | ||
|  | 
 | ||
|  | module.exports = __WEBPACK_EXTERNAL_MODULE__0__; | ||
|  | 
 | ||
|  | /***/ }), | ||
|  | /* 1 */ | ||
|  | /***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
|  | 
 | ||
|  | "use strict"; | ||
|  | __webpack_require__.r(__webpack_exports__); | ||
|  | /* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0); | ||
|  | /* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__); | ||
|  | /* eslint-disable */ | ||
|  | 
 | ||
|  | /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ | ||
|  | 
 | ||
|  | /* vim: set ts=2 et sw=2 tw=80: */ | ||
|  | 
 | ||
|  | /************************************************************* | ||
|  |  * | ||
|  |  *  KaTeX mhchem.js | ||
|  |  * | ||
|  |  *  This file implements a KaTeX version of mhchem version 3.3.0. | ||
|  |  *  It is adapted from MathJax/extensions/TeX/mhchem.js | ||
|  |  *  It differs from the MathJax version as follows: | ||
|  |  *    1. The interface is changed so that it can be called from KaTeX, not MathJax. | ||
|  |  *    2. \rlap and \llap are replaced with \mathrlap and \mathllap. | ||
|  |  *    3. Four lines of code are edited in order to use \raisebox instead of \raise. | ||
|  |  *    4. The reaction arrow code is simplified. All reaction arrows are rendered | ||
|  |  *       using KaTeX extensible arrows instead of building non-extensible arrows. | ||
|  |  *    5. \tripledash vertical alignment is slightly adjusted. | ||
|  |  * | ||
|  |  *    This code, as other KaTeX code, is released under the MIT license. | ||
|  |  * | ||
|  |  * /************************************************************* | ||
|  |  * | ||
|  |  *  MathJax/extensions/TeX/mhchem.js | ||
|  |  * | ||
|  |  *  Implements the \ce command for handling chemical formulas | ||
|  |  *  from the mhchem LaTeX package. | ||
|  |  * | ||
|  |  *  --------------------------------------------------------------------- | ||
|  |  * | ||
|  |  *  Copyright (c) 2011-2015 The MathJax Consortium | ||
|  |  *  Copyright (c) 2015-2018 Martin Hensel | ||
|  |  * | ||
|  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||
|  |  *  you may not use this file except in compliance with the License. | ||
|  |  *  You may obtain a copy of the License at | ||
|  |  * | ||
|  |  *      http://www.apache.org/licenses/LICENSE-2.0
 | ||
|  |  * | ||
|  |  *  Unless required by applicable law or agreed to in writing, software | ||
|  |  *  distributed under the License is distributed on an "AS IS" BASIS, | ||
|  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  |  *  See the License for the specific language governing permissions and | ||
|  |  *  limitations under the License. | ||
|  |  */ | ||
|  | //
 | ||
|  | // Coding Style
 | ||
|  | //   - use '' for identifiers that can by minified/uglified
 | ||
|  | //   - use "" for strings that need to stay untouched
 | ||
|  | // version: "3.3.0" for MathJax and KaTeX
 | ||
|  | // Add \ce, \pu, and \tripledash to the KaTeX macros.
 | ||
|  | katex__WEBPACK_IMPORTED_MODULE_0___default.a.__defineMacro("\\ce", function (context) { | ||
|  |   return chemParse(context.consumeArgs(1)[0], "ce"); | ||
|  | }); | ||
|  | 
 | ||
|  | katex__WEBPACK_IMPORTED_MODULE_0___default.a.__defineMacro("\\pu", function (context) { | ||
|  |   return chemParse(context.consumeArgs(1)[0], "pu"); | ||
|  | }); //  Needed for \bond for the ~ forms
 | ||
|  | //  Raise by 2.56mu, not 2mu. We're raising a hyphen-minus, U+002D, not
 | ||
|  | //  a mathematical minus, U+2212. So we need that extra 0.56.
 | ||
|  | 
 | ||
|  | 
 | ||
|  | katex__WEBPACK_IMPORTED_MODULE_0___default.a.__defineMacro("\\tripledash", "{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu" + "\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}"); | ||
|  | 
 | ||
|  |  //
 | ||
|  | //  This is the main function for handing the \ce and \pu commands.
 | ||
|  | //  It takes the argument to \ce or \pu and returns the corresponding TeX string.
 | ||
|  | //
 | ||
|  | 
 | ||
|  | var chemParse = function chemParse(tokens, stateMachine) { | ||
|  |   // Recreate the argument string from KaTeX's array of tokens.
 | ||
|  |   var str = ""; | ||
|  |   var expectedLoc = tokens[tokens.length - 1].loc.start; | ||
|  | 
 | ||
|  |   for (var i = tokens.length - 1; i >= 0; i--) { | ||
|  |     if (tokens[i].loc.start > expectedLoc) { | ||
|  |       // context.consumeArgs has eaten a space.
 | ||
|  |       str += " "; | ||
|  |       expectedLoc = tokens[i].loc.start; | ||
|  |     } | ||
|  | 
 | ||
|  |     str += tokens[i].text; | ||
|  |     expectedLoc += tokens[i].text.length; | ||
|  |   } | ||
|  | 
 | ||
|  |   var tex = texify.go(mhchemParser.go(str, stateMachine)); | ||
|  |   return tex; | ||
|  | }; //
 | ||
|  | // Core parser for mhchem syntax  (recursive)
 | ||
|  | //
 | ||
|  | 
 | ||
|  | /** @type {MhchemParser} */ | ||
|  | 
 | ||
|  | 
 | ||
|  | var mhchemParser = { | ||
|  |   //
 | ||
|  |   // Parses mchem \ce syntax
 | ||
|  |   //
 | ||
|  |   // Call like
 | ||
|  |   //   go("H2O");
 | ||
|  |   //
 | ||
|  |   go: function go(input, stateMachine) { | ||
|  |     if (!input) { | ||
|  |       return []; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (stateMachine === undefined) { | ||
|  |       stateMachine = 'ce'; | ||
|  |     } | ||
|  | 
 | ||
|  |     var state = '0'; //
 | ||
|  |     // String buffers for parsing:
 | ||
|  |     //
 | ||
|  |     // buffer.a == amount
 | ||
|  |     // buffer.o == element
 | ||
|  |     // buffer.b == left-side superscript
 | ||
|  |     // buffer.p == left-side subscript
 | ||
|  |     // buffer.q == right-side subscript
 | ||
|  |     // buffer.d == right-side superscript
 | ||
|  |     //
 | ||
|  |     // buffer.r == arrow
 | ||
|  |     // buffer.rdt == arrow, script above, type
 | ||
|  |     // buffer.rd == arrow, script above, content
 | ||
|  |     // buffer.rqt == arrow, script below, type
 | ||
|  |     // buffer.rq == arrow, script below, content
 | ||
|  |     //
 | ||
|  |     // buffer.text_
 | ||
|  |     // buffer.rm
 | ||
|  |     // etc.
 | ||
|  |     //
 | ||
|  |     // buffer.parenthesisLevel == int, starting at 0
 | ||
|  |     // buffer.sb == bool, space before
 | ||
|  |     // buffer.beginsWithBond == bool
 | ||
|  |     //
 | ||
|  |     // These letters are also used as state names.
 | ||
|  |     //
 | ||
|  |     // Other states:
 | ||
|  |     // 0 == begin of main part (arrow/operator unlikely)
 | ||
|  |     // 1 == next entity
 | ||
|  |     // 2 == next entity (arrow/operator unlikely)
 | ||
|  |     // 3 == next atom
 | ||
|  |     // c == macro
 | ||
|  |     //
 | ||
|  | 
 | ||
|  |     /** @type {Buffer} */ | ||
|  | 
 | ||
|  |     var buffer = {}; | ||
|  |     buffer['parenthesisLevel'] = 0; | ||
|  |     input = input.replace(/\n/g, " "); | ||
|  |     input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-"); | ||
|  |     input = input.replace(/[\u2026]/g, "..."); //
 | ||
|  |     // Looks through mhchemParser.transitions, to execute a matching action
 | ||
|  |     // (recursive)
 | ||
|  |     //
 | ||
|  | 
 | ||
|  |     var lastInput; | ||
|  |     var watchdog = 10; | ||
|  |     /** @type {ParserOutput[]} */ | ||
|  | 
 | ||
|  |     var output = []; | ||
|  | 
 | ||
|  |     while (true) { | ||
|  |       if (lastInput !== input) { | ||
|  |         watchdog = 10; | ||
|  |         lastInput = input; | ||
|  |       } else { | ||
|  |         watchdog--; | ||
|  |       } //
 | ||
|  |       // Find actions in transition table
 | ||
|  |       //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |       var machine = mhchemParser.stateMachines[stateMachine]; | ||
|  |       var t = machine.transitions[state] || machine.transitions['*']; | ||
|  | 
 | ||
|  |       iterateTransitions: for (var i = 0; i < t.length; i++) { | ||
|  |         var matches = mhchemParser.patterns.match_(t[i].pattern, input); | ||
|  | 
 | ||
|  |         if (matches) { | ||
|  |           //
 | ||
|  |           // Execute actions
 | ||
|  |           //
 | ||
|  |           var task = t[i].task; | ||
|  | 
 | ||
|  |           for (var iA = 0; iA < task.action_.length; iA++) { | ||
|  |             var o; //
 | ||
|  |             // Find and execute action
 | ||
|  |             //
 | ||
|  | 
 | ||
|  |             if (machine.actions[task.action_[iA].type_]) { | ||
|  |               o = machine.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option); | ||
|  |             } else if (mhchemParser.actions[task.action_[iA].type_]) { | ||
|  |               o = mhchemParser.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option); | ||
|  |             } else { | ||
|  |               throw ["MhchemBugA", "mhchem bug A. Please report. (" + task.action_[iA].type_ + ")"]; // Trying to use non-existing action
 | ||
|  |             } //
 | ||
|  |             // Add output
 | ||
|  |             //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |             mhchemParser.concatArray(output, o); | ||
|  |           } //
 | ||
|  |           // Set next state,
 | ||
|  |           // Shorten input,
 | ||
|  |           // Continue with next character
 | ||
|  |           //   (= apply only one transition per position)
 | ||
|  |           //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |           state = task.nextState || state; | ||
|  | 
 | ||
|  |           if (input.length > 0) { | ||
|  |             if (!task.revisit) { | ||
|  |               input = matches.remainder; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (!task.toContinue) { | ||
|  |               break iterateTransitions; | ||
|  |             } | ||
|  |           } else { | ||
|  |             return output; | ||
|  |           } | ||
|  |         } | ||
|  |       } //
 | ||
|  |       // Prevent infinite loop
 | ||
|  |       //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |       if (watchdog <= 0) { | ||
|  |         throw ["MhchemBugU", "mhchem bug U. Please report."]; // Unexpected character
 | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   concatArray: function concatArray(a, b) { | ||
|  |     if (b) { | ||
|  |       if (Array.isArray(b)) { | ||
|  |         for (var iB = 0; iB < b.length; iB++) { | ||
|  |           a.push(b[iB]); | ||
|  |         } | ||
|  |       } else { | ||
|  |         a.push(b); | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   patterns: { | ||
|  |     //
 | ||
|  |     // Matching patterns
 | ||
|  |     // either regexps or function that return null or {match_:"a", remainder:"bc"}
 | ||
|  |     //
 | ||
|  |     patterns: { | ||
|  |       // property names must not look like integers ("2") for correct property traversal order, later on
 | ||
|  |       'empty': /^$/, | ||
|  |       'else': /^./, | ||
|  |       'else2': /^./, | ||
|  |       'space': /^\s/, | ||
|  |       'space A': /^\s(?=[A-Z\\$])/, | ||
|  |       'space$': /^\s$/, | ||
|  |       'a-z': /^[a-z]/, | ||
|  |       'x': /^x/, | ||
|  |       'x$': /^x$/, | ||
|  |       'i$': /^i$/, | ||
|  |       'letters': /^(?:[a-zA-Z\u03B1-\u03C9\u0391-\u03A9?@]|(?:\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))))+/, | ||
|  |       '\\greek': /^\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))/, | ||
|  |       'one lowercase latin letter $': /^(?:([a-z])(?:$|[^a-zA-Z]))$/, | ||
|  |       '$one lowercase latin letter$ $': /^\$(?:([a-z])(?:$|[^a-zA-Z]))\$$/, | ||
|  |       'one lowercase greek letter $': /^(?:\$?[\u03B1-\u03C9]\$?|\$?\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\s*\$?)(?:\s+|\{\}|(?![a-zA-Z]))$/, | ||
|  |       'digits': /^[0-9]+/, | ||
|  |       '-9.,9': /^[+\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))/, | ||
|  |       '-9.,9 no missing 0': /^[+\-]?[0-9]+(?:[.,][0-9]+)?/, | ||
|  |       '(-)(9.,9)(e)(99)': function e99(input) { | ||
|  |         var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))?(\((?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))\))?(?:([eE]|\s*(\*|x|\\times|\u00D7)\s*10\^)([+\-]?[0-9]+|\{[+\-]?[0-9]+\}))?/); | ||
|  | 
 | ||
|  |         if (m && m[0]) { | ||
|  |           return { | ||
|  |             match_: m.splice(1), | ||
|  |             remainder: input.substr(m[0].length) | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       }, | ||
|  |       '(-)(9)^(-9)': function _(input) { | ||
|  |         var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+)?)\^([+\-]?[0-9]+|\{[+\-]?[0-9]+\})/); | ||
|  | 
 | ||
|  |         if (m && m[0]) { | ||
|  |           return { | ||
|  |             match_: m.splice(1), | ||
|  |             remainder: input.substr(m[0].length) | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       }, | ||
|  |       'state of aggregation $': function stateOfAggregation$(input) { | ||
|  |         // ... or crystal system
 | ||
|  |         var a = mhchemParser.patterns.findObserveGroups(input, "", /^\([a-z]{1,3}(?=[\),])/, ")", ""); // (aq), (aq,$\infty$), (aq, sat)
 | ||
|  | 
 | ||
|  |         if (a && a.remainder.match(/^($|[\s,;\)\]\}])/)) { | ||
|  |           return a; | ||
|  |         } //  AND end of 'phrase'
 | ||
|  | 
 | ||
|  | 
 | ||
|  |         var m = input.match(/^(?:\((?:\\ca\s?)?\$[amothc]\$\))/); // OR crystal system ($o$) (\ca$c$)
 | ||
|  | 
 | ||
|  |         if (m) { | ||
|  |           return { | ||
|  |             match_: m[0], | ||
|  |             remainder: input.substr(m[0].length) | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       }, | ||
|  |       '_{(state of aggregation)}$': /^_\{(\([a-z]{1,3}\))\}/, | ||
|  |       '{[(': /^(?:\\\{|\[|\()/, | ||
|  |       ')]}': /^(?:\)|\]|\\\})/, | ||
|  |       ', ': /^[,;]\s*/, | ||
|  |       ',': /^[,;]/, | ||
|  |       '.': /^[.]/, | ||
|  |       '. ': /^([.\u22C5\u00B7\u2022])\s*/, | ||
|  |       '...': /^\.\.\.(?=$|[^.])/, | ||
|  |       '* ': /^([*])\s*/, | ||
|  |       '^{(...)}': function _(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "^{", "", "", "}"); | ||
|  |       }, | ||
|  |       '^($...$)': function $$(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "^", "$", "$", ""); | ||
|  |       }, | ||
|  |       '^a': /^\^([0-9]+|[^\\_])/, | ||
|  |       '^\\x{}{}': function x(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); | ||
|  |       }, | ||
|  |       '^\\x{}': function x(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", ""); | ||
|  |       }, | ||
|  |       '^\\x': /^\^(\\[a-zA-Z]+)\s*/, | ||
|  |       '^(-1)': /^\^(-?\d+)/, | ||
|  |       '\'': /^'/, | ||
|  |       '_{(...)}': function _(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "_{", "", "", "}"); | ||
|  |       }, | ||
|  |       '_($...$)': function _$$(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "_", "$", "$", ""); | ||
|  |       }, | ||
|  |       '_9': /^_([+\-]?[0-9]+|[^\\])/, | ||
|  |       '_\\x{}{}': function _X(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); | ||
|  |       }, | ||
|  |       '_\\x{}': function _X(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", ""); | ||
|  |       }, | ||
|  |       '_\\x': /^_(\\[a-zA-Z]+)\s*/, | ||
|  |       '^_': /^(?:\^(?=_)|\_(?=\^)|[\^_]$)/, | ||
|  |       '{}': /^\{\}/, | ||
|  |       '{...}': function _(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "", "{", "}", ""); | ||
|  |       }, | ||
|  |       '{(...)}': function _(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "{", "", "", "}"); | ||
|  |       }, | ||
|  |       '$...$': function $$(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "", "$", "$", ""); | ||
|  |       }, | ||
|  |       '${(...)}$': function $$(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "${", "", "", "}$"); | ||
|  |       }, | ||
|  |       '$(...)$': function $$(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "$", "", "", "$"); | ||
|  |       }, | ||
|  |       '=<>': /^[=<>]/, | ||
|  |       '#': /^[#\u2261]/, | ||
|  |       '+': /^\+/, | ||
|  |       '-$': /^-(?=[\s_},;\]/]|$|\([a-z]+\))/, | ||
|  |       // -space -, -; -] -/ -$ -state-of-aggregation
 | ||
|  |       '-9': /^-(?=[0-9])/, | ||
|  |       '- orbital overlap': /^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/, | ||
|  |       '-': /^-/, | ||
|  |       'pm-operator': /^(?:\\pm|\$\\pm\$|\+-|\+\/-)/, | ||
|  |       'operator': /^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/, | ||
|  |       'arrowUpDown': /^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/, | ||
|  |       '\\bond{(...)}': function bond(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\bond{", "", "", "}"); | ||
|  |       }, | ||
|  |       '->': /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/, | ||
|  |       'CMT': /^[CMT](?=\[)/, | ||
|  |       '[(...)]': function _(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "[", "", "", "]"); | ||
|  |       }, | ||
|  |       '1st-level escape': /^(&|\\\\|\\hline)\s*/, | ||
|  |       '\\,': /^(?:\\[,\ ;:])/, | ||
|  |       // \\x - but output no space before
 | ||
|  |       '\\x{}{}': function x(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); | ||
|  |       }, | ||
|  |       '\\x{}': function x(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", ""); | ||
|  |       }, | ||
|  |       '\\ca': /^\\ca(?:\s+|(?![a-zA-Z]))/, | ||
|  |       '\\x': /^(?:\\[a-zA-Z]+\s*|\\[_&{}%])/, | ||
|  |       'orbital': /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/, | ||
|  |       // only those with numbers in front, because the others will be formatted correctly anyway
 | ||
|  |       'others': /^[\/~|]/, | ||
|  |       '\\frac{(...)}': function frac(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\frac{", "", "", "}", "{", "", "", "}"); | ||
|  |       }, | ||
|  |       '\\overset{(...)}': function overset(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\overset{", "", "", "}", "{", "", "", "}"); | ||
|  |       }, | ||
|  |       "\\underset{(...)}": function underset(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\underset{", "", "", "}", "{", "", "", "}"); | ||
|  |       }, | ||
|  |       "\\underbrace{(...)}": function underbrace(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\underbrace{", "", "", "}_", "{", "", "", "}"); | ||
|  |       }, | ||
|  |       '\\color{(...)}0': function color0(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}"); | ||
|  |       }, | ||
|  |       '\\color{(...)}{(...)}1': function color1(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}", "{", "", "", "}"); | ||
|  |       }, | ||
|  |       '\\color(...){(...)}2': function color2(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\color", "\\", "", /^(?=\{)/, "{", "", "", "}"); | ||
|  |       }, | ||
|  |       '\\ce{(...)}': function ce(input) { | ||
|  |         return mhchemParser.patterns.findObserveGroups(input, "\\ce{", "", "", "}"); | ||
|  |       }, | ||
|  |       'oxidation$': /^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, | ||
|  |       'd-oxidation$': /^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, | ||
|  |       // 0 could be oxidation or charge
 | ||
|  |       'roman numeral': /^[IVX]+/, | ||
|  |       '1/2$': /^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/, | ||
|  |       'amount': function amount(input) { | ||
|  |         var match; // e.g. 2, 0.5, 1/2, -2, n/2, +;  $a$ could be added later in parsing
 | ||
|  | 
 | ||
|  |         match = input.match(/^(?:(?:(?:\([+\-]?[0-9]+\/[0-9]+\)|[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+|[+\-]?[0-9]+[.,][0-9]+|[+\-]?\.[0-9]+|[+\-]?[0-9]+)(?:[a-z](?=\s*[A-Z]))?)|[+\-]?[a-z](?=\s*[A-Z])|\+(?!\s))/); | ||
|  | 
 | ||
|  |         if (match) { | ||
|  |           return { | ||
|  |             match_: match[0], | ||
|  |             remainder: input.substr(match[0].length) | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         var a = mhchemParser.patterns.findObserveGroups(input, "", "$", "$", ""); | ||
|  | 
 | ||
|  |         if (a) { | ||
|  |           // e.g. $2n-1$, $-$
 | ||
|  |           match = a.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/); | ||
|  | 
 | ||
|  |           if (match) { | ||
|  |             return { | ||
|  |               match_: match[0], | ||
|  |               remainder: input.substr(match[0].length) | ||
|  |             }; | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       }, | ||
|  |       'amount2': function amount2(input) { | ||
|  |         return this['amount'](input); | ||
|  |       }, | ||
|  |       '(KV letters),': /^(?:[A-Z][a-z]{0,2}|i)(?=,)/, | ||
|  |       'formula$': function formula$(input) { | ||
|  |         if (input.match(/^\([a-z]+\)$/)) { | ||
|  |           return null; | ||
|  |         } // state of aggregation = no formula
 | ||
|  | 
 | ||
|  | 
 | ||
|  |         var match = input.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/); | ||
|  | 
 | ||
|  |         if (match) { | ||
|  |           return { | ||
|  |             match_: match[0], | ||
|  |             remainder: input.substr(match[0].length) | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       }, | ||
|  |       'uprightEntities': /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/, | ||
|  |       '/': /^\s*(\/)\s*/, | ||
|  |       '//': /^\s*(\/\/)\s*/, | ||
|  |       '*': /^\s*[*.]\s*/ | ||
|  |     }, | ||
|  |     findObserveGroups: function findObserveGroups(input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) { | ||
|  |       /** @type {{(input: string, pattern: string | RegExp): string | string[] | null;}} */ | ||
|  |       var _match = function _match(input, pattern) { | ||
|  |         if (typeof pattern === "string") { | ||
|  |           if (input.indexOf(pattern) !== 0) { | ||
|  |             return null; | ||
|  |           } | ||
|  | 
 | ||
|  |           return pattern; | ||
|  |         } else { | ||
|  |           var match = input.match(pattern); | ||
|  | 
 | ||
|  |           if (!match) { | ||
|  |             return null; | ||
|  |           } | ||
|  | 
 | ||
|  |           return match[0]; | ||
|  |         } | ||
|  |       }; | ||
|  |       /** @type {{(input: string, i: number, endChars: string | RegExp): {endMatchBegin: number, endMatchEnd: number} | null;}} */ | ||
|  | 
 | ||
|  | 
 | ||
|  |       var _findObserveGroups = function _findObserveGroups(input, i, endChars) { | ||
|  |         var braces = 0; | ||
|  | 
 | ||
|  |         while (i < input.length) { | ||
|  |           var a = input.charAt(i); | ||
|  | 
 | ||
|  |           var match = _match(input.substr(i), endChars); | ||
|  | 
 | ||
|  |           if (match !== null && braces === 0) { | ||
|  |             return { | ||
|  |               endMatchBegin: i, | ||
|  |               endMatchEnd: i + match.length | ||
|  |             }; | ||
|  |           } else if (a === "{") { | ||
|  |             braces++; | ||
|  |           } else if (a === "}") { | ||
|  |             if (braces === 0) { | ||
|  |               throw ["ExtraCloseMissingOpen", "Extra close brace or missing open brace"]; | ||
|  |             } else { | ||
|  |               braces--; | ||
|  |             } | ||
|  |           } | ||
|  | 
 | ||
|  |           i++; | ||
|  |         } | ||
|  | 
 | ||
|  |         if (braces > 0) { | ||
|  |           return null; | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       }; | ||
|  | 
 | ||
|  |       var match = _match(input, begExcl); | ||
|  | 
 | ||
|  |       if (match === null) { | ||
|  |         return null; | ||
|  |       } | ||
|  | 
 | ||
|  |       input = input.substr(match.length); | ||
|  |       match = _match(input, begIncl); | ||
|  | 
 | ||
|  |       if (match === null) { | ||
|  |         return null; | ||
|  |       } | ||
|  | 
 | ||
|  |       var e = _findObserveGroups(input, match.length, endIncl || endExcl); | ||
|  | 
 | ||
|  |       if (e === null) { | ||
|  |         return null; | ||
|  |       } | ||
|  | 
 | ||
|  |       var match1 = input.substring(0, endIncl ? e.endMatchEnd : e.endMatchBegin); | ||
|  | 
 | ||
|  |       if (!(beg2Excl || beg2Incl)) { | ||
|  |         return { | ||
|  |           match_: match1, | ||
|  |           remainder: input.substr(e.endMatchEnd) | ||
|  |         }; | ||
|  |       } else { | ||
|  |         var group2 = this.findObserveGroups(input.substr(e.endMatchEnd), beg2Excl, beg2Incl, end2Incl, end2Excl); | ||
|  | 
 | ||
|  |         if (group2 === null) { | ||
|  |           return null; | ||
|  |         } | ||
|  |         /** @type {string[]} */ | ||
|  | 
 | ||
|  | 
 | ||
|  |         var matchRet = [match1, group2.match_]; | ||
|  |         return { | ||
|  |           match_: combine ? matchRet.join("") : matchRet, | ||
|  |           remainder: group2.remainder | ||
|  |         }; | ||
|  |       } | ||
|  |     }, | ||
|  |     //
 | ||
|  |     // Matching function
 | ||
|  |     // e.g. match("a", input) will look for the regexp called "a" and see if it matches
 | ||
|  |     // returns null or {match_:"a", remainder:"bc"}
 | ||
|  |     //
 | ||
|  |     match_: function match_(m, input) { | ||
|  |       var pattern = mhchemParser.patterns.patterns[m]; | ||
|  | 
 | ||
|  |       if (pattern === undefined) { | ||
|  |         throw ["MhchemBugP", "mhchem bug P. Please report. (" + m + ")"]; // Trying to use non-existing pattern
 | ||
|  |       } else if (typeof pattern === "function") { | ||
|  |         return mhchemParser.patterns.patterns[m](input); // cannot use cached var pattern here, because some pattern functions need this===mhchemParser
 | ||
|  |       } else { | ||
|  |         // RegExp
 | ||
|  |         var match = input.match(pattern); | ||
|  | 
 | ||
|  |         if (match) { | ||
|  |           var mm; | ||
|  | 
 | ||
|  |           if (match[2]) { | ||
|  |             mm = [match[1], match[2]]; | ||
|  |           } else if (match[1]) { | ||
|  |             mm = match[1]; | ||
|  |           } else { | ||
|  |             mm = match[0]; | ||
|  |           } | ||
|  | 
 | ||
|  |           return { | ||
|  |             match_: mm, | ||
|  |             remainder: input.substr(match[0].length) | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         return null; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   //
 | ||
|  |   // Generic state machine actions
 | ||
|  |   //
 | ||
|  |   actions: { | ||
|  |     'a=': function a(buffer, m) { | ||
|  |       buffer.a = (buffer.a || "") + m; | ||
|  |     }, | ||
|  |     'b=': function b(buffer, m) { | ||
|  |       buffer.b = (buffer.b || "") + m; | ||
|  |     }, | ||
|  |     'p=': function p(buffer, m) { | ||
|  |       buffer.p = (buffer.p || "") + m; | ||
|  |     }, | ||
|  |     'o=': function o(buffer, m) { | ||
|  |       buffer.o = (buffer.o || "") + m; | ||
|  |     }, | ||
|  |     'q=': function q(buffer, m) { | ||
|  |       buffer.q = (buffer.q || "") + m; | ||
|  |     }, | ||
|  |     'd=': function d(buffer, m) { | ||
|  |       buffer.d = (buffer.d || "") + m; | ||
|  |     }, | ||
|  |     'rm=': function rm(buffer, m) { | ||
|  |       buffer.rm = (buffer.rm || "") + m; | ||
|  |     }, | ||
|  |     'text=': function text(buffer, m) { | ||
|  |       buffer.text_ = (buffer.text_ || "") + m; | ||
|  |     }, | ||
|  |     'insert': function insert(buffer, m, a) { | ||
|  |       return { | ||
|  |         type_: a | ||
|  |       }; | ||
|  |     }, | ||
|  |     'insert+p1': function insertP1(buffer, m, a) { | ||
|  |       return { | ||
|  |         type_: a, | ||
|  |         p1: m | ||
|  |       }; | ||
|  |     }, | ||
|  |     'insert+p1+p2': function insertP1P2(buffer, m, a) { | ||
|  |       return { | ||
|  |         type_: a, | ||
|  |         p1: m[0], | ||
|  |         p2: m[1] | ||
|  |       }; | ||
|  |     }, | ||
|  |     'copy': function copy(buffer, m) { | ||
|  |       return m; | ||
|  |     }, | ||
|  |     'rm': function rm(buffer, m) { | ||
|  |       return { | ||
|  |         type_: 'rm', | ||
|  |         p1: m || "" | ||
|  |       }; | ||
|  |     }, | ||
|  |     'text': function text(buffer, m) { | ||
|  |       return mhchemParser.go(m, 'text'); | ||
|  |     }, | ||
|  |     '{text}': function text(buffer, m) { | ||
|  |       var ret = ["{"]; | ||
|  |       mhchemParser.concatArray(ret, mhchemParser.go(m, 'text')); | ||
|  |       ret.push("}"); | ||
|  |       return ret; | ||
|  |     }, | ||
|  |     'tex-math': function texMath(buffer, m) { | ||
|  |       return mhchemParser.go(m, 'tex-math'); | ||
|  |     }, | ||
|  |     'tex-math tight': function texMathTight(buffer, m) { | ||
|  |       return mhchemParser.go(m, 'tex-math tight'); | ||
|  |     }, | ||
|  |     'bond': function bond(buffer, m, k) { | ||
|  |       return { | ||
|  |         type_: 'bond', | ||
|  |         kind_: k || m | ||
|  |       }; | ||
|  |     }, | ||
|  |     'color0-output': function color0Output(buffer, m) { | ||
|  |       return { | ||
|  |         type_: 'color0', | ||
|  |         color: m[0] | ||
|  |       }; | ||
|  |     }, | ||
|  |     'ce': function ce(buffer, m) { | ||
|  |       return mhchemParser.go(m); | ||
|  |     }, | ||
|  |     '1/2': function _(buffer, m) { | ||
|  |       /** @type {ParserOutput[]} */ | ||
|  |       var ret = []; | ||
|  | 
 | ||
|  |       if (m.match(/^[+\-]/)) { | ||
|  |         ret.push(m.substr(0, 1)); | ||
|  |         m = m.substr(1); | ||
|  |       } | ||
|  | 
 | ||
|  |       var n = m.match(/^([0-9]+|\$[a-z]\$|[a-z])\/([0-9]+)(\$[a-z]\$|[a-z])?$/); | ||
|  |       n[1] = n[1].replace(/\$/g, ""); | ||
|  |       ret.push({ | ||
|  |         type_: 'frac', | ||
|  |         p1: n[1], | ||
|  |         p2: n[2] | ||
|  |       }); | ||
|  | 
 | ||
|  |       if (n[3]) { | ||
|  |         n[3] = n[3].replace(/\$/g, ""); | ||
|  |         ret.push({ | ||
|  |           type_: 'tex-math', | ||
|  |           p1: n[3] | ||
|  |         }); | ||
|  |       } | ||
|  | 
 | ||
|  |       return ret; | ||
|  |     }, | ||
|  |     '9,9': function _(buffer, m) { | ||
|  |       return mhchemParser.go(m, '9,9'); | ||
|  |     } | ||
|  |   }, | ||
|  |   //
 | ||
|  |   // createTransitions
 | ||
|  |   // convert  { 'letter': { 'state': { action_: 'output' } } }  to  { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] }
 | ||
|  |   // with expansion of 'a|b' to 'a' and 'b' (at 2 places)
 | ||
|  |   //
 | ||
|  |   createTransitions: function createTransitions(o) { | ||
|  |     var pattern, state; | ||
|  |     /** @type {string[]} */ | ||
|  | 
 | ||
|  |     var stateArray; | ||
|  |     var i; //
 | ||
|  |     // 1. Collect all states
 | ||
|  |     //
 | ||
|  | 
 | ||
|  |     /** @type {Transitions} */ | ||
|  | 
 | ||
|  |     var transitions = {}; | ||
|  | 
 | ||
|  |     for (pattern in o) { | ||
|  |       for (state in o[pattern]) { | ||
|  |         stateArray = state.split("|"); | ||
|  |         o[pattern][state].stateArray = stateArray; | ||
|  | 
 | ||
|  |         for (i = 0; i < stateArray.length; i++) { | ||
|  |           transitions[stateArray[i]] = []; | ||
|  |         } | ||
|  |       } | ||
|  |     } //
 | ||
|  |     // 2. Fill states
 | ||
|  |     //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     for (pattern in o) { | ||
|  |       for (state in o[pattern]) { | ||
|  |         stateArray = o[pattern][state].stateArray || []; | ||
|  | 
 | ||
|  |         for (i = 0; i < stateArray.length; i++) { | ||
|  |           //
 | ||
|  |           // 2a. Normalize actions into array:  'text=' ==> [{type_:'text='}]
 | ||
|  |           // (Note to myself: Resolving the function here would be problematic. It would need .bind (for *this*) and currying (for *option*).)
 | ||
|  |           //
 | ||
|  | 
 | ||
|  |           /** @type {any} */ | ||
|  |           var p = o[pattern][state]; | ||
|  | 
 | ||
|  |           if (p.action_) { | ||
|  |             p.action_ = [].concat(p.action_); | ||
|  | 
 | ||
|  |             for (var k = 0; k < p.action_.length; k++) { | ||
|  |               if (typeof p.action_[k] === "string") { | ||
|  |                 p.action_[k] = { | ||
|  |                   type_: p.action_[k] | ||
|  |                 }; | ||
|  |               } | ||
|  |             } | ||
|  |           } else { | ||
|  |             p.action_ = []; | ||
|  |           } //
 | ||
|  |           // 2.b Multi-insert
 | ||
|  |           //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |           var patternArray = pattern.split("|"); | ||
|  | 
 | ||
|  |           for (var j = 0; j < patternArray.length; j++) { | ||
|  |             if (stateArray[i] === '*') { | ||
|  |               // insert into all
 | ||
|  |               for (var t in transitions) { | ||
|  |                 transitions[t].push({ | ||
|  |                   pattern: patternArray[j], | ||
|  |                   task: p | ||
|  |                 }); | ||
|  |               } | ||
|  |             } else { | ||
|  |               transitions[stateArray[i]].push({ | ||
|  |                 pattern: patternArray[j], | ||
|  |                 task: p | ||
|  |               }); | ||
|  |             } | ||
|  |           } | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     return transitions; | ||
|  |   }, | ||
|  |   stateMachines: {} | ||
|  | }; //
 | ||
|  | // Definition of state machines
 | ||
|  | //
 | ||
|  | 
 | ||
|  | mhchemParser.stateMachines = { | ||
|  |   //
 | ||
|  |   // \ce state machines
 | ||
|  |   //
 | ||
|  |   //#region ce
 | ||
|  |   'ce': { | ||
|  |     // main parser
 | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': { | ||
|  |           action_: 'output' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '0|1|2': { | ||
|  |           action_: 'beginsWithBond=false', | ||
|  |           revisit: true, | ||
|  |           toContinue: true | ||
|  |         } | ||
|  |       }, | ||
|  |       'oxidation$': { | ||
|  |         '0': { | ||
|  |           action_: 'oxidation-output' | ||
|  |         } | ||
|  |       }, | ||
|  |       'CMT': { | ||
|  |         'r': { | ||
|  |           action_: 'rdt=', | ||
|  |           nextState: 'rt' | ||
|  |         }, | ||
|  |         'rd': { | ||
|  |           action_: 'rqt=', | ||
|  |           nextState: 'rdt' | ||
|  |         } | ||
|  |       }, | ||
|  |       'arrowUpDown': { | ||
|  |         '0|1|2|as': { | ||
|  |           action_: ['sb=false', 'output', 'operator'], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       'uprightEntities': { | ||
|  |         '0|1|2': { | ||
|  |           action_: ['o=', 'output'], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       'orbital': { | ||
|  |         '0|1|2|3': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       '->': { | ||
|  |         '0|1|2|3': { | ||
|  |           action_: 'r=', | ||
|  |           nextState: 'r' | ||
|  |         }, | ||
|  |         'a|as': { | ||
|  |           action_: ['output', 'r='], | ||
|  |           nextState: 'r' | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: ['output', 'r='], | ||
|  |           nextState: 'r' | ||
|  |         } | ||
|  |       }, | ||
|  |       '+': { | ||
|  |         'o': { | ||
|  |           action_: 'd= kv', | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         'd|D': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         'q': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'qd' | ||
|  |         }, | ||
|  |         'qd|qD': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'qd' | ||
|  |         }, | ||
|  |         'dq': { | ||
|  |           action_: ['output', 'd='], | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         '3': { | ||
|  |           action_: ['sb=false', 'output', 'operator'], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       'amount': { | ||
|  |         '0|2': { | ||
|  |           action_: 'a=', | ||
|  |           nextState: 'a' | ||
|  |         } | ||
|  |       }, | ||
|  |       'pm-operator': { | ||
|  |         '0|1|2|a|as': { | ||
|  |           action_: ['sb=false', 'output', { | ||
|  |             type_: 'operator', | ||
|  |             option: '\\pm' | ||
|  |           }], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       'operator': { | ||
|  |         '0|1|2|a|as': { | ||
|  |           action_: ['sb=false', 'output', 'operator'], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '-$': { | ||
|  |         'o|q': { | ||
|  |           action_: ['charge or bond', 'output'], | ||
|  |           nextState: 'qd' | ||
|  |         }, | ||
|  |         'd': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         'D': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'bond', | ||
|  |             option: "-" | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         }, | ||
|  |         'q': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'qd' | ||
|  |         }, | ||
|  |         'qd': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'qd' | ||
|  |         }, | ||
|  |         'qD|dq': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'bond', | ||
|  |             option: "-" | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '-9': { | ||
|  |         '3|o': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert', | ||
|  |             option: 'hyphen' | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '- orbital overlap': { | ||
|  |         'o': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert', | ||
|  |             option: 'hyphen' | ||
|  |           }], | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         'd': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert', | ||
|  |             option: 'hyphen' | ||
|  |           }], | ||
|  |           nextState: '2' | ||
|  |         } | ||
|  |       }, | ||
|  |       '-': { | ||
|  |         '0|1|2': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 1 | ||
|  |           }, 'beginsWithBond=true', { | ||
|  |             type_: 'bond', | ||
|  |             option: "-" | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         }, | ||
|  |         '3': { | ||
|  |           action_: { | ||
|  |             type_: 'bond', | ||
|  |             option: "-" | ||
|  |           } | ||
|  |         }, | ||
|  |         'a': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert', | ||
|  |             option: 'hyphen' | ||
|  |           }], | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         'as': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, { | ||
|  |             type_: 'bond', | ||
|  |             option: "-" | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         }, | ||
|  |         'b': { | ||
|  |           action_: 'b=' | ||
|  |         }, | ||
|  |         'o': { | ||
|  |           action_: { | ||
|  |             type_: '- after o/d', | ||
|  |             option: false | ||
|  |           }, | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         'q': { | ||
|  |           action_: { | ||
|  |             type_: '- after o/d', | ||
|  |             option: false | ||
|  |           }, | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         'd|qd|dq': { | ||
|  |           action_: { | ||
|  |             type_: '- after o/d', | ||
|  |             option: true | ||
|  |           }, | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         'D|qD|p': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'bond', | ||
|  |             option: "-" | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       'amount2': { | ||
|  |         '1|3': { | ||
|  |           action_: 'a=', | ||
|  |           nextState: 'a' | ||
|  |         } | ||
|  |       }, | ||
|  |       'letters': { | ||
|  |         '0|1|2|3|a|as|b|p|bp|o': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: 'o' | ||
|  |         }, | ||
|  |         'q|dq': { | ||
|  |           action_: ['output', 'o='], | ||
|  |           nextState: 'o' | ||
|  |         }, | ||
|  |         'd|D|qd|qD': { | ||
|  |           action_: 'o after d', | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       'digits': { | ||
|  |         'o': { | ||
|  |           action_: 'q=', | ||
|  |           nextState: 'q' | ||
|  |         }, | ||
|  |         'd|D': { | ||
|  |           action_: 'q=', | ||
|  |           nextState: 'dq' | ||
|  |         }, | ||
|  |         'q': { | ||
|  |           action_: ['output', 'o='], | ||
|  |           nextState: 'o' | ||
|  |         }, | ||
|  |         'a': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       'space A': { | ||
|  |         'b|p|bp': {} | ||
|  |       }, | ||
|  |       'space': { | ||
|  |         'a': { | ||
|  |           nextState: 'as' | ||
|  |         }, | ||
|  |         '0': { | ||
|  |           action_: 'sb=false' | ||
|  |         }, | ||
|  |         '1|2': { | ||
|  |           action_: 'sb=true' | ||
|  |         }, | ||
|  |         'r|rt|rd|rdt|rdq': { | ||
|  |           action_: 'output', | ||
|  |           nextState: '0' | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: ['output', 'sb=true'], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       '1st-level escape': { | ||
|  |         '1|2': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert+p1', | ||
|  |             option: '1st-level escape' | ||
|  |           }] | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert+p1', | ||
|  |             option: '1st-level escape' | ||
|  |           }], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '[(...)]': { | ||
|  |         'r|rt': { | ||
|  |           action_: 'rd=', | ||
|  |           nextState: 'rd' | ||
|  |         }, | ||
|  |         'rd|rdt': { | ||
|  |           action_: 'rq=', | ||
|  |           nextState: 'rdq' | ||
|  |         } | ||
|  |       }, | ||
|  |       '...': { | ||
|  |         'o|d|D|dq|qd|qD': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'bond', | ||
|  |             option: "..." | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 1 | ||
|  |           }, { | ||
|  |             type_: 'insert', | ||
|  |             option: 'ellipsis' | ||
|  |           }], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       '. |* ': { | ||
|  |         '*': { | ||
|  |           action_: ['output', { | ||
|  |             type_: 'insert', | ||
|  |             option: 'addition compound' | ||
|  |           }], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       'state of aggregation $': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'state of aggregation'], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{[(': { | ||
|  |         'a|as|o': { | ||
|  |           action_: ['o=', 'output', 'parenthesisLevel++'], | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         '0|1|2|3': { | ||
|  |           action_: ['o=', 'output', 'parenthesisLevel++'], | ||
|  |           nextState: '2' | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: ['output', 'o=', 'output', 'parenthesisLevel++'], | ||
|  |           nextState: '2' | ||
|  |         } | ||
|  |       }, | ||
|  |       ')]}': { | ||
|  |         '0|1|2|3|b|p|bp|o': { | ||
|  |           action_: ['o=', 'parenthesisLevel--'], | ||
|  |           nextState: 'o' | ||
|  |         }, | ||
|  |         'a|as|d|D|q|qd|qD|dq': { | ||
|  |           action_: ['output', 'o=', 'parenthesisLevel--'], | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       ', ': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'comma'], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '^_': { | ||
|  |         // ^ and _ without a sensible argument
 | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       '^{(...)}|^($...$)': { | ||
|  |         '0|1|2|as': { | ||
|  |           action_: 'b=', | ||
|  |           nextState: 'b' | ||
|  |         }, | ||
|  |         'p': { | ||
|  |           action_: 'b=', | ||
|  |           nextState: 'bp' | ||
|  |         }, | ||
|  |         '3|o': { | ||
|  |           action_: 'd= kv', | ||
|  |           nextState: 'D' | ||
|  |         }, | ||
|  |         'q': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'qD' | ||
|  |         }, | ||
|  |         'd|D|qd|qD|dq': { | ||
|  |           action_: ['output', 'd='], | ||
|  |           nextState: 'D' | ||
|  |         } | ||
|  |       }, | ||
|  |       '^a|^\\x{}{}|^\\x{}|^\\x|\'': { | ||
|  |         '0|1|2|as': { | ||
|  |           action_: 'b=', | ||
|  |           nextState: 'b' | ||
|  |         }, | ||
|  |         'p': { | ||
|  |           action_: 'b=', | ||
|  |           nextState: 'bp' | ||
|  |         }, | ||
|  |         '3|o': { | ||
|  |           action_: 'd= kv', | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         'q': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'qd' | ||
|  |         }, | ||
|  |         'd|qd|D|qD': { | ||
|  |           action_: 'd=' | ||
|  |         }, | ||
|  |         'dq': { | ||
|  |           action_: ['output', 'd='], | ||
|  |           nextState: 'd' | ||
|  |         } | ||
|  |       }, | ||
|  |       '_{(state of aggregation)}$': { | ||
|  |         'd|D|q|qd|qD|dq': { | ||
|  |           action_: ['output', 'q='], | ||
|  |           nextState: 'q' | ||
|  |         } | ||
|  |       }, | ||
|  |       '_{(...)}|_($...$)|_9|_\\x{}{}|_\\x{}|_\\x': { | ||
|  |         '0|1|2|as': { | ||
|  |           action_: 'p=', | ||
|  |           nextState: 'p' | ||
|  |         }, | ||
|  |         'b': { | ||
|  |           action_: 'p=', | ||
|  |           nextState: 'bp' | ||
|  |         }, | ||
|  |         '3|o': { | ||
|  |           action_: 'q=', | ||
|  |           nextState: 'q' | ||
|  |         }, | ||
|  |         'd|D': { | ||
|  |           action_: 'q=', | ||
|  |           nextState: 'dq' | ||
|  |         }, | ||
|  |         'q|qd|qD|dq': { | ||
|  |           action_: ['output', 'q='], | ||
|  |           nextState: 'q' | ||
|  |         } | ||
|  |       }, | ||
|  |       '=<>': { | ||
|  |         '0|1|2|3|a|as|o|q|d|D|qd|qD|dq': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'bond'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '#': { | ||
|  |         '0|1|2|3|a|as|o': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, { | ||
|  |             type_: 'bond', | ||
|  |             option: "#" | ||
|  |           }], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{}': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'output', | ||
|  |             option: 1 | ||
|  |           }, | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{...}': { | ||
|  |         '0|1|2|3|a|as|b|p|bp': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: 'o' | ||
|  |         }, | ||
|  |         'o|d|D|q|qd|qD|dq': { | ||
|  |           action_: ['output', 'o='], | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       '$...$': { | ||
|  |         'a': { | ||
|  |           action_: 'a=' | ||
|  |         }, | ||
|  |         // 2$n$
 | ||
|  |         '0|1|2|3|as|b|p|bp|o': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: 'o' | ||
|  |         }, | ||
|  |         // not 'amount'
 | ||
|  |         'as|o': { | ||
|  |           action_: 'o=' | ||
|  |         }, | ||
|  |         'q|d|D|qd|qD|dq': { | ||
|  |           action_: ['output', 'o='], | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\bond{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'bond'], | ||
|  |           nextState: "3" | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\frac{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 1 | ||
|  |           }, 'frac-output'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\overset{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'overset-output'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       "\\underset{(...)}": { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'underset-output'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       "\\underbrace{(...)}": { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'underbrace-output'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\color{(...)}{(...)}1|\\color(...){(...)}2': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'color-output'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\color{(...)}0': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'color0-output'] | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\ce{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 2 | ||
|  |           }, 'ce'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\,': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 1 | ||
|  |           }, 'copy'], | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\x{}{}|\\x{}|\\x': { | ||
|  |         '0|1|2|3|a|as|b|p|bp|o|c0': { | ||
|  |           action_: ['o=', 'output'], | ||
|  |           nextState: '3' | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: ['output', 'o=', 'output'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       'others': { | ||
|  |         '*': { | ||
|  |           action_: [{ | ||
|  |             type_: 'output', | ||
|  |             option: 1 | ||
|  |           }, 'copy'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else2': { | ||
|  |         'a': { | ||
|  |           action_: 'a to o', | ||
|  |           nextState: 'o', | ||
|  |           revisit: true | ||
|  |         }, | ||
|  |         'as': { | ||
|  |           action_: ['output', 'sb=true'], | ||
|  |           nextState: '1', | ||
|  |           revisit: true | ||
|  |         }, | ||
|  |         'r|rt|rd|rdt|rdq': { | ||
|  |           action_: ['output'], | ||
|  |           nextState: '0', | ||
|  |           revisit: true | ||
|  |         }, | ||
|  |         '*': { | ||
|  |           action_: ['output', 'copy'], | ||
|  |           nextState: '3' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'o after d': function oAfterD(buffer, m) { | ||
|  |         var ret; | ||
|  | 
 | ||
|  |         if ((buffer.d || "").match(/^[0-9]+$/)) { | ||
|  |           var tmp = buffer.d; | ||
|  |           buffer.d = undefined; | ||
|  |           ret = this['output'](buffer); | ||
|  |           buffer.b = tmp; | ||
|  |         } else { | ||
|  |           ret = this['output'](buffer); | ||
|  |         } | ||
|  | 
 | ||
|  |         mhchemParser.actions['o='](buffer, m); | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'd= kv': function dKv(buffer, m) { | ||
|  |         buffer.d = m; | ||
|  |         buffer.dType = 'kv'; | ||
|  |       }, | ||
|  |       'charge or bond': function chargeOrBond(buffer, m) { | ||
|  |         if (buffer['beginsWithBond']) { | ||
|  |           /** @type {ParserOutput[]} */ | ||
|  |           var ret = []; | ||
|  |           mhchemParser.concatArray(ret, this['output'](buffer)); | ||
|  |           mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-")); | ||
|  |           return ret; | ||
|  |         } else { | ||
|  |           buffer.d = m; | ||
|  |         } | ||
|  |       }, | ||
|  |       '- after o/d': function afterOD(buffer, m, isAfterD) { | ||
|  |         var c1 = mhchemParser.patterns.match_('orbital', buffer.o || ""); | ||
|  |         var c2 = mhchemParser.patterns.match_('one lowercase greek letter $', buffer.o || ""); | ||
|  |         var c3 = mhchemParser.patterns.match_('one lowercase latin letter $', buffer.o || ""); | ||
|  |         var c4 = mhchemParser.patterns.match_('$one lowercase latin letter$ $', buffer.o || ""); | ||
|  |         var hyphenFollows = m === "-" && (c1 && c1.remainder === "" || c2 || c3 || c4); | ||
|  | 
 | ||
|  |         if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) { | ||
|  |           buffer.o = '$' + buffer.o + '$'; | ||
|  |         } | ||
|  |         /** @type {ParserOutput[]} */ | ||
|  | 
 | ||
|  | 
 | ||
|  |         var ret = []; | ||
|  | 
 | ||
|  |         if (hyphenFollows) { | ||
|  |           mhchemParser.concatArray(ret, this['output'](buffer)); | ||
|  |           ret.push({ | ||
|  |             type_: 'hyphen' | ||
|  |           }); | ||
|  |         } else { | ||
|  |           c1 = mhchemParser.patterns.match_('digits', buffer.d || ""); | ||
|  | 
 | ||
|  |           if (isAfterD && c1 && c1.remainder === '') { | ||
|  |             mhchemParser.concatArray(ret, mhchemParser.actions['d='](buffer, m)); | ||
|  |             mhchemParser.concatArray(ret, this['output'](buffer)); | ||
|  |           } else { | ||
|  |             mhchemParser.concatArray(ret, this['output'](buffer)); | ||
|  |             mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-")); | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'a to o': function aToO(buffer) { | ||
|  |         buffer.o = buffer.a; | ||
|  |         buffer.a = undefined; | ||
|  |       }, | ||
|  |       'sb=true': function sbTrue(buffer) { | ||
|  |         buffer.sb = true; | ||
|  |       }, | ||
|  |       'sb=false': function sbFalse(buffer) { | ||
|  |         buffer.sb = false; | ||
|  |       }, | ||
|  |       'beginsWithBond=true': function beginsWithBondTrue(buffer) { | ||
|  |         buffer['beginsWithBond'] = true; | ||
|  |       }, | ||
|  |       'beginsWithBond=false': function beginsWithBondFalse(buffer) { | ||
|  |         buffer['beginsWithBond'] = false; | ||
|  |       }, | ||
|  |       'parenthesisLevel++': function parenthesisLevel(buffer) { | ||
|  |         buffer['parenthesisLevel']++; | ||
|  |       }, | ||
|  |       'parenthesisLevel--': function parenthesisLevel(buffer) { | ||
|  |         buffer['parenthesisLevel']--; | ||
|  |       }, | ||
|  |       'state of aggregation': function stateOfAggregation(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'state of aggregation', | ||
|  |           p1: mhchemParser.go(m, 'o') | ||
|  |         }; | ||
|  |       }, | ||
|  |       'comma': function comma(buffer, m) { | ||
|  |         var a = m.replace(/\s*$/, ''); | ||
|  |         var withSpace = a !== m; | ||
|  | 
 | ||
|  |         if (withSpace && buffer['parenthesisLevel'] === 0) { | ||
|  |           return { | ||
|  |             type_: 'comma enumeration L', | ||
|  |             p1: a | ||
|  |           }; | ||
|  |         } else { | ||
|  |           return { | ||
|  |             type_: 'comma enumeration M', | ||
|  |             p1: a | ||
|  |           }; | ||
|  |         } | ||
|  |       }, | ||
|  |       'output': function output(buffer, m, entityFollows) { | ||
|  |         // entityFollows:
 | ||
|  |         //   undefined = if we have nothing else to output, also ignore the just read space (buffer.sb)
 | ||
|  |         //   1 = an entity follows, never omit the space if there was one just read before (can only apply to state 1)
 | ||
|  |         //   2 = 1 + the entity can have an amount, so output a\, instead of converting it to o (can only apply to states a|as)
 | ||
|  | 
 | ||
|  |         /** @type {ParserOutput | ParserOutput[]} */ | ||
|  |         var ret; | ||
|  | 
 | ||
|  |         if (!buffer.r) { | ||
|  |           ret = []; | ||
|  | 
 | ||
|  |           if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) {//ret = [];
 | ||
|  |           } else { | ||
|  |             if (buffer.sb) { | ||
|  |               ret.push({ | ||
|  |                 type_: 'entitySkip' | ||
|  |               }); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows !== 2) { | ||
|  |               buffer.o = buffer.a; | ||
|  |               buffer.a = undefined; | ||
|  |             } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) { | ||
|  |               buffer.o = buffer.a; | ||
|  |               buffer.d = buffer.b; | ||
|  |               buffer.q = buffer.p; | ||
|  |               buffer.a = buffer.b = buffer.p = undefined; | ||
|  |             } else { | ||
|  |               if (buffer.o && buffer.dType === 'kv' && mhchemParser.patterns.match_('d-oxidation$', buffer.d || "")) { | ||
|  |                 buffer.dType = 'oxidation'; | ||
|  |               } else if (buffer.o && buffer.dType === 'kv' && !buffer.q) { | ||
|  |                 buffer.dType = undefined; | ||
|  |               } | ||
|  |             } | ||
|  | 
 | ||
|  |             ret.push({ | ||
|  |               type_: 'chemfive', | ||
|  |               a: mhchemParser.go(buffer.a, 'a'), | ||
|  |               b: mhchemParser.go(buffer.b, 'bd'), | ||
|  |               p: mhchemParser.go(buffer.p, 'pq'), | ||
|  |               o: mhchemParser.go(buffer.o, 'o'), | ||
|  |               q: mhchemParser.go(buffer.q, 'pq'), | ||
|  |               d: mhchemParser.go(buffer.d, buffer.dType === 'oxidation' ? 'oxidation' : 'bd'), | ||
|  |               dType: buffer.dType | ||
|  |             }); | ||
|  |           } | ||
|  |         } else { | ||
|  |           // r
 | ||
|  | 
 | ||
|  |           /** @type {ParserOutput[]} */ | ||
|  |           var rd; | ||
|  | 
 | ||
|  |           if (buffer.rdt === 'M') { | ||
|  |             rd = mhchemParser.go(buffer.rd, 'tex-math'); | ||
|  |           } else if (buffer.rdt === 'T') { | ||
|  |             rd = [{ | ||
|  |               type_: 'text', | ||
|  |               p1: buffer.rd || "" | ||
|  |             }]; | ||
|  |           } else { | ||
|  |             rd = mhchemParser.go(buffer.rd); | ||
|  |           } | ||
|  |           /** @type {ParserOutput[]} */ | ||
|  | 
 | ||
|  | 
 | ||
|  |           var rq; | ||
|  | 
 | ||
|  |           if (buffer.rqt === 'M') { | ||
|  |             rq = mhchemParser.go(buffer.rq, 'tex-math'); | ||
|  |           } else if (buffer.rqt === 'T') { | ||
|  |             rq = [{ | ||
|  |               type_: 'text', | ||
|  |               p1: buffer.rq || "" | ||
|  |             }]; | ||
|  |           } else { | ||
|  |             rq = mhchemParser.go(buffer.rq); | ||
|  |           } | ||
|  | 
 | ||
|  |           ret = { | ||
|  |             type_: 'arrow', | ||
|  |             r: buffer.r, | ||
|  |             rd: rd, | ||
|  |             rq: rq | ||
|  |           }; | ||
|  |         } | ||
|  | 
 | ||
|  |         for (var p in buffer) { | ||
|  |           if (p !== 'parenthesisLevel' && p !== 'beginsWithBond') { | ||
|  |             delete buffer[p]; | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'oxidation-output': function oxidationOutput(buffer, m) { | ||
|  |         var ret = ["{"]; | ||
|  |         mhchemParser.concatArray(ret, mhchemParser.go(m, 'oxidation')); | ||
|  |         ret.push("}"); | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'frac-output': function fracOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'frac-ce', | ||
|  |           p1: mhchemParser.go(m[0]), | ||
|  |           p2: mhchemParser.go(m[1]) | ||
|  |         }; | ||
|  |       }, | ||
|  |       'overset-output': function oversetOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'overset', | ||
|  |           p1: mhchemParser.go(m[0]), | ||
|  |           p2: mhchemParser.go(m[1]) | ||
|  |         }; | ||
|  |       }, | ||
|  |       'underset-output': function undersetOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'underset', | ||
|  |           p1: mhchemParser.go(m[0]), | ||
|  |           p2: mhchemParser.go(m[1]) | ||
|  |         }; | ||
|  |       }, | ||
|  |       'underbrace-output': function underbraceOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'underbrace', | ||
|  |           p1: mhchemParser.go(m[0]), | ||
|  |           p2: mhchemParser.go(m[1]) | ||
|  |         }; | ||
|  |       }, | ||
|  |       'color-output': function colorOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'color', | ||
|  |           color1: m[0], | ||
|  |           color2: mhchemParser.go(m[1]) | ||
|  |         }; | ||
|  |       }, | ||
|  |       'r=': function r(buffer, m) { | ||
|  |         buffer.r = m; | ||
|  |       }, | ||
|  |       'rdt=': function rdt(buffer, m) { | ||
|  |         buffer.rdt = m; | ||
|  |       }, | ||
|  |       'rd=': function rd(buffer, m) { | ||
|  |         buffer.rd = m; | ||
|  |       }, | ||
|  |       'rqt=': function rqt(buffer, m) { | ||
|  |         buffer.rqt = m; | ||
|  |       }, | ||
|  |       'rq=': function rq(buffer, m) { | ||
|  |         buffer.rq = m; | ||
|  |       }, | ||
|  |       'operator': function operator(buffer, m, p1) { | ||
|  |         return { | ||
|  |           type_: 'operator', | ||
|  |           kind_: p1 || m | ||
|  |         }; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'a': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       '1/2$': { | ||
|  |         '0': { | ||
|  |           action_: '1/2' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '0': { | ||
|  |           nextState: '1', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       '$(...)$': { | ||
|  |         '*': { | ||
|  |           action_: 'tex-math tight', | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       }, | ||
|  |       ',': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'insert', | ||
|  |             option: 'commaDecimal' | ||
|  |           } | ||
|  |         } | ||
|  |       }, | ||
|  |       'else2': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: {} | ||
|  |   }, | ||
|  |   'o': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       '1/2$': { | ||
|  |         '0': { | ||
|  |           action_: '1/2' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '0': { | ||
|  |           nextState: '1', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       'letters': { | ||
|  |         '*': { | ||
|  |           action_: 'rm' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\ca': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'insert', | ||
|  |             option: 'circa' | ||
|  |           } | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\x{}{}|\\x{}|\\x': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       }, | ||
|  |       '${(...)}$|$(...)$': { | ||
|  |         '*': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: '{text}' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else2': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: {} | ||
|  |   }, | ||
|  |   'text': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': { | ||
|  |           action_: 'output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{...}': { | ||
|  |         '*': { | ||
|  |           action_: 'text=' | ||
|  |         } | ||
|  |       }, | ||
|  |       '${(...)}$|$(...)$': { | ||
|  |         '*': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\greek': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'rm'] | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\,|\\x{}{}|\\x{}|\\x': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'copy'] | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '*': { | ||
|  |           action_: 'text=' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'output': function output(buffer) { | ||
|  |         if (buffer.text_) { | ||
|  |           /** @type {ParserOutput} */ | ||
|  |           var ret = { | ||
|  |             type_: 'text', | ||
|  |             p1: buffer.text_ | ||
|  |           }; | ||
|  | 
 | ||
|  |           for (var p in buffer) { | ||
|  |             delete buffer[p]; | ||
|  |           } | ||
|  | 
 | ||
|  |           return ret; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'pq': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       'state of aggregation $': { | ||
|  |         '*': { | ||
|  |           action_: 'state of aggregation' | ||
|  |         } | ||
|  |       }, | ||
|  |       'i$': { | ||
|  |         '0': { | ||
|  |           nextState: '!f', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       '(KV letters),': { | ||
|  |         '0': { | ||
|  |           action_: 'rm', | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       'formula$': { | ||
|  |         '0': { | ||
|  |           nextState: 'f', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       '1/2$': { | ||
|  |         '0': { | ||
|  |           action_: '1/2' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '0': { | ||
|  |           nextState: '!f', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       '${(...)}$|$(...)$': { | ||
|  |         '*': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: 'text' | ||
|  |         } | ||
|  |       }, | ||
|  |       'a-z': { | ||
|  |         'f': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       'letters': { | ||
|  |         '*': { | ||
|  |           action_: 'rm' | ||
|  |         } | ||
|  |       }, | ||
|  |       '-9.,9': { | ||
|  |         '*': { | ||
|  |           action_: '9,9' | ||
|  |         } | ||
|  |       }, | ||
|  |       ',': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'insert+p1', | ||
|  |             option: 'comma enumeration S' | ||
|  |           } | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\color{(...)}{(...)}1|\\color(...){(...)}2': { | ||
|  |         '*': { | ||
|  |           action_: 'color-output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\color{(...)}0': { | ||
|  |         '*': { | ||
|  |           action_: 'color0-output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\ce{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: 'ce' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\,|\\x{}{}|\\x{}|\\x': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else2': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'state of aggregation': function stateOfAggregation(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'state of aggregation subscript', | ||
|  |           p1: mhchemParser.go(m, 'o') | ||
|  |         }; | ||
|  |       }, | ||
|  |       'color-output': function colorOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'color', | ||
|  |           color1: m[0], | ||
|  |           color2: mhchemParser.go(m[1], 'pq') | ||
|  |         }; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'bd': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       'x$': { | ||
|  |         '0': { | ||
|  |           nextState: '!f', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       'formula$': { | ||
|  |         '0': { | ||
|  |           nextState: 'f', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '0': { | ||
|  |           nextState: '!f', | ||
|  |           revisit: true | ||
|  |         } | ||
|  |       }, | ||
|  |       '-9.,9 no missing 0': { | ||
|  |         '*': { | ||
|  |           action_: '9,9' | ||
|  |         } | ||
|  |       }, | ||
|  |       '.': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'insert', | ||
|  |             option: 'electron dot' | ||
|  |           } | ||
|  |         } | ||
|  |       }, | ||
|  |       'a-z': { | ||
|  |         'f': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       'x': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'insert', | ||
|  |             option: 'KV x' | ||
|  |           } | ||
|  |         } | ||
|  |       }, | ||
|  |       'letters': { | ||
|  |         '*': { | ||
|  |           action_: 'rm' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\'': { | ||
|  |         '*': { | ||
|  |           action_: { | ||
|  |             type_: 'insert', | ||
|  |             option: 'prime' | ||
|  |           } | ||
|  |         } | ||
|  |       }, | ||
|  |       '${(...)}$|$(...)$': { | ||
|  |         '*': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: 'text' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\color{(...)}{(...)}1|\\color(...){(...)}2': { | ||
|  |         '*': { | ||
|  |           action_: 'color-output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\color{(...)}0': { | ||
|  |         '*': { | ||
|  |           action_: 'color0-output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\ce{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: 'ce' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\,|\\x{}{}|\\x{}|\\x': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else2': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'color-output': function colorOutput(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'color', | ||
|  |           color1: m[0], | ||
|  |           color2: mhchemParser.go(m[1], 'bd') | ||
|  |         }; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'oxidation': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       'roman numeral': { | ||
|  |         '*': { | ||
|  |           action_: 'roman-numeral' | ||
|  |         } | ||
|  |       }, | ||
|  |       '${(...)}$|$(...)$': { | ||
|  |         '*': { | ||
|  |           action_: 'tex-math' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'roman-numeral': function romanNumeral(buffer, m) { | ||
|  |         return { | ||
|  |           type_: 'roman numeral', | ||
|  |           p1: m || "" | ||
|  |         }; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'tex-math': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': { | ||
|  |           action_: 'output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\ce{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'ce'] | ||
|  |         } | ||
|  |       }, | ||
|  |       '{...}|\\,|\\x{}{}|\\x{}|\\x': { | ||
|  |         '*': { | ||
|  |           action_: 'o=' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '*': { | ||
|  |           action_: 'o=' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'output': function output(buffer) { | ||
|  |         if (buffer.o) { | ||
|  |           /** @type {ParserOutput} */ | ||
|  |           var ret = { | ||
|  |             type_: 'tex-math', | ||
|  |             p1: buffer.o | ||
|  |           }; | ||
|  | 
 | ||
|  |           for (var p in buffer) { | ||
|  |             delete buffer[p]; | ||
|  |           } | ||
|  | 
 | ||
|  |           return ret; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'tex-math tight': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': { | ||
|  |           action_: 'output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\ce{(...)}': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'ce'] | ||
|  |         } | ||
|  |       }, | ||
|  |       '{...}|\\,|\\x{}{}|\\x{}|\\x': { | ||
|  |         '*': { | ||
|  |           action_: 'o=' | ||
|  |         } | ||
|  |       }, | ||
|  |       '-|+': { | ||
|  |         '*': { | ||
|  |           action_: 'tight operator' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '*': { | ||
|  |           action_: 'o=' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'tight operator': function tightOperator(buffer, m) { | ||
|  |         buffer.o = (buffer.o || "") + "{" + m + "}"; | ||
|  |       }, | ||
|  |       'output': function output(buffer) { | ||
|  |         if (buffer.o) { | ||
|  |           /** @type {ParserOutput} */ | ||
|  |           var ret = { | ||
|  |             type_: 'tex-math', | ||
|  |             p1: buffer.o | ||
|  |           }; | ||
|  | 
 | ||
|  |           for (var p in buffer) { | ||
|  |             delete buffer[p]; | ||
|  |           } | ||
|  | 
 | ||
|  |           return ret; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   '9,9': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': {} | ||
|  |       }, | ||
|  |       ',': { | ||
|  |         '*': { | ||
|  |           action_: 'comma' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '*': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'comma': function comma() { | ||
|  |         return { | ||
|  |           type_: 'commaDecimal' | ||
|  |         }; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   //#endregion
 | ||
|  |   //
 | ||
|  |   // \pu state machines
 | ||
|  |   //
 | ||
|  |   //#region pu
 | ||
|  |   'pu': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': { | ||
|  |           action_: 'output' | ||
|  |         } | ||
|  |       }, | ||
|  |       'space$': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'space'] | ||
|  |         } | ||
|  |       }, | ||
|  |       '{[(|)]}': { | ||
|  |         '0|a': { | ||
|  |           action_: 'copy' | ||
|  |         } | ||
|  |       }, | ||
|  |       '(-)(9)^(-9)': { | ||
|  |         '0': { | ||
|  |           action_: 'number^', | ||
|  |           nextState: 'a' | ||
|  |         } | ||
|  |       }, | ||
|  |       '(-)(9.,9)(e)(99)': { | ||
|  |         '0': { | ||
|  |           action_: 'enumber', | ||
|  |           nextState: 'a' | ||
|  |         } | ||
|  |       }, | ||
|  |       'space': { | ||
|  |         '0|a': {} | ||
|  |       }, | ||
|  |       'pm-operator': { | ||
|  |         '0|a': { | ||
|  |           action_: { | ||
|  |             type_: 'operator', | ||
|  |             option: '\\pm' | ||
|  |           }, | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       'operator': { | ||
|  |         '0|a': { | ||
|  |           action_: 'copy', | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '//': { | ||
|  |         'd': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: '/' | ||
|  |         } | ||
|  |       }, | ||
|  |       '/': { | ||
|  |         'd': { | ||
|  |           action_: 'o=', | ||
|  |           nextState: '/' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{...}|else': { | ||
|  |         '0|d': { | ||
|  |           action_: 'd=', | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         'a': { | ||
|  |           action_: ['space', 'd='], | ||
|  |           nextState: 'd' | ||
|  |         }, | ||
|  |         '/|q': { | ||
|  |           action_: 'q=', | ||
|  |           nextState: 'q' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'enumber': function enumber(buffer, m) { | ||
|  |         /** @type {ParserOutput[]} */ | ||
|  |         var ret = []; | ||
|  | 
 | ||
|  |         if (m[0] === "+-" || m[0] === "+/-") { | ||
|  |           ret.push("\\pm "); | ||
|  |         } else if (m[0]) { | ||
|  |           ret.push(m[0]); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (m[1]) { | ||
|  |           mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9')); | ||
|  | 
 | ||
|  |           if (m[2]) { | ||
|  |             if (m[2].match(/[,.]/)) { | ||
|  |               mhchemParser.concatArray(ret, mhchemParser.go(m[2], 'pu-9,9')); | ||
|  |             } else { | ||
|  |               ret.push(m[2]); | ||
|  |             } | ||
|  |           } | ||
|  | 
 | ||
|  |           m[3] = m[4] || m[3]; | ||
|  | 
 | ||
|  |           if (m[3]) { | ||
|  |             m[3] = m[3].trim(); | ||
|  | 
 | ||
|  |             if (m[3] === "e" || m[3].substr(0, 1) === "*") { | ||
|  |               ret.push({ | ||
|  |                 type_: 'cdot' | ||
|  |               }); | ||
|  |             } else { | ||
|  |               ret.push({ | ||
|  |                 type_: 'times' | ||
|  |               }); | ||
|  |             } | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         if (m[3]) { | ||
|  |           ret.push("10^{" + m[5] + "}"); | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'number^': function number(buffer, m) { | ||
|  |         /** @type {ParserOutput[]} */ | ||
|  |         var ret = []; | ||
|  | 
 | ||
|  |         if (m[0] === "+-" || m[0] === "+/-") { | ||
|  |           ret.push("\\pm "); | ||
|  |         } else if (m[0]) { | ||
|  |           ret.push(m[0]); | ||
|  |         } | ||
|  | 
 | ||
|  |         mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9')); | ||
|  |         ret.push("^{" + m[2] + "}"); | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'operator': function operator(buffer, m, p1) { | ||
|  |         return { | ||
|  |           type_: 'operator', | ||
|  |           kind_: p1 || m | ||
|  |         }; | ||
|  |       }, | ||
|  |       'space': function space() { | ||
|  |         return { | ||
|  |           type_: 'pu-space-1' | ||
|  |         }; | ||
|  |       }, | ||
|  |       'output': function output(buffer) { | ||
|  |         /** @type {ParserOutput | ParserOutput[]} */ | ||
|  |         var ret; | ||
|  |         var md = mhchemParser.patterns.match_('{(...)}', buffer.d || ""); | ||
|  | 
 | ||
|  |         if (md && md.remainder === '') { | ||
|  |           buffer.d = md.match_; | ||
|  |         } | ||
|  | 
 | ||
|  |         var mq = mhchemParser.patterns.match_('{(...)}', buffer.q || ""); | ||
|  | 
 | ||
|  |         if (mq && mq.remainder === '') { | ||
|  |           buffer.q = mq.match_; | ||
|  |         } | ||
|  | 
 | ||
|  |         if (buffer.d) { | ||
|  |           buffer.d = buffer.d.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C"); | ||
|  |           buffer.d = buffer.d.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F"); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (buffer.q) { | ||
|  |           // fraction
 | ||
|  |           buffer.q = buffer.q.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C"); | ||
|  |           buffer.q = buffer.q.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F"); | ||
|  |           var b5 = { | ||
|  |             d: mhchemParser.go(buffer.d, 'pu'), | ||
|  |             q: mhchemParser.go(buffer.q, 'pu') | ||
|  |           }; | ||
|  | 
 | ||
|  |           if (buffer.o === '//') { | ||
|  |             ret = { | ||
|  |               type_: 'pu-frac', | ||
|  |               p1: b5.d, | ||
|  |               p2: b5.q | ||
|  |             }; | ||
|  |           } else { | ||
|  |             ret = b5.d; | ||
|  | 
 | ||
|  |             if (b5.d.length > 1 || b5.q.length > 1) { | ||
|  |               ret.push({ | ||
|  |                 type_: ' / ' | ||
|  |               }); | ||
|  |             } else { | ||
|  |               ret.push({ | ||
|  |                 type_: '/' | ||
|  |               }); | ||
|  |             } | ||
|  | 
 | ||
|  |             mhchemParser.concatArray(ret, b5.q); | ||
|  |           } | ||
|  |         } else { | ||
|  |           // no fraction
 | ||
|  |           ret = mhchemParser.go(buffer.d, 'pu-2'); | ||
|  |         } | ||
|  | 
 | ||
|  |         for (var p in buffer) { | ||
|  |           delete buffer[p]; | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'pu-2': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '*': { | ||
|  |           action_: 'output' | ||
|  |         } | ||
|  |       }, | ||
|  |       '*': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'cdot'], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '\\x': { | ||
|  |         '*': { | ||
|  |           action_: 'rm=' | ||
|  |         } | ||
|  |       }, | ||
|  |       'space': { | ||
|  |         '*': { | ||
|  |           action_: ['output', 'space'], | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '^{(...)}|^(-1)': { | ||
|  |         '1': { | ||
|  |           action_: '^(-1)' | ||
|  |         } | ||
|  |       }, | ||
|  |       '-9.,9': { | ||
|  |         '0': { | ||
|  |           action_: 'rm=', | ||
|  |           nextState: '0' | ||
|  |         }, | ||
|  |         '1': { | ||
|  |           action_: '^(-1)', | ||
|  |           nextState: '0' | ||
|  |         } | ||
|  |       }, | ||
|  |       '{...}|else': { | ||
|  |         '*': { | ||
|  |           action_: 'rm=', | ||
|  |           nextState: '1' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'cdot': function cdot() { | ||
|  |         return { | ||
|  |           type_: 'tight cdot' | ||
|  |         }; | ||
|  |       }, | ||
|  |       '^(-1)': function _(buffer, m) { | ||
|  |         buffer.rm += "^{" + m + "}"; | ||
|  |       }, | ||
|  |       'space': function space() { | ||
|  |         return { | ||
|  |           type_: 'pu-space-2' | ||
|  |         }; | ||
|  |       }, | ||
|  |       'output': function output(buffer) { | ||
|  |         /** @type {ParserOutput | ParserOutput[]} */ | ||
|  |         var ret = []; | ||
|  | 
 | ||
|  |         if (buffer.rm) { | ||
|  |           var mrm = mhchemParser.patterns.match_('{(...)}', buffer.rm || ""); | ||
|  | 
 | ||
|  |           if (mrm && mrm.remainder === '') { | ||
|  |             ret = mhchemParser.go(mrm.match_, 'pu'); | ||
|  |           } else { | ||
|  |             ret = { | ||
|  |               type_: 'rm', | ||
|  |               p1: buffer.rm | ||
|  |             }; | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         for (var p in buffer) { | ||
|  |           delete buffer[p]; | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       } | ||
|  |     } | ||
|  |   }, | ||
|  |   'pu-9,9': { | ||
|  |     transitions: mhchemParser.createTransitions({ | ||
|  |       'empty': { | ||
|  |         '0': { | ||
|  |           action_: 'output-0' | ||
|  |         }, | ||
|  |         'o': { | ||
|  |           action_: 'output-o' | ||
|  |         } | ||
|  |       }, | ||
|  |       ',': { | ||
|  |         '0': { | ||
|  |           action_: ['output-0', 'comma'], | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       '.': { | ||
|  |         '0': { | ||
|  |           action_: ['output-0', 'copy'], | ||
|  |           nextState: 'o' | ||
|  |         } | ||
|  |       }, | ||
|  |       'else': { | ||
|  |         '*': { | ||
|  |           action_: 'text=' | ||
|  |         } | ||
|  |       } | ||
|  |     }), | ||
|  |     actions: { | ||
|  |       'comma': function comma() { | ||
|  |         return { | ||
|  |           type_: 'commaDecimal' | ||
|  |         }; | ||
|  |       }, | ||
|  |       'output-0': function output0(buffer) { | ||
|  |         /** @type {ParserOutput[]} */ | ||
|  |         var ret = []; | ||
|  |         buffer.text_ = buffer.text_ || ""; | ||
|  | 
 | ||
|  |         if (buffer.text_.length > 4) { | ||
|  |           var a = buffer.text_.length % 3; | ||
|  | 
 | ||
|  |           if (a === 0) { | ||
|  |             a = 3; | ||
|  |           } | ||
|  | 
 | ||
|  |           for (var i = buffer.text_.length - 3; i > 0; i -= 3) { | ||
|  |             ret.push(buffer.text_.substr(i, 3)); | ||
|  |             ret.push({ | ||
|  |               type_: '1000 separator' | ||
|  |             }); | ||
|  |           } | ||
|  | 
 | ||
|  |           ret.push(buffer.text_.substr(0, a)); | ||
|  |           ret.reverse(); | ||
|  |         } else { | ||
|  |           ret.push(buffer.text_); | ||
|  |         } | ||
|  | 
 | ||
|  |         for (var p in buffer) { | ||
|  |           delete buffer[p]; | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       }, | ||
|  |       'output-o': function outputO(buffer) { | ||
|  |         /** @type {ParserOutput[]} */ | ||
|  |         var ret = []; | ||
|  |         buffer.text_ = buffer.text_ || ""; | ||
|  | 
 | ||
|  |         if (buffer.text_.length > 4) { | ||
|  |           var a = buffer.text_.length - 3; | ||
|  | 
 | ||
|  |           for (var i = 0; i < a; i += 3) { | ||
|  |             ret.push(buffer.text_.substr(i, 3)); | ||
|  |             ret.push({ | ||
|  |               type_: '1000 separator' | ||
|  |             }); | ||
|  |           } | ||
|  | 
 | ||
|  |           ret.push(buffer.text_.substr(i)); | ||
|  |         } else { | ||
|  |           ret.push(buffer.text_); | ||
|  |         } | ||
|  | 
 | ||
|  |         for (var p in buffer) { | ||
|  |           delete buffer[p]; | ||
|  |         } | ||
|  | 
 | ||
|  |         return ret; | ||
|  |       } | ||
|  |     } //#endregion
 | ||
|  | 
 | ||
|  |   } | ||
|  | }; //
 | ||
|  | // texify: Take MhchemParser output and convert it to TeX
 | ||
|  | //
 | ||
|  | 
 | ||
|  | /** @type {Texify} */ | ||
|  | 
 | ||
|  | var texify = { | ||
|  |   go: function go(input, isInner) { | ||
|  |     // (recursive, max 4 levels)
 | ||
|  |     if (!input) { | ||
|  |       return ""; | ||
|  |     } | ||
|  | 
 | ||
|  |     var res = ""; | ||
|  |     var cee = false; | ||
|  | 
 | ||
|  |     for (var i = 0; i < input.length; i++) { | ||
|  |       var inputi = input[i]; | ||
|  | 
 | ||
|  |       if (typeof inputi === "string") { | ||
|  |         res += inputi; | ||
|  |       } else { | ||
|  |         res += texify._go2(inputi); | ||
|  | 
 | ||
|  |         if (inputi.type_ === '1st-level escape') { | ||
|  |           cee = true; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     if (!isInner && !cee && res) { | ||
|  |       res = "{" + res + "}"; | ||
|  |     } | ||
|  | 
 | ||
|  |     return res; | ||
|  |   }, | ||
|  |   _goInner: function _goInner(input) { | ||
|  |     if (!input) { | ||
|  |       return input; | ||
|  |     } | ||
|  | 
 | ||
|  |     return texify.go(input, true); | ||
|  |   }, | ||
|  |   _go2: function _go2(buf) { | ||
|  |     /** @type {undefined | string} */ | ||
|  |     var res; | ||
|  | 
 | ||
|  |     switch (buf.type_) { | ||
|  |       case 'chemfive': | ||
|  |         res = ""; | ||
|  |         var b5 = { | ||
|  |           a: texify._goInner(buf.a), | ||
|  |           b: texify._goInner(buf.b), | ||
|  |           p: texify._goInner(buf.p), | ||
|  |           o: texify._goInner(buf.o), | ||
|  |           q: texify._goInner(buf.q), | ||
|  |           d: texify._goInner(buf.d) | ||
|  |         }; //
 | ||
|  |         // a
 | ||
|  |         //
 | ||
|  | 
 | ||
|  |         if (b5.a) { | ||
|  |           if (b5.a.match(/^[+\-]/)) { | ||
|  |             b5.a = "{" + b5.a + "}"; | ||
|  |           } | ||
|  | 
 | ||
|  |           res += b5.a + "\\,"; | ||
|  |         } //
 | ||
|  |         // b and p
 | ||
|  |         //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |         if (b5.b || b5.p) { | ||
|  |           res += "{\\vphantom{X}}"; | ||
|  |           res += "^{\\hphantom{" + (b5.b || "") + "}}_{\\hphantom{" + (b5.p || "") + "}}"; | ||
|  |           res += "{\\vphantom{X}}"; | ||
|  |           res += "^{\\smash[t]{\\vphantom{2}}\\mathllap{" + (b5.b || "") + "}}"; | ||
|  |           res += "_{\\vphantom{2}\\mathllap{\\smash[t]{" + (b5.p || "") + "}}}"; | ||
|  |         } //
 | ||
|  |         // o
 | ||
|  |         //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |         if (b5.o) { | ||
|  |           if (b5.o.match(/^[+\-]/)) { | ||
|  |             b5.o = "{" + b5.o + "}"; | ||
|  |           } | ||
|  | 
 | ||
|  |           res += b5.o; | ||
|  |         } //
 | ||
|  |         // q and d
 | ||
|  |         //
 | ||
|  | 
 | ||
|  | 
 | ||
|  |         if (buf.dType === 'kv') { | ||
|  |           if (b5.d || b5.q) { | ||
|  |             res += "{\\vphantom{X}}"; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (b5.d) { | ||
|  |             res += "^{" + b5.d + "}"; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (b5.q) { | ||
|  |             res += "_{\\smash[t]{" + b5.q + "}}"; | ||
|  |           } | ||
|  |         } else if (buf.dType === 'oxidation') { | ||
|  |           if (b5.d) { | ||
|  |             res += "{\\vphantom{X}}"; | ||
|  |             res += "^{" + b5.d + "}"; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (b5.q) { | ||
|  |             res += "{\\vphantom{X}}"; | ||
|  |             res += "_{\\smash[t]{" + b5.q + "}}"; | ||
|  |           } | ||
|  |         } else { | ||
|  |           if (b5.q) { | ||
|  |             res += "{\\vphantom{X}}"; | ||
|  |             res += "_{\\smash[t]{" + b5.q + "}}"; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (b5.d) { | ||
|  |             res += "{\\vphantom{X}}"; | ||
|  |             res += "^{" + b5.d + "}"; | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'rm': | ||
|  |         res = "\\mathrm{" + buf.p1 + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'text': | ||
|  |         if (buf.p1.match(/[\^_]/)) { | ||
|  |           buf.p1 = buf.p1.replace(" ", "~").replace("-", "\\text{-}"); | ||
|  |           res = "\\mathrm{" + buf.p1 + "}"; | ||
|  |         } else { | ||
|  |           res = "\\text{" + buf.p1 + "}"; | ||
|  |         } | ||
|  | 
 | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'roman numeral': | ||
|  |         res = "\\mathrm{" + buf.p1 + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'state of aggregation': | ||
|  |         res = "\\mskip2mu " + texify._goInner(buf.p1); | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'state of aggregation subscript': | ||
|  |         res = "\\mskip1mu " + texify._goInner(buf.p1); | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'bond': | ||
|  |         res = texify._getBond(buf.kind_); | ||
|  | 
 | ||
|  |         if (!res) { | ||
|  |           throw ["MhchemErrorBond", "mhchem Error. Unknown bond type (" + buf.kind_ + ")"]; | ||
|  |         } | ||
|  | 
 | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'frac': | ||
|  |         var c = "\\frac{" + buf.p1 + "}{" + buf.p2 + "}"; | ||
|  |         res = "\\mathchoice{\\textstyle" + c + "}{" + c + "}{" + c + "}{" + c + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'pu-frac': | ||
|  |         var d = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; | ||
|  |         res = "\\mathchoice{\\textstyle" + d + "}{" + d + "}{" + d + "}{" + d + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'tex-math': | ||
|  |         res = buf.p1 + " "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'frac-ce': | ||
|  |         res = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'overset': | ||
|  |         res = "\\overset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'underset': | ||
|  |         res = "\\underset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'underbrace': | ||
|  |         res = "\\underbrace{" + texify._goInner(buf.p1) + "}_{" + texify._goInner(buf.p2) + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'color': | ||
|  |         res = "{\\color{" + buf.color1 + "}{" + texify._goInner(buf.color2) + "}}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'color0': | ||
|  |         res = "\\color{" + buf.color + "}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'arrow': | ||
|  |         var b6 = { | ||
|  |           rd: texify._goInner(buf.rd), | ||
|  |           rq: texify._goInner(buf.rq) | ||
|  |         }; | ||
|  | 
 | ||
|  |         var arrow = "\\x" + texify._getArrow(buf.r); | ||
|  | 
 | ||
|  |         if (b6.rq) { | ||
|  |           arrow += "[{" + b6.rq + "}]"; | ||
|  |         } | ||
|  | 
 | ||
|  |         if (b6.rd) { | ||
|  |           arrow += "{" + b6.rd + "}"; | ||
|  |         } else { | ||
|  |           arrow += "{}"; | ||
|  |         } | ||
|  | 
 | ||
|  |         res = arrow; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'operator': | ||
|  |         res = texify._getOperator(buf.kind_); | ||
|  |         break; | ||
|  | 
 | ||
|  |       case '1st-level escape': | ||
|  |         res = buf.p1 + " "; // &, \\\\, \\hlin
 | ||
|  | 
 | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'space': | ||
|  |         res = " "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'entitySkip': | ||
|  |         res = "~"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'pu-space-1': | ||
|  |         res = "~"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'pu-space-2': | ||
|  |         res = "\\mkern3mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case '1000 separator': | ||
|  |         res = "\\mkern2mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'commaDecimal': | ||
|  |         res = "{,}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'comma enumeration L': | ||
|  |         res = "{" + buf.p1 + "}\\mkern6mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'comma enumeration M': | ||
|  |         res = "{" + buf.p1 + "}\\mkern3mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'comma enumeration S': | ||
|  |         res = "{" + buf.p1 + "}\\mkern1mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'hyphen': | ||
|  |         res = "\\text{-}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'addition compound': | ||
|  |         res = "\\,{\\cdot}\\,"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'electron dot': | ||
|  |         res = "\\mkern1mu \\bullet\\mkern1mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'KV x': | ||
|  |         res = "{\\times}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'prime': | ||
|  |         res = "\\prime "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'cdot': | ||
|  |         res = "\\cdot "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'tight cdot': | ||
|  |         res = "\\mkern1mu{\\cdot}\\mkern1mu "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'times': | ||
|  |         res = "\\times "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'circa': | ||
|  |         res = "{\\sim}"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case '^': | ||
|  |         res = "uparrow"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'v': | ||
|  |         res = "downarrow"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case 'ellipsis': | ||
|  |         res = "\\ldots "; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case '/': | ||
|  |         res = "/"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       case ' / ': | ||
|  |         res = "\\,/\\,"; | ||
|  |         break; | ||
|  | 
 | ||
|  |       default: | ||
|  |         assertNever(buf); | ||
|  |         throw ["MhchemBugT", "mhchem bug T. Please report."]; | ||
|  |       // Missing texify rule or unknown MhchemParser output
 | ||
|  |     } | ||
|  | 
 | ||
|  |     assertString(res); | ||
|  |     return res; | ||
|  |   }, | ||
|  |   _getArrow: function _getArrow(a) { | ||
|  |     switch (a) { | ||
|  |       case "->": | ||
|  |         return "rightarrow"; | ||
|  | 
 | ||
|  |       case "\u2192": | ||
|  |         return "rightarrow"; | ||
|  | 
 | ||
|  |       case "\u27F6": | ||
|  |         return "rightarrow"; | ||
|  | 
 | ||
|  |       case "<-": | ||
|  |         return "leftarrow"; | ||
|  | 
 | ||
|  |       case "<->": | ||
|  |         return "leftrightarrow"; | ||
|  | 
 | ||
|  |       case "<-->": | ||
|  |         return "rightleftarrows"; | ||
|  | 
 | ||
|  |       case "<=>": | ||
|  |         return "rightleftharpoons"; | ||
|  | 
 | ||
|  |       case "\u21CC": | ||
|  |         return "rightleftharpoons"; | ||
|  | 
 | ||
|  |       case "<=>>": | ||
|  |         return "rightequilibrium"; | ||
|  | 
 | ||
|  |       case "<<=>": | ||
|  |         return "leftequilibrium"; | ||
|  | 
 | ||
|  |       default: | ||
|  |         assertNever(a); | ||
|  |         throw ["MhchemBugT", "mhchem bug T. Please report."]; | ||
|  |     } | ||
|  |   }, | ||
|  |   _getBond: function _getBond(a) { | ||
|  |     switch (a) { | ||
|  |       case "-": | ||
|  |         return "{-}"; | ||
|  | 
 | ||
|  |       case "1": | ||
|  |         return "{-}"; | ||
|  | 
 | ||
|  |       case "=": | ||
|  |         return "{=}"; | ||
|  | 
 | ||
|  |       case "2": | ||
|  |         return "{=}"; | ||
|  | 
 | ||
|  |       case "#": | ||
|  |         return "{\\equiv}"; | ||
|  | 
 | ||
|  |       case "3": | ||
|  |         return "{\\equiv}"; | ||
|  | 
 | ||
|  |       case "~": | ||
|  |         return "{\\tripledash}"; | ||
|  | 
 | ||
|  |       case "~-": | ||
|  |         return "{\\mathrlap{\\raisebox{-.1em}{$-$}}\\raisebox{.1em}{$\\tripledash$}}"; | ||
|  | 
 | ||
|  |       case "~=": | ||
|  |         return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}"; | ||
|  | 
 | ||
|  |       case "~--": | ||
|  |         return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}"; | ||
|  | 
 | ||
|  |       case "-~-": | ||
|  |         return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$-$}}\\tripledash}"; | ||
|  | 
 | ||
|  |       case "...": | ||
|  |         return "{{\\cdot}{\\cdot}{\\cdot}}"; | ||
|  | 
 | ||
|  |       case "....": | ||
|  |         return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}"; | ||
|  | 
 | ||
|  |       case "->": | ||
|  |         return "{\\rightarrow}"; | ||
|  | 
 | ||
|  |       case "<-": | ||
|  |         return "{\\leftarrow}"; | ||
|  | 
 | ||
|  |       case "<": | ||
|  |         return "{<}"; | ||
|  | 
 | ||
|  |       case ">": | ||
|  |         return "{>}"; | ||
|  | 
 | ||
|  |       default: | ||
|  |         assertNever(a); | ||
|  |         throw ["MhchemBugT", "mhchem bug T. Please report."]; | ||
|  |     } | ||
|  |   }, | ||
|  |   _getOperator: function _getOperator(a) { | ||
|  |     switch (a) { | ||
|  |       case "+": | ||
|  |         return " {}+{} "; | ||
|  | 
 | ||
|  |       case "-": | ||
|  |         return " {}-{} "; | ||
|  | 
 | ||
|  |       case "=": | ||
|  |         return " {}={} "; | ||
|  | 
 | ||
|  |       case "<": | ||
|  |         return " {}<{} "; | ||
|  | 
 | ||
|  |       case ">": | ||
|  |         return " {}>{} "; | ||
|  | 
 | ||
|  |       case "<<": | ||
|  |         return " {}\\ll{} "; | ||
|  | 
 | ||
|  |       case ">>": | ||
|  |         return " {}\\gg{} "; | ||
|  | 
 | ||
|  |       case "\\pm": | ||
|  |         return " {}\\pm{} "; | ||
|  | 
 | ||
|  |       case "\\approx": | ||
|  |         return " {}\\approx{} "; | ||
|  | 
 | ||
|  |       case "$\\approx$": | ||
|  |         return " {}\\approx{} "; | ||
|  | 
 | ||
|  |       case "v": | ||
|  |         return " \\downarrow{} "; | ||
|  | 
 | ||
|  |       case "(v)": | ||
|  |         return " \\downarrow{} "; | ||
|  | 
 | ||
|  |       case "^": | ||
|  |         return " \\uparrow{} "; | ||
|  | 
 | ||
|  |       case "(^)": | ||
|  |         return " \\uparrow{} "; | ||
|  | 
 | ||
|  |       default: | ||
|  |         assertNever(a); | ||
|  |         throw ["MhchemBugT", "mhchem bug T. Please report."]; | ||
|  |     } | ||
|  |   } | ||
|  | }; //
 | ||
|  | // Helpers for code anaylsis
 | ||
|  | // Will show type error at calling position
 | ||
|  | //
 | ||
|  | 
 | ||
|  | /** @param {number} a */ | ||
|  | 
 | ||
|  | function assertNever(a) {} | ||
|  | /** @param {string} a */ | ||
|  | 
 | ||
|  | 
 | ||
|  | function assertString(a) {} | ||
|  | 
 | ||
|  | /***/ }) | ||
|  | /******/ ])["default"]; | ||
|  | }); |