@robdobsn/raftjs 1.1.1

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 (149) hide show
  1. package/.editorconfig +14 -0
  2. package/.gitattributes +11 -0
  3. package/.nvmrc +1 -0
  4. package/LICENSE +22 -0
  5. package/README.md +11 -0
  6. package/TODO.md +1 -0
  7. package/dist/RaftAttributeHandler.d.ts +12 -0
  8. package/dist/RaftAttributeHandler.js +241 -0
  9. package/dist/RaftAttributeHandler.js.map +1 -0
  10. package/dist/RaftChannel.d.ts +18 -0
  11. package/dist/RaftChannel.js +12 -0
  12. package/dist/RaftChannel.js.map +1 -0
  13. package/dist/RaftChannelWebBLE.d.ts +38 -0
  14. package/dist/RaftChannelWebBLE.js +274 -0
  15. package/dist/RaftChannelWebBLE.js.map +1 -0
  16. package/dist/RaftChannelWebSerial.d.ts +37 -0
  17. package/dist/RaftChannelWebSerial.js +319 -0
  18. package/dist/RaftChannelWebSerial.js.map +1 -0
  19. package/dist/RaftChannelWebSocket.d.ts +28 -0
  20. package/dist/RaftChannelWebSocket.js +197 -0
  21. package/dist/RaftChannelWebSocket.js.map +1 -0
  22. package/dist/RaftCommsStats.d.ts +39 -0
  23. package/dist/RaftCommsStats.js +128 -0
  24. package/dist/RaftCommsStats.js.map +1 -0
  25. package/dist/RaftConnEvents.d.ts +31 -0
  26. package/dist/RaftConnEvents.js +44 -0
  27. package/dist/RaftConnEvents.js.map +1 -0
  28. package/dist/RaftConnector.d.ts +242 -0
  29. package/dist/RaftConnector.js +613 -0
  30. package/dist/RaftConnector.js.map +1 -0
  31. package/dist/RaftCustomAttrHandler.d.ts +4 -0
  32. package/dist/RaftCustomAttrHandler.js +50 -0
  33. package/dist/RaftCustomAttrHandler.js.map +1 -0
  34. package/dist/RaftDeviceInfo.d.ts +64 -0
  35. package/dist/RaftDeviceInfo.js +36 -0
  36. package/dist/RaftDeviceInfo.js.map +1 -0
  37. package/dist/RaftDeviceManager.d.ts +37 -0
  38. package/dist/RaftDeviceManager.js +450 -0
  39. package/dist/RaftDeviceManager.js.map +1 -0
  40. package/dist/RaftDeviceMsg.d.ts +9 -0
  41. package/dist/RaftDeviceMsg.js +11 -0
  42. package/dist/RaftDeviceMsg.js.map +1 -0
  43. package/dist/RaftDeviceStates.d.ts +33 -0
  44. package/dist/RaftDeviceStates.js +60 -0
  45. package/dist/RaftDeviceStates.js.map +1 -0
  46. package/dist/RaftFileHandler.d.ts +52 -0
  47. package/dist/RaftFileHandler.js +502 -0
  48. package/dist/RaftFileHandler.js.map +1 -0
  49. package/dist/RaftLog.d.ts +22 -0
  50. package/dist/RaftLog.js +63 -0
  51. package/dist/RaftLog.js.map +1 -0
  52. package/dist/RaftMiniHDLC.d.ts +18 -0
  53. package/dist/RaftMiniHDLC.js +383 -0
  54. package/dist/RaftMiniHDLC.js.map +1 -0
  55. package/dist/RaftMsgHandler.d.ts +57 -0
  56. package/dist/RaftMsgHandler.js +480 -0
  57. package/dist/RaftMsgHandler.js.map +1 -0
  58. package/dist/RaftMsgTrackInfo.d.ts +17 -0
  59. package/dist/RaftMsgTrackInfo.js +42 -0
  60. package/dist/RaftMsgTrackInfo.js.map +1 -0
  61. package/dist/RaftProtocolDefs.d.ts +30 -0
  62. package/dist/RaftProtocolDefs.js +48 -0
  63. package/dist/RaftProtocolDefs.js.map +1 -0
  64. package/dist/RaftStreamHandler.d.ts +38 -0
  65. package/dist/RaftStreamHandler.js +257 -0
  66. package/dist/RaftStreamHandler.js.map +1 -0
  67. package/dist/RaftSystemType.d.ts +21 -0
  68. package/dist/RaftSystemType.js +3 -0
  69. package/dist/RaftSystemType.js.map +1 -0
  70. package/dist/RaftSystemUtils.d.ts +136 -0
  71. package/dist/RaftSystemUtils.js +410 -0
  72. package/dist/RaftSystemUtils.js.map +1 -0
  73. package/dist/RaftTypes.d.ts +184 -0
  74. package/dist/RaftTypes.js +157 -0
  75. package/dist/RaftTypes.js.map +1 -0
  76. package/dist/RaftUpdateEvents.d.ts +33 -0
  77. package/dist/RaftUpdateEvents.js +46 -0
  78. package/dist/RaftUpdateEvents.js.map +1 -0
  79. package/dist/RaftUpdateManager.d.ts +61 -0
  80. package/dist/RaftUpdateManager.js +618 -0
  81. package/dist/RaftUpdateManager.js.map +1 -0
  82. package/dist/RaftUtils.d.ts +125 -0
  83. package/dist/RaftUtils.js +454 -0
  84. package/dist/RaftUtils.js.map +1 -0
  85. package/dist/RaftWifiTypes.d.ts +23 -0
  86. package/dist/RaftWifiTypes.js +43 -0
  87. package/dist/RaftWifiTypes.js.map +1 -0
  88. package/dist/TestDataGen.d.ts +7 -0
  89. package/dist/TestDataGen.js +133 -0
  90. package/dist/TestDataGen.js.map +1 -0
  91. package/dist/main.d.ts +18 -0
  92. package/dist/main.js +42 -0
  93. package/dist/main.js.map +1 -0
  94. package/eslint.config.mjs +33 -0
  95. package/examples/dashboard/package.json +39 -0
  96. package/examples/dashboard/src/ConnManager.ts +86 -0
  97. package/examples/dashboard/src/Main.tsx +100 -0
  98. package/examples/dashboard/src/StatusScreen.tsx +72 -0
  99. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +144 -0
  100. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +77 -0
  101. package/examples/dashboard/src/SystemTypeMarty/RICAddOn.ts +70 -0
  102. package/examples/dashboard/src/SystemTypeMarty/RICAddOnBase.ts +33 -0
  103. package/examples/dashboard/src/SystemTypeMarty/RICAddOnManager.ts +342 -0
  104. package/examples/dashboard/src/SystemTypeMarty/RICCommsStats.ts +170 -0
  105. package/examples/dashboard/src/SystemTypeMarty/RICHWElem.ts +123 -0
  106. package/examples/dashboard/src/SystemTypeMarty/RICLEDPatternChecker.ts +207 -0
  107. package/examples/dashboard/src/SystemTypeMarty/RICROSSerial.ts +464 -0
  108. package/examples/dashboard/src/SystemTypeMarty/RICServoFaultDetector.ts +146 -0
  109. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +32 -0
  110. package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +371 -0
  111. package/examples/dashboard/src/SystemTypeMarty/RICTypes.ts +20 -0
  112. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +113 -0
  113. package/examples/dashboard/src/index.html +15 -0
  114. package/examples/dashboard/src/index.tsx +15 -0
  115. package/examples/dashboard/src/styles.css +122 -0
  116. package/examples/dashboard/tsconfig.json +18 -0
  117. package/jest.config.js +11 -0
  118. package/package.json +50 -0
  119. package/src/RaftAttributeHandler.ts +289 -0
  120. package/src/RaftChannel.ts +30 -0
  121. package/src/RaftChannelWebBLE.ts +342 -0
  122. package/src/RaftChannelWebSerial.ts +408 -0
  123. package/src/RaftChannelWebSocket.ts +245 -0
  124. package/src/RaftCommsStats.ts +142 -0
  125. package/src/RaftConnEvents.ts +46 -0
  126. package/src/RaftConnector.ts +745 -0
  127. package/src/RaftCustomAttrHandler.ts +54 -0
  128. package/src/RaftDeviceInfo.ts +104 -0
  129. package/src/RaftDeviceManager.ts +542 -0
  130. package/src/RaftDeviceMsg.ts +20 -0
  131. package/src/RaftDeviceStates.ts +89 -0
  132. package/src/RaftFileHandler.ts +668 -0
  133. package/src/RaftLog.ts +70 -0
  134. package/src/RaftMiniHDLC.ts +396 -0
  135. package/src/RaftMsgHandler.ts +778 -0
  136. package/src/RaftMsgTrackInfo.ts +51 -0
  137. package/src/RaftProtocolDefs.ts +46 -0
  138. package/src/RaftStreamHandler.ts +328 -0
  139. package/src/RaftSystemType.ts +25 -0
  140. package/src/RaftSystemUtils.ts +487 -0
  141. package/src/RaftTypes.ts +250 -0
  142. package/src/RaftUpdateEvents.ts +48 -0
  143. package/src/RaftUpdateManager.ts +778 -0
  144. package/src/RaftUtils.ts +484 -0
  145. package/src/RaftWifiTypes.ts +36 -0
  146. package/src/TestDataGen.ts +157 -0
  147. package/src/main.ts +28 -0
  148. package/testdata/TestDeviceTypeRecs.json +492 -0
  149. package/tsconfig.json +27 -0
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3
+ //
4
+ // RaftChannelWebBLE
5
+ // Part of RaftJS
6
+ //
7
+ // Rob Dobson & Chris Greening 2020-2024
8
+ // (C) 2020-2024 All rights reserved
9
+ //
10
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const tslib_1 = require("tslib");
13
+ const RaftConnEvents_1 = require("./RaftConnEvents");
14
+ const RaftLog_1 = tslib_1.__importDefault(require("./RaftLog"));
15
+ const RaftUtils_1 = tslib_1.__importDefault(require("./RaftUtils"));
16
+ class RaftChannelWebBLE {
17
+ constructor() {
18
+ // Device and characteristics
19
+ this._bleDevice = null;
20
+ this._characteristicTx = null;
21
+ this._characteristicRx = null;
22
+ // Message handler
23
+ this._raftMsgHandler = null;
24
+ // Conn event fn
25
+ this._onConnEvent = null;
26
+ // Last message tx time
27
+ this._msgTxTimeLast = Date.now();
28
+ this._msgTxMinTimeBetweenMs = 1;
29
+ this.maxRetries = 1;
30
+ // Connected flag and retries
31
+ this._isConnected = false;
32
+ this._maxConnRetries = 3;
33
+ // Event listener fn
34
+ this._eventListenerFn = null;
35
+ // File Handler parameters
36
+ this._requestedBatchAckSize = 10;
37
+ this._requestedFileBlockSize = 500;
38
+ }
39
+ fhBatchAckSize() {
40
+ return this._requestedBatchAckSize;
41
+ }
42
+ fhFileBlockSize() {
43
+ return this._requestedFileBlockSize;
44
+ }
45
+ // Set message handler
46
+ setMsgHandler(raftMsgHandler) {
47
+ this._raftMsgHandler = raftMsgHandler;
48
+ }
49
+ requiresSubscription() {
50
+ return true;
51
+ }
52
+ // RICREST command before disconnect
53
+ ricRestCmdBeforeDisconnect() {
54
+ return "blerestart";
55
+ }
56
+ // isEnabled
57
+ isEnabled() {
58
+ if (navigator.bluetooth) {
59
+ RaftLog_1.default.error("Web Bluetooth is supported in your browser.");
60
+ return true;
61
+ }
62
+ else {
63
+ window.alert("Web Bluetooth API is not available.\n" +
64
+ 'Please make sure the "Experimental Web Platform features" flag is enabled.');
65
+ return false;
66
+ }
67
+ }
68
+ // isConnected
69
+ isConnected() {
70
+ return this._bleDevice !== null && this._isConnected;
71
+ }
72
+ // Set onConnEvent handler
73
+ setOnConnEvent(connEventFn) {
74
+ this._onConnEvent = connEventFn;
75
+ }
76
+ // Disconnection event
77
+ onDisconnected(event) {
78
+ const device = event.target;
79
+ RaftLog_1.default.debug(`RaftChannelWebBLE.onDisconnected ${device.name}`);
80
+ if (this._bleDevice) {
81
+ this._bleDevice.removeEventListener("gattserverdisconnected", this._eventListenerFn);
82
+ }
83
+ this._isConnected = false;
84
+ if (this._onConnEvent) {
85
+ this._onConnEvent(RaftConnEvents_1.RaftConnEvent.CONN_DISCONNECTED);
86
+ }
87
+ }
88
+ // Get connected locator
89
+ getConnectedLocator() {
90
+ return this._bleDevice || "";
91
+ }
92
+ // Connect to a device
93
+ async connect(locator, _connectorOptions) {
94
+ // RaftLog.debug(`Selected device: ${deviceID}`);
95
+ this._bleDevice = locator;
96
+ if (this._bleDevice && this._bleDevice.gatt) {
97
+ try {
98
+ // Connect
99
+ for (let connRetry = 0; connRetry < this._maxConnRetries; connRetry++) {
100
+ // Connect
101
+ const connTimeoutMs = _connectorOptions.connTimeoutMs || 5000;
102
+ await RaftUtils_1.default.withTimeout(connTimeoutMs, this._bleDevice.gatt.connect());
103
+ RaftLog_1.default.debug(`RaftChannelWebBLE.connect - ${this._bleDevice.gatt.connected ? "OK" : "FAILED"} attempt ${connRetry + 1} connection to device ${this._bleDevice.name}`);
104
+ if (this._bleDevice.gatt.connected) {
105
+ // Delay a bit
106
+ await new Promise(resolve => setTimeout(resolve, 100));
107
+ // Get service
108
+ try {
109
+ const service = await this._bleDevice.gatt.getPrimaryService(RaftChannelWebBLE.ServiceUUID);
110
+ RaftLog_1.default.debug(`RaftChannelWebBLE.connect - found service: ${service.uuid}`);
111
+ try {
112
+ // Get Tx and Rx characteristics
113
+ this._characteristicTx = await service.getCharacteristic(RaftChannelWebBLE.CmdUUID);
114
+ RaftLog_1.default.debug(`RaftChannelWebBLE.connect - found char ${this._characteristicTx.uuid}`);
115
+ this._characteristicRx = await service.getCharacteristic(RaftChannelWebBLE.RespUUID);
116
+ RaftLog_1.default.debug(`RaftChannelWebBLE.connect - found char ${this._characteristicRx.uuid}`);
117
+ // Notifications of received messages
118
+ try {
119
+ await this._characteristicRx.startNotifications();
120
+ RaftLog_1.default.debug("RaftChannelWebBLE.connect - notifications started");
121
+ this._characteristicRx.addEventListener("characteristicvaluechanged", this._onMsgRx.bind(this));
122
+ }
123
+ catch (error) {
124
+ RaftLog_1.default.debug("RaftChannelWebBLE.connnect - addEventListener failed " + error);
125
+ }
126
+ // Connected ok
127
+ RaftLog_1.default.debug(`RaftChannelWebBLE.connect ${this._bleDevice.name}`);
128
+ // Add disconnect listener
129
+ this._eventListenerFn = this.onDisconnected.bind(this);
130
+ this._bleDevice.addEventListener("gattserverdisconnected", this._eventListenerFn);
131
+ // Connected
132
+ this._isConnected = true;
133
+ return true;
134
+ }
135
+ catch (error) {
136
+ RaftLog_1.default.error(`RaftChannelWebBLE.connect - cannot find characteristic: ${error}`);
137
+ }
138
+ }
139
+ catch (error) {
140
+ if (connRetry === this._maxConnRetries - 1) {
141
+ RaftLog_1.default.error(`RaftChannelWebBLE.connect - cannot get primary service ${error} - attempt #${connRetry + 1} - giving up`);
142
+ }
143
+ else {
144
+ RaftLog_1.default.debug(`RaftChannelWebBLE.connect - cannot get primary service - attempt #${connRetry + 1} ${error}`);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ catch (error) {
151
+ RaftLog_1.default.warn(`RaftChannelWebBLE.connect - cannot connect ${error}`);
152
+ }
153
+ // Disconnect
154
+ if (this._bleDevice &&
155
+ this._bleDevice.gatt &&
156
+ this._bleDevice.gatt.connected) {
157
+ try {
158
+ await this._bleDevice.gatt.disconnect();
159
+ }
160
+ catch (error) {
161
+ RaftLog_1.default.warn(`RaftChannelWebBLE.connect - cannot disconnect ${error}`);
162
+ }
163
+ }
164
+ }
165
+ return false;
166
+ }
167
+ // Disconnect
168
+ async disconnect() {
169
+ if (this._bleDevice && this._bleDevice.gatt) {
170
+ try {
171
+ RaftLog_1.default.debug(`RaftChannelWebBLE.disconnect GATT`);
172
+ await this._bleDevice.gatt.disconnect();
173
+ }
174
+ catch (error) {
175
+ RaftLog_1.default.debug(`RaftChannelWebBLE.disconnect ${error}`);
176
+ }
177
+ }
178
+ }
179
+ pauseConnection(pause) {
180
+ RaftLog_1.default.verbose(`pauseConnection ${pause} - no effect for this channel type`);
181
+ return;
182
+ }
183
+ // Handle notifications
184
+ _onMsgRx(event) {
185
+ // Get characteristic
186
+ const characteristic = event.target;
187
+ // Get value
188
+ const value = characteristic.value;
189
+ if (value !== undefined) {
190
+ const msg = new Uint8Array(value.buffer);
191
+ // Handle message
192
+ if (this._raftMsgHandler) {
193
+ try {
194
+ this._raftMsgHandler.handleNewRxMsg(msg);
195
+ }
196
+ catch (error) {
197
+ RaftLog_1.default.debug(`RaftChannelWebBLE.onMsgRx ${error}`);
198
+ }
199
+ }
200
+ }
201
+ }
202
+ // Send a message
203
+ async sendTxMsg(msg
204
+ // _sendWithResponse: boolean
205
+ ) {
206
+ // Check valid
207
+ if (this._bleDevice === null) {
208
+ return false;
209
+ }
210
+ // Retry upto maxRetries
211
+ for (let retryIdx = 0; retryIdx < this.maxRetries; retryIdx++) {
212
+ // Check for min time between messages
213
+ while (Date.now() - this._msgTxTimeLast < this._msgTxMinTimeBetweenMs) {
214
+ await new Promise((resolve) => setTimeout(resolve, 5));
215
+ }
216
+ this._msgTxTimeLast = Date.now();
217
+ // Write to the characteristic
218
+ try {
219
+ if (this._characteristicTx) {
220
+ if (this._characteristicTx.writeValueWithoutResponse) {
221
+ await this._characteristicTx.writeValueWithoutResponse(msg);
222
+ }
223
+ else if (this._characteristicTx.writeValue) {
224
+ await this._characteristicTx.writeValue(msg);
225
+ }
226
+ else if (this._characteristicTx.writeValueWithResponse) {
227
+ await this._characteristicTx.writeValueWithResponse(msg);
228
+ }
229
+ }
230
+ break;
231
+ }
232
+ catch (error) {
233
+ if (retryIdx === this.maxRetries - 1) {
234
+ RaftLog_1.default.info(`RaftChannelWebBLE.sendTxMsg ${error} retried ${retryIdx} times`);
235
+ }
236
+ }
237
+ }
238
+ return true;
239
+ }
240
+ // Send message without awaiting response
241
+ async sendTxMsgNoAwait(msg
242
+ // _sendWithResponse: boolean
243
+ ) {
244
+ // Check valid
245
+ if (this._bleDevice === null) {
246
+ return false;
247
+ }
248
+ // Check for min time between messages
249
+ while (Date.now() - this._msgTxTimeLast < this._msgTxMinTimeBetweenMs) {
250
+ await new Promise((resolve) => setTimeout(resolve, 5));
251
+ }
252
+ this._msgTxTimeLast = Date.now();
253
+ // Write to the characteristic
254
+ if (this._characteristicTx) {
255
+ if (this._characteristicTx.writeValueWithoutResponse) {
256
+ this._characteristicTx.writeValueWithoutResponse(msg);
257
+ }
258
+ else if (this._characteristicTx.writeValue) {
259
+ this._characteristicTx.writeValue(msg);
260
+ }
261
+ else if (this._characteristicTx.writeValueWithResponse) {
262
+ this._characteristicTx.writeValueWithResponse(msg);
263
+ }
264
+ return true;
265
+ }
266
+ return false;
267
+ }
268
+ }
269
+ // BLE UUIDS
270
+ RaftChannelWebBLE.ServiceUUID = "aa76677e-9cfd-4626-a510-0d305be57c8d";
271
+ RaftChannelWebBLE.CmdUUID = "aa76677e-9cfd-4626-a510-0d305be57c8e";
272
+ RaftChannelWebBLE.RespUUID = "aa76677e-9cfd-4626-a510-0d305be57c8f";
273
+ exports.default = RaftChannelWebBLE;
274
+ //# sourceMappingURL=RaftChannelWebBLE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RaftChannelWebBLE.js","sourceRoot":"","sources":["../src/RaftChannelWebBLE.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import RaftChannel from "./RaftChannel";
2
+ import RaftMsgHandler from "./RaftMsgHandler";
3
+ import { RaftConnEventFn } from "./RaftConnEvents";
4
+ import { ConnectorOptions } from "./RaftSystemType";
5
+ export default class RaftChannelWebSerial implements RaftChannel {
6
+ private _raftMsgHandler;
7
+ private _port;
8
+ private _reader?;
9
+ private _isConnected;
10
+ private _connPaused;
11
+ private _serialBuffer;
12
+ private _escapeSeqCode;
13
+ private _OVERASCII_ESCAPE_1;
14
+ private _OVERASCII_ESCAPE_2;
15
+ private _OVERASCII_ESCAPE_3;
16
+ private _OVERASCII_MOD_CODE;
17
+ private _onConnEvent;
18
+ private _requestedBatchAckSize;
19
+ private _requestedFileBlockSize;
20
+ fhBatchAckSize(): number;
21
+ fhFileBlockSize(): number;
22
+ isConnected(): boolean;
23
+ setMsgHandler(raftMsgHandler: RaftMsgHandler): void;
24
+ requiresSubscription(): boolean;
25
+ ricRestCmdBeforeDisconnect(): string | null;
26
+ setOnConnEvent(connEventFn: RaftConnEventFn): void;
27
+ getConnectedLocator(): string | object;
28
+ connect(locator: string | object, _connectorOptions: ConnectorOptions): Promise<boolean>;
29
+ disconnect(): Promise<void>;
30
+ pauseConnection(pause: boolean): void;
31
+ private _overasciiDecodeByte;
32
+ private _overasciiEncode;
33
+ _onMsgRx(msg: Uint8Array | null): void;
34
+ sendTxMsg(msg: Uint8Array, sendWithResponse: boolean): Promise<boolean>;
35
+ sendTxMsgNoAwait(msg: Uint8Array, sendWithResponse: boolean): Promise<boolean>;
36
+ _readLoop(): Promise<void>;
37
+ }
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3
+ //
4
+ // RaftChannelWebSerial
5
+ // Part of RaftJS
6
+ //
7
+ // Rob Dobson & Chris Greening 2020-2024
8
+ // (C) 2020-2024 All rights reserved
9
+ //
10
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const tslib_1 = require("tslib");
13
+ const RaftLog_1 = tslib_1.__importDefault(require("./RaftLog"));
14
+ const RaftConnEvents_1 = require("./RaftConnEvents");
15
+ class RaftChannelWebSerial {
16
+ constructor() {
17
+ // Message handler
18
+ this._raftMsgHandler = null;
19
+ this._port = null;
20
+ // Last message tx time
21
+ // private _msgTxTimeLast = Date.now();
22
+ // private _msgTxMinTimeBetweenMs = 15;
23
+ // Is connected
24
+ this._isConnected = false;
25
+ this._connPaused = false;
26
+ this._serialBuffer = [];
27
+ this._escapeSeqCode = 0;
28
+ this._OVERASCII_ESCAPE_1 = 0x85;
29
+ this._OVERASCII_ESCAPE_2 = 0x8E;
30
+ this._OVERASCII_ESCAPE_3 = 0x8F;
31
+ this._OVERASCII_MOD_CODE = 0x20;
32
+ // Conn event fn
33
+ this._onConnEvent = null;
34
+ // File Handler parameters
35
+ this._requestedBatchAckSize = 1;
36
+ this._requestedFileBlockSize = 1200;
37
+ }
38
+ fhBatchAckSize() { return this._requestedBatchAckSize; }
39
+ fhFileBlockSize() { return this._requestedFileBlockSize; }
40
+ // isConnected
41
+ isConnected() {
42
+ return this._isConnected;
43
+ }
44
+ // Set message handler
45
+ setMsgHandler(raftMsgHandler) {
46
+ this._raftMsgHandler = raftMsgHandler;
47
+ }
48
+ // Serial interface will require subscription, but don't start it by default
49
+ requiresSubscription() {
50
+ return false;
51
+ }
52
+ // RICREST command before disconnect
53
+ ricRestCmdBeforeDisconnect() {
54
+ return null;
55
+ }
56
+ // Set onConnEvent handler
57
+ setOnConnEvent(connEventFn) {
58
+ this._onConnEvent = connEventFn;
59
+ }
60
+ // Get connected locator
61
+ getConnectedLocator() {
62
+ return this._port || "";
63
+ }
64
+ // Connect to a device
65
+ async connect(locator, _connectorOptions) {
66
+ console.log("_connectorOptions", _connectorOptions);
67
+ // Debug
68
+ RaftLog_1.default.debug("RaftChannelWebSerial.connect " + locator.toString());
69
+ // Check already connected
70
+ if (await this.isConnected()) {
71
+ return true;
72
+ }
73
+ try {
74
+ if (('serial' in navigator) && (!this._port || locator != "reusePort")) {
75
+ const port = await navigator.serial.requestPort();
76
+ this._port = port;
77
+ }
78
+ // Connect
79
+ if (!this._port)
80
+ return false;
81
+ try {
82
+ RaftLog_1.default.info("opening port");
83
+ await this._port.open({ baudRate: 115200 });
84
+ }
85
+ catch (err) {
86
+ if (err.name == "InvalidStateError") {
87
+ RaftLog_1.default.debug(`Opening port failed - already open ${err}`);
88
+ }
89
+ else {
90
+ RaftLog_1.default.error(`Opening port failed: ${err}`);
91
+ throw err;
92
+ }
93
+ }
94
+ this._isConnected = true;
95
+ // start read loop
96
+ this._readLoop();
97
+ this._port.addEventListener('disconnect', (event) => {
98
+ RaftLog_1.default.debug("WebSerial disconnect " + JSON.stringify(event));
99
+ if (this._onConnEvent)
100
+ this._onConnEvent(RaftConnEvents_1.RaftConnEvent.CONN_DISCONNECTED);
101
+ });
102
+ // TODO: handle errors
103
+ }
104
+ catch (err) {
105
+ RaftLog_1.default.error("RaftChannelWebSerial.connect fail. Error: " + JSON.stringify(err));
106
+ return false;
107
+ }
108
+ return true;
109
+ }
110
+ // Disconnect
111
+ async disconnect() {
112
+ // Not connected
113
+ this._isConnected = false;
114
+ RaftLog_1.default.debug(`RaftChannelWebSerial.disconnect attempting to close webserial`);
115
+ while (this._reader) {
116
+ await new Promise((resolve) => setTimeout(resolve, 100));
117
+ }
118
+ // Disconnect webserial
119
+ try {
120
+ if (this._port)
121
+ await this._port.close();
122
+ }
123
+ catch (err) {
124
+ console.debug(`Error closing port ${err}`);
125
+ }
126
+ if (this._onConnEvent)
127
+ this._onConnEvent(RaftConnEvents_1.RaftConnEvent.CONN_DISCONNECTED);
128
+ RaftLog_1.default.debug("WebSerial port closed");
129
+ return;
130
+ }
131
+ pauseConnection(pause) {
132
+ this._connPaused = pause;
133
+ }
134
+ _overasciiDecodeByte(ch) {
135
+ // Check if in escape sequence
136
+ if (this._escapeSeqCode != 0) {
137
+ const prevEscCode = this._escapeSeqCode;
138
+ this._escapeSeqCode = 0;
139
+ if (prevEscCode == 1) {
140
+ return (ch ^ this._OVERASCII_MOD_CODE) & 0x7f;
141
+ }
142
+ else if (prevEscCode == 2) {
143
+ return ch ^ this._OVERASCII_MOD_CODE;
144
+ }
145
+ return ch;
146
+ }
147
+ else if (ch == this._OVERASCII_ESCAPE_1) {
148
+ this._escapeSeqCode = 1;
149
+ return -1;
150
+ }
151
+ else if (ch == this._OVERASCII_ESCAPE_2) {
152
+ this._escapeSeqCode = 2;
153
+ return -1;
154
+ }
155
+ else if (ch == this._OVERASCII_ESCAPE_3) {
156
+ this._escapeSeqCode = 3;
157
+ return -1;
158
+ }
159
+ else {
160
+ return ch & 0x7f;
161
+ }
162
+ }
163
+ _overasciiEncode(inData) {
164
+ /*
165
+ Encode frame
166
+ Values 0x00-0x0F map to ESCAPE_CODE_1, VALUE_XOR_20H_AND_MSB_SET
167
+ Values 0x10-0x7f map to VALUE_WITH_MSB_SET
168
+ Values 0x80-0x8F map to ESCAPE_CODE_2, VALUE_XOR_20H
169
+ Values 0x90-0xff map to ESCAPE_CODE_3, VALUE
170
+ Value ESCAPE_CODE_1 maps to ESCAPE_CODE_1 + VALUE
171
+ Args:
172
+ inData: data to encode (bytes)
173
+ Returns:
174
+ encoded frame (bytes)
175
+ */
176
+ // Iterate over frame
177
+ const encodedFrame = [];
178
+ for (let i = 0; i < inData.length; i++) {
179
+ if (inData[i] <= 0x0f) {
180
+ encodedFrame.push(this._OVERASCII_ESCAPE_1);
181
+ encodedFrame.push((inData[i] ^ this._OVERASCII_MOD_CODE) | 0x80);
182
+ }
183
+ else if ((inData[i] >= 0x10) && (inData[i] <= 0x7f)) {
184
+ encodedFrame.push(inData[i] | 0x80);
185
+ }
186
+ else if ((inData[i] >= 0x80) && (inData[i] <= 0x8f)) {
187
+ encodedFrame.push(this._OVERASCII_ESCAPE_2);
188
+ encodedFrame.push(inData[i] ^ this._OVERASCII_MOD_CODE);
189
+ }
190
+ else {
191
+ encodedFrame.push(this._OVERASCII_ESCAPE_3);
192
+ encodedFrame.push(inData[i]);
193
+ }
194
+ }
195
+ return new Uint8Array(encodedFrame);
196
+ }
197
+ // Handle notifications
198
+ _onMsgRx(msg) {
199
+ if (msg === null)
200
+ return;
201
+ // Debug
202
+ //const decoder = new TextDecoder();
203
+ //RaftLog.debug(`RaftChannelWebSerial._onMsgRx ${decoder.decode(msg)}`);
204
+ const overasciiBuffer = [];
205
+ for (let i = 0; i < msg.length; i++) {
206
+ if (msg[i] > 127) {
207
+ const ch = this._overasciiDecodeByte(msg[i]);
208
+ if (ch != -1) {
209
+ overasciiBuffer.push(ch);
210
+ }
211
+ }
212
+ else {
213
+ this._serialBuffer.push(msg[i]);
214
+ }
215
+ }
216
+ if (this._raftMsgHandler)
217
+ this._raftMsgHandler.handleNewRxMsg(new Uint8Array(overasciiBuffer));
218
+ // any output over the non overascii channel will be delimited by a new line character
219
+ // scan for this, and log any lines as they occur before removing them from the buffer
220
+ if (this._serialBuffer.includes(0x0a)) {
221
+ const decoder = new TextDecoder();
222
+ RaftLog_1.default.debug(decoder.decode(new Uint8Array(this._serialBuffer.slice(0, this._serialBuffer.indexOf(0x0a)))));
223
+ this._serialBuffer.splice(0, this._serialBuffer.indexOf(0x0a) + 1);
224
+ }
225
+ }
226
+ // Send a message
227
+ async sendTxMsg(msg, sendWithResponse) {
228
+ // Check connected
229
+ if (!this._isConnected || !this._port)
230
+ return false;
231
+ // Debug
232
+ const decoder = new TextDecoder();
233
+ RaftLog_1.default.verbose(`RaftChannelWebSerial.sendTxMsg ${msg.toString()} ${decoder.decode(msg)} sendWithResp ${sendWithResponse.toString()}`);
234
+ try {
235
+ if (this._port.writable != null) {
236
+ const writer = this._port.writable.getWriter();
237
+ await writer.write(this._overasciiEncode(msg));
238
+ writer.releaseLock();
239
+ }
240
+ }
241
+ catch (err) {
242
+ RaftLog_1.default.warn("sendMsg error: " + JSON.stringify(err));
243
+ return false;
244
+ }
245
+ return true;
246
+ }
247
+ async sendTxMsgNoAwait(msg, sendWithResponse) {
248
+ // Check connected
249
+ if (!this._isConnected || !this._port)
250
+ return false;
251
+ // Debug
252
+ RaftLog_1.default.verbose(`RaftChannelWebSerial.sendTxMsgNoAwait ${msg.toString()} sendWithResp ${sendWithResponse.toString()}`);
253
+ try {
254
+ if (this._port.writable != null) {
255
+ const writer = this._port.writable.getWriter();
256
+ writer.write(msg).then(() => { writer.releaseLock(); });
257
+ }
258
+ }
259
+ catch (err) {
260
+ RaftLog_1.default.error("sendMsg error: " + JSON.stringify(err));
261
+ }
262
+ return true;
263
+ }
264
+ async _readLoop() {
265
+ RaftLog_1.default.debug("Starting read loop");
266
+ if (!this._port)
267
+ return;
268
+ let retries = 10;
269
+ try {
270
+ if (!this._port.readable) {
271
+ RaftLog_1.default.error("RaftChannelWebSerial _readLoop port is not readble");
272
+ return;
273
+ }
274
+ this._reader = this._port.readable.getReader();
275
+ while (this._port.readable && this._isConnected) {
276
+ if (this._connPaused) {
277
+ if (this._reader) {
278
+ this._reader.releaseLock();
279
+ this._reader = undefined;
280
+ }
281
+ await new Promise(resolve => setTimeout(resolve, 100));
282
+ continue;
283
+ }
284
+ try {
285
+ if (!this._reader)
286
+ this._reader = this._port.readable.getReader();
287
+ const { value, done } = await this._reader.read();
288
+ if (done) {
289
+ this._reader.releaseLock();
290
+ break;
291
+ }
292
+ if (!value || value.length === 0) {
293
+ continue;
294
+ }
295
+ this._onMsgRx(new Uint8Array(value));
296
+ }
297
+ catch (err) {
298
+ RaftLog_1.default.error("read loop issue: " + JSON.stringify(err));
299
+ retries -= 1;
300
+ if (!retries)
301
+ break;
302
+ await new Promise(resolve => setTimeout(resolve, 100));
303
+ this._reader = this._port.readable.getReader();
304
+ }
305
+ }
306
+ if (this._reader)
307
+ this._reader.releaseLock();
308
+ this._reader = undefined;
309
+ }
310
+ catch (err) {
311
+ RaftLog_1.default.error("Read loop got disconnected. err: " + JSON.stringify(err));
312
+ }
313
+ // Disconnected!
314
+ this._isConnected = false;
315
+ RaftLog_1.default.debug("Finished read loop");
316
+ }
317
+ }
318
+ exports.default = RaftChannelWebSerial;
319
+ //# sourceMappingURL=RaftChannelWebSerial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RaftChannelWebSerial.js","sourceRoot":"","sources":["../src/RaftChannelWebSerial.ts"],"names":[],"mappings":";AAAA,iHAAiH;AACjH,EAAE;AACF,uBAAuB;AACvB,iBAAiB;AACjB,EAAE;AACF,wCAAwC;AACxC,oCAAoC;AACpC,EAAE;AACF,iHAAiH;;;AAIjH,gEAAgC;AAChC,qDAAkE;AA0DlE,MAAqB,oBAAoB;IAAzC;QAEE,kBAAkB;QACV,oBAAe,GAA0B,IAAI,CAAC;QAE9C,UAAK,GAA0B,IAAI,CAAC;QAG5C,uBAAuB;QACvB,uCAAuC;QACvC,uCAAuC;QAEvC,eAAe;QACP,iBAAY,GAAG,KAAK,CAAC;QACrB,gBAAW,GAAG,KAAK,CAAC;QAEpB,kBAAa,GAAa,EAAE,CAAC;QAE7B,mBAAc,GAAG,CAAC,CAAC;QACnB,wBAAmB,GAAG,IAAI,CAAC;QAC3B,wBAAmB,GAAG,IAAI,CAAC;QAC3B,wBAAmB,GAAG,IAAI,CAAC;QAC3B,wBAAmB,GAAG,IAAI,CAAC;QAEnC,gBAAgB;QACR,iBAAY,GAA2B,IAAI,CAAC;QAEpD,0BAA0B;QAClB,2BAAsB,GAAG,CAAC,CAAC;QAC3B,4BAAuB,GAAG,IAAI,CAAC;IAmTzC,CAAC;IAjTC,cAAc,KAAa,OAAO,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAChE,eAAe,KAAa,OAAO,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAElE,cAAc;IACd,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,sBAAsB;IACtB,aAAa,CAAC,cAA8B;QAC1C,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;IACxC,CAAC;IAED,4EAA4E;IAC5E,oBAAoB;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oCAAoC;IACpC,0BAA0B;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0BAA0B;IAC1B,cAAc,CAAC,WAA4B;QACzC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,wBAAwB;IACxB,mBAAmB;QACjB,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,sBAAsB;IACtB,KAAK,CAAC,OAAO,CAAC,OAAwB,EAAE,iBAAmC;QACzE,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;QACpD,QAAQ;QACR,iBAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEpE,0BAA0B;QAC1B,IAAI,MAAM,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,WAAW,CAAC,EAAE,CAAC;gBACvE,MAAM,IAAI,GAAG,MAAO,SAAiC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC3E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,UAAU;YACV,IAAI,CAAC,IAAI,CAAC,KAAK;gBACb,OAAO,KAAK,CAAC;YAEf,IAAI,CAAC;gBACH,iBAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IAAI,GAAG,CAAC,IAAI,IAAI,mBAAmB,EAAE,CAAC;oBACpC,iBAAO,CAAC,KAAK,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;gBAC7D,CAAC;qBAAM,CAAC;oBACN,iBAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;oBAC7C,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;YAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAEzB,kBAAkB;YAClB,IAAI,CAAC,SAAS,EAAE,CAAC;YAEjB,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClD,iBAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC/D,IAAI,IAAI,CAAC,YAAY;oBACnB,IAAI,CAAC,YAAY,CAAC,8BAAa,CAAC,iBAAiB,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;YACH,sBAAsB;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iBAAO,CAAC,KAAK,CAAC,4CAA4C,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAClF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,aAAa;IACb,KAAK,CAAC,UAAU;QAEd,gBAAgB;QAChB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAE1B,iBAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAE/E,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK;gBACZ,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,IAAI,CAAC,YAAY;YACnB,IAAI,CAAC,YAAY,CAAC,8BAAa,CAAC,iBAAiB,CAAC,CAAC;QAErD,iBAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,eAAe,CAAC,KAAc;QAC5B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAEO,oBAAoB,CAAC,EAAU;QACrC,8BAA8B;QAC9B,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC;YACxC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC;YAChD,CAAC;iBAAM,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;gBAC5B,OAAO,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC;YACvC,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,IAAI,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1C,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1C,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1C,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,MAAkB;QACzC;;;;;;;;;;;UAWE;QACF,qBAAqB;QACrB,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBACtB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC5C,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;YACnE,CAAC;iBAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;gBACtD,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACtC,CAAC;iBAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;gBACtD,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC5C,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC5C,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC;IAGD,uBAAuB;IACvB,QAAQ,CAAC,GAAsB;QAE7B,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO;QACzB,QAAQ;QACR,oCAAoC;QACpC,wEAAwE;QAExE,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC;gBACjB,MAAM,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7C,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;oBACb,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,eAAe;YACtB,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;QAEvE,sFAAsF;QACtF,sFAAsF;QACtF,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAClC,iBAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7G,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,KAAK,CAAC,SAAS,CACb,GAAe,EACf,gBAAyB;QAGzB,kBAAkB;QAClB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK;YACnC,OAAO,KAAK,CAAC;QAEf,QAAQ;QACR,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,iBAAO,CAAC,OAAO,CAAC,kCAAkC,GAAG,CAAC,QAAQ,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAEvI,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;gBAChC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC/C,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC/C,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iBAAO,CAAC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,GAAe,EACf,gBAAyB;QAGzB,kBAAkB;QAClB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK;YACnC,OAAO,KAAK,CAAC;QAEf,QAAQ;QACR,iBAAO,CAAC,OAAO,CAAC,yCAAyC,GAAG,CAAC,QAAQ,EAAE,iBAAiB,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAEvH,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;gBAChC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iBAAO,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,SAAS;QACb,iBAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAEpC,IAAI,CAAC,IAAI,CAAC,KAAK;YACb,OAAO;QAET,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACzB,iBAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBACpE,OAAO;YACT,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAChD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wBACjB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;wBAC3B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;oBAC3B,CAAC;oBACD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;oBACvD,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC;oBACH,IAAI,CAAC,IAAI,CAAC,OAAO;wBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;oBAClE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;oBAClD,IAAI,IAAI,EAAE,CAAC;wBACT,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;wBAC3B,MAAM;oBACR,CAAC;oBACD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACjC,SAAS;oBACX,CAAC;oBAED,IAAI,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;gBACvC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,iBAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;oBACzD,OAAO,IAAI,CAAC,CAAC;oBACb,IAAI,CAAC,OAAO;wBAAE,MAAM;oBACpB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;oBACvD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iBAAO,CAAC,KAAK,CAAC,mCAAmC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,CAAC;QACD,gBAAgB;QAChB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,iBAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACtC,CAAC;CACF;AAhVD,uCAgVC"}