diff --git a/content/posts/2018-10-26-twenty-years-of-rsa-attacks.md b/content/posts/2018-10-26-twenty-years-of-rsa-attacks.md
index 9a6271b..e57bc94 100644
--- a/content/posts/2018-10-26-twenty-years-of-rsa-attacks.md
+++ b/content/posts/2018-10-26-twenty-years-of-rsa-attacks.md
@@ -2,21 +2,30 @@
title = "twenty years of attacks on rsa with examples"
date = 2018-10-26
toc = true
-tags = ["crypto"]
+tags = ["ctf", "crypto"]
languages = ["python"]
+math = true
+++
-There's [a great paper][1] I found by Dan Boneh from 1998 highlighting the weaknesses of the RSA cryptosystem. I found this paper to be a particularly enlightening read (and interestingly enough, it's been 20 years since that paper!), so here I'm going to reiterate some of the attacks described in the paper, but using examples with numbers in them.
+There's [a great paper][1] I found by Dan Boneh from 1998 highlighting the
+weaknesses of the RSA cryptosystem. I found this paper to be a particularly
+enlightening read (and interestingly enough, it's been 20 years since that
+paper!), so here I'm going to reiterate some of the attacks described in the
+paper, but using examples with numbers in them.
-(Also please excuse the lack of proper formatting, I've yet to figure out how to get Gutenberg to accept Latex)
-
-That being said, I _am_ going to skip over the primer of how the RSA cryptosystem works, since there's already a great number of resources on how to do that.
+That being said, I _am_ going to skip over the primer of how the RSA
+cryptosystem works, since there's already a great number of resources on that.
## factoring large integers
-Obviously this is a pretty bruteforce-ish way to crack the cryptosystem, and probably won't work in time for you to see the result, but can still be considered an attack vector. This trick works by just factoring the modulus, N. With N, finding the private exponent d from the public exponent e is a piece of cake.
+Obviously this is a pretty bruteforce-ish way to crack the cryptosystem, and
+probably won't work in time for you to see the result, but can still be
+considered an attack vector. This trick works by just factoring the modulus,
+$N$. With $N$, finding the private exponent $d$ from the public exponent $e$ is
+a piece of cake.
-Let's choose some small numbers to demonstrate this one (you can follow along in a Python REPL if you want):
+Let's choose some small numbers to demonstrate this one (you can follow along in
+a Python REPL if you want):
```py
>>> N = 881653369
@@ -24,7 +33,9 @@ Let's choose some small numbers to demonstrate this one (you can follow along in
>>> c = 875978376
```
-N is clearly factorable in this case, and we can use resources like [msieve][7] or [factordb][2] to find smaller primes in this case. Since we know now that `N = 20717 * 42557`, we can find the totient of N:
+$N$ is clearly factorable in this case, and we can use resources like
+[msieve][7] or [factordb][2] to find smaller primes in this case. Since we know
+now that $N = 20717 \times 42557$, we can find the totient of $N$:
```py
>>> p = 20717
@@ -33,7 +44,8 @@ N is clearly factorable in this case, and we can use resources like [msieve][7]
881590096
```
-Now all that's left is to discover the private exponent and solve for the original message! (you can find the modular inverse function I used [here][3])
+Now all that's left is to discover the private exponent and solve for the
+original message! (you can find the modular inverse function I used [here][3])
```py
>>> d = modinv(e, tot)
@@ -46,15 +58,28 @@ And that's it! Now let's look at some more sophisticated attacks...
## elementary attacks
-These attacks are related to the _misuse_ of the RSA system. (if you can't tell, I'm mirroring the document structure of the original paper)
+These attacks are related to the _misuse_ of the RSA system. (if you can't tell,
+I'm mirroring the document structure of the original paper)
### common modulus
-My cryptography professor gave this example as well. Suppose there was a setup in which the modulus was reused, maybe for convenience (although I suppose with libraries today, it'd actually be more _inconvenient_ to reuse the key). Key pairs would be issued to different users and they would share public keys with each other and keep private keys to themselves.
+My cryptography professor gave this example as well. Suppose there was a setup
+in which the modulus was reused, maybe for convenience (although I suppose with
+libraries today, it'd actually be more _inconvenient_ to reuse the key). Key
+pairs would be issued to different users and they would share public keys with
+each other and keep private keys to themselves.
-The problem here is if you have a key pair, and you got someone else's public key, you could easily derive the private key by just factoring the modulus. Let's see how this works with a real example now.
+The problem here is if you have a key pair, and you got someone else's public
+key, you could easily derive the private key by just factoring the modulus.
+Let's see how this works with a real example now.
-Since this is a big problem if you were to really use this cryptosystem, I'll be using actual keys from an actual crypto library instead of the small numbers like in the first example to show that this works on 2048-bit RSA. The library is called [PyCrypto][4], and if you're planning on doing anything related to crypto with Python, it's a good tool to have with you. For now, I'm going to generate a 2048-bit key (by the way, in practice you probably shouldn't be using 2048-bit keys anymore, I'm just trying to spare my computer here).
+Since this is a big problem if you were to really use this cryptosystem, I'll be
+using actual keys from an actual crypto library instead of the small numbers
+like in the first example to show that this works on 2048-bit RSA. The library
+is called [PyCrypto][4], and if you're planning on doing anything related to
+crypto with Python, it's a good tool to have with you. For now, I'm going to
+generate a 2048-bit key (by the way, in practice you probably shouldn't be using
+2048-bit keys anymore, I'm just trying to spare my computer here).
```py
>>> from Crypto.PublicKey import RSA
@@ -62,7 +87,10 @@ Since this is a big problem if you were to really use this cryptosystem, I'll be
<_RSAobj @0x7f3d3226dfd0 n(2048),e,d,p,q,u,private>
```
-Now, normally when you generate a new key, it'd generate a new modulus. For the sake of this common modulus attack, we'll force the new key to use the same modulus. This also means we'll have to choose an exponent e other than the default choice of 65537 (see [this link][5] for documentation):
+Now, normally when you generate a new key, it'd generate a new modulus. For the
+sake of this common modulus attack, we'll force the new key to use the same
+modulus. This also means we'll have to choose an exponent $e$ other than the
+default choice of 65537 (see [this link][5] for documentation):
```py
>>> N = k1.p * k1.q
@@ -78,11 +106,33 @@ Now, normally when you generate a new key, it'd generate a new modulus. For the
<_RSAobj @0x7f3d31c7c5f8 n(2048),e,d,p,q,u,private>
```
-Ok, now we have two keys, `k1` and `k2`. Now I'll show how using only the public and private key of `k1` (assuming this is the pair that we got legitimately from the crypto operator), and the public key of `k2`, which is tied to the same modulus, we can find the private key of `k2`.
+Ok, now we have two keys, $k_1$ and $k_2$. Now I'll show how using only the public
+and private key of $k_1$ (assuming this is the pair that we got legitimately from
+the crypto operator), and the public key of $k_2$, which is tied to the same
+modulus, we can find the private key of $k_2$.
-To do this, we'll try to find the roots of the equation `f(x) = x^2 - (p + q)x + pq`. You'll find that for values of `p` and `q`, this will produce `f(p) = p^2 - p^2 - qp + pq`, and `f(q) = q^2 - pq - q^2 + pq`. We know that `N = pq`. How can we find `p + q`? Since `phi(N) = (p - 1)(q - 1) = pq - p - q + 1`, we can find that `phi(N) = N - (p + q) + 1`, so `p + q = N - phi(N) + 1`. Now we need to use `e` and `d` to estimate `phi(N)`. Recall that `ed = 1 mod phi(N)`. This is equivalent to saying `ed = 1 + k*phi(N)`. Then `(ed - 1) / phi(N) = k`.
+To do this, we'll try to find the roots of the equation:
-It turns out that `k` is extremely close to `ed/N`: `ed/N = (1 + k*phi(N)) / N = 1/N + k*phi(N)/N`. `1/N` is basically 0, and `phi(N)` is very close to `N`, so it shouldn't change the value of `k` by very much. We now use `ed/N` to estimate `k`: `phi(N) = (ed - 1) / (ed / N)`.
+$$ f(x) = x^2 - (p + q)x + pq $$
+
+You'll find that for values of $p$ and $q$, this will produce $f(p) = p^2 - p^2
+\- qp + pq$, and $f(q) = q^2 - pq - q^2 + pq$. We know that $N = pq$. How can we
+find $p + q$? Since $\phi(N) = (p - 1)(q - 1) = pq - p - q + 1$, we can find
+that $\phi(N) = N - (p + q) + 1$, so $p + q = N - \phi(N) + 1$.
+
+Now we need to use $e$ and $d$ to estimate $\phi(N)$. Recall that $ed = 1 \mod
+\phi(N)$. This is equivalent to saying $ed = 1 + k\phi(N)$. Then $\frac{ed -
+1}{\phi(N)} = k$.
+
+It turns out that $k$ is extremely close to $\frac{ed}{N}$:
+
+$$ \frac{ed}{N} = \frac{1 + k\phi(N)}{N} = \frac{1}{N} + \frac{k\phi(N)}{N} $$
+
+$\frac{1}{N}$ is basically 0, and $\phi(N)$ is very close to $N$, so it
+shouldn't change the value of $k$ by very much. We now use $\frac{ed}{N}$ to
+estimate $k$:
+
+$$ \phi(N) = \frac{ed - 1}{\frac{ed}{N}} $$
```py
>>> from decimal import Decimal, getcontext
@@ -93,7 +143,7 @@ It turns out that `k` is extremely close to `ed/N`: `ed/N = (1 + k*phi(N)) / N =
Decimal('29977270253913673973269594877868500604696844309480395834898813292056864035968758602074842333119394545818563664205865827843973433118231606201251719390934610989873635763197929136439794366715495587924829697045618064595517091398323127000591150167969423793125376862942962617933168868125721044755585292104012767604575090001864613992237960887242026855773279634028088706121371418922552125986506064146112561599205615974813154971272528592745144988174228621487749404677959591894452249599588096076892574585613962026186332366180174253118634077603697727952204486962202338916762987146793208323561031870496718547544796269555861921652')
```
-Then we can get `p + q` through the formula mentioend above:
+Then we can get $p + q$ through the formula mentioend above:
```py
>>> B = Decimal(N) - phi + 1
@@ -101,7 +151,8 @@ Decimal('34642192582980793929380236893725052051755685627449634068179923908929124
>>> C = Decimal(N)
```
-Check to make sure B and C are integers. If they're not, try using a higher precision in `getcontext().prec`. Now solve the quadratic equation:
+Check to make sure $B$ and $C$ are integers. If they're not, try using a higher
+precision in `getcontext().prec`. Now solve the quadratic equation:
```py
>>> p = (B + (B * B - 4 * C).sqrt()) / Decimal(2)
@@ -112,13 +163,18 @@ Decimal('16823427526200025299629360726790945249096067335633200400252946099787748
True
```
-We've successfully recovered `p` and `q` from just `N`, `e`, and `d`!
+We've successfully recovered $p$ and $q$ from just $N$, $e$, and $d$!
### blinding
-This attack is actually about RSA _signatures_ (which uses the opposite keys as encryption: private for signing and public for verifying), and shows how you can compute the signature of a message M using the signature of a derived message M'.
+This attack is actually about RSA _signatures_ (which uses the opposite keys as
+encryption: private for signing and public for verifying), and shows how you can
+compute the signature of a message $M$ using the signature of a derived message
+$M'$.
-Suppose Marvin wants Bob to sign the following message: `"I (Bob) owes Marvin $100,000 USD"`. Marvin hands this to Bob saying something like, "I'll just need you to sign this with your private key." Let's generate Bob's private key:
+Suppose Marvin wants Bob to sign the following message: `"I (Bob) owes Marvin
+$100,000 USD"`. Marvin hands this to Bob saying something like, "I'll just need
+you to sign this with your private key." Let's generate Bob's private key:
```py
>>> from Crypto.Util.number import bytes_to_long, long_to_bytes
@@ -128,7 +184,10 @@ Suppose Marvin wants Bob to sign the following message: `"I (Bob) owes Marvin $1
>>> M = b"I (Bob) owes Marvin $100,000 USD"
```
-Obviously, Bob, an intellectual, will refuse to sign the message. However, suppose Marvin now transforms his message into a more innocent looking one. He does this by turning M into `M' = (r^e)*M mod N` where r is an integer that's coprime to N:
+Obviously, Bob, an intellectual, will refuse to sign the message. However,
+suppose Marvin now transforms his message into a more innocent looking one. He
+does this by turning $M$ into $M' = r^eM \mod N$ where r is an integer that's
+coprime to $N$:
```py
>>> from random import randint
@@ -138,21 +197,32 @@ Obviously, Bob, an intellectual, will refuse to sign the message. However, suppo
b'7\x90\xbc\xf9%T\xa9\xee\xf4\xe3?>]\x88\xcd\xb4\xd6D#\xfc\xcb\x0fd\xf0\x8e\xbc>\n\x06\xcd\x0f\x89\x0bp\xa7o\xd6\x02\xa6\xa7\x81\xd8\n\xae\xfb\x08\xaa|\xbd.\xc9E\xf1|\x86\xcaZ\xaa\xd4L\xafaA\x0c}\x84\x04\n\xa4\xa5\x80\xecX<\xe0\xb5\xf6\xfb\xe3\xcc\xd5BD7\xdc\xaep\x7f\xe9vi\xabB\xe2\xadE\xa41K\xc6\xb7\xae\x01\xcb\x04C\xaf\x8b\x17\x83\xffX7z\xb1\xbf\xceF\xafN(x\x00\x9f\xe1kV\xee\x0b\xbd\xc3H\r\xee9\x81\x16\xb2\x10hb.\x90\x08\xe42$Q\x92Ew+\xe1@\xf9\x17%\xce/\xbd\x00\xad\xe2\x12\x01\x93\x8b\xc4\x1bx\xe6H?\x15\xdfPE@\xf9j\xe3\xb7\x9e\xa0\x86\xd1\xd3\xb6[\xf7q\xf1\x95N\xd3>/\x06\x80\xc7\xa3\x8a\xcbDy\xc6v\x01P\x14\xa9Be\xf7~p\xc5\xaa\xac\xa0\xaf\xbe#\xe5\x18\xc6\x1d\xd5\x14\xc1\xbbYXD\x0c\x91{\xc0s\xde]\x18Z\x8bSk\x07k\xb6\x9a\xa5`Iqe~'
```
-Now he asks Bob to sign this more... innocently-looking message. Without questioning, Bob, an intellectual, signs his life away. Let's say he produces a signature `S' = (M'^d) = (r^e * M)^d = r^(ed) * M^d = r * M^d mod N`.
+Now he asks Bob to sign this more... innocently-looking message. Without
+questioning, Bob, an intellectual, signs his life away. Let's say he produces a
+signature
+
+$$\begin{aligned}
+S' &= (M'^d) \\\
+&= (r^e * M)^d \\\
+&= r^{ed} * M^d \\\
+&= r * M^d \mod N
+\end{aligned}$$
```py
>>> Sp, = bob.sign(Mp, 0)
4222298342813922437811434251340999736739055616654488323193778229765071846717137952694561809398626068283668428796351354154566771597532278827070832905206221261994843265685464173739776886856384806238418884247949451413559988796455422271296883338455956330421559319009950760931899199217936823999874162064553735563087382870564193673989865778229832918474778963380170967676966373703157629615331081637805594392084045827925764529711433584853942576464491576212176547485726609891593617931393545058401472883178443786988683045423150809606471425615670582973274971087459634959553685559458456237617436410759134193279063427911112115134
```
-Now, all Marvin has to do is multiply by the modular inverse of r, to obtain `M^d`, the signature of the original message:
+Now, all Marvin has to do is multiply by the modular inverse of $r$, to obtain
+$M^d$, the signature of the original message:
```py
>>> S = (Sp * modinv(r, N)) % N
6137678992536399703654836416525985142902780822513172949427421060785532284955531529418529725602418902796840570634560123808769013384654624916503940938715718120521434666716675795201896105310462331838807171312705686415521871046533303776516500490921892398440988515777575520183847518597482163414665355222659603386541869176930658730416118799866012276767364050134126722746224706026850062367243018313483359694686773566231956425606553198607719740067340776177716443517567144901614253170719278035838849363127850910135864099535083004590180745762100334268408681888925040382341592080592207557742366581814701422371311084081150092871
```
-Sure enough, if you try to verify the "original" signature against the original message, it checks out.
+Sure enough, if you try to verify the "original" signature against the original
+message, it checks out.
```py
>>> bob.verify(M, (S,))
diff --git a/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/index.md b/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/index.md
new file mode 100644
index 0000000..6017cb7
--- /dev/null
+++ b/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/index.md
@@ -0,0 +1,53 @@
++++
+title = "The Cyber Grabs CTF: Unbr34k4bl3 (942)"
+draft = true
+date = 2022-02-02
+tags = ["ctf", "crypto"]
+languages = ["python"]
+layout = "single"
+math = true
++++
+
+Crypto challenge Unbr34k4bl3 from the Cyber Grabs CTF.
+
+
+> No one can break my rsa encryption, prove me wrong !!
+>
+> Flag Format: cybergrabs{}
+>
+> Author: Mritunjya
+>
+> [output.txt] [source.py]
+
+[output.txt]: ./output.txt
+[source.py]: ./source.py
+
+Looking at the source code, this challenge looks like a typical RSA challenge at
+first, but there are some important differences to note:
+
+- $N = pqr$ (line 34). This is a twist but RSA strategies can easily be
+ extended to 3 prime components.
+- $p, q \equiv 3 \mod 4$ (line 19). This suggests that the cryptosystem is
+ actually a [Rabin cryptosystem][Rabin].
+- We're not given the public keys $e_1$ and $e_2$, but they are related through
+ $x$.
+
+[Rabin]: https://en.wikipedia.org/wiki/Rabin_cryptosystem
+
+## Finding $e_1$ and $e_2$
+
+We know that $e_1$ and $e_2$ are related through $x$, which is some even number
+greater than 2, but we're not given any of their real values. We're also given
+through an oddly-named `functor` function that:
+
+$$
+\begin{aligned}
+ 1 + e_1 + e_1^2 + \cdots + e_1^x &= 1 + e_2 + e_2^2 \\\
+ \frac{1 - e_1^x}{1 - e_1} &= 1 + e_2 + e_2^2
+\end{aligned}
+$$
+
+Interestingly enough, since $e_1$ and $e_2$ are primes, that means
+
+I'd like to thank @10, @sahuang, and @thebishop in the Project Sekai discord for
+their help throughout this challenge.
diff --git a/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/output.txt b/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/output.txt
new file mode 100644
index 0000000..a658bd9
--- /dev/null
+++ b/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/output.txt
@@ -0,0 +1,5 @@
+n:267362205744654830055585746250317245125479735269853713372687604676608285629127977574310510441358104169652444917329986129098240750401425257601282268733834091593200445244725460613298199140690597119199763970064359847666802255456013592631532853951273286284878230893809080250386646832110506402289378691079462364884899662707502858007857457806853302449695351229004051902617728418480990341155900565542195318206284041182555579388392863474548687784403795738945489219689610881075059037192656116884269582257788959555951074322245033492165406470004019896763472332962300128378758934128374039937693688718317737657946435827745981009467876838127075176808098467305627394472135213533754815713468369763665632168616054982745256773112537152292099369137072982289095951236065885648588670059655452986720063260146952425798150221407866669449837430999779776718047668562687216933053536759554900663226163021145439386115076821161003965334731127329486856711654741683760749336235855319144478194501034662638054193682000283319917096796971
+ip:65491313526527942082900846848440586365393305192439699810712229312474732937502934334921061033822729150056656630858908294464249602368303871630644420585085642204592189073314730233318796675949142968346807766087775542461078648703191450221286915401606901781524237580646760734493950360267230729125514156671619347616
+iq:97034409222811998555255396847918439343239825222504093225438959283117395075159811973044380473862026342866489725039905931430797650466599952795602909181290621103197493223080488468216279214006070950393096075839913101687588555346523517436421698916141195686143520143972735534402754157166545851899187305574703394138
+c1:103687839591259628532585171241634220321003599759860095236990117623065664975385083122971507015385215246948744078816596026772744294701233346732383214113445480056584639282712898073542520168025667980980057512174927564196375256682206601425714094930670415979638437119896258396784978194294581076901000507291277729888015413204446158926865037965291316577726275211006619643531704449499845352147547986667837681877488120093302675775792115380914560935989896453159186176952126083066619414338359303033325593504442257083571002878083287293828310810483726711816109297046925744157605591270761804522735216774801135342322479770391505911100485259078064775709124730966391629468398187269096529671187877954443617005248499140455160589093379715757808387108825458007733207099871941497372539249357162437077379731766825184301649010270921003130776410066972952756983157217280397531412843118202051922048479332111760976091302376602674590153876045380552746826056547929265785960676415919260117136285580971488670143947003566230254837742519
+c2:171159809874438596904787534111610260851529969068192878049771299710688449419966698428704180474774734112617652498954998301185232279153644173070897800123538474930545720934844727376637921072749901149514789723141795042182408704214998390482343965532559149095934231081729041402598776401575561653660624208366051273601230345754361771067242657825194926706328336322383296953817730346429591680463526267530372572332663327157636745578067246913529155120642276894180354494816411827468256127607558873938451944866168777913756913920336763454881108023708284527878322162463081091624350220308273550298342755582044860337692076513609120342318151660103532559583052954725303030103413034880155621982581677423267299780543045375467310718078800411397780269409147558121862038983169509828944551199620508493589091401498720419409158373805529997911655270528589050795214164221299581104149954423726171539700223299445034347915430838395255700425648686205603925507474877720680274914513203566997846945579395522000899007446797091893230195801607
diff --git a/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/source.py b/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/source.py
new file mode 100644
index 0000000..ee71306
--- /dev/null
+++ b/content/posts/2022-02-07-cybergrabs-ctf-unbreakable/source.py
@@ -0,0 +1,53 @@
+from Crypto.Util.number import *
+from secret import *
+
+
+assert (x>2 and x%2 == 0)
+assert (isPrime(e1) and isPrime(e2))
+
+def functor():
+ val1 , val2 = 0,0
+ for i in range(x+1):
+ val1 += pow(e1,i)
+ for j in range(3):
+ val2 += pow(e2,j)
+ assert (val1 == val2)
+
+def keygen():
+ while True:
+ p,q = [getStrongPrime(1024) for _ in range(2)]
+ if p%4==3 and q%4==3:
+ break
+
+ r = 2
+ while True:
+ r = r*x
+ if r.bit_length()>1024 and isPrime(r-1):
+ r = r-1
+ break
+
+ return p,q,r
+
+
+functor()
+p,q,r = keygen()
+n = p*q*r
+print(f"p:{p}")
+print(f"q:{q}")
+ip = inverse(p,q)
+iq = inverse(q,p)
+c1 = pow(bytes_to_long(flag[0:len(flag)//2].encode('utf-8')),e1,n)
+c2 = pow(bytes_to_long(flag[len(flag)//2:].encode('utf-8')),e2,n)
+print(f"n:{n}",f"ip:{ip}",f"iq:{iq}",f"c1:{c1}",f"c2:{c2}",sep="\n")
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index b01520c..2b6c341 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -6,6 +6,7 @@
michael's blog
{{ block "headExtra" . }}{{ end }}
+ {{ partial "head" . }}
{{ $style := resources.Get "sass/main.scss" | resources.ToCSS }}
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
new file mode 100644
index 0000000..b54d19f
--- /dev/null
+++ b/layouts/partials/head.html
@@ -0,0 +1 @@
+{{ if .Params.math }}{{ partial "katex.html" . }}{{ end }}
diff --git a/layouts/partials/katex.html b/layouts/partials/katex.html
new file mode 100644
index 0000000..ad660a5
--- /dev/null
+++ b/layouts/partials/katex.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/static/katex/README.md b/static/katex/README.md
new file mode 100644
index 0000000..ce6a7b3
--- /dev/null
+++ b/static/katex/README.md
@@ -0,0 +1,119 @@
+# [](https://katex.org/)
+[![npm](https://img.shields.io/npm/v/katex.svg)](https://www.npmjs.com/package/katex)
+[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
+[![CI](https://github.com/KaTeX/KaTeX/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/KaTeX/KaTeX/actions?query=workflow%3ACI)
+[![codecov](https://codecov.io/gh/KaTeX/KaTeX/branch/main/graph/badge.svg)](https://codecov.io/gh/KaTeX/KaTeX)
+[![Discussions](https://img.shields.io/badge/Discussions-join-brightgreen)](https://github.com/KaTeX/KaTeX/discussions)
+[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/katex/badge?style=rounded)](https://www.jsdelivr.com/package/npm/katex)
+![katex.min.js size](https://img.badgesize.io/https://unpkg.com/katex/dist/katex.min.js?compression=gzip)
+[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/KaTeX/KaTeX)
+[![Financial Contributors on Open Collective](https://opencollective.com/katex/all/badge.svg?label=financial+contributors)](https://opencollective.com/katex)
+
+KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web.
+
+ * **Fast:** KaTeX renders its math synchronously and doesn't need to reflow the page. See how it compares to a competitor in [this speed test](http://www.intmath.com/cg5/katex-mathjax-comparison.php).
+ * **Print quality:** KaTeX's layout is based on Donald Knuth's TeX, the gold standard for math typesetting.
+ * **Self contained:** KaTeX has no dependencies and can easily be bundled with your website resources.
+ * **Server side rendering:** KaTeX produces the same output regardless of browser or environment, so you can pre-render expressions using Node.js and send them as plain HTML.
+
+KaTeX is compatible with all major browsers, including Chrome, Safari, Firefox, Opera, Edge, and IE 11.
+
+KaTeX supports much (but not all) of LaTeX and many LaTeX packages. See the [list of supported functions](https://katex.org/docs/supported.html).
+
+Try out KaTeX [on the demo page](https://katex.org/#demo)!
+
+## Getting started
+
+### Starter template
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+ ...
+
+```
+
+You can also [download KaTeX](https://github.com/KaTeX/KaTeX/releases) and host it yourself.
+
+For details on how to configure auto-render extension, refer to [the documentation](https://katex.org/docs/autorender.html).
+
+### API
+
+Call `katex.render` to render a TeX expression directly into a DOM element.
+For example:
+
+```js
+katex.render("c = \\pm\\sqrt{a^2 + b^2}", element, {
+ throwOnError: false
+});
+```
+
+Call `katex.renderToString` to generate an HTML string of the rendered math,
+e.g., for server-side rendering. For example:
+
+```js
+var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}", {
+ throwOnError: false
+});
+// '...'
+```
+
+Make sure to include the CSS and font files in both cases.
+If you are doing all rendering on the server, there is no need to include the
+JavaScript on the client.
+
+The examples above use the `throwOnError: false` option, which renders invalid
+inputs as the TeX source code in red (by default), with the error message as
+hover text. For other available options, see the
+[API documentation](https://katex.org/docs/api.html),
+[options documentation](https://katex.org/docs/options.html), and
+[handling errors documentation](https://katex.org/docs/error.html).
+
+## Demo and Documentation
+
+Learn more about using KaTeX [on the website](https://katex.org)!
+
+## Contributors
+
+### Code Contributors
+
+This project exists thanks to all the people who contribute code. If you'd like to help, see [our guide to contributing code](CONTRIBUTING.md).
+
+
+### Financial Contributors
+
+Become a financial contributor and help us sustain our community.
+
+#### Individuals
+
+
+
+#### Organizations
+
+Support this project with your organization. Your logo will show up here with a link to your website.
+
+
+
+
+
+
+
+
+
+
+
+
+## License
+
+KaTeX is licensed under the [MIT License](http://opensource.org/licenses/MIT).
diff --git a/static/katex/contrib/auto-render.js b/static/katex/contrib/auto-render.js
new file mode 100644
index 0000000..6980cdd
--- /dev/null
+++ b/static/katex/contrib/auto-render.js
@@ -0,0 +1,327 @@
+(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 if(typeof exports === 'object')
+ exports["renderMathInElement"] = factory(require("katex"));
+ else
+ root["renderMathInElement"] = factory(root["katex"]);
+})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__771__) {
+return /******/ (function() { // webpackBootstrap
+/******/ "use strict";
+/******/ var __webpack_modules__ = ({
+
+/***/ 771:
+/***/ (function(module) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
+
+/***/ })
+
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ // no module.id needed
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/compat get default export */
+/******/ !function() {
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function() { return module['default']; } :
+/******/ function() { return module; };
+/******/ __webpack_require__.d(getter, { a: getter });
+/******/ return getter;
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/define property getters */
+/******/ !function() {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = function(exports, definition) {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ !function() {
+/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
+/******/ }();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+!function() {
+
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, {
+ "default": function() { return /* binding */ auto_render; }
+});
+
+// EXTERNAL MODULE: external "katex"
+var external_katex_ = __webpack_require__(771);
+var external_katex_default = /*#__PURE__*/__webpack_require__.n(external_katex_);
+;// CONCATENATED MODULE: ./contrib/auto-render/splitAtDelimiters.js
+/* eslint no-constant-condition:0 */
+var findEndOfMath = function findEndOfMath(delimiter, text, startIndex) {
+ // Adapted from
+ // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
+ var index = startIndex;
+ var braceLevel = 0;
+ var delimLength = delimiter.length;
+
+ while (index < text.length) {
+ var character = text[index];
+
+ if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
+ return index;
+ } else if (character === "\\") {
+ index++;
+ } else if (character === "{") {
+ braceLevel++;
+ } else if (character === "}") {
+ braceLevel--;
+ }
+
+ index++;
+ }
+
+ return -1;
+};
+
+var escapeRegex = function escapeRegex(string) {
+ return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
+};
+
+var amsRegex = /^\\begin{/;
+
+var splitAtDelimiters = function splitAtDelimiters(text, delimiters) {
+ var index;
+ var data = [];
+ var regexLeft = new RegExp("(" + delimiters.map(function (x) {
+ return escapeRegex(x.left);
+ }).join("|") + ")");
+
+ while (true) {
+ index = text.search(regexLeft);
+
+ if (index === -1) {
+ break;
+ }
+
+ if (index > 0) {
+ data.push({
+ type: "text",
+ data: text.slice(0, index)
+ });
+ text = text.slice(index); // now text starts with delimiter
+ } // ... so this always succeeds:
+
+
+ var i = delimiters.findIndex(function (delim) {
+ return text.startsWith(delim.left);
+ });
+ index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
+
+ if (index === -1) {
+ break;
+ }
+
+ var rawData = text.slice(0, index + delimiters[i].right.length);
+ var math = amsRegex.test(rawData) ? rawData : text.slice(delimiters[i].left.length, index);
+ data.push({
+ type: "math",
+ data: math,
+ rawData: rawData,
+ display: delimiters[i].display
+ });
+ text = text.slice(index + delimiters[i].right.length);
+ }
+
+ if (text !== "") {
+ data.push({
+ type: "text",
+ data: text
+ });
+ }
+
+ return data;
+};
+
+/* harmony default export */ var auto_render_splitAtDelimiters = (splitAtDelimiters);
+;// CONCATENATED MODULE: ./contrib/auto-render/auto-render.js
+/* eslint no-console:0 */
+
+
+/* Note: optionsCopy is mutated by this method. If it is ever exposed in the
+ * API, we should copy it before mutating.
+ */
+
+var renderMathInText = function renderMathInText(text, optionsCopy) {
+ var data = auto_render_splitAtDelimiters(text, optionsCopy.delimiters);
+
+ if (data.length === 1 && data[0].type === 'text') {
+ // There is no formula in the text.
+ // Let's return null which means there is no need to replace
+ // the current text node with a new one.
+ return null;
+ }
+
+ var fragment = document.createDocumentFragment();
+
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].type === "text") {
+ fragment.appendChild(document.createTextNode(data[i].data));
+ } else {
+ var span = document.createElement("span");
+ var math = data[i].data; // Override any display mode defined in the settings with that
+ // defined by the text itself
+
+ optionsCopy.displayMode = data[i].display;
+
+ try {
+ if (optionsCopy.preProcess) {
+ math = optionsCopy.preProcess(math);
+ }
+
+ external_katex_default().render(math, span, optionsCopy);
+ } catch (e) {
+ if (!(e instanceof (external_katex_default()).ParseError)) {
+ throw e;
+ }
+
+ optionsCopy.errorCallback("KaTeX auto-render: Failed to parse `" + data[i].data + "` with ", e);
+ fragment.appendChild(document.createTextNode(data[i].rawData));
+ continue;
+ }
+
+ fragment.appendChild(span);
+ }
+ }
+
+ return fragment;
+};
+
+var renderElem = function renderElem(elem, optionsCopy) {
+ for (var i = 0; i < elem.childNodes.length; i++) {
+ var childNode = elem.childNodes[i];
+
+ if (childNode.nodeType === 3) {
+ // Text node
+ var frag = renderMathInText(childNode.textContent, optionsCopy);
+
+ if (frag) {
+ i += frag.childNodes.length - 1;
+ elem.replaceChild(frag, childNode);
+ }
+ } else if (childNode.nodeType === 1) {
+ (function () {
+ // Element node
+ var className = ' ' + childNode.className + ' ';
+ var shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(function (x) {
+ return className.indexOf(' ' + x + ' ') === -1;
+ });
+
+ if (shouldRender) {
+ renderElem(childNode, optionsCopy);
+ }
+ })();
+ } // Otherwise, it's something else, and ignore it.
+
+ }
+};
+
+var renderMathInElement = function renderMathInElement(elem, options) {
+ if (!elem) {
+ throw new Error("No element provided to render");
+ }
+
+ var optionsCopy = {}; // Object.assign(optionsCopy, option)
+
+ for (var option in options) {
+ if (options.hasOwnProperty(option)) {
+ optionsCopy[option] = options[option];
+ }
+ } // default options
+
+
+ optionsCopy.delimiters = optionsCopy.delimiters || [{
+ left: "$$",
+ right: "$$",
+ display: true
+ }, {
+ left: "\\(",
+ right: "\\)",
+ display: false
+ }, // LaTeX uses $…$, but it ruins the display of normal `$` in text:
+ // {left: "$", right: "$", display: false},
+ // $ must come after $$
+ // Render AMS environments even if outside $$…$$ delimiters.
+ {
+ left: "\\begin{equation}",
+ right: "\\end{equation}",
+ display: true
+ }, {
+ left: "\\begin{align}",
+ right: "\\end{align}",
+ display: true
+ }, {
+ left: "\\begin{alignat}",
+ right: "\\end{alignat}",
+ display: true
+ }, {
+ left: "\\begin{gather}",
+ right: "\\end{gather}",
+ display: true
+ }, {
+ left: "\\begin{CD}",
+ right: "\\end{CD}",
+ display: true
+ }, {
+ left: "\\[",
+ right: "\\]",
+ display: true
+ }];
+ optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option"];
+ optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
+ optionsCopy.errorCallback = optionsCopy.errorCallback || console.error; // Enable sharing of global macros defined via `\gdef` between different
+ // math elements within a single call to `renderMathInElement`.
+
+ optionsCopy.macros = optionsCopy.macros || {};
+ renderElem(elem, optionsCopy);
+};
+
+/* harmony default export */ var auto_render = (renderMathInElement);
+}();
+__webpack_exports__ = __webpack_exports__["default"];
+/******/ return __webpack_exports__;
+/******/ })()
+;
+});
\ No newline at end of file
diff --git a/static/katex/contrib/auto-render.min.js b/static/katex/contrib/auto-render.min.js
new file mode 100644
index 0000000..c169ec6
--- /dev/null
+++ b/static/katex/contrib/auto-render.min.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var a={};return function(){n.d(a,{default:function(){return s}});var e=n(771),t=n.n(e),r=function(e,t,r){for(var n=r,a=0,i=e.length;n0&&(a.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var l=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[l].right,e,t[l].left.length)))break;var d=e.slice(0,n+t[l].right.length),s=i.test(d)?d:e.slice(t[l].left.length,n);a.push({type:"math",data:s,rawData:d,display:t[l].display}),e=e.slice(n+t[l].right.length)}return""!==e&&a.push({type:"text",data:e}),a},l=function(e,r){var n=o(e,r.delimiters);if(1===n.length&&"text"===n[0].type)return null;for(var a=document.createDocumentFragment(),i=0;i escapeRegex(x.left)).join("|") + ")");
+
+ while (true) {
+ index = text.search(regexLeft);
+
+ if (index === -1) {
+ break;
+ }
+
+ if (index > 0) {
+ data.push({
+ type: "text",
+ data: text.slice(0, index)
+ });
+ text = text.slice(index); // now text starts with delimiter
+ } // ... so this always succeeds:
+
+
+ var i = delimiters.findIndex(delim => text.startsWith(delim.left));
+ index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
+
+ if (index === -1) {
+ break;
+ }
+
+ var rawData = text.slice(0, index + delimiters[i].right.length);
+ var math = amsRegex.test(rawData) ? rawData : text.slice(delimiters[i].left.length, index);
+ data.push({
+ type: "math",
+ data: math,
+ rawData,
+ display: delimiters[i].display
+ });
+ text = text.slice(index + delimiters[i].right.length);
+ }
+
+ if (text !== "") {
+ data.push({
+ type: "text",
+ data: text
+ });
+ }
+
+ return data;
+};
+
+/* eslint no-console:0 */
+/* Note: optionsCopy is mutated by this method. If it is ever exposed in the
+ * API, we should copy it before mutating.
+ */
+
+var renderMathInText = function renderMathInText(text, optionsCopy) {
+ var data = splitAtDelimiters(text, optionsCopy.delimiters);
+
+ if (data.length === 1 && data[0].type === 'text') {
+ // There is no formula in the text.
+ // Let's return null which means there is no need to replace
+ // the current text node with a new one.
+ return null;
+ }
+
+ var fragment = document.createDocumentFragment();
+
+ for (var i = 0; i < data.length; i++) {
+ if (data[i].type === "text") {
+ fragment.appendChild(document.createTextNode(data[i].data));
+ } else {
+ var span = document.createElement("span");
+ var math = data[i].data; // Override any display mode defined in the settings with that
+ // defined by the text itself
+
+ optionsCopy.displayMode = data[i].display;
+
+ try {
+ if (optionsCopy.preProcess) {
+ math = optionsCopy.preProcess(math);
+ }
+
+ katex.render(math, span, optionsCopy);
+ } catch (e) {
+ if (!(e instanceof katex.ParseError)) {
+ throw e;
+ }
+
+ optionsCopy.errorCallback("KaTeX auto-render: Failed to parse `" + data[i].data + "` with ", e);
+ fragment.appendChild(document.createTextNode(data[i].rawData));
+ continue;
+ }
+
+ fragment.appendChild(span);
+ }
+ }
+
+ return fragment;
+};
+
+var renderElem = function renderElem(elem, optionsCopy) {
+ for (var i = 0; i < elem.childNodes.length; i++) {
+ var childNode = elem.childNodes[i];
+
+ if (childNode.nodeType === 3) {
+ // Text node
+ var frag = renderMathInText(childNode.textContent, optionsCopy);
+
+ if (frag) {
+ i += frag.childNodes.length - 1;
+ elem.replaceChild(frag, childNode);
+ }
+ } else if (childNode.nodeType === 1) {
+ (function () {
+ // Element node
+ var className = ' ' + childNode.className + ' ';
+ var shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(x => className.indexOf(' ' + x + ' ') === -1);
+
+ if (shouldRender) {
+ renderElem(childNode, optionsCopy);
+ }
+ })();
+ } // Otherwise, it's something else, and ignore it.
+
+ }
+};
+
+var renderMathInElement = function renderMathInElement(elem, options) {
+ if (!elem) {
+ throw new Error("No element provided to render");
+ }
+
+ var optionsCopy = {}; // Object.assign(optionsCopy, option)
+
+ for (var option in options) {
+ if (options.hasOwnProperty(option)) {
+ optionsCopy[option] = options[option];
+ }
+ } // default options
+
+
+ optionsCopy.delimiters = optionsCopy.delimiters || [{
+ left: "$$",
+ right: "$$",
+ display: true
+ }, {
+ left: "\\(",
+ right: "\\)",
+ display: false
+ }, // LaTeX uses $…$, but it ruins the display of normal `$` in text:
+ // {left: "$", right: "$", display: false},
+ // $ must come after $$
+ // Render AMS environments even if outside $$…$$ delimiters.
+ {
+ left: "\\begin{equation}",
+ right: "\\end{equation}",
+ display: true
+ }, {
+ left: "\\begin{align}",
+ right: "\\end{align}",
+ display: true
+ }, {
+ left: "\\begin{alignat}",
+ right: "\\end{alignat}",
+ display: true
+ }, {
+ left: "\\begin{gather}",
+ right: "\\end{gather}",
+ display: true
+ }, {
+ left: "\\begin{CD}",
+ right: "\\end{CD}",
+ display: true
+ }, {
+ left: "\\[",
+ right: "\\]",
+ display: true
+ }];
+ optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option"];
+ optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
+ optionsCopy.errorCallback = optionsCopy.errorCallback || console.error; // Enable sharing of global macros defined via `\gdef` between different
+ // math elements within a single call to `renderMathInElement`.
+
+ optionsCopy.macros = optionsCopy.macros || {};
+ renderElem(elem, optionsCopy);
+};
+
+export { renderMathInElement as default };
diff --git a/static/katex/contrib/copy-tex.css b/static/katex/contrib/copy-tex.css
new file mode 100644
index 0000000..f925578
--- /dev/null
+++ b/static/katex/contrib/copy-tex.css
@@ -0,0 +1,14 @@
+/* Force selection of entire .katex/.katex-display blocks, so that we can
+ * copy/paste the entire source code. If you omit this CSS, partial
+ * selections of a formula will work, but will copy the ugly HTML
+ * representation instead of the LaTeX source code. (Full selections will
+ * still produce the LaTeX source code.)
+ */
+.katex,
+.katex-display {
+ -webkit-user-select: all;
+ -moz-user-select: all;
+ -ms-user-select: all;
+ user-select: all;
+}
+
diff --git a/static/katex/contrib/copy-tex.js b/static/katex/contrib/copy-tex.js
new file mode 100644
index 0000000..bf54df2
--- /dev/null
+++ b/static/katex/contrib/copy-tex.js
@@ -0,0 +1,116 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define([], factory);
+ else {
+ var a = factory();
+ for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
+ }
+})((typeof self !== 'undefined' ? self : this), function() {
+return /******/ (function() { // webpackBootstrap
+/******/ "use strict";
+var __webpack_exports__ = {};
+
+;// CONCATENATED MODULE: ./contrib/copy-tex/katex2tex.js
+// Set these to how you want inline and display math to be delimited.
+var defaultCopyDelimiters = {
+ inline: ['$', '$'],
+ // alternative: ['\(', '\)']
+ display: ['$$', '$$'] // alternative: ['\[', '\]']
+
+}; // Replace .katex elements with their TeX source ( element).
+// Modifies fragment in-place. Useful for writing your own 'copy' handler,
+// as in copy-tex.js.
+
+var katexReplaceWithTex = function katexReplaceWithTex(fragment, copyDelimiters) {
+ if (copyDelimiters === void 0) {
+ copyDelimiters = defaultCopyDelimiters;
+ }
+
+ // Remove .katex-html blocks that are preceded by .katex-mathml blocks
+ // (which will get replaced below).
+ var katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html');
+
+ for (var i = 0; i < katexHtml.length; i++) {
+ var element = katexHtml[i];
+
+ if (element.remove) {
+ element.remove(null);
+ } else {
+ element.parentNode.removeChild(element);
+ }
+ } // Replace .katex-mathml elements with their annotation (TeX source)
+ // descendant, with inline delimiters.
+
+
+ var katexMathml = fragment.querySelectorAll('.katex-mathml');
+
+ for (var _i = 0; _i < katexMathml.length; _i++) {
+ var _element = katexMathml[_i];
+
+ var texSource = _element.querySelector('annotation');
+
+ if (texSource) {
+ if (_element.replaceWith) {
+ _element.replaceWith(texSource);
+ } else {
+ _element.parentNode.replaceChild(texSource, _element);
+ }
+
+ texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1];
+ }
+ } // Switch display math to display delimiters.
+
+
+ var displays = fragment.querySelectorAll('.katex-display annotation');
+
+ for (var _i2 = 0; _i2 < displays.length; _i2++) {
+ var _element2 = displays[_i2];
+ _element2.innerHTML = copyDelimiters.display[0] + _element2.innerHTML.substr(copyDelimiters.inline[0].length, _element2.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length) + copyDelimiters.display[1];
+ }
+
+ return fragment;
+};
+/* harmony default export */ var katex2tex = (katexReplaceWithTex);
+;// CONCATENATED MODULE: ./contrib/copy-tex/copy-tex.js
+ // Global copy handler to modify behavior on .katex elements.
+
+document.addEventListener('copy', function (event) {
+ var selection = window.getSelection();
+
+ if (selection.isCollapsed) {
+ return; // default action OK if selection is empty
+ }
+
+ var fragment = selection.getRangeAt(0).cloneContents();
+
+ if (!fragment.querySelector('.katex-mathml')) {
+ return; // default action OK if no .katex-mathml elements
+ } // Preserve usual HTML copy/paste behavior.
+
+
+ var html = [];
+
+ for (var i = 0; i < fragment.childNodes.length; i++) {
+ html.push(fragment.childNodes[i].outerHTML);
+ }
+
+ event.clipboardData.setData('text/html', html.join('')); // Rewrite plain-text version.
+
+ event.clipboardData.setData('text/plain', katex2tex(fragment).textContent); // Prevent normal copy handling.
+
+ event.preventDefault();
+});
+;// CONCATENATED MODULE: ./contrib/copy-tex/copy-tex.webpack.js
+/**
+ * This is the webpack entry point for KaTeX. As ECMAScript doesn't support
+ * CSS modules natively, a separate entry point is used.
+ */
+
+
+__webpack_exports__ = __webpack_exports__["default"];
+/******/ return __webpack_exports__;
+/******/ })()
+;
+});
\ No newline at end of file
diff --git a/static/katex/contrib/copy-tex.min.css b/static/katex/contrib/copy-tex.min.css
new file mode 100644
index 0000000..6f97f56
--- /dev/null
+++ b/static/katex/contrib/copy-tex.min.css
@@ -0,0 +1 @@
+.katex,.katex-display{-webkit-user-select:all;-moz-user-select:all;-ms-user-select:all;user-select:all}
diff --git a/static/katex/contrib/copy-tex.min.js b/static/katex/contrib/copy-tex.min.js
new file mode 100644
index 0000000..9e9d26e
--- /dev/null
+++ b/static/katex/contrib/copy-tex.min.js
@@ -0,0 +1 @@
+!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var l in n)("object"==typeof exports?exports:e)[l]=n[l]}}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={},t={inline:["$","$"],display:["$$","$$"]},n=function(e,n){void 0===n&&(n=t);for(var l=e.querySelectorAll(".katex-mathml + .katex-html"),r=0;r element).
+// Modifies fragment in-place. Useful for writing your own 'copy' handler,
+// as in copy-tex.js.
+
+var katexReplaceWithTex = function katexReplaceWithTex(fragment, copyDelimiters) {
+ if (copyDelimiters === void 0) {
+ copyDelimiters = defaultCopyDelimiters;
+ }
+
+ // Remove .katex-html blocks that are preceded by .katex-mathml blocks
+ // (which will get replaced below).
+ var katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html');
+
+ for (var i = 0; i < katexHtml.length; i++) {
+ var element = katexHtml[i];
+
+ if (element.remove) {
+ element.remove(null);
+ } else {
+ element.parentNode.removeChild(element);
+ }
+ } // Replace .katex-mathml elements with their annotation (TeX source)
+ // descendant, with inline delimiters.
+
+
+ var katexMathml = fragment.querySelectorAll('.katex-mathml');
+
+ for (var _i = 0; _i < katexMathml.length; _i++) {
+ var _element = katexMathml[_i];
+
+ var texSource = _element.querySelector('annotation');
+
+ if (texSource) {
+ if (_element.replaceWith) {
+ _element.replaceWith(texSource);
+ } else {
+ _element.parentNode.replaceChild(texSource, _element);
+ }
+
+ texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1];
+ }
+ } // Switch display math to display delimiters.
+
+
+ var displays = fragment.querySelectorAll('.katex-display annotation');
+
+ for (var _i2 = 0; _i2 < displays.length; _i2++) {
+ var _element2 = displays[_i2];
+ _element2.innerHTML = copyDelimiters.display[0] + _element2.innerHTML.substr(copyDelimiters.inline[0].length, _element2.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length) + copyDelimiters.display[1];
+ }
+
+ return fragment;
+};
+
+document.addEventListener('copy', function (event) {
+ var selection = window.getSelection();
+
+ if (selection.isCollapsed) {
+ return; // default action OK if selection is empty
+ }
+
+ var fragment = selection.getRangeAt(0).cloneContents();
+
+ if (!fragment.querySelector('.katex-mathml')) {
+ return; // default action OK if no .katex-mathml elements
+ } // Preserve usual HTML copy/paste behavior.
+
+
+ var html = [];
+
+ for (var i = 0; i < fragment.childNodes.length; i++) {
+ html.push(fragment.childNodes[i].outerHTML);
+ }
+
+ event.clipboardData.setData('text/html', html.join('')); // Rewrite plain-text version.
+
+ event.clipboardData.setData('text/plain', katexReplaceWithTex(fragment).textContent); // Prevent normal copy handling.
+
+ event.preventDefault();
+});
diff --git a/static/katex/contrib/mathtex-script-type.js b/static/katex/contrib/mathtex-script-type.js
new file mode 100644
index 0000000..d82c41d
--- /dev/null
+++ b/static/katex/contrib/mathtex-script-type.js
@@ -0,0 +1,112 @@
+(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__771__) {
+return /******/ (function() { // webpackBootstrap
+/******/ "use strict";
+/******/ var __webpack_modules__ = ({
+
+/***/ 771:
+/***/ (function(module) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
+
+/***/ })
+
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ // no module.id needed
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/compat get default export */
+/******/ !function() {
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function() { return module['default']; } :
+/******/ function() { return module; };
+/******/ __webpack_require__.d(getter, { a: getter });
+/******/ return getter;
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/define property getters */
+/******/ !function() {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = function(exports, definition) {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ !function() {
+/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
+/******/ }();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+!function() {
+/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(771);
+/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__);
+
+var scripts = document.body.getElementsByTagName("script");
+scripts = Array.prototype.slice.call(scripts);
+scripts.forEach(function (script) {
+ if (!script.type || !script.type.match(/math\/tex/i)) {
+ return -1;
+ }
+
+ var display = script.type.match(/mode\s*=\s*display(;|\s|\n|$)/) != null;
+ var katexElement = document.createElement(display ? "div" : "span");
+ katexElement.setAttribute("class", display ? "equation" : "inline-equation");
+
+ try {
+ katex__WEBPACK_IMPORTED_MODULE_0___default().render(script.text, katexElement, {
+ displayMode: display
+ });
+ } catch (err) {
+ //console.error(err); linter doesn't like this
+ katexElement.textContent = script.text;
+ }
+
+ script.parentNode.replaceChild(katexElement, script);
+});
+}();
+__webpack_exports__ = __webpack_exports__["default"];
+/******/ return __webpack_exports__;
+/******/ })()
+;
+});
\ No newline at end of file
diff --git a/static/katex/contrib/mathtex-script-type.min.js b/static/katex/contrib/mathtex-script-type.min.js
new file mode 100644
index 0000000..af02830
--- /dev/null
+++ b/static/katex/contrib/mathtex-script-type.min.js
@@ -0,0 +1 @@
+!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("katex"));else if("function"==typeof define&&define.amd)define(["katex"],t);else{var r="object"==typeof exports?t(require("katex")):t(e.katex);for(var n in r)("object"==typeof exports?exports:e)[n]=r[n]}}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var o=r[e];if(void 0!==o)return o.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o,i,a,u={};return o=n(771),i=n.n(o),a=document.body.getElementsByTagName("script"),(a=Array.prototype.slice.call(a)).forEach((function(e){if(!e.type||!e.type.match(/math\/tex/i))return-1;var t=null!=e.type.match(/mode\s*=\s*display(;|\s|\n|$)/),r=document.createElement(t?"div":"span");r.setAttribute("class",t?"equation":"inline-equation");try{i().render(e.text,r,{displayMode:t})}catch(t){r.textContent=e.text}e.parentNode.replaceChild(r,e)})),u=u.default}()}));
\ No newline at end of file
diff --git a/static/katex/contrib/mathtex-script-type.mjs b/static/katex/contrib/mathtex-script-type.mjs
new file mode 100644
index 0000000..1083b92
--- /dev/null
+++ b/static/katex/contrib/mathtex-script-type.mjs
@@ -0,0 +1,24 @@
+import katex from '../katex.mjs';
+
+var scripts = document.body.getElementsByTagName("script");
+scripts = Array.prototype.slice.call(scripts);
+scripts.forEach(function (script) {
+ if (!script.type || !script.type.match(/math\/tex/i)) {
+ return -1;
+ }
+
+ var display = script.type.match(/mode\s*=\s*display(;|\s|\n|$)/) != null;
+ var katexElement = document.createElement(display ? "div" : "span");
+ katexElement.setAttribute("class", display ? "equation" : "inline-equation");
+
+ try {
+ katex.render(script.text, katexElement, {
+ displayMode: display
+ });
+ } catch (err) {
+ //console.error(err); linter doesn't like this
+ katexElement.textContent = script.text;
+ }
+
+ script.parentNode.replaceChild(katexElement, script);
+});
diff --git a/static/katex/contrib/mhchem.js b/static/katex/contrib/mhchem.js
new file mode 100644
index 0000000..c557b4e
--- /dev/null
+++ b/static/katex/contrib/mhchem.js
@@ -0,0 +1,3216 @@
+(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__771__) {
+return /******/ (function() { // webpackBootstrap
+/******/ "use strict";
+/******/ var __webpack_modules__ = ({
+
+/***/ 771:
+/***/ (function(module) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
+
+/***/ })
+
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ // no module.id needed
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/compat get default export */
+/******/ !function() {
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function() { return module['default']; } :
+/******/ function() { return module; };
+/******/ __webpack_require__.d(getter, { a: getter });
+/******/ return getter;
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/define property getters */
+/******/ !function() {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = function(exports, definition) {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ !function() {
+/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
+/******/ }();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+!function() {
+/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(771);
+/* 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().__defineMacro("\\ce", function (context) {
+ return chemParse(context.consumeArgs(1)[0], "ce");
+});
+
+katex__WEBPACK_IMPORTED_MODULE_0___default().__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().__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) {}
+}();
+__webpack_exports__ = __webpack_exports__["default"];
+/******/ return __webpack_exports__;
+/******/ })()
+;
+});
\ No newline at end of file
diff --git a/static/katex/contrib/mhchem.min.js b/static/katex/contrib/mhchem.min.js
new file mode 100644
index 0000000..e0c4a5e
--- /dev/null
+++ b/static/katex/contrib/mhchem.min.js
@@ -0,0 +1 @@
+!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("katex"));else if("function"==typeof define&&define.amd)define(["katex"],e);else{var n="object"==typeof exports?e(require("katex")):e(t.katex);for(var o in n)("object"==typeof exports?exports:t)[o]=n[o]}}("undefined"!=typeof self?self:this,(function(t){return function(){"use strict";var e={771:function(e){e.exports=t}},n={};function o(t){var a=n[t];if(void 0!==a)return a.exports;var r=n[t]={exports:{}};return e[t](r,r.exports,o),r.exports}o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,{a:e}),e},o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};var a={};return function(){var t=o(771),e=o.n(t);e().__defineMacro("\\ce",(function(t){return n(t.consumeArgs(1)[0],"ce")})),e().__defineMacro("\\pu",(function(t){return n(t.consumeArgs(1)[0],"pu")})),e().__defineMacro("\\tripledash","{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}");var n=function(t,e){for(var n="",o=t[t.length-1].loc.start,i=t.length-1;i>=0;i--)t[i].loc.start>o&&(n+=" ",o=t[i].loc.start),n+=t[i].text,o+=t[i].text.length;return r.go(a.go(n,e))},a={go:function(t,e){if(!t)return[];void 0===e&&(e="ce");var n,o="0",r={};r.parenthesisLevel=0,t=(t=(t=t.replace(/\n/g," ")).replace(/[\u2212\u2013\u2014\u2010]/g,"-")).replace(/[\u2026]/g,"...");for(var i=10,c=[];;){n!==t?(i=10,n=t):i--;var u=a.stateMachines[e],p=u.transitions[o]||u.transitions["*"];t:for(var s=0;s0))return c;if(d.revisit||(t=_.remainder),!d.toContinue)break t}}if(i<=0)throw["MhchemBugU","mhchem bug U. Please report."]}},concatArray:function(t,e){if(e)if(Array.isArray(e))for(var n=0;n":/^[=<>]/,"#":/^[#\u2261]/,"+":/^\+/,"-$":/^-(?=[\s_},;\]/]|$|\([a-z]+\))/,"-9":/^-(?=[0-9])/,"- orbital overlap":/^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/,"-":/^-/,"pm-operator":/^(?:\\pm|\$\\pm\$|\+-|\+\/-)/,operator:/^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/,arrowUpDown:/^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/,"\\bond{(...)}":function(t){return a.patterns.findObserveGroups(t,"\\bond{","","","}")},"->":/^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/,CMT:/^[CMT](?=\[)/,"[(...)]":function(t){return a.patterns.findObserveGroups(t,"[","","","]")},"1st-level escape":/^(&|\\\\|\\hline)\s*/,"\\,":/^(?:\\[,\ ;:])/,"\\x{}{}":function(t){return a.patterns.findObserveGroups(t,"",/^\\[a-zA-Z]+\{/,"}","","","{","}","",!0)},"\\x{}":function(t){return a.patterns.findObserveGroups(t,"",/^\\[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])/,others:/^[\/~|]/,"\\frac{(...)}":function(t){return a.patterns.findObserveGroups(t,"\\frac{","","","}","{","","","}")},"\\overset{(...)}":function(t){return a.patterns.findObserveGroups(t,"\\overset{","","","}","{","","","}")},"\\underset{(...)}":function(t){return a.patterns.findObserveGroups(t,"\\underset{","","","}","{","","","}")},"\\underbrace{(...)}":function(t){return a.patterns.findObserveGroups(t,"\\underbrace{","","","}_","{","","","}")},"\\color{(...)}0":function(t){return a.patterns.findObserveGroups(t,"\\color{","","","}")},"\\color{(...)}{(...)}1":function(t){return a.patterns.findObserveGroups(t,"\\color{","","","}","{","","","}")},"\\color(...){(...)}2":function(t){return a.patterns.findObserveGroups(t,"\\color","\\","",/^(?=\{)/,"{","","","}")},"\\ce{(...)}":function(t){return a.patterns.findObserveGroups(t,"\\ce{","","","}")},oxidation$:/^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,"d-oxidation$":/^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,"roman numeral":/^[IVX]+/,"1/2$":/^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/,amount:function(t){var e;if(e=t.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))/))return{match_:e[0],remainder:t.substr(e[0].length)};var n=a.patterns.findObserveGroups(t,"","$","$","");return n&&(e=n.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/))?{match_:e[0],remainder:t.substr(e[0].length)}:null},amount2:function(t){return this.amount(t)},"(KV letters),":/^(?:[A-Z][a-z]{0,2}|i)(?=,)/,formula$:function(t){if(t.match(/^\([a-z]+\)$/))return null;var e=t.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/);return e?{match_:e[0],remainder:t.substr(e[0].length)}:null},uprightEntities:/^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/,"/":/^\s*(\/)\s*/,"//":/^\s*(\/\/)\s*/,"*":/^\s*[*.]\s*/},findObserveGroups:function(t,e,n,o,a,r,i,c,u,p){var s=function(t,e){if("string"==typeof e)return 0!==t.indexOf(e)?null:e;var n=t.match(e);return n?n[0]:null},_=s(t,e);if(null===_)return null;if(t=t.substr(_.length),null===(_=s(t,n)))return null;var d=function(t,e,n){for(var o=0;e":{"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:!1},nextState:"2"},q:{action_:{type_:"- after o/d",option:!1},nextState:"2"},"d|qd|dq":{action_:{type_:"- after o/d",option:!0},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"}},"^_":{"*":{}},"^{(...)}|^($...$)":{"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="},"0|1|2|3|as|b|p|bp|o":{action_:"o=",nextState:"o"},"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:!0},as:{action_:["output","sb=true"],nextState:"1",revisit:!0},"r|rt|rd|rdt|rdq":{action_:["output"],nextState:"0",revisit:!0},"*":{action_:["output","copy"],nextState:"3"}}}),actions:{"o after d":function(t,e){var n;if((t.d||"").match(/^[0-9]+$/)){var o=t.d;t.d=void 0,n=this.output(t),t.b=o}else n=this.output(t);return a.actions["o="](t,e),n},"d= kv":function(t,e){t.d=e,t.dType="kv"},"charge or bond":function(t,e){if(t.beginsWithBond){var n=[];return a.concatArray(n,this.output(t)),a.concatArray(n,a.actions.bond(t,e,"-")),n}t.d=e},"- after o/d":function(t,e,n){var o=a.patterns.match_("orbital",t.o||""),r=a.patterns.match_("one lowercase greek letter $",t.o||""),i=a.patterns.match_("one lowercase latin letter $",t.o||""),c=a.patterns.match_("$one lowercase latin letter$ $",t.o||""),u="-"===e&&(o&&""===o.remainder||r||i||c);!u||t.a||t.b||t.p||t.d||t.q||o||!i||(t.o="$"+t.o+"$");var p=[];return u?(a.concatArray(p,this.output(t)),p.push({type_:"hyphen"})):(o=a.patterns.match_("digits",t.d||""),n&&o&&""===o.remainder?(a.concatArray(p,a.actions["d="](t,e)),a.concatArray(p,this.output(t))):(a.concatArray(p,this.output(t)),a.concatArray(p,a.actions.bond(t,e,"-")))),p},"a to o":function(t){t.o=t.a,t.a=void 0},"sb=true":function(t){t.sb=!0},"sb=false":function(t){t.sb=!1},"beginsWithBond=true":function(t){t.beginsWithBond=!0},"beginsWithBond=false":function(t){t.beginsWithBond=!1},"parenthesisLevel++":function(t){t.parenthesisLevel++},"parenthesisLevel--":function(t){t.parenthesisLevel--},"state of aggregation":function(t,e){return{type_:"state of aggregation",p1:a.go(e,"o")}},comma:function(t,e){var n=e.replace(/\s*$/,"");return n!==e&&0===t.parenthesisLevel?{type_:"comma enumeration L",p1:n}:{type_:"comma enumeration M",p1:n}},output:function(t,e,n){var o,r,i;t.r?(r="M"===t.rdt?a.go(t.rd,"tex-math"):"T"===t.rdt?[{type_:"text",p1:t.rd||""}]:a.go(t.rd),i="M"===t.rqt?a.go(t.rq,"tex-math"):"T"===t.rqt?[{type_:"text",p1:t.rq||""}]:a.go(t.rq),o={type_:"arrow",r:t.r,rd:r,rq:i}):(o=[],(t.a||t.b||t.p||t.o||t.q||t.d||n)&&(t.sb&&o.push({type_:"entitySkip"}),t.o||t.q||t.d||t.b||t.p||2===n?t.o||t.q||t.d||!t.b&&!t.p?t.o&&"kv"===t.dType&&a.patterns.match_("d-oxidation$",t.d||"")?t.dType="oxidation":t.o&&"kv"===t.dType&&!t.q&&(t.dType=void 0):(t.o=t.a,t.d=t.b,t.q=t.p,t.a=t.b=t.p=void 0):(t.o=t.a,t.a=void 0),o.push({type_:"chemfive",a:a.go(t.a,"a"),b:a.go(t.b,"bd"),p:a.go(t.p,"pq"),o:a.go(t.o,"o"),q:a.go(t.q,"pq"),d:a.go(t.d,"oxidation"===t.dType?"oxidation":"bd"),dType:t.dType})));for(var c in t)"parenthesisLevel"!==c&&"beginsWithBond"!==c&&delete t[c];return o},"oxidation-output":function(t,e){var n=["{"];return a.concatArray(n,a.go(e,"oxidation")),n.push("}"),n},"frac-output":function(t,e){return{type_:"frac-ce",p1:a.go(e[0]),p2:a.go(e[1])}},"overset-output":function(t,e){return{type_:"overset",p1:a.go(e[0]),p2:a.go(e[1])}},"underset-output":function(t,e){return{type_:"underset",p1:a.go(e[0]),p2:a.go(e[1])}},"underbrace-output":function(t,e){return{type_:"underbrace",p1:a.go(e[0]),p2:a.go(e[1])}},"color-output":function(t,e){return{type_:"color",color1:e[0],color2:a.go(e[1])}},"r=":function(t,e){t.r=e},"rdt=":function(t,e){t.rdt=e},"rd=":function(t,e){t.rd=e},"rqt=":function(t,e){t.rqt=e},"rq=":function(t,e){t.rq=e},operator:function(t,e,n){return{type_:"operator",kind_:n||e}}}},a:{transitions:a.createTransitions({empty:{"*":{}},"1/2$":{0:{action_:"1/2"}},else:{0:{nextState:"1",revisit:!0}},"$(...)$":{"*":{action_:"tex-math tight",nextState:"1"}},",":{"*":{action_:{type_:"insert",option:"commaDecimal"}}},else2:{"*":{action_:"copy"}}}),actions:{}},o:{transitions:a.createTransitions({empty:{"*":{}},"1/2$":{0:{action_:"1/2"}},else:{0:{nextState:"1",revisit:!0}},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:a.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(t){if(t.text_){var e={type_:"text",p1:t.text_};for(var n in t)delete t[n];return e}}}},pq:{transitions:a.createTransitions({empty:{"*":{}},"state of aggregation $":{"*":{action_:"state of aggregation"}},i$:{0:{nextState:"!f",revisit:!0}},"(KV letters),":{0:{action_:"rm",nextState:"0"}},formula$:{0:{nextState:"f",revisit:!0}},"1/2$":{0:{action_:"1/2"}},else:{0:{nextState:"!f",revisit:!0}},"${(...)}$|$(...)$":{"*":{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(t,e){return{type_:"state of aggregation subscript",p1:a.go(e,"o")}},"color-output":function(t,e){return{type_:"color",color1:e[0],color2:a.go(e[1],"pq")}}}},bd:{transitions:a.createTransitions({empty:{"*":{}},x$:{0:{nextState:"!f",revisit:!0}},formula$:{0:{nextState:"f",revisit:!0}},else:{0:{nextState:"!f",revisit:!0}},"-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(t,e){return{type_:"color",color1:e[0],color2:a.go(e[1],"bd")}}}},oxidation:{transitions:a.createTransitions({empty:{"*":{}},"roman numeral":{"*":{action_:"roman-numeral"}},"${(...)}$|$(...)$":{"*":{action_:"tex-math"}},else:{"*":{action_:"copy"}}}),actions:{"roman-numeral":function(t,e){return{type_:"roman numeral",p1:e||""}}}},"tex-math":{transitions:a.createTransitions({empty:{"*":{action_:"output"}},"\\ce{(...)}":{"*":{action_:["output","ce"]}},"{...}|\\,|\\x{}{}|\\x{}|\\x":{"*":{action_:"o="}},else:{"*":{action_:"o="}}}),actions:{output:function(t){if(t.o){var e={type_:"tex-math",p1:t.o};for(var n in t)delete t[n];return e}}}},"tex-math tight":{transitions:a.createTransitions({empty:{"*":{action_:"output"}},"\\ce{(...)}":{"*":{action_:["output","ce"]}},"{...}|\\,|\\x{}{}|\\x{}|\\x":{"*":{action_:"o="}},"-|+":{"*":{action_:"tight operator"}},else:{"*":{action_:"o="}}}),actions:{"tight operator":function(t,e){t.o=(t.o||"")+"{"+e+"}"},output:function(t){if(t.o){var e={type_:"tex-math",p1:t.o};for(var n in t)delete t[n];return e}}}},"9,9":{transitions:a.createTransitions({empty:{"*":{}},",":{"*":{action_:"comma"}},else:{"*":{action_:"copy"}}}),actions:{comma:function(){return{type_:"commaDecimal"}}}},pu:{transitions:a.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(t,e){var n=[];return"+-"===e[0]||"+/-"===e[0]?n.push("\\pm "):e[0]&&n.push(e[0]),e[1]&&(a.concatArray(n,a.go(e[1],"pu-9,9")),e[2]&&(e[2].match(/[,.]/)?a.concatArray(n,a.go(e[2],"pu-9,9")):n.push(e[2])),e[3]=e[4]||e[3],e[3]&&(e[3]=e[3].trim(),"e"===e[3]||"*"===e[3].substr(0,1)?n.push({type_:"cdot"}):n.push({type_:"times"}))),e[3]&&n.push("10^{"+e[5]+"}"),n},"number^":function(t,e){var n=[];return"+-"===e[0]||"+/-"===e[0]?n.push("\\pm "):e[0]&&n.push(e[0]),a.concatArray(n,a.go(e[1],"pu-9,9")),n.push("^{"+e[2]+"}"),n},operator:function(t,e,n){return{type_:"operator",kind_:n||e}},space:function(){return{type_:"pu-space-1"}},output:function(t){var e,n=a.patterns.match_("{(...)}",t.d||"");n&&""===n.remainder&&(t.d=n.match_);var o=a.patterns.match_("{(...)}",t.q||"");if(o&&""===o.remainder&&(t.q=o.match_),t.d&&(t.d=t.d.replace(/\u00B0C|\^oC|\^{o}C/g,"{}^{\\circ}C"),t.d=t.d.replace(/\u00B0F|\^oF|\^{o}F/g,"{}^{\\circ}F")),t.q){t.q=t.q.replace(/\u00B0C|\^oC|\^{o}C/g,"{}^{\\circ}C"),t.q=t.q.replace(/\u00B0F|\^oF|\^{o}F/g,"{}^{\\circ}F");var r={d:a.go(t.d,"pu"),q:a.go(t.q,"pu")};"//"===t.o?e={type_:"pu-frac",p1:r.d,p2:r.q}:(e=r.d,r.d.length>1||r.q.length>1?e.push({type_:" / "}):e.push({type_:"/"}),a.concatArray(e,r.q))}else e=a.go(t.d,"pu-2");for(var i in t)delete t[i];return e}}},"pu-2":{transitions:a.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(){return{type_:"tight cdot"}},"^(-1)":function(t,e){t.rm+="^{"+e+"}"},space:function(){return{type_:"pu-space-2"}},output:function(t){var e=[];if(t.rm){var n=a.patterns.match_("{(...)}",t.rm||"");e=n&&""===n.remainder?a.go(n.match_,"pu"):{type_:"rm",p1:t.rm}}for(var o in t)delete t[o];return e}}},"pu-9,9":{transitions:a.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(){return{type_:"commaDecimal"}},"output-0":function(t){var e=[];if(t.text_=t.text_||"",t.text_.length>4){var n=t.text_.length%3;0===n&&(n=3);for(var o=t.text_.length-3;o>0;o-=3)e.push(t.text_.substr(o,3)),e.push({type_:"1000 separator"});e.push(t.text_.substr(0,n)),e.reverse()}else e.push(t.text_);for(var a in t)delete t[a];return e},"output-o":function(t){var e=[];if(t.text_=t.text_||"",t.text_.length>4){for(var n=t.text_.length-3,o=0;o":case"\u2192":case"\u27f6":return"rightarrow";case"<-":return"leftarrow";case"<->":return"leftrightarrow";case"<--\x3e":return"rightleftarrows";case"<=>":case"\u21cc":return"rightleftharpoons";case"<=>>":return"rightequilibrium";case"<<=>":return"leftequilibrium";default:throw["MhchemBugT","mhchem bug T. Please report."]}},_getBond:function(t){switch(t){case"-":case"1":return"{-}";case"=":case"2":return"{=}";case"#":case"3":return"{\\equiv}";case"~":return"{\\tripledash}";case"~-":return"{\\mathrlap{\\raisebox{-.1em}{$-$}}\\raisebox{.1em}{$\\tripledash$}}";case"~=":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:throw["MhchemBugT","mhchem bug T. Please report."]}},_getOperator:function(t){switch(t){case"+":return" {}+{} ";case"-":return" {}-{} ";case"=":return" {}={} ";case"<":return" {}<{} ";case">":return" {}>{} ";case"<<":return" {}\\ll{} ";case">>":return" {}\\gg{} ";case"\\pm":return" {}\\pm{} ";case"\\approx":case"$\\approx$":return" {}\\approx{} ";case"v":case"(v)":return" \\downarrow{} ";case"^":case"(^)":return" \\uparrow{} ";default:throw["MhchemBugT","mhchem bug T. Please report."]}}}}(),a=a.default}()}));
\ No newline at end of file
diff --git a/static/katex/contrib/mhchem.mjs b/static/katex/contrib/mhchem.mjs
new file mode 100644
index 0000000..55511ad
--- /dev/null
+++ b/static/katex/contrib/mhchem.mjs
@@ -0,0 +1,3109 @@
+import katex from '../katex.mjs';
+
+/* 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.__defineMacro("\\ce", function (context) {
+ return chemParse(context.consumeArgs(1)[0], "ce");
+});
+
+katex.__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.__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) ; 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:
+ throw ["MhchemBugT", "mhchem bug T. Please report."];
+ // Missing texify rule or unknown MhchemParser output
+ }
+ 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:
+ 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:
+ 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:
+ throw ["MhchemBugT", "mhchem bug T. Please report."];
+ }
+ }
+}; //
diff --git a/static/katex/contrib/render-a11y-string.js b/static/katex/contrib/render-a11y-string.js
new file mode 100644
index 0000000..a96caca
--- /dev/null
+++ b/static/katex/contrib/render-a11y-string.js
@@ -0,0 +1,875 @@
+(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__771__) {
+return /******/ (function() { // webpackBootstrap
+/******/ "use strict";
+/******/ var __webpack_modules__ = ({
+
+/***/ 771:
+/***/ (function(module) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__771__;
+
+/***/ })
+
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ // no module.id needed
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/compat get default export */
+/******/ !function() {
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function() { return module['default']; } :
+/******/ function() { return module; };
+/******/ __webpack_require__.d(getter, { a: getter });
+/******/ return getter;
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/define property getters */
+/******/ !function() {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = function(exports, definition) {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ !function() {
+/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
+/******/ }();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+!function() {
+/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(771);
+/* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__);
+/**
+ * renderA11yString returns a readable string.
+ *
+ * In some cases the string will have the proper semantic math
+ * meaning,:
+ * renderA11yString("\\frac{1}{2}"")
+ * -> "start fraction, 1, divided by, 2, end fraction"
+ *
+ * However, other cases do not:
+ * renderA11yString("f(x) = x^2")
+ * -> "f, left parenthesis, x, right parenthesis, equals, x, squared"
+ *
+ * The commas in the string aim to increase ease of understanding
+ * when read by a screenreader.
+ */
+// NOTE: since we're importing types here these files won't actually be
+// included in the build.
+// $FlowIgnore: we import the types directly anyways
+
+var stringMap = {
+ "(": "left parenthesis",
+ ")": "right parenthesis",
+ "[": "open bracket",
+ "]": "close bracket",
+ "\\{": "left brace",
+ "\\}": "right brace",
+ "\\lvert": "open vertical bar",
+ "\\rvert": "close vertical bar",
+ "|": "vertical bar",
+ "\\uparrow": "up arrow",
+ "\\Uparrow": "up arrow",
+ "\\downarrow": "down arrow",
+ "\\Downarrow": "down arrow",
+ "\\updownarrow": "up down arrow",
+ "\\leftarrow": "left arrow",
+ "\\Leftarrow": "left arrow",
+ "\\rightarrow": "right arrow",
+ "\\Rightarrow": "right arrow",
+ "\\langle": "open angle",
+ "\\rangle": "close angle",
+ "\\lfloor": "open floor",
+ "\\rfloor": "close floor",
+ "\\int": "integral",
+ "\\intop": "integral",
+ "\\lim": "limit",
+ "\\ln": "natural log",
+ "\\log": "log",
+ "\\sin": "sine",
+ "\\cos": "cosine",
+ "\\tan": "tangent",
+ "\\cot": "cotangent",
+ "\\sum": "sum",
+ "/": "slash",
+ ",": "comma",
+ ".": "point",
+ "-": "negative",
+ "+": "plus",
+ "~": "tilde",
+ ":": "colon",
+ "?": "question mark",
+ "'": "apostrophe",
+ "\\%": "percent",
+ " ": "space",
+ "\\ ": "space",
+ "\\$": "dollar sign",
+ "\\angle": "angle",
+ "\\degree": "degree",
+ "\\circ": "circle",
+ "\\vec": "vector",
+ "\\triangle": "triangle",
+ "\\pi": "pi",
+ "\\prime": "prime",
+ "\\infty": "infinity",
+ "\\alpha": "alpha",
+ "\\beta": "beta",
+ "\\gamma": "gamma",
+ "\\omega": "omega",
+ "\\theta": "theta",
+ "\\sigma": "sigma",
+ "\\lambda": "lambda",
+ "\\tau": "tau",
+ "\\Delta": "delta",
+ "\\delta": "delta",
+ "\\mu": "mu",
+ "\\rho": "rho",
+ "\\nabla": "del",
+ "\\ell": "ell",
+ "\\ldots": "dots",
+ // TODO: add entries for all accents
+ "\\hat": "hat",
+ "\\acute": "acute"
+};
+var powerMap = {
+ "prime": "prime",
+ "degree": "degrees",
+ "circle": "degrees",
+ "2": "squared",
+ "3": "cubed"
+};
+var openMap = {
+ "|": "open vertical bar",
+ ".": ""
+};
+var closeMap = {
+ "|": "close vertical bar",
+ ".": ""
+};
+var binMap = {
+ "+": "plus",
+ "-": "minus",
+ "\\pm": "plus minus",
+ "\\cdot": "dot",
+ "*": "times",
+ "/": "divided by",
+ "\\times": "times",
+ "\\div": "divided by",
+ "\\circ": "circle",
+ "\\bullet": "bullet"
+};
+var relMap = {
+ "=": "equals",
+ "\\approx": "approximately equals",
+ "≠": "does not equal",
+ "\\geq": "is greater than or equal to",
+ "\\ge": "is greater than or equal to",
+ "\\leq": "is less than or equal to",
+ "\\le": "is less than or equal to",
+ ">": "is greater than",
+ "<": "is less than",
+ "\\leftarrow": "left arrow",
+ "\\Leftarrow": "left arrow",
+ "\\rightarrow": "right arrow",
+ "\\Rightarrow": "right arrow",
+ ":": "colon"
+};
+var accentUnderMap = {
+ "\\underleftarrow": "left arrow",
+ "\\underrightarrow": "right arrow",
+ "\\underleftrightarrow": "left-right arrow",
+ "\\undergroup": "group",
+ "\\underlinesegment": "line segment",
+ "\\utilde": "tilde"
+};
+
+var buildString = function buildString(str, type, a11yStrings) {
+ if (!str) {
+ return;
+ }
+
+ var ret;
+
+ if (type === "open") {
+ ret = str in openMap ? openMap[str] : stringMap[str] || str;
+ } else if (type === "close") {
+ ret = str in closeMap ? closeMap[str] : stringMap[str] || str;
+ } else if (type === "bin") {
+ ret = binMap[str] || str;
+ } else if (type === "rel") {
+ ret = relMap[str] || str;
+ } else {
+ ret = stringMap[str] || str;
+ } // If the text to add is a number and there is already a string
+ // in the list and the last string is a number then we should
+ // combine them into a single number
+
+
+ if (/^\d+$/.test(ret) && a11yStrings.length > 0 && // TODO(kevinb): check that the last item in a11yStrings is a string
+ // I think we might be able to drop the nested arrays, which would make
+ // this easier to type
+ // $FlowFixMe
+ /^\d+$/.test(a11yStrings[a11yStrings.length - 1])) {
+ a11yStrings[a11yStrings.length - 1] += ret;
+ } else if (ret) {
+ a11yStrings.push(ret);
+ }
+};
+
+var buildRegion = function buildRegion(a11yStrings, callback) {
+ var regionStrings = [];
+ a11yStrings.push(regionStrings);
+ callback(regionStrings);
+};
+
+var handleObject = function handleObject(tree, a11yStrings, atomType) {
+ // Everything else is assumed to be an object...
+ switch (tree.type) {
+ case "accent":
+ {
+ buildRegion(a11yStrings, function (a11yStrings) {
+ buildA11yStrings(tree.base, a11yStrings, atomType);
+ a11yStrings.push("with");
+ buildString(tree.label, "normal", a11yStrings);
+ a11yStrings.push("on top");
+ });
+ break;
+ }
+
+ case "accentUnder":
+ {
+ buildRegion(a11yStrings, function (a11yStrings) {
+ buildA11yStrings(tree.base, a11yStrings, atomType);
+ a11yStrings.push("with");
+ buildString(accentUnderMap[tree.label], "normal", a11yStrings);
+ a11yStrings.push("underneath");
+ });
+ break;
+ }
+
+ case "accent-token":
+ {
+ // Used internally by accent symbols.
+ break;
+ }
+
+ case "atom":
+ {
+ var text = tree.text;
+
+ switch (tree.family) {
+ case "bin":
+ {
+ buildString(text, "bin", a11yStrings);
+ break;
+ }
+
+ case "close":
+ {
+ buildString(text, "close", a11yStrings);
+ break;
+ }
+ // TODO(kevinb): figure out what should be done for inner
+
+ case "inner":
+ {
+ buildString(tree.text, "inner", a11yStrings);
+ break;
+ }
+
+ case "open":
+ {
+ buildString(text, "open", a11yStrings);
+ break;
+ }
+
+ case "punct":
+ {
+ buildString(text, "punct", a11yStrings);
+ break;
+ }
+
+ case "rel":
+ {
+ buildString(text, "rel", a11yStrings);
+ break;
+ }
+
+ default:
+ {
+ tree.family;
+ throw new Error("\"" + tree.family + "\" is not a valid atom type");
+ }
+ }
+
+ break;
+ }
+
+ case "color":
+ {
+ var color = tree.color.replace(/katex-/, "");
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start color " + color);
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end color " + color);
+ });
+ break;
+ }
+
+ case "color-token":
+ {
+ // Used by \color, \colorbox, and \fcolorbox but not directly rendered.
+ // It's a leaf node and has no children so just break.
+ break;
+ }
+
+ case "delimsizing":
+ {
+ if (tree.delim && tree.delim !== ".") {
+ buildString(tree.delim, "normal", a11yStrings);
+ }
+
+ break;
+ }
+
+ case "genfrac":
+ {
+ buildRegion(a11yStrings, function (regionStrings) {
+ // genfrac can have unbalanced delimiters
+ var leftDelim = tree.leftDelim,
+ rightDelim = tree.rightDelim; // NOTE: Not sure if this is a safe assumption
+ // hasBarLine true -> fraction, false -> binomial
+
+ if (tree.hasBarLine) {
+ regionStrings.push("start fraction");
+ leftDelim && buildString(leftDelim, "open", regionStrings);
+ buildA11yStrings(tree.numer, regionStrings, atomType);
+ regionStrings.push("divided by");
+ buildA11yStrings(tree.denom, regionStrings, atomType);
+ rightDelim && buildString(rightDelim, "close", regionStrings);
+ regionStrings.push("end fraction");
+ } else {
+ regionStrings.push("start binomial");
+ leftDelim && buildString(leftDelim, "open", regionStrings);
+ buildA11yStrings(tree.numer, regionStrings, atomType);
+ regionStrings.push("over");
+ buildA11yStrings(tree.denom, regionStrings, atomType);
+ rightDelim && buildString(rightDelim, "close", regionStrings);
+ regionStrings.push("end binomial");
+ }
+ });
+ break;
+ }
+
+ case "hbox":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "kern":
+ {
+ // No op: we don't attempt to present kerning information
+ // to the screen reader.
+ break;
+ }
+
+ case "leftright":
+ {
+ buildRegion(a11yStrings, function (regionStrings) {
+ buildString(tree.left, "open", regionStrings);
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ buildString(tree.right, "close", regionStrings);
+ });
+ break;
+ }
+
+ case "leftright-right":
+ {
+ // TODO: double check that this is a no-op
+ break;
+ }
+
+ case "lap":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "mathord":
+ {
+ buildString(tree.text, "normal", a11yStrings);
+ break;
+ }
+
+ case "op":
+ {
+ var body = tree.body,
+ name = tree.name;
+
+ if (body) {
+ buildA11yStrings(body, a11yStrings, atomType);
+ } else if (name) {
+ buildString(name, "normal", a11yStrings);
+ }
+
+ break;
+ }
+
+ case "op-token":
+ {
+ // Used internally by operator symbols.
+ buildString(tree.text, atomType, a11yStrings);
+ break;
+ }
+
+ case "ordgroup":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "overline":
+ {
+ buildRegion(a11yStrings, function (a11yStrings) {
+ a11yStrings.push("start overline");
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ a11yStrings.push("end overline");
+ });
+ break;
+ }
+
+ case "phantom":
+ {
+ a11yStrings.push("empty space");
+ break;
+ }
+
+ case "raisebox":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "rule":
+ {
+ a11yStrings.push("rectangle");
+ break;
+ }
+
+ case "sizing":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "spacing":
+ {
+ a11yStrings.push("space");
+ break;
+ }
+
+ case "styling":
+ {
+ // We ignore the styling and just pass through the contents
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "sqrt":
+ {
+ buildRegion(a11yStrings, function (regionStrings) {
+ var body = tree.body,
+ index = tree.index;
+
+ if (index) {
+ var indexString = flatten(buildA11yStrings(index, [], atomType)).join(",");
+
+ if (indexString === "3") {
+ regionStrings.push("cube root of");
+ buildA11yStrings(body, regionStrings, atomType);
+ regionStrings.push("end cube root");
+ return;
+ }
+
+ regionStrings.push("root");
+ regionStrings.push("start index");
+ buildA11yStrings(index, regionStrings, atomType);
+ regionStrings.push("end index");
+ return;
+ }
+
+ regionStrings.push("square root of");
+ buildA11yStrings(body, regionStrings, atomType);
+ regionStrings.push("end square root");
+ });
+ break;
+ }
+
+ case "supsub":
+ {
+ var base = tree.base,
+ sub = tree.sub,
+ sup = tree.sup;
+ var isLog = false;
+
+ if (base) {
+ buildA11yStrings(base, a11yStrings, atomType);
+ isLog = base.type === "op" && base.name === "\\log";
+ }
+
+ if (sub) {
+ var regionName = isLog ? "base" : "subscript";
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start " + regionName);
+ buildA11yStrings(sub, regionStrings, atomType);
+ regionStrings.push("end " + regionName);
+ });
+ }
+
+ if (sup) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ var supString = flatten(buildA11yStrings(sup, [], atomType)).join(",");
+
+ if (supString in powerMap) {
+ regionStrings.push(powerMap[supString]);
+ return;
+ }
+
+ regionStrings.push("start superscript");
+ buildA11yStrings(sup, regionStrings, atomType);
+ regionStrings.push("end superscript");
+ });
+ }
+
+ break;
+ }
+
+ case "text":
+ {
+ // TODO: handle other fonts
+ if (tree.font === "\\textbf") {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start bold text");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end bold text");
+ });
+ break;
+ }
+
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start text");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end text");
+ });
+ break;
+ }
+
+ case "textord":
+ {
+ buildString(tree.text, atomType, a11yStrings);
+ break;
+ }
+
+ case "smash":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "enclose":
+ {
+ // TODO: create a map for these.
+ // TODO: differentiate between a body with a single atom, e.g.
+ // "cancel a" instead of "start cancel, a, end cancel"
+ if (/cancel/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start cancel");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end cancel");
+ });
+ break;
+ } else if (/box/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start box");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end box");
+ });
+ break;
+ } else if (/sout/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start strikeout");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end strikeout");
+ });
+ break;
+ } else if (/phase/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start phase angle");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end phase angle");
+ });
+ break;
+ }
+
+ throw new Error("KaTeX-a11y: enclose node with " + tree.label + " not supported yet");
+ }
+
+ case "vcenter":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "vphantom":
+ {
+ throw new Error("KaTeX-a11y: vphantom not implemented yet");
+ }
+
+ case "hphantom":
+ {
+ throw new Error("KaTeX-a11y: hphantom not implemented yet");
+ }
+
+ case "operatorname":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "array":
+ {
+ throw new Error("KaTeX-a11y: array not implemented yet");
+ }
+
+ case "raw":
+ {
+ throw new Error("KaTeX-a11y: raw not implemented yet");
+ }
+
+ case "size":
+ {
+ // Although there are nodes of type "size" in the parse tree, they have
+ // no semantic meaning and should be ignored.
+ break;
+ }
+
+ case "url":
+ {
+ throw new Error("KaTeX-a11y: url not implemented yet");
+ }
+
+ case "tag":
+ {
+ throw new Error("KaTeX-a11y: tag not implemented yet");
+ }
+
+ case "verb":
+ {
+ buildString("start verbatim", "normal", a11yStrings);
+ buildString(tree.body, "normal", a11yStrings);
+ buildString("end verbatim", "normal", a11yStrings);
+ break;
+ }
+
+ case "environment":
+ {
+ throw new Error("KaTeX-a11y: environment not implemented yet");
+ }
+
+ case "horizBrace":
+ {
+ buildString("start " + tree.label.slice(1), "normal", a11yStrings);
+ buildA11yStrings(tree.base, a11yStrings, atomType);
+ buildString("end " + tree.label.slice(1), "normal", a11yStrings);
+ break;
+ }
+
+ case "infix":
+ {
+ // All infix nodes are replace with other nodes.
+ break;
+ }
+
+ case "includegraphics":
+ {
+ throw new Error("KaTeX-a11y: includegraphics not implemented yet");
+ }
+
+ case "font":
+ {
+ // TODO: callout the start/end of specific fonts
+ // TODO: map \BBb{N} to "the naturals" or something like that
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "href":
+ {
+ throw new Error("KaTeX-a11y: href not implemented yet");
+ }
+
+ case "cr":
+ {
+ // This is used by environments.
+ throw new Error("KaTeX-a11y: cr not implemented yet");
+ }
+
+ case "underline":
+ {
+ buildRegion(a11yStrings, function (a11yStrings) {
+ a11yStrings.push("start underline");
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ a11yStrings.push("end underline");
+ });
+ break;
+ }
+
+ case "xArrow":
+ {
+ throw new Error("KaTeX-a11y: xArrow not implemented yet");
+ }
+
+ case "cdlabel":
+ {
+ throw new Error("KaTeX-a11y: cdlabel not implemented yet");
+ }
+
+ case "cdlabelparent":
+ {
+ throw new Error("KaTeX-a11y: cdlabelparent not implemented yet");
+ }
+
+ case "mclass":
+ {
+ // \neq and \ne are macros so we let "htmlmathml" render the mathmal
+ // side of things and extract the text from that.
+ var _atomType = tree.mclass.slice(1); // $FlowFixMe: drop the leading "m" from the values in mclass
+
+
+ buildA11yStrings(tree.body, a11yStrings, _atomType);
+ break;
+ }
+
+ case "mathchoice":
+ {
+ // TODO: track which which style we're using, e.g. dispaly, text, etc.
+ // default to text style if even that may not be the correct style
+ buildA11yStrings(tree.text, a11yStrings, atomType);
+ break;
+ }
+
+ case "htmlmathml":
+ {
+ buildA11yStrings(tree.mathml, a11yStrings, atomType);
+ break;
+ }
+
+ case "middle":
+ {
+ buildString(tree.delim, atomType, a11yStrings);
+ break;
+ }
+
+ case "internal":
+ {
+ // internal nodes are never included in the parse tree
+ break;
+ }
+
+ case "html":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ default:
+ tree.type;
+ throw new Error("KaTeX a11y un-recognized type: " + tree.type);
+ }
+};
+
+var buildA11yStrings = function buildA11yStrings(tree, a11yStrings, atomType) {
+ if (a11yStrings === void 0) {
+ a11yStrings = [];
+ }
+
+ if (tree instanceof Array) {
+ for (var i = 0; i < tree.length; i++) {
+ buildA11yStrings(tree[i], a11yStrings, atomType);
+ }
+ } else {
+ handleObject(tree, a11yStrings, atomType);
+ }
+
+ return a11yStrings;
+};
+
+var flatten = function flatten(array) {
+ var result = [];
+ array.forEach(function (item) {
+ if (item instanceof Array) {
+ result = result.concat(flatten(item));
+ } else {
+ result.push(item);
+ }
+ });
+ return result;
+};
+
+var renderA11yString = function renderA11yString(text, settings) {
+ var tree = katex__WEBPACK_IMPORTED_MODULE_0___default().__parse(text, settings);
+
+ var a11yStrings = buildA11yStrings(tree, [], "normal");
+ return flatten(a11yStrings).join(", ");
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (renderA11yString);
+}();
+__webpack_exports__ = __webpack_exports__["default"];
+/******/ return __webpack_exports__;
+/******/ })()
+;
+});
\ No newline at end of file
diff --git a/static/katex/contrib/render-a11y-string.min.js b/static/katex/contrib/render-a11y-string.min.js
new file mode 100644
index 0000000..e746189
--- /dev/null
+++ b/static/katex/contrib/render-a11y-string.min.js
@@ -0,0 +1 @@
+!function(e,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r(require("katex"));else if("function"==typeof define&&define.amd)define(["katex"],r);else{var a="object"==typeof exports?r(require("katex")):r(e.katex);for(var t in a)("object"==typeof exports?exports:e)[t]=a[t]}}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var r={771:function(r){r.exports=e}},a={};function t(e){var o=a[e];if(void 0!==o)return o.exports;var n=a[e]={exports:{}};return r[e](n,n.exports,t),n.exports}t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,{a:r}),r},t.d=function(e,r){for(var a in r)t.o(r,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:r[a]})},t.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)};var o,n,s,i,l,c,u,p,d,b,h,m,f,y,w={};return o=t(771),n=t.n(o),s={"(":"left parenthesis",")":"right parenthesis","[":"open bracket","]":"close bracket","\\{":"left brace","\\}":"right brace","\\lvert":"open vertical bar","\\rvert":"close vertical bar","|":"vertical bar","\\uparrow":"up arrow","\\Uparrow":"up arrow","\\downarrow":"down arrow","\\Downarrow":"down arrow","\\updownarrow":"up down arrow","\\leftarrow":"left arrow","\\Leftarrow":"left arrow","\\rightarrow":"right arrow","\\Rightarrow":"right arrow","\\langle":"open angle","\\rangle":"close angle","\\lfloor":"open floor","\\rfloor":"close floor","\\int":"integral","\\intop":"integral","\\lim":"limit","\\ln":"natural log","\\log":"log","\\sin":"sine","\\cos":"cosine","\\tan":"tangent","\\cot":"cotangent","\\sum":"sum","/":"slash",",":"comma",".":"point","-":"negative","+":"plus","~":"tilde",":":"colon","?":"question mark","'":"apostrophe","\\%":"percent"," ":"space","\\ ":"space","\\$":"dollar sign","\\angle":"angle","\\degree":"degree","\\circ":"circle","\\vec":"vector","\\triangle":"triangle","\\pi":"pi","\\prime":"prime","\\infty":"infinity","\\alpha":"alpha","\\beta":"beta","\\gamma":"gamma","\\omega":"omega","\\theta":"theta","\\sigma":"sigma","\\lambda":"lambda","\\tau":"tau","\\Delta":"delta","\\delta":"delta","\\mu":"mu","\\rho":"rho","\\nabla":"del","\\ell":"ell","\\ldots":"dots","\\hat":"hat","\\acute":"acute"},i={prime:"prime",degree:"degrees",circle:"degrees",2:"squared",3:"cubed"},l={"|":"open vertical bar",".":""},c={"|":"close vertical bar",".":""},u={"+":"plus","-":"minus","\\pm":"plus minus","\\cdot":"dot","*":"times","/":"divided by","\\times":"times","\\div":"divided by","\\circ":"circle","\\bullet":"bullet"},p={"=":"equals","\\approx":"approximately equals","\u2260":"does not equal","\\geq":"is greater than or equal to","\\ge":"is greater than or equal to","\\leq":"is less than or equal to","\\le":"is less than or equal to",">":"is greater than","<":"is less than","\\leftarrow":"left arrow","\\Leftarrow":"left arrow","\\rightarrow":"right arrow","\\Rightarrow":"right arrow",":":"colon"},d={"\\underleftarrow":"left arrow","\\underrightarrow":"right arrow","\\underleftrightarrow":"left-right arrow","\\undergroup":"group","\\underlinesegment":"line segment","\\utilde":"tilde"},b=function(e,r,a){var t;e&&(/^\d+$/.test(t="open"===r?e in l?l[e]:s[e]||e:"close"===r?e in c?c[e]:s[e]||e:"bin"===r?u[e]||e:"rel"===r?p[e]||e:s[e]||e)&&a.length>0&&/^\d+$/.test(a[a.length-1])?a[a.length-1]+=t:t&&a.push(t))},h=function(e,r){var a=[];e.push(a),r(a)},m=function(e,r,a){switch(e.type){case"accent":h(r,(function(r){f(e.base,r,a),r.push("with"),b(e.label,"normal",r),r.push("on top")}));break;case"accentUnder":h(r,(function(r){f(e.base,r,a),r.push("with"),b(d[e.label],"normal",r),r.push("underneath")}));break;case"accent-token":break;case"atom":var t=e.text;switch(e.family){case"bin":b(t,"bin",r);break;case"close":b(t,"close",r);break;case"inner":b(e.text,"inner",r);break;case"open":b(t,"open",r);break;case"punct":b(t,"punct",r);break;case"rel":b(t,"rel",r);break;default:throw e.family,new Error('"'+e.family+'" is not a valid atom type')}break;case"color":var o=e.color.replace(/katex-/,"");h(r,(function(r){r.push("start color "+o),f(e.body,r,a),r.push("end color "+o)}));break;case"color-token":break;case"delimsizing":e.delim&&"."!==e.delim&&b(e.delim,"normal",r);break;case"genfrac":h(r,(function(r){var t=e.leftDelim,o=e.rightDelim;e.hasBarLine?(r.push("start fraction"),t&&b(t,"open",r),f(e.numer,r,a),r.push("divided by"),f(e.denom,r,a),o&&b(o,"close",r),r.push("end fraction")):(r.push("start binomial"),t&&b(t,"open",r),f(e.numer,r,a),r.push("over"),f(e.denom,r,a),o&&b(o,"close",r),r.push("end binomial"))}));break;case"hbox":f(e.body,r,a);break;case"kern":break;case"leftright":h(r,(function(r){b(e.left,"open",r),f(e.body,r,a),b(e.right,"close",r)}));break;case"leftright-right":break;case"lap":f(e.body,r,a);break;case"mathord":b(e.text,"normal",r);break;case"op":var n=e.body,s=e.name;n?f(n,r,a):s&&b(s,"normal",r);break;case"op-token":b(e.text,a,r);break;case"ordgroup":f(e.body,r,a);break;case"overline":h(r,(function(r){r.push("start overline"),f(e.body,r,a),r.push("end overline")}));break;case"phantom":r.push("empty space");break;case"raisebox":f(e.body,r,a);break;case"rule":r.push("rectangle");break;case"sizing":f(e.body,r,a);break;case"spacing":r.push("space");break;case"styling":f(e.body,r,a);break;case"sqrt":h(r,(function(r){var t=e.body,o=e.index;if(o)return"3"===y(f(o,[],a)).join(",")?(r.push("cube root of"),f(t,r,a),void r.push("end cube root")):(r.push("root"),r.push("start index"),f(o,r,a),void r.push("end index"));r.push("square root of"),f(t,r,a),r.push("end square root")}));break;case"supsub":var l=e.base,c=e.sub,u=e.sup,p=!1;if(l&&(f(l,r,a),p="op"===l.type&&"\\log"===l.name),c){var m=p?"base":"subscript";h(r,(function(e){e.push("start "+m),f(c,e,a),e.push("end "+m)}))}u&&h(r,(function(e){var r=y(f(u,[],a)).join(",");r in i?e.push(i[r]):(e.push("start superscript"),f(u,e,a),e.push("end superscript"))}));break;case"text":if("\\textbf"===e.font){h(r,(function(r){r.push("start bold text"),f(e.body,r,a),r.push("end bold text")}));break}h(r,(function(r){r.push("start text"),f(e.body,r,a),r.push("end text")}));break;case"textord":b(e.text,a,r);break;case"smash":f(e.body,r,a);break;case"enclose":if(/cancel/.test(e.label)){h(r,(function(r){r.push("start cancel"),f(e.body,r,a),r.push("end cancel")}));break}if(/box/.test(e.label)){h(r,(function(r){r.push("start box"),f(e.body,r,a),r.push("end box")}));break}if(/sout/.test(e.label)){h(r,(function(r){r.push("start strikeout"),f(e.body,r,a),r.push("end strikeout")}));break}if(/phase/.test(e.label)){h(r,(function(r){r.push("start phase angle"),f(e.body,r,a),r.push("end phase angle")}));break}throw new Error("KaTeX-a11y: enclose node with "+e.label+" not supported yet");case"vcenter":f(e.body,r,a);break;case"vphantom":throw new Error("KaTeX-a11y: vphantom not implemented yet");case"hphantom":throw new Error("KaTeX-a11y: hphantom not implemented yet");case"operatorname":f(e.body,r,a);break;case"array":throw new Error("KaTeX-a11y: array not implemented yet");case"raw":throw new Error("KaTeX-a11y: raw not implemented yet");case"size":break;case"url":throw new Error("KaTeX-a11y: url not implemented yet");case"tag":throw new Error("KaTeX-a11y: tag not implemented yet");case"verb":b("start verbatim","normal",r),b(e.body,"normal",r),b("end verbatim","normal",r);break;case"environment":throw new Error("KaTeX-a11y: environment not implemented yet");case"horizBrace":b("start "+e.label.slice(1),"normal",r),f(e.base,r,a),b("end "+e.label.slice(1),"normal",r);break;case"infix":break;case"includegraphics":throw new Error("KaTeX-a11y: includegraphics not implemented yet");case"font":f(e.body,r,a);break;case"href":throw new Error("KaTeX-a11y: href not implemented yet");case"cr":throw new Error("KaTeX-a11y: cr not implemented yet");case"underline":h(r,(function(r){r.push("start underline"),f(e.body,r,a),r.push("end underline")}));break;case"xArrow":throw new Error("KaTeX-a11y: xArrow not implemented yet");case"cdlabel":throw new Error("KaTeX-a11y: cdlabel not implemented yet");case"cdlabelparent":throw new Error("KaTeX-a11y: cdlabelparent not implemented yet");case"mclass":var w=e.mclass.slice(1);f(e.body,r,w);break;case"mathchoice":f(e.text,r,a);break;case"htmlmathml":f(e.mathml,r,a);break;case"middle":b(e.delim,a,r);break;case"internal":break;case"html":f(e.body,r,a);break;default:throw e.type,new Error("KaTeX a11y un-recognized type: "+e.type)}},f=function e(r,a,t){if(void 0===a&&(a=[]),r instanceof Array)for(var o=0;o "start fraction, 1, divided by, 2, end fraction"
+ *
+ * However, other cases do not:
+ * renderA11yString("f(x) = x^2")
+ * -> "f, left parenthesis, x, right parenthesis, equals, x, squared"
+ *
+ * The commas in the string aim to increase ease of understanding
+ * when read by a screenreader.
+ */
+var stringMap = {
+ "(": "left parenthesis",
+ ")": "right parenthesis",
+ "[": "open bracket",
+ "]": "close bracket",
+ "\\{": "left brace",
+ "\\}": "right brace",
+ "\\lvert": "open vertical bar",
+ "\\rvert": "close vertical bar",
+ "|": "vertical bar",
+ "\\uparrow": "up arrow",
+ "\\Uparrow": "up arrow",
+ "\\downarrow": "down arrow",
+ "\\Downarrow": "down arrow",
+ "\\updownarrow": "up down arrow",
+ "\\leftarrow": "left arrow",
+ "\\Leftarrow": "left arrow",
+ "\\rightarrow": "right arrow",
+ "\\Rightarrow": "right arrow",
+ "\\langle": "open angle",
+ "\\rangle": "close angle",
+ "\\lfloor": "open floor",
+ "\\rfloor": "close floor",
+ "\\int": "integral",
+ "\\intop": "integral",
+ "\\lim": "limit",
+ "\\ln": "natural log",
+ "\\log": "log",
+ "\\sin": "sine",
+ "\\cos": "cosine",
+ "\\tan": "tangent",
+ "\\cot": "cotangent",
+ "\\sum": "sum",
+ "/": "slash",
+ ",": "comma",
+ ".": "point",
+ "-": "negative",
+ "+": "plus",
+ "~": "tilde",
+ ":": "colon",
+ "?": "question mark",
+ "'": "apostrophe",
+ "\\%": "percent",
+ " ": "space",
+ "\\ ": "space",
+ "\\$": "dollar sign",
+ "\\angle": "angle",
+ "\\degree": "degree",
+ "\\circ": "circle",
+ "\\vec": "vector",
+ "\\triangle": "triangle",
+ "\\pi": "pi",
+ "\\prime": "prime",
+ "\\infty": "infinity",
+ "\\alpha": "alpha",
+ "\\beta": "beta",
+ "\\gamma": "gamma",
+ "\\omega": "omega",
+ "\\theta": "theta",
+ "\\sigma": "sigma",
+ "\\lambda": "lambda",
+ "\\tau": "tau",
+ "\\Delta": "delta",
+ "\\delta": "delta",
+ "\\mu": "mu",
+ "\\rho": "rho",
+ "\\nabla": "del",
+ "\\ell": "ell",
+ "\\ldots": "dots",
+ // TODO: add entries for all accents
+ "\\hat": "hat",
+ "\\acute": "acute"
+};
+var powerMap = {
+ "prime": "prime",
+ "degree": "degrees",
+ "circle": "degrees",
+ "2": "squared",
+ "3": "cubed"
+};
+var openMap = {
+ "|": "open vertical bar",
+ ".": ""
+};
+var closeMap = {
+ "|": "close vertical bar",
+ ".": ""
+};
+var binMap = {
+ "+": "plus",
+ "-": "minus",
+ "\\pm": "plus minus",
+ "\\cdot": "dot",
+ "*": "times",
+ "/": "divided by",
+ "\\times": "times",
+ "\\div": "divided by",
+ "\\circ": "circle",
+ "\\bullet": "bullet"
+};
+var relMap = {
+ "=": "equals",
+ "\\approx": "approximately equals",
+ "≠": "does not equal",
+ "\\geq": "is greater than or equal to",
+ "\\ge": "is greater than or equal to",
+ "\\leq": "is less than or equal to",
+ "\\le": "is less than or equal to",
+ ">": "is greater than",
+ "<": "is less than",
+ "\\leftarrow": "left arrow",
+ "\\Leftarrow": "left arrow",
+ "\\rightarrow": "right arrow",
+ "\\Rightarrow": "right arrow",
+ ":": "colon"
+};
+var accentUnderMap = {
+ "\\underleftarrow": "left arrow",
+ "\\underrightarrow": "right arrow",
+ "\\underleftrightarrow": "left-right arrow",
+ "\\undergroup": "group",
+ "\\underlinesegment": "line segment",
+ "\\utilde": "tilde"
+};
+
+var buildString = (str, type, a11yStrings) => {
+ if (!str) {
+ return;
+ }
+
+ var ret;
+
+ if (type === "open") {
+ ret = str in openMap ? openMap[str] : stringMap[str] || str;
+ } else if (type === "close") {
+ ret = str in closeMap ? closeMap[str] : stringMap[str] || str;
+ } else if (type === "bin") {
+ ret = binMap[str] || str;
+ } else if (type === "rel") {
+ ret = relMap[str] || str;
+ } else {
+ ret = stringMap[str] || str;
+ } // If the text to add is a number and there is already a string
+ // in the list and the last string is a number then we should
+ // combine them into a single number
+
+
+ if (/^\d+$/.test(ret) && a11yStrings.length > 0 && // TODO(kevinb): check that the last item in a11yStrings is a string
+ // I think we might be able to drop the nested arrays, which would make
+ // this easier to type
+ // $FlowFixMe
+ /^\d+$/.test(a11yStrings[a11yStrings.length - 1])) {
+ a11yStrings[a11yStrings.length - 1] += ret;
+ } else if (ret) {
+ a11yStrings.push(ret);
+ }
+};
+
+var buildRegion = (a11yStrings, callback) => {
+ var regionStrings = [];
+ a11yStrings.push(regionStrings);
+ callback(regionStrings);
+};
+
+var handleObject = (tree, a11yStrings, atomType) => {
+ // Everything else is assumed to be an object...
+ switch (tree.type) {
+ case "accent":
+ {
+ buildRegion(a11yStrings, a11yStrings => {
+ buildA11yStrings(tree.base, a11yStrings, atomType);
+ a11yStrings.push("with");
+ buildString(tree.label, "normal", a11yStrings);
+ a11yStrings.push("on top");
+ });
+ break;
+ }
+
+ case "accentUnder":
+ {
+ buildRegion(a11yStrings, a11yStrings => {
+ buildA11yStrings(tree.base, a11yStrings, atomType);
+ a11yStrings.push("with");
+ buildString(accentUnderMap[tree.label], "normal", a11yStrings);
+ a11yStrings.push("underneath");
+ });
+ break;
+ }
+
+ case "accent-token":
+ {
+ // Used internally by accent symbols.
+ break;
+ }
+
+ case "atom":
+ {
+ var {
+ text
+ } = tree;
+
+ switch (tree.family) {
+ case "bin":
+ {
+ buildString(text, "bin", a11yStrings);
+ break;
+ }
+
+ case "close":
+ {
+ buildString(text, "close", a11yStrings);
+ break;
+ }
+ // TODO(kevinb): figure out what should be done for inner
+
+ case "inner":
+ {
+ buildString(tree.text, "inner", a11yStrings);
+ break;
+ }
+
+ case "open":
+ {
+ buildString(text, "open", a11yStrings);
+ break;
+ }
+
+ case "punct":
+ {
+ buildString(text, "punct", a11yStrings);
+ break;
+ }
+
+ case "rel":
+ {
+ buildString(text, "rel", a11yStrings);
+ break;
+ }
+
+ default:
+ {
+ tree.family;
+ throw new Error("\"" + tree.family + "\" is not a valid atom type");
+ }
+ }
+
+ break;
+ }
+
+ case "color":
+ {
+ var color = tree.color.replace(/katex-/, "");
+ buildRegion(a11yStrings, regionStrings => {
+ regionStrings.push("start color " + color);
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end color " + color);
+ });
+ break;
+ }
+
+ case "color-token":
+ {
+ // Used by \color, \colorbox, and \fcolorbox but not directly rendered.
+ // It's a leaf node and has no children so just break.
+ break;
+ }
+
+ case "delimsizing":
+ {
+ if (tree.delim && tree.delim !== ".") {
+ buildString(tree.delim, "normal", a11yStrings);
+ }
+
+ break;
+ }
+
+ case "genfrac":
+ {
+ buildRegion(a11yStrings, regionStrings => {
+ // genfrac can have unbalanced delimiters
+ var {
+ leftDelim,
+ rightDelim
+ } = tree; // NOTE: Not sure if this is a safe assumption
+ // hasBarLine true -> fraction, false -> binomial
+
+ if (tree.hasBarLine) {
+ regionStrings.push("start fraction");
+ leftDelim && buildString(leftDelim, "open", regionStrings);
+ buildA11yStrings(tree.numer, regionStrings, atomType);
+ regionStrings.push("divided by");
+ buildA11yStrings(tree.denom, regionStrings, atomType);
+ rightDelim && buildString(rightDelim, "close", regionStrings);
+ regionStrings.push("end fraction");
+ } else {
+ regionStrings.push("start binomial");
+ leftDelim && buildString(leftDelim, "open", regionStrings);
+ buildA11yStrings(tree.numer, regionStrings, atomType);
+ regionStrings.push("over");
+ buildA11yStrings(tree.denom, regionStrings, atomType);
+ rightDelim && buildString(rightDelim, "close", regionStrings);
+ regionStrings.push("end binomial");
+ }
+ });
+ break;
+ }
+
+ case "hbox":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "kern":
+ {
+ // No op: we don't attempt to present kerning information
+ // to the screen reader.
+ break;
+ }
+
+ case "leftright":
+ {
+ buildRegion(a11yStrings, regionStrings => {
+ buildString(tree.left, "open", regionStrings);
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ buildString(tree.right, "close", regionStrings);
+ });
+ break;
+ }
+
+ case "leftright-right":
+ {
+ // TODO: double check that this is a no-op
+ break;
+ }
+
+ case "lap":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "mathord":
+ {
+ buildString(tree.text, "normal", a11yStrings);
+ break;
+ }
+
+ case "op":
+ {
+ var {
+ body,
+ name
+ } = tree;
+
+ if (body) {
+ buildA11yStrings(body, a11yStrings, atomType);
+ } else if (name) {
+ buildString(name, "normal", a11yStrings);
+ }
+
+ break;
+ }
+
+ case "op-token":
+ {
+ // Used internally by operator symbols.
+ buildString(tree.text, atomType, a11yStrings);
+ break;
+ }
+
+ case "ordgroup":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "overline":
+ {
+ buildRegion(a11yStrings, function (a11yStrings) {
+ a11yStrings.push("start overline");
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ a11yStrings.push("end overline");
+ });
+ break;
+ }
+
+ case "phantom":
+ {
+ a11yStrings.push("empty space");
+ break;
+ }
+
+ case "raisebox":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "rule":
+ {
+ a11yStrings.push("rectangle");
+ break;
+ }
+
+ case "sizing":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "spacing":
+ {
+ a11yStrings.push("space");
+ break;
+ }
+
+ case "styling":
+ {
+ // We ignore the styling and just pass through the contents
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "sqrt":
+ {
+ buildRegion(a11yStrings, regionStrings => {
+ var {
+ body,
+ index
+ } = tree;
+
+ if (index) {
+ var indexString = flatten(buildA11yStrings(index, [], atomType)).join(",");
+
+ if (indexString === "3") {
+ regionStrings.push("cube root of");
+ buildA11yStrings(body, regionStrings, atomType);
+ regionStrings.push("end cube root");
+ return;
+ }
+
+ regionStrings.push("root");
+ regionStrings.push("start index");
+ buildA11yStrings(index, regionStrings, atomType);
+ regionStrings.push("end index");
+ return;
+ }
+
+ regionStrings.push("square root of");
+ buildA11yStrings(body, regionStrings, atomType);
+ regionStrings.push("end square root");
+ });
+ break;
+ }
+
+ case "supsub":
+ {
+ var {
+ base,
+ sub,
+ sup
+ } = tree;
+ var isLog = false;
+
+ if (base) {
+ buildA11yStrings(base, a11yStrings, atomType);
+ isLog = base.type === "op" && base.name === "\\log";
+ }
+
+ if (sub) {
+ var regionName = isLog ? "base" : "subscript";
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start " + regionName);
+ buildA11yStrings(sub, regionStrings, atomType);
+ regionStrings.push("end " + regionName);
+ });
+ }
+
+ if (sup) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ var supString = flatten(buildA11yStrings(sup, [], atomType)).join(",");
+
+ if (supString in powerMap) {
+ regionStrings.push(powerMap[supString]);
+ return;
+ }
+
+ regionStrings.push("start superscript");
+ buildA11yStrings(sup, regionStrings, atomType);
+ regionStrings.push("end superscript");
+ });
+ }
+
+ break;
+ }
+
+ case "text":
+ {
+ // TODO: handle other fonts
+ if (tree.font === "\\textbf") {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start bold text");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end bold text");
+ });
+ break;
+ }
+
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start text");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end text");
+ });
+ break;
+ }
+
+ case "textord":
+ {
+ buildString(tree.text, atomType, a11yStrings);
+ break;
+ }
+
+ case "smash":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "enclose":
+ {
+ // TODO: create a map for these.
+ // TODO: differentiate between a body with a single atom, e.g.
+ // "cancel a" instead of "start cancel, a, end cancel"
+ if (/cancel/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start cancel");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end cancel");
+ });
+ break;
+ } else if (/box/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start box");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end box");
+ });
+ break;
+ } else if (/sout/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start strikeout");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end strikeout");
+ });
+ break;
+ } else if (/phase/.test(tree.label)) {
+ buildRegion(a11yStrings, function (regionStrings) {
+ regionStrings.push("start phase angle");
+ buildA11yStrings(tree.body, regionStrings, atomType);
+ regionStrings.push("end phase angle");
+ });
+ break;
+ }
+
+ throw new Error("KaTeX-a11y: enclose node with " + tree.label + " not supported yet");
+ }
+
+ case "vcenter":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "vphantom":
+ {
+ throw new Error("KaTeX-a11y: vphantom not implemented yet");
+ }
+
+ case "hphantom":
+ {
+ throw new Error("KaTeX-a11y: hphantom not implemented yet");
+ }
+
+ case "operatorname":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "array":
+ {
+ throw new Error("KaTeX-a11y: array not implemented yet");
+ }
+
+ case "raw":
+ {
+ throw new Error("KaTeX-a11y: raw not implemented yet");
+ }
+
+ case "size":
+ {
+ // Although there are nodes of type "size" in the parse tree, they have
+ // no semantic meaning and should be ignored.
+ break;
+ }
+
+ case "url":
+ {
+ throw new Error("KaTeX-a11y: url not implemented yet");
+ }
+
+ case "tag":
+ {
+ throw new Error("KaTeX-a11y: tag not implemented yet");
+ }
+
+ case "verb":
+ {
+ buildString("start verbatim", "normal", a11yStrings);
+ buildString(tree.body, "normal", a11yStrings);
+ buildString("end verbatim", "normal", a11yStrings);
+ break;
+ }
+
+ case "environment":
+ {
+ throw new Error("KaTeX-a11y: environment not implemented yet");
+ }
+
+ case "horizBrace":
+ {
+ buildString("start " + tree.label.slice(1), "normal", a11yStrings);
+ buildA11yStrings(tree.base, a11yStrings, atomType);
+ buildString("end " + tree.label.slice(1), "normal", a11yStrings);
+ break;
+ }
+
+ case "infix":
+ {
+ // All infix nodes are replace with other nodes.
+ break;
+ }
+
+ case "includegraphics":
+ {
+ throw new Error("KaTeX-a11y: includegraphics not implemented yet");
+ }
+
+ case "font":
+ {
+ // TODO: callout the start/end of specific fonts
+ // TODO: map \BBb{N} to "the naturals" or something like that
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ case "href":
+ {
+ throw new Error("KaTeX-a11y: href not implemented yet");
+ }
+
+ case "cr":
+ {
+ // This is used by environments.
+ throw new Error("KaTeX-a11y: cr not implemented yet");
+ }
+
+ case "underline":
+ {
+ buildRegion(a11yStrings, function (a11yStrings) {
+ a11yStrings.push("start underline");
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ a11yStrings.push("end underline");
+ });
+ break;
+ }
+
+ case "xArrow":
+ {
+ throw new Error("KaTeX-a11y: xArrow not implemented yet");
+ }
+
+ case "cdlabel":
+ {
+ throw new Error("KaTeX-a11y: cdlabel not implemented yet");
+ }
+
+ case "cdlabelparent":
+ {
+ throw new Error("KaTeX-a11y: cdlabelparent not implemented yet");
+ }
+
+ case "mclass":
+ {
+ // \neq and \ne are macros so we let "htmlmathml" render the mathmal
+ // side of things and extract the text from that.
+ var _atomType = tree.mclass.slice(1); // $FlowFixMe: drop the leading "m" from the values in mclass
+
+
+ buildA11yStrings(tree.body, a11yStrings, _atomType);
+ break;
+ }
+
+ case "mathchoice":
+ {
+ // TODO: track which which style we're using, e.g. dispaly, text, etc.
+ // default to text style if even that may not be the correct style
+ buildA11yStrings(tree.text, a11yStrings, atomType);
+ break;
+ }
+
+ case "htmlmathml":
+ {
+ buildA11yStrings(tree.mathml, a11yStrings, atomType);
+ break;
+ }
+
+ case "middle":
+ {
+ buildString(tree.delim, atomType, a11yStrings);
+ break;
+ }
+
+ case "internal":
+ {
+ // internal nodes are never included in the parse tree
+ break;
+ }
+
+ case "html":
+ {
+ buildA11yStrings(tree.body, a11yStrings, atomType);
+ break;
+ }
+
+ default:
+ tree.type;
+ throw new Error("KaTeX a11y un-recognized type: " + tree.type);
+ }
+};
+
+var buildA11yStrings = function buildA11yStrings(tree, a11yStrings, atomType) {
+ if (a11yStrings === void 0) {
+ a11yStrings = [];
+ }
+
+ if (tree instanceof Array) {
+ for (var i = 0; i < tree.length; i++) {
+ buildA11yStrings(tree[i], a11yStrings, atomType);
+ }
+ } else {
+ handleObject(tree, a11yStrings, atomType);
+ }
+
+ return a11yStrings;
+};
+
+var flatten = function flatten(array) {
+ var result = [];
+ array.forEach(function (item) {
+ if (item instanceof Array) {
+ result = result.concat(flatten(item));
+ } else {
+ result.push(item);
+ }
+ });
+ return result;
+};
+
+var renderA11yString = function renderA11yString(text, settings) {
+ var tree = katex.__parse(text, settings);
+
+ var a11yStrings = buildA11yStrings(tree, [], "normal");
+ return flatten(a11yStrings).join(", ");
+};
+
+export { renderA11yString as default };
diff --git a/static/katex/fonts/KaTeX_AMS-Regular.ttf b/static/katex/fonts/KaTeX_AMS-Regular.ttf
new file mode 100644
index 0000000..c6f9a5e
Binary files /dev/null and b/static/katex/fonts/KaTeX_AMS-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_AMS-Regular.woff b/static/katex/fonts/KaTeX_AMS-Regular.woff
new file mode 100644
index 0000000..b804d7b
Binary files /dev/null and b/static/katex/fonts/KaTeX_AMS-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_AMS-Regular.woff2 b/static/katex/fonts/KaTeX_AMS-Regular.woff2
new file mode 100644
index 0000000..0acaaff
Binary files /dev/null and b/static/katex/fonts/KaTeX_AMS-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf b/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf
new file mode 100644
index 0000000..9ff4a5e
Binary files /dev/null and b/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf differ
diff --git a/static/katex/fonts/KaTeX_Caligraphic-Bold.woff b/static/katex/fonts/KaTeX_Caligraphic-Bold.woff
new file mode 100644
index 0000000..9759710
Binary files /dev/null and b/static/katex/fonts/KaTeX_Caligraphic-Bold.woff differ
diff --git a/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 b/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2
new file mode 100644
index 0000000..f390922
Binary files /dev/null and b/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf
new file mode 100644
index 0000000..f522294
Binary files /dev/null and b/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Caligraphic-Regular.woff b/static/katex/fonts/KaTeX_Caligraphic-Regular.woff
new file mode 100644
index 0000000..9bdd534
Binary files /dev/null and b/static/katex/fonts/KaTeX_Caligraphic-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2
new file mode 100644
index 0000000..75344a1
Binary files /dev/null and b/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Fraktur-Bold.ttf b/static/katex/fonts/KaTeX_Fraktur-Bold.ttf
new file mode 100644
index 0000000..4e98259
Binary files /dev/null and b/static/katex/fonts/KaTeX_Fraktur-Bold.ttf differ
diff --git a/static/katex/fonts/KaTeX_Fraktur-Bold.woff b/static/katex/fonts/KaTeX_Fraktur-Bold.woff
new file mode 100644
index 0000000..e7730f6
Binary files /dev/null and b/static/katex/fonts/KaTeX_Fraktur-Bold.woff differ
diff --git a/static/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/static/katex/fonts/KaTeX_Fraktur-Bold.woff2
new file mode 100644
index 0000000..395f28b
Binary files /dev/null and b/static/katex/fonts/KaTeX_Fraktur-Bold.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Fraktur-Regular.ttf b/static/katex/fonts/KaTeX_Fraktur-Regular.ttf
new file mode 100644
index 0000000..b8461b2
Binary files /dev/null and b/static/katex/fonts/KaTeX_Fraktur-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Fraktur-Regular.woff b/static/katex/fonts/KaTeX_Fraktur-Regular.woff
new file mode 100644
index 0000000..acab069
Binary files /dev/null and b/static/katex/fonts/KaTeX_Fraktur-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Fraktur-Regular.woff2 b/static/katex/fonts/KaTeX_Fraktur-Regular.woff2
new file mode 100644
index 0000000..735f694
Binary files /dev/null and b/static/katex/fonts/KaTeX_Fraktur-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Main-Bold.ttf b/static/katex/fonts/KaTeX_Main-Bold.ttf
new file mode 100644
index 0000000..4060e62
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Bold.ttf differ
diff --git a/static/katex/fonts/KaTeX_Main-Bold.woff b/static/katex/fonts/KaTeX_Main-Bold.woff
new file mode 100644
index 0000000..f38136a
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Bold.woff differ
diff --git a/static/katex/fonts/KaTeX_Main-Bold.woff2 b/static/katex/fonts/KaTeX_Main-Bold.woff2
new file mode 100644
index 0000000..ab2ad21
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Bold.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Main-BoldItalic.ttf b/static/katex/fonts/KaTeX_Main-BoldItalic.ttf
new file mode 100644
index 0000000..dc00797
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-BoldItalic.ttf differ
diff --git a/static/katex/fonts/KaTeX_Main-BoldItalic.woff b/static/katex/fonts/KaTeX_Main-BoldItalic.woff
new file mode 100644
index 0000000..67807b0
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-BoldItalic.woff differ
diff --git a/static/katex/fonts/KaTeX_Main-BoldItalic.woff2 b/static/katex/fonts/KaTeX_Main-BoldItalic.woff2
new file mode 100644
index 0000000..5931794
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-BoldItalic.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Main-Italic.ttf b/static/katex/fonts/KaTeX_Main-Italic.ttf
new file mode 100644
index 0000000..0e9b0f3
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Italic.ttf differ
diff --git a/static/katex/fonts/KaTeX_Main-Italic.woff b/static/katex/fonts/KaTeX_Main-Italic.woff
new file mode 100644
index 0000000..6f43b59
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Italic.woff differ
diff --git a/static/katex/fonts/KaTeX_Main-Italic.woff2 b/static/katex/fonts/KaTeX_Main-Italic.woff2
new file mode 100644
index 0000000..b50920e
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Italic.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Main-Regular.ttf b/static/katex/fonts/KaTeX_Main-Regular.ttf
new file mode 100644
index 0000000..dd45e1e
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Main-Regular.woff b/static/katex/fonts/KaTeX_Main-Regular.woff
new file mode 100644
index 0000000..21f5812
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Main-Regular.woff2 b/static/katex/fonts/KaTeX_Main-Regular.woff2
new file mode 100644
index 0000000..eb24a7b
Binary files /dev/null and b/static/katex/fonts/KaTeX_Main-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Math-BoldItalic.ttf b/static/katex/fonts/KaTeX_Math-BoldItalic.ttf
new file mode 100644
index 0000000..728ce7a
Binary files /dev/null and b/static/katex/fonts/KaTeX_Math-BoldItalic.ttf differ
diff --git a/static/katex/fonts/KaTeX_Math-BoldItalic.woff b/static/katex/fonts/KaTeX_Math-BoldItalic.woff
new file mode 100644
index 0000000..0ae390d
Binary files /dev/null and b/static/katex/fonts/KaTeX_Math-BoldItalic.woff differ
diff --git a/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/static/katex/fonts/KaTeX_Math-BoldItalic.woff2
new file mode 100644
index 0000000..2965702
Binary files /dev/null and b/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Math-Italic.ttf b/static/katex/fonts/KaTeX_Math-Italic.ttf
new file mode 100644
index 0000000..70d559b
Binary files /dev/null and b/static/katex/fonts/KaTeX_Math-Italic.ttf differ
diff --git a/static/katex/fonts/KaTeX_Math-Italic.woff b/static/katex/fonts/KaTeX_Math-Italic.woff
new file mode 100644
index 0000000..eb5159d
Binary files /dev/null and b/static/katex/fonts/KaTeX_Math-Italic.woff differ
diff --git a/static/katex/fonts/KaTeX_Math-Italic.woff2 b/static/katex/fonts/KaTeX_Math-Italic.woff2
new file mode 100644
index 0000000..215c143
Binary files /dev/null and b/static/katex/fonts/KaTeX_Math-Italic.woff2 differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Bold.ttf b/static/katex/fonts/KaTeX_SansSerif-Bold.ttf
new file mode 100644
index 0000000..2f65a8a
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Bold.ttf differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Bold.woff b/static/katex/fonts/KaTeX_SansSerif-Bold.woff
new file mode 100644
index 0000000..8d47c02
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Bold.woff differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/static/katex/fonts/KaTeX_SansSerif-Bold.woff2
new file mode 100644
index 0000000..cfaa3bd
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Bold.woff2 differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Italic.ttf b/static/katex/fonts/KaTeX_SansSerif-Italic.ttf
new file mode 100644
index 0000000..d5850df
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Italic.ttf differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Italic.woff b/static/katex/fonts/KaTeX_SansSerif-Italic.woff
new file mode 100644
index 0000000..7e02df9
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Italic.woff differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Italic.woff2 b/static/katex/fonts/KaTeX_SansSerif-Italic.woff2
new file mode 100644
index 0000000..349c06d
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Italic.woff2 differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Regular.ttf b/static/katex/fonts/KaTeX_SansSerif-Regular.ttf
new file mode 100644
index 0000000..537279f
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Regular.woff b/static/katex/fonts/KaTeX_SansSerif-Regular.woff
new file mode 100644
index 0000000..31b8482
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/static/katex/fonts/KaTeX_SansSerif-Regular.woff2
new file mode 100644
index 0000000..a90eea8
Binary files /dev/null and b/static/katex/fonts/KaTeX_SansSerif-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Script-Regular.ttf b/static/katex/fonts/KaTeX_Script-Regular.ttf
new file mode 100644
index 0000000..fd679bf
Binary files /dev/null and b/static/katex/fonts/KaTeX_Script-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Script-Regular.woff b/static/katex/fonts/KaTeX_Script-Regular.woff
new file mode 100644
index 0000000..0e7da82
Binary files /dev/null and b/static/katex/fonts/KaTeX_Script-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Script-Regular.woff2 b/static/katex/fonts/KaTeX_Script-Regular.woff2
new file mode 100644
index 0000000..b3048fc
Binary files /dev/null and b/static/katex/fonts/KaTeX_Script-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Size1-Regular.ttf b/static/katex/fonts/KaTeX_Size1-Regular.ttf
new file mode 100644
index 0000000..871fd7d
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size1-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Size1-Regular.woff b/static/katex/fonts/KaTeX_Size1-Regular.woff
new file mode 100644
index 0000000..7f292d9
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size1-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Size1-Regular.woff2 b/static/katex/fonts/KaTeX_Size1-Regular.woff2
new file mode 100644
index 0000000..c5a8462
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size1-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Size2-Regular.ttf b/static/katex/fonts/KaTeX_Size2-Regular.ttf
new file mode 100644
index 0000000..7a212ca
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size2-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Size2-Regular.woff b/static/katex/fonts/KaTeX_Size2-Regular.woff
new file mode 100644
index 0000000..d241d9b
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size2-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Size2-Regular.woff2 b/static/katex/fonts/KaTeX_Size2-Regular.woff2
new file mode 100644
index 0000000..e1bccfe
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size2-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Size3-Regular.ttf b/static/katex/fonts/KaTeX_Size3-Regular.ttf
new file mode 100644
index 0000000..00bff34
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size3-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Size3-Regular.woff b/static/katex/fonts/KaTeX_Size3-Regular.woff
new file mode 100644
index 0000000..e6e9b65
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size3-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Size3-Regular.woff2 b/static/katex/fonts/KaTeX_Size3-Regular.woff2
new file mode 100644
index 0000000..249a286
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size3-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Size4-Regular.ttf b/static/katex/fonts/KaTeX_Size4-Regular.ttf
new file mode 100644
index 0000000..74f0892
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size4-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Size4-Regular.woff b/static/katex/fonts/KaTeX_Size4-Regular.woff
new file mode 100644
index 0000000..e1ec545
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size4-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Size4-Regular.woff2 b/static/katex/fonts/KaTeX_Size4-Regular.woff2
new file mode 100644
index 0000000..680c130
Binary files /dev/null and b/static/katex/fonts/KaTeX_Size4-Regular.woff2 differ
diff --git a/static/katex/fonts/KaTeX_Typewriter-Regular.ttf b/static/katex/fonts/KaTeX_Typewriter-Regular.ttf
new file mode 100644
index 0000000..c83252c
Binary files /dev/null and b/static/katex/fonts/KaTeX_Typewriter-Regular.ttf differ
diff --git a/static/katex/fonts/KaTeX_Typewriter-Regular.woff b/static/katex/fonts/KaTeX_Typewriter-Regular.woff
new file mode 100644
index 0000000..2432419
Binary files /dev/null and b/static/katex/fonts/KaTeX_Typewriter-Regular.woff differ
diff --git a/static/katex/fonts/KaTeX_Typewriter-Regular.woff2 b/static/katex/fonts/KaTeX_Typewriter-Regular.woff2
new file mode 100644
index 0000000..771f1af
Binary files /dev/null and b/static/katex/fonts/KaTeX_Typewriter-Regular.woff2 differ
diff --git a/static/katex/katex.css b/static/katex/katex.css
new file mode 100644
index 0000000..9c3ffae
--- /dev/null
+++ b/static/katex/katex.css
@@ -0,0 +1,1079 @@
+/* stylelint-disable font-family-no-missing-generic-family-keyword */
+@font-face {
+ font-family: 'KaTeX_AMS';
+ src: url(fonts/KaTeX_AMS-Regular.woff2) format('woff2'), url(fonts/KaTeX_AMS-Regular.woff) format('woff'), url(fonts/KaTeX_AMS-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Caligraphic';
+ src: url(fonts/KaTeX_Caligraphic-Bold.woff2) format('woff2'), url(fonts/KaTeX_Caligraphic-Bold.woff) format('woff'), url(fonts/KaTeX_Caligraphic-Bold.ttf) format('truetype');
+ font-weight: bold;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Caligraphic';
+ src: url(fonts/KaTeX_Caligraphic-Regular.woff2) format('woff2'), url(fonts/KaTeX_Caligraphic-Regular.woff) format('woff'), url(fonts/KaTeX_Caligraphic-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Fraktur';
+ src: url(fonts/KaTeX_Fraktur-Bold.woff2) format('woff2'), url(fonts/KaTeX_Fraktur-Bold.woff) format('woff'), url(fonts/KaTeX_Fraktur-Bold.ttf) format('truetype');
+ font-weight: bold;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Fraktur';
+ src: url(fonts/KaTeX_Fraktur-Regular.woff2) format('woff2'), url(fonts/KaTeX_Fraktur-Regular.woff) format('woff'), url(fonts/KaTeX_Fraktur-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Main';
+ src: url(fonts/KaTeX_Main-Bold.woff2) format('woff2'), url(fonts/KaTeX_Main-Bold.woff) format('woff'), url(fonts/KaTeX_Main-Bold.ttf) format('truetype');
+ font-weight: bold;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Main';
+ src: url(fonts/KaTeX_Main-BoldItalic.woff2) format('woff2'), url(fonts/KaTeX_Main-BoldItalic.woff) format('woff'), url(fonts/KaTeX_Main-BoldItalic.ttf) format('truetype');
+ font-weight: bold;
+ font-style: italic;
+}
+@font-face {
+ font-family: 'KaTeX_Main';
+ src: url(fonts/KaTeX_Main-Italic.woff2) format('woff2'), url(fonts/KaTeX_Main-Italic.woff) format('woff'), url(fonts/KaTeX_Main-Italic.ttf) format('truetype');
+ font-weight: normal;
+ font-style: italic;
+}
+@font-face {
+ font-family: 'KaTeX_Main';
+ src: url(fonts/KaTeX_Main-Regular.woff2) format('woff2'), url(fonts/KaTeX_Main-Regular.woff) format('woff'), url(fonts/KaTeX_Main-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Math';
+ src: url(fonts/KaTeX_Math-BoldItalic.woff2) format('woff2'), url(fonts/KaTeX_Math-BoldItalic.woff) format('woff'), url(fonts/KaTeX_Math-BoldItalic.ttf) format('truetype');
+ font-weight: bold;
+ font-style: italic;
+}
+@font-face {
+ font-family: 'KaTeX_Math';
+ src: url(fonts/KaTeX_Math-Italic.woff2) format('woff2'), url(fonts/KaTeX_Math-Italic.woff) format('woff'), url(fonts/KaTeX_Math-Italic.ttf) format('truetype');
+ font-weight: normal;
+ font-style: italic;
+}
+@font-face {
+ font-family: 'KaTeX_SansSerif';
+ src: url(fonts/KaTeX_SansSerif-Bold.woff2) format('woff2'), url(fonts/KaTeX_SansSerif-Bold.woff) format('woff'), url(fonts/KaTeX_SansSerif-Bold.ttf) format('truetype');
+ font-weight: bold;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_SansSerif';
+ src: url(fonts/KaTeX_SansSerif-Italic.woff2) format('woff2'), url(fonts/KaTeX_SansSerif-Italic.woff) format('woff'), url(fonts/KaTeX_SansSerif-Italic.ttf) format('truetype');
+ font-weight: normal;
+ font-style: italic;
+}
+@font-face {
+ font-family: 'KaTeX_SansSerif';
+ src: url(fonts/KaTeX_SansSerif-Regular.woff2) format('woff2'), url(fonts/KaTeX_SansSerif-Regular.woff) format('woff'), url(fonts/KaTeX_SansSerif-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Script';
+ src: url(fonts/KaTeX_Script-Regular.woff2) format('woff2'), url(fonts/KaTeX_Script-Regular.woff) format('woff'), url(fonts/KaTeX_Script-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Size1';
+ src: url(fonts/KaTeX_Size1-Regular.woff2) format('woff2'), url(fonts/KaTeX_Size1-Regular.woff) format('woff'), url(fonts/KaTeX_Size1-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Size2';
+ src: url(fonts/KaTeX_Size2-Regular.woff2) format('woff2'), url(fonts/KaTeX_Size2-Regular.woff) format('woff'), url(fonts/KaTeX_Size2-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Size3';
+ src: url(fonts/KaTeX_Size3-Regular.woff2) format('woff2'), url(fonts/KaTeX_Size3-Regular.woff) format('woff'), url(fonts/KaTeX_Size3-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Size4';
+ src: url(fonts/KaTeX_Size4-Regular.woff2) format('woff2'), url(fonts/KaTeX_Size4-Regular.woff) format('woff'), url(fonts/KaTeX_Size4-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'KaTeX_Typewriter';
+ src: url(fonts/KaTeX_Typewriter-Regular.woff2) format('woff2'), url(fonts/KaTeX_Typewriter-Regular.woff) format('woff'), url(fonts/KaTeX_Typewriter-Regular.ttf) format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+.katex {
+ font: normal 1.21em KaTeX_Main, Times New Roman, serif;
+ line-height: 1.2;
+ text-indent: 0;
+ text-rendering: auto;
+}
+.katex * {
+ -ms-high-contrast-adjust: none !important;
+ border-color: currentColor;
+}
+.katex .katex-version::after {
+ content: "0.15.2";
+}
+.katex .katex-mathml {
+ /* Accessibility hack to only show to screen readers
+ Found at: http://a11yproject.com/posts/how-to-hide-content/ */
+ position: absolute;
+ clip: rect(1px, 1px, 1px, 1px);
+ padding: 0;
+ border: 0;
+ height: 1px;
+ width: 1px;
+ overflow: hidden;
+}
+.katex .katex-html {
+ /* \newline is an empty block at top level, between .base elements */
+}
+.katex .katex-html > .newline {
+ display: block;
+}
+.katex .base {
+ position: relative;
+ display: inline-block;
+ white-space: nowrap;
+ width: -webkit-min-content;
+ width: -moz-min-content;
+ width: min-content;
+}
+.katex .strut {
+ display: inline-block;
+}
+.katex .textbf {
+ font-weight: bold;
+}
+.katex .textit {
+ font-style: italic;
+}
+.katex .textrm {
+ font-family: KaTeX_Main;
+}
+.katex .textsf {
+ font-family: KaTeX_SansSerif;
+}
+.katex .texttt {
+ font-family: KaTeX_Typewriter;
+}
+.katex .mathnormal {
+ font-family: KaTeX_Math;
+ font-style: italic;
+}
+.katex .mathit {
+ font-family: KaTeX_Main;
+ font-style: italic;
+}
+.katex .mathrm {
+ font-style: normal;
+}
+.katex .mathbf {
+ font-family: KaTeX_Main;
+ font-weight: bold;
+}
+.katex .boldsymbol {
+ font-family: KaTeX_Math;
+ font-weight: bold;
+ font-style: italic;
+}
+.katex .amsrm {
+ font-family: KaTeX_AMS;
+}
+.katex .mathbb,
+.katex .textbb {
+ font-family: KaTeX_AMS;
+}
+.katex .mathcal {
+ font-family: KaTeX_Caligraphic;
+}
+.katex .mathfrak,
+.katex .textfrak {
+ font-family: KaTeX_Fraktur;
+}
+.katex .mathtt {
+ font-family: KaTeX_Typewriter;
+}
+.katex .mathscr,
+.katex .textscr {
+ font-family: KaTeX_Script;
+}
+.katex .mathsf,
+.katex .textsf {
+ font-family: KaTeX_SansSerif;
+}
+.katex .mathboldsf,
+.katex .textboldsf {
+ font-family: KaTeX_SansSerif;
+ font-weight: bold;
+}
+.katex .mathitsf,
+.katex .textitsf {
+ font-family: KaTeX_SansSerif;
+ font-style: italic;
+}
+.katex .mainrm {
+ font-family: KaTeX_Main;
+ font-style: normal;
+}
+.katex .vlist-t {
+ display: inline-table;
+ table-layout: fixed;
+ border-collapse: collapse;
+}
+.katex .vlist-r {
+ display: table-row;
+}
+.katex .vlist {
+ display: table-cell;
+ vertical-align: bottom;
+ position: relative;
+}
+.katex .vlist > span {
+ display: block;
+ height: 0;
+ position: relative;
+}
+.katex .vlist > span > span {
+ display: inline-block;
+}
+.katex .vlist > span > .pstrut {
+ overflow: hidden;
+ width: 0;
+}
+.katex .vlist-t2 {
+ margin-right: -2px;
+}
+.katex .vlist-s {
+ display: table-cell;
+ vertical-align: bottom;
+ font-size: 1px;
+ width: 2px;
+ min-width: 2px;
+}
+.katex .vbox {
+ display: inline-flex;
+ flex-direction: column;
+ align-items: baseline;
+}
+.katex .hbox {
+ display: inline-flex;
+ flex-direction: row;
+ width: 100%;
+}
+.katex .thinbox {
+ display: inline-flex;
+ flex-direction: row;
+ width: 0;
+ max-width: 0;
+}
+.katex .msupsub {
+ text-align: left;
+}
+.katex .mfrac > span > span {
+ text-align: center;
+}
+.katex .mfrac .frac-line {
+ display: inline-block;
+ width: 100%;
+ border-bottom-style: solid;
+}
+.katex .mfrac .frac-line,
+.katex .overline .overline-line,
+.katex .underline .underline-line,
+.katex .hline,
+.katex .hdashline,
+.katex .rule {
+ min-height: 1px;
+}
+.katex .mspace {
+ display: inline-block;
+}
+.katex .llap,
+.katex .rlap,
+.katex .clap {
+ width: 0;
+ position: relative;
+}
+.katex .llap > .inner,
+.katex .rlap > .inner,
+.katex .clap > .inner {
+ position: absolute;
+}
+.katex .llap > .fix,
+.katex .rlap > .fix,
+.katex .clap > .fix {
+ display: inline-block;
+}
+.katex .llap > .inner {
+ right: 0;
+}
+.katex .rlap > .inner,
+.katex .clap > .inner {
+ left: 0;
+}
+.katex .clap > .inner > span {
+ margin-left: -50%;
+ margin-right: 50%;
+}
+.katex .rule {
+ display: inline-block;
+ border: solid 0;
+ position: relative;
+}
+.katex .overline .overline-line,
+.katex .underline .underline-line,
+.katex .hline {
+ display: inline-block;
+ width: 100%;
+ border-bottom-style: solid;
+}
+.katex .hdashline {
+ display: inline-block;
+ width: 100%;
+ border-bottom-style: dashed;
+}
+.katex .sqrt > .root {
+ /* These values are taken from the definition of `\r@@t`,
+ `\mkern 5mu` and `\mkern -10mu`. */
+ margin-left: 0.27777778em;
+ margin-right: -0.55555556em;
+}
+.katex .sizing.reset-size1.size1,
+.katex .fontsize-ensurer.reset-size1.size1 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size1.size2,
+.katex .fontsize-ensurer.reset-size1.size2 {
+ font-size: 1.2em;
+}
+.katex .sizing.reset-size1.size3,
+.katex .fontsize-ensurer.reset-size1.size3 {
+ font-size: 1.4em;
+}
+.katex .sizing.reset-size1.size4,
+.katex .fontsize-ensurer.reset-size1.size4 {
+ font-size: 1.6em;
+}
+.katex .sizing.reset-size1.size5,
+.katex .fontsize-ensurer.reset-size1.size5 {
+ font-size: 1.8em;
+}
+.katex .sizing.reset-size1.size6,
+.katex .fontsize-ensurer.reset-size1.size6 {
+ font-size: 2em;
+}
+.katex .sizing.reset-size1.size7,
+.katex .fontsize-ensurer.reset-size1.size7 {
+ font-size: 2.4em;
+}
+.katex .sizing.reset-size1.size8,
+.katex .fontsize-ensurer.reset-size1.size8 {
+ font-size: 2.88em;
+}
+.katex .sizing.reset-size1.size9,
+.katex .fontsize-ensurer.reset-size1.size9 {
+ font-size: 3.456em;
+}
+.katex .sizing.reset-size1.size10,
+.katex .fontsize-ensurer.reset-size1.size10 {
+ font-size: 4.148em;
+}
+.katex .sizing.reset-size1.size11,
+.katex .fontsize-ensurer.reset-size1.size11 {
+ font-size: 4.976em;
+}
+.katex .sizing.reset-size2.size1,
+.katex .fontsize-ensurer.reset-size2.size1 {
+ font-size: 0.83333333em;
+}
+.katex .sizing.reset-size2.size2,
+.katex .fontsize-ensurer.reset-size2.size2 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size2.size3,
+.katex .fontsize-ensurer.reset-size2.size3 {
+ font-size: 1.16666667em;
+}
+.katex .sizing.reset-size2.size4,
+.katex .fontsize-ensurer.reset-size2.size4 {
+ font-size: 1.33333333em;
+}
+.katex .sizing.reset-size2.size5,
+.katex .fontsize-ensurer.reset-size2.size5 {
+ font-size: 1.5em;
+}
+.katex .sizing.reset-size2.size6,
+.katex .fontsize-ensurer.reset-size2.size6 {
+ font-size: 1.66666667em;
+}
+.katex .sizing.reset-size2.size7,
+.katex .fontsize-ensurer.reset-size2.size7 {
+ font-size: 2em;
+}
+.katex .sizing.reset-size2.size8,
+.katex .fontsize-ensurer.reset-size2.size8 {
+ font-size: 2.4em;
+}
+.katex .sizing.reset-size2.size9,
+.katex .fontsize-ensurer.reset-size2.size9 {
+ font-size: 2.88em;
+}
+.katex .sizing.reset-size2.size10,
+.katex .fontsize-ensurer.reset-size2.size10 {
+ font-size: 3.45666667em;
+}
+.katex .sizing.reset-size2.size11,
+.katex .fontsize-ensurer.reset-size2.size11 {
+ font-size: 4.14666667em;
+}
+.katex .sizing.reset-size3.size1,
+.katex .fontsize-ensurer.reset-size3.size1 {
+ font-size: 0.71428571em;
+}
+.katex .sizing.reset-size3.size2,
+.katex .fontsize-ensurer.reset-size3.size2 {
+ font-size: 0.85714286em;
+}
+.katex .sizing.reset-size3.size3,
+.katex .fontsize-ensurer.reset-size3.size3 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size3.size4,
+.katex .fontsize-ensurer.reset-size3.size4 {
+ font-size: 1.14285714em;
+}
+.katex .sizing.reset-size3.size5,
+.katex .fontsize-ensurer.reset-size3.size5 {
+ font-size: 1.28571429em;
+}
+.katex .sizing.reset-size3.size6,
+.katex .fontsize-ensurer.reset-size3.size6 {
+ font-size: 1.42857143em;
+}
+.katex .sizing.reset-size3.size7,
+.katex .fontsize-ensurer.reset-size3.size7 {
+ font-size: 1.71428571em;
+}
+.katex .sizing.reset-size3.size8,
+.katex .fontsize-ensurer.reset-size3.size8 {
+ font-size: 2.05714286em;
+}
+.katex .sizing.reset-size3.size9,
+.katex .fontsize-ensurer.reset-size3.size9 {
+ font-size: 2.46857143em;
+}
+.katex .sizing.reset-size3.size10,
+.katex .fontsize-ensurer.reset-size3.size10 {
+ font-size: 2.96285714em;
+}
+.katex .sizing.reset-size3.size11,
+.katex .fontsize-ensurer.reset-size3.size11 {
+ font-size: 3.55428571em;
+}
+.katex .sizing.reset-size4.size1,
+.katex .fontsize-ensurer.reset-size4.size1 {
+ font-size: 0.625em;
+}
+.katex .sizing.reset-size4.size2,
+.katex .fontsize-ensurer.reset-size4.size2 {
+ font-size: 0.75em;
+}
+.katex .sizing.reset-size4.size3,
+.katex .fontsize-ensurer.reset-size4.size3 {
+ font-size: 0.875em;
+}
+.katex .sizing.reset-size4.size4,
+.katex .fontsize-ensurer.reset-size4.size4 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size4.size5,
+.katex .fontsize-ensurer.reset-size4.size5 {
+ font-size: 1.125em;
+}
+.katex .sizing.reset-size4.size6,
+.katex .fontsize-ensurer.reset-size4.size6 {
+ font-size: 1.25em;
+}
+.katex .sizing.reset-size4.size7,
+.katex .fontsize-ensurer.reset-size4.size7 {
+ font-size: 1.5em;
+}
+.katex .sizing.reset-size4.size8,
+.katex .fontsize-ensurer.reset-size4.size8 {
+ font-size: 1.8em;
+}
+.katex .sizing.reset-size4.size9,
+.katex .fontsize-ensurer.reset-size4.size9 {
+ font-size: 2.16em;
+}
+.katex .sizing.reset-size4.size10,
+.katex .fontsize-ensurer.reset-size4.size10 {
+ font-size: 2.5925em;
+}
+.katex .sizing.reset-size4.size11,
+.katex .fontsize-ensurer.reset-size4.size11 {
+ font-size: 3.11em;
+}
+.katex .sizing.reset-size5.size1,
+.katex .fontsize-ensurer.reset-size5.size1 {
+ font-size: 0.55555556em;
+}
+.katex .sizing.reset-size5.size2,
+.katex .fontsize-ensurer.reset-size5.size2 {
+ font-size: 0.66666667em;
+}
+.katex .sizing.reset-size5.size3,
+.katex .fontsize-ensurer.reset-size5.size3 {
+ font-size: 0.77777778em;
+}
+.katex .sizing.reset-size5.size4,
+.katex .fontsize-ensurer.reset-size5.size4 {
+ font-size: 0.88888889em;
+}
+.katex .sizing.reset-size5.size5,
+.katex .fontsize-ensurer.reset-size5.size5 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size5.size6,
+.katex .fontsize-ensurer.reset-size5.size6 {
+ font-size: 1.11111111em;
+}
+.katex .sizing.reset-size5.size7,
+.katex .fontsize-ensurer.reset-size5.size7 {
+ font-size: 1.33333333em;
+}
+.katex .sizing.reset-size5.size8,
+.katex .fontsize-ensurer.reset-size5.size8 {
+ font-size: 1.6em;
+}
+.katex .sizing.reset-size5.size9,
+.katex .fontsize-ensurer.reset-size5.size9 {
+ font-size: 1.92em;
+}
+.katex .sizing.reset-size5.size10,
+.katex .fontsize-ensurer.reset-size5.size10 {
+ font-size: 2.30444444em;
+}
+.katex .sizing.reset-size5.size11,
+.katex .fontsize-ensurer.reset-size5.size11 {
+ font-size: 2.76444444em;
+}
+.katex .sizing.reset-size6.size1,
+.katex .fontsize-ensurer.reset-size6.size1 {
+ font-size: 0.5em;
+}
+.katex .sizing.reset-size6.size2,
+.katex .fontsize-ensurer.reset-size6.size2 {
+ font-size: 0.6em;
+}
+.katex .sizing.reset-size6.size3,
+.katex .fontsize-ensurer.reset-size6.size3 {
+ font-size: 0.7em;
+}
+.katex .sizing.reset-size6.size4,
+.katex .fontsize-ensurer.reset-size6.size4 {
+ font-size: 0.8em;
+}
+.katex .sizing.reset-size6.size5,
+.katex .fontsize-ensurer.reset-size6.size5 {
+ font-size: 0.9em;
+}
+.katex .sizing.reset-size6.size6,
+.katex .fontsize-ensurer.reset-size6.size6 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size6.size7,
+.katex .fontsize-ensurer.reset-size6.size7 {
+ font-size: 1.2em;
+}
+.katex .sizing.reset-size6.size8,
+.katex .fontsize-ensurer.reset-size6.size8 {
+ font-size: 1.44em;
+}
+.katex .sizing.reset-size6.size9,
+.katex .fontsize-ensurer.reset-size6.size9 {
+ font-size: 1.728em;
+}
+.katex .sizing.reset-size6.size10,
+.katex .fontsize-ensurer.reset-size6.size10 {
+ font-size: 2.074em;
+}
+.katex .sizing.reset-size6.size11,
+.katex .fontsize-ensurer.reset-size6.size11 {
+ font-size: 2.488em;
+}
+.katex .sizing.reset-size7.size1,
+.katex .fontsize-ensurer.reset-size7.size1 {
+ font-size: 0.41666667em;
+}
+.katex .sizing.reset-size7.size2,
+.katex .fontsize-ensurer.reset-size7.size2 {
+ font-size: 0.5em;
+}
+.katex .sizing.reset-size7.size3,
+.katex .fontsize-ensurer.reset-size7.size3 {
+ font-size: 0.58333333em;
+}
+.katex .sizing.reset-size7.size4,
+.katex .fontsize-ensurer.reset-size7.size4 {
+ font-size: 0.66666667em;
+}
+.katex .sizing.reset-size7.size5,
+.katex .fontsize-ensurer.reset-size7.size5 {
+ font-size: 0.75em;
+}
+.katex .sizing.reset-size7.size6,
+.katex .fontsize-ensurer.reset-size7.size6 {
+ font-size: 0.83333333em;
+}
+.katex .sizing.reset-size7.size7,
+.katex .fontsize-ensurer.reset-size7.size7 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size7.size8,
+.katex .fontsize-ensurer.reset-size7.size8 {
+ font-size: 1.2em;
+}
+.katex .sizing.reset-size7.size9,
+.katex .fontsize-ensurer.reset-size7.size9 {
+ font-size: 1.44em;
+}
+.katex .sizing.reset-size7.size10,
+.katex .fontsize-ensurer.reset-size7.size10 {
+ font-size: 1.72833333em;
+}
+.katex .sizing.reset-size7.size11,
+.katex .fontsize-ensurer.reset-size7.size11 {
+ font-size: 2.07333333em;
+}
+.katex .sizing.reset-size8.size1,
+.katex .fontsize-ensurer.reset-size8.size1 {
+ font-size: 0.34722222em;
+}
+.katex .sizing.reset-size8.size2,
+.katex .fontsize-ensurer.reset-size8.size2 {
+ font-size: 0.41666667em;
+}
+.katex .sizing.reset-size8.size3,
+.katex .fontsize-ensurer.reset-size8.size3 {
+ font-size: 0.48611111em;
+}
+.katex .sizing.reset-size8.size4,
+.katex .fontsize-ensurer.reset-size8.size4 {
+ font-size: 0.55555556em;
+}
+.katex .sizing.reset-size8.size5,
+.katex .fontsize-ensurer.reset-size8.size5 {
+ font-size: 0.625em;
+}
+.katex .sizing.reset-size8.size6,
+.katex .fontsize-ensurer.reset-size8.size6 {
+ font-size: 0.69444444em;
+}
+.katex .sizing.reset-size8.size7,
+.katex .fontsize-ensurer.reset-size8.size7 {
+ font-size: 0.83333333em;
+}
+.katex .sizing.reset-size8.size8,
+.katex .fontsize-ensurer.reset-size8.size8 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size8.size9,
+.katex .fontsize-ensurer.reset-size8.size9 {
+ font-size: 1.2em;
+}
+.katex .sizing.reset-size8.size10,
+.katex .fontsize-ensurer.reset-size8.size10 {
+ font-size: 1.44027778em;
+}
+.katex .sizing.reset-size8.size11,
+.katex .fontsize-ensurer.reset-size8.size11 {
+ font-size: 1.72777778em;
+}
+.katex .sizing.reset-size9.size1,
+.katex .fontsize-ensurer.reset-size9.size1 {
+ font-size: 0.28935185em;
+}
+.katex .sizing.reset-size9.size2,
+.katex .fontsize-ensurer.reset-size9.size2 {
+ font-size: 0.34722222em;
+}
+.katex .sizing.reset-size9.size3,
+.katex .fontsize-ensurer.reset-size9.size3 {
+ font-size: 0.40509259em;
+}
+.katex .sizing.reset-size9.size4,
+.katex .fontsize-ensurer.reset-size9.size4 {
+ font-size: 0.46296296em;
+}
+.katex .sizing.reset-size9.size5,
+.katex .fontsize-ensurer.reset-size9.size5 {
+ font-size: 0.52083333em;
+}
+.katex .sizing.reset-size9.size6,
+.katex .fontsize-ensurer.reset-size9.size6 {
+ font-size: 0.5787037em;
+}
+.katex .sizing.reset-size9.size7,
+.katex .fontsize-ensurer.reset-size9.size7 {
+ font-size: 0.69444444em;
+}
+.katex .sizing.reset-size9.size8,
+.katex .fontsize-ensurer.reset-size9.size8 {
+ font-size: 0.83333333em;
+}
+.katex .sizing.reset-size9.size9,
+.katex .fontsize-ensurer.reset-size9.size9 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size9.size10,
+.katex .fontsize-ensurer.reset-size9.size10 {
+ font-size: 1.20023148em;
+}
+.katex .sizing.reset-size9.size11,
+.katex .fontsize-ensurer.reset-size9.size11 {
+ font-size: 1.43981481em;
+}
+.katex .sizing.reset-size10.size1,
+.katex .fontsize-ensurer.reset-size10.size1 {
+ font-size: 0.24108004em;
+}
+.katex .sizing.reset-size10.size2,
+.katex .fontsize-ensurer.reset-size10.size2 {
+ font-size: 0.28929605em;
+}
+.katex .sizing.reset-size10.size3,
+.katex .fontsize-ensurer.reset-size10.size3 {
+ font-size: 0.33751205em;
+}
+.katex .sizing.reset-size10.size4,
+.katex .fontsize-ensurer.reset-size10.size4 {
+ font-size: 0.38572806em;
+}
+.katex .sizing.reset-size10.size5,
+.katex .fontsize-ensurer.reset-size10.size5 {
+ font-size: 0.43394407em;
+}
+.katex .sizing.reset-size10.size6,
+.katex .fontsize-ensurer.reset-size10.size6 {
+ font-size: 0.48216008em;
+}
+.katex .sizing.reset-size10.size7,
+.katex .fontsize-ensurer.reset-size10.size7 {
+ font-size: 0.57859209em;
+}
+.katex .sizing.reset-size10.size8,
+.katex .fontsize-ensurer.reset-size10.size8 {
+ font-size: 0.69431051em;
+}
+.katex .sizing.reset-size10.size9,
+.katex .fontsize-ensurer.reset-size10.size9 {
+ font-size: 0.83317261em;
+}
+.katex .sizing.reset-size10.size10,
+.katex .fontsize-ensurer.reset-size10.size10 {
+ font-size: 1em;
+}
+.katex .sizing.reset-size10.size11,
+.katex .fontsize-ensurer.reset-size10.size11 {
+ font-size: 1.19961427em;
+}
+.katex .sizing.reset-size11.size1,
+.katex .fontsize-ensurer.reset-size11.size1 {
+ font-size: 0.20096463em;
+}
+.katex .sizing.reset-size11.size2,
+.katex .fontsize-ensurer.reset-size11.size2 {
+ font-size: 0.24115756em;
+}
+.katex .sizing.reset-size11.size3,
+.katex .fontsize-ensurer.reset-size11.size3 {
+ font-size: 0.28135048em;
+}
+.katex .sizing.reset-size11.size4,
+.katex .fontsize-ensurer.reset-size11.size4 {
+ font-size: 0.32154341em;
+}
+.katex .sizing.reset-size11.size5,
+.katex .fontsize-ensurer.reset-size11.size5 {
+ font-size: 0.36173633em;
+}
+.katex .sizing.reset-size11.size6,
+.katex .fontsize-ensurer.reset-size11.size6 {
+ font-size: 0.40192926em;
+}
+.katex .sizing.reset-size11.size7,
+.katex .fontsize-ensurer.reset-size11.size7 {
+ font-size: 0.48231511em;
+}
+.katex .sizing.reset-size11.size8,
+.katex .fontsize-ensurer.reset-size11.size8 {
+ font-size: 0.57877814em;
+}
+.katex .sizing.reset-size11.size9,
+.katex .fontsize-ensurer.reset-size11.size9 {
+ font-size: 0.69453376em;
+}
+.katex .sizing.reset-size11.size10,
+.katex .fontsize-ensurer.reset-size11.size10 {
+ font-size: 0.83360129em;
+}
+.katex .sizing.reset-size11.size11,
+.katex .fontsize-ensurer.reset-size11.size11 {
+ font-size: 1em;
+}
+.katex .delimsizing.size1 {
+ font-family: KaTeX_Size1;
+}
+.katex .delimsizing.size2 {
+ font-family: KaTeX_Size2;
+}
+.katex .delimsizing.size3 {
+ font-family: KaTeX_Size3;
+}
+.katex .delimsizing.size4 {
+ font-family: KaTeX_Size4;
+}
+.katex .delimsizing.mult .delim-size1 > span {
+ font-family: KaTeX_Size1;
+}
+.katex .delimsizing.mult .delim-size4 > span {
+ font-family: KaTeX_Size4;
+}
+.katex .nulldelimiter {
+ display: inline-block;
+ width: 0.12em;
+}
+.katex .delimcenter {
+ position: relative;
+}
+.katex .op-symbol {
+ position: relative;
+}
+.katex .op-symbol.small-op {
+ font-family: KaTeX_Size1;
+}
+.katex .op-symbol.large-op {
+ font-family: KaTeX_Size2;
+}
+.katex .op-limits > .vlist-t {
+ text-align: center;
+}
+.katex .accent > .vlist-t {
+ text-align: center;
+}
+.katex .accent .accent-body {
+ position: relative;
+}
+.katex .accent .accent-body:not(.accent-full) {
+ width: 0;
+}
+.katex .overlay {
+ display: block;
+}
+.katex .mtable .vertical-separator {
+ display: inline-block;
+ min-width: 1px;
+}
+.katex .mtable .arraycolsep {
+ display: inline-block;
+}
+.katex .mtable .col-align-c > .vlist-t {
+ text-align: center;
+}
+.katex .mtable .col-align-l > .vlist-t {
+ text-align: left;
+}
+.katex .mtable .col-align-r > .vlist-t {
+ text-align: right;
+}
+.katex .svg-align {
+ text-align: left;
+}
+.katex svg {
+ display: block;
+ position: absolute;
+ width: 100%;
+ height: inherit;
+ fill: currentColor;
+ stroke: currentColor;
+ fill-rule: nonzero;
+ fill-opacity: 1;
+ stroke-width: 1;
+ stroke-linecap: butt;
+ stroke-linejoin: miter;
+ stroke-miterlimit: 4;
+ stroke-dasharray: none;
+ stroke-dashoffset: 0;
+ stroke-opacity: 1;
+}
+.katex svg path {
+ stroke: none;
+}
+.katex img {
+ border-style: none;
+ min-width: 0;
+ min-height: 0;
+ max-width: none;
+ max-height: none;
+}
+.katex .stretchy {
+ width: 100%;
+ display: block;
+ position: relative;
+ overflow: hidden;
+}
+.katex .stretchy::before,
+.katex .stretchy::after {
+ content: "";
+}
+.katex .hide-tail {
+ width: 100%;
+ position: relative;
+ overflow: hidden;
+}
+.katex .halfarrow-left {
+ position: absolute;
+ left: 0;
+ width: 50.2%;
+ overflow: hidden;
+}
+.katex .halfarrow-right {
+ position: absolute;
+ right: 0;
+ width: 50.2%;
+ overflow: hidden;
+}
+.katex .brace-left {
+ position: absolute;
+ left: 0;
+ width: 25.1%;
+ overflow: hidden;
+}
+.katex .brace-center {
+ position: absolute;
+ left: 25%;
+ width: 50%;
+ overflow: hidden;
+}
+.katex .brace-right {
+ position: absolute;
+ right: 0;
+ width: 25.1%;
+ overflow: hidden;
+}
+.katex .x-arrow-pad {
+ padding: 0 0.5em;
+}
+.katex .cd-arrow-pad {
+ padding: 0 0.55556em 0 0.27778em;
+}
+.katex .x-arrow,
+.katex .mover,
+.katex .munder {
+ text-align: center;
+}
+.katex .boxpad {
+ padding: 0 0.3em;
+}
+.katex .fbox,
+.katex .fcolorbox {
+ box-sizing: border-box;
+ border: 0.04em solid;
+}
+.katex .cancel-pad {
+ padding: 0 0.2em;
+}
+.katex .cancel-lap {
+ margin-left: -0.2em;
+ margin-right: -0.2em;
+}
+.katex .sout {
+ border-bottom-style: solid;
+ border-bottom-width: 0.08em;
+}
+.katex .angl {
+ box-sizing: border-box;
+ border-top: 0.049em solid;
+ border-right: 0.049em solid;
+ margin-right: 0.03889em;
+}
+.katex .anglpad {
+ padding: 0 0.03889em;
+}
+.katex .eqn-num::before {
+ counter-increment: katexEqnNo;
+ content: "(" counter(katexEqnNo) ")";
+}
+.katex .mml-eqn-num::before {
+ counter-increment: mmlEqnNo;
+ content: "(" counter(mmlEqnNo) ")";
+}
+.katex .mtr-glue {
+ width: 50%;
+}
+.katex .cd-vert-arrow {
+ display: inline-block;
+ position: relative;
+}
+.katex .cd-label-left {
+ display: inline-block;
+ position: absolute;
+ right: calc(50% + 0.3em);
+ text-align: left;
+}
+.katex .cd-label-right {
+ display: inline-block;
+ position: absolute;
+ left: calc(50% + 0.3em);
+ text-align: right;
+}
+.katex-display {
+ display: block;
+ margin: 1em 0;
+ text-align: center;
+}
+.katex-display > .katex {
+ display: block;
+ text-align: center;
+ white-space: nowrap;
+}
+.katex-display > .katex > .katex-html {
+ display: block;
+ position: relative;
+}
+.katex-display > .katex > .katex-html > .tag {
+ position: absolute;
+ right: 0;
+}
+.katex-display.leqno > .katex > .katex-html > .tag {
+ left: 0;
+ right: auto;
+}
+.katex-display.fleqn > .katex {
+ text-align: left;
+ padding-left: 2em;
+}
+body {
+ counter-reset: katexEqnNo mmlEqnNo;
+}
+
diff --git a/static/katex/katex.js b/static/katex/katex.js
new file mode 100644
index 0000000..ab4956b
--- /dev/null
+++ b/static/katex/katex.js
@@ -0,0 +1,18456 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define([], factory);
+ else if(typeof exports === 'object')
+ exports["katex"] = factory();
+ else
+ root["katex"] = factory();
+})((typeof self !== 'undefined' ? self : this), function() {
+return /******/ (function() { // webpackBootstrap
+/******/ "use strict";
+/******/ // The require scope
+/******/ var __webpack_require__ = {};
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/define property getters */
+/******/ !function() {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = function(exports, definition) {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ !function() {
+/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
+/******/ }();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, {
+ "default": function() { return /* binding */ katex_webpack; }
+});
+
+;// CONCATENATED MODULE: ./src/ParseError.js
+
+
+/**
+ * This is the ParseError class, which is the main error thrown by KaTeX
+ * functions when something has gone wrong. This is used to distinguish internal
+ * errors from errors in the expression that the user provided.
+ *
+ * If possible, a caller should provide a Token or ParseNode with information
+ * about where in the source string the problem occurred.
+ */
+var ParseError = // Error position based on passed-in Token or ParseNode.
+function ParseError(message, // The error message
+token // An object providing position information
+) {
+ this.position = void 0;
+ var error = "KaTeX parse error: " + message;
+ var start;
+ var loc = token && token.loc;
+
+ if (loc && loc.start <= loc.end) {
+ // If we have the input and a position, make the error a bit fancier
+ // Get the input
+ var input = loc.lexer.input; // Prepend some information
+
+ start = loc.start;
+ var end = loc.end;
+
+ if (start === input.length) {
+ error += " at end of input: ";
+ } else {
+ error += " at position " + (start + 1) + ": ";
+ } // Underline token in question using combining underscores
+
+
+ var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332"); // Extract some context from the input and add it to the error
+
+ var left;
+
+ if (start > 15) {
+ left = "…" + input.slice(start - 15, start);
+ } else {
+ left = input.slice(0, start);
+ }
+
+ var right;
+
+ if (end + 15 < input.length) {
+ right = input.slice(end, end + 15) + "…";
+ } else {
+ right = input.slice(end);
+ }
+
+ error += left + underlined + right;
+ } // Some hackery to make ParseError a prototype of Error
+ // See http://stackoverflow.com/a/8460753
+
+
+ var self = new Error(error);
+ self.name = "ParseError"; // $FlowFixMe
+
+ self.__proto__ = ParseError.prototype; // $FlowFixMe
+
+ self.position = start;
+ return self;
+}; // $FlowFixMe More hackery
+
+
+ParseError.prototype.__proto__ = Error.prototype;
+/* harmony default export */ var src_ParseError = (ParseError);
+;// CONCATENATED MODULE: ./src/utils.js
+/**
+ * This file contains a list of utility functions which are useful in other
+ * files.
+ */
+
+/**
+ * Return whether an element is contained in a list
+ */
+var contains = function contains(list, elem) {
+ return list.indexOf(elem) !== -1;
+};
+/**
+ * Provide a default value if a setting is undefined
+ * NOTE: Couldn't use `T` as the output type due to facebook/flow#5022.
+ */
+
+
+var deflt = function deflt(setting, defaultIfUndefined) {
+ return setting === undefined ? defaultIfUndefined : setting;
+}; // hyphenate and escape adapted from Facebook's React under Apache 2 license
+
+
+var uppercase = /([A-Z])/g;
+
+var hyphenate = function hyphenate(str) {
+ return str.replace(uppercase, "-$1").toLowerCase();
+};
+
+var ESCAPE_LOOKUP = {
+ "&": "&",
+ ">": ">",
+ "<": "<",
+ "\"": """,
+ "'": "'"
+};
+var ESCAPE_REGEX = /[&><"']/g;
+/**
+ * Escapes text to prevent scripting attacks.
+ */
+
+function utils_escape(text) {
+ return String(text).replace(ESCAPE_REGEX, function (match) {
+ return ESCAPE_LOOKUP[match];
+ });
+}
+/**
+ * Sometimes we want to pull out the innermost element of a group. In most
+ * cases, this will just be the group itself, but when ordgroups and colors have
+ * a single element, we want to pull that out.
+ */
+
+
+var getBaseElem = function getBaseElem(group) {
+ if (group.type === "ordgroup") {
+ if (group.body.length === 1) {
+ return getBaseElem(group.body[0]);
+ } else {
+ return group;
+ }
+ } else if (group.type === "color") {
+ if (group.body.length === 1) {
+ return getBaseElem(group.body[0]);
+ } else {
+ return group;
+ }
+ } else if (group.type === "font") {
+ return getBaseElem(group.body);
+ } else {
+ return group;
+ }
+};
+/**
+ * TeXbook algorithms often reference "character boxes", which are simply groups
+ * with a single character in them. To decide if something is a character box,
+ * we find its innermost group, and see if it is a single character.
+ */
+
+
+var isCharacterBox = function isCharacterBox(group) {
+ var baseElem = getBaseElem(group); // These are all they types of groups which hold single characters
+
+ return baseElem.type === "mathord" || baseElem.type === "textord" || baseElem.type === "atom";
+};
+
+var assert = function assert(value) {
+ if (!value) {
+ throw new Error('Expected non-null, but got ' + String(value));
+ }
+
+ return value;
+};
+/**
+ * Return the protocol of a URL, or "_relative" if the URL does not specify a
+ * protocol (and thus is relative).
+ */
+
+var protocolFromUrl = function protocolFromUrl(url) {
+ var protocol = /^\s*([^\\/#]*?)(?::|*58|*3a)/i.exec(url);
+ return protocol != null ? protocol[1] : "_relative";
+};
+/* harmony default export */ var utils = ({
+ contains: contains,
+ deflt: deflt,
+ escape: utils_escape,
+ hyphenate: hyphenate,
+ getBaseElem: getBaseElem,
+ isCharacterBox: isCharacterBox,
+ protocolFromUrl: protocolFromUrl
+});
+;// CONCATENATED MODULE: ./src/Settings.js
+/* eslint no-console:0 */
+
+/**
+ * This is a module for storing settings passed into KaTeX. It correctly handles
+ * default settings.
+ */
+
+
+
+// TODO: automatically generate documentation
+// TODO: check all properties on Settings exist
+// TODO: check the type of a property on Settings matches
+var SETTINGS_SCHEMA = {
+ displayMode: {
+ type: "boolean",
+ description: "Render math in display mode, which puts the math in " + "display style (so \\int and \\sum are large, for example), and " + "centers the math on the page on its own line.",
+ cli: "-d, --display-mode"
+ },
+ output: {
+ type: {
+ enum: ["htmlAndMathml", "html", "mathml"]
+ },
+ description: "Determines the markup language of the output.",
+ cli: "-F, --format "
+ },
+ leqno: {
+ type: "boolean",
+ description: "Render display math in leqno style (left-justified tags)."
+ },
+ fleqn: {
+ type: "boolean",
+ description: "Render display math flush left."
+ },
+ throwOnError: {
+ type: "boolean",
+ default: true,
+ cli: "-t, --no-throw-on-error",
+ cliDescription: "Render errors (in the color given by --error-color) ins" + "tead of throwing a ParseError exception when encountering an error."
+ },
+ errorColor: {
+ type: "string",
+ default: "#cc0000",
+ cli: "-c, --error-color ",
+ cliDescription: "A color string given in the format 'rgb' or 'rrggbb' " + "(no #). This option determines the color of errors rendered by the " + "-t option.",
+ cliProcessor: function cliProcessor(color) {
+ return "#" + color;
+ }
+ },
+ macros: {
+ type: "object",
+ cli: "-m, --macro ",
+ cliDescription: "Define custom macro of the form '\\foo:expansion' (use " + "multiple -m arguments for multiple macros).",
+ cliDefault: [],
+ cliProcessor: function cliProcessor(def, defs) {
+ defs.push(def);
+ return defs;
+ }
+ },
+ minRuleThickness: {
+ type: "number",
+ description: "Specifies a minimum thickness, in ems, for fraction lines," + " `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, " + "`\\hdashline`, `\\underline`, `\\overline`, and the borders of " + "`\\fbox`, `\\boxed`, and `\\fcolorbox`.",
+ processor: function processor(t) {
+ return Math.max(0, t);
+ },
+ cli: "--min-rule-thickness ",
+ cliProcessor: parseFloat
+ },
+ colorIsTextColor: {
+ type: "boolean",
+ description: "Makes \\color behave like LaTeX's 2-argument \\textcolor, " + "instead of LaTeX's one-argument \\color mode change.",
+ cli: "-b, --color-is-text-color"
+ },
+ strict: {
+ type: [{
+ enum: ["warn", "ignore", "error"]
+ }, "boolean", "function"],
+ description: "Turn on strict / LaTeX faithfulness mode, which throws an " + "error if the input uses features that are not supported by LaTeX.",
+ cli: "-S, --strict",
+ cliDefault: false
+ },
+ trust: {
+ type: ["boolean", "function"],
+ description: "Trust the input, enabling all HTML features such as \\url.",
+ cli: "-T, --trust"
+ },
+ maxSize: {
+ type: "number",
+ default: Infinity,
+ description: "If non-zero, all user-specified sizes, e.g. in " + "\\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, " + "elements and spaces can be arbitrarily large",
+ processor: function processor(s) {
+ return Math.max(0, s);
+ },
+ cli: "-s, --max-size ",
+ cliProcessor: parseInt
+ },
+ maxExpand: {
+ type: "number",
+ default: 1000,
+ description: "Limit the number of macro expansions to the specified " + "number, to prevent e.g. infinite macro loops. If set to Infinity, " + "the macro expander will try to fully expand as in LaTeX.",
+ processor: function processor(n) {
+ return Math.max(0, n);
+ },
+ cli: "-e, --max-expand ",
+ cliProcessor: function cliProcessor(n) {
+ return n === "Infinity" ? Infinity : parseInt(n);
+ }
+ },
+ globalGroup: {
+ type: "boolean",
+ cli: false
+ }
+};
+
+function getDefaultValue(schema) {
+ if (schema.default) {
+ return schema.default;
+ }
+
+ var type = schema.type;
+ var defaultType = Array.isArray(type) ? type[0] : type;
+
+ if (typeof defaultType !== 'string') {
+ return defaultType.enum[0];
+ }
+
+ switch (defaultType) {
+ case 'boolean':
+ return false;
+
+ case 'string':
+ return '';
+
+ case 'number':
+ return 0;
+
+ case 'object':
+ return {};
+ }
+}
+/**
+ * The main Settings object
+ *
+ * The current options stored are:
+ * - displayMode: Whether the expression should be typeset as inline math
+ * (false, the default), meaning that the math starts in
+ * \textstyle and is placed in an inline-block); or as display
+ * math (true), meaning that the math starts in \displaystyle
+ * and is placed in a block with vertical margin.
+ */
+
+
+var Settings = /*#__PURE__*/function () {
+ function Settings(options) {
+ this.displayMode = void 0;
+ this.output = void 0;
+ this.leqno = void 0;
+ this.fleqn = void 0;
+ this.throwOnError = void 0;
+ this.errorColor = void 0;
+ this.macros = void 0;
+ this.minRuleThickness = void 0;
+ this.colorIsTextColor = void 0;
+ this.strict = void 0;
+ this.trust = void 0;
+ this.maxSize = void 0;
+ this.maxExpand = void 0;
+ this.globalGroup = void 0;
+ // allow null options
+ options = options || {};
+
+ for (var prop in SETTINGS_SCHEMA) {
+ if (SETTINGS_SCHEMA.hasOwnProperty(prop)) {
+ // $FlowFixMe
+ var schema = SETTINGS_SCHEMA[prop]; // TODO: validate options
+ // $FlowFixMe
+
+ this[prop] = options[prop] !== undefined ? schema.processor ? schema.processor(options[prop]) : options[prop] : getDefaultValue(schema);
+ }
+ }
+ }
+ /**
+ * Report nonstrict (non-LaTeX-compatible) input.
+ * Can safely not be called if `this.strict` is false in JavaScript.
+ */
+
+
+ var _proto = Settings.prototype;
+
+ _proto.reportNonstrict = function reportNonstrict(errorCode, errorMsg, token) {
+ var strict = this.strict;
+
+ if (typeof strict === "function") {
+ // Allow return value of strict function to be boolean or string
+ // (or null/undefined, meaning no further processing).
+ strict = strict(errorCode, errorMsg, token);
+ }
+
+ if (!strict || strict === "ignore") {
+ return;
+ } else if (strict === true || strict === "error") {
+ throw new src_ParseError("LaTeX-incompatible input and strict mode is set to 'error': " + (errorMsg + " [" + errorCode + "]"), token);
+ } else if (strict === "warn") {
+ typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]"));
+ } else {
+ // won't happen in type-safe code
+ typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]"));
+ }
+ }
+ /**
+ * Check whether to apply strict (LaTeX-adhering) behavior for unusual
+ * input (like `\\`). Unlike `nonstrict`, will not throw an error;
+ * instead, "error" translates to a return value of `true`, while "ignore"
+ * translates to a return value of `false`. May still print a warning:
+ * "warn" prints a warning and returns `false`.
+ * This is for the second category of `errorCode`s listed in the README.
+ */
+ ;
+
+ _proto.useStrictBehavior = function useStrictBehavior(errorCode, errorMsg, token) {
+ var strict = this.strict;
+
+ if (typeof strict === "function") {
+ // Allow return value of strict function to be boolean or string
+ // (or null/undefined, meaning no further processing).
+ // But catch any exceptions thrown by function, treating them
+ // like "error".
+ try {
+ strict = strict(errorCode, errorMsg, token);
+ } catch (error) {
+ strict = "error";
+ }
+ }
+
+ if (!strict || strict === "ignore") {
+ return false;
+ } else if (strict === true || strict === "error") {
+ return true;
+ } else if (strict === "warn") {
+ typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]"));
+ return false;
+ } else {
+ // won't happen in type-safe code
+ typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]"));
+ return false;
+ }
+ }
+ /**
+ * Check whether to test potentially dangerous input, and return
+ * `true` (trusted) or `false` (untrusted). The sole argument `context`
+ * should be an object with `command` field specifying the relevant LaTeX
+ * command (as a string starting with `\`), and any other arguments, etc.
+ * If `context` has a `url` field, a `protocol` field will automatically
+ * get added by this function (changing the specified object).
+ */
+ ;
+
+ _proto.isTrusted = function isTrusted(context) {
+ if (context.url && !context.protocol) {
+ context.protocol = utils.protocolFromUrl(context.url);
+ }
+
+ var trust = typeof this.trust === "function" ? this.trust(context) : this.trust;
+ return Boolean(trust);
+ };
+
+ return Settings;
+}();
+
+
+;// CONCATENATED MODULE: ./src/Style.js
+/**
+ * This file contains information and classes for the various kinds of styles
+ * used in TeX. It provides a generic `Style` class, which holds information
+ * about a specific style. It then provides instances of all the different kinds
+ * of styles possible, and provides functions to move between them and get
+ * information about them.
+ */
+
+/**
+ * The main style class. Contains a unique id for the style, a size (which is
+ * the same for cramped and uncramped version of a style), and a cramped flag.
+ */
+var Style = /*#__PURE__*/function () {
+ function Style(id, size, cramped) {
+ this.id = void 0;
+ this.size = void 0;
+ this.cramped = void 0;
+ this.id = id;
+ this.size = size;
+ this.cramped = cramped;
+ }
+ /**
+ * Get the style of a superscript given a base in the current style.
+ */
+
+
+ var _proto = Style.prototype;
+
+ _proto.sup = function sup() {
+ return styles[_sup[this.id]];
+ }
+ /**
+ * Get the style of a subscript given a base in the current style.
+ */
+ ;
+
+ _proto.sub = function sub() {
+ return styles[_sub[this.id]];
+ }
+ /**
+ * Get the style of a fraction numerator given the fraction in the current
+ * style.
+ */
+ ;
+
+ _proto.fracNum = function fracNum() {
+ return styles[_fracNum[this.id]];
+ }
+ /**
+ * Get the style of a fraction denominator given the fraction in the current
+ * style.
+ */
+ ;
+
+ _proto.fracDen = function fracDen() {
+ return styles[_fracDen[this.id]];
+ }
+ /**
+ * Get the cramped version of a style (in particular, cramping a cramped style
+ * doesn't change the style).
+ */
+ ;
+
+ _proto.cramp = function cramp() {
+ return styles[_cramp[this.id]];
+ }
+ /**
+ * Get a text or display version of this style.
+ */
+ ;
+
+ _proto.text = function text() {
+ return styles[_text[this.id]];
+ }
+ /**
+ * Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle)
+ */
+ ;
+
+ _proto.isTight = function isTight() {
+ return this.size >= 2;
+ };
+
+ return Style;
+}(); // Export an interface for type checking, but don't expose the implementation.
+// This way, no more styles can be generated.
+
+
+// IDs of the different styles
+var D = 0;
+var Dc = 1;
+var T = 2;
+var Tc = 3;
+var S = 4;
+var Sc = 5;
+var SS = 6;
+var SSc = 7; // Instances of the different styles
+
+var styles = [new Style(D, 0, false), new Style(Dc, 0, true), new Style(T, 1, false), new Style(Tc, 1, true), new Style(S, 2, false), new Style(Sc, 2, true), new Style(SS, 3, false), new Style(SSc, 3, true)]; // Lookup tables for switching from one style to another
+
+var _sup = [S, Sc, S, Sc, SS, SSc, SS, SSc];
+var _sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc];
+var _fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc];
+var _fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc];
+var _cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
+var _text = [D, Dc, T, Tc, T, Tc, T, Tc]; // We only export some of the styles.
+
+/* harmony default export */ var src_Style = ({
+ DISPLAY: styles[D],
+ TEXT: styles[T],
+ SCRIPT: styles[S],
+ SCRIPTSCRIPT: styles[SS]
+});
+;// CONCATENATED MODULE: ./src/unicodeScripts.js
+/*
+ * This file defines the Unicode scripts and script families that we
+ * support. To add new scripts or families, just add a new entry to the
+ * scriptData array below. Adding scripts to the scriptData array allows
+ * characters from that script to appear in \text{} environments.
+ */
+
+/**
+ * Each script or script family has a name and an array of blocks.
+ * Each block is an array of two numbers which specify the start and
+ * end points (inclusive) of a block of Unicode codepoints.
+ */
+
+/**
+ * Unicode block data for the families of scripts we support in \text{}.
+ * Scripts only need to appear here if they do not have font metrics.
+ */
+var scriptData = [{
+ // Latin characters beyond the Latin-1 characters we have metrics for.
+ // Needed for Czech, Hungarian and Turkish text, for example.
+ name: 'latin',
+ blocks: [[0x0100, 0x024f], // Latin Extended-A and Latin Extended-B
+ [0x0300, 0x036f] // Combining Diacritical marks
+ ]
+}, {
+ // The Cyrillic script used by Russian and related languages.
+ // A Cyrillic subset used to be supported as explicitly defined
+ // symbols in symbols.js
+ name: 'cyrillic',
+ blocks: [[0x0400, 0x04ff]]
+}, {
+ // Armenian
+ name: 'armenian',
+ blocks: [[0x0530, 0x058F]]
+}, {
+ // The Brahmic scripts of South and Southeast Asia
+ // Devanagari (0900–097F)
+ // Bengali (0980–09FF)
+ // Gurmukhi (0A00–0A7F)
+ // Gujarati (0A80–0AFF)
+ // Oriya (0B00–0B7F)
+ // Tamil (0B80–0BFF)
+ // Telugu (0C00–0C7F)
+ // Kannada (0C80–0CFF)
+ // Malayalam (0D00–0D7F)
+ // Sinhala (0D80–0DFF)
+ // Thai (0E00–0E7F)
+ // Lao (0E80–0EFF)
+ // Tibetan (0F00–0FFF)
+ // Myanmar (1000–109F)
+ name: 'brahmic',
+ blocks: [[0x0900, 0x109F]]
+}, {
+ name: 'georgian',
+ blocks: [[0x10A0, 0x10ff]]
+}, {
+ // Chinese and Japanese.
+ // The "k" in cjk is for Korean, but we've separated Korean out
+ name: "cjk",
+ blocks: [[0x3000, 0x30FF], // CJK symbols and punctuation, Hiragana, Katakana
+ [0x4E00, 0x9FAF], // CJK ideograms
+ [0xFF00, 0xFF60] // Fullwidth punctuation
+ // TODO: add halfwidth Katakana and Romanji glyphs
+ ]
+}, {
+ // Korean
+ name: 'hangul',
+ blocks: [[0xAC00, 0xD7AF]]
+}];
+/**
+ * Given a codepoint, return the name of the script or script family
+ * it is from, or null if it is not part of a known block
+ */
+
+function scriptFromCodepoint(codepoint) {
+ for (var i = 0; i < scriptData.length; i++) {
+ var script = scriptData[i];
+
+ for (var _i = 0; _i < script.blocks.length; _i++) {
+ var block = script.blocks[_i];
+
+ if (codepoint >= block[0] && codepoint <= block[1]) {
+ return script.name;
+ }
+ }
+ }
+
+ return null;
+}
+/**
+ * A flattened version of all the supported blocks in a single array.
+ * This is an optimization to make supportedCodepoint() fast.
+ */
+
+var allBlocks = [];
+scriptData.forEach(function (s) {
+ return s.blocks.forEach(function (b) {
+ return allBlocks.push.apply(allBlocks, b);
+ });
+});
+/**
+ * Given a codepoint, return true if it falls within one of the
+ * scripts or script families defined above and false otherwise.
+ *
+ * Micro benchmarks shows that this is faster than
+ * /[\u3000-\u30FF\u4E00-\u9FAF\uFF00-\uFF60\uAC00-\uD7AF\u0900-\u109F]/.test()
+ * in Firefox, Chrome and Node.
+ */
+
+function supportedCodepoint(codepoint) {
+ for (var i = 0; i < allBlocks.length; i += 2) {
+ if (codepoint >= allBlocks[i] && codepoint <= allBlocks[i + 1]) {
+ return true;
+ }
+ }
+
+ return false;
+}
+;// CONCATENATED MODULE: ./src/svgGeometry.js
+/**
+ * This file provides support to domTree.js and delimiter.js.
+ * It's a storehouse of path geometry for SVG images.
+ */
+// In all paths below, the viewBox-to-em scale is 1000:1.
+var hLinePad = 80; // padding above a sqrt viniculum. Prevents image cropping.
+// The viniculum of a \sqrt can be made thicker by a KaTeX rendering option.
+// Think of variable extraViniculum as two detours in the SVG path.
+// The detour begins at the lower left of the area labeled extraViniculum below.
+// The detour proceeds one extraViniculum distance up and slightly to the right,
+// displacing the radiused corner between surd and viniculum. The radius is
+// traversed as usual, then the detour resumes. It goes right, to the end of
+// the very long viniculumn, then down one extraViniculum distance,
+// after which it resumes regular path geometry for the radical.
+
+/* viniculum
+ /
+ /▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒←extraViniculum
+ / █████████████████████←0.04em (40 unit) std viniculum thickness
+ / /
+ / /
+ / /\
+ / / surd
+*/
+
+var sqrtMain = function sqrtMain(extraViniculum, hLinePad) {
+ // sqrtMain path geometry is from glyph U221A in the font KaTeX Main
+ return "M95," + (622 + extraViniculum + hLinePad) + "\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl" + extraViniculum / 2.075 + " -" + extraViniculum + "\nc5.3,-9.3,12,-14,20,-14\nH400000v" + (40 + extraViniculum) + "H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM" + (834 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "h-400000z";
+};
+
+var sqrtSize1 = function sqrtSize1(extraViniculum, hLinePad) {
+ // size1 is from glyph U221A in the font KaTeX_Size1-Regular
+ return "M263," + (601 + extraViniculum + hLinePad) + "c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl" + extraViniculum / 2.084 + " -" + extraViniculum + "\nc4.7,-7.3,11,-11,19,-11\nH40000v" + (40 + extraViniculum) + "H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM" + (1001 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "h-400000z";
+};
+
+var sqrtSize2 = function sqrtSize2(extraViniculum, hLinePad) {
+ // size2 is from glyph U221A in the font KaTeX_Size2-Regular
+ return "M983 " + (10 + extraViniculum + hLinePad) + "\nl" + extraViniculum / 3.13 + " -" + extraViniculum + "\nc4,-6.7,10,-10,18,-10 H400000v" + (40 + extraViniculum) + "\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM" + (1001 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "h-400000z";
+};
+
+var sqrtSize3 = function sqrtSize3(extraViniculum, hLinePad) {
+ // size3 is from glyph U221A in the font KaTeX_Size3-Regular
+ return "M424," + (2398 + extraViniculum + hLinePad) + "\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl" + extraViniculum / 4.223 + " -" + extraViniculum + "c4,-6.7,10,-10,18,-10 H400000\nv" + (40 + extraViniculum) + "H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M" + (1001 + extraViniculum) + " " + hLinePad + "\nh400000v" + (40 + extraViniculum) + "h-400000z";
+};
+
+var sqrtSize4 = function sqrtSize4(extraViniculum, hLinePad) {
+ // size4 is from glyph U221A in the font KaTeX_Size4-Regular
+ return "M473," + (2713 + extraViniculum + hLinePad) + "\nc339.3,-1799.3,509.3,-2700,510,-2702 l" + extraViniculum / 5.298 + " -" + extraViniculum + "\nc3.3,-7.3,9.3,-11,18,-11 H400000v" + (40 + extraViniculum) + "H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM" + (1001 + extraViniculum) + " " + hLinePad + "h400000v" + (40 + extraViniculum) + "H1017.7z";
+};
+
+var phasePath = function phasePath(y) {
+ var x = y / 2; // x coordinate at top of angle
+
+ return "M400000 " + y + " H0 L" + x + " 0 l65 45 L145 " + (y - 80) + " H400000z";
+};
+
+var sqrtTall = function sqrtTall(extraViniculum, hLinePad, viewBoxHeight) {
+ // sqrtTall is from glyph U23B7 in the font KaTeX_Size4-Regular
+ // One path edge has a variable length. It runs vertically from the viniculumn
+ // to a point near (14 units) the bottom of the surd. The viniculum
+ // is normally 40 units thick. So the length of the line in question is:
+ var vertSegment = viewBoxHeight - 54 - hLinePad - extraViniculum;
+ return "M702 " + (extraViniculum + hLinePad) + "H400000" + (40 + extraViniculum) + "\nH742v" + vertSegment + "l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 " + hLinePad + "H400000v" + (40 + extraViniculum) + "H742z";
+};
+
+var sqrtPath = function sqrtPath(size, extraViniculum, viewBoxHeight) {
+ extraViniculum = 1000 * extraViniculum; // Convert from document ems to viewBox.
+
+ var path = "";
+
+ switch (size) {
+ case "sqrtMain":
+ path = sqrtMain(extraViniculum, hLinePad);
+ break;
+
+ case "sqrtSize1":
+ path = sqrtSize1(extraViniculum, hLinePad);
+ break;
+
+ case "sqrtSize2":
+ path = sqrtSize2(extraViniculum, hLinePad);
+ break;
+
+ case "sqrtSize3":
+ path = sqrtSize3(extraViniculum, hLinePad);
+ break;
+
+ case "sqrtSize4":
+ path = sqrtSize4(extraViniculum, hLinePad);
+ break;
+
+ case "sqrtTall":
+ path = sqrtTall(extraViniculum, hLinePad, viewBoxHeight);
+ }
+
+ return path;
+};
+var innerPath = function innerPath(name, height) {
+ // The inner part of stretchy tall delimiters
+ switch (name) {
+ case "\u239C":
+ return "M291 0 H417 V" + height + " H291z M291 0 H417 V" + height + " H291z";
+
+ case "\u2223":
+ return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z";
+
+ case "\u2225":
+ return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z" + ("M367 0 H410 V" + height + " H367z M367 0 H410 V" + height + " H367z");
+
+ case "\u239F":
+ return "M457 0 H583 V" + height + " H457z M457 0 H583 V" + height + " H457z";
+
+ case "\u23A2":
+ return "M319 0 H403 V" + height + " H319z M319 0 H403 V" + height + " H319z";
+
+ case "\u23A5":
+ return "M263 0 H347 V" + height + " H263z M263 0 H347 V" + height + " H263z";
+
+ case "\u23AA":
+ return "M384 0 H504 V" + height + " H384z M384 0 H504 V" + height + " H384z";
+
+ case "\u23D0":
+ return "M312 0 H355 V" + height + " H312z M312 0 H355 V" + height + " H312z";
+
+ case "\u2016":
+ return "M257 0 H300 V" + height + " H257z M257 0 H300 V" + height + " H257z" + ("M478 0 H521 V" + height + " H478z M478 0 H521 V" + height + " H478z");
+
+ default:
+ return "";
+ }
+};
+var path = {
+ // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main
+ doubleleftarrow: "M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",
+ // doublerightarrow is from glyph U+21D2 in font KaTeX Main
+ doublerightarrow: "M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",
+ // leftarrow is from glyph U+2190 in font KaTeX Main
+ leftarrow: "M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",
+ // overbrace is from glyphs U+23A9/23A8/23A7 in font KaTeX_Size4-Regular
+ leftbrace: "M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",
+ leftbraceunder: "M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",
+ // overgroup is from the MnSymbol package (public domain)
+ leftgroup: "M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",
+ leftgroupunder: "M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",
+ // Harpoons are from glyph U+21BD in font KaTeX Main
+ leftharpoon: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",
+ leftharpoonplus: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",
+ leftharpoondown: "M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",
+ leftharpoondownplus: "M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",
+ // hook is from glyph U+21A9 in font KaTeX Main
+ lefthook: "M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",
+ leftlinesegment: "M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",
+ leftmapsto: "M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",
+ // tofrom is from glyph U+21C4 in font KaTeX AMS Regular
+ leftToFrom: "M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",
+ longequal: "M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",
+ midbrace: "M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",
+ midbraceunder: "M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",
+ oiintSize1: "M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",
+ oiintSize2: "M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",
+ oiiintSize1: "M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",
+ oiiintSize2: "M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",
+ rightarrow: "M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",
+ rightbrace: "M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",
+ rightbraceunder: "M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",
+ rightgroup: "M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",
+ rightgroupunder: "M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",
+ rightharpoon: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",
+ rightharpoonplus: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",
+ rightharpoondown: "M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",
+ rightharpoondownplus: "M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",
+ righthook: "M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",
+ rightlinesegment: "M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",
+ rightToFrom: "M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",
+ // twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular
+ twoheadleftarrow: "M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",
+ twoheadrightarrow: "M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",
+ // tilde1 is a modified version of a glyph from the MnSymbol package
+ tilde1: "M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",
+ // ditto tilde2, tilde3, & tilde4
+ tilde2: "M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",
+ tilde3: "M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",
+ tilde4: "M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",
+ // vec is from glyph U+20D7 in font KaTeX Main
+ vec: "M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",
+ // widehat1 is a modified version of a glyph from the MnSymbol package
+ widehat1: "M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",
+ // ditto widehat2, widehat3, & widehat4
+ widehat2: "M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",
+ widehat3: "M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",
+ widehat4: "M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",
+ // widecheck paths are all inverted versions of widehat
+ widecheck1: "M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",
+ widecheck2: "M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",
+ widecheck3: "M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",
+ widecheck4: "M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",
+ // The next ten paths support reaction arrows from the mhchem package.
+ // Arrows for \ce{<-->} are offset from xAxis by 0.22ex, per mhchem in LaTeX
+ // baraboveleftarrow is mostly from from glyph U+2190 in font KaTeX Main
+ baraboveleftarrow: "M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",
+ // rightarrowabovebar is mostly from glyph U+2192, KaTeX Main
+ rightarrowabovebar: "M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",
+ // The short left harpoon has 0.5em (i.e. 500 units) kern on the left end.
+ // Ref from mhchem.sty: \rlap{\raisebox{-.22ex}{$\kern0.5em
+ baraboveshortleftharpoon: "M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",
+ rightharpoonaboveshortbar: "M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",
+ shortbaraboveleftharpoon: "M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",
+ shortrightharpoonabovebar: "M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"
+};
+;// CONCATENATED MODULE: ./src/tree.js
+
+
+/**
+ * This node represents a document fragment, which contains elements, but when
+ * placed into the DOM doesn't have any representation itself. It only contains
+ * children and doesn't have any DOM node properties.
+ */
+var DocumentFragment = /*#__PURE__*/function () {
+ // HtmlDomNode
+ // Never used; needed for satisfying interface.
+ function DocumentFragment(children) {
+ this.children = void 0;
+ this.classes = void 0;
+ this.height = void 0;
+ this.depth = void 0;
+ this.maxFontSize = void 0;
+ this.style = void 0;
+ this.children = children;
+ this.classes = [];
+ this.height = 0;
+ this.depth = 0;
+ this.maxFontSize = 0;
+ this.style = {};
+ }
+
+ var _proto = DocumentFragment.prototype;
+
+ _proto.hasClass = function hasClass(className) {
+ return utils.contains(this.classes, className);
+ }
+ /** Convert the fragment into a node. */
+ ;
+
+ _proto.toNode = function toNode() {
+ var frag = document.createDocumentFragment();
+
+ for (var i = 0; i < this.children.length; i++) {
+ frag.appendChild(this.children[i].toNode());
+ }
+
+ return frag;
+ }
+ /** Convert the fragment into HTML markup. */
+ ;
+
+ _proto.toMarkup = function toMarkup() {
+ var markup = ""; // Simply concatenate the markup for the children together.
+
+ for (var i = 0; i < this.children.length; i++) {
+ markup += this.children[i].toMarkup();
+ }
+
+ return markup;
+ }
+ /**
+ * Converts the math node into a string, similar to innerText. Applies to
+ * MathDomNode's only.
+ */
+ ;
+
+ _proto.toText = function toText() {
+ // To avoid this, we would subclass documentFragment separately for
+ // MathML, but polyfills for subclassing is expensive per PR 1469.
+ // $FlowFixMe: Only works for ChildType = MathDomNode.
+ var toText = function toText(child) {
+ return child.toText();
+ };
+
+ return this.children.map(toText).join("");
+ };
+
+ return DocumentFragment;
+}();
+;// CONCATENATED MODULE: ./src/fontMetricsData.js
+// This file is GENERATED by buildMetrics.sh. DO NOT MODIFY.
+/* harmony default export */ var fontMetricsData = ({
+ "AMS-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "65": [0, 0.68889, 0, 0, 0.72222],
+ "66": [0, 0.68889, 0, 0, 0.66667],
+ "67": [0, 0.68889, 0, 0, 0.72222],
+ "68": [0, 0.68889, 0, 0, 0.72222],
+ "69": [0, 0.68889, 0, 0, 0.66667],
+ "70": [0, 0.68889, 0, 0, 0.61111],
+ "71": [0, 0.68889, 0, 0, 0.77778],
+ "72": [0, 0.68889, 0, 0, 0.77778],
+ "73": [0, 0.68889, 0, 0, 0.38889],
+ "74": [0.16667, 0.68889, 0, 0, 0.5],
+ "75": [0, 0.68889, 0, 0, 0.77778],
+ "76": [0, 0.68889, 0, 0, 0.66667],
+ "77": [0, 0.68889, 0, 0, 0.94445],
+ "78": [0, 0.68889, 0, 0, 0.72222],
+ "79": [0.16667, 0.68889, 0, 0, 0.77778],
+ "80": [0, 0.68889, 0, 0, 0.61111],
+ "81": [0.16667, 0.68889, 0, 0, 0.77778],
+ "82": [0, 0.68889, 0, 0, 0.72222],
+ "83": [0, 0.68889, 0, 0, 0.55556],
+ "84": [0, 0.68889, 0, 0, 0.66667],
+ "85": [0, 0.68889, 0, 0, 0.72222],
+ "86": [0, 0.68889, 0, 0, 0.72222],
+ "87": [0, 0.68889, 0, 0, 1.0],
+ "88": [0, 0.68889, 0, 0, 0.72222],
+ "89": [0, 0.68889, 0, 0, 0.72222],
+ "90": [0, 0.68889, 0, 0, 0.66667],
+ "107": [0, 0.68889, 0, 0, 0.55556],
+ "160": [0, 0, 0, 0, 0.25],
+ "165": [0, 0.675, 0.025, 0, 0.75],
+ "174": [0.15559, 0.69224, 0, 0, 0.94666],
+ "240": [0, 0.68889, 0, 0, 0.55556],
+ "295": [0, 0.68889, 0, 0, 0.54028],
+ "710": [0, 0.825, 0, 0, 2.33334],
+ "732": [0, 0.9, 0, 0, 2.33334],
+ "770": [0, 0.825, 0, 0, 2.33334],
+ "771": [0, 0.9, 0, 0, 2.33334],
+ "989": [0.08167, 0.58167, 0, 0, 0.77778],
+ "1008": [0, 0.43056, 0.04028, 0, 0.66667],
+ "8245": [0, 0.54986, 0, 0, 0.275],
+ "8463": [0, 0.68889, 0, 0, 0.54028],
+ "8487": [0, 0.68889, 0, 0, 0.72222],
+ "8498": [0, 0.68889, 0, 0, 0.55556],
+ "8502": [0, 0.68889, 0, 0, 0.66667],
+ "8503": [0, 0.68889, 0, 0, 0.44445],
+ "8504": [0, 0.68889, 0, 0, 0.66667],
+ "8513": [0, 0.68889, 0, 0, 0.63889],
+ "8592": [-0.03598, 0.46402, 0, 0, 0.5],
+ "8594": [-0.03598, 0.46402, 0, 0, 0.5],
+ "8602": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8603": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8606": [0.01354, 0.52239, 0, 0, 1.0],
+ "8608": [0.01354, 0.52239, 0, 0, 1.0],
+ "8610": [0.01354, 0.52239, 0, 0, 1.11111],
+ "8611": [0.01354, 0.52239, 0, 0, 1.11111],
+ "8619": [0, 0.54986, 0, 0, 1.0],
+ "8620": [0, 0.54986, 0, 0, 1.0],
+ "8621": [-0.13313, 0.37788, 0, 0, 1.38889],
+ "8622": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8624": [0, 0.69224, 0, 0, 0.5],
+ "8625": [0, 0.69224, 0, 0, 0.5],
+ "8630": [0, 0.43056, 0, 0, 1.0],
+ "8631": [0, 0.43056, 0, 0, 1.0],
+ "8634": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8635": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8638": [0.19444, 0.69224, 0, 0, 0.41667],
+ "8639": [0.19444, 0.69224, 0, 0, 0.41667],
+ "8642": [0.19444, 0.69224, 0, 0, 0.41667],
+ "8643": [0.19444, 0.69224, 0, 0, 0.41667],
+ "8644": [0.1808, 0.675, 0, 0, 1.0],
+ "8646": [0.1808, 0.675, 0, 0, 1.0],
+ "8647": [0.1808, 0.675, 0, 0, 1.0],
+ "8648": [0.19444, 0.69224, 0, 0, 0.83334],
+ "8649": [0.1808, 0.675, 0, 0, 1.0],
+ "8650": [0.19444, 0.69224, 0, 0, 0.83334],
+ "8651": [0.01354, 0.52239, 0, 0, 1.0],
+ "8652": [0.01354, 0.52239, 0, 0, 1.0],
+ "8653": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8654": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8655": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8666": [0.13667, 0.63667, 0, 0, 1.0],
+ "8667": [0.13667, 0.63667, 0, 0, 1.0],
+ "8669": [-0.13313, 0.37788, 0, 0, 1.0],
+ "8672": [-0.064, 0.437, 0, 0, 1.334],
+ "8674": [-0.064, 0.437, 0, 0, 1.334],
+ "8705": [0, 0.825, 0, 0, 0.5],
+ "8708": [0, 0.68889, 0, 0, 0.55556],
+ "8709": [0.08167, 0.58167, 0, 0, 0.77778],
+ "8717": [0, 0.43056, 0, 0, 0.42917],
+ "8722": [-0.03598, 0.46402, 0, 0, 0.5],
+ "8724": [0.08198, 0.69224, 0, 0, 0.77778],
+ "8726": [0.08167, 0.58167, 0, 0, 0.77778],
+ "8733": [0, 0.69224, 0, 0, 0.77778],
+ "8736": [0, 0.69224, 0, 0, 0.72222],
+ "8737": [0, 0.69224, 0, 0, 0.72222],
+ "8738": [0.03517, 0.52239, 0, 0, 0.72222],
+ "8739": [0.08167, 0.58167, 0, 0, 0.22222],
+ "8740": [0.25142, 0.74111, 0, 0, 0.27778],
+ "8741": [0.08167, 0.58167, 0, 0, 0.38889],
+ "8742": [0.25142, 0.74111, 0, 0, 0.5],
+ "8756": [0, 0.69224, 0, 0, 0.66667],
+ "8757": [0, 0.69224, 0, 0, 0.66667],
+ "8764": [-0.13313, 0.36687, 0, 0, 0.77778],
+ "8765": [-0.13313, 0.37788, 0, 0, 0.77778],
+ "8769": [-0.13313, 0.36687, 0, 0, 0.77778],
+ "8770": [-0.03625, 0.46375, 0, 0, 0.77778],
+ "8774": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8776": [-0.01688, 0.48312, 0, 0, 0.77778],
+ "8778": [0.08167, 0.58167, 0, 0, 0.77778],
+ "8782": [0.06062, 0.54986, 0, 0, 0.77778],
+ "8783": [0.06062, 0.54986, 0, 0, 0.77778],
+ "8785": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8786": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8787": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8790": [0, 0.69224, 0, 0, 0.77778],
+ "8791": [0.22958, 0.72958, 0, 0, 0.77778],
+ "8796": [0.08198, 0.91667, 0, 0, 0.77778],
+ "8806": [0.25583, 0.75583, 0, 0, 0.77778],
+ "8807": [0.25583, 0.75583, 0, 0, 0.77778],
+ "8808": [0.25142, 0.75726, 0, 0, 0.77778],
+ "8809": [0.25142, 0.75726, 0, 0, 0.77778],
+ "8812": [0.25583, 0.75583, 0, 0, 0.5],
+ "8814": [0.20576, 0.70576, 0, 0, 0.77778],
+ "8815": [0.20576, 0.70576, 0, 0, 0.77778],
+ "8816": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8817": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8818": [0.22958, 0.72958, 0, 0, 0.77778],
+ "8819": [0.22958, 0.72958, 0, 0, 0.77778],
+ "8822": [0.1808, 0.675, 0, 0, 0.77778],
+ "8823": [0.1808, 0.675, 0, 0, 0.77778],
+ "8828": [0.13667, 0.63667, 0, 0, 0.77778],
+ "8829": [0.13667, 0.63667, 0, 0, 0.77778],
+ "8830": [0.22958, 0.72958, 0, 0, 0.77778],
+ "8831": [0.22958, 0.72958, 0, 0, 0.77778],
+ "8832": [0.20576, 0.70576, 0, 0, 0.77778],
+ "8833": [0.20576, 0.70576, 0, 0, 0.77778],
+ "8840": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8841": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8842": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8843": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8847": [0.03517, 0.54986, 0, 0, 0.77778],
+ "8848": [0.03517, 0.54986, 0, 0, 0.77778],
+ "8858": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8859": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8861": [0.08198, 0.58198, 0, 0, 0.77778],
+ "8862": [0, 0.675, 0, 0, 0.77778],
+ "8863": [0, 0.675, 0, 0, 0.77778],
+ "8864": [0, 0.675, 0, 0, 0.77778],
+ "8865": [0, 0.675, 0, 0, 0.77778],
+ "8872": [0, 0.69224, 0, 0, 0.61111],
+ "8873": [0, 0.69224, 0, 0, 0.72222],
+ "8874": [0, 0.69224, 0, 0, 0.88889],
+ "8876": [0, 0.68889, 0, 0, 0.61111],
+ "8877": [0, 0.68889, 0, 0, 0.61111],
+ "8878": [0, 0.68889, 0, 0, 0.72222],
+ "8879": [0, 0.68889, 0, 0, 0.72222],
+ "8882": [0.03517, 0.54986, 0, 0, 0.77778],
+ "8883": [0.03517, 0.54986, 0, 0, 0.77778],
+ "8884": [0.13667, 0.63667, 0, 0, 0.77778],
+ "8885": [0.13667, 0.63667, 0, 0, 0.77778],
+ "8888": [0, 0.54986, 0, 0, 1.11111],
+ "8890": [0.19444, 0.43056, 0, 0, 0.55556],
+ "8891": [0.19444, 0.69224, 0, 0, 0.61111],
+ "8892": [0.19444, 0.69224, 0, 0, 0.61111],
+ "8901": [0, 0.54986, 0, 0, 0.27778],
+ "8903": [0.08167, 0.58167, 0, 0, 0.77778],
+ "8905": [0.08167, 0.58167, 0, 0, 0.77778],
+ "8906": [0.08167, 0.58167, 0, 0, 0.77778],
+ "8907": [0, 0.69224, 0, 0, 0.77778],
+ "8908": [0, 0.69224, 0, 0, 0.77778],
+ "8909": [-0.03598, 0.46402, 0, 0, 0.77778],
+ "8910": [0, 0.54986, 0, 0, 0.76042],
+ "8911": [0, 0.54986, 0, 0, 0.76042],
+ "8912": [0.03517, 0.54986, 0, 0, 0.77778],
+ "8913": [0.03517, 0.54986, 0, 0, 0.77778],
+ "8914": [0, 0.54986, 0, 0, 0.66667],
+ "8915": [0, 0.54986, 0, 0, 0.66667],
+ "8916": [0, 0.69224, 0, 0, 0.66667],
+ "8918": [0.0391, 0.5391, 0, 0, 0.77778],
+ "8919": [0.0391, 0.5391, 0, 0, 0.77778],
+ "8920": [0.03517, 0.54986, 0, 0, 1.33334],
+ "8921": [0.03517, 0.54986, 0, 0, 1.33334],
+ "8922": [0.38569, 0.88569, 0, 0, 0.77778],
+ "8923": [0.38569, 0.88569, 0, 0, 0.77778],
+ "8926": [0.13667, 0.63667, 0, 0, 0.77778],
+ "8927": [0.13667, 0.63667, 0, 0, 0.77778],
+ "8928": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8929": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8934": [0.23222, 0.74111, 0, 0, 0.77778],
+ "8935": [0.23222, 0.74111, 0, 0, 0.77778],
+ "8936": [0.23222, 0.74111, 0, 0, 0.77778],
+ "8937": [0.23222, 0.74111, 0, 0, 0.77778],
+ "8938": [0.20576, 0.70576, 0, 0, 0.77778],
+ "8939": [0.20576, 0.70576, 0, 0, 0.77778],
+ "8940": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8941": [0.30274, 0.79383, 0, 0, 0.77778],
+ "8994": [0.19444, 0.69224, 0, 0, 0.77778],
+ "8995": [0.19444, 0.69224, 0, 0, 0.77778],
+ "9416": [0.15559, 0.69224, 0, 0, 0.90222],
+ "9484": [0, 0.69224, 0, 0, 0.5],
+ "9488": [0, 0.69224, 0, 0, 0.5],
+ "9492": [0, 0.37788, 0, 0, 0.5],
+ "9496": [0, 0.37788, 0, 0, 0.5],
+ "9585": [0.19444, 0.68889, 0, 0, 0.88889],
+ "9586": [0.19444, 0.74111, 0, 0, 0.88889],
+ "9632": [0, 0.675, 0, 0, 0.77778],
+ "9633": [0, 0.675, 0, 0, 0.77778],
+ "9650": [0, 0.54986, 0, 0, 0.72222],
+ "9651": [0, 0.54986, 0, 0, 0.72222],
+ "9654": [0.03517, 0.54986, 0, 0, 0.77778],
+ "9660": [0, 0.54986, 0, 0, 0.72222],
+ "9661": [0, 0.54986, 0, 0, 0.72222],
+ "9664": [0.03517, 0.54986, 0, 0, 0.77778],
+ "9674": [0.11111, 0.69224, 0, 0, 0.66667],
+ "9733": [0.19444, 0.69224, 0, 0, 0.94445],
+ "10003": [0, 0.69224, 0, 0, 0.83334],
+ "10016": [0, 0.69224, 0, 0, 0.83334],
+ "10731": [0.11111, 0.69224, 0, 0, 0.66667],
+ "10846": [0.19444, 0.75583, 0, 0, 0.61111],
+ "10877": [0.13667, 0.63667, 0, 0, 0.77778],
+ "10878": [0.13667, 0.63667, 0, 0, 0.77778],
+ "10885": [0.25583, 0.75583, 0, 0, 0.77778],
+ "10886": [0.25583, 0.75583, 0, 0, 0.77778],
+ "10887": [0.13597, 0.63597, 0, 0, 0.77778],
+ "10888": [0.13597, 0.63597, 0, 0, 0.77778],
+ "10889": [0.26167, 0.75726, 0, 0, 0.77778],
+ "10890": [0.26167, 0.75726, 0, 0, 0.77778],
+ "10891": [0.48256, 0.98256, 0, 0, 0.77778],
+ "10892": [0.48256, 0.98256, 0, 0, 0.77778],
+ "10901": [0.13667, 0.63667, 0, 0, 0.77778],
+ "10902": [0.13667, 0.63667, 0, 0, 0.77778],
+ "10933": [0.25142, 0.75726, 0, 0, 0.77778],
+ "10934": [0.25142, 0.75726, 0, 0, 0.77778],
+ "10935": [0.26167, 0.75726, 0, 0, 0.77778],
+ "10936": [0.26167, 0.75726, 0, 0, 0.77778],
+ "10937": [0.26167, 0.75726, 0, 0, 0.77778],
+ "10938": [0.26167, 0.75726, 0, 0, 0.77778],
+ "10949": [0.25583, 0.75583, 0, 0, 0.77778],
+ "10950": [0.25583, 0.75583, 0, 0, 0.77778],
+ "10955": [0.28481, 0.79383, 0, 0, 0.77778],
+ "10956": [0.28481, 0.79383, 0, 0, 0.77778],
+ "57350": [0.08167, 0.58167, 0, 0, 0.22222],
+ "57351": [0.08167, 0.58167, 0, 0, 0.38889],
+ "57352": [0.08167, 0.58167, 0, 0, 0.77778],
+ "57353": [0, 0.43056, 0.04028, 0, 0.66667],
+ "57356": [0.25142, 0.75726, 0, 0, 0.77778],
+ "57357": [0.25142, 0.75726, 0, 0, 0.77778],
+ "57358": [0.41951, 0.91951, 0, 0, 0.77778],
+ "57359": [0.30274, 0.79383, 0, 0, 0.77778],
+ "57360": [0.30274, 0.79383, 0, 0, 0.77778],
+ "57361": [0.41951, 0.91951, 0, 0, 0.77778],
+ "57366": [0.25142, 0.75726, 0, 0, 0.77778],
+ "57367": [0.25142, 0.75726, 0, 0, 0.77778],
+ "57368": [0.25142, 0.75726, 0, 0, 0.77778],
+ "57369": [0.25142, 0.75726, 0, 0, 0.77778],
+ "57370": [0.13597, 0.63597, 0, 0, 0.77778],
+ "57371": [0.13597, 0.63597, 0, 0, 0.77778]
+ },
+ "Caligraphic-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "65": [0, 0.68333, 0, 0.19445, 0.79847],
+ "66": [0, 0.68333, 0.03041, 0.13889, 0.65681],
+ "67": [0, 0.68333, 0.05834, 0.13889, 0.52653],
+ "68": [0, 0.68333, 0.02778, 0.08334, 0.77139],
+ "69": [0, 0.68333, 0.08944, 0.11111, 0.52778],
+ "70": [0, 0.68333, 0.09931, 0.11111, 0.71875],
+ "71": [0.09722, 0.68333, 0.0593, 0.11111, 0.59487],
+ "72": [0, 0.68333, 0.00965, 0.11111, 0.84452],
+ "73": [0, 0.68333, 0.07382, 0, 0.54452],
+ "74": [0.09722, 0.68333, 0.18472, 0.16667, 0.67778],
+ "75": [0, 0.68333, 0.01445, 0.05556, 0.76195],
+ "76": [0, 0.68333, 0, 0.13889, 0.68972],
+ "77": [0, 0.68333, 0, 0.13889, 1.2009],
+ "78": [0, 0.68333, 0.14736, 0.08334, 0.82049],
+ "79": [0, 0.68333, 0.02778, 0.11111, 0.79611],
+ "80": [0, 0.68333, 0.08222, 0.08334, 0.69556],
+ "81": [0.09722, 0.68333, 0, 0.11111, 0.81667],
+ "82": [0, 0.68333, 0, 0.08334, 0.8475],
+ "83": [0, 0.68333, 0.075, 0.13889, 0.60556],
+ "84": [0, 0.68333, 0.25417, 0, 0.54464],
+ "85": [0, 0.68333, 0.09931, 0.08334, 0.62583],
+ "86": [0, 0.68333, 0.08222, 0, 0.61278],
+ "87": [0, 0.68333, 0.08222, 0.08334, 0.98778],
+ "88": [0, 0.68333, 0.14643, 0.13889, 0.7133],
+ "89": [0.09722, 0.68333, 0.08222, 0.08334, 0.66834],
+ "90": [0, 0.68333, 0.07944, 0.13889, 0.72473],
+ "160": [0, 0, 0, 0, 0.25]
+ },
+ "Fraktur-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69141, 0, 0, 0.29574],
+ "34": [0, 0.69141, 0, 0, 0.21471],
+ "38": [0, 0.69141, 0, 0, 0.73786],
+ "39": [0, 0.69141, 0, 0, 0.21201],
+ "40": [0.24982, 0.74947, 0, 0, 0.38865],
+ "41": [0.24982, 0.74947, 0, 0, 0.38865],
+ "42": [0, 0.62119, 0, 0, 0.27764],
+ "43": [0.08319, 0.58283, 0, 0, 0.75623],
+ "44": [0, 0.10803, 0, 0, 0.27764],
+ "45": [0.08319, 0.58283, 0, 0, 0.75623],
+ "46": [0, 0.10803, 0, 0, 0.27764],
+ "47": [0.24982, 0.74947, 0, 0, 0.50181],
+ "48": [0, 0.47534, 0, 0, 0.50181],
+ "49": [0, 0.47534, 0, 0, 0.50181],
+ "50": [0, 0.47534, 0, 0, 0.50181],
+ "51": [0.18906, 0.47534, 0, 0, 0.50181],
+ "52": [0.18906, 0.47534, 0, 0, 0.50181],
+ "53": [0.18906, 0.47534, 0, 0, 0.50181],
+ "54": [0, 0.69141, 0, 0, 0.50181],
+ "55": [0.18906, 0.47534, 0, 0, 0.50181],
+ "56": [0, 0.69141, 0, 0, 0.50181],
+ "57": [0.18906, 0.47534, 0, 0, 0.50181],
+ "58": [0, 0.47534, 0, 0, 0.21606],
+ "59": [0.12604, 0.47534, 0, 0, 0.21606],
+ "61": [-0.13099, 0.36866, 0, 0, 0.75623],
+ "63": [0, 0.69141, 0, 0, 0.36245],
+ "65": [0, 0.69141, 0, 0, 0.7176],
+ "66": [0, 0.69141, 0, 0, 0.88397],
+ "67": [0, 0.69141, 0, 0, 0.61254],
+ "68": [0, 0.69141, 0, 0, 0.83158],
+ "69": [0, 0.69141, 0, 0, 0.66278],
+ "70": [0.12604, 0.69141, 0, 0, 0.61119],
+ "71": [0, 0.69141, 0, 0, 0.78539],
+ "72": [0.06302, 0.69141, 0, 0, 0.7203],
+ "73": [0, 0.69141, 0, 0, 0.55448],
+ "74": [0.12604, 0.69141, 0, 0, 0.55231],
+ "75": [0, 0.69141, 0, 0, 0.66845],
+ "76": [0, 0.69141, 0, 0, 0.66602],
+ "77": [0, 0.69141, 0, 0, 1.04953],
+ "78": [0, 0.69141, 0, 0, 0.83212],
+ "79": [0, 0.69141, 0, 0, 0.82699],
+ "80": [0.18906, 0.69141, 0, 0, 0.82753],
+ "81": [0.03781, 0.69141, 0, 0, 0.82699],
+ "82": [0, 0.69141, 0, 0, 0.82807],
+ "83": [0, 0.69141, 0, 0, 0.82861],
+ "84": [0, 0.69141, 0, 0, 0.66899],
+ "85": [0, 0.69141, 0, 0, 0.64576],
+ "86": [0, 0.69141, 0, 0, 0.83131],
+ "87": [0, 0.69141, 0, 0, 1.04602],
+ "88": [0, 0.69141, 0, 0, 0.71922],
+ "89": [0.18906, 0.69141, 0, 0, 0.83293],
+ "90": [0.12604, 0.69141, 0, 0, 0.60201],
+ "91": [0.24982, 0.74947, 0, 0, 0.27764],
+ "93": [0.24982, 0.74947, 0, 0, 0.27764],
+ "94": [0, 0.69141, 0, 0, 0.49965],
+ "97": [0, 0.47534, 0, 0, 0.50046],
+ "98": [0, 0.69141, 0, 0, 0.51315],
+ "99": [0, 0.47534, 0, 0, 0.38946],
+ "100": [0, 0.62119, 0, 0, 0.49857],
+ "101": [0, 0.47534, 0, 0, 0.40053],
+ "102": [0.18906, 0.69141, 0, 0, 0.32626],
+ "103": [0.18906, 0.47534, 0, 0, 0.5037],
+ "104": [0.18906, 0.69141, 0, 0, 0.52126],
+ "105": [0, 0.69141, 0, 0, 0.27899],
+ "106": [0, 0.69141, 0, 0, 0.28088],
+ "107": [0, 0.69141, 0, 0, 0.38946],
+ "108": [0, 0.69141, 0, 0, 0.27953],
+ "109": [0, 0.47534, 0, 0, 0.76676],
+ "110": [0, 0.47534, 0, 0, 0.52666],
+ "111": [0, 0.47534, 0, 0, 0.48885],
+ "112": [0.18906, 0.52396, 0, 0, 0.50046],
+ "113": [0.18906, 0.47534, 0, 0, 0.48912],
+ "114": [0, 0.47534, 0, 0, 0.38919],
+ "115": [0, 0.47534, 0, 0, 0.44266],
+ "116": [0, 0.62119, 0, 0, 0.33301],
+ "117": [0, 0.47534, 0, 0, 0.5172],
+ "118": [0, 0.52396, 0, 0, 0.5118],
+ "119": [0, 0.52396, 0, 0, 0.77351],
+ "120": [0.18906, 0.47534, 0, 0, 0.38865],
+ "121": [0.18906, 0.47534, 0, 0, 0.49884],
+ "122": [0.18906, 0.47534, 0, 0, 0.39054],
+ "160": [0, 0, 0, 0, 0.25],
+ "8216": [0, 0.69141, 0, 0, 0.21471],
+ "8217": [0, 0.69141, 0, 0, 0.21471],
+ "58112": [0, 0.62119, 0, 0, 0.49749],
+ "58113": [0, 0.62119, 0, 0, 0.4983],
+ "58114": [0.18906, 0.69141, 0, 0, 0.33328],
+ "58115": [0.18906, 0.69141, 0, 0, 0.32923],
+ "58116": [0.18906, 0.47534, 0, 0, 0.50343],
+ "58117": [0, 0.69141, 0, 0, 0.33301],
+ "58118": [0, 0.62119, 0, 0, 0.33409],
+ "58119": [0, 0.47534, 0, 0, 0.50073]
+ },
+ "Main-Bold": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0, 0, 0.35],
+ "34": [0, 0.69444, 0, 0, 0.60278],
+ "35": [0.19444, 0.69444, 0, 0, 0.95833],
+ "36": [0.05556, 0.75, 0, 0, 0.575],
+ "37": [0.05556, 0.75, 0, 0, 0.95833],
+ "38": [0, 0.69444, 0, 0, 0.89444],
+ "39": [0, 0.69444, 0, 0, 0.31944],
+ "40": [0.25, 0.75, 0, 0, 0.44722],
+ "41": [0.25, 0.75, 0, 0, 0.44722],
+ "42": [0, 0.75, 0, 0, 0.575],
+ "43": [0.13333, 0.63333, 0, 0, 0.89444],
+ "44": [0.19444, 0.15556, 0, 0, 0.31944],
+ "45": [0, 0.44444, 0, 0, 0.38333],
+ "46": [0, 0.15556, 0, 0, 0.31944],
+ "47": [0.25, 0.75, 0, 0, 0.575],
+ "48": [0, 0.64444, 0, 0, 0.575],
+ "49": [0, 0.64444, 0, 0, 0.575],
+ "50": [0, 0.64444, 0, 0, 0.575],
+ "51": [0, 0.64444, 0, 0, 0.575],
+ "52": [0, 0.64444, 0, 0, 0.575],
+ "53": [0, 0.64444, 0, 0, 0.575],
+ "54": [0, 0.64444, 0, 0, 0.575],
+ "55": [0, 0.64444, 0, 0, 0.575],
+ "56": [0, 0.64444, 0, 0, 0.575],
+ "57": [0, 0.64444, 0, 0, 0.575],
+ "58": [0, 0.44444, 0, 0, 0.31944],
+ "59": [0.19444, 0.44444, 0, 0, 0.31944],
+ "60": [0.08556, 0.58556, 0, 0, 0.89444],
+ "61": [-0.10889, 0.39111, 0, 0, 0.89444],
+ "62": [0.08556, 0.58556, 0, 0, 0.89444],
+ "63": [0, 0.69444, 0, 0, 0.54305],
+ "64": [0, 0.69444, 0, 0, 0.89444],
+ "65": [0, 0.68611, 0, 0, 0.86944],
+ "66": [0, 0.68611, 0, 0, 0.81805],
+ "67": [0, 0.68611, 0, 0, 0.83055],
+ "68": [0, 0.68611, 0, 0, 0.88194],
+ "69": [0, 0.68611, 0, 0, 0.75555],
+ "70": [0, 0.68611, 0, 0, 0.72361],
+ "71": [0, 0.68611, 0, 0, 0.90416],
+ "72": [0, 0.68611, 0, 0, 0.9],
+ "73": [0, 0.68611, 0, 0, 0.43611],
+ "74": [0, 0.68611, 0, 0, 0.59444],
+ "75": [0, 0.68611, 0, 0, 0.90138],
+ "76": [0, 0.68611, 0, 0, 0.69166],
+ "77": [0, 0.68611, 0, 0, 1.09166],
+ "78": [0, 0.68611, 0, 0, 0.9],
+ "79": [0, 0.68611, 0, 0, 0.86388],
+ "80": [0, 0.68611, 0, 0, 0.78611],
+ "81": [0.19444, 0.68611, 0, 0, 0.86388],
+ "82": [0, 0.68611, 0, 0, 0.8625],
+ "83": [0, 0.68611, 0, 0, 0.63889],
+ "84": [0, 0.68611, 0, 0, 0.8],
+ "85": [0, 0.68611, 0, 0, 0.88472],
+ "86": [0, 0.68611, 0.01597, 0, 0.86944],
+ "87": [0, 0.68611, 0.01597, 0, 1.18888],
+ "88": [0, 0.68611, 0, 0, 0.86944],
+ "89": [0, 0.68611, 0.02875, 0, 0.86944],
+ "90": [0, 0.68611, 0, 0, 0.70277],
+ "91": [0.25, 0.75, 0, 0, 0.31944],
+ "92": [0.25, 0.75, 0, 0, 0.575],
+ "93": [0.25, 0.75, 0, 0, 0.31944],
+ "94": [0, 0.69444, 0, 0, 0.575],
+ "95": [0.31, 0.13444, 0.03194, 0, 0.575],
+ "97": [0, 0.44444, 0, 0, 0.55902],
+ "98": [0, 0.69444, 0, 0, 0.63889],
+ "99": [0, 0.44444, 0, 0, 0.51111],
+ "100": [0, 0.69444, 0, 0, 0.63889],
+ "101": [0, 0.44444, 0, 0, 0.52708],
+ "102": [0, 0.69444, 0.10903, 0, 0.35139],
+ "103": [0.19444, 0.44444, 0.01597, 0, 0.575],
+ "104": [0, 0.69444, 0, 0, 0.63889],
+ "105": [0, 0.69444, 0, 0, 0.31944],
+ "106": [0.19444, 0.69444, 0, 0, 0.35139],
+ "107": [0, 0.69444, 0, 0, 0.60694],
+ "108": [0, 0.69444, 0, 0, 0.31944],
+ "109": [0, 0.44444, 0, 0, 0.95833],
+ "110": [0, 0.44444, 0, 0, 0.63889],
+ "111": [0, 0.44444, 0, 0, 0.575],
+ "112": [0.19444, 0.44444, 0, 0, 0.63889],
+ "113": [0.19444, 0.44444, 0, 0, 0.60694],
+ "114": [0, 0.44444, 0, 0, 0.47361],
+ "115": [0, 0.44444, 0, 0, 0.45361],
+ "116": [0, 0.63492, 0, 0, 0.44722],
+ "117": [0, 0.44444, 0, 0, 0.63889],
+ "118": [0, 0.44444, 0.01597, 0, 0.60694],
+ "119": [0, 0.44444, 0.01597, 0, 0.83055],
+ "120": [0, 0.44444, 0, 0, 0.60694],
+ "121": [0.19444, 0.44444, 0.01597, 0, 0.60694],
+ "122": [0, 0.44444, 0, 0, 0.51111],
+ "123": [0.25, 0.75, 0, 0, 0.575],
+ "124": [0.25, 0.75, 0, 0, 0.31944],
+ "125": [0.25, 0.75, 0, 0, 0.575],
+ "126": [0.35, 0.34444, 0, 0, 0.575],
+ "160": [0, 0, 0, 0, 0.25],
+ "163": [0, 0.69444, 0, 0, 0.86853],
+ "168": [0, 0.69444, 0, 0, 0.575],
+ "172": [0, 0.44444, 0, 0, 0.76666],
+ "176": [0, 0.69444, 0, 0, 0.86944],
+ "177": [0.13333, 0.63333, 0, 0, 0.89444],
+ "184": [0.17014, 0, 0, 0, 0.51111],
+ "198": [0, 0.68611, 0, 0, 1.04166],
+ "215": [0.13333, 0.63333, 0, 0, 0.89444],
+ "216": [0.04861, 0.73472, 0, 0, 0.89444],
+ "223": [0, 0.69444, 0, 0, 0.59722],
+ "230": [0, 0.44444, 0, 0, 0.83055],
+ "247": [0.13333, 0.63333, 0, 0, 0.89444],
+ "248": [0.09722, 0.54167, 0, 0, 0.575],
+ "305": [0, 0.44444, 0, 0, 0.31944],
+ "338": [0, 0.68611, 0, 0, 1.16944],
+ "339": [0, 0.44444, 0, 0, 0.89444],
+ "567": [0.19444, 0.44444, 0, 0, 0.35139],
+ "710": [0, 0.69444, 0, 0, 0.575],
+ "711": [0, 0.63194, 0, 0, 0.575],
+ "713": [0, 0.59611, 0, 0, 0.575],
+ "714": [0, 0.69444, 0, 0, 0.575],
+ "715": [0, 0.69444, 0, 0, 0.575],
+ "728": [0, 0.69444, 0, 0, 0.575],
+ "729": [0, 0.69444, 0, 0, 0.31944],
+ "730": [0, 0.69444, 0, 0, 0.86944],
+ "732": [0, 0.69444, 0, 0, 0.575],
+ "733": [0, 0.69444, 0, 0, 0.575],
+ "915": [0, 0.68611, 0, 0, 0.69166],
+ "916": [0, 0.68611, 0, 0, 0.95833],
+ "920": [0, 0.68611, 0, 0, 0.89444],
+ "923": [0, 0.68611, 0, 0, 0.80555],
+ "926": [0, 0.68611, 0, 0, 0.76666],
+ "928": [0, 0.68611, 0, 0, 0.9],
+ "931": [0, 0.68611, 0, 0, 0.83055],
+ "933": [0, 0.68611, 0, 0, 0.89444],
+ "934": [0, 0.68611, 0, 0, 0.83055],
+ "936": [0, 0.68611, 0, 0, 0.89444],
+ "937": [0, 0.68611, 0, 0, 0.83055],
+ "8211": [0, 0.44444, 0.03194, 0, 0.575],
+ "8212": [0, 0.44444, 0.03194, 0, 1.14999],
+ "8216": [0, 0.69444, 0, 0, 0.31944],
+ "8217": [0, 0.69444, 0, 0, 0.31944],
+ "8220": [0, 0.69444, 0, 0, 0.60278],
+ "8221": [0, 0.69444, 0, 0, 0.60278],
+ "8224": [0.19444, 0.69444, 0, 0, 0.51111],
+ "8225": [0.19444, 0.69444, 0, 0, 0.51111],
+ "8242": [0, 0.55556, 0, 0, 0.34444],
+ "8407": [0, 0.72444, 0.15486, 0, 0.575],
+ "8463": [0, 0.69444, 0, 0, 0.66759],
+ "8465": [0, 0.69444, 0, 0, 0.83055],
+ "8467": [0, 0.69444, 0, 0, 0.47361],
+ "8472": [0.19444, 0.44444, 0, 0, 0.74027],
+ "8476": [0, 0.69444, 0, 0, 0.83055],
+ "8501": [0, 0.69444, 0, 0, 0.70277],
+ "8592": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8593": [0.19444, 0.69444, 0, 0, 0.575],
+ "8594": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8595": [0.19444, 0.69444, 0, 0, 0.575],
+ "8596": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8597": [0.25, 0.75, 0, 0, 0.575],
+ "8598": [0.19444, 0.69444, 0, 0, 1.14999],
+ "8599": [0.19444, 0.69444, 0, 0, 1.14999],
+ "8600": [0.19444, 0.69444, 0, 0, 1.14999],
+ "8601": [0.19444, 0.69444, 0, 0, 1.14999],
+ "8636": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8637": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8640": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8641": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8656": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8657": [0.19444, 0.69444, 0, 0, 0.70277],
+ "8658": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8659": [0.19444, 0.69444, 0, 0, 0.70277],
+ "8660": [-0.10889, 0.39111, 0, 0, 1.14999],
+ "8661": [0.25, 0.75, 0, 0, 0.70277],
+ "8704": [0, 0.69444, 0, 0, 0.63889],
+ "8706": [0, 0.69444, 0.06389, 0, 0.62847],
+ "8707": [0, 0.69444, 0, 0, 0.63889],
+ "8709": [0.05556, 0.75, 0, 0, 0.575],
+ "8711": [0, 0.68611, 0, 0, 0.95833],
+ "8712": [0.08556, 0.58556, 0, 0, 0.76666],
+ "8715": [0.08556, 0.58556, 0, 0, 0.76666],
+ "8722": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8723": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8725": [0.25, 0.75, 0, 0, 0.575],
+ "8726": [0.25, 0.75, 0, 0, 0.575],
+ "8727": [-0.02778, 0.47222, 0, 0, 0.575],
+ "8728": [-0.02639, 0.47361, 0, 0, 0.575],
+ "8729": [-0.02639, 0.47361, 0, 0, 0.575],
+ "8730": [0.18, 0.82, 0, 0, 0.95833],
+ "8733": [0, 0.44444, 0, 0, 0.89444],
+ "8734": [0, 0.44444, 0, 0, 1.14999],
+ "8736": [0, 0.69224, 0, 0, 0.72222],
+ "8739": [0.25, 0.75, 0, 0, 0.31944],
+ "8741": [0.25, 0.75, 0, 0, 0.575],
+ "8743": [0, 0.55556, 0, 0, 0.76666],
+ "8744": [0, 0.55556, 0, 0, 0.76666],
+ "8745": [0, 0.55556, 0, 0, 0.76666],
+ "8746": [0, 0.55556, 0, 0, 0.76666],
+ "8747": [0.19444, 0.69444, 0.12778, 0, 0.56875],
+ "8764": [-0.10889, 0.39111, 0, 0, 0.89444],
+ "8768": [0.19444, 0.69444, 0, 0, 0.31944],
+ "8771": [0.00222, 0.50222, 0, 0, 0.89444],
+ "8773": [0.027, 0.638, 0, 0, 0.894],
+ "8776": [0.02444, 0.52444, 0, 0, 0.89444],
+ "8781": [0.00222, 0.50222, 0, 0, 0.89444],
+ "8801": [0.00222, 0.50222, 0, 0, 0.89444],
+ "8804": [0.19667, 0.69667, 0, 0, 0.89444],
+ "8805": [0.19667, 0.69667, 0, 0, 0.89444],
+ "8810": [0.08556, 0.58556, 0, 0, 1.14999],
+ "8811": [0.08556, 0.58556, 0, 0, 1.14999],
+ "8826": [0.08556, 0.58556, 0, 0, 0.89444],
+ "8827": [0.08556, 0.58556, 0, 0, 0.89444],
+ "8834": [0.08556, 0.58556, 0, 0, 0.89444],
+ "8835": [0.08556, 0.58556, 0, 0, 0.89444],
+ "8838": [0.19667, 0.69667, 0, 0, 0.89444],
+ "8839": [0.19667, 0.69667, 0, 0, 0.89444],
+ "8846": [0, 0.55556, 0, 0, 0.76666],
+ "8849": [0.19667, 0.69667, 0, 0, 0.89444],
+ "8850": [0.19667, 0.69667, 0, 0, 0.89444],
+ "8851": [0, 0.55556, 0, 0, 0.76666],
+ "8852": [0, 0.55556, 0, 0, 0.76666],
+ "8853": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8854": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8855": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8856": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8857": [0.13333, 0.63333, 0, 0, 0.89444],
+ "8866": [0, 0.69444, 0, 0, 0.70277],
+ "8867": [0, 0.69444, 0, 0, 0.70277],
+ "8868": [0, 0.69444, 0, 0, 0.89444],
+ "8869": [0, 0.69444, 0, 0, 0.89444],
+ "8900": [-0.02639, 0.47361, 0, 0, 0.575],
+ "8901": [-0.02639, 0.47361, 0, 0, 0.31944],
+ "8902": [-0.02778, 0.47222, 0, 0, 0.575],
+ "8968": [0.25, 0.75, 0, 0, 0.51111],
+ "8969": [0.25, 0.75, 0, 0, 0.51111],
+ "8970": [0.25, 0.75, 0, 0, 0.51111],
+ "8971": [0.25, 0.75, 0, 0, 0.51111],
+ "8994": [-0.13889, 0.36111, 0, 0, 1.14999],
+ "8995": [-0.13889, 0.36111, 0, 0, 1.14999],
+ "9651": [0.19444, 0.69444, 0, 0, 1.02222],
+ "9657": [-0.02778, 0.47222, 0, 0, 0.575],
+ "9661": [0.19444, 0.69444, 0, 0, 1.02222],
+ "9667": [-0.02778, 0.47222, 0, 0, 0.575],
+ "9711": [0.19444, 0.69444, 0, 0, 1.14999],
+ "9824": [0.12963, 0.69444, 0, 0, 0.89444],
+ "9825": [0.12963, 0.69444, 0, 0, 0.89444],
+ "9826": [0.12963, 0.69444, 0, 0, 0.89444],
+ "9827": [0.12963, 0.69444, 0, 0, 0.89444],
+ "9837": [0, 0.75, 0, 0, 0.44722],
+ "9838": [0.19444, 0.69444, 0, 0, 0.44722],
+ "9839": [0.19444, 0.69444, 0, 0, 0.44722],
+ "10216": [0.25, 0.75, 0, 0, 0.44722],
+ "10217": [0.25, 0.75, 0, 0, 0.44722],
+ "10815": [0, 0.68611, 0, 0, 0.9],
+ "10927": [0.19667, 0.69667, 0, 0, 0.89444],
+ "10928": [0.19667, 0.69667, 0, 0, 0.89444],
+ "57376": [0.19444, 0.69444, 0, 0, 0]
+ },
+ "Main-BoldItalic": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0.11417, 0, 0.38611],
+ "34": [0, 0.69444, 0.07939, 0, 0.62055],
+ "35": [0.19444, 0.69444, 0.06833, 0, 0.94444],
+ "37": [0.05556, 0.75, 0.12861, 0, 0.94444],
+ "38": [0, 0.69444, 0.08528, 0, 0.88555],
+ "39": [0, 0.69444, 0.12945, 0, 0.35555],
+ "40": [0.25, 0.75, 0.15806, 0, 0.47333],
+ "41": [0.25, 0.75, 0.03306, 0, 0.47333],
+ "42": [0, 0.75, 0.14333, 0, 0.59111],
+ "43": [0.10333, 0.60333, 0.03306, 0, 0.88555],
+ "44": [0.19444, 0.14722, 0, 0, 0.35555],
+ "45": [0, 0.44444, 0.02611, 0, 0.41444],
+ "46": [0, 0.14722, 0, 0, 0.35555],
+ "47": [0.25, 0.75, 0.15806, 0, 0.59111],
+ "48": [0, 0.64444, 0.13167, 0, 0.59111],
+ "49": [0, 0.64444, 0.13167, 0, 0.59111],
+ "50": [0, 0.64444, 0.13167, 0, 0.59111],
+ "51": [0, 0.64444, 0.13167, 0, 0.59111],
+ "52": [0.19444, 0.64444, 0.13167, 0, 0.59111],
+ "53": [0, 0.64444, 0.13167, 0, 0.59111],
+ "54": [0, 0.64444, 0.13167, 0, 0.59111],
+ "55": [0.19444, 0.64444, 0.13167, 0, 0.59111],
+ "56": [0, 0.64444, 0.13167, 0, 0.59111],
+ "57": [0, 0.64444, 0.13167, 0, 0.59111],
+ "58": [0, 0.44444, 0.06695, 0, 0.35555],
+ "59": [0.19444, 0.44444, 0.06695, 0, 0.35555],
+ "61": [-0.10889, 0.39111, 0.06833, 0, 0.88555],
+ "63": [0, 0.69444, 0.11472, 0, 0.59111],
+ "64": [0, 0.69444, 0.09208, 0, 0.88555],
+ "65": [0, 0.68611, 0, 0, 0.86555],
+ "66": [0, 0.68611, 0.0992, 0, 0.81666],
+ "67": [0, 0.68611, 0.14208, 0, 0.82666],
+ "68": [0, 0.68611, 0.09062, 0, 0.87555],
+ "69": [0, 0.68611, 0.11431, 0, 0.75666],
+ "70": [0, 0.68611, 0.12903, 0, 0.72722],
+ "71": [0, 0.68611, 0.07347, 0, 0.89527],
+ "72": [0, 0.68611, 0.17208, 0, 0.8961],
+ "73": [0, 0.68611, 0.15681, 0, 0.47166],
+ "74": [0, 0.68611, 0.145, 0, 0.61055],
+ "75": [0, 0.68611, 0.14208, 0, 0.89499],
+ "76": [0, 0.68611, 0, 0, 0.69777],
+ "77": [0, 0.68611, 0.17208, 0, 1.07277],
+ "78": [0, 0.68611, 0.17208, 0, 0.8961],
+ "79": [0, 0.68611, 0.09062, 0, 0.85499],
+ "80": [0, 0.68611, 0.0992, 0, 0.78721],
+ "81": [0.19444, 0.68611, 0.09062, 0, 0.85499],
+ "82": [0, 0.68611, 0.02559, 0, 0.85944],
+ "83": [0, 0.68611, 0.11264, 0, 0.64999],
+ "84": [0, 0.68611, 0.12903, 0, 0.7961],
+ "85": [0, 0.68611, 0.17208, 0, 0.88083],
+ "86": [0, 0.68611, 0.18625, 0, 0.86555],
+ "87": [0, 0.68611, 0.18625, 0, 1.15999],
+ "88": [0, 0.68611, 0.15681, 0, 0.86555],
+ "89": [0, 0.68611, 0.19803, 0, 0.86555],
+ "90": [0, 0.68611, 0.14208, 0, 0.70888],
+ "91": [0.25, 0.75, 0.1875, 0, 0.35611],
+ "93": [0.25, 0.75, 0.09972, 0, 0.35611],
+ "94": [0, 0.69444, 0.06709, 0, 0.59111],
+ "95": [0.31, 0.13444, 0.09811, 0, 0.59111],
+ "97": [0, 0.44444, 0.09426, 0, 0.59111],
+ "98": [0, 0.69444, 0.07861, 0, 0.53222],
+ "99": [0, 0.44444, 0.05222, 0, 0.53222],
+ "100": [0, 0.69444, 0.10861, 0, 0.59111],
+ "101": [0, 0.44444, 0.085, 0, 0.53222],
+ "102": [0.19444, 0.69444, 0.21778, 0, 0.4],
+ "103": [0.19444, 0.44444, 0.105, 0, 0.53222],
+ "104": [0, 0.69444, 0.09426, 0, 0.59111],
+ "105": [0, 0.69326, 0.11387, 0, 0.35555],
+ "106": [0.19444, 0.69326, 0.1672, 0, 0.35555],
+ "107": [0, 0.69444, 0.11111, 0, 0.53222],
+ "108": [0, 0.69444, 0.10861, 0, 0.29666],
+ "109": [0, 0.44444, 0.09426, 0, 0.94444],
+ "110": [0, 0.44444, 0.09426, 0, 0.64999],
+ "111": [0, 0.44444, 0.07861, 0, 0.59111],
+ "112": [0.19444, 0.44444, 0.07861, 0, 0.59111],
+ "113": [0.19444, 0.44444, 0.105, 0, 0.53222],
+ "114": [0, 0.44444, 0.11111, 0, 0.50167],
+ "115": [0, 0.44444, 0.08167, 0, 0.48694],
+ "116": [0, 0.63492, 0.09639, 0, 0.385],
+ "117": [0, 0.44444, 0.09426, 0, 0.62055],
+ "118": [0, 0.44444, 0.11111, 0, 0.53222],
+ "119": [0, 0.44444, 0.11111, 0, 0.76777],
+ "120": [0, 0.44444, 0.12583, 0, 0.56055],
+ "121": [0.19444, 0.44444, 0.105, 0, 0.56166],
+ "122": [0, 0.44444, 0.13889, 0, 0.49055],
+ "126": [0.35, 0.34444, 0.11472, 0, 0.59111],
+ "160": [0, 0, 0, 0, 0.25],
+ "168": [0, 0.69444, 0.11473, 0, 0.59111],
+ "176": [0, 0.69444, 0, 0, 0.94888],
+ "184": [0.17014, 0, 0, 0, 0.53222],
+ "198": [0, 0.68611, 0.11431, 0, 1.02277],
+ "216": [0.04861, 0.73472, 0.09062, 0, 0.88555],
+ "223": [0.19444, 0.69444, 0.09736, 0, 0.665],
+ "230": [0, 0.44444, 0.085, 0, 0.82666],
+ "248": [0.09722, 0.54167, 0.09458, 0, 0.59111],
+ "305": [0, 0.44444, 0.09426, 0, 0.35555],
+ "338": [0, 0.68611, 0.11431, 0, 1.14054],
+ "339": [0, 0.44444, 0.085, 0, 0.82666],
+ "567": [0.19444, 0.44444, 0.04611, 0, 0.385],
+ "710": [0, 0.69444, 0.06709, 0, 0.59111],
+ "711": [0, 0.63194, 0.08271, 0, 0.59111],
+ "713": [0, 0.59444, 0.10444, 0, 0.59111],
+ "714": [0, 0.69444, 0.08528, 0, 0.59111],
+ "715": [0, 0.69444, 0, 0, 0.59111],
+ "728": [0, 0.69444, 0.10333, 0, 0.59111],
+ "729": [0, 0.69444, 0.12945, 0, 0.35555],
+ "730": [0, 0.69444, 0, 0, 0.94888],
+ "732": [0, 0.69444, 0.11472, 0, 0.59111],
+ "733": [0, 0.69444, 0.11472, 0, 0.59111],
+ "915": [0, 0.68611, 0.12903, 0, 0.69777],
+ "916": [0, 0.68611, 0, 0, 0.94444],
+ "920": [0, 0.68611, 0.09062, 0, 0.88555],
+ "923": [0, 0.68611, 0, 0, 0.80666],
+ "926": [0, 0.68611, 0.15092, 0, 0.76777],
+ "928": [0, 0.68611, 0.17208, 0, 0.8961],
+ "931": [0, 0.68611, 0.11431, 0, 0.82666],
+ "933": [0, 0.68611, 0.10778, 0, 0.88555],
+ "934": [0, 0.68611, 0.05632, 0, 0.82666],
+ "936": [0, 0.68611, 0.10778, 0, 0.88555],
+ "937": [0, 0.68611, 0.0992, 0, 0.82666],
+ "8211": [0, 0.44444, 0.09811, 0, 0.59111],
+ "8212": [0, 0.44444, 0.09811, 0, 1.18221],
+ "8216": [0, 0.69444, 0.12945, 0, 0.35555],
+ "8217": [0, 0.69444, 0.12945, 0, 0.35555],
+ "8220": [0, 0.69444, 0.16772, 0, 0.62055],
+ "8221": [0, 0.69444, 0.07939, 0, 0.62055]
+ },
+ "Main-Italic": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0.12417, 0, 0.30667],
+ "34": [0, 0.69444, 0.06961, 0, 0.51444],
+ "35": [0.19444, 0.69444, 0.06616, 0, 0.81777],
+ "37": [0.05556, 0.75, 0.13639, 0, 0.81777],
+ "38": [0, 0.69444, 0.09694, 0, 0.76666],
+ "39": [0, 0.69444, 0.12417, 0, 0.30667],
+ "40": [0.25, 0.75, 0.16194, 0, 0.40889],
+ "41": [0.25, 0.75, 0.03694, 0, 0.40889],
+ "42": [0, 0.75, 0.14917, 0, 0.51111],
+ "43": [0.05667, 0.56167, 0.03694, 0, 0.76666],
+ "44": [0.19444, 0.10556, 0, 0, 0.30667],
+ "45": [0, 0.43056, 0.02826, 0, 0.35778],
+ "46": [0, 0.10556, 0, 0, 0.30667],
+ "47": [0.25, 0.75, 0.16194, 0, 0.51111],
+ "48": [0, 0.64444, 0.13556, 0, 0.51111],
+ "49": [0, 0.64444, 0.13556, 0, 0.51111],
+ "50": [0, 0.64444, 0.13556, 0, 0.51111],
+ "51": [0, 0.64444, 0.13556, 0, 0.51111],
+ "52": [0.19444, 0.64444, 0.13556, 0, 0.51111],
+ "53": [0, 0.64444, 0.13556, 0, 0.51111],
+ "54": [0, 0.64444, 0.13556, 0, 0.51111],
+ "55": [0.19444, 0.64444, 0.13556, 0, 0.51111],
+ "56": [0, 0.64444, 0.13556, 0, 0.51111],
+ "57": [0, 0.64444, 0.13556, 0, 0.51111],
+ "58": [0, 0.43056, 0.0582, 0, 0.30667],
+ "59": [0.19444, 0.43056, 0.0582, 0, 0.30667],
+ "61": [-0.13313, 0.36687, 0.06616, 0, 0.76666],
+ "63": [0, 0.69444, 0.1225, 0, 0.51111],
+ "64": [0, 0.69444, 0.09597, 0, 0.76666],
+ "65": [0, 0.68333, 0, 0, 0.74333],
+ "66": [0, 0.68333, 0.10257, 0, 0.70389],
+ "67": [0, 0.68333, 0.14528, 0, 0.71555],
+ "68": [0, 0.68333, 0.09403, 0, 0.755],
+ "69": [0, 0.68333, 0.12028, 0, 0.67833],
+ "70": [0, 0.68333, 0.13305, 0, 0.65277],
+ "71": [0, 0.68333, 0.08722, 0, 0.77361],
+ "72": [0, 0.68333, 0.16389, 0, 0.74333],
+ "73": [0, 0.68333, 0.15806, 0, 0.38555],
+ "74": [0, 0.68333, 0.14028, 0, 0.525],
+ "75": [0, 0.68333, 0.14528, 0, 0.76888],
+ "76": [0, 0.68333, 0, 0, 0.62722],
+ "77": [0, 0.68333, 0.16389, 0, 0.89666],
+ "78": [0, 0.68333, 0.16389, 0, 0.74333],
+ "79": [0, 0.68333, 0.09403, 0, 0.76666],
+ "80": [0, 0.68333, 0.10257, 0, 0.67833],
+ "81": [0.19444, 0.68333, 0.09403, 0, 0.76666],
+ "82": [0, 0.68333, 0.03868, 0, 0.72944],
+ "83": [0, 0.68333, 0.11972, 0, 0.56222],
+ "84": [0, 0.68333, 0.13305, 0, 0.71555],
+ "85": [0, 0.68333, 0.16389, 0, 0.74333],
+ "86": [0, 0.68333, 0.18361, 0, 0.74333],
+ "87": [0, 0.68333, 0.18361, 0, 0.99888],
+ "88": [0, 0.68333, 0.15806, 0, 0.74333],
+ "89": [0, 0.68333, 0.19383, 0, 0.74333],
+ "90": [0, 0.68333, 0.14528, 0, 0.61333],
+ "91": [0.25, 0.75, 0.1875, 0, 0.30667],
+ "93": [0.25, 0.75, 0.10528, 0, 0.30667],
+ "94": [0, 0.69444, 0.06646, 0, 0.51111],
+ "95": [0.31, 0.12056, 0.09208, 0, 0.51111],
+ "97": [0, 0.43056, 0.07671, 0, 0.51111],
+ "98": [0, 0.69444, 0.06312, 0, 0.46],
+ "99": [0, 0.43056, 0.05653, 0, 0.46],
+ "100": [0, 0.69444, 0.10333, 0, 0.51111],
+ "101": [0, 0.43056, 0.07514, 0, 0.46],
+ "102": [0.19444, 0.69444, 0.21194, 0, 0.30667],
+ "103": [0.19444, 0.43056, 0.08847, 0, 0.46],
+ "104": [0, 0.69444, 0.07671, 0, 0.51111],
+ "105": [0, 0.65536, 0.1019, 0, 0.30667],
+ "106": [0.19444, 0.65536, 0.14467, 0, 0.30667],
+ "107": [0, 0.69444, 0.10764, 0, 0.46],
+ "108": [0, 0.69444, 0.10333, 0, 0.25555],
+ "109": [0, 0.43056, 0.07671, 0, 0.81777],
+ "110": [0, 0.43056, 0.07671, 0, 0.56222],
+ "111": [0, 0.43056, 0.06312, 0, 0.51111],
+ "112": [0.19444, 0.43056, 0.06312, 0, 0.51111],
+ "113": [0.19444, 0.43056, 0.08847, 0, 0.46],
+ "114": [0, 0.43056, 0.10764, 0, 0.42166],
+ "115": [0, 0.43056, 0.08208, 0, 0.40889],
+ "116": [0, 0.61508, 0.09486, 0, 0.33222],
+ "117": [0, 0.43056, 0.07671, 0, 0.53666],
+ "118": [0, 0.43056, 0.10764, 0, 0.46],
+ "119": [0, 0.43056, 0.10764, 0, 0.66444],
+ "120": [0, 0.43056, 0.12042, 0, 0.46389],
+ "121": [0.19444, 0.43056, 0.08847, 0, 0.48555],
+ "122": [0, 0.43056, 0.12292, 0, 0.40889],
+ "126": [0.35, 0.31786, 0.11585, 0, 0.51111],
+ "160": [0, 0, 0, 0, 0.25],
+ "168": [0, 0.66786, 0.10474, 0, 0.51111],
+ "176": [0, 0.69444, 0, 0, 0.83129],
+ "184": [0.17014, 0, 0, 0, 0.46],
+ "198": [0, 0.68333, 0.12028, 0, 0.88277],
+ "216": [0.04861, 0.73194, 0.09403, 0, 0.76666],
+ "223": [0.19444, 0.69444, 0.10514, 0, 0.53666],
+ "230": [0, 0.43056, 0.07514, 0, 0.71555],
+ "248": [0.09722, 0.52778, 0.09194, 0, 0.51111],
+ "338": [0, 0.68333, 0.12028, 0, 0.98499],
+ "339": [0, 0.43056, 0.07514, 0, 0.71555],
+ "710": [0, 0.69444, 0.06646, 0, 0.51111],
+ "711": [0, 0.62847, 0.08295, 0, 0.51111],
+ "713": [0, 0.56167, 0.10333, 0, 0.51111],
+ "714": [0, 0.69444, 0.09694, 0, 0.51111],
+ "715": [0, 0.69444, 0, 0, 0.51111],
+ "728": [0, 0.69444, 0.10806, 0, 0.51111],
+ "729": [0, 0.66786, 0.11752, 0, 0.30667],
+ "730": [0, 0.69444, 0, 0, 0.83129],
+ "732": [0, 0.66786, 0.11585, 0, 0.51111],
+ "733": [0, 0.69444, 0.1225, 0, 0.51111],
+ "915": [0, 0.68333, 0.13305, 0, 0.62722],
+ "916": [0, 0.68333, 0, 0, 0.81777],
+ "920": [0, 0.68333, 0.09403, 0, 0.76666],
+ "923": [0, 0.68333, 0, 0, 0.69222],
+ "926": [0, 0.68333, 0.15294, 0, 0.66444],
+ "928": [0, 0.68333, 0.16389, 0, 0.74333],
+ "931": [0, 0.68333, 0.12028, 0, 0.71555],
+ "933": [0, 0.68333, 0.11111, 0, 0.76666],
+ "934": [0, 0.68333, 0.05986, 0, 0.71555],
+ "936": [0, 0.68333, 0.11111, 0, 0.76666],
+ "937": [0, 0.68333, 0.10257, 0, 0.71555],
+ "8211": [0, 0.43056, 0.09208, 0, 0.51111],
+ "8212": [0, 0.43056, 0.09208, 0, 1.02222],
+ "8216": [0, 0.69444, 0.12417, 0, 0.30667],
+ "8217": [0, 0.69444, 0.12417, 0, 0.30667],
+ "8220": [0, 0.69444, 0.1685, 0, 0.51444],
+ "8221": [0, 0.69444, 0.06961, 0, 0.51444],
+ "8463": [0, 0.68889, 0, 0, 0.54028]
+ },
+ "Main-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0, 0, 0.27778],
+ "34": [0, 0.69444, 0, 0, 0.5],
+ "35": [0.19444, 0.69444, 0, 0, 0.83334],
+ "36": [0.05556, 0.75, 0, 0, 0.5],
+ "37": [0.05556, 0.75, 0, 0, 0.83334],
+ "38": [0, 0.69444, 0, 0, 0.77778],
+ "39": [0, 0.69444, 0, 0, 0.27778],
+ "40": [0.25, 0.75, 0, 0, 0.38889],
+ "41": [0.25, 0.75, 0, 0, 0.38889],
+ "42": [0, 0.75, 0, 0, 0.5],
+ "43": [0.08333, 0.58333, 0, 0, 0.77778],
+ "44": [0.19444, 0.10556, 0, 0, 0.27778],
+ "45": [0, 0.43056, 0, 0, 0.33333],
+ "46": [0, 0.10556, 0, 0, 0.27778],
+ "47": [0.25, 0.75, 0, 0, 0.5],
+ "48": [0, 0.64444, 0, 0, 0.5],
+ "49": [0, 0.64444, 0, 0, 0.5],
+ "50": [0, 0.64444, 0, 0, 0.5],
+ "51": [0, 0.64444, 0, 0, 0.5],
+ "52": [0, 0.64444, 0, 0, 0.5],
+ "53": [0, 0.64444, 0, 0, 0.5],
+ "54": [0, 0.64444, 0, 0, 0.5],
+ "55": [0, 0.64444, 0, 0, 0.5],
+ "56": [0, 0.64444, 0, 0, 0.5],
+ "57": [0, 0.64444, 0, 0, 0.5],
+ "58": [0, 0.43056, 0, 0, 0.27778],
+ "59": [0.19444, 0.43056, 0, 0, 0.27778],
+ "60": [0.0391, 0.5391, 0, 0, 0.77778],
+ "61": [-0.13313, 0.36687, 0, 0, 0.77778],
+ "62": [0.0391, 0.5391, 0, 0, 0.77778],
+ "63": [0, 0.69444, 0, 0, 0.47222],
+ "64": [0, 0.69444, 0, 0, 0.77778],
+ "65": [0, 0.68333, 0, 0, 0.75],
+ "66": [0, 0.68333, 0, 0, 0.70834],
+ "67": [0, 0.68333, 0, 0, 0.72222],
+ "68": [0, 0.68333, 0, 0, 0.76389],
+ "69": [0, 0.68333, 0, 0, 0.68056],
+ "70": [0, 0.68333, 0, 0, 0.65278],
+ "71": [0, 0.68333, 0, 0, 0.78472],
+ "72": [0, 0.68333, 0, 0, 0.75],
+ "73": [0, 0.68333, 0, 0, 0.36111],
+ "74": [0, 0.68333, 0, 0, 0.51389],
+ "75": [0, 0.68333, 0, 0, 0.77778],
+ "76": [0, 0.68333, 0, 0, 0.625],
+ "77": [0, 0.68333, 0, 0, 0.91667],
+ "78": [0, 0.68333, 0, 0, 0.75],
+ "79": [0, 0.68333, 0, 0, 0.77778],
+ "80": [0, 0.68333, 0, 0, 0.68056],
+ "81": [0.19444, 0.68333, 0, 0, 0.77778],
+ "82": [0, 0.68333, 0, 0, 0.73611],
+ "83": [0, 0.68333, 0, 0, 0.55556],
+ "84": [0, 0.68333, 0, 0, 0.72222],
+ "85": [0, 0.68333, 0, 0, 0.75],
+ "86": [0, 0.68333, 0.01389, 0, 0.75],
+ "87": [0, 0.68333, 0.01389, 0, 1.02778],
+ "88": [0, 0.68333, 0, 0, 0.75],
+ "89": [0, 0.68333, 0.025, 0, 0.75],
+ "90": [0, 0.68333, 0, 0, 0.61111],
+ "91": [0.25, 0.75, 0, 0, 0.27778],
+ "92": [0.25, 0.75, 0, 0, 0.5],
+ "93": [0.25, 0.75, 0, 0, 0.27778],
+ "94": [0, 0.69444, 0, 0, 0.5],
+ "95": [0.31, 0.12056, 0.02778, 0, 0.5],
+ "97": [0, 0.43056, 0, 0, 0.5],
+ "98": [0, 0.69444, 0, 0, 0.55556],
+ "99": [0, 0.43056, 0, 0, 0.44445],
+ "100": [0, 0.69444, 0, 0, 0.55556],
+ "101": [0, 0.43056, 0, 0, 0.44445],
+ "102": [0, 0.69444, 0.07778, 0, 0.30556],
+ "103": [0.19444, 0.43056, 0.01389, 0, 0.5],
+ "104": [0, 0.69444, 0, 0, 0.55556],
+ "105": [0, 0.66786, 0, 0, 0.27778],
+ "106": [0.19444, 0.66786, 0, 0, 0.30556],
+ "107": [0, 0.69444, 0, 0, 0.52778],
+ "108": [0, 0.69444, 0, 0, 0.27778],
+ "109": [0, 0.43056, 0, 0, 0.83334],
+ "110": [0, 0.43056, 0, 0, 0.55556],
+ "111": [0, 0.43056, 0, 0, 0.5],
+ "112": [0.19444, 0.43056, 0, 0, 0.55556],
+ "113": [0.19444, 0.43056, 0, 0, 0.52778],
+ "114": [0, 0.43056, 0, 0, 0.39167],
+ "115": [0, 0.43056, 0, 0, 0.39445],
+ "116": [0, 0.61508, 0, 0, 0.38889],
+ "117": [0, 0.43056, 0, 0, 0.55556],
+ "118": [0, 0.43056, 0.01389, 0, 0.52778],
+ "119": [0, 0.43056, 0.01389, 0, 0.72222],
+ "120": [0, 0.43056, 0, 0, 0.52778],
+ "121": [0.19444, 0.43056, 0.01389, 0, 0.52778],
+ "122": [0, 0.43056, 0, 0, 0.44445],
+ "123": [0.25, 0.75, 0, 0, 0.5],
+ "124": [0.25, 0.75, 0, 0, 0.27778],
+ "125": [0.25, 0.75, 0, 0, 0.5],
+ "126": [0.35, 0.31786, 0, 0, 0.5],
+ "160": [0, 0, 0, 0, 0.25],
+ "163": [0, 0.69444, 0, 0, 0.76909],
+ "167": [0.19444, 0.69444, 0, 0, 0.44445],
+ "168": [0, 0.66786, 0, 0, 0.5],
+ "172": [0, 0.43056, 0, 0, 0.66667],
+ "176": [0, 0.69444, 0, 0, 0.75],
+ "177": [0.08333, 0.58333, 0, 0, 0.77778],
+ "182": [0.19444, 0.69444, 0, 0, 0.61111],
+ "184": [0.17014, 0, 0, 0, 0.44445],
+ "198": [0, 0.68333, 0, 0, 0.90278],
+ "215": [0.08333, 0.58333, 0, 0, 0.77778],
+ "216": [0.04861, 0.73194, 0, 0, 0.77778],
+ "223": [0, 0.69444, 0, 0, 0.5],
+ "230": [0, 0.43056, 0, 0, 0.72222],
+ "247": [0.08333, 0.58333, 0, 0, 0.77778],
+ "248": [0.09722, 0.52778, 0, 0, 0.5],
+ "305": [0, 0.43056, 0, 0, 0.27778],
+ "338": [0, 0.68333, 0, 0, 1.01389],
+ "339": [0, 0.43056, 0, 0, 0.77778],
+ "567": [0.19444, 0.43056, 0, 0, 0.30556],
+ "710": [0, 0.69444, 0, 0, 0.5],
+ "711": [0, 0.62847, 0, 0, 0.5],
+ "713": [0, 0.56778, 0, 0, 0.5],
+ "714": [0, 0.69444, 0, 0, 0.5],
+ "715": [0, 0.69444, 0, 0, 0.5],
+ "728": [0, 0.69444, 0, 0, 0.5],
+ "729": [0, 0.66786, 0, 0, 0.27778],
+ "730": [0, 0.69444, 0, 0, 0.75],
+ "732": [0, 0.66786, 0, 0, 0.5],
+ "733": [0, 0.69444, 0, 0, 0.5],
+ "915": [0, 0.68333, 0, 0, 0.625],
+ "916": [0, 0.68333, 0, 0, 0.83334],
+ "920": [0, 0.68333, 0, 0, 0.77778],
+ "923": [0, 0.68333, 0, 0, 0.69445],
+ "926": [0, 0.68333, 0, 0, 0.66667],
+ "928": [0, 0.68333, 0, 0, 0.75],
+ "931": [0, 0.68333, 0, 0, 0.72222],
+ "933": [0, 0.68333, 0, 0, 0.77778],
+ "934": [0, 0.68333, 0, 0, 0.72222],
+ "936": [0, 0.68333, 0, 0, 0.77778],
+ "937": [0, 0.68333, 0, 0, 0.72222],
+ "8211": [0, 0.43056, 0.02778, 0, 0.5],
+ "8212": [0, 0.43056, 0.02778, 0, 1.0],
+ "8216": [0, 0.69444, 0, 0, 0.27778],
+ "8217": [0, 0.69444, 0, 0, 0.27778],
+ "8220": [0, 0.69444, 0, 0, 0.5],
+ "8221": [0, 0.69444, 0, 0, 0.5],
+ "8224": [0.19444, 0.69444, 0, 0, 0.44445],
+ "8225": [0.19444, 0.69444, 0, 0, 0.44445],
+ "8230": [0, 0.123, 0, 0, 1.172],
+ "8242": [0, 0.55556, 0, 0, 0.275],
+ "8407": [0, 0.71444, 0.15382, 0, 0.5],
+ "8463": [0, 0.68889, 0, 0, 0.54028],
+ "8465": [0, 0.69444, 0, 0, 0.72222],
+ "8467": [0, 0.69444, 0, 0.11111, 0.41667],
+ "8472": [0.19444, 0.43056, 0, 0.11111, 0.63646],
+ "8476": [0, 0.69444, 0, 0, 0.72222],
+ "8501": [0, 0.69444, 0, 0, 0.61111],
+ "8592": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8593": [0.19444, 0.69444, 0, 0, 0.5],
+ "8594": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8595": [0.19444, 0.69444, 0, 0, 0.5],
+ "8596": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8597": [0.25, 0.75, 0, 0, 0.5],
+ "8598": [0.19444, 0.69444, 0, 0, 1.0],
+ "8599": [0.19444, 0.69444, 0, 0, 1.0],
+ "8600": [0.19444, 0.69444, 0, 0, 1.0],
+ "8601": [0.19444, 0.69444, 0, 0, 1.0],
+ "8614": [0.011, 0.511, 0, 0, 1.0],
+ "8617": [0.011, 0.511, 0, 0, 1.126],
+ "8618": [0.011, 0.511, 0, 0, 1.126],
+ "8636": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8637": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8640": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8641": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8652": [0.011, 0.671, 0, 0, 1.0],
+ "8656": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8657": [0.19444, 0.69444, 0, 0, 0.61111],
+ "8658": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8659": [0.19444, 0.69444, 0, 0, 0.61111],
+ "8660": [-0.13313, 0.36687, 0, 0, 1.0],
+ "8661": [0.25, 0.75, 0, 0, 0.61111],
+ "8704": [0, 0.69444, 0, 0, 0.55556],
+ "8706": [0, 0.69444, 0.05556, 0.08334, 0.5309],
+ "8707": [0, 0.69444, 0, 0, 0.55556],
+ "8709": [0.05556, 0.75, 0, 0, 0.5],
+ "8711": [0, 0.68333, 0, 0, 0.83334],
+ "8712": [0.0391, 0.5391, 0, 0, 0.66667],
+ "8715": [0.0391, 0.5391, 0, 0, 0.66667],
+ "8722": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8723": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8725": [0.25, 0.75, 0, 0, 0.5],
+ "8726": [0.25, 0.75, 0, 0, 0.5],
+ "8727": [-0.03472, 0.46528, 0, 0, 0.5],
+ "8728": [-0.05555, 0.44445, 0, 0, 0.5],
+ "8729": [-0.05555, 0.44445, 0, 0, 0.5],
+ "8730": [0.2, 0.8, 0, 0, 0.83334],
+ "8733": [0, 0.43056, 0, 0, 0.77778],
+ "8734": [0, 0.43056, 0, 0, 1.0],
+ "8736": [0, 0.69224, 0, 0, 0.72222],
+ "8739": [0.25, 0.75, 0, 0, 0.27778],
+ "8741": [0.25, 0.75, 0, 0, 0.5],
+ "8743": [0, 0.55556, 0, 0, 0.66667],
+ "8744": [0, 0.55556, 0, 0, 0.66667],
+ "8745": [0, 0.55556, 0, 0, 0.66667],
+ "8746": [0, 0.55556, 0, 0, 0.66667],
+ "8747": [0.19444, 0.69444, 0.11111, 0, 0.41667],
+ "8764": [-0.13313, 0.36687, 0, 0, 0.77778],
+ "8768": [0.19444, 0.69444, 0, 0, 0.27778],
+ "8771": [-0.03625, 0.46375, 0, 0, 0.77778],
+ "8773": [-0.022, 0.589, 0, 0, 0.778],
+ "8776": [-0.01688, 0.48312, 0, 0, 0.77778],
+ "8781": [-0.03625, 0.46375, 0, 0, 0.77778],
+ "8784": [-0.133, 0.673, 0, 0, 0.778],
+ "8801": [-0.03625, 0.46375, 0, 0, 0.77778],
+ "8804": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8805": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8810": [0.0391, 0.5391, 0, 0, 1.0],
+ "8811": [0.0391, 0.5391, 0, 0, 1.0],
+ "8826": [0.0391, 0.5391, 0, 0, 0.77778],
+ "8827": [0.0391, 0.5391, 0, 0, 0.77778],
+ "8834": [0.0391, 0.5391, 0, 0, 0.77778],
+ "8835": [0.0391, 0.5391, 0, 0, 0.77778],
+ "8838": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8839": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8846": [0, 0.55556, 0, 0, 0.66667],
+ "8849": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8850": [0.13597, 0.63597, 0, 0, 0.77778],
+ "8851": [0, 0.55556, 0, 0, 0.66667],
+ "8852": [0, 0.55556, 0, 0, 0.66667],
+ "8853": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8854": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8855": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8856": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8857": [0.08333, 0.58333, 0, 0, 0.77778],
+ "8866": [0, 0.69444, 0, 0, 0.61111],
+ "8867": [0, 0.69444, 0, 0, 0.61111],
+ "8868": [0, 0.69444, 0, 0, 0.77778],
+ "8869": [0, 0.69444, 0, 0, 0.77778],
+ "8872": [0.249, 0.75, 0, 0, 0.867],
+ "8900": [-0.05555, 0.44445, 0, 0, 0.5],
+ "8901": [-0.05555, 0.44445, 0, 0, 0.27778],
+ "8902": [-0.03472, 0.46528, 0, 0, 0.5],
+ "8904": [0.005, 0.505, 0, 0, 0.9],
+ "8942": [0.03, 0.903, 0, 0, 0.278],
+ "8943": [-0.19, 0.313, 0, 0, 1.172],
+ "8945": [-0.1, 0.823, 0, 0, 1.282],
+ "8968": [0.25, 0.75, 0, 0, 0.44445],
+ "8969": [0.25, 0.75, 0, 0, 0.44445],
+ "8970": [0.25, 0.75, 0, 0, 0.44445],
+ "8971": [0.25, 0.75, 0, 0, 0.44445],
+ "8994": [-0.14236, 0.35764, 0, 0, 1.0],
+ "8995": [-0.14236, 0.35764, 0, 0, 1.0],
+ "9136": [0.244, 0.744, 0, 0, 0.412],
+ "9137": [0.244, 0.745, 0, 0, 0.412],
+ "9651": [0.19444, 0.69444, 0, 0, 0.88889],
+ "9657": [-0.03472, 0.46528, 0, 0, 0.5],
+ "9661": [0.19444, 0.69444, 0, 0, 0.88889],
+ "9667": [-0.03472, 0.46528, 0, 0, 0.5],
+ "9711": [0.19444, 0.69444, 0, 0, 1.0],
+ "9824": [0.12963, 0.69444, 0, 0, 0.77778],
+ "9825": [0.12963, 0.69444, 0, 0, 0.77778],
+ "9826": [0.12963, 0.69444, 0, 0, 0.77778],
+ "9827": [0.12963, 0.69444, 0, 0, 0.77778],
+ "9837": [0, 0.75, 0, 0, 0.38889],
+ "9838": [0.19444, 0.69444, 0, 0, 0.38889],
+ "9839": [0.19444, 0.69444, 0, 0, 0.38889],
+ "10216": [0.25, 0.75, 0, 0, 0.38889],
+ "10217": [0.25, 0.75, 0, 0, 0.38889],
+ "10222": [0.244, 0.744, 0, 0, 0.412],
+ "10223": [0.244, 0.745, 0, 0, 0.412],
+ "10229": [0.011, 0.511, 0, 0, 1.609],
+ "10230": [0.011, 0.511, 0, 0, 1.638],
+ "10231": [0.011, 0.511, 0, 0, 1.859],
+ "10232": [0.024, 0.525, 0, 0, 1.609],
+ "10233": [0.024, 0.525, 0, 0, 1.638],
+ "10234": [0.024, 0.525, 0, 0, 1.858],
+ "10236": [0.011, 0.511, 0, 0, 1.638],
+ "10815": [0, 0.68333, 0, 0, 0.75],
+ "10927": [0.13597, 0.63597, 0, 0, 0.77778],
+ "10928": [0.13597, 0.63597, 0, 0, 0.77778],
+ "57376": [0.19444, 0.69444, 0, 0, 0]
+ },
+ "Math-BoldItalic": {
+ "32": [0, 0, 0, 0, 0.25],
+ "48": [0, 0.44444, 0, 0, 0.575],
+ "49": [0, 0.44444, 0, 0, 0.575],
+ "50": [0, 0.44444, 0, 0, 0.575],
+ "51": [0.19444, 0.44444, 0, 0, 0.575],
+ "52": [0.19444, 0.44444, 0, 0, 0.575],
+ "53": [0.19444, 0.44444, 0, 0, 0.575],
+ "54": [0, 0.64444, 0, 0, 0.575],
+ "55": [0.19444, 0.44444, 0, 0, 0.575],
+ "56": [0, 0.64444, 0, 0, 0.575],
+ "57": [0.19444, 0.44444, 0, 0, 0.575],
+ "65": [0, 0.68611, 0, 0, 0.86944],
+ "66": [0, 0.68611, 0.04835, 0, 0.8664],
+ "67": [0, 0.68611, 0.06979, 0, 0.81694],
+ "68": [0, 0.68611, 0.03194, 0, 0.93812],
+ "69": [0, 0.68611, 0.05451, 0, 0.81007],
+ "70": [0, 0.68611, 0.15972, 0, 0.68889],
+ "71": [0, 0.68611, 0, 0, 0.88673],
+ "72": [0, 0.68611, 0.08229, 0, 0.98229],
+ "73": [0, 0.68611, 0.07778, 0, 0.51111],
+ "74": [0, 0.68611, 0.10069, 0, 0.63125],
+ "75": [0, 0.68611, 0.06979, 0, 0.97118],
+ "76": [0, 0.68611, 0, 0, 0.75555],
+ "77": [0, 0.68611, 0.11424, 0, 1.14201],
+ "78": [0, 0.68611, 0.11424, 0, 0.95034],
+ "79": [0, 0.68611, 0.03194, 0, 0.83666],
+ "80": [0, 0.68611, 0.15972, 0, 0.72309],
+ "81": [0.19444, 0.68611, 0, 0, 0.86861],
+ "82": [0, 0.68611, 0.00421, 0, 0.87235],
+ "83": [0, 0.68611, 0.05382, 0, 0.69271],
+ "84": [0, 0.68611, 0.15972, 0, 0.63663],
+ "85": [0, 0.68611, 0.11424, 0, 0.80027],
+ "86": [0, 0.68611, 0.25555, 0, 0.67778],
+ "87": [0, 0.68611, 0.15972, 0, 1.09305],
+ "88": [0, 0.68611, 0.07778, 0, 0.94722],
+ "89": [0, 0.68611, 0.25555, 0, 0.67458],
+ "90": [0, 0.68611, 0.06979, 0, 0.77257],
+ "97": [0, 0.44444, 0, 0, 0.63287],
+ "98": [0, 0.69444, 0, 0, 0.52083],
+ "99": [0, 0.44444, 0, 0, 0.51342],
+ "100": [0, 0.69444, 0, 0, 0.60972],
+ "101": [0, 0.44444, 0, 0, 0.55361],
+ "102": [0.19444, 0.69444, 0.11042, 0, 0.56806],
+ "103": [0.19444, 0.44444, 0.03704, 0, 0.5449],
+ "104": [0, 0.69444, 0, 0, 0.66759],
+ "105": [0, 0.69326, 0, 0, 0.4048],
+ "106": [0.19444, 0.69326, 0.0622, 0, 0.47083],
+ "107": [0, 0.69444, 0.01852, 0, 0.6037],
+ "108": [0, 0.69444, 0.0088, 0, 0.34815],
+ "109": [0, 0.44444, 0, 0, 1.0324],
+ "110": [0, 0.44444, 0, 0, 0.71296],
+ "111": [0, 0.44444, 0, 0, 0.58472],
+ "112": [0.19444, 0.44444, 0, 0, 0.60092],
+ "113": [0.19444, 0.44444, 0.03704, 0, 0.54213],
+ "114": [0, 0.44444, 0.03194, 0, 0.5287],
+ "115": [0, 0.44444, 0, 0, 0.53125],
+ "116": [0, 0.63492, 0, 0, 0.41528],
+ "117": [0, 0.44444, 0, 0, 0.68102],
+ "118": [0, 0.44444, 0.03704, 0, 0.56666],
+ "119": [0, 0.44444, 0.02778, 0, 0.83148],
+ "120": [0, 0.44444, 0, 0, 0.65903],
+ "121": [0.19444, 0.44444, 0.03704, 0, 0.59028],
+ "122": [0, 0.44444, 0.04213, 0, 0.55509],
+ "160": [0, 0, 0, 0, 0.25],
+ "915": [0, 0.68611, 0.15972, 0, 0.65694],
+ "916": [0, 0.68611, 0, 0, 0.95833],
+ "920": [0, 0.68611, 0.03194, 0, 0.86722],
+ "923": [0, 0.68611, 0, 0, 0.80555],
+ "926": [0, 0.68611, 0.07458, 0, 0.84125],
+ "928": [0, 0.68611, 0.08229, 0, 0.98229],
+ "931": [0, 0.68611, 0.05451, 0, 0.88507],
+ "933": [0, 0.68611, 0.15972, 0, 0.67083],
+ "934": [0, 0.68611, 0, 0, 0.76666],
+ "936": [0, 0.68611, 0.11653, 0, 0.71402],
+ "937": [0, 0.68611, 0.04835, 0, 0.8789],
+ "945": [0, 0.44444, 0, 0, 0.76064],
+ "946": [0.19444, 0.69444, 0.03403, 0, 0.65972],
+ "947": [0.19444, 0.44444, 0.06389, 0, 0.59003],
+ "948": [0, 0.69444, 0.03819, 0, 0.52222],
+ "949": [0, 0.44444, 0, 0, 0.52882],
+ "950": [0.19444, 0.69444, 0.06215, 0, 0.50833],
+ "951": [0.19444, 0.44444, 0.03704, 0, 0.6],
+ "952": [0, 0.69444, 0.03194, 0, 0.5618],
+ "953": [0, 0.44444, 0, 0, 0.41204],
+ "954": [0, 0.44444, 0, 0, 0.66759],
+ "955": [0, 0.69444, 0, 0, 0.67083],
+ "956": [0.19444, 0.44444, 0, 0, 0.70787],
+ "957": [0, 0.44444, 0.06898, 0, 0.57685],
+ "958": [0.19444, 0.69444, 0.03021, 0, 0.50833],
+ "959": [0, 0.44444, 0, 0, 0.58472],
+ "960": [0, 0.44444, 0.03704, 0, 0.68241],
+ "961": [0.19444, 0.44444, 0, 0, 0.6118],
+ "962": [0.09722, 0.44444, 0.07917, 0, 0.42361],
+ "963": [0, 0.44444, 0.03704, 0, 0.68588],
+ "964": [0, 0.44444, 0.13472, 0, 0.52083],
+ "965": [0, 0.44444, 0.03704, 0, 0.63055],
+ "966": [0.19444, 0.44444, 0, 0, 0.74722],
+ "967": [0.19444, 0.44444, 0, 0, 0.71805],
+ "968": [0.19444, 0.69444, 0.03704, 0, 0.75833],
+ "969": [0, 0.44444, 0.03704, 0, 0.71782],
+ "977": [0, 0.69444, 0, 0, 0.69155],
+ "981": [0.19444, 0.69444, 0, 0, 0.7125],
+ "982": [0, 0.44444, 0.03194, 0, 0.975],
+ "1009": [0.19444, 0.44444, 0, 0, 0.6118],
+ "1013": [0, 0.44444, 0, 0, 0.48333],
+ "57649": [0, 0.44444, 0, 0, 0.39352],
+ "57911": [0.19444, 0.44444, 0, 0, 0.43889]
+ },
+ "Math-Italic": {
+ "32": [0, 0, 0, 0, 0.25],
+ "48": [0, 0.43056, 0, 0, 0.5],
+ "49": [0, 0.43056, 0, 0, 0.5],
+ "50": [0, 0.43056, 0, 0, 0.5],
+ "51": [0.19444, 0.43056, 0, 0, 0.5],
+ "52": [0.19444, 0.43056, 0, 0, 0.5],
+ "53": [0.19444, 0.43056, 0, 0, 0.5],
+ "54": [0, 0.64444, 0, 0, 0.5],
+ "55": [0.19444, 0.43056, 0, 0, 0.5],
+ "56": [0, 0.64444, 0, 0, 0.5],
+ "57": [0.19444, 0.43056, 0, 0, 0.5],
+ "65": [0, 0.68333, 0, 0.13889, 0.75],
+ "66": [0, 0.68333, 0.05017, 0.08334, 0.75851],
+ "67": [0, 0.68333, 0.07153, 0.08334, 0.71472],
+ "68": [0, 0.68333, 0.02778, 0.05556, 0.82792],
+ "69": [0, 0.68333, 0.05764, 0.08334, 0.7382],
+ "70": [0, 0.68333, 0.13889, 0.08334, 0.64306],
+ "71": [0, 0.68333, 0, 0.08334, 0.78625],
+ "72": [0, 0.68333, 0.08125, 0.05556, 0.83125],
+ "73": [0, 0.68333, 0.07847, 0.11111, 0.43958],
+ "74": [0, 0.68333, 0.09618, 0.16667, 0.55451],
+ "75": [0, 0.68333, 0.07153, 0.05556, 0.84931],
+ "76": [0, 0.68333, 0, 0.02778, 0.68056],
+ "77": [0, 0.68333, 0.10903, 0.08334, 0.97014],
+ "78": [0, 0.68333, 0.10903, 0.08334, 0.80347],
+ "79": [0, 0.68333, 0.02778, 0.08334, 0.76278],
+ "80": [0, 0.68333, 0.13889, 0.08334, 0.64201],
+ "81": [0.19444, 0.68333, 0, 0.08334, 0.79056],
+ "82": [0, 0.68333, 0.00773, 0.08334, 0.75929],
+ "83": [0, 0.68333, 0.05764, 0.08334, 0.6132],
+ "84": [0, 0.68333, 0.13889, 0.08334, 0.58438],
+ "85": [0, 0.68333, 0.10903, 0.02778, 0.68278],
+ "86": [0, 0.68333, 0.22222, 0, 0.58333],
+ "87": [0, 0.68333, 0.13889, 0, 0.94445],
+ "88": [0, 0.68333, 0.07847, 0.08334, 0.82847],
+ "89": [0, 0.68333, 0.22222, 0, 0.58056],
+ "90": [0, 0.68333, 0.07153, 0.08334, 0.68264],
+ "97": [0, 0.43056, 0, 0, 0.52859],
+ "98": [0, 0.69444, 0, 0, 0.42917],
+ "99": [0, 0.43056, 0, 0.05556, 0.43276],
+ "100": [0, 0.69444, 0, 0.16667, 0.52049],
+ "101": [0, 0.43056, 0, 0.05556, 0.46563],
+ "102": [0.19444, 0.69444, 0.10764, 0.16667, 0.48959],
+ "103": [0.19444, 0.43056, 0.03588, 0.02778, 0.47697],
+ "104": [0, 0.69444, 0, 0, 0.57616],
+ "105": [0, 0.65952, 0, 0, 0.34451],
+ "106": [0.19444, 0.65952, 0.05724, 0, 0.41181],
+ "107": [0, 0.69444, 0.03148, 0, 0.5206],
+ "108": [0, 0.69444, 0.01968, 0.08334, 0.29838],
+ "109": [0, 0.43056, 0, 0, 0.87801],
+ "110": [0, 0.43056, 0, 0, 0.60023],
+ "111": [0, 0.43056, 0, 0.05556, 0.48472],
+ "112": [0.19444, 0.43056, 0, 0.08334, 0.50313],
+ "113": [0.19444, 0.43056, 0.03588, 0.08334, 0.44641],
+ "114": [0, 0.43056, 0.02778, 0.05556, 0.45116],
+ "115": [0, 0.43056, 0, 0.05556, 0.46875],
+ "116": [0, 0.61508, 0, 0.08334, 0.36111],
+ "117": [0, 0.43056, 0, 0.02778, 0.57246],
+ "118": [0, 0.43056, 0.03588, 0.02778, 0.48472],
+ "119": [0, 0.43056, 0.02691, 0.08334, 0.71592],
+ "120": [0, 0.43056, 0, 0.02778, 0.57153],
+ "121": [0.19444, 0.43056, 0.03588, 0.05556, 0.49028],
+ "122": [0, 0.43056, 0.04398, 0.05556, 0.46505],
+ "160": [0, 0, 0, 0, 0.25],
+ "915": [0, 0.68333, 0.13889, 0.08334, 0.61528],
+ "916": [0, 0.68333, 0, 0.16667, 0.83334],
+ "920": [0, 0.68333, 0.02778, 0.08334, 0.76278],
+ "923": [0, 0.68333, 0, 0.16667, 0.69445],
+ "926": [0, 0.68333, 0.07569, 0.08334, 0.74236],
+ "928": [0, 0.68333, 0.08125, 0.05556, 0.83125],
+ "931": [0, 0.68333, 0.05764, 0.08334, 0.77986],
+ "933": [0, 0.68333, 0.13889, 0.05556, 0.58333],
+ "934": [0, 0.68333, 0, 0.08334, 0.66667],
+ "936": [0, 0.68333, 0.11, 0.05556, 0.61222],
+ "937": [0, 0.68333, 0.05017, 0.08334, 0.7724],
+ "945": [0, 0.43056, 0.0037, 0.02778, 0.6397],
+ "946": [0.19444, 0.69444, 0.05278, 0.08334, 0.56563],
+ "947": [0.19444, 0.43056, 0.05556, 0, 0.51773],
+ "948": [0, 0.69444, 0.03785, 0.05556, 0.44444],
+ "949": [0, 0.43056, 0, 0.08334, 0.46632],
+ "950": [0.19444, 0.69444, 0.07378, 0.08334, 0.4375],
+ "951": [0.19444, 0.43056, 0.03588, 0.05556, 0.49653],
+ "952": [0, 0.69444, 0.02778, 0.08334, 0.46944],
+ "953": [0, 0.43056, 0, 0.05556, 0.35394],
+ "954": [0, 0.43056, 0, 0, 0.57616],
+ "955": [0, 0.69444, 0, 0, 0.58334],
+ "956": [0.19444, 0.43056, 0, 0.02778, 0.60255],
+ "957": [0, 0.43056, 0.06366, 0.02778, 0.49398],
+ "958": [0.19444, 0.69444, 0.04601, 0.11111, 0.4375],
+ "959": [0, 0.43056, 0, 0.05556, 0.48472],
+ "960": [0, 0.43056, 0.03588, 0, 0.57003],
+ "961": [0.19444, 0.43056, 0, 0.08334, 0.51702],
+ "962": [0.09722, 0.43056, 0.07986, 0.08334, 0.36285],
+ "963": [0, 0.43056, 0.03588, 0, 0.57141],
+ "964": [0, 0.43056, 0.1132, 0.02778, 0.43715],
+ "965": [0, 0.43056, 0.03588, 0.02778, 0.54028],
+ "966": [0.19444, 0.43056, 0, 0.08334, 0.65417],
+ "967": [0.19444, 0.43056, 0, 0.05556, 0.62569],
+ "968": [0.19444, 0.69444, 0.03588, 0.11111, 0.65139],
+ "969": [0, 0.43056, 0.03588, 0, 0.62245],
+ "977": [0, 0.69444, 0, 0.08334, 0.59144],
+ "981": [0.19444, 0.69444, 0, 0.08334, 0.59583],
+ "982": [0, 0.43056, 0.02778, 0, 0.82813],
+ "1009": [0.19444, 0.43056, 0, 0.08334, 0.51702],
+ "1013": [0, 0.43056, 0, 0.05556, 0.4059],
+ "57649": [0, 0.43056, 0, 0.02778, 0.32246],
+ "57911": [0.19444, 0.43056, 0, 0.08334, 0.38403]
+ },
+ "SansSerif-Bold": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0, 0, 0.36667],
+ "34": [0, 0.69444, 0, 0, 0.55834],
+ "35": [0.19444, 0.69444, 0, 0, 0.91667],
+ "36": [0.05556, 0.75, 0, 0, 0.55],
+ "37": [0.05556, 0.75, 0, 0, 1.02912],
+ "38": [0, 0.69444, 0, 0, 0.83056],
+ "39": [0, 0.69444, 0, 0, 0.30556],
+ "40": [0.25, 0.75, 0, 0, 0.42778],
+ "41": [0.25, 0.75, 0, 0, 0.42778],
+ "42": [0, 0.75, 0, 0, 0.55],
+ "43": [0.11667, 0.61667, 0, 0, 0.85556],
+ "44": [0.10556, 0.13056, 0, 0, 0.30556],
+ "45": [0, 0.45833, 0, 0, 0.36667],
+ "46": [0, 0.13056, 0, 0, 0.30556],
+ "47": [0.25, 0.75, 0, 0, 0.55],
+ "48": [0, 0.69444, 0, 0, 0.55],
+ "49": [0, 0.69444, 0, 0, 0.55],
+ "50": [0, 0.69444, 0, 0, 0.55],
+ "51": [0, 0.69444, 0, 0, 0.55],
+ "52": [0, 0.69444, 0, 0, 0.55],
+ "53": [0, 0.69444, 0, 0, 0.55],
+ "54": [0, 0.69444, 0, 0, 0.55],
+ "55": [0, 0.69444, 0, 0, 0.55],
+ "56": [0, 0.69444, 0, 0, 0.55],
+ "57": [0, 0.69444, 0, 0, 0.55],
+ "58": [0, 0.45833, 0, 0, 0.30556],
+ "59": [0.10556, 0.45833, 0, 0, 0.30556],
+ "61": [-0.09375, 0.40625, 0, 0, 0.85556],
+ "63": [0, 0.69444, 0, 0, 0.51945],
+ "64": [0, 0.69444, 0, 0, 0.73334],
+ "65": [0, 0.69444, 0, 0, 0.73334],
+ "66": [0, 0.69444, 0, 0, 0.73334],
+ "67": [0, 0.69444, 0, 0, 0.70278],
+ "68": [0, 0.69444, 0, 0, 0.79445],
+ "69": [0, 0.69444, 0, 0, 0.64167],
+ "70": [0, 0.69444, 0, 0, 0.61111],
+ "71": [0, 0.69444, 0, 0, 0.73334],
+ "72": [0, 0.69444, 0, 0, 0.79445],
+ "73": [0, 0.69444, 0, 0, 0.33056],
+ "74": [0, 0.69444, 0, 0, 0.51945],
+ "75": [0, 0.69444, 0, 0, 0.76389],
+ "76": [0, 0.69444, 0, 0, 0.58056],
+ "77": [0, 0.69444, 0, 0, 0.97778],
+ "78": [0, 0.69444, 0, 0, 0.79445],
+ "79": [0, 0.69444, 0, 0, 0.79445],
+ "80": [0, 0.69444, 0, 0, 0.70278],
+ "81": [0.10556, 0.69444, 0, 0, 0.79445],
+ "82": [0, 0.69444, 0, 0, 0.70278],
+ "83": [0, 0.69444, 0, 0, 0.61111],
+ "84": [0, 0.69444, 0, 0, 0.73334],
+ "85": [0, 0.69444, 0, 0, 0.76389],
+ "86": [0, 0.69444, 0.01528, 0, 0.73334],
+ "87": [0, 0.69444, 0.01528, 0, 1.03889],
+ "88": [0, 0.69444, 0, 0, 0.73334],
+ "89": [0, 0.69444, 0.0275, 0, 0.73334],
+ "90": [0, 0.69444, 0, 0, 0.67223],
+ "91": [0.25, 0.75, 0, 0, 0.34306],
+ "93": [0.25, 0.75, 0, 0, 0.34306],
+ "94": [0, 0.69444, 0, 0, 0.55],
+ "95": [0.35, 0.10833, 0.03056, 0, 0.55],
+ "97": [0, 0.45833, 0, 0, 0.525],
+ "98": [0, 0.69444, 0, 0, 0.56111],
+ "99": [0, 0.45833, 0, 0, 0.48889],
+ "100": [0, 0.69444, 0, 0, 0.56111],
+ "101": [0, 0.45833, 0, 0, 0.51111],
+ "102": [0, 0.69444, 0.07639, 0, 0.33611],
+ "103": [0.19444, 0.45833, 0.01528, 0, 0.55],
+ "104": [0, 0.69444, 0, 0, 0.56111],
+ "105": [0, 0.69444, 0, 0, 0.25556],
+ "106": [0.19444, 0.69444, 0, 0, 0.28611],
+ "107": [0, 0.69444, 0, 0, 0.53056],
+ "108": [0, 0.69444, 0, 0, 0.25556],
+ "109": [0, 0.45833, 0, 0, 0.86667],
+ "110": [0, 0.45833, 0, 0, 0.56111],
+ "111": [0, 0.45833, 0, 0, 0.55],
+ "112": [0.19444, 0.45833, 0, 0, 0.56111],
+ "113": [0.19444, 0.45833, 0, 0, 0.56111],
+ "114": [0, 0.45833, 0.01528, 0, 0.37222],
+ "115": [0, 0.45833, 0, 0, 0.42167],
+ "116": [0, 0.58929, 0, 0, 0.40417],
+ "117": [0, 0.45833, 0, 0, 0.56111],
+ "118": [0, 0.45833, 0.01528, 0, 0.5],
+ "119": [0, 0.45833, 0.01528, 0, 0.74445],
+ "120": [0, 0.45833, 0, 0, 0.5],
+ "121": [0.19444, 0.45833, 0.01528, 0, 0.5],
+ "122": [0, 0.45833, 0, 0, 0.47639],
+ "126": [0.35, 0.34444, 0, 0, 0.55],
+ "160": [0, 0, 0, 0, 0.25],
+ "168": [0, 0.69444, 0, 0, 0.55],
+ "176": [0, 0.69444, 0, 0, 0.73334],
+ "180": [0, 0.69444, 0, 0, 0.55],
+ "184": [0.17014, 0, 0, 0, 0.48889],
+ "305": [0, 0.45833, 0, 0, 0.25556],
+ "567": [0.19444, 0.45833, 0, 0, 0.28611],
+ "710": [0, 0.69444, 0, 0, 0.55],
+ "711": [0, 0.63542, 0, 0, 0.55],
+ "713": [0, 0.63778, 0, 0, 0.55],
+ "728": [0, 0.69444, 0, 0, 0.55],
+ "729": [0, 0.69444, 0, 0, 0.30556],
+ "730": [0, 0.69444, 0, 0, 0.73334],
+ "732": [0, 0.69444, 0, 0, 0.55],
+ "733": [0, 0.69444, 0, 0, 0.55],
+ "915": [0, 0.69444, 0, 0, 0.58056],
+ "916": [0, 0.69444, 0, 0, 0.91667],
+ "920": [0, 0.69444, 0, 0, 0.85556],
+ "923": [0, 0.69444, 0, 0, 0.67223],
+ "926": [0, 0.69444, 0, 0, 0.73334],
+ "928": [0, 0.69444, 0, 0, 0.79445],
+ "931": [0, 0.69444, 0, 0, 0.79445],
+ "933": [0, 0.69444, 0, 0, 0.85556],
+ "934": [0, 0.69444, 0, 0, 0.79445],
+ "936": [0, 0.69444, 0, 0, 0.85556],
+ "937": [0, 0.69444, 0, 0, 0.79445],
+ "8211": [0, 0.45833, 0.03056, 0, 0.55],
+ "8212": [0, 0.45833, 0.03056, 0, 1.10001],
+ "8216": [0, 0.69444, 0, 0, 0.30556],
+ "8217": [0, 0.69444, 0, 0, 0.30556],
+ "8220": [0, 0.69444, 0, 0, 0.55834],
+ "8221": [0, 0.69444, 0, 0, 0.55834]
+ },
+ "SansSerif-Italic": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0.05733, 0, 0.31945],
+ "34": [0, 0.69444, 0.00316, 0, 0.5],
+ "35": [0.19444, 0.69444, 0.05087, 0, 0.83334],
+ "36": [0.05556, 0.75, 0.11156, 0, 0.5],
+ "37": [0.05556, 0.75, 0.03126, 0, 0.83334],
+ "38": [0, 0.69444, 0.03058, 0, 0.75834],
+ "39": [0, 0.69444, 0.07816, 0, 0.27778],
+ "40": [0.25, 0.75, 0.13164, 0, 0.38889],
+ "41": [0.25, 0.75, 0.02536, 0, 0.38889],
+ "42": [0, 0.75, 0.11775, 0, 0.5],
+ "43": [0.08333, 0.58333, 0.02536, 0, 0.77778],
+ "44": [0.125, 0.08333, 0, 0, 0.27778],
+ "45": [0, 0.44444, 0.01946, 0, 0.33333],
+ "46": [0, 0.08333, 0, 0, 0.27778],
+ "47": [0.25, 0.75, 0.13164, 0, 0.5],
+ "48": [0, 0.65556, 0.11156, 0, 0.5],
+ "49": [0, 0.65556, 0.11156, 0, 0.5],
+ "50": [0, 0.65556, 0.11156, 0, 0.5],
+ "51": [0, 0.65556, 0.11156, 0, 0.5],
+ "52": [0, 0.65556, 0.11156, 0, 0.5],
+ "53": [0, 0.65556, 0.11156, 0, 0.5],
+ "54": [0, 0.65556, 0.11156, 0, 0.5],
+ "55": [0, 0.65556, 0.11156, 0, 0.5],
+ "56": [0, 0.65556, 0.11156, 0, 0.5],
+ "57": [0, 0.65556, 0.11156, 0, 0.5],
+ "58": [0, 0.44444, 0.02502, 0, 0.27778],
+ "59": [0.125, 0.44444, 0.02502, 0, 0.27778],
+ "61": [-0.13, 0.37, 0.05087, 0, 0.77778],
+ "63": [0, 0.69444, 0.11809, 0, 0.47222],
+ "64": [0, 0.69444, 0.07555, 0, 0.66667],
+ "65": [0, 0.69444, 0, 0, 0.66667],
+ "66": [0, 0.69444, 0.08293, 0, 0.66667],
+ "67": [0, 0.69444, 0.11983, 0, 0.63889],
+ "68": [0, 0.69444, 0.07555, 0, 0.72223],
+ "69": [0, 0.69444, 0.11983, 0, 0.59722],
+ "70": [0, 0.69444, 0.13372, 0, 0.56945],
+ "71": [0, 0.69444, 0.11983, 0, 0.66667],
+ "72": [0, 0.69444, 0.08094, 0, 0.70834],
+ "73": [0, 0.69444, 0.13372, 0, 0.27778],
+ "74": [0, 0.69444, 0.08094, 0, 0.47222],
+ "75": [0, 0.69444, 0.11983, 0, 0.69445],
+ "76": [0, 0.69444, 0, 0, 0.54167],
+ "77": [0, 0.69444, 0.08094, 0, 0.875],
+ "78": [0, 0.69444, 0.08094, 0, 0.70834],
+ "79": [0, 0.69444, 0.07555, 0, 0.73611],
+ "80": [0, 0.69444, 0.08293, 0, 0.63889],
+ "81": [0.125, 0.69444, 0.07555, 0, 0.73611],
+ "82": [0, 0.69444, 0.08293, 0, 0.64584],
+ "83": [0, 0.69444, 0.09205, 0, 0.55556],
+ "84": [0, 0.69444, 0.13372, 0, 0.68056],
+ "85": [0, 0.69444, 0.08094, 0, 0.6875],
+ "86": [0, 0.69444, 0.1615, 0, 0.66667],
+ "87": [0, 0.69444, 0.1615, 0, 0.94445],
+ "88": [0, 0.69444, 0.13372, 0, 0.66667],
+ "89": [0, 0.69444, 0.17261, 0, 0.66667],
+ "90": [0, 0.69444, 0.11983, 0, 0.61111],
+ "91": [0.25, 0.75, 0.15942, 0, 0.28889],
+ "93": [0.25, 0.75, 0.08719, 0, 0.28889],
+ "94": [0, 0.69444, 0.0799, 0, 0.5],
+ "95": [0.35, 0.09444, 0.08616, 0, 0.5],
+ "97": [0, 0.44444, 0.00981, 0, 0.48056],
+ "98": [0, 0.69444, 0.03057, 0, 0.51667],
+ "99": [0, 0.44444, 0.08336, 0, 0.44445],
+ "100": [0, 0.69444, 0.09483, 0, 0.51667],
+ "101": [0, 0.44444, 0.06778, 0, 0.44445],
+ "102": [0, 0.69444, 0.21705, 0, 0.30556],
+ "103": [0.19444, 0.44444, 0.10836, 0, 0.5],
+ "104": [0, 0.69444, 0.01778, 0, 0.51667],
+ "105": [0, 0.67937, 0.09718, 0, 0.23889],
+ "106": [0.19444, 0.67937, 0.09162, 0, 0.26667],
+ "107": [0, 0.69444, 0.08336, 0, 0.48889],
+ "108": [0, 0.69444, 0.09483, 0, 0.23889],
+ "109": [0, 0.44444, 0.01778, 0, 0.79445],
+ "110": [0, 0.44444, 0.01778, 0, 0.51667],
+ "111": [0, 0.44444, 0.06613, 0, 0.5],
+ "112": [0.19444, 0.44444, 0.0389, 0, 0.51667],
+ "113": [0.19444, 0.44444, 0.04169, 0, 0.51667],
+ "114": [0, 0.44444, 0.10836, 0, 0.34167],
+ "115": [0, 0.44444, 0.0778, 0, 0.38333],
+ "116": [0, 0.57143, 0.07225, 0, 0.36111],
+ "117": [0, 0.44444, 0.04169, 0, 0.51667],
+ "118": [0, 0.44444, 0.10836, 0, 0.46111],
+ "119": [0, 0.44444, 0.10836, 0, 0.68334],
+ "120": [0, 0.44444, 0.09169, 0, 0.46111],
+ "121": [0.19444, 0.44444, 0.10836, 0, 0.46111],
+ "122": [0, 0.44444, 0.08752, 0, 0.43472],
+ "126": [0.35, 0.32659, 0.08826, 0, 0.5],
+ "160": [0, 0, 0, 0, 0.25],
+ "168": [0, 0.67937, 0.06385, 0, 0.5],
+ "176": [0, 0.69444, 0, 0, 0.73752],
+ "184": [0.17014, 0, 0, 0, 0.44445],
+ "305": [0, 0.44444, 0.04169, 0, 0.23889],
+ "567": [0.19444, 0.44444, 0.04169, 0, 0.26667],
+ "710": [0, 0.69444, 0.0799, 0, 0.5],
+ "711": [0, 0.63194, 0.08432, 0, 0.5],
+ "713": [0, 0.60889, 0.08776, 0, 0.5],
+ "714": [0, 0.69444, 0.09205, 0, 0.5],
+ "715": [0, 0.69444, 0, 0, 0.5],
+ "728": [0, 0.69444, 0.09483, 0, 0.5],
+ "729": [0, 0.67937, 0.07774, 0, 0.27778],
+ "730": [0, 0.69444, 0, 0, 0.73752],
+ "732": [0, 0.67659, 0.08826, 0, 0.5],
+ "733": [0, 0.69444, 0.09205, 0, 0.5],
+ "915": [0, 0.69444, 0.13372, 0, 0.54167],
+ "916": [0, 0.69444, 0, 0, 0.83334],
+ "920": [0, 0.69444, 0.07555, 0, 0.77778],
+ "923": [0, 0.69444, 0, 0, 0.61111],
+ "926": [0, 0.69444, 0.12816, 0, 0.66667],
+ "928": [0, 0.69444, 0.08094, 0, 0.70834],
+ "931": [0, 0.69444, 0.11983, 0, 0.72222],
+ "933": [0, 0.69444, 0.09031, 0, 0.77778],
+ "934": [0, 0.69444, 0.04603, 0, 0.72222],
+ "936": [0, 0.69444, 0.09031, 0, 0.77778],
+ "937": [0, 0.69444, 0.08293, 0, 0.72222],
+ "8211": [0, 0.44444, 0.08616, 0, 0.5],
+ "8212": [0, 0.44444, 0.08616, 0, 1.0],
+ "8216": [0, 0.69444, 0.07816, 0, 0.27778],
+ "8217": [0, 0.69444, 0.07816, 0, 0.27778],
+ "8220": [0, 0.69444, 0.14205, 0, 0.5],
+ "8221": [0, 0.69444, 0.00316, 0, 0.5]
+ },
+ "SansSerif-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "33": [0, 0.69444, 0, 0, 0.31945],
+ "34": [0, 0.69444, 0, 0, 0.5],
+ "35": [0.19444, 0.69444, 0, 0, 0.83334],
+ "36": [0.05556, 0.75, 0, 0, 0.5],
+ "37": [0.05556, 0.75, 0, 0, 0.83334],
+ "38": [0, 0.69444, 0, 0, 0.75834],
+ "39": [0, 0.69444, 0, 0, 0.27778],
+ "40": [0.25, 0.75, 0, 0, 0.38889],
+ "41": [0.25, 0.75, 0, 0, 0.38889],
+ "42": [0, 0.75, 0, 0, 0.5],
+ "43": [0.08333, 0.58333, 0, 0, 0.77778],
+ "44": [0.125, 0.08333, 0, 0, 0.27778],
+ "45": [0, 0.44444, 0, 0, 0.33333],
+ "46": [0, 0.08333, 0, 0, 0.27778],
+ "47": [0.25, 0.75, 0, 0, 0.5],
+ "48": [0, 0.65556, 0, 0, 0.5],
+ "49": [0, 0.65556, 0, 0, 0.5],
+ "50": [0, 0.65556, 0, 0, 0.5],
+ "51": [0, 0.65556, 0, 0, 0.5],
+ "52": [0, 0.65556, 0, 0, 0.5],
+ "53": [0, 0.65556, 0, 0, 0.5],
+ "54": [0, 0.65556, 0, 0, 0.5],
+ "55": [0, 0.65556, 0, 0, 0.5],
+ "56": [0, 0.65556, 0, 0, 0.5],
+ "57": [0, 0.65556, 0, 0, 0.5],
+ "58": [0, 0.44444, 0, 0, 0.27778],
+ "59": [0.125, 0.44444, 0, 0, 0.27778],
+ "61": [-0.13, 0.37, 0, 0, 0.77778],
+ "63": [0, 0.69444, 0, 0, 0.47222],
+ "64": [0, 0.69444, 0, 0, 0.66667],
+ "65": [0, 0.69444, 0, 0, 0.66667],
+ "66": [0, 0.69444, 0, 0, 0.66667],
+ "67": [0, 0.69444, 0, 0, 0.63889],
+ "68": [0, 0.69444, 0, 0, 0.72223],
+ "69": [0, 0.69444, 0, 0, 0.59722],
+ "70": [0, 0.69444, 0, 0, 0.56945],
+ "71": [0, 0.69444, 0, 0, 0.66667],
+ "72": [0, 0.69444, 0, 0, 0.70834],
+ "73": [0, 0.69444, 0, 0, 0.27778],
+ "74": [0, 0.69444, 0, 0, 0.47222],
+ "75": [0, 0.69444, 0, 0, 0.69445],
+ "76": [0, 0.69444, 0, 0, 0.54167],
+ "77": [0, 0.69444, 0, 0, 0.875],
+ "78": [0, 0.69444, 0, 0, 0.70834],
+ "79": [0, 0.69444, 0, 0, 0.73611],
+ "80": [0, 0.69444, 0, 0, 0.63889],
+ "81": [0.125, 0.69444, 0, 0, 0.73611],
+ "82": [0, 0.69444, 0, 0, 0.64584],
+ "83": [0, 0.69444, 0, 0, 0.55556],
+ "84": [0, 0.69444, 0, 0, 0.68056],
+ "85": [0, 0.69444, 0, 0, 0.6875],
+ "86": [0, 0.69444, 0.01389, 0, 0.66667],
+ "87": [0, 0.69444, 0.01389, 0, 0.94445],
+ "88": [0, 0.69444, 0, 0, 0.66667],
+ "89": [0, 0.69444, 0.025, 0, 0.66667],
+ "90": [0, 0.69444, 0, 0, 0.61111],
+ "91": [0.25, 0.75, 0, 0, 0.28889],
+ "93": [0.25, 0.75, 0, 0, 0.28889],
+ "94": [0, 0.69444, 0, 0, 0.5],
+ "95": [0.35, 0.09444, 0.02778, 0, 0.5],
+ "97": [0, 0.44444, 0, 0, 0.48056],
+ "98": [0, 0.69444, 0, 0, 0.51667],
+ "99": [0, 0.44444, 0, 0, 0.44445],
+ "100": [0, 0.69444, 0, 0, 0.51667],
+ "101": [0, 0.44444, 0, 0, 0.44445],
+ "102": [0, 0.69444, 0.06944, 0, 0.30556],
+ "103": [0.19444, 0.44444, 0.01389, 0, 0.5],
+ "104": [0, 0.69444, 0, 0, 0.51667],
+ "105": [0, 0.67937, 0, 0, 0.23889],
+ "106": [0.19444, 0.67937, 0, 0, 0.26667],
+ "107": [0, 0.69444, 0, 0, 0.48889],
+ "108": [0, 0.69444, 0, 0, 0.23889],
+ "109": [0, 0.44444, 0, 0, 0.79445],
+ "110": [0, 0.44444, 0, 0, 0.51667],
+ "111": [0, 0.44444, 0, 0, 0.5],
+ "112": [0.19444, 0.44444, 0, 0, 0.51667],
+ "113": [0.19444, 0.44444, 0, 0, 0.51667],
+ "114": [0, 0.44444, 0.01389, 0, 0.34167],
+ "115": [0, 0.44444, 0, 0, 0.38333],
+ "116": [0, 0.57143, 0, 0, 0.36111],
+ "117": [0, 0.44444, 0, 0, 0.51667],
+ "118": [0, 0.44444, 0.01389, 0, 0.46111],
+ "119": [0, 0.44444, 0.01389, 0, 0.68334],
+ "120": [0, 0.44444, 0, 0, 0.46111],
+ "121": [0.19444, 0.44444, 0.01389, 0, 0.46111],
+ "122": [0, 0.44444, 0, 0, 0.43472],
+ "126": [0.35, 0.32659, 0, 0, 0.5],
+ "160": [0, 0, 0, 0, 0.25],
+ "168": [0, 0.67937, 0, 0, 0.5],
+ "176": [0, 0.69444, 0, 0, 0.66667],
+ "184": [0.17014, 0, 0, 0, 0.44445],
+ "305": [0, 0.44444, 0, 0, 0.23889],
+ "567": [0.19444, 0.44444, 0, 0, 0.26667],
+ "710": [0, 0.69444, 0, 0, 0.5],
+ "711": [0, 0.63194, 0, 0, 0.5],
+ "713": [0, 0.60889, 0, 0, 0.5],
+ "714": [0, 0.69444, 0, 0, 0.5],
+ "715": [0, 0.69444, 0, 0, 0.5],
+ "728": [0, 0.69444, 0, 0, 0.5],
+ "729": [0, 0.67937, 0, 0, 0.27778],
+ "730": [0, 0.69444, 0, 0, 0.66667],
+ "732": [0, 0.67659, 0, 0, 0.5],
+ "733": [0, 0.69444, 0, 0, 0.5],
+ "915": [0, 0.69444, 0, 0, 0.54167],
+ "916": [0, 0.69444, 0, 0, 0.83334],
+ "920": [0, 0.69444, 0, 0, 0.77778],
+ "923": [0, 0.69444, 0, 0, 0.61111],
+ "926": [0, 0.69444, 0, 0, 0.66667],
+ "928": [0, 0.69444, 0, 0, 0.70834],
+ "931": [0, 0.69444, 0, 0, 0.72222],
+ "933": [0, 0.69444, 0, 0, 0.77778],
+ "934": [0, 0.69444, 0, 0, 0.72222],
+ "936": [0, 0.69444, 0, 0, 0.77778],
+ "937": [0, 0.69444, 0, 0, 0.72222],
+ "8211": [0, 0.44444, 0.02778, 0, 0.5],
+ "8212": [0, 0.44444, 0.02778, 0, 1.0],
+ "8216": [0, 0.69444, 0, 0, 0.27778],
+ "8217": [0, 0.69444, 0, 0, 0.27778],
+ "8220": [0, 0.69444, 0, 0, 0.5],
+ "8221": [0, 0.69444, 0, 0, 0.5]
+ },
+ "Script-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "65": [0, 0.7, 0.22925, 0, 0.80253],
+ "66": [0, 0.7, 0.04087, 0, 0.90757],
+ "67": [0, 0.7, 0.1689, 0, 0.66619],
+ "68": [0, 0.7, 0.09371, 0, 0.77443],
+ "69": [0, 0.7, 0.18583, 0, 0.56162],
+ "70": [0, 0.7, 0.13634, 0, 0.89544],
+ "71": [0, 0.7, 0.17322, 0, 0.60961],
+ "72": [0, 0.7, 0.29694, 0, 0.96919],
+ "73": [0, 0.7, 0.19189, 0, 0.80907],
+ "74": [0.27778, 0.7, 0.19189, 0, 1.05159],
+ "75": [0, 0.7, 0.31259, 0, 0.91364],
+ "76": [0, 0.7, 0.19189, 0, 0.87373],
+ "77": [0, 0.7, 0.15981, 0, 1.08031],
+ "78": [0, 0.7, 0.3525, 0, 0.9015],
+ "79": [0, 0.7, 0.08078, 0, 0.73787],
+ "80": [0, 0.7, 0.08078, 0, 1.01262],
+ "81": [0, 0.7, 0.03305, 0, 0.88282],
+ "82": [0, 0.7, 0.06259, 0, 0.85],
+ "83": [0, 0.7, 0.19189, 0, 0.86767],
+ "84": [0, 0.7, 0.29087, 0, 0.74697],
+ "85": [0, 0.7, 0.25815, 0, 0.79996],
+ "86": [0, 0.7, 0.27523, 0, 0.62204],
+ "87": [0, 0.7, 0.27523, 0, 0.80532],
+ "88": [0, 0.7, 0.26006, 0, 0.94445],
+ "89": [0, 0.7, 0.2939, 0, 0.70961],
+ "90": [0, 0.7, 0.24037, 0, 0.8212],
+ "160": [0, 0, 0, 0, 0.25]
+ },
+ "Size1-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "40": [0.35001, 0.85, 0, 0, 0.45834],
+ "41": [0.35001, 0.85, 0, 0, 0.45834],
+ "47": [0.35001, 0.85, 0, 0, 0.57778],
+ "91": [0.35001, 0.85, 0, 0, 0.41667],
+ "92": [0.35001, 0.85, 0, 0, 0.57778],
+ "93": [0.35001, 0.85, 0, 0, 0.41667],
+ "123": [0.35001, 0.85, 0, 0, 0.58334],
+ "125": [0.35001, 0.85, 0, 0, 0.58334],
+ "160": [0, 0, 0, 0, 0.25],
+ "710": [0, 0.72222, 0, 0, 0.55556],
+ "732": [0, 0.72222, 0, 0, 0.55556],
+ "770": [0, 0.72222, 0, 0, 0.55556],
+ "771": [0, 0.72222, 0, 0, 0.55556],
+ "8214": [-0.00099, 0.601, 0, 0, 0.77778],
+ "8593": [1e-05, 0.6, 0, 0, 0.66667],
+ "8595": [1e-05, 0.6, 0, 0, 0.66667],
+ "8657": [1e-05, 0.6, 0, 0, 0.77778],
+ "8659": [1e-05, 0.6, 0, 0, 0.77778],
+ "8719": [0.25001, 0.75, 0, 0, 0.94445],
+ "8720": [0.25001, 0.75, 0, 0, 0.94445],
+ "8721": [0.25001, 0.75, 0, 0, 1.05556],
+ "8730": [0.35001, 0.85, 0, 0, 1.0],
+ "8739": [-0.00599, 0.606, 0, 0, 0.33333],
+ "8741": [-0.00599, 0.606, 0, 0, 0.55556],
+ "8747": [0.30612, 0.805, 0.19445, 0, 0.47222],
+ "8748": [0.306, 0.805, 0.19445, 0, 0.47222],
+ "8749": [0.306, 0.805, 0.19445, 0, 0.47222],
+ "8750": [0.30612, 0.805, 0.19445, 0, 0.47222],
+ "8896": [0.25001, 0.75, 0, 0, 0.83334],
+ "8897": [0.25001, 0.75, 0, 0, 0.83334],
+ "8898": [0.25001, 0.75, 0, 0, 0.83334],
+ "8899": [0.25001, 0.75, 0, 0, 0.83334],
+ "8968": [0.35001, 0.85, 0, 0, 0.47222],
+ "8969": [0.35001, 0.85, 0, 0, 0.47222],
+ "8970": [0.35001, 0.85, 0, 0, 0.47222],
+ "8971": [0.35001, 0.85, 0, 0, 0.47222],
+ "9168": [-0.00099, 0.601, 0, 0, 0.66667],
+ "10216": [0.35001, 0.85, 0, 0, 0.47222],
+ "10217": [0.35001, 0.85, 0, 0, 0.47222],
+ "10752": [0.25001, 0.75, 0, 0, 1.11111],
+ "10753": [0.25001, 0.75, 0, 0, 1.11111],
+ "10754": [0.25001, 0.75, 0, 0, 1.11111],
+ "10756": [0.25001, 0.75, 0, 0, 0.83334],
+ "10758": [0.25001, 0.75, 0, 0, 0.83334]
+ },
+ "Size2-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "40": [0.65002, 1.15, 0, 0, 0.59722],
+ "41": [0.65002, 1.15, 0, 0, 0.59722],
+ "47": [0.65002, 1.15, 0, 0, 0.81111],
+ "91": [0.65002, 1.15, 0, 0, 0.47222],
+ "92": [0.65002, 1.15, 0, 0, 0.81111],
+ "93": [0.65002, 1.15, 0, 0, 0.47222],
+ "123": [0.65002, 1.15, 0, 0, 0.66667],
+ "125": [0.65002, 1.15, 0, 0, 0.66667],
+ "160": [0, 0, 0, 0, 0.25],
+ "710": [0, 0.75, 0, 0, 1.0],
+ "732": [0, 0.75, 0, 0, 1.0],
+ "770": [0, 0.75, 0, 0, 1.0],
+ "771": [0, 0.75, 0, 0, 1.0],
+ "8719": [0.55001, 1.05, 0, 0, 1.27778],
+ "8720": [0.55001, 1.05, 0, 0, 1.27778],
+ "8721": [0.55001, 1.05, 0, 0, 1.44445],
+ "8730": [0.65002, 1.15, 0, 0, 1.0],
+ "8747": [0.86225, 1.36, 0.44445, 0, 0.55556],
+ "8748": [0.862, 1.36, 0.44445, 0, 0.55556],
+ "8749": [0.862, 1.36, 0.44445, 0, 0.55556],
+ "8750": [0.86225, 1.36, 0.44445, 0, 0.55556],
+ "8896": [0.55001, 1.05, 0, 0, 1.11111],
+ "8897": [0.55001, 1.05, 0, 0, 1.11111],
+ "8898": [0.55001, 1.05, 0, 0, 1.11111],
+ "8899": [0.55001, 1.05, 0, 0, 1.11111],
+ "8968": [0.65002, 1.15, 0, 0, 0.52778],
+ "8969": [0.65002, 1.15, 0, 0, 0.52778],
+ "8970": [0.65002, 1.15, 0, 0, 0.52778],
+ "8971": [0.65002, 1.15, 0, 0, 0.52778],
+ "10216": [0.65002, 1.15, 0, 0, 0.61111],
+ "10217": [0.65002, 1.15, 0, 0, 0.61111],
+ "10752": [0.55001, 1.05, 0, 0, 1.51112],
+ "10753": [0.55001, 1.05, 0, 0, 1.51112],
+ "10754": [0.55001, 1.05, 0, 0, 1.51112],
+ "10756": [0.55001, 1.05, 0, 0, 1.11111],
+ "10758": [0.55001, 1.05, 0, 0, 1.11111]
+ },
+ "Size3-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "40": [0.95003, 1.45, 0, 0, 0.73611],
+ "41": [0.95003, 1.45, 0, 0, 0.73611],
+ "47": [0.95003, 1.45, 0, 0, 1.04445],
+ "91": [0.95003, 1.45, 0, 0, 0.52778],
+ "92": [0.95003, 1.45, 0, 0, 1.04445],
+ "93": [0.95003, 1.45, 0, 0, 0.52778],
+ "123": [0.95003, 1.45, 0, 0, 0.75],
+ "125": [0.95003, 1.45, 0, 0, 0.75],
+ "160": [0, 0, 0, 0, 0.25],
+ "710": [0, 0.75, 0, 0, 1.44445],
+ "732": [0, 0.75, 0, 0, 1.44445],
+ "770": [0, 0.75, 0, 0, 1.44445],
+ "771": [0, 0.75, 0, 0, 1.44445],
+ "8730": [0.95003, 1.45, 0, 0, 1.0],
+ "8968": [0.95003, 1.45, 0, 0, 0.58334],
+ "8969": [0.95003, 1.45, 0, 0, 0.58334],
+ "8970": [0.95003, 1.45, 0, 0, 0.58334],
+ "8971": [0.95003, 1.45, 0, 0, 0.58334],
+ "10216": [0.95003, 1.45, 0, 0, 0.75],
+ "10217": [0.95003, 1.45, 0, 0, 0.75]
+ },
+ "Size4-Regular": {
+ "32": [0, 0, 0, 0, 0.25],
+ "40": [1.25003, 1.75, 0, 0, 0.79167],
+ "41": [1.25003, 1.75, 0, 0, 0.79167],
+ "47": [1.25003, 1.75, 0, 0, 1.27778],
+ "91": [1.25003, 1.75, 0, 0, 0.58334],
+ "92": [1.25003, 1.75, 0, 0, 1.27778],
+ "93": [1.25003, 1.75, 0, 0, 0.58334],
+ "123": [1.25003, 1.75, 0, 0, 0.80556],
+ "125": [1.25003, 1.75, 0, 0, 0.80556],
+ "160": [0, 0, 0, 0, 0.25],
+ "710": [0, 0.825, 0, 0, 1.8889],
+ "732": [0, 0.825, 0, 0, 1.8889],
+ "770": [0, 0.825, 0, 0, 1.8889],
+ "771": [0, 0.825, 0, 0, 1.8889],
+ "8730": [1.25003, 1.75, 0, 0, 1.0],
+ "8968": [1.25003, 1.75, 0, 0, 0.63889],
+ "8969": [1.25003, 1.75, 0, 0, 0.63889],
+ "8970": [1.25003, 1.75, 0, 0, 0.63889],
+ "8971": [1.25003, 1.75, 0, 0, 0.63889],
+ "9115": [0.64502, 1.155, 0, 0, 0.875],
+ "9116": [1e-05, 0.6, 0, 0, 0.875],
+ "9117": [0.64502, 1.155, 0, 0, 0.875],
+ "9118": [0.64502, 1.155, 0, 0, 0.875],
+ "9119": [1e-05, 0.6, 0, 0, 0.875],
+ "9120": [0.64502, 1.155, 0, 0, 0.875],
+ "9121": [0.64502, 1.155, 0, 0, 0.66667],
+ "9122": [-0.00099, 0.601, 0, 0, 0.66667],
+ "9123": [0.64502, 1.155, 0, 0, 0.66667],
+ "9124": [0.64502, 1.155, 0, 0, 0.66667],
+ "9125": [-0.00099, 0.601, 0, 0, 0.66667],
+ "9126": [0.64502, 1.155, 0, 0, 0.66667],
+ "9127": [1e-05, 0.9, 0, 0, 0.88889],
+ "9128": [0.65002, 1.15, 0, 0, 0.88889],
+ "9129": [0.90001, 0, 0, 0, 0.88889],
+ "9130": [0, 0.3, 0, 0, 0.88889],
+ "9131": [1e-05, 0.9, 0, 0, 0.88889],
+ "9132": [0.65002, 1.15, 0, 0, 0.88889],
+ "9133": [0.90001, 0, 0, 0, 0.88889],
+ "9143": [0.88502, 0.915, 0, 0, 1.05556],
+ "10216": [1.25003, 1.75, 0, 0, 0.80556],
+ "10217": [1.25003, 1.75, 0, 0, 0.80556],
+ "57344": [-0.00499, 0.605, 0, 0, 1.05556],
+ "57345": [-0.00499, 0.605, 0, 0, 1.05556],
+ "57680": [0, 0.12, 0, 0, 0.45],
+ "57681": [0, 0.12, 0, 0, 0.45],
+ "57682": [0, 0.12, 0, 0, 0.45],
+ "57683": [0, 0.12, 0, 0, 0.45]
+ },
+ "Typewriter-Regular": {
+ "32": [0, 0, 0, 0, 0.525],
+ "33": [0, 0.61111, 0, 0, 0.525],
+ "34": [0, 0.61111, 0, 0, 0.525],
+ "35": [0, 0.61111, 0, 0, 0.525],
+ "36": [0.08333, 0.69444, 0, 0, 0.525],
+ "37": [0.08333, 0.69444, 0, 0, 0.525],
+ "38": [0, 0.61111, 0, 0, 0.525],
+ "39": [0, 0.61111, 0, 0, 0.525],
+ "40": [0.08333, 0.69444, 0, 0, 0.525],
+ "41": [0.08333, 0.69444, 0, 0, 0.525],
+ "42": [0, 0.52083, 0, 0, 0.525],
+ "43": [-0.08056, 0.53055, 0, 0, 0.525],
+ "44": [0.13889, 0.125, 0, 0, 0.525],
+ "45": [-0.08056, 0.53055, 0, 0, 0.525],
+ "46": [0, 0.125, 0, 0, 0.525],
+ "47": [0.08333, 0.69444, 0, 0, 0.525],
+ "48": [0, 0.61111, 0, 0, 0.525],
+ "49": [0, 0.61111, 0, 0, 0.525],
+ "50": [0, 0.61111, 0, 0, 0.525],
+ "51": [0, 0.61111, 0, 0, 0.525],
+ "52": [0, 0.61111, 0, 0, 0.525],
+ "53": [0, 0.61111, 0, 0, 0.525],
+ "54": [0, 0.61111, 0, 0, 0.525],
+ "55": [0, 0.61111, 0, 0, 0.525],
+ "56": [0, 0.61111, 0, 0, 0.525],
+ "57": [0, 0.61111, 0, 0, 0.525],
+ "58": [0, 0.43056, 0, 0, 0.525],
+ "59": [0.13889, 0.43056, 0, 0, 0.525],
+ "60": [-0.05556, 0.55556, 0, 0, 0.525],
+ "61": [-0.19549, 0.41562, 0, 0, 0.525],
+ "62": [-0.05556, 0.55556, 0, 0, 0.525],
+ "63": [0, 0.61111, 0, 0, 0.525],
+ "64": [0, 0.61111, 0, 0, 0.525],
+ "65": [0, 0.61111, 0, 0, 0.525],
+ "66": [0, 0.61111, 0, 0, 0.525],
+ "67": [0, 0.61111, 0, 0, 0.525],
+ "68": [0, 0.61111, 0, 0, 0.525],
+ "69": [0, 0.61111, 0, 0, 0.525],
+ "70": [0, 0.61111, 0, 0, 0.525],
+ "71": [0, 0.61111, 0, 0, 0.525],
+ "72": [0, 0.61111, 0, 0, 0.525],
+ "73": [0, 0.61111, 0, 0, 0.525],
+ "74": [0, 0.61111, 0, 0, 0.525],
+ "75": [0, 0.61111, 0, 0, 0.525],
+ "76": [0, 0.61111, 0, 0, 0.525],
+ "77": [0, 0.61111, 0, 0, 0.525],
+ "78": [0, 0.61111, 0, 0, 0.525],
+ "79": [0, 0.61111, 0, 0, 0.525],
+ "80": [0, 0.61111, 0, 0, 0.525],
+ "81": [0.13889, 0.61111, 0, 0, 0.525],
+ "82": [0, 0.61111, 0, 0, 0.525],
+ "83": [0, 0.61111, 0, 0, 0.525],
+ "84": [0, 0.61111, 0, 0, 0.525],
+ "85": [0, 0.61111, 0, 0, 0.525],
+ "86": [0, 0.61111, 0, 0, 0.525],
+ "87": [0, 0.61111, 0, 0, 0.525],
+ "88": [0, 0.61111, 0, 0, 0.525],
+ "89": [0, 0.61111, 0, 0, 0.525],
+ "90": [0, 0.61111, 0, 0, 0.525],
+ "91": [0.08333, 0.69444, 0, 0, 0.525],
+ "92": [0.08333, 0.69444, 0, 0, 0.525],
+ "93": [0.08333, 0.69444, 0, 0, 0.525],
+ "94": [0, 0.61111, 0, 0, 0.525],
+ "95": [0.09514, 0, 0, 0, 0.525],
+ "96": [0, 0.61111, 0, 0, 0.525],
+ "97": [0, 0.43056, 0, 0, 0.525],
+ "98": [0, 0.61111, 0, 0, 0.525],
+ "99": [0, 0.43056, 0, 0, 0.525],
+ "100": [0, 0.61111, 0, 0, 0.525],
+ "101": [0, 0.43056, 0, 0, 0.525],
+ "102": [0, 0.61111, 0, 0, 0.525],
+ "103": [0.22222, 0.43056, 0, 0, 0.525],
+ "104": [0, 0.61111, 0, 0, 0.525],
+ "105": [0, 0.61111, 0, 0, 0.525],
+ "106": [0.22222, 0.61111, 0, 0, 0.525],
+ "107": [0, 0.61111, 0, 0, 0.525],
+ "108": [0, 0.61111, 0, 0, 0.525],
+ "109": [0, 0.43056, 0, 0, 0.525],
+ "110": [0, 0.43056, 0, 0, 0.525],
+ "111": [0, 0.43056, 0, 0, 0.525],
+ "112": [0.22222, 0.43056, 0, 0, 0.525],
+ "113": [0.22222, 0.43056, 0, 0, 0.525],
+ "114": [0, 0.43056, 0, 0, 0.525],
+ "115": [0, 0.43056, 0, 0, 0.525],
+ "116": [0, 0.55358, 0, 0, 0.525],
+ "117": [0, 0.43056, 0, 0, 0.525],
+ "118": [0, 0.43056, 0, 0, 0.525],
+ "119": [0, 0.43056, 0, 0, 0.525],
+ "120": [0, 0.43056, 0, 0, 0.525],
+ "121": [0.22222, 0.43056, 0, 0, 0.525],
+ "122": [0, 0.43056, 0, 0, 0.525],
+ "123": [0.08333, 0.69444, 0, 0, 0.525],
+ "124": [0.08333, 0.69444, 0, 0, 0.525],
+ "125": [0.08333, 0.69444, 0, 0, 0.525],
+ "126": [0, 0.61111, 0, 0, 0.525],
+ "127": [0, 0.61111, 0, 0, 0.525],
+ "160": [0, 0, 0, 0, 0.525],
+ "176": [0, 0.61111, 0, 0, 0.525],
+ "184": [0.19445, 0, 0, 0, 0.525],
+ "305": [0, 0.43056, 0, 0, 0.525],
+ "567": [0.22222, 0.43056, 0, 0, 0.525],
+ "711": [0, 0.56597, 0, 0, 0.525],
+ "713": [0, 0.56555, 0, 0, 0.525],
+ "714": [0, 0.61111, 0, 0, 0.525],
+ "715": [0, 0.61111, 0, 0, 0.525],
+ "728": [0, 0.61111, 0, 0, 0.525],
+ "730": [0, 0.61111, 0, 0, 0.525],
+ "770": [0, 0.61111, 0, 0, 0.525],
+ "771": [0, 0.61111, 0, 0, 0.525],
+ "776": [0, 0.61111, 0, 0, 0.525],
+ "915": [0, 0.61111, 0, 0, 0.525],
+ "916": [0, 0.61111, 0, 0, 0.525],
+ "920": [0, 0.61111, 0, 0, 0.525],
+ "923": [0, 0.61111, 0, 0, 0.525],
+ "926": [0, 0.61111, 0, 0, 0.525],
+ "928": [0, 0.61111, 0, 0, 0.525],
+ "931": [0, 0.61111, 0, 0, 0.525],
+ "933": [0, 0.61111, 0, 0, 0.525],
+ "934": [0, 0.61111, 0, 0, 0.525],
+ "936": [0, 0.61111, 0, 0, 0.525],
+ "937": [0, 0.61111, 0, 0, 0.525],
+ "8216": [0, 0.61111, 0, 0, 0.525],
+ "8217": [0, 0.61111, 0, 0, 0.525],
+ "8242": [0, 0.61111, 0, 0, 0.525],
+ "9251": [0.11111, 0.21944, 0, 0, 0.525]
+ }
+});
+;// CONCATENATED MODULE: ./src/fontMetrics.js
+
+
+/**
+ * This file contains metrics regarding fonts and individual symbols. The sigma
+ * and xi variables, as well as the metricMap map contain data extracted from
+ * TeX, TeX font metrics, and the TTF files. These data are then exposed via the
+ * `metrics` variable and the getCharacterMetrics function.
+ */
+// In TeX, there are actually three sets of dimensions, one for each of
+// textstyle (size index 5 and higher: >=9pt), scriptstyle (size index 3 and 4:
+// 7-8pt), and scriptscriptstyle (size index 1 and 2: 5-6pt). These are
+// provided in the the arrays below, in that order.
+//
+// The font metrics are stored in fonts cmsy10, cmsy7, and cmsy5 respsectively.
+// This was determined by running the following script:
+//
+// latex -interaction=nonstopmode \
+// '\documentclass{article}\usepackage{amsmath}\begin{document}' \
+// '$a$ \expandafter\show\the\textfont2' \
+// '\expandafter\show\the\scriptfont2' \
+// '\expandafter\show\the\scriptscriptfont2' \
+// '\stop'
+//
+// The metrics themselves were retreived using the following commands:
+//
+// tftopl cmsy10
+// tftopl cmsy7
+// tftopl cmsy5
+//
+// The output of each of these commands is quite lengthy. The only part we
+// care about is the FONTDIMEN section. Each value is measured in EMs.
+var sigmasAndXis = {
+ slant: [0.250, 0.250, 0.250],
+ // sigma1
+ space: [0.000, 0.000, 0.000],
+ // sigma2
+ stretch: [0.000, 0.000, 0.000],
+ // sigma3
+ shrink: [0.000, 0.000, 0.000],
+ // sigma4
+ xHeight: [0.431, 0.431, 0.431],
+ // sigma5
+ quad: [1.000, 1.171, 1.472],
+ // sigma6
+ extraSpace: [0.000, 0.000, 0.000],
+ // sigma7
+ num1: [0.677, 0.732, 0.925],
+ // sigma8
+ num2: [0.394, 0.384, 0.387],
+ // sigma9
+ num3: [0.444, 0.471, 0.504],
+ // sigma10
+ denom1: [0.686, 0.752, 1.025],
+ // sigma11
+ denom2: [0.345, 0.344, 0.532],
+ // sigma12
+ sup1: [0.413, 0.503, 0.504],
+ // sigma13
+ sup2: [0.363, 0.431, 0.404],
+ // sigma14
+ sup3: [0.289, 0.286, 0.294],
+ // sigma15
+ sub1: [0.150, 0.143, 0.200],
+ // sigma16
+ sub2: [0.247, 0.286, 0.400],
+ // sigma17
+ supDrop: [0.386, 0.353, 0.494],
+ // sigma18
+ subDrop: [0.050, 0.071, 0.100],
+ // sigma19
+ delim1: [2.390, 1.700, 1.980],
+ // sigma20
+ delim2: [1.010, 1.157, 1.420],
+ // sigma21
+ axisHeight: [0.250, 0.250, 0.250],
+ // sigma22
+ // These font metrics are extracted from TeX by using tftopl on cmex10.tfm;
+ // they correspond to the font parameters of the extension fonts (family 3).
+ // See the TeXbook, page 441. In AMSTeX, the extension fonts scale; to
+ // match cmex7, we'd use cmex7.tfm values for script and scriptscript
+ // values.
+ defaultRuleThickness: [0.04, 0.049, 0.049],
+ // xi8; cmex7: 0.049
+ bigOpSpacing1: [0.111, 0.111, 0.111],
+ // xi9
+ bigOpSpacing2: [0.166, 0.166, 0.166],
+ // xi10
+ bigOpSpacing3: [0.2, 0.2, 0.2],
+ // xi11
+ bigOpSpacing4: [0.6, 0.611, 0.611],
+ // xi12; cmex7: 0.611
+ bigOpSpacing5: [0.1, 0.143, 0.143],
+ // xi13; cmex7: 0.143
+ // The \sqrt rule width is taken from the height of the surd character.
+ // Since we use the same font at all sizes, this thickness doesn't scale.
+ sqrtRuleThickness: [0.04, 0.04, 0.04],
+ // This value determines how large a pt is, for metrics which are defined
+ // in terms of pts.
+ // This value is also used in katex.less; if you change it make sure the
+ // values match.
+ ptPerEm: [10.0, 10.0, 10.0],
+ // The space between adjacent `|` columns in an array definition. From
+ // `\showthe\doublerulesep` in LaTeX. Equals 2.0 / ptPerEm.
+ doubleRuleSep: [0.2, 0.2, 0.2],
+ // The width of separator lines in {array} environments. From
+ // `\showthe\arrayrulewidth` in LaTeX. Equals 0.4 / ptPerEm.
+ arrayRuleWidth: [0.04, 0.04, 0.04],
+ // Two values from LaTeX source2e:
+ fboxsep: [0.3, 0.3, 0.3],
+ // 3 pt / ptPerEm
+ fboxrule: [0.04, 0.04, 0.04] // 0.4 pt / ptPerEm
+
+}; // This map contains a mapping from font name and character code to character
+// metrics, including height, depth, italic correction, and skew (kern from the
+// character to the corresponding \skewchar)
+// This map is generated via `make metrics`. It should not be changed manually.
+
+ // These are very rough approximations. We default to Times New Roman which
+// should have Latin-1 and Cyrillic characters, but may not depending on the
+// operating system. The metrics do not account for extra height from the
+// accents. In the case of Cyrillic characters which have both ascenders and
+// descenders we prefer approximations with ascenders, primarily to prevent
+// the fraction bar or root line from intersecting the glyph.
+// TODO(kevinb) allow union of multiple glyph metrics for better accuracy.
+
+var extraCharacterMap = {
+ // Latin-1
+ 'Å': 'A',
+ 'Ð': 'D',
+ 'Þ': 'o',
+ 'å': 'a',
+ 'ð': 'd',
+ 'þ': 'o',
+ // Cyrillic
+ 'А': 'A',
+ 'Б': 'B',
+ 'В': 'B',
+ 'Г': 'F',
+ 'Д': 'A',
+ 'Е': 'E',
+ 'Ж': 'K',
+ 'З': '3',
+ 'И': 'N',
+ 'Й': 'N',
+ 'К': 'K',
+ 'Л': 'N',
+ 'М': 'M',
+ 'Н': 'H',
+ 'О': 'O',
+ 'П': 'N',
+ 'Р': 'P',
+ 'С': 'C',
+ 'Т': 'T',
+ 'У': 'y',
+ 'Ф': 'O',
+ 'Х': 'X',
+ 'Ц': 'U',
+ 'Ч': 'h',
+ 'Ш': 'W',
+ 'Щ': 'W',
+ 'Ъ': 'B',
+ 'Ы': 'X',
+ 'Ь': 'B',
+ 'Э': '3',
+ 'Ю': 'X',
+ 'Я': 'R',
+ 'а': 'a',
+ 'б': 'b',
+ 'в': 'a',
+ 'г': 'r',
+ 'д': 'y',
+ 'е': 'e',
+ 'ж': 'm',
+ 'з': 'e',
+ 'и': 'n',
+ 'й': 'n',
+ 'к': 'n',
+ 'л': 'n',
+ 'м': 'm',
+ 'н': 'n',
+ 'о': 'o',
+ 'п': 'n',
+ 'р': 'p',
+ 'с': 'c',
+ 'т': 'o',
+ 'у': 'y',
+ 'ф': 'b',
+ 'х': 'x',
+ 'ц': 'n',
+ 'ч': 'n',
+ 'ш': 'w',
+ 'щ': 'w',
+ 'ъ': 'a',
+ 'ы': 'm',
+ 'ь': 'a',
+ 'э': 'e',
+ 'ю': 'm',
+ 'я': 'r'
+};
+
+/**
+ * This function adds new font metrics to default metricMap
+ * It can also override existing metrics
+ */
+function setFontMetrics(fontName, metrics) {
+ fontMetricsData[fontName] = metrics;
+}
+/**
+ * This function is a convenience function for looking up information in the
+ * metricMap table. It takes a character as a string, and a font.
+ *
+ * Note: the `width` property may be undefined if fontMetricsData.js wasn't
+ * built using `Make extended_metrics`.
+ */
+
+function getCharacterMetrics(character, font, mode) {
+ if (!fontMetricsData[font]) {
+ throw new Error("Font metrics not found for font: " + font + ".");
+ }
+
+ var ch = character.charCodeAt(0);
+ var metrics = fontMetricsData[font][ch];
+
+ if (!metrics && character[0] in extraCharacterMap) {
+ ch = extraCharacterMap[character[0]].charCodeAt(0);
+ metrics = fontMetricsData[font][ch];
+ }
+
+ if (!metrics && mode === 'text') {
+ // We don't typically have font metrics for Asian scripts.
+ // But since we support them in text mode, we need to return
+ // some sort of metrics.
+ // So if the character is in a script we support but we
+ // don't have metrics for it, just use the metrics for
+ // the Latin capital letter M. This is close enough because
+ // we (currently) only care about the height of the glpyh
+ // not its width.
+ if (supportedCodepoint(ch)) {
+ metrics = fontMetricsData[font][77]; // 77 is the charcode for 'M'
+ }
+ }
+
+ if (metrics) {
+ return {
+ depth: metrics[0],
+ height: metrics[1],
+ italic: metrics[2],
+ skew: metrics[3],
+ width: metrics[4]
+ };
+ }
+}
+var fontMetricsBySizeIndex = {};
+/**
+ * Get the font metrics for a given size.
+ */
+
+function getGlobalMetrics(size) {
+ var sizeIndex;
+
+ if (size >= 5) {
+ sizeIndex = 0;
+ } else if (size >= 3) {
+ sizeIndex = 1;
+ } else {
+ sizeIndex = 2;
+ }
+
+ if (!fontMetricsBySizeIndex[sizeIndex]) {
+ var metrics = fontMetricsBySizeIndex[sizeIndex] = {
+ cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18
+ };
+
+ for (var key in sigmasAndXis) {
+ if (sigmasAndXis.hasOwnProperty(key)) {
+ metrics[key] = sigmasAndXis[key][sizeIndex];
+ }
+ }
+ }
+
+ return fontMetricsBySizeIndex[sizeIndex];
+}
+;// CONCATENATED MODULE: ./src/Options.js
+/**
+ * This file contains information about the options that the Parser carries
+ * around with it while parsing. Data is held in an `Options` object, and when
+ * recursing, a new `Options` object can be created with the `.with*` and
+ * `.reset` functions.
+ */
+
+var sizeStyleMap = [// Each element contains [textsize, scriptsize, scriptscriptsize].
+// The size mappings are taken from TeX with \normalsize=10pt.
+[1, 1, 1], // size1: [5, 5, 5] \tiny
+[2, 1, 1], // size2: [6, 5, 5]
+[3, 1, 1], // size3: [7, 5, 5] \scriptsize
+[4, 2, 1], // size4: [8, 6, 5] \footnotesize
+[5, 2, 1], // size5: [9, 6, 5] \small
+[6, 3, 1], // size6: [10, 7, 5] \normalsize
+[7, 4, 2], // size7: [12, 8, 6] \large
+[8, 6, 3], // size8: [14.4, 10, 7] \Large
+[9, 7, 6], // size9: [17.28, 12, 10] \LARGE
+[10, 8, 7], // size10: [20.74, 14.4, 12] \huge
+[11, 10, 9] // size11: [24.88, 20.74, 17.28] \HUGE
+];
+var sizeMultipliers = [// fontMetrics.js:getGlobalMetrics also uses size indexes, so if
+// you change size indexes, change that function.
+0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488];
+
+var sizeAtStyle = function sizeAtStyle(size, style) {
+ return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1];
+}; // In these types, "" (empty string) means "no change".
+
+
+/**
+ * This is the main options class. It contains the current style, size, color,
+ * and font.
+ *
+ * Options objects should not be modified. To create a new Options with
+ * different properties, call a `.having*` method.
+ */
+var Options = /*#__PURE__*/function () {
+ // A font family applies to a group of fonts (i.e. SansSerif), while a font
+ // represents a specific font (i.e. SansSerif Bold).
+ // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm
+
+ /**
+ * The base size index.
+ */
+ function Options(data) {
+ this.style = void 0;
+ this.color = void 0;
+ this.size = void 0;
+ this.textSize = void 0;
+ this.phantom = void 0;
+ this.font = void 0;
+ this.fontFamily = void 0;
+ this.fontWeight = void 0;
+ this.fontShape = void 0;
+ this.sizeMultiplier = void 0;
+ this.maxSize = void 0;
+ this.minRuleThickness = void 0;
+ this._fontMetrics = void 0;
+ this.style = data.style;
+ this.color = data.color;
+ this.size = data.size || Options.BASESIZE;
+ this.textSize = data.textSize || this.size;
+ this.phantom = !!data.phantom;
+ this.font = data.font || "";
+ this.fontFamily = data.fontFamily || "";
+ this.fontWeight = data.fontWeight || '';
+ this.fontShape = data.fontShape || '';
+ this.sizeMultiplier = sizeMultipliers[this.size - 1];
+ this.maxSize = data.maxSize;
+ this.minRuleThickness = data.minRuleThickness;
+ this._fontMetrics = undefined;
+ }
+ /**
+ * Returns a new options object with the same properties as "this". Properties
+ * from "extension" will be copied to the new options object.
+ */
+
+
+ var _proto = Options.prototype;
+
+ _proto.extend = function extend(extension) {
+ var data = {
+ style: this.style,
+ size: this.size,
+ textSize: this.textSize,
+ color: this.color,
+ phantom: this.phantom,
+ font: this.font,
+ fontFamily: this.fontFamily,
+ fontWeight: this.fontWeight,
+ fontShape: this.fontShape,
+ maxSize: this.maxSize,
+ minRuleThickness: this.minRuleThickness
+ };
+
+ for (var key in extension) {
+ if (extension.hasOwnProperty(key)) {
+ data[key] = extension[key];
+ }
+ }
+
+ return new Options(data);
+ }
+ /**
+ * Return an options object with the given style. If `this.style === style`,
+ * returns `this`.
+ */
+ ;
+
+ _proto.havingStyle = function havingStyle(style) {
+ if (this.style === style) {
+ return this;
+ } else {
+ return this.extend({
+ style: style,
+ size: sizeAtStyle(this.textSize, style)
+ });
+ }
+ }
+ /**
+ * Return an options object with a cramped version of the current style. If
+ * the current style is cramped, returns `this`.
+ */
+ ;
+
+ _proto.havingCrampedStyle = function havingCrampedStyle() {
+ return this.havingStyle(this.style.cramp());
+ }
+ /**
+ * Return an options object with the given size and in at least `\textstyle`.
+ * Returns `this` if appropriate.
+ */
+ ;
+
+ _proto.havingSize = function havingSize(size) {
+ if (this.size === size && this.textSize === size) {
+ return this;
+ } else {
+ return this.extend({
+ style: this.style.text(),
+ size: size,
+ textSize: size,
+ sizeMultiplier: sizeMultipliers[size - 1]
+ });
+ }
+ }
+ /**
+ * Like `this.havingSize(BASESIZE).havingStyle(style)`. If `style` is omitted,
+ * changes to at least `\textstyle`.
+ */
+ ;
+
+ _proto.havingBaseStyle = function havingBaseStyle(style) {
+ style = style || this.style.text();
+ var wantSize = sizeAtStyle(Options.BASESIZE, style);
+
+ if (this.size === wantSize && this.textSize === Options.BASESIZE && this.style === style) {
+ return this;
+ } else {
+ return this.extend({
+ style: style,
+ size: wantSize
+ });
+ }
+ }
+ /**
+ * Remove the effect of sizing changes such as \Huge.
+ * Keep the effect of the current style, such as \scriptstyle.
+ */
+ ;
+
+ _proto.havingBaseSizing = function havingBaseSizing() {
+ var size;
+
+ switch (this.style.id) {
+ case 4:
+ case 5:
+ size = 3; // normalsize in scriptstyle
+
+ break;
+
+ case 6:
+ case 7:
+ size = 1; // normalsize in scriptscriptstyle
+
+ break;
+
+ default:
+ size = 6;
+ // normalsize in textstyle or displaystyle
+ }
+
+ return this.extend({
+ style: this.style.text(),
+ size: size
+ });
+ }
+ /**
+ * Create a new options object with the given color.
+ */
+ ;
+
+ _proto.withColor = function withColor(color) {
+ return this.extend({
+ color: color
+ });
+ }
+ /**
+ * Create a new options object with "phantom" set to true.
+ */
+ ;
+
+ _proto.withPhantom = function withPhantom() {
+ return this.extend({
+ phantom: true
+ });
+ }
+ /**
+ * Creates a new options object with the given math font or old text font.
+ * @type {[type]}
+ */
+ ;
+
+ _proto.withFont = function withFont(font) {
+ return this.extend({
+ font: font
+ });
+ }
+ /**
+ * Create a new options objects with the given fontFamily.
+ */
+ ;
+
+ _proto.withTextFontFamily = function withTextFontFamily(fontFamily) {
+ return this.extend({
+ fontFamily: fontFamily,
+ font: ""
+ });
+ }
+ /**
+ * Creates a new options object with the given font weight
+ */
+ ;
+
+ _proto.withTextFontWeight = function withTextFontWeight(fontWeight) {
+ return this.extend({
+ fontWeight: fontWeight,
+ font: ""
+ });
+ }
+ /**
+ * Creates a new options object with the given font weight
+ */
+ ;
+
+ _proto.withTextFontShape = function withTextFontShape(fontShape) {
+ return this.extend({
+ fontShape: fontShape,
+ font: ""
+ });
+ }
+ /**
+ * Return the CSS sizing classes required to switch from enclosing options
+ * `oldOptions` to `this`. Returns an array of classes.
+ */
+ ;
+
+ _proto.sizingClasses = function sizingClasses(oldOptions) {
+ if (oldOptions.size !== this.size) {
+ return ["sizing", "reset-size" + oldOptions.size, "size" + this.size];
+ } else {
+ return [];
+ }
+ }
+ /**
+ * Return the CSS sizing classes required to switch to the base size. Like
+ * `this.havingSize(BASESIZE).sizingClasses(this)`.
+ */
+ ;
+
+ _proto.baseSizingClasses = function baseSizingClasses() {
+ if (this.size !== Options.BASESIZE) {
+ return ["sizing", "reset-size" + this.size, "size" + Options.BASESIZE];
+ } else {
+ return [];
+ }
+ }
+ /**
+ * Return the font metrics for this size.
+ */
+ ;
+
+ _proto.fontMetrics = function fontMetrics() {
+ if (!this._fontMetrics) {
+ this._fontMetrics = getGlobalMetrics(this.size);
+ }
+
+ return this._fontMetrics;
+ }
+ /**
+ * Gets the CSS color of the current options object
+ */
+ ;
+
+ _proto.getColor = function getColor() {
+ if (this.phantom) {
+ return "transparent";
+ } else {
+ return this.color;
+ }
+ };
+
+ return Options;
+}();
+
+Options.BASESIZE = 6;
+/* harmony default export */ var src_Options = (Options);
+;// CONCATENATED MODULE: ./src/units.js
+/**
+ * This file does conversion between units. In particular, it provides
+ * calculateSize to convert other units into ems.
+ */
+
+ // This table gives the number of TeX pts in one of each *absolute* TeX unit.
+// Thus, multiplying a length by this number converts the length from units
+// into pts. Dividing the result by ptPerEm gives the number of ems
+// *assuming* a font size of ptPerEm (normal size, normal style).
+
+var ptPerUnit = {
+ // https://en.wikibooks.org/wiki/LaTeX/Lengths and
+ // https://tex.stackexchange.com/a/8263
+ "pt": 1,
+ // TeX point
+ "mm": 7227 / 2540,
+ // millimeter
+ "cm": 7227 / 254,
+ // centimeter
+ "in": 72.27,
+ // inch
+ "bp": 803 / 800,
+ // big (PostScript) points
+ "pc": 12,
+ // pica
+ "dd": 1238 / 1157,
+ // didot
+ "cc": 14856 / 1157,
+ // cicero (12 didot)
+ "nd": 685 / 642,
+ // new didot
+ "nc": 1370 / 107,
+ // new cicero (12 new didot)
+ "sp": 1 / 65536,
+ // scaled point (TeX's internal smallest unit)
+ // https://tex.stackexchange.com/a/41371
+ "px": 803 / 800 // \pdfpxdimen defaults to 1 bp in pdfTeX and LuaTeX
+
+}; // Dictionary of relative units, for fast validity testing.
+
+var relativeUnit = {
+ "ex": true,
+ "em": true,
+ "mu": true
+};
+
+/**
+ * Determine whether the specified unit (either a string defining the unit
+ * or a "size" parse node containing a unit field) is valid.
+ */
+var validUnit = function validUnit(unit) {
+ if (typeof unit !== "string") {
+ unit = unit.unit;
+ }
+
+ return unit in ptPerUnit || unit in relativeUnit || unit === "ex";
+};
+/*
+ * Convert a "size" parse node (with numeric "number" and string "unit" fields,
+ * as parsed by functions.js argType "size") into a CSS em value for the
+ * current style/scale. `options` gives the current options.
+ */
+
+var calculateSize = function calculateSize(sizeValue, options) {
+ var scale;
+
+ if (sizeValue.unit in ptPerUnit) {
+ // Absolute units
+ scale = ptPerUnit[sizeValue.unit] // Convert unit to pt
+ / options.fontMetrics().ptPerEm // Convert pt to CSS em
+ / options.sizeMultiplier; // Unscale to make absolute units
+ } else if (sizeValue.unit === "mu") {
+ // `mu` units scale with scriptstyle/scriptscriptstyle.
+ scale = options.fontMetrics().cssEmPerMu;
+ } else {
+ // Other relative units always refer to the *textstyle* font
+ // in the current size.
+ var unitOptions;
+
+ if (options.style.isTight()) {
+ // isTight() means current style is script/scriptscript.
+ unitOptions = options.havingStyle(options.style.text());
+ } else {
+ unitOptions = options;
+ } // TODO: In TeX these units are relative to the quad of the current
+ // *text* font, e.g. cmr10. KaTeX instead uses values from the
+ // comparably-sized *Computer Modern symbol* font. At 10pt, these
+ // match. At 7pt and 5pt, they differ: cmr7=1.138894, cmsy7=1.170641;
+ // cmr5=1.361133, cmsy5=1.472241. Consider $\scriptsize a\kern1emb$.
+ // TeX \showlists shows a kern of 1.13889 * fontsize;
+ // KaTeX shows a kern of 1.171 * fontsize.
+
+
+ if (sizeValue.unit === "ex") {
+ scale = unitOptions.fontMetrics().xHeight;
+ } else if (sizeValue.unit === "em") {
+ scale = unitOptions.fontMetrics().quad;
+ } else {
+ throw new src_ParseError("Invalid unit: '" + sizeValue.unit + "'");
+ }
+
+ if (unitOptions !== options) {
+ scale *= unitOptions.sizeMultiplier / options.sizeMultiplier;
+ }
+ }
+
+ return Math.min(sizeValue.number * scale, options.maxSize);
+};
+/**
+ * Round `n` to 4 decimal places, or to the nearest 1/10,000th em. See
+ * https://github.com/KaTeX/KaTeX/pull/2460.
+ */
+
+var makeEm = function makeEm(n) {
+ return +n.toFixed(4) + "em";
+};
+;// CONCATENATED MODULE: ./src/domTree.js
+/**
+ * These objects store the data about the DOM nodes we create, as well as some
+ * extra data. They can then be transformed into real DOM nodes with the
+ * `toNode` function or HTML markup using `toMarkup`. They are useful for both
+ * storing extra properties on the nodes, as well as providing a way to easily
+ * work with the DOM.
+ *
+ * Similar functions for working with MathML nodes exist in mathMLTree.js.
+ *
+ * TODO: refactor `span` and `anchor` into common superclass when
+ * target environments support class inheritance
+ */
+
+
+
+
+
+
+/**
+ * Create an HTML className based on a list of classes. In addition to joining
+ * with spaces, we also remove empty classes.
+ */
+var createClass = function createClass(classes) {
+ return classes.filter(function (cls) {
+ return cls;
+ }).join(" ");
+};
+
+var initNode = function initNode(classes, options, style) {
+ this.classes = classes || [];
+ this.attributes = {};
+ this.height = 0;
+ this.depth = 0;
+ this.maxFontSize = 0;
+ this.style = style || {};
+
+ if (options) {
+ if (options.style.isTight()) {
+ this.classes.push("mtight");
+ }
+
+ var color = options.getColor();
+
+ if (color) {
+ this.style.color = color;
+ }
+ }
+};
+/**
+ * Convert into an HTML node
+ */
+
+
+var _toNode = function toNode(tagName) {
+ var node = document.createElement(tagName); // Apply the class
+
+ node.className = createClass(this.classes); // Apply inline styles
+
+ for (var style in this.style) {
+ if (this.style.hasOwnProperty(style)) {
+ // $FlowFixMe Flow doesn't seem to understand span.style's type.
+ node.style[style] = this.style[style];
+ }
+ } // Apply attributes
+
+
+ for (var attr in this.attributes) {
+ if (this.attributes.hasOwnProperty(attr)) {
+ node.setAttribute(attr, this.attributes[attr]);
+ }
+ } // Append the children, also as HTML nodes
+
+
+ for (var i = 0; i < this.children.length; i++) {
+ node.appendChild(this.children[i].toNode());
+ }
+
+ return node;
+};
+/**
+ * Convert into an HTML markup string
+ */
+
+
+var _toMarkup = function toMarkup(tagName) {
+ var markup = "<" + tagName; // Add the class
+
+ if (this.classes.length) {
+ markup += " class=\"" + utils.escape(createClass(this.classes)) + "\"";
+ }
+
+ var styles = ""; // Add the styles, after hyphenation
+
+ for (var style in this.style) {
+ if (this.style.hasOwnProperty(style)) {
+ styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
+ }
+ }
+
+ if (styles) {
+ markup += " style=\"" + utils.escape(styles) + "\"";
+ } // Add the attributes
+
+
+ for (var attr in this.attributes) {
+ if (this.attributes.hasOwnProperty(attr)) {
+ markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\"";
+ }
+ }
+
+ markup += ">"; // Add the markup of the children, also as markup
+
+ for (var i = 0; i < this.children.length; i++) {
+ markup += this.children[i].toMarkup();
+ }
+
+ markup += "" + tagName + ">";
+ return markup;
+}; // Making the type below exact with all optional fields doesn't work due to
+// - https://github.com/facebook/flow/issues/4582
+// - https://github.com/facebook/flow/issues/5688
+// However, since *all* fields are optional, $Shape<> works as suggested in 5688
+// above.
+// This type does not include all CSS properties. Additional properties should
+// be added as needed.
+
+
+/**
+ * This node represents a span node, with a className, a list of children, and
+ * an inline style. It also contains information about its height, depth, and
+ * maxFontSize.
+ *
+ * Represents two types with different uses: SvgSpan to wrap an SVG and DomSpan
+ * otherwise. This typesafety is important when HTML builders access a span's
+ * children.
+ */
+var Span = /*#__PURE__*/function () {
+ function Span(classes, children, options, style) {
+ this.children = void 0;
+ this.attributes = void 0;
+ this.classes = void 0;
+ this.height = void 0;
+ this.depth = void 0;
+ this.width = void 0;
+ this.maxFontSize = void 0;
+ this.style = void 0;
+ initNode.call(this, classes, options, style);
+ this.children = children || [];
+ }
+ /**
+ * Sets an arbitrary attribute on the span. Warning: use this wisely. Not
+ * all browsers support attributes the same, and having too many custom
+ * attributes is probably bad.
+ */
+
+
+ var _proto = Span.prototype;
+
+ _proto.setAttribute = function setAttribute(attribute, value) {
+ this.attributes[attribute] = value;
+ };
+
+ _proto.hasClass = function hasClass(className) {
+ return utils.contains(this.classes, className);
+ };
+
+ _proto.toNode = function toNode() {
+ return _toNode.call(this, "span");
+ };
+
+ _proto.toMarkup = function toMarkup() {
+ return _toMarkup.call(this, "span");
+ };
+
+ return Span;
+}();
+/**
+ * This node represents an anchor () element with a hyperlink. See `span`
+ * for further details.
+ */
+
+var Anchor = /*#__PURE__*/function () {
+ function Anchor(href, classes, children, options) {
+ this.children = void 0;
+ this.attributes = void 0;
+ this.classes = void 0;
+ this.height = void 0;
+ this.depth = void 0;
+ this.maxFontSize = void 0;
+ this.style = void 0;
+ initNode.call(this, classes, options);
+ this.children = children || [];
+ this.setAttribute('href', href);
+ }
+
+ var _proto2 = Anchor.prototype;
+
+ _proto2.setAttribute = function setAttribute(attribute, value) {
+ this.attributes[attribute] = value;
+ };
+
+ _proto2.hasClass = function hasClass(className) {
+ return utils.contains(this.classes, className);
+ };
+
+ _proto2.toNode = function toNode() {
+ return _toNode.call(this, "a");
+ };
+
+ _proto2.toMarkup = function toMarkup() {
+ return _toMarkup.call(this, "a");
+ };
+
+ return Anchor;
+}();
+/**
+ * This node represents an image embed () element.
+ */
+
+var Img = /*#__PURE__*/function () {
+ function Img(src, alt, style) {
+ this.src = void 0;
+ this.alt = void 0;
+ this.classes = void 0;
+ this.height = void 0;
+ this.depth = void 0;
+ this.maxFontSize = void 0;
+ this.style = void 0;
+ this.alt = alt;
+ this.src = src;
+ this.classes = ["mord"];
+ this.style = style;
+ }
+
+ var _proto3 = Img.prototype;
+
+ _proto3.hasClass = function hasClass(className) {
+ return utils.contains(this.classes, className);
+ };
+
+ _proto3.toNode = function toNode() {
+ var node = document.createElement("img");
+ node.src = this.src;
+ node.alt = this.alt;
+ node.className = "mord"; // Apply inline styles
+
+ for (var style in this.style) {
+ if (this.style.hasOwnProperty(style)) {
+ // $FlowFixMe
+ node.style[style] = this.style[style];
+ }
+ }
+
+ return node;
+ };
+
+ _proto3.toMarkup = function toMarkup() {
+ var markup = "";
+ return markup;
+ };
+
+ return Img;
+}();
+var iCombinations = {
+ 'î': "\u0131\u0302",
+ 'ï': "\u0131\u0308",
+ 'í': "\u0131\u0301",
+ // 'ī': '\u0131\u0304', // enable when we add Extended Latin
+ 'ì': "\u0131\u0300"
+};
+/**
+ * A symbol node contains information about a single symbol. It either renders
+ * to a single text node, or a span with a single text node in it, depending on
+ * whether it has CSS classes, styles, or needs italic correction.
+ */
+
+var SymbolNode = /*#__PURE__*/function () {
+ function SymbolNode(text, height, depth, italic, skew, width, classes, style) {
+ this.text = void 0;
+ this.height = void 0;
+ this.depth = void 0;
+ this.italic = void 0;
+ this.skew = void 0;
+ this.width = void 0;
+ this.maxFontSize = void 0;
+ this.classes = void 0;
+ this.style = void 0;
+ this.text = text;
+ this.height = height || 0;
+ this.depth = depth || 0;
+ this.italic = italic || 0;
+ this.skew = skew || 0;
+ this.width = width || 0;
+ this.classes = classes || [];
+ this.style = style || {};
+ this.maxFontSize = 0; // Mark text from non-Latin scripts with specific classes so that we
+ // can specify which fonts to use. This allows us to render these
+ // characters with a serif font in situations where the browser would
+ // either default to a sans serif or render a placeholder character.
+ // We use CSS class names like cjk_fallback, hangul_fallback and
+ // brahmic_fallback. See ./unicodeScripts.js for the set of possible
+ // script names
+
+ var script = scriptFromCodepoint(this.text.charCodeAt(0));
+
+ if (script) {
+ this.classes.push(script + "_fallback");
+ }
+
+ if (/[îïíì]/.test(this.text)) {
+ // add ī when we add Extended Latin
+ this.text = iCombinations[this.text];
+ }
+ }
+
+ var _proto4 = SymbolNode.prototype;
+
+ _proto4.hasClass = function hasClass(className) {
+ return utils.contains(this.classes, className);
+ }
+ /**
+ * Creates a text node or span from a symbol node. Note that a span is only
+ * created if it is needed.
+ */
+ ;
+
+ _proto4.toNode = function toNode() {
+ var node = document.createTextNode(this.text);
+ var span = null;
+
+ if (this.italic > 0) {
+ span = document.createElement("span");
+ span.style.marginRight = makeEm(this.italic);
+ }
+
+ if (this.classes.length > 0) {
+ span = span || document.createElement("span");
+ span.className = createClass(this.classes);
+ }
+
+ for (var style in this.style) {
+ if (this.style.hasOwnProperty(style)) {
+ span = span || document.createElement("span"); // $FlowFixMe Flow doesn't seem to understand span.style's type.
+
+ span.style[style] = this.style[style];
+ }
+ }
+
+ if (span) {
+ span.appendChild(node);
+ return span;
+ } else {
+ return node;
+ }
+ }
+ /**
+ * Creates markup for a symbol node.
+ */
+ ;
+
+ _proto4.toMarkup = function toMarkup() {
+ // TODO(alpert): More duplication than I'd like from
+ // span.prototype.toMarkup and symbolNode.prototype.toNode...
+ var needsSpan = false;
+ var markup = " 0) {
+ styles += "margin-right:" + this.italic + "em;";
+ }
+
+ for (var style in this.style) {
+ if (this.style.hasOwnProperty(style)) {
+ styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
+ }
+ }
+
+ if (styles) {
+ needsSpan = true;
+ markup += " style=\"" + utils.escape(styles) + "\"";
+ }
+
+ var escaped = utils.escape(this.text);
+
+ if (needsSpan) {
+ markup += ">";
+ markup += escaped;
+ markup += "";
+ return markup;
+ } else {
+ return escaped;
+ }
+ };
+
+ return SymbolNode;
+}();
+/**
+ * SVG nodes are used to render stretchy wide elements.
+ */
+
+var SvgNode = /*#__PURE__*/function () {
+ function SvgNode(children, attributes) {
+ this.children = void 0;
+ this.attributes = void 0;
+ this.children = children || [];
+ this.attributes = attributes || {};
+ }
+
+ var _proto5 = SvgNode.prototype;
+
+ _proto5.toNode = function toNode() {
+ var svgNS = "http://www.w3.org/2000/svg";
+ var node = document.createElementNS(svgNS, "svg"); // Apply attributes
+
+ for (var attr in this.attributes) {
+ if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
+ node.setAttribute(attr, this.attributes[attr]);
+ }
+ }
+
+ for (var i = 0; i < this.children.length; i++) {
+ node.appendChild(this.children[i].toNode());
+ }
+
+ return node;
+ };
+
+ _proto5.toMarkup = function toMarkup() {
+ var markup = "";
+ return markup;
+ };
+
+ return SvgNode;
+}();
+var PathNode = /*#__PURE__*/function () {
+ function PathNode(pathName, alternate) {
+ this.pathName = void 0;
+ this.alternate = void 0;
+ this.pathName = pathName;
+ this.alternate = alternate; // Used only for \sqrt, \phase, & tall delims
+ }
+
+ var _proto6 = PathNode.prototype;
+
+ _proto6.toNode = function toNode() {
+ var svgNS = "http://www.w3.org/2000/svg";
+ var node = document.createElementNS(svgNS, "path");
+
+ if (this.alternate) {
+ node.setAttribute("d", this.alternate);
+ } else {
+ node.setAttribute("d", path[this.pathName]);
+ }
+
+ return node;
+ };
+
+ _proto6.toMarkup = function toMarkup() {
+ if (this.alternate) {
+ return "";
+ } else {
+ return "";
+ }
+ };
+
+ return PathNode;
+}();
+var LineNode = /*#__PURE__*/function () {
+ function LineNode(attributes) {
+ this.attributes = void 0;
+ this.attributes = attributes || {};
+ }
+
+ var _proto7 = LineNode.prototype;
+
+ _proto7.toNode = function toNode() {
+ var svgNS = "http://www.w3.org/2000/svg";
+ var node = document.createElementNS(svgNS, "line"); // Apply attributes
+
+ for (var attr in this.attributes) {
+ if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
+ node.setAttribute(attr, this.attributes[attr]);
+ }
+ }
+
+ return node;
+ };
+
+ _proto7.toMarkup = function toMarkup() {
+ var markup = "";
+ return markup;
+ };
+
+ return LineNode;
+}();
+function assertSymbolDomNode(group) {
+ if (group instanceof SymbolNode) {
+ return group;
+ } else {
+ throw new Error("Expected symbolNode but got " + String(group) + ".");
+ }
+}
+function assertSpan(group) {
+ if (group instanceof Span) {
+ return group;
+ } else {
+ throw new Error("Expected span but got " + String(group) + ".");
+ }
+}
+;// CONCATENATED MODULE: ./src/symbols.js
+/**
+ * This file holds a list of all no-argument functions and single-character
+ * symbols (like 'a' or ';').
+ *
+ * For each of the symbols, there are three properties they can have:
+ * - font (required): the font to be used for this symbol. Either "main" (the
+ normal font), or "ams" (the ams fonts).
+ * - group (required): the ParseNode group type the symbol should have (i.e.
+ "textord", "mathord", etc).
+ See https://github.com/KaTeX/KaTeX/wiki/Examining-TeX#group-types
+ * - replace: the character that this symbol or function should be
+ * replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi
+ * character in the main font).
+ *
+ * The outermost map in the table indicates what mode the symbols should be
+ * accepted in (e.g. "math" or "text").
+ */
+// Some of these have a "-token" suffix since these are also used as `ParseNode`
+// types for raw text tokens, and we want to avoid conflicts with higher-level
+// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
+// looking up the `symbols` map.
+var ATOMS = {
+ "bin": 1,
+ "close": 1,
+ "inner": 1,
+ "open": 1,
+ "punct": 1,
+ "rel": 1
+};
+var NON_ATOMS = {
+ "accent-token": 1,
+ "mathord": 1,
+ "op-token": 1,
+ "spacing": 1,
+ "textord": 1
+};
+var symbols = {
+ "math": {},
+ "text": {}
+};
+/* harmony default export */ var src_symbols = (symbols);
+/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
+
+function defineSymbol(mode, font, group, replace, name, acceptUnicodeChar) {
+ symbols[mode][name] = {
+ font: font,
+ group: group,
+ replace: replace
+ };
+
+ if (acceptUnicodeChar && replace) {
+ symbols[mode][replace] = symbols[mode][name];
+ }
+} // Some abbreviations for commonly used strings.
+// This helps minify the code, and also spotting typos using jshint.
+// modes:
+
+var math = "math";
+var symbols_text = "text"; // fonts:
+
+var main = "main";
+var ams = "ams"; // groups:
+
+var accent = "accent-token";
+var bin = "bin";
+var symbols_close = "close";
+var inner = "inner";
+var mathord = "mathord";
+var op = "op-token";
+var symbols_open = "open";
+var punct = "punct";
+var rel = "rel";
+var spacing = "spacing";
+var textord = "textord"; // Now comes the symbol table
+// Relation Symbols
+
+defineSymbol(math, main, rel, "\u2261", "\\equiv", true);
+defineSymbol(math, main, rel, "\u227A", "\\prec", true);
+defineSymbol(math, main, rel, "\u227B", "\\succ", true);
+defineSymbol(math, main, rel, "\u223C", "\\sim", true);
+defineSymbol(math, main, rel, "\u22A5", "\\perp");
+defineSymbol(math, main, rel, "\u2AAF", "\\preceq", true);
+defineSymbol(math, main, rel, "\u2AB0", "\\succeq", true);
+defineSymbol(math, main, rel, "\u2243", "\\simeq", true);
+defineSymbol(math, main, rel, "\u2223", "\\mid", true);
+defineSymbol(math, main, rel, "\u226A", "\\ll", true);
+defineSymbol(math, main, rel, "\u226B", "\\gg", true);
+defineSymbol(math, main, rel, "\u224D", "\\asymp", true);
+defineSymbol(math, main, rel, "\u2225", "\\parallel");
+defineSymbol(math, main, rel, "\u22C8", "\\bowtie", true);
+defineSymbol(math, main, rel, "\u2323", "\\smile", true);
+defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq", true);
+defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq", true);
+defineSymbol(math, main, rel, "\u2250", "\\doteq", true);
+defineSymbol(math, main, rel, "\u2322", "\\frown", true);
+defineSymbol(math, main, rel, "\u220B", "\\ni", true);
+defineSymbol(math, main, rel, "\u221D", "\\propto", true);
+defineSymbol(math, main, rel, "\u22A2", "\\vdash", true);
+defineSymbol(math, main, rel, "\u22A3", "\\dashv", true);
+defineSymbol(math, main, rel, "\u220B", "\\owns"); // Punctuation
+
+defineSymbol(math, main, punct, ".", "\\ldotp");
+defineSymbol(math, main, punct, "\u22C5", "\\cdotp"); // Misc Symbols
+
+defineSymbol(math, main, textord, "#", "\\#");
+defineSymbol(symbols_text, main, textord, "#", "\\#");
+defineSymbol(math, main, textord, "&", "\\&");
+defineSymbol(symbols_text, main, textord, "&", "\\&");
+defineSymbol(math, main, textord, "\u2135", "\\aleph", true);
+defineSymbol(math, main, textord, "\u2200", "\\forall", true);
+defineSymbol(math, main, textord, "\u210F", "\\hbar", true);
+defineSymbol(math, main, textord, "\u2203", "\\exists", true);
+defineSymbol(math, main, textord, "\u2207", "\\nabla", true);
+defineSymbol(math, main, textord, "\u266D", "\\flat", true);
+defineSymbol(math, main, textord, "\u2113", "\\ell", true);
+defineSymbol(math, main, textord, "\u266E", "\\natural", true);
+defineSymbol(math, main, textord, "\u2663", "\\clubsuit", true);
+defineSymbol(math, main, textord, "\u2118", "\\wp", true);
+defineSymbol(math, main, textord, "\u266F", "\\sharp", true);
+defineSymbol(math, main, textord, "\u2662", "\\diamondsuit", true);
+defineSymbol(math, main, textord, "\u211C", "\\Re", true);
+defineSymbol(math, main, textord, "\u2661", "\\heartsuit", true);
+defineSymbol(math, main, textord, "\u2111", "\\Im", true);
+defineSymbol(math, main, textord, "\u2660", "\\spadesuit", true);
+defineSymbol(math, main, textord, "\xA7", "\\S", true);
+defineSymbol(symbols_text, main, textord, "\xA7", "\\S");
+defineSymbol(math, main, textord, "\xB6", "\\P", true);
+defineSymbol(symbols_text, main, textord, "\xB6", "\\P"); // Math and Text
+
+defineSymbol(math, main, textord, "\u2020", "\\dag");
+defineSymbol(symbols_text, main, textord, "\u2020", "\\dag");
+defineSymbol(symbols_text, main, textord, "\u2020", "\\textdagger");
+defineSymbol(math, main, textord, "\u2021", "\\ddag");
+defineSymbol(symbols_text, main, textord, "\u2021", "\\ddag");
+defineSymbol(symbols_text, main, textord, "\u2021", "\\textdaggerdbl"); // Large Delimiters
+
+defineSymbol(math, main, symbols_close, "\u23B1", "\\rmoustache", true);
+defineSymbol(math, main, symbols_open, "\u23B0", "\\lmoustache", true);
+defineSymbol(math, main, symbols_close, "\u27EF", "\\rgroup", true);
+defineSymbol(math, main, symbols_open, "\u27EE", "\\lgroup", true); // Binary Operators
+
+defineSymbol(math, main, bin, "\u2213", "\\mp", true);
+defineSymbol(math, main, bin, "\u2296", "\\ominus", true);
+defineSymbol(math, main, bin, "\u228E", "\\uplus", true);
+defineSymbol(math, main, bin, "\u2293", "\\sqcap", true);
+defineSymbol(math, main, bin, "\u2217", "\\ast");
+defineSymbol(math, main, bin, "\u2294", "\\sqcup", true);
+defineSymbol(math, main, bin, "\u25EF", "\\bigcirc", true);
+defineSymbol(math, main, bin, "\u2219", "\\bullet");
+defineSymbol(math, main, bin, "\u2021", "\\ddagger");
+defineSymbol(math, main, bin, "\u2240", "\\wr", true);
+defineSymbol(math, main, bin, "\u2A3F", "\\amalg");
+defineSymbol(math, main, bin, "&", "\\And"); // from amsmath
+// Arrow Symbols
+
+defineSymbol(math, main, rel, "\u27F5", "\\longleftarrow", true);
+defineSymbol(math, main, rel, "\u21D0", "\\Leftarrow", true);
+defineSymbol(math, main, rel, "\u27F8", "\\Longleftarrow", true);
+defineSymbol(math, main, rel, "\u27F6", "\\longrightarrow", true);
+defineSymbol(math, main, rel, "\u21D2", "\\Rightarrow", true);
+defineSymbol(math, main, rel, "\u27F9", "\\Longrightarrow", true);
+defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow", true);
+defineSymbol(math, main, rel, "\u27F7", "\\longleftrightarrow", true);
+defineSymbol(math, main, rel, "\u21D4", "\\Leftrightarrow", true);
+defineSymbol(math, main, rel, "\u27FA", "\\Longleftrightarrow", true);
+defineSymbol(math, main, rel, "\u21A6", "\\mapsto", true);
+defineSymbol(math, main, rel, "\u27FC", "\\longmapsto", true);
+defineSymbol(math, main, rel, "\u2197", "\\nearrow", true);
+defineSymbol(math, main, rel, "\u21A9", "\\hookleftarrow", true);
+defineSymbol(math, main, rel, "\u21AA", "\\hookrightarrow", true);
+defineSymbol(math, main, rel, "\u2198", "\\searrow", true);
+defineSymbol(math, main, rel, "\u21BC", "\\leftharpoonup", true);
+defineSymbol(math, main, rel, "\u21C0", "\\rightharpoonup", true);
+defineSymbol(math, main, rel, "\u2199", "\\swarrow", true);
+defineSymbol(math, main, rel, "\u21BD", "\\leftharpoondown", true);
+defineSymbol(math, main, rel, "\u21C1", "\\rightharpoondown", true);
+defineSymbol(math, main, rel, "\u2196", "\\nwarrow", true);
+defineSymbol(math, main, rel, "\u21CC", "\\rightleftharpoons", true); // AMS Negated Binary Relations
+
+defineSymbol(math, ams, rel, "\u226E", "\\nless", true); // Symbol names preceeded by "@" each have a corresponding macro.
+
+defineSymbol(math, ams, rel, "\uE010", "\\@nleqslant");
+defineSymbol(math, ams, rel, "\uE011", "\\@nleqq");
+defineSymbol(math, ams, rel, "\u2A87", "\\lneq", true);
+defineSymbol(math, ams, rel, "\u2268", "\\lneqq", true);
+defineSymbol(math, ams, rel, "\uE00C", "\\@lvertneqq");
+defineSymbol(math, ams, rel, "\u22E6", "\\lnsim", true);
+defineSymbol(math, ams, rel, "\u2A89", "\\lnapprox", true);
+defineSymbol(math, ams, rel, "\u2280", "\\nprec", true); // unicode-math maps \u22e0 to \npreccurlyeq. We'll use the AMS synonym.
+
+defineSymbol(math, ams, rel, "\u22E0", "\\npreceq", true);
+defineSymbol(math, ams, rel, "\u22E8", "\\precnsim", true);
+defineSymbol(math, ams, rel, "\u2AB9", "\\precnapprox", true);
+defineSymbol(math, ams, rel, "\u2241", "\\nsim", true);
+defineSymbol(math, ams, rel, "\uE006", "\\@nshortmid");
+defineSymbol(math, ams, rel, "\u2224", "\\nmid", true);
+defineSymbol(math, ams, rel, "\u22AC", "\\nvdash", true);
+defineSymbol(math, ams, rel, "\u22AD", "\\nvDash", true);
+defineSymbol(math, ams, rel, "\u22EA", "\\ntriangleleft");
+defineSymbol(math, ams, rel, "\u22EC", "\\ntrianglelefteq", true);
+defineSymbol(math, ams, rel, "\u228A", "\\subsetneq", true);
+defineSymbol(math, ams, rel, "\uE01A", "\\@varsubsetneq");
+defineSymbol(math, ams, rel, "\u2ACB", "\\subsetneqq", true);
+defineSymbol(math, ams, rel, "\uE017", "\\@varsubsetneqq");
+defineSymbol(math, ams, rel, "\u226F", "\\ngtr", true);
+defineSymbol(math, ams, rel, "\uE00F", "\\@ngeqslant");
+defineSymbol(math, ams, rel, "\uE00E", "\\@ngeqq");
+defineSymbol(math, ams, rel, "\u2A88", "\\gneq", true);
+defineSymbol(math, ams, rel, "\u2269", "\\gneqq", true);
+defineSymbol(math, ams, rel, "\uE00D", "\\@gvertneqq");
+defineSymbol(math, ams, rel, "\u22E7", "\\gnsim", true);
+defineSymbol(math, ams, rel, "\u2A8A", "\\gnapprox", true);
+defineSymbol(math, ams, rel, "\u2281", "\\nsucc", true); // unicode-math maps \u22e1 to \nsucccurlyeq. We'll use the AMS synonym.
+
+defineSymbol(math, ams, rel, "\u22E1", "\\nsucceq", true);
+defineSymbol(math, ams, rel, "\u22E9", "\\succnsim", true);
+defineSymbol(math, ams, rel, "\u2ABA", "\\succnapprox", true); // unicode-math maps \u2246 to \simneqq. We'll use the AMS synonym.
+
+defineSymbol(math, ams, rel, "\u2246", "\\ncong", true);
+defineSymbol(math, ams, rel, "\uE007", "\\@nshortparallel");
+defineSymbol(math, ams, rel, "\u2226", "\\nparallel", true);
+defineSymbol(math, ams, rel, "\u22AF", "\\nVDash", true);
+defineSymbol(math, ams, rel, "\u22EB", "\\ntriangleright");
+defineSymbol(math, ams, rel, "\u22ED", "\\ntrianglerighteq", true);
+defineSymbol(math, ams, rel, "\uE018", "\\@nsupseteqq");
+defineSymbol(math, ams, rel, "\u228B", "\\supsetneq", true);
+defineSymbol(math, ams, rel, "\uE01B", "\\@varsupsetneq");
+defineSymbol(math, ams, rel, "\u2ACC", "\\supsetneqq", true);
+defineSymbol(math, ams, rel, "\uE019", "\\@varsupsetneqq");
+defineSymbol(math, ams, rel, "\u22AE", "\\nVdash", true);
+defineSymbol(math, ams, rel, "\u2AB5", "\\precneqq", true);
+defineSymbol(math, ams, rel, "\u2AB6", "\\succneqq", true);
+defineSymbol(math, ams, rel, "\uE016", "\\@nsubseteqq");
+defineSymbol(math, ams, bin, "\u22B4", "\\unlhd");
+defineSymbol(math, ams, bin, "\u22B5", "\\unrhd"); // AMS Negated Arrows
+
+defineSymbol(math, ams, rel, "\u219A", "\\nleftarrow", true);
+defineSymbol(math, ams, rel, "\u219B", "\\nrightarrow", true);
+defineSymbol(math, ams, rel, "\u21CD", "\\nLeftarrow", true);
+defineSymbol(math, ams, rel, "\u21CF", "\\nRightarrow", true);
+defineSymbol(math, ams, rel, "\u21AE", "\\nleftrightarrow", true);
+defineSymbol(math, ams, rel, "\u21CE", "\\nLeftrightarrow", true); // AMS Misc
+
+defineSymbol(math, ams, rel, "\u25B3", "\\vartriangle");
+defineSymbol(math, ams, textord, "\u210F", "\\hslash");
+defineSymbol(math, ams, textord, "\u25BD", "\\triangledown");
+defineSymbol(math, ams, textord, "\u25CA", "\\lozenge");
+defineSymbol(math, ams, textord, "\u24C8", "\\circledS");
+defineSymbol(math, ams, textord, "\xAE", "\\circledR");
+defineSymbol(symbols_text, ams, textord, "\xAE", "\\circledR");
+defineSymbol(math, ams, textord, "\u2221", "\\measuredangle", true);
+defineSymbol(math, ams, textord, "\u2204", "\\nexists");
+defineSymbol(math, ams, textord, "\u2127", "\\mho");
+defineSymbol(math, ams, textord, "\u2132", "\\Finv", true);
+defineSymbol(math, ams, textord, "\u2141", "\\Game", true);
+defineSymbol(math, ams, textord, "\u2035", "\\backprime");
+defineSymbol(math, ams, textord, "\u25B2", "\\blacktriangle");
+defineSymbol(math, ams, textord, "\u25BC", "\\blacktriangledown");
+defineSymbol(math, ams, textord, "\u25A0", "\\blacksquare");
+defineSymbol(math, ams, textord, "\u29EB", "\\blacklozenge");
+defineSymbol(math, ams, textord, "\u2605", "\\bigstar");
+defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle", true);
+defineSymbol(math, ams, textord, "\u2201", "\\complement", true); // unicode-math maps U+F0 to \matheth. We map to AMS function \eth
+
+defineSymbol(math, ams, textord, "\xF0", "\\eth", true);
+defineSymbol(symbols_text, main, textord, "\xF0", "\xF0");
+defineSymbol(math, ams, textord, "\u2571", "\\diagup");
+defineSymbol(math, ams, textord, "\u2572", "\\diagdown");
+defineSymbol(math, ams, textord, "\u25A1", "\\square");
+defineSymbol(math, ams, textord, "\u25A1", "\\Box");
+defineSymbol(math, ams, textord, "\u25CA", "\\Diamond"); // unicode-math maps U+A5 to \mathyen. We map to AMS function \yen
+
+defineSymbol(math, ams, textord, "\xA5", "\\yen", true);
+defineSymbol(symbols_text, ams, textord, "\xA5", "\\yen", true);
+defineSymbol(math, ams, textord, "\u2713", "\\checkmark", true);
+defineSymbol(symbols_text, ams, textord, "\u2713", "\\checkmark"); // AMS Hebrew
+
+defineSymbol(math, ams, textord, "\u2136", "\\beth", true);
+defineSymbol(math, ams, textord, "\u2138", "\\daleth", true);
+defineSymbol(math, ams, textord, "\u2137", "\\gimel", true); // AMS Greek
+
+defineSymbol(math, ams, textord, "\u03DD", "\\digamma", true);
+defineSymbol(math, ams, textord, "\u03F0", "\\varkappa"); // AMS Delimiters
+
+defineSymbol(math, ams, symbols_open, "\u250C", "\\@ulcorner", true);
+defineSymbol(math, ams, symbols_close, "\u2510", "\\@urcorner", true);
+defineSymbol(math, ams, symbols_open, "\u2514", "\\@llcorner", true);
+defineSymbol(math, ams, symbols_close, "\u2518", "\\@lrcorner", true); // AMS Binary Relations
+
+defineSymbol(math, ams, rel, "\u2266", "\\leqq", true);
+defineSymbol(math, ams, rel, "\u2A7D", "\\leqslant", true);
+defineSymbol(math, ams, rel, "\u2A95", "\\eqslantless", true);
+defineSymbol(math, ams, rel, "\u2272", "\\lesssim", true);
+defineSymbol(math, ams, rel, "\u2A85", "\\lessapprox", true);
+defineSymbol(math, ams, rel, "\u224A", "\\approxeq", true);
+defineSymbol(math, ams, bin, "\u22D6", "\\lessdot");
+defineSymbol(math, ams, rel, "\u22D8", "\\lll", true);
+defineSymbol(math, ams, rel, "\u2276", "\\lessgtr", true);
+defineSymbol(math, ams, rel, "\u22DA", "\\lesseqgtr", true);
+defineSymbol(math, ams, rel, "\u2A8B", "\\lesseqqgtr", true);
+defineSymbol(math, ams, rel, "\u2251", "\\doteqdot");
+defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq", true);
+defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq", true);
+defineSymbol(math, ams, rel, "\u223D", "\\backsim", true);
+defineSymbol(math, ams, rel, "\u22CD", "\\backsimeq", true);
+defineSymbol(math, ams, rel, "\u2AC5", "\\subseteqq", true);
+defineSymbol(math, ams, rel, "\u22D0", "\\Subset", true);
+defineSymbol(math, ams, rel, "\u228F", "\\sqsubset", true);
+defineSymbol(math, ams, rel, "\u227C", "\\preccurlyeq", true);
+defineSymbol(math, ams, rel, "\u22DE", "\\curlyeqprec", true);
+defineSymbol(math, ams, rel, "\u227E", "\\precsim", true);
+defineSymbol(math, ams, rel, "\u2AB7", "\\precapprox", true);
+defineSymbol(math, ams, rel, "\u22B2", "\\vartriangleleft");
+defineSymbol(math, ams, rel, "\u22B4", "\\trianglelefteq");
+defineSymbol(math, ams, rel, "\u22A8", "\\vDash", true);
+defineSymbol(math, ams, rel, "\u22AA", "\\Vvdash", true);
+defineSymbol(math, ams, rel, "\u2323", "\\smallsmile");
+defineSymbol(math, ams, rel, "\u2322", "\\smallfrown");
+defineSymbol(math, ams, rel, "\u224F", "\\bumpeq", true);
+defineSymbol(math, ams, rel, "\u224E", "\\Bumpeq", true);
+defineSymbol(math, ams, rel, "\u2267", "\\geqq", true);
+defineSymbol(math, ams, rel, "\u2A7E", "\\geqslant", true);
+defineSymbol(math, ams, rel, "\u2A96", "\\eqslantgtr", true);
+defineSymbol(math, ams, rel, "\u2273", "\\gtrsim", true);
+defineSymbol(math, ams, rel, "\u2A86", "\\gtrapprox", true);
+defineSymbol(math, ams, bin, "\u22D7", "\\gtrdot");
+defineSymbol(math, ams, rel, "\u22D9", "\\ggg", true);
+defineSymbol(math, ams, rel, "\u2277", "\\gtrless", true);
+defineSymbol(math, ams, rel, "\u22DB", "\\gtreqless", true);
+defineSymbol(math, ams, rel, "\u2A8C", "\\gtreqqless", true);
+defineSymbol(math, ams, rel, "\u2256", "\\eqcirc", true);
+defineSymbol(math, ams, rel, "\u2257", "\\circeq", true);
+defineSymbol(math, ams, rel, "\u225C", "\\triangleq", true);
+defineSymbol(math, ams, rel, "\u223C", "\\thicksim");
+defineSymbol(math, ams, rel, "\u2248", "\\thickapprox");
+defineSymbol(math, ams, rel, "\u2AC6", "\\supseteqq", true);
+defineSymbol(math, ams, rel, "\u22D1", "\\Supset", true);
+defineSymbol(math, ams, rel, "\u2290", "\\sqsupset", true);
+defineSymbol(math, ams, rel, "\u227D", "\\succcurlyeq", true);
+defineSymbol(math, ams, rel, "\u22DF", "\\curlyeqsucc", true);
+defineSymbol(math, ams, rel, "\u227F", "\\succsim", true);
+defineSymbol(math, ams, rel, "\u2AB8", "\\succapprox", true);
+defineSymbol(math, ams, rel, "\u22B3", "\\vartriangleright");
+defineSymbol(math, ams, rel, "\u22B5", "\\trianglerighteq");
+defineSymbol(math, ams, rel, "\u22A9", "\\Vdash", true);
+defineSymbol(math, ams, rel, "\u2223", "\\shortmid");
+defineSymbol(math, ams, rel, "\u2225", "\\shortparallel");
+defineSymbol(math, ams, rel, "\u226C", "\\between", true);
+defineSymbol(math, ams, rel, "\u22D4", "\\pitchfork", true);
+defineSymbol(math, ams, rel, "\u221D", "\\varpropto");
+defineSymbol(math, ams, rel, "\u25C0", "\\blacktriangleleft"); // unicode-math says that \therefore is a mathord atom.
+// We kept the amssymb atom type, which is rel.
+
+defineSymbol(math, ams, rel, "\u2234", "\\therefore", true);
+defineSymbol(math, ams, rel, "\u220D", "\\backepsilon");
+defineSymbol(math, ams, rel, "\u25B6", "\\blacktriangleright"); // unicode-math says that \because is a mathord atom.
+// We kept the amssymb atom type, which is rel.
+
+defineSymbol(math, ams, rel, "\u2235", "\\because", true);
+defineSymbol(math, ams, rel, "\u22D8", "\\llless");
+defineSymbol(math, ams, rel, "\u22D9", "\\gggtr");
+defineSymbol(math, ams, bin, "\u22B2", "\\lhd");
+defineSymbol(math, ams, bin, "\u22B3", "\\rhd");
+defineSymbol(math, ams, rel, "\u2242", "\\eqsim", true);
+defineSymbol(math, main, rel, "\u22C8", "\\Join");
+defineSymbol(math, ams, rel, "\u2251", "\\Doteq", true); // AMS Binary Operators
+
+defineSymbol(math, ams, bin, "\u2214", "\\dotplus", true);
+defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus");
+defineSymbol(math, ams, bin, "\u22D2", "\\Cap", true);
+defineSymbol(math, ams, bin, "\u22D3", "\\Cup", true);
+defineSymbol(math, ams, bin, "\u2A5E", "\\doublebarwedge", true);
+defineSymbol(math, ams, bin, "\u229F", "\\boxminus", true);
+defineSymbol(math, ams, bin, "\u229E", "\\boxplus", true);
+defineSymbol(math, ams, bin, "\u22C7", "\\divideontimes", true);
+defineSymbol(math, ams, bin, "\u22C9", "\\ltimes", true);
+defineSymbol(math, ams, bin, "\u22CA", "\\rtimes", true);
+defineSymbol(math, ams, bin, "\u22CB", "\\leftthreetimes", true);
+defineSymbol(math, ams, bin, "\u22CC", "\\rightthreetimes", true);
+defineSymbol(math, ams, bin, "\u22CF", "\\curlywedge", true);
+defineSymbol(math, ams, bin, "\u22CE", "\\curlyvee", true);
+defineSymbol(math, ams, bin, "\u229D", "\\circleddash", true);
+defineSymbol(math, ams, bin, "\u229B", "\\circledast", true);
+defineSymbol(math, ams, bin, "\u22C5", "\\centerdot");
+defineSymbol(math, ams, bin, "\u22BA", "\\intercal", true);
+defineSymbol(math, ams, bin, "\u22D2", "\\doublecap");
+defineSymbol(math, ams, bin, "\u22D3", "\\doublecup");
+defineSymbol(math, ams, bin, "\u22A0", "\\boxtimes", true); // AMS Arrows
+// Note: unicode-math maps \u21e2 to their own function \rightdasharrow.
+// We'll map it to AMS function \dashrightarrow. It produces the same atom.
+
+defineSymbol(math, ams, rel, "\u21E2", "\\dashrightarrow", true); // unicode-math maps \u21e0 to \leftdasharrow. We'll use the AMS synonym.
+
+defineSymbol(math, ams, rel, "\u21E0", "\\dashleftarrow", true);
+defineSymbol(math, ams, rel, "\u21C7", "\\leftleftarrows", true);
+defineSymbol(math, ams, rel, "\u21C6", "\\leftrightarrows", true);
+defineSymbol(math, ams, rel, "\u21DA", "\\Lleftarrow", true);
+defineSymbol(math, ams, rel, "\u219E", "\\twoheadleftarrow", true);
+defineSymbol(math, ams, rel, "\u21A2", "\\leftarrowtail", true);
+defineSymbol(math, ams, rel, "\u21AB", "\\looparrowleft", true);
+defineSymbol(math, ams, rel, "\u21CB", "\\leftrightharpoons", true);
+defineSymbol(math, ams, rel, "\u21B6", "\\curvearrowleft", true); // unicode-math maps \u21ba to \acwopencirclearrow. We'll use the AMS synonym.
+
+defineSymbol(math, ams, rel, "\u21BA", "\\circlearrowleft", true);
+defineSymbol(math, ams, rel, "\u21B0", "\\Lsh", true);
+defineSymbol(math, ams, rel, "\u21C8", "\\upuparrows", true);
+defineSymbol(math, ams, rel, "\u21BF", "\\upharpoonleft", true);
+defineSymbol(math, ams, rel, "\u21C3", "\\downharpoonleft", true);
+defineSymbol(math, main, rel, "\u22B6", "\\origof", true); // not in font
+
+defineSymbol(math, main, rel, "\u22B7", "\\imageof", true); // not in font
+
+defineSymbol(math, ams, rel, "\u22B8", "\\multimap", true);
+defineSymbol(math, ams, rel, "\u21AD", "\\leftrightsquigarrow", true);
+defineSymbol(math, ams, rel, "\u21C9", "\\rightrightarrows", true);
+defineSymbol(math, ams, rel, "\u21C4", "\\rightleftarrows", true);
+defineSymbol(math, ams, rel, "\u21A0", "\\twoheadrightarrow", true);
+defineSymbol(math, ams, rel, "\u21A3", "\\rightarrowtail", true);
+defineSymbol(math, ams, rel, "\u21AC", "\\looparrowright", true);
+defineSymbol(math, ams, rel, "\u21B7", "\\curvearrowright", true); // unicode-math maps \u21bb to \cwopencirclearrow. We'll use the AMS synonym.
+
+defineSymbol(math, ams, rel, "\u21BB", "\\circlearrowright", true);
+defineSymbol(math, ams, rel, "\u21B1", "\\Rsh", true);
+defineSymbol(math, ams, rel, "\u21CA", "\\downdownarrows", true);
+defineSymbol(math, ams, rel, "\u21BE", "\\upharpoonright", true);
+defineSymbol(math, ams, rel, "\u21C2", "\\downharpoonright", true);
+defineSymbol(math, ams, rel, "\u21DD", "\\rightsquigarrow", true);
+defineSymbol(math, ams, rel, "\u21DD", "\\leadsto");
+defineSymbol(math, ams, rel, "\u21DB", "\\Rrightarrow", true);
+defineSymbol(math, ams, rel, "\u21BE", "\\restriction");
+defineSymbol(math, main, textord, "\u2018", "`");
+defineSymbol(math, main, textord, "$", "\\$");
+defineSymbol(symbols_text, main, textord, "$", "\\$");
+defineSymbol(symbols_text, main, textord, "$", "\\textdollar");
+defineSymbol(math, main, textord, "%", "\\%");
+defineSymbol(symbols_text, main, textord, "%", "\\%");
+defineSymbol(math, main, textord, "_", "\\_");
+defineSymbol(symbols_text, main, textord, "_", "\\_");
+defineSymbol(symbols_text, main, textord, "_", "\\textunderscore");
+defineSymbol(math, main, textord, "\u2220", "\\angle", true);
+defineSymbol(math, main, textord, "\u221E", "\\infty", true);
+defineSymbol(math, main, textord, "\u2032", "\\prime");
+defineSymbol(math, main, textord, "\u25B3", "\\triangle");
+defineSymbol(math, main, textord, "\u0393", "\\Gamma", true);
+defineSymbol(math, main, textord, "\u0394", "\\Delta", true);
+defineSymbol(math, main, textord, "\u0398", "\\Theta", true);
+defineSymbol(math, main, textord, "\u039B", "\\Lambda", true);
+defineSymbol(math, main, textord, "\u039E", "\\Xi", true);
+defineSymbol(math, main, textord, "\u03A0", "\\Pi", true);
+defineSymbol(math, main, textord, "\u03A3", "\\Sigma", true);
+defineSymbol(math, main, textord, "\u03A5", "\\Upsilon", true);
+defineSymbol(math, main, textord, "\u03A6", "\\Phi", true);
+defineSymbol(math, main, textord, "\u03A8", "\\Psi", true);
+defineSymbol(math, main, textord, "\u03A9", "\\Omega", true);
+defineSymbol(math, main, textord, "A", "\u0391");
+defineSymbol(math, main, textord, "B", "\u0392");
+defineSymbol(math, main, textord, "E", "\u0395");
+defineSymbol(math, main, textord, "Z", "\u0396");
+defineSymbol(math, main, textord, "H", "\u0397");
+defineSymbol(math, main, textord, "I", "\u0399");
+defineSymbol(math, main, textord, "K", "\u039A");
+defineSymbol(math, main, textord, "M", "\u039C");
+defineSymbol(math, main, textord, "N", "\u039D");
+defineSymbol(math, main, textord, "O", "\u039F");
+defineSymbol(math, main, textord, "P", "\u03A1");
+defineSymbol(math, main, textord, "T", "\u03A4");
+defineSymbol(math, main, textord, "X", "\u03A7");
+defineSymbol(math, main, textord, "\xAC", "\\neg", true);
+defineSymbol(math, main, textord, "\xAC", "\\lnot");
+defineSymbol(math, main, textord, "\u22A4", "\\top");
+defineSymbol(math, main, textord, "\u22A5", "\\bot");
+defineSymbol(math, main, textord, "\u2205", "\\emptyset");
+defineSymbol(math, ams, textord, "\u2205", "\\varnothing");
+defineSymbol(math, main, mathord, "\u03B1", "\\alpha", true);
+defineSymbol(math, main, mathord, "\u03B2", "\\beta", true);
+defineSymbol(math, main, mathord, "\u03B3", "\\gamma", true);
+defineSymbol(math, main, mathord, "\u03B4", "\\delta", true);
+defineSymbol(math, main, mathord, "\u03F5", "\\epsilon", true);
+defineSymbol(math, main, mathord, "\u03B6", "\\zeta", true);
+defineSymbol(math, main, mathord, "\u03B7", "\\eta", true);
+defineSymbol(math, main, mathord, "\u03B8", "\\theta", true);
+defineSymbol(math, main, mathord, "\u03B9", "\\iota", true);
+defineSymbol(math, main, mathord, "\u03BA", "\\kappa", true);
+defineSymbol(math, main, mathord, "\u03BB", "\\lambda", true);
+defineSymbol(math, main, mathord, "\u03BC", "\\mu", true);
+defineSymbol(math, main, mathord, "\u03BD", "\\nu", true);
+defineSymbol(math, main, mathord, "\u03BE", "\\xi", true);
+defineSymbol(math, main, mathord, "\u03BF", "\\omicron", true);
+defineSymbol(math, main, mathord, "\u03C0", "\\pi", true);
+defineSymbol(math, main, mathord, "\u03C1", "\\rho", true);
+defineSymbol(math, main, mathord, "\u03C3", "\\sigma", true);
+defineSymbol(math, main, mathord, "\u03C4", "\\tau", true);
+defineSymbol(math, main, mathord, "\u03C5", "\\upsilon", true);
+defineSymbol(math, main, mathord, "\u03D5", "\\phi", true);
+defineSymbol(math, main, mathord, "\u03C7", "\\chi", true);
+defineSymbol(math, main, mathord, "\u03C8", "\\psi", true);
+defineSymbol(math, main, mathord, "\u03C9", "\\omega", true);
+defineSymbol(math, main, mathord, "\u03B5", "\\varepsilon", true);
+defineSymbol(math, main, mathord, "\u03D1", "\\vartheta", true);
+defineSymbol(math, main, mathord, "\u03D6", "\\varpi", true);
+defineSymbol(math, main, mathord, "\u03F1", "\\varrho", true);
+defineSymbol(math, main, mathord, "\u03C2", "\\varsigma", true);
+defineSymbol(math, main, mathord, "\u03C6", "\\varphi", true);
+defineSymbol(math, main, bin, "\u2217", "*", true);
+defineSymbol(math, main, bin, "+", "+");
+defineSymbol(math, main, bin, "\u2212", "-", true);
+defineSymbol(math, main, bin, "\u22C5", "\\cdot", true);
+defineSymbol(math, main, bin, "\u2218", "\\circ");
+defineSymbol(math, main, bin, "\xF7", "\\div", true);
+defineSymbol(math, main, bin, "\xB1", "\\pm", true);
+defineSymbol(math, main, bin, "\xD7", "\\times", true);
+defineSymbol(math, main, bin, "\u2229", "\\cap", true);
+defineSymbol(math, main, bin, "\u222A", "\\cup", true);
+defineSymbol(math, main, bin, "\u2216", "\\setminus");
+defineSymbol(math, main, bin, "\u2227", "\\land");
+defineSymbol(math, main, bin, "\u2228", "\\lor");
+defineSymbol(math, main, bin, "\u2227", "\\wedge", true);
+defineSymbol(math, main, bin, "\u2228", "\\vee", true);
+defineSymbol(math, main, textord, "\u221A", "\\surd");
+defineSymbol(math, main, symbols_open, "\u27E8", "\\langle", true);
+defineSymbol(math, main, symbols_open, "\u2223", "\\lvert");
+defineSymbol(math, main, symbols_open, "\u2225", "\\lVert");
+defineSymbol(math, main, symbols_close, "?", "?");
+defineSymbol(math, main, symbols_close, "!", "!");
+defineSymbol(math, main, symbols_close, "\u27E9", "\\rangle", true);
+defineSymbol(math, main, symbols_close, "\u2223", "\\rvert");
+defineSymbol(math, main, symbols_close, "\u2225", "\\rVert");
+defineSymbol(math, main, rel, "=", "=");
+defineSymbol(math, main, rel, ":", ":");
+defineSymbol(math, main, rel, "\u2248", "\\approx", true);
+defineSymbol(math, main, rel, "\u2245", "\\cong", true);
+defineSymbol(math, main, rel, "\u2265", "\\ge");
+defineSymbol(math, main, rel, "\u2265", "\\geq", true);
+defineSymbol(math, main, rel, "\u2190", "\\gets");
+defineSymbol(math, main, rel, ">", "\\gt", true);
+defineSymbol(math, main, rel, "\u2208", "\\in", true);
+defineSymbol(math, main, rel, "\uE020", "\\@not");
+defineSymbol(math, main, rel, "\u2282", "\\subset", true);
+defineSymbol(math, main, rel, "\u2283", "\\supset", true);
+defineSymbol(math, main, rel, "\u2286", "\\subseteq", true);
+defineSymbol(math, main, rel, "\u2287", "\\supseteq", true);
+defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq", true);
+defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq", true);
+defineSymbol(math, main, rel, "\u22A8", "\\models");
+defineSymbol(math, main, rel, "\u2190", "\\leftarrow", true);
+defineSymbol(math, main, rel, "\u2264", "\\le");
+defineSymbol(math, main, rel, "\u2264", "\\leq", true);
+defineSymbol(math, main, rel, "<", "\\lt", true);
+defineSymbol(math, main, rel, "\u2192", "\\rightarrow", true);
+defineSymbol(math, main, rel, "\u2192", "\\to");
+defineSymbol(math, ams, rel, "\u2271", "\\ngeq", true);
+defineSymbol(math, ams, rel, "\u2270", "\\nleq", true);
+defineSymbol(math, main, spacing, "\xA0", "\\ ");
+defineSymbol(math, main, spacing, "\xA0", "\\space"); // Ref: LaTeX Source 2e: \DeclareRobustCommand{\nobreakspace}{%
+
+defineSymbol(math, main, spacing, "\xA0", "\\nobreakspace");
+defineSymbol(symbols_text, main, spacing, "\xA0", "\\ ");
+defineSymbol(symbols_text, main, spacing, "\xA0", " ");
+defineSymbol(symbols_text, main, spacing, "\xA0", "\\space");
+defineSymbol(symbols_text, main, spacing, "\xA0", "\\nobreakspace");
+defineSymbol(math, main, spacing, null, "\\nobreak");
+defineSymbol(math, main, spacing, null, "\\allowbreak");
+defineSymbol(math, main, punct, ",", ",");
+defineSymbol(math, main, punct, ";", ";");
+defineSymbol(math, ams, bin, "\u22BC", "\\barwedge", true);
+defineSymbol(math, ams, bin, "\u22BB", "\\veebar", true);
+defineSymbol(math, main, bin, "\u2299", "\\odot", true);
+defineSymbol(math, main, bin, "\u2295", "\\oplus", true);
+defineSymbol(math, main, bin, "\u2297", "\\otimes", true);
+defineSymbol(math, main, textord, "\u2202", "\\partial", true);
+defineSymbol(math, main, bin, "\u2298", "\\oslash", true);
+defineSymbol(math, ams, bin, "\u229A", "\\circledcirc", true);
+defineSymbol(math, ams, bin, "\u22A1", "\\boxdot", true);
+defineSymbol(math, main, bin, "\u25B3", "\\bigtriangleup");
+defineSymbol(math, main, bin, "\u25BD", "\\bigtriangledown");
+defineSymbol(math, main, bin, "\u2020", "\\dagger");
+defineSymbol(math, main, bin, "\u22C4", "\\diamond");
+defineSymbol(math, main, bin, "\u22C6", "\\star");
+defineSymbol(math, main, bin, "\u25C3", "\\triangleleft");
+defineSymbol(math, main, bin, "\u25B9", "\\triangleright");
+defineSymbol(math, main, symbols_open, "{", "\\{");
+defineSymbol(symbols_text, main, textord, "{", "\\{");
+defineSymbol(symbols_text, main, textord, "{", "\\textbraceleft");
+defineSymbol(math, main, symbols_close, "}", "\\}");
+defineSymbol(symbols_text, main, textord, "}", "\\}");
+defineSymbol(symbols_text, main, textord, "}", "\\textbraceright");
+defineSymbol(math, main, symbols_open, "{", "\\lbrace");
+defineSymbol(math, main, symbols_close, "}", "\\rbrace");
+defineSymbol(math, main, symbols_open, "[", "\\lbrack", true);
+defineSymbol(symbols_text, main, textord, "[", "\\lbrack", true);
+defineSymbol(math, main, symbols_close, "]", "\\rbrack", true);
+defineSymbol(symbols_text, main, textord, "]", "\\rbrack", true);
+defineSymbol(math, main, symbols_open, "(", "\\lparen", true);
+defineSymbol(math, main, symbols_close, ")", "\\rparen", true);
+defineSymbol(symbols_text, main, textord, "<", "\\textless", true); // in T1 fontenc
+
+defineSymbol(symbols_text, main, textord, ">", "\\textgreater", true); // in T1 fontenc
+
+defineSymbol(math, main, symbols_open, "\u230A", "\\lfloor", true);
+defineSymbol(math, main, symbols_close, "\u230B", "\\rfloor", true);
+defineSymbol(math, main, symbols_open, "\u2308", "\\lceil", true);
+defineSymbol(math, main, symbols_close, "\u2309", "\\rceil", true);
+defineSymbol(math, main, textord, "\\", "\\backslash");
+defineSymbol(math, main, textord, "\u2223", "|");
+defineSymbol(math, main, textord, "\u2223", "\\vert");
+defineSymbol(symbols_text, main, textord, "|", "\\textbar", true); // in T1 fontenc
+
+defineSymbol(math, main, textord, "\u2225", "\\|");
+defineSymbol(math, main, textord, "\u2225", "\\Vert");
+defineSymbol(symbols_text, main, textord, "\u2225", "\\textbardbl");
+defineSymbol(symbols_text, main, textord, "~", "\\textasciitilde");
+defineSymbol(symbols_text, main, textord, "\\", "\\textbackslash");
+defineSymbol(symbols_text, main, textord, "^", "\\textasciicircum");
+defineSymbol(math, main, rel, "\u2191", "\\uparrow", true);
+defineSymbol(math, main, rel, "\u21D1", "\\Uparrow", true);
+defineSymbol(math, main, rel, "\u2193", "\\downarrow", true);
+defineSymbol(math, main, rel, "\u21D3", "\\Downarrow", true);
+defineSymbol(math, main, rel, "\u2195", "\\updownarrow", true);
+defineSymbol(math, main, rel, "\u21D5", "\\Updownarrow", true);
+defineSymbol(math, main, op, "\u2210", "\\coprod");
+defineSymbol(math, main, op, "\u22C1", "\\bigvee");
+defineSymbol(math, main, op, "\u22C0", "\\bigwedge");
+defineSymbol(math, main, op, "\u2A04", "\\biguplus");
+defineSymbol(math, main, op, "\u22C2", "\\bigcap");
+defineSymbol(math, main, op, "\u22C3", "\\bigcup");
+defineSymbol(math, main, op, "\u222B", "\\int");
+defineSymbol(math, main, op, "\u222B", "\\intop");
+defineSymbol(math, main, op, "\u222C", "\\iint");
+defineSymbol(math, main, op, "\u222D", "\\iiint");
+defineSymbol(math, main, op, "\u220F", "\\prod");
+defineSymbol(math, main, op, "\u2211", "\\sum");
+defineSymbol(math, main, op, "\u2A02", "\\bigotimes");
+defineSymbol(math, main, op, "\u2A01", "\\bigoplus");
+defineSymbol(math, main, op, "\u2A00", "\\bigodot");
+defineSymbol(math, main, op, "\u222E", "\\oint");
+defineSymbol(math, main, op, "\u222F", "\\oiint");
+defineSymbol(math, main, op, "\u2230", "\\oiiint");
+defineSymbol(math, main, op, "\u2A06", "\\bigsqcup");
+defineSymbol(math, main, op, "\u222B", "\\smallint");
+defineSymbol(symbols_text, main, inner, "\u2026", "\\textellipsis");
+defineSymbol(math, main, inner, "\u2026", "\\mathellipsis");
+defineSymbol(symbols_text, main, inner, "\u2026", "\\ldots", true);
+defineSymbol(math, main, inner, "\u2026", "\\ldots", true);
+defineSymbol(math, main, inner, "\u22EF", "\\@cdots", true);
+defineSymbol(math, main, inner, "\u22F1", "\\ddots", true);
+defineSymbol(math, main, textord, "\u22EE", "\\varvdots"); // \vdots is a macro
+
+defineSymbol(math, main, accent, "\u02CA", "\\acute");
+defineSymbol(math, main, accent, "\u02CB", "\\grave");
+defineSymbol(math, main, accent, "\xA8", "\\ddot");
+defineSymbol(math, main, accent, "~", "\\tilde");
+defineSymbol(math, main, accent, "\u02C9", "\\bar");
+defineSymbol(math, main, accent, "\u02D8", "\\breve");
+defineSymbol(math, main, accent, "\u02C7", "\\check");
+defineSymbol(math, main, accent, "^", "\\hat");
+defineSymbol(math, main, accent, "\u20D7", "\\vec");
+defineSymbol(math, main, accent, "\u02D9", "\\dot");
+defineSymbol(math, main, accent, "\u02DA", "\\mathring"); // \imath and \jmath should be invariant to \mathrm, \mathbf, etc., so use PUA
+
+defineSymbol(math, main, mathord, "\uE131", "\\@imath");
+defineSymbol(math, main, mathord, "\uE237", "\\@jmath");
+defineSymbol(math, main, textord, "\u0131", "\u0131");
+defineSymbol(math, main, textord, "\u0237", "\u0237");
+defineSymbol(symbols_text, main, textord, "\u0131", "\\i", true);
+defineSymbol(symbols_text, main, textord, "\u0237", "\\j", true);
+defineSymbol(symbols_text, main, textord, "\xDF", "\\ss", true);
+defineSymbol(symbols_text, main, textord, "\xE6", "\\ae", true);
+defineSymbol(symbols_text, main, textord, "\u0153", "\\oe", true);
+defineSymbol(symbols_text, main, textord, "\xF8", "\\o", true);
+defineSymbol(symbols_text, main, textord, "\xC6", "\\AE", true);
+defineSymbol(symbols_text, main, textord, "\u0152", "\\OE", true);
+defineSymbol(symbols_text, main, textord, "\xD8", "\\O", true);
+defineSymbol(symbols_text, main, accent, "\u02CA", "\\'"); // acute
+
+defineSymbol(symbols_text, main, accent, "\u02CB", "\\`"); // grave
+
+defineSymbol(symbols_text, main, accent, "\u02C6", "\\^"); // circumflex
+
+defineSymbol(symbols_text, main, accent, "\u02DC", "\\~"); // tilde
+
+defineSymbol(symbols_text, main, accent, "\u02C9", "\\="); // macron
+
+defineSymbol(symbols_text, main, accent, "\u02D8", "\\u"); // breve
+
+defineSymbol(symbols_text, main, accent, "\u02D9", "\\."); // dot above
+
+defineSymbol(symbols_text, main, accent, "\xB8", "\\c"); // cedilla
+
+defineSymbol(symbols_text, main, accent, "\u02DA", "\\r"); // ring above
+
+defineSymbol(symbols_text, main, accent, "\u02C7", "\\v"); // caron
+
+defineSymbol(symbols_text, main, accent, "\xA8", '\\"'); // diaresis
+
+defineSymbol(symbols_text, main, accent, "\u02DD", "\\H"); // double acute
+
+defineSymbol(symbols_text, main, accent, "\u25EF", "\\textcircled"); // \bigcirc glyph
+// These ligatures are detected and created in Parser.js's `formLigatures`.
+
+var ligatures = {
+ "--": true,
+ "---": true,
+ "``": true,
+ "''": true
+};
+defineSymbol(symbols_text, main, textord, "\u2013", "--", true);
+defineSymbol(symbols_text, main, textord, "\u2013", "\\textendash");
+defineSymbol(symbols_text, main, textord, "\u2014", "---", true);
+defineSymbol(symbols_text, main, textord, "\u2014", "\\textemdash");
+defineSymbol(symbols_text, main, textord, "\u2018", "`", true);
+defineSymbol(symbols_text, main, textord, "\u2018", "\\textquoteleft");
+defineSymbol(symbols_text, main, textord, "\u2019", "'", true);
+defineSymbol(symbols_text, main, textord, "\u2019", "\\textquoteright");
+defineSymbol(symbols_text, main, textord, "\u201C", "``", true);
+defineSymbol(symbols_text, main, textord, "\u201C", "\\textquotedblleft");
+defineSymbol(symbols_text, main, textord, "\u201D", "''", true);
+defineSymbol(symbols_text, main, textord, "\u201D", "\\textquotedblright"); // \degree from gensymb package
+
+defineSymbol(math, main, textord, "\xB0", "\\degree", true);
+defineSymbol(symbols_text, main, textord, "\xB0", "\\degree"); // \textdegree from inputenc package
+
+defineSymbol(symbols_text, main, textord, "\xB0", "\\textdegree", true); // TODO: In LaTeX, \pounds can generate a different character in text and math
+// mode, but among our fonts, only Main-Regular defines this character "163".
+
+defineSymbol(math, main, textord, "\xA3", "\\pounds");
+defineSymbol(math, main, textord, "\xA3", "\\mathsterling", true);
+defineSymbol(symbols_text, main, textord, "\xA3", "\\pounds");
+defineSymbol(symbols_text, main, textord, "\xA3", "\\textsterling", true);
+defineSymbol(math, ams, textord, "\u2720", "\\maltese");
+defineSymbol(symbols_text, ams, textord, "\u2720", "\\maltese"); // There are lots of symbols which are the same, so we add them in afterwards.
+// All of these are textords in math mode
+
+var mathTextSymbols = "0123456789/@.\"";
+
+for (var i = 0; i < mathTextSymbols.length; i++) {
+ var ch = mathTextSymbols.charAt(i);
+ defineSymbol(math, main, textord, ch, ch);
+} // All of these are textords in text mode
+
+
+var textSymbols = "0123456789!@*()-=+\";:?/.,";
+
+for (var _i = 0; _i < textSymbols.length; _i++) {
+ var _ch = textSymbols.charAt(_i);
+
+ defineSymbol(symbols_text, main, textord, _ch, _ch);
+} // All of these are textords in text mode, and mathords in math mode
+
+
+var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+for (var _i2 = 0; _i2 < letters.length; _i2++) {
+ var _ch2 = letters.charAt(_i2);
+
+ defineSymbol(math, main, mathord, _ch2, _ch2);
+ defineSymbol(symbols_text, main, textord, _ch2, _ch2);
+} // Blackboard bold and script letters in Unicode range
+
+
+defineSymbol(math, ams, textord, "C", "\u2102"); // blackboard bold
+
+defineSymbol(symbols_text, ams, textord, "C", "\u2102");
+defineSymbol(math, ams, textord, "H", "\u210D");
+defineSymbol(symbols_text, ams, textord, "H", "\u210D");
+defineSymbol(math, ams, textord, "N", "\u2115");
+defineSymbol(symbols_text, ams, textord, "N", "\u2115");
+defineSymbol(math, ams, textord, "P", "\u2119");
+defineSymbol(symbols_text, ams, textord, "P", "\u2119");
+defineSymbol(math, ams, textord, "Q", "\u211A");
+defineSymbol(symbols_text, ams, textord, "Q", "\u211A");
+defineSymbol(math, ams, textord, "R", "\u211D");
+defineSymbol(symbols_text, ams, textord, "R", "\u211D");
+defineSymbol(math, ams, textord, "Z", "\u2124");
+defineSymbol(symbols_text, ams, textord, "Z", "\u2124");
+defineSymbol(math, main, mathord, "h", "\u210E"); // italic h, Planck constant
+
+defineSymbol(symbols_text, main, mathord, "h", "\u210E"); // The next loop loads wide (surrogate pair) characters.
+// We support some letters in the Unicode range U+1D400 to U+1D7FF,
+// Mathematical Alphanumeric Symbols.
+// Some editors do not deal well with wide characters. So don't write the
+// string into this file. Instead, create the string from the surrogate pair.
+
+var wideChar = "";
+
+for (var _i3 = 0; _i3 < letters.length; _i3++) {
+ var _ch3 = letters.charAt(_i3); // The hex numbers in the next line are a surrogate pair.
+ // 0xD835 is the high surrogate for all letters in the range we support.
+ // 0xDC00 is the low surrogate for bold A.
+
+
+ wideChar = String.fromCharCode(0xD835, 0xDC00 + _i3); // A-Z a-z bold
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDC34 + _i3); // A-Z a-z italic
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDC68 + _i3); // A-Z a-z bold italic
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDD04 + _i3); // A-Z a-z Fractur
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDDA0 + _i3); // A-Z a-z sans-serif
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDDD4 + _i3); // A-Z a-z sans bold
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDE08 + _i3); // A-Z a-z sans italic
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDE70 + _i3); // A-Z a-z monospace
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+
+ if (_i3 < 26) {
+ // KaTeX fonts have only capital letters for blackboard bold and script.
+ // See exception for k below.
+ wideChar = String.fromCharCode(0xD835, 0xDD38 + _i3); // A-Z double struck
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDC9C + _i3); // A-Z script
+
+ defineSymbol(math, main, mathord, _ch3, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch3, wideChar);
+ } // TODO: Add bold script when it is supported by a KaTeX font.
+
+} // "k" is the only double struck lower case letter in the KaTeX fonts.
+
+
+wideChar = String.fromCharCode(0xD835, 0xDD5C); // k double struck
+
+defineSymbol(math, main, mathord, "k", wideChar);
+defineSymbol(symbols_text, main, textord, "k", wideChar); // Next, some wide character numerals
+
+for (var _i4 = 0; _i4 < 10; _i4++) {
+ var _ch4 = _i4.toString();
+
+ wideChar = String.fromCharCode(0xD835, 0xDFCE + _i4); // 0-9 bold
+
+ defineSymbol(math, main, mathord, _ch4, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch4, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDFE2 + _i4); // 0-9 sans serif
+
+ defineSymbol(math, main, mathord, _ch4, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch4, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDFEC + _i4); // 0-9 bold sans
+
+ defineSymbol(math, main, mathord, _ch4, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch4, wideChar);
+ wideChar = String.fromCharCode(0xD835, 0xDFF6 + _i4); // 0-9 monospace
+
+ defineSymbol(math, main, mathord, _ch4, wideChar);
+ defineSymbol(symbols_text, main, textord, _ch4, wideChar);
+} // We add these Latin-1 letters as symbols for backwards-compatibility,
+// but they are not actually in the font, nor are they supported by the
+// Unicode accent mechanism, so they fall back to Times font and look ugly.
+// TODO(edemaine): Fix this.
+
+
+var extraLatin = "\xD0\xDE\xFE";
+
+for (var _i5 = 0; _i5 < extraLatin.length; _i5++) {
+ var _ch5 = extraLatin.charAt(_i5);
+
+ defineSymbol(math, main, mathord, _ch5, _ch5);
+ defineSymbol(symbols_text, main, textord, _ch5, _ch5);
+}
+;// CONCATENATED MODULE: ./src/wide-character.js
+/**
+ * This file provides support for Unicode range U+1D400 to U+1D7FF,
+ * Mathematical Alphanumeric Symbols.
+ *
+ * Function wideCharacterFont takes a wide character as input and returns
+ * the font information necessary to render it properly.
+ */
+
+/**
+ * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf
+ * That document sorts characters into groups by font type, say bold or italic.
+ *
+ * In the arrays below, each subarray consists three elements:
+ * * The CSS class of that group when in math mode.
+ * * The CSS class of that group when in text mode.
+ * * The font name, so that KaTeX can get font metrics.
+ */
+
+var wideLatinLetterData = [["mathbf", "textbf", "Main-Bold"], // A-Z bold upright
+["mathbf", "textbf", "Main-Bold"], // a-z bold upright
+["mathnormal", "textit", "Math-Italic"], // A-Z italic
+["mathnormal", "textit", "Math-Italic"], // a-z italic
+["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic
+["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic
+// Map fancy A-Z letters to script, not calligraphic.
+// This aligns with unicode-math and math fonts (except Cambria Math).
+["mathscr", "textscr", "Script-Regular"], // A-Z script
+["", "", ""], // a-z script. No font
+["", "", ""], // A-Z bold script. No font
+["", "", ""], // a-z bold script. No font
+["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur
+["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur
+["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck
+["mathbb", "textbb", "AMS-Regular"], // k double-struck
+["", "", ""], // A-Z bold Fraktur No font metrics
+["", "", ""], // a-z bold Fraktur. No font.
+["mathsf", "textsf", "SansSerif-Regular"], // A-Z sans-serif
+["mathsf", "textsf", "SansSerif-Regular"], // a-z sans-serif
+["mathboldsf", "textboldsf", "SansSerif-Bold"], // A-Z bold sans-serif
+["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif
+["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif
+["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif
+["", "", ""], // A-Z bold italic sans. No font
+["", "", ""], // a-z bold italic sans. No font
+["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace
+["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace
+];
+var wideNumeralData = [["mathbf", "textbf", "Main-Bold"], // 0-9 bold
+["", "", ""], // 0-9 double-struck. No KaTeX font.
+["mathsf", "textsf", "SansSerif-Regular"], // 0-9 sans-serif
+["mathboldsf", "textboldsf", "SansSerif-Bold"], // 0-9 bold sans-serif
+["mathtt", "texttt", "Typewriter-Regular"] // 0-9 monospace
+];
+var wideCharacterFont = function wideCharacterFont(wideChar, mode) {
+ // IE doesn't support codePointAt(). So work with the surrogate pair.
+ var H = wideChar.charCodeAt(0); // high surrogate
+
+ var L = wideChar.charCodeAt(1); // low surrogate
+
+ var codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000;
+ var j = mode === "math" ? 0 : 1; // column index for CSS class.
+
+ if (0x1D400 <= codePoint && codePoint < 0x1D6A4) {
+ // wideLatinLetterData contains exactly 26 chars on each row.
+ // So we can calculate the relevant row. No traverse necessary.
+ var i = Math.floor((codePoint - 0x1D400) / 26);
+ return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]];
+ } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) {
+ // Numerals, ten per row.
+ var _i = Math.floor((codePoint - 0x1D7CE) / 10);
+
+ return [wideNumeralData[_i][2], wideNumeralData[_i][j]];
+ } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) {
+ // dotless i or j
+ return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]];
+ } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) {
+ // Greek letters. Not supported, yet.
+ return ["", ""];
+ } else {
+ // We don't support any wide characters outside 1D400–1D7FF.
+ throw new src_ParseError("Unsupported character: " + wideChar);
+ }
+};
+;// CONCATENATED MODULE: ./src/buildCommon.js
+/* eslint no-console:0 */
+
+/**
+ * This module contains general functions that can be used for building
+ * different kinds of domTree nodes in a consistent manner.
+ */
+
+
+
+
+
+
+
+/**
+ * Looks up the given symbol in fontMetrics, after applying any symbol
+ * replacements defined in symbol.js
+ */
+var lookupSymbol = function lookupSymbol(value, // TODO(#963): Use a union type for this.
+fontName, mode) {
+ // Replace the value with its replaced value from symbol.js
+ if (src_symbols[mode][value] && src_symbols[mode][value].replace) {
+ value = src_symbols[mode][value].replace;
+ }
+
+ return {
+ value: value,
+ metrics: getCharacterMetrics(value, fontName, mode)
+ };
+};
+/**
+ * Makes a symbolNode after translation via the list of symbols in symbols.js.
+ * Correctly pulls out metrics for the character, and optionally takes a list of
+ * classes to be attached to the node.
+ *
+ * TODO: make argument order closer to makeSpan
+ * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which
+ * should if present come first in `classes`.
+ * TODO(#953): Make `options` mandatory and always pass it in.
+ */
+
+
+var makeSymbol = function makeSymbol(value, fontName, mode, options, classes) {
+ var lookup = lookupSymbol(value, fontName, mode);
+ var metrics = lookup.metrics;
+ value = lookup.value;
+ var symbolNode;
+
+ if (metrics) {
+ var italic = metrics.italic;
+
+ if (mode === "text" || options && options.font === "mathit") {
+ italic = 0;
+ }
+
+ symbolNode = new SymbolNode(value, metrics.height, metrics.depth, italic, metrics.skew, metrics.width, classes);
+ } else {
+ // TODO(emily): Figure out a good way to only print this in development
+ typeof console !== "undefined" && console.warn("No character metrics " + ("for '" + value + "' in style '" + fontName + "' and mode '" + mode + "'"));
+ symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes);
+ }
+
+ if (options) {
+ symbolNode.maxFontSize = options.sizeMultiplier;
+
+ if (options.style.isTight()) {
+ symbolNode.classes.push("mtight");
+ }
+
+ var color = options.getColor();
+
+ if (color) {
+ symbolNode.style.color = color;
+ }
+ }
+
+ return symbolNode;
+};
+/**
+ * Makes a symbol in Main-Regular or AMS-Regular.
+ * Used for rel, bin, open, close, inner, and punct.
+ */
+
+
+var mathsym = function mathsym(value, mode, options, classes) {
+ if (classes === void 0) {
+ classes = [];
+ }
+
+ // Decide what font to render the symbol in by its entry in the symbols
+ // table.
+ // Have a special case for when the value = \ because the \ is used as a
+ // textord in unsupported command errors but cannot be parsed as a regular
+ // text ordinal and is therefore not present as a symbol in the symbols
+ // table for text, as well as a special case for boldsymbol because it
+ // can be used for bold + and -
+ if (options.font === "boldsymbol" && lookupSymbol(value, "Main-Bold", mode).metrics) {
+ return makeSymbol(value, "Main-Bold", mode, options, classes.concat(["mathbf"]));
+ } else if (value === "\\" || src_symbols[mode][value].font === "main") {
+ return makeSymbol(value, "Main-Regular", mode, options, classes);
+ } else {
+ return makeSymbol(value, "AMS-Regular", mode, options, classes.concat(["amsrm"]));
+ }
+};
+/**
+ * Determines which of the two font names (Main-Bold and Math-BoldItalic) and
+ * corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol",
+ * depending on the symbol. Use this function instead of fontMap for font
+ * "boldsymbol".
+ */
+
+
+var boldsymbol = function boldsymbol(value, mode, options, classes, type) {
+ if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
+ return {
+ fontName: "Math-BoldItalic",
+ fontClass: "boldsymbol"
+ };
+ } else {
+ // Some glyphs do not exist in Math-BoldItalic so we need to use
+ // Main-Bold instead.
+ return {
+ fontName: "Main-Bold",
+ fontClass: "mathbf"
+ };
+ }
+};
+/**
+ * Makes either a mathord or textord in the correct font and color.
+ */
+
+
+var makeOrd = function makeOrd(group, options, type) {
+ var mode = group.mode;
+ var text = group.text;
+ var classes = ["mord"]; // Math mode or Old font (i.e. \rm)
+
+ var isFont = mode === "math" || mode === "text" && options.font;
+ var fontOrFamily = isFont ? options.font : options.fontFamily;
+
+ if (text.charCodeAt(0) === 0xD835) {
+ // surrogate pairs get special treatment
+ var _wideCharacterFont = wideCharacterFont(text, mode),
+ wideFontName = _wideCharacterFont[0],
+ wideFontClass = _wideCharacterFont[1];
+
+ return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass));
+ } else if (fontOrFamily) {
+ var fontName;
+ var fontClasses;
+
+ if (fontOrFamily === "boldsymbol") {
+ var fontData = boldsymbol(text, mode, options, classes, type);
+ fontName = fontData.fontName;
+ fontClasses = [fontData.fontClass];
+ } else if (isFont) {
+ fontName = fontMap[fontOrFamily].fontName;
+ fontClasses = [fontOrFamily];
+ } else {
+ fontName = retrieveTextFontName(fontOrFamily, options.fontWeight, options.fontShape);
+ fontClasses = [fontOrFamily, options.fontWeight, options.fontShape];
+ }
+
+ if (lookupSymbol(text, fontName, mode).metrics) {
+ return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses));
+ } else if (ligatures.hasOwnProperty(text) && fontName.substr(0, 10) === "Typewriter") {
+ // Deconstruct ligatures in monospace fonts (\texttt, \tt).
+ var parts = [];
+
+ for (var i = 0; i < text.length; i++) {
+ parts.push(makeSymbol(text[i], fontName, mode, options, classes.concat(fontClasses)));
+ }
+
+ return makeFragment(parts);
+ }
+ } // Makes a symbol in the default font for mathords and textords.
+
+
+ if (type === "mathord") {
+ return makeSymbol(text, "Math-Italic", mode, options, classes.concat(["mathnormal"]));
+ } else if (type === "textord") {
+ var font = src_symbols[mode][text] && src_symbols[mode][text].font;
+
+ if (font === "ams") {
+ var _fontName = retrieveTextFontName("amsrm", options.fontWeight, options.fontShape);
+
+ return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", options.fontWeight, options.fontShape));
+ } else if (font === "main" || !font) {
+ var _fontName2 = retrieveTextFontName("textrm", options.fontWeight, options.fontShape);
+
+ return makeSymbol(text, _fontName2, mode, options, classes.concat(options.fontWeight, options.fontShape));
+ } else {
+ // fonts added by plugins
+ var _fontName3 = retrieveTextFontName(font, options.fontWeight, options.fontShape); // We add font name as a css class
+
+
+ return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, options.fontWeight, options.fontShape));
+ }
+ } else {
+ throw new Error("unexpected type: " + type + " in makeOrd");
+ }
+};
+/**
+ * Returns true if subsequent symbolNodes have the same classes, skew, maxFont,
+ * and styles.
+ */
+
+
+var canCombine = function canCombine(prev, next) {
+ if (createClass(prev.classes) !== createClass(next.classes) || prev.skew !== next.skew || prev.maxFontSize !== next.maxFontSize) {
+ return false;
+ } // If prev and next both are just "mbin"s or "mord"s we don't combine them
+ // so that the proper spacing can be preserved.
+
+
+ if (prev.classes.length === 1) {
+ var cls = prev.classes[0];
+
+ if (cls === "mbin" || cls === "mord") {
+ return false;
+ }
+ }
+
+ for (var style in prev.style) {
+ if (prev.style.hasOwnProperty(style) && prev.style[style] !== next.style[style]) {
+ return false;
+ }
+ }
+
+ for (var _style in next.style) {
+ if (next.style.hasOwnProperty(_style) && prev.style[_style] !== next.style[_style]) {
+ return false;
+ }
+ }
+
+ return true;
+};
+/**
+ * Combine consecutive domTree.symbolNodes into a single symbolNode.
+ * Note: this function mutates the argument.
+ */
+
+
+var tryCombineChars = function tryCombineChars(chars) {
+ for (var i = 0; i < chars.length - 1; i++) {
+ var prev = chars[i];
+ var next = chars[i + 1];
+
+ if (prev instanceof SymbolNode && next instanceof SymbolNode && canCombine(prev, next)) {
+ prev.text += next.text;
+ prev.height = Math.max(prev.height, next.height);
+ prev.depth = Math.max(prev.depth, next.depth); // Use the last character's italic correction since we use
+ // it to add padding to the right of the span created from
+ // the combined characters.
+
+ prev.italic = next.italic;
+ chars.splice(i + 1, 1);
+ i--;
+ }
+ }
+
+ return chars;
+};
+/**
+ * Calculate the height, depth, and maxFontSize of an element based on its
+ * children.
+ */
+
+
+var sizeElementFromChildren = function sizeElementFromChildren(elem) {
+ var height = 0;
+ var depth = 0;
+ var maxFontSize = 0;
+
+ for (var i = 0; i < elem.children.length; i++) {
+ var child = elem.children[i];
+
+ if (child.height > height) {
+ height = child.height;
+ }
+
+ if (child.depth > depth) {
+ depth = child.depth;
+ }
+
+ if (child.maxFontSize > maxFontSize) {
+ maxFontSize = child.maxFontSize;
+ }
+ }
+
+ elem.height = height;
+ elem.depth = depth;
+ elem.maxFontSize = maxFontSize;
+};
+/**
+ * Makes a span with the given list of classes, list of children, and options.
+ *
+ * TODO(#953): Ensure that `options` is always provided (currently some call
+ * sites don't pass it) and make the type below mandatory.
+ * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which
+ * should if present come first in `classes`.
+ */
+
+
+var makeSpan = function makeSpan(classes, children, options, style) {
+ var span = new Span(classes, children, options, style);
+ sizeElementFromChildren(span);
+ return span;
+}; // SVG one is simpler -- doesn't require height, depth, max-font setting.
+// This is also a separate method for typesafety.
+
+
+var makeSvgSpan = function makeSvgSpan(classes, children, options, style) {
+ return new Span(classes, children, options, style);
+};
+
+var makeLineSpan = function makeLineSpan(className, options, thickness) {
+ var line = makeSpan([className], [], options);
+ line.height = Math.max(thickness || options.fontMetrics().defaultRuleThickness, options.minRuleThickness);
+ line.style.borderBottomWidth = makeEm(line.height);
+ line.maxFontSize = 1.0;
+ return line;
+};
+/**
+ * Makes an anchor with the given href, list of classes, list of children,
+ * and options.
+ */
+
+
+var makeAnchor = function makeAnchor(href, classes, children, options) {
+ var anchor = new Anchor(href, classes, children, options);
+ sizeElementFromChildren(anchor);
+ return anchor;
+};
+/**
+ * Makes a document fragment with the given list of children.
+ */
+
+
+var makeFragment = function makeFragment(children) {
+ var fragment = new DocumentFragment(children);
+ sizeElementFromChildren(fragment);
+ return fragment;
+};
+/**
+ * Wraps group in a span if it's a document fragment, allowing to apply classes
+ * and styles
+ */
+
+
+var wrapFragment = function wrapFragment(group, options) {
+ if (group instanceof DocumentFragment) {
+ return makeSpan([], [group], options);
+ }
+
+ return group;
+}; // These are exact object types to catch typos in the names of the optional fields.
+
+
+// Computes the updated `children` list and the overall depth.
+//
+// This helper function for makeVList makes it easier to enforce type safety by
+// allowing early exits (returns) in the logic.
+var getVListChildrenAndDepth = function getVListChildrenAndDepth(params) {
+ if (params.positionType === "individualShift") {
+ var oldChildren = params.children;
+ var children = [oldChildren[0]]; // Add in kerns to the list of params.children to get each element to be
+ // shifted to the correct specified shift
+
+ var _depth = -oldChildren[0].shift - oldChildren[0].elem.depth;
+
+ var currPos = _depth;
+
+ for (var i = 1; i < oldChildren.length; i++) {
+ var diff = -oldChildren[i].shift - currPos - oldChildren[i].elem.depth;
+ var size = diff - (oldChildren[i - 1].elem.height + oldChildren[i - 1].elem.depth);
+ currPos = currPos + diff;
+ children.push({
+ type: "kern",
+ size: size
+ });
+ children.push(oldChildren[i]);
+ }
+
+ return {
+ children: children,
+ depth: _depth
+ };
+ }
+
+ var depth;
+
+ if (params.positionType === "top") {
+ // We always start at the bottom, so calculate the bottom by adding up
+ // all the sizes
+ var bottom = params.positionData;
+
+ for (var _i = 0; _i < params.children.length; _i++) {
+ var child = params.children[_i];
+ bottom -= child.type === "kern" ? child.size : child.elem.height + child.elem.depth;
+ }
+
+ depth = bottom;
+ } else if (params.positionType === "bottom") {
+ depth = -params.positionData;
+ } else {
+ var firstChild = params.children[0];
+
+ if (firstChild.type !== "elem") {
+ throw new Error('First child must have type "elem".');
+ }
+
+ if (params.positionType === "shift") {
+ depth = -firstChild.elem.depth - params.positionData;
+ } else if (params.positionType === "firstBaseline") {
+ depth = -firstChild.elem.depth;
+ } else {
+ throw new Error("Invalid positionType " + params.positionType + ".");
+ }
+ }
+
+ return {
+ children: params.children,
+ depth: depth
+ };
+};
+/**
+ * Makes a vertical list by stacking elements and kerns on top of each other.
+ * Allows for many different ways of specifying the positioning method.
+ *
+ * See VListParam documentation above.
+ */
+
+
+var makeVList = function makeVList(params, options) {
+ var _getVListChildrenAndD = getVListChildrenAndDepth(params),
+ children = _getVListChildrenAndD.children,
+ depth = _getVListChildrenAndD.depth; // Create a strut that is taller than any list item. The strut is added to
+ // each item, where it will determine the item's baseline. Since it has
+ // `overflow:hidden`, the strut's top edge will sit on the item's line box's
+ // top edge and the strut's bottom edge will sit on the item's baseline,
+ // with no additional line-height spacing. This allows the item baseline to
+ // be positioned precisely without worrying about font ascent and
+ // line-height.
+
+
+ var pstrutSize = 0;
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+
+ if (child.type === "elem") {
+ var elem = child.elem;
+ pstrutSize = Math.max(pstrutSize, elem.maxFontSize, elem.height);
+ }
+ }
+
+ pstrutSize += 2;
+ var pstrut = makeSpan(["pstrut"], []);
+ pstrut.style.height = makeEm(pstrutSize); // Create a new list of actual children at the correct offsets
+
+ var realChildren = [];
+ var minPos = depth;
+ var maxPos = depth;
+ var currPos = depth;
+
+ for (var _i2 = 0; _i2 < children.length; _i2++) {
+ var _child = children[_i2];
+
+ if (_child.type === "kern") {
+ currPos += _child.size;
+ } else {
+ var _elem = _child.elem;
+ var classes = _child.wrapperClasses || [];
+ var style = _child.wrapperStyle || {};
+ var childWrap = makeSpan(classes, [pstrut, _elem], undefined, style);
+ childWrap.style.top = makeEm(-pstrutSize - currPos - _elem.depth);
+
+ if (_child.marginLeft) {
+ childWrap.style.marginLeft = _child.marginLeft;
+ }
+
+ if (_child.marginRight) {
+ childWrap.style.marginRight = _child.marginRight;
+ }
+
+ realChildren.push(childWrap);
+ currPos += _elem.height + _elem.depth;
+ }
+
+ minPos = Math.min(minPos, currPos);
+ maxPos = Math.max(maxPos, currPos);
+ } // The vlist contents go in a table-cell with `vertical-align:bottom`.
+ // This cell's bottom edge will determine the containing table's baseline
+ // without overly expanding the containing line-box.
+
+
+ var vlist = makeSpan(["vlist"], realChildren);
+ vlist.style.height = makeEm(maxPos); // A second row is used if necessary to represent the vlist's depth.
+
+ var rows;
+
+ if (minPos < 0) {
+ // We will define depth in an empty span with display: table-cell.
+ // It should render with the height that we define. But Chrome, in
+ // contenteditable mode only, treats that span as if it contains some
+ // text content. And that min-height over-rides our desired height.
+ // So we put another empty span inside the depth strut span.
+ var emptySpan = makeSpan([], []);
+ var depthStrut = makeSpan(["vlist"], [emptySpan]);
+ depthStrut.style.height = makeEm(-minPos); // Safari wants the first row to have inline content; otherwise it
+ // puts the bottom of the *second* row on the baseline.
+
+ var topStrut = makeSpan(["vlist-s"], [new SymbolNode("\u200B")]);
+ rows = [makeSpan(["vlist-r"], [vlist, topStrut]), makeSpan(["vlist-r"], [depthStrut])];
+ } else {
+ rows = [makeSpan(["vlist-r"], [vlist])];
+ }
+
+ var vtable = makeSpan(["vlist-t"], rows);
+
+ if (rows.length === 2) {
+ vtable.classes.push("vlist-t2");
+ }
+
+ vtable.height = maxPos;
+ vtable.depth = -minPos;
+ return vtable;
+}; // Glue is a concept from TeX which is a flexible space between elements in
+// either a vertical or horizontal list. In KaTeX, at least for now, it's
+// static space between elements in a horizontal layout.
+
+
+var makeGlue = function makeGlue(measurement, options) {
+ // Make an empty span for the space
+ var rule = makeSpan(["mspace"], [], options);
+ var size = calculateSize(measurement, options);
+ rule.style.marginRight = makeEm(size);
+ return rule;
+}; // Takes font options, and returns the appropriate fontLookup name
+
+
+var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight, fontShape) {
+ var baseFontName = "";
+
+ switch (fontFamily) {
+ case "amsrm":
+ baseFontName = "AMS";
+ break;
+
+ case "textrm":
+ baseFontName = "Main";
+ break;
+
+ case "textsf":
+ baseFontName = "SansSerif";
+ break;
+
+ case "texttt":
+ baseFontName = "Typewriter";
+ break;
+
+ default:
+ baseFontName = fontFamily;
+ // use fonts added by a plugin
+ }
+
+ var fontStylesName;
+
+ if (fontWeight === "textbf" && fontShape === "textit") {
+ fontStylesName = "BoldItalic";
+ } else if (fontWeight === "textbf") {
+ fontStylesName = "Bold";
+ } else if (fontWeight === "textit") {
+ fontStylesName = "Italic";
+ } else {
+ fontStylesName = "Regular";
+ }
+
+ return baseFontName + "-" + fontStylesName;
+};
+/**
+ * Maps TeX font commands to objects containing:
+ * - variant: string used for "mathvariant" attribute in buildMathML.js
+ * - fontName: the "style" parameter to fontMetrics.getCharacterMetrics
+ */
+// A map between tex font commands an MathML mathvariant attribute values
+
+
+var fontMap = {
+ // styles
+ "mathbf": {
+ variant: "bold",
+ fontName: "Main-Bold"
+ },
+ "mathrm": {
+ variant: "normal",
+ fontName: "Main-Regular"
+ },
+ "textit": {
+ variant: "italic",
+ fontName: "Main-Italic"
+ },
+ "mathit": {
+ variant: "italic",
+ fontName: "Main-Italic"
+ },
+ "mathnormal": {
+ variant: "italic",
+ fontName: "Math-Italic"
+ },
+ // "boldsymbol" is missing because they require the use of multiple fonts:
+ // Math-BoldItalic and Main-Bold. This is handled by a special case in
+ // makeOrd which ends up calling boldsymbol.
+ // families
+ "mathbb": {
+ variant: "double-struck",
+ fontName: "AMS-Regular"
+ },
+ "mathcal": {
+ variant: "script",
+ fontName: "Caligraphic-Regular"
+ },
+ "mathfrak": {
+ variant: "fraktur",
+ fontName: "Fraktur-Regular"
+ },
+ "mathscr": {
+ variant: "script",
+ fontName: "Script-Regular"
+ },
+ "mathsf": {
+ variant: "sans-serif",
+ fontName: "SansSerif-Regular"
+ },
+ "mathtt": {
+ variant: "monospace",
+ fontName: "Typewriter-Regular"
+ }
+};
+var svgData = {
+ // path, width, height
+ vec: ["vec", 0.471, 0.714],
+ // values from the font glyph
+ oiintSize1: ["oiintSize1", 0.957, 0.499],
+ // oval to overlay the integrand
+ oiintSize2: ["oiintSize2", 1.472, 0.659],
+ oiiintSize1: ["oiiintSize1", 1.304, 0.499],
+ oiiintSize2: ["oiiintSize2", 1.98, 0.659]
+};
+
+var staticSvg = function staticSvg(value, options) {
+ // Create a span with inline SVG for the element.
+ var _svgData$value = svgData[value],
+ pathName = _svgData$value[0],
+ width = _svgData$value[1],
+ height = _svgData$value[2];
+ var path = new PathNode(pathName);
+ var svgNode = new SvgNode([path], {
+ "width": makeEm(width),
+ "height": makeEm(height),
+ // Override CSS rule `.katex svg { width: 100% }`
+ "style": "width:" + makeEm(width),
+ "viewBox": "0 0 " + 1000 * width + " " + 1000 * height,
+ "preserveAspectRatio": "xMinYMin"
+ });
+ var span = makeSvgSpan(["overlay"], [svgNode], options);
+ span.height = height;
+ span.style.height = makeEm(height);
+ span.style.width = makeEm(width);
+ return span;
+};
+
+/* harmony default export */ var buildCommon = ({
+ fontMap: fontMap,
+ makeSymbol: makeSymbol,
+ mathsym: mathsym,
+ makeSpan: makeSpan,
+ makeSvgSpan: makeSvgSpan,
+ makeLineSpan: makeLineSpan,
+ makeAnchor: makeAnchor,
+ makeFragment: makeFragment,
+ wrapFragment: wrapFragment,
+ makeVList: makeVList,
+ makeOrd: makeOrd,
+ makeGlue: makeGlue,
+ staticSvg: staticSvg,
+ svgData: svgData,
+ tryCombineChars: tryCombineChars
+});
+;// CONCATENATED MODULE: ./src/spacingData.js
+/**
+ * Describes spaces between different classes of atoms.
+ */
+var thinspace = {
+ number: 3,
+ unit: "mu"
+};
+var mediumspace = {
+ number: 4,
+ unit: "mu"
+};
+var thickspace = {
+ number: 5,
+ unit: "mu"
+}; // Making the type below exact with all optional fields doesn't work due to
+// - https://github.com/facebook/flow/issues/4582
+// - https://github.com/facebook/flow/issues/5688
+// However, since *all* fields are optional, $Shape<> works as suggested in 5688
+// above.
+
+// Spacing relationships for display and text styles
+var spacings = {
+ mord: {
+ mop: thinspace,
+ mbin: mediumspace,
+ mrel: thickspace,
+ minner: thinspace
+ },
+ mop: {
+ mord: thinspace,
+ mop: thinspace,
+ mrel: thickspace,
+ minner: thinspace
+ },
+ mbin: {
+ mord: mediumspace,
+ mop: mediumspace,
+ mopen: mediumspace,
+ minner: mediumspace
+ },
+ mrel: {
+ mord: thickspace,
+ mop: thickspace,
+ mopen: thickspace,
+ minner: thickspace
+ },
+ mopen: {},
+ mclose: {
+ mop: thinspace,
+ mbin: mediumspace,
+ mrel: thickspace,
+ minner: thinspace
+ },
+ mpunct: {
+ mord: thinspace,
+ mop: thinspace,
+ mrel: thickspace,
+ mopen: thinspace,
+ mclose: thinspace,
+ mpunct: thinspace,
+ minner: thinspace
+ },
+ minner: {
+ mord: thinspace,
+ mop: thinspace,
+ mbin: mediumspace,
+ mrel: thickspace,
+ mopen: thinspace,
+ mpunct: thinspace,
+ minner: thinspace
+ }
+}; // Spacing relationships for script and scriptscript styles
+
+var tightSpacings = {
+ mord: {
+ mop: thinspace
+ },
+ mop: {
+ mord: thinspace,
+ mop: thinspace
+ },
+ mbin: {},
+ mrel: {},
+ mopen: {},
+ mclose: {
+ mop: thinspace
+ },
+ mpunct: {},
+ minner: {
+ mop: thinspace
+ }
+};
+;// CONCATENATED MODULE: ./src/defineFunction.js
+/** Context provided to function handlers for error messages. */
+// Note: reverse the order of the return type union will cause a flow error.
+// See https://github.com/facebook/flow/issues/3663.
+// More general version of `HtmlBuilder` for nodes (e.g. \sum, accent types)
+// whose presence impacts super/subscripting. In this case, ParseNode<"supsub">
+// delegates its HTML building to the HtmlBuilder corresponding to these nodes.
+
+/**
+ * Final function spec for use at parse time.
+ * This is almost identical to `FunctionPropSpec`, except it
+ * 1. includes the function handler, and
+ * 2. requires all arguments except argTypes.
+ * It is generated by `defineFunction()` below.
+ */
+
+/**
+ * All registered functions.
+ * `functions.js` just exports this same dictionary again and makes it public.
+ * `Parser.js` requires this dictionary.
+ */
+var _functions = {};
+/**
+ * All HTML builders. Should be only used in the `define*` and the `build*ML`
+ * functions.
+ */
+
+var _htmlGroupBuilders = {};
+/**
+ * All MathML builders. Should be only used in the `define*` and the `build*ML`
+ * functions.
+ */
+
+var _mathmlGroupBuilders = {};
+function defineFunction(_ref) {
+ var type = _ref.type,
+ names = _ref.names,
+ props = _ref.props,
+ handler = _ref.handler,
+ htmlBuilder = _ref.htmlBuilder,
+ mathmlBuilder = _ref.mathmlBuilder;
+ // Set default values of functions
+ var data = {
+ type: type,
+ numArgs: props.numArgs,
+ argTypes: props.argTypes,
+ allowedInArgument: !!props.allowedInArgument,
+ allowedInText: !!props.allowedInText,
+ allowedInMath: props.allowedInMath === undefined ? true : props.allowedInMath,
+ numOptionalArgs: props.numOptionalArgs || 0,
+ infix: !!props.infix,
+ primitive: !!props.primitive,
+ handler: handler
+ };
+
+ for (var i = 0; i < names.length; ++i) {
+ _functions[names[i]] = data;
+ }
+
+ if (type) {
+ if (htmlBuilder) {
+ _htmlGroupBuilders[type] = htmlBuilder;
+ }
+
+ if (mathmlBuilder) {
+ _mathmlGroupBuilders[type] = mathmlBuilder;
+ }
+ }
+}
+/**
+ * Use this to register only the HTML and MathML builders for a function (e.g.
+ * if the function's ParseNode is generated in Parser.js rather than via a
+ * stand-alone handler provided to `defineFunction`).
+ */
+
+function defineFunctionBuilders(_ref2) {
+ var type = _ref2.type,
+ htmlBuilder = _ref2.htmlBuilder,
+ mathmlBuilder = _ref2.mathmlBuilder;
+ defineFunction({
+ type: type,
+ names: [],
+ props: {
+ numArgs: 0
+ },
+ handler: function handler() {
+ throw new Error('Should never be called.');
+ },
+ htmlBuilder: htmlBuilder,
+ mathmlBuilder: mathmlBuilder
+ });
+}
+var normalizeArgument = function normalizeArgument(arg) {
+ return arg.type === "ordgroup" && arg.body.length === 1 ? arg.body[0] : arg;
+}; // Since the corresponding buildHTML/buildMathML function expects a
+// list of elements, we normalize for different kinds of arguments
+
+var ordargument = function ordargument(arg) {
+ return arg.type === "ordgroup" ? arg.body : [arg];
+};
+;// CONCATENATED MODULE: ./src/buildHTML.js
+/**
+ * This file does the main work of building a domTree structure from a parse
+ * tree. The entry point is the `buildHTML` function, which takes a parse tree.
+ * Then, the buildExpression, buildGroup, and various groupBuilders functions
+ * are called, to produce a final HTML tree.
+ */
+
+
+
+
+
+
+
+
+
+var buildHTML_makeSpan = buildCommon.makeSpan; // Binary atoms (first class `mbin`) change into ordinary atoms (`mord`)
+// depending on their surroundings. See TeXbook pg. 442-446, Rules 5 and 6,
+// and the text before Rule 19.
+
+var binLeftCanceller = ["leftmost", "mbin", "mopen", "mrel", "mop", "mpunct"];
+var binRightCanceller = ["rightmost", "mrel", "mclose", "mpunct"];
+var styleMap = {
+ "display": src_Style.DISPLAY,
+ "text": src_Style.TEXT,
+ "script": src_Style.SCRIPT,
+ "scriptscript": src_Style.SCRIPTSCRIPT
+};
+var DomEnum = {
+ mord: "mord",
+ mop: "mop",
+ mbin: "mbin",
+ mrel: "mrel",
+ mopen: "mopen",
+ mclose: "mclose",
+ mpunct: "mpunct",
+ minner: "minner"
+};
+
+/**
+ * Take a list of nodes, build them in order, and return a list of the built
+ * nodes. documentFragments are flattened into their contents, so the
+ * returned list contains no fragments. `isRealGroup` is true if `expression`
+ * is a real group (no atoms will be added on either side), as opposed to
+ * a partial group (e.g. one created by \color). `surrounding` is an array
+ * consisting type of nodes that will be added to the left and right.
+ */
+var buildExpression = function buildExpression(expression, options, isRealGroup, surrounding) {
+ if (surrounding === void 0) {
+ surrounding = [null, null];
+ }
+
+ // Parse expressions into `groups`.
+ var groups = [];
+
+ for (var i = 0; i < expression.length; i++) {
+ var output = buildGroup(expression[i], options);
+
+ if (output instanceof DocumentFragment) {
+ var children = output.children;
+ groups.push.apply(groups, children);
+ } else {
+ groups.push(output);
+ }
+ } // Combine consecutive domTree.symbolNodes into a single symbolNode.
+
+
+ buildCommon.tryCombineChars(groups); // If `expression` is a partial group, let the parent handle spacings
+ // to avoid processing groups multiple times.
+
+ if (!isRealGroup) {
+ return groups;
+ }
+
+ var glueOptions = options;
+
+ if (expression.length === 1) {
+ var node = expression[0];
+
+ if (node.type === "sizing") {
+ glueOptions = options.havingSize(node.size);
+ } else if (node.type === "styling") {
+ glueOptions = options.havingStyle(styleMap[node.style]);
+ }
+ } // Dummy spans for determining spacings between surrounding atoms.
+ // If `expression` has no atoms on the left or right, class "leftmost"
+ // or "rightmost", respectively, is used to indicate it.
+
+
+ var dummyPrev = buildHTML_makeSpan([surrounding[0] || "leftmost"], [], options);
+ var dummyNext = buildHTML_makeSpan([surrounding[1] || "rightmost"], [], options); // TODO: These code assumes that a node's math class is the first element
+ // of its `classes` array. A later cleanup should ensure this, for
+ // instance by changing the signature of `makeSpan`.
+ // Before determining what spaces to insert, perform bin cancellation.
+ // Binary operators change to ordinary symbols in some contexts.
+
+ var isRoot = isRealGroup === "root";
+ traverseNonSpaceNodes(groups, function (node, prev) {
+ var prevType = prev.classes[0];
+ var type = node.classes[0];
+
+ if (prevType === "mbin" && utils.contains(binRightCanceller, type)) {
+ prev.classes[0] = "mord";
+ } else if (type === "mbin" && utils.contains(binLeftCanceller, prevType)) {
+ node.classes[0] = "mord";
+ }
+ }, {
+ node: dummyPrev
+ }, dummyNext, isRoot);
+ traverseNonSpaceNodes(groups, function (node, prev) {
+ var prevType = getTypeOfDomTree(prev);
+ var type = getTypeOfDomTree(node); // 'mtight' indicates that the node is script or scriptscript style.
+
+ var space = prevType && type ? node.hasClass("mtight") ? tightSpacings[prevType][type] : spacings[prevType][type] : null;
+
+ if (space) {
+ // Insert glue (spacing) after the `prev`.
+ return buildCommon.makeGlue(space, glueOptions);
+ }
+ }, {
+ node: dummyPrev
+ }, dummyNext, isRoot);
+ return groups;
+}; // Depth-first traverse non-space `nodes`, calling `callback` with the current and
+// previous node as arguments, optionally returning a node to insert after the
+// previous node. `prev` is an object with the previous node and `insertAfter`
+// function to insert after it. `next` is a node that will be added to the right.
+// Used for bin cancellation and inserting spacings.
+
+var traverseNonSpaceNodes = function traverseNonSpaceNodes(nodes, callback, prev, next, isRoot) {
+ if (next) {
+ // temporarily append the right node, if exists
+ nodes.push(next);
+ }
+
+ var i = 0;
+
+ for (; i < nodes.length; i++) {
+ var node = nodes[i];
+ var partialGroup = checkPartialGroup(node);
+
+ if (partialGroup) {
+ // Recursive DFS
+ // $FlowFixMe: make nodes a $ReadOnlyArray by returning a new array
+ traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot);
+ continue;
+ } // Ignore explicit spaces (e.g., \;, \,) when determining what implicit
+ // spacing should go between atoms of different classes
+
+
+ var nonspace = !node.hasClass("mspace");
+
+ if (nonspace) {
+ var result = callback(node, prev.node);
+
+ if (result) {
+ if (prev.insertAfter) {
+ prev.insertAfter(result);
+ } else {
+ // insert at front
+ nodes.unshift(result);
+ i++;
+ }
+ }
+ }
+
+ if (nonspace) {
+ prev.node = node;
+ } else if (isRoot && node.hasClass("newline")) {
+ prev.node = buildHTML_makeSpan(["leftmost"]); // treat like beginning of line
+ }
+
+ prev.insertAfter = function (index) {
+ return function (n) {
+ nodes.splice(index + 1, 0, n);
+ i++;
+ };
+ }(i);
+ }
+
+ if (next) {
+ nodes.pop();
+ }
+}; // Check if given node is a partial group, i.e., does not affect spacing around.
+
+
+var checkPartialGroup = function checkPartialGroup(node) {
+ if (node instanceof DocumentFragment || node instanceof Anchor || node instanceof Span && node.hasClass("enclosing")) {
+ return node;
+ }
+
+ return null;
+}; // Return the outermost node of a domTree.
+
+
+var getOutermostNode = function getOutermostNode(node, side) {
+ var partialGroup = checkPartialGroup(node);
+
+ if (partialGroup) {
+ var children = partialGroup.children;
+
+ if (children.length) {
+ if (side === "right") {
+ return getOutermostNode(children[children.length - 1], "right");
+ } else if (side === "left") {
+ return getOutermostNode(children[0], "left");
+ }
+ }
+ }
+
+ return node;
+}; // Return math atom class (mclass) of a domTree.
+// If `side` is given, it will get the type of the outermost node at given side.
+
+
+var getTypeOfDomTree = function getTypeOfDomTree(node, side) {
+ if (!node) {
+ return null;
+ }
+
+ if (side) {
+ node = getOutermostNode(node, side);
+ } // This makes a lot of assumptions as to where the type of atom
+ // appears. We should do a better job of enforcing this.
+
+
+ return DomEnum[node.classes[0]] || null;
+};
+var makeNullDelimiter = function makeNullDelimiter(options, classes) {
+ var moreClasses = ["nulldelimiter"].concat(options.baseSizingClasses());
+ return buildHTML_makeSpan(classes.concat(moreClasses));
+};
+/**
+ * buildGroup is the function that takes a group and calls the correct groupType
+ * function for it. It also handles the interaction of size and style changes
+ * between parents and children.
+ */
+
+var buildGroup = function buildGroup(group, options, baseOptions) {
+ if (!group) {
+ return buildHTML_makeSpan();
+ }
+
+ if (_htmlGroupBuilders[group.type]) {
+ // Call the groupBuilders function
+ // $FlowFixMe
+ var groupNode = _htmlGroupBuilders[group.type](group, options); // If the size changed between the parent and the current group, account
+ // for that size difference.
+
+ if (baseOptions && options.size !== baseOptions.size) {
+ groupNode = buildHTML_makeSpan(options.sizingClasses(baseOptions), [groupNode], options);
+ var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier;
+ groupNode.height *= multiplier;
+ groupNode.depth *= multiplier;
+ }
+
+ return groupNode;
+ } else {
+ throw new src_ParseError("Got group of unknown type: '" + group.type + "'");
+ }
+};
+/**
+ * Combine an array of HTML DOM nodes (e.g., the output of `buildExpression`)
+ * into an unbreakable HTML node of class .base, with proper struts to
+ * guarantee correct vertical extent. `buildHTML` calls this repeatedly to
+ * make up the entire expression as a sequence of unbreakable units.
+ */
+
+function buildHTMLUnbreakable(children, options) {
+ // Compute height and depth of this chunk.
+ var body = buildHTML_makeSpan(["base"], children, options); // Add strut, which ensures that the top of the HTML element falls at
+ // the height of the expression, and the bottom of the HTML element
+ // falls at the depth of the expression.
+
+ var strut = buildHTML_makeSpan(["strut"]);
+ strut.style.height = makeEm(body.height + body.depth);
+
+ if (body.depth) {
+ strut.style.verticalAlign = makeEm(-body.depth);
+ }
+
+ body.children.unshift(strut);
+ return body;
+}
+/**
+ * Take an entire parse tree, and build it into an appropriate set of HTML
+ * nodes.
+ */
+
+
+function buildHTML(tree, options) {
+ // Strip off outer tag wrapper for processing below.
+ var tag = null;
+
+ if (tree.length === 1 && tree[0].type === "tag") {
+ tag = tree[0].tag;
+ tree = tree[0].body;
+ } // Build the expression contained in the tree
+
+
+ var expression = buildExpression(tree, options, "root");
+ var eqnNum;
+
+ if (expression.length === 2 && expression[1].hasClass("tag")) {
+ // An environment with automatic equation numbers, e.g. {gather}.
+ eqnNum = expression.pop();
+ }
+
+ var children = []; // Create one base node for each chunk between potential line breaks.
+ // The TeXBook [p.173] says "A formula will be broken only after a
+ // relation symbol like $=$ or $<$ or $\rightarrow$, or after a binary
+ // operation symbol like $+$ or $-$ or $\times$, where the relation or
+ // binary operation is on the ``outer level'' of the formula (i.e., not
+ // enclosed in {...} and not part of an \over construction)."
+
+ var parts = [];
+
+ for (var i = 0; i < expression.length; i++) {
+ parts.push(expression[i]);
+
+ if (expression[i].hasClass("mbin") || expression[i].hasClass("mrel") || expression[i].hasClass("allowbreak")) {
+ // Put any post-operator glue on same line as operator.
+ // Watch for \nobreak along the way, and stop at \newline.
+ var nobreak = false;
+
+ while (i < expression.length - 1 && expression[i + 1].hasClass("mspace") && !expression[i + 1].hasClass("newline")) {
+ i++;
+ parts.push(expression[i]);
+
+ if (expression[i].hasClass("nobreak")) {
+ nobreak = true;
+ }
+ } // Don't allow break if \nobreak among the post-operator glue.
+
+
+ if (!nobreak) {
+ children.push(buildHTMLUnbreakable(parts, options));
+ parts = [];
+ }
+ } else if (expression[i].hasClass("newline")) {
+ // Write the line except the newline
+ parts.pop();
+
+ if (parts.length > 0) {
+ children.push(buildHTMLUnbreakable(parts, options));
+ parts = [];
+ } // Put the newline at the top level
+
+
+ children.push(expression[i]);
+ }
+ }
+
+ if (parts.length > 0) {
+ children.push(buildHTMLUnbreakable(parts, options));
+ } // Now, if there was a tag, build it too and append it as a final child.
+
+
+ var tagChild;
+
+ if (tag) {
+ tagChild = buildHTMLUnbreakable(buildExpression(tag, options, true));
+ tagChild.classes = ["tag"];
+ children.push(tagChild);
+ } else if (eqnNum) {
+ children.push(eqnNum);
+ }
+
+ var htmlNode = buildHTML_makeSpan(["katex-html"], children);
+ htmlNode.setAttribute("aria-hidden", "true"); // Adjust the strut of the tag to be the maximum height of all children
+ // (the height of the enclosing htmlNode) for proper vertical alignment.
+
+ if (tagChild) {
+ var strut = tagChild.children[0];
+ strut.style.height = makeEm(htmlNode.height + htmlNode.depth);
+
+ if (htmlNode.depth) {
+ strut.style.verticalAlign = makeEm(-htmlNode.depth);
+ }
+ }
+
+ return htmlNode;
+}
+;// CONCATENATED MODULE: ./src/mathMLTree.js
+/**
+ * These objects store data about MathML nodes. This is the MathML equivalent
+ * of the types in domTree.js. Since MathML handles its own rendering, and
+ * since we're mainly using MathML to improve accessibility, we don't manage
+ * any of the styling state that the plain DOM nodes do.
+ *
+ * The `toNode` and `toMarkup` functions work simlarly to how they do in
+ * domTree.js, creating namespaced DOM nodes and HTML text markup respectively.
+ */
+
+
+
+
+function newDocumentFragment(children) {
+ return new DocumentFragment(children);
+}
+/**
+ * This node represents a general purpose MathML node of any type. The
+ * constructor requires the type of node to create (for example, `"mo"` or
+ * `"mspace"`, corresponding to `` and `` tags).
+ */
+
+var MathNode = /*#__PURE__*/function () {
+ function MathNode(type, children, classes) {
+ this.type = void 0;
+ this.attributes = void 0;
+ this.children = void 0;
+ this.classes = void 0;
+ this.type = type;
+ this.attributes = {};
+ this.children = children || [];
+ this.classes = classes || [];
+ }
+ /**
+ * Sets an attribute on a MathML node. MathML depends on attributes to convey a
+ * semantic content, so this is used heavily.
+ */
+
+
+ var _proto = MathNode.prototype;
+
+ _proto.setAttribute = function setAttribute(name, value) {
+ this.attributes[name] = value;
+ }
+ /**
+ * Gets an attribute on a MathML node.
+ */
+ ;
+
+ _proto.getAttribute = function getAttribute(name) {
+ return this.attributes[name];
+ }
+ /**
+ * Converts the math node into a MathML-namespaced DOM element.
+ */
+ ;
+
+ _proto.toNode = function toNode() {
+ var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", this.type);
+
+ for (var attr in this.attributes) {
+ if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
+ node.setAttribute(attr, this.attributes[attr]);
+ }
+ }
+
+ if (this.classes.length > 0) {
+ node.className = createClass(this.classes);
+ }
+
+ for (var i = 0; i < this.children.length; i++) {
+ node.appendChild(this.children[i].toNode());
+ }
+
+ return node;
+ }
+ /**
+ * Converts the math node into an HTML markup string.
+ */
+ ;
+
+ _proto.toMarkup = function toMarkup() {
+ var markup = "<" + this.type; // Add the attributes
+
+ for (var attr in this.attributes) {
+ if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
+ markup += " " + attr + "=\"";
+ markup += utils.escape(this.attributes[attr]);
+ markup += "\"";
+ }
+ }
+
+ if (this.classes.length > 0) {
+ markup += " class =\"" + utils.escape(createClass(this.classes)) + "\"";
+ }
+
+ markup += ">";
+
+ for (var i = 0; i < this.children.length; i++) {
+ markup += this.children[i].toMarkup();
+ }
+
+ markup += "" + this.type + ">";
+ return markup;
+ }
+ /**
+ * Converts the math node into a string, similar to innerText, but escaped.
+ */
+ ;
+
+ _proto.toText = function toText() {
+ return this.children.map(function (child) {
+ return child.toText();
+ }).join("");
+ };
+
+ return MathNode;
+}();
+/**
+ * This node represents a piece of text.
+ */
+
+var TextNode = /*#__PURE__*/function () {
+ function TextNode(text) {
+ this.text = void 0;
+ this.text = text;
+ }
+ /**
+ * Converts the text node into a DOM text node.
+ */
+
+
+ var _proto2 = TextNode.prototype;
+
+ _proto2.toNode = function toNode() {
+ return document.createTextNode(this.text);
+ }
+ /**
+ * Converts the text node into escaped HTML markup
+ * (representing the text itself).
+ */
+ ;
+
+ _proto2.toMarkup = function toMarkup() {
+ return utils.escape(this.toText());
+ }
+ /**
+ * Converts the text node into a string
+ * (representing the text iteself).
+ */
+ ;
+
+ _proto2.toText = function toText() {
+ return this.text;
+ };
+
+ return TextNode;
+}();
+/**
+ * This node represents a space, but may render as or as text,
+ * depending on the width.
+ */
+
+var SpaceNode = /*#__PURE__*/function () {
+ /**
+ * Create a Space node with width given in CSS ems.
+ */
+ function SpaceNode(width) {
+ this.width = void 0;
+ this.character = void 0;
+ this.width = width; // See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html
+ // for a table of space-like characters. We use Unicode
+ // representations instead of &LongNames; as it's not clear how to
+ // make the latter via document.createTextNode.
+
+ if (width >= 0.05555 && width <= 0.05556) {
+ this.character = "\u200A"; //  
+ } else if (width >= 0.1666 && width <= 0.1667) {
+ this.character = "\u2009"; //  
+ } else if (width >= 0.2222 && width <= 0.2223) {
+ this.character = "\u2005"; //  
+ } else if (width >= 0.2777 && width <= 0.2778) {
+ this.character = "\u2005\u200A"; //   
+ } else if (width >= -0.05556 && width <= -0.05555) {
+ this.character = "\u200A\u2063"; // ​
+ } else if (width >= -0.1667 && width <= -0.1666) {
+ this.character = "\u2009\u2063"; // ​
+ } else if (width >= -0.2223 && width <= -0.2222) {
+ this.character = "\u205F\u2063"; // ​
+ } else if (width >= -0.2778 && width <= -0.2777) {
+ this.character = "\u2005\u2063"; // ​
+ } else {
+ this.character = null;
+ }
+ }
+ /**
+ * Converts the math node into a MathML-namespaced DOM element.
+ */
+
+
+ var _proto3 = SpaceNode.prototype;
+
+ _proto3.toNode = function toNode() {
+ if (this.character) {
+ return document.createTextNode(this.character);
+ } else {
+ var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mspace");
+ node.setAttribute("width", makeEm(this.width));
+ return node;
+ }
+ }
+ /**
+ * Converts the math node into an HTML markup string.
+ */
+ ;
+
+ _proto3.toMarkup = function toMarkup() {
+ if (this.character) {
+ return "" + this.character + "";
+ } else {
+ return "";
+ }
+ }
+ /**
+ * Converts the math node into a string, similar to innerText.
+ */
+ ;
+
+ _proto3.toText = function toText() {
+ if (this.character) {
+ return this.character;
+ } else {
+ return " ";
+ }
+ };
+
+ return SpaceNode;
+}();
+
+/* harmony default export */ var mathMLTree = ({
+ MathNode: MathNode,
+ TextNode: TextNode,
+ SpaceNode: SpaceNode,
+ newDocumentFragment: newDocumentFragment
+});
+;// CONCATENATED MODULE: ./src/buildMathML.js
+/**
+ * This file converts a parse tree into a cooresponding MathML tree. The main
+ * entry point is the `buildMathML` function, which takes a parse tree from the
+ * parser.
+ */
+
+
+
+
+
+
+
+
+
+/**
+ * Takes a symbol and converts it into a MathML text node after performing
+ * optional replacement from symbols.js.
+ */
+var makeText = function makeText(text, mode, options) {
+ if (src_symbols[mode][text] && src_symbols[mode][text].replace && text.charCodeAt(0) !== 0xD835 && !(ligatures.hasOwnProperty(text) && options && (options.fontFamily && options.fontFamily.substr(4, 2) === "tt" || options.font && options.font.substr(4, 2) === "tt"))) {
+ text = src_symbols[mode][text].replace;
+ }
+
+ return new mathMLTree.TextNode(text);
+};
+/**
+ * Wrap the given array of nodes in an node if needed, i.e.,
+ * unless the array has length 1. Always returns a single node.
+ */
+
+var makeRow = function makeRow(body) {
+ if (body.length === 1) {
+ return body[0];
+ } else {
+ return new mathMLTree.MathNode("mrow", body);
+ }
+};
+/**
+ * Returns the math variant as a string or null if none is required.
+ */
+
+var getVariant = function getVariant(group, options) {
+ // Handle \text... font specifiers as best we can.
+ // MathML has a limited list of allowable mathvariant specifiers; see
+ // https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt
+ if (options.fontFamily === "texttt") {
+ return "monospace";
+ } else if (options.fontFamily === "textsf") {
+ if (options.fontShape === "textit" && options.fontWeight === "textbf") {
+ return "sans-serif-bold-italic";
+ } else if (options.fontShape === "textit") {
+ return "sans-serif-italic";
+ } else if (options.fontWeight === "textbf") {
+ return "bold-sans-serif";
+ } else {
+ return "sans-serif";
+ }
+ } else if (options.fontShape === "textit" && options.fontWeight === "textbf") {
+ return "bold-italic";
+ } else if (options.fontShape === "textit") {
+ return "italic";
+ } else if (options.fontWeight === "textbf") {
+ return "bold";
+ }
+
+ var font = options.font;
+
+ if (!font || font === "mathnormal") {
+ return null;
+ }
+
+ var mode = group.mode;
+
+ if (font === "mathit") {
+ return "italic";
+ } else if (font === "boldsymbol") {
+ return group.type === "textord" ? "bold" : "bold-italic";
+ } else if (font === "mathbf") {
+ return "bold";
+ } else if (font === "mathbb") {
+ return "double-struck";
+ } else if (font === "mathfrak") {
+ return "fraktur";
+ } else if (font === "mathscr" || font === "mathcal") {
+ // MathML makes no distinction between script and caligrahpic
+ return "script";
+ } else if (font === "mathsf") {
+ return "sans-serif";
+ } else if (font === "mathtt") {
+ return "monospace";
+ }
+
+ var text = group.text;
+
+ if (utils.contains(["\\imath", "\\jmath"], text)) {
+ return null;
+ }
+
+ if (src_symbols[mode][text] && src_symbols[mode][text].replace) {
+ text = src_symbols[mode][text].replace;
+ }
+
+ var fontName = buildCommon.fontMap[font].fontName;
+
+ if (getCharacterMetrics(text, fontName, mode)) {
+ return buildCommon.fontMap[font].variant;
+ }
+
+ return null;
+};
+/**
+ * Takes a list of nodes, builds them, and returns a list of the generated
+ * MathML nodes. Also combine consecutive outputs into a single
+ * tag.
+ */
+
+var buildMathML_buildExpression = function buildExpression(expression, options, isOrdgroup) {
+ if (expression.length === 1) {
+ var group = buildMathML_buildGroup(expression[0], options);
+
+ if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
+ // When TeX writers want to suppress spacing on an operator,
+ // they often put the operator by itself inside braces.
+ group.setAttribute("lspace", "0em");
+ group.setAttribute("rspace", "0em");
+ }
+
+ return [group];
+ }
+
+ var groups = [];
+ var lastGroup;
+
+ for (var i = 0; i < expression.length; i++) {
+ var _group = buildMathML_buildGroup(expression[i], options);
+
+ if (_group instanceof MathNode && lastGroup instanceof MathNode) {
+ // Concatenate adjacent s
+ if (_group.type === 'mtext' && lastGroup.type === 'mtext' && _group.getAttribute('mathvariant') === lastGroup.getAttribute('mathvariant')) {
+ var _lastGroup$children;
+
+ (_lastGroup$children = lastGroup.children).push.apply(_lastGroup$children, _group.children);
+
+ continue; // Concatenate adjacent s
+ } else if (_group.type === 'mn' && lastGroup.type === 'mn') {
+ var _lastGroup$children2;
+
+ (_lastGroup$children2 = lastGroup.children).push.apply(_lastGroup$children2, _group.children);
+
+ continue; // Concatenate ... followed by .
+ } else if (_group.type === 'mi' && _group.children.length === 1 && lastGroup.type === 'mn') {
+ var child = _group.children[0];
+
+ if (child instanceof TextNode && child.text === '.') {
+ var _lastGroup$children3;
+
+ (_lastGroup$children3 = lastGroup.children).push.apply(_lastGroup$children3, _group.children);
+
+ continue;
+ }
+ } else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) {
+ var lastChild = lastGroup.children[0];
+
+ if (lastChild instanceof TextNode && lastChild.text === "\u0338" && (_group.type === 'mo' || _group.type === 'mi' || _group.type === 'mn')) {
+ var _child = _group.children[0];
+
+ if (_child instanceof TextNode && _child.text.length > 0) {
+ // Overlay with combining character long solidus
+ _child.text = _child.text.slice(0, 1) + "\u0338" + _child.text.slice(1);
+ groups.pop();
+ }
+ }
+ }
+ }
+
+ groups.push(_group);
+ lastGroup = _group;
+ }
+
+ return groups;
+};
+/**
+ * Equivalent to buildExpression, but wraps the elements in an
+ * if there's more than one. Returns a single node instead of an array.
+ */
+
+var buildExpressionRow = function buildExpressionRow(expression, options, isOrdgroup) {
+ return makeRow(buildMathML_buildExpression(expression, options, isOrdgroup));
+};
+/**
+ * Takes a group from the parser and calls the appropriate groupBuilders function
+ * on it to produce a MathML node.
+ */
+
+var buildMathML_buildGroup = function buildGroup(group, options) {
+ if (!group) {
+ return new mathMLTree.MathNode("mrow");
+ }
+
+ if (_mathmlGroupBuilders[group.type]) {
+ // Call the groupBuilders function
+ // $FlowFixMe
+ var result = _mathmlGroupBuilders[group.type](group, options); // $FlowFixMe
+
+ return result;
+ } else {
+ throw new src_ParseError("Got group of unknown type: '" + group.type + "'");
+ }
+};
+/**
+ * Takes a full parse tree and settings and builds a MathML representation of
+ * it. In particular, we put the elements from building the parse tree into a
+ * tag so we can also include that TeX source as an annotation.
+ *
+ * Note that we actually return a domTree element with a `