iosignal 1.7.0 → 1.8.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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +254 -247
  3. package/auth_file.json +13 -13
  4. package/auth_file.mjs +23 -23
  5. package/dist/iosignal-iife.js +11 -0
  6. package/dist/iosignal-iife.js.map +1 -0
  7. package/dist/iosignal.cjs +1 -2
  8. package/dist/iosignal.js +11 -0
  9. package/dist/iosignal.js.map +1 -0
  10. package/index.js +19 -19
  11. package/indexWebBrowser.js +13 -13
  12. package/package.json +56 -59
  13. package/rollup.config.js +72 -69
  14. package/src/api/RedisAPI.js +65 -65
  15. package/src/api/api_constant.js +7 -7
  16. package/src/api/api_reply.js +31 -31
  17. package/src/api/api_sudo.js +91 -91
  18. package/src/auth/Auth_Env.js +76 -76
  19. package/src/auth/Auth_File.js +71 -71
  20. package/src/auth/Auth_Redis.js +44 -44
  21. package/src/auth/BohoAuth.js +164 -164
  22. package/src/client/CongPacket.js +141 -141
  23. package/src/client/IOCongSocket.js +81 -81
  24. package/src/client/IOCore.js +822 -822
  25. package/src/client/IOWS.js +80 -80
  26. package/src/client/IOWebSocket.js +111 -111
  27. package/src/common/constants.js +148 -148
  28. package/src/common/payload.js +81 -81
  29. package/src/common/quotaTable.js +68 -68
  30. package/src/common/util.js +61 -61
  31. package/src/server/FileLogger.js +30 -30
  32. package/src/server/Manager.js +433 -433
  33. package/src/server/Metric.js +155 -155
  34. package/src/server/Remote.js +207 -207
  35. package/src/server/RemoteCore.js +439 -439
  36. package/src/server/Server.js +163 -163
  37. package/src/server/serverOption.js +56 -56
  38. package/test-browser/favicon.ico +0 -0
  39. package/test-browser/index.html +96 -96
  40. package/test-browser/server.js +11 -11
  41. package/test-client-nodejs/client.cjs +17 -17
  42. package/test-client-nodejs/client.mjs +17 -17
  43. package/test-client-nodejs/client_api_reply.mjs +15 -15
  44. package/test-client-nodejs/stateChange.mjs +19 -19
  45. package/test-server/server-Auth_Env.js +19 -19
  46. package/test-server/server-Auth_File.js +12 -12
  47. package/test-server/server-api_reply.js +6 -6
  48. package/test-server/server-api_sudo.js +7 -7
  49. package/test-server/server-commonjs.cjs +8 -8
  50. package/test-server/server-esm.mjs +20 -20
  51. package/test-server/simple-server.mjs +11 -11
  52. package/test-signal-payloadType/signalPack.js +34 -34
  53. package/test-signal-payloadType/signaling.js +60 -60
  54. package/dist/iosignal.esm.js +0 -3
  55. package/dist/iosignal.esm.js.map +0 -1
  56. package/dist/iosignal.min.js +0 -3
  57. package/dist/iosignal.min.js.map +0 -1
@@ -1,80 +1,80 @@
1
- import { IOCore } from "./IOCore.js";
2
- import { WebSocket } from "ws";
3
-
4
- // Node.js 'ws' websocket
5
- export class IOWS extends IOCore {
6
- constructor(url) {
7
- super(url);
8
- if (url) this.open();
9
- }
10
-
11
-
12
-
13
- close() {
14
- if (this.socket) {
15
- this.socket.onclose = null
16
- this.socket.onmessage = null
17
- this.socket.onerror = null
18
- this.socket.close();
19
- this.socket = null;
20
- }
21
- this.emit('close')
22
- }
23
-
24
-
25
-
26
- stop() {
27
- this.close()
28
- clearInterval(this.connectionCheckerIntervalID);
29
- this.connectionCheckerIntervalID = null
30
- }
31
-
32
- keepAlive() {
33
- if (!this.socket || this.socket?.readyState === 3) {
34
- this.open();
35
- }
36
- }
37
-
38
-
39
- createConnection(url) {
40
- // node WebSocket
41
- this.socket = new WebSocket(url);
42
- this.stateChange('opening')
43
-
44
- this.socket.onopen = () => {
45
- this.socket.on('message', this.onWebSocketMessage.bind(this));
46
- this.emit('open');
47
- };
48
-
49
- this.socket.onerror = (e) => {
50
- this.emit('error', e)
51
- }
52
-
53
- this.socket.onclose = () => {
54
- this.emit('close');
55
- }
56
- }
57
-
58
- onWebSocketMessage(data) {
59
- this.rxCounter++;
60
- this.lastTxRxTime = Date.now();
61
- this.rxBytes += data.byteLength
62
- this.emit('socket_data', data);
63
- }
64
-
65
- socket_send(data) {
66
- if (this.socket?.readyState === 1) {
67
- this.socket.send(data)
68
- this.txCounter++;
69
- this.txBytes += data.byteLength
70
- this.lastTxRxTime = Date.now();
71
- } else {
72
- console.log('.')
73
- }
74
- }
75
-
76
- }
77
-
78
-
79
-
80
-
1
+ import { IOCore } from "./IOCore.js";
2
+ import { WebSocket } from "ws";
3
+
4
+ // Node.js 'ws' websocket
5
+ export class IOWS extends IOCore {
6
+ constructor(url) {
7
+ super(url);
8
+ if (url) this.open();
9
+ }
10
+
11
+
12
+
13
+ close() {
14
+ if (this.socket) {
15
+ this.socket.onclose = null
16
+ this.socket.onmessage = null
17
+ this.socket.onerror = null
18
+ this.socket.close();
19
+ this.socket = null;
20
+ }
21
+ this.emit('close')
22
+ }
23
+
24
+
25
+
26
+ stop() {
27
+ this.close()
28
+ clearInterval(this.connectionCheckerIntervalID);
29
+ this.connectionCheckerIntervalID = null
30
+ }
31
+
32
+ keepAlive() {
33
+ if (!this.socket || this.socket?.readyState === 3) {
34
+ this.open();
35
+ }
36
+ }
37
+
38
+
39
+ createConnection(url) {
40
+ // node WebSocket
41
+ this.socket = new WebSocket(url);
42
+ this.stateChange('opening')
43
+
44
+ this.socket.onopen = () => {
45
+ this.socket.on('message', this.onWebSocketMessage.bind(this));
46
+ this.emit('open');
47
+ };
48
+
49
+ this.socket.onerror = (e) => {
50
+ this.emit('error', e)
51
+ }
52
+
53
+ this.socket.onclose = () => {
54
+ this.emit('close');
55
+ }
56
+ }
57
+
58
+ onWebSocketMessage(data) {
59
+ this.rxCounter++;
60
+ this.lastTxRxTime = Date.now();
61
+ this.rxBytes += data.byteLength
62
+ this.emit('socket_data', data);
63
+ }
64
+
65
+ socket_send(data) {
66
+ if (this.socket?.readyState === 1) {
67
+ this.socket.send(data)
68
+ this.txCounter++;
69
+ this.txBytes += data.byteLength
70
+ this.lastTxRxTime = Date.now();
71
+ } else {
72
+ console.log('.')
73
+ }
74
+ }
75
+
76
+ }
77
+
78
+
79
+
80
+
@@ -1,111 +1,111 @@
1
- import { IOCore } from "./IOCore.js";
2
- import { Buffer } from 'meta-buffer-pack'
3
- export { Boho, RAND, BohoMsg, Meta, MetaSize, sha256, MBP, Buffer } from 'boho'
4
- export * from '../common/constants.js'
5
-
6
- // Browser WebSocket
7
- export class IO extends IOCore {
8
- static binaryType = "arraybuffer"
9
-
10
- constructor(url) {
11
- super(url);
12
- document.addEventListener('visibilitychange', this.browserVisiblePing.bind(this));
13
- if (url) this.open();
14
- }
15
-
16
- browserVisiblePing() {
17
- if (document.visibilityState === 'visible') {
18
- this.ping()
19
- }
20
- }
21
-
22
-
23
- close() {
24
- if (this.socket) {
25
- this.socket.onclose = null
26
- this.socket.onmessage = null
27
- this.socket.onerror = null
28
- this.socket.close();
29
- this.socket = null;
30
- }
31
- this.emit('close')
32
- }
33
-
34
-
35
- stop() {
36
- this.close()
37
- clearInterval(this.connectionCheckerIntervalID);
38
- this.connectionCheckerIntervalID = null
39
- }
40
-
41
-
42
- keepAlive() {
43
- if (!this.socket || this.socket?.readyState === 3) {
44
- this.open();
45
- }
46
- }
47
-
48
-
49
-
50
- createConnection(url) {
51
- // Web Browser WebSocket
52
- this.socket = new WebSocket(url);
53
- this.socket.binaryType = IO.binaryType
54
-
55
- this.stateChange('opening')
56
-
57
- this.socket.onopen = () => {
58
- if (this.socket.binaryType == "arraybuffer") {
59
- this.socket.onmessage = this.onWebSocketMessage.bind(this);
60
- } else { // blob
61
- this.socket.onmessage = this.onWebSocketMessageBlob.bind(this);
62
- }
63
- this.emit('open');
64
- };
65
-
66
- this.socket.onerror = (e) => {
67
- this.emit('error', e)
68
- }
69
-
70
- this.socket.onclose = () => {
71
- this.emit('close');
72
- }
73
- }
74
-
75
- onWebSocketMessage(event) {
76
- // event.data is arrayBuffer or text_message
77
- this.rxCounter++;
78
- this.lastTxRxTime = Date.now();
79
- let buffer = Buffer.from(event.data)
80
- this.rxBytes += buffer.byteLength
81
- this.emit('socket_data', buffer);
82
- }
83
-
84
- async onWebSocketMessageBlob(event) {
85
- // event.data is Blob or text_message
86
- this.rxCounter++;
87
- this.lastTxRxTime = Date.now();
88
- let buffer;
89
- if (event.data instanceof Blob) {
90
- let ab = await event.data.arrayBuffer()
91
- buffer = Buffer.from(ab)
92
- } else {
93
- buffer = Buffer.from(event.data)
94
- }
95
- this.rxBytes += buffer.byteLength
96
- this.emit('socket_data', buffer);
97
- }
98
-
99
- socket_send(data) {
100
- if (this.socket?.readyState === 1) {
101
- this.socket.send(data)
102
- this.txCounter++;
103
- this.txBytes += data.byteLength
104
- this.lastTxRxTime = Date.now();
105
- } else {
106
- console.log('.')
107
- }
108
- }
109
-
110
- }
111
-
1
+ import { IOCore } from "./IOCore.js";
2
+ import { Buffer } from 'meta-buffer-pack'
3
+ export { Boho, RAND, BohoMsg, Meta, MetaSize, sha256, MBP, Buffer } from 'boho'
4
+ export * from '../common/constants.js'
5
+
6
+ // Browser WebSocket
7
+ export class IO extends IOCore {
8
+ static binaryType = "arraybuffer"
9
+
10
+ constructor(url) {
11
+ super(url);
12
+ document.addEventListener('visibilitychange', this.browserVisiblePing.bind(this));
13
+ if (url) this.open();
14
+ }
15
+
16
+ browserVisiblePing() {
17
+ if (document.visibilityState === 'visible') {
18
+ this.ping()
19
+ }
20
+ }
21
+
22
+
23
+ close() {
24
+ if (this.socket) {
25
+ this.socket.onclose = null
26
+ this.socket.onmessage = null
27
+ this.socket.onerror = null
28
+ this.socket.close();
29
+ this.socket = null;
30
+ }
31
+ this.emit('close')
32
+ }
33
+
34
+
35
+ stop() {
36
+ this.close()
37
+ clearInterval(this.connectionCheckerIntervalID);
38
+ this.connectionCheckerIntervalID = null
39
+ }
40
+
41
+
42
+ keepAlive() {
43
+ if (!this.socket || this.socket?.readyState === 3) {
44
+ this.open();
45
+ }
46
+ }
47
+
48
+
49
+
50
+ createConnection(url) {
51
+ // Web Browser WebSocket
52
+ this.socket = new WebSocket(url);
53
+ this.socket.binaryType = IO.binaryType
54
+
55
+ this.stateChange('opening')
56
+
57
+ this.socket.onopen = () => {
58
+ if (this.socket.binaryType == "arraybuffer") {
59
+ this.socket.onmessage = this.onWebSocketMessage.bind(this);
60
+ } else { // blob
61
+ this.socket.onmessage = this.onWebSocketMessageBlob.bind(this);
62
+ }
63
+ this.emit('open');
64
+ };
65
+
66
+ this.socket.onerror = (e) => {
67
+ this.emit('error', e)
68
+ }
69
+
70
+ this.socket.onclose = () => {
71
+ this.emit('close');
72
+ }
73
+ }
74
+
75
+ onWebSocketMessage(event) {
76
+ // event.data is arrayBuffer or text_message
77
+ this.rxCounter++;
78
+ this.lastTxRxTime = Date.now();
79
+ let buffer = Buffer.from(event.data)
80
+ this.rxBytes += buffer.byteLength
81
+ this.emit('socket_data', buffer);
82
+ }
83
+
84
+ async onWebSocketMessageBlob(event) {
85
+ // event.data is Blob or text_message
86
+ this.rxCounter++;
87
+ this.lastTxRxTime = Date.now();
88
+ let buffer;
89
+ if (event.data instanceof Blob) {
90
+ let ab = await event.data.arrayBuffer()
91
+ buffer = Buffer.from(ab)
92
+ } else {
93
+ buffer = Buffer.from(event.data)
94
+ }
95
+ this.rxBytes += buffer.byteLength
96
+ this.emit('socket_data', buffer);
97
+ }
98
+
99
+ socket_send(data) {
100
+ if (this.socket?.readyState === 1) {
101
+ this.socket.send(data)
102
+ this.txCounter++;
103
+ this.txBytes += data.byteLength
104
+ this.lastTxRxTime = Date.now();
105
+ } else {
106
+ console.log('.')
107
+ }
108
+ }
109
+
110
+ }
111
+
@@ -1,148 +1,148 @@
1
-
2
- // Client STATES: name and number
3
- export const STATES = {
4
- OPENING: 0,
5
- OPEN: 1,
6
- CLOSING: 2,
7
- CLOSED: 3,
8
- SERVER_READY: 4,
9
- AUTH_FAIL: 5,
10
- AUTH_READY: 6,
11
- READY: 7,
12
- REDIRECTING: 8
13
- }
14
- for (let c in STATES) { STATES[STATES[c]] = c }
15
-
16
- // server side client state
17
- export const CLIENT_STATE = {
18
- INIT: 0,
19
- SENT_SERVER_READY: 1,
20
- RECV_AUTH_REQ: 2,
21
- SENT_SERVER_NONCE: 3,
22
- RECV_AUTH_HMAC: 4,
23
- AUTH_FAIL: 5,
24
- AUTH_READY: 6,
25
- CID_READY: 7
26
- }
27
- for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
28
-
29
- export let ENC_MODE = {
30
- NO: 0,
31
- YES: 1,
32
- AUTO: 2
33
- }
34
-
35
- for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
36
-
37
-
38
- export const SIZE_LIMIT = {
39
- TAG_LEN1: 255,
40
- TAG_LEN2: 65535,
41
- CONNECTION_CHECKER_PERIOD: 3000,
42
- PROMISE_TIMEOUT: 5000,
43
- DID: 8,
44
- CID: 12
45
- }
46
-
47
- export let PAYLOAD_TYPE = {
48
- EMPTY: 0,
49
- TEXT: 1,
50
- BINARY: 2,
51
- OBJECT: 3, // one stringifiable object. it's string.
52
- MJSON: 4, // multiple stringifiable obejct. it's top-level array JSON string.
53
- MBA: 5 // "meta_buffer_arguments" arbitary types. it's meta-buffer-pack.
54
- }
55
- for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
56
-
57
-
58
- // IO message's one-byte headers.
59
- export let IOMsg = {
60
-
61
- /*
62
- * 0~127dec. reserved. for text stream.
63
- * 0~31: control code
64
- * 32~126: ascii charactor
65
- * 127: DEL
66
- */
67
-
68
- // ADMIN_REQ: 0xA0,
69
-
70
- // DO NOT USE: 0xB0~ 0xBF
71
- // Boho module using this numbers.
72
- // AUTH_REQ : 0xB0,
73
- // AUTH_NONCE: 0xB1,
74
- // AUTH_HMAC: 0xB2,
75
- // AUTH_ACK: 0xB3,
76
- // AUTH_FAIL: 0xB4,
77
- // AUTH_EXT: 0xB5,
78
- // ENC_PACK : 0xB6,
79
- // ENC_E2E : 0xB7,
80
- // ENC_488 : 0xB8
81
- // reserved ~0xBF
82
-
83
- // C. IO status contorl.
84
- SERVER_READY: 0xC0,
85
- CID_REQ: 0xC1,
86
- CID_RES: 0xC2,
87
- QUOTA_LEVEL: 0xC3,
88
- SERVER_CLEAR_AUTH: 0xC4,
89
- SERVER_REDIRECT: 0xC5,
90
-
91
- // ..
92
- LOOP: 0xCB,
93
- ECHO: 0xCC,
94
- PING: 0xCD,
95
- PONG: 0xCE,
96
- CLOSE: 0xCF,
97
- // ~CF
98
-
99
-
100
- // D. IO data signaling
101
- SIGNAL: 0xD0,
102
- SIGNAL_REQ: 0xD1,
103
- SIGNAL_E2E: 0xD2,
104
- SUBSCRIBE: 0xD3,
105
- SUBSCRIBE_REQ: 0xD4,
106
- UNSUBSCRIBE: 0xD5,
107
- SERVER_SIGNAL: 0xD6,
108
-
109
- // ..
110
- IAM: 0xD9,
111
- IAM_RES: 0xDA,
112
-
113
- //..
114
- SET: 0xDB, //
115
- RESPONSE_CODE: 0xDC,
116
- RESPONSE_MBP: 0xDD,
117
-
118
- REQUEST: 0xDE, //client public
119
- RESPONSE: 0xDF,
120
- // ~DF
121
-
122
-
123
- // F. Framing Flow control related framing protocol.(CongPacket)
124
- FLOW_MODE: 0xF0,
125
- WAIT: 0xF1,
126
- RESUME: 0xF2,
127
- //..
128
- TIME_OUT: 0xFD,
129
- OVER_SIZE: 0xFE,
130
- OVER_FLOW: 0xFF
131
-
132
- }
133
-
134
- for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
135
- // console.log( IOMsg );
136
-
137
- export const API_TYPE = {
138
- 'REQUEST_RESPONSE': 'requet_response',
139
- 'ONE_WAY': 'one_way'
140
- }
141
-
142
- // api response status code
143
- export const STATUS = {
144
- OK: 0,
145
- //0~127: success
146
- //128~255: fail
147
- ERROR: 255
148
- }
1
+
2
+ // Client STATES: name and number
3
+ export const STATES = {
4
+ OPENING: 0,
5
+ OPEN: 1,
6
+ CLOSING: 2,
7
+ CLOSED: 3,
8
+ SERVER_READY: 4,
9
+ AUTH_FAIL: 5,
10
+ AUTH_READY: 6,
11
+ READY: 7,
12
+ REDIRECTING: 8
13
+ }
14
+ for (let c in STATES) { STATES[STATES[c]] = c }
15
+
16
+ // server side client state
17
+ export const CLIENT_STATE = {
18
+ INIT: 0,
19
+ SENT_SERVER_READY: 1,
20
+ RECV_AUTH_REQ: 2,
21
+ SENT_SERVER_NONCE: 3,
22
+ RECV_AUTH_HMAC: 4,
23
+ AUTH_FAIL: 5,
24
+ AUTH_READY: 6,
25
+ CID_READY: 7
26
+ }
27
+ for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
28
+
29
+ export let ENC_MODE = {
30
+ NO: 0,
31
+ YES: 1,
32
+ AUTO: 2
33
+ }
34
+
35
+ for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
36
+
37
+
38
+ export const SIZE_LIMIT = {
39
+ TAG_LEN1: 255,
40
+ TAG_LEN2: 65535,
41
+ CONNECTION_CHECKER_PERIOD: 3000,
42
+ PROMISE_TIMEOUT: 5000,
43
+ DID: 8,
44
+ CID: 12
45
+ }
46
+
47
+ export let PAYLOAD_TYPE = {
48
+ EMPTY: 0,
49
+ TEXT: 1,
50
+ BINARY: 2,
51
+ OBJECT: 3, // one stringifiable object. it's string.
52
+ MJSON: 4, // multiple stringifiable obejct. it's top-level array JSON string.
53
+ MBA: 5 // "meta_buffer_arguments" arbitary types. it's meta-buffer-pack.
54
+ }
55
+ for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
56
+
57
+
58
+ // IO message's one-byte headers.
59
+ export let IOMsg = {
60
+
61
+ /*
62
+ * 0~127dec. reserved. for text stream.
63
+ * 0~31: control code
64
+ * 32~126: ascii charactor
65
+ * 127: DEL
66
+ */
67
+
68
+ // ADMIN_REQ: 0xA0,
69
+
70
+ // DO NOT USE: 0xB0~ 0xBF
71
+ // Boho module using this numbers.
72
+ // AUTH_REQ : 0xB0,
73
+ // AUTH_NONCE: 0xB1,
74
+ // AUTH_HMAC: 0xB2,
75
+ // AUTH_ACK: 0xB3,
76
+ // AUTH_FAIL: 0xB4,
77
+ // AUTH_EXT: 0xB5,
78
+ // ENC_PACK : 0xB6,
79
+ // ENC_E2E : 0xB7,
80
+ // ENC_488 : 0xB8
81
+ // reserved ~0xBF
82
+
83
+ // C. IO status contorl.
84
+ SERVER_READY: 0xC0,
85
+ CID_REQ: 0xC1,
86
+ CID_RES: 0xC2,
87
+ QUOTA_LEVEL: 0xC3,
88
+ SERVER_CLEAR_AUTH: 0xC4,
89
+ SERVER_REDIRECT: 0xC5,
90
+
91
+ // ..
92
+ LOOP: 0xCB,
93
+ ECHO: 0xCC,
94
+ PING: 0xCD,
95
+ PONG: 0xCE,
96
+ CLOSE: 0xCF,
97
+ // ~CF
98
+
99
+
100
+ // D. IO data signaling
101
+ SIGNAL: 0xD0,
102
+ SIGNAL_REQ: 0xD1,
103
+ SIGNAL_E2E: 0xD2,
104
+ SUBSCRIBE: 0xD3,
105
+ SUBSCRIBE_REQ: 0xD4,
106
+ UNSUBSCRIBE: 0xD5,
107
+ SERVER_SIGNAL: 0xD6,
108
+
109
+ // ..
110
+ IAM: 0xD9,
111
+ IAM_RES: 0xDA,
112
+
113
+ //..
114
+ SET: 0xDB, //
115
+ RESPONSE_CODE: 0xDC,
116
+ RESPONSE_MBP: 0xDD,
117
+
118
+ REQUEST: 0xDE, //client public
119
+ RESPONSE: 0xDF,
120
+ // ~DF
121
+
122
+
123
+ // F. Framing Flow control related framing protocol.(CongPacket)
124
+ FLOW_MODE: 0xF0,
125
+ WAIT: 0xF1,
126
+ RESUME: 0xF2,
127
+ //..
128
+ TIME_OUT: 0xFD,
129
+ OVER_SIZE: 0xFE,
130
+ OVER_FLOW: 0xFF
131
+
132
+ }
133
+
134
+ for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
135
+ // console.log( IOMsg );
136
+
137
+ export const API_TYPE = {
138
+ 'REQUEST_RESPONSE': 'requet_response',
139
+ 'ONE_WAY': 'one_way'
140
+ }
141
+
142
+ // api response status code
143
+ export const STATUS = {
144
+ OK: 0,
145
+ //0~127: success
146
+ //128~255: fail
147
+ ERROR: 255
148
+ }