molly-db 1.0.7 → 1.0.11
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/main.js +3 -4
- package/module/_crypto_.js +17 -13
- package/module/_init_.js +5 -6
- package/module/_server_.js +187 -80
- package/module/_worker_.js +19 -12
- package/package.json +1 -1
package/main.js
CHANGED
|
@@ -22,7 +22,6 @@ class molly_db{
|
|
|
22
22
|
if( opt.pass )
|
|
23
23
|
this.pass = opt.pass;
|
|
24
24
|
this.port = opt.port || 27017;
|
|
25
|
-
this.type = opt.type || 'local';
|
|
26
25
|
this.path = opt.path.replace(/^\./,process.cwd());
|
|
27
26
|
|
|
28
27
|
if( this.worker ) return console.log(`server is running`);
|
|
@@ -34,9 +33,9 @@ class molly_db{
|
|
|
34
33
|
}
|
|
35
34
|
);
|
|
36
35
|
|
|
37
|
-
this.worker.on('exit',(err)=>{ });
|
|
38
|
-
this.worker.on('error',(err)=>{ });
|
|
39
|
-
this.worker.on('message',(msg)=>{ console.log(msg); response()
|
|
36
|
+
this.worker.on('exit',(err)=>{ console.log(err); reject() });
|
|
37
|
+
this.worker.on('error',(err)=>{ console.log(err); reject() });
|
|
38
|
+
this.worker.on('message',(msg)=>{ console.log(msg); response() });
|
|
40
39
|
});
|
|
41
40
|
}
|
|
42
41
|
|
package/module/_crypto_.js
CHANGED
|
@@ -28,19 +28,23 @@ const JsonFormatter = {
|
|
|
28
28
|
/* --------------------------------------------------------------------------------------- */
|
|
29
29
|
|
|
30
30
|
output.slugify = (str)=>{
|
|
31
|
-
|
|
32
|
-
'c'
|
|
33
|
-
'n'
|
|
34
|
-
'e'
|
|
35
|
-
'i'
|
|
36
|
-
'u'
|
|
37
|
-
'o'
|
|
38
|
-
'a'
|
|
39
|
-
''
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
str=str.replace(
|
|
43
|
-
} return str.toLowerCase();
|
|
31
|
+
[
|
|
32
|
+
['c','ç'],
|
|
33
|
+
['n','ñ'],
|
|
34
|
+
['e','é|è|ê|ë'],
|
|
35
|
+
['i','í|ì|î|ï'],
|
|
36
|
+
['u','ú|ù|û|ü'],
|
|
37
|
+
['o','ó|ò|ô|õ|ö'],
|
|
38
|
+
['a','á|à|ã|â|ä'],
|
|
39
|
+
['' ,/\s+|\W+/,]
|
|
40
|
+
].map(x=>{
|
|
41
|
+
const regex = new RegExp(x[1],'gi');
|
|
42
|
+
str = str.replace( regex,x[0] );
|
|
43
|
+
}); return str.toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
output.hash = (data,nonce)=>{
|
|
47
|
+
return crypto.SHA256(Math.random+data+nonce).toString();
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
output.encrypt = ( _message,_password )=>{
|
package/module/_init_.js
CHANGED
|
@@ -43,7 +43,8 @@ function fillDB( _db, _table, _path ){
|
|
|
43
43
|
|
|
44
44
|
const DB = db._init_.DB[i];
|
|
45
45
|
const name = DB.name;
|
|
46
|
-
|
|
46
|
+
delete db[name];
|
|
47
|
+
|
|
47
48
|
db[name] = new Object();
|
|
48
49
|
|
|
49
50
|
for( var j in DB.tables ){
|
|
@@ -57,12 +58,10 @@ function fillDB( _db, _table, _path ){
|
|
|
57
58
|
|
|
58
59
|
} catch(e) {
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
db._buff_ = fs.readFileSync( path );
|
|
61
|
+
db._init_ = { DB:[] };
|
|
62
62
|
db._path_ = query.path;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
fs.writeFileSync( path,db._init_ );
|
|
63
|
+
const path = `${query.path}/_init_.json`;
|
|
64
|
+
fs.writeFileSync( path,JSON.stringify(db._init_) );
|
|
66
65
|
|
|
67
66
|
} response();
|
|
68
67
|
})();
|
package/module/_server_.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
const api = url.parse( req.url,true );
|
|
3
|
+
let params = api.query;
|
|
4
|
+
let body = undefined;
|
|
5
|
+
let parse = api;
|
|
6
|
+
|
|
7
|
+
/* --------------------------------------------------------------------------------------- */
|
|
6
8
|
|
|
7
9
|
function error( _error ){
|
|
8
|
-
res.writeHead(
|
|
9
|
-
res.end(
|
|
10
|
-
console.log(_error);
|
|
10
|
+
res.writeHead(404,{'contetn-type':'application/json'});
|
|
11
|
+
res.end(JSON.stringify([{ status:'error', message:_error }]));
|
|
12
|
+
console.log( _error,req.url );
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
function json( _data ){
|
|
@@ -17,13 +19,38 @@ function json( _data ){
|
|
|
17
19
|
|
|
18
20
|
/* --------------------------------------------------------------------------------------- */
|
|
19
21
|
|
|
22
|
+
function bodyParser( _data ){
|
|
23
|
+
|
|
24
|
+
const date = Date.now();
|
|
25
|
+
const result = new Array();
|
|
26
|
+
|
|
27
|
+
if( typeof _data.length == 'number' ){
|
|
28
|
+
for( var i in _data ){
|
|
29
|
+
if(!_data[i]?.hash)
|
|
30
|
+
_data[i].hash = crypto.hash( date,0 );
|
|
31
|
+
result.push(JSON.stringify(_data[i]));
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
if(!_data?.hash)
|
|
35
|
+
_data.hash = crypto.hash( date,0 );
|
|
36
|
+
result.push(JSON.stringify(_data));
|
|
37
|
+
} return result;
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
20
41
|
function getBody(){
|
|
21
42
|
return new Promise((response,reject)=>{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
try{
|
|
44
|
+
if( req.method == 'POST' || (/push|unshift|splice|update/).test(api.pathname) ){
|
|
45
|
+
const data = new Array();
|
|
46
|
+
req.on('data',(chunk)=>{ data.push(chunk); });
|
|
47
|
+
req.on('close',()=>{ try{
|
|
48
|
+
const buff = Buffer.concat(data);
|
|
49
|
+
const json = JSON.parse(buff);
|
|
50
|
+
response( bodyParser(json) );
|
|
51
|
+
} catch(e) { response(false) } });
|
|
52
|
+
} else { response(true) }
|
|
53
|
+
} catch(e) { response(false) }
|
|
27
54
|
});
|
|
28
55
|
}
|
|
29
56
|
|
|
@@ -49,6 +76,38 @@ function encryptDB( _db,_table, _path ){
|
|
|
49
76
|
});
|
|
50
77
|
}
|
|
51
78
|
|
|
79
|
+
function validate( _params ){
|
|
80
|
+
return new Promise((response,reject)=>{
|
|
81
|
+
|
|
82
|
+
let validator = false;
|
|
83
|
+
|
|
84
|
+
const vdb = (key)=>{ return db._init_.DB.some(x=>{ return x.name == key; }) }
|
|
85
|
+
const vtb = (key)=>{ return db._init_.DB.some(x=>{ return x.tables.join().match(key); }) }
|
|
86
|
+
|
|
87
|
+
validator = [
|
|
88
|
+
[ !_params?.offset, '_params.offset = 0' ],
|
|
89
|
+
[ !_params?.target, '_params.target = ""' ],
|
|
90
|
+
[ !_params?.length, '_params.length = 100' ],
|
|
91
|
+
].every(x=>{ if(x[0]) eval(x[1]); return true; });
|
|
92
|
+
|
|
93
|
+
validator = [
|
|
94
|
+
[!body, {status:'error',message:'invalid data'}],
|
|
95
|
+
[!_params?.db, {status:'error',message:'no db name added'}],
|
|
96
|
+
[!_params?.table, {status:'error',message:'no table name added'}]
|
|
97
|
+
].some(x=>{ if(x[0]) reject(x[1]); return x[0];}); if(validator) return 0;
|
|
98
|
+
|
|
99
|
+
if( !(/table|db/gi).test(parse.pathname) ){
|
|
100
|
+
validator = [
|
|
101
|
+
[!vdb(_params?.db), {status:'error',message:`no db called ${_params.db} exist`}],
|
|
102
|
+
[!vtb(_params?.table), {status:'error',message:`no table called ${_params.table} exist`}]
|
|
103
|
+
].some(x=>{ if(x[0]) reject(x[1]); return x[0];}); if(validator) return 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
response(_params);
|
|
107
|
+
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
52
111
|
/* --------------------------------------------------------------------------------------- */
|
|
53
112
|
|
|
54
113
|
function list( _params ){
|
|
@@ -83,118 +142,144 @@ function hash( _params ){
|
|
|
83
142
|
/* --------------------------------------------------------------------------------------- */
|
|
84
143
|
|
|
85
144
|
function shift( _params ){
|
|
86
|
-
const result = db[_params.db][_params.table].shift();
|
|
87
|
-
modifyDB( _params.db,_params.table ); return result;
|
|
145
|
+
const result = db[_params.db][_params.table].shift(); save( _params ); return result;
|
|
88
146
|
}
|
|
89
147
|
|
|
90
148
|
function pop( _params ){
|
|
91
|
-
const result = db[_params.db][_params.table].pop();
|
|
92
|
-
modifyDB( _params.db,_params.table ); return result; return result;
|
|
149
|
+
const result = db[_params.db][_params.table].pop(); save( _params ); return result;
|
|
93
150
|
}
|
|
94
151
|
|
|
95
152
|
/* --------------------------------------------------------------------------------------- */
|
|
96
153
|
|
|
97
154
|
async function push( _params ){
|
|
98
155
|
|
|
99
|
-
|
|
100
|
-
db[_params.db][_params.table].push( body );
|
|
156
|
+
db[_params.db][_params.table].push( ...body );
|
|
101
157
|
|
|
102
|
-
|
|
103
|
-
return {
|
|
158
|
+
save( _params ); return [{
|
|
104
159
|
database: _params.db,
|
|
105
160
|
table: _params.table,
|
|
106
161
|
status: 'pushed'
|
|
107
|
-
};
|
|
162
|
+
}];
|
|
108
163
|
|
|
109
164
|
}
|
|
110
165
|
|
|
111
166
|
async function splice( _params ){
|
|
112
167
|
|
|
113
|
-
const body = await getBody();
|
|
114
168
|
db[_params.db][_params.table].splice(
|
|
115
|
-
_params.offset,_params.length
|
|
169
|
+
_params.offset,_params.length,...body
|
|
116
170
|
);
|
|
117
171
|
|
|
118
|
-
|
|
119
|
-
return {
|
|
172
|
+
save( _params ); return [{
|
|
120
173
|
database: _params.db,
|
|
121
174
|
table: _params.table,
|
|
122
175
|
status: 'spliced'
|
|
123
|
-
};
|
|
176
|
+
}];
|
|
124
177
|
}
|
|
125
178
|
|
|
126
179
|
async function unshift( _params ){
|
|
127
180
|
|
|
128
|
-
|
|
129
|
-
db[_params.db][_params.table].unshift( body );
|
|
181
|
+
db[_params.db][_params.table].unshift( ...body );
|
|
130
182
|
|
|
131
|
-
|
|
132
|
-
return {
|
|
183
|
+
save( _params ); return [{
|
|
133
184
|
database: _params.db,
|
|
134
185
|
table: _params.table,
|
|
135
186
|
status: 'unshifted'
|
|
136
|
-
};
|
|
187
|
+
}];
|
|
137
188
|
}
|
|
138
189
|
|
|
139
190
|
/* --------------------------------------------------------------------------------------- */
|
|
140
191
|
|
|
141
|
-
function
|
|
142
|
-
|
|
143
|
-
const init = `${query.path}/_init_.json`;
|
|
192
|
+
async function update( _params ){
|
|
144
193
|
|
|
145
|
-
db.
|
|
146
|
-
|
|
147
|
-
|
|
194
|
+
const index = db[_params.db][_params.table].findIndex(x=>{
|
|
195
|
+
const regex = new RegExp(_params.target,'gi');
|
|
196
|
+
return regex.test(x);
|
|
148
197
|
});
|
|
149
198
|
|
|
150
|
-
|
|
151
|
-
|
|
199
|
+
if( !(index<0) )
|
|
200
|
+
db[_params.db][_params.table].splice( index,1,...body );
|
|
152
201
|
|
|
153
|
-
return {
|
|
202
|
+
save( _params ); return [{
|
|
154
203
|
database: _params.db,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
204
|
+
table: _params.table,
|
|
205
|
+
status: 'udated'
|
|
206
|
+
}];
|
|
158
207
|
}
|
|
159
208
|
|
|
160
|
-
function
|
|
209
|
+
async function remove( _params ){
|
|
161
210
|
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
return x
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
db._init_.DB[i].tables.forEach(x=>{
|
|
168
|
-
const path = `${query.path}/${x}.json`;
|
|
169
|
-
fs.unlinkSync(path);
|
|
170
|
-
}); db._init_.DB.splice(i,1);
|
|
211
|
+
const index = db[_params.db][_params.table].findIndex(x=>{
|
|
212
|
+
const regex = new RegExp(_params.target,'gi');
|
|
213
|
+
return regex.test(x);
|
|
214
|
+
});
|
|
171
215
|
|
|
172
|
-
|
|
173
|
-
|
|
216
|
+
if( !(index<0) )
|
|
217
|
+
db[_params.db][_params.table].splice( index,1 );
|
|
174
218
|
|
|
175
|
-
return {
|
|
219
|
+
save( _params ); return [{
|
|
176
220
|
database: _params.db,
|
|
177
221
|
table: _params.table,
|
|
178
|
-
status: '
|
|
179
|
-
};
|
|
222
|
+
status: 'removed'
|
|
223
|
+
}];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* --------------------------------------------------------------------------------------- */
|
|
227
|
+
|
|
228
|
+
function addDB( _params ){
|
|
229
|
+
try{
|
|
230
|
+
|
|
231
|
+
db._init_.DB.push({
|
|
232
|
+
tables: [],
|
|
233
|
+
name: _params.db,
|
|
234
|
+
}); db[_params.db] = new Array();
|
|
180
235
|
|
|
236
|
+
save( _params ); return [{
|
|
237
|
+
database: _params.db,
|
|
238
|
+
status: 'DB added'
|
|
239
|
+
}];
|
|
240
|
+
|
|
241
|
+
} catch(e) { }
|
|
181
242
|
}
|
|
182
243
|
|
|
183
|
-
function
|
|
244
|
+
function removeDB( _params ){
|
|
245
|
+
try{
|
|
184
246
|
|
|
185
|
-
|
|
186
|
-
|
|
247
|
+
const i = db._init_.DB.findIndex(x=>{
|
|
248
|
+
return x.name == _params.db
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
db._init_.DB[i].tables.forEach(x=>{
|
|
252
|
+
const path = `${query.path}/${x}.json`;
|
|
253
|
+
fs.unlinkSync(path);
|
|
254
|
+
}); db._init_.DB.splice(i,1);
|
|
255
|
+
db[_params.db] = new Array();
|
|
256
|
+
|
|
257
|
+
save( _params ); return [{
|
|
258
|
+
database: _params.db,
|
|
259
|
+
table: _params.table,
|
|
260
|
+
status: 'DB deleted'
|
|
261
|
+
}];
|
|
187
262
|
|
|
188
|
-
|
|
263
|
+
} catch(e) { }
|
|
264
|
+
}
|
|
189
265
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if( length>0 ) encryptDB( _name, _table, path );
|
|
193
|
-
else fs.writeFileSync( path,'' );
|
|
194
|
-
} catch(e) {
|
|
195
|
-
fs.unlinkSync( path );
|
|
196
|
-
}
|
|
266
|
+
function modifyDB( _name, _table ){
|
|
267
|
+
try{
|
|
197
268
|
|
|
269
|
+
const init = `${query.path}/_init_.json`;
|
|
270
|
+
const path = `${query.path}/${_table}.json`;
|
|
271
|
+
|
|
272
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
const length = db[_name][_table].length;
|
|
276
|
+
if( length>0 ) encryptDB( _name, _table, path );
|
|
277
|
+
else fs.writeFileSync( path,'' );
|
|
278
|
+
} catch(e) {
|
|
279
|
+
fs.unlinkSync( path );
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
} catch(e) { }
|
|
198
283
|
}
|
|
199
284
|
|
|
200
285
|
/* --------------------------------------------------------------------------------------- */
|
|
@@ -213,13 +298,12 @@ function addTable( _params ){
|
|
|
213
298
|
}); db._init_.DB[i].tables.push(_params.table);
|
|
214
299
|
|
|
215
300
|
db[_params.db][_params.table] = new Array();
|
|
216
|
-
modifyDB( _params.db,_params.table );
|
|
217
301
|
|
|
218
|
-
return {
|
|
302
|
+
save( _params ); return [{
|
|
219
303
|
database: _params.db,
|
|
220
304
|
table: _params.table,
|
|
221
305
|
status: 'table added'
|
|
222
|
-
};
|
|
306
|
+
}];
|
|
223
307
|
|
|
224
308
|
}
|
|
225
309
|
|
|
@@ -235,28 +319,51 @@ function removeTable( _params ){
|
|
|
235
319
|
|
|
236
320
|
db._init_.DB[i].tables.splice(j,1);
|
|
237
321
|
delete db[_params.db][_params.table];
|
|
238
|
-
modifyDB( _params.db,_params.table );
|
|
239
322
|
|
|
240
|
-
return {
|
|
323
|
+
save( _params ); return [{
|
|
241
324
|
database: _params.db,
|
|
242
325
|
table: _params.table,
|
|
243
326
|
status: 'table removed'
|
|
244
|
-
};
|
|
327
|
+
}];
|
|
245
328
|
|
|
246
329
|
}
|
|
247
330
|
|
|
248
331
|
/* --------------------------------------------------------------------------------------- */
|
|
249
332
|
|
|
250
|
-
(
|
|
251
|
-
|
|
333
|
+
function refresh( _params ){
|
|
334
|
+
return new Promise((response,reject)=>{
|
|
335
|
+
_init_().then(()=>{ response([{status: 'done'}]) })
|
|
336
|
+
.catch((e)=>{ reject([{status:'error',message:e.message}]) });
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function save( _params ){
|
|
341
|
+
modifyDB( _params.db,_params.table );
|
|
342
|
+
return [{
|
|
343
|
+
database: _params.db,
|
|
344
|
+
table: _params.table,
|
|
345
|
+
status: 'saved'
|
|
346
|
+
}];
|
|
347
|
+
}
|
|
252
348
|
|
|
253
|
-
|
|
254
|
-
|
|
349
|
+
/* --------------------------------------------------------------------------------------- */
|
|
350
|
+
|
|
351
|
+
(async ()=>{
|
|
352
|
+
try{
|
|
353
|
+
|
|
354
|
+
body = await getBody();
|
|
355
|
+
params = await validate(params);
|
|
255
356
|
|
|
256
357
|
/* Find Api */
|
|
257
358
|
if( api.pathname == '/list' ) json( await list(params) )
|
|
258
359
|
else if( api.pathname == '/hash' ) json( await hash(params) )
|
|
259
360
|
else if( api.pathname == '/match' ) json( await match(params) )
|
|
361
|
+
else if( api.pathname == '/update' ) json( await update(params) )
|
|
362
|
+
|
|
363
|
+
/* Save Api */
|
|
364
|
+
else if( api.pathname == '/save' ) json( await save(params) )
|
|
365
|
+
else if( api.pathname == '/remove' ) json( await remove(params) )
|
|
366
|
+
else if( api.pathname == '/refresh' ) json( await refresh(params) )
|
|
260
367
|
|
|
261
368
|
/* Remove Api */
|
|
262
369
|
else if( api.pathname == '/pop' ) json( await pop(params) )
|
|
@@ -277,7 +384,7 @@ function removeTable( _params ){
|
|
|
277
384
|
|
|
278
385
|
else error('Oops something went wrong');
|
|
279
386
|
|
|
280
|
-
} catch(e) { error(e); }
|
|
387
|
+
} catch(e) { error(e?.message||e); }
|
|
281
388
|
})();
|
|
282
389
|
|
|
283
390
|
/* --------------------------------------------------------------------------------------- */
|
package/module/_worker_.js
CHANGED
|
@@ -9,19 +9,22 @@ const fs = require('fs');
|
|
|
9
9
|
|
|
10
10
|
const query = worker.workerData;
|
|
11
11
|
const db = new Object();
|
|
12
|
-
|
|
13
12
|
/* --------------------------------------------------------------------------------------- */
|
|
14
13
|
|
|
15
|
-
function
|
|
16
|
-
|
|
14
|
+
function _init_(){
|
|
15
|
+
return new Promise((response,reject)=>{
|
|
16
|
+
try{
|
|
17
|
+
eval( fs.readFileSync(`${__dirname}/_init_.js`).toString() );
|
|
18
|
+
} catch(e){ console.log(e); }
|
|
19
|
+
});
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
/* --------------------------------------------------------------------------------------- */
|
|
20
23
|
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
eval( fs.readFileSync(`${__dirname}/
|
|
24
|
-
})
|
|
24
|
+
function app(req,res){
|
|
25
|
+
try{
|
|
26
|
+
eval( fs.readFileSync(`${__dirname}/_server_.js`).toString() );
|
|
27
|
+
} catch(e) { console.log(e) }
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
/* --------------------------------------------------------------------------------------- */
|
|
@@ -29,14 +32,18 @@ function _init_(){
|
|
|
29
32
|
(()=>{
|
|
30
33
|
try{
|
|
31
34
|
http.createServer( app ).listen( query.port,()=>{
|
|
32
|
-
console.log('molly-db is running, please wait');
|
|
35
|
+
console.log('molly-db cluster is running, please wait');
|
|
33
36
|
_init_().then(()=>{
|
|
34
|
-
worker.parentPort.postMessage(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
worker.parentPort.postMessage({
|
|
38
|
+
protocol: 'HTTP',
|
|
39
|
+
status: 'started',
|
|
40
|
+
workerID: process.pid,
|
|
41
|
+
msg: 'molly-db is running',
|
|
42
|
+
server: `http://localhost:${query.port}`,
|
|
43
|
+
});
|
|
37
44
|
}).catch(e=>{ process.exit(1); });
|
|
38
45
|
});
|
|
39
|
-
} catch(e) {
|
|
46
|
+
} catch(e) {}
|
|
40
47
|
})();
|
|
41
48
|
|
|
42
49
|
/* --------------------------------------------------------------------------------------- */
|