diff --git a/mc_man.go b/mc_man.go index e3ceff5..a94f6fc 100644 --- a/mc_man.go +++ b/mc_man.go @@ -88,11 +88,9 @@ func main() { }() // Web Server Routine - /* - go func() { - util.StartServer(ch) - }() - */ + go func() { + util.StartServer(ch) + }() // The forever loop to monitor everything for { diff --git a/util/config.go b/util/config.go index 02eea19..ac28cf8 100644 --- a/util/config.go +++ b/util/config.go @@ -13,11 +13,14 @@ type Config struct { Options jason.Object FeatureTPHome bool FeatureTPVisit bool + FeatureTP bool FeatureDayNight bool MCUsers []*MCUser LoggedInMCUsers []*MCUser Whitelist []string Ops []string + TeleportPoints map[string]string + model *Model } var c *Config @@ -28,7 +31,7 @@ func LoadConfig(mm *MessageManager) { message_manager = mm c = new(Config) - mc_model := InitializeModel() + c.model = InitializeModel() // Load the whitelist whitelist_rd, err := ioutil.ReadFile("whitelist.json") @@ -67,57 +70,99 @@ func LoadConfig(mm *MessageManager) { fmt.Println("> Activating 'stop' listener") AddListener(func(i *Message) bool { if i.MCUser.IsOp && i.Text == "!stop\n" { - mm.Output("stop") - StopServer = true + DoStopServer() return true } return false }) - for _, option := range o { - opt_name, _ := option.GetString("name") - opt_enabled, _ := option.GetBoolean("enabled") - if opt_name == "home" { - c.FeatureTPHome = opt_enabled - if opt_enabled { - fmt.Println("> Activating 'home' listeners") - // Add !set home listener - AddListener(func(i *Message) bool { - if i.MCUser.Name != "" && i.Text == "!set home\n" { - AddTempListener(func(inp *Message) bool { - listen_for := "Teleported " + i.MCUser.Name + " to " - if inp.MCUser.Name == "" && strings.Contains(inp.Text, listen_for) { - // Found the text - r := strings.Split(inp.Text, listen_for) - if len(r) > 0 { - p_str := r[1] - p_str = strings.Replace(p_str, ",", "", -1) - p_str = strings.Replace(p_str, "\n", "", -1) - SetHome(i.MCUser.Name, p_str) - mm.Tell(i.MCUser.Name, "Set your home to "+p_str, "blue") - return true - } - } - return false - }) - mm.Output("tp " + i.MCUser.Name + " ~ ~ ~") - return true - } - return false - }) - // Add !home listener - AddListener(func(i *Message) bool { - if i.MCUser.Name != "" && i.Text == "!home\n" { - home_str, found := GetHome(i.MCUser.Name) - if found { - mm.Output("tp " + i.MCUser.Name + " " + home_str) - } else { - mm.Tell(i.MCUser.Name, "I don't know where your home is. Set it to your current position by typing '!set home'", "red") + c.FeatureTPHome = c.model.mcFeatureIsEnabled("tphome") + if c.FeatureTPHome { + fmt.Println("> Activating 'home' listeners") + // Add !set home listener + AddListener(func(i *Message) bool { + if i.MCUser.Name != "" && i.Text == "!set home\n" { + AddTempListener(func(inp *Message) bool { + listen_for := "Teleported " + i.MCUser.Name + " to " + if inp.MCUser.Name == "" && strings.Contains(inp.Text, listen_for) { + // Found the text + r := strings.Split(inp.Text, listen_for) + if len(r) > 0 { + p_str := r[1] + p_str = strings.Replace(p_str, ",", "", -1) + p_str = strings.Replace(p_str, "\n", "", -1) + SetHome(i.MCUser.Name, p_str) + mm.Tell(i.MCUser.Name, "Set your home to "+p_str, "blue") + return true } } return false }) + mm.Output("tp " + i.MCUser.Name + " ~ ~ ~") + return true } + return false + }) + // Add !home listener + AddListener(func(i *Message) bool { + if i.MCUser.Name != "" && i.Text == "!home\n" { + home_str, found := GetHome(i.MCUser.Name) + if found { + mm.Output("tp " + i.MCUser.Name + " " + home_str) + } else { + mm.Tell(i.MCUser.Name, "I don't know where your home is. Set it to your current position by typing '!set home'", "red") + } + } + return false + }) + } + + for _, option := range o { + opt_name, _ := option.GetString("name") + opt_enabled, _ := option.GetBoolean("enabled") + if opt_name == "home" { + /* + c.FeatureTPHome = opt_enabled + if opt_enabled { + fmt.Println("> Activating 'home' listeners") + // Add !set home listener + AddListener(func(i *Message) bool { + if i.MCUser.Name != "" && i.Text == "!set home\n" { + AddTempListener(func(inp *Message) bool { + listen_for := "Teleported " + i.MCUser.Name + " to " + if inp.MCUser.Name == "" && strings.Contains(inp.Text, listen_for) { + // Found the text + r := strings.Split(inp.Text, listen_for) + if len(r) > 0 { + p_str := r[1] + p_str = strings.Replace(p_str, ",", "", -1) + p_str = strings.Replace(p_str, "\n", "", -1) + SetHome(i.MCUser.Name, p_str) + mm.Tell(i.MCUser.Name, "Set your home to "+p_str, "blue") + return true + } + } + return false + }) + mm.Output("tp " + i.MCUser.Name + " ~ ~ ~") + return true + } + return false + }) + // Add !home listener + AddListener(func(i *Message) bool { + if i.MCUser.Name != "" && i.Text == "!home\n" { + home_str, found := GetHome(i.MCUser.Name) + if found { + mm.Output("tp " + i.MCUser.Name + " " + home_str) + } else { + mm.Tell(i.MCUser.Name, "I don't know where your home is. Set it to your current position by typing '!set home'", "red") + } + } + return false + }) + } + */ } else if opt_name == "visit" { c.FeatureTPVisit = opt_enabled if opt_enabled { @@ -163,6 +208,64 @@ func LoadConfig(mm *MessageManager) { return false }) } + } else if opt_name == "teleport" { + // The 'teleport to spawn' listener + c.TeleportPoints = make(map[string]string) + // Load all of the teleport points + if point_array, err := option.GetObjectArray("points"); err == nil { + if len(point_array) > 0 { + for k := range point_array { + if tp_name, err := point_array[k].GetString("name"); err == nil { + if tp_loc, err := point_array[k].GetString("location"); err == nil { + c.TeleportPoints[tp_name] = tp_loc + } + } + } + } + } + + c.FeatureTP = opt_enabled + if opt_enabled { + fmt.Println("> Activating 'teleport' listener") + // Add !tp listener + AddListener(func(i *Message) bool { + if i.MCUser.Name != "" && strings.HasPrefix(i.Text, "!tp ") { + tp_name := strings.Split(i.Text, " ")[1] + tp_str, found := GetTPPoint(tp_name) + if found { + mm.Output("tp " + i.MCUser.Name + " " + tp_str) + } else { + mm.Tell(i.MCUser.Name, "I don't know where "+tp_name+".", "red") + } + } + return false + }) + // Add !tpset listener + AddListener(func(i *Message) bool { + if i.MCUser.IsOp && strings.HasPrefix(i.Text, "!tpset ") { + tp_name := strings.Split(i.Text, " ")[1] + // Save user's current position as tp_name point + AddTempListener(func(inp *Message) bool { + listen_for := "Teleported " + i.MCUser.Name + " to " + if inp.MCUser.Name == "" && strings.Contains(inp.Text, listen_for) { + // Found the text + r := strings.Split(inp.Text, listen_for) + if len(r) > 0 { + p_str := r[1] + p_str = strings.Replace(p_str, ",", "", -1) + SetTPPoint(tp_name, p_str) + mm.Tell(i.MCUser.Name, "Added TP Point "+tp_name+" at "+p_str, "blue") + return true + } + } + return false + }) + mm.Output("tp " + i.MCUser.Name + " ~ ~ ~") + return true + } + return false + }) + } } else if opt_name == "daynight" { c.FeatureDayNight = opt_enabled if opt_enabled { @@ -274,6 +377,7 @@ func LoadConfig(mm *MessageManager) { } us.Home = user_home us.Porch = user_porch + c.model.updateMcUser(us) c.MCUsers = append(c.MCUsers, us) } } @@ -281,6 +385,13 @@ func LoadConfig(mm *MessageManager) { } } +func DoStopServer() { + message_manager.Output("stop") + WriteConfig() + c.model.closeDatabase() + StopServer = true +} + func LoginMCUser(u MCUser) { for _, user := range c.LoggedInMCUsers { if user.Name == u.Name { @@ -312,6 +423,11 @@ func AddMCUser(username string) { } func WriteConfig() { + c.model.mcSaveFeature("tphome", c.FeatureTPHome) + c.model.mcSaveFeature("tpvisit", c.FeatureTPVisit) + c.model.mcSaveFeature("tp", c.FeatureTP) + c.model.mcSaveFeature("daynight", c.FeatureDayNight) + // TODO: Make mc_man aware of the world // Generate the JSON string for the config file d := "{\"options\":[" @@ -328,6 +444,21 @@ func WriteConfig() { } else { d = d + "false" } + d = d + "},{\"name\":\"teleport\",\"enabled\":" + if c.FeatureTP { + d = d + "true" + // Output all TP Points + d = d + ",\"points\":[" + for k, v := range c.TeleportPoints { + d = d + "{\"name\":\"" + k + "\",\"location:\"" + v + "\"}" + } + if len(c.TeleportPoints) > 0 { + d = d[:len(d)-1] + } + d = d + "]" + } else { + d = d + "false" + } d = d + "},{\"name\":\"daynight\",\"enabled\":" if c.FeatureDayNight { d = d + "true" @@ -349,7 +480,7 @@ func WriteConfig() { ioutil.WriteFile("mc_man.config", do, 0664) } -func SetHome(user string, loc string) { +func SetHome(user, loc string) { u := FindMCUser(user, true) if u.Index != -1 { u.Home = strings.Replace(loc, "\n", "", -1) @@ -367,7 +498,7 @@ func GetHome(user string) (string, bool) { return u.Home, true } -func SetPorch(user string, loc string) { +func SetPorch(user, loc string) { u := FindMCUser(user, true) if u.Index != -1 { u.Porch = strings.Replace(loc, "\n", "", -1) @@ -384,6 +515,15 @@ func GetPorch(user string) (string, bool) { return u.Porch, true } +func SetTPPoint(tp_name, loc string) { + c.TeleportPoints[tp_name] = loc +} + +func GetTPPoint(tp_name string) (string, bool) { + ret := c.TeleportPoints[tp_name] + return ret, (ret != "") +} + func FindMCUser(name string, create bool) *MCUser { for _, user := range c.MCUsers { if user.Name == name { diff --git a/util/model.go b/util/model.go index 3b7b622..d384215 100644 --- a/util/model.go +++ b/util/model.go @@ -2,39 +2,150 @@ package util import ( "bytes" + "errors" + "fmt" "github.com/boltdb/bolt" "log" "time" ) -var users_bucket string -var user_prefix string - type Model struct { + // Bucket Names + mc_bucket string + mc_users_bucket string + mc_config_bucket string + web_bucket string + web_users_bucket string + + // Key prefixes + user_prefix string + config_feature_prefix string + db *bolt.DB } func InitializeModel() *Model { var err error - var ret *Model - users_bucket = "mc_users" - user_prefix = "mc_user_" + ret := new(Model) + ret.mc_bucket = "mc" + ret.mc_users_bucket = "mc_users" + ret.mc_config_bucket = "mc_config" + ret.web_bucket = "web" + ret.web_users_bucket = "web_users" + ret.user_prefix = "user_" + ret.config_feature_prefix = "feature_" + ret.db, err = bolt.Open("mc_man.db", 0600, nil) if err != nil { log.Fatal(err) } - defer ret.db.Close() return ret } +func (m *Model) closeDatabase() { + m.db.Close() +} + +/* Web Server Stuff */ +func (m *Model) getWebUser(username string) WebUser { + var ret WebUser + m.db.View(func(tx *bolt.Tx) error { + if web_b := tx.Bucket([]byte(m.web_bucket)); web_b != nil { + if web_u_b := web_b.Bucket([]byte(m.web_users_bucket)); web_u_b != nil { + user_key := m.user_prefix + username + if ub := web_u_b.Bucket([]byte(user_key)); ub != nil { + ret_uname := string(ub.Get([]byte("username"))) + ret_pass := string(ub.Get([]byte("password"))) + ret = WebUser{Username: ret_uname, Password: ret_pass} + return nil + } else { + return errors.New("Invalid User") + } + } + } + return errors.New("No Web Users") + }) + return ret +} + +func (m *Model) updateWebUser(u *WebUser) { + fmt.Printf("BOLT: Adding Web User %s\n", u.Username) + m.db.Update(func(tx *bolt.Tx) error { + web_b, err := tx.CreateBucketIfNotExists([]byte(m.web_bucket)) + if err != nil { + return err + } + + web_u_b, err := web_b.CreateBucketIfNotExists([]byte(m.web_users_bucket)) + if err != nil { + return err + } + user_key := m.user_prefix + u.Username + ub, uberr := web_u_b.CreateBucketIfNotExists([]byte(user_key)) + if uberr != nil { + return uberr + } + addStringPairToBucket(ub, "username", u.Username) + addStringPairToBucket(ub, "password", u.Password) + return nil + }) +} + +func (m *Model) mcSaveFeature(opt string, enabled bool) { + err := m.db.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists([]byte(m.mc_bucket)) + if err != nil { + return err + } + bc, err := b.CreateBucketIfNotExists([]byte(m.mc_config_bucket)) + if err != nil { + return err + } + addBooleanPairToBucket(bc, m.config_feature_prefix+opt, enabled) + return nil + }) + if err != nil { + fmt.Printf("Save Feature Error: %s", err) + } +} + +func (m *Model) mcFeatureIsEnabled(opt string) bool { + ret := false + m.db.View(func(tx *bolt.Tx) error { + lookingfor := []byte(opt) + b := tx.Bucket([]byte(m.mc_bucket)) + if b != nil { + bc := b.Bucket([]byte(m.mc_config_bucket)) + c := bc.Cursor() + srch_prefix := []byte(m.config_feature_prefix + opt) + fmt.Printf("%s:%s=> ", string(m.mc_config_bucket), string(srch_prefix)) + for k, v := c.Seek(srch_prefix); bytes.HasPrefix(k, srch_prefix); k, v = c.Next() { + // k should be the feature name, v is whether it is enabled or not + fmt.Printf("%s == %s => ", string(k), string(lookingfor)) + if bytes.Equal(k, lookingfor) { + ret = bytes.Equal(v, []byte("true")) + if ret { + fmt.Printf("It's On!\n") + } else { + fmt.Printf("It's Off!\n") + } + return nil + } + } + } + return errors.New("Feature Not Found") + }) + return ret +} + +/* Minecraft Config Stuff */ func (m *Model) getMcUsers() []MCUser { var ret []MCUser m.db.View(func(tx *bolt.Tx) error { - b := tx.Bucket([]byte(users_bucket)) + b := tx.Bucket([]byte(m.mc_users_bucket)) c := b.Cursor() - srch_prefix := []byte(user_prefix) + srch_prefix := []byte(m.user_prefix) for k, _ := c.Seek(srch_prefix); bytes.HasPrefix(k, srch_prefix); k, _ = c.Next() { - // v should be a mc_user bucket if user_bucket := b.Bucket(k); user_bucket != nil { if us_name := user_bucket.Get([]byte("name")); us_name != nil { new_user := NewMCUser(string(us_name)) @@ -53,14 +164,20 @@ func (m *Model) getMcUsers() []MCUser { } // updateMcUser adds or updates a user -func (m *Model) updateMcUser(u MCUser) { +func (m *Model) updateMcUser(u *MCUser) { + fmt.Printf("BOLT: Adding User %s\n", u.Name) m.db.Update(func(tx *bolt.Tx) error { - b, err := tx.CreateBucketIfNotExists([]byte(users_bucket)) + mc_b, err := tx.CreateBucketIfNotExists([]byte(m.mc_bucket)) if err != nil { return err } - user_key := user_prefix + u.Name - ub, uberr := b.CreateBucketIfNotExists([]byte(user_key)) + + mc_u_b, err := mc_b.CreateBucketIfNotExists([]byte(m.mc_users_bucket)) + if err != nil { + return err + } + user_key := m.user_prefix + u.Name + ub, uberr := mc_u_b.CreateBucketIfNotExists([]byte(user_key)) if uberr != nil { return uberr } diff --git a/util/webserver.go b/util/webserver.go new file mode 100644 index 0000000..7741ebd --- /dev/null +++ b/util/webserver.go @@ -0,0 +1,929 @@ +package util + +import ( + "fmt" + "github.com/gorilla/context" + "github.com/gorilla/sessions" + "io" + "io/ioutil" + "net/http" + "os" + "strings" +) + +var output_channel chan string + +type WebUser struct { + Username string + Password string +} + +var session_store = sessions.NewCookieStore([]byte("super_secret_secret :D")) + +func StartServer(ch chan string) { + output_channel = ch + _, err := os.Stat("mapcrafter/index.html") + if err == nil { + // Looks like mapcrafter is present + output_channel <- "* Mapcrafter Directory is Present, routing to /\n" + fs := http.FileServer(http.Dir("mapcrafter")) + http.Handle("/", fs) + } + http.HandleFunc("/assets/", getAsset) + http.HandleFunc("/admin/", serveMcMan) + output_channel <- "* Admin site running at /admin/\n" + http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux)) +} + +func serveMcMan(w http.ResponseWriter, r *http.Request) { + output := "" + output_channel <- fmt.Sprint("HTTP Request: (", r.Method, ") ", r.URL, "\n") + + the_path := r.URL.Path + the_path = strings.TrimPrefix(strings.ToLower(the_path), "/admin") + + if strings.HasPrefix(the_path, "/login") || the_path == "/" { + output = getHTML(loginScreen, w, r) + } else if strings.HasPrefix(the_path, "/dologin") { + output = getHTML(doLogin, w, r) + } else if strings.HasPrefix(the_path, "/api/") { + output = getAuthJSON(serveAPI, w, r) + } + fmt.Fprintf(w, output) +} + +func serveAPI(w http.ResponseWriter, r *http.Request) string { + _, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) + //body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) + if err != nil { + panic(err) + } + if err := r.Body.Close(); err != nil { + panic(err) + } + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + // What are we doing with this request? + the_path := strings.TrimPrefix(strings.ToLower(r.URL.Path), "/admin") + output_string := "" + if strings.HasPrefix(the_path, "/api") { + the_path = strings.TrimPrefix(the_path, "/api") + if strings.HasPrefix(the_path, "/v1") { + the_path = strings.TrimPrefix(the_path, "/v1") + if strings.HasPrefix(the_path, "/whitelist") { + output_string = handleWhitelist(r) + } else if strings.HasPrefix(the_path, "/ops") { + output_string = handleOps(r) + } else if strings.HasPrefix(the_path, "/stop") { + DoStopServer() + } else if strings.HasPrefix(the_path, "/init") { + v := WebUser{"br0xen", "asdf"} + c.model.updateWebUser(&v) + } + } + } + return output_string +} + +/* JSON Functions */ +func getJSON(mid func(http.ResponseWriter, *http.Request) string, + w http.ResponseWriter, r *http.Request) string { + w.Header().Set("Content-Type", "application/json") + return mid(w, r) +} + +func getAuthJSON(mid func(http.ResponseWriter, *http.Request) string, + w http.ResponseWriter, r *http.Request) string { + session, _ := session_store.Get(r, "mc_man_session") + + // Vaildate that the session is authenticated + if val, ok := session.Values["is_logged_in"].(string); ok { + switch val { + case "": + w.WriteHeader(403) + w.Header().Set("Content-Type", "application/json") + return "{\"status\":\"error\"}" + default: + w.Header().Set("Content-Type", "application/json") + return mid(w, r) + } + } else { + w.WriteHeader(403) + w.Header().Set("Content-Type", "application/json") + return "{\"status\":\"error\"}" + } + return "" +} + +func handleOps(r *http.Request) string { + if r.Method == "GET" { + return getOps() + } else if r.Method == "POST" { + // Add posted user to Ops + } + return "" +} + +func handleWhitelist(r *http.Request) string { + if r.Method == "GET" { + return getWhitelist() + } else if r.Method == "POST" { + // Add posted user to whitelist + } + return "" +} + +/* HTML Functions */ +func getAuthHTML(mid func(http.ResponseWriter, *http.Request) string, + w http.ResponseWriter, r *http.Request) string { + session, _ := session_store.Get(r, "mc_man_session") + + // Vaildate that the session is authenticated + if val, ok := session.Values["is_logged_in"].(string); ok { + switch val { + case "": + http.Redirect(w, r, "/admin/login", http.StatusFound) + default: + return mid(w, r) + } + } else { + http.Redirect(w, r, "/admin/login", http.StatusFound) + } + return "" +} + +func getHTML(mid func(http.ResponseWriter, *http.Request) string, + w http.ResponseWriter, r *http.Request) string { + return fmt.Sprintf("%s%s%s", htmlHeader("Minecraft Manager"), mid(w, r), htmlFooter()) +} + +func loginScreen(w http.ResponseWriter, r *http.Request) string { + return ` +
+
+ + + +
+
+` +} + +func doLogin(w http.ResponseWriter, r *http.Request) string { + ret := "Do Login
" + login_user := r.FormValue("username") + login_pass := r.FormValue("password") + lu := c.model.getWebUser(login_user) + // Set the Cookie + + if login_pass == lu.Password { + session, _ := session_store.Get(r, "mc_man_session") + session.Values["is_logged_in"] = login_user + session.Save(r, w) + + ret = ret + "Logged In!" + } + + return ret +} + +func htmlHeader(title string) string { + head := ` + + + + ` + head += title + head += ` + + + + + + + + + + +` + return head +} + +func htmlFooter() string { + return ` + + + + +` +} + +/* Data Functions */ +func getOps() string { + ret := "[" + num_users := 0 + for _, op_user := range GetConfig().Ops { + if num_users > 0 { + ret += "," + } + ret += fmt.Sprint("\"", op_user, "\"") + } + ret += "]" + return ret +} + +func getWhitelist() string { + ret := "[" + num_users := 0 + for _, wl_user := range GetConfig().Whitelist { + if num_users > 0 { + ret += "," + } + ret += fmt.Sprint("\"", wl_user, "\"") + } + ret += "]" + return ret +} + +/* Assets (Javascript/CSS) */ +func getAsset(w http.ResponseWriter, r *http.Request) { + output := "" + output_channel <- fmt.Sprint("HTTP Request: (", r.Method, ") ", r.URL, "\n") + + the_path := strings.ToLower(r.URL.Path) + the_path = strings.TrimPrefix(the_path, "/assets") + if strings.HasPrefix(the_path, "/js") { + w.Header().Set("Content-Type", "text/javascript; charset=UTF-8") + the_path = strings.TrimPrefix(the_path, "/js") + if strings.HasPrefix(the_path, "/b.js") { + output = getjsB() + } else if strings.HasPrefix(the_path, "/mc_man.js") { + output = getjsMcMan() + } + } else if strings.HasPrefix(the_path, "/css") { + w.Header().Set("Content-Type", "text/css; charset=UTF-8") + the_path = strings.TrimPrefix(the_path, "/css") + if strings.HasPrefix(the_path, "/pure.css") { + output = getcssPure() + } else if strings.HasPrefix(the_path, "/mc_man.css") { + output = getcssMcMan() + } + } + fmt.Fprintf(w, output) +} + +func getjsMcMan() string { + return ` +(function(window,document){ + B('#stop_link').on('click',function(){ + var oReq = new XMLHttpRequest(); + oReq.onload = function(){console.log(this.responseText);}; + oReq.open("get", "/admin/api/v1/stop", true); + oReq.send(); + }); + var menu=B('#menu'), + WINDOW_CHANGE_EVENT=('onorientationchange' in window)?'orientationchange':'resize'; + function toggleHorizontal(){ + [].forEach.call( + B('#menu .custom-can-transform'), + function(el){ + el.classList.toggle('pure-menu-horizontal'); + } + ); + }; + function toggleMenu(){ + if(menu[0].classList.contains('open')){ + setTimeout(toggleHorizontal,500); + } else { + toggleHorizontal(); + } + menu.classList.toggle('open'); + B('#toggle').classList.toggle('x'); + }; + function closeMenu(){ + if(menu[0].classList.contains('open')){ + toggleMenu(); + } + }; + B('#toggle').on('click', function(e){ + toggleMenu(); + }); + window.addEventListener(WINDOW_CHANGE_EVENT,closeMenu); +})(this,this.document); +` +} + +func getcssMcMan() string { + return ` +button{padding:8px;} +.button-success,.button-error,.button-warning,.button-secondary{ +color: white;border-radius: 4px;text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);} +.button-success{background: rgb(28, 184, 65);} +.button-error{background: rgb(202, 60, 60);} +.button-warning{background: rgb(223, 117, 20);} +.button-secondary{background: rgb(66, 184, 221);} +// Menu Stuff +.mcman-wrapper{background-color:#ffd390;margin-bottom:1em;-webkit-font-smoothing:antialiased; +height:2.1em;overflow:hidden;-webkit-transition:height 0.5s;-moz-transition:height 0.5s; +-ms-transition:height 0.5s;transition:height 0.5s;} +.mcman-wrapper.open{height:14em;} +.mcman-menu-3{text-align:right;} +.mcman-toggle{width:34px;height:34px;display:block;position:absolute;top:0;right:0;display:none;} +.mcman-toggle .bar{background-color:#777;display:block;width:20px;height:2px;border-radius:100px; +position:absolute;top:18px;right:7px;-webkit-transition:all 0.5s;-moz-transition:all 0.5s; +-ms-transition:all 0.5s;transition:all 0.5s;} +.mcman-toggle .bar:first-child{-webkit-transform:translateY(-6px);-moz-transform:translateY(-6px); +-ms-transform:translateY(-6px);transform:translateY(-6px);} +.mcman-toggle.x .bar{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg); +-ms-transform:rotate(45deg);transform:rotate(45deg);} +.mcman-toggle.x .bar:first-child{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg); +-ms-transform:rotate(-45deg);transform:rotate(-45deg);} +@media (max-width:47.999em){.custom-menu-3{text-align:left;}.custom-toggle{display:block;} +` +} + +func getjsB() string { + return ` +function B(els, attrs) { + // Turn 'this' into an array of passed in elements. + function B(els) { + if(typeof els === "string") { + els = this.brb.create(els); + } + for(var i = 0; i < els.length; i++) { + this[i] = els[i]; + } + this.length = els.length; +// return this; + } + + // Map a function to all elements in 'this' + B.prototype.map = function(callback) { + var results = [], i = 0; + for(;i 1 ? m : m[0]; + }; + + // Update css for each element in 'this' + B.prototype.css = function(css_opt_var, css_opt_val) { + if(typeof css_opt_var !== "string") { + for(css_var in css_opt_var) { + this.forEach(function(el){el.style[css_var]=css_opt_var[css_var];}); + } + return this; + } else { + if(typeof css_opt_val !== "undefined") { + return this.forEach(function(el){el.style[css_opt_var]=css_opt_val;}); + } else { + return this.mapOne(function(el){return el.style[css_opt_var];}); + } + } + }; + + // Update the innerText for each element in 'this' + B.prototype.text = function(text) { + if(typeof text !== "undefined") { + return this.forEach(function(el){el.innerText=text;}); + } else { + return this.mapOne(function(el){return el.innerText;}); + } + }; + + // Add a class to each element in 'this' + B.prototype.addClass = function(classes) { + var className = ""; + if(typeof classes !== "string") { + for(var i=0;i-1){ + cs = cs.slice(0,i).concat(cs.slice(++i)); + } + el.className=cs.join(" "); + }); + }; + + // Set an attribute for each element in 'this' + B.prototype.attr = function(attr,val){ + if(typeof val!=="undefined"){ + if(this[0].tagName=="INPUT" && attr.toUpperCase()=="VALUE") { + // If we're setting the 'VALUE' then it's actually .value + return this.forEach(function(el){ + el.value=val; + }); + } else { + // Otherwise use .setAttribute + return this.forEach(function(el){ + el.setAttribute(attr,val); + }); + } + } else { + // And clearing the value + if(this[0].tagName=="INPUT" && attr.toUpperCase()=="VALUE") { + return this.mapOne(function(el){ + return el.value; + }); + } else { + return this.mapOne(function(el){ + return el.getAttribute(attr); + }); + } + } + }; + + // Actually set a value on each element (can be done with attr too.) + B.prototype.val = function(new_val) { + if(typeof new_val!=="undefined"){ + return this.forEach(function(el){ + el.value = new_val; + }); + } else { + // Just retrieve the value for the first element + return this.mapOne(function(el) { + return el.value; + }); + } + } + + // Append an element to the DOM after each element in 'this' + B.prototype.append = function(els) { + this.forEach(function(parEl, i) { + els.forEach(function(childEl) { + if(i>0) { + childEl=childEl.cloneNode(true); + } + parEl.appendChild(childEl); + }); + }); + }; + + // Prepend an element to the DOM before each element in 'this' + B.prototype.prepend = function(els) { + return this.forEach(function(parEl, i) { + for(var j = els.length-1; j>-1; j--) { + childEl=(i>0)?els[j].cloneNode(true):els[j]; + parEl.insertBefore(childEl, parEl.firstChild); + } + }); + }; + + // Remove all elements in 'this' from the DOM + B.prototype.remove = function() { + return this.forEach(function(el){ + return el.parentNode.removeChild(el); + }); + }; + + // Find children that match selector + B.prototype.children = function(selector) { + var results = []; + this.forEach(function(el) { + var sub_r = el.querySelectorAll(selector); + for(var i = 0; i < sub_r.length; i++) { + results.push(sub_r[i]); + } + }); + return results; + } + + B.prototype.firstChild = function(selector) { + return this.children(selector)[0]; + } + + // Add an event listener to each element in 'this' + B.prototype.on = (function(){ + // Browser compatibility... + if(document.addEventListener) { + return function(evt,fn) { + return this.forEach(function(el){ + el.addEventListener(evt, fn, false); + }); + }; + } else if(document.attachEvent) { + return function(evt,fn) { + return this.forEach(function(el){ + el.attachEvent("on"+evt,fn); + }); + }; + } else { + return function(evt, fn) { + return this.forEach(function(el){ + el["on"+evt]=fn; + }); + }; + } + }()); + + // Disable event listeners on elements in 'this' + B.prototype.off = (function(){ + // Browser compatibility... + if(document.removeEventListener) { + return function(evt, fn) { + return this.forEach(function(el) { + el.removeEventListener(evt, fn, false); + }); + }; + } else if(document.detachEvent) { + return function(evt, fn) { + return this.forEach(function(el) { + el.detachEvent("on"+evt, fn); + }); + }; + } else { + return function(evt, fn) { + return this.forEach(function(el){ + el["on"+evt]=null; + }); + }; + } + }()); + + // The actual framework object, yay! + var brb = { + // Get an element + get: function(selector) { + var els; + if(typeof selector === "string") { + els = document.querySelectorAll(selector); + } else if(selector.length) { + els = selector; + } else { + els = [selector]; + } + return new B(els); + }, + // Create a new element + create: function(tagName, attrs) { + var el = new B([document.createElement(tagName)]); + // Set attributes on new element + if(attrs) { + if(attrs.className) { + // Classes + el.addClass(attrs.className); + delete attrs.classname; + } + if(attrs.text) { + // Text + el.text(attrs.text); + delete attrs.text; + } + for(var key in attrs) { + // All other Attributes + if(attrs.hasOwnProperty(key)) { + el.attr(key, attrs[key]); + } + } + } + return el; + } + }; + if(els.match) { + var match_tags = els.match(/<([^>\s\/]*)\s?\/?>/); + } + if(match_tags && match_tags.length > 0) { + // It's a 'create tag' command + return brb.create(match_tags[1], attrs); + } else { + // Just search for matches + return brb.get(els); + } +}; +` +} + +func getcssPure() string { + return ` +/*! +Pure v0.6.0 +Copyright 2014 Yahoo! Inc. All rights reserved. +Licensed under the BSD License. +https://github.com/yahoo/pure/blob/master/LICENSE.md +*/ +/*! +normalize.css v^3.0 | MIT License | git.io/normalize +Copyright (c) Nicolas Gallagher and Jonathan Neal +*/ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust: +100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup, +main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align: +baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color: +transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{ +font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{ +font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{ +border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing: +content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em} +button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button, +select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{ +-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default} +button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal} +input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0} +input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto} +input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box; +box-sizing:content-box}input[type=search]::-webkit-search-cancel-button, +input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver; +margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{ +font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.hidden,[hidden]{ +display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em; +*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed; +font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex; +-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap;-ms-align-content:flex-start; +-webkit-align-content:flex-start;align-content:flex-start}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em} +.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal; +vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1, +.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5, +.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12, +.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24, +.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24, +.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24, +.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1; +letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{ +width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8, +.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%} +.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{ +width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%; +*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%} +.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%} +.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12, +.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{ +width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{ +width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{ +width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{ +width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12, +.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1, +.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;zoom:1;line-height:normal; +white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none; +-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none; +-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-button::-moz-focus-inner{ +padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;padding:.5em 1em;color:#444; +color:rgba(0,0,0,.8);border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6; +text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{ +filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', +GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent), +color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1))); +background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1)); +background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1)); +background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1)); +background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{ +outline:0}.pure-button-active,.pure-button:active{ +box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset;border-color:#000\9} +.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus, +.pure-button-disabled:active{border:0;background-image:none; +filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4; +-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none} +.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected, +a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text], +.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url], +.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time], +.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week], +.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel], +.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block; +border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle; +-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){ +padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd; +border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} +.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus, +.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus, +.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus, +.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus, +.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus, +.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus, +.pure-form textarea:focus{outline:0;border-color:#129FEA}.pure-form input:not([type]):focus{ +outline:0;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus, +.pure-form input[type=checkbox]:focus{outline:thin solid #129FEA;outline:1px auto #129FEA} +.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block} +.pure-form input[type=text][disabled],.pure-form input[type=password][disabled], +.pure-form input[type=email][disabled],.pure-form input[type=url][disabled], +.pure-form input[type=date][disabled],.pure-form input[type=month][disabled], +.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled], +.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled], +.pure-form input[type=number][disabled],.pure-form input[type=search][disabled], +.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled], +.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3} +.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3} +.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{ +background-color:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid, +.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#e9322d} +.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus, +.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{height:2.25em; +border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{ +margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{ +display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5} +.pure-form-stacked input[type=text],.pure-form-stacked input[type=password], +.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date], +.pure-form-stacked input[type=month],.pure-form-stacked input[type=time], +.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local], +.pure-form-stacked input[type=week],.pure-form-stacked input[type=number], +.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color], +.pure-form-stacked input[type=file],.pure-form-stacked select,.pure-form-stacked label, +.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){ +display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select, +.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1; +vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{ +margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block; +vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 11em} +.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em} +.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input,.pure-form .pure-group +textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}.pure-form +.pure-group input:focus,.pure-form .pure-group textarea:focus{z-index:3}.pure-form .pure-group +input:first-child,.pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0} +.pure-form .pure-group input:first-child:last-child,.pure-form .pure-group textarea:first-child:last-child{ +top:1px;border-radius:4px;margin:0}.pure-form .pure-group input:last-child,.pure-form .pure-group +textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}.pure-form .pure-group button{margin:.35em 0} +.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%} +.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline, +.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle; +font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em} +@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0} +.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password], +.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date], +.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime], +.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number], +.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color], +.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text], +.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url], +.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time], +.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week], +.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel], +.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{ +margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{ +margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{ +display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu{-webkit-box-sizing:border-box; +-moz-box-sizing:border-box;box-sizing:border-box}.pure-menu-fixed{position:fixed;left:0;top:0;z-index:3} +.pure-menu-list,.pure-menu-item{position:relative}.pure-menu-list{list-style:none;margin:0;padding:0} +.pure-menu-item{padding:0;margin:0;height:100%}.pure-menu-link,.pure-menu-heading{display:block; +text-decoration:none;white-space:nowrap}.pure-menu-horizontal{width:100%;white-space:nowrap} +.pure-menu-horizontal .pure-menu-list{display:inline-block}.pure-menu-horizontal .pure-menu-item, +.pure-menu-horizontal .pure-menu-heading,.pure-menu-horizontal .pure-menu-separator{display:inline-block; +*display:inline;zoom:1;vertical-align:middle}.pure-menu-item .pure-menu-item{display:block}.pure-menu-children{ +display:none;position:absolute;left:100%;top:0;margin:0;padding:0;z-index:3}.pure-menu-horizontal +.pure-menu-children{left:0;top:auto;width:inherit}.pure-menu-allow-hover:hover>.pure-menu-children, +.pure-menu-active>.pure-menu-children{display:block;position:absolute}.pure-menu-has-children> +.pure-menu-link:after{padding-left:.5em;content:"\25B8";font-size:small}.pure-menu-horizontal +.pure-menu-has-children>.pure-menu-link:after{content:"\25BE"}.pure-menu-scrollable{overflow-y:scroll; +overflow-x:hidden}.pure-menu-scrollable .pure-menu-list{display:block}.pure-menu-horizontal +.pure-menu-scrollable .pure-menu-list{display:inline-block}.pure-menu-horizontal.pure-menu-scrollable{ +white-space:nowrap;overflow-y:hidden;overflow-x:auto;-ms-overflow-style:none; +-webkit-overflow-scrolling:touch;padding:.5em 0}.pure-menu-horizontal.pure-menu-scrollable::-webkit-scrollbar{ +display:none}.pure-menu-separator{background-color:#ccc;height:1px;margin:.3em 0}.pure-menu-horizontal +.pure-menu-separator{width:1px;height:1.3em;margin:0 .3em}.pure-menu-heading{text-transform:uppercase; +color:#565d64}.pure-menu-link{color:#777}.pure-menu-children{background-color:#fff}.pure-menu-link, +.pure-menu-disabled,.pure-menu-heading{padding:.5em 1em}.pure-menu-disabled{opacity:.5}.pure-menu-disabled +.pure-menu-link:hover{background-color:transparent}.pure-menu-active>.pure-menu-link,.pure-menu-link:hover, +.pure-menu-link:focus{background-color:#eee}.pure-menu-selected .pure-menu-link,.pure-menu-selected +.pure-menu-link:visited{color:#000}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show; +border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0; +text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px; +font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child, +.pure-table th:first-child{border-left-width:0}.pure-table thead{background-color:#e0e0e0;color:#000; +text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{ +background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2} +.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child>td{ +border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px; +border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child>td{border-bottom-width:0} + +@media screen and (min-width:35.5em){.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-1-2,.pure-u-sm-1-3, +.pure-u-sm-2-3,.pure-u-sm-1-4,.pure-u-sm-3-4,.pure-u-sm-1-5,.pure-u-sm-2-5,.pure-u-sm-3-5, +.pure-u-sm-4-5,.pure-u-sm-5-5,.pure-u-sm-1-6,.pure-u-sm-5-6,.pure-u-sm-1-8,.pure-u-sm-3-8, +.pure-u-sm-5-8,.pure-u-sm-7-8,.pure-u-sm-1-12,.pure-u-sm-5-12,.pure-u-sm-7-12,.pure-u-sm-11-12, +.pure-u-sm-1-24,.pure-u-sm-2-24,.pure-u-sm-3-24,.pure-u-sm-4-24,.pure-u-sm-5-24,.pure-u-sm-6-24, +.pure-u-sm-7-24,.pure-u-sm-8-24,.pure-u-sm-9-24,.pure-u-sm-10-24,.pure-u-sm-11-24,.pure-u-sm-12-24, +.pure-u-sm-13-24,.pure-u-sm-14-24,.pure-u-sm-15-24,.pure-u-sm-16-24,.pure-u-sm-17-24,.pure-u-sm-18-24, +.pure-u-sm-19-24,.pure-u-sm-20-24,.pure-u-sm-21-24,.pure-u-sm-22-24,.pure-u-sm-23-24,.pure-u-sm-24-24{ +display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top; +text-rendering:auto}.pure-u-sm-1-24{width:4.1667%;*width:4.1357%}.pure-u-sm-1-12,.pure-u-sm-2-24{ +width:8.3333%;*width:8.3023%}.pure-u-sm-1-8,.pure-u-sm-3-24{width:12.5%;*width:12.469%}.pure-u-sm-1-6, +.pure-u-sm-4-24{width:16.6667%;*width:16.6357%}.pure-u-sm-1-5{width:20%;*width:19.969%}.pure-u-sm-5-24{ +width:20.8333%;*width:20.8023%}.pure-u-sm-1-4,.pure-u-sm-6-24{width:25%;*width:24.969%}.pure-u-sm-7-24{ +width:29.1667%;*width:29.1357%}.pure-u-sm-1-3,.pure-u-sm-8-24{width:33.3333%;*width:33.3023%} +.pure-u-sm-3-8,.pure-u-sm-9-24{width:37.5%;*width:37.469%}.pure-u-sm-2-5{width:40%;*width:39.969%} +.pure-u-sm-5-12,.pure-u-sm-10-24{width:41.6667%;*width:41.6357%}.pure-u-sm-11-24{width:45.8333%; +*width:45.8023%}.pure-u-sm-1-2,.pure-u-sm-12-24{width:50%;*width:49.969%}.pure-u-sm-13-24{width:54.1667%; +*width:54.1357%}.pure-u-sm-7-12,.pure-u-sm-14-24{width:58.3333%;*width:58.3023%}.pure-u-sm-3-5{ +width:60%;*width:59.969%}.pure-u-sm-5-8,.pure-u-sm-15-24{width:62.5%;*width:62.469%}.pure-u-sm-2-3, +.pure-u-sm-16-24{width:66.6667%;*width:66.6357%}.pure-u-sm-17-24{width:70.8333%;*width:70.8023%} +.pure-u-sm-3-4,.pure-u-sm-18-24{width:75%;*width:74.969%}.pure-u-sm-19-24{width:79.1667%;*width:79.1357%} +.pure-u-sm-4-5{width:80%;*width:79.969%}.pure-u-sm-5-6,.pure-u-sm-20-24{width:83.3333%;*width:83.3023%} +.pure-u-sm-7-8,.pure-u-sm-21-24{width:87.5%;*width:87.469%}.pure-u-sm-11-12,.pure-u-sm-22-24{ +width:91.6667%;*width:91.6357%}.pure-u-sm-23-24{width:95.8333%;*width:95.8023%}.pure-u-sm-1,.pure-u-sm-1-1, +.pure-u-sm-5-5,.pure-u-sm-24-24{width:100%}}@media screen and (min-width:48em){.pure-u-md-1,.pure-u-md-1-1, +.pure-u-md-1-2,.pure-u-md-1-3,.pure-u-md-2-3,.pure-u-md-1-4,.pure-u-md-3-4,.pure-u-md-1-5,.pure-u-md-2-5, +.pure-u-md-3-5,.pure-u-md-4-5,.pure-u-md-5-5,.pure-u-md-1-6,.pure-u-md-5-6,.pure-u-md-1-8,.pure-u-md-3-8, +.pure-u-md-5-8,.pure-u-md-7-8,.pure-u-md-1-12,.pure-u-md-5-12,.pure-u-md-7-12,.pure-u-md-11-12, +.pure-u-md-1-24,.pure-u-md-2-24,.pure-u-md-3-24,.pure-u-md-4-24,.pure-u-md-5-24,.pure-u-md-6-24, +.pure-u-md-7-24,.pure-u-md-8-24,.pure-u-md-9-24,.pure-u-md-10-24,.pure-u-md-11-24,.pure-u-md-12-24, +.pure-u-md-13-24,.pure-u-md-14-24,.pure-u-md-15-24,.pure-u-md-16-24,.pure-u-md-17-24,.pure-u-md-18-24, +.pure-u-md-19-24,.pure-u-md-20-24,.pure-u-md-21-24,.pure-u-md-22-24,.pure-u-md-23-24,.pure-u-md-24-24{ +display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top; +text-rendering:auto}.pure-u-md-1-24{width:4.1667%;*width:4.1357%}.pure-u-md-1-12,.pure-u-md-2-24{ +width:8.3333%;*width:8.3023%}.pure-u-md-1-8,.pure-u-md-3-24{width:12.5%;*width:12.469%}.pure-u-md-1-6, +.pure-u-md-4-24{width:16.6667%;*width:16.6357%}.pure-u-md-1-5{width:20%;*width:19.969%}.pure-u-md-5-24{ +width:20.8333%;*width:20.8023%}.pure-u-md-1-4,.pure-u-md-6-24{width:25%;*width:24.969%}.pure-u-md-7-24{ +width:29.1667%;*width:29.1357%}.pure-u-md-1-3,.pure-u-md-8-24{width:33.3333%;*width:33.3023%} +.pure-u-md-3-8,.pure-u-md-9-24{width:37.5%;*width:37.469%}.pure-u-md-2-5{width:40%;*width:39.969%} +.pure-u-md-5-12,.pure-u-md-10-24{width:41.6667%;*width:41.6357%}.pure-u-md-11-24{width:45.8333%; +*width:45.8023%}.pure-u-md-1-2,.pure-u-md-12-24{width:50%;*width:49.969%}.pure-u-md-13-24{width:54.1667%; +*width:54.1357%}.pure-u-md-7-12,.pure-u-md-14-24{width:58.3333%;*width:58.3023%}.pure-u-md-3-5{width:60%; +*width:59.969%}.pure-u-md-5-8,.pure-u-md-15-24{width:62.5%;*width:62.469%}.pure-u-md-2-3,.pure-u-md-16-24{ +width:66.6667%;*width:66.6357%}.pure-u-md-17-24{width:70.8333%;*width:70.8023%}.pure-u-md-3-4, +.pure-u-md-18-24{width:75%;*width:74.969%}.pure-u-md-19-24{width:79.1667%;*width:79.1357%}.pure-u-md-4-5{ +width:80%;*width:79.969%}.pure-u-md-5-6,.pure-u-md-20-24{width:83.3333%;*width:83.3023%}.pure-u-md-7-8, +.pure-u-md-21-24{width:87.5%;*width:87.469%}.pure-u-md-11-12,.pure-u-md-22-24{width:91.6667%; +*width:91.6357%}.pure-u-md-23-24{width:95.8333%;*width:95.8023%}.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-5-5, +.pure-u-md-24-24{width:100%}}@media screen and (min-width:64em){.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-1-2, +.pure-u-lg-1-3,.pure-u-lg-2-3,.pure-u-lg-1-4,.pure-u-lg-3-4,.pure-u-lg-1-5,.pure-u-lg-2-5,.pure-u-lg-3-5, +.pure-u-lg-4-5,.pure-u-lg-5-5,.pure-u-lg-1-6,.pure-u-lg-5-6,.pure-u-lg-1-8,.pure-u-lg-3-8,.pure-u-lg-5-8, +.pure-u-lg-7-8,.pure-u-lg-1-12,.pure-u-lg-5-12,.pure-u-lg-7-12,.pure-u-lg-11-12,.pure-u-lg-1-24, +.pure-u-lg-2-24,.pure-u-lg-3-24,.pure-u-lg-4-24,.pure-u-lg-5-24,.pure-u-lg-6-24,.pure-u-lg-7-24, +.pure-u-lg-8-24,.pure-u-lg-9-24,.pure-u-lg-10-24,.pure-u-lg-11-24,.pure-u-lg-12-24,.pure-u-lg-13-24, +.pure-u-lg-14-24,.pure-u-lg-15-24,.pure-u-lg-16-24,.pure-u-lg-17-24,.pure-u-lg-18-24,.pure-u-lg-19-24, +.pure-u-lg-20-24,.pure-u-lg-21-24,.pure-u-lg-22-24,.pure-u-lg-23-24,.pure-u-lg-24-24{display:inline-block; +*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto} +.pure-u-lg-1-24{width:4.1667%;*width:4.1357%}.pure-u-lg-1-12,.pure-u-lg-2-24{width:8.3333%;*width:8.3023%} +.pure-u-lg-1-8,.pure-u-lg-3-24{width:12.5%;*width:12.469%}.pure-u-lg-1-6,.pure-u-lg-4-24{width:16.6667%; +*width:16.6357%}.pure-u-lg-1-5{width:20%;*width:19.969%}.pure-u-lg-5-24{width:20.8333%;*width:20.8023%} +.pure-u-lg-1-4,.pure-u-lg-6-24{width:25%;*width:24.969%}.pure-u-lg-7-24{width:29.1667%;*width:29.1357%} +.pure-u-lg-1-3,.pure-u-lg-8-24{width:33.3333%;*width:33.3023%}.pure-u-lg-3-8,.pure-u-lg-9-24{width:37.5%; +*width:37.469%}.pure-u-lg-2-5{width:40%;*width:39.969%}.pure-u-lg-5-12,.pure-u-lg-10-24{width:41.6667%; +*width:41.6357%}.pure-u-lg-11-24{width:45.8333%;*width:45.8023%}.pure-u-lg-1-2,.pure-u-lg-12-24{width:50%; +*width:49.969%}.pure-u-lg-13-24{width:54.1667%;*width:54.1357%}.pure-u-lg-7-12,.pure-u-lg-14-24{ +width:58.3333%;*width:58.3023%}.pure-u-lg-3-5{width:60%;*width:59.969%}.pure-u-lg-5-8,.pure-u-lg-15-24{ +width:62.5%;*width:62.469%}.pure-u-lg-2-3,.pure-u-lg-16-24{width:66.6667%;*width:66.6357%}.pure-u-lg-17-24{ +width:70.8333%;*width:70.8023%}.pure-u-lg-3-4,.pure-u-lg-18-24{width:75%;*width:74.969%}.pure-u-lg-19-24{ +width:79.1667%;*width:79.1357%}.pure-u-lg-4-5{width:80%;*width:79.969%}.pure-u-lg-5-6,.pure-u-lg-20-24{ +width:83.3333%;*width:83.3023%}.pure-u-lg-7-8,.pure-u-lg-21-24{width:87.5%;*width:87.469%}.pure-u-lg-11-12, +.pure-u-lg-22-24{width:91.6667%;*width:91.6357%}.pure-u-lg-23-24{width:95.8333%;*width:95.8023%} +.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-5-5,.pure-u-lg-24-24{width:100%}}@media screen and (min-width:80em){ +.pure-u-xl-1,.pure-u-xl-1-1,.pure-u-xl-1-2,.pure-u-xl-1-3,.pure-u-xl-2-3,.pure-u-xl-1-4,.pure-u-xl-3-4, +.pure-u-xl-1-5,.pure-u-xl-2-5,.pure-u-xl-3-5,.pure-u-xl-4-5,.pure-u-xl-5-5,.pure-u-xl-1-6,.pure-u-xl-5-6, +.pure-u-xl-1-8,.pure-u-xl-3-8,.pure-u-xl-5-8,.pure-u-xl-7-8,.pure-u-xl-1-12,.pure-u-xl-5-12, +.pure-u-xl-7-12,.pure-u-xl-11-12,.pure-u-xl-1-24,.pure-u-xl-2-24,.pure-u-xl-3-24,.pure-u-xl-4-24, +.pure-u-xl-5-24,.pure-u-xl-6-24,.pure-u-xl-7-24,.pure-u-xl-8-24,.pure-u-xl-9-24,.pure-u-xl-10-24, +.pure-u-xl-11-24,.pure-u-xl-12-24,.pure-u-xl-13-24,.pure-u-xl-14-24,.pure-u-xl-15-24,.pure-u-xl-16-24, +.pure-u-xl-17-24,.pure-u-xl-18-24,.pure-u-xl-19-24,.pure-u-xl-20-24,.pure-u-xl-21-24,.pure-u-xl-22-24, +.pure-u-xl-23-24,.pure-u-xl-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal; +word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-xl-1-24{width:4.1667%;*width:4.1357%} +.pure-u-xl-1-12,.pure-u-xl-2-24{width:8.3333%;*width:8.3023%}.pure-u-xl-1-8,.pure-u-xl-3-24{width:12.5%; +*width:12.469%}.pure-u-xl-1-6,.pure-u-xl-4-24{width:16.6667%;*width:16.6357%}.pure-u-xl-1-5{width:20%; +*width:19.969%}.pure-u-xl-5-24{width:20.8333%;*width:20.8023%}.pure-u-xl-1-4,.pure-u-xl-6-24{width:25%; +*width:24.969%}.pure-u-xl-7-24{width:29.1667%;*width:29.1357%}.pure-u-xl-1-3,.pure-u-xl-8-24{ +width:33.3333%;*width:33.3023%}.pure-u-xl-3-8,.pure-u-xl-9-24{width:37.5%;*width:37.469%}.pure-u-xl-2-5{ +width:40%;*width:39.969%}.pure-u-xl-5-12,.pure-u-xl-10-24{width:41.6667%;*width:41.6357%}.pure-u-xl-11-24{ +width:45.8333%;*width:45.8023%}.pure-u-xl-1-2,.pure-u-xl-12-24{width:50%;*width:49.969%}.pure-u-xl-13-24{ +width:54.1667%;*width:54.1357%}.pure-u-xl-7-12,.pure-u-xl-14-24{width:58.3333%;*width:58.3023%} +.pure-u-xl-3-5{width:60%;*width:59.969%}.pure-u-xl-5-8,.pure-u-xl-15-24{width:62.5%;*width:62.469%} +.pure-u-xl-2-3,.pure-u-xl-16-24{width:66.6667%;*width:66.6357%}.pure-u-xl-17-24{width:70.8333%; +*width:70.8023%}.pure-u-xl-3-4,.pure-u-xl-18-24{width:75%;*width:74.969%}.pure-u-xl-19-24{width:79.1667%; +*width:79.1357%}.pure-u-xl-4-5{width:80%;*width:79.969%}.pure-u-xl-5-6,.pure-u-xl-20-24{width:83.3333%; +*width:83.3023%}.pure-u-xl-7-8,.pure-u-xl-21-24{width:87.5%;*width:87.469%}.pure-u-xl-11-12, +.pure-u-xl-22-24{width:91.6667%;*width:91.6357%}.pure-u-xl-23-24{width:95.8333%;*width:95.8023%} +.pure-u-xl-1,.pure-u-xl-1-1,.pure-u-xl-5-5,.pure-u-xl-24-24{width:100%}} +` +} diff --git a/util/webserver.go.disabled b/util/webserver.go.disabled deleted file mode 100644 index 072afb9..0000000 --- a/util/webserver.go.disabled +++ /dev/null @@ -1,203 +0,0 @@ -package util - -import ( - //"database/sql" - "fmt" - //_ "github.com/mattn/go-sqlite3" - //"encoding/json" - "github.com/boltdb/bolt" - "io" - "io/ioutil" - //"log" - "net/http" - "os" - "strings" -) - -var output_channel chan string - -type WebUser struct { - Username string `json:"username"` - Password string `json:"password"` -} - -func StartServer(ch chan string) { - output_channel = ch - _, err := os.Stat("mapcrafter/index.html") - if err == nil { - // Looks like mapcrafter is present - output_channel <- "* Mapcrafter Directory is Present, routing to /map\n" - fs := http.FileServer(http.Dir("mapcrafter")) - http.Handle("/", fs) - } - http.HandleFunc("/admin/", serveMcMan) - http.ListenAndServe(":8080", nil) -} - -func serveMcMan(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, htmlHeader("mc_man - Minecraft Manager")) - - the_path := r.URL.Path - output_channel <- the_path + "\n" - - the_path = strings.TrimPrefix(strings.ToLower(the_path), "/admin") - output_channel <- the_path + "\n" - - fmt.Fprintf(w, the_path) - if strings.HasPrefix(the_path, "/login") { - fmt.Fprintf(w, loginScreen()) - } else if strings.HasPrefix(the_path, "/dologin") { - fmt.Fprintf(w, doLogin(w, r)) - } else if strings.HasPrefix(the_path, "/api/") { - fmt.Fprintf(w, serveAPI(w, r)) - } - - fmt.Fprintf(w, htmlFooter()) -} - -func loginScreen() string { - return ` -
- - - -
-` -} - -func doLogin(w http.ResponseWriter, r *http.Request) string { - ret := "Do Login
" - ret = ret + r.FormValue("username") - ret = ret + r.FormValue("password") - - return ret -} - -func serveAPI(w http.ResponseWriter, r *http.Request) { - _, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) - //body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) - if err != nil { - panic(err) - } - if err := r.Body.Close(); err != nil { - panic(err) - } - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - // What are we doing with this request? - output_channel <- fmt.Sprint("HTTP Request: (", r.Method, ") ", r.URL, "\n") - the_path := r.URL.Path - output_string := "" - if strings.HasPrefix(the_path, "/api") { - the_path = strings.TrimPrefix(the_path, "/api") - if strings.HasPrefix(the_path, "/v1") { - the_path = strings.TrimPrefix(the_path, "/v1") - if strings.HasPrefix(the_path, "/whitelist") { - output_string = handleWhitelist(r) - } else if strings.HasPrefix(the_path, "/ops") { - output_string = handleOps(r) - } - } - } - fmt.Fprintf(w, output_string) -} - -/* JSON Functions */ -func handleOps(r *http.Request) string { - if r.Method == "GET" { - return getOps() - } else if r.Method == "POST" { - // Add posted user to Ops - } - return "" -} - -func handleWhitelist(r *http.Request) string { - if r.Method == "GET" { - return getWhitelist() - } else if r.Method == "POST" { - // Add posted user to whitelist - } - return "" -} - -func getOps() string { - ret := "[" - num_users := 0 - for _, op_user := range GetConfig().Ops { - if num_users > 0 { - ret += "," - } - ret += fmt.Sprint("\"", op_user, "\"") - } - ret += "]" - return ret - -} - -func getWhitelist() string { - ret := "[" - num_users := 0 - for _, wl_user := range GetConfig().Whitelist { - if num_users > 0 { - ret += "," - } - ret += fmt.Sprint("\"", wl_user, "\"") - } - ret += "]" - return ret -} - -func setupDatabase() bool { - /* - db, err := bolt.Open("mc_man.db", 0600, nil) - if err != nil { - log.Fatal(err) - } - defer db.Close() - - err = db.Update(func(tx *bolt.Tx) error { - return nil - }) - */ - /* - var err error - web_database, err = sql.Open("sqlite3", "mc_man.db") - defer web_database.Close() - - if err == nil { - // Error opening the DB, can't log in - return false - } - rows, err := db.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='users';") - defer rows.Close() - for rows.Next() { - err := rows.Scan - } - // rows, err := db.Query("SELECT * FROM USERS") - return true - */ - return true -} - -/* HTML Functions */ -func htmlHeader(title string) string { - head := ` - - - - ` - head += title - head += ` - - - -` - return head -} - -func htmlFooter() string { - return ` - - -` -}