qr 0.2.4 → 0.4.2
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/LICENSE +203 -21
- package/LICENSE-MIT +21 -0
- package/README.md +249 -65
- package/decode.d.ts +62 -0
- package/decode.d.ts.map +1 -0
- package/decode.js +930 -0
- package/dom.d.ts +102 -0
- package/dom.d.ts.map +1 -0
- package/dom.js +328 -0
- package/esm/decode.d.ts +62 -0
- package/esm/decode.d.ts.map +1 -0
- package/esm/decode.js +926 -0
- package/esm/decode.js.map +1 -0
- package/esm/dom.d.ts +102 -0
- package/esm/dom.d.ts.map +1 -0
- package/esm/dom.js +320 -0
- package/esm/dom.js.map +1 -0
- package/esm/index.d.ts +232 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +1123 -0
- package/esm/index.js.map +1 -0
- package/esm/package.json +1 -0
- package/index.d.ts +232 -0
- package/index.d.ts.map +1 -0
- package/index.js +1129 -0
- package/package.json +72 -25
- package/.npmignore +0 -1
- package/.travis.yml +0 -9
- package/benchmark.js +0 -15
- package/lib/encoder.js +0 -140
- package/qr.js +0 -1
- package/test/encoder.js +0 -176
- package/test/qr.js +0 -16
package/package.json
CHANGED
|
@@ -1,30 +1,77 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"name": "qr",
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Minimal 0-dep QR code generator & reader. Supports ascii, term, gif and svg formats",
|
|
5
|
+
"files": [
|
|
6
|
+
"esm",
|
|
7
|
+
"index.js",
|
|
8
|
+
"index.d.ts",
|
|
9
|
+
"index.d.ts.map",
|
|
10
|
+
"index.ts",
|
|
11
|
+
"decode.js",
|
|
12
|
+
"decode.d.ts",
|
|
13
|
+
"decode.d.ts.map",
|
|
14
|
+
"decode.ts",
|
|
15
|
+
"dom.js",
|
|
16
|
+
"dom.d.ts",
|
|
17
|
+
"dom.d.ts.map",
|
|
18
|
+
"dom.ts",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"LICENSE-MIT"
|
|
21
|
+
],
|
|
22
|
+
"main": "index.js",
|
|
23
|
+
"module": "index.js",
|
|
24
|
+
"types": "index.d.ts",
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@paulmillr/jsbt": "0.3.3",
|
|
28
|
+
"micro-bmark": "0.4.1",
|
|
29
|
+
"micro-should": "0.5.2",
|
|
30
|
+
"prettier": "3.5.3",
|
|
31
|
+
"typescript": "5.8.3"
|
|
32
|
+
},
|
|
33
|
+
"author": "Paul Miller (https://paulmillr.com)",
|
|
34
|
+
"license": "(MIT OR Apache-2.0)",
|
|
35
|
+
"homepage": "https://github.com/paulmillr/qr",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/paulmillr/qr.git"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc && tsc -p tsconfig.cjs.json",
|
|
42
|
+
"build:release": "npx jsbt esbuild test/build",
|
|
43
|
+
"lint": "prettier --check src",
|
|
44
|
+
"format": "prettier --write src",
|
|
45
|
+
"test": "cd test; npm ci; node index.js",
|
|
46
|
+
"test:bun": "cd test; bun install; bun index.js",
|
|
47
|
+
"test:deno": "cd test; npm install; deno --allow-env --allow-read index.js"
|
|
48
|
+
},
|
|
49
|
+
"exports": {
|
|
50
|
+
".": {
|
|
51
|
+
"import": "./esm/index.js",
|
|
52
|
+
"require": "./index.js"
|
|
8
53
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"vows": ">= 0.5.8",
|
|
14
|
-
"benchmark": ""
|
|
54
|
+
"./decode.js": {
|
|
55
|
+
"import": "./esm/decode.js",
|
|
56
|
+
"require": "./decode.js"
|
|
15
57
|
},
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"repository": {
|
|
20
|
-
"type": "git",
|
|
21
|
-
"url": "git://github.com/heavyco/node-qr.git"
|
|
22
|
-
},
|
|
23
|
-
"license": {
|
|
24
|
-
"type": "MIT",
|
|
25
|
-
"url": "http://www.opensource.org/licenses/mit-license.php"
|
|
26
|
-
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"test": "vows --spec test/*.js"
|
|
58
|
+
"./dom.js": {
|
|
59
|
+
"import": "./esm/dom.js",
|
|
60
|
+
"require": "./dom.js"
|
|
29
61
|
}
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"qr",
|
|
65
|
+
"code",
|
|
66
|
+
"qr code",
|
|
67
|
+
"qr pattern",
|
|
68
|
+
"qr generator",
|
|
69
|
+
"qr reader",
|
|
70
|
+
"ascii",
|
|
71
|
+
"gif",
|
|
72
|
+
"svg",
|
|
73
|
+
"camera",
|
|
74
|
+
"file"
|
|
75
|
+
],
|
|
76
|
+
"funding": "https://paulmillr.com/funding/"
|
|
30
77
|
}
|
package/.npmignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
node_modules
|
package/.travis.yml
DELETED
package/benchmark.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
var Encoder = require('./qr').Encoder,
|
|
2
|
-
Benchmark = require('benchmark');
|
|
3
|
-
var encoder = new Encoder;
|
|
4
|
-
var suite = new Benchmark.Suite
|
|
5
|
-
|
|
6
|
-
suite.add('Encoder#encode()', function(){
|
|
7
|
-
encoder.encode('node-qr');
|
|
8
|
-
})
|
|
9
|
-
.on('cycle', function(event, bench){
|
|
10
|
-
console.log(String(bench));
|
|
11
|
-
})
|
|
12
|
-
.on('complete', function(){
|
|
13
|
-
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
|
14
|
-
})
|
|
15
|
-
.run({ 'async': true });
|
package/lib/encoder.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
var util = require('util'),
|
|
2
|
-
events = require('events'),
|
|
3
|
-
child_process = require('child_process');
|
|
4
|
-
|
|
5
|
-
var Encoder = exports.Encoder = function(){
|
|
6
|
-
events.EventEmitter.call(this);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
util.inherits(Encoder, events.EventEmitter);
|
|
11
|
-
|
|
12
|
-
Encoder.prototype.default_options = {
|
|
13
|
-
foreground_color: '#000000', // change foreground color in qrencode v3.4.0+
|
|
14
|
-
background_color: '#FFFFFF', // change background color in qrencode v3.4.0+
|
|
15
|
-
dot_size: 3, // default 3x3px per dot
|
|
16
|
-
margin: 4, // default 4 dots for the margin
|
|
17
|
-
level: 'L', // valid args (lowest to highest): L, M, Q, H
|
|
18
|
-
case_sensitive: true, // case sensitive,
|
|
19
|
-
version: 1, // default version 1,
|
|
20
|
-
type : null // Default to null type, removing this flag qrencode < v3.4.0
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
Encoder.prototype.types = ['PNG', 'EPS', 'SVG', 'ANSI', 'ANSI256', 'ASCII',
|
|
24
|
-
'ASCIIi', 'UTF8', 'ANSIUTF8', null];
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Converts a string value to QR Code PNG data, and optionally saves to a file
|
|
28
|
-
*
|
|
29
|
-
* @param String value The value to be encoded
|
|
30
|
-
* @param String path Where to save the PNG file (optional)
|
|
31
|
-
* @param Object options A hash of options (optional)
|
|
32
|
-
* @return void
|
|
33
|
-
*/
|
|
34
|
-
Encoder.prototype.encode = function(value, path, options)
|
|
35
|
-
{
|
|
36
|
-
// preserve scope in callbacks with self
|
|
37
|
-
var self = this,
|
|
38
|
-
cmd_options, qrencode_args, stdout, stderr, qrencode, exitcode;
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
// check for undefined value
|
|
42
|
-
if(value == undefined) {
|
|
43
|
-
throw new Error('No value specified for encode method');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// create new buffer for value
|
|
47
|
-
value = new Buffer(value);
|
|
48
|
-
|
|
49
|
-
// if options are given, override defaults
|
|
50
|
-
cmd_options = {};
|
|
51
|
-
if(options == null) options = {};
|
|
52
|
-
for(var key in this.default_options) {
|
|
53
|
-
cmd_options[key] = (options[key] == undefined) ?
|
|
54
|
-
this.default_options[key]
|
|
55
|
-
: options[key];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// start with base set of args that we'll always pass
|
|
59
|
-
qrencode_args = [
|
|
60
|
-
'-s', cmd_options.dot_size,
|
|
61
|
-
'-m', cmd_options.margin,
|
|
62
|
-
'-l', cmd_options.level,
|
|
63
|
-
'-v', cmd_options.version
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
// only set foreground and background colors if they differ from
|
|
67
|
-
// defaults to maintain compatibility with qrencode pre-v3.4.0
|
|
68
|
-
if(cmd_options.foreground_color !== self.default_options.foreground_color
|
|
69
|
-
|| cmd_options.background_color !== self.default_options.background_color) {
|
|
70
|
-
|
|
71
|
-
// remove # symbol from color codes because qrencoder does not like it
|
|
72
|
-
cmd_options.foreground_color = cmd_options.foreground_color.replace('#', '');
|
|
73
|
-
cmd_options.background_color = cmd_options.background_color.replace('#', '');
|
|
74
|
-
|
|
75
|
-
qrencode_args.push(
|
|
76
|
-
'--foreground=' + cmd_options.foreground_color,
|
|
77
|
-
'--background=' + cmd_options.background_color
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Only include the type flag if it has been passed to
|
|
82
|
-
// maintain compatibility with qrencode pre-v3.4.0
|
|
83
|
-
if(cmd_options.type !== null){
|
|
84
|
-
if(self.types.indexOf(cmd_options.type.toUpperCase()) === -1){
|
|
85
|
-
throw new Error('type must be one of ', self.types.toString());
|
|
86
|
-
}
|
|
87
|
-
qrencode_args.push('-t' + cmd_options.type);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// if case-sensitivity is disabled, add flag
|
|
91
|
-
if(!cmd_options.case_sensitive) qrencode_args.push('-i');
|
|
92
|
-
|
|
93
|
-
// if we have a path, write to the path
|
|
94
|
-
// otherwise, it will write to stdout
|
|
95
|
-
qrencode_args.push('-o');
|
|
96
|
-
if(path != null) {
|
|
97
|
-
qrencode_args.push(path);
|
|
98
|
-
} else {
|
|
99
|
-
qrencode_args.push('-');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// add the value to be encoded
|
|
103
|
-
qrencode_args.push(value);
|
|
104
|
-
|
|
105
|
-
// spawn the child process
|
|
106
|
-
qrencode = child_process.spawn(
|
|
107
|
-
'qrencode',
|
|
108
|
-
qrencode_args
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
// add event listener for stdout data and populate stdout var
|
|
112
|
-
// in the event no path was given
|
|
113
|
-
qrencode.stdout.on('data', function(data) {
|
|
114
|
-
stdout = data;
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// add event listener for stderr
|
|
118
|
-
qrencode.stderr.on('data', function(data) {
|
|
119
|
-
stderr = data;
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// add listener for process exit and save exit code
|
|
123
|
-
qrencode.on('exit', function(code) {
|
|
124
|
-
exitcode = code;
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// add listener for filehandle close and emit end or error event
|
|
128
|
-
// depending on exit code
|
|
129
|
-
qrencode.on('close', function() {
|
|
130
|
-
if(exitcode !== 0) {
|
|
131
|
-
self.emit('error', new Error(stderr));
|
|
132
|
-
} else {
|
|
133
|
-
self.emit('end', stdout);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
} catch(err) {
|
|
138
|
-
this.emit('error', err);
|
|
139
|
-
}
|
|
140
|
-
}
|
package/qr.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
exports.Encoder = require('./lib/encoder').Encoder;
|
package/test/encoder.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
var vows = require('vows'),
|
|
2
|
-
events = require('events'),
|
|
3
|
-
assert = require('assert'),
|
|
4
|
-
fs = require('fs'),
|
|
5
|
-
util = require('util'),
|
|
6
|
-
child_process = require('child_process'),
|
|
7
|
-
qr = require('../qr');
|
|
8
|
-
|
|
9
|
-
var Encoder = qr.Encoder;
|
|
10
|
-
var test_file_name = './test.png';
|
|
11
|
-
|
|
12
|
-
vows.describe('Encoder').addBatch({
|
|
13
|
-
'The libqrencode library': {
|
|
14
|
-
topic: function() {
|
|
15
|
-
var which = child_process.spawn('which', ['qrencode']);
|
|
16
|
-
which.on('exit', this.callback);
|
|
17
|
-
},
|
|
18
|
-
'is installed and available via $PATH': function(exit_code, process) {
|
|
19
|
-
assert.equal(exit_code, null, 'libqrencode does not appear to have been installed properly');
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}).addBatch({
|
|
23
|
-
'The encoder': {
|
|
24
|
-
topic: new(Encoder),
|
|
25
|
-
'is an event emitter': function(encoder) {
|
|
26
|
-
assert.ok((encoder instanceof events.EventEmitter));
|
|
27
|
-
},
|
|
28
|
-
'has some default options': function(encoder) {
|
|
29
|
-
assert.ok(encoder.default_options);
|
|
30
|
-
},
|
|
31
|
-
'has an encode method': function(encoder) {
|
|
32
|
-
assert.ok((typeof encoder.encode == "function"));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}).addBatch({
|
|
36
|
-
'The encode method': {
|
|
37
|
-
'with a provided value': {
|
|
38
|
-
'and a path': {
|
|
39
|
-
topic: function() {
|
|
40
|
-
var encoder = new Encoder;
|
|
41
|
-
encoder.on('end', this.callback);
|
|
42
|
-
encoder.encode('test', test_file_name);
|
|
43
|
-
},
|
|
44
|
-
'emits an \'end\' event': function(result, encoder) {
|
|
45
|
-
return true;
|
|
46
|
-
},
|
|
47
|
-
'creates a PNG file at provided path': function(result, encoder) {
|
|
48
|
-
var stats = fs.statSync(test_file_name);
|
|
49
|
-
assert.notEqual(stats.size, 0, 'Zero file size');
|
|
50
|
-
fs.unlinkSync(test_file_name);
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
'and no path': {
|
|
54
|
-
topic: function() {
|
|
55
|
-
var encoder = new Encoder;
|
|
56
|
-
encoder.on('end', this.callback);
|
|
57
|
-
encoder.encode('test');
|
|
58
|
-
},
|
|
59
|
-
'emits an \'end\' event': function(result, encoder) {
|
|
60
|
-
return true;
|
|
61
|
-
},
|
|
62
|
-
'provides PNG data with event': function(result, encoder) {
|
|
63
|
-
assert.ok((result instanceof Buffer));
|
|
64
|
-
assert.notEqual(result.length, 0, 'Zero buffer length');
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
'and a custom size option': {
|
|
68
|
-
topic: function() {
|
|
69
|
-
var encoder = new Encoder;
|
|
70
|
-
encoder.on('end', this.callback);
|
|
71
|
-
// set custom dot size of 10px
|
|
72
|
-
encoder.encode('test', null, { dot_size: 10 });
|
|
73
|
-
},
|
|
74
|
-
'provides PNG data with a custom size': function(result, encoder) {
|
|
75
|
-
assert.ok((result instanceof Buffer));
|
|
76
|
-
assert.notEqual(result.length, 0, 'Zero buffer length for custom size');
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
'and a custom margin option': {
|
|
80
|
-
topic: function() {
|
|
81
|
-
var encoder = new Encoder;
|
|
82
|
-
encoder.on('end', this.callback);
|
|
83
|
-
// set custom margin size of 5 dots
|
|
84
|
-
encoder.encode('test', null, { margin: 5 });
|
|
85
|
-
},
|
|
86
|
-
'provides PNG data with a custom margin': function(result, encoder) {
|
|
87
|
-
assert.ok((result instanceof Buffer));
|
|
88
|
-
assert.notEqual(result.length, 0, 'Zero buffer length for custom margin');
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
'and a custom level option': {
|
|
92
|
-
topic: function() {
|
|
93
|
-
var encoder = new Encoder;
|
|
94
|
-
encoder.on('end', this.callback);
|
|
95
|
-
// set a custom level option of 'H'
|
|
96
|
-
encoder.encode('test', null, { level: 'H' });
|
|
97
|
-
},
|
|
98
|
-
'provides PNG data with a custom level': function(result, encoder) {
|
|
99
|
-
assert.ok((result instanceof Buffer));
|
|
100
|
-
assert.notEqual(result.length, 0, 'Zero buffer length for custom level');
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
'and a custom version option': {
|
|
104
|
-
topic: function() {
|
|
105
|
-
var encoder = new Encoder;
|
|
106
|
-
encoder.on('end', this.callback);
|
|
107
|
-
// set a custom version
|
|
108
|
-
encoder.encode('test', null, { version: 10 });
|
|
109
|
-
},
|
|
110
|
-
'provides PNG data with a different version': function(result, encoder) {
|
|
111
|
-
assert.ok((result instanceof Buffer));
|
|
112
|
-
assert.notEqual(result.length, 0, 'Zero buffer length for custom version');
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
'and a custom type option': {
|
|
116
|
-
topic: function() {
|
|
117
|
-
var encoder = new Encoder;
|
|
118
|
-
encoder.on('end', this.callback);
|
|
119
|
-
// set a custom output
|
|
120
|
-
encoder.encode('test', null, { type: 'SVG' });
|
|
121
|
-
},
|
|
122
|
-
'provides SVG data' : function(result, encoder) {
|
|
123
|
-
assert.ok((result instanceof Buffer));
|
|
124
|
-
assert.notEqual(result.length, 0, 'Zero buffer length for custom type');
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
'and an invalid type option': {
|
|
128
|
-
topic: function() {
|
|
129
|
-
var encoder = new Encoder;
|
|
130
|
-
encoder.on('error', this.callback);
|
|
131
|
-
// set an incorrect type option
|
|
132
|
-
encoder.encode('test', null, { type: 'SPVG' });
|
|
133
|
-
},
|
|
134
|
-
'emits an \'error\' event with Error object' : function(result, encoder) {
|
|
135
|
-
assert.ok((result instanceof Error), 'Unexpected result emitted with error event');
|
|
136
|
-
assert.notEqual(result.message, "");
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
'and an invalid option': {
|
|
140
|
-
topic: function() {
|
|
141
|
-
var encoder = new Encoder;
|
|
142
|
-
encoder.on('error', this.callback);
|
|
143
|
-
// set bad option
|
|
144
|
-
encoder.encode('test', null, { version: 1000 });
|
|
145
|
-
},
|
|
146
|
-
'emits an \'error\' event with Error object': function(result, encoder) {
|
|
147
|
-
assert.ok((result instanceof Error), 'Unexpcted result emitted with error event');
|
|
148
|
-
assert.notEqual(result.message, "");
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
'and a bad path': {
|
|
152
|
-
topic: function() {
|
|
153
|
-
var encoder = new Encoder;
|
|
154
|
-
encoder.on('error', this.callback);
|
|
155
|
-
// set a bad path
|
|
156
|
-
encoder.encode('test', 'C:/notwindows/');
|
|
157
|
-
},
|
|
158
|
-
'emits an \'error\' event with Error object': function(result, encoder) {
|
|
159
|
-
assert.ok((result instanceof Error), 'Unexpcted result emitted with error event');
|
|
160
|
-
assert.notEqual(result.message, "");
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
'without a provided value': {
|
|
165
|
-
topic: function() {
|
|
166
|
-
var encoder = new Encoder;
|
|
167
|
-
encoder.on('error', this.callback);
|
|
168
|
-
encoder.encode();
|
|
169
|
-
},
|
|
170
|
-
'emits an \'error\' event with an Error object': function(result, encoder) {
|
|
171
|
-
assert.ok((result instanceof Error), 'Unexpcted result emitted with error event');
|
|
172
|
-
assert.equal(result.message, "No value specified for encode method");
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}).export(module);
|
package/test/qr.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
var vows = require('vows'),
|
|
2
|
-
assert = require('assert'),
|
|
3
|
-
util = require('util'),
|
|
4
|
-
qr = require('../qr');
|
|
5
|
-
|
|
6
|
-
vows.describe('QR').addBatch({
|
|
7
|
-
'The QR module': {
|
|
8
|
-
topic: qr,
|
|
9
|
-
'exists': function(qr) {
|
|
10
|
-
assert.notEqual(qr, undefined, 'QR module is undefined');
|
|
11
|
-
},
|
|
12
|
-
'has an encoder object': function(qr) {
|
|
13
|
-
assert.notEqual(qr.Encoder, undefined, 'QR Encoder undefined');
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}).export(module);
|