diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f71851e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+
+## Local install
+
+Project is created with netbeans. It would be better to use netbeans to build it.
+
+## You'll need
+
+* Netbeans
+* Java
+* Server (Tomcat)
+* Postgresql
+
+## Modifications you need to do before build
+
+* 'urrsm.sng.Config' contains important configurations. You need to change them accordingly
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..d25495e
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+ Builds, tests, and runs the project UChats.
+
+
+
diff --git a/lib/gson-2.8.2-sources.jar b/lib/gson-2.8.2-sources.jar
new file mode 100644
index 0000000..4910645
Binary files /dev/null and b/lib/gson-2.8.2-sources.jar differ
diff --git a/lib/gson-2.8.2.jar b/lib/gson-2.8.2.jar
new file mode 100644
index 0000000..d0d030c
Binary files /dev/null and b/lib/gson-2.8.2.jar differ
diff --git a/lib/postgresql-42.2.1.jar b/lib/postgresql-42.2.1.jar
new file mode 100644
index 0000000..e934846
Binary files /dev/null and b/lib/postgresql-42.2.1.jar differ
diff --git a/nbproject/ant-deploy.xml b/nbproject/ant-deploy.xml
new file mode 100644
index 0000000..55566c8
--- /dev/null
+++ b/nbproject/ant-deploy.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
new file mode 100644
index 0000000..177854e
--- /dev/null
+++ b/nbproject/build-impl.xml
@@ -0,0 +1,1446 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set src.dir
+ Must set test.src.dir
+ Must set build.dir
+ Must set build.web.dir
+ Must set build.generated.dir
+ Must set dist.dir
+ Must set build.classes.dir
+ Must set dist.javadoc.dir
+ Must set build.test.classes.dir
+ Must set build.test.results.dir
+ Must set build.classes.excludes
+ Must set dist.war
+
+
+
+
+
+
+
+
+
+The Java EE server classpath is not correctly set up - server home directory is missing.
+Either open the project in the IDE and assign the server or setup the server classpath manually.
+For example like this:
+ ant -Dj2ee.server.home=<app_server_installation_directory>
+
+
+The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}.
+Either open the project in the IDE and assign the server or setup the server classpath manually.
+For example like this:
+ ant -Duser.properties.file=<path_to_property_file> (where you put the property "j2ee.platform.classpath" in a .properties file)
+or ant -Dj2ee.platform.classpath=<server_classpath> (where no properties file is used)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No tests executed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The libs.CopyLibs.classpath property is not set up.
+This property must point to
+org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part
+of NetBeans IDE installation and is usually located at
+<netbeans_installation>/java<version>/ant/extra folder.
+Either open the project in the IDE and make sure CopyLibs library
+exists or setup the property manually. For example like this:
+ ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set JVM to use for profiling in profiler.info.jvm
+ Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.jsp.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select a file in the IDE or set jsp.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable.
+
+
+ Launching ${browse.url}
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must set fix.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This target only works when run from inside the NetBeans IDE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+ Some tests failed; see details above.
+
+
+
+ Must select some files in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+ Must select one file in the IDE or set test.class
+
+
+
+ Must select one file in the IDE or set test.class
+ Must select some method in the IDE or set test.method
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
new file mode 100644
index 0000000..4739a0a
--- /dev/null
+++ b/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=eee99f0d
+build.xml.script.CRC32=f46ca8d5
+build.xml.stylesheet.CRC32=651128d4@1.77.1.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=eee99f0d
+nbproject/build-impl.xml.script.CRC32=755bcc5e
+nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.77.1.1
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000..c22dc62
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,89 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=true
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+build.classes.dir=${build.web.dir}/WEB-INF/classes
+build.classes.excludes=**/*.java,**/*.form
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+build.web.dir=${build.dir}/web
+build.web.excludes=${build.classes.excludes}
+client.urlPart=
+compile.jsps=false
+conf.dir=${source.root}/conf
+debug.classpath=${build.classes.dir}:${javac.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+display.browser=true
+# Files to be excluded from distribution war
+dist.archive.excludes=
+dist.dir=dist
+dist.ear.war=${dist.dir}/${war.ear.name}
+dist.javadoc.dir=${dist.dir}/javadoc
+dist.war=${dist.dir}/${war.name}
+endorsed.classpath=\
+ ${libs.javaee-endorsed-api-7.0.classpath}
+excludes=
+file.reference.gson-2.8.2.jar=lib/gson-2.8.2.jar
+file.reference.postgresql-42.2.1.jar=lib/postgresql-42.2.1.jar
+includes=**
+j2ee.compile.on.save=true
+j2ee.copy.static.files.on.save=true
+j2ee.deploy.on.save=true
+j2ee.platform=1.7-web
+j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.4.2.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
+j2ee.server.type=Tomcat
+jar.compress=false
+javac.classpath=\
+ ${file.reference.postgresql-42.2.1.jar}:\
+ ${file.reference.gson-2.8.2.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.debug=true
+javac.deprecation=false
+javac.processorpath=\
+ ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+javac.test.processorpath=\
+ ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.preview=true
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+lib.dir=${web.docbase.dir}/WEB-INF/lib
+no.dependencies=false
+persistence.xml.dir=${conf.dir}
+platform.active=default_platform
+resource.dir=setup
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+# Space-separated list of JVM arguments used when running a class with a main method or a unit test
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value):
+runmain.jvmargs=
+source.encoding=UTF-8
+source.reference.gson-2.8.2.jar=lib/gson-2.8.2-sources.jar
+source.root=src
+src.dir=${source.root}/java
+test.src.dir=test
+war.content.additional=
+war.ear.name=${war.name}
+war.name=UChats.war
+web.docbase.dir=web
+webinf.dir=web/WEB-INF
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..c93bfcd
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,27 @@
+
+
+ org.netbeans.modules.web.project
+
+
+ UChats
+ 1.6.5
+
+
+ ${file.reference.postgresql-42.2.1.jar}
+ WEB-INF/lib
+
+
+ ${file.reference.gson-2.8.2.jar}
+ WEB-INF/lib
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/src/conf/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/src/java/urrsm/sng/Config.java b/src/java/urrsm/sng/Config.java
new file mode 100644
index 0000000..f59e9fe
--- /dev/null
+++ b/src/java/urrsm/sng/Config.java
@@ -0,0 +1,42 @@
+package urrsm.sng;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.net.URI;
+
+/**
+ *
+ * @author piyush
+ *
+ * Configurations for UChat Server
+ *
+ */
+public class Config
+{
+ public static String admin = ""; // name of admin
+ public static String password = "bawal"; // password of admin
+ public static String mods[] = {"4f26ae"}; // trips of mods
+ public static String salt = "My Salt Is This"; // salt for trips
+
+ public static String dburl = "jdbc:postgresql://localhost:5432/database"; // url to database
+ public static String dbusername = "user"; // database username
+ public static String dbpassword = "pass"; // database password
+
+ static
+ {
+ if(System.getenv("DATABASE_URL")!=null)
+ {
+ try
+ {
+ URI dbUri = new URI(System.getenv("DATABASE_URL"));
+ dbusername = dbUri.getUserInfo().split(":")[0];
+ dbpassword = dbUri.getUserInfo().split(":")[1];
+ dburl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath();
+ }
+ catch(Exception ex)
+ {
+ Logger.getLogger(Config.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+}
diff --git a/src/java/urrsm/sng/JsonStructure.java b/src/java/urrsm/sng/JsonStructure.java
new file mode 100644
index 0000000..8a8aeb7
--- /dev/null
+++ b/src/java/urrsm/sng/JsonStructure.java
@@ -0,0 +1,23 @@
+package urrsm.sng;
+
+import java.util.ArrayList;
+
+/**
+ *
+ * @author piyush
+ *
+ * Structure of json send between user and server
+ * It is required because we are using Gson
+ *
+ */
+public class JsonStructure {
+ String cmd;
+ String nick;
+ String channel;
+ String text;
+ boolean admin;
+ boolean mod;
+ String trip;
+ String ip;
+ ArrayList nicks;
+}
diff --git a/src/java/urrsm/sng/RecordManager.java b/src/java/urrsm/sng/RecordManager.java
new file mode 100644
index 0000000..6b7c758
--- /dev/null
+++ b/src/java/urrsm/sng/RecordManager.java
@@ -0,0 +1,141 @@
+package urrsm.sng;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author piyush
+ *
+ * Record Manager
+ *
+ */
+public class RecordManager {
+
+ long blocktime = 3600000;
+
+ public RecordManager() throws ClassNotFoundException, SQLException
+ {
+ Class.forName("org.postgresql.Driver");
+
+ String sql = "CREATE TABLE IF NOT EXISTS blocklist(\n" +
+ " ip TEXT NOT NULL,\n" +
+ " time REAL NOT NULL\n"+
+ ");";
+
+ try(Connection con = this.connect(); Statement stmt = con.createStatement())
+ {
+ stmt.execute(sql);
+ }
+ catch(SQLException ex)
+ {
+ Logger.getLogger(RecordManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ /**
+ * Block an ip
+ * @param ip
+ */
+ public void block(String ip)
+ {
+ String sql = "INSERT INTO blocklist VALUES ( ? , ? );";
+
+ try(Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql))
+ {
+ pstmt.setString(1, ip);
+ pstmt.setLong(2, System.currentTimeMillis());
+ pstmt.executeUpdate();
+ }
+ catch(SQLException ex)
+ {
+ Logger.getLogger(RecordManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ /**
+ * unblock an ip
+ * @param ip
+ */
+ public void unblock(String ip)
+ {
+ String sql = "DELETE FROM blocklist WHERE ip = ? ;";
+
+ try(Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql))
+ {
+ pstmt.setString(1, ip);
+ pstmt.executeUpdate();
+ }
+ catch(SQLException ex)
+ {
+ Logger.getLogger(RecordManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ /**
+ * unblock those ip who have passed blocktime in blocklist
+ */
+ public void unblockrun()
+ {
+ String sql = "DELETE FROM blocklist WHERE ? >= time + ?;";
+
+ try(Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql))
+ {
+ pstmt.setLong(1, System.currentTimeMillis());
+ pstmt.setLong(2, blocktime);
+ pstmt.executeUpdate();
+ }
+ catch(SQLException ex)
+ {
+ Logger.getLogger(RecordManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+
+ /**
+ * Check if user is blocked
+ * @param ip
+ * @return
+ */
+ public boolean isUserBlocked(String ip)
+ {
+ String sql = "SELECT * FROM blocklist WHERE ip = ? ;";
+
+ try(Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql))
+ {
+ pstmt.setString(1, ip);
+ ResultSet res = pstmt.executeQuery();
+ return res.next();
+ }
+ catch(SQLException ex)
+ {
+ Logger.getLogger(RecordManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return false;
+ }
+
+ /**
+ * Connect database
+ * @return
+ */
+ private Connection connect()
+ {
+ Connection con = null;
+ try
+ {
+ con = DriverManager.getConnection(Config.dburl, Config.dbusername, Config.dbpassword);
+ }
+ catch(SQLException ex)
+ {
+ Logger.getLogger(RecordManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return con;
+ }
+
+}
diff --git a/src/java/urrsm/sng/RequestListener.java b/src/java/urrsm/sng/RequestListener.java
new file mode 100644
index 0000000..5d2297b
--- /dev/null
+++ b/src/java/urrsm/sng/RequestListener.java
@@ -0,0 +1,25 @@
+package urrsm.sng;
+
+/**
+ *
+ * @author piyush
+ */
+
+import javax.servlet.annotation.WebListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+
+@WebListener()
+public class RequestListener implements ServletRequestListener {
+
+ @Override
+ public void requestDestroyed(ServletRequestEvent event) {
+
+ }
+
+ @Override
+ public void requestInitialized(ServletRequestEvent event) {
+ WebScocketEnd.ipaddress = event.getServletRequest().getRemoteAddr();
+ }
+
+}
diff --git a/src/java/urrsm/sng/USession.java b/src/java/urrsm/sng/USession.java
new file mode 100644
index 0000000..e2a8b63
--- /dev/null
+++ b/src/java/urrsm/sng/USession.java
@@ -0,0 +1,29 @@
+package urrsm.sng;
+
+import javax.websocket.Session;
+
+/**
+ *
+ * @author piyush
+ */
+public class USession
+{
+ Session peer;
+ String nick = "";
+ String channel = "";
+ String trip = new String();
+ String ip = "";
+
+ public USession(Session peer, String nick, String channel, String trip, long lastping)
+ {
+ this.peer = peer;
+ this.nick = nick;
+ this.channel = channel;
+ this.trip = trip;
+ }
+
+ public USession(Session peer)
+ {
+ this.peer = peer;
+ }
+}
diff --git a/src/java/urrsm/sng/WebScocketEnd.java b/src/java/urrsm/sng/WebScocketEnd.java
new file mode 100644
index 0000000..341f3a5
--- /dev/null
+++ b/src/java/urrsm/sng/WebScocketEnd.java
@@ -0,0 +1,402 @@
+package urrsm.sng;
+
+import com.google.gson.Gson;
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.Timer;
+import javax.websocket.EncodeException;
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+
+/**
+ *
+ * @author piyush
+ *
+ * Websocket Manager
+ *
+ */
+
+@ServerEndpoint("/uchatsserver")
+public class WebScocketEnd {
+
+ public static ArrayList sessions = new ArrayList();
+ public static String ipaddress = null;
+ public RecordManager recordmanager;
+ public Gson gson = new Gson();
+
+ public WebScocketEnd() throws ClassNotFoundException, SQLException
+ {
+ recordmanager = new RecordManager();
+ Timer timer = new javax.swing.Timer(1000, new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ recordmanager.unblockrun();
+ }
+ });
+ timer.start();
+ }
+
+ @OnMessage
+ public String onMessage(String message, Session session) throws IOException, EncodeException, NoSuchAlgorithmException {
+ JsonStructure json = gson.fromJson(message, JsonStructure.class);
+ USession ses = getSessionByPeer(session);
+ if(recordmanager.isUserBlocked(ipaddress))
+ {
+ return null;
+ }
+ // If user do Ping
+ if(json.cmd.equals("ping"))
+ {
+ // Do nothing
+ }
+
+ // If user join
+ else if(json.cmd.equals("join"))
+ {
+ String trip = " ";
+ if(json.nick.split("#").length != 1)
+ {
+ trip = calcHash(json.nick.split("#")[1]);
+ }
+
+ if(json.nick.split("#")[0].toLowerCase().equals(Config.admin.toLowerCase()) &&
+ !trip.toLowerCase().equals(calcHash(Config.password).toLowerCase()))
+ {
+ JsonStructure msg = new JsonStructure();
+ msg.cmd = "warn";
+ msg.text = "***Impersonating Admin???***";
+ session.getBasicRemote().sendText(gson.toJson(msg));
+ return null;
+ }
+
+ if(!json.nick.split("#")[0].matches("[a-zA-Z0-9_]*") && !(json.nick.split("#")[0].length() < 25))
+ {
+ JsonStructure msg = new JsonStructure();
+ msg.cmd = "warn";
+ msg.text = "Nickname must consist of up to 24 letters, numbers, and underscores!";
+ session.getBasicRemote().sendText(gson.toJson(msg));
+ return null;
+ }
+
+ if(json.channel.trim().equals(""))
+ {
+ JsonStructure msg = new JsonStructure();
+ msg.cmd = "warn";
+ msg.text = "Channel must not be spaces";
+ session.getBasicRemote().sendText(gson.toJson(msg));
+ return null;
+ }
+
+ for(USession sess : sessions)
+ {
+ if(sess.channel.equals(json.channel) && sess.nick.equals(json.nick.split("#")[0]))
+ {
+ JsonStructure msg = new JsonStructure();
+ msg.cmd = "warn";
+ msg.text = "Nickname already taken!";
+ session.getBasicRemote().sendText(gson.toJson(msg));
+ return null;
+ }
+ }
+
+ ses.nick = json.nick.split("#")[0];
+ ses.channel = json.channel;
+ ses.trip = trip;
+ ses.ip = ipaddress;
+
+ JsonStructure cmdonline = new JsonStructure();
+ cmdonline.cmd = "onlineAdd";
+ cmdonline.nick = json.nick.split("#")[0];
+ boardcast(gson.toJson(cmdonline),json.channel);
+
+ ArrayList nicks = new ArrayList();
+ for(USession sess : sessions)
+ {
+ if(sess.channel.endsWith(json.channel)) nicks.add(sess.nick);
+ }
+
+ JsonStructure onlinelist = new JsonStructure();
+ onlinelist.cmd = "onlineSet";
+ onlinelist.nicks = nicks;
+ session.getBasicRemote().sendText(gson.toJson(onlinelist));
+
+ }
+
+ //user sends message
+ else if(json.cmd.equals("chat"))
+ {
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "chat";
+ chat.nick = ses.nick;
+ chat.text = json.text;
+ chat.trip = ses.trip;
+ if(isAdmin(ses)) chat.admin = true;
+ if(isMod(ses)) chat.mod = true;
+ boardcast(gson.toJson(chat), ses.channel);
+ }
+
+ //user invites user to another random channel
+ else if(json.cmd.equals("invite"))
+ {
+ for(USession sess : sessions)
+ {
+ if(sess.nick.equals(json.nick))
+ {
+ String channel = String.valueOf(calcHash(String.valueOf(Math.random()))).substring(0, 6);
+
+ if(sess.peer == ses.peer)
+ {
+ return null;
+ }
+
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "info";
+ chat.text = ses.nick + " invited you to ?"+channel;
+ sess.peer.getBasicRemote().sendText(gson.toJson(chat));
+ chat.text = "you invited "+ses.nick +" to ?"+channel;
+ ses.peer.getBasicRemote().sendText(gson.toJson(chat));
+ }
+ }
+ }
+
+ // Status
+ if(json.cmd.equals("stats"))
+ {
+ ArrayList channels = new ArrayList();
+ for(USession sess : sessions)
+ {
+ if(channels.indexOf(sess.channel) == -1)
+ {
+ channels.add(sess.channel);
+ }
+ }
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "info";
+ chat.text = " Users Connected : "+sessions.size()+"\n"
+ + " Channels : "+channels.size();
+
+ boardcast(gson.toJson(chat), ses.channel);
+ }
+
+ // super power
+ // Ban a user
+ else if(json.cmd.equals("ban"))
+ {
+ if(!isAdmin(ses) && !isMod(ses))
+ {
+ return null;
+ }
+ for(USession sess : sessions)
+ {
+ if(ses.channel.equals(sess.channel) && json.nick.equals(sess.nick))
+ {
+ recordmanager.block(sess.ip);
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "chat";
+ chat.nick = "Server";
+ chat.text = "Ip "+sess.ip+" is banned!";
+ chat.trip = "server";
+ ses.peer.getBasicRemote().sendText(gson.toJson(chat));
+ }
+ }
+ }
+
+ // Unban a user
+ else if(json.cmd.equals("unban"))
+ {
+ if(!isAdmin(ses) && !isMod(ses))
+ {
+ return null;
+ }
+ recordmanager.unblock(json.ip);
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "chat";
+ chat.nick = "Server";
+ chat.text = "Ip "+json.ip+" is unbanned!";
+ chat.trip = "server";
+ ses.peer.getBasicRemote().sendText(gson.toJson(chat));
+
+ }
+
+ // VIP Super Power
+ // List users and their info
+ else if(json.cmd.equals("listUsers"))
+ {
+ if(!isAdmin(ses))
+ {
+ return null;
+ }
+ String data = "";
+ for(USession sess : sessions)
+ {
+ data = data + "\n"+sess.nick+"\t"+sess.channel+"\t"+sess.trip+"\t"+sess.ip;
+ }
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "chat";
+ chat.nick = "Server";
+ chat.text = "Nick\tChannel\tTrip\tIp\n"+data;
+ chat.trip = "server";
+ ses.peer.getBasicRemote().sendText(gson.toJson(chat));
+ }
+
+ // bordcast a message to all channel
+ else if(json.cmd.equals("broadcast"))
+ {
+ if(!isAdmin(ses))
+ {
+ return null;
+ }
+ JsonStructure chat = new JsonStructure();
+ chat.cmd = "chat";
+ chat.nick = "Server";
+ chat.text = json.text;
+ chat.trip = "server";
+ wildspread(gson.toJson(chat));
+ }
+ return null;
+ }
+
+ @OnOpen
+ public void onOpen (Session peer) throws IOException {
+ // Limit number of user and filter blocked users
+ if(sessions.size() < 10000 && !recordmanager.isUserBlocked(ipaddress))
+ {
+ sessions.add(new USession(peer, " ", " ", " ", System.currentTimeMillis()));
+ peer.getBasicRemote().sendText(ipaddress);
+ }
+ else
+ {
+ peer.getBasicRemote().sendText("Unable to book your seat in chatroom!");
+ }
+ }
+
+ @OnClose
+ public void onClose (Session peer) {
+ USession leavingsession = getSessionByPeer(peer);
+ if(!leavingsession.trip.equals(" "))
+ {
+ JsonStructure cmdonline = new JsonStructure();
+ cmdonline.cmd = "onlineRemove";
+ cmdonline.nick = leavingsession.nick;
+ String channel = leavingsession.channel;
+ sessions.remove(leavingsession);
+ boardcast(gson.toJson(cmdonline),channel);
+ }
+ else sessions.remove(leavingsession);
+ }
+
+ @OnError
+ public void onError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /**
+ * Get USession from Arraylist
+ * @param peer
+ * @return
+ */
+ public USession getSessionByPeer(Session peer)
+ {
+ for(USession session : sessions)
+ {
+ if(session.peer == peer) return session;
+ }
+ return null;
+ }
+
+ /**
+ * Send message to a channel
+ * @param message
+ * @param channel
+ */
+ public void boardcast(String message, String channel)
+ {
+ for(USession session : sessions)
+ {
+ try {
+ if(session.channel.equals(channel)) session.peer.getBasicRemote().sendText(message);
+ } catch (IOException ex) {
+ Logger.getLogger(WebScocketEnd.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ /**
+ * Send message to all channels
+ * @param message
+ */
+ public void wildspread(String message)
+ {
+ for(USession session : sessions)
+ {
+ try {
+ session.peer.getBasicRemote().sendText(message);
+ } catch (IOException ex) {
+ Logger.getLogger(WebScocketEnd.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ /**
+ * Calculate SHA-1 sum with salt
+ * @param passwd
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws UnsupportedEncodingException
+ */
+ public String calcHash(String passwd) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ MessageDigest crypt = MessageDigest.getInstance("SHA-1");
+ crypt.reset();
+ crypt.update(passwd.getBytes("UTF-8"));
+ String hash = new BigInteger(1, crypt.digest()).toString(16);
+ return hash.substring(0, 6);
+ }
+
+ /**
+ * Check if USession is of admin
+ * @param session
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws UnsupportedEncodingException
+ */
+ public boolean isAdmin(USession session) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ if(session.trip.toLowerCase().equals(calcHash(Config.password).toLowerCase()))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if USession is of mod
+ * @param session
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws UnsupportedEncodingException
+ */
+ public boolean isMod(USession session) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ for(String trip: Config.mods)
+ {
+ if(session.trip.toLowerCase().equals(trip.toLowerCase()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/web/META-INF/context.xml b/web/META-INF/context.xml
new file mode 100644
index 0000000..7c7a71a
--- /dev/null
+++ b/web/META-INF/context.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/web/base16/android.less b/web/base16/android.less
new file mode 100644
index 0000000..da0a06d
--- /dev/null
+++ b/web/base16/android.less
@@ -0,0 +1,24 @@
+//
+// Base16 Bright
+// Created by Fredrik Broman (http://frebro.com)
+// Based on the Android visual guidelines
+// http://developer.android.com/design/style/color.html
+//
+
+@base00: #212121;
+@base01: #333333;
+@base02: #626261;
+@base03: #858585;
+@base04: #dddddd;
+@base05: #e0e0e0;
+@base06: #f2f2f2;
+@base07: #ffffff;
+
+@base08: #e94749;
+@base09: #f18618;
+@base0A: #fbba37;
+@base0B: #99C21D;
+@base0C: #33B5E5;
+@base0D: #0099CC;
+@base0E: #9568AA;
+@base0F: #754595;
diff --git a/web/base16/atelier-dune.less b/web/base16/atelier-dune.less
new file mode 100644
index 0000000..eedd88b
--- /dev/null
+++ b/web/base16/atelier-dune.less
@@ -0,0 +1,21 @@
+//
+// Base16 Atelier Dune
+// Created by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/)
+//
+
+@base00: #20201d;
+@base01: #292824;
+@base02: #6e6b5e;
+@base03: #7d7a68;
+@base04: #999580;
+@base05: #a6a28c;
+@base06: #e8e4cf;
+@base07: #fefbec;
+@base08: #d73737;
+@base09: #b65611;
+@base0A: #cfb017;
+@base0B: #60ac39;
+@base0C: #1fad83;
+@base0D: #6684e1;
+@base0E: #b854d4;
+@base0F: #d43552;
diff --git a/web/base16/atelier-forest.less b/web/base16/atelier-forest.less
new file mode 100644
index 0000000..90bded9
--- /dev/null
+++ b/web/base16/atelier-forest.less
@@ -0,0 +1,21 @@
+//
+// Base16 Atelier Forest
+// Created by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/)
+//
+
+@base00: #1b1918;
+@base01: #2c2421;
+@base02: #68615e;
+@base03: #766e6b;
+@base04: #9c9491;
+@base05: #a8a19f;
+@base06: #e6e2e0;
+@base07: #f1efee;
+@base08: #f22c40;
+@base09: #df5320;
+@base0A: #d5911a;
+@base0B: #5ab738;
+@base0C: #00ad9c;
+@base0D: #407ee7;
+@base0E: #6666ea;
+@base0F: #c33ff3;
diff --git a/web/base16/atelier-heath.less b/web/base16/atelier-heath.less
new file mode 100644
index 0000000..5fe328c
--- /dev/null
+++ b/web/base16/atelier-heath.less
@@ -0,0 +1,21 @@
+//
+// Base16 Atelier Heath
+// Created by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/)
+//
+
+@base00: #1b181b;
+@base01: #292329;
+@base02: #695d69;
+@base03: #776977;
+@base04: #9e8f9e;
+@base05: #ab9bab;
+@base06: #d8cad8;
+@base07: #f7f3f7;
+@base08: #ca402b;
+@base09: #a65926;
+@base0A: #bb8a35;
+@base0B: #379a37;
+@base0C: #159393;
+@base0D: #516aec;
+@base0E: #7b59c0;
+@base0F: #cc33cc;
diff --git a/web/base16/atelier-lakeside.less b/web/base16/atelier-lakeside.less
new file mode 100644
index 0000000..4f6d2e2
--- /dev/null
+++ b/web/base16/atelier-lakeside.less
@@ -0,0 +1,21 @@
+//
+// Base16 Atelier Lakeside
+// Created by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/)
+//
+
+@base00: #161b1d;
+@base01: #1f292e;
+@base02: #516d7b;
+@base03: #5a7b8c;
+@base04: #7195a8;
+@base05: #7ea2b4;
+@base06: #c1e4f6;
+@base07: #ebf8ff;
+@base08: #d22d72;
+@base09: #935c25;
+@base0A: #8a8a0f;
+@base0B: #568c3b;
+@base0C: #2d8f6f;
+@base0D: #257fad;
+@base0E: #5d5db1;
+@base0F: #b72dd2;
diff --git a/web/base16/atelier-seaside.less b/web/base16/atelier-seaside.less
new file mode 100644
index 0000000..9f6d40d
--- /dev/null
+++ b/web/base16/atelier-seaside.less
@@ -0,0 +1,21 @@
+//
+// Base16 Atelier Seaside
+// Created by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/)
+//
+
+@base00: #131513;
+@base01: #242924;
+@base02: #5e6e5e;
+@base03: #687d68;
+@base04: #809980;
+@base05: #8ca68c;
+@base06: #cfe8cf;
+@base07: #f0fff0;
+@base08: #e6193c;
+@base09: #87711d;
+@base0A: #c3c322;
+@base0B: #29a329;
+@base0C: #1999b3;
+@base0D: #3d62f5;
+@base0E: #ad2bee;
+@base0F: #e619c3;
diff --git a/web/base16/bright.less b/web/base16/bright.less
new file mode 100644
index 0000000..6733ec3
--- /dev/null
+++ b/web/base16/bright.less
@@ -0,0 +1,21 @@
+//
+// Base16 Bright
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #000000;
+@base01: #303030;
+@base02: #505050;
+@base03: #b0b0b0;
+@base04: #d0d0d0;
+@base05: #e0e0e0;
+@base06: #f5f5f5;
+@base07: #ffffff;
+@base08: #fb0120;
+@base09: #fc6d24;
+@base0A: #fda331;
+@base0B: #a1c659;
+@base0C: #76c7b7;
+@base0D: #6fb3d2;
+@base0E: #d381c3;
+@base0F: #be643c;
diff --git a/web/base16/chalk.less b/web/base16/chalk.less
new file mode 100644
index 0000000..6d00446
--- /dev/null
+++ b/web/base16/chalk.less
@@ -0,0 +1,21 @@
+//
+// Base16 Chalk
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #151515;
+@base01: #202020;
+@base02: #303030;
+@base03: #505050;
+@base04: #b0b0b0;
+@base05: #d0d0d0;
+@base06: #e0e0e0;
+@base07: #f5f5f5;
+@base08: #fb9fb1;
+@base09: #eda987;
+@base0A: #ddb26f;
+@base0B: #acc267;
+@base0C: #12cfc0;
+@base0D: #6fc2ef;
+@base0E: #e1a3ee;
+@base0F: #deaf8f;
diff --git a/web/base16/default.less b/web/base16/default.less
new file mode 100644
index 0000000..29fe5fe
--- /dev/null
+++ b/web/base16/default.less
@@ -0,0 +1,21 @@
+//
+// Base16 Default
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #151515;
+@base01: #202020;
+@base02: #303030;
+@base03: #505050;
+@base04: #b0b0b0;
+@base05: #d0d0d0;
+@base06: #e0e0e0;
+@base07: #f5f5f5;
+@base08: #ac4142;
+@base09: #d28445;
+@base0A: #f4bf75;
+@base0B: #90a959;
+@base0C: #75b5aa;
+@base0D: #6a9fb5;
+@base0E: #aa759f;
+@base0F: #8f5536;
diff --git a/web/base16/eighties.less b/web/base16/eighties.less
new file mode 100644
index 0000000..436e79b
--- /dev/null
+++ b/web/base16/eighties.less
@@ -0,0 +1,21 @@
+//
+// Base16 Eighties
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #2d2d2d;
+@base01: #393939;
+@base02: #515151;
+@base03: #747369;
+@base04: #a09f93;
+@base05: #d3d0c8;
+@base06: #e8e6df;
+@base07: #f2f0ec;
+@base08: #f2777a;
+@base09: #f99157;
+@base0A: #ffcc66;
+@base0B: #99cc99;
+@base0C: #66cccc;
+@base0D: #6699cc;
+@base0E: #cc99cc;
+@base0F: #d27b53;
diff --git a/web/base16/greenscreen.less b/web/base16/greenscreen.less
new file mode 100644
index 0000000..9005fb7
--- /dev/null
+++ b/web/base16/greenscreen.less
@@ -0,0 +1,21 @@
+//
+// Base16 Greenscreen
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #001100;
+@base01: #003300;
+@base02: #005500;
+@base03: #007700;
+@base04: #009900;
+@base05: #00bb00;
+@base06: #00dd00;
+@base07: #00ff00;
+@base08: #007700;
+@base09: #009900;
+@base0A: #007700;
+@base0B: #00bb00;
+@base0C: #005500;
+@base0D: #009900;
+@base0E: #00bb00;
+@base0F: #005500;
diff --git a/web/base16/mocha.less b/web/base16/mocha.less
new file mode 100644
index 0000000..9899d20
--- /dev/null
+++ b/web/base16/mocha.less
@@ -0,0 +1,21 @@
+//
+// Base16 Mocha
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #3B3228;
+@base01: #534636;
+@base02: #645240;
+@base03: #7e705a;
+@base04: #b8afad;
+@base05: #d0c8c6;
+@base06: #e9e1dd;
+@base07: #f5eeeb;
+@base08: #cb6077;
+@base09: #d28b71;
+@base0A: #f4bc87;
+@base0B: #beb55b;
+@base0C: #7bbda4;
+@base0D: #8ab3b5;
+@base0E: #a89bb9;
+@base0F: #bb9584;
diff --git a/web/base16/monokai.less b/web/base16/monokai.less
new file mode 100644
index 0000000..1c5d242
--- /dev/null
+++ b/web/base16/monokai.less
@@ -0,0 +1,21 @@
+//
+// Base16 Monokai
+// Created by Wimer Hazenberg (http://www.monokai.nl)
+//
+
+@base00: #272822;
+@base01: #383830;
+@base02: #49483e;
+@base03: #75715e;
+@base04: #a59f85;
+@base05: #f8f8f2;
+@base06: #f5f4f1;
+@base07: #f9f8f5;
+@base08: #f92672;
+@base09: #fd971f;
+@base0A: #f4bf75;
+@base0B: #a6e22e;
+@base0C: #a1efe4;
+@base0D: #66d9ef;
+@base0E: #ae81ff;
+@base0F: #cc6633;
diff --git a/web/base16/nese.less b/web/base16/nese.less
new file mode 100644
index 0000000..6d3c431
--- /dev/null
+++ b/web/base16/nese.less
@@ -0,0 +1,26 @@
+//
+// Base16 NE.se color system
+// Created by Fredrik Broman (http://frebro.com)
+//
+// Reference on Adobe Kuler:
+// https://kuler.adobe.com/NESE-Warm-color-theme-2900819/
+// https://kuler.adobe.com/NESE-Cold-color-theme-2900847/
+//
+
+@base00: lighten(black, 1%); // #030303
+@base01: lighten(black, 5%); // #0c0c0c
+@base02: lighten(black, 20%); // #262626
+@base03: lighten(black, 45%); // #5f5f5f
+@base04: lighten(black, 65%); // #959595
+@base05: lighten(black, 80%); // #c1c1c1
+@base06: lighten(black, 95%); // #efefef
+@base07: lighten(black, 99%); // #fcfcfc
+
+@base08: #f73e30; // Red
+@base09: mix(@base08, @base0A, 50%); // Orange = #f97c37
+@base0A: #faba3d; // Yellow
+@base0B: #1ab857; // Green
+@base0C: mix(@base0B, @base0D, 50%); // Cyan = #29a188
+@base0D: #388bb8; // Blue
+@base0E: mix(@base0D, @base0F, 50%); // Purple = #9c73a7
+@base0F: #ff5a96; // Pink
diff --git a/web/base16/ocean.less b/web/base16/ocean.less
new file mode 100644
index 0000000..b91d1a8
--- /dev/null
+++ b/web/base16/ocean.less
@@ -0,0 +1,21 @@
+//
+// Base16 Ocean
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #2b303b;
+@base01: #343d46;
+@base02: #4f5b66;
+@base03: #65737e;
+@base04: #a7adba;
+@base05: #c0c5ce;
+@base06: #dfe1e8;
+@base07: #eff1f5;
+@base08: #bf616a;
+@base09: #d08770;
+@base0A: #ebcb8b;
+@base0B: #a3be8c;
+@base0C: #96b5b4;
+@base0D: #8fa1b3;
+@base0E: #b48ead;
+@base0F: #ab7967;
diff --git a/web/base16/pop.less b/web/base16/pop.less
new file mode 100644
index 0000000..933f585
--- /dev/null
+++ b/web/base16/pop.less
@@ -0,0 +1,21 @@
+//
+// Base16 Pop
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #000000;
+@base01: #202020;
+@base02: #303030;
+@base03: #505050;
+@base04: #b0b0b0;
+@base05: #d0d0d0;
+@base06: #e0e0e0;
+@base07: #ffffff;
+@base08: #eb008a;
+@base09: #f29333;
+@base0A: #f8ca12;
+@base0B: #37b349;
+@base0C: #00aabb;
+@base0D: #0e5a94;
+@base0E: #b31e8d;
+@base0F: #7a2d00;
diff --git a/web/base16/railscasts.less b/web/base16/railscasts.less
new file mode 100644
index 0000000..8a27403
--- /dev/null
+++ b/web/base16/railscasts.less
@@ -0,0 +1,21 @@
+//
+// Base16 Railscasts
+// Created by Ryan Bates (http://railscasts.com)
+//
+
+@base00: #2b2b2b;
+@base01: #272935;
+@base02: #3a4055;
+@base03: #5a647e;
+@base04: #d4cfc9;
+@base05: #e6e1dc;
+@base06: #f4f1ed;
+@base07: #f9f7f3;
+@base08: #da4939;
+@base09: #cc7833;
+@base0A: #ffc66d;
+@base0B: #a5c261;
+@base0C: #519f50;
+@base0D: #6d9cbe;
+@base0E: #b6b3eb;
+@base0F: #bc9458;
diff --git a/web/base16/solarized.less b/web/base16/solarized.less
new file mode 100644
index 0000000..a885f8e
--- /dev/null
+++ b/web/base16/solarized.less
@@ -0,0 +1,21 @@
+//
+// Base16 Solarized
+// Created by Ethan Schoonover (http://ethanschoonover.com/solarized)
+//
+
+@base00: #002b36;
+@base01: #073642;
+@base02: #586e75;
+@base03: #657b83;
+@base04: #839496;
+@base05: #93a1a1;
+@base06: #eee8d5;
+@base07: #fdf6e3;
+@base08: #dc322f;
+@base09: #cb4b16;
+@base0A: #b58900;
+@base0B: #859900;
+@base0C: #2aa198;
+@base0D: #268bd2;
+@base0E: #6c71c4;
+@base0F: #d33682;
diff --git a/web/base16/tomorrow.less b/web/base16/tomorrow.less
new file mode 100644
index 0000000..fb5b075
--- /dev/null
+++ b/web/base16/tomorrow.less
@@ -0,0 +1,21 @@
+//
+// Base16 Tomorrow
+// Created by Chris Kempson (http://chriskempson.com)
+//
+
+@base00: #1d1f21;
+@base01: #282a2e;
+@base02: #373b41;
+@base03: #969896;
+@base04: #b4b7b4;
+@base05: #c5c8c6;
+@base06: #e0e0e0;
+@base07: #ffffff;
+@base08: #cc6666;
+@base09: #de935f;
+@base0A: #f0c674;
+@base0B: #b5bd68;
+@base0C: #8abeb7;
+@base0D: #81a2be;
+@base0E: #b294bb;
+@base0F: #a3685a;
diff --git a/web/client.js b/web/client.js
new file mode 100644
index 0000000..4e3842e
--- /dev/null
+++ b/web/client.js
@@ -0,0 +1,537 @@
+var frontpage = [
+ " _ _ ___ _ _ ",
+ " | || || _|| |_ ___| |_ __",
+ " | || || |_ | |_ || _||_ |",
+ " |____||___||_|_|__/|_| |__|",
+ "",
+ "",
+ "Welcome to UChats, a minimal, distraction-free chat application made with java. It is clone of Hack.chat(https://github.com/AndrewBelt/hack.chat)",
+ "Channels are created and joined by going to https://uchats.herokuapp.com/?your-channel. There are no channel lists, so a secret channel name can be used for private discussions.",
+ "",
+ "Here are some pre-made channels you can join:",
+ "?devs ?meta",
+ "?math ?physics ?chemistry",
+ "?technology ?programming",
+ "?games ?banana",
+ "And here's a random one generated just for you: ?" + Math.random().toString(36).substr(2, 8),
+ "",
+ "",
+ "Formatting:",
+ "Whitespace is preserved, so source code can be pasted verbatim.",
+ "Surround LaTeX with a dollar sign for inline style $\\zeta(2) = \\pi^2/6$, and two dollars for display. $$\\int_0^1 \\int_0^1 \\frac{1}{1-xy} dx dy = \\frac{\\pi^2}{6}$$",
+ "",
+ "GitHub: https://github.com/PiyushXCoder/uchat",
+ "",
+ "Server and web client released under the MIT license.",
+ "No message history is retained on the UChats server.",
+].join("\n")
+
+function $(query) {return document.querySelector(query)}
+
+function localStorageGet(key) {
+ try {
+ return window.localStorage[key]
+ }
+ catch(e) {}
+}
+
+function localStorageSet(key, val) {
+ try {
+ window.localStorage[key] = val
+ }
+ catch(e) {}
+}
+
+
+var ws
+var myNick = localStorageGet('my-nick')
+var myChannel = window.location.search.replace(/^\?/, '')
+var lastSent = [""]
+var lastSentPos = 0
+
+
+// Ping server every 50 seconds to retain WebSocket connection
+window.setInterval(function() {
+ send({cmd: 'ping'})
+}, 50000)
+
+
+function join(channel) {
+
+ if (document.domain == 'uchats.herokuapp.com') {
+ ws = new WebSocket('wss://uchats.herokuapp.com/uchatsserver')
+ }
+ else {
+ // for local installs
+ ws = new WebSocket('ws://' + location.hostname+":"+location.port + '/uchatsserver')
+ }
+
+ var wasConnected = false
+
+ ws.onopen = function() {
+ if (!wasConnected) {
+ if (location.hash) {
+ myNick = location.hash.substr(1)
+ }
+ else {
+ myNick = prompt('Nickname:', myNick)
+ }
+ }
+ if (myNick) {
+ localStorageSet('my-nick', myNick)
+ send({cmd: 'join', channel: channel, nick: myNick})
+ }
+ wasConnected = true
+ }
+
+ ws.onclose = function() {
+ if (wasConnected) {
+ pushMessage({nick: '!', text: "Server disconnected. Attempting to reconnect..."})
+ }
+ window.setTimeout(function() {
+ join(channel)
+ }, 2000)
+ }
+
+ ws.onmessage = function(message) {
+ var args = JSON.parse(message.data)
+ var cmd = args.cmd
+ var command = COMMANDS[cmd]
+ command.call(null, args)
+ }
+}
+
+
+var COMMANDS = {
+ chat: function(args) {
+ if (ignoredUsers.indexOf(args.nick) >= 0) {
+ return
+ }
+ pushMessage(args)
+ },
+ info: function(args) {
+ args.nick = '*'
+ pushMessage(args)
+ },
+ warn: function(args) {
+ args.nick = '!'
+ pushMessage(args)
+ },
+ onlineSet: function(args) {
+ var nicks = args.nicks
+ usersClear()
+ nicks.forEach(function(nick) {
+ userAdd(nick)
+ })
+ pushMessage({nick: '*', text: "Users online: " + nicks.join(", ")})
+ },
+ onlineAdd: function(args) {
+ var nick = args.nick
+ userAdd(nick)
+ if ($('#joined-left').checked) {
+ pushMessage({nick: '*', text: nick + " joined"})
+ }
+ },
+ onlineRemove: function(args) {
+ var nick = args.nick
+ userRemove(nick)
+ if ($('#joined-left').checked) {
+ pushMessage({nick: '*', text: nick + " left"})
+ }
+ },
+}
+
+
+function pushMessage(args) {
+ // Message container
+ var messageEl = document.createElement('div')
+ messageEl.classList.add('message')
+
+ if (args.nick == myNick) {
+ messageEl.classList.add('me')
+ }
+ else if (args.nick == '!') {
+ messageEl.classList.add('warn')
+ }
+ else if (args.nick == '*') {
+ messageEl.classList.add('info')
+ }
+ else if (args.admin) {
+ messageEl.classList.add('admin')
+ }
+ else if (args.mod) {
+ messageEl.classList.add('mod')
+ }
+
+ // Nickname
+ var nickSpanEl = document.createElement('span')
+ nickSpanEl.classList.add('nick')
+ messageEl.appendChild(nickSpanEl)
+
+ if (args.trip) {
+ var tripEl = document.createElement('span')
+ tripEl.textContent = args.trip + " "
+ tripEl.classList.add('trip')
+ nickSpanEl.appendChild(tripEl)
+ }
+
+ if (args.nick) {
+ var nickLinkEl = document.createElement('a')
+ nickLinkEl.textContent = args.nick
+ nickLinkEl.onclick = function() {
+ insertAtCursor("@" + args.nick + " ")
+ $('#chatinput').focus()
+ }
+ var date = new Date(args.time || Date.now())
+ nickLinkEl.title = date.toLocaleString()
+ nickSpanEl.appendChild(nickLinkEl)
+ }
+
+ // Text
+ var textEl = document.createElement('pre')
+ textEl.classList.add('text')
+
+ textEl.textContent = args.text || ''
+ textEl.innerHTML = textEl.innerHTML.replace(/(\?|https?:\/\/)\S+?(?=[,.!?:)]?\s|$)/g, parseLinks)
+
+ if ($('#parse-latex').checked) {
+ // Temporary hotfix for \rule spamming, see https://github.com/Khan/KaTeX/issues/109
+ textEl.innerHTML = textEl.innerHTML.replace(/\\rule|\\\\\s*\[.*?\]/g, '')
+ try {
+ renderMathInElement(textEl, {delimiters: [
+ {left: "$$", right: "$$", display: true},
+ {left: "$", right: "$", display: false},
+ ]})
+ }
+ catch (e) {
+ console.warn(e)
+ }
+ }
+
+ messageEl.appendChild(textEl)
+
+ // Scroll to bottom
+ var atBottom = isAtBottom()
+ $('#messages').appendChild(messageEl)
+ if (atBottom) {
+ window.scrollTo(0, document.body.scrollHeight)
+ }
+
+ unread += 1
+ updateTitle()
+}
+
+
+function insertAtCursor(text) {
+ var input = $('#chatinput')
+ var start = input.selectionStart || 0
+ var before = input.value.substr(0, start)
+ var after = input.value.substr(start)
+ before += text
+ input.value = before + after
+ input.selectionStart = input.selectionEnd = before.length
+ updateInputSize()
+}
+
+
+function send(data) {
+ if (ws && ws.readyState == ws.OPEN) {
+ ws.send(JSON.stringify(data))
+ }
+}
+
+
+function parseLinks(g0) {
+ var a = document.createElement('a')
+ a.innerHTML = g0
+ var url = a.textContent
+ a.href = url
+ a.target = '_blank'
+ return a.outerHTML
+}
+
+
+var windowActive = true
+var unread = 0
+
+window.onfocus = function() {
+ windowActive = true
+ updateTitle()
+}
+
+window.onblur = function() {
+ windowActive = false
+}
+
+window.onscroll = function() {
+ if (isAtBottom()) {
+ updateTitle()
+ }
+}
+
+function isAtBottom() {
+ return (window.innerHeight + window.scrollY) >= (document.body.scrollHeight - 1)
+}
+
+function updateTitle() {
+ if (windowActive && isAtBottom()) {
+ unread = 0
+ }
+
+ var title
+ if (myChannel) {
+ title = "?" + myChannel
+ }
+ else {
+ title = "UChats"
+ }
+ if (unread > 0) {
+ title = '(' + unread + ') ' + title
+ }
+ document.title = title
+}
+
+/* footer */
+
+$('#footer').onclick = function() {
+ $('#chatinput').focus()
+}
+
+$('#chatinput').onkeydown = function(e) {
+ if (e.keyCode == 13 /* ENTER */ && !e.shiftKey) {
+ e.preventDefault()
+ // Submit message
+ if (e.target.value != '') {
+ var text = e.target.value
+ e.target.value = ''
+ send({cmd: 'chat', text: text})
+ lastSent[0] = text
+ lastSent.unshift("")
+ lastSentPos = 0
+ updateInputSize()
+ }
+ }
+ else if (e.keyCode == 38 /* UP */) {
+ // Restore previous sent messages
+ if (e.target.selectionStart === 0 && lastSentPos < lastSent.length - 1) {
+ e.preventDefault()
+ if (lastSentPos == 0) {
+ lastSent[0] = e.target.value
+ }
+ lastSentPos += 1
+ e.target.value = lastSent[lastSentPos]
+ e.target.selectionStart = e.target.selectionEnd = e.target.value.length
+ updateInputSize()
+ }
+ }
+ else if (e.keyCode == 40 /* DOWN */) {
+ if (e.target.selectionStart === e.target.value.length && lastSentPos > 0) {
+ e.preventDefault()
+ lastSentPos -= 1
+ e.target.value = lastSent[lastSentPos]
+ e.target.selectionStart = e.target.selectionEnd = 0
+ updateInputSize()
+ }
+ }
+ else if (e.keyCode == 27 /* ESC */) {
+ e.preventDefault()
+ // Clear input field
+ e.target.value = ""
+ lastSentPos = 0
+ lastSent[lastSentPos] = ""
+ updateInputSize()
+ }
+ else if (e.keyCode == 9 /* TAB */) {
+ // Tab complete nicknames starting with @
+ e.preventDefault()
+ var pos = e.target.selectionStart || 0
+ var text = e.target.value
+ var index = text.lastIndexOf('@', pos)
+ if (index >= 0) {
+ var stub = text.substring(index + 1, pos).toLowerCase()
+ // Search for nick beginning with stub
+ var nicks = onlineUsers.filter(function(nick) {
+ return nick.toLowerCase().indexOf(stub) == 0
+ })
+ if (nicks.length == 1) {
+ insertAtCursor(nicks[0].substr(stub.length) + " ")
+ }
+ }
+ }
+}
+
+
+function updateInputSize() {
+ var atBottom = isAtBottom()
+
+ var input = $('#chatinput')
+ input.style.height = 0
+ input.style.height = input.scrollHeight + 'px'
+ document.body.style.marginBottom = $('#footer').offsetHeight + 'px'
+
+ if (atBottom) {
+ window.scrollTo(0, document.body.scrollHeight)
+ }
+}
+
+$('#chatinput').oninput = function() {
+ updateInputSize()
+}
+
+updateInputSize()
+
+
+/* sidebar */
+
+$('#sidebar').onmouseenter = $('#sidebar').ontouchstart = function(e) {
+ $('#sidebar-content').classList.remove('hidden')
+ e.stopPropagation()
+}
+
+$('#sidebar').onmouseleave = document.ontouchstart = function() {
+ if (!$('#pin-sidebar').checked) {
+ $('#sidebar-content').classList.add('hidden')
+ }
+}
+
+$('#clear-messages').onclick = function() {
+ // Delete children elements
+ var messages = $('#messages')
+ while (messages.firstChild) {
+ messages.removeChild(messages.firstChild)
+ }
+}
+
+// Restore settings from localStorage
+
+if (localStorageGet('pin-sidebar') == 'true') {
+ $('#pin-sidebar').checked = true
+ $('#sidebar-content').classList.remove('hidden')
+}
+if (localStorageGet('joined-left') == 'false') {
+ $('#joined-left').checked = false
+}
+if (localStorageGet('parse-latex') == 'false') {
+ $('#parse-latex').checked = false
+}
+
+$('#pin-sidebar').onchange = function(e) {
+ localStorageSet('pin-sidebar', !!e.target.checked)
+}
+$('#joined-left').onchange = function(e) {
+ localStorageSet('joined-left', !!e.target.checked)
+}
+$('#parse-latex').onchange = function(e) {
+ localStorageSet('parse-latex', !!e.target.checked)
+}
+
+// User list
+
+var onlineUsers = []
+var ignoredUsers = []
+
+function userAdd(nick) {
+ var user = document.createElement('a')
+ user.textContent = nick
+ user.onclick = function(e) {
+ userInvite(nick)
+ }
+ var userLi = document.createElement('li')
+ userLi.appendChild(user)
+ $('#users').appendChild(userLi)
+ onlineUsers.push(nick)
+}
+
+function userRemove(nick) {
+ var users = $('#users')
+ var children = users.children
+ for (var i = 0; i < children.length; i++) {
+ var user = children[i]
+ if (user.textContent == nick) {
+ users.removeChild(user)
+ }
+ }
+ var index = onlineUsers.indexOf(nick)
+ if (index >= 0) {
+ onlineUsers.splice(index, 1)
+ }
+}
+
+function usersClear() {
+ var users = $('#users')
+ while (users.firstChild) {
+ users.removeChild(users.firstChild)
+ }
+ onlineUsers.length = 0
+}
+
+function userInvite(nick) {
+ send({cmd: 'invite', nick: nick})
+}
+
+function userIgnore(nick) {
+ ignoredUsers.push(nick)
+}
+
+/* color scheme switcher */
+
+var schemes = [
+ 'android',
+ 'atelier-dune',
+ 'atelier-forest',
+ 'atelier-heath',
+ 'atelier-lakeside',
+ 'atelier-seaside',
+ 'bright',
+ 'chalk',
+ 'default',
+ 'eighties',
+ 'greenscreen',
+ 'mocha',
+ 'monokai',
+ 'nese',
+ 'ocean',
+ 'pop',
+ 'railscasts',
+ 'solarized',
+ 'tomorrow',
+]
+
+var currentScheme = 'atelier-dune'
+
+function setScheme(scheme) {
+ currentScheme = scheme
+ $('#scheme-link').href = "/schemes/" + scheme + ".css"
+ localStorageSet('scheme', scheme)
+}
+
+// Add scheme options to dropdown selector
+schemes.forEach(function(scheme) {
+ var option = document.createElement('option')
+ option.textContent = scheme
+ option.value = scheme
+ $('#scheme-selector').appendChild(option)
+})
+
+$('#scheme-selector').onchange = function(e) {
+ setScheme(e.target.value)
+}
+
+// Load sidebar configaration values from local storage if available
+if (localStorageGet('scheme')) {
+ setScheme(localStorageGet('scheme'))
+}
+
+$('#scheme-selector').value = currentScheme
+
+
+/* main */
+
+if (myChannel == '') {
+ pushMessage({text: frontpage})
+ $('#footer').classList.add('hidden')
+ $('#sidebar').classList.add('hidden')
+}
+else {
+ join(myChannel)
+}
diff --git a/web/index.jsp b/web/index.jsp
new file mode 100644
index 0000000..cd09586
--- /dev/null
+++ b/web/index.jsp
@@ -0,0 +1,37 @@
+
+
+
+
+
+ hack.chat
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/jquery-3.2.1.min.js b/web/jquery-3.2.1.min.js
new file mode 100755
index 0000000..644d35e
--- /dev/null
+++ b/web/jquery-3.2.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
+a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/
+```
+
+#### In-browser rendering
+
+Call `katex.render` with a TeX expression and a DOM element to render into:
+
+```js
+katex.render("c = \\pm\\sqrt{a^2 + b^2}", element);
+```
+
+If KaTeX can't parse the expression, it throws a `katex.ParseError` error.
+
+#### Server side rendering or rendering to a string
+
+To generate HTML on the server or to generate an HTML string of the rendered math, you can use `katex.renderToString`:
+
+```js
+var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}");
+// '...'
+```
+
+Make sure to include the CSS and font files, but there is no need to include the JavaScript. Like `render`, `renderToString` throws if it can't parse the expression.
+
+#### Rendering options
+
+You can provide an object of options as the last argument to `katex.render` and `katex.renderToString`. Available options are:
+
+- `displayMode`: `boolean`. If `true` the math will be rendered in display mode, which will put the math in display style (so `\int` and `\sum` are large, for example), and will center the math on the page on its own line. If `false` the math will be rendered in inline mode. (default: `false`)
+
+For example:
+
+```js
+katex.render("c = \\pm\\sqrt{a^2 + b^2}", element, { displayMode: true });
+```
+
+#### Automatic rendering of math on a page
+
+Math on the page can be automatically rendered using the auto-render extension. See [the Auto-render README](contrib/auto-render/README.md) for more information.
+
+## Contributing
+
+See [CONTRIBUTING.md](CONTRIBUTING.md)
+
+## License
+
+KaTeX is licensed under the [MIT License](http://opensource.org/licenses/MIT).
diff --git a/web/katex/katex/contrib/auto-render.min.js b/web/katex/katex/contrib/auto-render.min.js
new file mode 100644
index 0000000..5eab253
--- /dev/null
+++ b/web/katex/katex/contrib/auto-render.min.js
@@ -0,0 +1 @@
+(function(e){if("function"==typeof bootstrap)bootstrap("rendermathinelement",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeRenderMathInElement=e}else"undefined"!=typeof window?window.renderMathInElement=e():global.renderMathInElement=e()})(function(){var e,t,r,n,a;return function i(e,t,r){function n(o,l){if(!t[o]){if(!e[o]){var f=typeof require=="function"&&require;if(!l&&f)return f(o,!0);if(a)return a(o,!0);throw new Error("Cannot find module '"+o+"'")}var s=t[o]={exports:{}};e[o][0].call(s.exports,function(t){var r=e[o][1][t];return n(r?r:t)},s,s.exports,i,e,t,r)}return t[o].exports}var a=typeof require=="function"&&require;for(var o=0;o.katex{display:inline-block}.katex{font:400 1.21em KaTeX_Main;line-height:1.2;white-space:nowrap;text-indent:0}.katex .katex-html{display:inline-block}.katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .base,.katex .strut{display:inline-block}.katex .mathit{font-family:KaTeX_Math;font-style:italic}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .amsrm,.katex .mathbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr{font-family:KaTeX_Script}.katex .mathsf{font-family:KaTeX_SansSerif}.katex .mainit{font-family:KaTeX_Main;font-style:italic}.katex .textstyle>.mord+.mop{margin-left:.16667em}.katex .textstyle>.mord+.mbin{margin-left:.22222em}.katex .textstyle>.mord+.mrel{margin-left:.27778em}.katex .textstyle>.mop+.mop,.katex .textstyle>.mop+.mord,.katex .textstyle>.mord+.minner{margin-left:.16667em}.katex .textstyle>.mop+.mrel{margin-left:.27778em}.katex .textstyle>.mop+.minner{margin-left:.16667em}.katex .textstyle>.mbin+.minner,.katex .textstyle>.mbin+.mop,.katex .textstyle>.mbin+.mopen,.katex .textstyle>.mbin+.mord{margin-left:.22222em}.katex .textstyle>.mrel+.minner,.katex .textstyle>.mrel+.mop,.katex .textstyle>.mrel+.mopen,.katex .textstyle>.mrel+.mord{margin-left:.27778em}.katex .textstyle>.mclose+.mop{margin-left:.16667em}.katex .textstyle>.mclose+.mbin{margin-left:.22222em}.katex .textstyle>.mclose+.mrel{margin-left:.27778em}.katex .textstyle>.mclose+.minner,.katex .textstyle>.minner+.mop,.katex .textstyle>.minner+.mord,.katex .textstyle>.mpunct+.mclose,.katex .textstyle>.mpunct+.minner,.katex .textstyle>.mpunct+.mop,.katex .textstyle>.mpunct+.mopen,.katex .textstyle>.mpunct+.mord,.katex .textstyle>.mpunct+.mpunct,.katex .textstyle>.mpunct+.mrel{margin-left:.16667em}.katex .textstyle>.minner+.mbin{margin-left:.22222em}.katex .textstyle>.minner+.mrel{margin-left:.27778em}.katex .mclose+.mop,.katex .minner+.mop,.katex .mop+.mop,.katex .mop+.mord,.katex .mord+.mop,.katex .textstyle>.minner+.minner,.katex .textstyle>.minner+.mopen,.katex .textstyle>.minner+.mpunct{margin-left:.16667em}.katex .reset-textstyle.textstyle{font-size:1em}.katex .reset-textstyle.scriptstyle{font-size:.7em}.katex .reset-textstyle.scriptscriptstyle{font-size:.5em}.katex .reset-scriptstyle.textstyle{font-size:1.42857em}.katex .reset-scriptstyle.scriptstyle{font-size:1em}.katex .reset-scriptstyle.scriptscriptstyle{font-size:.71429em}.katex .reset-scriptscriptstyle.textstyle{font-size:2em}.katex .reset-scriptscriptstyle.scriptstyle{font-size:1.4em}.katex .reset-scriptscriptstyle.scriptscriptstyle{font-size:1em}.katex .style-wrap{position:relative}.katex .vlist{display:inline-block}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist .baseline-fix{display:inline-table;table-layout:fixed}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{width:100%}.katex .mfrac .frac-line:before{border-bottom-style:solid;border-bottom-width:1px;content:"";display:block}.katex .mfrac .frac-line:after{border-bottom-style:solid;border-bottom-width:.04em;content:"";display:block;margin-top:-1px}.katex .mspace{display:inline-block}.katex .mspace.negativethinspace{margin-left:-.16667em}.katex .mspace.thinspace{width:.16667em}.katex .mspace.mediumspace{width:.22222em}.katex .mspace.thickspace{width:.27778em}.katex .mspace.enspace{width:.5em}.katex .mspace.quad{width:1em}.katex .mspace.qquad{width:2em}.katex .llap,.katex .rlap{width:0;position:relative}.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .rlap>.inner{left:0}.katex .katex-logo .a{font-size:.75em;margin-left:-.32em;position:relative;top:-.2em}.katex .katex-logo .t{margin-left:-.23em}.katex .katex-logo .e{margin-left:-.1667em;position:relative;top:.2155em}.katex .katex-logo .x{margin-left:-.125em}.katex .rule{display:inline-block;border-style:solid;position:relative}.katex .overline .overline-line{width:100%}.katex .overline .overline-line:before{border-bottom-style:solid;border-bottom-width:1px;content:"";display:block}.katex .overline .overline-line:after{border-bottom-style:solid;border-bottom-width:.04em;content:"";display:block;margin-top:-1px}.katex .sqrt>.sqrt-sign{position:relative}.katex .sqrt .sqrt-line{width:100%}.katex .sqrt .sqrt-line:before{border-bottom-style:solid;border-bottom-width:1px;content:"";display:block}.katex .sqrt .sqrt-line:after{border-bottom-style:solid;border-bottom-width:.04em;content:"";display:block;margin-top:-1px}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer,.katex .sizing{display:inline-block}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:2em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:3.46em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:4.14em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.98em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.47142857em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.95714286em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.55714286em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.875em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.125em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.25em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.5em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.8em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.1625em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.5875em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:3.1125em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.77777778em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.88888889em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.6em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.92222222em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.3em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.76666667em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.7em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.8em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.9em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.2em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.44em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.73em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:2.07em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.49em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.58333333em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.66666667em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.75em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.83333333em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44166667em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.725em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.075em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.48611111em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.55555556em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.625em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.69444444em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.20138889em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.4375em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72916667em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.28901734em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.40462428em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.46242775em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.52023121em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.57803468em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69364162em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83236994em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.19653179em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.43930636em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.24154589em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.33816425em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.38647343em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.43478261em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.48309179em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.57971014em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69565217em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83574879em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20289855em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.20080321em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2811245em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.32128514em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.36144578em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.40160643em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48192771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57831325em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69477912em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8313253em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{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:.12em}.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist>span,.katex .op-limits>.vlist>span{text-align:center}.katex .accent .accent-body>span{width:0}.katex .accent .accent-body.accent-vec>span{position:relative;left:.326em}.katex .arraycolsep{display:inline-block}.katex .col-align-c>.vlist{text-align:center}.katex .col-align-l>.vlist{text-align:left}.katex .col-align-r>.vlist{text-align:right}
\ No newline at end of file
diff --git a/web/katex/katex/katex.min.js b/web/katex/katex/katex.min.js
new file mode 100644
index 0000000..578cb23
--- /dev/null
+++ b/web/katex/katex/katex.min.js
@@ -0,0 +1,6 @@
+(function(e){if("function"==typeof bootstrap)bootstrap("katex",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeKatex=e}else"undefined"!=typeof window?window.katex=e():global.katex=e()})(function(){var e,t,i,h,a;return function r(e,t,i){function h(l,s){if(!t[l]){if(!e[l]){var p=typeof require=="function"&&require;if(!s&&p)return p(l,!0);if(a)return a(l,!0);throw new Error("Cannot find module '"+l+"'")}var c=t[l]={exports:{}};e[l][0].call(c.exports,function(t){var i=e[l][1][t];return h(i?i:t)},c,c.exports,r,e,t,i)}return t[l].exports}var a=typeof require=="function"&&require;for(var l=0;l:]/,/[,;]/,/['\^_{}]/,/[(\[]/,/[)\]?!]/,/~/,/&/,/\\\\/];var p=[/[a-zA-Z0-9`!@*()-=+\[\]'";:?\/.,]/,/[{}]/,/~/,/&/,/\\\\/];var c=/\s*/;var n=/ +|\\ +/;var g=/\\(?:[a-zA-Z]+|.)/;r.prototype._innerLex=function(e,t,i){var r=this._input;var s;if(i){s=h(c,r,e)[0];e+=s.length}else{s=h(n,r,e);if(s!==null){return new l(" ",null,e+s[0].length)}}if(e===r.length){return new l("EOF",null,e)}var p;if(p=h(g,r,e)){return new l(p[0],null,e+p[0].length)}else{for(var o=0;ou){return this.parseFunction(e,t)}else{throw new c("Got function '"+r.result.result+"' with no arguments "+"as "+a,this.lexer,e)}}else{return r.result}};n.prototype.parseAtom=function(e,t){var i=this.parseImplicitGroup(e,t);if(t==="text"){return i}var h;if(!i){h=e;i=undefined}else{h=i.position}var a;var r;var l;while(true){var s=this.lexer.lex(h,t);if(s.text==="^"){if(a){throw new c("Double superscript",this.lexer,h)}l=this.handleSupSubscript(s.position,t,s.text,"superscript");h=l.position;a=l.result}else if(s.text==="_"){if(r){throw new c("Double subscript",this.lexer,h)}l=this.handleSupSubscript(s.position,t,s.text,"subscript");h=l.position;r=l.result}else if(s.text==="'"){var p=new g("textord","\\prime",t);var n=[p];h=s.position;while((s=this.lexer.lex(h,t)).text==="'"){n.push(p);h=s.position}a=new g("ordgroup",n,t)}else{break}}if(a||r){return new o(new g("supsub",{base:i&&i.result,sup:a,sub:r},t),h)}else{return i}};var k=["\\tiny","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];var m=["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"];n.prototype.parseImplicitGroup=function(e,t){var i=this.parseSymbol(e,t);if(!i||!i.result){return this.parseFunction(e,t)}var h=i.result.result;var r;if(h==="\\left"){var l=this.parseFunction(e,t);r=this.parseExpression(l.position,t,false);this.expect(r.peek,"\\right");var p=this.parseFunction(r.position,t);return new o(new g("leftright",{body:r.result,left:l.result.value.value,right:p.result.value.value},t),p.position)}else if(h==="\\begin"){var n=this.parseFunction(e,t);var d=n.result.value.name;if(!a.hasOwnProperty(d)){throw new c("No such environment: "+d,this.lexer,n.result.value.namepos)}var w=a[d];var u=[null,t,d];var f=this.parseArguments(n.position,t,"\\begin{"+d+"}",w,u);u[0]=f;var v=w.handler.apply(this,u);var y=this.lexer.lex(v.position,t);this.expect(y,"\\end");var x=this.parseFunction(v.position,t);if(x.result.value.name!==d){throw new c("Mismatch: \\begin{"+d+"} matched "+"by \\end{"+x.result.value.name+"}",this.lexer,x.namepos)}v.position=x.position;return v}else if(s.contains(k,h)){r=this.parseExpression(i.result.position,t,false);return new o(new g("sizing",{size:"size"+(s.indexOf(k,h)+1),value:r.result},t),r.position)}else if(s.contains(m,h)){r=this.parseExpression(i.result.position,t,true);return new o(new g("styling",{style:h.slice(1,h.length-5),value:r.result},t),r.position)}else{return this.parseFunction(e,t)}};n.prototype.parseFunction=function(e,t){var i=this.parseGroup(e,t);if(i){if(i.isFunction){var a=i.result.result;var r=h.funcs[a];if(t==="text"&&!r.allowedInText){throw new c("Can't use function '"+a+"' in text mode",this.lexer,i.position)}var l=[a];var s=this.parseArguments(i.result.position,t,a,r,l);var p=h.funcs[a].handler.apply(this,l);return new o(new g(p.type,p,t),s)}else{return i.result}}else{return null}};n.prototype.parseArguments=function(e,t,i,a,r){var l=a.numArgs+a.numOptionalArgs;if(l===0){return e}var s=e;var p=a.greediness;var n=[s];for(var g=0;gp){w=this.parseFunction(s,t)}else{throw new c("Got function '"+d.result.result+"' as "+"argument to '"+i+"'",this.lexer,d.result.position-1)}}else{w=d.result}r.push(w.result);n.push(w.position);s=w.position}r.push(n);return s};n.prototype.parseSpecialGroup=function(e,t,i,h){if(t==="original"){t=i}if(t==="color"||t==="size"){var a=this.lexer.lex(e,i);if(h&&a.text!=="["){return null}this.expect(a,h?"[":"{");var r=this.lexer.lex(a.position,t);var l;if(t==="color"){l=r.text}else{l=r.data}var s=this.lexer.lex(r.position,i);this.expect(s,h?"]":"}");return new d(new o(new g(t,l,i),s.position),false)}else if(t==="text"){var p=this.lexer.lex(e,"whitespace");e=p.position}if(h){return this.parseOptionalGroup(e,t)}else{return this.parseGroup(e,t)}};n.prototype.parseGroup=function(e,t){var i=this.lexer.lex(e,t);if(i.text==="{"){var h=this.parseExpression(i.position,t,false);var a=this.lexer.lex(h.position,t);this.expect(a,"}");return new d(new o(new g("ordgroup",h.result,t),a.position),false)}else{return this.parseSymbol(e,t)}};n.prototype.parseOptionalGroup=function(e,t){var i=this.lexer.lex(e,t);if(i.text==="["){var h=this.parseExpression(i.position,t,false,"]");var a=this.lexer.lex(h.position,t);this.expect(a,"]");return new d(new o(new g("ordgroup",h.result,t),a.position),false)}else{return null}};n.prototype.parseSymbol=function(e,t){var i=this.lexer.lex(e,t);if(h.funcs[i.text]){return new d(new o(i.text,i.position),true)}else if(l[t][i.text]){return new d(new o(new g(l[t][i.text].group,i.text,t),i.position),false)}else{return null}};n.prototype.ParseNode=g;t.exports=n},{"./Lexer":3,"./ParseError":5,"./environments":15,"./functions":17,"./parseData":19,"./symbols":21,"./utils":22}],7:[function(e,t,i){function h(e,t){return e===undefined?t:e}function a(e){e=e||{};this.displayMode=h(e.displayMode,false)}t.exports=a},{}],8:[function(e,t,i){function h(e,t,i,h){this.id=e;this.size=t;this.cramped=h;this.sizeMultiplier=i}h.prototype.sup=function(){return w[u[this.id]]};h.prototype.sub=function(){return w[k[this.id]]};h.prototype.fracNum=function(){return w[m[this.id]]};h.prototype.fracDen=function(){return w[f[this.id]]};h.prototype.cramp=function(){return w[v[this.id]]};h.prototype.cls=function(){return o[this.size]+(this.cramped?" cramped":" uncramped")};h.prototype.reset=function(){return d[this.size]};var a=0;var r=1;var l=2;var s=3;var p=4;var c=5;var n=6;var g=7;var o=["displaystyle textstyle","textstyle","scriptstyle","scriptscriptstyle"];var d=["reset-textstyle","reset-textstyle","reset-scriptstyle","reset-scriptscriptstyle"];var w=[new h(a,0,1,false),new h(r,0,1,true),new h(l,1,1,false),new h(s,1,1,true),new h(p,2,.7,false),new h(c,2,.7,true),new h(n,3,.5,false),new h(g,3,.5,true)];var u=[p,c,p,c,n,g,n,g];var k=[c,c,c,c,g,g,g,g];var m=[l,s,p,c,n,g,n,g];var f=[s,s,c,c,g,g,g,g];var v=[r,r,s,s,c,c,g,g];t.exports={DISPLAY:w[a],TEXT:w[l],SCRIPT:w[p],SCRIPTSCRIPT:w[n]}},{}],9:[function(e,t,i){var h=e("./domTree");var a=e("./fontMetrics");var r=e("./symbols");var l=e("./utils");var s=function(e,t,i,l,s){if(r[i][e]&&r[i][e].replace){e=r[i][e].replace}var p=a.getCharacterMetrics(e,t);var c;if(p){c=new h.symbolNode(e,p.height,p.depth,p.italic,p.skew,s)}else{typeof console!=="undefined"&&console.warn("No character metrics for '"+e+"' in style '"+t+"'");c=new h.symbolNode(e,0,0,0,0,s)}if(l){c.style.color=l}return c};var p=function(e,t,i,h){if(r[t][e].font==="main"){return s(e,"Main-Regular",t,i,h)}else{return s(e,"AMS-Regular",t,i,h.concat(["amsrm"]))}};var c=function(e,t,i,h,a){if(a==="mathord"){return n(e,t,i,h)}else if(a==="textord"){return s(e,"Main-Regular",t,i,h.concat(["mathrm"]))}else{throw new Error("unexpected type: "+a+" in mathDefault")}};var n=function(e,t,i,h){if(/[0-9]/.test(e.charAt(0))||l.contains(["\u0131","\u0237"],e)||l.contains(v,e)){return s(e,"Main-Italic",t,i,h.concat(["mainit"]))}else{return s(e,"Math-Italic",t,i,h.concat(["mathit"]))}};var g=function(e,t,i){var h=e.mode;var p=e.value;if(r[h][p]&&r[h][p].replace){p=r[h][p].replace}var g=["mord"];var o=t.getColor();var d=t.font;if(d){if(d==="mathit"||l.contains(["\u0131","\u0237"],p)){return n(p,h,o,g.concat(["mathit"]))}else{var w=y[d].fontName;if(a.getCharacterMetrics(p,w)){return s(p,w,h,o,g.concat([d]))}else{return c(p,h,o,g,i)}}}else{return c(p,h,o,g,i)}};var o=function(e){var t=0;var i=0;var h=0;if(e.children){for(var a=0;at){t=e.children[a].height}if(e.children[a].depth>i){i=e.children[a].depth}if(e.children[a].maxFontSize>h){h=e.children[a].maxFontSize}}}e.height=t;e.depth=i;e.maxFontSize=h};var d=function(e,t,i){var a=new h.span(e,t);o(a);if(i){a.style.color=i}return a};var w=function(e){var t=new h.documentFragment(e);o(t);return t};var u=function(e,t){var i=d([],[new h.symbolNode("\u200b")]);i.style.fontSize=t/e.style.sizeMultiplier+"em";var a=d(["fontsize-ensurer","reset-"+e.size,"size5"],[i]);return a};var k=function(e,t,i,a){var r;var l;var s;if(t==="individualShift"){var p=e;e=[p[0]];r=-p[0].shift-p[0].elem.depth;l=r;for(s=1;s0){d+=M;k-=M}}z=l.makeVList([{type:"elem",elem:s,shift:k},{type:"elem",elem:a,shift:-d}],"individualShift",null,t);if(h instanceof p.symbolNode){z.children[0].style.marginLeft=-h.italic+"em"}z.children[0].style.marginRight=b;z.children[1].style.marginRight=b}return g([w(e.value.base)],[h,z])},genfrac:function(e,t,i){var h=t.style;if(e.value.size==="display"){h=r.DISPLAY}else if(e.value.size==="text"){h=r.TEXT}var a=h.fracNum();var p=h.fracDen();var n=y(e.value.numer,t.withStyle(a));var o=g([h.reset(),a.cls()],[n]);var d=y(e.value.denom,t.withStyle(p));var w=g([h.reset(),p.cls()],[d]);var u;if(e.value.hasBarLine){u=c.metrics.defaultRuleThickness/t.style.sizeMultiplier}else{u=0}var k;var m;var v;if(h.size===r.DISPLAY.size){k=c.metrics.num1;if(u>0){m=3*u}else{m=7*c.metrics.defaultRuleThickness}v=c.metrics.denom1}else{if(u>0){k=c.metrics.num2;m=u}else{k=c.metrics.num3;m=3*c.metrics.defaultRuleThickness}v=c.metrics.denom2}var x;if(u===0){var b=k-n.depth-(d.height-v);if(b0){q+=f;if(z0||e.value.hskipBeforeAndAfter){E=n.deflt(R.pregap,d);if(E!==0){C=g(["arraycolsep"],[]);C.style.width=E+"em";N.push(C)}}var P=[];for(h=0;hh.height+h.depth+o){o=(o+k-h.height-h.depth)/2}var m=-(h.height+o+a)+u.height;u.style.top=m+"em";u.height-=m;u.depth+=m;var f;if(h.height===0&&h.depth===0){f=g()}else{f=l.makeVList([{type:"elem",elem:h},{type:"kern",size:o},{type:"elem",elem:p},{type:"kern",size:a}],"firstBaseline",null,t)}if(!e.value.index){return g(["sqrt","mord"],[u,f])}else{var v=y(e.value.index,t.withStyle(r.SCRIPTSCRIPT));var x=g([t.style.reset(),r.SCRIPTSCRIPT.cls()],[v]);var b=Math.max(u.height,f.height);var z=Math.max(u.depth,f.depth);var S=.6*(b-z);var M=l.makeVList([{type:"elem",elem:x}],"shift",-S,t);var q=g(["root"],[M]);return g(["sqrt","mord"],[q,u,f])}},sizing:function(e,t,i){var h=o(e.value.value,t.withSize(e.value.size),i);var a=g(["mord"],[g(["sizing","reset-"+t.size,e.value.size,t.style.cls()],h)]);var r=l.sizingMultiplier[e.value.size];a.maxFontSize=r*t.style.sizeMultiplier;return a},styling:function(e,t,i){var h={display:r.DISPLAY,text:r.TEXT,script:r.SCRIPT,scriptscript:r.SCRIPTSCRIPT};var a=h[e.value.style];var l=o(e.value.value,t.withStyle(a),i);return g([t.style.reset(),a.cls()],l)},font:function(e,t,i){var h=e.value.font;return y(e.value.body,t.withFont(h),i)},delimsizing:function(e,t,i){var h=e.value.value;if(h==="."){return g([d[e.value.delimType]])}return g([d[e.value.delimType]],[s.sizedDelim(h,e.value.size,t,e.mode)])},leftright:function(e,t,i){var h=o(e.value.body,t.reset());var a=0;var r=0;for(var l=0;l","\\langle","\\rangle","/","\\backslash"];var y=[0,1.2,1.8,2.4,3];var x=function(e,t,i,a){if(e==="<"){e="\\langle"}else if(e===">"){e="\\rangle"}if(p.contains(m,e)||p.contains(v,e)){return w(e,t,false,i,a)}else if(p.contains(f,e)){return k(e,y[t],false,i,a)}else{throw new h("Illegal delimiter: '"+e+"'")}};var b=[{type:"small",style:a.SCRIPTSCRIPT},{type:"small",style:a.SCRIPT},{type:"small",style:a.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}];var z=[{type:"small",style:a.SCRIPTSCRIPT},{type:"small",style:a.SCRIPT},{type:"small",style:a.TEXT},{type:"stack"}];var S=[{type:"small",style:a.SCRIPTSCRIPT},{type:"small",style:a.SCRIPT},{type:"small",style:a.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}];var M=function(e){if(e.type==="small"){return"Main-Regular"}else if(e.type==="large"){return"Size"+e.size+"-Regular"}else if(e.type==="stack"){return"Size4-Regular"}};var q=function(e,t,i,h){var a=Math.min(2,3-h.style.size);for(var r=a;rt){return i[r]}}return i[i.length-1]};var A=function(e,t,i,h,a){if(e==="<"){e="\\langle"}else if(e===">"){e="\\rangle"}var r;if(p.contains(v,e)){r=b}else if(p.contains(m,e)){r=S}else{r=z}var l=q(e,t,r,h);if(l.type==="small"){return d(e,l.style,i,h,a)}else if(l.type==="large"){return w(e,l.size,i,h,a)}else if(l.type==="stack"){return k(e,t,i,h,a)}};var T=function(e,t,i,h,a){var r=l.metrics.axisHeight*h.style.sizeMultiplier;var s=901;var p=5/l.metrics.ptPerEm;var c=Math.max(t-r,i+r);var n=Math.max(c/500*s,2*c-p);return A(e,n,true,h,a)};t.exports={sizedDelim:x,customSizedDelim:A,leftRightDelim:T}},{"./ParseError":5,"./Style":8,"./buildCommon":9,"./fontMetrics":16,"./symbols":21,"./utils":22}],14:[function(e,t,i){var h=e("./utils");var a=function(e){e=e.slice();for(var t=e.length-1;t>=0;t--){if(!e[t]){e.splice(t,1)}}return e.join(" ")};function r(e,t,i,h,a,r){this.classes=e||[];this.children=t||[];this.height=i||0;this.depth=h||0;this.maxFontSize=a||0;this.style=r||{};this.attributes={}}r.prototype.setAttribute=function(e,t){this.attributes[e]=t};r.prototype.toNode=function(){var e=document.createElement("span");e.className=a(this.classes);for(var t in this.style){if(Object.prototype.hasOwnProperty.call(this.style,t)){e.style[t]=this.style[t]}}for(var i in this.attributes){if(Object.prototype.hasOwnProperty.call(this.attributes,i)){e.setAttribute(i,this.attributes[i])}}for(var h=0;h";for(var l=0;l";return e};function l(e,t,i,h){this.children=e||[];this.height=t||0;this.depth=i||0;this.maxFontSize=h||0}l.prototype.toNode=function(){var e=document.createDocumentFragment();for(var t=0;t0){t=document.createElement("span");t.style.marginRight=this.italic+"em"}if(this.classes.length>0){t=t||document.createElement("span");t.className=a(this.classes)}for(var i in this.style){if(this.style.hasOwnProperty(i)){t=t||document.createElement("span");t.style[i]=this.style[i]}}if(t){t.appendChild(e);return t}else{return e}};s.prototype.toMarkup=function(){var e=false;var t="0){i+="margin-right:"+this.italic+"em;"}for(var r in this.style){if(this.style.hasOwnProperty(r)){i+=h.hyphenate(r)+":"+this.style[r]+";"}}if(i){e=true;t+=' style="'+h.escape(i)+'"'}var l=h.escape(this.value);if(e){t+=">";t+=l;t+="";return t}else{return l}};t.exports={span:r,documentFragment:l,symbolNode:s}},{"./utils":22}],15:[function(e,t,i){var h=e("./fontMetrics");var a=e("./parseData");var r=e("./ParseError");var l=a.ParseNode;var s=a.ParseResult;function p(e,t,i,h){var a=[],p=[a],c=[];while(true){var n=e.parseExpression(t,i,false,null);a.push(new l("ordgroup",n.result,i));t=n.position;var g=n.peek.text;if(g==="&"){t=n.peek.position}else if(g==="\\end"){break}else if(g==="\\\\"||g==="\\cr"){var o=e.parseFunction(t,i);c.push(o.result.value.size);t=o.position;a=[];p.push(a)}else{throw new r("Expected & or \\\\ or \\end",e.lexer,n.peek.position)}}h.body=p;h.rowGaps=c;return new s(new l(h.type,h,i),t)}var c=[{names:["array"],numArgs:1,handler:function(e,t,i,h,a){var l=this;h=h.value.map?h.value:[h];var s=h.map(function(e){var t=e.value;if("lcr".indexOf(t)!==-1){return{align:t}}throw new r("Unknown column alignment: "+e.value,l.lexer,a[1])});var c={type:"array",cols:s,hskipBeforeAndAfter:true};c=p(l,e,t,c);return c}},{names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix"],handler:function(e,t,i){var h={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[i];var a={type:"array",hskipBeforeAndAfter:false};a=p(this,e,t,a);if(h){a.result=new l("leftright",{body:[a.result],left:h[0],right:h[1]},t)}return a}},{names:["cases"],handler:function(e,t,i){var a={type:"array",arraystretch:1.2,cols:[{align:"l",pregap:0,postgap:h.metrics.quad},{align:"l",pregap:0,postgap:0}]};a=p(this,e,t,a);a.result=new l("leftright",{body:[a.result],left:"\\{",right:"."},t);return a}}];t.exports=function(){var e={};for(var t=0;t","\\langle","\\rangle","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];var p={"\\frak":"\\mathfrak","\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\rm":"\\mathrm","\\sf":"\\mathsf","\\tt":"\\mathtt","\\bf":"\\mathbf","\\it":"\\mathit","\\cal":"\\mathcal"};var c=[{funcs:["\\blue","\\orange","\\pink","\\red","\\green","\\gray","\\purple","\\blueA","\\blueB","\\blueC","\\blueD","\\blueE","\\tealA","\\tealB","\\tealC","\\tealD","\\tealE","\\greenA","\\greenB","\\greenC","\\greenD","\\greenE","\\goldA","\\goldB","\\goldC","\\goldD","\\goldE","\\redA","\\redB","\\redC","\\redD","\\redE","\\maroonA","\\maroonB","\\maroonC","\\maroonD","\\maroonE","\\purpleA","\\purpleB","\\purpleC","\\purpleD","\\purpleE","\\mintA","\\mintB","\\mintC","\\grayA","\\grayB","\\grayC","\\grayD","\\grayE","\\grayF","\\grayG","\\grayH","\\grayI","\\kaBlue","\\kaGreen"],data:{numArgs:1,allowedInText:true,greediness:3,handler:function(e,t){var i;if(t.type==="ordgroup"){i=t.value}else{i=[t]}return{type:"color",color:"katex-"+e.slice(1),value:i}}}},{funcs:["\\arcsin","\\arccos","\\arctan","\\arg","\\cos","\\cosh","\\cot","\\coth","\\csc","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\tan","\\tanh"],data:{numArgs:0,handler:function(e){return{type:"op",limits:false,symbol:false,body:e}}}},{funcs:["\\det","\\gcd","\\inf","\\lim","\\liminf","\\limsup","\\max","\\min","\\Pr","\\sup"],data:{numArgs:0,handler:function(e){return{type:"op",limits:true,symbol:false,body:e}}}},{funcs:["\\int","\\iint","\\iiint","\\oint"],data:{numArgs:0,handler:function(e){return{type:"op",limits:false,symbol:true,body:e}}}},{funcs:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint"],data:{numArgs:0,handler:function(e){return{type:"op",limits:true,symbol:true,body:e}}}},{funcs:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom"],data:{numArgs:2,greediness:2,handler:function(e,t,i){var h;var a=null;var r=null;var l="auto";switch(e){case"\\dfrac":case"\\frac":case"\\tfrac":h=true;break;case"\\dbinom":case"\\binom":case"\\tbinom":h=false;a="(";r=")";break;default:throw new Error("Unrecognized genfrac command")}switch(e){case"\\dfrac":case"\\dbinom":l="display";break;case"\\tfrac":case"\\tbinom":l="text";break}return{type:"genfrac",numer:t,denom:i,hasBarLine:h,leftDelim:a,rightDelim:r,size:l}}}},{funcs:["\\llap","\\rlap"],data:{numArgs:1,allowedInText:true,handler:function(e,t){return{type:e.slice(1),body:t}}}},{funcs:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg","\\left","\\right"],data:{numArgs:1,handler:function(e,t,i){if(!h.contains(s,t.value)){throw new a("Invalid delimiter: '"+t.value+"' after '"+e+"'",this.lexer,i[1])}if(e==="\\left"||e==="\\right"){return{type:"leftright",value:t.value}}else{return{type:"delimsizing",size:l[e].size,delimType:l[e].type,value:t.value}}}}},{funcs:["\\tiny","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"],data:{numArgs:0}},{funcs:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],data:{numArgs:0}},{funcs:["\\mathrm","\\mathit","\\mathbf","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt"],data:{numArgs:1,handler:function(e,t){if(e in p){e=p[e]}return{type:"font",font:e.slice(1),body:t}}}},{funcs:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot"],data:{numArgs:1,handler:function(e,t){return{type:"accent",accent:e,base:t}}}},{funcs:["\\over","\\choose"],data:{numArgs:0,handler:function(e){var t;switch(e){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",replaceWith:t}}}},{funcs:["\\\\","\\cr"],data:{numArgs:0,numOptionalArgs:1,argTypes:["size"],handler:function(e,t){return{type:"cr",size:t}}}},{funcs:["\\begin","\\end"],data:{numArgs:1,argTypes:["text"],handler:function(e,t,i){if(t.type!=="ordgroup"){throw new a("Invalid environment name",this.lexer,i[1])}var h="";for(var r=0;r";for(var i=0;i";return e};function r(e){this.text=e}r.prototype.toNode=function(){return document.createTextNode(this.text)};r.prototype.toMarkup=function(){return h.escape(this.text)};t.exports={MathNode:a,TextNode:r}},{"./utils":22}],19:[function(e,t,i){function h(e,t,i){this.type=e;this.value=t;this.mode=i}function a(e,t,i){this.result=e;this.position=t}t.exports={ParseNode:h,ParseResult:a}},{}],20:[function(e,t,i){var h=e("./Parser");var a=function(e,t){var i=new h(e,t);return i.parse()};t.exports=a},{"./Parser":6}],21:[function(e,t,i){var h={math:{"\\equiv":{font:"main",group:"rel",replace:"\u2261"},"\\prec":{font:"main",group:"rel",replace:"\u227a"},"\\succ":{font:"main",group:"rel",replace:"\u227b"},"\\sim":{font:"main",group:"rel",replace:"\u223c"},"\\perp":{font:"main",group:"rel",replace:"\u22a5"},"\\preceq":{font:"main",group:"rel",replace:"\u2aaf"},"\\succeq":{font:"main",group:"rel",replace:"\u2ab0"},"\\simeq":{font:"main",group:"rel",replace:"\u2243"},"\\mid":{font:"main",group:"rel",replace:"\u2223"},"\\ll":{font:"main",group:"rel",replace:"\u226a"},"\\gg":{font:"main",group:"rel",replace:"\u226b"},"\\asymp":{font:"main",group:"rel",replace:"\u224d"},"\\parallel":{font:"main",group:"rel",replace:"\u2225"},"\\bowtie":{font:"main",group:"rel",replace:"\u22c8"},"\\smile":{font:"main",group:"rel",replace:"\u2323"},"\\sqsubseteq":{font:"main",group:"rel",replace:"\u2291"},"\\sqsupseteq":{font:"main",group:"rel",replace:"\u2292"},"\\doteq":{font:"main",group:"rel",replace:"\u2250"},"\\frown":{font:"main",group:"rel",replace:"\u2322"},"\\ni":{font:"main",group:"rel",replace:"\u220b"},"\\propto":{font:"main",group:"rel",replace:"\u221d"},"\\vdash":{font:"main",group:"rel",replace:"\u22a2"},"\\dashv":{font:"main",group:"rel",replace:"\u22a3"},"\\owns":{font:"main",group:"rel",replace:"\u220b"},"\\ldotp":{font:"main",group:"punct",replace:"."},"\\cdotp":{font:"main",group:"punct",replace:"\u22c5"},"\\#":{font:"main",group:"textord",replace:"#"},"\\&":{font:"main",group:"textord",replace:"&"},"\\aleph":{font:"main",group:"textord",replace:"\u2135"},"\\forall":{font:"main",group:"textord",replace:"\u2200"},"\\hbar":{font:"main",group:"textord",replace:"\u210f"},"\\exists":{font:"main",group:"textord",replace:"\u2203"},"\\nabla":{font:"main",group:"textord",replace:"\u2207"},"\\flat":{font:"main",group:"textord",replace:"\u266d"},"\\ell":{font:"main",group:"textord",replace:"\u2113"},"\\natural":{font:"main",group:"textord",replace:"\u266e"},"\\clubsuit":{font:"main",group:"textord",replace:"\u2663"},"\\wp":{font:"main",group:"textord",replace:"\u2118"},"\\sharp":{font:"main",group:"textord",replace:"\u266f"},"\\diamondsuit":{font:"main",group:"textord",replace:"\u2662"},"\\Re":{font:"main",group:"textord",replace:"\u211c"},"\\heartsuit":{font:"main",group:"textord",replace:"\u2661"},"\\Im":{font:"main",group:"textord",replace:"\u2111"},"\\spadesuit":{font:"main",group:"textord",replace:"\u2660"},"\\dag":{font:"main",group:"textord",replace:"\u2020"},"\\ddag":{font:"main",group:"textord",replace:"\u2021"},"\\rmoustache":{font:"main",group:"close",replace:"\u23b1"},"\\lmoustache":{font:"main",group:"open",replace:"\u23b0"},"\\rgroup":{font:"main",group:"close",replace:"\u27ef"},"\\lgroup":{font:"main",group:"open",replace:"\u27ee"},"\\mp":{font:"main",group:"bin",replace:"\u2213"},"\\ominus":{font:"main",group:"bin",replace:"\u2296"},"\\uplus":{font:"main",group:"bin",replace:"\u228e"},"\\sqcap":{font:"main",group:"bin",replace:"\u2293"},"\\ast":{font:"main",group:"bin",replace:"\u2217"},"\\sqcup":{font:"main",group:"bin",replace:"\u2294"},"\\bigcirc":{font:"main",group:"bin",replace:"\u25ef"},"\\bullet":{font:"main",group:"bin",replace:"\u2219"},"\\ddagger":{font:"main",group:"bin",replace:"\u2021"},"\\wr":{font:"main",group:"bin",replace:"\u2240"},"\\amalg":{font:"main",group:"bin",replace:"\u2a3f"},"\\longleftarrow":{font:"main",group:"rel",replace:"\u27f5"},"\\Leftarrow":{font:"main",group:"rel",replace:"\u21d0"},"\\Longleftarrow":{font:"main",group:"rel",replace:"\u27f8"},"\\longrightarrow":{font:"main",group:"rel",replace:"\u27f6"},"\\Rightarrow":{font:"main",group:"rel",replace:"\u21d2"},"\\Longrightarrow":{font:"main",group:"rel",replace:"\u27f9"},"\\leftrightarrow":{font:"main",group:"rel",replace:"\u2194"},"\\longleftrightarrow":{font:"main",group:"rel",replace:"\u27f7"},"\\Leftrightarrow":{font:"main",group:"rel",replace:"\u21d4"},"\\Longleftrightarrow":{font:"main",group:"rel",replace:"\u27fa"},"\\mapsto":{font:"main",group:"rel",replace:"\u21a6"},"\\longmapsto":{font:"main",group:"rel",replace:"\u27fc"},"\\nearrow":{font:"main",group:"rel",replace:"\u2197"},"\\hookleftarrow":{font:"main",group:"rel",replace:"\u21a9"},"\\hookrightarrow":{font:"main",group:"rel",replace:"\u21aa"},"\\searrow":{font:"main",group:"rel",replace:"\u2198"},"\\leftharpoonup":{font:"main",group:"rel",replace:"\u21bc"},"\\rightharpoonup":{font:"main",group:"rel",replace:"\u21c0"},"\\swarrow":{font:"main",group:"rel",replace:"\u2199"},"\\leftharpoondown":{font:"main",group:"rel",replace:"\u21bd"},"\\rightharpoondown":{font:"main",group:"rel",replace:"\u21c1"},"\\nwarrow":{font:"main",group:"rel",replace:"\u2196"},"\\rightleftharpoons":{font:"main",group:"rel",replace:"\u21cc"},"\\nless":{font:"ams",group:"rel",replace:"\u226e"},"\\nleqslant":{font:"ams",group:"rel",replace:"\ue010"},"\\nleqq":{font:"ams",group:"rel",replace:"\ue011"},"\\lneq":{font:"ams",group:"rel",replace:"\u2a87"},"\\lneqq":{font:"ams",group:"rel",replace:"\u2268"},"\\lvertneqq":{font:"ams",group:"rel",replace:"\ue00c"},"\\lnsim":{font:"ams",group:"rel",replace:"\u22e6"},"\\lnapprox":{font:"ams",group:"rel",replace:"\u2a89"},"\\nprec":{font:"ams",group:"rel",replace:"\u2280"},"\\npreceq":{font:"ams",group:"rel",replace:"\u22e0"},"\\precnsim":{font:"ams",group:"rel",replace:"\u22e8"},"\\precnapprox":{font:"ams",group:"rel",replace:"\u2ab9"},"\\nsim":{font:"ams",group:"rel",replace:"\u2241"},"\\nshortmid":{font:"ams",group:"rel",replace:"\ue006"},"\\nmid":{font:"ams",group:"rel",replace:"\u2224"},"\\nvdash":{font:"ams",group:"rel",replace:"\u22ac"},"\\nvDash":{font:"ams",group:"rel",replace:"\u22ad"},"\\ntriangleleft":{font:"ams",group:"rel",replace:"\u22ea"},"\\ntrianglelefteq":{font:"ams",group:"rel",replace:"\u22ec"},"\\subsetneq":{font:"ams",group:"rel",replace:"\u228a"},"\\varsubsetneq":{font:"ams",group:"rel",replace:"\ue01a"},"\\subsetneqq":{font:"ams",group:"rel",replace:"\u2acb"},"\\varsubsetneqq":{font:"ams",group:"rel",replace:"\ue017"},"\\ngtr":{font:"ams",group:"rel",replace:"\u226f"},"\\ngeqslant":{font:"ams",group:"rel",replace:"\ue00f"},"\\ngeqq":{font:"ams",group:"rel",replace:"\ue00e"},"\\gneq":{font:"ams",group:"rel",replace:"\u2a88"},"\\gneqq":{font:"ams",group:"rel",replace:"\u2269"},"\\gvertneqq":{font:"ams",group:"rel",replace:"\ue00d"},"\\gnsim":{font:"ams",group:"rel",replace:"\u22e7"},"\\gnapprox":{font:"ams",group:"rel",replace:"\u2a8a"},"\\nsucc":{font:"ams",group:"rel",replace:"\u2281"},"\\nsucceq":{font:"ams",group:"rel",replace:"\u22e1"},"\\succnsim":{font:"ams",group:"rel",replace:"\u22e9"},"\\succnapprox":{font:"ams",group:"rel",replace:"\u2aba"},"\\ncong":{font:"ams",group:"rel",replace:"\u2246"},"\\nshortparallel":{font:"ams",group:"rel",replace:"\ue007"},"\\nparallel":{font:"ams",group:"rel",replace:"\u2226"},"\\nVDash":{font:"ams",group:"rel",replace:"\u22af"},"\\ntriangleright":{font:"ams",group:"rel",replace:"\u22eb"},"\\ntrianglerighteq":{font:"ams",group:"rel",replace:"\u22ed"},"\\nsupseteqq":{font:"ams",group:"rel",replace:"\ue018"},"\\supsetneq":{font:"ams",group:"rel",replace:"\u228b"},"\\varsupsetneq":{font:"ams",group:"rel",replace:"\ue01b"},"\\supsetneqq":{font:"ams",group:"rel",replace:"\u2acc"},"\\varsupsetneqq":{font:"ams",group:"rel",replace:"\ue019"},"\\nVdash":{font:"ams",group:"rel",replace:"\u22ae"},"\\precneqq":{font:"ams",group:"rel",replace:"\u2ab5"},"\\succneqq":{font:"ams",group:"rel",replace:"\u2ab6"},"\\nsubseteqq":{font:"ams",group:"rel",replace:"\ue016"},"\\unlhd":{font:"ams",group:"bin",replace:"\u22b4"},"\\unrhd":{font:"ams",group:"bin",replace:"\u22b5"},"\\nleftarrow":{font:"ams",group:"rel",replace:"\u219a"},"\\nrightarrow":{font:"ams",group:"rel",replace:"\u219b"},"\\nLeftarrow":{font:"ams",group:"rel",replace:"\u21cd"},"\\nRightarrow":{font:"ams",group:"rel",replace:"\u21cf"},"\\nleftrightarrow":{font:"ams",group:"rel",replace:"\u21ae"},"\\nLeftrightarrow":{font:"ams",group:"rel",replace:"\u21ce"},"\\vartriangle":{font:"ams",group:"rel",replace:"\u25b3"},"\\hslash":{font:"ams",group:"textord",replace:"\u210f"},"\\triangledown":{font:"ams",group:"textord",replace:"\u25bd"},"\\lozenge":{font:"ams",group:"textord",replace:"\u25ca"},"\\circledS":{font:"ams",group:"textord",replace:"\u24c8"},"\\circledR":{font:"ams",group:"textord",replace:"\xae"},"\\measuredangle":{font:"ams",group:"textord",replace:"\u2221"},"\\nexists":{font:"ams",group:"textord",replace:"\u2204"},"\\mho":{font:"ams",group:"textord",replace:"\u2127"},"\\Finv":{font:"ams",group:"textord",replace:"\u2132"},"\\Game":{font:"ams",group:"textord",replace:"\u2141"},"\\Bbbk":{font:"ams",group:"textord",replace:"k"},"\\backprime":{font:"ams",group:"textord",replace:"\u2035"},"\\blacktriangle":{font:"ams",group:"textord",replace:"\u25b2"},"\\blacktriangledown":{font:"ams",group:"textord",replace:"\u25bc"},"\\blacksquare":{font:"ams",group:"textord",replace:"\u25a0"},"\\blacklozenge":{font:"ams",group:"textord",replace:"\u29eb"},"\\bigstar":{font:"ams",group:"textord",replace:"\u2605"},"\\sphericalangle":{font:"ams",group:"textord",replace:"\u2222"},"\\complement":{font:"ams",group:"textord",replace:"\u2201"},"\\eth":{font:"ams",group:"textord",replace:"\xf0"},"\\diagup":{font:"ams",group:"textord",replace:"\u2571"},"\\diagdown":{font:"ams",group:"textord",replace:"\u2572"},"\\square":{font:"ams",group:"textord",replace:"\u25a1"},"\\Box":{font:"ams",group:"textord",replace:"\u25a1"},"\\Diamond":{font:"ams",group:"textord",replace:"\u25ca"},"\\yen":{font:"ams",group:"textord",replace:"\xa5"},"\\checkmark":{font:"ams",group:"textord",replace:"\u2713"},"\\beth":{font:"ams",group:"textord",replace:"\u2136"},"\\daleth":{font:"ams",group:"textord",replace:"\u2138"},"\\gimel":{font:"ams",group:"textord",replace:"\u2137"},"\\digamma":{font:"ams",group:"textord",replace:"\u03dd"},"\\varkappa":{font:"ams",group:"textord",replace:"\u03f0"},"\\ulcorner":{font:"ams",group:"textord",replace:"\u250c"},"\\urcorner":{font:"ams",group:"textord",replace:"\u2510"},"\\llcorner":{font:"ams",group:"textord",replace:"\u2514"},"\\lrcorner":{font:"ams",group:"textord",replace:"\u2518"},"\\leqq":{font:"ams",group:"rel",replace:"\u2266"},"\\leqslant":{font:"ams",group:"rel",replace:"\u2a7d"},"\\eqslantless":{font:"ams",group:"rel",replace:"\u2a95"},"\\lesssim":{font:"ams",group:"rel",replace:"\u2272"},"\\lessapprox":{font:"ams",group:"rel",replace:"\u2a85"},"\\approxeq":{font:"ams",group:"rel",replace:"\u224a"},"\\lessdot":{font:"ams",group:"bin",replace:"\u22d6"},"\\lll":{font:"ams",group:"rel",replace:"\u22d8"},"\\lessgtr":{font:"ams",group:"rel",replace:"\u2276"},"\\lesseqgtr":{font:"ams",group:"rel",replace:"\u22da"},"\\lesseqqgtr":{font:"ams",group:"rel",replace:"\u2a8b"},"\\doteqdot":{font:"ams",group:"rel",replace:"\u2251"},"\\risingdotseq":{font:"ams",group:"rel",replace:"\u2253"},"\\fallingdotseq":{font:"ams",group:"rel",replace:"\u2252"},"\\backsim":{font:"ams",group:"rel",replace:"\u223d"},"\\backsimeq":{font:"ams",group:"rel",replace:"\u22cd"},"\\subseteqq":{font:"ams",group:"rel",replace:"\u2ac5"},"\\Subset":{font:"ams",group:"rel",replace:"\u22d0"},"\\sqsubset":{font:"ams",group:"rel",replace:"\u228f"},"\\preccurlyeq":{font:"ams",group:"rel",replace:"\u227c"},"\\curlyeqprec":{font:"ams",group:"rel",replace:"\u22de"},"\\precsim":{font:"ams",group:"rel",replace:"\u227e"},"\\precapprox":{font:"ams",group:"rel",replace:"\u2ab7"},"\\vartriangleleft":{font:"ams",group:"rel",replace:"\u22b2"},"\\trianglelefteq":{font:"ams",group:"rel",replace:"\u22b4"},"\\vDash":{font:"ams",group:"rel",replace:"\u22a8"},"\\Vvdash":{font:"ams",group:"rel",replace:"\u22aa"},"\\smallsmile":{font:"ams",group:"rel",replace:"\u2323"},"\\smallfrown":{font:"ams",group:"rel",replace:"\u2322"},"\\bumpeq":{font:"ams",group:"rel",replace:"\u224f"},"\\Bumpeq":{font:"ams",group:"rel",replace:"\u224e"},"\\geqq":{font:"ams",group:"rel",replace:"\u2267"},"\\geqslant":{font:"ams",group:"rel",replace:"\u2a7e"},"\\eqslantgtr":{font:"ams",group:"rel",replace:"\u2a96"},"\\gtrsim":{font:"ams",group:"rel",replace:"\u2273"},"\\gtrapprox":{font:"ams",group:"rel",replace:"\u2a86"},"\\gtrdot":{font:"ams",group:"bin",replace:"\u22d7"},"\\ggg":{font:"ams",group:"rel",replace:"\u22d9"},"\\gtrless":{font:"ams",group:"rel",replace:"\u2277"},"\\gtreqless":{font:"ams",group:"rel",replace:"\u22db"},"\\gtreqqless":{font:"ams",group:"rel",replace:"\u2a8c"},"\\eqcirc":{font:"ams",group:"rel",replace:"\u2256"},"\\circeq":{font:"ams",group:"rel",replace:"\u2257"},"\\triangleq":{font:"ams",group:"rel",replace:"\u225c"},"\\thicksim":{font:"ams",group:"rel",replace:"\u223c"},"\\thickapprox":{font:"ams",group:"rel",replace:"\u2248"},"\\supseteqq":{font:"ams",group:"rel",replace:"\u2ac6"},"\\Supset":{font:"ams",group:"rel",replace:"\u22d1"},"\\sqsupset":{font:"ams",group:"rel",replace:"\u2290"},"\\succcurlyeq":{font:"ams",group:"rel",replace:"\u227d"},"\\curlyeqsucc":{font:"ams",group:"rel",replace:"\u22df"},"\\succsim":{font:"ams",group:"rel",replace:"\u227f"},"\\succapprox":{font:"ams",group:"rel",replace:"\u2ab8"},"\\vartriangleright":{font:"ams",group:"rel",replace:"\u22b3"},"\\trianglerighteq":{font:"ams",group:"rel",replace:"\u22b5"},"\\Vdash":{font:"ams",group:"rel",replace:"\u22a9"},"\\shortmid":{font:"ams",group:"rel",replace:"\u2223"},"\\shortparallel":{font:"ams",group:"rel",replace:"\u2225"},"\\between":{font:"ams",group:"rel",replace:"\u226c"},"\\pitchfork":{font:"ams",group:"rel",replace:"\u22d4"},"\\varpropto":{font:"ams",group:"rel",replace:"\u221d"},"\\blacktriangleleft":{font:"ams",group:"rel",replace:"\u25c0"},"\\therefore":{font:"ams",group:"rel",replace:"\u2234"},"\\backepsilon":{font:"ams",group:"rel",replace:"\u220d"},"\\blacktriangleright":{font:"ams",group:"rel",replace:"\u25b6"},"\\because":{font:"ams",group:"rel",replace:"\u2235"},"\\llless":{font:"ams",group:"rel",replace:"\u22d8"},"\\gggtr":{font:"ams",group:"rel",replace:"\u22d9"},"\\lhd":{font:"ams",group:"bin",replace:"\u22b2"},"\\rhd":{font:"ams",group:"bin",replace:"\u22b3"},"\\eqsim":{font:"ams",group:"rel",replace:"\u2242"},"\\Join":{font:"main",group:"rel",replace:"\u22c8"},"\\Doteq":{font:"ams",group:"rel",replace:"\u2251"},"\\dotplus":{font:"ams",group:"bin",replace:"\u2214"},"\\smallsetminus":{font:"ams",group:"bin",replace:"\u2216"},"\\Cap":{font:"ams",group:"bin",replace:"\u22d2"},"\\Cup":{font:"ams",group:"bin",replace:"\u22d3"},"\\doublebarwedge":{font:"ams",group:"bin",replace:"\u2a5e"},"\\boxminus":{font:"ams",group:"bin",replace:"\u229f"},"\\boxplus":{font:"ams",group:"bin",replace:"\u229e"},"\\divideontimes":{font:"ams",group:"bin",replace:"\u22c7"},"\\ltimes":{font:"ams",group:"bin",replace:"\u22c9"},"\\rtimes":{font:"ams",group:"bin",replace:"\u22ca"},"\\leftthreetimes":{font:"ams",group:"bin",replace:"\u22cb"},"\\rightthreetimes":{font:"ams",group:"bin",replace:"\u22cc"},"\\curlywedge":{font:"ams",group:"bin",replace:"\u22cf"},"\\curlyvee":{font:"ams",group:"bin",replace:"\u22ce"},"\\circleddash":{font:"ams",group:"bin",replace:"\u229d"},"\\circledast":{font:"ams",group:"bin",replace:"\u229b"},"\\centerdot":{font:"ams",group:"bin",replace:"\u22c5"},"\\intercal":{font:"ams",group:"bin",replace:"\u22ba"},"\\doublecap":{font:"ams",group:"bin",replace:"\u22d2"},"\\doublecup":{font:"ams",group:"bin",replace:"\u22d3"},"\\boxtimes":{font:"ams",group:"bin",replace:"\u22a0"},"\\dashrightarrow":{font:"ams",group:"rel",replace:"\u21e2"},"\\dashleftarrow":{font:"ams",group:"rel",replace:"\u21e0"},"\\leftleftarrows":{font:"ams",group:"rel",replace:"\u21c7"},"\\leftrightarrows":{font:"ams",group:"rel",replace:"\u21c6"},"\\Lleftarrow":{font:"ams",group:"rel",replace:"\u21da"},"\\twoheadleftarrow":{font:"ams",group:"rel",replace:"\u219e"},"\\leftarrowtail":{font:"ams",group:"rel",replace:"\u21a2"},"\\looparrowleft":{font:"ams",group:"rel",replace:"\u21ab"},"\\leftrightharpoons":{font:"ams",group:"rel",replace:"\u21cb"},"\\curvearrowleft":{font:"ams",group:"rel",replace:"\u21b6"},"\\circlearrowleft":{font:"ams",group:"rel",replace:"\u21ba"},"\\Lsh":{font:"ams",group:"rel",replace:"\u21b0"},"\\upuparrows":{font:"ams",group:"rel",replace:"\u21c8"},"\\upharpoonleft":{font:"ams",group:"rel",replace:"\u21bf"},"\\downharpoonleft":{font:"ams",group:"rel",replace:"\u21c3"},"\\multimap":{font:"ams",group:"rel",replace:"\u22b8"},"\\leftrightsquigarrow":{font:"ams",group:"rel",replace:"\u21ad"},"\\rightrightarrows":{font:"ams",group:"rel",replace:"\u21c9"},"\\rightleftarrows":{font:"ams",group:"rel",replace:"\u21c4"},"\\twoheadrightarrow":{font:"ams",group:"rel",replace:"\u21a0"},"\\rightarrowtail":{font:"ams",group:"rel",replace:"\u21a3"},"\\looparrowright":{font:"ams",group:"rel",replace:"\u21ac"},"\\curvearrowright":{font:"ams",group:"rel",replace:"\u21b7"},"\\circlearrowright":{font:"ams",group:"rel",replace:"\u21bb"},"\\Rsh":{font:"ams",group:"rel",replace:"\u21b1"},"\\downdownarrows":{font:"ams",group:"rel",replace:"\u21ca"},"\\upharpoonright":{font:"ams",group:"rel",replace:"\u21be"},"\\downharpoonright":{font:"ams",group:"rel",replace:"\u21c2"},"\\rightsquigarrow":{font:"ams",group:"rel",replace:"\u21dd"},"\\leadsto":{font:"ams",group:"rel",replace:"\u21dd"},"\\Rrightarrow":{font:"ams",group:"rel",replace:"\u21db"},"\\restriction":{font:"ams",group:"rel",replace:"\u21be"},"`":{font:"main",group:"textord",replace:"\u2018"},"\\$":{font:"main",group:"textord",replace:"$"},"\\%":{font:"main",group:"textord",replace:"%"},"\\_":{font:"main",group:"textord",replace:"_"},"\\angle":{font:"main",group:"textord",replace:"\u2220"},"\\infty":{font:"main",group:"textord",replace:"\u221e"},"\\prime":{font:"main",group:"textord",replace:"\u2032"},"\\triangle":{font:"main",group:"textord",replace:"\u25b3"},"\\Gamma":{font:"main",group:"textord",replace:"\u0393"},"\\Delta":{font:"main",group:"textord",replace:"\u0394"},"\\Theta":{font:"main",group:"textord",replace:"\u0398"},"\\Lambda":{font:"main",group:"textord",replace:"\u039b"},"\\Xi":{font:"main",group:"textord",replace:"\u039e"},"\\Pi":{font:"main",group:"textord",replace:"\u03a0"},"\\Sigma":{font:"main",group:"textord",replace:"\u03a3"},"\\Upsilon":{font:"main",group:"textord",replace:"\u03a5"},"\\Phi":{font:"main",group:"textord",replace:"\u03a6"},"\\Psi":{font:"main",group:"textord",replace:"\u03a8"},"\\Omega":{font:"main",group:"textord",replace:"\u03a9"},"\\neg":{font:"main",group:"textord",replace:"\xac"},"\\lnot":{font:"main",group:"textord",replace:"\xac"},"\\top":{font:"main",group:"textord",replace:"\u22a4"},"\\bot":{font:"main",group:"textord",replace:"\u22a5"},"\\emptyset":{font:"main",group:"textord",replace:"\u2205"},"\\varnothing":{font:"ams",group:"textord",replace:"\u2205"},"\\alpha":{font:"main",group:"mathord",replace:"\u03b1"},"\\beta":{font:"main",group:"mathord",replace:"\u03b2"},"\\gamma":{font:"main",group:"mathord",replace:"\u03b3"},"\\delta":{font:"main",group:"mathord",replace:"\u03b4"},"\\epsilon":{font:"main",group:"mathord",replace:"\u03f5"},"\\zeta":{font:"main",group:"mathord",replace:"\u03b6"},"\\eta":{font:"main",group:"mathord",replace:"\u03b7"},"\\theta":{font:"main",group:"mathord",replace:"\u03b8"},"\\iota":{font:"main",group:"mathord",replace:"\u03b9"},"\\kappa":{font:"main",group:"mathord",replace:"\u03ba"},"\\lambda":{font:"main",group:"mathord",replace:"\u03bb"},"\\mu":{font:"main",group:"mathord",replace:"\u03bc"},"\\nu":{font:"main",group:"mathord",replace:"\u03bd"},"\\xi":{font:"main",group:"mathord",replace:"\u03be"},"\\omicron":{font:"main",group:"mathord",replace:"o"},"\\pi":{font:"main",group:"mathord",replace:"\u03c0"},"\\rho":{font:"main",group:"mathord",replace:"\u03c1"},"\\sigma":{font:"main",group:"mathord",replace:"\u03c3"},"\\tau":{font:"main",group:"mathord",replace:"\u03c4"},"\\upsilon":{font:"main",group:"mathord",replace:"\u03c5"},"\\phi":{font:"main",group:"mathord",replace:"\u03d5"},"\\chi":{font:"main",group:"mathord",replace:"\u03c7"},"\\psi":{font:"main",group:"mathord",replace:"\u03c8"},"\\omega":{font:"main",group:"mathord",replace:"\u03c9"
+},"\\varepsilon":{font:"main",group:"mathord",replace:"\u03b5"},"\\vartheta":{font:"main",group:"mathord",replace:"\u03d1"},"\\varpi":{font:"main",group:"mathord",replace:"\u03d6"},"\\varrho":{font:"main",group:"mathord",replace:"\u03f1"},"\\varsigma":{font:"main",group:"mathord",replace:"\u03c2"},"\\varphi":{font:"main",group:"mathord",replace:"\u03c6"},"*":{font:"main",group:"bin",replace:"\u2217"},"+":{font:"main",group:"bin"},"-":{font:"main",group:"bin",replace:"\u2212"},"\\cdot":{font:"main",group:"bin",replace:"\u22c5"},"\\circ":{font:"main",group:"bin",replace:"\u2218"},"\\div":{font:"main",group:"bin",replace:"\xf7"},"\\pm":{font:"main",group:"bin",replace:"\xb1"},"\\times":{font:"main",group:"bin",replace:"\xd7"},"\\cap":{font:"main",group:"bin",replace:"\u2229"},"\\cup":{font:"main",group:"bin",replace:"\u222a"},"\\setminus":{font:"main",group:"bin",replace:"\u2216"},"\\land":{font:"main",group:"bin",replace:"\u2227"},"\\lor":{font:"main",group:"bin",replace:"\u2228"},"\\wedge":{font:"main",group:"bin",replace:"\u2227"},"\\vee":{font:"main",group:"bin",replace:"\u2228"},"\\surd":{font:"main",group:"textord",replace:"\u221a"},"(":{font:"main",group:"open"},"[":{font:"main",group:"open"},"\\langle":{font:"main",group:"open",replace:"\u27e8"},"\\lvert":{font:"main",group:"open",replace:"\u2223"},")":{font:"main",group:"close"},"]":{font:"main",group:"close"},"?":{font:"main",group:"close"},"!":{font:"main",group:"close"},"\\rangle":{font:"main",group:"close",replace:"\u27e9"},"\\rvert":{font:"main",group:"close",replace:"\u2223"},"=":{font:"main",group:"rel"},"<":{font:"main",group:"rel"},">":{font:"main",group:"rel"},":":{font:"main",group:"rel"},"\\approx":{font:"main",group:"rel",replace:"\u2248"},"\\cong":{font:"main",group:"rel",replace:"\u2245"},"\\ge":{font:"main",group:"rel",replace:"\u2265"},"\\geq":{font:"main",group:"rel",replace:"\u2265"},"\\gets":{font:"main",group:"rel",replace:"\u2190"},"\\in":{font:"main",group:"rel",replace:"\u2208"},"\\notin":{font:"main",group:"rel",replace:"\u2209"},"\\subset":{font:"main",group:"rel",replace:"\u2282"},"\\supset":{font:"main",group:"rel",replace:"\u2283"},"\\subseteq":{font:"main",group:"rel",replace:"\u2286"},"\\supseteq":{font:"main",group:"rel",replace:"\u2287"},"\\nsubseteq":{font:"ams",group:"rel",replace:"\u2288"},"\\nsupseteq":{font:"ams",group:"rel",replace:"\u2289"},"\\models":{font:"main",group:"rel",replace:"\u22a8"},"\\leftarrow":{font:"main",group:"rel",replace:"\u2190"},"\\le":{font:"main",group:"rel",replace:"\u2264"},"\\leq":{font:"main",group:"rel",replace:"\u2264"},"\\ne":{font:"main",group:"rel",replace:"\u2260"},"\\neq":{font:"main",group:"rel",replace:"\u2260"},"\\rightarrow":{font:"main",group:"rel",replace:"\u2192"},"\\to":{font:"main",group:"rel",replace:"\u2192"},"\\ngeq":{font:"ams",group:"rel",replace:"\u2271"},"\\nleq":{font:"ams",group:"rel",replace:"\u2270"},"\\!":{font:"main",group:"spacing"},"\\ ":{font:"main",group:"spacing",replace:"\xa0"},"~":{font:"main",group:"spacing",replace:"\xa0"},"\\,":{font:"main",group:"spacing"},"\\:":{font:"main",group:"spacing"},"\\;":{font:"main",group:"spacing"},"\\enspace":{font:"main",group:"spacing"},"\\qquad":{font:"main",group:"spacing"},"\\quad":{font:"main",group:"spacing"},"\\space":{font:"main",group:"spacing",replace:"\xa0"},",":{font:"main",group:"punct"},";":{font:"main",group:"punct"},"\\colon":{font:"main",group:"punct",replace:":"},"\\barwedge":{font:"ams",group:"textord",replace:"\u22bc"},"\\veebar":{font:"ams",group:"textord",replace:"\u22bb"},"\\odot":{font:"main",group:"bin",replace:"\u2299"},"\\oplus":{font:"main",group:"bin",replace:"\u2295"},"\\otimes":{font:"main",group:"bin",replace:"\u2297"},"\\partial":{font:"main",group:"textord",replace:"\u2202"},"\\oslash":{font:"main",group:"bin",replace:"\u2298"},"\\circledcirc":{font:"ams",group:"textord",replace:"\u229a"},"\\boxdot":{font:"ams",group:"textord",replace:"\u22a1"},"\\bigtriangleup":{font:"main",group:"bin",replace:"\u25b3"},"\\bigtriangledown":{font:"main",group:"bin",replace:"\u25bd"},"\\dagger":{font:"main",group:"bin",replace:"\u2020"},"\\diamond":{font:"main",group:"bin",replace:"\u22c4"},"\\star":{font:"main",group:"bin",replace:"\u22c6"},"\\triangleleft":{font:"main",group:"bin",replace:"\u25c3"},"\\triangleright":{font:"main",group:"bin",replace:"\u25b9"},"\\{":{font:"main",group:"open",replace:"{"},"\\}":{font:"main",group:"close",replace:"}"},"\\lbrace":{font:"main",group:"open",replace:"{"},"\\rbrace":{font:"main",group:"close",replace:"}"},"\\lbrack":{font:"main",group:"open",replace:"["},"\\rbrack":{font:"main",group:"close",replace:"]"},"\\lfloor":{font:"main",group:"open",replace:"\u230a"},"\\rfloor":{font:"main",group:"close",replace:"\u230b"},"\\lceil":{font:"main",group:"open",replace:"\u2308"},"\\rceil":{font:"main",group:"close",replace:"\u2309"},"\\backslash":{font:"main",group:"textord",replace:"\\"},"|":{font:"main",group:"textord",replace:"\u2223"},"\\vert":{font:"main",group:"textord",replace:"\u2223"},"\\|":{font:"main",group:"textord",replace:"\u2225"},"\\Vert":{font:"main",group:"textord",replace:"\u2225"},"\\uparrow":{font:"main",group:"textord",replace:"\u2191"},"\\Uparrow":{font:"main",group:"textord",replace:"\u21d1"},"\\downarrow":{font:"main",group:"textord",replace:"\u2193"},"\\Downarrow":{font:"main",group:"textord",replace:"\u21d3"},"\\updownarrow":{font:"main",group:"textord",replace:"\u2195"},"\\Updownarrow":{font:"main",group:"textord",replace:"\u21d5"},"\\coprod":{font:"math",group:"op",replace:"\u2210"},"\\bigvee":{font:"math",group:"op",replace:"\u22c1"},"\\bigwedge":{font:"math",group:"op",replace:"\u22c0"},"\\biguplus":{font:"math",group:"op",replace:"\u2a04"},"\\bigcap":{font:"math",group:"op",replace:"\u22c2"},"\\bigcup":{font:"math",group:"op",replace:"\u22c3"},"\\int":{font:"math",group:"op",replace:"\u222b"},"\\intop":{font:"math",group:"op",replace:"\u222b"},"\\iint":{font:"math",group:"op",replace:"\u222c"},"\\iiint":{font:"math",group:"op",replace:"\u222d"},"\\prod":{font:"math",group:"op",replace:"\u220f"},"\\sum":{font:"math",group:"op",replace:"\u2211"},"\\bigotimes":{font:"math",group:"op",replace:"\u2a02"},"\\bigoplus":{font:"math",group:"op",replace:"\u2a01"},"\\bigodot":{font:"math",group:"op",replace:"\u2a00"},"\\oint":{font:"math",group:"op",replace:"\u222e"},"\\bigsqcup":{font:"math",group:"op",replace:"\u2a06"},"\\smallint":{font:"math",group:"op",replace:"\u222b"},"\\ldots":{font:"main",group:"punct",replace:"\u2026"},"\\cdots":{font:"main",group:"inner",replace:"\u22ef"},"\\ddots":{font:"main",group:"inner",replace:"\u22f1"},"\\vdots":{font:"main",group:"textord",replace:"\u22ee"},"\\acute":{font:"main",group:"accent",replace:"\xb4"},"\\grave":{font:"main",group:"accent",replace:"`"},"\\ddot":{font:"main",group:"accent",replace:"\xa8"},"\\tilde":{font:"main",group:"accent",replace:"~"},"\\bar":{font:"main",group:"accent",replace:"\xaf"},"\\breve":{font:"main",group:"accent",replace:"\u02d8"},"\\check":{font:"main",group:"accent",replace:"\u02c7"},"\\hat":{font:"main",group:"accent",replace:"^"},"\\vec":{font:"main",group:"accent",replace:"\u20d7"},"\\dot":{font:"main",group:"accent",replace:"\u02d9"},"\\imath":{font:"main",group:"mathord",replace:"\u0131"},"\\jmath":{font:"main",group:"mathord",replace:"\u0237"}},text:{"\\ ":{font:"main",group:"spacing",replace:"\xa0"}," ":{font:"main",group:"spacing",replace:"\xa0"},"~":{font:"main",group:"spacing",replace:"\xa0"}}};var a='0123456789/@."';for(var r=0;r":">","<":"<",'"':""","'":"'"};var n=/[&><"']/g;function g(e){return c[e]}function o(e){return(""+e).replace(n,g)}var d;if(typeof document!=="undefined"){var w=document.createElement("span");if("textContent"in w){d=function(e,t){e.textContent=t}}else{d=function(e,t){e.innerText=t}}}function u(e){d(e,"")}t.exports={contains:r,deflt:l,escape:o,hyphenate:p,indexOf:a,setTextContent:d,clearNode:u}},{}]},{},[1])(1)});
diff --git a/web/schemes/android.css b/web/schemes/android.css
new file mode 100644
index 0000000..35c2165
--- /dev/null
+++ b/web/schemes/android.css
@@ -0,0 +1,47 @@
+body {
+ background: #212121;
+ color: #e0e0e0;
+}
+input,
+textarea {
+ color: #e0e0e0;
+}
+.messages {
+ border-color: #858585;
+}
+.nick {
+ color: #0099CC;
+}
+.trip {
+ color: #626261;
+}
+.text a {
+ color: #f2f2f2;
+}
+.admin .nick {
+ color: #e94749;
+}
+.mod .nick {
+ color: #33B5E5;
+}
+.me .nick {
+ color: #9568AA;
+}
+.info .nick,
+.info .text {
+ color: #99C21D;
+}
+.warn .nick,
+.warn .text {
+ color: #fbba37;
+}
+#footer {
+ background: #212121;
+}
+#sidebar {
+ background: #333333;
+ border-color: #858585;
+}
+#chatform {
+ border-color: #858585;
+}
diff --git a/web/schemes/atelier-dune.css b/web/schemes/atelier-dune.css
new file mode 100644
index 0000000..56175f4
--- /dev/null
+++ b/web/schemes/atelier-dune.css
@@ -0,0 +1,47 @@
+body {
+ background: #20201d;
+ color: #a6a28c;
+}
+input,
+textarea {
+ color: #a6a28c;
+}
+.messages {
+ border-color: #7d7a68;
+}
+.nick {
+ color: #6684e1;
+}
+.trip {
+ color: #6e6b5e;
+}
+.text a {
+ color: #e8e4cf;
+}
+.admin .nick {
+ color: #d73737;
+}
+.mod .nick {
+ color: #1fad83;
+}
+.me .nick {
+ color: #b854d4;
+}
+.info .nick,
+.info .text {
+ color: #60ac39;
+}
+.warn .nick,
+.warn .text {
+ color: #cfb017;
+}
+#footer {
+ background: #20201d;
+}
+#sidebar {
+ background: #292824;
+ border-color: #7d7a68;
+}
+#chatform {
+ border-color: #7d7a68;
+}
diff --git a/web/schemes/atelier-forest.css b/web/schemes/atelier-forest.css
new file mode 100644
index 0000000..c022005
--- /dev/null
+++ b/web/schemes/atelier-forest.css
@@ -0,0 +1,47 @@
+body {
+ background: #1b1918;
+ color: #a8a19f;
+}
+input,
+textarea {
+ color: #a8a19f;
+}
+.messages {
+ border-color: #766e6b;
+}
+.nick {
+ color: #407ee7;
+}
+.trip {
+ color: #68615e;
+}
+.text a {
+ color: #e6e2e0;
+}
+.admin .nick {
+ color: #f22c40;
+}
+.mod .nick {
+ color: #00ad9c;
+}
+.me .nick {
+ color: #6666ea;
+}
+.info .nick,
+.info .text {
+ color: #5ab738;
+}
+.warn .nick,
+.warn .text {
+ color: #d5911a;
+}
+#footer {
+ background: #1b1918;
+}
+#sidebar {
+ background: #2c2421;
+ border-color: #766e6b;
+}
+#chatform {
+ border-color: #766e6b;
+}
diff --git a/web/schemes/atelier-heath.css b/web/schemes/atelier-heath.css
new file mode 100644
index 0000000..5c6a77f
--- /dev/null
+++ b/web/schemes/atelier-heath.css
@@ -0,0 +1,47 @@
+body {
+ background: #1b181b;
+ color: #ab9bab;
+}
+input,
+textarea {
+ color: #ab9bab;
+}
+.messages {
+ border-color: #776977;
+}
+.nick {
+ color: #516aec;
+}
+.trip {
+ color: #695d69;
+}
+.text a {
+ color: #d8cad8;
+}
+.admin .nick {
+ color: #ca402b;
+}
+.mod .nick {
+ color: #159393;
+}
+.me .nick {
+ color: #7b59c0;
+}
+.info .nick,
+.info .text {
+ color: #379a37;
+}
+.warn .nick,
+.warn .text {
+ color: #bb8a35;
+}
+#footer {
+ background: #1b181b;
+}
+#sidebar {
+ background: #292329;
+ border-color: #776977;
+}
+#chatform {
+ border-color: #776977;
+}
diff --git a/web/schemes/atelier-lakeside.css b/web/schemes/atelier-lakeside.css
new file mode 100644
index 0000000..e0dbbbe
--- /dev/null
+++ b/web/schemes/atelier-lakeside.css
@@ -0,0 +1,47 @@
+body {
+ background: #161b1d;
+ color: #7ea2b4;
+}
+input,
+textarea {
+ color: #7ea2b4;
+}
+.messages {
+ border-color: #5a7b8c;
+}
+.nick {
+ color: #257fad;
+}
+.trip {
+ color: #516d7b;
+}
+.text a {
+ color: #c1e4f6;
+}
+.admin .nick {
+ color: #d22d72;
+}
+.mod .nick {
+ color: #2d8f6f;
+}
+.me .nick {
+ color: #5d5db1;
+}
+.info .nick,
+.info .text {
+ color: #568c3b;
+}
+.warn .nick,
+.warn .text {
+ color: #8a8a0f;
+}
+#footer {
+ background: #161b1d;
+}
+#sidebar {
+ background: #1f292e;
+ border-color: #5a7b8c;
+}
+#chatform {
+ border-color: #5a7b8c;
+}
diff --git a/web/schemes/atelier-seaside.css b/web/schemes/atelier-seaside.css
new file mode 100644
index 0000000..b494c27
--- /dev/null
+++ b/web/schemes/atelier-seaside.css
@@ -0,0 +1,47 @@
+body {
+ background: #131513;
+ color: #8ca68c;
+}
+input,
+textarea {
+ color: #8ca68c;
+}
+.messages {
+ border-color: #687d68;
+}
+.nick {
+ color: #3d62f5;
+}
+.trip {
+ color: #5e6e5e;
+}
+.text a {
+ color: #cfe8cf;
+}
+.admin .nick {
+ color: #e6193c;
+}
+.mod .nick {
+ color: #1999b3;
+}
+.me .nick {
+ color: #ad2bee;
+}
+.info .nick,
+.info .text {
+ color: #29a329;
+}
+.warn .nick,
+.warn .text {
+ color: #c3c322;
+}
+#footer {
+ background: #131513;
+}
+#sidebar {
+ background: #242924;
+ border-color: #687d68;
+}
+#chatform {
+ border-color: #687d68;
+}
diff --git a/web/schemes/bright.css b/web/schemes/bright.css
new file mode 100644
index 0000000..abeb2da
--- /dev/null
+++ b/web/schemes/bright.css
@@ -0,0 +1,47 @@
+body {
+ background: #000000;
+ color: #e0e0e0;
+}
+input,
+textarea {
+ color: #e0e0e0;
+}
+.messages {
+ border-color: #b0b0b0;
+}
+.nick {
+ color: #6fb3d2;
+}
+.trip {
+ color: #505050;
+}
+.text a {
+ color: #f5f5f5;
+}
+.admin .nick {
+ color: #fb0120;
+}
+.mod .nick {
+ color: #76c7b7;
+}
+.me .nick {
+ color: #d381c3;
+}
+.info .nick,
+.info .text {
+ color: #a1c659;
+}
+.warn .nick,
+.warn .text {
+ color: #fda331;
+}
+#footer {
+ background: #000000;
+}
+#sidebar {
+ background: #303030;
+ border-color: #b0b0b0;
+}
+#chatform {
+ border-color: #b0b0b0;
+}
diff --git a/web/schemes/chalk.css b/web/schemes/chalk.css
new file mode 100644
index 0000000..c004c15
--- /dev/null
+++ b/web/schemes/chalk.css
@@ -0,0 +1,47 @@
+body {
+ background: #151515;
+ color: #d0d0d0;
+}
+input,
+textarea {
+ color: #d0d0d0;
+}
+.messages {
+ border-color: #505050;
+}
+.nick {
+ color: #6fc2ef;
+}
+.trip {
+ color: #303030;
+}
+.text a {
+ color: #e0e0e0;
+}
+.admin .nick {
+ color: #fb9fb1;
+}
+.mod .nick {
+ color: #12cfc0;
+}
+.me .nick {
+ color: #e1a3ee;
+}
+.info .nick,
+.info .text {
+ color: #acc267;
+}
+.warn .nick,
+.warn .text {
+ color: #ddb26f;
+}
+#footer {
+ background: #151515;
+}
+#sidebar {
+ background: #202020;
+ border-color: #505050;
+}
+#chatform {
+ border-color: #505050;
+}
diff --git a/web/schemes/default.css b/web/schemes/default.css
new file mode 100644
index 0000000..f8a6b4d
--- /dev/null
+++ b/web/schemes/default.css
@@ -0,0 +1,47 @@
+body {
+ background: #151515;
+ color: #d0d0d0;
+}
+input,
+textarea {
+ color: #d0d0d0;
+}
+.messages {
+ border-color: #505050;
+}
+.nick {
+ color: #6a9fb5;
+}
+.trip {
+ color: #303030;
+}
+.text a {
+ color: #e0e0e0;
+}
+.admin .nick {
+ color: #ac4142;
+}
+.mod .nick {
+ color: #75b5aa;
+}
+.me .nick {
+ color: #aa759f;
+}
+.info .nick,
+.info .text {
+ color: #90a959;
+}
+.warn .nick,
+.warn .text {
+ color: #f4bf75;
+}
+#footer {
+ background: #151515;
+}
+#sidebar {
+ background: #202020;
+ border-color: #505050;
+}
+#chatform {
+ border-color: #505050;
+}
diff --git a/web/schemes/eighties.css b/web/schemes/eighties.css
new file mode 100644
index 0000000..e0ccebb
--- /dev/null
+++ b/web/schemes/eighties.css
@@ -0,0 +1,47 @@
+body {
+ background: #2d2d2d;
+ color: #d3d0c8;
+}
+input,
+textarea {
+ color: #d3d0c8;
+}
+.messages {
+ border-color: #747369;
+}
+.nick {
+ color: #6699cc;
+}
+.trip {
+ color: #515151;
+}
+.text a {
+ color: #e8e6df;
+}
+.admin .nick {
+ color: #f2777a;
+}
+.mod .nick {
+ color: #66cccc;
+}
+.me .nick {
+ color: #cc99cc;
+}
+.info .nick,
+.info .text {
+ color: #99cc99;
+}
+.warn .nick,
+.warn .text {
+ color: #ffcc66;
+}
+#footer {
+ background: #2d2d2d;
+}
+#sidebar {
+ background: #393939;
+ border-color: #747369;
+}
+#chatform {
+ border-color: #747369;
+}
diff --git a/web/schemes/greenscreen.css b/web/schemes/greenscreen.css
new file mode 100644
index 0000000..fd7c794
--- /dev/null
+++ b/web/schemes/greenscreen.css
@@ -0,0 +1,47 @@
+body {
+ background: #001100;
+ color: #00bb00;
+}
+input,
+textarea {
+ color: #00bb00;
+}
+.messages {
+ border-color: #007700;
+}
+.nick {
+ color: #009900;
+}
+.trip {
+ color: #005500;
+}
+.text a {
+ color: #00dd00;
+}
+.admin .nick {
+ color: #007700;
+}
+.mod .nick {
+ color: #005500;
+}
+.me .nick {
+ color: #00bb00;
+}
+.info .nick,
+.info .text {
+ color: #00bb00;
+}
+.warn .nick,
+.warn .text {
+ color: #007700;
+}
+#footer {
+ background: #001100;
+}
+#sidebar {
+ background: #003300;
+ border-color: #007700;
+}
+#chatform {
+ border-color: #007700;
+}
diff --git a/web/schemes/mocha.css b/web/schemes/mocha.css
new file mode 100644
index 0000000..7b7a439
--- /dev/null
+++ b/web/schemes/mocha.css
@@ -0,0 +1,47 @@
+body {
+ background: #3B3228;
+ color: #d0c8c6;
+}
+input,
+textarea {
+ color: #d0c8c6;
+}
+.messages {
+ border-color: #7e705a;
+}
+.nick {
+ color: #8ab3b5;
+}
+.trip {
+ color: #645240;
+}
+.text a {
+ color: #e9e1dd;
+}
+.admin .nick {
+ color: #cb6077;
+}
+.mod .nick {
+ color: #7bbda4;
+}
+.me .nick {
+ color: #a89bb9;
+}
+.info .nick,
+.info .text {
+ color: #beb55b;
+}
+.warn .nick,
+.warn .text {
+ color: #f4bc87;
+}
+#footer {
+ background: #3B3228;
+}
+#sidebar {
+ background: #534636;
+ border-color: #7e705a;
+}
+#chatform {
+ border-color: #7e705a;
+}
diff --git a/web/schemes/monokai.css b/web/schemes/monokai.css
new file mode 100644
index 0000000..adef41d
--- /dev/null
+++ b/web/schemes/monokai.css
@@ -0,0 +1,47 @@
+body {
+ background: #272822;
+ color: #f8f8f2;
+}
+input,
+textarea {
+ color: #f8f8f2;
+}
+.messages {
+ border-color: #75715e;
+}
+.nick {
+ color: #66d9ef;
+}
+.trip {
+ color: #49483e;
+}
+.text a {
+ color: #f5f4f1;
+}
+.admin .nick {
+ color: #f92672;
+}
+.mod .nick {
+ color: #a1efe4;
+}
+.me .nick {
+ color: #ae81ff;
+}
+.info .nick,
+.info .text {
+ color: #a6e22e;
+}
+.warn .nick,
+.warn .text {
+ color: #f4bf75;
+}
+#footer {
+ background: #272822;
+}
+#sidebar {
+ background: #383830;
+ border-color: #75715e;
+}
+#chatform {
+ border-color: #75715e;
+}
diff --git a/web/schemes/nese.css b/web/schemes/nese.css
new file mode 100644
index 0000000..8fe5844
--- /dev/null
+++ b/web/schemes/nese.css
@@ -0,0 +1,47 @@
+body {
+ background: #030303;
+ color: #cccccc;
+}
+input,
+textarea {
+ color: #cccccc;
+}
+.messages {
+ border-color: #737373;
+}
+.nick {
+ color: #388bb8;
+}
+.trip {
+ color: #333333;
+}
+.text a {
+ color: #f2f2f2;
+}
+.admin .nick {
+ color: #f73e30;
+}
+.mod .nick {
+ color: #29a288;
+}
+.me .nick {
+ color: #9c73a7;
+}
+.info .nick,
+.info .text {
+ color: #1ab857;
+}
+.warn .nick,
+.warn .text {
+ color: #faba3d;
+}
+#footer {
+ background: #030303;
+}
+#sidebar {
+ background: #0d0d0d;
+ border-color: #737373;
+}
+#chatform {
+ border-color: #737373;
+}
diff --git a/web/schemes/ocean.css b/web/schemes/ocean.css
new file mode 100644
index 0000000..c4ba031
--- /dev/null
+++ b/web/schemes/ocean.css
@@ -0,0 +1,47 @@
+body {
+ background: #2b303b;
+ color: #c0c5ce;
+}
+input,
+textarea {
+ color: #c0c5ce;
+}
+.messages {
+ border-color: #65737e;
+}
+.nick {
+ color: #8fa1b3;
+}
+.trip {
+ color: #4f5b66;
+}
+.text a {
+ color: #dfe1e8;
+}
+.admin .nick {
+ color: #bf616a;
+}
+.mod .nick {
+ color: #96b5b4;
+}
+.me .nick {
+ color: #b48ead;
+}
+.info .nick,
+.info .text {
+ color: #a3be8c;
+}
+.warn .nick,
+.warn .text {
+ color: #ebcb8b;
+}
+#footer {
+ background: #2b303b;
+}
+#sidebar {
+ background: #343d46;
+ border-color: #65737e;
+}
+#chatform {
+ border-color: #65737e;
+}
diff --git a/web/schemes/pop.css b/web/schemes/pop.css
new file mode 100644
index 0000000..697170b
--- /dev/null
+++ b/web/schemes/pop.css
@@ -0,0 +1,47 @@
+body {
+ background: #000000;
+ color: #d0d0d0;
+}
+input,
+textarea {
+ color: #d0d0d0;
+}
+.messages {
+ border-color: #505050;
+}
+.nick {
+ color: #0e5a94;
+}
+.trip {
+ color: #303030;
+}
+.text a {
+ color: #e0e0e0;
+}
+.admin .nick {
+ color: #eb008a;
+}
+.mod .nick {
+ color: #00aabb;
+}
+.me .nick {
+ color: #b31e8d;
+}
+.info .nick,
+.info .text {
+ color: #37b349;
+}
+.warn .nick,
+.warn .text {
+ color: #f8ca12;
+}
+#footer {
+ background: #000000;
+}
+#sidebar {
+ background: #202020;
+ border-color: #505050;
+}
+#chatform {
+ border-color: #505050;
+}
diff --git a/web/schemes/railscasts.css b/web/schemes/railscasts.css
new file mode 100644
index 0000000..886240a
--- /dev/null
+++ b/web/schemes/railscasts.css
@@ -0,0 +1,47 @@
+body {
+ background: #2b2b2b;
+ color: #e6e1dc;
+}
+input,
+textarea {
+ color: #e6e1dc;
+}
+.messages {
+ border-color: #5a647e;
+}
+.nick {
+ color: #6d9cbe;
+}
+.trip {
+ color: #3a4055;
+}
+.text a {
+ color: #f4f1ed;
+}
+.admin .nick {
+ color: #da4939;
+}
+.mod .nick {
+ color: #519f50;
+}
+.me .nick {
+ color: #b6b3eb;
+}
+.info .nick,
+.info .text {
+ color: #a5c261;
+}
+.warn .nick,
+.warn .text {
+ color: #ffc66d;
+}
+#footer {
+ background: #2b2b2b;
+}
+#sidebar {
+ background: #272935;
+ border-color: #5a647e;
+}
+#chatform {
+ border-color: #5a647e;
+}
diff --git a/web/schemes/solarized.css b/web/schemes/solarized.css
new file mode 100644
index 0000000..3435491
--- /dev/null
+++ b/web/schemes/solarized.css
@@ -0,0 +1,47 @@
+body {
+ background: #002b36;
+ color: #93a1a1;
+}
+input,
+textarea {
+ color: #93a1a1;
+}
+.messages {
+ border-color: #657b83;
+}
+.nick {
+ color: #268bd2;
+}
+.trip {
+ color: #586e75;
+}
+.text a {
+ color: #eee8d5;
+}
+.admin .nick {
+ color: #dc322f;
+}
+.mod .nick {
+ color: #2aa198;
+}
+.me .nick {
+ color: #6c71c4;
+}
+.info .nick,
+.info .text {
+ color: #859900;
+}
+.warn .nick,
+.warn .text {
+ color: #b58900;
+}
+#footer {
+ background: #002b36;
+}
+#sidebar {
+ background: #073642;
+ border-color: #657b83;
+}
+#chatform {
+ border-color: #657b83;
+}
diff --git a/web/schemes/tomorrow.css b/web/schemes/tomorrow.css
new file mode 100644
index 0000000..80a8db1
--- /dev/null
+++ b/web/schemes/tomorrow.css
@@ -0,0 +1,47 @@
+body {
+ background: #1d1f21;
+ color: #c5c8c6;
+}
+input,
+textarea {
+ color: #c5c8c6;
+}
+.messages {
+ border-color: #969896;
+}
+.nick {
+ color: #81a2be;
+}
+.trip {
+ color: #373b41;
+}
+.text a {
+ color: #e0e0e0;
+}
+.admin .nick {
+ color: #cc6666;
+}
+.mod .nick {
+ color: #8abeb7;
+}
+.me .nick {
+ color: #b294bb;
+}
+.info .nick,
+.info .text {
+ color: #b5bd68;
+}
+.warn .nick,
+.warn .text {
+ color: #f0c674;
+}
+#footer {
+ background: #1d1f21;
+}
+#sidebar {
+ background: #282a2e;
+ border-color: #969896;
+}
+#chatform {
+ border-color: #969896;
+}
diff --git a/web/style.css b/web/style.css
new file mode 100644
index 0000000..18abc33
--- /dev/null
+++ b/web/style.css
@@ -0,0 +1,137 @@
+body {
+ padding: 0;
+ margin: 0;
+ overflow-y: scroll;
+}
+body,
+input,
+textarea {
+ font-family: 'DejaVu Sans Mono', monospace;
+ font-size: 12px;
+}
+input[type="checkbox"] {
+ margin: 0;
+ margin-right: 1em;
+}
+label {
+ vertical-align: 3px;
+}
+input,
+textarea {
+ background: none;
+ border: none;
+ outline: none;
+ resize: none;
+}
+h4 {
+ font-size: 12px;
+ margin: 1em 0;
+ font-weight: bold;
+}
+pre {
+ tab-size: 2;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ tab-size: 4;
+ -moz-tab-size: 4;
+}
+a {
+ color: inherit;
+ text-decoration: none;
+ cursor: pointer;
+}
+a:hover {
+ text-decoration: underline;
+}
+ul {
+ padding-left: 0;
+}
+ul li {
+ list-style: inside;
+}
+.hidden {
+ display: none;
+}
+.container {
+ max-width: 600px;
+ margin: 0 auto;
+}
+.messages {
+ border-left: 1px solid;
+}
+#messages {
+ padding-top: 2em;
+}
+.message {
+ padding-bottom: 1em;
+}
+.nick {
+ float: left;
+ width: 16em;
+ margin-left: -17em;
+ margin-right: 1em;
+ text-align: right;
+ white-space: nowrap;
+ overflow: hidden;
+}
+.trip {
+ font-size: 10px;
+}
+.text {
+ margin: 0;
+ margin-left: 1em;
+}
+.text p {
+ margin: 0;
+}
+#footer {
+ position: fixed;
+ bottom: 0;
+ width: 100%;
+}
+#chatform {
+ border-top: 1px solid;
+}
+#chatinput {
+ width: 100%;
+ padding: 1em;
+ box-sizing: border-box;
+}
+#sidebar {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ padding: 1em;
+ border-left: solid 1px;
+ overflow-y: auto;
+}
+#sidebar-content {
+ width: 180px;
+}
+@media only screen and (max-width: 600px) {
+ .messages {
+ border: none;
+ }
+ #messages {
+ padding: 0.5em;
+ }
+ .message {
+ padding-bottom: 0.5em;
+ }
+ .nick {
+ margin: 0;
+ float: none;
+ text-align: left;
+ display: inline;
+ }
+ .text {
+ display: inline;
+ }
+ #sidebar {
+ top: 0.5em;
+ bottom: auto;
+ right: 0.5em;
+ border: none;
+ }
+}