🎉 初始化提交

This commit is contained in:
zhaojun1998
2019-08-19 21:57:02 +08:00
commit 61ad4b52c5
159 changed files with 18824 additions and 0 deletions

34
.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
HELP.md
target/
.mvn/wrapper/**
!**/src/main/**
**/src/test/**
mvnw
mvnw.cmd
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/

140
pom.xml Normal file
View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<groupId>im.zhaojun</groupId>
<artifactId>zfile</artifactId>
<version>0.1</version>
<name>zfile</name>
<description>一个在线的文件浏览系统</description>
<properties>
<java.version>1.8</java.version>
<mybatis.starter.version>1.3.2</mybatis.starter.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.5.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.7.0</version>
</dependency>
<!-- 对象存储 API -->
<dependency>
<groupId>com.upyun</groupId>
<artifactId>java-sdk</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.23</version>
</dependency>
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java</artifactId>
<version>3.19.5</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.nuxeo.onedrive</groupId>
<artifactId>onedrive-java-client</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.3</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.starter.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>nuxeo</id>
<name>nuxeo</name>
<url>http://maven.nuxeo.org/nexus/content/groups/public</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,15 @@
package im.zhaojun;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class ZfileApplication {
public static void main(String[] args) {
SpringApplication.run(ZfileApplication.class, args);
}
}

View File

@@ -0,0 +1,109 @@
package im.zhaojun.aliyun.service;
import cn.hutool.core.util.URLUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class AliyunService implements FileService {
@Value("${zfile.cache.timeout}")
private Long timeout;
@Resource
private StorageConfigService storageConfigService;
private static final String BUCKET_NAME_KEY = "bucket-name";
private static final String ACCESS_KEY = "accessKey";
private static final String SECRET_KEY = "secretKey";
private static final String DOMAIN_KEY = "domain";
private static final String ENDPOINT_KEY = "endPoint";
private OSS ossClient;
private String bucketName;
private String domain;
private boolean isPrivate;
@Override
public void initMethod() {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.ALIYUN);
String accessKey = stringStorageConfigMap.get(ACCESS_KEY).getValue();
String secretKey = stringStorageConfigMap.get(SECRET_KEY).getValue();
String endPoint = stringStorageConfigMap.get(ENDPOINT_KEY).getValue();
bucketName = stringStorageConfigMap.get(BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(DOMAIN_KEY).getValue();
ossClient = new OSSClientBuilder().build(endPoint, accessKey, secretKey);
AccessControlList bucketAcl = ossClient.getBucketAcl(bucketName);
CannedAccessControlList cannedACL = bucketAcl.getCannedACL();
isPrivate = "Private".equals(cannedACL.name());
}
@Override
public List<FileItem> fileList(String path) {
path = StringUtils.removeFirstSeparator(path);
List<FileItem> fileItemList = new ArrayList<>();
ObjectListing objectListing =
ossClient.listObjects(new ListObjectsRequest(bucketName).withDelimiter("/").withPrefix(path));
for (OSSObjectSummary s : objectListing.getObjectSummaries()) {
FileItem fileItem = new FileItem();
fileItem.setName(s.getKey().substring(path.length()));
fileItem.setSize(s.getSize());
fileItem.setTime(s.getLastModified());
fileItem.setType(FileTypeEnum.FILE);
fileItemList.add(fileItem);
}
for (String commonPrefix : objectListing.getCommonPrefixes()) {
FileItem fileItem = new FileItem();
fileItem.setName(commonPrefix.substring(path.length(), commonPrefix.length() - 1));
fileItem.setType(FileTypeEnum.FOLDER);
fileItemList.add(fileItem);
}
return fileItemList;
}
@Override
public String getDownloadUrl(String path) throws Exception {
path = StringUtils.removeFirstSeparator(path);
path = URLDecoder.decode(path, "utf8");
if (isPrivate) {
Date expirationDate = new Date(new Date().getTime() + timeout * 1000);
URL url = ossClient.generatePresignedUrl(bucketName, path, expirationDate);
return URLUtil.complateUrl(domain, url.getFile());
} else {
return URLUtil.complateUrl(domain, path);
}
}
}

View File

@@ -0,0 +1,63 @@
package im.zhaojun.common.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching
public class CaffeineConfiguration {
@Value("${zfile.cache.timeout}")
private Long timeout;
public static final String CACHE_NAME = "zfile";
/**
* 个性化配置缓存
*/
@Bean
public CacheManager cacheManager() {
SimpleCacheManager manager = new SimpleCacheManager();
ArrayList<CaffeineCache> caches = new ArrayList<>();
caches.add(new CaffeineCache(CACHE_NAME,
Caffeine.newBuilder().recordStats()
.expireAfterWrite(timeout, TimeUnit.SECONDS)
.build())
);
manager.setCaches(caches);
return manager;
}
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
char separator = ':';
StringBuilder strBuilder = new StringBuilder();
// 类名
strBuilder.append(target.getClass().getSimpleName());
strBuilder.append(separator);
// 方法名
strBuilder.append(method.getName());
strBuilder.append(separator);
// 参数值
for (Object object : params) {
strBuilder.append(object).append(",");
}
return strBuilder.toString();
}
};
}
}

View File

@@ -0,0 +1,14 @@
package im.zhaojun.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}

View File

@@ -0,0 +1,49 @@
package im.zhaojun.common.config;
import im.zhaojun.aliyun.service.AliyunService;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.service.FileService;
import im.zhaojun.ftp.service.FtpService;
import im.zhaojun.huawei.service.HuaweiService;
import im.zhaojun.local.service.LocalService;
import im.zhaojun.qiniu.service.QiniuService;
import im.zhaojun.tencent.TencentService;
import im.zhaojun.upyun.service.UpYunService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 存储类型工厂类
*/
@Component
public class StorageTypeFactory implements ApplicationContextAware {
private static Map<String, FileService> storageTypeEnumFileServiceMap;
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext act) throws BeansException {
applicationContext = act;
storageTypeEnumFileServiceMap = act.getBeansOfType(FileService.class);
}
public static <T extends FileService> T getTrafficMode(StorageTypeEnum type) {
String beanName = "";
switch (type) {
case UPYUN: beanName = applicationContext.getBeanNamesForType(UpYunService.class)[0]; break;
case QINIU: beanName = applicationContext.getBeanNamesForType(QiniuService.class)[0]; break;
case HUAWEI: beanName = applicationContext.getBeanNamesForType(HuaweiService.class)[0]; break;
case FTP: beanName = applicationContext.getBeanNamesForType(FtpService.class)[0]; break;
case ALIYUN: beanName = applicationContext.getBeanNamesForType(AliyunService.class)[0]; break;
case LOCAL: beanName = applicationContext.getBeanNamesForType(LocalService.class)[0]; break;
case TENCENT: beanName = applicationContext.getBeanNamesForType(TencentService.class)[0]; break;
}
return (T) storageTypeEnumFileServiceMap.get(beanName);
}
}

View File

@@ -0,0 +1,120 @@
package im.zhaojun.common.controller;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.config.StorageTypeFactory;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.ImageInfo;
import im.zhaojun.common.model.ResultBean;
import im.zhaojun.common.model.SiteConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.SystemConfigService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
@RestController
public class FileController {
private FileService fileService;
@Resource
private SystemConfigService configService;
@GetMapping("/filelist")
public ResultBean list(String path, String sortBy, boolean descending) throws Exception {
List<FileItem> fileItems = fileService.fileList(path);
// 排序, 先按照文件类型比较, 文件夹在前, 文件在后, 然后根据 sortBy 字段排序, 默认为升序;
fileItems.sort((o1, o2) -> {
FileTypeEnum o1Type = o1.getType();
FileTypeEnum o2Type = o2.getType();
if (o1Type.equals(o2Type)) {
switch (sortBy) {
case "name": return o1.getName().compareTo(o2.getName());
case "time": return o1.getTime().compareTo(o2.getTime());
case "size": return o1.getSize().compareTo(o2.getSize());
default: return o1.getName().compareTo(o2.getName());
}
}
if (o1Type.equals(FileTypeEnum.FOLDER)) {
return -1;
} else {
return 1;
}
});
if (descending) {
Collections.reverse(fileItems);
}
return ResultBean.successData(fileItems);
}
/**
* 获取下载链接
* @param path 路径
* @return 下载链接
*/
@GetMapping("/downloadUrl")
public ResultBean getDownloadUrl(String path) throws Exception {
return ResultBean.successData(fileService.getDownloadUrl(path));
}
/**
* 获取文件类容, 仅限用于, txt, md, ini 等普通文本文件.
* @param path 文件路径
* @return 文件内容
*/
@GetMapping("/getContent")
public ResultBean getContent(String path) throws Exception {
return ResultBean.successData(fileService.getTextContent(path));
}
/**
* 获取系统配置信息和当前页的标题, 文件头, 文件尾信息
* @param path 路径
*/
@GetMapping("/getConfig")
public ResultBean getConfig(String path) throws Exception {
SiteConfig config = fileService.getConfig(path);
config.setSystemConfig(configService.getSystemConfig());
return ResultBean.successData(config);
}
/**
* 更新存储策略, 使用 @PostConstruct 注解, 以用于第一次启动时, 根据数据库的配置值, 读取默认的存储策略.
*/
@PostConstruct
@GetMapping("/updateStorageStrategy")
public ResultBean updateConfig() {
StorageTypeEnum storageStrategy = configService.getSystemConfig().getStorageStrategy();
fileService = StorageTypeFactory.getTrafficMode(storageStrategy);
return ResultBean.success();
}
@GetMapping("clearCache")
public ResultBean clearCache() throws Exception {
fileService.clearCache();
return ResultBean.success();
}
@GetMapping("/getImageInfo")
public ResultBean getImageInfo(String url) throws Exception {
return ResultBean.success(fileService.getImageInfo(url));
}
}

View File

@@ -0,0 +1,32 @@
package im.zhaojun.common.controller;
import im.zhaojun.common.service.SystemConfigService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
@Controller
public class IndexController {
@Resource
private SystemConfigService systemConfigService;
@GetMapping("/")
public ModelAndView index(ModelAndView modelAndView) {
modelAndView.setViewName("index");
modelAndView.addObject("systemConfig", systemConfigService.getSystemConfig());
return modelAndView;
}
@GetMapping("/admin")
public ModelAndView admin(ModelAndView modelAndView) {
modelAndView.setViewName("admin");
modelAndView.addObject("systemConfig", systemConfigService.getSystemConfig());
return modelAndView;
}
}

View File

@@ -0,0 +1,19 @@
package im.zhaojun.common.enums;
public enum FileTypeEnum {
FILE("File"), FOLDER("Folder");
private String value;
FileTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,52 @@
package im.zhaojun.common.enums;
import java.util.HashMap;
import java.util.Map;
public enum StorageTypeEnum {
UPYUN("upyun", "又拍云 USS"),
QINIU("qiniu", "七牛云 KODO"),
HUAWEI("huawei", "华为云 OBS"),
ALIYUN("aliyun", "阿里云 OSS"),
FTP("ftp", "FTP"),
LOCAL("local", "本地存储"),
TENCENT("tencent", "腾讯云 COS");;
private static Map<String, StorageTypeEnum> enumMap = new HashMap<>();
static {
for (StorageTypeEnum type : StorageTypeEnum.values()) {
enumMap.put(type.getKey(), type);
}
}
StorageTypeEnum(String key, String description) {
this.key = key;
this.description = description;
}
private String key;
private String description;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static StorageTypeEnum getEnum(String value) {
return enumMap.get(value);
}
}

View File

@@ -0,0 +1,58 @@
package im.zhaojun.common.enums;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class StorageTypeEnumTypeHandler extends BaseTypeHandler<StorageTypeEnum>{
public StorageTypeEnumTypeHandler(Class<StorageTypeEnum> type) {
if (type == null)
throw new IllegalArgumentException("Type argument cannot be null");
StorageTypeEnum[] enums = type.getEnumConstants();
if (enums == null)
throw new IllegalArgumentException(type.getSimpleName()
+ " does not represent an enum type.");
}
@Override
public StorageTypeEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
String i = rs.getString(columnName);
if (rs.wasNull()) {
return null;
} else {
return StorageTypeEnum.getEnum(i);
}
}
@Override
public StorageTypeEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String i = rs.getString(columnIndex);
if (rs.wasNull()) {
return null;
} else {
return StorageTypeEnum.getEnum(i);
}
}
@Override
public StorageTypeEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String i = cs.getString(columnIndex);
if (cs.wasNull()) {
return null;
} else {
return StorageTypeEnum.getEnum(i);
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, StorageTypeEnum parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter.getKey());
}
}

View File

@@ -0,0 +1,38 @@
package im.zhaojun.common.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.HashMap;
import java.util.Map;
public enum ViewModeEnum {
DETAILS("details"), ICONS("icons"), GRID("grid");
private static Map<String, ViewModeEnum> enumMap = new HashMap<>();
static {
for (ViewModeEnum type : ViewModeEnum.values()) {
enumMap.put(type.getValue(), type);
}
}
String value;
ViewModeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static ViewModeEnum getEnum(String value) {
return enumMap.get(value);
}
}

View File

@@ -0,0 +1,59 @@
package im.zhaojun.common.enums;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ViewModeEnumTypeHandler extends BaseTypeHandler<ViewModeEnum>{
public ViewModeEnumTypeHandler(Class<ViewModeEnum> type) {
if (type == null)
throw new IllegalArgumentException("Type argument cannot be null");
ViewModeEnum[] enums = type.getEnumConstants();
if (enums == null)
throw new IllegalArgumentException(type.getSimpleName()
+ " does not represent an enum type.");
}
@Override
public ViewModeEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
String i = rs.getString(columnName);
if (rs.wasNull()) {
return null;
} else {
return ViewModeEnum.getEnum(i);
}
}
@Override
public ViewModeEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String i = rs.getString(columnIndex);
if (rs.wasNull()) {
return null;
} else {
return ViewModeEnum.getEnum(i);
}
}
@Override
public ViewModeEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String i = cs.getString(columnIndex);
if (cs.wasNull()) {
return null;
} else {
return ViewModeEnum.getEnum(i);
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, ViewModeEnum parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter.getValue());
}
}

View File

@@ -0,0 +1,24 @@
package im.zhaojun.common.mapper;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.StorageConfig;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface StorageConfigMapper {
int deleteByPrimaryKey(Integer id);
int insert(StorageConfig record);
int insertSelective(StorageConfig record);
StorageConfig selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(StorageConfig record);
int updateByPrimaryKey(StorageConfig record);
List<StorageConfig> selectStorageConfigByType(StorageTypeEnum type);
}

View File

@@ -0,0 +1,16 @@
package im.zhaojun.common.mapper;
import im.zhaojun.common.model.SystemConfig;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SystemConfigMapper {
int insert(SystemConfig record);
int updateByPrimaryKeySelective(SystemConfig record);
int updateByPrimaryKey(SystemConfig record);
SystemConfig selectFirstConfig();
}

View File

@@ -0,0 +1,46 @@
package im.zhaojun.common.model;
import im.zhaojun.common.enums.FileTypeEnum;
import java.io.Serializable;
import java.util.Date;
public class FileItem implements Serializable {
private String name;
private Date time;
private Long size;
private FileTypeEnum type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public Long getSize() {
return size;
}
public void setSize(Long size) {
this.size = size;
}
public FileTypeEnum getType() {
return type;
}
public void setType(FileTypeEnum type) {
this.type = type;
}
}

View File

@@ -0,0 +1,14 @@
package im.zhaojun.common.model;
public class FolderItem {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,27 @@
package im.zhaojun.common.model;
public class ImageInfo {
private Integer width;
private Integer height;
public ImageInfo(Integer width, Integer height) {
this.width = width;
this.height = height;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}

View File

@@ -0,0 +1,79 @@
package im.zhaojun.common.model;
import java.io.Serializable;
public class ResultBean implements Serializable {
private static final long serialVersionUID = -8276264968757808344L;
private static final int SUCCESS = 0;
private static final int FAIL = -1;
private String msg = "操作成功";
private int code = SUCCESS;
private Object data;
private ResultBean() {
super();
}
private ResultBean(String msg, Object data, int code) {
this.msg = msg;
this.data = data;
this.code = code;
}
public static ResultBean success() {
return success("操作成功");
}
public static ResultBean success(String msg) {
return success(msg, null);
}
public static ResultBean successData(Object data) {
return success("操作成功", data);
}
public static ResultBean success(Object data) {
return success("操作成功", data);
}
public static ResultBean success(String msg, Object data) {
return new ResultBean(msg, data, SUCCESS);
}
public static ResultBean error(String msg) {
ResultBean resultBean = new ResultBean();
resultBean.setCode(FAIL);
resultBean.setMsg(msg);
return resultBean;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@@ -0,0 +1,38 @@
package im.zhaojun.common.model;
import java.io.Serializable;
public class SiteConfig implements Serializable {
private static final long serialVersionUID = 8811196207046121740L;
private String header;
private String footer;
private SystemConfig systemConfig;
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public String getFooter() {
return footer;
}
public void setFooter(String footer) {
this.footer = footer;
}
public SystemConfig getSystemConfig() {
return systemConfig;
}
public void setSystemConfig(SystemConfig systemConfig) {
this.systemConfig = systemConfig;
}
}

View File

@@ -0,0 +1,56 @@
package im.zhaojun.common.model;
import im.zhaojun.common.enums.StorageTypeEnum;
public class StorageConfig {
private Integer id;
private StorageTypeEnum type;
private String key;
private String title;
private String value;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public StorageTypeEnum getType() {
return type;
}
public void setType(StorageTypeEnum type) {
this.type = type;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,90 @@
package im.zhaojun.common.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.enums.ViewModeEnum;
public class SystemConfig {
@JsonIgnore
private Integer id;
private String siteName;
private ViewModeEnum mode;
private Boolean sidebarEnable;
private Boolean infoEnable;
private Boolean searchEnable;
private Boolean searchIgnoreCase;
@JsonIgnore
private StorageTypeEnum storageStrategy;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSiteName() {
return siteName;
}
public void setSiteName(String siteName) {
this.siteName = siteName;
}
public ViewModeEnum getMode() {
return mode;
}
public void setMode(ViewModeEnum mode) {
this.mode = mode;
}
public Boolean getSidebarEnable() {
return sidebarEnable;
}
public void setSidebarEnable(Boolean sidebarEnable) {
this.sidebarEnable = sidebarEnable;
}
public Boolean getInfoEnable() {
return infoEnable;
}
public void setInfoEnable(Boolean infoEnable) {
this.infoEnable = infoEnable;
}
public Boolean getSearchEnable() {
return searchEnable;
}
public void setSearchEnable(Boolean searchEnable) {
this.searchEnable = searchEnable;
}
public Boolean getSearchIgnoreCase() {
return searchIgnoreCase;
}
public void setSearchIgnoreCase(Boolean searchIgnoreCase) {
this.searchIgnoreCase = searchIgnoreCase;
}
public StorageTypeEnum getStorageStrategy() {
return storageStrategy;
}
public void setStorageStrategy(StorageTypeEnum storageStrategy) {
this.storageStrategy = storageStrategy;
}
}

View File

@@ -0,0 +1,75 @@
package im.zhaojun.common.service;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import im.zhaojun.common.config.CaffeineConfiguration;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.ImageInfo;
import im.zhaojun.common.model.SiteConfig;
import im.zhaojun.common.util.StringUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.util.List;
@CacheConfig(cacheNames = CaffeineConfiguration.CACHE_NAME, keyGenerator = "keyGenerator")
public interface FileService {
@Cacheable
List<FileItem> fileList(String path) throws Exception;
@Cacheable
String getDownloadUrl(String path) throws Exception;
/**
* 构建指定路径下标题, 页头, 页尾
* @param path 路径
*/
@Cacheable
default SiteConfig getConfig(String path) throws Exception {
path = StringUtils.removeLastSeparator(path);
SiteConfig siteConfig = new SiteConfig();
for (FileItem fileItem : fileList(path)) {
if ("readme.md".equalsIgnoreCase(fileItem.getName())) {
siteConfig.setFooter(getTextContent(path + "/" + fileItem.getName()));
} else if ("header.md".equalsIgnoreCase(fileItem.getName())) {
siteConfig.setHeader(getTextContent(path + "/" + fileItem.getName()));
}
}
return siteConfig;
}
default String getTextContent(String path) throws Exception {
return HttpUtil.get(URLDecoder.decode(getDownloadUrl(path), "utf8"));
}
@PostConstruct
default void initMethod() throws Exception {}
/**
* 清除缓存.
*/
@CacheEvict(allEntries = true)
default void clearCache() throws Exception {
}
/**
* 获取图片信息
* @param url 图片 URL
* @return 图片的信息, 宽、高
*/
@Cacheable
default ImageInfo getImageInfo(String url) throws Exception {
url = URLUtil.decode(url);
InputStream inputStream = new URL(url).openStream();
BufferedImage sourceImg = ImageIO.read(inputStream);
return new ImageInfo(sourceImg.getWidth(), sourceImg.getHeight());
}
}

View File

@@ -0,0 +1,30 @@
package im.zhaojun.common.service;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.mapper.StorageConfigMapper;
import im.zhaojun.common.model.StorageConfig;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class StorageConfigService {
@Resource
private StorageConfigMapper storageConfigMapper;
public List<StorageConfig> selectStorageConfigByType(StorageTypeEnum storageTypeEnum) {
return storageConfigMapper.selectStorageConfigByType(storageTypeEnum);
}
public Map<String, StorageConfig> selectStorageConfigMapByKey(StorageTypeEnum storageTypeEnum) {
Map<String, StorageConfig> map = new HashMap<>();
for (StorageConfig storageConfig : selectStorageConfigByType(storageTypeEnum)) {
map.put(storageConfig.getKey(), storageConfig);
}
return map;
}
}

View File

@@ -0,0 +1,20 @@
package im.zhaojun.common.service;
import im.zhaojun.common.mapper.SystemConfigMapper;
import im.zhaojun.common.model.SystemConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class SystemConfigService {
@Resource
private SystemConfigMapper systemConfigMapper;
@Cacheable("zfile")
public SystemConfig getSystemConfig() {
return systemConfigMapper.selectFirstConfig();
}
}

View File

@@ -0,0 +1,44 @@
package im.zhaojun.common.util;
public class StringUtils {
/**
* 移除 URL 中的第一个 '/'
* @return 如 path = '/folder1/file1', 返回 'folder1/file1'
*/
public static String removeFirstSeparator(String path) {
if (!"".equals(path) && path.charAt(0) == '/') {
path = path.substring(1);
}
return path;
}
/**
* 移除 URL 中的最后一个 '/'
* @return 如 path = '/folder1/file1/', 返回 '/folder1/file1'
*/
public static String removeLastSeparator(String path) {
if (!"".equals(path) && path.charAt(path.length() - 1) == '/') {
path = path.substring(0, path.length() - 1);
}
return path;
}
/**
* 将域名和路径组装成 URL, 主要用来处理分隔符 '/'
* @param domain 域名
* @param path 路径
* @return URL
*/
public static String concatDomainAndPath(String domain, String path) {
if (path != null && path.length() > 1 && path.charAt(0) != '/') {
path = '/' + path;
}
if (domain.charAt(domain.length() - 1) == '/') {
domain = domain.substring(0, domain.length() - 2);
}
return domain + path;
}
}

View File

@@ -0,0 +1,73 @@
package im.zhaojun.ftp.service;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.ftp.Ftp;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class FtpService implements FileService {
@Resource
private StorageConfigService storageConfigService;
private static final String HOST_KEY = "host";
private static final String PORT_KEY = "port";
private static final String USERNAME_KEY = "username";
private static final String PASSWORD_KEY = "password";
private static final String DOMAIN_KEY = "domain";
private Ftp ftp;
private String domain;
@Override
public void initMethod() {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.FTP);
String host = stringStorageConfigMap.get(HOST_KEY).getValue();
String port = stringStorageConfigMap.get(PORT_KEY).getValue();
String username = stringStorageConfigMap.get(USERNAME_KEY).getValue();
String password = stringStorageConfigMap.get(PASSWORD_KEY).getValue();
domain = stringStorageConfigMap.get(DOMAIN_KEY).getValue();
ftp = new Ftp(host, Integer.parseInt(port), username, password);
}
@Override
public List<FileItem> fileList(String path) {
FTPFile[] ftpFiles = ftp.lsFiles(path);
List<FileItem> fileItemList = new ArrayList<>();
for (FTPFile ftpFile : ftpFiles) {
FileItem fileItem = new FileItem();
fileItem.setName(ftpFile.getName());
fileItem.setSize(ftpFile.getSize());
fileItem.setTime(ftpFile.getTimestamp().getTime());
fileItem.setType(ftpFile.isDirectory() ? FileTypeEnum.FOLDER : FileTypeEnum.FILE);
fileItemList.add(fileItem);
}
return fileItemList;
}
@Override
public String getDownloadUrl(String path) {
return URLUtil.complateUrl(domain, path);
}
}

View File

@@ -0,0 +1,107 @@
package im.zhaojun.huawei.service;
import cn.hutool.core.util.URLUtil;
import com.obs.services.ObsClient;
import com.obs.services.model.*;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class HuaweiService implements FileService {
private String bucketName;
private String domain;
@Value("${zfile.cache.timeout}")
private Long timeout;
private static final String BUCKET_NAME_KEY = "bucket-name";
private static final String ACCESS_KEY = "accessKey";
private static final String SECRET_KEY = "secretKey";
private static final String DOMAIN_KEY = "domain";
private static final String ENDPOINT_KEY = "endPoint";
@Resource
private StorageConfigService storageConfigService;
private ObsClient obsClient;
@Override
public void initMethod() {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.HUAWEI);
String accessKey = stringStorageConfigMap.get(ACCESS_KEY).getValue();
String secretKey = stringStorageConfigMap.get(SECRET_KEY).getValue();
String endPoint = stringStorageConfigMap.get(ENDPOINT_KEY).getValue();
bucketName = stringStorageConfigMap.get(BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(DOMAIN_KEY).getValue();
obsClient = new ObsClient(accessKey, secretKey, endPoint);
}
@Override
public List<FileItem> fileList(String path) {
path = StringUtils.removeFirstSeparator(path);
List<FileItem> fileItemList = new ArrayList<>();
ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
listObjectsRequest.setBucketName(bucketName);
listObjectsRequest.setDelimiter("/");
listObjectsRequest.setPrefix(path);
ObjectListing objectListing = obsClient.listObjects(listObjectsRequest);
List<ObsObject> objects = objectListing.getObjects();
for (ObsObject object : objects) {
String fileName = object.getObjectKey();
ObjectMetadata metadata = object.getMetadata();
FileItem fileItem = new FileItem();
fileItem.setName(fileName.substring(path.length()));
fileItem.setSize(metadata.getContentLength());
fileItem.setTime(metadata.getLastModified());
fileItem.setType(FileTypeEnum.FILE);
fileItemList.add(fileItem);
}
for (String commonPrefix : objectListing.getCommonPrefixes()) {
FileItem fileItem = new FileItem();
fileItem.setName(commonPrefix.substring(0, commonPrefix.length() - 1));
fileItem.setType(FileTypeEnum.FOLDER);
fileItemList.add(fileItem);
}
return fileItemList;
}
@Override
public String getDownloadUrl(String path) throws Exception {
path = StringUtils.removeFirstSeparator(path);
path = URLDecoder.decode(path, "utf8");
TemporarySignatureRequest req = new TemporarySignatureRequest(HttpMethodEnum.GET, timeout);
req.setBucketName(bucketName);
req.setObjectKey(path);
TemporarySignatureResponse res = obsClient.createTemporarySignature(req);
URL url = new URL(res.getSignedUrl());
return URLUtil.complateUrl(domain, url.getFile());
}
}

View File

@@ -0,0 +1,60 @@
package im.zhaojun.local.controller;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.util.StringUtils;
import im.zhaojun.local.service.LocalService;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.util.Date;
@Controller
public class LocalController {
@Resource
private LocalService localService;
@GetMapping("/local-download")
@ResponseBody
public ResponseEntity<FileSystemResource> downAttachment(String fileName) throws IOException {
return export(new File(StringUtils.concatDomainAndPath(localService.getFilePath(), URLUtil.decode(fileName))));
}
private ResponseEntity<FileSystemResource> export(File file) throws IOException {
// 获取文件 MIME 类型
String fileMimeType = Files.probeContentType(file.toPath());
MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;
HttpHeaders headers = new HttpHeaders();
// 如果
if (fileMimeType == null || "".equals(fileMimeType)) {
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=" + file.getName());
} else {
mediaType = MediaType.parseMediaType(fileMimeType);
}
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.add("Last-Modified", new Date().toString());
headers.add("ETag", String.valueOf(System.currentTimeMillis()));
return ResponseEntity
.ok()
.headers(headers)
.contentLength(file.length())
.contentType(mediaType)
.body(new FileSystemResource(file));
}
}

View File

@@ -0,0 +1,99 @@
package im.zhaojun.local.service;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.ImageInfo;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class LocalService implements FileService {
private static final String FILE_PATH_KEY = "filePath";
@Resource
private StorageConfigService storageConfigService;
private String filePath;
@Override
public void initMethod() {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.LOCAL);
filePath = stringStorageConfigMap.get(FILE_PATH_KEY).getValue();
}
@Override
public List<FileItem> fileList(String path) throws Exception {
List<FileItem> fileItemList = new ArrayList<>();
String fullPath = StringUtils.concatDomainAndPath(filePath, path);
File file = new File(fullPath);
File[] files = file.listFiles();
if (files == null) {
return fileItemList;
}
for (File f : files) {
FileItem fileItem = new FileItem();
fileItem.setType(f.isDirectory() ? FileTypeEnum.FOLDER : FileTypeEnum.FILE);
fileItem.setTime(new Date(f.lastModified()));
fileItem.setSize(f.length());
fileItem.setName(f.getName());
fileItemList.add(fileItem);
}
return fileItemList;
}
@Override
public String getDownloadUrl(String path) throws Exception {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 网络协议
String networkProtocol = request.getScheme();
// 网络ip
String ip = request.getServerName();
// 端口号
int port = request.getServerPort();
// 项目发布名称
String webApp = request.getContextPath();
return StringUtils.concatDomainAndPath(networkProtocol + "://" + ip + ":" + port + webApp, "local-download?fileName=" + path);
}
@Override
public ImageInfo getImageInfo(String url) throws Exception {
String query = new URL(URLUtil.decode(url)).getQuery();
url = url.replace(query, URLUtil.encode(query));
InputStream inputStream = new URL(url).openStream();
BufferedImage sourceImg = ImageIO.read(inputStream);
return new ImageInfo(sourceImg.getWidth(), sourceImg.getHeight());
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}

View File

@@ -0,0 +1,112 @@
package im.zhaojun.qiniu.service;
import cn.hutool.core.util.URLUtil;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.storage.model.FileListing;
import com.qiniu.util.Auth;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class QiniuService implements FileService {
@Value("${zfile.cache.timeout}")
private Long timeout;
@Resource
private StorageConfigService storageConfigService;
private static final String BUCKET_NAME_KEY = "bucket-name";
private static final String ACCESS_KEY = "accessKey";
private static final String SECRET_KEY = "secretKey";
private static final String DOMAIN_KEY = "domain";
private BucketManager bucketManager;
private Auth auth;
private String bucketName;
private String domain;
private boolean isPrivate;
public void initMethod() throws QiniuException {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.QINIU);
String accessKey = stringStorageConfigMap.get(ACCESS_KEY).getValue();
String secretKey = stringStorageConfigMap.get(SECRET_KEY).getValue();
Configuration cfg = new Configuration(Zone.autoZone());
auth = Auth.create(accessKey, secretKey);
bucketManager = new BucketManager(auth, cfg);
bucketName = stringStorageConfigMap.get(BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(DOMAIN_KEY).getValue();
isPrivate = bucketManager.getBucketInfo(bucketName).getPrivate() == 1;
}
@Override
public List<FileItem> fileList(String path) throws Exception {
path = StringUtils.removeFirstSeparator(path);
List<FileItem> fileItemList = new ArrayList<>();
// 每次迭代的长度限制, 最大1000, 推荐值 1000
int limit = 1000;
// 指定目录分隔符, 列出所有公共前缀(模拟列出目录效果). 缺省值为空字符串
String delimiter = "/";
// 列举空间文件列表
FileListing fileListing = bucketManager.listFilesV2(bucketName, path, "", limit, delimiter);
for (FileInfo item : fileListing.items) {
String fileKey = item.key;
String fileName = fileKey.substring(path.length());
FileItem fileItem = new FileItem();
fileItem.setName(fileName);
fileItem.setSize(item.fsize);
fileItem.setTime(new Date(item.putTime / 1000));
fileItem.setType(FileTypeEnum.FILE);
fileItemList.add(fileItem);
}
String[] commonPrefixes = fileListing.commonPrefixes;
for (String commonPrefix : commonPrefixes) {
FileItem fileItem = new FileItem();
fileItem.setName(commonPrefix.substring(0, commonPrefix.length() - 1));
fileItem.setType(FileTypeEnum.FOLDER);
fileItemList.add(fileItem);
}
return fileItemList;
}
@Override
public String getDownloadUrl(String path) {
String url = URLUtil.complateUrl(domain, path);
if (isPrivate) {
url = auth.privateDownloadUrl(url, timeout);
}
return url;
}
}

View File

@@ -0,0 +1,103 @@
package im.zhaojun.tencent;
import cn.hutool.core.util.URLUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.COSObjectSummary;
import com.qcloud.cos.model.ListObjectsRequest;
import com.qcloud.cos.model.ObjectListing;
import com.qcloud.cos.region.Region;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class TencentService implements FileService {
@Resource
private StorageConfigService storageConfigService;
private static final String BUCKET_NAME_KEY = "bucket-name";
private static final String SECRET_ID_KEY = "secretId";
private static final String SECRET_KEY = "secretKey";
private static final String DOMAIN_KEY = "domain";
private static final String ENDPOINT_KEY = "endPoint";
@Value("${zfile.cache.timeout}")
private Long timeout;
private String bucketName;
private String domain;
private COSClient cosClient;
@Override
public void initMethod() {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.TENCENT);
String secretId = stringStorageConfigMap.get(SECRET_ID_KEY).getValue();
String secretKey = stringStorageConfigMap.get(SECRET_KEY).getValue();
String endPoint = stringStorageConfigMap.get(ENDPOINT_KEY).getValue();
bucketName = stringStorageConfigMap.get(BUCKET_NAME_KEY).getValue();
domain = stringStorageConfigMap.get(DOMAIN_KEY).getValue();
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
Region region = new Region("ap-shanghai");
ClientConfig clientConfig = new ClientConfig(region);
// clientConfig.setSignExpired();
cosClient = new COSClient(cred, clientConfig);
}
@Override
public List<FileItem> fileList(String path) {
path = StringUtils.removeFirstSeparator(path);
List<FileItem> fileItemList = new ArrayList<>();
ObjectListing objectListing = cosClient.listObjects(new ListObjectsRequest().withBucketName(bucketName).withDelimiter("/").withPrefix(path));
for (COSObjectSummary s : objectListing.getObjectSummaries()) {
FileItem fileItem = new FileItem();
fileItem.setName(s.getKey().substring(path.length()));
fileItem.setSize(s.getSize());
fileItem.setTime(s.getLastModified());
fileItem.setType(FileTypeEnum.FILE);
fileItemList.add(fileItem);
}
for (String commonPrefix : objectListing.getCommonPrefixes()) {
FileItem fileItem = new FileItem();
fileItem.setName(commonPrefix.substring(path.length(), commonPrefix.length() - 1));
fileItem.setType(FileTypeEnum.FOLDER);
fileItemList.add(fileItem);
}
return fileItemList;
}
@Override
public String getDownloadUrl(String path) {
Date expirationDate = new Date(new Date().getTime() + timeout * 1000);
URL url = cosClient.generatePresignedUrl(bucketName, path, expirationDate);
return URLUtil.complateUrl(domain, url.getFile());
}
}

View File

@@ -0,0 +1,76 @@
package im.zhaojun.upyun.service;
import cn.hutool.core.util.URLUtil;
import com.UpYun;
import com.upyun.UpException;
import im.zhaojun.common.enums.FileTypeEnum;
import im.zhaojun.common.enums.StorageTypeEnum;
import im.zhaojun.common.model.FileItem;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class UpYunService implements FileService {
@Resource
private StorageConfigService storageConfigService;
private static final String BUCKET_NAME_KEY = "bucket-name";
private static final String USERNAME_KEY = "username";
private static final String PASSWORD_KEY = "password";
private static final String DOMAIN_KEY = "domain";
private String domain;
private UpYun upYun;
public void initMethod() {
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByKey(StorageTypeEnum.UPYUN);
String bucketName = stringStorageConfigMap.get(BUCKET_NAME_KEY).getValue();
String username = stringStorageConfigMap.get(USERNAME_KEY).getValue();
String password = stringStorageConfigMap.get(PASSWORD_KEY).getValue();
domain = stringStorageConfigMap.get(DOMAIN_KEY).getValue();
upYun = new UpYun(bucketName, username, password);
}
public List<FileItem> fileList(String path) throws IOException, UpException {
ArrayList<FileItem> fileItems = new ArrayList<>();
List<UpYun.FolderItem> folderItems = upYun.readDir(path, null);
if (folderItems != null) {
for (UpYun.FolderItem folderItem : folderItems) {
FileItem fileItem = new FileItem();
fileItem.setName(folderItem.name);
fileItem.setSize(folderItem.size);
fileItem.setTime(folderItem.date);
if ("Folder".equals(folderItem.type)) {
fileItem.setType(FileTypeEnum.FOLDER);
} else if ("File".equals(folderItem.type)) {
fileItem.setType(FileTypeEnum.FILE);
}
fileItems.add(fileItem);
}
}
return fileItems;
}
@Override
public String getDownloadUrl(String path) {
return URLUtil.complateUrl(domain, path);
}
}

View File

@@ -0,0 +1,8 @@
{
"properties": [
{
"name": "zfile.cache.timeout",
"type": "java.lang.Long",
"description": "目录缓存过期时间 和 下载地址过期时间. 单位为秒."
}
] }

View File

@@ -0,0 +1,17 @@
# \u76EE\u5F55\u7F13\u5B58\u8FC7\u671F\u65F6\u95F4 \u548C \u4E0B\u8F7D\u5730\u5740\u8FC7\u671F\u65F6\u95F4. \u5355\u4F4D\u4E3A\u79D2.
zfile.cache.timeout = 300
spring.cache.type=caffeine
logging.level.im.zhaojun = debug
logging.level.com.obs.services = error
logging.level.org.springframework.cache = debug
spring.jackson.date-format=yyyy-MM-dd HH:mm
spring.jackson.time-zone=GMT+8
spring.datasource.url=jdbc:sqlite:E:/sqlite/1.db
spring.datasource.driver-class-name=org.sqlite.JDBC
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.mapper-locations=classpath:mapper/*.xml

View File

@@ -0,0 +1,16 @@
{
"disableSidebar": false,
"hidden": ["^\\.", "^_h5ai"],
"modes": "details",
"info": {
"enabled": true,
"show": true,
"qrCode": true,
"qrFill": "#999",
"qrBack": "#fff"
},
"search": {
"enabled": true,
"ignoreCase": true
}
}

View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="im.zhaojun.common.mapper.StorageConfigMapper">
<resultMap id="BaseResultMap" type="im.zhaojun.common.model.StorageConfig">
<!--@mbg.generated-->
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="type" jdbcType="LONGVARCHAR" property="type" javaType="im.zhaojun.common.enums.StorageTypeEnum"
typeHandler="im.zhaojun.common.enums.StorageTypeEnumTypeHandler"/>
<result column="key" jdbcType="LONGVARCHAR" property="key"/>
<result column="title" jdbcType="LONGVARCHAR" property="title"/>
<result column="value" jdbcType="LONGVARCHAR" property="value"/>
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, "type", "key", title, "value"
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--@mbg.generated-->
select
<include refid="Base_Column_List"/>
from storage_config
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--@mbg.generated-->
delete from storage_config
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="im.zhaojun.common.model.StorageConfig"
useGeneratedKeys="true">
<!--@mbg.generated-->
insert into storage_config ("key", "type", title,
"value")
values (#{key,jdbcType=LONGVARCHAR}, #{type,jdbcType=LONGVARCHAR}, #{title,jdbcType=LONGVARCHAR},
#{value,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="im.zhaojun.common.model.StorageConfig"
useGeneratedKeys="true">
<!--@mbg.generated-->
insert into storage_config
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="key != null">
"key",
</if>
<if test="type != null">
"type",
</if>
<if test="title != null">
title,
</if>
<if test="value != null">
"value",
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="key != null">
#{key,jdbcType=LONGVARCHAR},
</if>
<if test="type != null">
#{type,jdbcType=LONGVARCHAR},
</if>
<if test="title != null">
#{title,jdbcType=LONGVARCHAR},
</if>
<if test="value != null">
#{value,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="im.zhaojun.common.model.StorageConfig">
<!--@mbg.generated-->
update storage_config
<set>
<if test="key != null">
"key" = #{key,jdbcType=LONGVARCHAR},
</if>
<if test="type != null">
"type" = #{type,jdbcType=LONGVARCHAR},
</if>
<if test="title != null">
title = #{title,jdbcType=LONGVARCHAR},
</if>
<if test="value != null">
"value" = #{value,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="im.zhaojun.common.model.StorageConfig">
<!--@mbg.generated-->
update storage_config
set "key" = #{key,jdbcType=LONGVARCHAR},
"type" = #{type,jdbcType=LONGVARCHAR},
title = #{title,jdbcType=LONGVARCHAR},
"value" = #{value,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectStorageConfigByType" parameterType="im.zhaojun.common.enums.StorageTypeEnum" resultMap="BaseResultMap">
select * from storage_config where `type` = #{type, typeHandler=im.zhaojun.common.enums.StorageTypeEnumTypeHandler}
</select>
</mapper>

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="im.zhaojun.common.mapper.SystemConfigMapper">
<resultMap id="BaseResultMap" type="im.zhaojun.common.model.SystemConfig">
<!--@mbg.generated-->
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="site_name" jdbcType="LONGVARCHAR" property="siteName"/>
<result column="mode" jdbcType="LONGVARCHAR" property="mode" javaType="im.zhaojun.common.enums.ViewModeEnum"
typeHandler="im.zhaojun.common.enums.ViewModeEnumTypeHandler"/>
<result column="sidebarEnable" jdbcType="NUMERIC" property="sidebarEnable"/>
<result column="infoEnable" jdbcType="NUMERIC" property="infoEnable"/>
<result column="searchEnable" jdbcType="NUMERIC" property="searchEnable"/>
<result column="searchIgnoreCase" jdbcType="NUMERIC" property="searchIgnoreCase"/>
<result column="storageStrategy" jdbcType="LONGVARCHAR" property="storageStrategy" javaType="im.zhaojun.common.enums.StorageTypeEnum" typeHandler="im.zhaojun.common.enums.StorageTypeEnumTypeHandler"/>
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, site_name, "mode", sidebarEnable, infoEnable, searchEnable, searchIgnoreCase, storageStrategy
</sql>
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="im.zhaojun.common.model.SystemConfig"
useGeneratedKeys="true">
<!--@mbg.generated-->
insert into system_config (site_name, "mode", sidebarEnable,
infoEnable, searchEnable, searchIgnoreCase, storage_strategy, timeout
)
values (#{siteName,jdbcType=LONGVARCHAR}, #{mode,jdbcType=NUMERIC}, #{sidebarenable,jdbcType=NUMERIC},
#{infoenable,jdbcType=NUMERIC}, #{searchenable,jdbcType=NUMERIC}, #{searchignorecase,jdbcType=NUMERIC},
#{storageStrategy,jdbcType=LONGVARCHAR}
)
</insert>
<update id="updateByPrimaryKeySelective" parameterType="im.zhaojun.common.model.SystemConfig">
<!--@mbg.generated-->
update system_config
<set>
<if test="siteName != null">
site_name = #{siteName,jdbcType=LONGVARCHAR},
</if>
<if test="mode != null">
"mode" = #{mode,jdbcType=NUMERIC},
</if>
<if test="sidebarenable != null">
sidebarEnable = #{sidebarEnable,jdbcType=NUMERIC},
</if>
<if test="infoenable != null">
infoEnable = #{infoEnable,jdbcType=NUMERIC},
</if>
<if test="searchenable != null">
searchEnable = #{searchEnable,jdbcType=NUMERIC},
</if>
<if test="searchignorecase != null">
searchIgnoreCase = #{searchIgnoreCase,jdbcType=NUMERIC},
</if>
<if test="storage_strategy != null">
storageStrategy = #{storageStrategy,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="im.zhaojun.common.model.SystemConfig">
<!--@mbg.generated-->
update system_config
set site_name = #{siteName,jdbcType=LONGVARCHAR},
"mode" = #{mode,jdbcType=NUMERIC},
sidebarEnable = #{sidebarEnable,jdbcType=NUMERIC},
infoEnable = #{infoEnable,jdbcType=NUMERIC},
searchEnable = #{searchEnable,jdbcType=NUMERIC},
searchIgnoreCase = #{searchIgnoreCase,jdbcType=NUMERIC},
storageStrategy = #{storageStrategy,jdbcType=NUMERIC}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectFirstConfig" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from system_config limit 1
</select>
</mapper>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.zeroturnaround.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">
<classpath>
<dir name="E:/idea_work/zfile/target/classes">
</dir>
</classpath>
</application>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,142 @@
<p align="center">
<img src="https://ws4.sinaimg.cn/large/006tKfTcgy1fhu01y9uy7j305k04s3yc.jpg" alt="ADPlayer" width="100">
</p>
<h1 align="center">DPlayer</h1>
> 🍭 Wow, such a lovely HTML5 danmaku video player
[![npm](https://img.shields.io/npm/v/dplayer.svg?style=flat-square)](https://www.npmjs.com/package/dplayer)
[![npm](https://img.shields.io/npm/l/dplayer.svg?style=flat-square)](https://github.com/MoePlayer/DPlayer/blob/master/LICENSE)
[![npm](https://img.shields.io/npm/dt/dplayer.svg?style=flat-square)](https://www.npmjs.com/package/dplayer)
[![size](https://badge-size.herokuapp.com/MoePlayer/DPlayer/master/dist/DPlayer.min.js?compression=gzip&style=flat-square)](https://github.com/MoePlayer/DPlayer/tree/master/dist)
[![Travis](https://img.shields.io/travis/MoePlayer/DPlayer.svg?style=flat-square)](https://travis-ci.org/MoePlayer/DPlayer)
[![devDependency Status](https://img.shields.io/david/dev/MoePlayer/dplayer.svg?style=flat-square)](https://david-dm.org/MoePlayer/DPlayer#info=devDependencies)
[![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?style=flat-square)](https://github.com/MoePlayer/DPlayer#donate)
## Introduction
![image](http://i.imgur.com/207ch36.jpg)
DPlayer is a lovely HTML5 danmaku video player to help people build video and danmaku easily.
**DPlayer supports:**
- Streaming formats
- [HLS](https://github.com/video-dev/hls.js)
- [FLV](https://github.com/Bilibili/flv.js)
- [MPEG DASH](https://github.com/Dash-Industry-Forum/dash.js)
- [WebTorrent](https://github.com/webtorrent/webtorrent)
- Any other custom streaming formats
- Media formats
- MP4 H.264
- WebM
- Ogg Theora Vorbis
- Features
- Danmaku
- Screenshot
- Hotkeys
- Quality switching
- Thumbnails
- Subtitle
Using DPlayer on your project? [Let me know!](https://github.com/DIYgod/DPlayer/issues/31)
**[Docs](http://dplayer.js.org)**
**[中文文档](http://dplayer.js.org/#/zh-Hans/)**
## Join the Discussion
- [Telegram Group](https://t.me/adplayer)
## Related Projects
Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
### Tooling
- [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
### Danmaku api
- [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
- [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
- [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
- [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
### Plugins
- [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
- [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
- [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
- [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
- [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
- [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
- [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
- [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
### Other
- [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
- [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
## Who use DPlayer?
- [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
- [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
- [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站D站
- [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
- [浙江大学CC98论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛中国各大学中较活跃的BBS之一
- [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
- [otomads](https://otomads.com/): 专注于音MAD的视频弹幕网站
- [Cloudreve](https://github.com/HFO4/Cloudreve): 基于ThinkPHP构建的网盘系统
- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
## Current Premium Sponsors
### Special Sponsors
<a href="https://pear.hk/" target="_blank">
<img width="222px" src="https://i.imgur.com/5qQYmfc.png">
</a>
<a href="https://console.upyun.com/register/?invite=BkLZ2Xqob" target="_blank">
<img width="222px" src="https://imgur.com/apG1uKf.png">
</a>
### OpenCollective backers
![](https://opencollective.com/DPlayer/backers.svg?width=890)
## Contributors
This project exists thanks to all the people who contribute.
<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>
## Donate
DPlayer is an MIT licensed open source project and completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing.
## One-time Donations
We accept donations through these channels:
- [Paypal](https://www.paypal.me/DIYgod)
- [WeChat Pay](https://i.imgur.com/aq6PtWa.png)
- [Alipay](https://i.imgur.com/wv1Pj2k.png)
- Bitcoin: 13CwQLHzPYm2tewNMSJBeArbbRM5NSmCD1
## Recurring Pledges
Recurring pledges come with exclusive perks, e.g. having your name or your company logo listed in the DPlayer GitHub repository and this website.
- Become a backer or sponsor via [OpenCollective](https://opencollective.com/dplayer)
- E-mail us: i#html.love
## Author
**DPlayer** © [DIYgod](https://github.com/DIYgod), Released under the [MIT](./LICENSE) License.<br>
Authored and maintained by DIYgod with help from contributors ([list](https://github.com/DIYgod/DPlayer/contributors)).
> [Blog](https://diygod.me) · GitHub [@DIYgod](https://github.com/DIYgod) · Twitter [@DIYgod](https://twitter.com/DIYgod) · Telegram Channel [@awesomeDIYgod](https://t.me/awesomeDIYgod)

View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>
<body>
<link rel="stylesheet" href="DPlayer.min.css">
<div id="dplayer"></div>
<script src="DPlayer.min.js"></script>
<script>
const dp = new DPlayer({
container: document.getElementById('dplayer'),
video: {
url: decodeURIComponent(window.location.hash.substring(1))
},
autoplay: true
});
</script>
</body>
</html>

View File

@@ -0,0 +1,5 @@
{
"SITE_NAME": "H5AI",
"SHOW_STATS": true,
"FOOTER": "<h1>Footer</h1>"
}

View File

@@ -0,0 +1,309 @@
@charset "UTF-8";
/*!
* jQuery contextMenu - Plugin for simple contextMenu handling
*
* Version: v2.8.0
*
* Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF)
* Web: http://swisnl.github.io/jQuery-contextMenu/
*
* Copyright (c) 2011-2019 SWIS BV and contributors
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
*
* Date: 2019-01-16T15:45:48.418Z
*/
@-webkit-keyframes cm-spin {
0% {
-webkit-transform: translateY(-50%) rotate(0deg);
transform: translateY(-50%) rotate(0deg);
}
100% {
-webkit-transform: translateY(-50%) rotate(359deg);
transform: translateY(-50%) rotate(359deg);
}
}
@-o-keyframes cm-spin {
0% {
-webkit-transform: translateY(-50%) rotate(0deg);
-o-transform: translateY(-50%) rotate(0deg);
transform: translateY(-50%) rotate(0deg);
}
100% {
-webkit-transform: translateY(-50%) rotate(359deg);
-o-transform: translateY(-50%) rotate(359deg);
transform: translateY(-50%) rotate(359deg);
}
}
@keyframes cm-spin {
0% {
-webkit-transform: translateY(-50%) rotate(0deg);
-o-transform: translateY(-50%) rotate(0deg);
transform: translateY(-50%) rotate(0deg);
}
100% {
-webkit-transform: translateY(-50%) rotate(359deg);
-o-transform: translateY(-50%) rotate(359deg);
transform: translateY(-50%) rotate(359deg);
}
}
@font-face {
font-family: "context-menu-icons";
font-style: normal;
font-weight: normal;
src: url("font/context-menu-icons.eot?2lkho");
src: url("font/context-menu-icons.eot?2lkho#iefix") format("embedded-opentype"), url("font/context-menu-icons.woff2?2lkho") format("woff2"), url("font/context-menu-icons.woff?2lkho") format("woff"), url("font/context-menu-icons.ttf?2lkho") format("truetype");
}
.context-menu-icon-add:before {
content: "\EA01";
}
.context-menu-icon-copy:before {
content: "\EA02";
}
.context-menu-icon-cut:before {
content: "\EA03";
}
.context-menu-icon-delete:before {
content: "\EA04";
}
.context-menu-icon-edit:before {
content: "\EA05";
}
.context-menu-icon-loading:before {
content: "\EA06";
}
.context-menu-icon-paste:before {
content: "\EA07";
}
.context-menu-icon-quit:before {
content: "\EA08";
}
.context-menu-icon::before {
position: absolute;
top: 50%;
left: 0;
width: 2em;
font-family: "context-menu-icons";
font-size: 1em;
font-style: normal;
font-weight: normal;
line-height: 1;
color: #2980b9;
text-align: center;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.context-menu-icon.context-menu-hover:before {
color: #fff;
}
.context-menu-icon.context-menu-disabled::before {
color: #bbb;
}
.context-menu-icon.context-menu-icon-loading:before {
-webkit-animation: cm-spin 2s infinite;
-o-animation: cm-spin 2s infinite;
animation: cm-spin 2s infinite;
}
.context-menu-icon.context-menu-icon--fa {
display: list-item;
font-family: inherit;
line-height: inherit;
}
.context-menu-icon.context-menu-icon--fa::before {
position: absolute;
top: 50%;
left: 0;
width: 2em;
font-family: FontAwesome;
font-size: 1em;
font-style: normal;
font-weight: normal;
line-height: 1;
color: #2980b9;
text-align: center;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.context-menu-icon.context-menu-icon--fa.context-menu-hover:before {
color: #fff;
}
.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before {
color: #bbb;
}
.context-menu-icon.context-menu-icon--fa5 {
display: list-item;
font-family: inherit;
line-height: inherit;
}
.context-menu-icon.context-menu-icon--fa5 i, .context-menu-icon.context-menu-icon--fa5 svg {
position: absolute;
top: .3em;
left: .5em;
color: #2980b9;
}
.context-menu-icon.context-menu-icon--fa5.context-menu-hover > i, .context-menu-icon.context-menu-icon--fa5.context-menu-hover > svg {
color: #fff;
}
.context-menu-icon.context-menu-icon--fa5.context-menu-disabled i, .context-menu-icon.context-menu-icon--fa5.context-menu-disabled svg {
color: #bbb;
}
.context-menu-list {
position: absolute;
display: inline-block;
min-width: 13em;
max-width: 26em;
padding: .25em 0;
margin: .3em;
font-family: inherit;
font-size: inherit;
list-style-type: none;
background: #fff;
border: 1px solid #bebebe;
border-radius: .2em;
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
}
.context-menu-item {
position: relative;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
padding: .2em 2em;
color: #2f2f2f;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: #fff;
}
.context-menu-separator {
padding: 0;
margin: .35em 0;
border-bottom: 1px solid #e6e6e6;
}
.context-menu-item > label > input,
.context-menu-item > label > textarea {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.context-menu-item.context-menu-hover {
color: #fff;
cursor: pointer;
background-color: #2980b9;
}
.context-menu-item.context-menu-disabled {
color: #bbb;
cursor: default;
background-color: #fff;
}
.context-menu-input.context-menu-hover {
color: #2f2f2f;
cursor: default;
}
.context-menu-submenu:after {
position: absolute;
top: 50%;
right: .5em;
z-index: 1;
width: 0;
height: 0;
content: '';
border-color: transparent transparent transparent #2f2f2f;
border-style: solid;
border-width: .25em 0 .25em .25em;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}
/**
* Inputs
*/
.context-menu-item.context-menu-input {
padding: .3em .6em;
}
/* vertically align inside labels */
.context-menu-input > label > * {
vertical-align: top;
}
/* position checkboxes and radios as icons */
.context-menu-input > label > input[type="checkbox"],
.context-menu-input > label > input[type="radio"] {
position: relative;
top: .12em;
margin-right: .4em;
}
.context-menu-input > label {
margin: 0;
}
.context-menu-input > label,
.context-menu-input > label > input[type="text"],
.context-menu-input > label > textarea,
.context-menu-input > label > select {
display: block;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.context-menu-input > label > textarea {
height: 7em;
}
.context-menu-item > .context-menu-list {
top: .3em;
/* re-positioned by js */
right: -.3em;
display: none;
}
.context-menu-item.context-menu-visible > .context-menu-list {
display: block;
}
.context-menu-accesskey {
text-decoration: underline;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,513 @@
/*! jQuery UI - v1.12.1 - 2016-09-16
* http://jqueryui.com
* Includes: position.js
* Copyright jQuery Foundation and other contributors; Licensed MIT */
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define([ "jquery" ], factory );
} else {
// Browser globals
factory( jQuery );
}
}(function( $ ) {
$.ui = $.ui || {};
var version = $.ui.version = "1.12.1";
/*!
* jQuery UI Position 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/position/
*/
//>>label: Position
//>>group: Core
//>>description: Positions elements relative to other elements.
//>>docs: http://api.jqueryui.com/position/
//>>demos: http://jqueryui.com/position/
( function() {
var cachedScrollbarWidth,
max = Math.max,
abs = Math.abs,
rhorizontal = /left|center|right/,
rvertical = /top|center|bottom/,
roffset = /[\+\-]\d+(\.[\d]+)?%?/,
rposition = /^\w+/,
rpercent = /%$/,
_position = $.fn.position;
function getOffsets( offsets, width, height ) {
return [
parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
];
}
function parseCss( element, property ) {
return parseInt( $.css( element, property ), 10 ) || 0;
}
function getDimensions( elem ) {
var raw = elem[ 0 ];
if ( raw.nodeType === 9 ) {
return {
width: elem.width(),
height: elem.height(),
offset: { top: 0, left: 0 }
};
}
if ( $.isWindow( raw ) ) {
return {
width: elem.width(),
height: elem.height(),
offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
};
}
if ( raw.preventDefault ) {
return {
width: 0,
height: 0,
offset: { top: raw.pageY, left: raw.pageX }
};
}
return {
width: elem.outerWidth(),
height: elem.outerHeight(),
offset: elem.offset()
};
}
$.position = {
scrollbarWidth: function() {
if ( cachedScrollbarWidth !== undefined ) {
return cachedScrollbarWidth;
}
var w1, w2,
div = $( "<div " +
"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
"<div style='height:100px;width:auto;'></div></div>" ),
innerDiv = div.children()[ 0 ];
$( "body" ).append( div );
w1 = innerDiv.offsetWidth;
div.css( "overflow", "scroll" );
w2 = innerDiv.offsetWidth;
if ( w1 === w2 ) {
w2 = div[ 0 ].clientWidth;
}
div.remove();
return ( cachedScrollbarWidth = w1 - w2 );
},
getScrollInfo: function( within ) {
var overflowX = within.isWindow || within.isDocument ? "" :
within.element.css( "overflow-x" ),
overflowY = within.isWindow || within.isDocument ? "" :
within.element.css( "overflow-y" ),
hasOverflowX = overflowX === "scroll" ||
( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
hasOverflowY = overflowY === "scroll" ||
( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
return {
width: hasOverflowY ? $.position.scrollbarWidth() : 0,
height: hasOverflowX ? $.position.scrollbarWidth() : 0
};
},
getWithinInfo: function( element ) {
var withinElement = $( element || window ),
isWindow = $.isWindow( withinElement[ 0 ] ),
isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
hasOffset = !isWindow && !isDocument;
return {
element: withinElement,
isWindow: isWindow,
isDocument: isDocument,
offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
scrollLeft: withinElement.scrollLeft(),
scrollTop: withinElement.scrollTop(),
width: withinElement.outerWidth(),
height: withinElement.outerHeight()
};
}
};
$.fn.position = function( options ) {
if ( !options || !options.of ) {
return _position.apply( this, arguments );
}
// Make a copy, we don't want to modify arguments
options = $.extend( {}, options );
var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
target = $( options.of ),
within = $.position.getWithinInfo( options.within ),
scrollInfo = $.position.getScrollInfo( within ),
collision = ( options.collision || "flip" ).split( " " ),
offsets = {};
dimensions = getDimensions( target );
if ( target[ 0 ].preventDefault ) {
// Force left top to allow flipping
options.at = "left top";
}
targetWidth = dimensions.width;
targetHeight = dimensions.height;
targetOffset = dimensions.offset;
// Clone to reuse original targetOffset later
basePosition = $.extend( {}, targetOffset );
// Force my and at to have valid horizontal and vertical positions
// if a value is missing or invalid, it will be converted to center
$.each( [ "my", "at" ], function() {
var pos = ( options[ this ] || "" ).split( " " ),
horizontalOffset,
verticalOffset;
if ( pos.length === 1 ) {
pos = rhorizontal.test( pos[ 0 ] ) ?
pos.concat( [ "center" ] ) :
rvertical.test( pos[ 0 ] ) ?
[ "center" ].concat( pos ) :
[ "center", "center" ];
}
pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
// Calculate offsets
horizontalOffset = roffset.exec( pos[ 0 ] );
verticalOffset = roffset.exec( pos[ 1 ] );
offsets[ this ] = [
horizontalOffset ? horizontalOffset[ 0 ] : 0,
verticalOffset ? verticalOffset[ 0 ] : 0
];
// Reduce to just the positions without the offsets
options[ this ] = [
rposition.exec( pos[ 0 ] )[ 0 ],
rposition.exec( pos[ 1 ] )[ 0 ]
];
} );
// Normalize collision option
if ( collision.length === 1 ) {
collision[ 1 ] = collision[ 0 ];
}
if ( options.at[ 0 ] === "right" ) {
basePosition.left += targetWidth;
} else if ( options.at[ 0 ] === "center" ) {
basePosition.left += targetWidth / 2;
}
if ( options.at[ 1 ] === "bottom" ) {
basePosition.top += targetHeight;
} else if ( options.at[ 1 ] === "center" ) {
basePosition.top += targetHeight / 2;
}
atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
basePosition.left += atOffset[ 0 ];
basePosition.top += atOffset[ 1 ];
return this.each( function() {
var collisionPosition, using,
elem = $( this ),
elemWidth = elem.outerWidth(),
elemHeight = elem.outerHeight(),
marginLeft = parseCss( this, "marginLeft" ),
marginTop = parseCss( this, "marginTop" ),
collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
scrollInfo.width,
collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
scrollInfo.height,
position = $.extend( {}, basePosition ),
myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
if ( options.my[ 0 ] === "right" ) {
position.left -= elemWidth;
} else if ( options.my[ 0 ] === "center" ) {
position.left -= elemWidth / 2;
}
if ( options.my[ 1 ] === "bottom" ) {
position.top -= elemHeight;
} else if ( options.my[ 1 ] === "center" ) {
position.top -= elemHeight / 2;
}
position.left += myOffset[ 0 ];
position.top += myOffset[ 1 ];
collisionPosition = {
marginLeft: marginLeft,
marginTop: marginTop
};
$.each( [ "left", "top" ], function( i, dir ) {
if ( $.ui.position[ collision[ i ] ] ) {
$.ui.position[ collision[ i ] ][ dir ]( position, {
targetWidth: targetWidth,
targetHeight: targetHeight,
elemWidth: elemWidth,
elemHeight: elemHeight,
collisionPosition: collisionPosition,
collisionWidth: collisionWidth,
collisionHeight: collisionHeight,
offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
my: options.my,
at: options.at,
within: within,
elem: elem
} );
}
} );
if ( options.using ) {
// Adds feedback as second argument to using callback, if present
using = function( props ) {
var left = targetOffset.left - position.left,
right = left + targetWidth - elemWidth,
top = targetOffset.top - position.top,
bottom = top + targetHeight - elemHeight,
feedback = {
target: {
element: target,
left: targetOffset.left,
top: targetOffset.top,
width: targetWidth,
height: targetHeight
},
element: {
element: elem,
left: position.left,
top: position.top,
width: elemWidth,
height: elemHeight
},
horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
};
if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
feedback.horizontal = "center";
}
if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
feedback.vertical = "middle";
}
if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
feedback.important = "horizontal";
} else {
feedback.important = "vertical";
}
options.using.call( this, props, feedback );
};
}
elem.offset( $.extend( position, { using: using } ) );
} );
};
$.ui.position = {
fit: {
left: function( position, data ) {
var within = data.within,
withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
outerWidth = within.width,
collisionPosLeft = position.left - data.collisionPosition.marginLeft,
overLeft = withinOffset - collisionPosLeft,
overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
newOverRight;
// Element is wider than within
if ( data.collisionWidth > outerWidth ) {
// Element is initially over the left side of within
if ( overLeft > 0 && overRight <= 0 ) {
newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
withinOffset;
position.left += overLeft - newOverRight;
// Element is initially over right side of within
} else if ( overRight > 0 && overLeft <= 0 ) {
position.left = withinOffset;
// Element is initially over both left and right sides of within
} else {
if ( overLeft > overRight ) {
position.left = withinOffset + outerWidth - data.collisionWidth;
} else {
position.left = withinOffset;
}
}
// Too far left -> align with left edge
} else if ( overLeft > 0 ) {
position.left += overLeft;
// Too far right -> align with right edge
} else if ( overRight > 0 ) {
position.left -= overRight;
// Adjust based on position and margin
} else {
position.left = max( position.left - collisionPosLeft, position.left );
}
},
top: function( position, data ) {
var within = data.within,
withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
outerHeight = data.within.height,
collisionPosTop = position.top - data.collisionPosition.marginTop,
overTop = withinOffset - collisionPosTop,
overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
newOverBottom;
// Element is taller than within
if ( data.collisionHeight > outerHeight ) {
// Element is initially over the top of within
if ( overTop > 0 && overBottom <= 0 ) {
newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
withinOffset;
position.top += overTop - newOverBottom;
// Element is initially over bottom of within
} else if ( overBottom > 0 && overTop <= 0 ) {
position.top = withinOffset;
// Element is initially over both top and bottom of within
} else {
if ( overTop > overBottom ) {
position.top = withinOffset + outerHeight - data.collisionHeight;
} else {
position.top = withinOffset;
}
}
// Too far up -> align with top
} else if ( overTop > 0 ) {
position.top += overTop;
// Too far down -> align with bottom edge
} else if ( overBottom > 0 ) {
position.top -= overBottom;
// Adjust based on position and margin
} else {
position.top = max( position.top - collisionPosTop, position.top );
}
}
},
flip: {
left: function( position, data ) {
var within = data.within,
withinOffset = within.offset.left + within.scrollLeft,
outerWidth = within.width,
offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
collisionPosLeft = position.left - data.collisionPosition.marginLeft,
overLeft = collisionPosLeft - offsetLeft,
overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
myOffset = data.my[ 0 ] === "left" ?
-data.elemWidth :
data.my[ 0 ] === "right" ?
data.elemWidth :
0,
atOffset = data.at[ 0 ] === "left" ?
data.targetWidth :
data.at[ 0 ] === "right" ?
-data.targetWidth :
0,
offset = -2 * data.offset[ 0 ],
newOverRight,
newOverLeft;
if ( overLeft < 0 ) {
newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
outerWidth - withinOffset;
if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
position.left += myOffset + atOffset + offset;
}
} else if ( overRight > 0 ) {
newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
atOffset + offset - offsetLeft;
if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
position.left += myOffset + atOffset + offset;
}
}
},
top: function( position, data ) {
var within = data.within,
withinOffset = within.offset.top + within.scrollTop,
outerHeight = within.height,
offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
collisionPosTop = position.top - data.collisionPosition.marginTop,
overTop = collisionPosTop - offsetTop,
overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
top = data.my[ 1 ] === "top",
myOffset = top ?
-data.elemHeight :
data.my[ 1 ] === "bottom" ?
data.elemHeight :
0,
atOffset = data.at[ 1 ] === "top" ?
data.targetHeight :
data.at[ 1 ] === "bottom" ?
-data.targetHeight :
0,
offset = -2 * data.offset[ 1 ],
newOverTop,
newOverBottom;
if ( overTop < 0 ) {
newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
outerHeight - withinOffset;
if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
position.top += myOffset + atOffset + offset;
}
} else if ( overBottom > 0 ) {
newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
offset - offsetTop;
if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
position.top += myOffset + atOffset + offset;
}
}
}
},
flipfit: {
left: function() {
$.ui.position.flip.left.apply( this, arguments );
$.ui.position.fit.left.apply( this, arguments );
},
top: function() {
$.ui.position.flip.top.apply( this, arguments );
$.ui.position.fit.top.apply( this, arguments );
}
}
};
} )();
var position = $.ui.position;
}));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,72 @@
# h5ai
[![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github]
A modern HTTP web server index for Apache httpd, lighttpd, nginx and Cherokee.
## Important
* Do **not** install any files from the `src` folder, they need to be
preprocessed to work correctly!
* Find a preprocessed package and detailed install instructions on the
[project page][web].
* For bug reports and feature requests please use [issues][github-issues].
## Build
There are installation ready packages for the latest [releases][release] and
[dev builds][develop]. But to build **h5ai** yourself either `git clone` or
download the repository. From within the root folder run the following
commands to find a fresh zipball in folder `build` (tested on linux only,
requires [`node 6.0+`][node] to be installed).
~~~sh
> npm install
> npm run build
~~~
## License
The MIT License (MIT)
Copyright (c) 2016 Lars Jung (https://larsjung.de)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## References
**h5ai** profits from other projects, all of them licensed under the MIT license
too. Exceptions are some [Material Design icons][material-design-icons] (CC BY 4.0).
[web]: https://larsjung.de/h5ai/
[github]: https://github.com/lrsjng/h5ai
[github-issues]: https://github.com/lrsjng/h5ai/issues
[release]: https://release.larsjung.de/h5ai/
[develop]: https://release.larsjung.de/h5ai/develop/
[node]: https://nodejs.org
[material-design-icons]: https://github.com/google/material-design-icons
[license-img]: https://img.shields.io/badge/license-MIT-a0a060.svg?style=flat-square
[web-img]: https://img.shields.io/badge/web-larsjung.de/h5ai-a0a060.svg?style=flat-square
[github-img]: https://img.shields.io/badge/github-lrsjng/h5ai-a0a060.svg?style=flat-square

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1529221522960" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="8871"
width="128" height="128"><defs><style type="text/css"></style></defs><path d="M213.992727 162.909091c0-64 42.612364-85.922909 94.673455-48.733091l462.266182 330.193455c52.061091 37.213091 52.061091 98.071273 0 135.284363L308.689455 909.824c-52.084364 37.189818-94.696727 15.266909-94.696728-48.733091V162.909091z" fill="#555555" p-id="8872"></path></svg>

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#555" d="M 1,2 1,14 15,14 15,4 9,4 7,2 z"/>
</svg>

After

Width:  |  Height:  |  Size: 148 B

View File

@@ -0,0 +1,34 @@
# editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[package.json]
indent_style = space
indent_size = 2
[.travis.yml]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[*.jade]
trim_trailing_whitespace = false
[*.svg]
insert_final_newline = false

View File

@@ -0,0 +1,9 @@
# Themes
This directory will contain any themes you add. At the moment there are only
icon themes supported. The folder structure is: `<theme-name>/<type>.<ext>`,
with `<ext>` one of `svg`, `png` or `jpg`.
To select a theme use the option `view > theme` in file `conf/options.json`.
You will find the previously included icon themes [here](https://github.com/lrsjng/h5ai-themes).

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#a4c639" d="M14.5 3.2C14.4 3.2 14.2 3.3 14.1 3.5L13.3 5C12.3 4.4 11.2 4 10 4 8.8 4 7.7 4.3 6.8 4.9L5.9 3.5C5.8 3.3 5.6 3.2 5.5 3.3 5.4 3.3 5.4 3.2 5.3 3.3L5.2 3.3C5 3.5 4.9 3.8 5.1 4L6 5.6C4.8 6.7 4 8.2 4 10L16 10C16 8.3 15.3 6.7 14.1 5.6L15 4C15.1 3.8 15 3.5 14.8 3.3L14.7 3.3C14.7 3.2 14.6 3.2 14.5 3.2zM7.3 7C7.8 7 8.2 7.4 8.2 7.9 8.2 8.4 7.8 8.8 7.3 8.8 6.8 8.8 6.4 8.4 6.4 7.9 6.4 7.4 6.8 7 7.3 7zM12.7 7C13.2 7 13.6 7.4 13.6 7.9 13.6 8.4 13.2 8.8 12.7 8.8 12.2 8.8 11.8 8.4 11.8 7.9 11.8 7.4 12.2 7 12.7 7zM4 10.5L4 16 16 16 16 10.5 4 10.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 656 B

View File

@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="-60 -75 20 20">
<g fill="#d70751" transform="matrix(0.06427071,0,0,0.06427071,-52.892053,-68.534728)">
<path d="m 64.525,62.053 c -4.125,0.058 0.78,2.125 6.165,2.954 1.488,-1.161 2.838,-2.336 4.04,-3.479 -3.354,0.821 -6.765,0.838 -10.205,0.525"/>
<path d="m 86.665,56.533 c 2.457,-3.389 4.246,-7.102 4.878,-10.939 -0.551,2.736 -2.035,5.099 -3.435,7.592 -7.711,4.854 -0.726,-2.883 -0.004,-5.824 -8.29,10.436 -1.138,6.257 -1.439,9.171"/>
<path d="m 94.839,35.268 c 0.497,-7.428 -1.462,-5.08 -2.121,-2.245 0.766,0.4 1.377,5.237 2.121,2.245"/>
<path d="m 48.883,-66.264 c 2.201,0.395 4.757,0.698 4.398,1.224 2.407,-0.528 2.954,-1.015 -4.398,-1.224"/>
<path d="m 53.281,-65.04 -1.556,0.32 1.448,-0.127 0.108,-0.193"/>
<path d="m 121.93,38.085 c 0.247,6.671 -1.95,9.907 -3.932,15.637 l -3.564,1.781 c -2.919,5.666 0.282,3.598 -1.807,8.105 -4.556,4.049 -13.823,12.67 -16.789,13.457 -2.163,-0.047 1.469,-2.554 1.943,-3.537 -6.097,4.188 -4.894,6.285 -14.217,8.83 L 83.291,81.751 C 60.29,92.569 28.344,71.129 28.765,41.875 28.519,43.732 28.067,43.268 27.557,44.019 26.371,28.967 34.509,13.849 48.232,7.676 61.659,1.03 77.395,3.758 87.012,12.72 81.73,5.8 71.217,-1.534 58.757,-0.848 46.549,-0.655 35.132,7.102 31.321,15.521 c -6.253,3.938 -6.979,15.177 -9.704,17.233 -3.665,26.943 6.896,38.583 24.762,52.275 2.812,1.896 0.792,2.184 1.173,3.627 C 41.616,85.877 36.18,81.68 31.711,76.542 c 2.372,3.473 4.931,6.847 8.239,9.499 -5.596,-1.897 -13.074,-13.563 -15.256,-14.038 9.647,17.274 39.142,30.295 54.587,23.836 -7.146,0.263 -16.226,0.146 -24.256,-2.822 -3.371,-1.734 -7.958,-5.331 -7.14,-6.003 21.079,7.875 42.854,5.965 61.09,-8.655 4.641,-3.614 9.709,-9.761 11.173,-9.846 -2.206,3.317 0.377,1.596 -1.318,4.523 4.625,-7.456 -2.008,-3.035 4.779,-12.877 l 2.507,3.453 c -0.931,-6.188 7.687,-13.704 6.813,-23.492 1.975,-2.994 2.206,3.22 0.107,10.107 2.912,-7.64 0.767,-8.867 1.516,-15.171 0.81,2.118 1.867,4.37 2.412,6.606 -1.895,-7.382 1.948,-12.433 2.898,-16.724 -0.937,-0.415 -2.928,3.264 -3.383,-5.457 0.065,-3.788 1.054,-1.985 1.435,-2.917 -0.744,-0.427 -2.694,-3.33 -3.88,-8.9 0.86,-1.308 2.3,3.393 3.47,3.586 -0.753,-4.429 -2.049,-7.805 -2.103,-11.202 -3.421,-7.149 -1.211,0.953 -3.985,-3.069 -3.641,-11.357 3.021,-2.637 3.47,-7.796 5.52,7.995 8.667,20.387 10.11,25.519 -1.103,-6.258 -2.883,-12.32 -5.058,-18.185 1.677,0.705 -2.699,-12.875 2.18,-3.882 -5.21,-19.172 -22.302,-37.087 -38.025,-45.493 1.924,1.76 4.354,3.971 3.481,4.317 -7.819,-4.656 -6.444,-5.018 -7.565,-6.985 -6.369,-2.591 -6.788,0.208 -11.007,0.004 -12.005,-6.368 -14.318,-5.69 -25.368,-9.681 l 0.502,2.349 c -7.953,-2.649 -9.265,1.005 -17.862,0.009 -0.523,-0.409 2.753,-1.479 5.452,-1.871 -7.69,1.015 -7.329,-1.515 -14.854,0.279 1.855,-1.301 3.815,-2.162 5.793,-3.269 -6.271,0.381 -14.971,3.649 -12.286,0.677 -10.235,4.569 -28.403,10.976 -38.597,20.535 l -0.321,-2.142 c -4.672,5.608 -20.371,16.748 -21.622,24.011 l -1.249,0.291 c -2.431,4.116 -4.004,8.781 -5.932,13.016 -3.18,5.417 -4.661,2.085 -4.208,2.934 -6.253,12.679 -9.359,23.332 -12.043,32.069 1.912,2.858 0.046,17.206 0.769,28.688 -3.141,56.709 39.8,111.77 86.737,124.48 6.88,2.459 17.11,2.364 25.813,2.618 -10.268,-2.937 -11.595,-1.556 -21.595,-5.044 -7.215,-3.398 -8.797,-7.277 -13.907,-11.711 l 2.022,3.573 c -10.021,-3.547 -5.829,-4.39 -13.982,-6.972 l 2.16,-2.82 C 11.175,156.251 5.82,151.022 4.355,148.126 l -3.553,0.14 c -4.27,-5.269 -6.545,-9.063 -6.379,-12.005 l -1.148,2.047 c -1.301,-2.235 -15.709,-19.759 -8.234,-15.679 -1.389,-1.271 -3.235,-2.067 -5.237,-5.703 l 1.522,-1.739 c -3.597,-4.627 -6.621,-10.562 -6.391,-12.536 1.919,2.592 3.25,3.075 4.568,3.52 -9.083,-22.539 -9.593,-1.242 -16.474,-22.942 l 1.456,-0.116 c -1.116,-1.682 -1.793,-3.506 -2.69,-5.298 l 0.633,-6.313 C -44.113,63.94 -39.401,39.351 -38.459,25.865 -37.804,20.38 -33,14.543 -29.345,5.388 l -2.227,-0.384 c 4.256,-7.423 24.301,-29.814 33.583,-28.662 4.499,-5.649 -0.892,-0.02 -1.772,-1.443 9.878,-10.223 12.984,-7.222 19.65,-9.061 7.19,-4.268 -6.17,1.664 -2.761,-1.628 12.427,-3.174 8.808,-7.216 25.021,-8.828 1.71,0.973 -3.969,1.503 -5.395,2.766 10.354,-5.066 32.769,-3.914 47.326,2.811 16.895,7.896 35.873,31.232 36.622,53.189 l 0.852,0.229 c -0.431,8.729 1.336,18.822 -1.727,28.094 l 2.1,-4.385"/>
<path d="m 19.5,67.715 -0.578,2.893 c 2.71,3.683 4.861,7.673 8.323,10.552 -2.49,-4.863 -4.341,-6.872 -7.745,-13.445"/>
<path d="m 25.909,67.464 c -1.435,-1.587 -2.284,-3.497 -3.235,-5.4 0.909,3.345 2.771,6.219 4.504,9.143 l -1.269,-3.743"/>
<path d="m 139.32,42.814 -0.605,1.52 c -1.111,7.892 -3.511,15.701 -7.189,22.941 4.06,-7.639 6.69,-15.995 7.79,-24.461"/>
<path d="m 49.698,-68.243 c 2.789,-1.022 6.855,-0.56 9.814,-1.233 -3.855,0.324 -7.693,0.517 -11.484,1.005 l 1.67,0.228"/>
<path d="m -48.219,-16.176 c 0.642,5.951 -4.477,8.26 1.134,4.337 3.007,-6.773 -1.175,-1.87 -1.134,-4.337"/>
<path d="m -54.812,11.362 c 1.292,-3.967 1.526,-6.349 2.02,-8.645 -3.571,4.566 -1.643,5.539 -2.02,8.645"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 13.913043 15.22257">
<g fill="#000" transform="matrix(0.01974442,0,0,0.01974442,0.59799609,3.692127)">
<path d="m 242.1304,26.136154 c 12.57375,-1.931991 25.25548,-3.344345 37.9671,-4.013656 2.25826,-0.538041 4.59412,-0.428086 6.90119,-0.510544 18.03637,-0.575318 36.09759,-0.549286 54.12636,0.262939 32.54014,2.301468 64.91549,7.707276 96.30586,16.718582 l -0.13292,0.17627 c -4.60202,6.223907 -9.21752,12.438019 -13.73035,18.725891 -1.35219,0.249481 -2.53581,-0.605759 -3.74014,-1.036484 -23.8157,-9.827469 -49.16701,-15.53215 -74.68315,-18.619186 -41.97006,-4.297928 -84.93817,-0.844666 -125.2014,12.070068 -29.64401,9.587738 -58.27112,24.371842 -80.37665,46.666519 -15.66559,16.020307 -27.69327,36.744737 -29.32584,59.451997 -1.51913,10.82149 1.07187,21.62427 3.36382,32.12558 L 14.185699,205.68005 C 13.945419,188.13843 18.523071,170.78329 25.80806,154.91394 40.297989,124.01501 65.424713,99.327652 93.421997,80.42572 112.35318,67.714981 132.81692,57.345383 154.07152,49.122925 182.38751,38.052567 212.05559,30.488739 242.1304,26.136154 z"/>
<path d="m 301.70334,148.63515 c 1.94578,-3.16858 5.37183,-5.69597 9.26865,-5.22687 4.4046,0.11267 7.79878,3.75244 8.71124,7.87158 l 310.75082,55.27789 -1.03752,5.20607 -310.68332,-54.48095 c -2.47844,4.31216 -8.22775,6.5392 -12.74457,3.9928 -3.13145,-1.36889 -4.19975,-4.71973 -5.61303,-7.53113 l -19.12972,-3.06511 0.87691,-5.38129 19.60054,3.33701 z"/>
<path d="m 13.649231,221.30466 c 18.262405,-0.12262 36.52626,-0.0226 54.789398,-0.051 0.01808,0.6767 0.05426,2.03008 0.07234,2.70677 13.269959,-2.88977 26.908417,-4.11874 40.480651,-3.36956 9.88256,0.90474 18.95615,5.13992 27.79413,9.3441 -9.96293,6.16172 -20.10092,12.09585 -29.82344,18.61522 -10.834169,-8.36657 -25.559114,-8.37398 -38.193818,-4.71335 -0.157685,1.35187 -0.305954,2.70839 -0.319413,4.07715 0.0064,31.4396 0.01517,62.87977 -0.0037,94.32 -18.255799,-0.006 -36.511368,0.0168 -54.767029,-0.0115 -0.0388,-40.30612 0.01926,-80.61204 -0.02911,-120.91781 z"/>
<path d="m 155.75305,221.30997 c 16.07997,-0.13549 32.16204,-0.0238 48.2433,-0.0572 23.83194,-0.13529 48.05416,2.93651 70.20328,12.1031 13.75632,5.82483 27.06233,14.43199 35.03758,27.39059 6.05672,10.0663 8.17432,22.99054 3.41974,34.00478 -5.58125,13.21376 -17.53407,22.37564 -29.70006,29.22304 -22.30197,11.93273 -47.08825,18.27707 -72.31572,19.34199 l -0.0437,24.93099 -54.85077,7.52423 0.006,-154.46153 z"/>
<path d="m 350.73776,221.33231 c 62.75727,-0.19167 125.51848,-0.0234 188.27761,-0.0843 18.36058,0.076 37.02661,0.1922 54.8872,4.94194 5.14029,1.69319 11.99558,3.70666 13.34763,9.68171 0.13403,35.45186 0.05,70.91191 0.0409,106.36713 -18.26615,-0.004 -36.53138,-0.0113 -54.79609,0.004 -0.004,-35.17893 -0.0756,-70.3591 0.0357,-105.53679 -3.31824,-2.87891 -8.04874,-2.75609 -12.16869,-3.25885 -11.26521,-0.29326 -22.53945,-0.084 -33.80654,-0.11576 0.002,36.30307 0.0406,72.60642 -0.0191,108.90969 -18.292,-0.0171 -36.58319,0.005 -54.87403,-0.0112 -0.0542,-29.07907 -0.008,-58.15799 -0.0231,-87.23671 -0.14635,-6.3542 0.31845,-12.73225 -0.27677,-19.06588 -5.14636,-2.16309 -10.78398,-2.58689 -16.30214,-2.61335 -9.79776,-0.0158 -19.5944,0.007 -29.39029,-0.01 -0.048,36.31536 0.0591,72.63149 -0.0537,108.94673 -17.22348,-0.022 -34.44665,-0.0339 -51.66902,0.007 l -3.31752,-0.0131 c 0.28336,-40.07539 0.0678,-80.83315 0.108,-120.91222 z"/>
<path fill="#d72123" d="m 423.56764,57.495636 c 4.51283,-6.287872 9.12833,-12.501984 13.73035,-18.725891 42.14722,12.344238 82.84823,31.836792 116.09491,60.881943 13.59442,12.173292 25.88991,25.944912 35.33316,41.613512 11.1826,18.43936 18.26884,39.55612 19.02705,61.19006 -33.0565,-5.77759 -66.1038,-11.60446 -99.1558,-17.40172 4.06793,-12.93818 4.10266,-27.0249 1.31704,-40.22806 -5.16264,-22.81849 -19.7915,-42.41004 -37.43728,-57.282084 C 457.76711,75.165924 440.98531,65.246307 423.20515,57.986771 l 0.36249,-0.491135 z"/>
<path fill="#fff" d="m 210.67975,234.60013 c 14.04689,1.40957 26.7447,9.34711 36.33964,19.39103 8.27451,8.70258 14.12349,20.84611 12.10276,33.07682 -2.20877,12.25284 -10.73442,22.20633 -20.32152,29.61572 -8.32672,6.11266 -17.74312,11.38919 -28.12337,12.77234 -0.0358,-31.61874 -0.0407,-63.2376 0.002,-94.85591 z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g transform="matrix(0.04742975,0,0,0.04742975,2.9426429,-1.9210171)">
<path fill="#1572b6" d="M 27.142,386.29 0.071,82.67 l 297.45,0 -27.096,303.571 -121.811,33.77 L 27.142,386.29 z m 0,0"/>
<path fill="#33a9dc" d="m 148.798,394.199 98.427,-27.288 23.157,-259.415 -121.584,0 0,286.703 z m 0,0"/>
<g transform="translate(55,142)">
<path fill="#ffffff" d="m 93.797,75.496 49.275,0 3.403,-38.132 -52.678,0 0,-37.239 0.129,0 93.246,0 -0.893,9.991 -9.152,102.616 -83.33,0 0,-37.236 z m 0,0"/>
<path fill="#ebebeb" d="m 94.02,172.204 -0.163,0.046 -41.472,-11.199 -2.652,-29.698 -20.151,0 -17.228,0 5.216,58.467 76.278,21.176 0.172,-0.048 0,-38.744 z m 0,0"/>
<path fill="#ffffff" d="m 139.907,111.156 -4.484,49.87 -41.532,11.21 0,38.742 76.339,-21.158 0.56,-6.29 6.478,-72.374 -37.361,0 z m 0,0"/>
<path fill="#ebebeb" d="m 93.926,0.125 0,23.128 0,14.019 0,0.092 -89.828,0 -0.119,0 -0.747,-8.37 -1.697,-18.878 -0.89,-9.991 93.281,0 z m 0,0"/>
<path fill="#ebebeb" d="m 93.797,75.5 0,23.129 0,14.017 0,0.092 -40.828,0 -0.119,0 -0.746,-8.369 -1.698,-18.878 -0.89,-9.991 44.281,0 z m 0,0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,29 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#f6d2a2" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 10.634,-238.979 c 0.764,15.751 16.499,8.463 23.626,3.539 6.765,-4.675 8.743,-0.789 9.337,-10.015 0.389,-6.064 1.088,-12.128 0.744,-18.216 -10.23,-0.927 -21.357,1.509 -29.744,7.602 -4.32,3.139 -12.42,13.158 -3.963,17.09" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#c6b198" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 10.634,-238.979 c 2.29,-0.852 4.717,-1.457 6.271,-3.528" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#6ad7e5" fill-rule="evenodd" stroke="#000" stroke-width="3" d="M46.997-426.619c-60.297-16.956-15.461-93.664 32.959-62.113l-32.959 62.113zM314.895-494.488c47.727-33.523 90.856 42.111 35.388 61.141l-35.388-61.141z" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#f6d2a2" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 325.161,-45.128999 c 12.123,7.501 34.282,30.182 16.096,41.1799995 -17.474,15.9990005 -27.254,-17.5609995 -42.591,-22.2109995 6.605,-8.97 14.977,-17.149 26.495,-18.969 z" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="none" stroke="#000" stroke-width="3" d="m 341.257,-3.9499995 c -2.696,-5.361 -3.601,-11.6179995 -8.102,-15.9389995" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#f6d2a2" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 108.579,-19.496999 c -14.229,2.202 -22.238,15.0389995 -34.1,21.5579995 -11.178,6.665 -15.454,-2.13399996 -16.461,-3.92 -1.752,-0.799 -1.605,0.744 -4.309,-1.979 -10.362,-16.3539995 10.797,-28.3079995 21.815,-36.4319995 15.346,-3.102 24.963,10.202 33.055,20.773 z" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="none" stroke="#000" stroke-width="3" d="m 58.019,-1.8599995 c 0.542,-6.233 5.484,-10.4069995 7.838,-15.6769995" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill-rule="evenodd" d="M49.513-447.805c-7.955-4.208-13.791-9.923-8.925-19.124 4.505-8.518 12.874-7.593 20.83-3.385l-11.905 22.509zM337.716-455.805c7.955-4.208 13.791-9.923 8.925-19.124-4.505-8.518-12.874-7.593-20.83-3.385l11.905 22.509z" clip-rule="evenodd" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#f6d2a2" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 392.475,-240.979 c -0.764,15.751 -16.499,8.463 -23.626,3.539 -6.765,-4.675 -8.743,-0.789 -9.337,-10.015 -0.389,-6.064 -1.088,-12.128 -0.744,-18.216 10.23,-0.927 21.357,1.509 29.744,7.602 4.319,3.139 12.42,13.158 3.963,17.09" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#c6b198" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 392.475,-240.979 c -2.29,-0.852 -4.717,-1.457 -6.271,-3.528" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#6ad7e5" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 195.512,13.124 c 60.365,0 116.953,8.633 146.452,66.629 26.478,65.006 17.062,135.104 21.1,203.806 3.468,58.992 11.157,127.145 -16.21,181.812 -28.79,57.514 -100.73,71.982 -160,69.863 C 140.299,533.568 84.06,518.38 57.785,475.845 26.959,425.945 41.553,351.747 43.792,296.223 46.444,230.452 25.977,164.481 47.584,100.122 69.999,33.359 130.451,18.271 195.512,13.124" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 1.636)"/>
<path fill="#fff" fill-rule="evenodd" stroke="#000" stroke-width="2.908" d="m 206.169,-445.312 c 10.838,63.003 113.822,46.345 99.03,-17.197 -13.264,-56.98 -102.632,-41.208 -99.03,17.197" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#fff" fill-rule="evenodd" stroke="#000" stroke-width="2.821" d="m 83.103,-435.122 c 14.047,54.85 101.864,40.807 98.554,-14.213 -3.966,-65.895 -111.984,-53.18 -98.554,14.213" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<path fill="#fff" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 218.594,-369.71 c 0.046,8.191 1.861,17.387 0.312,26.101 -2.091,3.952 -6.193,4.37 -9.729,5.967 -4.89,-0.767 -9.002,-3.978 -10.963,-8.552 -1.255,-9.946 0.468,-19.576 0.785,-29.526 l 19.595,6.01 z" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<g fill-rule="evenodd" transform="matrix(.03 0 0 .03 3.959 1.636)" clip-rule="evenodd">
<ellipse cx="107.324" cy="95.404" ry="16.062" rx="14.829"/>
<ellipse cx="114.069" cy="99.029" fill="#fff" ry="4.082" rx="3.496"/>
</g>
<g fill-rule="evenodd" transform="matrix(.03 0 0 .03 3.959 1.636)" clip-rule="evenodd">
<ellipse cx="231.571" cy="91.404" ry="16.062" rx="14.582"/>
<ellipse cx="238.204" cy="95.029" fill="#fff" ry="4.082" rx="3.438"/>
</g>
<path fill="#fff" fill-rule="evenodd" stroke="#000" stroke-width="3" d="m 176.217,-370.602 c -6.47,15.68 3.608,47.035 21.163,23.908 -1.255,-9.946 0.468,-19.576 0.785,-29.526 l -21.948,5.618 z" clip-rule="evenodd" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 17.82)"/>
<g fill-rule="evenodd" clip-rule="evenodd">
<path fill="#f6d2a2" stroke="#231f20" stroke-width="3" d="m 178.431,138.673 c -12.059,1.028 -21.916,15.366 -15.646,26.709 8.303,15.024 26.836,-1.329 38.379,0.203 13.285,0.272 24.17,14.047 34.84,2.49 11.867,-12.854 -5.109,-25.373 -18.377,-30.97 l -39.196,1.568 z" stroke-linecap="round" transform="matrix(.03 0 0 .03 3.959 1.636)"/>
<path d="m 176.913,138.045 c -0.893,-20.891 38.938,-23.503 43.642,-6.016 4.692,17.446 -41.681,21.498 -43.642,6.016 -1.565,-12.363 0,0 0,0 z" transform="matrix(.03 0 0 .03 3.959 1.636)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g transform="matrix(0.03889348,0,0,0.03889348,0.04326912,-1.9134619)">
<polygon fill="#e44d26" points="437.367,100.62 404.321,470.819 255.778,512 107.644,470.877 74.633,100.62"/>
<polygon fill="#f16529" points="256,130.894 256,480.523 376.03,447.246 404.27,130.894"/>
<polygon fill="#ebebeb" points="143.219,188.488 154.38,313.627 256,313.627 256,268.217 195.91,268.217 191.76,221.716 256,221.716 256,176.305 255.843,176.305 142.132,176.305"/>
<polygon fill="#ebebeb" points="256,386.153 255.801,386.206 205.227,372.55 201.994,336.333 177.419,336.333 156.409,336.333 162.771,407.634 255.791,433.457 256,433.399"/>
<polygon fill="#ffffff" points="255.843,433.435 348.937,407.634 349.62,399.962 360.291,280.411 361.399,268.217 349.162,268.217 255.843,268.217 255.843,313.627 311.761,313.627 306.49,372.521 255.843,386.191"/>
<polygon fill="#ffffff" points="366.442,211.509 368.511,188.488 369.597,176.305 255.843,176.305 255.843,204.509 255.843,221.605 255.843,221.716 365.385,221.716 365.385,221.716 365.531,221.716"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#fbc02d" stroke="#fbc02d" stroke-width="1" d="M 14.1875 4.6875 C 13.09018 4.6875104 12.199333 4.9405471 11.5625 5.46875 C 10.925664 5.9871904 10.624999 6.7055265 10.625 7.625 C 10.624999 8.0651846 10.696787 8.4682415 10.84375 8.78125 C 11.000508 9.0942712 11.192562 9.3375261 11.4375 9.5625 C 11.692232 9.7874849 11.989182 9.9997477 12.3125 10.15625 C 12.645612 10.302981 12.991037 10.435342 13.34375 10.5625 C 13.696455 10.679886 14.006917 10.810341 14.28125 10.9375 C 14.555575 11.054885 14.782593 11.165778 14.96875 11.3125 C 15.164694 11.449448 15.308271 11.605183 15.40625 11.78125 C 15.514016 11.957323 15.562494 12.16171 15.5625 12.40625 C 15.562494 12.817085 15.428715 13.150022 15.125 13.375 C 14.821273 13.599981 14.322474 13.718751 13.65625 13.71875 C 13.019412 13.718751 12.481931 13.646727 12.03125 13.5 C 11.580565 13.353276 11.23328 13.209228 10.96875 13.0625 L 10.40625 14.5625 C 10.52382 14.630973 10.679049 14.724461 10.875 14.8125 C 11.070949 14.890754 11.297967 14.952993 11.5625 15.03125 C 11.836828 15.109504 12.157087 15.169839 12.5 15.21875 C 12.852707 15.277443 13.234955 15.3125 13.65625 15.3125 C 14.910321 15.3125 15.853361 15.061368 16.5 14.5625 C 17.156424 14.053851 17.499993 13.325734 17.5 12.40625 C 17.499993 11.92695 17.418407 11.551332 17.28125 11.21875 C 17.144079 10.876394 16.952025 10.557047 16.6875 10.3125 C 16.432759 10.058181 16.132095 9.8635762 15.75 9.6875 C 15.377691 9.5016528 14.948821 9.3010768 14.46875 9.125 C 14.194416 9.0271889 13.922635 8.9201051 13.6875 8.8125 C 13.462155 8.7049074 13.270101 8.5959189 13.09375 8.46875 C 12.92719 8.3415943 12.785469 8.2190145 12.6875 8.0625 C 12.599319 7.896218 12.562497 7.693737 12.5625 7.46875 C 12.562497 7.0970525 12.694418 6.7991744 12.96875 6.59375 C 13.252873 6.3883426 13.656575 6.2812588 14.15625 6.28125 C 14.577537 6.2812588 14.983096 6.3396915 15.375 6.4375 C 15.776691 6.5353258 16.13563 6.6891556 16.46875 6.875 L 17.03125 5.375 C 16.747117 5.2087206 16.374665 5.0432042 15.875 4.90625 C 15.385121 4.7595342 14.82433 4.6875104 14.1875 4.6875 z M 6.9375 4.9375 L 6.9375 11.625 C 6.9374954 12.387977 6.8153722 12.936987 6.53125 13.25 C 6.2471196 13.563017 5.7832845 13.718751 5.15625 13.71875 C 4.7839439 13.718751 4.4250043 13.646727 4.0625 13.5 C 3.7097899 13.343494 3.4011857 13.166291 3.15625 13 L 2.5 14.46875 C 2.7547338 14.674167 3.1234709 14.876648 3.59375 15.0625 C 4.0738243 15.238567 4.6346149 15.3125 5.28125 15.3125 C 5.9768667 15.3125 6.5493124 15.217103 7 15.03125 C 7.460476 14.845398 7.829213 14.604047 8.09375 14.28125 C 8.3680731 13.958455 8.5484718 13.555398 8.65625 13.125 C 8.7640159 12.694607 8.8124936 12.248871 8.8125 11.75 L 8.8125 4.9375 L 6.9375 4.9375 z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="#5c6bc0" transform="matrix(0.02460339,0,0,0.02460339,1.0508613,-2.0358995)">
<path d="m 635.0385,526.8108 c 35.909,12.563 53.856,34.088 53.856,64.543 0,20.046 -7.443,35.957 -22.296,47.725 -14.838,11.776 -36.005,19.084 -63.557,19.084 -27.552,0 -53.037,-7.983 -76.51,-21.088 0.254,-6.95 2.091,-14.575 5.463,-22.852 3.372,-8.277 7.363,-14.853 11.936,-19.656 21.573,11.211 40.346,16.826 56.281,16.826 7.531,0 13.358,-1.264 17.414,-3.809 4.063,-2.536 6.083,-5.94 6.083,-10.217 0,-8.039 -6.226,-14.051 -18.638,-18.058 l -22.296,-8.421 c -33.73,-12.293 -50.596,-32.323 -50.596,-60.146 0,-20.316 7.085,-36.418 21.255,-48.33 14.17,-11.895 33.269,-22.137 57.283,-22.137 11.88,0 24.96,1.67 39.272,5.01 14.297,3.348 26.042,11.594 35.218,16.125 0.541,7.49 -0.962,15.712 -4.452,24.665 -3.515,8.961 -7.824,15.306 -12.969,19.052 -22.685,-10.162 -41.562,-15.243 -56.686,-15.243 -5.415,0 -9.494,1.201 -12.357,3.618 -2.831,2.41 -4.223,5.478 -4.223,9.224 0,6.417 5.121,11.49 15.386,15.235 l 25.133,8.85 z"/>
<path d="m 455.6835,526.8108 c 35.909,12.563 53.848,34.088 53.848,64.543 0,20.046 -7.443,35.957 -22.272,47.725 -14.853,11.776 -36.028,19.084 -63.572,19.084 -27.528,0 -53.045,-7.983 -76.51,-21.088 0.254,-6.95 2.091,-14.575 5.47,-22.852 3.372,-8.277 7.347,-14.853 11.936,-19.656 21.597,11.211 40.362,16.826 56.289,16.826 7.538,0 13.366,-1.264 17.406,-3.809 4.048,-2.536 6.083,-5.94 6.083,-10.217 0,-8.039 -6.226,-14.051 -18.638,-18.058 l -22.281,-8.421 c -33.738,-12.293 -50.611,-32.323 -50.611,-60.146 0,-20.316 7.085,-36.418 21.27,-48.33 14.162,-11.895 33.253,-22.137 57.267,-22.137 11.872,0 24.984,1.67 39.265,5.01 14.313,3.348 26.042,11.594 35.225,16.125 0.541,7.49 -0.962,15.712 -4.452,24.665 -3.507,8.961 -7.824,15.306 -12.961,19.052 -22.694,-10.162 -41.571,-15.243 -56.702,-15.243 -5.407,0 -9.502,1.201 -12.349,3.618 -2.823,2.41 -4.23,5.478 -4.23,9.224 0,6.417 5.128,11.49 15.394,15.235 l 25.125,8.85 z"/>
<path d="m 324.8885,529.6408 c 0,-12.293 -1.956,-23.656 -5.868,-34.089 -3.904,-10.432 -9.51,-19.378 -16.794,-26.868 -7.292,-7.49 -16.126,-13.367 -26.511,-17.645 -10.401,-4.27 -22.074,-10.711 -35.027,-10.711 -15.387,0 -28.816,6.966 -40.282,12.317 -11.466,5.344 -20.913,12.691 -28.332,22.05 -7.435,9.366 -12.969,20.388 -16.611,33.086 -3.642,12.699 -5.463,26.534 -5.463,41.499 0,15.49 1.479,29.818 4.453,42.914 2.966,13.08 8.03,24.435 15.18,34.073 7.156,9.621 16.467,17.104 27.941,22.439 11.474,5.344 25.715,9.447 42.716,9.447 31.305,0 57.752,-9.065 79.348,-24.292 -2.139,-15.49 -7.657,-27.807 -16.523,-36.896 -11.029,4.142 -20.786,7.108 -29.246,8.93 -8.468,1.798 -15.935,2.704 -22.383,2.704 -12.906,0 -22.193,-3.284 -27.83,-9.915 -5.631,-6.608 -8.72,-14.424 -9.267,-26.296 h 105.265 c 3.477,-11.243 5.234,-26.438 5.234,-42.747 z m -110.9,2.776 c 0.802,-13.645 3.292,-28.244 7.435,-34.255 4.151,-6.019 10.504,-9.025 19.083,-9.025 8.835,0 15.466,3.197 19.879,9.614 4.422,6.417 6.631,19.346 6.631,29.237 l 0.008,4.429 h -53.036 l 0,0 z"/>
<path d="m 129.3525,604.6078 h -10.933 c -11.887,0 -16.364,-6.25 -16.364,-18.805 V 355.05779 c 0,-13.875 -4.007,-23.616 -9.137,-29.229 -5.129,-5.598 -14.034,-5.542 -26.717,-5.542 h -24.69 l -2.91,-0.056 v 0.238 l -0.024,34.343 V 596.9678 c 0,19.258 4.326,33.349 12.022,42.318 7.705,8.953 20.722,13.422 39.074,13.422 12.691,0 27.131,-1.336 43.32,-4.016 0.811,-2.704 1.217,-8.492 1.217,-17.374 0,-8.906 -1.621,-17.788 -4.858,-26.71 z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#ad1457" d="M12.078 10h2.3V6.007h2.32V10H19l-3.46 3.993zM1 13.993V6.007h2.32l2.355 2.917L8.03 6.007h2.32v7.986H8.03V9.398l-2.355 2.887L3.32 9.398v4.595z"/>
</svg>

After

Width:  |  Height:  |  Size: 260 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#6c7eb7" fill-rule="evenodd" d="M 8.625 5.65625 L 7.25 12.6875 L 8.90625 12.6875 L 9.6875 8.78125 L 11 8.78125 C 11.609 8.78125 11.587 9.03375 11.5 9.46875 L 10.90625 12.6875 L 12.65625 12.6875 L 13.25 9.125 C 13.424 8.255 12.892 7.55575 11.5 7.46875 L 9.9375 7.46875 L 10.28125 5.65625 L 8.625 5.65625 z M 2.34375 7.46875 L 0.9375 14.53125 L 2.59375 14.53125 L 2.9375 12.6875 L 4.5 12.6875 C 5.979 12.7745 7.65625 11.55675 7.65625 9.46875 C 7.65625 8.25075 6.9545 7.55575 5.5625 7.46875 L 2.34375 7.46875 z M 13.84375 7.46875 L 12.4375 14.5 L 14.09375 14.5 L 14.4375 12.6875 L 16 12.6875 C 17.47899 12.7745 19.125 11.556754 19.125 9.46875 C 19.125 8.2507462 18.454491 7.55575 17.0625 7.46875 L 13.84375 7.46875 z M 15.21875 8.75 L 16.34375 8.75 C 16.952746 8.75 17.40625 9.0092466 17.40625 9.53125 C 17.31925 11.010253 16.626745 11.288 15.84375 11.375 L 14.78125 11.375 L 15.21875 8.75 z M 3.71875 8.78125 L 4.875 8.78125 C 5.484 8.78125 5.90625 9.0405 5.90625 9.5625 C 5.81925 11.0415 5.12675 11.31925 4.34375 11.40625 L 3.28125 11.40625 L 3.71875 8.78125 z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g transform="translate(-473.36088,-341.57095)">
<g transform="matrix(0.14489978,0,0,0.14489978,468.84945,333.83641)">
<path fill="#387eb8" d="M 99.75,67.46875 C 71.718268,67.468752 73.46875,79.625 73.46875,79.625 L 73.5,92.21875 l 26.75,0 0,3.78125 -37.375,0 c 0,0 -17.9375,-2.034276 -17.9375,26.25 -2e-6,28.28427 15.65625,27.28125 15.65625,27.28125 l 9.34375,0 0,-13.125 c 0,0 -0.503652,-15.65625 15.40625,-15.65625 15.9099,0 26.53125,0 26.53125,0 0,0 14.90625,0.24096 14.90625,-14.40625 0,-14.647206 0,-24.21875 0,-24.21875 0,-2e-6 2.26318,-14.65625 -27.03125,-14.65625 z M 85,75.9375 c 2.661429,-2e-6 4.8125,2.151071 4.8125,4.8125 2e-6,2.661429 -2.151071,4.8125 -4.8125,4.8125 -2.661429,2e-6 -4.8125,-2.151071 -4.8125,-4.8125 -2e-6,-2.661429 2.151071,-4.8125 4.8125,-4.8125 z"/>
<path fill="#ffe052" d="m 100.5461,177.31485 c 28.03174,0 26.28125,-12.15625 26.28125,-12.15625 l -0.0312,-12.59375 -26.75,0 0,-3.78125 37.375,0 c 0,0 17.9375,2.03427 17.9375,-26.25001 10e-6,-28.284267 -15.65625,-27.281247 -15.65625,-27.281247 l -9.34375,0 0,13.124997 c 0,0 0.50366,15.65625 -15.40625,15.65625 -15.909902,0 -26.531252,0 -26.531252,0 0,0 -14.90625,-0.24096 -14.90625,14.40626 0,14.6472 0,24.21875 0,24.21875 0,0 -2.26318,14.65625 27.031252,14.65625 z m 14.75,-8.46875 c -2.66143,0 -4.8125,-2.15107 -4.8125,-4.8125 0,-2.66143 2.15107,-4.8125 4.8125,-4.8125 2.66143,0 4.8125,2.15107 4.8125,4.8125 1e-5,2.66143 -2.15107,4.8125 -4.8125,4.8125 z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#e53935" d="M 10.707376,3.0220971 12.625,4.28125 11.5,7.90625 7.4375,11.6875 3.90625,12.46875 3.1875,10.46875 3,14.15625 c 0.07668,2.758421 2.05851,2.788289 2.90625,2.8125 L 5.875,17 16.96875,16.90625 17.0625,5.8125 C 17.122609,4.2480709 15.364825,3.0014165 14.375,3 z M 5.8700983,5.9390704 C 3.7805688,8.0101404 3.256183,9.918237 4.289943,10.960517 5.3229925,12.003507 7.2816787,11.165285 9.3712087,9.09421 11.460739,7.0231401 12.097651,5.0845033 11.06453,4.0415133 9.4255397,2.6480655 6.9773962,4.7208064 5.8700983,5.9390704 z"/>
</svg>

After

Width:  |  Height:  |  Size: 636 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#795548" d="M18 9.9 17.3 9.5c0 0 0-0.1 0-0.1L17.9 8.8C17.9 8.8 18 8.6 18 8.5 18 8.4 17.9 8.4 17.9 8.4L17.1 8.1c0 0 0-0.1 0-0.1l0.4-0.7c0 0 0-0.1 0-0.3 0-0.1-0.1-0.1-0.1-0.1L16.5 6.7c0 0 0-0.1-0.1-0.1l0.3-0.7c0-0.1 0-0.1 0-0.3 0 0-0.1-0.1-0.1-0.1l-0.8 0c0 0-0.1-0.1-0.1-0.1L15.7 4.6c0-0.1 0-0.1 0-0.3 0 0-0.1-0.1-0.3 0l-0.8 0.1c0 0-0.1-0.1-0.1-0.1l0-0.8c0-0.1 0-0.1-0.1-0.1 0 0-0.1 0-0.3 0l-0.7 0.3c0 0-0.1 0-0.1-0.1L13.1 2.7c0-0.1 0-0.1-0.1-0.1-0.1 0-0.1 0-0.3 0l-0.7 0.4c0 0-0.1 0-0.1 0L11.6 2.3c0-0.1-0.1-0.1-0.1-0.1-0.1 0-0.1 0-0.3 0.1l-0.5 0.5c0 0-0.1 0-0.1 0L10.1 2.1C10.1 2 10 2 10 2 9.9 2 9.9 2 9.9 2.1l-0.4 0.7c0 0-0.1 0-0.1 0L8.8 2.3c0 0-0.1-0.1-0.3-0.1-0.1 0-0.1 0.1-0.1 0.1L8.1 2.9c0 0-0.1 0-0.1 0L7.3 2.5c0 0-0.1 0-0.3 0-0.1 0-0.1 0.1-0.1 0.1L6.7 3.5c0 0-0.1 0-0.1 0.1L5.9 3.4c-0.1 0-0.1 0-0.3 0 0 0-0.1 0.1-0.1 0.1l0 0.8c0 0-0.1 0.1-0.1 0.1L4.6 4.3c-0.1 0-0.1 0-0.3 0 0 0-0.1 0.1 0 0.3l0.1 0.8c0 0-0.1 0.1-0.1 0.1l-0.8 0c-0.1 0-0.1 0-0.1 0.1 0 0 0 0.1 0 0.3l0.3 0.7c0 0 0 0.1-0.1 0.1L2.7 6.9c-0.1 0-0.1 0-0.1 0.1 0 0.1 0 0.1 0 0.3l0.4 0.7c0 0 0 0.1 0 0.1L2.3 8.4c-0.1 0-0.1 0.1-0.1 0.1 0 0.1 0 0.1 0.1 0.3l0.5 0.5c0 0 0 0.1 0 0.1L2.1 9.9C2 9.9 2 10 2 10c0 0.1 0 0.1 0.1 0.1l0.7 0.4c0 0 0 0.1 0 0.1l-0.5 0.5c0 0-0.1 0.1-0.1 0.3 0 0.1 0.1 0.1 0.1 0.1l0.7 0.3c0 0 0 0.1 0 0.1l-0.4 0.7c0 0 0 0.1 0 0.3 0 0.1 0.1 0.1 0.1 0.1l0.8 0.1c0 0 0 0.1 0.1 0.1l-0.3 0.7c0 0.1 0 0.1 0 0.3 0 0 0.1 0.1 0.1 0.1l0.8 0c0 0 0.1 0.1 0.1 0.1l-0.1 0.8c0 0.1 0 0.1 0 0.3 0 0 0.1 0.1 0.3 0l0.8-0.1c0 0 0.1 0.1 0.1 0.1l0 0.8c0 0.1 0 0.1 0.1 0.1 0 0 0.1 0 0.3 0l0.7-0.3c0 0 0.1 0 0.1 0.1l0.1 0.8c0 0.1 0 0.1 0.1 0.1 0.1 0 0.1 0 0.3 0l0.7-0.4c0 0 0.1 0 0.1 0l0.3 0.7c0 0.1 0.1 0.1 0.1 0.1 0.1 0 0.1 0 0.3-0.1l0.5-0.5c0 0 0.1 0 0.1 0l0.4 0.7C9.9 17.9 10 18 10 18c0.1 0 0.1 0 0.1-0.1l0.4-0.7c0 0 0.1 0 0.1 0l0.5 0.5c0 0 0.1 0.1 0.3 0.1 0.1 0 0.1-0.1 0.1-0.1l0.3-0.7c0 0 0.1 0 0.1 0l0.7 0.4c0 0 0.1 0 0.3 0 0.1 0 0.1-0.1 0.1-0.1l0.1-0.8c0 0 0.1 0 0.1-0.1l0.7 0.3c0.1 0 0.1 0 0.3 0 0 0 0.1-0.1 0.1-0.1l0-0.8c0 0 0.1-0.1 0.1-0.1l0.8 0.1c0.1 0 0.1 0 0.3 0 0 0 0.1-0.1 0-0.3l-0.1-0.8c0 0 0.1-0.1 0.1-0.1l0.8 0c0.1 0 0.1 0 0.1-0.1 0 0 0-0.1 0-0.3l-0.3-0.7c0 0 0-0.1 0.1-0.1l0.8-0.1c0.1 0 0.1 0 0.1-0.1 0-0.1 0-0.1 0-0.3l-0.4-0.7c0 0 0-0.1 0-0.1l0.7-0.3c0.1 0 0.1-0.1 0.1-0.1 0-0.1 0-0.1-0.1-0.3l-0.5-0.5c0 0 0-0.1 0-0.1l0.7-0.4C18 10.1 18 10 18 10 18 9.9 18 9.9 17.9 9.9zm-4.5 5.6c-0.3 0-0.4-0.3-0.4-0.5 0-0.3 0.3-0.4 0.5-0.4 0.3 0 0.4 0.3 0.4 0.5 0 0.3-0.3 0.4-0.5 0.4zm-0.3-1.5c-0.3 0-0.4 0.1-0.5 0.3l-0.3 1.1C11.8 15.6 10.9 15.8 10 15.8c-0.8 0-1.8-0.1-2.4-0.5L7.3 14.2c0-0.3-0.3-0.4-0.5-0.3L5.8 14.2C5.7 13.9 5.5 13.7 5.4 13.5l4.7 0c0 0 0.1 0 0.1 0l0-1.6c0 0 0 0-0.1 0l-1.4 0 0-1.1 1.5 0c0.1 0 0.7 0 0.9 0.8 0 0.3 0.1 0.9 0.3 1.2 0.1 0.3 0.4 0.8 0.8 0.8l2.4 0c0 0 0 0 0.1 0-0.1 0.3-0.4 0.4-0.5 0.7l-1.1-0.4zm-6.6 1.5c-0.3 0-0.5-0.1-0.5-0.4 0-0.3 0.1-0.5 0.4-0.5 0.3 0 0.5 0.1 0.5 0.4 0 0.3-0.1 0.5-0.4 0.5zM4.8 8.1c0.1 0.3 0 0.5-0.3 0.7-0.3 0.1-0.5 0-0.7-0.3-0.1-0.3 0-0.5 0.3-0.7 0.3-0.1 0.5 0 0.7 0.3zM4.3 9.5 5.4 9.1C5.7 8.9 5.7 8.6 5.7 8.5l-0.3-0.5 0.8 0 0 3.8-1.6 0C4.4 11.2 4.3 10.7 4.3 10.1c0-0.3 0-0.4 0-0.7zm4.5-0.4 0-1.1 2 0c0.1 0 0.7 0.1 0.7 0.5 0 0.4-0.4 0.5-0.8 0.5l-1.8 0zM16 10c0 0.1 0 0.3 0 0.4l-0.5 0c0 0-0.1 0-0.1 0.1l0 0.3c0 0.7-0.4 0.8-0.7 0.8-0.3 0-0.7-0.1-0.7-0.3-0.1-0.9-0.5-1.2-0.9-1.6 0.5-0.4 1.2-0.9 1.2-1.6 0-0.8-0.5-1.4-0.9-1.5C12.7 6.2 12.2 6.2 12 6.2l-6.2 0C6.6 5.3 7.8 4.6 9.1 4.3l0.7 0.8c0.1 0.1 0.4 0.1 0.7 0l0.8-0.8c1.8 0.3 3.1 1.4 3.9 2.8l-0.5 1.2c-0.1 0.3 0 0.4 0.3 0.5l1.1 0.5c0 0.1 0 0.4 0 0.5zM9.7 3.6c0.1-0.1 0.5-0.1 0.7 0 0.1 0.1 0.1 0.5 0 0.7-0.1 0.1-0.5 0.1-0.7 0-0.1-0.1-0.1-0.5 0-0.7zm5.6 4.5C15.4 7.8 15.7 7.7 16 7.8 16.2 8 16.4 8.2 16.2 8.5 16.1 8.8 15.8 8.9 15.6 8.8 15.3 8.6 15.2 8.4 15.3 8.1z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#1976d2" d="M 8.59375 3 L 8 5.09375 L 6.84375 5.8125 L 4.625 5.34375 L 3.21875 7.65625 L 4.84375 9.3125 L 4.84375 10.6875 L 3.21875 12.34375 L 4.625 14.65625 L 6.84375 14.1875 L 8 14.90625 L 8.59375 17 L 11.40625 17 L 12.09375 14.90625 L 13.15625 14.1875 L 15.375 14.65625 L 16.78125 12.34375 L 15.25 10.6875 L 15.25 9.3125 L 16.78125 7.65625 L 15.375 5.34375 L 13.15625 5.8125 L 12.09375 5.09375 L 11.40625 3 L 8.59375 3 z M 10 7.5 C 11.380712 7.5 12.5 8.6192881 12.5 10 C 12.5 11.380712 11.380712 12.5 10 12.5 C 8.6192881 12.5 7.5 11.380712 7.5 10 C 7.5 8.6192881 8.6192881 7.5 10 7.5 z"/>
</svg>

After

Width:  |  Height:  |  Size: 696 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#e33" d="M 7.1837924,11.307953 C 7.6707878,10.353408 8.2243075,9.2777656 8.6673693,8.1977207 l 0,0 0.1750865,-0.4261233 C 8.2638361,5.5694562 7.9167872,3.8015945 8.2268175,2.65879 l 0,0 C 8.3103144,2.3606956 8.6554508,2.1799563 9.0244582,2.1799563 l 0,0 0.2246724,0.0031 0.041496,0 c 0.5051971,-0.00754 0.7430344,0.6351036 0.7700294,0.8848773 l 0,0 c 0.04457,0.4160895 -0.1480415,1.1202107 -0.1480415,1.1202107 l 0,0 c 0,-0.2842813 0.011293,-0.7436667 -0.1681885,-1.1402846 l 0,0 C 9.5354439,2.5891118 9.3358716,2.3148707 9.1570283,2.2715686 l 0,0 C 9.0667026,2.3318431 8.9787995,2.4566961 8.9486794,2.69706 l 0,0 c -0.062153,0.337009 -0.080934,0.7625005 -0.080934,0.9815213 l 0,0 c 0,0.7750507 0.1524795,1.7973568 0.4524699,2.8516732 l 0,0 C 9.376732,6.3670176 9.4262491,6.2102008 9.4658631,6.0633393 l 0,0 C 9.5273333,5.831768 9.9183329,4.2967327 9.9183329,4.2967327 l 0,0 c 0,0 -0.098522,2.0433649 -0.2359592,2.6615218 l 0,0 c -0.029539,0.130453 -0.062152,0.2598125 -0.095963,0.3922291 l 0,0 c 0.4945263,1.3812802 1.2909033,2.613824 2.2410503,3.5012084 l 0,0 c 0.374662,0.350187 0.847839,0.632591 1.295924,0.889897 l 0,0 c 0.977747,-0.140017 1.878312,-0.205837 2.629514,-0.197674 l 0,0 c 0.996584,0.01322 1.728324,0.160674 2.024539,0.452468 l 0,0 c 0.144967,0.141893 0.203958,0.313158 0.222161,0.505196 l 0,0 c 0.0046,0.07457 -0.03192,0.250406 -0.04265,0.294341 l 0,0 c 0.01063,-0.0533 0.01063,-0.315665 -0.789481,-0.571091 l 0,0 c -0.630087,-0.201452 -1.809285,-0.195167 -3.224454,-0.04454 l 0,0 c 1.636707,0.800785 3.231353,1.198664 3.736549,0.960177 l 0,0 c 0.123621,-0.06024 0.273628,-0.265462 0.273628,-0.265462 l 0,0 c 0,0 -0.08911,0.404778 -0.153163,0.505805 l 0,0 c -0.08162,0.109794 -0.241612,0.229069 -0.393496,0.26923 l 0,0 c -0.79828,0.212748 -2.875529,-0.279901 -4.686694,-1.314763 l 0,0 C 10.696554,12.63337 8.4743315,13.183748 6.69329,13.768015 l 0,0 c -1.7505467,3.067553 -3.0665588,4.476442 -4.1371905,3.940501 l 0,0 -0.3934914,-0.197673 C 2.0026124,17.419141 1.9780925,17.196419 2.0150773,17.015058 l 0,0 C 2.139895,16.40444 2.9055885,15.484427 4.443769,14.566287 l 0,0 c 0.1656275,-0.100408 0.9030766,-0.490141 0.9030766,-0.490141 l 0,0 c 0,0 -0.5459891,0.528424 -0.6740006,0.631965 l 0,0 c -1.2275229,1.005988 -2.1337362,2.2718 -2.1111425,2.762564 l 0,0 0.00437,0.04265 c 1.0430672,-0.148719 2.6069697,-2.271187 4.6177021,-6.205417 m 0.6369822,0.326336 C 7.4850166,12.266842 7.156801,12.852992 6.8536863,13.391448 l 0,0 C 8.5299255,12.689213 10.33419,12.239865 12.051848,11.920429 l 0,0 c -0.23094,-0.159484 -0.454977,-0.328215 -0.665855,-0.506443 l 0,0 C 10.440248,10.613209 9.7191732,9.6141206 9.196409,8.562942 l 0,0 C 8.8650521,9.4559636 8.4709445,10.40486 7.8207804,11.634266"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M3 3v14h14V6l-3-3zm2 2h4v3h2V5h2l2 2v8H5z"/>
</svg>

After

Width:  |  Height:  |  Size: 158 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M6 4l9 6-9 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 130 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M 8.59375 3 L 8 5.09375 L 6.84375 5.8125 L 4.625 5.34375 L 3.21875 7.65625 L 4.84375 9.3125 L 4.84375 10.6875 L 3.21875 12.34375 L 4.625 14.65625 L 6.84375 14.1875 L 8 14.90625 L 8.59375 17 L 11.40625 17 L 12.09375 14.90625 L 13.15625 14.1875 L 15.375 14.65625 L 16.78125 12.34375 L 15.25 10.6875 L 15.25 9.3125 L 16.78125 7.65625 L 15.375 5.34375 L 13.15625 5.8125 L 12.09375 5.09375 L 11.40625 3 L 8.59375 3 z M 10 7.5 C 11.380712 7.5 12.5 8.6192881 12.5 10 C 12.5 11.380712 11.380712 12.5 10 12.5 C 8.6192881 12.5 7.5 11.380712 7.5 10 C 7.5 8.6192881 8.6192881 7.5 10 7.5 z"/>
</svg>

After

Width:  |  Height:  |  Size: 693 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M3 2v16h14V6l-4-4zm2 2h7l3 3v9H5z"/>
</svg>

After

Width:  |  Height:  |  Size: 150 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M2 3v14h16V5h-8L8 3H2zm14 4v8H8l8-8z"/>
</svg>

After

Width:  |  Height:  |  Size: 153 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M9 4l-6 6 6 6 1.4-1.4L6.8 11H16V9H6.8l3.6-3.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 163 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M2 3v14h16V5h-8L8 3z"/>
</svg>

After

Width:  |  Height:  |  Size: 137 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M8 8l3 4.712L13 11l4 5H3zm8-2a2 2 0 1 1-4 0 2 2 0 1 1 4 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M4 3v2h12V3zm0 4v2h8V7zm0 4v2h12v-2zm0 4v2h6v-2z"/>
</svg>

After

Width:  |  Height:  |  Size: 165 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M6 4l9 6-9 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 130 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#555" d="M3 2v16h14V6l-4-4zm2 2h7l3 3v9H5z"/>
</svg>

After

Width:  |  Height:  |  Size: 150 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" version="1.1">
<path d="M20 11h-12.17l5.59-5.59-1.42-1.41-8 8 8 8 1.41-1.41-5.58-5.59h12.17v-2z" fill="#555"/>
</svg>

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" version="1.1">
<path d="M10 6l-1.4 1.4 4.6 4.6-4.6 4.6 1.4 1.4 6-6z" fill="#555"/>
</svg>

After

Width:  |  Height:  |  Size: 174 B

Some files were not shown because too many files have changed in this diff Show More