Added static web server and black / whitelist template

- Added static web server
- Added static web server default index
- Added embeded templates to blacklist / whitelist
- Added wip Web Directory Manager

Place the templates at ./www/templates/blacklist.html or whitelist.html to replace the build in embedded template for access control 403 error
-
This commit is contained in:
Toby Chui 2023-09-14 16:15:40 +08:00
parent ed92cccf0e
commit b63a0fc246
34 changed files with 6991 additions and 26 deletions

View File

@ -2,7 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil" "io"
"log" "log"
"math/rand" "math/rand"
"net/http" "net/http"
@ -65,7 +65,7 @@ func acmeRegisterSpecialRoutingRule() {
return return
} }
resBody, err := ioutil.ReadAll(res.Body) resBody, err := io.ReadAll(res.Body)
defer res.Body.Close() defer res.Body.Close()
if err != nil { if err != nil {
fmt.Printf("error reading: %s\n", err) fmt.Printf("error reading: %s\n", err)

View File

@ -169,6 +169,26 @@ func initAPIs() {
authRouter.HandleFunc("/api/acme/autoRenew/renewNow", acmeAutoRenewer.HandleRenewNow) authRouter.HandleFunc("/api/acme/autoRenew/renewNow", acmeAutoRenewer.HandleRenewNow)
authRouter.HandleFunc("/api/acme/wizard", acmewizard.HandleGuidedStepCheck) //ACME Wizard authRouter.HandleFunc("/api/acme/wizard", acmewizard.HandleGuidedStepCheck) //ACME Wizard
//Static Web Server
authRouter.HandleFunc("/api/webserv/status", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/webserv/start", staticWebServer.HandleStartServer)
authRouter.HandleFunc("/api/webserv/stop", staticWebServer.HandleStopServer)
authRouter.HandleFunc("/api/webserv/setPort", staticWebServer.HandlePortChange)
authRouter.HandleFunc("/api/webserv/setDirList", staticWebServer.SetEnableDirectoryListing)
if *allowWebFileManager {
//Web Directory Manager file operation functions
/*
authRouter.HandleFunc("/api/fs/list", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/upload", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/download", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/newFolder", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/copy", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/move", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/properties", staticWebServer.HandleGetStatus)
authRouter.HandleFunc("/api/fs/del", staticWebServer.HandleGetStatus)
*/
}
//Others //Others
http.HandleFunc("/api/info/x", HandleZoraxyInfo) http.HandleFunc("/api/info/x", HandleZoraxyInfo)
authRouter.HandleFunc("/api/info/geoip", HandleGeoIpLookup) authRouter.HandleFunc("/api/info/geoip", HandleGeoIpLookup)

View File

@ -43,6 +43,7 @@ var ztAPIPort = flag.Int("ztport", 9993, "ZeroTier controller API port")
var acmeAutoRenewInterval = flag.Int("autorenew", 86400, "ACME auto TLS/SSL certificate renew check interval (seconds)") var acmeAutoRenewInterval = flag.Int("autorenew", 86400, "ACME auto TLS/SSL certificate renew check interval (seconds)")
var enableHighSpeedGeoIPLookup = flag.Bool("fastgeoip", false, "Enable high speed geoip lookup, require 1GB extra memory (Not recommend for low end devices)") var enableHighSpeedGeoIPLookup = flag.Bool("fastgeoip", false, "Enable high speed geoip lookup, require 1GB extra memory (Not recommend for low end devices)")
var staticWebServerRoot = flag.String("webroot", "./www", "Static web server root folder. Only allow chnage in start paramters") var staticWebServerRoot = flag.String("webroot", "./www", "Static web server root folder. Only allow chnage in start paramters")
var allowWebFileManager = flag.Bool("webfm", true, "Enable web file manager for static web server root folder")
var ( var (
name = "Zoraxy" name = "Zoraxy"

View File

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path/filepath"
"strings" "strings"
"imuslab.com/zoraxy/mod/geodb" "imuslab.com/zoraxy/mod/geodb"
@ -192,9 +193,9 @@ func (h *ProxyHandler) handleAccessRouting(w http.ResponseWriter, r *http.Reques
if h.Parent.Option.GeodbStore.IsBlacklisted(clientIpAddr) { if h.Parent.Option.GeodbStore.IsBlacklisted(clientIpAddr) {
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
template, err := os.ReadFile("./web/forbidden.html") template, err := os.ReadFile(filepath.Join(h.Parent.Option.WebDirectory, "templates/blacklist.html"))
if err != nil { if err != nil {
w.Write([]byte("403 - Forbidden")) w.Write(page_forbidden)
} else { } else {
w.Write(template) w.Write(template)
} }
@ -206,9 +207,9 @@ func (h *ProxyHandler) handleAccessRouting(w http.ResponseWriter, r *http.Reques
if !h.Parent.Option.GeodbStore.IsWhitelisted(clientIpAddr) { if !h.Parent.Option.GeodbStore.IsWhitelisted(clientIpAddr) {
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
template, err := os.ReadFile("./web/forbidden.html") template, err := os.ReadFile(filepath.Join(h.Parent.Option.WebDirectory, "templates/whitelist.html"))
if err != nil { if err != nil {
w.Write([]byte("403 - Forbidden")) w.Write(page_forbidden)
} else { } else {
w.Write(template) w.Write(template)
} }

View File

@ -0,0 +1,55 @@
<html>
<head>
<!-- Zoraxy Forbidden Template -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.5.0/semantic.min.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.5.0/semantic.min.js"></script>
<title>Forbidden</title>
<style>
#msg{
position: absolute;
top: calc(50% - 150px);
left: calc(50% - 250px);
width: 500px;
height: 300px;
text-align: center;
}
#footer{
position: fixed;
padding: 2em;
padding-left: 5em;
padding-right: 5em;
bottom: 0px;
left: 0px;
width: 100%;
}
small{
word-break: break-word;
}
</style>
</head>
<body>
<div id="msg">
<h1 style="font-size: 6em; margin-bottom: 0px;"><i class="red ban icon"></i></h1>
<div>
<h3 style="margin-top: 1em;">403 - Forbidden</h3>
<div class="ui divider"></div>
<p>You do not have permission to view this directory or page. <br>
This might cause by the region limit setting of this site.</p>
<div class="ui divider"></div>
<div style="text-align: left;">
<small>Request time: <span id="reqtime"></span></small><br>
<small id="reqURLDisplay">Request URI: <span id="requrl"></span></small>
</div>
</div>
</div>
<script>
$("#reqtime").text(new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}));
$("#requrl").text(window.location.href);
</script>
</body>
</html>

View File

@ -1,6 +1,7 @@
package dynamicproxy package dynamicproxy
import ( import (
_ "embed"
"net" "net"
"net/http" "net/http"
"sync" "sync"
@ -31,6 +32,7 @@ type RouterOption struct {
RedirectRuleTable *redirection.RuleTable RedirectRuleTable *redirection.RuleTable
GeodbStore *geodb.Store //GeoIP blacklist and whitelist GeodbStore *geodb.Store //GeoIP blacklist and whitelist
StatisticCollector *statistic.Collector StatisticCollector *statistic.Collector
WebDirectory string //The static web server directory containing the templates folder
} }
type Router struct { type Router struct {
@ -123,3 +125,11 @@ type SubdOptions struct {
BasicAuthCredentials []*BasicAuthCredentials BasicAuthCredentials []*BasicAuthCredentials
BasicAuthExceptionRules []*BasicAuthExceptionRule BasicAuthExceptionRules []*BasicAuthExceptionRule
} }
/*
Web Templates
*/
var (
//go:embed templates/forbidden.html
page_forbidden []byte
)

View File

@ -5,6 +5,7 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -76,6 +77,22 @@ func PostBool(r *http.Request, key string) (bool, error) {
return false, errors.New("invalid boolean given") return false, errors.New("invalid boolean given")
} }
// Get POST paramter as int
func PostInt(r *http.Request, key string) (int, error) {
x, err := PostPara(r, key)
if err != nil {
return 0, err
}
x = strings.TrimSpace(x)
rx, err := strconv.Atoi(x)
if err != nil {
return 0, err
}
return rx, nil
}
func FileExists(filename string) bool { func FileExists(filename string) bool {
_, err := os.Stat(filename) _, err := os.Stat(filename)
if os.IsNotExist(err) { if os.IsNotExist(err) {

View File

@ -1,5 +1,13 @@
package webserv package webserv
import (
"encoding/json"
"net/http"
"strconv"
"imuslab.com/zoraxy/mod/utils"
)
/* /*
Handler.go Handler.go
@ -7,3 +15,74 @@ package webserv
web server is directly listening to the TCP port web server is directly listening to the TCP port
handlers in this script are for setting change only handlers in this script are for setting change only
*/ */
type StaticWebServerStatus struct {
ListeningPort int
EnableDirectoryListing bool
WebRoot string
Running bool
EnableWebDirManager bool
}
// Handle getting current static web server status
func (ws *WebServer) HandleGetStatus(w http.ResponseWriter, r *http.Request) {
listeningPortInt, _ := strconv.Atoi(ws.option.Port)
currentStatus := StaticWebServerStatus{
ListeningPort: listeningPortInt,
EnableDirectoryListing: ws.option.EnableDirectoryListing,
WebRoot: ws.option.WebRoot,
Running: ws.isRunning,
EnableWebDirManager: ws.option.EnableWebDirManager,
}
js, _ := json.Marshal(currentStatus)
utils.SendJSONResponse(w, string(js))
}
// Handle request for starting the static web server
func (ws *WebServer) HandleStartServer(w http.ResponseWriter, r *http.Request) {
err := ws.Start()
if err != nil {
utils.SendErrorResponse(w, err.Error())
return
}
utils.SendOK(w)
}
// Handle request for stopping the static web server
func (ws *WebServer) HandleStopServer(w http.ResponseWriter, r *http.Request) {
err := ws.Stop()
if err != nil {
utils.SendErrorResponse(w, err.Error())
return
}
utils.SendOK(w)
}
// Handle change server listening port request
func (ws *WebServer) HandlePortChange(w http.ResponseWriter, r *http.Request) {
newPort, err := utils.PostInt(r, "port")
if err != nil {
utils.SendErrorResponse(w, "invalid port number given")
return
}
err = ws.ChangePort(strconv.Itoa(newPort))
if err != nil {
utils.SendErrorResponse(w, err.Error())
return
}
utils.SendOK(w)
}
// Change enable directory listing settings
func (ws *WebServer) SetEnableDirectoryListing(w http.ResponseWriter, r *http.Request) {
enableList, err := utils.PostBool(r, "enable")
if err != nil {
utils.SendErrorResponse(w, "invalid setting given")
return
}
ws.option.EnableDirectoryListing = enableList
utils.SendOK(w)
}

View File

@ -22,7 +22,7 @@ func (ws *WebServer) resolveFileDiskPath(requestPath string) string {
// File server middleware to handle directory listing (and future expansion) // File server middleware to handle directory listing (and future expansion)
func (ws *WebServer) fsMiddleware(h http.Handler) http.Handler { func (ws *WebServer) fsMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if ws.option.EnableDirectoryListing { if !ws.option.EnableDirectoryListing {
if strings.HasSuffix(r.URL.Path, "/") { if strings.HasSuffix(r.URL.Path, "/") {
//This is a folder. Let check if index exists //This is a folder. Let check if index exists
if utils.FileExists(filepath.Join(ws.resolveFileDiskPath(r.URL.Path), "index.html")) { if utils.FileExists(filepath.Join(ws.resolveFileDiskPath(r.URL.Path), "index.html")) {

View File

@ -0,0 +1,61 @@
<html>
<head>
<title>Hello Zoraxy</title>
<style>
body {
font-family: Tahoma, sans-serif;
background-color: #f6f6f6;
color: #2d2e30;
}
.sectionHeader{
background-color: #c4d0d9;
padding: 0.1em;
}
.sectionHeader h3{
text-align: center;
}
.container{
margin: 4em;
margin-left: 10em;
margin-right: 10em;
background-color: #fefefe;
}
@media (max-width:960px) {
.container{
margin-left: 1em;
margin-right: 1em;
}
.sectionHeader{
padding-left: 1em;
padding-right: 1em;
}
}
.textcontainer{
padding: 1em;
}
</style>
</head>
<body>
<div class="container">
<div class="sectionHeader">
<h3>Welcome to Zoraxy Static Web Server!</h3>
</div>
<div class="textcontainer">
<p>If you see this page, that means your static web server is running.<br>
By default, all the html files are stored under <code>./web/html/</code>
relative to the zoraxy runtime directory.<br>
You can upload your html files to your web directory via the <b>Web Directory Manager</b>.
</p>
<p>
For online documentation, please refer to <a href="//zoraxy.arozos.com">zoraxy.arozos.com</a> or the <a href="https://github.com/tobychui/zoraxy/wiki">project wiki</a>.<br>
Thank you for using Zoraxy!
</p>
</div>
</div>
</body>
</html>

View File

@ -1,6 +1,8 @@
package webserv package webserv
import ( import (
"embed"
_ "embed"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -9,6 +11,7 @@ import (
"path/filepath" "path/filepath"
"sync" "sync"
"imuslab.com/zoraxy/mod/database"
"imuslab.com/zoraxy/mod/utils" "imuslab.com/zoraxy/mod/utils"
) )
@ -18,11 +21,17 @@ import (
This module host a static web server This module host a static web server
*/ */
//go:embed templates/*
var templates embed.FS
type WebServerOptions struct { type WebServerOptions struct {
Port string //Port for listening Port string //Port for listening
EnableDirectoryListing bool //Enable listing of directory EnableDirectoryListing bool //Enable listing of directory
WebRoot string //Folder for stroing the static web folders WebRoot string //Folder for stroing the static web folders
EnableWebDirManager bool //Enable web file manager to handle files in web directory
Sysdb *database.Database //Database for storing configs
} }
type WebServer struct { type WebServer struct {
mux *http.ServeMux mux *http.ServeMux
server *http.Server server *http.Server
@ -31,13 +40,23 @@ type WebServer struct {
mu sync.Mutex mu sync.Mutex
} }
// NewWebServer creates a new WebServer instance. // NewWebServer creates a new WebServer instance. One instance only
func NewWebServer(options *WebServerOptions) *WebServer { func NewWebServer(options *WebServerOptions) *WebServer {
if !utils.FileExists(options.WebRoot) { if !utils.FileExists(options.WebRoot) {
//Web root folder not exists. Create one //Web root folder not exists. Create one with default templates
os.MkdirAll(filepath.Join(options.WebRoot, "html"), 0775) os.MkdirAll(filepath.Join(options.WebRoot, "html"), 0775)
os.MkdirAll(filepath.Join(options.WebRoot, "templates"), 0775) os.MkdirAll(filepath.Join(options.WebRoot, "templates"), 0775)
indexTemplate, err := templates.ReadFile("templates/index.html")
if err != nil {
log.Println("Failed to read static wev server template file: ", err.Error())
} else {
os.WriteFile(filepath.Join(options.WebRoot, "html", "index.html"), indexTemplate, 0775)
}
} }
//Create new table to store the config
options.Sysdb.NewTable("webserv")
return &WebServer{ return &WebServer{
mux: http.NewServeMux(), mux: http.NewServeMux(),
option: options, option: options,
@ -46,11 +65,31 @@ func NewWebServer(options *WebServerOptions) *WebServer {
} }
} }
// Restore the configuration to previous config
func (ws *WebServer) RestorePreviousState() {
//Set the port
port := ws.option.Port
ws.option.Sysdb.Read("webserv", "port", &port)
ws.option.Port = port
//Set the enable directory list
enableDirList := ws.option.EnableDirectoryListing
ws.option.Sysdb.Read("webserv", "dirlist", &enableDirList)
ws.option.EnableDirectoryListing = enableDirList
//Check the running state
webservRunning := false
ws.option.Sysdb.Read("webserv", "enabled", &webservRunning)
if webservRunning {
ws.Start()
} else {
ws.Stop()
}
}
// ChangePort changes the server's port. // ChangePort changes the server's port.
func (ws *WebServer) ChangePort(port string) error { func (ws *WebServer) ChangePort(port string) error {
ws.mu.Lock()
defer ws.mu.Unlock()
if ws.isRunning { if ws.isRunning {
if err := ws.Stop(); err != nil { if err := ws.Stop(); err != nil {
return err return err
@ -60,6 +99,13 @@ func (ws *WebServer) ChangePort(port string) error {
ws.option.Port = port ws.option.Port = port
ws.server.Addr = ":" + port ws.server.Addr = ":" + port
err := ws.Start()
if err != nil {
return err
}
ws.option.Sysdb.Write("webserv", "port", port)
return nil return nil
} }
@ -100,7 +146,7 @@ func (ws *WebServer) Start() error {
log.Println("Static Web Server started. Listeing on :" + ws.option.Port) log.Println("Static Web Server started. Listeing on :" + ws.option.Port)
ws.isRunning = true ws.isRunning = true
ws.option.Sysdb.Write("webserv", "enabled", true)
return nil return nil
} }
@ -118,17 +164,14 @@ func (ws *WebServer) Stop() error {
} }
ws.isRunning = false ws.isRunning = false
ws.option.Sysdb.Write("webserv", "enabled", false)
return nil return nil
} }
// UpdateDirectoryListing enables or disables directory listing. // UpdateDirectoryListing enables or disables directory listing.
func (ws *WebServer) UpdateDirectoryListing(enable bool) { func (ws *WebServer) UpdateDirectoryListing(enable bool) {
ws.mu.Lock()
defer ws.mu.Unlock()
ws.option.EnableDirectoryListing = enable ws.option.EnableDirectoryListing = enable
ws.option.Sysdb.Write("webserv", "dirlist", enable)
} }
// Close stops the web server without returning an error. // Close stops the web server without returning an error.

View File

@ -64,6 +64,7 @@ func ReverseProxtInit() {
RedirectRuleTable: redirectTable, RedirectRuleTable: redirectTable,
GeodbStore: geodbStore, GeodbStore: geodbStore,
StatisticCollector: statisticCollector, StatisticCollector: statisticCollector,
WebDirectory: *staticWebServerRoot,
}) })
if err != nil { if err != nil {
log.Println(err.Error()) log.Println(err.Error())

View File

@ -217,13 +217,14 @@ func startupSequence() {
*/ */
staticWebServer = webserv.NewWebServer(&webserv.WebServerOptions{ staticWebServer = webserv.NewWebServer(&webserv.WebServerOptions{
Port: "8081", Sysdb: sysdb,
Port: "8081", //Default Port
WebRoot: *staticWebServerRoot, WebRoot: *staticWebServerRoot,
EnableDirectoryListing: true, EnableDirectoryListing: true,
EnableWebDirManager: *allowWebFileManager,
}) })
//Restore the web server to previous shutdown state
//TODO: Connect UI element to static web server staticWebServer.RestorePreviousState()
staticWebServer.Start()
} }
// This sequence start after everything is initialized // This sequence start after everything is initialized

View File

@ -4,6 +4,16 @@
<p>A simple static web server that serve html css and js files</p> <p>A simple static web server that serve html css and js files</p>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>
<div class="ui basic segment">
<h4 class="ui header" id="webservRunningState">
<i class="green circle icon"></i>
<div class="content">
<span class="webserv_status">Running</span>
<div class="sub header">Listening on :<span class="webserv_port">8081</span></div>
</div>
</h4>
</div>
<h3>Web Server Settings</h3> <h3>Web Server Settings</h3>
<div class="ui form"> <div class="ui form">
<div class="inline field"> <div class="inline field">
@ -29,10 +39,11 @@
</div> </div>
<div class="field"> <div class="field">
<label>Port Number</label> <label>Port Number</label>
<input id="webserv_docRoot" type="number" step="1" min="0" max="65535" value="8081" onchange="updateWebServLinkExample(this.value);"> <input id="webserv_listenPort" type="number" step="1" min="0" max="65535" value="8081" onchange="updateWebServLinkExample(this.value);">
<small>Use <code>http://127.0.0.1:<span class="webserv_port">8081</span></code> in proxy rules to access the web server</small> <small>Use <code>http://127.0.0.1:<span class="webserv_port">8081</span></code> in proxy rules to access the web server</small>
</div> </div>
</div> </div>
<small><i class="ui blue save icon"></i> Changes are saved automatically</small>
<br> <br>
<div class="ui message"> <div class="ui message">
<div class="ui accordion webservhelp"> <div class="ui accordion webservhelp">
@ -63,10 +74,108 @@
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>
<div class="ui basic segment">
<h2>Web Directory Manager</h2>
<p>Manage your files inside your web directory</p>
</div>
<iframe id="webserv_dirManager" src="tools/fs.html" style="width: 100%; height: 800px; border: 0px; overflow-y: hidden;">
</iframe>
<small>If you do not want to enable web access to your web directory, you can disable this feature with <code>-webfm=false</code> startup paramter</small>
<script> <script>
$(".webservhelp").accordion(); $(".webservhelp").accordion();
$(".ui.checkbox").checkbox();
function setWebServerRunningState(running){
if (running){
$("#webserv_enable").parent().checkbox("set checked");
$("#webservRunningState").find("i").attr("class", "green circle icon");
$("#webservRunningState").find(".webserv_status").text("Running");
}else{
$("#webserv_enable").parent().checkbox("set unchecked");
$("#webservRunningState").find("i").attr("class", "red circle icon");
$("#webservRunningState").find(".webserv_status").text("Stopped");
}
}
function updateWebServState(){
$.get("/api/webserv/status", function(data){
setWebServerRunningState(data.Running);
if (data.EnableDirectoryListing){
$("#webserv_enableDirList").parent().checkbox("set checked");
}else{
$("#webserv_enableDirList").parent().checkbox("set unchecked");
}
$("#webserv_docRoot").val(data.WebRoot + "/html/");
if (!data.EnableWebDirManager){
$("#webserv_dirManager").remove();
}
$("#webserv_listenPort").val(data.ListeningPort);
updateWebServLinkExample(data.ListeningPort);
//Bind checkbox events
$("#webserv_enable").off("change").on("change", function(){
let enable = $(this)[0].checked;
if (enable){
$.get("/api/webserv/start", function(data){
if (data.error != undefined){
msgbox(data.error, false);
}else{
msgbox("Static web server started");
setWebServerRunningState(true);
}
});
}else{
$.get("/api/webserv/stop", function(data){
if (data.error != undefined){
msgbox(data.error, false);
}else{
msgbox("Static web server stopped");
setWebServerRunningState(false);
}
});
}
});
$("#webserv_enableDirList").off("change").on("change", function(){
let enable = $(this)[0].checked;
$.ajax({
url: "/api/webserv/setDirList",
method: "POST",
data: {"enable": enable},
success: function(data){
if (data.error != undefined){
msgbox(data.error, false);
}else{
msgbox("Directory listing setting updated");
}
}
})
});
$("#webserv_listenPort").off("change").on("change", function(){
let newPort = $(this).val();
$.ajax({
url: "/api/webserv/setPort",
method: "POST",
data: {"port": newPort},
success: function(data){
if (data.error != undefined){
msgbox(data.error, false);
}else{
msgbox("Listening port updated");
}
}
})
});
})
}
updateWebServState();
function updateWebServLinkExample(newport){ function updateWebServLinkExample(newport){
$(".webserv_port").text(newport); $(".webserv_port").text(newport);

1388
src/web/tools/fs.css Normal file

File diff suppressed because it is too large Load Diff

1156
src/web/tools/fs.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<polygon fill="#FFFFFF" stroke="#231815" stroke-width="3" stroke-miterlimit="10" points="105.518,113.641 20.981,64.833
105.518,16.027 "/>
</svg>

After

Width:  |  Height:  |  Size: 618 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<polygon fill="#FFFFFF" stroke="#231815" stroke-width="3" stroke-miterlimit="10" points="20.981,16.026 105.518,64.833
20.981,113.64 "/>
</svg>

After

Width:  |  Height:  |  Size: 616 B

8
src/web/tools/img/eq.svg Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="48px" height="48px" viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
<path fill="#4f4f4f" d="M13.95,36.15v-24.3h3.3v24.3H13.95z M22.35,44.15V3.85h3.3v40.3H22.35z M5.6,28.15v-8.3h3.25v8.3H5.6z
M30.75,36.15v-24.3h3.3v24.3H30.75z M39.15,28.15v-8.3h3.25v8.3H39.15z"/>
</svg>

After

Width:  |  Height:  |  Size: 669 B

3442
src/web/tools/img/file.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 251 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="128px"
height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g id="圖層_2">
<polygon fill="#DBAC50" points="104.03,38.089 104.03,101.074 22.388,101.074 22.388,27.94 49.702,27.75 55.666,38.345 "/>
</g>
<g id="圖層_3">
<polygon fill="#E5BD64" points="104.328,101.97 22.836,101.97 38.209,52.716 118.806,52.716 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 728 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="200px" height="50px" viewBox="0 0 200 50" enable-background="new 0 0 200 50" xml:space="preserve">
<polygon fill="#DBDCDC" points="18.325,42.875 37.912,6.593 57.5,42.875 "/>
<polygon fill="#EEEEEF" points="66.771,6.594 94.125,24.744 66.771,42.895 "/>
<polygon fill="#9E9E9F" points="180.347,6.594 165.384,25 150.421,6.594 "/>
<polygon fill="#9E9E9F" points="150.422,42.875 165.384,24.469 180.347,42.875 "/>
<circle fill="#DBDCDC" cx="122.75" cy="25.156" r="17.875"/>
</svg>

After

Width:  |  Height:  |  Size: 843 B

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="128px"
height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g id="圖層_2">
<polygon fill="#95D5F4" points="110.998,23.424 110.998,84.064 17.001,84.064 17.001,13.652 48.449,13.469 55.315,23.669 "/>
</g>
<g id="圖層_3">
<polygon fill="#6BC2EC" points="110.998,84.064 17.001,84.064 17.087,31.401 110.57,31.401 "/>
</g>
<g id="圖層_4">
<rect x="17.001" y="103.51" fill="#B5B5B6" width="93.997" height="4.691"/>
<rect x="60.985" y="84.064" fill="#B5B5B6" width="6.029" height="19.445"/>
<path fill="#C9CACA" d="M72.935,110.512c0,2.221-1.8,4.02-4.021,4.02h-9.827c-2.221,0-4.021-1.799-4.021-4.02v-9.828
c0-2.221,1.8-4.021,4.021-4.021h9.827c2.221,0,4.021,1.801,4.021,4.021V110.512z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<polygon fill="#FFFFFF" stroke="#9FA0A0" stroke-width="3" stroke-miterlimit="10" points="78.125,32.875 78.125,83.25
30.125,83.25 30.125,22 68.625,22 "/>
<polyline fill="none" stroke="#9FA0A0" stroke-width="3" stroke-miterlimit="10" points="78.125,35.75 65.125,35.75 65.125,22 "/>
<line fill="none" stroke="#65D0FF" stroke-width="3" stroke-miterlimit="10" x1="35.75" y1="38.667" x2="60.417" y2="38.667"/>
<line fill="none" stroke="#65D0FF" stroke-width="3" stroke-miterlimit="10" x1="35.75" y1="45.167" x2="73.25" y2="45.167"/>
<line fill="none" stroke="#65D0FF" stroke-width="3" stroke-miterlimit="10" x1="35.75" y1="51.25" x2="73.25" y2="51.25"/>
<line fill="none" stroke="#65D0FF" stroke-width="3" stroke-miterlimit="10" x1="35.75" y1="57.833" x2="73.25" y2="57.833"/>
<line fill="none" stroke="#65D0FF" stroke-width="3" stroke-miterlimit="10" x1="35.417" y1="64" x2="73.25" y2="64"/>
<line fill="none" stroke="#65D0FF" stroke-width="3" stroke-miterlimit="10" x1="35.417" y1="70.75" x2="73.25" y2="70.75"/>
<polygon fill="#FFFFFF" stroke="#9FA0A0" stroke-width="3" stroke-miterlimit="10" points="104.5,57.916 104.5,108.291
56.5,108.291 56.5,47.041 95,47.041 "/>
<polyline fill="none" stroke="#9FA0A0" stroke-width="3" stroke-miterlimit="10" points="104.5,60.791 91.5,60.791 91.5,47.041 "/>
<line fill="none" stroke="#2EA7E0" stroke-width="3" stroke-miterlimit="10" x1="62.125" y1="63.708" x2="86.791" y2="63.708"/>
<line fill="none" stroke="#2EA7E0" stroke-width="3" stroke-miterlimit="10" x1="62.125" y1="70.207" x2="99.625" y2="70.207"/>
<line fill="none" stroke="#2EA7E0" stroke-width="3" stroke-miterlimit="10" x1="62.125" y1="76.291" x2="99.625" y2="76.291"/>
<line fill="none" stroke="#2EA7E0" stroke-width="3" stroke-miterlimit="10" x1="62.125" y1="82.875" x2="99.625" y2="82.875"/>
<line fill="none" stroke="#2EA7E0" stroke-width="3" stroke-miterlimit="10" x1="61.792" y1="89.041" x2="99.625" y2="89.041"/>
<line fill="none" stroke="#2EA7E0" stroke-width="3" stroke-miterlimit="10" x1="61.792" y1="95.791" x2="99.625" y2="95.791"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<polygon fill="#EC0013" stroke="#C30D23" stroke-miterlimit="10" points="95.338,37.37 88.63,30.662 64,55.292 39.37,30.662
32.662,37.37 57.292,62 32.662,86.63 39.369,93.338 64,68.707 88.63,93.338 95.338,86.631 70.707,62 "/>
</svg>

After

Width:  |  Height:  |  Size: 702 B

View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<image display="none" overflow="visible" width="347" height="333" xlink:href="data:image/jpeg;base64,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" transform="matrix(0.3272 0 0 0.3272 5.9824 3.0469)">
</image>
<rect x="19.833" y="28.5" fill="#322912" width="92.667" height="52.5"/>
<rect x="19.833" y="81" fill="#DCDDDD" width="92.667" height="10.667"/>
<rect x="50.167" y="101.167" fill="#DCDDDD" width="32.5" height="3.666"/>
<rect x="59.833" y="91.667" fill="#C9CACA" width="13.5" height="9.5"/>
<rect x="23.333" y="31.667" fill="#00A0E9" width="85.833" height="46"/>
<polyline fill="none" stroke="#FFFFFF" stroke-width="8" stroke-miterlimit="10" points="55.591,51.929 66.042,63.104
77.577,51.929 "/>
<line fill="none" stroke="#FFFFFF" stroke-width="8" stroke-miterlimit="10" x1="66.042" y1="63.104" x2="66.043" y2="28.5"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<rect x="26.2" y="17.403" fill="#F5D370" width="71.08" height="88.553"/>
<g>
<g>
<polygon fill="#FFE79C" points="59.98,72.606 59.98,22.099 26.2,17.403 26.2,105.956 49.486,109.192 49.486,76.212 "/>
</g>
</g>
<polygon fill="#FFFFFF" stroke="#727171" stroke-miterlimit="10" points="109.001,90.244 94.813,90.244 94.813,76.057
87.313,76.057 87.313,90.244 73.126,90.244 73.126,97.744 87.313,97.744 87.313,111.932 94.813,111.932 94.813,97.744
109.001,97.744 "/>
</svg>

After

Width:  |  Height:  |  Size: 943 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g id="圖層_2">
<g>
<polygon fill="#FADA79" points="104.029,38.089 104.029,101.074 22.388,101.074 22.388,27.94 49.702,27.75 55.666,38.345 "/>
</g>
</g>
<g id="圖層_3">
<g>
<polygon fill="#FFE79E" points="104.328,101.971 22.836,101.971 38.209,52.716 118.807,52.716 "/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 772 B

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<image display="none" overflow="visible" width="256" height="256" xlink:href="data:image/jpeg;base64,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
z/ad/wAVfOxia5zSMNU0ziHoY7S5SKa2yDOPCLi1YTH3VqwmFwsa2TrSykOUrv1ISHKuFcP9l3/F
XzsImuc0jDVNM4h6GO0uUim+BuiJafQSkfpqOTsMilIysImuc0jDVNM4h6GO0uUim+CiTO8TS5rC
JrnNIw1TTOIehjtLlIpunJUZkV+4M5WEvIZysJeQzlYS8hnKwl5DOVhLyGcrCXkM5WEvIZysJeQz
lYS8hnKwl5DOVhLyBqSZmZlJdk8umLqlzWETXOaRhqmmcQ9DHaXKRTfBRdUuawia5zSMNU0ziHoY
7S5SxdOUlBrPsLqY4dXjqjh1eOqOHV46o4dXjqjh1eOqOHV46o4dXjqjh1eOqOHV46o4dXjqjh1e
OqDJTRtkRSynL5F0xdUuawia5zSMNU0ziHoY7S5SxfBRdUuawia5zSMNU0ziGoY7S5SxfBRdUuaw
ia5zSMNU0ziHoY7S5SxdOQZmRX5SGeoZ6hnqGeoZ6hnqGeoZ6hnqGeoZ6hlEozlKS70xdUuawia5
zSMNU0ziGoY7S5SxfBRdUuawia5zSMNU0ziGoY7S5SxdOUSTUfYQ2KuvcNirr3DYq69w2KuvcNir
r3DYq69w2KuvcNirr3DYq69w2KuvcNirr3A5UGiTt6YuqXNYRNc5pGGqaZxDUMdpcpYvgouqXNYR
Nc5pGGqaZxD0MdpcpYvgouqXNYRNc5pGELv5KiPAcoZUh1KFoKT7xyENuzvCHEM7whxDO8IcQzvC
HEM7whxDO8IcQzvCHEM7wg4RKSssq+g8or3b05BmZfMhnqGeoZ6hnqGeoZ6hnqGeoZ6hnqGeoHIo
zl7emLqlzWETXOaR9B/pOKRLfyTkF19fqMbZeExtl4TG2XhMbZeExtl4TG2XhMbZeEwpTijUr9VV
07p/BRdUuawia5zSO1nXK6cokmr5ENirr3DYq69w2KuvcNirr3DYq69w2KuvcNirr3DYq69w2Kuv
cNirr3DYq69wOVBok7emLqlzWETXOaR2s65XwUXVLmsImuc0jtZ1yvgouqXMdhE1zmkdrOuX8FF1
K5rCJrnNI7WdcoXheF4XheF4XheF4XheF4XheF4XheEXUrmsImuc0jtf6TEQ403LLkpUZFKf0HGP
esxxj3rMcY96zHGPesxxj3rMcY96zHGPesxxj3rMcY96zHGPesxxj3rMcY96zHGPesxxj3rMcY96
zHGPesxxj3rMGRxbpkdwyNZ2ETXOaR/8D//Z" transform="matrix(0.459 0 0 0.459 5.25 4.5)">
</image>
<path fill="#D0B065" stroke="#B28247" stroke-width="2" stroke-miterlimit="10" d="M81.61,90.593c0,0.923-0.748,1.671-1.671,1.671
H24.671c-0.923,0-1.672-0.748-1.672-1.671V20.698c0-0.924,0.749-1.672,1.672-1.672h55.268c0.923,0,1.671,0.749,1.671,1.672V90.593z"
/>
<rect x="41.492" y="18.085" fill="#DCDDDD" stroke="#9FA0A0" stroke-width="2" stroke-miterlimit="10" width="22.985" height="10.552"/>
<polygon fill="#FFFFFF" stroke="#9FA0A0" stroke-width="3" stroke-miterlimit="10" points="105.714,53.116 105.714,106.334
55.004,106.334 55.004,41.627 95.679,41.627 "/>
<polyline fill="none" stroke="#9FA0A0" stroke-width="3" stroke-miterlimit="10" points="105.714,56.153 91.98,56.153 91.98,41.627
"/>
<line fill="none" stroke="#DCDDDD" stroke-width="3" stroke-miterlimit="10" x1="60.947" y1="59.234" x2="87.006" y2="59.234"/>
<line fill="none" stroke="#DCDDDD" stroke-width="3" stroke-miterlimit="10" x1="60.947" y1="66.101" x2="100.563" y2="66.101"/>
<line fill="none" stroke="#DCDDDD" stroke-width="3" stroke-miterlimit="10" x1="60.947" y1="72.527" x2="100.563" y2="72.527"/>
<line fill="none" stroke="#DCDDDD" stroke-width="3" stroke-miterlimit="10" x1="60.947" y1="79.484" x2="100.563" y2="79.484"/>
<line fill="none" stroke="#DCDDDD" stroke-width="3" stroke-miterlimit="10" x1="60.595" y1="85.998" x2="100.563" y2="85.998"/>
<line fill="none" stroke="#DCDDDD" stroke-width="3" stroke-miterlimit="10" x1="60.595" y1="93.129" x2="100.563" y2="93.129"/>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<circle fill="#24CC29" cx="84.5" cy="42.833" r="13.833"/>
<circle fill="#24CC29" cx="36.5" cy="67.334" r="13.833"/>
<circle fill="#24CC29" cx="84.5" cy="92.167" r="13.833"/>
<line fill="none" stroke="#24CC29" stroke-width="9" stroke-miterlimit="10" x1="36.5" y1="67.334" x2="84.5" y2="42.833"/>
<line fill="none" stroke="#24CC29" stroke-width="9" stroke-miterlimit="10" x1="36.5" y1="67.334" x2="84.5" y2="92.166"/>
</svg>

After

Width:  |  Height:  |  Size: 894 B

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g>
<circle fill="#86D1EF" cx="37.667" cy="71.896" r="25.083"/>
<circle fill="#86D1EF" cx="64.917" cy="58.895" r="36.249"/>
<circle fill="#86D1EF" cx="94.999" cy="76.729" r="20.417"/>
<path fill="#86D1EF" d="M96.416,95.146c0,1.104-0.777,2-1.738,2H37.156c-0.961,0-1.739-0.896-1.739-2v-31c0-1.106,0.778-2,1.739-2
h57.521c0.961,0,1.738,0.895,1.738,2V95.146z"/>
</g>
<image display="none" overflow="visible" width="512" height="512" xlink:href="data:image/jpeg;base64,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
AeWG6LhvhCHNj7MT6vAf2QcwhzTaIs+jPyO7US5DbZJVDz2IQ+WGLXX08xw9ran8dujZzdMCIQPo
NluBBs3CLT9bLIwIfajNJPhJoOAqkWfQ1LiGjpNhEfc+68eFln32kWQB9hhuiy7Ci5xLnG2TZPM8
Pa2p/Hbo2c9+KM9o6KSRgKsxA/GaPhQu9Dhm9SF5LMJXkMwleQzCV5DMJXkMwleQzCV5DMJXkMwl
eQzCV5DMJXkMwleQzCV5DMJXkMwleQzCV5DMJXkMwleQzCV5DMJXkMwleQzCV5DMJXkMwleQzCV5
DMJXkMwleQzCV5DMJXkMwleQzCV5DMJXkMwleQzCV3YcNt8ErzQwfxAH60qmNFc/GJI5zh7W1P47
dGz1A4e1tT+O3Rs9QOHtbU/jt0bPUDh7W1P47dGz1A4e1tT+O3Rs9QOHtbU/jt0bPUDh7W1P47dG
z1A4e1tT+O3Rs9QOHtbU/jt0bPUDh7W1P47dGz1A4e1tRti2x/l+faHmLd5bvLd5bvLd5bvLd5bv
Ld5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvL
d5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5bvLd5f/AJX+H/t8zQf+
S//Z" transform="matrix(0.2174 0 0 0.2174 8.354 3.207)">
</image>
<polyline fill="none" stroke="#FFFFFF" stroke-width="10" stroke-miterlimit="10" points="78.459,66.957 64.917,52.479
49.973,66.957 "/>
<line fill="none" stroke="#FFFFFF" stroke-width="10" stroke-miterlimit="10" x1="64.917" y1="52.479" x2="64.917" y2="97.313"/>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="128px" height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<circle fill="#231815" stroke="#231815" stroke-miterlimit="10" cx="64" cy="98.551" r="8.801"/>
<path fill="none" stroke="#231815" stroke-width="14" stroke-miterlimit="10" d="M10.296,49.66
c29.139-29.141,76.297-29.141,105.436,0"/>
<path fill="none" stroke="#231815" stroke-width="14" stroke-miterlimit="10" d="M28.269,65.352
c19.917-19.917,52.152-19.917,72.068,0"/>
<path fill="none" stroke="#231815" stroke-width="14" stroke-miterlimit="10" d="M45.548,81.838
c10.367-10.367,27.145-10.367,37.509,0"/>
</svg>

After

Width:  |  Height:  |  Size: 981 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 0 24 24" width="48px" fill="#FFFFFF"><path d="M0 0h24v24H0V0z" fill="none"/><path stroke="#231815" stroke-width="0.4px" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zm.5-7H9v2H7v1h2v2h1v-2h2V9h-2z"/></svg>

After

Width:  |  Height:  |  Size: 462 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0V0z" fill="none"/><path stroke="#231815" stroke-width="0.4px" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"/></svg>

After

Width:  |  Height:  |  Size: 442 B