ee-bin 1.5.0-beta.1 → 1.6.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/index.js +122 -120
- package/lib/pargv.js +263 -263
- package/lib/utils.js +121 -111
- package/package.json +26 -24
- package/tools/encrypt.js +315 -315
- package/tools/iconGen.js +182 -182
- package/tools/move.js +84 -84
- package/tools/replaceDist.js +82 -82
- package/tools/serve.js +167 -163
package/tools/replaceDist.js
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const fsPro = require('fs-extra');
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
const Utils = require('../lib/utils');
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 资源替换
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
module.exports = {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 执行
|
|
17
|
-
*/
|
|
18
|
-
run(options = {}) {
|
|
19
|
-
const warnTips = chalk.bgYellow('Warning') + ': This command is deprecated. Use move instead !';
|
|
20
|
-
console.log(warnTips);
|
|
21
|
-
|
|
22
|
-
console.log('[ee-bin] [rd] Start moving resources');
|
|
23
|
-
const homeDir = process.cwd();
|
|
24
|
-
let { dist, target, config } = options;
|
|
25
|
-
|
|
26
|
-
let distDir = './frontend/dist';
|
|
27
|
-
let targetDir = './public/dist';
|
|
28
|
-
|
|
29
|
-
// 命令行优先
|
|
30
|
-
if (dist) {
|
|
31
|
-
distDir = dist;
|
|
32
|
-
}
|
|
33
|
-
if (target) {
|
|
34
|
-
targetDir = target;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 如果命令行没参数,从bin config 获取
|
|
38
|
-
if (!dist && !target) {
|
|
39
|
-
const hasConfig = Utils.checkConfig(config);
|
|
40
|
-
if (hasConfig) {
|
|
41
|
-
const cfg = Utils.loadConfig(config);
|
|
42
|
-
if (cfg.rd && cfg.rd.dist) {
|
|
43
|
-
distDir = cfg.rd.dist;
|
|
44
|
-
}
|
|
45
|
-
if (cfg.rd && cfg.rd.target) {
|
|
46
|
-
targetDir = cfg.rd.target;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const sourceDir = path.join(homeDir, distDir);
|
|
52
|
-
if (!fs.existsSync(sourceDir)) {
|
|
53
|
-
const errorTips = chalk.bgRed('Error') + ' Frontend resource does not exist, please build !';
|
|
54
|
-
console.error(errorTips);
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// 清空历史资源 并 复制到ee资源目录
|
|
59
|
-
const eeResourceDir = path.join(homeDir, targetDir);
|
|
60
|
-
if (!fs.existsSync(eeResourceDir)) {
|
|
61
|
-
fs.mkdirSync(eeResourceDir, {recursive: true, mode: 0o777});
|
|
62
|
-
} else {
|
|
63
|
-
this._rmFolder(eeResourceDir);
|
|
64
|
-
console.log('[ee-bin] [rd] Clear history resources:', eeResourceDir);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
fsPro.copySync(sourceDir, eeResourceDir);
|
|
68
|
-
console.log('[ee-bin] [rd] Copy a resource to:', eeResourceDir);
|
|
69
|
-
console.log('[ee-bin] [rd] End');
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 删除文件夹
|
|
74
|
-
*/
|
|
75
|
-
_rmFolder(folder) {
|
|
76
|
-
const nodeVersion = (process.versions && process.versions.node) || null;
|
|
77
|
-
if (nodeVersion && Utils.compareVersion(nodeVersion, '14.14.0') == 1) {
|
|
78
|
-
fs.rmSync(folder, {recursive: true});
|
|
79
|
-
} else {
|
|
80
|
-
fs.rmdirSync(folder, {recursive: true});
|
|
81
|
-
}
|
|
82
|
-
},
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const fsPro = require('fs-extra');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const Utils = require('../lib/utils');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 资源替换
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 执行
|
|
17
|
+
*/
|
|
18
|
+
run(options = {}) {
|
|
19
|
+
const warnTips = chalk.bgYellow('Warning') + ': This command is deprecated. Use move instead !';
|
|
20
|
+
console.log(warnTips);
|
|
21
|
+
|
|
22
|
+
console.log('[ee-bin] [rd] Start moving resources');
|
|
23
|
+
const homeDir = process.cwd();
|
|
24
|
+
let { dist, target, config } = options;
|
|
25
|
+
|
|
26
|
+
let distDir = './frontend/dist';
|
|
27
|
+
let targetDir = './public/dist';
|
|
28
|
+
|
|
29
|
+
// 命令行优先
|
|
30
|
+
if (dist) {
|
|
31
|
+
distDir = dist;
|
|
32
|
+
}
|
|
33
|
+
if (target) {
|
|
34
|
+
targetDir = target;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 如果命令行没参数,从bin config 获取
|
|
38
|
+
if (!dist && !target) {
|
|
39
|
+
const hasConfig = Utils.checkConfig(config);
|
|
40
|
+
if (hasConfig) {
|
|
41
|
+
const cfg = Utils.loadConfig(config);
|
|
42
|
+
if (cfg.rd && cfg.rd.dist) {
|
|
43
|
+
distDir = cfg.rd.dist;
|
|
44
|
+
}
|
|
45
|
+
if (cfg.rd && cfg.rd.target) {
|
|
46
|
+
targetDir = cfg.rd.target;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const sourceDir = path.join(homeDir, distDir);
|
|
52
|
+
if (!fs.existsSync(sourceDir)) {
|
|
53
|
+
const errorTips = chalk.bgRed('Error') + ' Frontend resource does not exist, please build !';
|
|
54
|
+
console.error(errorTips);
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 清空历史资源 并 复制到ee资源目录
|
|
59
|
+
const eeResourceDir = path.join(homeDir, targetDir);
|
|
60
|
+
if (!fs.existsSync(eeResourceDir)) {
|
|
61
|
+
fs.mkdirSync(eeResourceDir, {recursive: true, mode: 0o777});
|
|
62
|
+
} else {
|
|
63
|
+
this._rmFolder(eeResourceDir);
|
|
64
|
+
console.log('[ee-bin] [rd] Clear history resources:', eeResourceDir);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
fsPro.copySync(sourceDir, eeResourceDir);
|
|
68
|
+
console.log('[ee-bin] [rd] Copy a resource to:', eeResourceDir);
|
|
69
|
+
console.log('[ee-bin] [rd] End');
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 删除文件夹
|
|
74
|
+
*/
|
|
75
|
+
_rmFolder(folder) {
|
|
76
|
+
const nodeVersion = (process.versions && process.versions.node) || null;
|
|
77
|
+
if (nodeVersion && Utils.compareVersion(nodeVersion, '14.14.0') == 1) {
|
|
78
|
+
fs.rmSync(folder, {recursive: true});
|
|
79
|
+
} else {
|
|
80
|
+
fs.rmdirSync(folder, {recursive: true});
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
83
|
}
|
package/tools/serve.js
CHANGED
|
@@ -1,163 +1,167 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const Utils = require('../lib/utils');
|
|
5
|
-
const is = require('is-type-of');
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
const crossSpawn = require('cross-spawn');
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
|
|
11
|
-
execProcess: {},
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 启动前端、主进程服务
|
|
15
|
-
*/
|
|
16
|
-
dev(options = {}) {
|
|
17
|
-
const { config, serve } = options;
|
|
18
|
-
const binCmd = 'dev';
|
|
19
|
-
const binCfg = Utils.loadConfig(config);
|
|
20
|
-
const binCmdConfig = binCfg[binCmd];
|
|
21
|
-
|
|
22
|
-
let command = serve;
|
|
23
|
-
if (!command) {
|
|
24
|
-
command = Object.keys(binCmdConfig).join();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const opt = {
|
|
28
|
-
binCmd,
|
|
29
|
-
binCmdConfig,
|
|
30
|
-
command,
|
|
31
|
-
}
|
|
32
|
-
this.multiExec(opt);
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 启动主进程服务
|
|
37
|
-
*/
|
|
38
|
-
start(options = {}) {
|
|
39
|
-
const { config } = options;
|
|
40
|
-
const binCmd = 'start';
|
|
41
|
-
const binCfg = Utils.loadConfig(config);
|
|
42
|
-
const binCmdConfig = {
|
|
43
|
-
start: binCfg[binCmd]
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const opt = {
|
|
47
|
-
binCmd,
|
|
48
|
-
binCmdConfig,
|
|
49
|
-
command: binCmd,
|
|
50
|
-
}
|
|
51
|
-
this.multiExec(opt);
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
sleep(ms) {
|
|
55
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 构建
|
|
60
|
-
*/
|
|
61
|
-
build(options = {}) {
|
|
62
|
-
const { config, cmds } = options;
|
|
63
|
-
const binCmd = 'build';
|
|
64
|
-
const binCfg = Utils.loadConfig(config);
|
|
65
|
-
const binCmdConfig = binCfg[binCmd];
|
|
66
|
-
|
|
67
|
-
if (!cmds || cmds == "") {
|
|
68
|
-
// [todo]
|
|
69
|
-
let tip = chalk.bgYellow('Warning') + ' Please modify the ' + chalk.blue('build') + ' config, See: ';
|
|
70
|
-
tip += chalk.underline('https://www.kaka996.com/pages/c492f8/');
|
|
71
|
-
console.log(tip);
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const opt = {
|
|
76
|
-
binCmd,
|
|
77
|
-
binCmdConfig,
|
|
78
|
-
command: cmds,
|
|
79
|
-
}
|
|
80
|
-
this.multiExec(opt);
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 执行自定义命令
|
|
85
|
-
*/
|
|
86
|
-
exec(options = {}) {
|
|
87
|
-
let { config, command, cmds } = options;
|
|
88
|
-
const binCmd = 'exec';
|
|
89
|
-
const binCfg = Utils.loadConfig(config);
|
|
90
|
-
const binCmdConfig = binCfg[binCmd];
|
|
91
|
-
|
|
92
|
-
// if (typeof command !== "string" || !cmds) {
|
|
93
|
-
// console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.red(`Error: Please specify parameters for --cmds` ));
|
|
94
|
-
// return
|
|
95
|
-
// }
|
|
96
|
-
|
|
97
|
-
// 兼容
|
|
98
|
-
if (typeof command === "string") {
|
|
99
|
-
cmds = command;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const opt = {
|
|
103
|
-
binCmd,
|
|
104
|
-
binCmdConfig,
|
|
105
|
-
command: cmds,
|
|
106
|
-
}
|
|
107
|
-
this.multiExec(opt);
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 支持多个命令
|
|
112
|
-
*/
|
|
113
|
-
multiExec(opt = {}) {
|
|
114
|
-
//console.log('multiExec opt:', opt)
|
|
115
|
-
const { binCmd, binCmdConfig, command } = opt;
|
|
116
|
-
|
|
117
|
-
let cmds;
|
|
118
|
-
const cmdString = command.trim();
|
|
119
|
-
if (cmdString.indexOf(',') !== -1) {
|
|
120
|
-
cmds = cmdString.split(',');
|
|
121
|
-
} else {
|
|
122
|
-
cmds = [cmdString];
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
for (let i = 0; i < cmds.length; i++) {
|
|
126
|
-
let cmd = cmds[i];
|
|
127
|
-
let cfg = binCmdConfig[cmd];
|
|
128
|
-
|
|
129
|
-
if (!cfg) {
|
|
130
|
-
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.red(`Error: [${binCmd} ${cmd}] config does not exist` ));
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// frontend 如果是 file:// 协议,则不启动
|
|
135
|
-
if (cmd == 'frontend' && cfg.protocol == 'file://') {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + "Run " + chalk.green(`[${binCmd} ${cmd}]` + " command"));
|
|
140
|
-
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.green('config:'), JSON.stringify(cfg));
|
|
141
|
-
|
|
142
|
-
let execDir = path.join(process.cwd(), cfg.directory);
|
|
143
|
-
let execArgs = is.string(cfg.args) ? [cfg.args] : cfg.args;
|
|
144
|
-
let stdio = cfg.stdio ? cfg.stdio: 'inherit';
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const Utils = require('../lib/utils');
|
|
5
|
+
const is = require('is-type-of');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const crossSpawn = require('cross-spawn');
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
|
|
11
|
+
execProcess: {},
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 启动前端、主进程服务
|
|
15
|
+
*/
|
|
16
|
+
dev(options = {}) {
|
|
17
|
+
const { config, serve } = options;
|
|
18
|
+
const binCmd = 'dev';
|
|
19
|
+
const binCfg = Utils.loadConfig(config);
|
|
20
|
+
const binCmdConfig = binCfg[binCmd];
|
|
21
|
+
|
|
22
|
+
let command = serve;
|
|
23
|
+
if (!command) {
|
|
24
|
+
command = Object.keys(binCmdConfig).join();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const opt = {
|
|
28
|
+
binCmd,
|
|
29
|
+
binCmdConfig,
|
|
30
|
+
command,
|
|
31
|
+
}
|
|
32
|
+
this.multiExec(opt);
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 启动主进程服务
|
|
37
|
+
*/
|
|
38
|
+
start(options = {}) {
|
|
39
|
+
const { config } = options;
|
|
40
|
+
const binCmd = 'start';
|
|
41
|
+
const binCfg = Utils.loadConfig(config);
|
|
42
|
+
const binCmdConfig = {
|
|
43
|
+
start: binCfg[binCmd]
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const opt = {
|
|
47
|
+
binCmd,
|
|
48
|
+
binCmdConfig,
|
|
49
|
+
command: binCmd,
|
|
50
|
+
}
|
|
51
|
+
this.multiExec(opt);
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
sleep(ms) {
|
|
55
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 构建
|
|
60
|
+
*/
|
|
61
|
+
build(options = {}) {
|
|
62
|
+
const { config, cmds } = options;
|
|
63
|
+
const binCmd = 'build';
|
|
64
|
+
const binCfg = Utils.loadConfig(config);
|
|
65
|
+
const binCmdConfig = binCfg[binCmd];
|
|
66
|
+
|
|
67
|
+
if (!cmds || cmds == "") {
|
|
68
|
+
// [todo]
|
|
69
|
+
let tip = chalk.bgYellow('Warning') + ' Please modify the ' + chalk.blue('build') + ' config, See: ';
|
|
70
|
+
tip += chalk.underline('https://www.kaka996.com/pages/c492f8/');
|
|
71
|
+
console.log(tip);
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const opt = {
|
|
76
|
+
binCmd,
|
|
77
|
+
binCmdConfig,
|
|
78
|
+
command: cmds,
|
|
79
|
+
}
|
|
80
|
+
this.multiExec(opt);
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 执行自定义命令
|
|
85
|
+
*/
|
|
86
|
+
exec(options = {}) {
|
|
87
|
+
let { config, command, cmds } = options;
|
|
88
|
+
const binCmd = 'exec';
|
|
89
|
+
const binCfg = Utils.loadConfig(config);
|
|
90
|
+
const binCmdConfig = binCfg[binCmd];
|
|
91
|
+
|
|
92
|
+
// if (typeof command !== "string" || !cmds) {
|
|
93
|
+
// console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.red(`Error: Please specify parameters for --cmds` ));
|
|
94
|
+
// return
|
|
95
|
+
// }
|
|
96
|
+
|
|
97
|
+
// 兼容
|
|
98
|
+
if (typeof command === "string") {
|
|
99
|
+
cmds = command;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const opt = {
|
|
103
|
+
binCmd,
|
|
104
|
+
binCmdConfig,
|
|
105
|
+
command: cmds,
|
|
106
|
+
}
|
|
107
|
+
this.multiExec(opt);
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 支持多个命令
|
|
112
|
+
*/
|
|
113
|
+
multiExec(opt = {}) {
|
|
114
|
+
//console.log('multiExec opt:', opt)
|
|
115
|
+
const { binCmd, binCmdConfig, command } = opt;
|
|
116
|
+
|
|
117
|
+
let cmds;
|
|
118
|
+
const cmdString = command.trim();
|
|
119
|
+
if (cmdString.indexOf(',') !== -1) {
|
|
120
|
+
cmds = cmdString.split(',');
|
|
121
|
+
} else {
|
|
122
|
+
cmds = [cmdString];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < cmds.length; i++) {
|
|
126
|
+
let cmd = cmds[i];
|
|
127
|
+
let cfg = binCmdConfig[cmd];
|
|
128
|
+
|
|
129
|
+
if (!cfg) {
|
|
130
|
+
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.red(`Error: [${binCmd} ${cmd}] config does not exist` ));
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// frontend 如果是 file:// 协议,则不启动
|
|
135
|
+
if (cmd == 'frontend' && cfg.protocol == 'file://') {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + "Run " + chalk.green(`[${binCmd} ${cmd}]` + " command"));
|
|
140
|
+
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.green('config:'), JSON.stringify(cfg));
|
|
141
|
+
|
|
142
|
+
let execDir = path.join(process.cwd(), cfg.directory);
|
|
143
|
+
let execArgs = is.string(cfg.args) ? [cfg.args] : cfg.args;
|
|
144
|
+
let stdio = cfg.stdio ? cfg.stdio: 'inherit';
|
|
145
|
+
|
|
146
|
+
const handler = cfg.sync ? crossSpawn.sync : crossSpawn;
|
|
147
|
+
|
|
148
|
+
this.execProcess[cmd] = handler(
|
|
149
|
+
cfg.cmd,
|
|
150
|
+
execArgs,
|
|
151
|
+
{ stdio: stdio, cwd: execDir, maxBuffer: 1024 * 1024 * 1024 },
|
|
152
|
+
);
|
|
153
|
+
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + 'The ' + chalk.green(`[${binCmd} ${cmd}]`) + ` command is ${cfg.sync ? 'run completed' : 'running'}`);
|
|
154
|
+
|
|
155
|
+
if(!cfg.sync) {
|
|
156
|
+
this.execProcess[cmd].on('exit', () => {
|
|
157
|
+
if (cmd == 'electron') {
|
|
158
|
+
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + chalk.green('Press "CTRL+C" to exit'));
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
console.log(chalk.blue(`[ee-bin] [${binCmd}] `) + 'The ' + chalk.green(`[${binCmd} ${cmd}]`) + ' command is executed and exits');
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
}
|