Compare commits
2 Commits
e9807ebf07
...
654c31db23
Author | SHA1 | Date |
---|---|---|
![]() |
654c31db23 | |
![]() |
869db702f3 |
|
@ -2,6 +2,10 @@ package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.sm.SM2EngineExtend;
|
||||||
|
import com.ruoyi.common.utils.sm.SM2Utils;
|
||||||
|
import com.ruoyi.common.utils.sm.SM2crypto;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
@ -56,6 +60,8 @@ public class SysLoginController extends BaseController
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
|
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
|
||||||
{
|
{
|
||||||
|
System.out.println(super.getRequest().getHeader( "user-agent" ));
|
||||||
|
password = SM2Utils.decrypt(SM2crypto.priKey, password, SM2EngineExtend.CIPHERMODE_BC);//sm2私钥解密
|
||||||
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
|
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
|
||||||
Subject subject = SecurityUtils.getSubject();
|
Subject subject = SecurityUtils.getSubject();
|
||||||
try
|
try
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
.skin-light .navbar .nav .open>a:focus,
|
.skin-light .navbar .nav .open>a:focus,
|
||||||
.skin-light .navbar .nav>.active>a {
|
.skin-light .navbar .nav>.active>a {
|
||||||
background: #0D6EFD;
|
background: #0D6EFD;
|
||||||
|
box-shadow: 0px 0px 5px #333333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-light .navbar .sidebar-toggle {
|
.skin-light .navbar .sidebar-toggle {
|
||||||
|
@ -69,7 +70,8 @@
|
||||||
.skin-light .logo {
|
.skin-light .logo {
|
||||||
background-color: #0D6EFD;
|
background-color: #0D6EFD;
|
||||||
/*color: #63686e;*/
|
/*color: #63686e;*/
|
||||||
border-bottom: 0 solid transparent
|
border-bottom: 0 solid transparent;
|
||||||
|
line-height: 46px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-light li.user-header {
|
.skin-light li.user-header {
|
||||||
|
|
|
@ -134,7 +134,7 @@ body.body-small .navbar-top-links li:last-child {
|
||||||
|
|
||||||
.dropdown-menu>li>a {
|
.dropdown-menu>li>a {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
color: inherit;
|
color: #777;
|
||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
|
@ -99,17 +99,49 @@ angular.module('flowableModeler').controller('FlowableTextPropertyCtrl', [ '$sco
|
||||||
$scope.property.mode = 'read';
|
$scope.property.mode = 'read';
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Open the dialog
|
// Open the dialog
|
||||||
_internalCreateModal(opts, $modal, $scope);
|
_internalCreateModal(opts, $modal, $scope);
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
angular.module('flowableModeler').controller('FlowableTextPropertyPopupCtrl', ['$scope', function($scope) {
|
angular.module('flowableModeler').controller('FlowableTextPropertyPopupCtrl', ['$scope', function($scope) {
|
||||||
|
|
||||||
$scope.save = function() {
|
$scope.save = function() {
|
||||||
$scope.updatePropertyInModel($scope.property);
|
$scope.updatePropertyInModel($scope.property);
|
||||||
$scope.close();
|
$scope.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.close = function() {
|
||||||
|
$scope.property.mode = 'read';
|
||||||
|
$scope.$hide();
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Json Text controller
|
||||||
|
*/
|
||||||
|
angular.module('flowableModeler').controller('FlowableJsonTextPropertyCtrl', [ '$scope', '$modal', '$timeout', function($scope, $modal, $timeout) {
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
template: 'editor-app/configuration/properties/jsontext-popup.html?version=' + Date.now(),
|
||||||
|
scope: $scope,
|
||||||
|
prefixEvent: 'jsonTextModalEvent'
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.$on('jsonTextModalEvent.hide.before', function() {
|
||||||
|
$timeout(function() {
|
||||||
|
$scope.property.mode = 'read';
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Open the dialog
|
||||||
|
_internalCreateModal(opts, $modal, $scope);
|
||||||
|
}]);
|
||||||
|
angular.module('flowableModeler').controller('FlowableJsonTextPropertyPopupCtrl', ['$scope', function($scope) {
|
||||||
|
|
||||||
|
$scope.save = function() {
|
||||||
|
$scope.updatePropertyInModel($scope.property);
|
||||||
|
$scope.close();
|
||||||
|
};
|
||||||
|
|
||||||
$scope.close = function() {
|
$scope.close = function() {
|
||||||
$scope.property.mode = 'read';
|
$scope.property.mode = 'read';
|
||||||
|
|
|
@ -26,6 +26,10 @@ FLOWABLE.PROPERTY_CONFIG =
|
||||||
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
|
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
|
||||||
"writeModeTemplateUrl": "editor-app/configuration/properties/text-property-write-template.html"
|
"writeModeTemplateUrl": "editor-app/configuration/properties/text-property-write-template.html"
|
||||||
},
|
},
|
||||||
|
"jsontext" : {
|
||||||
|
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
|
||||||
|
"writeModeTemplateUrl": "editor-app/configuration/properties/jsontext-property-write-template.html"
|
||||||
|
},
|
||||||
"flowable-calledelementtype" : {
|
"flowable-calledelementtype" : {
|
||||||
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
|
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
|
||||||
"writeModeTemplateUrl": "editor-app/configuration/properties/calledelementtype-property-write-template.html"
|
"writeModeTemplateUrl": "editor-app/configuration/properties/calledelementtype-property-write-template.html"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
<div class="modal" ng-controller="FlowableJsonTextPropertyPopupCtrl">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-click="close()">×</button>
|
||||||
|
<h3>{{'PROPERTY.PROPERTY.EDIT.TITLE' | translate}} "{{property.title | translate}}"</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div ng-jsoneditor auto-focus
|
||||||
|
class="form-control"
|
||||||
|
ng-model="property.value"
|
||||||
|
options="{ mode: 'text' }"
|
||||||
|
style="width:100%; height:100%; "></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button ng-click="save()" class="btn btn-primary" translate >ACTION.SAVE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
<!-- Just need to instantiate the controller, and it will take care of showing the modal dialog -->
|
||||||
|
<span ng-controller="FlowableJsonTextPropertyCtrl">
|
||||||
|
</span>
|
|
@ -17,6 +17,24 @@
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 整个滚动条 */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
/* 对应纵向滚动条的宽度 */
|
||||||
|
width: 10px;
|
||||||
|
/* 对应横向滚动条的宽度 */
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
/* 滚动条上的滚动滑块 */
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #49b1f5;
|
||||||
|
border-radius: 32px;
|
||||||
|
}
|
||||||
|
/* 滚动条轨道 */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background-color: #dbeffd;
|
||||||
|
border-radius: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.row-no-gutter .col-xs-9,
|
.row-no-gutter .col-xs-9,
|
||||||
.row-no-gutter .col-xs-12 {
|
.row-no-gutter .col-xs-12 {
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
|
@ -188,7 +206,7 @@
|
||||||
-------------------------------- */
|
-------------------------------- */
|
||||||
div.canvas-wrapper {
|
div.canvas-wrapper {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: #F8F8F8;
|
background-color: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas_resize_indicator i {
|
.canvas_resize_indicator i {
|
||||||
|
@ -241,7 +259,7 @@ div.canvas-wrapper {
|
||||||
|
|
||||||
div.propertySection {
|
div.propertySection {
|
||||||
height: 250px;
|
height: 250px;
|
||||||
background-color: #e8edf1;
|
background-color: #ffffff;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,6 +268,7 @@ div.propertySection {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 2px 0 2px 8px;
|
padding: 2px 0 2px 8px;
|
||||||
border-bottom: 1px solid #a4acb9;
|
border-bottom: 1px solid #a4acb9;
|
||||||
|
border-top: 1px solid #a4acb9;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +356,7 @@ div.propertySection {
|
||||||
}
|
}
|
||||||
|
|
||||||
.propertySection.collapsed .selected-item-title {
|
.propertySection.collapsed .selected-item-title {
|
||||||
border: none;
|
/*border: none;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.property-row input[type="text"] {
|
.property-row input[type="text"] {
|
||||||
|
@ -1123,7 +1142,7 @@ hot-table .column-header.label {
|
||||||
#paletteSectionFooter {
|
#paletteSectionFooter {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #e8edf1;
|
background-color: #ffffff;
|
||||||
border-top: 1px solid #a4acb9;
|
border-top: 1px solid #a4acb9;
|
||||||
border-right: 1px solid #a4acb9;
|
border-right: 1px solid #a4acb9;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -1137,7 +1156,7 @@ hot-table .column-header.label {
|
||||||
#paletteSectionOpen {
|
#paletteSectionOpen {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
background-color: #e8edf1;
|
background-color: #ffffff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
bottom: 1px;
|
bottom: 1px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -1181,6 +1200,7 @@ hot-table .column-header.label {
|
||||||
background: #f3f3f3;
|
background: #f3f3f3;
|
||||||
border-right: 1px solid #bbbbbb;
|
border-right: 1px solid #bbbbbb;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
display: none;/*隐藏左边树下部分*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.process-treeview-header {
|
.process-treeview-header {
|
||||||
|
|
|
@ -255,7 +255,7 @@ angular.module('flowableModeler')
|
||||||
canvas.height(totalAvailable - propSectionHeight);
|
canvas.height(totalAvailable - propSectionHeight);
|
||||||
var footerHeight = jQuery('#paletteSectionFooter').height();
|
var footerHeight = jQuery('#paletteSectionFooter').height();
|
||||||
var treeViewHeight = jQuery('#process-treeview-wrapper').height();
|
var treeViewHeight = jQuery('#process-treeview-wrapper').height();
|
||||||
jQuery('#paletteSection').height(totalAvailable - treeViewHeight - footerHeight-15);
|
jQuery('#paletteSection').height(totalAvailable/* - treeViewHeight*/ - footerHeight-15);//隐藏左边树下部分
|
||||||
|
|
||||||
// Update positions of the resize-markers, according to the canvas
|
// Update positions of the resize-markers, according to the canvas
|
||||||
|
|
||||||
|
|
|
@ -626,6 +626,7 @@ angular.module('flowableModeler')
|
||||||
return $scope.selectedItem.properties[index].templateUrl;
|
return $scope.selectedItem.properties[index].templateUrl;
|
||||||
};
|
};
|
||||||
$scope.getPropertyReadModeTemplateUrl = function (index) {
|
$scope.getPropertyReadModeTemplateUrl = function (index) {
|
||||||
|
//debugger
|
||||||
return $scope.selectedItem.properties[index].readModeTemplateUrl;
|
return $scope.selectedItem.properties[index].readModeTemplateUrl;
|
||||||
};
|
};
|
||||||
$scope.getPropertyWriteModeTemplateUrl = function (index) {
|
$scope.getPropertyWriteModeTemplateUrl = function (index) {
|
||||||
|
|
|
@ -348,7 +348,7 @@
|
||||||
"name" : "jsontextpackage",
|
"name" : "jsontextpackage",
|
||||||
"properties" : [ {
|
"properties" : [ {
|
||||||
"id" : "jsontext",
|
"id" : "jsontext",
|
||||||
"type" : "Text",
|
"type" : "JsonText",
|
||||||
"title" : "JSON报文",
|
"title" : "JSON报文",
|
||||||
"value" : "",
|
"value" : "",
|
||||||
"description" : "JSON报文文本",
|
"description" : "JSON报文文本",
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<link href="styles/common/style-retina.css" rel="stylesheet">
|
<link href="styles/common/style-retina.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="styles/style-editor.css">
|
<link rel="stylesheet" href="styles/style-editor.css">
|
||||||
<!-- endbuild -->
|
<!-- endbuild -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.3/jsoneditor.min.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body ng-app="flowableModeler" ng-cloak>
|
<body ng-app="flowableModeler" ng-cloak>
|
||||||
<!--导航头,可以删除掉-->
|
<!--导航头,可以删除掉-->
|
||||||
|
@ -274,5 +274,7 @@
|
||||||
<!-- Integration extensions -->
|
<!-- Integration extensions -->
|
||||||
<script src="scripts/resource-loader.js?v=2" app="editor"></script>
|
<script src="scripts/resource-loader.js?v=2" app="editor"></script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.10.3/jsoneditor.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-jsoneditor/1.0.0/ng-jsoneditor.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -32,7 +32,8 @@ var flowableModeler = angular.module('flowableModeler', [
|
||||||
'angularSpectrumColorpicker',
|
'angularSpectrumColorpicker',
|
||||||
'duScroll',
|
'duScroll',
|
||||||
'dndLists',
|
'dndLists',
|
||||||
'ngHandsontable'
|
'ngHandsontable',
|
||||||
|
'ng.jsoneditor'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var flowableModule = flowableModeler;
|
var flowableModule = flowableModeler;
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -14,10 +14,12 @@ $.validator.setDefaults({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var pubkeyHex = "04c06ff757285f47a74c85dc3574a7a144d71b8328da1f251d606855588881bd028d258fea53df0c89df8d1f82ee31257842ceb197fb74592decc9854ba72b693f";
|
||||||
function login() {
|
function login() {
|
||||||
$.modal.loading($("#btnSubmit").data("loading"));
|
$.modal.loading($("#btnSubmit").data("loading"));
|
||||||
var username = $.common.trim($("input[name='username']").val());
|
var username = $.common.trim($("input[name='username']").val());
|
||||||
var password = $.common.trim($("input[name='password']").val());
|
var password = $.common.trim($("input[name='password']").val());
|
||||||
|
var sm2Password = sm2Encrypt(password, pubkeyHex, 0);
|
||||||
var validateCode = $("input[name='validateCode']").val();
|
var validateCode = $("input[name='validateCode']").val();
|
||||||
var rememberMe = $("input[name='rememberme']").is(':checked');
|
var rememberMe = $("input[name='rememberme']").is(':checked');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -25,7 +27,7 @@ function login() {
|
||||||
url: ctx + "login",
|
url: ctx + "login",
|
||||||
data: {
|
data: {
|
||||||
"username": username,
|
"username": username,
|
||||||
"password": password,
|
"password": sm2Password,
|
||||||
"validateCode": validateCode,
|
"validateCode": validateCode,
|
||||||
"rememberMe": rememberMe
|
"rememberMe": rememberMe
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
<i class="fa-solid fa-xmark"></i>
|
<i class="fa-solid fa-xmark"></i>
|
||||||
</div>
|
</div>
|
||||||
<li class="logo hidden-xs">
|
<li class="logo hidden-xs">
|
||||||
<span class="logo-lg" th:text="${ruoYiConfig.name }"></span>
|
<img th:src="@{/img/logo_bai_tou.png}" style="height: 80%;">
|
||||||
|
<!--span class="logo-lg" th:text="${ruoYiConfig.name }"></span-->
|
||||||
</li>
|
</li>
|
||||||
<div class="sidebar-collapse tab-content" id="side-menu">
|
<div class="sidebar-collapse tab-content" id="side-menu">
|
||||||
<!--div class="user-panel">
|
<!--div class="user-panel">
|
||||||
|
@ -204,10 +205,10 @@
|
||||||
|
|
||||||
<!--右侧部分开始-->
|
<!--右侧部分开始-->
|
||||||
<div id="page-wrapper" class="gray-bg dashbard-1">
|
<div id="page-wrapper" class="gray-bg dashbard-1">
|
||||||
<div class="row" style="background-color: transparent">
|
<div class="row" style="background-color: #0D6EFD;">
|
||||||
<nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0">
|
<nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<a class="navbar-minimalize minimalize-styl-2" style="color:#495057;" href="#" title="收起菜单">
|
<a class="navbar-minimalize minimalize-styl-2" style="color:#FFFFFF;" href="#" title="收起菜单">
|
||||||
<i class="fa-solid fa-bars"></i>
|
<i class="fa-solid fa-bars"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
<!--[if lte IE 8]><script>window.location.href=ctx+'html/ie.html';</script><![endif]-->
|
<!--[if lte IE 8]><script>window.location.href=ctx+'html/ie.html';</script><![endif]-->
|
||||||
<!-- 全局js -->
|
<!-- 全局js -->
|
||||||
<script th:src="@{/js/jquery.min.js}"></script>
|
<script th:src="@{/js/jquery.min.js}"></script>
|
||||||
|
<script th:src="@{/js/crypto-js.js}"></script>
|
||||||
|
<script th:src="@{/js/sm2.js}"></script>
|
||||||
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
|
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
|
||||||
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
|
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
|
||||||
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
|
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
|
||||||
|
|
|
@ -4,6 +4,6 @@ import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class SM2crypto {
|
public class SM2crypto {
|
||||||
public static String pubKey = "04ebe49444321237d1d2415427a78b73ab1661e11a511221ac635546f647e44347332857b37f59705c6b95dbd9fcf0188f830946ac156b64c0e30623c3a0500342";
|
public static String pubKey = "04c06ff757285f47a74c85dc3574a7a144d71b8328da1f251d606855588881bd028d258fea53df0c89df8d1f82ee31257842ceb197fb74592decc9854ba72b693f";
|
||||||
public static String priKey = "7a70604a24c35fbdd099a84307bff1196eb9955280cc98cadcd18442ba3e3a83";
|
public static String priKey = "afdf6d44466de149e52a0438634a14559f98d16566ee033d167f380e9cfa1e6c";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue