Browse Source

✨ New Feature

- [Apps] This is a feature that has been highly requested by the community. Import the original Docker application into CasaOS. Now it's easy to import with just a few clicks!
- [Apps] App list supports a custom sorting function! You can arrange apps in different orders by dragging the icons.
- [Apps] App custom installation supports Docker Compose configuration import in YAML format.
- [Files] Added thumbnail preview function for image files.
- [Connect] Multiple CasaConenct devices in the LAN will be transmitted through the LAN network.
- [System] Added a switch for auto-mounting USB disk devices.

🎈 Enhancement
- [System] Optimized the system update alert, you will see the new version update log from the next version.
- [Apps] Added live preview for icons in custom installed apps.
- [Apps] Optimized the input of WebUI.
- [Files] Completely updated the image preview, now it supports switching all images in the same folder, as well as dragging, zooming, rotating and resetting.
- [Widgets] Added color levels for CPU and RAM charts.
- [Conenct] Optimized the display of the right-click menu of the Connect friends list.

🎈 Changed
- [Files] Change the initial display directory to /DATA

🐞 Fixed
- [System] Fixed an issue with Raspberry Pi devices failing to boot using USB disks. (Achieved by disabling USB disk auto-mount)
- [Apps] Fixed the issue that some Docker CLI commands failed to import.
- [Apps] Fixed the issue that the app is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as the app name. (Newly installed apps only)
- [Apps] Fixed the issue that Pi-hole cannot be launched after installation in the app store.
- [Apps] Fixed the issue that apps cannot be updated with WatchTower.
- [Files] Fixed the issue that when there is an upload task, the task status is lost after closing Files.
LinkLeong 3 năm trước cách đây
mục cha
commit
d0f3dc806e
72 tập tin đã thay đổi với 1235 bổ sung1271 xóa
  1. 29 2
      CHANGELOG.md
  2. 1 1
      UI
  3. 4 10
      conf/conf.ini.sample
  4. BIN
      github.com/IceWhaleTech/CasaOS-linux-amd64
  5. BIN
      github.com/IceWhaleTech/CasaOS-linux-arm64
  6. 2 2
      go.mod
  7. 2 2
      go.sum
  8. 2 2
      main.go
  9. 11 0
      model/app-analyse.go
  10. 1 0
      model/manifest.go
  11. 1 0
      model/receive/app.go
  12. 2 3
      pkg/config/init.go
  13. 0 1
      pkg/utils/file/file.go
  14. 5 3
      pkg/utils/file/image.go
  15. 1 0
      pkg/utils/httper/httper.go
  16. 30 0
      pkg/utils/network_detection.go
  17. 29 0
      pkg/utils/network_detection_test.go
  18. 0 73
      pkg/utils/sort/app_info_dev.go
  19. 0 74
      pkg/utils/sort/app_info_evn.go
  20. 0 73
      pkg/utils/sort/app_info_port.go
  21. 0 73
      pkg/utils/sort/app_info_vol.go
  22. 36 66
      route/init.go
  23. 5 5
      route/route.go
  24. 56 60
      route/v1/docker.go
  25. 2 2
      route/v1/file.go
  26. 27 8
      route/v1/person.go
  27. 22 7
      route/v1/system.go
  28. 93 68
      service/app.go
  29. 9 0
      service/app_test.go
  30. 2 0
      service/casa.go
  31. 4 4
      service/docker.go
  32. 1 1
      service/model/o_application.go
  33. 6 4
      service/model/o_container.go
  34. 12 0
      service/person.go
  35. 10 1
      service/system.go
  36. 0 12
      service/udpconn.go
  37. 5 0
      service/zima_info.go
  38. 6 2
      shell/helper.sh
  39. 12 2
      types/system.go
  40. 9 9
      web/browserconfig.xml
  41. 14 14
      web/favicon.svg
  42. BIN
      web/fonts/materialdesignicons-webfont.0fb040cb.woff2
  43. BIN
      web/fonts/materialdesignicons-webfont.1514bb9f.ttf
  44. BIN
      web/fonts/materialdesignicons-webfont.5a409f9f.woff
  45. BIN
      web/fonts/materialdesignicons-webfont.ff90567b.eot
  46. 0 0
      web/img/CasaConnect.svg
  47. 67 0
      web/img/Files.svg
  48. 11 11
      web/img/add_button.07d47199.svg
  49. 25 25
      web/img/android.48a6cf16.svg
  50. 28 28
      web/img/application-x-apple.5eb295b2.svg
  51. BIN
      web/img/bg3_blur.f7b30d87.jpg
  52. 11 11
      web/img/casa-white.f250568a.svg
  53. 39 39
      web/img/default-avatar.d92cd43a.svg
  54. 121 121
      web/img/folder-hdd.42e0a4ee.svg
  55. 113 113
      web/img/folder-usb.1011b135.svg
  56. BIN
      web/img/gradient.6c5a7f30.png
  57. 25 25
      web/img/icon/safari-pinned-tab.svg
  58. 158 158
      web/img/macos.6403eda3.svg
  59. 54 54
      web/img/syncthing-logo.27d25cad.svg
  60. 34 34
      web/index.html
  61. 0 0
      web/js/0.js
  62. 2 2
      web/js/2.js
  63. 5 5
      web/js/3.js
  64. 0 32
      web/js/4.js
  65. 4 4
      web/js/5.js
  66. 2 2
      web/js/6.js
  67. 2 2
      web/js/7.js
  68. 0 0
      web/js/app.js
  69. 62 0
      web/js/chunk-vendors.js
  70. 1 1
      web/robots.txt
  71. 14 14
      web/site.webmanifest
  72. 6 6
      web/static.go

+ 29 - 2
CHANGELOG.md

@@ -9,15 +9,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
-- Connect and file add image thumbnail function
+### Changed
+
+### Removed
+
+### Security
+
+### Fixed
+
+## [0.3.1-pre] - 2022-05-13
+
+### Added
+
+- CasaConnect and file add image thumbnail function
 - Import of docker applications
-- Apply manual upgrades
+- List support custom sorting function
 - CasaConnect gives priority to LAN connections
+- USB auto-mount switch (Raspberry Pi is off by default)
+- Application custom installation supports Docker Compose configuration import in YAML format
+- You will see the new version changelog from the next version
+- Added live preview for icons in custom installed applications
 
 ### Changed
 
 - Application data is no longer saved to the database
 - Optimize app store speed issues
+- Optimize the way WebUI is filled in
+- Image preview has been completely upgraded and now supports switching between all images in the same folder, as well as dragging, zooming, rotating and resetting.
+- Added color levels to the CPU and RAM charts
+- Optimized the display of the Connect friends list right-click menu
+- Change the initial display directory to /DATA
 
 ### Removed
 
@@ -27,6 +48,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Fixed
 
+- Fixed the problem that some Docker CLI commands failed to import
+- Fix the problem that the application is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as application name
+- Fix Pi-hole installation failure
+- Fixed the issue that the app could not be updated using WatchTower
+- Fixed the problem that the task status was lost after closing Files when there was an upload task
+
 ## [0.3.0] - 2022-04-08
 
 ### Added

+ 1 - 1
UI

@@ -1 +1 @@
-Subproject commit 4a8f15711ee5520f6bb644107f1eb25f252689b1
+Subproject commit 2f6deb2253df1d0247d5329cb0ea1aa983053a2e

+ 4 - 10
conf/conf.ini.sample

@@ -19,11 +19,11 @@ RunMode = release
 ServerApi = https://api.casaos.io
 Handshake = socket.casaos.io
 Token = 
-USBAutoMount = true
+USBAutoMount =
 
 [user]
-UserName = admin
-PWD = zimaboard
+UserName = 
+PWD = 
 Email = user@gmail.com
 Description = description
 Initialized = false
@@ -31,18 +31,12 @@ Avatar =
 NickName = 
 PublicKey =
 
-[redis]
-Host = 127.0.0.1:6379
-Password =
-MaxIdle = 30
-MaxActive = 30
-IdleTimeout = 200
-
 [system]
 ConfigStr = 
 WidgetList =
 Analyse =
 
+
 [file]
 ShareDir =
 DownloadDir =

BIN
github.com/IceWhaleTech/CasaOS-linux-amd64


BIN
github.com/IceWhaleTech/CasaOS-linux-arm64


+ 2 - 2
go.mod

@@ -3,6 +3,7 @@ module github.com/IceWhaleTech/CasaOS
 go 1.16
 
 require (
+	github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
 	github.com/Microsoft/go-winio v0.5.0 // indirect
 	github.com/Microsoft/hcsshim v0.8.22 // indirect
 	github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
@@ -13,9 +14,8 @@ require (
 	github.com/docker/distribution v2.8.0+incompatible // indirect
 	github.com/docker/docker v20.10.7+incompatible
 	github.com/docker/go-connections v0.4.0
-	github.com/dsoprea/go-exif v0.0.0-20210625224831-a6301f85c82b
 	github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b
-	github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd
+	github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
 	github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
 	github.com/gin-contrib/gzip v0.0.2
 	github.com/gin-gonic/gin v1.7.2

+ 2 - 2
go.sum

@@ -56,6 +56,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
+github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
 github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
 github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
 github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
@@ -287,8 +289,6 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
 github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
 github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/dsoprea/go-exif v0.0.0-20210625224831-a6301f85c82b h1:hoVHc4m/v8Al8mbWyvKJWr4Z37yM4QUSVh/NY6A5Sbc=
-github.com/dsoprea/go-exif v0.0.0-20210625224831-a6301f85c82b/go.mod h1:lOaOt7+UEppOgyvRy749v3do836U/hw0YVJNjoyPaEs=
 github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
 github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
 github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b h1:NgNuLvW/gAFKU30ULWW0gtkCt56JfB7FrZ2zyo0wT8I=

+ 2 - 2
main.go

@@ -49,8 +49,8 @@ func init() {
 	route.InitFunction()
 
 	go service.SendIPToServer()
-	go service.LoopFriend()
-	go service.MyService.App().CheckNewImage()
+	// go service.LoopFriend()
+	// go service.MyService.App().CheckNewImage()
 
 }
 

+ 11 - 0
model/app-analyse.go

@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-03-18 11:40:55
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-13 14:48:01
+ * @FilePath: /CasaOS/model/app-analyse.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package model
 
 type AppAnalyse struct {
@@ -5,6 +15,7 @@ type AppAnalyse struct {
 	Type     string `json:"type"`
 	UUId     string `json:"uuid"`
 	Language string `json:"language"`
+	Version  string `json:"version"`
 }
 
 type ConnectionStatus struct {

+ 1 - 0
model/manifest.go

@@ -104,6 +104,7 @@ func (p *PathArray) Scan(input interface{}) error {
 //}
 
 type CustomizationPostData struct {
+	CustomId     string    `json:"custom_id"`
 	Origin       string    `json:"origin"`
 	NetworkModel string    `json:"network_model"`
 	Index        string    `json:"index"`

+ 1 - 0
model/receive/app.go

@@ -0,0 +1 @@
+package receive

+ 2 - 3
pkg/config/init.go

@@ -22,8 +22,7 @@ var UserInfo = &model.UserModel{}
 //用户相关
 var AppInfo = &model.APPModel{}
 
-//redis相关配置
-var RedisInfo = &model.RedisModel{}
+//var RedisInfo = &model.RedisModel{}
 
 //server相关
 var ServerInfo = &model.ServerModel{}
@@ -53,7 +52,7 @@ func InitSetup(config string) {
 
 	mapTo("user", UserInfo)
 	mapTo("app", AppInfo)
-	mapTo("redis", RedisInfo)
+	//mapTo("redis", RedisInfo)
 	mapTo("server", ServerInfo)
 	mapTo("system", SystemConfigInfo)
 	mapTo("file", FileSettingInfo)

+ 0 - 1
pkg/utils/file/file.go

@@ -283,7 +283,6 @@ func CopyDir(src string, dst string) error {
 	return nil
 }
 
-//文件写入临时目录
 func WriteToPath(data []byte, path, name string) error {
 	fullPath := path
 	if strings.HasSuffix(path, "/") {

+ 5 - 3
pkg/utils/file/image.go

@@ -42,7 +42,9 @@ func GetThumbnailByOwnerPhotos(path string) ([]byte, error) {
 			break
 		}
 	}
-
+	if err != nil {
+		return nil, err
+	}
 	im, err := exifcommon.NewIfdMappingWithStandard()
 	if err != nil {
 		return nil, err
@@ -54,8 +56,8 @@ func GetThumbnailByOwnerPhotos(path string) ([]byte, error) {
 	}
 
 	ifd := index.RootIfd.NextIfd()
-	if err != nil {
-		return nil, err
+	if ifd == nil {
+		return nil, exif.ErrNoThumbnail
 	}
 	thumbnail, err := ifd.Thumbnail()
 	if err != nil {

+ 1 - 0
pkg/utils/httper/httper.go

@@ -27,6 +27,7 @@ func Get(url string, head map[string]string) (response string) {
 	}
 	resp, err := client.Do(req)
 	if err != nil {
+		fmt.Println(err)
 		//需要错误日志的处理
 		//loger.Error(error)
 		return ""

+ 30 - 0
pkg/utils/network_detection.go

@@ -0,0 +1,30 @@
+/*
+ * @Author: LinkLeong a624669980@163.com
+ * @Date: 2022-05-08 14:58:46
+ * @LastEditors: LinkLeong a624669980@163.com
+ * @LastEditTime: 2022-05-09 13:42:26
+ * @FilePath: /CasaOS/pkg/utils/network_detection.go
+ * @Description:
+ *
+ * Copyright (c) 2022 by LinkLeong a624669980@163.com, All Rights Reserved.
+ */
+package utils
+
+import natType "github.com/Curtis-Milo/nat-type-identifier-go"
+
+/**
+ * @description:
+ * @param {chanstring} data
+ * @param {string} url
+ * @return {*}
+ */
+func GetNetWorkTypeDetection(data chan string, url string) {
+	// fmt.Println("url:", url)
+	// httper.Get(url, nil)
+	// aaa <- url
+	result, err := natType.GetDeterminedNatType(true, 5, url)
+	if err == nil {
+		data <- result
+	}
+
+}

+ 29 - 0
pkg/utils/network_detection_test.go

@@ -0,0 +1,29 @@
+/*
+ * @Author: LinkLeong a624669980@163.com
+ * @Date: 2022-05-08 15:07:31
+ * @LastEditors: LinkLeong a624669980@163.com
+ * @LastEditTime: 2022-05-09 11:43:30
+ * @FilePath: /CasaOS/pkg/utils/network_detection_test.go
+ * @Description:
+ *
+ * Copyright (c) 2022 by LinkLeong a624669980@163.com, All Rights Reserved.
+ */
+
+package utils
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestGetResultTest(t *testing.T) {
+	list := []string{"https://www.google.com", "https://www.bing.com", "https://www.baidu.com"}
+	data := make(chan string)
+	//data <- "init"
+	for _, v := range list {
+		go GetNetWorkTypeDetection(data, v)
+	}
+	result := <-data
+	close(data)
+	fmt.Println(result)
+}

+ 0 - 73
pkg/utils/sort/app_info_dev.go

@@ -1,73 +0,0 @@
-package sort
-
-import (
-	"github.com/IceWhaleTech/CasaOS/model"
-	"sort"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type devSorter struct {
-	dev  []model.Devices
-	less []lessFuncDev
-}
-
-// sort接口方法之一(Less)
-type lessFuncDev func(p1, p2 *model.Devices) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *devSorter) Sort(dev []model.Devices) {
-	ms.dev = dev
-	sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func DevSort(less ...lessFuncDev) *devSorter {
-	return &devSorter{
-		less: less,
-	}
-}
-
-// Len 为sort接口方法之一
-func (ms *devSorter) Len() int {
-	return len(ms.dev)
-}
-
-// Swap 为sort接口方法之一
-func (ms *devSorter) Swap(i, j int) {
-	ms.dev[i], ms.dev[j] = ms.dev[j], ms.dev[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *devSorter) Less(i, j int) bool {
-	temp := ms.dev
-	p, q := &temp[i], &temp[j]
-	// Try all but the last comparison.
-	var k int
-	// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
-	// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
-	for k = 0; k < len(ms.less)-1; k++ {
-		// 提取比较函数, 将函数赋值到新的变量中以便调用
-		less := ms.less[k]
-		switch {
-		case less(p, q):
-			// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			// 如果 p > q, 返回值为false, 则调到下一个case中处理
-			return true
-		case less(q, p):
-			// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			return false
-		}
-		// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
-		continue
-	}
-	// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
-	// 直接返回最后一次的比较结果数据即可
-	return ms.less[k](p, q)
-}

+ 0 - 74
pkg/utils/sort/app_info_evn.go

@@ -1,74 +0,0 @@
-package sort
-
-import (
-	"sort"
-
-	"github.com/IceWhaleTech/CasaOS/model"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type evnSorter struct {
-	evn  []model.Envs
-	less []lessFuncEnv
-}
-
-// sort接口方法之一(Less)
-type lessFuncEnv func(p1, p2 *model.Envs) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *evnSorter) Sort(env []model.Envs) {
-	ms.evn = env
-	sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func EnvSort(less ...lessFuncEnv) *evnSorter {
-	return &evnSorter{
-		less: less,
-	}
-}
-
-// Len 为sort接口方法之一
-func (ms *evnSorter) Len() int {
-	return len(ms.evn)
-}
-
-// Swap 为sort接口方法之一
-func (ms *evnSorter) Swap(i, j int) {
-	ms.evn[i], ms.evn[j] = ms.evn[j], ms.evn[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *evnSorter) Less(i, j int) bool {
-	temp := ms.evn
-	p, q := &temp[i], &temp[j]
-	// Try all but the last comparison.
-	var k int
-	// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
-	// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
-	for k = 0; k < len(ms.less)-1; k++ {
-		// 提取比较函数, 将函数赋值到新的变量中以便调用
-		less := ms.less[k]
-		switch {
-		case less(p, q):
-			// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			// 如果 p > q, 返回值为false, 则调到下一个case中处理
-			return true
-		case less(q, p):
-			// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			return false
-		}
-		// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
-		continue
-	}
-	// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
-	// 直接返回最后一次的比较结果数据即可
-	return ms.less[k](p, q)
-}

+ 0 - 73
pkg/utils/sort/app_info_port.go

@@ -1,73 +0,0 @@
-package sort
-
-import (
-	"github.com/IceWhaleTech/CasaOS/model"
-	"sort"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type multiSorter struct {
-	ports []model.Ports
-	less  []lessFunc
-}
-
-// sort接口方法之一(Less)
-type lessFunc func(p1, p2 *model.Ports) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *multiSorter) Sort(ports []model.Ports) {
-	ms.ports = ports
-	sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func PortsSort(less ...lessFunc) *multiSorter {
-	return &multiSorter{
-		less: less,
-	}
-}
-
-// Len 为sort接口方法之一
-func (ms *multiSorter) Len() int {
-	return len(ms.ports)
-}
-
-// Swap 为sort接口方法之一
-func (ms *multiSorter) Swap(i, j int) {
-	ms.ports[i], ms.ports[j] = ms.ports[j], ms.ports[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *multiSorter) Less(i, j int) bool {
-	port := ms.ports
-	p, q := &port[i], &port[j]
-	// Try all but the last comparison.
-	var k int
-	// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
-	// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
-	for k = 0; k < len(ms.less)-1; k++ {
-		// 提取比较函数, 将函数赋值到新的变量中以便调用
-		less := ms.less[k]
-		switch {
-		case less(p, q):
-			// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			// 如果 p > q, 返回值为false, 则调到下一个case中处理
-			return true
-		case less(q, p):
-			// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			return false
-		}
-		// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
-		continue
-	}
-	// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
-	// 直接返回最后一次的比较结果数据即可
-	return ms.less[k](p, q)
-}

+ 0 - 73
pkg/utils/sort/app_info_vol.go

@@ -1,73 +0,0 @@
-package sort
-
-import (
-	"github.com/IceWhaleTech/CasaOS/model"
-	"sort"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type volSorter struct {
-	vol  []model.Volume
-	less []lessFuncVol
-}
-
-// sort接口方法之一(Less)
-type lessFuncVol func(p1, p2 *model.Volume) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *volSorter) Sort(vol []model.Volume) {
-	ms.vol = vol
-	sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func VolSort(less ...lessFuncVol) *volSorter {
-	return &volSorter{
-		less: less,
-	}
-}
-
-// Len 为sort接口方法之一
-func (ms *volSorter) Len() int {
-	return len(ms.vol)
-}
-
-// Swap 为sort接口方法之一
-func (ms *volSorter) Swap(i, j int) {
-	ms.vol[i], ms.vol[j] = ms.vol[j], ms.vol[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *volSorter) Less(i, j int) bool {
-	temp := ms.vol
-	p, q := &temp[i], &temp[j]
-	// Try all but the last comparison.
-	var k int
-	// 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
-	// 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
-	for k = 0; k < len(ms.less)-1; k++ {
-		// 提取比较函数, 将函数赋值到新的变量中以便调用
-		less := ms.less[k]
-		switch {
-		case less(p, q):
-			// 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			// 如果 p > q, 返回值为false, 则调到下一个case中处理
-			return true
-		case less(q, p):
-			// 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
-			return false
-		}
-		// 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
-		continue
-	}
-	// 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
-	// 直接返回最后一次的比较结果数据即可
-	return ms.less[k](p, q)
-}

+ 36 - 66
route/init.go

@@ -1,17 +1,16 @@
 package route
 
 import (
-	"encoding/json"
 	"encoding/xml"
 	"fmt"
 	"runtime"
 	"strconv"
+	"strings"
 	"time"
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/model/system_app"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
-	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -105,7 +104,8 @@ func installSyncthing(appId string) {
 	m.Ports = appInfo.Ports
 	m.Restart = "always"
 	m.Volumes = appInfo.Volumes
-
+	m.Label = id
+	m.CustomId = id
 	containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m, appInfo.NetworkModel)
 	if err != nil {
 		fmt.Println("container create error", err)
@@ -114,83 +114,46 @@ func installSyncthing(appId string) {
 	}
 
 	//step:start container
-	err = service.MyService.Docker().DockerContainerStart(id)
+	err = service.MyService.Docker().DockerContainerStart(containerId)
 	if err != nil {
 		//start container error
 		return
 	}
 
-	portsStr, _ := json.Marshal(appInfo.Ports)
-	envsStr, _ := json.Marshal(appInfo.Envs)
-	volumesStr, _ := json.Marshal(appInfo.Volumes)
-	devicesStr, _ := json.Marshal(appInfo.Devices)
-	//step: 保存数据到数据库
-	md := model2.AppListDBModel{
-		CustomId: id,
-		Title:    appInfo.Title,
-		//ScreenshotLink: appInfo.ScreenshotLink,
-		Slogan:      appInfo.Tagline,
-		Description: appInfo.Description,
-		//Tags:           appInfo.Tags,
-		Icon:        appInfo.Icon,
-		Version:     dockerImageVersion,
-		ContainerId: containerId,
-		Image:       dockerImage,
-		Index:       appInfo.Index,
-		PortMap:     appInfo.PortMap,
-		Label:       appInfo.Title,
-		EnableUPNP:  false,
-		Ports:       string(portsStr),
-		Envs:        string(envsStr),
-		Volumes:     string(volumesStr),
-		Position:    true,
-		NetModel:    appInfo.NetworkModel,
-		Restart:     m.Restart,
-		CpuShares:   50,
-		Memory:      int64(appInfo.MaxMemory),
-		Devices:     string(devicesStr),
-		Origin:      m.Origin,
-		CreatedAt:   strconv.FormatInt(time.Now().Unix(), 10),
-		UpdatedAt:   strconv.FormatInt(time.Now().Unix(), 10),
-	}
-	service.MyService.App().SaveContainer(md)
-
 	checkSystemApp()
 }
 
 // check if the system application is installed
 func checkSystemApp() {
 	list := service.MyService.App().GetSystemAppList()
-	for _, v := range *list {
-		if v.Image == "linuxserver/syncthing" {
+	for _, v := range list {
+		info, err := service.MyService.Docker().DockerContainerInfo(v.ID)
+		if err != nil {
+			continue
+		}
+		if strings.Contains(info.Config.Image, "linuxserver/syncthing") {
 			if v.State != "running" {
 				//step:start container
-				service.MyService.Docker().DockerContainerStart(v.CustomId)
+				service.MyService.Docker().DockerContainerStart(v.ID)
 			}
 			syncIsExistence = true
-			if config.SystemConfigInfo.SyncPort != v.Port {
-				config.SystemConfigInfo.SyncPort = v.Port
+			if config.SystemConfigInfo.SyncPort != v.Labels["web"] {
+				config.SystemConfigInfo.SyncPort = v.Labels["web"]
 			}
-			var paths []model.PathMap
-			json.Unmarshal([]byte(v.Volumes), &paths)
+
 			path := ""
-			for _, i := range paths {
-				if i.ContainerPath == "/config" {
-					path = docker.GetDir(v.CustomId, i.Path) + "/config.xml"
-					for i := 0; i < 10; i++ {
-						if file.CheckNotExist(path) {
-							time.Sleep(1 * time.Second)
-						} else {
-							break
-						}
-					}
+			for _, i := range info.HostConfig.Mounts {
+				if i.Target == "/config" {
+					path = i.Source
+
 					break
 				}
 			}
-			content := file.ReadFullFile(path)
+			content := file.ReadFullFile(path + "config.xml")
 			syncConfig := &system_app.SyncConfig{}
 			xml.Unmarshal(content, &syncConfig)
 			config.SystemConfigInfo.SyncKey = syncConfig.Key
+			break
 		}
 	}
 	if !syncIsExistence {
@@ -283,7 +246,10 @@ func CheckToken2_11() {
 		config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
 	}
 
-	service.MyService.System().ExecUSBAutoMountShell(config.ServerInfo.USBAutoMount)
+	if service.MyService.ZiMa().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.ZiMa().GetDeviceTree(), "Raspberry Pi") {
+		service.MyService.System().UpdateUSBAutoMount("False")
+		service.MyService.System().ExecUSBAutoMountShell("False")
+	}
 
 	// str := []string{}
 	// str = append(str, "ddd")
@@ -301,10 +267,14 @@ func ImportApplications() {
 
 // 0.3.1
 func ChangeAPIUrl() {
-	newAPIUrl := "https://api.casaos.io"
-	config.ServerInfo.ServerApi = newAPIUrl
-	config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl)
-	config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+
+	newAPIUrl := "https://api.casaos.io/casaos-api"
+	if config.ServerInfo.ServerApi == "https://api.casaos.zimaboard.com" {
+		config.ServerInfo.ServerApi = newAPIUrl
+		config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl)
+		config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+	}
+
 }
 
 // 0.3.1
@@ -313,15 +283,15 @@ func InitSystemApplication() {
 	if len(list) != 2 {
 		application := model2.ApplicationModel{}
 		application.Name = "Files"
-		application.Icon = "http://demo.casaos.io/ui/img/folder-open.d382f130.svg"
+		application.Icon = "/ui/img/Files.svg"
 		application.Type = "system"
-		application.Index = 0
+		application.Order = 0
 		service.MyService.App().CreateApplication(application)
 
 		application.Name = "CasaConnect"
-		application.Icon = "http://demo.casaos.io/ui/img/folder-publicshare.0219e0d4.svg"
+		application.Icon = "/ui/img/CasaConnect.svg"
 		application.Type = "system"
-		application.Index = 0
+		application.Order = 0
 
 		service.MyService.App().CreateApplication(application)
 	}

+ 5 - 5
route/route.go

@@ -118,7 +118,8 @@ func InitRouter() *gin.Engine {
 			v1AppGroup.GET("/category", v1.CategoryList)
 			//容器相关
 			v1AppGroup.GET("/terminal/:id", v1.DockerTerminal)
-			v1AppGroup.PUT("/index/:id", v1.PutAppIndex)
+			v1AppGroup.GET("/order", v1.GetAppOrder)
+			v1AppGroup.POST("/order", v1.PostAppOrder)
 			//app容器详情
 			v1AppGroup.GET("/info/:id", v1.ContainerInfo)
 			//app容器日志
@@ -146,11 +147,10 @@ func InitRouter() *gin.Engine {
 		v1SysGroup := v1Group.Group("/sys")
 		v1SysGroup.Use()
 		{
-			//获取检查版本是否需要升级
 			v1SysGroup.GET("/check", v1.CheckVersion)
+			v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo)
 			v1SysGroup.GET("/client/version", v1.GetClientVersion)
 			v1SysGroup.POST("/update", v1.SystemUpdate)
-			v1SysGroup.GET("/sys", v1.Sys)
 			v1SysGroup.GET("/wsssh", v1.WsSsh)
 			v1SysGroup.GET("/config", v1.GetSystemConfig)
 			v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs)
@@ -162,13 +162,12 @@ func InitRouter() *gin.Engine {
 			v1SysGroup.POST("/kill", v1.PostKillCasaOS)
 			v1SysGroup.GET("/info", v1.Info)
 			v1SysGroup.PUT("/usb/off", v1.PutSystemOffUSBAutoMount)
-			v1SysGroup.GET("/usb/on", v1.PutSystemOnUSBAutoMount)
+			v1SysGroup.PUT("/usb/on", v1.PutSystemOnUSBAutoMount)
 			v1SysGroup.GET("/usb", v1.GetSystemUSBAutoMount)
 		}
 		v1FileGroup := v1Group.Group("/file")
 		v1FileGroup.Use()
 		{
-			//修改文件名称/目录名称
 			v1FileGroup.PUT("/rename", v1.RenamePath)
 			v1FileGroup.GET("/read", v1.GetFilerContent)
 			v1FileGroup.POST("/upload", v1.PostFileUpload)
@@ -246,6 +245,7 @@ func InitRouter() *gin.Engine {
 		v1PersonGroup := v1Group.Group("/person")
 		v1PersonGroup.Use()
 		{
+			v1PersonGroup.GET("/detection", v1.GetPersonDetection)
 			v1PersonGroup.GET("/users", v1.GetPersonFriend)
 			v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend)
 			v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend)

+ 56 - 60
route/v1/docker.go

@@ -16,6 +16,7 @@ import (
 	upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
 	oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
 	port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
@@ -155,15 +156,25 @@ func InstallApp(c *gin.Context) {
 	var dockerImageVersion string
 
 	//check app name is exist
-	if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
-		if m.Origin != "custom" {
-			m.Label = m.Label + "_" + time.Now().Local().Format("02150405")
-		} else {
+
+	if m.Origin != "custom" {
+		oldName := m.Label
+		for i := 0; true; i++ {
+			if i != 0 {
+				m.Label = oldName + "-" + strconv.Itoa(i)
+			}
+			if _, err := service.MyService.Docker().DockerListByName(m.Label); err != nil {
+				break
+			}
+		}
+	} else {
+		if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
 			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR_APP_NAME_EXIST, Message: oasis_err2.GetMsg(oasis_err2.ERROR_APP_NAME_EXIST)})
 			return
 		}
 
 	}
+
 	//检查端口
 	if len(m.PortMap) > 0 && m.PortMap != "0" {
 		//c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
@@ -257,8 +268,8 @@ func InstallApp(c *gin.Context) {
 	//if len(privileged) > 0 {
 	//
 	//}
-	//id := uuid.NewV4().String()
-
+	id := uuid.NewV4().String()
+	m.CustomId = id
 	var relyMap = make(map[string]string)
 	go func() {
 		installLog := model2.AppNotify{}
@@ -918,8 +929,10 @@ func UpdateSetting(c *gin.Context) {
 	// 	return
 	// }
 
+	service.MyService.Docker().DockerContainerStop(id)
 	portMap, _ := strconv.Atoi(m.PortMap)
 	if !port2.IsPortAvailable(portMap, "tcp") {
+		service.MyService.Docker().DockerContainerStart(id)
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + m.PortMap})
 		return
 	}
@@ -929,32 +942,34 @@ func UpdateSetting(c *gin.Context) {
 		if u.Protocol == "udp" {
 			t, _ := strconv.Atoi(u.CommendPort)
 			if !port2.IsPortAvailable(t, "udp") {
+				service.MyService.Docker().DockerContainerStart(id)
 				c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
 				return
 			}
 		} else if u.Protocol == "tcp" {
 			te, _ := strconv.Atoi(u.CommendPort)
 			if !port2.IsPortAvailable(te, "tcp") {
+				service.MyService.Docker().DockerContainerStart(id)
 				c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
 				return
 			}
 		} else if u.Protocol == "both" {
 			t, _ := strconv.Atoi(u.CommendPort)
 			if !port2.IsPortAvailable(t, "udp") {
+				service.MyService.Docker().DockerContainerStart(id)
 				c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
 				return
 			}
 
 			te, _ := strconv.Atoi(u.CommendPort)
 			if !port2.IsPortAvailable(te, "tcp") {
+				service.MyService.Docker().DockerContainerStart(id)
 				c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
 				return
 			}
 		}
 
 	}
-
-	service.MyService.Docker().DockerContainerStop(id)
 	service.MyService.Docker().DockerContainerUpdateName(id, id)
 	//service.MyService.Docker().DockerContainerRemove(id, true)
 
@@ -1100,59 +1115,34 @@ func PutAppUpdate(c *gin.Context) {
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
 }
 
-// @Summary update app index
+// @Summary get app index
 // @Produce  application/json
-// @Accept multipart/form-data
+// @Accept application/json
 // @Tags app
-// @Param id path string true "app id"
-// @Param index query int true "app index"
 // @Security ApiKeyAuth
 // @Success 200 {string} string "ok"
-// @Router /app/index/{id} [put]
-func PutAppIndex(c *gin.Context) {
-	id := c.Param("id")
-	index, _ := strconv.Atoi(c.Query("index"))
-
-	if len(id) == 0 {
-		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-		return
-	}
-
-	inspect, err := service.MyService.Docker().DockerContainerInfo(id)
-	if err != nil {
-		if len(service.MyService.App().GetApplicationById(id).Name) == 0 {
-			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
-			return
-		} else {
-			service.MyService.App().UpdateApplicationIndexById(id, index)
-			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
-			return
-		}
-
-	}
-	service.MyService.Docker().DockerContainerStop(id)
-	service.MyService.Docker().DockerContainerUpdateName(id, id)
-
-	inspect.Config.Labels["index"] = strconv.Itoa(index)
-
-	containerId, err := service.MyService.Docker().DockerContainerCopyCreate(inspect)
-	if err != nil {
-		service.MyService.Docker().DockerContainerUpdateName(inspect.Name, id)
-		service.MyService.Docker().DockerContainerStart(id)
-		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
-		return
-	}
-
-	//step:启动容器
-	err = service.MyService.Docker().DockerContainerStart(containerId)
-
-	if err != nil {
-		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
-		return
-	}
-	service.MyService.Docker().DockerContainerRemove(id, true)
+// @Router /app/order [get]
+func GetAppOrder(c *gin.Context) {
+	data := service.MyService.System().GetAppOrderFile()
+	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: json.RawMessage(data)})
+}
 
-	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
+// @Summary update app index
+// @Produce  application/json
+// @Accept application/json
+// @Tags app
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /app/order [post]
+func PostAppOrder(c *gin.Context) {
+	data := c.PostForm("data")
+	service.MyService.System().UpAppOrderFile(data)
+	c.JSON(http.StatusOK,
+		model.Result{
+			Success: oasis_err.SUCCESS,
+			Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+			Data:    json.RawMessage(data),
+		})
 }
 
 // @Summary 获取容器详情
@@ -1298,14 +1288,16 @@ func ContainerUpdateInfo(c *gin.Context) {
 	}
 
 	m := model.CustomizationPostData{}
-	m.Index = ""
 	m.Icon = info.Config.Labels["icon"]
 	m.Ports = port
-	m.Image = info.Image
+	m.Image = info.Config.Image
 	m.Origin = info.Config.Labels["origin"]
+	if len(m.Origin) == 0 {
+		m.Origin = "local"
+	}
 	m.NetworkModel = string(info.HostConfig.NetworkMode)
 	m.Description = info.Config.Labels["desc"]
-	m.Label = info.Name
+	m.Label = strings.ReplaceAll(info.Name, "/", "")
 	m.PortMap = info.Config.Labels["web"]
 	m.Devices = driver
 	m.Envs = envs
@@ -1314,8 +1306,12 @@ func ContainerUpdateInfo(c *gin.Context) {
 	m.Volumes = vol //appInfo.Volumes
 	m.Restart = info.HostConfig.RestartPolicy.Name
 	m.EnableUPNP = false
+	m.Index = info.Config.Labels["index"]
 	m.Position = false
-
+	m.CustomId = info.Config.Labels["custom_id"]
+	if len(m.CustomId) == 0 {
+		m.CustomId = uuid.NewV4().String()
+	}
 	m.CapAdd = info.HostConfig.CapAdd
 	m.Cmd = info.Config.Cmd
 	m.HostName = info.Config.Hostname

+ 2 - 2
route/v1/file.go

@@ -225,10 +225,10 @@ func DirPath(c *gin.Context) {
 	path := c.DefaultQuery("path", "")
 	info := service.MyService.ZiMa().GetDirPath(path)
 	if path == "/DATA/AppData" {
-		list := service.MyService.App().GetAllDBApps()
+		list := service.MyService.Docker().DockerContainerList()
 		apps := make(map[string]string, len(list))
 		for _, v := range list {
-			apps[v.CustomId] = v.Label
+			apps[strings.ReplaceAll(v.Names[0], "/", "")] = strings.ReplaceAll(v.Names[0], "/", "")
 		}
 		for i := 0; i < len(info); i++ {
 			if v, ok := apps[info[i].Name]; ok {

+ 27 - 8
route/v1/person.go

@@ -5,7 +5,6 @@ import (
 	"encoding/base64"
 	"encoding/gob"
 	"encoding/json"
-	"fmt"
 	"io/ioutil"
 	"net"
 	"net/http"
@@ -15,8 +14,7 @@ import (
 	"strings"
 	"time"
 
-	path2 "path"
-
+	natType "github.com/Curtis-Milo/nat-type-identifier-go"
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -282,9 +280,6 @@ func GetPersonImageThumbnail(c *gin.Context) {
 		c.JSON(http.StatusInternalServerError, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
 		return
 	}
-	filesuffix := strings.Split(path2.Ext(path), ".")[1]
-
-	fmt.Println("data:image/" + filesuffix + ";base64," + img.Data.(string))
 
 	imageBuffer, _ := base64.StdEncoding.DecodeString(img.Data.(string))
 	c.Writer.WriteString(string(imageBuffer))
@@ -304,7 +299,6 @@ func GetPersonFriend(c *gin.Context) {
 	for i := 0; i < len(list); i++ {
 		if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 {
 			list[i].OnLine = true
-			list[i].Avatar = v
 			if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
 				list[i].LocalIP = strings.Split(v, ":")[0]
 			}
@@ -313,6 +307,31 @@ func GetPersonFriend(c *gin.Context) {
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
 }
 
+// @Summary network type detection
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/detection [get]
+func GetPersonDetection(c *gin.Context) {
+	// - Blocked
+	// - Open Internet
+	// - Full Cone
+	// - Symmetric UDP Firewall
+	// - Restric NAT
+	// - Restric Port NAT
+	// - Symmetric NAT
+
+	result, err := natType.GetDeterminedNatType(true, 5, "stun.l.google.com")
+	if err != nil {
+		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
+		return
+	}
+	//result := service.MyService.Person().GetPersionNetWorkTypeDetection()
+	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: result})
+}
+
 // @Summary add friend
 // @Produce  application/json
 // @Accept application/json
@@ -571,7 +590,7 @@ func DeletePersonFriend(c *gin.Context) {
 // @Tags person
 // @Security ApiKeyAuth
 // @Success 200 {string} string "ok"
-// @Router /person/public [delete]
+// @Router /person/public [get]
 func GetPersonPublic(c *gin.Context) {
 	list := service.MyService.Casa().GetPersonPublic()
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})

+ 22 - 7
route/v1/system.go

@@ -141,7 +141,7 @@ func GetSystemConfigDebug(c *gin.Context) {
 	systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t"
 
 	list := service.MyService.App().GetSystemAppList()
-	for _, v := range *list {
+	for _, v := range list {
 		systemAppStatus += v.Image + ",\n\t"
 	}
 
@@ -162,9 +162,6 @@ func GetSystemConfigDebug(c *gin.Context) {
 
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: bugContent})
 }
-func Sys(c *gin.Context) {
-	service.DockerPull()
-}
 
 //widget配置
 func GetWidgetConfig(c *gin.Context) {
@@ -181,9 +178,7 @@ func GetWidgetConfig(c *gin.Context) {
 func PostSetWidgetConfig(c *gin.Context) {
 	buf := make([]byte, 1024)
 	n, _ := c.Request.Body.Read(buf)
-	fmt.Println("错误", strconv.Itoa(n))
 	service.MyService.System().UpSystemConfig("", string(buf[0:n]))
-	fmt.Println("错误1", string(buf[0:n]))
 	c.JSON(http.StatusOK,
 		model.Result{
 			Success: oasis_err.SUCCESS,
@@ -283,7 +278,7 @@ func PostKillCasaOS(c *gin.Context) {
 // @Tags sys
 // @Security ApiKeyAuth
 // @Success 200 {string} string "ok"
-// @Router /sys/usg/off [put]
+// @Router /sys/usb/off [put]
 func PutSystemOffUSBAutoMount(c *gin.Context) {
 	service.MyService.System().UpdateUSBAutoMount("False")
 	service.MyService.System().ExecUSBAutoMountShell("False")
@@ -306,6 +301,7 @@ func GetSystemUSBAutoMount(c *gin.Context) {
 	if config.ServerInfo.USBAutoMount == "False" {
 		state = "False"
 	}
+
 	c.JSON(http.StatusOK,
 		model.Result{
 			Success: oasis_err.SUCCESS,
@@ -314,6 +310,25 @@ func GetSystemUSBAutoMount(c *gin.Context) {
 		})
 }
 
+// @Summary get system hardware info
+// @Produce  application/json
+// @Accept application/json
+// @Tags sys
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /sys/hardware/info [get]
+func GetSystemHardwareInfo(c *gin.Context) {
+
+	data := make(map[string]string, 1)
+	data["drive_model"] = service.MyService.ZiMa().GetDeviceTree()
+	c.JSON(http.StatusOK,
+		model.Result{
+			Success: oasis_err.SUCCESS,
+			Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+			Data:    data,
+		})
+}
+
 // @Summary Turn off usb auto-mount
 // @Produce  application/json
 // @Accept application/json

+ 93 - 68
service/app.go

@@ -21,15 +21,17 @@ import (
 	"github.com/docker/docker/api/types/filters"
 	client2 "github.com/docker/docker/client"
 	"github.com/pkg/errors"
+	uuid "github.com/satori/go.uuid"
 	"gorm.io/gorm"
 )
 
 type AppService interface {
-	CreateApplication(m model2.ApplicationModel)
+	CreateApplication(m model2.ApplicationModel) model2.ApplicationModel
 	GetApplicationList() (m []model2.ApplicationModel)
 	GetApplicationById(id string) (m model2.ApplicationModel)
-	UpdateApplicationIndexById(id string, index int)
+	UpdateApplicationOrderById(id string, order int)
 	GetMyList(index, size int, position bool) (*[]model2.MyAppList, *[]model2.MyAppList)
+	GetCasaOSCount() int
 	SaveContainer(m model2.AppListDBModel)
 	GetUninstallInfo(id string) model2.AppListDBModel
 	DeleteApp(id string)
@@ -38,7 +40,7 @@ type AppService interface {
 	UpdateApp(m model2.AppListDBModel)
 	GetSimpleContainerInfo(name string) (types.Container, error)
 	DelAppConfigDir(path string)
-	GetSystemAppList() *[]model2.MyAppList
+	GetSystemAppList() []types.Container
 	GetHardwareUsageSteam()
 	GetHardwareUsage() []model.DockerStatsModel
 	GetAppStats(id string) string
@@ -57,12 +59,13 @@ func (a *appStruct) GetApplicationById(id string) (m model2.ApplicationModel) {
 	return
 }
 
-func (a *appStruct) UpdateApplicationIndexById(id string, index int) {
-	a.db.Model(&model2.ApplicationModel{}).Where("id = ?", id).Update("index", index)
+func (a *appStruct) UpdateApplicationOrderById(id string, order int) {
+	a.db.Model(&model2.ApplicationModel{}).Where("id = ?", id).Update("order", order)
 }
 
-func (a *appStruct) CreateApplication(m model2.ApplicationModel) {
+func (a *appStruct) CreateApplication(m model2.ApplicationModel) model2.ApplicationModel {
 	a.db.Create(&m)
+	return m
 }
 func (a *appStruct) GetApplicationList() (m []model2.ApplicationModel) {
 	a.db.Find(&m)
@@ -99,6 +102,8 @@ func (a *appStruct) ImportApplications(casaApp bool) {
 			info.Config.Labels["web"] = app.PortMap
 			info.Config.Labels["icon"] = app.Icon
 			info.Config.Labels["desc"] = app.Description
+			info.Config.Labels["index"] = app.Index
+			info.Config.Labels["custom_id"] = app.CustomId
 			info.Name = app.Title
 			container_id, err := MyService.Docker().DockerContainerCopyCreate(info)
 			if err != nil {
@@ -122,6 +127,8 @@ func (a *appStruct) ImportApplications(casaApp bool) {
 			info.Config.Labels["web"] = ""
 			info.Config.Labels["icon"] = ""
 			info.Config.Labels["desc"] = ""
+			info.Config.Labels["index"] = ""
+			info.Config.Labels["custom_id"] = uuid.NewV4().String()
 
 			_, err = MyService.Docker().DockerContainerCopyCreate(info)
 			if err != nil {
@@ -131,6 +138,46 @@ func (a *appStruct) ImportApplications(casaApp bool) {
 		}
 	}
 
+	// allcontainer := MyService.Docker().DockerContainerList()
+	// for _, app := range allcontainer {
+	// 	info, err := MyService.Docker().DockerContainerInfo(app.ID)
+	// 	if err != nil {
+	// 		continue
+	// 	}
+	// 	MyService.Docker().DockerContainerStop(app.ID)
+	// 	MyService.Docker().DockerContainerRemove(app.ID, false)
+	// 	//info.NetworkSettings
+	// 	info.Config.Labels["custom_id"] = uuid.NewV4().String()
+	// 	container_id, err := MyService.Docker().DockerContainerCopyCreate(info)
+	// 	if err != nil {
+	// 		fmt.Println(err)
+	// 		continue
+	// 	}
+	// 	MyService.Docker().DockerContainerStart(container_id)
+	//}
+
+}
+
+func (a *appStruct) GetCasaOSCount() int {
+	//获取docker应用
+	cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
+	if err != nil {
+		a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
+		return 0
+	}
+	defer cli.Close()
+	fts := filters.NewArgs()
+	fts.Add("label", "casaos=casaos")
+	//fts.Add("label", "casaos:casaos")
+
+	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: fts, Limit: 200})
+	if err != nil {
+		a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
+		return 0
+	}
+
+	systemApp := MyService.App().GetApplicationList()
+	return len(containers) + len(systemApp)
 }
 
 //获取我的应用列表
@@ -154,51 +201,59 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
 	unTranslation := []model2.MyAppList{}
 
 	list := []model2.MyAppList{}
-	for _, m := range containers {
-		_, newVersion := NewVersionApp[m.ID]
 
+	systemApp := MyService.App().GetApplicationList()
+	for _, v := range systemApp {
+		list = append(list, model2.MyAppList{
+			Name:     v.Name,
+			Icon:     v.Icon,
+			State:    strconv.Itoa(v.State),
+			Id:       strconv.Itoa(v.Id),
+			CustomId: strconv.Itoa(v.Id),
+			Port:     "",
+			//Order:      strconv.Itoa(v.Order),
+			Index:      "/",
+			Image:      "",
+			Type:       v.Type,
+			NewVersion: false,
+		})
+	}
+
+	for _, m := range containers {
 		if m.Labels["casaos"] == "casaos" {
+			if m.Labels["origin"] == "system" {
+				continue
+			}
+			_, newVersion := NewVersionApp[m.ID]
 			list = append(list, model2.MyAppList{
-				Name:     m.Names[0],
+				Name:     strings.ReplaceAll(m.Names[0], "/", ""),
 				Icon:     m.Labels["icon"],
 				State:    m.State,
-				CustomId: m.ID,
+				CustomId: m.Labels["custom_id"],
+				Id:       m.ID,
 				Port:     m.Labels["web"],
 				Index:    m.Labels["index"],
-				//UpTime:   tm,
+				//Order:      m.Labels["order"],
 				Image:      m.Image,
 				NewVersion: newVersion,
+				Type:       m.Labels["origin"],
 				//Slogan: m.Slogan,
 				//Rely:     m.Rely,
 			})
 		} else {
 			unTranslation = append(unTranslation, model2.MyAppList{
-				Name:       m.Names[0],
+				Name:       strings.ReplaceAll(m.Names[0], "/", ""),
 				Icon:       "",
 				State:      m.State,
 				CustomId:   m.ID,
+				Id:         m.ID,
 				Port:       "",
-				NewVersion: newVersion,
+				NewVersion: false,
 				Image:      m.Image,
 			})
 		}
 	}
 
-	systemApp := MyService.App().GetApplicationList()
-	for _, v := range systemApp {
-		list = append(list, model2.MyAppList{
-			Name:       "/" + v.Name,
-			Icon:       v.Icon,
-			State:      strconv.Itoa(v.State),
-			CustomId:   strconv.Itoa(v.Id),
-			Port:       "",
-			Index:      strconv.Itoa(v.Index),
-			Image:      "",
-			Type:       v.Type,
-			NewVersion: false,
-		})
-	}
-
 	//lMap := make(map[string]interface{})
 	// for _, dbModel := range lm {
 	// 	if position {
@@ -245,7 +300,7 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
 }
 
 //system application list
-func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
+func (a *appStruct) GetSystemAppList() []types.Container {
 	//获取docker应用
 	cli, err := client2.NewClientWithOpts(client2.FromEnv)
 	if err != nil {
@@ -261,46 +316,16 @@ func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
 
 	//获取本地数据库应用
 
-	var lm []model2.AppListDBModel
-	a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image,volumes").Find(&lm)
+	// var lm []model2.AppListDBModel
+	// a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image,volumes").Find(&lm)
 
-	list := []model2.MyAppList{}
-	lMap := make(map[string]interface{})
-	for _, dbModel := range lm {
-		lMap[dbModel.ContainerId] = dbModel
-	}
-	for _, container := range containers {
-
-		if lMap[container.ID] != nil {
-			m := lMap[container.ID].(model2.AppListDBModel)
-			if len(m.Label) == 0 {
-				m.Label = m.Title
-			}
-
-			info, err := cli.ContainerInspect(context.Background(), container.ID)
-			var tm string
-			if err != nil {
-				tm = time.Now().String()
-			} else {
-				tm = info.State.StartedAt
-			}
-			list = append(list, model2.MyAppList{
-				Name:     m.Label,
-				Icon:     m.Icon,
-				State:    container.State,
-				CustomId: strings.ReplaceAll(container.Names[0], "/", ""),
-				Port:     m.PortMap,
-				Index:    m.Index,
-				UpTime:   tm,
-				Image:    m.Image,
-				Slogan:   m.Slogan,
-				//Volumes:  m.Volumes,
-				//Rely:     m.Rely,
-			})
-		}
-	}
+	//list := []model2.MyAppList{}
+	//lMap := make(map[string]interface{})
+	// for _, dbModel := range lm {
+	// 	lMap[dbModel.ContainerId] = dbModel
+	// }
 
-	return &list
+	return containers
 
 }
 func (a *appStruct) GetAllDBApps() []model2.AppListDBModel {
@@ -471,7 +496,7 @@ func (a *appStruct) GetHardwareUsageSteam() {
 				}
 				dockerStats.Data = data
 				dockerStats.Icon = v.Labels["icon"]
-				dockerStats.Title = v.Names[0]
+				dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "")
 				dataStats.Store(v.ID, dockerStats)
 				if i == 99 {
 					stats.Body.Close()

+ 9 - 0
service/app_test.go

@@ -0,0 +1,9 @@
+package service
+
+import (
+	"testing"
+)
+
+func TestGetCasaOSCount(t *testing.T) {
+
+}

+ 2 - 0
service/casa.go

@@ -10,6 +10,7 @@ import (
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
 	model2 "github.com/IceWhaleTech/CasaOS/service/model"
+	"github.com/IceWhaleTech/CasaOS/types"
 	"github.com/tidwall/gjson"
 )
 
@@ -154,6 +155,7 @@ func (o *casaService) PushAppAnalyse(uuid, t string, name, language string) {
 	m.Type = t
 	m.Name = name
 	m.Language = language
+	m.Version = types.CURRENTVERSION
 	b, _ := json.Marshal(m)
 
 	head := make(map[string]string)

+ 4 - 4
service/docker.go

@@ -135,10 +135,7 @@ func DockerPull() {
 	cli, _ := client2.NewClientWithOpts(client2.FromEnv)
 	defer cli.Close()
 
-	authConfig := types.AuthConfig{
-		Username: "cn-north-4@M4OW0IULZ3U6PCQPBUZC",
-		Password: "7390181a1565f90927bbd98038436b57d6ebc66a3828d7a11dfda42b9c19d91d",
-	}
+	authConfig := types.AuthConfig{}
 	encodedJSON, err := json2.Marshal(authConfig)
 	fmt.Println(err)
 
@@ -531,6 +528,9 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
 	config.Labels["web"] = m.PortMap
 	config.Labels["icon"] = m.Icon
 	config.Labels["desc"] = m.Description
+	config.Labels["index"] = m.Index
+	config.Labels["custom_id"] = m.CustomId
+	//config.Labels["order"] = strconv.Itoa(MyService.App().GetCasaOSCount() + 1)
 	hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net), Privileged: m.Privileged, CapAdd: m.CapAdd}
 	//if net != "host" {
 	config.ExposedPorts = ports

+ 1 - 1
service/model/o_application.go

@@ -10,7 +10,7 @@ type ApplicationModel struct {
 	Icon      string    `json:"icon"`
 	State     int       `json:"state"`
 	Type      string    `json:"type"`
-	Index     int       `json:"index"`
+	Order     int       `json:"order"`
 	CreatedAt time.Time `gorm:"<-:create" json:"created_at"`
 	UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"`
 }

+ 6 - 4
service/model/o_container.go

@@ -49,15 +49,17 @@ func (p *AppListDBModel) TableName() string {
 }
 
 type MyAppList struct {
+	Id       string `json:"id"`
 	Name     string `json:"name"`
 	Icon     string `json:"icon"`
 	State    string `json:"state"`
 	CustomId string `gorm:"column:custom_id;primary_key" json:"custom_id"`
 	Index    string `json:"index"`
-	Port     string `json:"port"`
-	UpTime   string `json:"up_time"`
-	Slogan   string `json:"slogan"`
-	Type     string `json:"type"`
+	//Order    string `json:"order"`
+	Port   string `json:"port"`
+	UpTime string `json:"up_time"`
+	Slogan string `json:"slogan"`
+	Type   string `json:"type"`
 	//Rely       model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
 	Image      string `json:"image"`
 	Volumes    string `json:"volumes"`

+ 12 - 0
service/person.go

@@ -15,6 +15,7 @@ import (
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
@@ -27,6 +28,7 @@ import (
 
 type PersonService interface {
 	GetPersionInfo(token string) (m model.PersionModel, err error)
+	GetPersionNetWorkTypeDetection() string
 }
 
 type personService struct {
@@ -56,6 +58,16 @@ func (p *personService) GetPersionInfo(token string) (m model.PersionModel, err
 	err = json.Unmarshal([]byte(infoS), &m)
 	return
 }
+func (p *personService) GetPersionNetWorkTypeDetection() string {
+	data := make(chan string)
+	list := []string{"stun.l.google.com", "stun1.l.google.com", "stun2.l.google.com", "stun.sipgate.net"}
+	for _, v := range list {
+		go utils.GetNetWorkTypeDetection(data, v)
+	}
+	result := <-data
+	close(data)
+	return result
+}
 
 func NewPersonService(db *gorm.DB) PersonService {
 	return &personService{db: db}

+ 10 - 1
service/system.go

@@ -7,6 +7,7 @@ import (
 
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 )
 
@@ -20,6 +21,8 @@ type SystemService interface {
 	GetTimeZone() string
 	UpdateUSBAutoMount(state string)
 	ExecUSBAutoMountShell(state string)
+	UpAppOrderFile(str string)
+	GetAppOrderFile() []byte
 }
 type systemService struct {
 	log loger.OLog
@@ -62,9 +65,15 @@ func (s *systemService) UpSystemConfig(str string, widget string) {
 	}
 	config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
 }
+func (s *systemService) UpAppOrderFile(str string) {
+	file.WriteToPath([]byte(str), config.AppInfo.ProjectPath+"/conf", "app_order.json")
+}
+func (s *systemService) GetAppOrderFile() []byte {
+	return file.ReadFullFile(config.AppInfo.ProjectPath + "/conf/app_order.json")
+}
 func (s *systemService) UpdateUSBAutoMount(state string) {
 	config.ServerInfo.USBAutoMount = state
-	config.Cfg.Section("system").Key("USBAutoMount").SetValue(state)
+	config.Cfg.Section("server").Key("USBAutoMount").SetValue(state)
 	config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
 }
 func (s *systemService) UpSystemPort(port string) {

+ 0 - 12
service/udpconn.go

@@ -208,7 +208,6 @@ func ReadContent(stream quic.Stream) {
 			fmt.Println(err)
 			break
 		}
-		fmt.Println(m)
 		if m.Type == types.PERSONDOWNLOAD {
 			r := SaveFile(m, stream)
 			if r {
@@ -218,7 +217,6 @@ func ReadContent(stream quic.Stream) {
 			Summary(m, "download")
 		} else if m.Type == types.PERSONCONNECTION {
 			if len(m.Data.(string)) > 0 {
-				fmt.Println("设置ip", m.Data.(string))
 				UDPAddressMap[m.From] = m.Data.(string)
 			} else {
 				delete(UDPAddressMap, m.From)
@@ -253,12 +251,7 @@ func ReadContent(stream quic.Stream) {
 				notify.Type = types.NOTIFY_TYPE_PERSION_FIRNED_LIVE
 				go MyService.Notify().SendText(notify)
 			}
-			fmt.Println("设置ip", m.Data.(string))
 			UDPAddressMap[m.From] = m.Data.(string)
-			fmt.Println(config.ServerInfo.Token != m.From)
-			fmt.Println(strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0])
-			fmt.Println(strings.Split(m.Data.(string), ":")[0])
-			fmt.Println(strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0])
 			if config.ServerInfo.Token != m.From && strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0] {
 				msg := model.MessageModel{}
 				msg.Type = types.PERSONINTERNALINSPECTION
@@ -304,7 +297,6 @@ func SendIPToServer() {
 
 func LoopFriend() {
 	list := MyService.Friend().GetFriendList()
-	//list := MyService.Friend().GetFriendListRemote()
 	msg := model.MessageModel{}
 	msg.Type = types.PERSONGETIP
 	msg.Data = ""
@@ -333,14 +325,10 @@ func LoopFriend() {
 		if v, ok := UDPAddressMap[list[i].Token]; ok {
 			if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
 				msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort)
-				fmt.Println("判断为内网ip,设置自己的ip地址", msg.Data)
 			}
-			fmt.Println("ping的数据", UDPAddressMap[list[i].Token])
 			oldIP := UDPAddressMap[list[i].Token]
-			fmt.Println("old ip", oldIP)
 			data, err := Dial(msg, false)
 			if err != nil || reflect.DeepEqual(data, model.MessageModel{}) || len(data.Data.(string)) == 0 {
-				fmt.Println("ping失败", list[i].Token, err, data, UDPAddressMap[list[i].Token])
 				if oldIP == UDPAddressMap[list[i].Token] {
 					notify := model2.AppNotify{}
 					notify.CustomId = data.From

+ 5 - 0
service/zima_info.go

@@ -39,6 +39,7 @@ type ZiMaService interface {
 	CreateFile(path string) (int, error)
 	RenameFile(oldF, newF string) (int, error)
 	GetCpuInfo() []cpu.InfoStat
+	GetDeviceTree() string
 }
 
 var NetArray [][]model.IOCountersStat
@@ -149,6 +150,10 @@ func (c *zima) GetNet(physics bool) []string {
 	return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetNetCard " + t)
 }
 
+func (c *zima) GetDeviceTree() string {
+	return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetDeviceTree")
+}
+
 //shell脚本参数 { 网卡名称 }
 func (c *zima) GetNetState(name string) string {
 	return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;CatNetCardState " + name)

+ 6 - 2
shell/helper.sh

@@ -32,7 +32,7 @@ GetNetCard() {
 
 
 GetTimeZone(){
-  timedatectl | grep "Time zone" | awk '{print $3}'
+  timedatectl | grep "Time zone" | awk '{printf $3}'
 }
 
 #查看网卡状态
@@ -341,4 +341,8 @@ USB_Remove_File() {
   ((EUID)) && sudo_cmd="sudo"
   $sudo_cmd rm -fr /etc/udev/rules.d/11-usb-mount.rules
   $sudo_cmd rm -fr /etc/systemd/system/usb-mount@.service
-}
+}
+
+GetDeviceTree(){  
+  cat /proc/device-tree/model
+}

+ 12 - 2
types/system.go

@@ -1,5 +1,15 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-02-17 18:53:22
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-13 18:08:25
+ * @FilePath: /CasaOS/types/system.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package types
 
-const CURRENTVERSION = "0.3.0"
+const CURRENTVERSION = "0.3.1"
 
-const BODY = "<li>Add CasaConnect function, now you can share private files peer-to-peer with your friends.</li><li>Add a widget for network traffic monitoring</li><li>Updated the initial directory of Files to the Root directory</li><li>Fix the application ipv6 opening problem</li>"
+const BODY = ""

+ 9 - 9
web/browserconfig.xml

@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<browserconfig>
-    <msapplication>
-        <tile>
-            <square150x150logo src="/ui/img/icon/mstile-150x150.png"/>
-            <TileColor>#da532c</TileColor>
-        </tile>
-    </msapplication>
-</browserconfig>
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+    <msapplication>
+        <tile>
+            <square150x150logo src="/ui/img/icon/mstile-150x150.png"/>
+            <TileColor>#da532c</TileColor>
+        </tile>
+    </msapplication>
+</browserconfig>

+ 14 - 14
web/favicon.svg

@@ -1,14 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:none;stroke:#363636;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
-	@media ( prefers-color-scheme: dark ) {
-		.st0{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
-	}
-</style>
-<path class="st0" d="M12,22c5.5,0,10-4.5,10-10S17.5,2,12,2S2,6.5,2,12S6.5,22,12,22z"/>
-<path class="st0" d="M12,22c3.9,0,7-3.1,7-7s-3.1-7-7-7s-7,3.1-7,7S8.1,22,12,22z"/>
-<path class="st0" d="M12,22c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S9.8,22,12,22z"/>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:none;stroke:#363636;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
+	@media ( prefers-color-scheme: dark ) {
+		.st0{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
+	}
+</style>
+<path class="st0" d="M12,22c5.5,0,10-4.5,10-10S17.5,2,12,2S2,6.5,2,12S6.5,22,12,22z"/>
+<path class="st0" d="M12,22c3.9,0,7-3.1,7-7s-3.1-7-7-7s-7,3.1-7,7S8.1,22,12,22z"/>
+<path class="st0" d="M12,22c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S9.8,22,12,22z"/>
+</svg>

BIN
web/fonts/materialdesignicons-webfont.0fb040cb.woff2


BIN
web/fonts/materialdesignicons-webfont.1514bb9f.ttf


BIN
web/fonts/materialdesignicons-webfont.5a409f9f.woff


BIN
web/fonts/materialdesignicons-webfont.ff90567b.eot


+ 0 - 0
web/img/folder-publicshare.0219e0d4.svg → web/img/CasaConnect.svg


+ 67 - 0
web/img/Files.svg

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+  <style type="text/css"/>
+  <linearGradient id="linearGradient1951" x1="100" x2="133.19" y1="17.453" y2="51.606" gradientTransform="matrix(.26458 0 0 .24792 -20.108 .79576)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#26abe7" offset="0"/>
+   <stop stop-color="#0669bc" offset="1"/>
+  </linearGradient>
+  <linearGradient id="linearGradient11110" x1=".52917" x2="16.404" y1="5.3815" y2="5.3815" gradientTransform="matrix(1 0 0 .93702 6.5e-7 .92263)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#fff" offset="0"/>
+   <stop stop-color="#fff" stop-opacity="0" offset="1"/>
+  </linearGradient>
+  <linearGradient id="linearGradient1911" x1="25.085" x2="25.085" y1="24.031" y2="26.412" gradientTransform="translate(-17.897,-21.369)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#0271ca" offset="0"/>
+   <stop stop-color="#0768ba" offset="1"/>
+  </linearGradient>
+  <linearGradient id="linearGradient9169" x1="7.4082" x2="7.4082" y1="4.2333" y2="5.5561" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#fff" offset="0"/>
+   <stop stop-color="#e3e4e5" offset="1"/>
+  </linearGradient>
+  <linearGradient id="linearGradient23227" x1=".52916" x2="16.404" y1="14.196" y2="14.196" gradientTransform="translate(-18.282 -.015458)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#0a5ba8" stop-opacity=".99608" offset="0"/>
+   <stop stop-color="#104a8c" stop-opacity=".99608" offset="1"/>
+  </linearGradient>
+ </defs>
+ <metadata>
+  <rdf:RDF>
+   <cc:Work rdf:about="">
+    <dc:format>image/svg+xml</dc:format>
+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+   </cc:Work>
+  </rdf:RDF>
+ </metadata>
+ <path d="m1.1977 2.2644c-0.3653 0-0.66145 0.32575-0.66145 0.72759v2.9636c-0.0026 0.02629-0.0072 0.052-0.0072 0.07906v7.9373c0 0.40184 0.29614 0.72759 0.66144 0.72759h14.552c0.36531 0 0.66144-0.32575 0.66144-0.72759v-9.393c0-0.40184-0.29614-0.72759-0.66144-0.72759v5.16e-4h-8.1993l-0.89864-1.1095s-0.36607-0.478-1.0583-0.478h-1.3229z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="url(#linearGradient1911)" image-rendering="auto" shape-rendering="auto" solid-color="#000000" stop-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;font-variation-settings:normal;inline-size:0;isolation:auto;mix-blend-mode:normal;shape-margin:0;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+ <g fill="#5e4aa6" stroke-width=".26458">
+  <circle cx="-330.35" cy="-328.38" r="0"/>
+  <circle cx="-312.11" cy="-326.25" r="0"/>
+  <circle cx="-306.02" cy="-333.07" r="0"/>
+  <circle cx="-308.84" cy="-326.01" r="0"/>
+  <circle cx="-328.8" cy="-330.45" r="0"/>
+  <g transform="translate(24.108 -4.592)">
+   <circle cx="-330.35" cy="-328.38" r="0"/>
+   <circle cx="-312.11" cy="-326.25" r="0"/>
+   <circle cx="-306.02" cy="-333.07" r="0"/>
+   <circle cx="-308.84" cy="-326.01" r="0"/>
+   <circle cx="-328.8" cy="-330.45" r="0"/>
+  </g>
+  <g transform="translate(2.3479 -14.944)">
+   <circle cx="-330.35" cy="-328.38" r="0"/>
+   <circle cx="-312.11" cy="-326.25" r="0"/>
+   <circle cx="-306.02" cy="-333.07" r="0"/>
+   <circle cx="-308.84" cy="-326.01" r="0"/>
+   <circle cx="-328.8" cy="-330.45" r="0"/>
+  </g>
+  <g transform="translate(.000295 -.00036978)">
+   <circle cx="-330.35" cy="-328.38" r="0"/>
+   <circle cx="-312.11" cy="-326.25" r="0"/>
+   <circle cx="-306.02" cy="-333.07" r="0"/>
+   <circle cx="-308.84" cy="-326.01" r="0"/>
+   <circle cx="-328.8" cy="-330.45" r="0"/>
+  </g>
+ </g>
+ <path d="m0.52916 13.691v0.28215c0 0.20092 0.07357 0.3825 0.19327 0.51417s0.28553 0.21342 0.46818 0.21342h14.552c0.18265 0 0.34796-0.08175 0.46766-0.21342s0.19378-0.31325 0.19378-0.51417v-0.28215c0 0.20092-0.07409 0.3825-0.19378 0.51417-0.1197 0.13167-0.28501 0.21342-0.46766 0.21342h-14.552c-0.18265 0-0.34848-0.08176-0.46818-0.21342s-0.19327-0.31325-0.19327-0.51417z" fill="url(#linearGradient23227)" stroke-width=".26458"/>
+ <rect x=".79373" y="4.2333" width="15.346" height="8.9957" ry=".79373" fill="url(#linearGradient9169)" stroke-linecap="round" stroke-linejoin="round" stroke-width=".1077"/>
+ <path d="m7.542 4.7624s-0.35919 0.44853-1.1575 0.74229c-0.03271 0.0055-0.06509 0.010846-0.10077 0.015978h-5.4967c-0.21986 0-0.41824 0.082975-0.56171 0.21741-0.13937 0.13058-0.22042 0.31234-0.2253 0.51133v0.48421c0 0.02369-0.0021296 0.045593 0 0.073482l0.52916 6.9301c0.014339 0.18779 0.07357 0.35841 0.19327 0.48179s0.28553 0.19998 0.46818 0.19998h14.552c0.18265 0 0.34796-0.0766 0.46766-0.19998s0.18179-0.29386 0.19378-0.48179l0.52916-8.2935c0.011991-0.18793-0.07408-0.35889-0.19378-0.48227-0.11945-0.1231-0.28449-0.19866-0.46665-0.19901h-8.0112z" fill="url(#linearGradient1951)"/>
+ <path d="m7.542 4.7624s-0.35919 0.44853-1.1575 0.74229c-0.03271 0.0055-0.06509 0.010846-0.10077 0.015978h-5.49c-0.21986 0-0.41824 0.082975-0.56171 0.21741-0.13937 0.13058-0.22041 0.31234-0.2253 0.51132l-0.0067094 0.36074c0.0049-0.19899 0.092639-0.38123 0.23201-0.51181 0.14347-0.13443 0.34185-0.21741 0.56171-0.21741h5.49c0.03568-0.00513 0.06806-0.01048 0.10077-0.015978 0.75911-0.24646 1.2883-0.74229 1.2883-0.74229h8.5998c0.18216 3.471e-4 0.34718 0.075914 0.46663 0.19901 0.1197 0.12338 0.19378 0.29401 0.19378 0.48227v-0.36025c0-0.18827-0.07408-0.35889-0.19378-0.48227-0.11945-0.1231-0.28447-0.19866-0.46663-0.19901h-8.0112z" fill="url(#linearGradient11110)" opacity=".3"/>
+</svg>

+ 11 - 11
web/img/add_button.76237e85.svg → web/img/add_button.07d47199.svg

@@ -1,11 +1,11 @@
-<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect opacity="0.32" x="0.435625" y="0.435625" width="71.1288" height="71.1288" rx="7.56437" fill="white" stroke="url(#paint0_linear_812_2050)" stroke-width="0.87125"/>
-<path d="M36.0606 22L36.0239 50" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
-<path d="M22 36H50" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
-<defs>
-<linearGradient id="paint0_linear_812_2050" x1="77.6757" y1="64.5405" x2="35.9839" y2="53.5747" gradientUnits="userSpaceOnUse">
-<stop stop-color="#CBEFFF" stop-opacity="0.16"/>
-<stop offset="1" stop-color="white" stop-opacity="0"/>
-</linearGradient>
-</defs>
-</svg>
+<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect opacity="0.32" x="0.435625" y="0.435625" width="71.1288" height="71.1288" rx="7.56437" fill="white" stroke="url(#paint0_linear_812_2050)" stroke-width="0.87125"/>
+<path d="M36.0606 22L36.0239 50" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M22 36H50" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<defs>
+<linearGradient id="paint0_linear_812_2050" x1="77.6757" y1="64.5405" x2="35.9839" y2="53.5747" gradientUnits="userSpaceOnUse">
+<stop stop-color="#CBEFFF" stop-opacity="0.16"/>
+<stop offset="1" stop-color="white" stop-opacity="0"/>
+</linearGradient>
+</defs>
+</svg>

+ 25 - 25
web/img/android.149f5693.svg → web/img/android.48a6cf16.svg

@@ -1,25 +1,25 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 18.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="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
-<g>
-	<g>
-		<g>
-			<path fill="#A4C639" d="M32,0c17.7,0,32,14.3,32,32S49.7,64,32,64S0,49.7,0,32S14.3,0,32,0z"/>
-		</g>
-	</g>
-	<g>
-		<g>
-			<path fill="#FFFFFF" d="M16.6,24.6c-1.4,0-2.6,1.2-2.6,2.6L14,38c0,1.4,1.2,2.6,2.6,2.6c1.5,0,2.6-1.2,2.6-2.6l0-10.9
-				C19.3,25.7,18.1,24.6,16.6,24.6 M37.8,14.8l1.8-3.3c0.1-0.2,0-0.4-0.1-0.5c-0.2-0.1-0.4,0-0.5,0.1l-1.9,3.3
-				c-1.6-0.7-3.3-1.1-5.1-1.1c-1.8,0-3.6,0.4-5.1,1.1L25,11.2C24.9,11,24.7,11,24.5,11c-0.2,0.1-0.2,0.3-0.1,0.5l1.8,3.3
-				c-3.6,1.8-6,5.3-6,9.3l23.6,0C43.8,20.2,41.4,16.7,37.8,14.8 M26.6,19.9c-0.5,0-1-0.4-1-1c0-0.5,0.4-1,1-1c0.5,0,1,0.4,1,1
-				C27.6,19.5,27.2,19.9,26.6,19.9 M37.4,19.9c-0.5,0-1-0.4-1-1c0-0.5,0.4-1,1-1c0.5,0,1,0.4,1,1C38.4,19.5,37.9,19.9,37.4,19.9
-				 M20.3,25.1l0,16.8c0,1.5,1.3,2.8,2.8,2.8l1.9,0l0,5.7c0,1.4,1.2,2.6,2.6,2.6c1.5,0,2.6-1.2,2.6-2.6l0-5.7l3.5,0l0,5.7
-				c0,1.4,1.2,2.6,2.6,2.6c1.5,0,2.6-1.2,2.6-2.6l0-5.7l1.9,0c1.5,0,2.8-1.2,2.8-2.8l0-16.8L20.3,25.1z M50,27.2
-				c0-1.4-1.2-2.6-2.6-2.6c-1.4,0-2.6,1.2-2.6,2.6l0,10.9c0,1.4,1.2,2.6,2.6,2.6c1.4,0,2.6-1.2,2.6-2.6L50,27.2z"/>
-		</g>
-	</g>
-</g>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.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="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
+<g>
+	<g>
+		<g>
+			<path fill="#A4C639" d="M32,0c17.7,0,32,14.3,32,32S49.7,64,32,64S0,49.7,0,32S14.3,0,32,0z"/>
+		</g>
+	</g>
+	<g>
+		<g>
+			<path fill="#FFFFFF" d="M16.6,24.6c-1.4,0-2.6,1.2-2.6,2.6L14,38c0,1.4,1.2,2.6,2.6,2.6c1.5,0,2.6-1.2,2.6-2.6l0-10.9
+				C19.3,25.7,18.1,24.6,16.6,24.6 M37.8,14.8l1.8-3.3c0.1-0.2,0-0.4-0.1-0.5c-0.2-0.1-0.4,0-0.5,0.1l-1.9,3.3
+				c-1.6-0.7-3.3-1.1-5.1-1.1c-1.8,0-3.6,0.4-5.1,1.1L25,11.2C24.9,11,24.7,11,24.5,11c-0.2,0.1-0.2,0.3-0.1,0.5l1.8,3.3
+				c-3.6,1.8-6,5.3-6,9.3l23.6,0C43.8,20.2,41.4,16.7,37.8,14.8 M26.6,19.9c-0.5,0-1-0.4-1-1c0-0.5,0.4-1,1-1c0.5,0,1,0.4,1,1
+				C27.6,19.5,27.2,19.9,26.6,19.9 M37.4,19.9c-0.5,0-1-0.4-1-1c0-0.5,0.4-1,1-1c0.5,0,1,0.4,1,1C38.4,19.5,37.9,19.9,37.4,19.9
+				 M20.3,25.1l0,16.8c0,1.5,1.3,2.8,2.8,2.8l1.9,0l0,5.7c0,1.4,1.2,2.6,2.6,2.6c1.5,0,2.6-1.2,2.6-2.6l0-5.7l3.5,0l0,5.7
+				c0,1.4,1.2,2.6,2.6,2.6c1.5,0,2.6-1.2,2.6-2.6l0-5.7l1.9,0c1.5,0,2.8-1.2,2.8-2.8l0-16.8L20.3,25.1z M50,27.2
+				c0-1.4-1.2-2.6-2.6-2.6c-1.4,0-2.6,1.2-2.6,2.6l0,10.9c0,1.4,1.2,2.6,2.6,2.6c1.4,0,2.6-1.2,2.6-2.6L50,27.2z"/>
+		</g>
+	</g>
+</g>
+</svg>

+ 28 - 28
web/img/application-x-apple.500bd1f9.svg → web/img/application-x-apple.5eb295b2.svg

@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:#F4F4F4;}
-	.st1{opacity:0.1;fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_1_);enable-background:new    ;}
-	.st2{fill:#999999;}
-</style>
-<g id="图层_1">
-	<g transform="scale(.26458)">
-		<path class="st0" d="M49.1,15.1h143.6c10.4,0,18.9,8.5,18.9,18.9v173.9c0,10.4-8.5,18.9-18.9,18.9H49.1
-			c-10.4,0-18.9-8.5-18.9-18.9V34C30.2,23.6,38.7,15.1,49.1,15.1z"/>
-		
-			<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-957.3084" y1="2609.5137" x2="-955.1654" y2="2607.3706" gradientTransform="matrix(2.3333 0 0 -2.3333 2411.3325 6281.5693)">
-			<stop  offset="0" style="stop-color:#000000"/>
-			<stop  offset="1" style="stop-color:#000000;stop-opacity:0"/>
-		</linearGradient>
-		<path class="st1" d="M211.7,173.9l-52.9,52.9h34c10.5,0,18.9-8.4,18.9-18.9V173.9z"/>
-	</g>
-</g>
-<g id="图层_2">
-	<path class="st2" d="M41.1,31.4c0-4.2,3.4-6.2,3.6-6.3c-2-2.9-5-3.3-6.1-3.3c-2.6-0.3-5.1,1.5-6.4,1.5c-1.3,0-3.3-1.5-5.5-1.4
-		c-2.8,0-5.4,1.6-6.9,4.2c-2.9,5.1-0.8,12.6,2.1,16.8c1.4,2,3.1,4.3,5.3,4.2c2.1-0.1,2.9-1.4,5.4-1.4c2.5,0,3.3,1.4,5.5,1.3
-		c2.3,0,3.7-2.1,5.1-4.1c1.6-2.3,2.3-4.6,2.3-4.7C45.5,38.1,41.1,36.4,41.1,31.4L41.1,31.4z M36.9,19c1.2-1.4,1.9-3.4,1.7-5.3
-		c-1.7,0.1-3.7,1.1-4.9,2.5c-1.1,1.2-2,3.2-1.8,5.1C33.8,21.5,35.7,20.5,36.9,19L36.9,19z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:#F4F4F4;}
+	.st1{opacity:0.1;fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_1_);enable-background:new    ;}
+	.st2{fill:#999999;}
+</style>
+<g id="图层_1">
+	<g transform="scale(.26458)">
+		<path class="st0" d="M49.1,15.1h143.6c10.4,0,18.9,8.5,18.9,18.9v173.9c0,10.4-8.5,18.9-18.9,18.9H49.1
+			c-10.4,0-18.9-8.5-18.9-18.9V34C30.2,23.6,38.7,15.1,49.1,15.1z"/>
+		
+			<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-957.3084" y1="2609.5137" x2="-955.1654" y2="2607.3706" gradientTransform="matrix(2.3333 0 0 -2.3333 2411.3325 6281.5693)">
+			<stop  offset="0" style="stop-color:#000000"/>
+			<stop  offset="1" style="stop-color:#000000;stop-opacity:0"/>
+		</linearGradient>
+		<path class="st1" d="M211.7,173.9l-52.9,52.9h34c10.5,0,18.9-8.4,18.9-18.9V173.9z"/>
+	</g>
+</g>
+<g id="图层_2">
+	<path class="st2" d="M41.1,31.4c0-4.2,3.4-6.2,3.6-6.3c-2-2.9-5-3.3-6.1-3.3c-2.6-0.3-5.1,1.5-6.4,1.5c-1.3,0-3.3-1.5-5.5-1.4
+		c-2.8,0-5.4,1.6-6.9,4.2c-2.9,5.1-0.8,12.6,2.1,16.8c1.4,2,3.1,4.3,5.3,4.2c2.1-0.1,2.9-1.4,5.4-1.4c2.5,0,3.3,1.4,5.5,1.3
+		c2.3,0,3.7-2.1,5.1-4.1c1.6-2.3,2.3-4.6,2.3-4.7C45.5,38.1,41.1,36.4,41.1,31.4L41.1,31.4z M36.9,19c1.2-1.4,1.9-3.4,1.7-5.3
+		c-1.7,0.1-3.7,1.1-4.9,2.5c-1.1,1.2-2,3.2-1.8,5.1C33.8,21.5,35.7,20.5,36.9,19L36.9,19z"/>
+</g>
+</svg>

BIN
web/img/bg3_blur.f7b30d87.jpg


+ 11 - 11
web/img/casa-white.2579f069.svg → web/img/casa-white.f250568a.svg

@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<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"
-	 viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
-</style>
-<path class="st0" d="M12,22c5.5,0,10-4.5,10-10S17.5,2,12,2S2,6.5,2,12S6.5,22,12,22z"/>
-<path class="st0" d="M12,22c3.9,0,7-3.1,7-7s-3.1-7-7-7s-7,3.1-7,7S8.1,22,12,22z"/>
-<path class="st0" d="M12,22c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S9.8,22,12,22z"/>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<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"
+	 viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:2;}
+</style>
+<path class="st0" d="M12,22c5.5,0,10-4.5,10-10S17.5,2,12,2S2,6.5,2,12S6.5,22,12,22z"/>
+<path class="st0" d="M12,22c3.9,0,7-3.1,7-7s-3.1-7-7-7s-7,3.1-7,7S8.1,22,12,22z"/>
+<path class="st0" d="M12,22c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S9.8,22,12,22z"/>
+</svg>

+ 39 - 39
web/img/default-avatar.ab3b9bda.svg → web/img/default-avatar.d92cd43a.svg

@@ -1,39 +1,39 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<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"
-	 viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:url(#SVGID_1_);}
-	.st1{fill:url(#SVGID_2_);}
-	.st2{fill:url(#SVGID_3_);}
-</style>
-<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="60" y1="122" x2="60" y2="2" gradientTransform="matrix(1 0 0 -1 0 122)">
-	<stop  offset="0" style="stop-color:#5A9CFF"/>
-	<stop  offset="0.879" style="stop-color:#2A23D5"/>
-	<stop  offset="1" style="stop-color:#4A3CEC"/>
-</linearGradient>
-<path class="st0" d="M0,60C0,26.9,26.9,0,60,0l0,0c33.1,0,60,26.9,60,60l0,0c0,33.1-26.9,60-60,60l0,0C26.9,120,0,93.1,0,60L0,60z"
-	/>
-<g>
-	<g>
-		
-			<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="59.9999" y1="82" x2="59.9997" y2="29" gradientTransform="matrix(1 0 0 -1 0 122)">
-			<stop  offset="3.509020e-02" style="stop-color:#FFFFFF"/>
-			<stop  offset="0.5256" style="stop-color:#B0D4FF"/>
-			<stop  offset="0.8371" style="stop-color:#DEEDFF"/>
-			<stop  offset="1" style="stop-color:#FEFEFF"/>
-		</linearGradient>
-		<path class="st1" d="M75.1,42.1c0,8.4-6.8,15.1-15.1,15.1c-8.4,0-15.1-6.8-15.1-15.1S51.6,27,60,27C68.4,27,75.1,33.8,75.1,42.1z"
-			/>
-		
-			<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="60" y1="82" x2="59.9998" y2="29" gradientTransform="matrix(1 0 0 -1 0 122)">
-			<stop  offset="3.509020e-02" style="stop-color:#FFFFFF"/>
-			<stop  offset="0.5256" style="stop-color:#B0D4FF"/>
-			<stop  offset="0.8371" style="stop-color:#DEEDFF"/>
-			<stop  offset="1" style="stop-color:#FEFEFF"/>
-		</linearGradient>
-		<path class="st2" d="M34.4,71.7c6.9-5.6,15.8-9,25.6-9c9.8,0,18.7,3.4,25.6,9c3.9,3.2,3.9,9.1,0,12.3c-6.9,5.6-15.8,9-25.6,9
-			c-9.8,0-18.7-3.4-25.6-9C30.5,80.8,30.5,74.9,34.4,71.7z"/>
-	</g>
-</g>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<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"
+	 viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:url(#SVGID_1_);}
+	.st1{fill:url(#SVGID_2_);}
+	.st2{fill:url(#SVGID_3_);}
+</style>
+<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="60" y1="122" x2="60" y2="2" gradientTransform="matrix(1 0 0 -1 0 122)">
+	<stop  offset="0" style="stop-color:#5A9CFF"/>
+	<stop  offset="0.879" style="stop-color:#2A23D5"/>
+	<stop  offset="1" style="stop-color:#4A3CEC"/>
+</linearGradient>
+<path class="st0" d="M0,60C0,26.9,26.9,0,60,0l0,0c33.1,0,60,26.9,60,60l0,0c0,33.1-26.9,60-60,60l0,0C26.9,120,0,93.1,0,60L0,60z"
+	/>
+<g>
+	<g>
+		
+			<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="59.9999" y1="82" x2="59.9997" y2="29" gradientTransform="matrix(1 0 0 -1 0 122)">
+			<stop  offset="3.509020e-02" style="stop-color:#FFFFFF"/>
+			<stop  offset="0.5256" style="stop-color:#B0D4FF"/>
+			<stop  offset="0.8371" style="stop-color:#DEEDFF"/>
+			<stop  offset="1" style="stop-color:#FEFEFF"/>
+		</linearGradient>
+		<path class="st1" d="M75.1,42.1c0,8.4-6.8,15.1-15.1,15.1c-8.4,0-15.1-6.8-15.1-15.1S51.6,27,60,27C68.4,27,75.1,33.8,75.1,42.1z"
+			/>
+		
+			<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="60" y1="82" x2="59.9998" y2="29" gradientTransform="matrix(1 0 0 -1 0 122)">
+			<stop  offset="3.509020e-02" style="stop-color:#FFFFFF"/>
+			<stop  offset="0.5256" style="stop-color:#B0D4FF"/>
+			<stop  offset="0.8371" style="stop-color:#DEEDFF"/>
+			<stop  offset="1" style="stop-color:#FEFEFF"/>
+		</linearGradient>
+		<path class="st2" d="M34.4,71.7c6.9-5.6,15.8-9,25.6-9c9.8,0,18.7,3.4,25.6,9c3.9,3.2,3.9,9.1,0,12.3c-6.9,5.6-15.8,9-25.6,9
+			c-9.8,0-18.7-3.4-25.6-9C30.5,80.8,30.5,74.9,34.4,71.7z"/>
+	</g>
+</g>
+</svg>

+ 121 - 121
web/img/folder-hdd.adcf549a.svg → web/img/folder-hdd.42e0a4ee.svg

@@ -1,121 +1,121 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1"
-	 id="图层_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64"
-	 style="enable-background:new 0 0 64 64;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:#5E4AA6;}
-	.st1{fill:url(#SVGID_1_);}
-	.st2{opacity:1.000000e-03;fill:#1E5992;enable-background:new    ;}
-	.st3{fill:url(#SVGID_2_);}
-	.st4{opacity:0.3;fill:url(#SVGID_3_);enable-background:new    ;}
-	.st5{fill:url(#SVGID_4_);}
-	.st6{fill:url(#SVGID_5_);}
-	.st7{fill:url(#SVGID_6_);}
-</style>
-<g>
-	<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
-	<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
-	<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
-	<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
-	<g transform="translate(.000295 -.00032978)">
-		<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
-		<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
-		<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
-		<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
-		<rect x="-1242.7" y="-1249" class="st0" width="0" height="0"/>
-	</g>
-	<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
-	<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
-	<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
-	<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
-	<rect x="-1242.7" y="-1249" class="st0" width="0" height="0"/>
-	<g transform="translate(2.95e-4,-3.2978e-4)">
-		<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
-		<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
-		<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
-		<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
-		<rect x="-1242.7" y="-1249" class="st0" width="0" height="0"/>
-	</g>
-</g>
-<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-363.3979" y1="913.4439" x2="-363.3979" y2="911.0629" gradientTransform="matrix(3.7796 0 0 -3.7796 1405.5416 3462.4551)">
-	<stop  offset="0" style="stop-color:#0272CB"/>
-	<stop  offset="1" style="stop-color:#0768BA"/>
-</linearGradient>
-<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st1" d="M4.6,8.5c-1.4,0-2.5,1.2-2.5,2.8v11.2
-	c0,0.1,0,0.2,0,0.3v30c0,1.5,1.1,2.8,2.5,2.8h55c1.4,0,2.5-1.2,2.5-2.8V17.2c0-1.5-1.1-2.8-2.5-2.8v0h-31l-3.4-4.2
-	c0,0-1.4-1.8-4-1.8h-5L4.6,8.5z"/>
-<path class="st2" d="M31.6,14.4c-0.4,0-1.2-0.1-2,0.4c-2.8,1.4-2.9,2.2-5.9,2.7H5c-0.8,0-1.6,0.3-2.1,0.9c-0.5,0.5-0.8,1.3-0.9,2.1
-	v1c0-0.8,0.3-1.5,0.9-2.1c0.5-0.5,1.3-0.9,2.1-0.9h18.7c3-0.5,3.1-1.3,5.9-2.7c0.8-0.4,1.5-0.4,2-0.4h27.9c0.7,0,1.3,0.3,1.8,0.8
-	c0.5,0.5,0.7,1.2,0.7,1.9v-1c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8h-4.4H31.6z M2.1,22.4c0,0.1,0,0.2,0,0.3v1
-	c0-0.1,0-0.2,0-0.3V22.4z"/>
-<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="95.1452" y1="43.801" x2="128.3352" y2="9.648" gradientTransform="matrix(1 0 0 -1 -75.9965 65.4973)">
-	<stop  offset="0" style="stop-color:#27AEE9"/>
-	<stop  offset="1" style="stop-color:#0669BC"/>
-</linearGradient>
-<path class="st3" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9c-0.5,0.5-0.8,1.3-0.9,2.1v2
-	c0,0.1,0,0.2,0,0.3v28c0,0.8,0.3,1.4,0.7,1.9c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8c0.5-0.5,0.7-1.2,0.7-1.9V18.2
-	c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.3L28.5,15.5z"/>
-<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-389.233" y1="932.0934" x2="-373.3582" y2="932.0934" gradientTransform="matrix(3.7796 0 0 -3.7796 1473.188 3543.282)">
-	<stop  offset="0" style="stop-color:#FFFFFF"/>
-	<stop  offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
-</linearGradient>
-<path class="st4" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9c-0.5,0.5-0.8,1.3-0.9,2.1v1.5
-	c0-0.8,0.3-1.5,0.9-2.1C3.5,20.3,4.2,20,5,20h18.7c0.1,0,0.3,0,0.4-0.1c2.9-1,4.9-3,4.9-3h30.5c0.7,0,1.3,0.3,1.8,0.8
-	c0.5,0.5,0.7,1.2,0.7,1.9v-1.5c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.3H28.5z M2.1,23.4c0,0.1,0,0.2,0,0.3v1.5
-	c0-0.1,0-0.2,0-0.3V23.4z"/>
-<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-389.2331" y1="923.2966" x2="-373.3582" y2="923.2966" gradientTransform="matrix(3.7796 0 0 -3.7796 1473.188 3543.2234)">
-	<stop  offset="0" style="stop-color:#0A5BA8;stop-opacity:0.9961"/>
-	<stop  offset="1" style="stop-color:#104A8C;stop-opacity:0.9961"/>
-</linearGradient>
-<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st5" d="M2,51.6v1.1c0,0.8,0.3,1.4,0.7,1.9
-	c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8c0.5-0.5,0.7-1.2,0.7-1.9v-1.1c0,0.8-0.3,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.8,0.8
-	h-55c-0.7,0-1.3-0.3-1.8-0.8S2,52.4,2,51.6z"/>
-<g>
-	
-		<image style="overflow:visible;opacity:0.25;" width="34" height="44" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAsCAYAAAAATWqyAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
-GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA/JJREFUeNrMmFtv00AQhX2LyYUk
-pS0VIEA88P9/ES8IqZTShtI0JXHsmE31TXW6dRzb7UMtHSVO1rvHM2cuu0HwQq6wwX/hM61Vep97
-iYQgAqGgKwHDBpQ+IX9yWzx26IGE+y5kbMHCIXdYg0JI3V2JRypi8b7D0GHkMOC3uCORgsX/OSwc
-bh2W/HZvGZ9IDImJw7HDEd/7kGljFVtkzcLXDpcOF/yvbronotYYQeKLwyeHE4exwyvGBHWi84hu
-F1o5zB3OHX7weyEuuiOcePowIkeQ+OrwwWEKkdATnopORR7K2C2Rv1g2gNQNbsog88AiIffmmreQ
-+Ohw4JB6Ps+BEkmAairDooEQ6jPunnCVRnoIdIIlpnyPxd9m8gwy9lKpRN4rEX6JJSa7xJ9U5I9Y
-Jk1FpDmKv+LNrrlXIkN5gQPcbC63+SrTQbIjmemggtC7RfFnCO83vl4xbmuB17h0K/B3iH5oOtgx
-fyURX/m5xP8Fqv/u8JNQXHgWMaG/FzEeY5W8rmQkDRLRDdbYkvgGkXN8nnliTXHZgmftGnrh2prI
-ku8ziGxxymK56EldaBFlgt2K9RAXdiayYuIZmrjEQgVuGLNQAOk51rth7BRXpURaKyKlR2RDpFxh
-8g2mfgemkiPOwIqx9twYCxVVlbfOIsY+A5oJI6LjhOx7yDMznpnLcwvRWCpVt7FrAknjVsJtgphJ
-zTVjxi4lY0Ze+S+0wLUlEkpvkgg2kpBKWWgFLO1rcoylBrUiEsmbJ2TLiYSlpfuFRJeJ+RayZrXX
-aCoSQo2IaKq30v8G9WcsOpBK+hdcQOYfz45I85bqN3WdXl1mjSUPmAZ6fNrbhpLA5rgmwQpHpPtD
-7ld1Xd4+In2vYk6xSgyWEt5Grsfin8BbXBM+hUjK29hbHkvqzrHGBncE/DcktD9DxGpNJ4somQGT
-j6VeWJT0JULe8H2CW6z6jrBi0iVqNHwTyQ+aW+ztB5BY8oyR1n6k7Bq+fhhbYxMKmVx+n3AfisAH
-kneW+7r/fUQCb9cXSQmIvIa79PpW08N6nzWaEvHzSyATR+KyoOK/TdN9UBsiVaTKHZmy9Qa+K5Gg
-7UJBAzG+iCvZs2/deGh7+c+XTTs0XdyOETLZMkQdiNhGbC19zaPeJKkgkUurZ9U1kF1cWyIZc8yZ
-cyWEyl1ECmkNZ/SfATUl7Xg+kkHijDlvZPP9iEgp3ZZtK0+lKR7tqxU1RHIsMWPOK9mqVh7UqDV+
-MeCSqps+8cTI5v3D5kytUmsRK/NX0i4+5QwtZ+Fb6eofWCSsaZbTpo1vAzK6G8iqOvuw5jTAP958
-6hlr1fFmuS9FP/dhb6ND3xdx/RdgADBglifWgXLhAAAAAElFTkSuQmCC" transform="matrix(1 0 0 1 15 15)">
-	</image>
-	<g>
-		<g>
-			<g>
-				<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="32" y1="21.5142" x2="32" y2="51.1873">
-					<stop  offset="0" style="stop-color:#FBFDFE"/>
-					<stop  offset="0.9716" style="stop-color:#C6E8F5"/>
-				</linearGradient>
-				<path class="st6" d="M22.9,51.9h18.2c1,0,1.8-0.8,1.8-1.8V22.7c0-1-0.8-1.8-1.8-1.8H22.9c-1,0-1.8,0.8-1.8,1.8v27.4
-					C21.1,51.1,21.9,51.9,22.9,51.9z M39.8,49.7c-0.6,0-1.1-0.5-1.1-1.1c0-0.6,0.5-1.1,1.1-1.1c0.6,0,1.1,0.5,1.1,1.1
-					C40.9,49.3,40.4,49.7,39.8,49.7z M39.8,23.4c0.6,0,1.1,0.5,1.1,1.1s-0.5,1.1-1.1,1.1c-0.6,0-1.1-0.5-1.1-1.1
-					S39.2,23.4,39.8,23.4z M32,24.2c4.6,0,8.4,3.7,8.4,8.4s-3.7,8.4-8.4,8.4c-0.7,0-1.4-0.1-2.1-0.3l1.6-2.7
-					c0.5-0.8-0.4-1.7-1.2-1.2l-3.6,2.1c0,0,0,0,0,0c-1.8-1.5-2.9-3.8-2.9-6.4C23.6,27.9,27.4,24.2,32,24.2z M24.4,23.4
-					c0.6,0,1.1,0.5,1.1,1.1s-0.5,1.1-1.1,1.1s-1.1-0.5-1.1-1.1S23.8,23.4,24.4,23.4z M24.4,47.6c0.6,0,1.1,0.5,1.1,1.1
-					c0,0.6-0.5,1.1-1.1,1.1s-1.1-0.5-1.1-1.1C23.3,48.1,23.8,47.6,24.4,47.6z"/>
-				<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="31.9994" y1="32.4788" x2="32.0716" y2="36.9457">
-					<stop  offset="0" style="stop-color:#FBFDFE"/>
-					<stop  offset="1" style="stop-color:#C6E8F5"/>
-				</linearGradient>
-				<circle class="st7" cx="32" cy="32.5" r="2.2"/>
-			</g>
-		</g>
-	</g>
-</g>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1"
+	 id="图层_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64"
+	 style="enable-background:new 0 0 64 64;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:#5E4AA6;}
+	.st1{fill:url(#SVGID_1_);}
+	.st2{opacity:1.000000e-03;fill:#1E5992;enable-background:new    ;}
+	.st3{fill:url(#SVGID_2_);}
+	.st4{opacity:0.3;fill:url(#SVGID_3_);enable-background:new    ;}
+	.st5{fill:url(#SVGID_4_);}
+	.st6{fill:url(#SVGID_5_);}
+	.st7{fill:url(#SVGID_6_);}
+</style>
+<g>
+	<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
+	<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
+	<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
+	<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
+	<g transform="translate(.000295 -.00032978)">
+		<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
+		<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
+		<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
+		<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
+		<rect x="-1242.7" y="-1249" class="st0" width="0" height="0"/>
+	</g>
+	<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
+	<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
+	<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
+	<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
+	<rect x="-1242.7" y="-1249" class="st0" width="0" height="0"/>
+	<g transform="translate(2.95e-4,-3.2978e-4)">
+		<rect x="-1248.6" y="-1241.1" class="st0" width="0" height="0"/>
+		<rect x="-1179.7" y="-1233.1" class="st0" width="0" height="0"/>
+		<rect x="-1156.6" y="-1258.9" class="st0" width="0" height="0"/>
+		<rect x="-1167.3" y="-1232.2" class="st0" width="0" height="0"/>
+		<rect x="-1242.7" y="-1249" class="st0" width="0" height="0"/>
+	</g>
+</g>
+<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-363.3979" y1="913.4439" x2="-363.3979" y2="911.0629" gradientTransform="matrix(3.7796 0 0 -3.7796 1405.5416 3462.4551)">
+	<stop  offset="0" style="stop-color:#0272CB"/>
+	<stop  offset="1" style="stop-color:#0768BA"/>
+</linearGradient>
+<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st1" d="M4.6,8.5c-1.4,0-2.5,1.2-2.5,2.8v11.2
+	c0,0.1,0,0.2,0,0.3v30c0,1.5,1.1,2.8,2.5,2.8h55c1.4,0,2.5-1.2,2.5-2.8V17.2c0-1.5-1.1-2.8-2.5-2.8v0h-31l-3.4-4.2
+	c0,0-1.4-1.8-4-1.8h-5L4.6,8.5z"/>
+<path class="st2" d="M31.6,14.4c-0.4,0-1.2-0.1-2,0.4c-2.8,1.4-2.9,2.2-5.9,2.7H5c-0.8,0-1.6,0.3-2.1,0.9c-0.5,0.5-0.8,1.3-0.9,2.1
+	v1c0-0.8,0.3-1.5,0.9-2.1c0.5-0.5,1.3-0.9,2.1-0.9h18.7c3-0.5,3.1-1.3,5.9-2.7c0.8-0.4,1.5-0.4,2-0.4h27.9c0.7,0,1.3,0.3,1.8,0.8
+	c0.5,0.5,0.7,1.2,0.7,1.9v-1c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8h-4.4H31.6z M2.1,22.4c0,0.1,0,0.2,0,0.3v1
+	c0-0.1,0-0.2,0-0.3V22.4z"/>
+<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="95.1452" y1="43.801" x2="128.3352" y2="9.648" gradientTransform="matrix(1 0 0 -1 -75.9965 65.4973)">
+	<stop  offset="0" style="stop-color:#27AEE9"/>
+	<stop  offset="1" style="stop-color:#0669BC"/>
+</linearGradient>
+<path class="st3" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9c-0.5,0.5-0.8,1.3-0.9,2.1v2
+	c0,0.1,0,0.2,0,0.3v28c0,0.8,0.3,1.4,0.7,1.9c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8c0.5-0.5,0.7-1.2,0.7-1.9V18.2
+	c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.3L28.5,15.5z"/>
+<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-389.233" y1="932.0934" x2="-373.3582" y2="932.0934" gradientTransform="matrix(3.7796 0 0 -3.7796 1473.188 3543.282)">
+	<stop  offset="0" style="stop-color:#FFFFFF"/>
+	<stop  offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
+</linearGradient>
+<path class="st4" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9c-0.5,0.5-0.8,1.3-0.9,2.1v1.5
+	c0-0.8,0.3-1.5,0.9-2.1C3.5,20.3,4.2,20,5,20h18.7c0.1,0,0.3,0,0.4-0.1c2.9-1,4.9-3,4.9-3h30.5c0.7,0,1.3,0.3,1.8,0.8
+	c0.5,0.5,0.7,1.2,0.7,1.9v-1.5c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.3H28.5z M2.1,23.4c0,0.1,0,0.2,0,0.3v1.5
+	c0-0.1,0-0.2,0-0.3V23.4z"/>
+<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-389.2331" y1="923.2966" x2="-373.3582" y2="923.2966" gradientTransform="matrix(3.7796 0 0 -3.7796 1473.188 3543.2234)">
+	<stop  offset="0" style="stop-color:#0A5BA8;stop-opacity:0.9961"/>
+	<stop  offset="1" style="stop-color:#104A8C;stop-opacity:0.9961"/>
+</linearGradient>
+<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st5" d="M2,51.6v1.1c0,0.8,0.3,1.4,0.7,1.9
+	c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8c0.5-0.5,0.7-1.2,0.7-1.9v-1.1c0,0.8-0.3,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.8,0.8
+	h-55c-0.7,0-1.3-0.3-1.8-0.8S2,52.4,2,51.6z"/>
+<g>
+	
+		<image style="overflow:visible;opacity:0.25;" width="34" height="44" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAsCAYAAAAATWqyAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
+GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA/JJREFUeNrMmFtv00AQhX2LyYUk
+pS0VIEA88P9/ES8IqZTShtI0JXHsmE31TXW6dRzb7UMtHSVO1rvHM2cuu0HwQq6wwX/hM61Vep97
+iYQgAqGgKwHDBpQ+IX9yWzx26IGE+y5kbMHCIXdYg0JI3V2JRypi8b7D0GHkMOC3uCORgsX/OSwc
+bh2W/HZvGZ9IDImJw7HDEd/7kGljFVtkzcLXDpcOF/yvbronotYYQeKLwyeHE4exwyvGBHWi84hu
+F1o5zB3OHX7weyEuuiOcePowIkeQ+OrwwWEKkdATnopORR7K2C2Rv1g2gNQNbsog88AiIffmmreQ
++Ohw4JB6Ps+BEkmAairDooEQ6jPunnCVRnoIdIIlpnyPxd9m8gwy9lKpRN4rEX6JJSa7xJ9U5I9Y
+Jk1FpDmKv+LNrrlXIkN5gQPcbC63+SrTQbIjmemggtC7RfFnCO83vl4xbmuB17h0K/B3iH5oOtgx
+fyURX/m5xP8Fqv/u8JNQXHgWMaG/FzEeY5W8rmQkDRLRDdbYkvgGkXN8nnliTXHZgmftGnrh2prI
+ku8ziGxxymK56EldaBFlgt2K9RAXdiayYuIZmrjEQgVuGLNQAOk51rth7BRXpURaKyKlR2RDpFxh
+8g2mfgemkiPOwIqx9twYCxVVlbfOIsY+A5oJI6LjhOx7yDMznpnLcwvRWCpVt7FrAknjVsJtgphJ
+zTVjxi4lY0Ze+S+0wLUlEkpvkgg2kpBKWWgFLO1rcoylBrUiEsmbJ2TLiYSlpfuFRJeJ+RayZrXX
+aCoSQo2IaKq30v8G9WcsOpBK+hdcQOYfz45I85bqN3WdXl1mjSUPmAZ6fNrbhpLA5rgmwQpHpPtD
+7ld1Xd4+In2vYk6xSgyWEt5Grsfin8BbXBM+hUjK29hbHkvqzrHGBncE/DcktD9DxGpNJ4somQGT
+j6VeWJT0JULe8H2CW6z6jrBi0iVqNHwTyQ+aW+ztB5BY8oyR1n6k7Bq+fhhbYxMKmVx+n3AfisAH
+kneW+7r/fUQCb9cXSQmIvIa79PpW08N6nzWaEvHzSyATR+KyoOK/TdN9UBsiVaTKHZmy9Qa+K5Gg
+7UJBAzG+iCvZs2/deGh7+c+XTTs0XdyOETLZMkQdiNhGbC19zaPeJKkgkUurZ9U1kF1cWyIZc8yZ
+cyWEyl1ECmkNZ/SfATUl7Xg+kkHijDlvZPP9iEgp3ZZtK0+lKR7tqxU1RHIsMWPOK9mqVh7UqDV+
+MeCSqps+8cTI5v3D5kytUmsRK/NX0i4+5QwtZ+Fb6eofWCSsaZbTpo1vAzK6G8iqOvuw5jTAP958
+6hlr1fFmuS9FP/dhb6ND3xdx/RdgADBglifWgXLhAAAAAElFTkSuQmCC" transform="matrix(1 0 0 1 15 15)">
+	</image>
+	<g>
+		<g>
+			<g>
+				<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="32" y1="21.5142" x2="32" y2="51.1873">
+					<stop  offset="0" style="stop-color:#FBFDFE"/>
+					<stop  offset="0.9716" style="stop-color:#C6E8F5"/>
+				</linearGradient>
+				<path class="st6" d="M22.9,51.9h18.2c1,0,1.8-0.8,1.8-1.8V22.7c0-1-0.8-1.8-1.8-1.8H22.9c-1,0-1.8,0.8-1.8,1.8v27.4
+					C21.1,51.1,21.9,51.9,22.9,51.9z M39.8,49.7c-0.6,0-1.1-0.5-1.1-1.1c0-0.6,0.5-1.1,1.1-1.1c0.6,0,1.1,0.5,1.1,1.1
+					C40.9,49.3,40.4,49.7,39.8,49.7z M39.8,23.4c0.6,0,1.1,0.5,1.1,1.1s-0.5,1.1-1.1,1.1c-0.6,0-1.1-0.5-1.1-1.1
+					S39.2,23.4,39.8,23.4z M32,24.2c4.6,0,8.4,3.7,8.4,8.4s-3.7,8.4-8.4,8.4c-0.7,0-1.4-0.1-2.1-0.3l1.6-2.7
+					c0.5-0.8-0.4-1.7-1.2-1.2l-3.6,2.1c0,0,0,0,0,0c-1.8-1.5-2.9-3.8-2.9-6.4C23.6,27.9,27.4,24.2,32,24.2z M24.4,23.4
+					c0.6,0,1.1,0.5,1.1,1.1s-0.5,1.1-1.1,1.1s-1.1-0.5-1.1-1.1S23.8,23.4,24.4,23.4z M24.4,47.6c0.6,0,1.1,0.5,1.1,1.1
+					c0,0.6-0.5,1.1-1.1,1.1s-1.1-0.5-1.1-1.1C23.3,48.1,23.8,47.6,24.4,47.6z"/>
+				<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="31.9994" y1="32.4788" x2="32.0716" y2="36.9457">
+					<stop  offset="0" style="stop-color:#FBFDFE"/>
+					<stop  offset="1" style="stop-color:#C6E8F5"/>
+				</linearGradient>
+				<circle class="st7" cx="32" cy="32.5" r="2.2"/>
+			</g>
+		</g>
+	</g>
+</g>
+</svg>

+ 113 - 113
web/img/folder-usb.84d5b55d.svg → web/img/folder-usb.1011b135.svg

@@ -1,113 +1,113 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1"
-	 id="图层_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64"
-	 style="enable-background:new 0 0 64 64;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:#5E4AA6;}
-	.st1{fill:url(#SVGID_1_);}
-	.st2{opacity:1.000000e-03;fill:#1E5992;enable-background:new    ;}
-	.st3{fill:url(#SVGID_2_);}
-	.st4{opacity:0.3;fill:url(#SVGID_3_);enable-background:new    ;}
-	.st5{fill:url(#SVGID_4_);}
-	.st6{fill:url(#SVGID_5_);}
-</style>
-<g>
-	<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 	"/>
-	<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 	"/>
-	<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 	"/>
-	<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 	"/>
-	<g transform="translate(.000295 -.00032978)">
-		<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 		"/>
-		<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 		"/>
-		<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 		"/>
-		<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 		"/>
-		<polygon class="st0" points="-1242.7,-1249 -1242.7,-1249 -1242.7,-1249 		"/>
-	</g>
-	<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 	"/>
-	<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 	"/>
-	<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 	"/>
-	<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 	"/>
-	<polygon class="st0" points="-1242.7,-1249 -1242.7,-1249 -1242.7,-1249 	"/>
-	<g transform="translate(2.95e-4,-3.2978e-4)">
-		<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 		"/>
-		<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 		"/>
-		<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 		"/>
-		<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 		"/>
-		<polygon class="st0" points="-1242.7,-1249 -1242.7,-1249 -1242.7,-1249 		"/>
-	</g>
-</g>
-<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-753.1828" y1="651.0814" x2="-753.1828" y2="653.4623" gradientTransform="matrix(3.7796 0 0 3.7796 2878.7295 -2450.8245)">
-	<stop  offset="0" style="stop-color:#0272CB"/>
-	<stop  offset="1" style="stop-color:#0768BA"/>
-</linearGradient>
-<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st1" d="M4.5,8.5C3.1,8.5,2,9.7,2,11.2v11.2
-	c0,0.1,0,0.2,0,0.3v30c0,1.5,1.1,2.8,2.5,2.8h55c1.4,0,2.5-1.2,2.5-2.8V17.2c0-1.5-1.1-2.8-2.5-2.8l0,0h-31l-3.4-4.2
-	c0,0-1.4-1.8-4-1.8h-5L4.5,8.5z"/>
-<path class="st2" d="M31.6,14.4c-0.4,0-1.2-0.1-2,0.4c-2.8,1.4-2.9,2.2-5.9,2.7H5c-0.8,0-1.6,0.3-2.1,0.9c-0.6,0.5-0.9,1.2-0.9,2v1
-	c0-0.8,0.3-1.5,0.9-2.1c0.5-0.5,1.3-0.9,2.1-0.9h18.7c3-0.5,3.1-1.3,5.9-2.7c0.8-0.4,1.5-0.4,2-0.4h27.9c0.7,0,1.3,0.3,1.8,0.8
-	S62,17.3,62,18v-1c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8h-4.4L31.6,14.4L31.6,14.4z M2,22.4c0,0.1,0,0.2,0,0.3v1
-	c0-0.1,0-0.2,0-0.3V22.4z"/>
-<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="95.0853" y1="2392.217" x2="128.2754" y2="2426.3699" gradientTransform="matrix(1 0 0 1 -75.9965 -2370.5027)">
-	<stop  offset="0" style="stop-color:#27AEE9"/>
-	<stop  offset="1" style="stop-color:#0669BC"/>
-</linearGradient>
-<path class="st3" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9C2.4,20,2,20.7,2,21.5v2
-	c0,0.1,0,0.2,0,0.3v28c0,0.8,0.3,1.4,0.7,1.9c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8s0.7-1.2,0.7-1.9V18.2
-	c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.2L28.5,15.5z"/>
-<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-779.0179" y1="632.4208" x2="-763.1432" y2="632.4208" gradientTransform="matrix(3.7796 0 0 3.7796 2946.376 -2369.9976)">
-	<stop  offset="0" style="stop-color:#FFFFFF"/>
-	<stop  offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
-</linearGradient>
-<path class="st4" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9C2.4,20,2,20.7,2,21.5V23
-	c0-0.8,0.3-1.5,0.9-2.1C3.4,20.3,4.2,20,5,20h18.7c0.1,0,0.3,0,0.4-0.1c2.9-1,4.9-3,4.9-3h30.5c0.7,0,1.3,0.3,1.8,0.8
-	s0.7,1.2,0.7,1.9v-1.5c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.2h-2.7V15.5z M2,23.4c0,0.1,0,0.2,0,0.3v1.5
-	c0-0.1,0-0.2,0-0.3V23.4z"/>
-<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-779.0179" y1="641.2203" x2="-763.1432" y2="641.2203" gradientTransform="matrix(3.7796 0 0 3.7796 2946.376 -2370.0562)">
-	<stop  offset="0" style="stop-color:#0A5BA8;stop-opacity:0.9961"/>
-	<stop  offset="1" style="stop-color:#104A8C;stop-opacity:0.9961"/>
-</linearGradient>
-<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st5" d="M2,51.6v1.1c0,0.8,0.3,1.4,0.7,1.9
-	c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8s0.7-1.2,0.7-1.9v-1.1c0,0.8-0.3,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.8,0.8h-55
-	c-0.7,0-1.3-0.3-1.8-0.8S2,52.4,2,51.6z"/>
-<g>
-	
-		<image style="overflow:visible;opacity:0.25;" width="33" height="45" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAtCAYAAAAgJgIUAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
-GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABD9JREFUeNrMmAlv20YQhcXLoi6f
-cRzkQAv0//+m1i6ay67pIxYjiuR2CXwDvNCURSpOUgMPNKnl7tuZN8dyNPof/AXP/K77WSQCELbe
-bwjUXN2PJBGCyCMGIYuXoOK+7jtpNJBwMz7xmHgsPPY95tzHYpFB1ogGEAghMPU49HjhceZxAqFE
-XDLIEvFAK4zZ/SuPtx4vPVKPrx6X/B4IiXUfi8QDhNjsdOZx7PHG4w+ujWVyjwPGNbooRB9bXRMP
-cNseJBrzv/b4zeMdz3KssPJ48PiCddYSMd9FImRciitOscAbyMxYMIDArUcGkRUWedIacU9XmB4W
-uOOE6yHumOCCDJ188LiGVCEidbuSsKhIWXBBWE55ZmKcStgusFCKS0aSPx5ZJX4igYVCwBBjFYuA
-SsQXoBsjc4BWAq4rCD1KZtGGnVtSGjPpTHZ5zAK205DJl+jggf8riapENvcomUUdBGIWt4UPxcTm
-/5RdW4IqIJCLBiyxTZkvEsupa74hoVGwQHwvJSvuM1ncyh1OLOEgNxcBH7KhAIKFuMWpJnTSKRO8
-IzO+gFhFKFZMdA/MbWsINJY6Yt5m3A2bcvKORU3VFqbpYE4u+B2cSSK6Jg9Y/K8gNuI+lSjaw+RT
-rhlzp2LNUZclzB0HuOItCWmMv1PI3kiErEWcY+Yzizp2a+GctPqQ5uriDaU6FVEecb9k5xYBgSxi
-FlFdpTKm7hJkWxObOqdQmhfLEboTs8QaclY1E8ZGPDct5KIF15WsnEy64oVcdlgIylbJrhlXSNKy
-zTQ6+uTxGTcupbB9Q8KSRykmz5hgn+e5KHvFu04WM1IrFgp5ryHwj8dHSOTt6hq1UrUmLEtGewzO
-iYwv7DhBwBYJIxmfYPJm/HuPvyByKe/XmzKmamEPWEjV4oqQfHCMpSwrTiSBPeCCc48LLHErucZt
-6zG1ek5YIBELWaN7KnXExFiy2yt2f0Fpz7r00KfRNdckYpVZK3zn/G7izFj0AqgbVl2d1iYSrker
-f8DVMmNj/n9Z9BwYgfsuN/SxhGvV/Uiq6xwyE+kXrhDhnyLE5tkdv5eb+s34icULdqcnrrG4opax
-X1nsipC8JLy3EniqvXNSLR+EwJzyfMpVBWaJroBUu5Ma3Og6qYwFu1lK/ahFtBFuURdZoep1Uo+3
-aGLUKj6VRE0kYTsVsWoCi/ocuoccAwMJ16QVujUkjiRsUzm1V9vywNDPCO2GNRDNpNJ/xh3fMHa2
-hBOhrhGd6SNnjJXzcpcPJX1JlCx+TxheYvIQ/5eEZCZhud6UnIaScC0St+SBfUlSM37P+tSJXS1R
-Sz+RIcYRteCzNLJ3EPgbqyy3Jamh0WHNyr1o4IbUPGaRJc+upXkp+7gjGBAZejqbyElMT2G5CFaz
-5bN9vetqfjUzVhIhg6Jk6CdEPbG3v2Vq1R0Uos/9RXfnr7q//O8/AQYAxhWve3m9fqQAAAAASUVO
-RK5CYII=" transform="matrix(1 0 0 1 16 15)">
-	</image>
-	<g>
-		<g>
-			<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="32.3842" y1="22.1772" x2="32.3842" y2="51.1664">
-				<stop  offset="0" style="stop-color:#FBFDFE"/>
-				<stop  offset="0.9716" style="stop-color:#C6E8F5"/>
-			</linearGradient>
-			<path class="st6" d="M28.6,34.1c0-1.7-1.4-3.2-3.1-3.2c-1.8,0-3.3,1.4-3.3,3.2c0,1.4,0.9,2.6,2.2,3v1.2c0,0.7,0.4,1.5,1,1.9
-				l6.2,4.7c-1.6,0.5-2.7,1.9-2.7,3.6c0,2.1,1.7,3.8,3.8,3.8s3.8-1.7,3.8-3.8c0-1.7-1.2-3.2-2.8-3.7v-1.8l5.7-3.9c0.6-0.4,1-1.2,1-2
-				v-1.7h0.6c0.9,0,1.7-0.8,1.7-1.7V31c0-0.9-0.8-1.7-1.7-1.7h-3.3c-0.9,0-1.7,0.8-1.7,1.7v2.8c0,0.9,0.8,1.7,1.7,1.7h0.6v1.9
-				l-4.7,3.3V28.2h1.7c1.2,0,1.9-1.3,1.3-2.3L34,21.7c-0.7-1.1-2.2-1.1-2.9,0l-2.6,4.2c-0.6,1,0.1,2.3,1.3,2.3h1.8v14.3l-5.2-3.9
-				v-1.4C27.6,36.7,28.6,35.5,28.6,34.1z"/>
-		</g>
-	</g>
-</g>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1"
+	 id="图层_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64"
+	 style="enable-background:new 0 0 64 64;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:#5E4AA6;}
+	.st1{fill:url(#SVGID_1_);}
+	.st2{opacity:1.000000e-03;fill:#1E5992;enable-background:new    ;}
+	.st3{fill:url(#SVGID_2_);}
+	.st4{opacity:0.3;fill:url(#SVGID_3_);enable-background:new    ;}
+	.st5{fill:url(#SVGID_4_);}
+	.st6{fill:url(#SVGID_5_);}
+</style>
+<g>
+	<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 	"/>
+	<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 	"/>
+	<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 	"/>
+	<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 	"/>
+	<g transform="translate(.000295 -.00032978)">
+		<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 		"/>
+		<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 		"/>
+		<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 		"/>
+		<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 		"/>
+		<polygon class="st0" points="-1242.7,-1249 -1242.7,-1249 -1242.7,-1249 		"/>
+	</g>
+	<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 	"/>
+	<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 	"/>
+	<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 	"/>
+	<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 	"/>
+	<polygon class="st0" points="-1242.7,-1249 -1242.7,-1249 -1242.7,-1249 	"/>
+	<g transform="translate(2.95e-4,-3.2978e-4)">
+		<polygon class="st0" points="-1248.6,-1241.1 -1248.6,-1241.1 -1248.6,-1241.1 		"/>
+		<polygon class="st0" points="-1179.7,-1233.1 -1179.7,-1233.1 -1179.7,-1233.1 		"/>
+		<polygon class="st0" points="-1156.6,-1258.9 -1156.6,-1258.9 -1156.6,-1258.9 		"/>
+		<polygon class="st0" points="-1167.3,-1232.2 -1167.3,-1232.2 -1167.3,-1232.2 		"/>
+		<polygon class="st0" points="-1242.7,-1249 -1242.7,-1249 -1242.7,-1249 		"/>
+	</g>
+</g>
+<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-753.1828" y1="651.0814" x2="-753.1828" y2="653.4623" gradientTransform="matrix(3.7796 0 0 3.7796 2878.7295 -2450.8245)">
+	<stop  offset="0" style="stop-color:#0272CB"/>
+	<stop  offset="1" style="stop-color:#0768BA"/>
+</linearGradient>
+<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st1" d="M4.5,8.5C3.1,8.5,2,9.7,2,11.2v11.2
+	c0,0.1,0,0.2,0,0.3v30c0,1.5,1.1,2.8,2.5,2.8h55c1.4,0,2.5-1.2,2.5-2.8V17.2c0-1.5-1.1-2.8-2.5-2.8l0,0h-31l-3.4-4.2
+	c0,0-1.4-1.8-4-1.8h-5L4.5,8.5z"/>
+<path class="st2" d="M31.6,14.4c-0.4,0-1.2-0.1-2,0.4c-2.8,1.4-2.9,2.2-5.9,2.7H5c-0.8,0-1.6,0.3-2.1,0.9c-0.6,0.5-0.9,1.2-0.9,2v1
+	c0-0.8,0.3-1.5,0.9-2.1c0.5-0.5,1.3-0.9,2.1-0.9h18.7c3-0.5,3.1-1.3,5.9-2.7c0.8-0.4,1.5-0.4,2-0.4h27.9c0.7,0,1.3,0.3,1.8,0.8
+	S62,17.3,62,18v-1c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8h-4.4L31.6,14.4L31.6,14.4z M2,22.4c0,0.1,0,0.2,0,0.3v1
+	c0-0.1,0-0.2,0-0.3V22.4z"/>
+<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="95.0853" y1="2392.217" x2="128.2754" y2="2426.3699" gradientTransform="matrix(1 0 0 1 -75.9965 -2370.5027)">
+	<stop  offset="0" style="stop-color:#27AEE9"/>
+	<stop  offset="1" style="stop-color:#0669BC"/>
+</linearGradient>
+<path class="st3" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9C2.4,20,2,20.7,2,21.5v2
+	c0,0.1,0,0.2,0,0.3v28c0,0.8,0.3,1.4,0.7,1.9c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8s0.7-1.2,0.7-1.9V18.2
+	c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.2L28.5,15.5z"/>
+<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-779.0179" y1="632.4208" x2="-763.1432" y2="632.4208" gradientTransform="matrix(3.7796 0 0 3.7796 2946.376 -2369.9976)">
+	<stop  offset="0" style="stop-color:#FFFFFF"/>
+	<stop  offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
+</linearGradient>
+<path class="st4" d="M28.5,15.5c0,0-1.4,1.8-4.4,3c-0.1,0-0.2,0-0.4,0.1H5c-0.8,0-1.6,0.3-2.1,0.9C2.4,20,2,20.7,2,21.5V23
+	c0-0.8,0.3-1.5,0.9-2.1C3.4,20.3,4.2,20,5,20h18.7c0.1,0,0.3,0,0.4-0.1c2.9-1,4.9-3,4.9-3h30.5c0.7,0,1.3,0.3,1.8,0.8
+	s0.7,1.2,0.7,1.9v-1.5c0-0.8-0.3-1.4-0.7-1.9c-0.5-0.5-1.1-0.8-1.8-0.8H31.2h-2.7V15.5z M2,23.4c0,0.1,0,0.2,0,0.3v1.5
+	c0-0.1,0-0.2,0-0.3V23.4z"/>
+<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-779.0179" y1="641.2203" x2="-763.1432" y2="641.2203" gradientTransform="matrix(3.7796 0 0 3.7796 2946.376 -2370.0562)">
+	<stop  offset="0" style="stop-color:#0A5BA8;stop-opacity:0.9961"/>
+	<stop  offset="1" style="stop-color:#104A8C;stop-opacity:0.9961"/>
+</linearGradient>
+<path image-rendering="auto" shape-rendering="auto" color-rendering="auto" class="st5" d="M2,51.6v1.1c0,0.8,0.3,1.4,0.7,1.9
+	c0.5,0.5,1.1,0.8,1.8,0.8h55c0.7,0,1.3-0.3,1.8-0.8s0.7-1.2,0.7-1.9v-1.1c0,0.8-0.3,1.4-0.7,1.9c-0.5,0.5-1.1,0.8-1.8,0.8h-55
+	c-0.7,0-1.3-0.3-1.8-0.8S2,52.4,2,51.6z"/>
+<g>
+	
+		<image style="overflow:visible;opacity:0.25;" width="33" height="45" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAtCAYAAAAgJgIUAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
+GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABD9JREFUeNrMmAlv20YQhcXLoi6f
+cRzkQAv0//+m1i6ay67pIxYjiuR2CXwDvNCURSpOUgMPNKnl7tuZN8dyNPof/AXP/K77WSQCELbe
+bwjUXN2PJBGCyCMGIYuXoOK+7jtpNJBwMz7xmHgsPPY95tzHYpFB1ogGEAghMPU49HjhceZxAqFE
+XDLIEvFAK4zZ/SuPtx4vPVKPrx6X/B4IiXUfi8QDhNjsdOZx7PHG4w+ujWVyjwPGNbooRB9bXRMP
+cNseJBrzv/b4zeMdz3KssPJ48PiCddYSMd9FImRciitOscAbyMxYMIDArUcGkRUWedIacU9XmB4W
+uOOE6yHumOCCDJ188LiGVCEidbuSsKhIWXBBWE55ZmKcStgusFCKS0aSPx5ZJX4igYVCwBBjFYuA
+SsQXoBsjc4BWAq4rCD1KZtGGnVtSGjPpTHZ5zAK205DJl+jggf8riapENvcomUUdBGIWt4UPxcTm
+/5RdW4IqIJCLBiyxTZkvEsupa74hoVGwQHwvJSvuM1ncyh1OLOEgNxcBH7KhAIKFuMWpJnTSKRO8
+IzO+gFhFKFZMdA/MbWsINJY6Yt5m3A2bcvKORU3VFqbpYE4u+B2cSSK6Jg9Y/K8gNuI+lSjaw+RT
+rhlzp2LNUZclzB0HuOItCWmMv1PI3kiErEWcY+Yzizp2a+GctPqQ5uriDaU6FVEecb9k5xYBgSxi
+FlFdpTKm7hJkWxObOqdQmhfLEboTs8QaclY1E8ZGPDct5KIF15WsnEy64oVcdlgIylbJrhlXSNKy
+zTQ6+uTxGTcupbB9Q8KSRykmz5hgn+e5KHvFu04WM1IrFgp5ryHwj8dHSOTt6hq1UrUmLEtGewzO
+iYwv7DhBwBYJIxmfYPJm/HuPvyByKe/XmzKmamEPWEjV4oqQfHCMpSwrTiSBPeCCc48LLHErucZt
+6zG1ek5YIBELWaN7KnXExFiy2yt2f0Fpz7r00KfRNdckYpVZK3zn/G7izFj0AqgbVl2d1iYSrker
+f8DVMmNj/n9Z9BwYgfsuN/SxhGvV/Uiq6xwyE+kXrhDhnyLE5tkdv5eb+s34icULdqcnrrG4opax
+X1nsipC8JLy3EniqvXNSLR+EwJzyfMpVBWaJroBUu5Ma3Og6qYwFu1lK/ahFtBFuURdZoep1Uo+3
+aGLUKj6VRE0kYTsVsWoCi/ocuoccAwMJ16QVujUkjiRsUzm1V9vywNDPCO2GNRDNpNJ/xh3fMHa2
+hBOhrhGd6SNnjJXzcpcPJX1JlCx+TxheYvIQ/5eEZCZhud6UnIaScC0St+SBfUlSM37P+tSJXS1R
+Sz+RIcYRteCzNLJ3EPgbqyy3Jamh0WHNyr1o4IbUPGaRJc+upXkp+7gjGBAZejqbyElMT2G5CFaz
+5bN9vetqfjUzVhIhg6Jk6CdEPbG3v2Vq1R0Uos/9RXfnr7q//O8/AQYAxhWve3m9fqQAAAAASUVO
+RK5CYII=" transform="matrix(1 0 0 1 16 15)">
+	</image>
+	<g>
+		<g>
+			<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="32.3842" y1="22.1772" x2="32.3842" y2="51.1664">
+				<stop  offset="0" style="stop-color:#FBFDFE"/>
+				<stop  offset="0.9716" style="stop-color:#C6E8F5"/>
+			</linearGradient>
+			<path class="st6" d="M28.6,34.1c0-1.7-1.4-3.2-3.1-3.2c-1.8,0-3.3,1.4-3.3,3.2c0,1.4,0.9,2.6,2.2,3v1.2c0,0.7,0.4,1.5,1,1.9
+				l6.2,4.7c-1.6,0.5-2.7,1.9-2.7,3.6c0,2.1,1.7,3.8,3.8,3.8s3.8-1.7,3.8-3.8c0-1.7-1.2-3.2-2.8-3.7v-1.8l5.7-3.9c0.6-0.4,1-1.2,1-2
+				v-1.7h0.6c0.9,0,1.7-0.8,1.7-1.7V31c0-0.9-0.8-1.7-1.7-1.7h-3.3c-0.9,0-1.7,0.8-1.7,1.7v2.8c0,0.9,0.8,1.7,1.7,1.7h0.6v1.9
+				l-4.7,3.3V28.2h1.7c1.2,0,1.9-1.3,1.3-2.3L34,21.7c-0.7-1.1-2.2-1.1-2.9,0l-2.6,4.2c-0.6,1,0.1,2.3,1.3,2.3h1.8v14.3l-5.2-3.9
+				v-1.4C27.6,36.7,28.6,35.5,28.6,34.1z"/>
+		</g>
+	</g>
+</g>
+</svg>

BIN
web/img/gradient.6c5a7f30.png


+ 25 - 25
web/img/icon/safari-pinned-tab.svg

@@ -1,25 +1,25 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
- "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
-<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
- width="200.000000pt" height="200.000000pt" viewBox="0 0 200.000000 200.000000"
- preserveAspectRatio="xMidYMid meet">
-<metadata>
-Created by potrace 1.14, written by Peter Selinger 2001-2017
-</metadata>
-<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)"
-fill="#000000" stroke="none">
-<path d="M875 1894 c-11 -2 -51 -11 -88 -20 -341 -78 -610 -364 -673 -714 -82
--459 197 -902 647 -1030 94 -27 277 -37 378 -21 303 47 575 261 690 540 55
-133 66 192 65 361 -1 136 -4 165 -27 235 -36 116 -62 170 -123 261 -123 186
--347 336 -566 379 -42 8 -276 15 -303 9z m250 -168 c11 -2 42 -9 70 -16 131
--30 288 -135 387 -260 160 -201 198 -506 93 -745 l-22 -50 2 80 c3 180 -64
-351 -184 476 -209 216 -544 260 -807 105 -201 -117 -326 -347 -319 -587 l2
--74 -19 44 c-63 140 -80 332 -44 476 24 94 87 219 147 292 109 133 290 238
-448 259 25 3 47 7 49 9 5 4 173 -3 197 -9z m8 -501 c33 -8 85 -31 116 -50 227
--137 305 -418 183 -651 l-21 -39 -1 35 c-9 251 -245 439 -490 389 -186 -38
--323 -200 -330 -389 l-1 -35 -23 45 c-101 194 -61 429 99 578 130 122 292 162
-468 117z m-27 -499 c182 -85 183 -345 1 -438 -53 -27 -161 -26 -215 1 -146 75
--180 267 -69 390 63 69 190 90 283 47z"/>
-</g>
-</svg>
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="200.000000pt" height="200.000000pt" viewBox="0 0 200.000000 200.000000"
+ preserveAspectRatio="xMidYMid meet">
+<metadata>
+Created by potrace 1.14, written by Peter Selinger 2001-2017
+</metadata>
+<g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M875 1894 c-11 -2 -51 -11 -88 -20 -341 -78 -610 -364 -673 -714 -82
+-459 197 -902 647 -1030 94 -27 277 -37 378 -21 303 47 575 261 690 540 55
+133 66 192 65 361 -1 136 -4 165 -27 235 -36 116 -62 170 -123 261 -123 186
+-347 336 -566 379 -42 8 -276 15 -303 9z m250 -168 c11 -2 42 -9 70 -16 131
+-30 288 -135 387 -260 160 -201 198 -506 93 -745 l-22 -50 2 80 c3 180 -64
+351 -184 476 -209 216 -544 260 -807 105 -201 -117 -326 -347 -319 -587 l2
+-74 -19 44 c-63 140 -80 332 -44 476 24 94 87 219 147 292 109 133 290 238
+448 259 25 3 47 7 49 9 5 4 173 -3 197 -9z m8 -501 c33 -8 85 -31 116 -50 227
+-137 305 -418 183 -651 l-21 -39 -1 35 c-9 251 -245 439 -490 389 -186 -38
+-323 -200 -330 -389 l-1 -35 -23 45 c-101 194 -61 429 99 578 130 122 292 162
+468 117z m-27 -499 c182 -85 183 -345 1 -438 -53 -27 -161 -26 -215 1 -146 75
+-180 267 -69 390 63 69 190 90 283 47z"/>
+</g>
+</svg>

+ 158 - 158
web/img/macos.da8469ce.svg → web/img/macos.6403eda3.svg

@@ -1,159 +1,159 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 407 407"
-   style="enable-background:new 0 0 407 407;"
-   xml:space="preserve"><metadata
-   id="metadata36"><rdf:RDF><cc:Work
-       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-   id="defs34"><linearGradient
-   xlink:href="#SVGID_1_"
-   id="linearGradient46"
-   gradientUnits="userSpaceOnUse"
-   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
-   x1="203.7169"
-   y1="7.7039"
-   x2="203.7169"
-   y2="402.0255" /><linearGradient
-   xlink:href="#SVGID_1_"
-   id="linearGradient48"
-   gradientUnits="userSpaceOnUse"
-   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
-   x1="203.7169"
-   y1="7.7039"
-   x2="203.7169"
-   y2="402.0255" />
-	
-	
-<linearGradient
-   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
-   y2="402.02551"
-   x2="203.7169"
-   y1="7.7038999"
-   x1="203.7169"
-   gradientUnits="userSpaceOnUse"
-   id="linearGradient120"><stop
-     id="stop6-9"
-     style="stop-color:#F2F2F2"
-     offset="0" /><stop
-     id="stop8-1"
-     style="stop-color:#F7F7F7"
-     offset="0.5963" /><stop
-     id="stop10-7"
-     style="stop-color:#FEFEFE"
-     offset="1" /></linearGradient><filter
-   style="color-interpolation-filters:sRGB"
-   id="filter1002"
-   x="-0.013201674"
-   width="1.0264033"
-   y="-0.013198327"
-   height="1.0263967"><feGaussianBlur
-     stdDeviation="2.168925"
-     id="feGaussianBlur1004" /></filter></defs>
-<style
-   type="text/css"
-   id="style2">
-	.st0{fill:url(#SVGID_1_);}
-	.st1{fill:#515151;}
-</style>
-<g
-   transform="matrix(1,0,0,0.98477354,0,6.0829719)"
-   id="g15-0"
-   style="fill:#4d4d4d;filter:url(#filter1002)"><linearGradient
-     gradientTransform="matrix(1,0,0,-1,0,407.2074)"
-     y2="402.02551"
-     x2="203.7169"
-     y1="7.7038999"
-     x1="203.7169"
-     gradientUnits="userSpaceOnUse"
-     id="linearGradient91"><stop
-       id="stop85"
-       style="stop-color:#F2F2F2"
-       offset="0" /><stop
-       id="stop87"
-       style="stop-color:#F7F7F7"
-       offset="0.5963" /><stop
-       id="stop89"
-       style="stop-color:#FEFEFE"
-       offset="1" /></linearGradient><path
-     style="fill:#4d4d4d"
-     id="path13-7"
-     d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
-     class="st0" /><path
-     style="fill:#4d4d4d"
-     class="st0"
-     d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
-     id="path40-7" /></g><g
-   id="g15">
-		
-			
-		
-			<linearGradient
-   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
-   y2="402.02551"
-   x2="203.7169"
-   y1="7.7038999"
-   x1="203.7169"
-   gradientUnits="userSpaceOnUse"
-   id="SVGID_1_">
-			<stop
-   id="stop6"
-   style="stop-color:#F2F2F2"
-   offset="0" />
-			<stop
-   id="stop8"
-   style="stop-color:#F7F7F7"
-   offset="0.5963" />
-			<stop
-   id="stop10"
-   style="stop-color:#FEFEFE"
-   offset="1" />
-		</linearGradient>
-		<path
-   style="fill:url(#linearGradient46)"
-   id="path13"
-   d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
-   class="st0" />
-	<path
-   style="fill:url(#linearGradient48)"
-   class="st0"
-   d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
-   id="path40" /></g><g
-   id="g27">
-		<path
-   style="fill:#515151"
-   id="path17"
-   d="m 223.7,137.8 h 0.2 v 6.9 h 7.9 v -28.5 c 0,-2.1 -0.4,-3.9 -1.2,-5.6 -0.8,-1.7 -1.9,-3.1 -3.4,-4.3 -1.5,-1.2 -3.2,-2.1 -5.3,-2.7 -2.1,-0.6 -4.3,-1 -6.9,-1 -2.3,0 -4.5,0.3 -6.5,1 -2,0.6 -3.7,1.5 -5.2,2.7 -1.5,1.2 -2.6,2.5 -3.5,4.1 -0.9,1.6 -1.3,3.3 -1.4,5.1 h 7.8 c 0.2,-0.9 0.5,-1.7 1,-2.4 0.5,-0.7 1.1,-1.4 1.8,-1.9 0.7,-0.5 1.6,-0.9 2.6,-1.2 1,-0.3 2,-0.4 3.1,-0.4 2.8,0 4.9,0.6 6.5,1.9 1.5,1.2 2.3,3.1 2.3,5.5 v 3.2 l -11.2,0.6 c -5.2,0.3 -9.1,1.5 -11.8,3.6 -2.7,2.1 -4.1,4.9 -4.1,8.6 0,1.9 0.3,3.6 1,5.1 0.7,1.5 1.7,2.8 2.9,3.9 1.2,1.1 2.7,1.9 4.4,2.5 1.7,0.6 3.6,0.9 5.7,0.9 1.4,0 2.8,-0.2 4.1,-0.5 1.3,-0.3 2.6,-0.8 3.7,-1.5 1.1,-0.6 2.1,-1.4 3.1,-2.3 1,-1.2 1.8,-2.2 2.4,-3.3 z m -3.2,-2 c -1,0.8 -2.1,1.5 -3.4,2 -1.3,0.5 -2.8,0.7 -4.3,0.7 -2.4,0 -4.3,-0.5 -5.7,-1.6 -1.4,-1.1 -2.1,-2.5 -2.1,-4.3 0,-1.8 0.7,-3.3 2.2,-4.3 1.4,-1 3.6,-1.6 6.5,-1.8 l 10.1,-0.7 v 3.2 c 0,1.4 -0.3,2.6 -0.8,3.8 -0.8,1.2 -1.5,2.2 -2.5,3 z"
-   class="st1" />
-		<path
-   style="fill:#515151"
-   id="path19"
-   d="m 278.5,228.7 -13.7,-3.4 c -16.7,-4.2 -23.6,-9.7 -23.6,-18.9 0,-11.7 10.9,-19.8 26.7,-19.8 15.8,0 26.5,8 27.7,21 h 17.9 c -0.7,-21.6 -19,-36.7 -45.2,-36.7 -26.8,0 -45.7,15 -45.7,36.5 0,17.5 10.6,28.2 34.1,34 l 16.3,4 c 16.7,4.2 23.9,10.4 23.9,20.6 0,11.8 -11.9,20.4 -28.4,20.4 -17.2,0 -29.8,-8.6 -31.2,-21.7 h -18 c 1.3,22.8 20.2,37.3 47.9,37.3 29.7,0 48.4,-14.7 48.4,-38.3 -0.3,-18.4 -11,-28.7 -37.1,-35 z"
-   class="st1" />
-		<path
-   style="fill:#515151"
-   id="path21"
-   d="m 187.7,144.7 v -28.3 c 0,-2.1 -0.3,-4 -1,-5.6 -0.7,-1.6 -1.5,-3.1 -2.7,-4.3 -1.2,-1.2 -2.6,-2.1 -4.3,-2.8 -1.7,-0.7 -3.5,-1 -5.6,-1 -1.5,0 -2.9,0.2 -4.2,0.6 -1.3,0.4 -2.6,0.9 -3.7,1.6 -1.1,0.7 -2.1,1.6 -3,2.5 -0.9,0.9 -1.6,2.1 -2.1,3.4 h -0.2 c -0.8,-2.6 -2.3,-4.6 -4.3,-6 -2,-1.4 -4.5,-2.1 -7.4,-2.1 -1.3,0 -2.6,0.2 -3.9,0.5 -1.2,0.3 -2.3,0.8 -3.4,1.5 -1,0.7 -1.9,1.4 -2.7,2.4 -0.8,0.9 -1.4,2 -1.9,3.1 h -0.2 v -7 h -7.9 v 41.6 h 7.8 v -25.5 c 0,-1.3 0.7,-2.6 1.1,-3.7 0.4,-1.1 1,-2.1 1.8,-3 0.8,-0.8 1.7,-1.5 2.8,-2 1.1,-0.5 2.3,-0.7 3.5,-0.7 1.2,0 2.3,0.2 3.3,0.6 1,0.4 1.8,0.9 2.5,1.6 0.7,0.7 1.2,1.5 1.6,2.5 0.4,1 0.6,2.1 0.6,3.2 v 27 h 8.2 V 119 c 0,-1.3 0.2,-2.6 0.7,-3.7 0.4,-1.1 1,-2.1 1.8,-2.9 0.8,-0.8 1.7,-1.4 2.7,-1.9 1.1,-0.4 2.2,-0.7 3.5,-0.7 2.6,0 4.6,0.8 6,2.2 1.4,1.5 2.1,3.6 2.1,6.3 v 26.3 z"
-   class="st1" />
-		<path
-   style="fill:#515151"
-   id="path23"
-   d="m 147.4,170.9 c -36.3,0 -59.1,25.3 -59.1,65.6 0,40.3 22.8,65.6 59.1,65.6 36.3,0 59.1,-25.3 59.1,-65.6 -0.1,-40.3 -22.8,-65.6 -59.1,-65.6 z m 0,115 c -24.9,0 -40.5,-19.1 -40.5,-49.4 0,-30.4 15.6,-49.5 40.5,-49.5 24.8,0 40.5,19.1 40.5,49.5 -0.1,30.3 -15.7,49.4 -40.5,49.4 z"
-   class="st1" />
-		<path
-   style="fill:#515151"
-   id="path25"
-   d="m 252.1,113.5 c 1,-1.2 2.1,-2.2 3.5,-2.9 1.4,-0.7 2.9,-1 4.6,-1 1.4,0 2.7,0.2 3.8,0.6 1.1,0.4 2.1,0.9 3,1.6 0.8,0.7 1.5,1.5 2,2.5 0.5,1 0.9,2 1.1,3.1 h 7.9 c -0.2,-2 -0.7,-3.9 -1.6,-5.7 -0.9,-1.8 -2.1,-3.3 -3.6,-4.7 -1.5,-1.3 -3.4,-2.4 -5.5,-3.2 -2.1,-0.8 -4.5,-1.2 -7.2,-1.2 -2.9,0 -5.6,0.5 -8,1.5 -2.4,1 -4.4,2.4 -6.1,4.3 -1.7,1.9 -3,4.1 -3.9,6.7 -0.9,2.6 -1.4,5.5 -1.4,8.8 0,3.3 0.5,6.3 1.4,8.9 0.9,2.6 2.3,4.9 4,6.7 1.7,1.8 3.8,3.2 6.2,4.2 2.4,1 5.1,1.5 8,1.5 2.5,0 4.8,-0.4 6.9,-1 2.1,-0.6 3.9,-1.7 5.5,-2.9 1.5,-1.3 2.8,-2.8 3.8,-4.6 1,-1.8 1.6,-3.8 1.8,-5.9 h -7.9 c -0.5,2.5 -1.6,4.3 -3.3,5.6 -1.7,1.3 -3.9,1.9 -6.6,1.9 -1.7,0 -3.2,-0.3 -4.6,-1 -1.4,-0.6 -2.6,-1.6 -3.5,-2.8 -1,-1.2 -1.7,-2.7 -2.3,-4.5 -0.5,-1.8 -0.8,-3.8 -0.8,-6 0,-2.2 0.3,-4.1 0.8,-5.9 0.3,-1.9 1,-3.4 2,-4.6 z"
-   class="st1" />
-	</g>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 407 407"
+   style="enable-background:new 0 0 407 407;"
+   xml:space="preserve"><metadata
+   id="metadata36"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs34"><linearGradient
+   xlink:href="#SVGID_1_"
+   id="linearGradient46"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
+   x1="203.7169"
+   y1="7.7039"
+   x2="203.7169"
+   y2="402.0255" /><linearGradient
+   xlink:href="#SVGID_1_"
+   id="linearGradient48"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
+   x1="203.7169"
+   y1="7.7039"
+   x2="203.7169"
+   y2="402.0255" />
+	
+	
+<linearGradient
+   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
+   y2="402.02551"
+   x2="203.7169"
+   y1="7.7038999"
+   x1="203.7169"
+   gradientUnits="userSpaceOnUse"
+   id="linearGradient120"><stop
+     id="stop6-9"
+     style="stop-color:#F2F2F2"
+     offset="0" /><stop
+     id="stop8-1"
+     style="stop-color:#F7F7F7"
+     offset="0.5963" /><stop
+     id="stop10-7"
+     style="stop-color:#FEFEFE"
+     offset="1" /></linearGradient><filter
+   style="color-interpolation-filters:sRGB"
+   id="filter1002"
+   x="-0.013201674"
+   width="1.0264033"
+   y="-0.013198327"
+   height="1.0263967"><feGaussianBlur
+     stdDeviation="2.168925"
+     id="feGaussianBlur1004" /></filter></defs>
+<style
+   type="text/css"
+   id="style2">
+	.st0{fill:url(#SVGID_1_);}
+	.st1{fill:#515151;}
+</style>
+<g
+   transform="matrix(1,0,0,0.98477354,0,6.0829719)"
+   id="g15-0"
+   style="fill:#4d4d4d;filter:url(#filter1002)"><linearGradient
+     gradientTransform="matrix(1,0,0,-1,0,407.2074)"
+     y2="402.02551"
+     x2="203.7169"
+     y1="7.7038999"
+     x1="203.7169"
+     gradientUnits="userSpaceOnUse"
+     id="linearGradient91"><stop
+       id="stop85"
+       style="stop-color:#F2F2F2"
+       offset="0" /><stop
+       id="stop87"
+       style="stop-color:#F7F7F7"
+       offset="0.5963" /><stop
+       id="stop89"
+       style="stop-color:#FEFEFE"
+       offset="1" /></linearGradient><path
+     style="fill:#4d4d4d"
+     id="path13-7"
+     d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
+     class="st0" /><path
+     style="fill:#4d4d4d"
+     class="st0"
+     d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
+     id="path40-7" /></g><g
+   id="g15">
+		
+			
+		
+			<linearGradient
+   gradientTransform="matrix(1,0,0,-1,0,407.2074)"
+   y2="402.02551"
+   x2="203.7169"
+   y1="7.7038999"
+   x1="203.7169"
+   gradientUnits="userSpaceOnUse"
+   id="SVGID_1_">
+			<stop
+   id="stop6"
+   style="stop-color:#F2F2F2"
+   offset="0" />
+			<stop
+   id="stop8"
+   style="stop-color:#F7F7F7"
+   offset="0.5963" />
+			<stop
+   id="stop10"
+   style="stop-color:#FEFEFE"
+   offset="1" />
+		</linearGradient>
+		<path
+   style="fill:url(#linearGradient46)"
+   id="path13"
+   d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
+   class="st0" />
+	<path
+   style="fill:url(#linearGradient48)"
+   class="st0"
+   d="M 400.9,202.3 C 400.9,92.3 313.8,5.1 203.7,5.1 93.7,5.2 6.6,92.3 6.6,202.3 c 0,110 87.1,197.2 197.2,197.2 110.1,0 197.1,-87.1 197.1,-197.2 z"
+   id="path40" /></g><g
+   id="g27">
+		<path
+   style="fill:#515151"
+   id="path17"
+   d="m 223.7,137.8 h 0.2 v 6.9 h 7.9 v -28.5 c 0,-2.1 -0.4,-3.9 -1.2,-5.6 -0.8,-1.7 -1.9,-3.1 -3.4,-4.3 -1.5,-1.2 -3.2,-2.1 -5.3,-2.7 -2.1,-0.6 -4.3,-1 -6.9,-1 -2.3,0 -4.5,0.3 -6.5,1 -2,0.6 -3.7,1.5 -5.2,2.7 -1.5,1.2 -2.6,2.5 -3.5,4.1 -0.9,1.6 -1.3,3.3 -1.4,5.1 h 7.8 c 0.2,-0.9 0.5,-1.7 1,-2.4 0.5,-0.7 1.1,-1.4 1.8,-1.9 0.7,-0.5 1.6,-0.9 2.6,-1.2 1,-0.3 2,-0.4 3.1,-0.4 2.8,0 4.9,0.6 6.5,1.9 1.5,1.2 2.3,3.1 2.3,5.5 v 3.2 l -11.2,0.6 c -5.2,0.3 -9.1,1.5 -11.8,3.6 -2.7,2.1 -4.1,4.9 -4.1,8.6 0,1.9 0.3,3.6 1,5.1 0.7,1.5 1.7,2.8 2.9,3.9 1.2,1.1 2.7,1.9 4.4,2.5 1.7,0.6 3.6,0.9 5.7,0.9 1.4,0 2.8,-0.2 4.1,-0.5 1.3,-0.3 2.6,-0.8 3.7,-1.5 1.1,-0.6 2.1,-1.4 3.1,-2.3 1,-1.2 1.8,-2.2 2.4,-3.3 z m -3.2,-2 c -1,0.8 -2.1,1.5 -3.4,2 -1.3,0.5 -2.8,0.7 -4.3,0.7 -2.4,0 -4.3,-0.5 -5.7,-1.6 -1.4,-1.1 -2.1,-2.5 -2.1,-4.3 0,-1.8 0.7,-3.3 2.2,-4.3 1.4,-1 3.6,-1.6 6.5,-1.8 l 10.1,-0.7 v 3.2 c 0,1.4 -0.3,2.6 -0.8,3.8 -0.8,1.2 -1.5,2.2 -2.5,3 z"
+   class="st1" />
+		<path
+   style="fill:#515151"
+   id="path19"
+   d="m 278.5,228.7 -13.7,-3.4 c -16.7,-4.2 -23.6,-9.7 -23.6,-18.9 0,-11.7 10.9,-19.8 26.7,-19.8 15.8,0 26.5,8 27.7,21 h 17.9 c -0.7,-21.6 -19,-36.7 -45.2,-36.7 -26.8,0 -45.7,15 -45.7,36.5 0,17.5 10.6,28.2 34.1,34 l 16.3,4 c 16.7,4.2 23.9,10.4 23.9,20.6 0,11.8 -11.9,20.4 -28.4,20.4 -17.2,0 -29.8,-8.6 -31.2,-21.7 h -18 c 1.3,22.8 20.2,37.3 47.9,37.3 29.7,0 48.4,-14.7 48.4,-38.3 -0.3,-18.4 -11,-28.7 -37.1,-35 z"
+   class="st1" />
+		<path
+   style="fill:#515151"
+   id="path21"
+   d="m 187.7,144.7 v -28.3 c 0,-2.1 -0.3,-4 -1,-5.6 -0.7,-1.6 -1.5,-3.1 -2.7,-4.3 -1.2,-1.2 -2.6,-2.1 -4.3,-2.8 -1.7,-0.7 -3.5,-1 -5.6,-1 -1.5,0 -2.9,0.2 -4.2,0.6 -1.3,0.4 -2.6,0.9 -3.7,1.6 -1.1,0.7 -2.1,1.6 -3,2.5 -0.9,0.9 -1.6,2.1 -2.1,3.4 h -0.2 c -0.8,-2.6 -2.3,-4.6 -4.3,-6 -2,-1.4 -4.5,-2.1 -7.4,-2.1 -1.3,0 -2.6,0.2 -3.9,0.5 -1.2,0.3 -2.3,0.8 -3.4,1.5 -1,0.7 -1.9,1.4 -2.7,2.4 -0.8,0.9 -1.4,2 -1.9,3.1 h -0.2 v -7 h -7.9 v 41.6 h 7.8 v -25.5 c 0,-1.3 0.7,-2.6 1.1,-3.7 0.4,-1.1 1,-2.1 1.8,-3 0.8,-0.8 1.7,-1.5 2.8,-2 1.1,-0.5 2.3,-0.7 3.5,-0.7 1.2,0 2.3,0.2 3.3,0.6 1,0.4 1.8,0.9 2.5,1.6 0.7,0.7 1.2,1.5 1.6,2.5 0.4,1 0.6,2.1 0.6,3.2 v 27 h 8.2 V 119 c 0,-1.3 0.2,-2.6 0.7,-3.7 0.4,-1.1 1,-2.1 1.8,-2.9 0.8,-0.8 1.7,-1.4 2.7,-1.9 1.1,-0.4 2.2,-0.7 3.5,-0.7 2.6,0 4.6,0.8 6,2.2 1.4,1.5 2.1,3.6 2.1,6.3 v 26.3 z"
+   class="st1" />
+		<path
+   style="fill:#515151"
+   id="path23"
+   d="m 147.4,170.9 c -36.3,0 -59.1,25.3 -59.1,65.6 0,40.3 22.8,65.6 59.1,65.6 36.3,0 59.1,-25.3 59.1,-65.6 -0.1,-40.3 -22.8,-65.6 -59.1,-65.6 z m 0,115 c -24.9,0 -40.5,-19.1 -40.5,-49.4 0,-30.4 15.6,-49.5 40.5,-49.5 24.8,0 40.5,19.1 40.5,49.5 -0.1,30.3 -15.7,49.4 -40.5,49.4 z"
+   class="st1" />
+		<path
+   style="fill:#515151"
+   id="path25"
+   d="m 252.1,113.5 c 1,-1.2 2.1,-2.2 3.5,-2.9 1.4,-0.7 2.9,-1 4.6,-1 1.4,0 2.7,0.2 3.8,0.6 1.1,0.4 2.1,0.9 3,1.6 0.8,0.7 1.5,1.5 2,2.5 0.5,1 0.9,2 1.1,3.1 h 7.9 c -0.2,-2 -0.7,-3.9 -1.6,-5.7 -0.9,-1.8 -2.1,-3.3 -3.6,-4.7 -1.5,-1.3 -3.4,-2.4 -5.5,-3.2 -2.1,-0.8 -4.5,-1.2 -7.2,-1.2 -2.9,0 -5.6,0.5 -8,1.5 -2.4,1 -4.4,2.4 -6.1,4.3 -1.7,1.9 -3,4.1 -3.9,6.7 -0.9,2.6 -1.4,5.5 -1.4,8.8 0,3.3 0.5,6.3 1.4,8.9 0.9,2.6 2.3,4.9 4,6.7 1.7,1.8 3.8,3.2 6.2,4.2 2.4,1 5.1,1.5 8,1.5 2.5,0 4.8,-0.4 6.9,-1 2.1,-0.6 3.9,-1.7 5.5,-2.9 1.5,-1.3 2.8,-2.8 3.8,-4.6 1,-1.8 1.6,-3.8 1.8,-5.9 h -7.9 c -0.5,2.5 -1.6,4.3 -3.3,5.6 -1.7,1.3 -3.9,1.9 -6.6,1.9 -1.7,0 -3.2,-0.3 -4.6,-1 -1.4,-0.6 -2.6,-1.6 -3.5,-2.8 -1,-1.2 -1.7,-2.7 -2.3,-4.5 -0.5,-1.8 -0.8,-3.8 -0.8,-6 0,-2.2 0.3,-4.1 0.8,-5.9 0.3,-1.9 1,-3.4 2,-4.6 z"
+   class="st1" />
+	</g>
 </svg>

+ 54 - 54
web/img/syncthing-logo.e6163faa.svg → web/img/syncthing-logo.27d25cad.svg

@@ -1,54 +1,54 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 429 117.3" enable-background="new 0 0 429 117.3" xml:space="preserve">
-<g>
-	<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="58.666" y1="117.332" x2="58.666" y2="-9.094947e-13">
-		<stop  offset="0" style="stop-color:#0882C8"/>
-		<stop  offset="1" style="stop-color:#26B6DB"/>
-	</linearGradient>
-	<circle fill="url(#SVGID_1_)" cx="58.7" cy="58.7" r="58.7"/>
-	<g>
-		<circle fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" cx="58.7" cy="58.5" r="43.7"/>
-		<g>
-			<path fill="#FFFFFF" d="M94.7,47.8c4.7,1.6,9.8-0.9,11.4-5.6c1.6-4.7-0.9-9.8-5.6-11.4c-4.7-1.6-9.8,0.9-11.4,5.6
-				C87.5,41.1,90,46.2,94.7,47.8z"/>
-			<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="97.6" y1="39.4" x2="67.5" y2="64.4"/>
-		</g>
-		<g>
-			<path fill="#FFFFFF" d="M77.6,91c-0.4,4.9,3.2,9.3,8.2,9.8c5,0.4,9.3-3.2,9.8-8.2c0.4-4.9-3.2-9.3-8.2-9.8
-				C82.4,82.4,78,86,77.6,91z"/>
-			<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="86.5" y1="91.8" x2="67.5" y2="64.4"/>
-		</g>
-		<path fill="#FFFFFF" d="M60,69.3c2.7,4.2,8.3,5.4,12.4,2.7c4.2-2.7,5.4-8.3,2.7-12.4c-2.7-4.2-8.3-5.4-12.4-2.7
-			C58.5,59.5,57.3,65.1,60,69.3z"/>
-		<g>
-			<path fill="#FFFFFF" d="M21.2,61.4c-4.3-2.5-9.8-1.1-12.3,3.1c-2.5,4.3-1.1,9.8,3.1,12.3c4.3,2.5,9.8,1.1,12.3-3.1
-				C26.8,69.5,25.4,64,21.2,61.4z"/>
-			<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="16.6" y1="69.1" x2="67.5" y2="64.4"/>
-		</g>
-	</g>
-</g>
-<g>
-	<path fill="#0891D1" d="M163.8,50.2c-0.6-0.7-6.3-4.1-11.4-4.1c-3.4,0-5.2,1.2-5.2,3.5c0,2.9,3.2,3.7,8.9,5.2
-		c8.2,2.2,13.3,5,13.3,12.9c0,9.7-7.8,13-16,13c-6.2,0-13.1-2-18.2-5.3l4.3-8.6c0.8,0.8,7.5,5,14,5c3.5,0,5.2-1.1,5.2-3.2
-		c0-3.2-4.4-4-10.3-5.8c-7.9-2.4-11.5-5.3-11.5-11.8c0-9,7.2-13.9,15.7-13.9c6.1,0,11.6,2.5,15.4,4.7L163.8,50.2z"/>
-	<path fill="#0891D1" d="M175,85.1c1.7,0.5,3.3,0.8,4.4,0.8c2,0,3.3-1.5,4.2-5.5l-11.9-31.5h9.8l7.4,23.3l6.3-23.3h8.9l-12.1,36.6
-		c-1.7,5.3-6.2,8.7-11.8,8.8c-1.7,0-3.5-0.2-5.3-0.9V85.1z"/>
-	<path fill="#0891D1" d="M239.3,80.3h-9.6V62.6c0-4.1-1.7-5.9-4.3-5.9c-2.6,0-5.8,2.3-7,5.6v18.1h-9.6V48.8h8.6v5.3
-		c2.3-3.7,6.8-5.9,12.2-5.9c8.2,0,9.5,6.7,9.5,11.9V80.3z"/>
-	<path fill="#0891D1" d="M261.6,48.2c7.2,0,12.3,3.4,14.8,8.3l-9.4,2.8c-1.2-1.9-3.1-3-5.5-3c-4,0-7,3.2-7,8.2c0,5,3.1,8.3,7,8.3
-		c2.4,0,4.6-1.3,5.5-3.1l9.4,2.9c-2.3,4.9-7.6,8.3-14.8,8.3c-10.6,0-16.9-7.7-16.9-16.4S250.9,48.2,261.6,48.2z"/>
-	<path fill="#0891D1" d="M302.1,78.7c-2.6,1.1-6.2,2.3-9.7,2.3c-4.7,0-8.8-2.3-8.8-8.4V56.1h-4v-7.3h4v-10h9.6v10h6.4v7.3h-6.4v13.1
-		c0,2.1,1.2,2.9,2.8,2.9c1.4,0,3-0.6,4.2-1.1L302.1,78.7z"/>
-	<path fill="#0891D1" d="M337.2,80.3h-9.6V62.6c0-4.1-1.8-5.9-4.6-5.9c-2.3,0-5.5,2.2-6.7,5.6v18.1h-9.6V36.5h9.6v17.6
-		c2.3-3.7,6.3-5.9,10.9-5.9c8.5,0,9.9,6.5,9.9,11.9V80.3z"/>
-	<path fill="#0891D1" d="M343.4,45.2v-8.7h9.6v8.7H343.4z M343.4,80.3V48.8h9.6v31.5H343.4z"/>
-	<path fill="#0891D1" d="M389.9,80.3h-9.6V62.6c0-4.1-1.7-5.9-4.3-5.9c-2.6,0-5.8,2.3-7,5.6v18.1h-9.6V48.8h8.6v5.3
-		c2.3-3.7,6.8-5.9,12.2-5.9c8.2,0,9.5,6.7,9.5,11.9V80.3z"/>
-	<path fill="#0891D1" d="M395.5,64.6c0-9.2,6-16.3,14.6-16.3c4.7,0,8.4,2.2,10.6,5.8v-5.2h8.3v29.3c0,9.6-7.5,15.5-18.2,15.5
-		c-6.8,0-11.5-2.3-15-6.3l5.1-5.2c2.3,2.6,6,4.3,9.9,4.3c4.6,0,8.6-2.4,8.6-8.3v-3.1c-1.9,3.5-5.9,5.3-10,5.3
-		C401.1,80.5,395.5,73.3,395.5,64.6z M419.4,68.5v-6.6c-1.3-3.3-4.2-5.5-7.1-5.5c-4.1,0-7,4-7,8.4c0,4.6,3.2,8,7.5,8
-		C415.7,72.8,418.1,71,419.4,68.5z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 429 117.3" enable-background="new 0 0 429 117.3" xml:space="preserve">
+<g>
+	<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="58.666" y1="117.332" x2="58.666" y2="-9.094947e-13">
+		<stop  offset="0" style="stop-color:#0882C8"/>
+		<stop  offset="1" style="stop-color:#26B6DB"/>
+	</linearGradient>
+	<circle fill="url(#SVGID_1_)" cx="58.7" cy="58.7" r="58.7"/>
+	<g>
+		<circle fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" cx="58.7" cy="58.5" r="43.7"/>
+		<g>
+			<path fill="#FFFFFF" d="M94.7,47.8c4.7,1.6,9.8-0.9,11.4-5.6c1.6-4.7-0.9-9.8-5.6-11.4c-4.7-1.6-9.8,0.9-11.4,5.6
+				C87.5,41.1,90,46.2,94.7,47.8z"/>
+			<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="97.6" y1="39.4" x2="67.5" y2="64.4"/>
+		</g>
+		<g>
+			<path fill="#FFFFFF" d="M77.6,91c-0.4,4.9,3.2,9.3,8.2,9.8c5,0.4,9.3-3.2,9.8-8.2c0.4-4.9-3.2-9.3-8.2-9.8
+				C82.4,82.4,78,86,77.6,91z"/>
+			<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="86.5" y1="91.8" x2="67.5" y2="64.4"/>
+		</g>
+		<path fill="#FFFFFF" d="M60,69.3c2.7,4.2,8.3,5.4,12.4,2.7c4.2-2.7,5.4-8.3,2.7-12.4c-2.7-4.2-8.3-5.4-12.4-2.7
+			C58.5,59.5,57.3,65.1,60,69.3z"/>
+		<g>
+			<path fill="#FFFFFF" d="M21.2,61.4c-4.3-2.5-9.8-1.1-12.3,3.1c-2.5,4.3-1.1,9.8,3.1,12.3c4.3,2.5,9.8,1.1,12.3-3.1
+				C26.8,69.5,25.4,64,21.2,61.4z"/>
+			<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="16.6" y1="69.1" x2="67.5" y2="64.4"/>
+		</g>
+	</g>
+</g>
+<g>
+	<path fill="#0891D1" d="M163.8,50.2c-0.6-0.7-6.3-4.1-11.4-4.1c-3.4,0-5.2,1.2-5.2,3.5c0,2.9,3.2,3.7,8.9,5.2
+		c8.2,2.2,13.3,5,13.3,12.9c0,9.7-7.8,13-16,13c-6.2,0-13.1-2-18.2-5.3l4.3-8.6c0.8,0.8,7.5,5,14,5c3.5,0,5.2-1.1,5.2-3.2
+		c0-3.2-4.4-4-10.3-5.8c-7.9-2.4-11.5-5.3-11.5-11.8c0-9,7.2-13.9,15.7-13.9c6.1,0,11.6,2.5,15.4,4.7L163.8,50.2z"/>
+	<path fill="#0891D1" d="M175,85.1c1.7,0.5,3.3,0.8,4.4,0.8c2,0,3.3-1.5,4.2-5.5l-11.9-31.5h9.8l7.4,23.3l6.3-23.3h8.9l-12.1,36.6
+		c-1.7,5.3-6.2,8.7-11.8,8.8c-1.7,0-3.5-0.2-5.3-0.9V85.1z"/>
+	<path fill="#0891D1" d="M239.3,80.3h-9.6V62.6c0-4.1-1.7-5.9-4.3-5.9c-2.6,0-5.8,2.3-7,5.6v18.1h-9.6V48.8h8.6v5.3
+		c2.3-3.7,6.8-5.9,12.2-5.9c8.2,0,9.5,6.7,9.5,11.9V80.3z"/>
+	<path fill="#0891D1" d="M261.6,48.2c7.2,0,12.3,3.4,14.8,8.3l-9.4,2.8c-1.2-1.9-3.1-3-5.5-3c-4,0-7,3.2-7,8.2c0,5,3.1,8.3,7,8.3
+		c2.4,0,4.6-1.3,5.5-3.1l9.4,2.9c-2.3,4.9-7.6,8.3-14.8,8.3c-10.6,0-16.9-7.7-16.9-16.4S250.9,48.2,261.6,48.2z"/>
+	<path fill="#0891D1" d="M302.1,78.7c-2.6,1.1-6.2,2.3-9.7,2.3c-4.7,0-8.8-2.3-8.8-8.4V56.1h-4v-7.3h4v-10h9.6v10h6.4v7.3h-6.4v13.1
+		c0,2.1,1.2,2.9,2.8,2.9c1.4,0,3-0.6,4.2-1.1L302.1,78.7z"/>
+	<path fill="#0891D1" d="M337.2,80.3h-9.6V62.6c0-4.1-1.8-5.9-4.6-5.9c-2.3,0-5.5,2.2-6.7,5.6v18.1h-9.6V36.5h9.6v17.6
+		c2.3-3.7,6.3-5.9,10.9-5.9c8.5,0,9.9,6.5,9.9,11.9V80.3z"/>
+	<path fill="#0891D1" d="M343.4,45.2v-8.7h9.6v8.7H343.4z M343.4,80.3V48.8h9.6v31.5H343.4z"/>
+	<path fill="#0891D1" d="M389.9,80.3h-9.6V62.6c0-4.1-1.7-5.9-4.3-5.9c-2.6,0-5.8,2.3-7,5.6v18.1h-9.6V48.8h8.6v5.3
+		c2.3-3.7,6.8-5.9,12.2-5.9c8.2,0,9.5,6.7,9.5,11.9V80.3z"/>
+	<path fill="#0891D1" d="M395.5,64.6c0-9.2,6-16.3,14.6-16.3c4.7,0,8.4,2.2,10.6,5.8v-5.2h8.3v29.3c0,9.6-7.5,15.5-18.2,15.5
+		c-6.8,0-11.5-2.3-15-6.3l5.1-5.2c2.3,2.6,6,4.3,9.9,4.3c4.6,0,8.6-2.4,8.6-8.3v-3.1c-1.9,3.5-5.9,5.3-10,5.3
+		C401.1,80.5,395.5,73.3,395.5,64.6z M419.4,68.5v-6.6c-1.3-3.3-4.2-5.5-7.1-5.5c-4.1,0-7,4-7,8.4c0,4.6,3.2,8,7.5,8
+		C415.7,72.8,418.1,71,419.4,68.5z"/>
+</g>
+</svg>

+ 34 - 34
web/index.html

@@ -1,34 +1,34 @@
-<!DOCTYPE html>
-<html lang="">
-
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width,initial-scale=1">
-  <meta name="robots" content="noindex">
-  <script>
-    if (document.URL.indexOf("ui") === -1) {
-      window.location.replace("ui")
-    }
-  </script>
-  <link rel="apple-touch-icon" sizes="180x180" href="/ui/img/icon/apple-touch-icon.png">
-  <link rel="manifest" href="/ui/site.webmanifest">
-  <meta name="msapplication-TileColor" content="#da532c">
-  <meta name="theme-color" content="#ffffff">
-  <link rel="icon" href="/ui/favicon.svg" type="image/svg+xml">
-  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@mdi/font@6.5.95/css/materialdesignicons.min.css">
-  <title>
-    CasaOS
-  </title>
-<link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/5.js" rel="prefetch"><link href="/ui/js/6.js" rel="prefetch"><link href="/ui/js/7.js" rel="prefetch"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/chunk-vendors.js" rel="preload" as="script"></head>
-
-<body>
-  <noscript>
-    <strong>We're sorry but CasaOS doesn't work properly without JavaScript enabled.
-        Please enable it to continue.</strong>
-  </noscript>
-  <div id="app"></div>
-  <!-- built files will be auto injected -->
-<script type="text/javascript" src="/ui/js/chunk-vendors.js"></script><script type="text/javascript" src="/ui/js/app.js"></script></body>
-
-</html>
+<!DOCTYPE html>
+<html lang="">
+
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <meta name="robots" content="noindex">
+  <script>
+    if (document.URL.indexOf("ui") === -1) {
+      window.location.replace("ui")
+    }
+  </script>
+  <link rel="apple-touch-icon" sizes="180x180" href="/ui/img/icon/apple-touch-icon.png">
+  <link rel="manifest" href="/ui/site.webmanifest">
+  <meta name="msapplication-TileColor" content="#da532c">
+  <meta name="theme-color" content="#ffffff">
+  <link rel="icon" href="/ui/favicon.svg" type="image/svg+xml">
+
+  <title>
+    CasaOS
+  </title>
+<link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/5.js" rel="prefetch"><link href="/ui/js/6.js" rel="prefetch"><link href="/ui/js/7.js" rel="prefetch"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/chunk-vendors.js" rel="preload" as="script"></head>
+
+<body>
+  <noscript>
+    <strong>We're sorry but CasaOS doesn't work properly without JavaScript enabled.
+        Please enable it to continue.</strong>
+  </noscript>
+  <div id="app"></div>
+  <!-- built files will be auto injected -->
+<script type="text/javascript" src="/ui/js/chunk-vendors.js"></script><script type="text/javascript" src="/ui/js/app.js"></script></body>
+
+</html>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web/js/0.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
web/js/2.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5 - 5
web/js/3.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 32
web/js/4.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4 - 4
web/js/5.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
web/js/6.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
web/js/7.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web/js/app.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 62 - 0
web/js/chunk-vendors.js


+ 1 - 1
web/robots.txt

@@ -1,2 +1,2 @@
-User-agent: *
+User-agent: *
 Disallow: /

+ 14 - 14
web/site.webmanifest

@@ -1,14 +1,14 @@
-{
-    "name": "",
-    "short_name": "",
-    "icons": [
-        {
-            "src": "/ui/img/icon/android-chrome-192x192.png",
-            "sizes": "192x192",
-            "type": "image/png"
-        }
-    ],
-    "theme_color": "#ffffff",
-    "background_color": "#ffffff",
-    "display": "standalone"
-}
+{
+    "name": "",
+    "short_name": "",
+    "icons": [
+        {
+            "src": "/ui/img/icon/android-chrome-192x192.png",
+            "sizes": "192x192",
+            "type": "image/png"
+        }
+    ],
+    "theme_color": "#ffffff",
+    "background_color": "#ffffff",
+    "display": "standalone"
+}

+ 6 - 6
web/static.go

@@ -1,6 +1,6 @@
-package web
-
-import "embed"
-
-//go:embed index.html favicon.svg img js browserconfig.xml site.webmanifest robots.txt
-var Static embed.FS
+package web
+
+import "embed"
+
+//go:embed index.html favicon.svg browserconfig.xml site.webmanifest robots.txt img js fonts
+var Static embed.FS

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác