更新初始化文件
|
@ -17,48 +17,48 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher {
|
public class RetryLimitCredentialsMatcher extends HashedCredentialsMatcher {
|
||||||
|
|
||||||
private Cache<String, AtomicInteger> loginRetryCache;
|
private Cache<String, AtomicInteger> loginRetryCache;
|
||||||
|
|
||||||
private int maxRetryCount = 5;
|
private int maxRetryCount = 5;
|
||||||
|
|
||||||
public void setMaxRetryCount(int maxRetryCount) {
|
public void setMaxRetryCount(int maxRetryCount) {
|
||||||
this.maxRetryCount = maxRetryCount;
|
this.maxRetryCount = maxRetryCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RetryLimitCredentialsMatcher() {
|
public RetryLimitCredentialsMatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cacheManager
|
* @param cacheManager
|
||||||
* @param maxRetryCount 最大尝试次数
|
* @param maxRetryCount 最大尝试次数
|
||||||
*/
|
*/
|
||||||
public RetryLimitCredentialsMatcher(CacheManager cacheManager, int maxRetryCount) {
|
public RetryLimitCredentialsMatcher(CacheManager cacheManager, int maxRetryCount) {
|
||||||
this.maxRetryCount = maxRetryCount;
|
this.maxRetryCount = maxRetryCount;
|
||||||
this.loginRetryCache = cacheManager.getCache("loginRetryCache");
|
this.loginRetryCache = cacheManager.getCache("loginRetryCache");
|
||||||
}
|
}
|
||||||
|
|
||||||
public RetryLimitCredentialsMatcher(CacheManager cacheManager) {
|
public RetryLimitCredentialsMatcher(CacheManager cacheManager) {
|
||||||
this(cacheManager, 5);
|
this(cacheManager, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
|
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
|
||||||
String username = (String) token.getPrincipal();
|
String username = (String) token.getPrincipal();
|
||||||
//retry count + 1
|
//retry count + 1
|
||||||
AtomicInteger retryCount = loginRetryCache.get(username) == null ? new AtomicInteger(0) : loginRetryCache.get(username);
|
AtomicInteger retryCount = loginRetryCache.get(username) == null ? new AtomicInteger(0) : loginRetryCache.get(username);
|
||||||
log.info("retryCount:{}, username:{}", retryCount, username);
|
log.info("retryCount:{}, username:{}", retryCount, username);
|
||||||
if (retryCount.incrementAndGet() > this.maxRetryCount) {
|
if (retryCount.incrementAndGet() > this.maxRetryCount) {
|
||||||
log.warn("username: {} tried to login more than {} times in perid", username, this.maxRetryCount);
|
log.warn("username: {} tried to login more than {} times in perid", username, this.maxRetryCount);
|
||||||
throw new ExcessiveAttemptsException("username: " + username + "tried to login more than " + this.maxRetryCount + " times in perid");
|
throw new ExcessiveAttemptsException("username: " + username + "tried to login more than " + this.maxRetryCount + " times in perid");
|
||||||
}
|
}
|
||||||
boolean matches = super.doCredentialsMatch(token, info);
|
boolean matches = super.doCredentialsMatch(token, info);
|
||||||
|
|
||||||
if (matches) {
|
if (matches) {
|
||||||
loginRetryCache.remove(username);
|
loginRetryCache.remove(username);
|
||||||
} else {
|
} else {
|
||||||
loginRetryCache.put(username, retryCount);
|
loginRetryCache.put(username, retryCount);
|
||||||
log.info(String.valueOf(retryCount.get()));
|
log.info(String.valueOf(retryCount.get()));
|
||||||
}
|
}
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,74 +10,74 @@ import java.io.*;
|
||||||
*/
|
*/
|
||||||
public class SerializeUtils {
|
public class SerializeUtils {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
|
private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反序列化
|
* 反序列化
|
||||||
*
|
*
|
||||||
* @param bytes
|
* @param bytes
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Object deserialize(byte[] bytes) {
|
public static Object deserialize(byte[] bytes) {
|
||||||
|
|
||||||
Object result = null;
|
Object result = null;
|
||||||
|
|
||||||
if (isEmpty(bytes)) {
|
if (isEmpty(bytes)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
|
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
|
||||||
try {
|
try {
|
||||||
ObjectInputStream objectInputStream = new ObjectInputStream(byteStream);
|
ObjectInputStream objectInputStream = new ObjectInputStream(byteStream);
|
||||||
try {
|
try {
|
||||||
result = objectInputStream.readObject();
|
result = objectInputStream.readObject();
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
throw new Exception("Failed to deserialize object type", ex);
|
throw new Exception("Failed to deserialize object type", ex);
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new Exception("Failed to deserialize", ex);
|
throw new Exception("Failed to deserialize", ex);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to deserialize", e);
|
logger.error("Failed to deserialize", e);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isEmpty(byte[] data) {
|
public static boolean isEmpty(byte[] data) {
|
||||||
return (data == null || data.length == 0);
|
return (data == null || data.length == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化
|
* 序列化
|
||||||
*
|
*
|
||||||
* @param object
|
* @param object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static byte[] serialize(Object object) {
|
public static byte[] serialize(Object object) {
|
||||||
|
|
||||||
byte[] result = null;
|
byte[] result = null;
|
||||||
|
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
|
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
|
||||||
try {
|
try {
|
||||||
if (!(object instanceof Serializable)) {
|
if (!(object instanceof Serializable)) {
|
||||||
throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
|
throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
|
||||||
"but received an object of type [" + object.getClass().getName() + "]");
|
"but received an object of type [" + object.getClass().getName() + "]");
|
||||||
}
|
}
|
||||||
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
|
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
|
||||||
objectOutputStream.writeObject(object);
|
objectOutputStream.writeObject(object);
|
||||||
objectOutputStream.flush();
|
objectOutputStream.flush();
|
||||||
result = byteStream.toByteArray();
|
result = byteStream.toByteArray();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new Exception("Failed to serialize", ex);
|
throw new Exception("Failed to serialize", ex);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.error("Failed to serialize", ex);
|
logger.error("Failed to serialize", ex);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,9 +33,9 @@ public class SysLoginController {
|
||||||
* @param model
|
* @param model
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/welcome")
|
@GetMapping("/welcome-ui")
|
||||||
public String welcomeUI(Model model) {
|
public String welcomeUI(Model model) {
|
||||||
return "admin/welcome";
|
return "welcome";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,4 +65,15 @@ public class SysToolController extends BaseController {
|
||||||
return "system/tool/editor";
|
return "system/tool/editor";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 颜色选择
|
||||||
|
*
|
||||||
|
* @param model
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/form-step-ui")
|
||||||
|
public String formStepUI(Model model) {
|
||||||
|
return "system/tool/formStep";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@ import com.songpeng.sparchetype.common.Result;
|
||||||
import com.songpeng.sparchetype.system.config.shiro.SpUsernamePasswordToken;
|
import com.songpeng.sparchetype.system.config.shiro.SpUsernamePasswordToken;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.*;
|
||||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
|
||||||
import org.apache.shiro.crypto.hash.Md5Hash;
|
import org.apache.shiro.crypto.hash.Md5Hash;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -57,7 +56,25 @@ public class SysLoginController {
|
||||||
try {
|
try {
|
||||||
subject.login(token);
|
subject.login(token);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
} catch (AuthenticationException e) {
|
} catch (LockedAccountException e) {
|
||||||
|
log.error("锁定的帐号", e);
|
||||||
|
return Result.failure("锁定的帐号");
|
||||||
|
} catch (DisabledAccountException e) {
|
||||||
|
log.error("禁用的帐号", e);
|
||||||
|
return Result.failure("禁用的帐号");
|
||||||
|
} catch (UnknownAccountException e) {
|
||||||
|
log.error("错误的帐号", e);
|
||||||
|
return Result.failure("错误的帐号");
|
||||||
|
} catch (ExcessiveAttemptsException e) {
|
||||||
|
log.error("登录失败次数过多", e);
|
||||||
|
return Result.failure("登录失败次数过多");
|
||||||
|
}catch (IncorrectCredentialsException e) {
|
||||||
|
log.error("错误的凭证", e);
|
||||||
|
return Result.failure("错误的凭证");
|
||||||
|
}catch (ExpiredCredentialsException e) {
|
||||||
|
log.error("过期的凭证", e);
|
||||||
|
return Result.failure("过期的凭证");
|
||||||
|
}catch (AuthenticationException e) {
|
||||||
log.error("用户或密码错误", e);
|
log.error("用户或密码错误", e);
|
||||||
return Result.failure("用户或密码错误");
|
return Result.failure("用户或密码错误");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/**
|
|
||||||
* date:2019/08/16
|
|
||||||
* author:Mr.Chung
|
|
||||||
* description:此处放layui自定义扩展
|
|
||||||
*/
|
|
||||||
|
|
||||||
window.rootPath = (function (src) {
|
|
||||||
src = document.scripts[document.scripts.length - 1].src;
|
|
||||||
return src.substring(0, src.lastIndexOf("/") + 1);
|
|
||||||
})();
|
|
||||||
|
|
||||||
layui.config({
|
|
||||||
base: rootPath + "lay-module/",
|
|
||||||
version: true
|
|
||||||
}).extend({
|
|
||||||
layuimini: "layuimini/layuimini", // layuimini扩展
|
|
||||||
step: 'step-lay/step', // 分步表单扩展
|
|
||||||
treetable: 'treetable-lay/treetable', //table树形扩展
|
|
||||||
tableSelect: 'tableSelect/tableSelect', // table选择扩展
|
|
||||||
iconPickerFa: 'iconPicker/iconPickerFa', // fa图标选择扩展
|
|
||||||
echarts: 'echarts/echarts', // echarts图表扩展
|
|
||||||
echartsTheme: 'echarts/echartsTheme', // echarts图表主题扩展
|
|
||||||
wangEditor: 'wangEditor/wangEditor', // wangEditor富文本扩展
|
|
||||||
});
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* date:2019/08/16
|
||||||
|
* author:Mr.Chung
|
||||||
|
* description:此处放layui自定义扩展
|
||||||
|
*/
|
||||||
|
window.rootPath = (function (src) {
|
||||||
|
src = document.scripts[document.scripts.length - 1].src;
|
||||||
|
return src.substring(0, src.lastIndexOf("/") + 1);
|
||||||
|
})();
|
||||||
|
|
||||||
|
layui.config({
|
||||||
|
base: rootPath,
|
||||||
|
version: true
|
||||||
|
}).extend({
|
||||||
|
// layuimini扩展
|
||||||
|
layuimini: "layuimini/layuimini",
|
||||||
|
// 分步表单扩展
|
||||||
|
step: 'step-lay/step',
|
||||||
|
//table树形扩展
|
||||||
|
treetable: 'treetable-lay/treetable',
|
||||||
|
// table选择扩展
|
||||||
|
tableSelect: 'tableSelect/tableSelect',
|
||||||
|
// fa图标选择扩展
|
||||||
|
iconPickerFa: 'iconPicker/iconPickerFa',
|
||||||
|
// echarts图表扩展
|
||||||
|
echarts: 'echarts/echarts',
|
||||||
|
// echarts图表主题扩展
|
||||||
|
echartsTheme: 'echarts/echartsTheme',
|
||||||
|
// wangEditor富文本扩展
|
||||||
|
wangEditor: 'wangEditor/wangEditor',
|
||||||
|
// 自定义layer扩展组件
|
||||||
|
spLayer: 'spLayer/spLayer'
|
||||||
|
});
|
|
@ -3,7 +3,6 @@
|
||||||
* author:Mr.Chung
|
* author:Mr.Chung
|
||||||
* description:layuimini 框架扩展
|
* description:layuimini 框架扩展
|
||||||
*/
|
*/
|
||||||
|
|
||||||
layui.define(["element", "jquery"], function (exports) {
|
layui.define(["element", "jquery"], function (exports) {
|
||||||
var element = layui.element,
|
var element = layui.element,
|
||||||
$ = layui.$,
|
$ = layui.$,
|
||||||
|
@ -27,7 +26,7 @@ layui.define(["element", "jquery"], function (exports) {
|
||||||
urlHashLocation: true, // URL地址hash定位
|
urlHashLocation: true, // URL地址hash定位
|
||||||
urlSuffixDefault: true, // URL后缀
|
urlSuffixDefault: true, // URL后缀
|
||||||
BgColorDefault: 0, // 默认皮肤(0开始)
|
BgColorDefault: 0, // 默认皮肤(0开始)
|
||||||
checkUrlDefault: true, // 是否判断URL有效
|
checkUrlDefault: true // 是否判断URL有效
|
||||||
};
|
};
|
||||||
|
|
||||||
if (name == undefined) {
|
if (name == undefined) {
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* date:2019/12/24
|
||||||
|
* author:SongPeng
|
||||||
|
* description:扩展layui弹出框 框架扩展
|
||||||
|
*/
|
||||||
|
layui.define(['layer'], function (exports) {
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
var spLayer = {
|
||||||
|
// 渲染弹出框
|
||||||
|
open: function (param) {
|
||||||
|
console.log(param);
|
||||||
|
var config = {};
|
||||||
|
$.extend(config, param, {
|
||||||
|
// 这里写默认配置,会覆盖自定义配置 param
|
||||||
|
});
|
||||||
|
layer.open(config);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports('spLayer', spLayer);
|
||||||
|
});
|
|
@ -1,4 +1,9 @@
|
||||||
layui.define(['layer', 'carousel'], function (exports) {
|
/**
|
||||||
|
* date:2019/06/10
|
||||||
|
* author:Mr.Chung
|
||||||
|
* description:分步表单 框架扩展
|
||||||
|
*/
|
||||||
|
layui.define(['layer', 'carousel'], function (exports) {
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var carousel = layui.carousel;
|
var carousel = layui.carousel;
|
|
@ -0,0 +1,6 @@
|
||||||
|
// 工具类
|
||||||
|
var spUtil = {};
|
||||||
|
|
||||||
|
spUtil.open = function () {
|
||||||
|
|
||||||
|
};
|
|
@ -5,7 +5,7 @@
|
||||||
"homeInfo": {
|
"homeInfo": {
|
||||||
"title": "首页",
|
"title": "首页",
|
||||||
"icon": "fa fa-home",
|
"icon": "fa fa-home",
|
||||||
"href": "page/welcome-ui?mpi=m-p-i-0"
|
"href": "admin/welcome-ui"
|
||||||
},
|
},
|
||||||
"logoInfo": {
|
"logoInfo": {
|
||||||
"title": "后台管理",
|
"title": "后台管理",
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "分步表单",
|
"title": "分步表单",
|
||||||
"href": "page/form-step.html",
|
"href": "/admin/sys/tool/form-step-ui",
|
||||||
"icon": "fa fa-navicon",
|
"icon": "fa fa-navicon",
|
||||||
"target": "_self"
|
"target": "_self"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
/** layui-v2.5.4 MIT License By https://www.layui.com */
|
/** layui-v2.5.5 MIT License By https://www.layui.com */
|
||||||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}
|
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 701 B After Width: | Height: | Size: 701 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 277 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |