Index: trunk/HISTORY.md
===================================================================
--- trunk/HISTORY.md	(revision 67)
+++ trunk/HISTORY.md	(revision 67)
@@ -0,0 +1,13 @@
+## 2021
+[SimplyTranslate](https://codeberg.org/SimpleWeb/SimplyTranslate-Web) was founded by metalune and fattalion. 
+It was written in Python and used the Quart framework.
+
+## 2022
+fattalion created a Go implementation.
+
+## 2023
+* Both metalune and fattalion retired, and they handed SimplyTranslate over to [ManeraKai](https://manerakai.com).
+* Arya K. from [~vern](https://vern.cc) made a hard-fork named [Mozhi](https://codeberg.org/aryak/mozhi) and has vastly refactored it.
+
+## 2024 
+Izuru Yakumo took interest in SimplyTranslate and decided to fork it in October 2023, and in January he turned it into a hard-fork, eventually renaming it to "Mai", after a character from the fifth [Touhou Project](https://en.touhouwiki.net/wiki/Touhou_Project) game, [Mai](https://en.touhouwiki.net/wiki/Mai).
Index: trunk/INSTALL.md
===================================================================
--- trunk/INSTALL.md	(revision 67)
+++ trunk/INSTALL.md	(revision 67)
@@ -0,0 +1,11 @@
+# Installation
+
+```shell
+$ git clone https://git.chaotic.ninja/yakumo.izuru/mai
+$ cd mai
+$ make
+# make PREFIX=/usr/local install
+```
+* Read the [mai.ini(5)](mai.ini.5) manual page
+* Use any web server than is able to reverse proxy, like Apache, h2o, or NGINX.
+
Index: trunk/INSTANCES.md
===================================================================
--- trunk/INSTANCES.md	(revision 67)
+++ trunk/INSTANCES.md	(revision 67)
@@ -0,0 +1,6 @@
+# List of known instances
+
+* [tr.chaotic.ninja](https://tr.chaotic.ninja)
+    * Location: Germany
+    * Cloudflare: No
+
Index: trunk/LEGAL.md
===================================================================
--- trunk/LEGAL.md	(revision 67)
+++ trunk/LEGAL.md	(revision 67)
@@ -0,0 +1,9 @@
+Mai does not host any content. All content shown on any Mai instances is from [Google Translate](https://translate.google.com), [Reverso](https://www.reverso.net/), and [LibreTranslate](https://libretranslate.com)
+
+Mai is not affiliated with none of the above, which this program relays.
+
+Trademarks belong to their respective owners. 
+Google Translate is a trademark of [Google LLC](https://www.google.com). Reverso is a trademark of Reverso, et cetera.
+
+The creators and maintainers of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect.
+
Index: trunk/README.md
===================================================================
--- trunk/README.md	(revision 66)
+++ trunk/README.md	(revision 67)
@@ -2,43 +2,7 @@
 A privacy friendly frontend to multiple translation engines.
 
-### History
-1. SimplyTranslate was founded by [metalune and fattalion](https://codeberg.org/SimpleWeb/SimplyTranslate-Web). It was written in Python.
-2. Fattalion created a Go implementation.
-3. Both metalune and fattalion retired, and they handed SimplyTranslate over to ManeraKai.
-4. [Izuru Yakumo The Violet Hermit](https://geidontei.chaotic.ninja/usr/yakumo_izuru) stole it, and renamed it after [Mai](https://en.touhouwiki.net/wiki/Mai) from [Mystic Square](https://en.touhouwiki.net/wiki/Mystic_Square)
-
-### Instances
-| URL | Location | Cloudflare? |
-|-----|----------|-------------|
-| [tr.chaotic.ninja](https://tr.chaotic.ninja) | DE | No |
-
-### Installation
-
-```shell
-% git clone https://git.chaotic.ninja/yakumo.izuru/mai
-% cd mai
-% make
-# make install
-```
-
-### Setup
-For [nginx](https://www.nginx.com) you can use this snippet, this also serves the static resources.
-
-```nginx
-location / {
-    proxy_set_header Host $host;
-    proxy_pass http://localhost:5000;
-}
-```
-
-### Legal notice
-Mai does not host any content. All content shown on any Mai instances is from [Google Translate](https://translate.google.com), [Reverso](https://www.reverso.net/), [iCIBA](https://www.iciba.net) and [LibreTranslate](https://libretranslate.com)
-
-Mai is not affiliated with none of the above, which this program relays.
-
-Trademarks belong to their respective owners. 
-Google Translate is a trademark of [Google LLC](https://www.google.com). Reverso is a trademark of Reverso, et cetera.
-
-The creators and maintainers of this repository assume no liability for the accuracy and timeliness of any information provided above. Trademark owner information was researched to the best of the author's knowledge at the time of curation and may be outdated or incorrect.
+* [How to install](INSTALL.md)
+* [List of instances](INSTANCES.md)
+* [Legal notice](LEGAL.md)
 
 ### Other projects
Index: trunk/cmd/mai/main.go
===================================================================
--- trunk/cmd/mai/main.go	(revision 66)
+++ trunk/cmd/mai/main.go	(revision 67)
@@ -22,11 +22,11 @@
 var (
 	configfile string
+	groupname string
+	username string
 )
 var conf struct {
-	group string
 	listen string
 	staticpath string
 	tmplpath string
-	user string
 }
 func main() {
@@ -42,6 +42,6 @@
 	conf.tmplpath = "./views"
 
-	if conf.user != "" {
-		uid, gid, err := usergroupids(conf.user, conf.group)
+	if username != "" {
+		uid, gid, err := usergroupids(username, groupname)
 		if err != nil {
 			fmt.Println(err)
@@ -259,4 +259,7 @@
 		}
 	})
+	app.Get("/robots.txt", func(c *fiber.Ctx) error {
+		return c.SendString("User-Agent: *\nDisallow: /\n")
+	})
 	app.Get("/version", func(c *fiber.Ctx) error {
 		return c.JSON(fiber.Map{
Index: trunk/cmd/mai/parseflags.go
===================================================================
--- trunk/cmd/mai/parseflags.go	(revision 66)
+++ trunk/cmd/mai/parseflags.go	(revision 67)
@@ -8,4 +8,6 @@
 func parseFlags() {
 	flag.StringVar(&configfile, "f", "", "Configuration file")
+	flag.StringVar(&username, "u", "", "Sets the user to which privilege dropping is done")
+	flag.StringVar(&groupname, "g", "", "Sets the group to which privilege dropping is done")
 	flag.Parse()
 }
Index: trunk/cmd/mai/readconf.go
===================================================================
--- trunk/cmd/mai/readconf.go	(revision 66)
+++ trunk/cmd/mai/readconf.go	(revision 67)
@@ -11,9 +11,7 @@
 		return err					        
 	}
-	conf.group = cfg.Section("mai").Key("group").String()
 	conf.listen = cfg.Section("mai").Key("listen").String()
 	conf.staticpath = cfg.Section("mai").Key("static").String()
 	conf.tmplpath = cfg.Section("mai").Key("templates").String()
-	conf.user = cfg.Section("mai").Key("user").String()
 
 	return nil
Index: trunk/cmd/mai/usergroupids.go
===================================================================
--- trunk/cmd/mai/usergroupids.go	(revision 66)
+++ trunk/cmd/mai/usergroupids.go	(revision 67)
@@ -15,5 +15,5 @@
 	gid, _ := strconv.Atoi(u.Gid)
 
-	if conf.group != "" {
+	if groupname != "" {
 		g, err := user.LookupGroup(groupname)
 		if err != nil {
Index: trunk/docs/api/index.html
===================================================================
--- trunk/docs/api/index.html	(revision 66)
+++ trunk/docs/api/index.html	(revision 67)
@@ -8,48 +8,67 @@
 	</head>
 	<body id="body">
-		<h1 id="header">API Documentation</h1>
-		<br><hr>
-		<h2 class="get">[GET] /api/translate</h2>
-		<h2 class="post">[POST] /api/translate</h2>
-		<h3>Description</h3>
-		<p>Translation endpoint, input must be URL-encoded (e.g. multi-byte characters, words separated by space)</p>
-		<h3>Arguments</h3>
-		<ul>
-			<li>engine</li>
-			<li>from</li>
-			<li>text</li>
-			<li>to</li>
-		</ul>
-		<h3>Examples</h3>
-		<p><pre><code>GET /api/translate?engine=google&amp;from=auto&amp;to=en&amp;text="sonrisa"</code></pre></p>
-		<hr>
-		<h2 class="get">[GET] /api/source_languages</h2>
-		<h2 class="get">[GET] /api/target_languages</h2>
-		<h3>Description</h3>
-		<p>Get a JSON array of supported source and target languages for a particular engine</p>
-		<h3>Arguments</h3>
-		<ul>
-			<li>engine</li>
-		</ul>
-		<h3>Examples</h3>
-		<p><pre><code>GET /api/source_languages?engine=google</code></pre></p>
-		<p><pre><code>GET /api/target_languages?engine=google</code></pre></p>
-		<hr>
-		<h2 class="get">[GET] /api/tts</h2>
-		<h3>Description</h3>
-		<p>Obtain text-to-speech audio files from an engine, provided said engine supports them</p>
-		<h3>Arguments</h3>
-		<ul>
-			<li>engine</li>
-			<li>lang</li>
-			<li>text</li>
-		</ul>
-		<h3>Examples</h3>
-		<p><pre><code>GET /api/tts?engine=google&amp;lang=en&amp;text="hi"</code></pre></p>
-		<hr>
-		<h2 class="post">[POST] /switchlanguages</h2>
-		<h3>Description</h3>
-		<p>Switch between source and target languages, as long as the source language isn't "auto"</p>
-		<hr>
+		<h1>API documentation</h1>
+		<table border="1" align="center">
+			<tr>
+				<td>
+					<h2 class="get">[GET] /api/translate</h2>
+					<h2 class="post">[POST] /api/translate</h2>
+					<h3>Description</h3>
+					<p>Translation endpoint, input must be URL-encoded (e.g. multi-byte characters, words separated by space)</p>
+					<h3>Arguments</h3>
+					<ul>
+						<li>engine</li>
+						<li>from</li>
+						<li>text</li>
+						<li>to</li>
+					</ul>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<h2 class="get">[GET] /api/source_languages</h2>
+					<h2 class="get">[GET] /api/target_languages</h2>
+					<h3>Description</h3>
+					<p>Get a JSON array of supported source and target languages for a particular engine</p>
+					<h3>Arguments</h3>
+					<ul>
+						<li>engine</li>
+					</ul>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<h2 class="get">[GET] /api/tts</h2>
+					<h3>Description</h3>
+					<p>Obtain text-to-speech audio files from an engine, provided said engine supports them</p>
+					<h3>Arguments</h3>
+					<ul>
+						<li>engine</li>
+						<li>lang</li>
+						<li>text</li>
+					</ul>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<h2 class="get">[GET] /robots.txt</h2>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<h2 class="post">[POST] /switchlanguages</h2>
+					<h3>Description</h3>
+					<p>Switch between source and target languages, as long as the source language isn't "auto"</p>
+					<p>Must only be called inside the form interface</p>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<h2 class="get">[GET] /version</h2>
+					<h3>Description</h3>
+					<p>Return the software version as a JSON array</p>
+				</td>
+			</tr>
+		</table>
 	</body>
 </html>
Index: trunk/docs/index.html
===================================================================
--- trunk/docs/index.html	(revision 66)
+++ trunk/docs/index.html	(revision 67)
@@ -7,10 +7,25 @@
 		<title>Mai | Documentation</title>
 	</head>
-	<body id="body">
-		<img src="/static/favicon128x128.png" style="text-align: center;">
-		<h1 id="header">Documentation</h1>
-		<ul id="nav">
-			<li><a href="/docs/api">API</a></li>
-		</ul>
+	<body>
+		<table>
+			<tr><td>
+					<table border="1" align="left">
+						<tr>
+							<td><a href="/docs/api">API</a></td>
+						</tr>
+					</table>
+			</tr></td>
+			<tr><td>
+					<table border="1" align="center">
+						<tr>
+							<td>
+								<p>Welcome to Mai's documentation!<p>
+								<p>See the menu for the available entries</p>
+								<p>Anything else is covered by the man pages</p>
+							</td>
+						</tr>
+					</table>
+				</td></tr>
+		</table>
 	</body>
 </html>
Index: trunk/docs/style.css
===================================================================
--- trunk/docs/style.css	(revision 66)
+++ trunk/docs/style.css	(revision 67)
@@ -1,114 +1,22 @@
-/*
- * Taken from vnpower
- */
-
-* {
-  box-sizing: border-box; }
-
 body {
-  top: 0;
-  margin: 0;
-  background-color: #1d1f21;
-  color: white;
-  font-family: "Open Sans", "Roboto", "Noto Sans", "Noto Sans CJK JP", sans-serif;
-  line-height: 1.618; 
+	background-color: #f8cfd2;
+	color: rgb(206, 147, 191);
 }
 
-h2.get {
-	color: orange;
+a, a:visited {
+	color: rgb(206, 147, 191);
 }
 
-h2.post {
-	color: green;
+@media screen and (prefers-color-scheme: dark) {
+	body {
+		background-color: #700000;
+		color: #ffffff;
+	}
+	a, a:visited {
+		color: #18c018;
+	}
 }
 
-@media (max-width: 684px) {
-  body {
-    font-size: 1rem; } }
-
-@media (max-width: 382px) {
-  body {
-    font-size: 1rem; } }
-
-a {
-  color: #81a2be;
-  text-decoration-color: #81a2be; }
-
-#header {
-  width: 100%;
-  min-width: 320px;
-  background-color: #282a2e; }
-
-#header img {
-  width: 280px; }
-
-#header-content {
-  margin: 0 auto;
-  width: min-content; }
-
-#nav {
-  display: flex;
-  justify-content: center;
-  background-color: #373b41; }
-
-#footer {
-  margin-top: 0.5rem;
-  text-align: center; }
-
-#body {
-  min-height: 75vh;
-  max-width: 800px;
-  margin: 1rem auto;
-  padding: 0 0.6rem; }
-  #body h1,
-  #body h2,
-  #body h3,
-  #body h4,
-  #body h5,
-  #body h6 {
-    line-height: 1.1;
-    font-family: sans-serif;
-    font-weight: 700;
-    margin-top: 1rem;
-    margin-bottom: 1rem;
-    overflow-wrap: break-word;
-    word-wrap: break-word;
-    -ms-word-break: break-all;
-    word-break: break-word; }
-  #body h1 {
-    border-bottom: 1px solid #b5bd68;
-    display: block; }
-  #body p {
-    margin-top: 0px;
-    margin-bottom: 0.5rem; }
-  #body li > p {
-    padding: 0;
-    margin: 0; }
-  #body small,
-  #body sub,
-  #body sup {
-    font-size: 75%; }
-  #body img,
-  #body video {
-    height: auto;
-    max-width: 100%;
-    margin-top: 0.5rem;
-    margin-bottom: 0.5rem;
-    box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.12), 0px 2px 2px 0px rgba(0, 0, 0, 0.12), 0px 4px 4px 0px rgba(0, 0, 0, 0.12), 0px 8px 8px 0px rgba(0, 0, 0, 0.12), 0px 16px 16px 0px rgba(0, 0, 0, 0.12); }
-  #body pre {
-    background-color: #373b41;
-    display: block;
-    padding: 1em;
-    overflow-x: auto;
-    margin-top: 0px;
-    margin-bottom: 0.5rem; }
-  #body code, #body kbd, #body samp {
-    padding: 0 0.5em;
-    background-color: #373b41;
-    white-space: pre-wrap; }
-  #body pre > code {
-    padding: 0;
-    background-color: transparent;
-    white-space: pre;
-    font-size: 1em; }
-
+table {
+	border-color: white;
+}
Index: trunk/engines/engine.go
===================================================================
--- trunk/engines/engine.go	(revision 66)
+++ trunk/engines/engine.go	(revision 67)
@@ -25,5 +25,4 @@
 	"google": &GoogleTranslate{},
 	"reverso": &Reverso{},
-	"iciba": &ICIBA{},
 	"libretranslate": &LibreTranslate{
 		InstanceURL: os.Getenv("MAI_LIBRETRANSLATE_INSTANCE"),
Index: trunk/engines/iciba.go
===================================================================
--- trunk/engines/iciba.go	(revision 66)
+++ 	(revision )
@@ -1,283 +1,0 @@
-package engines
-
-import (
-	"crypto/md5"
-	"encoding/hex"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"net/url"
-)
-
-// iCIBA is an engine that fetches data from https://www.iciba.com.
-type ICIBA struct{}
-
-func (_ *ICIBA) DisplayName() string { return "iCIBA" }
-
-var icibaLanguages = Language{
-	// ICIBA does have an API, but they return Chinese names.
-	// For languages already present in Google translate, the English
-	// names in that engine file are used; Otherwise official names
-	// as researched on Wikipedia are used. They're validated against
-	// the Chinese names to the best of my ability.
-	// Missing "cni", "kbh", "tmh"
-	// due to conflict between ISO-639 table and Chinese label
-	// one "//" means on iciba but not on google
-	"ace": "Achinese",       //
-	"acu": "Achuar-Shiwiar", //
-	"af":  "Afrikaans",
-	"agr": "Aguaruna", //
-	"ake": "Akawaio",  //
-	"sq":  "Albanian",
-	"am":  "Amharic",
-	"ar":  "Arabic",
-	"hy":  "Armenian",
-	"az":  "Azerbaijani",
-	"bsn": "Barasana-Eduria", //
-	"ba":  "Bashkir",         //
-	"eu":  "Basque",
-	"be":  "Belarusian",
-	"bem": "Bemba", //
-	"bn":  "Bengali",
-	"ber": "Berber",  //
-	"bi":  "Bislama", //
-	"bs":  "Bosnian",
-	"br":  "Breton", //
-	"bg":  "Bulgarian",
-	"cjp": "Cabécar", //
-	"yue": "Cantonese",
-	"ca":  "Catalan",
-	"ceb": "Cebuano",
-	"cha": "Chamorro", //
-	"chr": "Cherokee", //
-	"ny":  "Chichewa",
-	"zh":  "Chinese (Simplified)",  // "zh-cn" on Google
-	"cht": "Chinese (Traditional)", // "zh-tw" on Google
-	"cv":  "Chuvash",
-	"cop": "Coptic", //
-	"co":  "Corsican",
-	"hr":  "Croatian",
-	"cs":  "Czech",
-	"da":  "Danish",
-	"dv":  "Dhivehi", //
-	"dik": "Dinka",   //
-	"nl":  "Dutch",
-	"dz":  "Dzongkha", //
-	"en":  "English",
-	"eo":  "Esperanto",
-	"et":  "Estonian",
-	"ee":  "Ewe",      //
-	"fo":  "Faroese",  //
-	"fj":  "Fijian",   //
-	"fil": "Filipino", // "tl" on Google
-	"fi":  "Finnish",
-	"fr":  "French",
-	"fy":  "Frisian",
-	"gbi": "Galela", //
-	"gl":  "Galician",
-	"lg":  "Ganda",    //
-	"jy":  "Georgian", // "ka" on Google
-	"de":  "German",
-	"el":  "Greek",
-	"amu": "Guerrero Amuzgo", //
-	"gu":  "Gujarati",
-	"ht":  "Haitian Creole",
-	"ha":  "Hausa",
-	"haw": "Hawaiian",
-	"he":  "Hebrew", // "iw" on Google
-	"hi":  "Hindi",
-	"mww": "Hmong Daw", //
-	"hmn": "Hmong",     // not in iciba
-	"hu":  "Hungarian",
-	"is":  "Icelandic",
-	"ig":  "Igbo",
-	"id":  "Indonesian",
-	"ga":  "Irish",
-	"it":  "Italian",
-	"jac": "Jacalteco", //
-	"ja":  "Japanese",
-	"jv":  "Javanese", // "jw" on Google
-	"kab": "Kabyle",   //
-	"kn":  "Kannada",
-	"cak": "Kaqchikel",         //
-	"ka":  "Kazakh",            // Google only has "kk"
-	"kk":  "Kazakh (Cyrillic)", // Google has it as just "Kazakh"
-	"kek": "Kekchí",            //
-	"km":  "Khmer",
-	"rw":  "Kinyarwanda",
-	"kg":  "Kongo", //
-	"ko":  "Korean",
-	"ku":  "Kurdish (Kurmanji)",
-	"ky":  "Kyrgyz",
-	"lo":  "Lao",
-	"la":  "Latin",
-	"lv":  "Latvian",
-	"ln":  "Lingala", //
-	"lt":  "Lithuanian",
-	"dop": "Lukpa", //
-	"lb":  "Luxembourgish",
-	"mk":  "Macedonian",
-	"mg":  "Malagasy",
-	"ms":  "Malay",
-	"ml":  "Malayalam",
-	"mt":  "Maltese",
-	"mam": "Mam",  //
-	"gv":  "Manx", //
-	"mi":  "Maori",
-	"mr":  "Marathi",
-	"mhr": "Mari (Eastern)", //
-	"mrj": "Mari (Western)", //
-	"mn":  "Mongolian",
-	"me":  "Montenegrin", //
-	"my":  "Myanmar (Burmese)",
-	"nhg": "Nahuatl", //
-	"djk": "Ndyuka",  //
-	"ne":  "Nepali",
-	"no":  "Norwegian",
-	"or":  "Odia (Oriya)",
-	"ojb": "Ojibwa",
-	"om":  "Oromo",      //
-	"os":  "Ossetian",   //
-	"pck": "Paite",      //
-	"pap": "Papiamento", //
-	"ps":  "Pashto",
-	"fa":  "Persian",
-	"pl":  "Polish",
-	"pt":  "Portuguese",
-	"pot": "Potawatomi", //
-	"pa":  "Punjabi",
-	"otq": "Querétaro Otomi",     //
-	"quc": "Quiché",              //
-	"quw": "Quichua",             //
-	"chq": "Quiotepec Chinantec", //
-	"rmn": "Romani",              //
-	"ro":  "Romanian",
-	"rn":  "Rundi", //
-	"ru":  "Russian",
-	"sm":  "Samoan",
-	"sg":  "Sango", //
-	"gd":  "Scots Gaelic",
-	"sr":  "Serbian",
-	"crs": "Seselwa Creole French", //
-	"st":  "Sesotho",
-	"sn":  "Shona",
-	"jiv": "Shuar", //
-	"sd":  "Sindhi",
-	"si":  "Sinhala",
-	"sk":  "Slovak",
-	"sl":  "Slovenian",
-	"so":  "Somali",
-	"es":  "Spanish",
-	"su":  "Sundanese",
-	"sw":  "Swahili",
-	"sv":  "Swedish",
-	"syc": "Syriac",    // considered "extinct" but is somehow supported
-	"shi": "Tachelhit", //
-	"ty":  "Tahitian",  //
-	"tg":  "Tajik",
-	"ta":  "Tamil",
-	"tt":  "Tatar",
-	"te":  "Telugu",
-	"tet": "Tetum", //
-	"th":  "Thai",
-	"ti":  "Tigre",     //
-	"tw":  "Tiwi",      //
-	"tpi": "Tok Pisin", //
-	"to":  "Tonga",     //
-	"ts":  "Tsonga",
-	"tn":  "Tswana", //
-	"tr":  "Turkish",
-	"tk":  "Turkmen",
-	"udm": "Udmurt", //
-	"uk":  "Ukrainian",
-	"ppk": "Uma", //
-	"ur":  "Urdu",
-	"usp": "Uspanteco", //
-	"uy":  "Uyghur",    // "ug" on Google
-	"uz":  "Uzbek",
-	"ve":  "Venda", //
-	"vi":  "Vietnamese",
-	"war": "Waray", //
-	"cy":  "Welsh",
-	"wal": "Wolaitta", //
-	"wol": "Wolof",
-	"xh":  "Xhosa",
-	"yi":  "Yiddish",
-	"yo":  "Yoruba",
-	"yua": "Yucatán Maya", //
-	"dje": "Zarma",        //
-	"zu":  "Zulu",
-}
-
-func (_ *ICIBA) SourceLanguages() (Language, error) {
-	icibaLanguagesCopy := make(Language)
-	for k, v := range icibaLanguages {
-		icibaLanguagesCopy[k] = v
-	}
-
-	icibaLanguagesCopy["auto"] = "Detect Language"
-	return icibaLanguagesCopy, nil
-}
-
-func (_ *ICIBA) TargetLanguages() (Language, error) { return icibaLanguages, nil }
-
-func (_ *ICIBA) Translate(text string, from, to string) (TranslationResult, error) {
-	requestURL, _ := url.Parse("https://ifanyi.iciba.com/index.php")
-
-	query := url.Values{}
-	query.Add("c", "trans")
-	query.Add("m", "fy")
-	query.Add("client", "6")
-	query.Add("auth_user", "key_web_fanyi")
-
-	sum := md5.Sum([]byte(("6key_web_fanyiifanyiweb8hc9s98e" + text)))
-	query.Add("sign", hex.EncodeToString(sum[:])[:16])
-
-	requestURL.RawQuery = query.Encode()
-
-	formData := url.Values{}
-	formData.Add("from", from)
-	formData.Add("to", to)
-	formData.Add("q", text)
-
-	response, err := http.PostForm(requestURL.String(), formData)
-	if err != nil {
-		return TranslationResult{}, err
-	}
-
-	defer response.Body.Close()
-
-	if response.StatusCode != 200 {
-		return TranslationResult{}, fmt.Errorf("got status code %d from iCIBA", response.StatusCode)
-	}
-
-	var responseJSON struct {
-		Content struct {
-			From string `json:"from"`
-			Out  string `json:"out"`
-		} `json:"content"`
-	}
-
-	if err := json.NewDecoder(response.Body).Decode(&responseJSON); err != nil {
-		return TranslationResult{}, err
-	}
-
-	for code := range icibaLanguages {
-		if code == responseJSON.Content.From {
-			from = code
-			break
-		}
-	}
-
-	if from == "" {
-		return TranslationResult{TranslatedText: responseJSON.Content.Out},
-			fmt.Errorf("language code \"%s\" is not in iCIBA's language list", responseJSON.Content.From)
-	}
-
-	return TranslationResult{
-		SourceLanguage: from,
-		TranslatedText: responseJSON.Content.Out,
-	}, nil
-}
-
-func (_ *ICIBA) Tts(text, lang string) (string, error) { return "", nil }
Index: trunk/example/mai.ini
===================================================================
--- trunk/example/mai.ini	(revision 66)
+++ trunk/example/mai.ini	(revision 67)
@@ -3,3 +3,2 @@
 rootdir = "./static"
 tmplpath = "./views"
-user = "www"
Index: trunk/mai.1
===================================================================
--- trunk/mai.1	(revision 66)
+++ trunk/mai.1	(revision 67)
@@ -8,4 +8,6 @@
 .Nm
 .Op Fl f Ar config-file
+.Op Fl u Ar user
+.Op Fl g Ar group
 .Sh DESCRIPTION
 This project has been forked from the remains of the
@@ -15,4 +17,14 @@
 Much to anyone's dismay, this was named after
 .Lk https://en.touhouwiki.net/wiki/Mai Mai from Mystic Square
+.Sh FEATURES
+.Bl -tag -width 11n -compact
+.It Command-line tool
+See
+.Xr suwako 1
+.It Privilege dropping
+Stolen from
+.Xr partage 1
+just so you do not run this as root
+.El
 .Sh AUTHORS
 .An fattalion
@@ -21,4 +33,2 @@
 .Sh MAINTAINERS
 .An Izuru Yakumo Aq Mt yakumo.izuru@chaotic.ninja
-.Sh BUGS
-iCIBA engine doesn't work, throws HTTP 500
Index: trunk/mai.ini.5
===================================================================
--- trunk/mai.ini.5	(revision 66)
+++ trunk/mai.ini.5	(revision 67)
@@ -8,7 +8,4 @@
 .Ss [mai] section
 .Bl -tag -width 11n
-.It group
-Group ID for dropping privileges to.
-If unset, assume the GID of user
 .It listen
 HTTP port for the server to listen.
@@ -20,6 +17,4 @@
 Directory where the templates are located.
 Default is "./views"
-.It user
-User ID for dropping privileges to.
 .El
 .Sh ENVIRONMENT
Index: trunk/rc.d/FreeBSD
===================================================================
--- trunk/rc.d/FreeBSD	(revision 66)
+++ trunk/rc.d/FreeBSD	(revision 67)
@@ -21,5 +21,5 @@
 command="/usr/sbin/daemon"
 procname="/usr/local/bin/${name}"
-mai_args="-f ${mai_config}"
+mai_args="-f ${mai_config} -u www -g www"
 command_args="-S -m 3 -s info -l daemon -p ${pidfile} /usr/bin/env ${procname} ${mai_args}"
 
Index: trunk/rc.d/NetBSD
===================================================================
--- trunk/rc.d/NetBSD	(revision 66)
+++ trunk/rc.d/NetBSD	(revision 67)
@@ -12,5 +12,5 @@
 rcvar=$name
 command="/usr/pkg/bin/mai"
-command_args="-f /usr/pkg/etc/mai/mai.ini"
+command_args="-f /usr/pkg/etc/mai/mai.ini -u www -g www"
 pidfile="/var/run/${name}.pid"
 start_cmd="mai_start"
Index: trunk/rc.d/OpenBSD
===================================================================
--- trunk/rc.d/OpenBSD	(revision 66)
+++ trunk/rc.d/OpenBSD	(revision 67)
@@ -3,5 +3,5 @@
 
 daemon="/usr/local/bin/mai"
-daemon_flags="-f /usr/local/etc/mai/mai.ini"
+daemon_flags="-f /usr/local/etc/mai/mai.ini -u www -g www"
 
 . /etc/rc.d/rc.subr
Index: trunk/rc.d/immortal.yml
===================================================================
--- trunk/rc.d/immortal.yml	(revision 66)
+++ trunk/rc.d/immortal.yml	(revision 67)
@@ -1,1 +1,2 @@
-cmd: /usr/local/bin/mai -f /usr/local/etc/mai/mai.ini
+cmd: /usr/local/bin/mai -f /usr/local/etc/mai/mai.ini -g www -u www
+cwd: /usr/local/share/mai
Index: trunk/views/index.html
===================================================================
--- trunk/views/index.html	(revision 66)
+++ trunk/views/index.html	(revision 67)
@@ -128,6 +128,8 @@
     <footer class="center">
 	    <p>
-	    <a href="https://git.chaotic.ninja/yakumo.izuru/mai">Source code</a><br>
-	    a <em>Mirage AIB</em> project | Favicon source is <a href="https://pixiv.net/en/artworks/97787072">ユキマイ</a>
+	    <a href="https://git.chaotic.ninja/yakumo.izuru/mai">Source code</a>
+	    </p>
+	    <p>
+	    A <a href="https://mirage.h0stname.net">Mirage AIB</a> project
 	    </p>
     </footer>
