ol-base-components 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/App.vue +496 -329
- package/src/api/api.js +30 -44
- package/src/api/run.js +12 -20
- package/src/bin/add.js +235 -41
- package/src/bin/initTemplate.js +196 -66
- package/src/package/form/index.js +4 -4
- package/src/package/form/src/index.vue +14 -2
- package/src/package/index.js +4 -3
- package/src/utils/initData.js +84 -0
- package/public/index.js +0 -59941
package/src/bin/initTemplate.js
CHANGED
|
@@ -5,12 +5,9 @@ function generateKeyName(url, method) {
|
|
|
5
5
|
|
|
6
6
|
// 处理 {xxx} 转换为 ByXxx
|
|
7
7
|
const processedArr = arr.map(
|
|
8
|
-
|
|
8
|
+
item =>
|
|
9
9
|
item
|
|
10
|
-
.replace(
|
|
11
|
-
/{(.*?)}/,
|
|
12
|
-
(_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`
|
|
13
|
-
) // 处理 {xxx}
|
|
10
|
+
.replace(/{(.*?)}/, (_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`) // 处理 {xxx}
|
|
14
11
|
.replace(/[-_]/g, "") // 去除 - 和 _
|
|
15
12
|
);
|
|
16
13
|
|
|
@@ -24,25 +21,132 @@ function generateKeyName(url, method) {
|
|
|
24
21
|
for (let i = 0; i < processedArr.length; i++) {
|
|
25
22
|
if (i === 0 || processedArr[i] !== processedArr[i - 1]) {
|
|
26
23
|
// 将每项首字母大写
|
|
27
|
-
const capitalizedItem =
|
|
28
|
-
processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
|
|
24
|
+
const capitalizedItem = processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
|
|
29
25
|
resultArr.push(capitalizedItem);
|
|
30
26
|
}
|
|
31
27
|
}
|
|
32
28
|
const key = resultArr.join("");
|
|
33
29
|
return `${method.toLowerCase()}${key}`;
|
|
34
30
|
}
|
|
31
|
+
const vue2Template = (moduleName, config = {}) => {
|
|
32
|
+
console.log(888, config);
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
// 生成各种接口的key名称
|
|
35
|
+
let pageUrlKey = "";
|
|
36
|
+
let exportUrlKey = "";
|
|
37
|
+
let addUrlKey = "";
|
|
38
|
+
let editUrlKey = "";
|
|
39
|
+
let deleteUrlKey = "";
|
|
40
|
+
let detailUrlKey = "";
|
|
41
|
+
|
|
42
|
+
if (config.pageUrl) pageUrlKey = generateKeyName(config.pageUrl, "get");
|
|
43
|
+
if (config.exportUrl) exportUrlKey = generateKeyName(config.exportUrl, "post");
|
|
44
|
+
if (config.addUrl) addUrlKey = generateKeyName(config.addUrl, "post");
|
|
45
|
+
if (config.editUrl) editUrlKey = generateKeyName(config.editUrl, "put");
|
|
46
|
+
if (config.deleteUrl) deleteUrlKey = generateKeyName(config.deleteUrl, "delete");
|
|
47
|
+
if (config.detailUrl) detailUrlKey = generateKeyName(config.detailUrl, "get");
|
|
48
|
+
|
|
49
|
+
// 生成导入语句
|
|
50
|
+
const generateImports = () => {
|
|
51
|
+
const imports = [];
|
|
52
|
+
if (config.pageUrl) imports.push(`${pageUrlKey}`);
|
|
53
|
+
if (config.addUrl) imports.push(`${addUrlKey}`);
|
|
54
|
+
if (config.editUrl) imports.push(`${editUrlKey}`);
|
|
55
|
+
if (config.deleteUrl) imports.push(`${deleteUrlKey}`);
|
|
56
|
+
if (config.detailUrl) imports.push(`${detailUrlKey}`);
|
|
57
|
+
return imports.join(", ");
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// 生成方法
|
|
61
|
+
const generateMethods = () => {
|
|
62
|
+
const methods = [];
|
|
63
|
+
if (config.hasAdd) {
|
|
64
|
+
methods.push(`
|
|
65
|
+
addBtnHandler() {
|
|
66
|
+
this.form.type = 1;
|
|
67
|
+
this.dialogVisible = true;
|
|
68
|
+
}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// if (config.hasEdit) {
|
|
72
|
+
// methods.push(`
|
|
73
|
+
// editBtnHandler() {
|
|
74
|
+
// this.form.type = 2;
|
|
75
|
+
// this.dialogVisible = true;
|
|
76
|
+
// }`);
|
|
77
|
+
// }
|
|
78
|
+
|
|
79
|
+
if (config.hasEdit) {
|
|
80
|
+
methods.push(`
|
|
81
|
+
${config.hasDetail ? `async ` : ``}editBtnHandler() {
|
|
82
|
+
const data = this.multipleSelection;
|
|
83
|
+
if(data.length !== 1) return this.$message.info("请选择一条数据");
|
|
84
|
+
const row = data[0];
|
|
85
|
+
this.form.type = 2;
|
|
86
|
+
${
|
|
87
|
+
config.hasDetail
|
|
88
|
+
? `const { result = {} } = await ${detailUrlKey}(row.${config.idField});
|
|
89
|
+
this.form.value = result || {};`
|
|
90
|
+
: `this.form.value = { ...row };`
|
|
91
|
+
}
|
|
92
|
+
this.dialogVisible = true;
|
|
93
|
+
}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// onCancel
|
|
97
|
+
if (config.hasAdd || config.hasEdit || config.hasDetail) {
|
|
98
|
+
methods.push(`
|
|
99
|
+
onCancel() {
|
|
100
|
+
this.dialogVisible = false;
|
|
101
|
+
}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// onSubmit
|
|
105
|
+
if (config.hasAdd || config.hasEdit) {
|
|
106
|
+
// editUrlKey
|
|
107
|
+
// addUrlKey
|
|
108
|
+
methods.push(`
|
|
109
|
+
async onSubmit({ form, data }) {
|
|
110
|
+
if(form.type === 1){
|
|
111
|
+
//新建
|
|
112
|
+
const res = await ${addUrlKey}(data);
|
|
113
|
+
if(res.code !== 200) return;
|
|
114
|
+
this.$message("新建成功");
|
|
115
|
+
}else if(form.type === 2){
|
|
116
|
+
//编辑
|
|
117
|
+
const res = await ${editUrlKey}(data['${config.idField}'], data);
|
|
118
|
+
if(res.code !== 200) return;
|
|
119
|
+
this.$message("编辑成功");
|
|
120
|
+
this.init();
|
|
121
|
+
};
|
|
122
|
+
this.init();
|
|
123
|
+
this.onCancel()
|
|
124
|
+
}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (config.hasDelete) {
|
|
128
|
+
methods.push(`
|
|
129
|
+
deleteBtnHandler() {
|
|
130
|
+
const data = this.multipleSelection;
|
|
131
|
+
if(data.length !== 1) return this.$message.info("请选择一条数据");
|
|
132
|
+
const row = data[0];
|
|
133
|
+
this.$confirm('确认删除当前数据吗?', '提示', {
|
|
134
|
+
confirmButtonText: '确定',
|
|
135
|
+
cancelButtonText: '取消',
|
|
136
|
+
type: 'warning'
|
|
137
|
+
}).then(() => {
|
|
138
|
+
${deleteUrlKey}(row.${config.idField}).then(() => {
|
|
139
|
+
this.$message.success('删除成功');
|
|
140
|
+
this.init();
|
|
141
|
+
}).catch(() => {
|
|
142
|
+
this.$message.error('删除失败');
|
|
143
|
+
});
|
|
144
|
+
}).catch(() => {});
|
|
145
|
+
}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return methods.join(",");
|
|
149
|
+
};
|
|
46
150
|
|
|
47
151
|
return `<!--
|
|
48
152
|
Filename: ${moduleName}.vue
|
|
@@ -53,13 +157,13 @@ const vue2Template = (moduleName, options = {}) => {
|
|
|
53
157
|
<template>
|
|
54
158
|
<div>
|
|
55
159
|
<ol-search
|
|
56
|
-
:url="swaggerUrl.${
|
|
160
|
+
:url="swaggerUrl.${pageUrlKey}"
|
|
57
161
|
:form-search-data="formSearchData"
|
|
58
162
|
@handleSearch="handleSearch"
|
|
59
163
|
@handleReset="handleReset"
|
|
60
164
|
/>
|
|
61
165
|
<ol-table
|
|
62
|
-
:url="swaggerUrl.${
|
|
166
|
+
:url="swaggerUrl.${pageUrlKey}"
|
|
63
167
|
:paginations="paginations"
|
|
64
168
|
:btnlist="this.hasBtn(this)"
|
|
65
169
|
:empty-img="tableData.emptyImg"
|
|
@@ -69,51 +173,76 @@ const vue2Template = (moduleName, options = {}) => {
|
|
|
69
173
|
@handleSizeChange="handleSizeChange"
|
|
70
174
|
@handleindexChange="handleindexChange"
|
|
71
175
|
/>
|
|
176
|
+
${
|
|
177
|
+
config.hasAdd || config.hasEdit || config.hasDetail
|
|
178
|
+
? `<el-dialog :title="this.form.title" :visible.sync="dialogVisible" width="80%">
|
|
179
|
+
<ol-form
|
|
180
|
+
v-if="dialogVisible"
|
|
181
|
+
:url="swaggerUrl.${pageUrlKey}"
|
|
182
|
+
:form="form"
|
|
183
|
+
@onCancel="onCancel"
|
|
184
|
+
@onSubmit="onSubmit"
|
|
185
|
+
/>
|
|
186
|
+
</el-dialog>`
|
|
187
|
+
: ""
|
|
188
|
+
}
|
|
72
189
|
</div>
|
|
73
190
|
</template>
|
|
74
191
|
<script>
|
|
75
|
-
import { ${
|
|
76
|
-
import { ${
|
|
192
|
+
import { ${generateImports()} } from "@/api/modules";
|
|
193
|
+
import { ${config.swaggerModule} } from '@/api/swagger';
|
|
77
194
|
export default {
|
|
78
195
|
name: "${moduleName}",
|
|
79
196
|
data() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
197
|
+
return {
|
|
198
|
+
swaggerUrl: ${config.swaggerModule},
|
|
199
|
+
multipleSelection: [],
|
|
200
|
+
// 查询表单
|
|
201
|
+
formSearchData: {
|
|
202
|
+
reset: true, // 重置
|
|
203
|
+
expendShow: true, // 展开
|
|
204
|
+
value: {},
|
|
205
|
+
tableSearch: []
|
|
206
|
+
},
|
|
207
|
+
// 表格数据
|
|
208
|
+
tableData: {
|
|
209
|
+
loading: false,
|
|
210
|
+
emptyImg: true,
|
|
211
|
+
options: {
|
|
212
|
+
selection: true, // 多选框
|
|
213
|
+
index: null, // 序号
|
|
214
|
+
headTool: true, // 开启头部工具栏
|
|
215
|
+
refreshBtn: true, // 开启表格头部刷新按钮
|
|
216
|
+
downloadBtn: true // 开启表格头部下载按钮
|
|
217
|
+
}, // 序号和复选框
|
|
218
|
+
rows: [], // 表数据
|
|
219
|
+
columns: [],
|
|
220
|
+
operatesAttrs: {},
|
|
221
|
+
operates: [], // 表格里面的操作按钮
|
|
222
|
+
tableHeightDiff: 330
|
|
223
|
+
},
|
|
224
|
+
paginations: {
|
|
225
|
+
page: 1, // 当前位于那页面
|
|
226
|
+
total: 10, // 总数
|
|
227
|
+
limit: 30, // 一页显示多少条
|
|
228
|
+
pagetionShow: true
|
|
229
|
+
},
|
|
230
|
+
${
|
|
231
|
+
config.hasAdd || config.hasEdit || config.hasDetail
|
|
232
|
+
? `form: {
|
|
233
|
+
type: 0, // 0详情,1新增, 2编辑
|
|
234
|
+
title: "",
|
|
235
|
+
// 默认值
|
|
236
|
+
defaultValue: {},
|
|
237
|
+
value: {},
|
|
238
|
+
model: [],
|
|
239
|
+
rules: {},
|
|
240
|
+
attrs: {},
|
|
241
|
+
},
|
|
242
|
+
dialogVisible: false`
|
|
243
|
+
: ""
|
|
244
|
+
}
|
|
245
|
+
}
|
|
117
246
|
},
|
|
118
247
|
methods: {
|
|
119
248
|
async init() {
|
|
@@ -122,7 +251,7 @@ export default {
|
|
|
122
251
|
Page: this.paginations.page,
|
|
123
252
|
MaxResultCount: this.paginations.limit
|
|
124
253
|
};
|
|
125
|
-
const { result: { items = [], totalCount = 0 } = {} } = await ${
|
|
254
|
+
const { result: { items = [], totalCount = 0 } = {} } = await ${pageUrlKey}(params, {
|
|
126
255
|
isLoading: true
|
|
127
256
|
});
|
|
128
257
|
this.tableData.rows = items;
|
|
@@ -152,13 +281,15 @@ export default {
|
|
|
152
281
|
this.paginations.page = val;
|
|
153
282
|
this.init();
|
|
154
283
|
},
|
|
155
|
-
|
|
156
|
-
|
|
284
|
+
${
|
|
285
|
+
config.hasExport
|
|
286
|
+
? `export() {
|
|
287
|
+
const timer = this.formSearchData.value.createdTime
|
|
157
288
|
;
|
|
158
289
|
this.formSearchData.value.BeginTime = timer ? timer[0] : "";
|
|
159
290
|
this.formSearchData.value.EndTime = timer ? timer[1] : "";
|
|
160
291
|
this.post({
|
|
161
|
-
url: ${
|
|
292
|
+
url: ${config.swaggerModule}.${exportUrlKey},
|
|
162
293
|
isLoading: true,
|
|
163
294
|
responseType: "blob",
|
|
164
295
|
data: Object.assign(this.formSearchData.value, {
|
|
@@ -168,12 +299,11 @@ export default {
|
|
|
168
299
|
}).then(res => {
|
|
169
300
|
this.fnexsl(res);
|
|
170
301
|
});
|
|
171
|
-
}
|
|
302
|
+
},`
|
|
303
|
+
: ""
|
|
304
|
+
}${generateMethods()}
|
|
172
305
|
}
|
|
173
306
|
}
|
|
174
|
-
</script>
|
|
175
|
-
<style lang="scss" scoped>
|
|
176
|
-
</style>
|
|
177
307
|
`;
|
|
178
308
|
};
|
|
179
309
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import OlForm from "./src/index.vue";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Vue.component("ol-form ",
|
|
3
|
+
OlForm.install = function (Vue) {
|
|
4
|
+
Vue.component("ol-form ", OlForm);
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
export default
|
|
7
|
+
export default OlForm;
|
|
@@ -153,6 +153,8 @@
|
|
|
153
153
|
<template v-else-if="item.type == 'slot'">
|
|
154
154
|
<slot :name="item.name" :item="item" />
|
|
155
155
|
</template>
|
|
156
|
+
<!-- 兜底 -->
|
|
157
|
+
<div v-else style="color: red">"{{ item.type }}"类型暂不支持,请手动添加</div>
|
|
156
158
|
</el-form-item>
|
|
157
159
|
</template>
|
|
158
160
|
</el-form>
|
|
@@ -209,6 +211,9 @@
|
|
|
209
211
|
| selectChange| 选择器值变化事件 | {obj: 当前项配置, val: 变化后的值} |
|
|
210
212
|
-->
|
|
211
213
|
<script>
|
|
214
|
+
import { getData } from "../../index.js";
|
|
215
|
+
import { initForm } from "../../../utils/initData.js";
|
|
216
|
+
|
|
212
217
|
// interface FormItem {
|
|
213
218
|
// type: Number;
|
|
214
219
|
// title?: String;
|
|
@@ -219,6 +224,11 @@
|
|
|
219
224
|
export default {
|
|
220
225
|
name: "form",
|
|
221
226
|
props: {
|
|
227
|
+
url: {
|
|
228
|
+
type: String,
|
|
229
|
+
// default: "/api/app/warehouse/warehouse",
|
|
230
|
+
default: "",
|
|
231
|
+
},
|
|
222
232
|
form: Object,
|
|
223
233
|
// 默认值
|
|
224
234
|
defaultValue: {
|
|
@@ -302,11 +312,13 @@ export default {
|
|
|
302
312
|
form.value[key] = this.defaultValue[key];
|
|
303
313
|
});
|
|
304
314
|
}
|
|
305
|
-
|
|
315
|
+
initForm({
|
|
316
|
+
url: this.url,
|
|
317
|
+
form: this.form,
|
|
318
|
+
});
|
|
306
319
|
},
|
|
307
320
|
// beforeDestroy() {},
|
|
308
321
|
methods: {
|
|
309
|
-
init() {},
|
|
310
322
|
// 保留之前的change调用方式,并添扩展新的
|
|
311
323
|
selectChangeHandle(val, item) {
|
|
312
324
|
(item &&
|
package/src/package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import OlTable from "./table";
|
|
2
2
|
import OlSearch from "./formSearch";
|
|
3
3
|
import Dialog from "./dialog";
|
|
4
|
-
import
|
|
4
|
+
import OlForm from "./form";
|
|
5
5
|
import SwaggerClient from "swagger-client";
|
|
6
6
|
|
|
7
7
|
const consoleTooltip = () => {
|
|
@@ -144,7 +144,6 @@ const swaggerUnload = async function () {
|
|
|
144
144
|
await clearData(); // 清空 IndexedDB 中的缓存数据
|
|
145
145
|
};
|
|
146
146
|
|
|
147
|
-
const components = [OlTable, OlSearch, Dialog];
|
|
148
147
|
|
|
149
148
|
// 自定义加载指示器
|
|
150
149
|
function showLoading() {
|
|
@@ -204,6 +203,8 @@ function hideLoading() {
|
|
|
204
203
|
}
|
|
205
204
|
}
|
|
206
205
|
|
|
206
|
+
|
|
207
|
+
const components = [OlTable, OlSearch, Dialog, OlForm];
|
|
207
208
|
const install = async function (Vue) {
|
|
208
209
|
// 设置全局数据
|
|
209
210
|
components.map((item) => {
|
|
@@ -213,5 +214,5 @@ const install = async function (Vue) {
|
|
|
213
214
|
};
|
|
214
215
|
|
|
215
216
|
export default install;
|
|
216
|
-
export { OlTable, OlSearch, Dialog,
|
|
217
|
+
export { OlTable, OlSearch, Dialog, OlForm };
|
|
217
218
|
export { swaggerInstall, swaggerUnload };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getData } from "../package/index.js";
|
|
2
|
+
// java数据类型转成js数据类型
|
|
3
|
+
const javaTypeToJsType = javaType => {
|
|
4
|
+
switch (javaType) {
|
|
5
|
+
case "integer":
|
|
6
|
+
return "number";
|
|
7
|
+
case "array":
|
|
8
|
+
return "Array";
|
|
9
|
+
case "object":
|
|
10
|
+
return "Object";
|
|
11
|
+
default:
|
|
12
|
+
return javaType;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const javaTypeToformType = javaType => {
|
|
17
|
+
switch (javaType) {
|
|
18
|
+
case "integer":
|
|
19
|
+
return "number";
|
|
20
|
+
case "boolean":
|
|
21
|
+
return "switch";
|
|
22
|
+
case "string":
|
|
23
|
+
return "input";
|
|
24
|
+
default:
|
|
25
|
+
return javaType;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const initForm = options => {
|
|
30
|
+
const { url, form } = options;
|
|
31
|
+
getData().then(swaggerData => {
|
|
32
|
+
const entity = swaggerData.paths[url].post;
|
|
33
|
+
// 添加title
|
|
34
|
+
// if (!form.title) form.title = entity.summary;
|
|
35
|
+
const schema = entity.requestBody.content["application/json"].schema;
|
|
36
|
+
const properties = schema.properties;
|
|
37
|
+
// 生成model
|
|
38
|
+
// 1.循环model,将properties中prop相同的匹配,属性合并,model权限大,properties权限小,且保持响应式
|
|
39
|
+
form.model.forEach(item => {
|
|
40
|
+
const property = properties[item.prop];
|
|
41
|
+
if (property) {
|
|
42
|
+
Object.assign(item, {
|
|
43
|
+
prop: item.prop,
|
|
44
|
+
label: property.description,
|
|
45
|
+
type: javaTypeToformType(property.type),
|
|
46
|
+
hidden: false,
|
|
47
|
+
listeners: () => {},
|
|
48
|
+
props: {},
|
|
49
|
+
...item,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// 2.将properties都push到model中(只提取swagger中有的type和description)
|
|
54
|
+
Object.keys(properties).forEach(key => {
|
|
55
|
+
const property = properties[key];
|
|
56
|
+
if (!form.model.find(item => item.prop == key) && property.description) {
|
|
57
|
+
// 删除对象的某些属性
|
|
58
|
+
const temp = {
|
|
59
|
+
prop: key,
|
|
60
|
+
label: property.description,
|
|
61
|
+
type: javaTypeToformType(property.type),
|
|
62
|
+
hidden: false,
|
|
63
|
+
listeners: () => {},
|
|
64
|
+
props: {},
|
|
65
|
+
};
|
|
66
|
+
form.model.push(temp);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// 校验规则
|
|
71
|
+
if (schema.required && Array.isArray(schema.required)) {
|
|
72
|
+
schema.required.forEach(item => {
|
|
73
|
+
if (!Object.keys(form.rules).includes(item)) {
|
|
74
|
+
form.rules[item] = [
|
|
75
|
+
{
|
|
76
|
+
required: true,
|
|
77
|
+
message: `${properties[item].description}不能为空`,
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
};
|