@v5x/cli 0.0.4 → 0.0.5
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/dist/index.js +745 -480
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -117,7 +117,7 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
117
117
|
// package.json
|
|
118
118
|
var package_default = {
|
|
119
119
|
name: "@v5x/cli",
|
|
120
|
-
version: "0.0.
|
|
120
|
+
version: "0.0.5",
|
|
121
121
|
description: "Command line interface for v5x.",
|
|
122
122
|
license: "MIT",
|
|
123
123
|
type: "module",
|
|
@@ -154,6 +154,7 @@ var package_default = {
|
|
|
154
154
|
"@types/bun": "^1.3.1"
|
|
155
155
|
},
|
|
156
156
|
dependencies: {
|
|
157
|
+
"@v5x/serial": "workspace:*",
|
|
157
158
|
"bun-serialport": "^0.1.1",
|
|
158
159
|
picocolors: "^1.1.1"
|
|
159
160
|
}
|
|
@@ -730,6 +731,8 @@ import { join as join2 } from "path";
|
|
|
730
731
|
import { platform as platform4 } from "os";
|
|
731
732
|
|
|
732
733
|
class WebSerialPortAdapter extends EventTarget {
|
|
734
|
+
onconnect = () => {};
|
|
735
|
+
ondisconnect = () => {};
|
|
733
736
|
_port = null;
|
|
734
737
|
_path;
|
|
735
738
|
_info;
|
|
@@ -742,9 +745,13 @@ class WebSerialPortAdapter extends EventTarget {
|
|
|
742
745
|
this._info = info;
|
|
743
746
|
}
|
|
744
747
|
get readable() {
|
|
748
|
+
if (!this._readable)
|
|
749
|
+
throw new Error("Port not open");
|
|
745
750
|
return this._readable;
|
|
746
751
|
}
|
|
747
752
|
get writable() {
|
|
753
|
+
if (!this._writable)
|
|
754
|
+
throw new Error("Port not open");
|
|
748
755
|
return this._writable;
|
|
749
756
|
}
|
|
750
757
|
getInfo() {
|
|
@@ -804,9 +811,14 @@ class WebSerialPortAdapter extends EventTarget {
|
|
|
804
811
|
this._writable = null;
|
|
805
812
|
this.dispatchEvent(new Event("disconnect"));
|
|
806
813
|
}
|
|
814
|
+
async forget() {
|
|
815
|
+
await this.close();
|
|
816
|
+
}
|
|
807
817
|
}
|
|
808
818
|
|
|
809
|
-
class WebSerialAdapter {
|
|
819
|
+
class WebSerialAdapter extends EventTarget {
|
|
820
|
+
onconnect = () => {};
|
|
821
|
+
ondisconnect = () => {};
|
|
810
822
|
async _listPortsLinux() {
|
|
811
823
|
const ttys = await readdir2("/sys/class/tty").catch(() => []);
|
|
812
824
|
const ports = [];
|
|
@@ -861,35 +873,37 @@ class WebSerialAdapter {
|
|
|
861
873
|
}
|
|
862
874
|
var serial = new WebSerialAdapter;
|
|
863
875
|
|
|
864
|
-
// ../serial/src/
|
|
876
|
+
// ../serial/src/Vex.ts
|
|
865
877
|
var USER_PROG_CHUNK_SIZE = 4096;
|
|
866
878
|
var USER_FLASH_USR_CODE_START = 58720256;
|
|
867
|
-
// ../serial/src/
|
|
879
|
+
// ../serial/src/VexEvent.ts
|
|
868
880
|
class VexEventEmitter {
|
|
869
|
-
|
|
881
|
+
handlerMap;
|
|
870
882
|
constructor() {
|
|
871
|
-
this.
|
|
883
|
+
this.handlerMap = new Map;
|
|
872
884
|
}
|
|
873
885
|
on(eventName, listener) {
|
|
874
|
-
|
|
875
|
-
|
|
886
|
+
let listeners = this.handlerMap.get(eventName);
|
|
887
|
+
listeners ??= [];
|
|
888
|
+
listeners.push(listener);
|
|
889
|
+
this.handlerMap.set(eventName, listeners);
|
|
876
890
|
}
|
|
877
891
|
remove(eventName, listener) {
|
|
878
|
-
|
|
879
|
-
|
|
892
|
+
let listeners = this.handlerMap.get(eventName);
|
|
893
|
+
listeners ??= [];
|
|
894
|
+
const index = listeners.indexOf(listener);
|
|
880
895
|
if (index > -1) {
|
|
881
|
-
|
|
896
|
+
listeners.splice(index, 1);
|
|
882
897
|
}
|
|
898
|
+
this.handlerMap.set(eventName, listeners);
|
|
883
899
|
}
|
|
884
900
|
emit(eventName, data) {
|
|
885
|
-
(this.
|
|
901
|
+
(this.handlerMap.get(eventName) ?? []).forEach((callback) => {
|
|
886
902
|
callback(data);
|
|
887
903
|
});
|
|
888
904
|
}
|
|
889
905
|
clearListeners() {
|
|
890
|
-
|
|
891
|
-
delete this.handlers[e];
|
|
892
|
-
});
|
|
906
|
+
this.handlerMap.clear();
|
|
893
907
|
}
|
|
894
908
|
}
|
|
895
909
|
|
|
@@ -912,9 +926,9 @@ class VexEventTarget {
|
|
|
912
926
|
}
|
|
913
927
|
}
|
|
914
928
|
|
|
915
|
-
// ../serial/src/
|
|
916
|
-
var
|
|
917
|
-
__export(
|
|
929
|
+
// ../serial/src/VexPacket.ts
|
|
930
|
+
var exports_VexPacket = {};
|
|
931
|
+
__export(exports_VexPacket, {
|
|
918
932
|
WriteKeyValueReplyD2HPacket: () => WriteKeyValueReplyD2HPacket,
|
|
919
933
|
WriteKeyValueH2DPacket: () => WriteKeyValueH2DPacket,
|
|
920
934
|
WriteFileReplyD2HPacket: () => WriteFileReplyD2HPacket,
|
|
@@ -991,14 +1005,14 @@ __export(exports_vex_packet, {
|
|
|
991
1005
|
ExitFileTransferH2DPacket: () => ExitFileTransferH2DPacket,
|
|
992
1006
|
EraseFileReplyD2HPacket: () => EraseFileReplyD2HPacket,
|
|
993
1007
|
EraseFileH2DPacket: () => EraseFileH2DPacket,
|
|
994
|
-
|
|
1008
|
+
EnableDashReplyD2HPacket: () => EnableDashReplyD2HPacket,
|
|
995
1009
|
EnableDashH2DPacket: () => EnableDashH2DPacket,
|
|
996
|
-
|
|
1010
|
+
DisableDashReplyD2HPacket: () => DisableDashReplyD2HPacket,
|
|
997
1011
|
DisableDashH2DPacket: () => DisableDashH2DPacket,
|
|
998
1012
|
DeviceBoundPacket: () => DeviceBoundPacket
|
|
999
1013
|
});
|
|
1000
1014
|
|
|
1001
|
-
// ../serial/src/
|
|
1015
|
+
// ../serial/src/VexFirmwareVersion.ts
|
|
1002
1016
|
class VexFirmwareVersion {
|
|
1003
1017
|
major;
|
|
1004
1018
|
minor;
|
|
@@ -1061,70 +1075,45 @@ class VexFirmwareVersion {
|
|
|
1061
1075
|
}
|
|
1062
1076
|
}
|
|
1063
1077
|
|
|
1064
|
-
// ../serial/src/
|
|
1065
|
-
class PacketView {
|
|
1066
|
-
view;
|
|
1078
|
+
// ../serial/src/VexPacketView.ts
|
|
1079
|
+
class PacketView extends DataView {
|
|
1067
1080
|
position = 0;
|
|
1068
1081
|
littleEndianDefault = true;
|
|
1069
1082
|
constructor(buffer, offset = 0, length = buffer.byteLength - offset) {
|
|
1070
|
-
|
|
1083
|
+
super(buffer, offset, length);
|
|
1071
1084
|
}
|
|
1072
1085
|
static fromPacket(packet) {
|
|
1073
|
-
|
|
1086
|
+
const view = new PacketView(packet.data.buffer, packet.data.byteOffset);
|
|
1074
1087
|
view.position = packet.ackIndex + 1;
|
|
1075
1088
|
return view;
|
|
1076
1089
|
}
|
|
1077
|
-
get byteLength() {
|
|
1078
|
-
return this.view.byteLength;
|
|
1079
|
-
}
|
|
1080
|
-
get buffer() {
|
|
1081
|
-
return this.view.buffer;
|
|
1082
|
-
}
|
|
1083
|
-
getInt8(byteOffset) {
|
|
1084
|
-
return this.view.getInt8(byteOffset);
|
|
1085
|
-
}
|
|
1086
|
-
getUint8(byteOffset) {
|
|
1087
|
-
return this.view.getUint8(byteOffset);
|
|
1088
|
-
}
|
|
1089
|
-
getInt16(byteOffset, littleEndian) {
|
|
1090
|
-
return this.view.getInt16(byteOffset, littleEndian);
|
|
1091
|
-
}
|
|
1092
|
-
getUint16(byteOffset, littleEndian) {
|
|
1093
|
-
return this.view.getUint16(byteOffset, littleEndian);
|
|
1094
|
-
}
|
|
1095
|
-
getInt32(byteOffset, littleEndian) {
|
|
1096
|
-
return this.view.getInt32(byteOffset, littleEndian);
|
|
1097
|
-
}
|
|
1098
|
-
getUint32(byteOffset, littleEndian) {
|
|
1099
|
-
return this.view.getUint32(byteOffset, littleEndian);
|
|
1100
|
-
}
|
|
1101
1090
|
nextInt8() {
|
|
1102
|
-
|
|
1091
|
+
const result = this.getInt8(this.position);
|
|
1103
1092
|
this.position += 1;
|
|
1104
1093
|
return result;
|
|
1105
1094
|
}
|
|
1106
1095
|
nextUint8() {
|
|
1107
|
-
|
|
1096
|
+
const result = this.getUint8(this.position);
|
|
1108
1097
|
this.position += 1;
|
|
1109
1098
|
return result;
|
|
1110
1099
|
}
|
|
1111
1100
|
nextInt16(littleEndian = this.littleEndianDefault) {
|
|
1112
|
-
|
|
1101
|
+
const result = this.getInt16(this.position, littleEndian);
|
|
1113
1102
|
this.position += 2;
|
|
1114
1103
|
return result;
|
|
1115
1104
|
}
|
|
1116
1105
|
nextUint16(littleEndian = this.littleEndianDefault) {
|
|
1117
|
-
|
|
1106
|
+
const result = this.getUint16(this.position, littleEndian);
|
|
1118
1107
|
this.position += 2;
|
|
1119
1108
|
return result;
|
|
1120
1109
|
}
|
|
1121
1110
|
nextInt32(littleEndian = this.littleEndianDefault) {
|
|
1122
|
-
|
|
1111
|
+
const result = this.getInt32(this.position, littleEndian);
|
|
1123
1112
|
this.position += 4;
|
|
1124
1113
|
return result;
|
|
1125
1114
|
}
|
|
1126
1115
|
nextUint32(littleEndian = this.littleEndianDefault) {
|
|
1127
|
-
|
|
1116
|
+
const result = this.getUint32(this.position, littleEndian);
|
|
1128
1117
|
this.position += 4;
|
|
1129
1118
|
return result;
|
|
1130
1119
|
}
|
|
@@ -1137,11 +1126,11 @@ class PacketView {
|
|
|
1137
1126
|
}
|
|
1138
1127
|
nextNTBS(length) {
|
|
1139
1128
|
let result = "";
|
|
1140
|
-
|
|
1129
|
+
const lastPosition = this.position;
|
|
1141
1130
|
for (let i = 0;i < length; i++) {
|
|
1142
1131
|
if (this.byteLength <= this.position)
|
|
1143
1132
|
break;
|
|
1144
|
-
|
|
1133
|
+
const g = this.nextUint8();
|
|
1145
1134
|
if (g === 0)
|
|
1146
1135
|
break;
|
|
1147
1136
|
result += String.fromCharCode(g);
|
|
@@ -1154,7 +1143,7 @@ class PacketView {
|
|
|
1154
1143
|
for (let i = 0;i < length; i++) {
|
|
1155
1144
|
if (this.byteLength <= this.position)
|
|
1156
1145
|
break;
|
|
1157
|
-
|
|
1146
|
+
const g = this.nextUint8();
|
|
1158
1147
|
if (g === 0)
|
|
1159
1148
|
break;
|
|
1160
1149
|
result += String.fromCharCode(g);
|
|
@@ -1162,13 +1151,13 @@ class PacketView {
|
|
|
1162
1151
|
return result;
|
|
1163
1152
|
}
|
|
1164
1153
|
nextVersion(reverse = false) {
|
|
1165
|
-
|
|
1154
|
+
const result = VexFirmwareVersion.fromUint8Array(new Uint8Array(this.buffer), this.position, reverse);
|
|
1166
1155
|
this.position += 4;
|
|
1167
1156
|
return result;
|
|
1168
1157
|
}
|
|
1169
1158
|
}
|
|
1170
1159
|
|
|
1171
|
-
// ../serial/src/
|
|
1160
|
+
// ../serial/src/VexCRC.ts
|
|
1172
1161
|
var CRC16TABLE = [
|
|
1173
1162
|
0,
|
|
1174
1163
|
4129,
|
|
@@ -1429,6 +1418,7 @@ var CRC16TABLE = [
|
|
|
1429
1418
|
];
|
|
1430
1419
|
|
|
1431
1420
|
class CrcGenerator {
|
|
1421
|
+
crc16Table;
|
|
1432
1422
|
crc32Table;
|
|
1433
1423
|
static POLYNOMIAL_CRC32 = 79764919;
|
|
1434
1424
|
static POLYNOMIAL_CRC16 = 4129;
|
|
@@ -1448,34 +1438,34 @@ class CrcGenerator {
|
|
|
1448
1438
|
return (accumulator & 65535) >>> 0;
|
|
1449
1439
|
}
|
|
1450
1440
|
crc32GenTable() {
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1441
|
+
let i;
|
|
1442
|
+
let j;
|
|
1443
|
+
let crcAccumulator;
|
|
1454
1444
|
for (i = 0;i < 256; i++) {
|
|
1455
|
-
|
|
1445
|
+
crcAccumulator = i << 24;
|
|
1456
1446
|
for (j = 0;j < 8; j++) {
|
|
1457
|
-
if (
|
|
1458
|
-
|
|
1447
|
+
if ((crcAccumulator & 2147483648) !== 0)
|
|
1448
|
+
crcAccumulator = crcAccumulator << 1 ^ CrcGenerator.POLYNOMIAL_CRC32;
|
|
1459
1449
|
else
|
|
1460
|
-
|
|
1450
|
+
crcAccumulator = crcAccumulator << 1;
|
|
1461
1451
|
}
|
|
1462
|
-
this.crc32Table[i] =
|
|
1452
|
+
this.crc32Table[i] = crcAccumulator;
|
|
1463
1453
|
}
|
|
1464
1454
|
}
|
|
1465
1455
|
crc32(buf, initValue) {
|
|
1466
1456
|
const numberOfBytes = buf.byteLength;
|
|
1467
|
-
let
|
|
1457
|
+
let crcAccumulator = initValue;
|
|
1468
1458
|
let i;
|
|
1469
1459
|
let j;
|
|
1470
1460
|
for (j = 0;j < numberOfBytes; j++) {
|
|
1471
|
-
i = (
|
|
1472
|
-
|
|
1461
|
+
i = (crcAccumulator >>> 24 ^ buf[j]) & 255;
|
|
1462
|
+
crcAccumulator = (crcAccumulator << 8 ^ this.crc32Table[i]) >>> 0;
|
|
1473
1463
|
}
|
|
1474
|
-
return (
|
|
1464
|
+
return (crcAccumulator & 4294967295) >>> 0;
|
|
1475
1465
|
}
|
|
1476
1466
|
}
|
|
1477
1467
|
|
|
1478
|
-
// ../serial/src/
|
|
1468
|
+
// ../serial/src/VexPacket.ts
|
|
1479
1469
|
class PacketEncoder {
|
|
1480
1470
|
static HEADERS_LENGTH = 4;
|
|
1481
1471
|
static HEADER_TO_DEVICE = [201, 54, 184, 71];
|
|
@@ -1493,7 +1483,7 @@ class PacketEncoder {
|
|
|
1493
1483
|
constructor() {
|
|
1494
1484
|
this.vexVersion = 0;
|
|
1495
1485
|
this.crcgen = new CrcGenerator;
|
|
1496
|
-
Object.values(
|
|
1486
|
+
Object.values(exports_VexPacket).forEach((packet) => {
|
|
1497
1487
|
if (packet.prototype instanceof HostBoundPacket) {
|
|
1498
1488
|
this.allPacketsTable[packet.COMMAND_ID + " " + packet.COMMAND_EXTENDED_ID] = packet;
|
|
1499
1489
|
}
|
|
@@ -1541,9 +1531,9 @@ class PacketEncoder {
|
|
|
1541
1531
|
h.set([cmd, ext, data.length], PacketEncoder.HEADERS_LENGTH);
|
|
1542
1532
|
h.set(data, PacketEncoder.HEADERS_LENGTH + 3);
|
|
1543
1533
|
} else {
|
|
1544
|
-
const
|
|
1545
|
-
const
|
|
1546
|
-
h.set([cmd, ext,
|
|
1534
|
+
const lengthMsb = (data.length >>> 8 | 128) >>> 0;
|
|
1535
|
+
const lengthLsb = (data.length & 255) >>> 0;
|
|
1536
|
+
h.set([cmd, ext, lengthMsb, lengthLsb], PacketEncoder.HEADERS_LENGTH);
|
|
1547
1537
|
h.set(data, PacketEncoder.HEADERS_LENGTH + 4);
|
|
1548
1538
|
}
|
|
1549
1539
|
const crc = this.crcgen.crc16(h.subarray(0, buf.byteLength - 2), 0);
|
|
@@ -1554,13 +1544,14 @@ class PacketEncoder {
|
|
|
1554
1544
|
return !(data[0] !== PacketEncoder.HEADER_TO_HOST[0] || data[1] !== PacketEncoder.HEADER_TO_HOST[1]);
|
|
1555
1545
|
}
|
|
1556
1546
|
validateMessageCdc(data) {
|
|
1557
|
-
|
|
1558
|
-
|
|
1547
|
+
const message = data.subarray(0, data.byteLength - 2);
|
|
1548
|
+
const lastTwoBytes = (data[data.byteLength - 2] << 8) + data[data.byteLength - 1];
|
|
1559
1549
|
return this.crcgen.crc16(message, 0) === lastTwoBytes;
|
|
1560
1550
|
}
|
|
1561
1551
|
getPayloadSize(data) {
|
|
1562
|
-
let t = 0
|
|
1563
|
-
|
|
1552
|
+
let t = 0;
|
|
1553
|
+
let a = data[3];
|
|
1554
|
+
if ((128 & a) !== 0) {
|
|
1564
1555
|
t = 127 & a;
|
|
1565
1556
|
a = data[4];
|
|
1566
1557
|
}
|
|
@@ -1579,7 +1570,7 @@ class Packet {
|
|
|
1579
1570
|
class DeviceBoundPacket extends Packet {
|
|
1580
1571
|
constructor(payload) {
|
|
1581
1572
|
super(new Uint8Array);
|
|
1582
|
-
|
|
1573
|
+
const me = this.__proto__.constructor;
|
|
1583
1574
|
if (me.COMMAND_EXTENDED_ID === undefined) {
|
|
1584
1575
|
if (payload === undefined) {
|
|
1585
1576
|
this.data = Packet.ENCODER.cdcCommand(me.COMMAND_ID);
|
|
@@ -1627,7 +1618,8 @@ class UpdateMatchModeH2DPacket extends DeviceBoundPacket {
|
|
|
1627
1618
|
case "disabled":
|
|
1628
1619
|
bit1 = 11;
|
|
1629
1620
|
}
|
|
1630
|
-
const payload = new Uint8Array(5)
|
|
1621
|
+
const payload = new Uint8Array(5);
|
|
1622
|
+
const view = new DataView(payload.buffer);
|
|
1631
1623
|
payload[0] = (15 & bit1) >>> 0;
|
|
1632
1624
|
view.setUint32(1, matchClock, true);
|
|
1633
1625
|
super(payload);
|
|
@@ -1677,8 +1669,8 @@ class InitFileTransferH2DPacket extends DeviceBoundPacket {
|
|
|
1677
1669
|
view.setUint32(12, operation === 1 /* WRITE */ ? Packet.ENCODER.crcgen.crc32(binary, 0) : 0, true);
|
|
1678
1670
|
const re = /(?:\.([^.]+))?$/;
|
|
1679
1671
|
const reResult = re.exec(name);
|
|
1680
|
-
let ext = reResult ? reResult[1] : undefined;
|
|
1681
|
-
ext
|
|
1672
|
+
let ext = reResult != null ? reResult[1] : undefined;
|
|
1673
|
+
ext ??= "";
|
|
1682
1674
|
ext = ext === "gz" ? "bin" : ext;
|
|
1683
1675
|
payload.set(new TextEncoder().encode(type ?? ext), 16);
|
|
1684
1676
|
const timestamp = (Date.now() / 1000 >>> 0) - PacketEncoder.J2000_EPOCH;
|
|
@@ -1698,7 +1690,7 @@ class ExitFileTransferH2DPacket extends DeviceBoundPacket {
|
|
|
1698
1690
|
static COMMAND_ID = 86;
|
|
1699
1691
|
static COMMAND_EXTENDED_ID = 18;
|
|
1700
1692
|
constructor(action) {
|
|
1701
|
-
|
|
1693
|
+
const payload = new Uint8Array(1);
|
|
1702
1694
|
payload[0] = action;
|
|
1703
1695
|
super(payload);
|
|
1704
1696
|
}
|
|
@@ -1733,7 +1725,7 @@ class LinkFileH2DPacket extends DeviceBoundPacket {
|
|
|
1733
1725
|
static COMMAND_EXTENDED_ID = 21;
|
|
1734
1726
|
constructor(vendor, fileName, options) {
|
|
1735
1727
|
const str = new TextEncoder().encode(fileName);
|
|
1736
|
-
|
|
1728
|
+
const payload = new Uint8Array(26);
|
|
1737
1729
|
payload.set([vendor, options], 0);
|
|
1738
1730
|
payload.set(str.subarray(0, 23), 2);
|
|
1739
1731
|
super(payload);
|
|
@@ -1744,7 +1736,7 @@ class GetDirectoryFileCountH2DPacket extends DeviceBoundPacket {
|
|
|
1744
1736
|
static COMMAND_ID = 86;
|
|
1745
1737
|
static COMMAND_EXTENDED_ID = 22;
|
|
1746
1738
|
constructor(vendor) {
|
|
1747
|
-
|
|
1739
|
+
const payload = new Uint8Array(2);
|
|
1748
1740
|
payload.set([vendor, 0], 0);
|
|
1749
1741
|
super(payload);
|
|
1750
1742
|
}
|
|
@@ -1754,7 +1746,7 @@ class GetDirectoryEntryH2DPacket extends DeviceBoundPacket {
|
|
|
1754
1746
|
static COMMAND_ID = 86;
|
|
1755
1747
|
static COMMAND_EXTENDED_ID = 23;
|
|
1756
1748
|
constructor(index) {
|
|
1757
|
-
|
|
1749
|
+
const payload = new Uint8Array(2);
|
|
1758
1750
|
payload.set([index, 0], 0);
|
|
1759
1751
|
super(payload);
|
|
1760
1752
|
}
|
|
@@ -1770,7 +1762,8 @@ class LoadFileActionH2DPacket extends DeviceBoundPacket {
|
|
|
1770
1762
|
} else {
|
|
1771
1763
|
fileName = "___s_" + (fileNameOrSlotNumber - 1) + ".bin";
|
|
1772
1764
|
}
|
|
1773
|
-
|
|
1765
|
+
const encodedName = new TextEncoder().encode(fileName);
|
|
1766
|
+
const payload = new Uint8Array(26);
|
|
1774
1767
|
payload.set([vendor, actionId], 0);
|
|
1775
1768
|
payload.set(encodedName.subarray(0, 23), 2);
|
|
1776
1769
|
super(payload);
|
|
@@ -1781,8 +1774,8 @@ class GetFileMetadataH2DPacket extends DeviceBoundPacket {
|
|
|
1781
1774
|
static COMMAND_ID = 86;
|
|
1782
1775
|
static COMMAND_EXTENDED_ID = 25;
|
|
1783
1776
|
constructor(vendor, fileName, options) {
|
|
1784
|
-
|
|
1785
|
-
|
|
1777
|
+
const encodedName = new TextEncoder().encode(fileName);
|
|
1778
|
+
const payload = new Uint8Array(26);
|
|
1786
1779
|
payload.set([vendor, options], 0);
|
|
1787
1780
|
payload.set(encodedName.subarray(0, 23), 2);
|
|
1788
1781
|
super(payload);
|
|
@@ -1793,15 +1786,15 @@ class SetFileMetadataH2DPacket extends DeviceBoundPacket {
|
|
|
1793
1786
|
static COMMAND_ID = 86;
|
|
1794
1787
|
static COMMAND_EXTENDED_ID = 26;
|
|
1795
1788
|
constructor(vendor, fileName, fileInfo, options) {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1789
|
+
const encodedName = new TextEncoder().encode(fileName);
|
|
1790
|
+
const encodedType = new TextEncoder().encode(fileInfo.type);
|
|
1791
|
+
const payload = new Uint8Array(42);
|
|
1792
|
+
const view = new DataView(payload.buffer);
|
|
1800
1793
|
view.setUint8(0, vendor);
|
|
1801
1794
|
view.setUint8(1, options);
|
|
1802
1795
|
view.setUint32(2, fileInfo.loadAddress, true);
|
|
1803
1796
|
payload.set(encodedType.subarray(0, 4), 6);
|
|
1804
|
-
|
|
1797
|
+
const timestamp = fileInfo.timestamp - PacketEncoder.J2000_EPOCH + 100;
|
|
1805
1798
|
view.setUint32(10, timestamp, true);
|
|
1806
1799
|
payload.set(fileInfo.version.toUint8Array(), 14);
|
|
1807
1800
|
payload.set(encodedName.subarray(0, 23), 18);
|
|
@@ -1813,8 +1806,8 @@ class EraseFileH2DPacket extends DeviceBoundPacket {
|
|
|
1813
1806
|
static COMMAND_ID = 86;
|
|
1814
1807
|
static COMMAND_EXTENDED_ID = 27;
|
|
1815
1808
|
constructor(vendor, fileName) {
|
|
1816
|
-
|
|
1817
|
-
|
|
1809
|
+
const encodedName = new TextEncoder().encode(fileName);
|
|
1810
|
+
const payload = new Uint8Array(26);
|
|
1818
1811
|
payload.set([vendor, 128], 0);
|
|
1819
1812
|
payload.set(encodedName.subarray(0, 23), 2);
|
|
1820
1813
|
super(payload);
|
|
@@ -1825,8 +1818,8 @@ class GetProgramSlotInfoH2DPacket extends DeviceBoundPacket {
|
|
|
1825
1818
|
static COMMAND_ID = 86;
|
|
1826
1819
|
static COMMAND_EXTENDED_ID = 28;
|
|
1827
1820
|
constructor(vendor, fileName) {
|
|
1828
|
-
|
|
1829
|
-
|
|
1821
|
+
const encodedName = new TextEncoder().encode(fileName);
|
|
1822
|
+
const payload = new Uint8Array(26);
|
|
1830
1823
|
payload.set([vendor, 0], 0);
|
|
1831
1824
|
payload.set(encodedName.subarray(0, 23), 2);
|
|
1832
1825
|
super(payload);
|
|
@@ -1837,7 +1830,7 @@ class FileClearUpH2DPacket extends DeviceBoundPacket {
|
|
|
1837
1830
|
static COMMAND_ID = 86;
|
|
1838
1831
|
static COMMAND_EXTENDED_ID = 30;
|
|
1839
1832
|
constructor(vendor) {
|
|
1840
|
-
|
|
1833
|
+
const payload = new Uint8Array(2);
|
|
1841
1834
|
payload.set([vendor, 0], 0);
|
|
1842
1835
|
super(payload);
|
|
1843
1836
|
}
|
|
@@ -1847,7 +1840,7 @@ class FileFormatH2DPacket extends DeviceBoundPacket {
|
|
|
1847
1840
|
static COMMAND_ID = 86;
|
|
1848
1841
|
static COMMAND_EXTENDED_ID = 31;
|
|
1849
1842
|
constructor() {
|
|
1850
|
-
|
|
1843
|
+
const payload = new Uint8Array(4);
|
|
1851
1844
|
payload.set([68, 67, 66, 65], 0);
|
|
1852
1845
|
super(payload);
|
|
1853
1846
|
}
|
|
@@ -1894,8 +1887,8 @@ class ReadLogPageH2DPacket extends DeviceBoundPacket {
|
|
|
1894
1887
|
static COMMAND_ID = 86;
|
|
1895
1888
|
static COMMAND_EXTENDED_ID = 37;
|
|
1896
1889
|
constructor(offset, count) {
|
|
1897
|
-
|
|
1898
|
-
|
|
1890
|
+
const payload = new Uint8Array(8);
|
|
1891
|
+
const view = new DataView(payload.buffer);
|
|
1899
1892
|
view.setUint32(0, offset, true);
|
|
1900
1893
|
view.setUint32(4, count, true);
|
|
1901
1894
|
super(payload);
|
|
@@ -1914,13 +1907,13 @@ class GetUserDataH2DPacket extends DeviceBoundPacket {
|
|
|
1914
1907
|
static COMMAND_ID = 86;
|
|
1915
1908
|
static COMMAND_EXTENDED_ID = 39;
|
|
1916
1909
|
constructor(e) {
|
|
1917
|
-
let len = e?.length
|
|
1910
|
+
let len = e?.length ?? 0;
|
|
1918
1911
|
if (len > 244)
|
|
1919
1912
|
len = 244;
|
|
1920
|
-
|
|
1913
|
+
const payload = new Uint8Array(2 + len);
|
|
1921
1914
|
payload[0] = 1;
|
|
1922
1915
|
payload[1] = len;
|
|
1923
|
-
payload.set(e
|
|
1916
|
+
payload.set(e ?? new Uint8Array(0), 2);
|
|
1924
1917
|
super(payload);
|
|
1925
1918
|
}
|
|
1926
1919
|
}
|
|
@@ -1929,7 +1922,7 @@ class ScreenCaptureH2DPacket extends DeviceBoundPacket {
|
|
|
1929
1922
|
static COMMAND_ID = 86;
|
|
1930
1923
|
static COMMAND_EXTENDED_ID = 40;
|
|
1931
1924
|
constructor(e) {
|
|
1932
|
-
|
|
1925
|
+
const payload = new Uint8Array(1);
|
|
1933
1926
|
payload[0] = e;
|
|
1934
1927
|
super(payload);
|
|
1935
1928
|
}
|
|
@@ -1939,8 +1932,8 @@ class SendDashTouchH2DPacket extends DeviceBoundPacket {
|
|
|
1939
1932
|
static COMMAND_ID = 86;
|
|
1940
1933
|
static COMMAND_EXTENDED_ID = 42;
|
|
1941
1934
|
constructor(x, y, press) {
|
|
1942
|
-
|
|
1943
|
-
|
|
1935
|
+
const payload = new Uint8Array(6);
|
|
1936
|
+
const view = new DataView(payload.buffer);
|
|
1944
1937
|
view.setUint16(0, x, true);
|
|
1945
1938
|
view.setUint16(2, y, true);
|
|
1946
1939
|
view.setUint16(4, press ? 1 : 0, true);
|
|
@@ -1952,7 +1945,7 @@ class SelectDashH2DPacket extends DeviceBoundPacket {
|
|
|
1952
1945
|
static COMMAND_ID = 86;
|
|
1953
1946
|
static COMMAND_EXTENDED_ID = 43;
|
|
1954
1947
|
constructor(screen, port) {
|
|
1955
|
-
|
|
1948
|
+
const payload = new Uint8Array(2);
|
|
1956
1949
|
payload[0] = screen;
|
|
1957
1950
|
payload[1] = port;
|
|
1958
1951
|
super(payload);
|
|
@@ -1966,7 +1959,7 @@ class EnableDashH2DPacket extends DeviceBoundPacket {
|
|
|
1966
1959
|
if (unknown1 === undefined) {
|
|
1967
1960
|
super(undefined);
|
|
1968
1961
|
} else {
|
|
1969
|
-
|
|
1962
|
+
const payload = new Uint8Array(1);
|
|
1970
1963
|
payload[0] = unknown1;
|
|
1971
1964
|
super(payload);
|
|
1972
1965
|
}
|
|
@@ -1985,7 +1978,7 @@ class ReadKeyValueH2DPacket extends DeviceBoundPacket {
|
|
|
1985
1978
|
static COMMAND_ID = 86;
|
|
1986
1979
|
static COMMAND_EXTENDED_ID = 46;
|
|
1987
1980
|
constructor(key) {
|
|
1988
|
-
|
|
1981
|
+
const payload = new Uint8Array(32);
|
|
1989
1982
|
payload.set(new TextEncoder().encode(key), 0);
|
|
1990
1983
|
super(payload);
|
|
1991
1984
|
}
|
|
@@ -1999,7 +1992,7 @@ class WriteKeyValueH2DPacket extends DeviceBoundPacket {
|
|
|
1999
1992
|
const strv = new TextEncoder().encode(value);
|
|
2000
1993
|
if (strk.byteLength > 31)
|
|
2001
1994
|
strk = strk.subarray(0, 31);
|
|
2002
|
-
|
|
1995
|
+
const payload = new Uint8Array(strk.length + strv.length + 20);
|
|
2003
1996
|
payload.set(strk, 0);
|
|
2004
1997
|
payload.set(strv, strk.length + 1);
|
|
2005
1998
|
super(payload);
|
|
@@ -2031,7 +2024,7 @@ class FactoryEnableH2DPacket extends DeviceBoundPacket {
|
|
|
2031
2024
|
static COMMAND_ID = 86;
|
|
2032
2025
|
static COMMAND_EXTENDED_ID = 255;
|
|
2033
2026
|
constructor() {
|
|
2034
|
-
|
|
2027
|
+
const payload = new Uint8Array(4);
|
|
2035
2028
|
payload.set([77, 76, 75, 74], 0);
|
|
2036
2029
|
super(payload);
|
|
2037
2030
|
}
|
|
@@ -2119,7 +2112,7 @@ class MatchStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2119
2112
|
constructor(data) {
|
|
2120
2113
|
super(data);
|
|
2121
2114
|
const dataView = PacketView.fromPacket(this);
|
|
2122
|
-
|
|
2115
|
+
const n = this.ackIndex;
|
|
2123
2116
|
this.rssi = dataView.nextInt8();
|
|
2124
2117
|
this.systemStatusBits = dataView.nextUint16();
|
|
2125
2118
|
this.radioStatusBits = dataView.nextUint16();
|
|
@@ -2185,10 +2178,10 @@ class ReadFileReplyD2HPacket extends HostBoundPacket {
|
|
|
2185
2178
|
constructor(data) {
|
|
2186
2179
|
super(data);
|
|
2187
2180
|
const dataView = PacketView.fromPacket(this);
|
|
2188
|
-
|
|
2181
|
+
const n = this.ackIndex;
|
|
2189
2182
|
this.addr = dataView.getUint32(n, true);
|
|
2190
2183
|
this.length = this.payloadSize - 7;
|
|
2191
|
-
this.buf =
|
|
2184
|
+
this.buf = data.slice(n + 4, n + 4 + this.length);
|
|
2192
2185
|
}
|
|
2193
2186
|
static isValidPacket(data, n) {
|
|
2194
2187
|
return data[4] === 4 ? data[n + 1] === 118 /* CDC2_ACK */ : true;
|
|
@@ -2308,9 +2301,10 @@ class GetSystemFlagsReplyD2HPacket extends HostBoundPacket {
|
|
|
2308
2301
|
this.radioSearching = false;
|
|
2309
2302
|
this.currentProgram = 0;
|
|
2310
2303
|
this.flags = dataView.nextUint32();
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2304
|
+
const hasPartner = (8192 & this.flags) !== 0;
|
|
2305
|
+
const hasRadio = (1536 & this.flags) === 1536;
|
|
2306
|
+
const byte1 = dataView.nextUint8();
|
|
2307
|
+
const byte2 = dataView.nextUint8();
|
|
2314
2308
|
if (this.payloadSize === 11) {
|
|
2315
2309
|
this.battery = 8 * (byte1 & 15);
|
|
2316
2310
|
if ((this.flags & 256) !== 0 || hasRadio)
|
|
@@ -2321,13 +2315,13 @@ class GetSystemFlagsReplyD2HPacket extends HostBoundPacket {
|
|
|
2321
2315
|
if (hasPartner)
|
|
2322
2316
|
this.partnerControllerBatteryPercent = 8 * (byte2 >> 4 & 15);
|
|
2323
2317
|
this.currentProgram = dataView.nextUint8();
|
|
2324
|
-
if (this.battery && this.battery > 100)
|
|
2318
|
+
if (this.battery != null && this.battery > 100)
|
|
2325
2319
|
this.battery = 100;
|
|
2326
|
-
if (this.controllerBatteryPercent && this.controllerBatteryPercent > 100)
|
|
2320
|
+
if (this.controllerBatteryPercent != null && this.controllerBatteryPercent > 100)
|
|
2327
2321
|
this.controllerBatteryPercent = 100;
|
|
2328
|
-
if (this.radioQuality && this.radioQuality > 100)
|
|
2322
|
+
if (this.radioQuality != null && this.radioQuality > 100)
|
|
2329
2323
|
this.radioQuality = 100;
|
|
2330
|
-
if (this.partnerControllerBatteryPercent && this.partnerControllerBatteryPercent > 100)
|
|
2324
|
+
if (this.partnerControllerBatteryPercent != null && this.partnerControllerBatteryPercent > 100)
|
|
2331
2325
|
this.partnerControllerBatteryPercent = 100;
|
|
2332
2326
|
}
|
|
2333
2327
|
}
|
|
@@ -2452,8 +2446,8 @@ class ReadLogPageReplyD2HPacket extends HostBoundPacket {
|
|
|
2452
2446
|
constructor(data) {
|
|
2453
2447
|
super(data);
|
|
2454
2448
|
const dataView = PacketView.fromPacket(this);
|
|
2455
|
-
|
|
2456
|
-
|
|
2449
|
+
const n = this.ackIndex;
|
|
2450
|
+
const size = dataView.nextUint8();
|
|
2457
2451
|
this.offset = dataView.nextUint32();
|
|
2458
2452
|
this.count = dataView.nextUint16();
|
|
2459
2453
|
this.entries = [];
|
|
@@ -2482,7 +2476,7 @@ class GetRadioStatusReplyD2HPacket extends HostBoundPacket {
|
|
|
2482
2476
|
constructor(data) {
|
|
2483
2477
|
super(data);
|
|
2484
2478
|
const dataView = PacketView.fromPacket(this);
|
|
2485
|
-
|
|
2479
|
+
const n = this.ackIndex;
|
|
2486
2480
|
this.device = dataView.nextUint8();
|
|
2487
2481
|
this.quality = dataView.nextUint16();
|
|
2488
2482
|
this.strength = dataView.nextInt16();
|
|
@@ -2511,12 +2505,12 @@ class SelectDashReplyD2HPacket extends HostBoundPacket {
|
|
|
2511
2505
|
static COMMAND_EXTENDED_ID = 43;
|
|
2512
2506
|
}
|
|
2513
2507
|
|
|
2514
|
-
class
|
|
2508
|
+
class EnableDashReplyD2HPacket extends HostBoundPacket {
|
|
2515
2509
|
static COMMAND_ID = 86;
|
|
2516
2510
|
static COMMAND_EXTENDED_ID = 44;
|
|
2517
2511
|
}
|
|
2518
2512
|
|
|
2519
|
-
class
|
|
2513
|
+
class DisableDashReplyD2HPacket extends HostBoundPacket {
|
|
2520
2514
|
static COMMAND_ID = 86;
|
|
2521
2515
|
static COMMAND_EXTENDED_ID = 45;
|
|
2522
2516
|
}
|
|
@@ -2548,12 +2542,12 @@ class GetSlot1to4InfoReplyD2HPacket extends HostBoundPacket {
|
|
|
2548
2542
|
this.slotFlags = dataView.nextUint8();
|
|
2549
2543
|
this.slots = [];
|
|
2550
2544
|
for (let i = 0;i < 4; i++) {
|
|
2551
|
-
|
|
2545
|
+
const hasData = (this.slotFlags & Math.pow(2, start - 1 + i)) !== 0;
|
|
2552
2546
|
if (!hasData)
|
|
2553
2547
|
continue;
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2548
|
+
const iconNum = dataView.nextUint16();
|
|
2549
|
+
const nameLen = dataView.nextUint8();
|
|
2550
|
+
const name = dataView.nextString(nameLen);
|
|
2557
2551
|
this.slots.push({
|
|
2558
2552
|
slot: start + i,
|
|
2559
2553
|
icon: iconNum,
|
|
@@ -2590,7 +2584,7 @@ class FactoryEnableReplyD2HPacket extends HostBoundPacket {
|
|
|
2590
2584
|
static COMMAND_EXTENDED_ID = 255;
|
|
2591
2585
|
}
|
|
2592
2586
|
|
|
2593
|
-
// ../serial/src/
|
|
2587
|
+
// ../serial/src/VexConnection.ts
|
|
2594
2588
|
var thePacketEncoder = PacketEncoder.getInstance();
|
|
2595
2589
|
|
|
2596
2590
|
class VexSerialConnection extends VexEventTarget {
|
|
@@ -2599,25 +2593,17 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2599
2593
|
reader;
|
|
2600
2594
|
port;
|
|
2601
2595
|
serial;
|
|
2602
|
-
isClosing = false;
|
|
2603
2596
|
callbacksQueue = [];
|
|
2604
2597
|
get isConnected() {
|
|
2605
|
-
return this.port && this.reader && this.writer
|
|
2598
|
+
return this.port !== undefined && this.reader !== undefined && this.writer !== undefined;
|
|
2606
2599
|
}
|
|
2607
2600
|
constructor(serial2) {
|
|
2608
2601
|
super();
|
|
2609
2602
|
this.serial = serial2;
|
|
2610
2603
|
}
|
|
2611
2604
|
async close() {
|
|
2612
|
-
if (this.isClosing)
|
|
2613
|
-
return;
|
|
2614
2605
|
if (!this.isConnected)
|
|
2615
2606
|
return;
|
|
2616
|
-
this.isClosing = true;
|
|
2617
|
-
for (const callbackInfo of this.callbacksQueue) {
|
|
2618
|
-
clearTimeout(callbackInfo.timeout);
|
|
2619
|
-
}
|
|
2620
|
-
this.callbacksQueue = [];
|
|
2621
2607
|
try {
|
|
2622
2608
|
await this.writer?.close();
|
|
2623
2609
|
this.writer = undefined;
|
|
@@ -2625,8 +2611,8 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2625
2611
|
try {
|
|
2626
2612
|
await this.reader?.cancel();
|
|
2627
2613
|
try {
|
|
2628
|
-
while (this.reader) {
|
|
2629
|
-
const {
|
|
2614
|
+
while (this.reader != null) {
|
|
2615
|
+
const { done } = await this.reader.read();
|
|
2630
2616
|
if (done)
|
|
2631
2617
|
break;
|
|
2632
2618
|
}
|
|
@@ -2640,37 +2626,36 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2640
2626
|
} catch (e) {
|
|
2641
2627
|
console.warn("Close port error.", e);
|
|
2642
2628
|
} finally {
|
|
2643
|
-
this.isClosing = false;
|
|
2644
2629
|
this.emit("disconnected", undefined);
|
|
2645
2630
|
}
|
|
2646
2631
|
}
|
|
2647
2632
|
async open(use = 0, askUser = true) {
|
|
2648
|
-
if (this.port)
|
|
2633
|
+
if (this.port !== undefined)
|
|
2649
2634
|
throw new Error("Already connected.");
|
|
2650
2635
|
let port;
|
|
2651
2636
|
if (use !== undefined) {
|
|
2652
|
-
|
|
2653
|
-
|
|
2637
|
+
const ports = (await this.serial.getPorts()).filter((p) => {
|
|
2638
|
+
const info = p.getInfo();
|
|
2654
2639
|
return this.filters.find((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
|
|
2655
|
-
}).filter((e) =>
|
|
2640
|
+
}).filter((e) => e.readable !== null);
|
|
2656
2641
|
port = ports[use];
|
|
2657
2642
|
}
|
|
2658
|
-
if (
|
|
2643
|
+
if (port == null && askUser) {
|
|
2659
2644
|
try {
|
|
2660
2645
|
port = await this.serial.requestPort({ filters: this.filters });
|
|
2661
2646
|
} catch (e) {
|
|
2662
|
-
|
|
2647
|
+
console.warn("No valid port selected.");
|
|
2663
2648
|
}
|
|
2664
2649
|
}
|
|
2665
|
-
if (
|
|
2650
|
+
if (port == null)
|
|
2666
2651
|
return;
|
|
2667
|
-
if (port.readable)
|
|
2652
|
+
if (port.readable != null)
|
|
2668
2653
|
return false;
|
|
2669
2654
|
try {
|
|
2670
2655
|
await port.open({ baudRate: 115200 });
|
|
2671
2656
|
this.port = port;
|
|
2672
|
-
this.port.addEventListener("disconnect",
|
|
2673
|
-
|
|
2657
|
+
this.port.addEventListener("disconnect", () => {
|
|
2658
|
+
this.close();
|
|
2674
2659
|
});
|
|
2675
2660
|
this.emit("connected", undefined);
|
|
2676
2661
|
this.writer = this.port.writable.getWriter();
|
|
@@ -2684,15 +2669,15 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2684
2669
|
writeData(rawData, resolve, timeout = 1000) {
|
|
2685
2670
|
this.writeDataAsync(rawData, timeout).then(resolve);
|
|
2686
2671
|
}
|
|
2687
|
-
writeDataAsync(rawData, timeout = 1000) {
|
|
2688
|
-
return new Promise(
|
|
2672
|
+
async writeDataAsync(rawData, timeout = 1000) {
|
|
2673
|
+
return await new Promise((resolve) => {
|
|
2689
2674
|
if (this.writer === undefined) {
|
|
2690
|
-
|
|
2675
|
+
resolve(255 /* CDC2_NACK */);
|
|
2691
2676
|
return;
|
|
2692
2677
|
}
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
callback:
|
|
2678
|
+
const data = rawData instanceof DeviceBoundPacket ? rawData.data : rawData;
|
|
2679
|
+
const cb = {
|
|
2680
|
+
callback: resolve,
|
|
2696
2681
|
timeout: setTimeout(() => {
|
|
2697
2682
|
this.callbacksQueue.shift()?.callback(256 /* TIMEOUT */);
|
|
2698
2683
|
}, timeout),
|
|
@@ -2700,19 +2685,16 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2700
2685
|
wantedCommandExId: rawData instanceof DeviceBoundPacket ? rawData.constructor.COMMAND_EXTENDED_ID : undefined
|
|
2701
2686
|
};
|
|
2702
2687
|
this.callbacksQueue.push(cb);
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
});
|
|
2707
|
-
} catch (error) {
|
|
2688
|
+
this.writer.write(data).then(() => {
|
|
2689
|
+
logData(data, 100);
|
|
2690
|
+
}).catch(() => {
|
|
2708
2691
|
this.callbacksQueue.splice(this.callbacksQueue.indexOf(cb), 1);
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
}
|
|
2692
|
+
resolve(257 /* WRITE_ERROR */);
|
|
2693
|
+
});
|
|
2712
2694
|
});
|
|
2713
2695
|
}
|
|
2714
2696
|
async readData(cache, expectedSize) {
|
|
2715
|
-
if (
|
|
2697
|
+
if (this.reader == null)
|
|
2716
2698
|
throw new Error("No reader");
|
|
2717
2699
|
while (cache.byteLength < expectedSize) {
|
|
2718
2700
|
const { value: readData, done: isDone } = await this.reader.read();
|
|
@@ -2723,7 +2705,8 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2723
2705
|
return cache;
|
|
2724
2706
|
}
|
|
2725
2707
|
async startReader() {
|
|
2726
|
-
let cache = new Uint8Array([])
|
|
2708
|
+
let cache = new Uint8Array([]);
|
|
2709
|
+
let sliceIdx = 0;
|
|
2727
2710
|
for (;; )
|
|
2728
2711
|
try {
|
|
2729
2712
|
cache = await this.readData(cache, 5);
|
|
@@ -2736,7 +2719,7 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2736
2719
|
cache = await this.readData(cache, totalSize);
|
|
2737
2720
|
sliceIdx = totalSize + 1;
|
|
2738
2721
|
const cmdId = cache[2];
|
|
2739
|
-
const hasExtId = cmdId
|
|
2722
|
+
const hasExtId = cmdId === 88 || cmdId === 86;
|
|
2740
2723
|
const cmdExId = hasExtId ? cache[n] : undefined;
|
|
2741
2724
|
const ack = cache[n + 1];
|
|
2742
2725
|
if (hasExtId) {
|
|
@@ -2747,7 +2730,7 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2747
2730
|
let wantedCmdId;
|
|
2748
2731
|
let wantedCmdExId;
|
|
2749
2732
|
let tryIdx = 0;
|
|
2750
|
-
while (callbackInfo = this.callbacksQueue[tryIdx++]) {
|
|
2733
|
+
while ((callbackInfo = this.callbacksQueue[tryIdx++]) !== null) {
|
|
2751
2734
|
wantedCmdId = callbackInfo?.wantedCommandId;
|
|
2752
2735
|
wantedCmdExId = callbackInfo?.wantedCommandExId;
|
|
2753
2736
|
if (wantedCmdId !== undefined && wantedCmdId !== cmdId || wantedCmdExId !== undefined && wantedCmdExId !== cmdExId) {
|
|
@@ -2759,13 +2742,13 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2759
2742
|
console.warn("Unexpected command", cmdId, cmdExId, ack);
|
|
2760
2743
|
continue;
|
|
2761
2744
|
}
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
if (wantedCmdId === undefined && wantedCmdExId === undefined ||
|
|
2765
|
-
callbackInfo.callback(data
|
|
2745
|
+
const data = cache.slice(0, sliceIdx);
|
|
2746
|
+
const PackageType = thePacketEncoder.allPacketsTable[wantedCmdId + " " + wantedCmdExId];
|
|
2747
|
+
if (wantedCmdId === undefined && wantedCmdExId === undefined || PackageType === undefined) {
|
|
2748
|
+
callbackInfo.callback(data);
|
|
2766
2749
|
} else {
|
|
2767
|
-
if (!hasExtId ||
|
|
2768
|
-
callbackInfo.callback(new
|
|
2750
|
+
if (!hasExtId || PackageType.isValidPacket(data, n)) {
|
|
2751
|
+
callbackInfo.callback(new PackageType(data));
|
|
2769
2752
|
} else {
|
|
2770
2753
|
console.warn("ack", ack);
|
|
2771
2754
|
callbackInfo.callback(ack);
|
|
@@ -2774,8 +2757,6 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2774
2757
|
clearTimeout(callbackInfo.timeout);
|
|
2775
2758
|
this.callbacksQueue.splice(tryIdx - 1, 1);
|
|
2776
2759
|
} catch (e) {
|
|
2777
|
-
if (this.isClosing)
|
|
2778
|
-
break;
|
|
2779
2760
|
console.warn("Read error.", e, cache);
|
|
2780
2761
|
await this.close();
|
|
2781
2762
|
break;
|
|
@@ -2784,11 +2765,11 @@ class VexSerialConnection extends VexEventTarget {
|
|
|
2784
2765
|
}
|
|
2785
2766
|
}
|
|
2786
2767
|
async query1() {
|
|
2787
|
-
|
|
2768
|
+
const result = await this.writeDataAsync(new Query1H2DPacket, 100);
|
|
2788
2769
|
return result instanceof Query1ReplyD2HPacket ? result : null;
|
|
2789
2770
|
}
|
|
2790
2771
|
async getSystemVersion() {
|
|
2791
|
-
|
|
2772
|
+
const result = await this.writeDataAsync(new SystemVersionH2DPacket);
|
|
2792
2773
|
return result instanceof SystemVersionReplyD2HPacket ? result.version : null;
|
|
2793
2774
|
}
|
|
2794
2775
|
}
|
|
@@ -2800,70 +2781,76 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
2800
2781
|
{ usbVendorId: 10376, usbProductId: 1283 /* V5_CONTROLLER */ }
|
|
2801
2782
|
];
|
|
2802
2783
|
async getDeviceStatus() {
|
|
2803
|
-
|
|
2784
|
+
const result = await this.writeDataAsync(new GetDeviceStatusH2DPacket);
|
|
2804
2785
|
return result instanceof GetDeviceStatusReplyD2HPacket ? result : null;
|
|
2805
2786
|
}
|
|
2806
2787
|
async getRadioStatus() {
|
|
2807
|
-
|
|
2788
|
+
const result = await this.writeDataAsync(new GetRadioStatusH2DPacket);
|
|
2808
2789
|
return result instanceof GetRadioStatusReplyD2HPacket ? result : null;
|
|
2809
2790
|
}
|
|
2810
2791
|
async getSystemFlags() {
|
|
2811
|
-
|
|
2792
|
+
const result = await this.writeDataAsync(new GetSystemFlagsH2DPacket);
|
|
2812
2793
|
return result instanceof GetSystemFlagsReplyD2HPacket ? result : null;
|
|
2813
2794
|
}
|
|
2814
2795
|
async getSystemStatus(timeout = 1000) {
|
|
2815
|
-
|
|
2796
|
+
const result = await this.writeDataAsync(new GetSystemStatusH2DPacket, timeout);
|
|
2816
2797
|
return result instanceof GetSystemStatusReplyD2HPacket ? result : null;
|
|
2817
2798
|
}
|
|
2818
2799
|
async getMatchStatus() {
|
|
2819
|
-
|
|
2800
|
+
const result = await this.writeDataAsync(new GetMatchStatusH2DPacket);
|
|
2820
2801
|
return result instanceof MatchStatusReplyD2HPacket ? result : null;
|
|
2821
2802
|
}
|
|
2822
2803
|
async uploadProgramToDevice(iniConfig, binFileBuf, coldFileBuf, progressCallback) {
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2804
|
+
const iniFileBuffer = new TextEncoder().encode(iniConfig.createIni());
|
|
2805
|
+
const basename = iniConfig.baseName;
|
|
2806
|
+
const iniRequest = {
|
|
2826
2807
|
filename: basename + ".ini",
|
|
2827
2808
|
buf: iniFileBuffer,
|
|
2828
2809
|
downloadTarget: 1 /* FILE_TARGET_QSPI */,
|
|
2829
2810
|
vid: 1 /* USER */,
|
|
2830
2811
|
autoRun: false
|
|
2831
2812
|
};
|
|
2832
|
-
|
|
2813
|
+
const r1 = await this.uploadFileToDevice(iniRequest, (current, total) => {
|
|
2814
|
+
progressCallback("INI", current, total);
|
|
2815
|
+
});
|
|
2833
2816
|
if (!r1)
|
|
2834
2817
|
return false;
|
|
2835
|
-
|
|
2818
|
+
const coldRequest = coldFileBuf !== undefined ? {
|
|
2836
2819
|
filename: basename + "_lib.bin",
|
|
2837
2820
|
buf: coldFileBuf,
|
|
2838
2821
|
downloadTarget: 1 /* FILE_TARGET_QSPI */,
|
|
2839
2822
|
vid: 24,
|
|
2840
2823
|
autoRun: false
|
|
2841
2824
|
} : undefined;
|
|
2842
|
-
if (coldRequest) {
|
|
2843
|
-
|
|
2825
|
+
if (coldRequest != null) {
|
|
2826
|
+
const r2 = await this.uploadFileToDevice(coldRequest, (current, total) => {
|
|
2827
|
+
progressCallback("COLD", current, total);
|
|
2828
|
+
});
|
|
2844
2829
|
if (!r2)
|
|
2845
2830
|
return;
|
|
2846
2831
|
}
|
|
2847
|
-
|
|
2832
|
+
const binRequest = {
|
|
2848
2833
|
filename: basename + ".bin",
|
|
2849
2834
|
buf: binFileBuf,
|
|
2850
2835
|
downloadTarget: 1 /* FILE_TARGET_QSPI */,
|
|
2851
2836
|
vid: 1 /* USER */,
|
|
2852
|
-
loadAddress: coldFileBuf ? 125829120 : undefined,
|
|
2837
|
+
loadAddress: coldFileBuf != null ? 125829120 : undefined,
|
|
2853
2838
|
autoRun: iniConfig.autorun,
|
|
2854
2839
|
linkedFile: coldRequest
|
|
2855
2840
|
};
|
|
2856
|
-
|
|
2841
|
+
const r3 = await this.uploadFileToDevice(binRequest, (current, total) => {
|
|
2842
|
+
progressCallback("BIN", current, total);
|
|
2843
|
+
});
|
|
2857
2844
|
return r3;
|
|
2858
2845
|
}
|
|
2859
2846
|
async downloadFileToHost(request, downloadTarget = 1 /* FILE_TARGET_QSPI */, progressCallback) {
|
|
2860
|
-
|
|
2847
|
+
const { filename, vendor, loadAddress, size } = request;
|
|
2861
2848
|
let nextAddress = loadAddress ?? USER_FLASH_USR_CODE_START;
|
|
2862
|
-
|
|
2849
|
+
const p1 = await this.writeDataAsync(new InitFileTransferH2DPacket(2 /* READ */, downloadTarget, vendor, 0 /* NONE */, new Uint8Array, nextAddress, filename, ""));
|
|
2863
2850
|
if (!(p1 instanceof InitFileTransferReplyD2HPacket))
|
|
2864
2851
|
throw new Error("InitFileTransferH2DPacket failed");
|
|
2865
|
-
|
|
2866
|
-
|
|
2852
|
+
const fileSize = size ?? p1.fileSize;
|
|
2853
|
+
const bufferChunkSize = p1.windowSize > 0 && p1.windowSize <= USER_PROG_CHUNK_SIZE ? p1.windowSize : USER_PROG_CHUNK_SIZE;
|
|
2867
2854
|
let bufferOffset = 0;
|
|
2868
2855
|
let fileBuf = new Uint8Array(fileSize + bufferChunkSize);
|
|
2869
2856
|
let lastBlock = false;
|
|
@@ -2871,16 +2858,16 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
2871
2858
|
if (fileSize <= bufferOffset + bufferChunkSize) {
|
|
2872
2859
|
lastBlock = true;
|
|
2873
2860
|
}
|
|
2874
|
-
|
|
2861
|
+
const p2 = await this.writeDataAsync(new ReadFileH2DPacket(nextAddress, bufferChunkSize), 3000);
|
|
2875
2862
|
if (!(p2 instanceof ReadFileReplyD2HPacket))
|
|
2876
2863
|
throw new Error("ReadFileReplyD2HPacket failed");
|
|
2877
2864
|
fileBuf.set(new Uint8Array(p2.buf), bufferOffset);
|
|
2878
|
-
if (progressCallback)
|
|
2865
|
+
if (progressCallback != null)
|
|
2879
2866
|
progressCallback(bufferOffset, fileSize);
|
|
2880
2867
|
bufferOffset += bufferChunkSize;
|
|
2881
2868
|
nextAddress += bufferChunkSize;
|
|
2882
2869
|
}
|
|
2883
|
-
|
|
2870
|
+
await this.writeDataAsync(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */), 30000);
|
|
2884
2871
|
fileBuf = fileBuf.slice(0, fileSize);
|
|
2885
2872
|
return fileBuf;
|
|
2886
2873
|
}
|
|
@@ -2902,74 +2889,76 @@ class V5SerialConnection extends VexSerialConnection {
|
|
|
2902
2889
|
vendor = vendor ?? 1 /* USER */;
|
|
2903
2890
|
let nextAddress = loadAddress ?? USER_FLASH_USR_CODE_START;
|
|
2904
2891
|
console.log("init file transfer", filename);
|
|
2905
|
-
|
|
2892
|
+
const p1 = await this.writeDataAsync(new InitFileTransferH2DPacket(1 /* WRITE */, downloadTarget, vendor, 1 /* OVERWRITE */, buf, nextAddress, filename, exttype));
|
|
2906
2893
|
if (!(p1 instanceof InitFileTransferReplyD2HPacket))
|
|
2907
2894
|
throw new Error("InitFileTransferH2DPacket failed");
|
|
2908
2895
|
console.log(p1);
|
|
2909
2896
|
if (linkedFile !== undefined) {
|
|
2910
|
-
|
|
2897
|
+
const p3 = await this.writeDataAsync(new LinkFileH2DPacket(linkedFile.vendor ?? 1 /* USER */, linkedFile.filename, 0), 1e4);
|
|
2911
2898
|
if (!(p3 instanceof LinkFileReplyD2HPacket))
|
|
2912
2899
|
throw new Error("LinkFileH2DPacket failed");
|
|
2913
2900
|
}
|
|
2914
|
-
|
|
2901
|
+
const bufferChunkSize = p1.windowSize > 0 && p1.windowSize <= USER_PROG_CHUNK_SIZE ? p1.windowSize : USER_PROG_CHUNK_SIZE;
|
|
2915
2902
|
let bufferOffset = 0;
|
|
2916
2903
|
let lastBlock = false;
|
|
2917
2904
|
while (!lastBlock) {
|
|
2918
|
-
|
|
2905
|
+
let tmpbuf;
|
|
2919
2906
|
if (buf.byteLength - bufferOffset > bufferChunkSize) {
|
|
2920
2907
|
tmpbuf = buf.subarray(bufferOffset, bufferOffset + bufferChunkSize);
|
|
2921
2908
|
} else {
|
|
2922
|
-
|
|
2909
|
+
const length = (buf.byteLength - bufferOffset + 3) / 4 >>> 0;
|
|
2923
2910
|
tmpbuf = new Uint8Array(length * 4);
|
|
2924
2911
|
tmpbuf.set(buf.subarray(bufferOffset, buf.byteLength));
|
|
2925
2912
|
lastBlock = true;
|
|
2926
2913
|
}
|
|
2927
|
-
|
|
2914
|
+
const p2 = await this.writeDataAsync(new WriteFileH2DPacket(nextAddress, tmpbuf), 3000);
|
|
2928
2915
|
if (!(p2 instanceof WriteFileReplyD2HPacket))
|
|
2929
2916
|
throw new Error("WriteFileReplyD2HPacket failed");
|
|
2930
|
-
if (progressCallback)
|
|
2917
|
+
if (progressCallback != null)
|
|
2931
2918
|
progressCallback(bufferOffset, buf.byteLength);
|
|
2932
2919
|
bufferOffset += bufferChunkSize;
|
|
2933
2920
|
nextAddress += bufferChunkSize;
|
|
2934
2921
|
}
|
|
2935
|
-
|
|
2922
|
+
const p4 = await this.writeDataAsync(new ExitFileTransferH2DPacket(autoRun ? 1 /* EXIT_RUN */ : 3 /* EXIT_HALT */), 30000);
|
|
2936
2923
|
return p4 instanceof ExitFileTransferReplyD2HPacket;
|
|
2937
2924
|
}
|
|
2938
2925
|
async setMatchMode(mode) {
|
|
2939
|
-
|
|
2926
|
+
const result = await this.writeDataAsync(new UpdateMatchModeH2DPacket(mode, 0));
|
|
2940
2927
|
return result instanceof MatchModeReplyD2HPacket ? result : null;
|
|
2941
2928
|
}
|
|
2942
2929
|
async loadProgram(value) {
|
|
2943
|
-
|
|
2930
|
+
const result = await this.writeDataAsync(new LoadFileActionH2DPacket(1 /* USER */, 0 /* RUN */, value));
|
|
2944
2931
|
return result instanceof LoadFileActionReplyD2HPacket ? result : null;
|
|
2945
2932
|
}
|
|
2946
2933
|
async stopProgram() {
|
|
2947
|
-
|
|
2934
|
+
const result = await this.writeDataAsync(new LoadFileActionH2DPacket(1 /* USER */, 128 /* STOP */, ""));
|
|
2948
2935
|
return result instanceof LoadFileActionReplyD2HPacket ? result : null;
|
|
2949
2936
|
}
|
|
2950
2937
|
async mockTouch(x, y, press) {
|
|
2951
|
-
|
|
2938
|
+
const result = await this.writeDataAsync(new SendDashTouchH2DPacket(x, y, press));
|
|
2939
|
+
return result instanceof SendDashTouchReplyD2HPacket ? result : null;
|
|
2940
|
+
}
|
|
2941
|
+
async openScreen(screen, port) {
|
|
2942
|
+
const result = await this.writeDataAsync(new SelectDashH2DPacket(screen, port));
|
|
2952
2943
|
return result instanceof SendDashTouchReplyD2HPacket ? result : null;
|
|
2953
2944
|
}
|
|
2954
2945
|
}
|
|
2955
2946
|
function logData(data, limitedSize) {
|
|
2956
2947
|
if (data === undefined)
|
|
2957
2948
|
return;
|
|
2958
|
-
limitedSize
|
|
2949
|
+
limitedSize ||= data.length;
|
|
2959
2950
|
let a = "";
|
|
2960
2951
|
for (let n = 0;n < data.length && n < limitedSize; n++)
|
|
2961
2952
|
a += ("00" + data[n].toString(16)).substr(-2, 2) + " ";
|
|
2962
2953
|
limitedSize < data.length && (a += " ... ");
|
|
2963
2954
|
}
|
|
2964
2955
|
function binaryArrayJoin(left, right) {
|
|
2965
|
-
const leftSize = left ? left.byteLength : 0;
|
|
2966
|
-
const rightSize = right ? right.byteLength : 0;
|
|
2956
|
+
const leftSize = left != null ? left.byteLength : 0;
|
|
2957
|
+
const rightSize = right != null ? right.byteLength : 0;
|
|
2967
2958
|
const all = new Uint8Array(leftSize + rightSize);
|
|
2968
|
-
return all.length === 0 ? new Uint8Array : (left && all.set(
|
|
2959
|
+
return all.length === 0 ? new Uint8Array : (left != null && all.set(new Uint8Array(left), 0), right != null && all.set(new Uint8Array(right), leftSize), all);
|
|
2969
2960
|
}
|
|
2970
|
-
// ../../node_modules/.bun/unzipit@
|
|
2971
|
-
var _a;
|
|
2972
|
-
var _b;
|
|
2961
|
+
// ../../node_modules/.bun/unzipit@1.4.3/node_modules/unzipit/dist/unzipit.module.js
|
|
2973
2962
|
function readBlobAsArrayBuffer(blob) {
|
|
2974
2963
|
if (blob.arrayBuffer) {
|
|
2975
2964
|
return blob.arrayBuffer();
|
|
@@ -2993,7 +2982,7 @@ function isBlob(v) {
|
|
|
2993
2982
|
function isSharedArrayBuffer(b) {
|
|
2994
2983
|
return typeof SharedArrayBuffer !== "undefined" && b instanceof SharedArrayBuffer;
|
|
2995
2984
|
}
|
|
2996
|
-
var isNode = typeof process !== "undefined" &&
|
|
2985
|
+
var isNode = typeof process !== "undefined" && process.versions && typeof process.versions.node !== "undefined" && typeof process.versions.electron === "undefined";
|
|
2997
2986
|
function isTypedArraySameAsArrayBuffer(typedArray) {
|
|
2998
2987
|
return typedArray.byteOffset === 0 && typedArray.byteLength === typedArray.buffer.byteLength;
|
|
2999
2988
|
}
|
|
@@ -3026,6 +3015,309 @@ class BlobReader {
|
|
|
3026
3015
|
return this.blob.slice(offset, offset + length, type);
|
|
3027
3016
|
}
|
|
3028
3017
|
}
|
|
3018
|
+
function inflate(data, buf) {
|
|
3019
|
+
var u8 = Uint8Array;
|
|
3020
|
+
if (data[0] == 3 && data[1] == 0)
|
|
3021
|
+
return buf ? buf : new u8(0);
|
|
3022
|
+
var bitsF = _bitsF, bitsE = _bitsE, decodeTiny = _decodeTiny, get17 = _get17;
|
|
3023
|
+
var noBuf = buf == null;
|
|
3024
|
+
if (noBuf)
|
|
3025
|
+
buf = new u8(data.length >>> 2 << 3);
|
|
3026
|
+
var BFINAL = 0, BTYPE = 0, HLIT = 0, HDIST = 0, HCLEN = 0, ML = 0, MD = 0;
|
|
3027
|
+
var off = 0, pos = 0;
|
|
3028
|
+
var lmap, dmap;
|
|
3029
|
+
while (BFINAL == 0) {
|
|
3030
|
+
BFINAL = bitsF(data, pos, 1);
|
|
3031
|
+
BTYPE = bitsF(data, pos + 1, 2);
|
|
3032
|
+
pos += 3;
|
|
3033
|
+
if (BTYPE == 0) {
|
|
3034
|
+
if ((pos & 7) != 0)
|
|
3035
|
+
pos += 8 - (pos & 7);
|
|
3036
|
+
var p8 = (pos >>> 3) + 4, len = data[p8 - 4] | data[p8 - 3] << 8;
|
|
3037
|
+
if (noBuf)
|
|
3038
|
+
buf = _check(buf, off + len);
|
|
3039
|
+
buf.set(new u8(data.buffer, data.byteOffset + p8, len), off);
|
|
3040
|
+
pos = p8 + len << 3;
|
|
3041
|
+
off += len;
|
|
3042
|
+
continue;
|
|
3043
|
+
}
|
|
3044
|
+
if (noBuf)
|
|
3045
|
+
buf = _check(buf, off + (1 << 17));
|
|
3046
|
+
if (BTYPE == 1) {
|
|
3047
|
+
lmap = U.flmap;
|
|
3048
|
+
dmap = U.fdmap;
|
|
3049
|
+
ML = (1 << 9) - 1;
|
|
3050
|
+
MD = (1 << 5) - 1;
|
|
3051
|
+
}
|
|
3052
|
+
if (BTYPE == 2) {
|
|
3053
|
+
HLIT = bitsE(data, pos, 5) + 257;
|
|
3054
|
+
HDIST = bitsE(data, pos + 5, 5) + 1;
|
|
3055
|
+
HCLEN = bitsE(data, pos + 10, 4) + 4;
|
|
3056
|
+
pos += 14;
|
|
3057
|
+
for (var i = 0;i < 38; i += 2) {
|
|
3058
|
+
U.itree[i] = 0;
|
|
3059
|
+
U.itree[i + 1] = 0;
|
|
3060
|
+
}
|
|
3061
|
+
var tl = 1;
|
|
3062
|
+
for (var i = 0;i < HCLEN; i++) {
|
|
3063
|
+
var l = bitsE(data, pos + i * 3, 3);
|
|
3064
|
+
U.itree[(U.ordr[i] << 1) + 1] = l;
|
|
3065
|
+
if (l > tl)
|
|
3066
|
+
tl = l;
|
|
3067
|
+
}
|
|
3068
|
+
pos += 3 * HCLEN;
|
|
3069
|
+
makeCodes(U.itree, tl);
|
|
3070
|
+
codes2map(U.itree, tl, U.imap);
|
|
3071
|
+
lmap = U.lmap;
|
|
3072
|
+
dmap = U.dmap;
|
|
3073
|
+
pos = decodeTiny(U.imap, (1 << tl) - 1, HLIT + HDIST, data, pos, U.ttree);
|
|
3074
|
+
var mx0 = _copyOut(U.ttree, 0, HLIT, U.ltree);
|
|
3075
|
+
ML = (1 << mx0) - 1;
|
|
3076
|
+
var mx1 = _copyOut(U.ttree, HLIT, HDIST, U.dtree);
|
|
3077
|
+
MD = (1 << mx1) - 1;
|
|
3078
|
+
makeCodes(U.ltree, mx0);
|
|
3079
|
+
codes2map(U.ltree, mx0, lmap);
|
|
3080
|
+
makeCodes(U.dtree, mx1);
|
|
3081
|
+
codes2map(U.dtree, mx1, dmap);
|
|
3082
|
+
}
|
|
3083
|
+
while (true) {
|
|
3084
|
+
var code = lmap[get17(data, pos) & ML];
|
|
3085
|
+
pos += code & 15;
|
|
3086
|
+
var lit = code >>> 4;
|
|
3087
|
+
if (lit >>> 8 == 0) {
|
|
3088
|
+
buf[off++] = lit;
|
|
3089
|
+
} else if (lit == 256) {
|
|
3090
|
+
break;
|
|
3091
|
+
} else {
|
|
3092
|
+
var end = off + lit - 254;
|
|
3093
|
+
if (lit > 264) {
|
|
3094
|
+
var ebs = U.ldef[lit - 257];
|
|
3095
|
+
end = off + (ebs >>> 3) + bitsE(data, pos, ebs & 7);
|
|
3096
|
+
pos += ebs & 7;
|
|
3097
|
+
}
|
|
3098
|
+
var dcode = dmap[get17(data, pos) & MD];
|
|
3099
|
+
pos += dcode & 15;
|
|
3100
|
+
var dlit = dcode >>> 4;
|
|
3101
|
+
var dbs = U.ddef[dlit], dst = (dbs >>> 4) + bitsF(data, pos, dbs & 15);
|
|
3102
|
+
pos += dbs & 15;
|
|
3103
|
+
if (noBuf)
|
|
3104
|
+
buf = _check(buf, off + (1 << 17));
|
|
3105
|
+
while (off < end) {
|
|
3106
|
+
buf[off] = buf[off++ - dst];
|
|
3107
|
+
buf[off] = buf[off++ - dst];
|
|
3108
|
+
buf[off] = buf[off++ - dst];
|
|
3109
|
+
buf[off] = buf[off++ - dst];
|
|
3110
|
+
}
|
|
3111
|
+
off = end;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
return buf.length == off ? buf : buf.slice(0, off);
|
|
3116
|
+
}
|
|
3117
|
+
function _check(buf, len) {
|
|
3118
|
+
var bl = buf.length;
|
|
3119
|
+
if (len <= bl)
|
|
3120
|
+
return buf;
|
|
3121
|
+
var nbuf = new Uint8Array(Math.max(bl << 1, len));
|
|
3122
|
+
nbuf.set(buf, 0);
|
|
3123
|
+
return nbuf;
|
|
3124
|
+
}
|
|
3125
|
+
function _decodeTiny(lmap, LL, len, data, pos, tree) {
|
|
3126
|
+
var bitsE = _bitsE, get17 = _get17;
|
|
3127
|
+
var i = 0;
|
|
3128
|
+
while (i < len) {
|
|
3129
|
+
var code = lmap[get17(data, pos) & LL];
|
|
3130
|
+
pos += code & 15;
|
|
3131
|
+
var lit = code >>> 4;
|
|
3132
|
+
if (lit <= 15) {
|
|
3133
|
+
tree[i] = lit;
|
|
3134
|
+
i++;
|
|
3135
|
+
} else {
|
|
3136
|
+
var ll = 0, n = 0;
|
|
3137
|
+
if (lit == 16) {
|
|
3138
|
+
n = 3 + bitsE(data, pos, 2);
|
|
3139
|
+
pos += 2;
|
|
3140
|
+
ll = tree[i - 1];
|
|
3141
|
+
} else if (lit == 17) {
|
|
3142
|
+
n = 3 + bitsE(data, pos, 3);
|
|
3143
|
+
pos += 3;
|
|
3144
|
+
} else if (lit == 18) {
|
|
3145
|
+
n = 11 + bitsE(data, pos, 7);
|
|
3146
|
+
pos += 7;
|
|
3147
|
+
}
|
|
3148
|
+
var ni = i + n;
|
|
3149
|
+
while (i < ni) {
|
|
3150
|
+
tree[i] = ll;
|
|
3151
|
+
i++;
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
return pos;
|
|
3156
|
+
}
|
|
3157
|
+
function _copyOut(src, off, len, tree) {
|
|
3158
|
+
var mx = 0, i = 0, tl = tree.length >>> 1;
|
|
3159
|
+
while (i < len) {
|
|
3160
|
+
var v = src[i + off];
|
|
3161
|
+
tree[i << 1] = 0;
|
|
3162
|
+
tree[(i << 1) + 1] = v;
|
|
3163
|
+
if (v > mx)
|
|
3164
|
+
mx = v;
|
|
3165
|
+
i++;
|
|
3166
|
+
}
|
|
3167
|
+
while (i < tl) {
|
|
3168
|
+
tree[i << 1] = 0;
|
|
3169
|
+
tree[(i << 1) + 1] = 0;
|
|
3170
|
+
i++;
|
|
3171
|
+
}
|
|
3172
|
+
return mx;
|
|
3173
|
+
}
|
|
3174
|
+
function makeCodes(tree, MAX_BITS) {
|
|
3175
|
+
var max_code = tree.length;
|
|
3176
|
+
var code, bits, n, i, len;
|
|
3177
|
+
var bl_count = U.bl_count;
|
|
3178
|
+
for (var i = 0;i <= MAX_BITS; i++)
|
|
3179
|
+
bl_count[i] = 0;
|
|
3180
|
+
for (i = 1;i < max_code; i += 2)
|
|
3181
|
+
bl_count[tree[i]]++;
|
|
3182
|
+
var next_code = U.next_code;
|
|
3183
|
+
code = 0;
|
|
3184
|
+
bl_count[0] = 0;
|
|
3185
|
+
for (bits = 1;bits <= MAX_BITS; bits++) {
|
|
3186
|
+
code = code + bl_count[bits - 1] << 1;
|
|
3187
|
+
next_code[bits] = code;
|
|
3188
|
+
}
|
|
3189
|
+
for (n = 0;n < max_code; n += 2) {
|
|
3190
|
+
len = tree[n + 1];
|
|
3191
|
+
if (len != 0) {
|
|
3192
|
+
tree[n] = next_code[len];
|
|
3193
|
+
next_code[len]++;
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
function codes2map(tree, MAX_BITS, map) {
|
|
3198
|
+
var max_code = tree.length;
|
|
3199
|
+
var r15 = U.rev15;
|
|
3200
|
+
for (var i = 0;i < max_code; i += 2)
|
|
3201
|
+
if (tree[i + 1] != 0) {
|
|
3202
|
+
var lit = i >> 1;
|
|
3203
|
+
var cl = tree[i + 1], val = lit << 4 | cl;
|
|
3204
|
+
var rest = MAX_BITS - cl, i0 = tree[i] << rest, i1 = i0 + (1 << rest);
|
|
3205
|
+
while (i0 != i1) {
|
|
3206
|
+
var p0 = r15[i0] >>> 15 - MAX_BITS;
|
|
3207
|
+
map[p0] = val;
|
|
3208
|
+
i0++;
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
function revCodes(tree, MAX_BITS) {
|
|
3213
|
+
var r15 = U.rev15, imb = 15 - MAX_BITS;
|
|
3214
|
+
for (var i = 0;i < tree.length; i += 2) {
|
|
3215
|
+
var i0 = tree[i] << MAX_BITS - tree[i + 1];
|
|
3216
|
+
tree[i] = r15[i0] >>> imb;
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
function _bitsE(dt, pos, length) {
|
|
3220
|
+
return (dt[pos >>> 3] | dt[(pos >>> 3) + 1] << 8) >>> (pos & 7) & (1 << length) - 1;
|
|
3221
|
+
}
|
|
3222
|
+
function _bitsF(dt, pos, length) {
|
|
3223
|
+
return (dt[pos >>> 3] | dt[(pos >>> 3) + 1] << 8 | dt[(pos >>> 3) + 2] << 16) >>> (pos & 7) & (1 << length) - 1;
|
|
3224
|
+
}
|
|
3225
|
+
function _get17(dt, pos) {
|
|
3226
|
+
return (dt[pos >>> 3] | dt[(pos >>> 3) + 1] << 8 | dt[(pos >>> 3) + 2] << 16) >>> (pos & 7);
|
|
3227
|
+
}
|
|
3228
|
+
var U = function() {
|
|
3229
|
+
var u16 = Uint16Array, u32 = Uint32Array;
|
|
3230
|
+
return {
|
|
3231
|
+
next_code: new u16(16),
|
|
3232
|
+
bl_count: new u16(16),
|
|
3233
|
+
ordr: [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],
|
|
3234
|
+
of0: [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 999, 999, 999],
|
|
3235
|
+
exb: [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0],
|
|
3236
|
+
ldef: new u16(32),
|
|
3237
|
+
df0: [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 65535, 65535],
|
|
3238
|
+
dxb: [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0],
|
|
3239
|
+
ddef: new u32(32),
|
|
3240
|
+
flmap: new u16(512),
|
|
3241
|
+
fltree: [],
|
|
3242
|
+
fdmap: new u16(32),
|
|
3243
|
+
fdtree: [],
|
|
3244
|
+
lmap: new u16(32768),
|
|
3245
|
+
ltree: [],
|
|
3246
|
+
ttree: [],
|
|
3247
|
+
dmap: new u16(32768),
|
|
3248
|
+
dtree: [],
|
|
3249
|
+
imap: new u16(512),
|
|
3250
|
+
itree: [],
|
|
3251
|
+
rev15: new u16(1 << 15),
|
|
3252
|
+
lhst: new u32(286),
|
|
3253
|
+
dhst: new u32(30),
|
|
3254
|
+
ihst: new u32(19),
|
|
3255
|
+
lits: new u32(15000),
|
|
3256
|
+
strt: new u16(1 << 16),
|
|
3257
|
+
prev: new u16(1 << 15)
|
|
3258
|
+
};
|
|
3259
|
+
}();
|
|
3260
|
+
(function() {
|
|
3261
|
+
var len = 1 << 15;
|
|
3262
|
+
for (var i = 0;i < len; i++) {
|
|
3263
|
+
var x = i;
|
|
3264
|
+
x = (x & 2863311530) >>> 1 | (x & 1431655765) << 1;
|
|
3265
|
+
x = (x & 3435973836) >>> 2 | (x & 858993459) << 2;
|
|
3266
|
+
x = (x & 4042322160) >>> 4 | (x & 252645135) << 4;
|
|
3267
|
+
x = (x & 4278255360) >>> 8 | (x & 16711935) << 8;
|
|
3268
|
+
U.rev15[i] = (x >>> 16 | x << 16) >>> 17;
|
|
3269
|
+
}
|
|
3270
|
+
function pushV(tgt, n, sv) {
|
|
3271
|
+
while (n-- != 0)
|
|
3272
|
+
tgt.push(0, sv);
|
|
3273
|
+
}
|
|
3274
|
+
for (var i = 0;i < 32; i++) {
|
|
3275
|
+
U.ldef[i] = U.of0[i] << 3 | U.exb[i];
|
|
3276
|
+
U.ddef[i] = U.df0[i] << 4 | U.dxb[i];
|
|
3277
|
+
}
|
|
3278
|
+
pushV(U.fltree, 144, 8);
|
|
3279
|
+
pushV(U.fltree, 255 - 143, 9);
|
|
3280
|
+
pushV(U.fltree, 279 - 255, 7);
|
|
3281
|
+
pushV(U.fltree, 287 - 279, 8);
|
|
3282
|
+
makeCodes(U.fltree, 9);
|
|
3283
|
+
codes2map(U.fltree, 9, U.flmap);
|
|
3284
|
+
revCodes(U.fltree, 9);
|
|
3285
|
+
pushV(U.fdtree, 32, 5);
|
|
3286
|
+
makeCodes(U.fdtree, 5);
|
|
3287
|
+
codes2map(U.fdtree, 5, U.fdmap);
|
|
3288
|
+
revCodes(U.fdtree, 5);
|
|
3289
|
+
pushV(U.itree, 19, 0);
|
|
3290
|
+
pushV(U.ltree, 286, 0);
|
|
3291
|
+
pushV(U.dtree, 30, 0);
|
|
3292
|
+
pushV(U.ttree, 320, 0);
|
|
3293
|
+
})();
|
|
3294
|
+
var crc = {
|
|
3295
|
+
table: function() {
|
|
3296
|
+
var tab = new Uint32Array(256);
|
|
3297
|
+
for (var n = 0;n < 256; n++) {
|
|
3298
|
+
var c = n;
|
|
3299
|
+
for (var k = 0;k < 8; k++) {
|
|
3300
|
+
if (c & 1)
|
|
3301
|
+
c = 3988292384 ^ c >>> 1;
|
|
3302
|
+
else
|
|
3303
|
+
c = c >>> 1;
|
|
3304
|
+
}
|
|
3305
|
+
tab[n] = c;
|
|
3306
|
+
}
|
|
3307
|
+
return tab;
|
|
3308
|
+
}(),
|
|
3309
|
+
update: function(c, buf, off, len) {
|
|
3310
|
+
for (var i = 0;i < len; i++)
|
|
3311
|
+
c = crc.table[(c ^ buf[off + i]) & 255] ^ c >>> 8;
|
|
3312
|
+
return c;
|
|
3313
|
+
},
|
|
3314
|
+
crc: function(b, o, l) {
|
|
3315
|
+
return crc.update(4294967295, b, o, l) ^ 4294967295;
|
|
3316
|
+
}
|
|
3317
|
+
};
|
|
3318
|
+
function inflateRaw(file, buf) {
|
|
3319
|
+
return inflate(file, buf);
|
|
3320
|
+
}
|
|
3029
3321
|
var config = {
|
|
3030
3322
|
numWorkers: 1,
|
|
3031
3323
|
workerURL: "",
|
|
@@ -3054,8 +3346,8 @@ function startWorker(url) {
|
|
|
3054
3346
|
const worker = new Worker(url);
|
|
3055
3347
|
worker.onmessage = (e) => {
|
|
3056
3348
|
if (e.data === "start") {
|
|
3057
|
-
worker.onerror =
|
|
3058
|
-
worker.onmessage =
|
|
3349
|
+
worker.onerror = undefined;
|
|
3350
|
+
worker.onmessage = undefined;
|
|
3059
3351
|
resolve(worker);
|
|
3060
3352
|
} else {
|
|
3061
3353
|
reject(new Error(`unexpected message: ${e.data}`));
|
|
@@ -3064,12 +3356,14 @@ function startWorker(url) {
|
|
|
3064
3356
|
worker.onerror = reject;
|
|
3065
3357
|
});
|
|
3066
3358
|
}
|
|
3359
|
+
function dynamicRequire(mod, request) {
|
|
3360
|
+
return mod.require ? mod.require(request) : {};
|
|
3361
|
+
}
|
|
3067
3362
|
var workerHelper = function() {
|
|
3068
3363
|
if (isNode) {
|
|
3364
|
+
const { Worker: Worker2 } = dynamicRequire(module_unzipit_module, "worker_threads");
|
|
3069
3365
|
return {
|
|
3070
3366
|
async createWorker(url) {
|
|
3071
|
-
const moduleId = "node:worker_threads";
|
|
3072
|
-
const { Worker: Worker2 } = await import(moduleId);
|
|
3073
3367
|
return new Worker2(url);
|
|
3074
3368
|
},
|
|
3075
3369
|
addEventListener(worker, fn) {
|
|
@@ -3087,7 +3381,7 @@ var workerHelper = function() {
|
|
|
3087
3381
|
try {
|
|
3088
3382
|
const worker = await startWorker(url);
|
|
3089
3383
|
return worker;
|
|
3090
|
-
} catch (
|
|
3384
|
+
} catch (e) {
|
|
3091
3385
|
console.warn("could not load worker:", url);
|
|
3092
3386
|
}
|
|
3093
3387
|
let text;
|
|
@@ -3101,7 +3395,7 @@ var workerHelper = function() {
|
|
|
3101
3395
|
const worker = await startWorker(url);
|
|
3102
3396
|
config.workerURL = url;
|
|
3103
3397
|
return worker;
|
|
3104
|
-
} catch (
|
|
3398
|
+
} catch (e) {
|
|
3105
3399
|
console.warn("could not load worker via fetch:", url);
|
|
3106
3400
|
}
|
|
3107
3401
|
if (text !== undefined) {
|
|
@@ -3110,7 +3404,7 @@ var workerHelper = function() {
|
|
|
3110
3404
|
const worker = await startWorker(url);
|
|
3111
3405
|
config.workerURL = url;
|
|
3112
3406
|
return worker;
|
|
3113
|
-
} catch (
|
|
3407
|
+
} catch (e) {
|
|
3114
3408
|
console.warn("could not load worker via dataURI");
|
|
3115
3409
|
}
|
|
3116
3410
|
}
|
|
@@ -3138,41 +3432,16 @@ async function getAvailableWorker() {
|
|
|
3138
3432
|
workers.push(worker);
|
|
3139
3433
|
availableWorkers.push(worker);
|
|
3140
3434
|
workerHelper.addEventListener(worker, handleResult);
|
|
3141
|
-
} catch (
|
|
3435
|
+
} catch (e) {
|
|
3142
3436
|
canUseWorkers = false;
|
|
3143
3437
|
}
|
|
3144
3438
|
}
|
|
3145
3439
|
return availableWorkers.pop();
|
|
3146
3440
|
}
|
|
3147
|
-
|
|
3148
|
-
const
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
const chunks = [];
|
|
3152
|
-
const reader = ds.readable.getReader();
|
|
3153
|
-
for (;; ) {
|
|
3154
|
-
const { done, value } = await reader.read();
|
|
3155
|
-
if (done) {
|
|
3156
|
-
break;
|
|
3157
|
-
}
|
|
3158
|
-
chunks.push(value);
|
|
3159
|
-
}
|
|
3160
|
-
const size = chunks.reduce((s, c) => s + c.byteLength, 0);
|
|
3161
|
-
const result = new Uint8Array(size);
|
|
3162
|
-
let offset = 0;
|
|
3163
|
-
for (const chunk of chunks) {
|
|
3164
|
-
result.set(chunk, offset);
|
|
3165
|
-
offset += chunk.byteLength;
|
|
3166
|
-
}
|
|
3167
|
-
return result;
|
|
3168
|
-
}
|
|
3169
|
-
async function inflateRawLocal(src, type, resolve, reject) {
|
|
3170
|
-
try {
|
|
3171
|
-
const dst = await decompressRaw(src);
|
|
3172
|
-
resolve(type ? new Blob([dst], { type }) : dst.buffer);
|
|
3173
|
-
} catch (e) {
|
|
3174
|
-
reject(e);
|
|
3175
|
-
}
|
|
3441
|
+
function inflateRawLocal(src, uncompressedSize, type, resolve) {
|
|
3442
|
+
const dst = new Uint8Array(uncompressedSize);
|
|
3443
|
+
inflateRaw(src, dst);
|
|
3444
|
+
resolve(type ? new Blob([dst], { type }) : dst.buffer);
|
|
3176
3445
|
}
|
|
3177
3446
|
async function processWaitingForWorkerQueue() {
|
|
3178
3447
|
if (waitingForWorkerQueue.length === 0) {
|
|
@@ -3187,7 +3456,7 @@ async function processWaitingForWorkerQueue() {
|
|
|
3187
3456
|
return;
|
|
3188
3457
|
}
|
|
3189
3458
|
const { id, src, uncompressedSize, type, resolve, reject } = waitingForWorkerQueue.shift();
|
|
3190
|
-
currentlyProcessingIdToRequestMap.set(id, { id,
|
|
3459
|
+
currentlyProcessingIdToRequestMap.set(id, { id, resolve, reject });
|
|
3191
3460
|
const transferables = [];
|
|
3192
3461
|
worker.postMessage({
|
|
3193
3462
|
type: "inflate",
|
|
@@ -3203,9 +3472,12 @@ async function processWaitingForWorkerQueue() {
|
|
|
3203
3472
|
}
|
|
3204
3473
|
}
|
|
3205
3474
|
while (waitingForWorkerQueue.length) {
|
|
3206
|
-
const { src, type, resolve
|
|
3207
|
-
|
|
3208
|
-
|
|
3475
|
+
const { src, uncompressedSize, type, resolve } = waitingForWorkerQueue.shift();
|
|
3476
|
+
let data = src;
|
|
3477
|
+
if (isBlob(src)) {
|
|
3478
|
+
data = await readBlobAsUint8Array(src);
|
|
3479
|
+
}
|
|
3480
|
+
inflateRawLocal(data, uncompressedSize, type, resolve);
|
|
3209
3481
|
}
|
|
3210
3482
|
}
|
|
3211
3483
|
function inflateRawAsync(src, uncompressedSize, type) {
|
|
@@ -3270,7 +3542,7 @@ async function readAsBlobOrTypedArray(reader, offset, length, type) {
|
|
|
3270
3542
|
}
|
|
3271
3543
|
return await reader.read(offset, length);
|
|
3272
3544
|
}
|
|
3273
|
-
var crc = {
|
|
3545
|
+
var crc$1 = {
|
|
3274
3546
|
unsigned() {
|
|
3275
3547
|
return 0;
|
|
3276
3548
|
}
|
|
@@ -3285,7 +3557,7 @@ function getUint64LE(uint8View, offset) {
|
|
|
3285
3557
|
return getUint32LE(uint8View, offset) + getUint32LE(uint8View, offset + 4) * 4294967296;
|
|
3286
3558
|
}
|
|
3287
3559
|
var utf8Decoder = new TextDecoder;
|
|
3288
|
-
function decodeBuffer(uint8View,
|
|
3560
|
+
function decodeBuffer(uint8View, isUTF8) {
|
|
3289
3561
|
if (isSharedArrayBuffer(uint8View.buffer)) {
|
|
3290
3562
|
uint8View = new Uint8Array(uint8View);
|
|
3291
3563
|
}
|
|
@@ -3372,7 +3644,6 @@ async function readEntries(reader, centralDirectoryOffset, centralDirectorySize,
|
|
|
3372
3644
|
}
|
|
3373
3645
|
readEntryCursor += 46;
|
|
3374
3646
|
const data = allEntriesBuffer.subarray(readEntryCursor, readEntryCursor + rawEntry.fileNameLength + rawEntry.extraFieldLength + rawEntry.fileCommentLength);
|
|
3375
|
-
rawEntry.generalPurposeBitFlag & 2048;
|
|
3376
3647
|
rawEntry.nameBytes = data.slice(0, rawEntry.fileNameLength);
|
|
3377
3648
|
rawEntry.name = decodeBuffer(rawEntry.nameBytes);
|
|
3378
3649
|
const fileCommentStart = rawEntry.fileNameLength + rawEntry.extraFieldLength;
|
|
@@ -3425,7 +3696,7 @@ async function readEntries(reader, centralDirectoryOffset, centralDirectorySize,
|
|
|
3425
3696
|
index += 8;
|
|
3426
3697
|
}
|
|
3427
3698
|
}
|
|
3428
|
-
const nameField = rawEntry.extraFields.find((e2) => e2.id === 28789 && e2.data.length >= 6 && e2.data[0] === 1 && getUint32LE(e2.data, 1), crc.unsigned());
|
|
3699
|
+
const nameField = rawEntry.extraFields.find((e2) => e2.id === 28789 && e2.data.length >= 6 && e2.data[0] === 1 && getUint32LE(e2.data, 1), crc$1.unsigned(rawEntry.nameBytes));
|
|
3429
3700
|
if (nameField) {
|
|
3430
3701
|
rawEntry.fileName = decodeBuffer(nameField.data.slice(5));
|
|
3431
3702
|
}
|
|
@@ -3489,7 +3760,7 @@ async function readEntryDataAsArrayBuffer(reader, rawEntry) {
|
|
|
3489
3760
|
return isTypedArraySameAsArrayBuffer(dataView) ? dataView.buffer : dataView.slice().buffer;
|
|
3490
3761
|
}
|
|
3491
3762
|
const typedArrayOrBlob = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize);
|
|
3492
|
-
const result = await inflateRawAsync(typedArrayOrBlob
|
|
3763
|
+
const result = await inflateRawAsync(typedArrayOrBlob, rawEntry.uncompressedSize);
|
|
3493
3764
|
return result;
|
|
3494
3765
|
}
|
|
3495
3766
|
async function readEntryDataAsBlob(reader, rawEntry, type) {
|
|
@@ -3499,10 +3770,10 @@ async function readEntryDataAsBlob(reader, rawEntry, type) {
|
|
|
3499
3770
|
if (isBlob(typedArrayOrBlob2)) {
|
|
3500
3771
|
return typedArrayOrBlob2;
|
|
3501
3772
|
}
|
|
3502
|
-
return new Blob([typedArrayOrBlob2], { type });
|
|
3773
|
+
return new Blob([isSharedArrayBuffer(typedArrayOrBlob2.buffer) ? new Uint8Array(typedArrayOrBlob2) : typedArrayOrBlob2], { type });
|
|
3503
3774
|
}
|
|
3504
3775
|
const typedArrayOrBlob = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize);
|
|
3505
|
-
const result = await inflateRawAsync(typedArrayOrBlob
|
|
3776
|
+
const result = await inflateRawAsync(typedArrayOrBlob, rawEntry.uncompressedSize, type);
|
|
3506
3777
|
return result;
|
|
3507
3778
|
}
|
|
3508
3779
|
async function unzipRaw(source) {
|
|
@@ -3539,14 +3810,14 @@ async function unzip(source) {
|
|
|
3539
3810
|
};
|
|
3540
3811
|
}
|
|
3541
3812
|
|
|
3542
|
-
// ../serial/src/
|
|
3543
|
-
function downloadFileFromInternet(link) {
|
|
3544
|
-
return new Promise((resolve, reject) => {
|
|
3545
|
-
|
|
3813
|
+
// ../serial/src/VexDevice.ts
|
|
3814
|
+
async function downloadFileFromInternet(link) {
|
|
3815
|
+
return await new Promise((resolve, reject) => {
|
|
3816
|
+
const oReq = new XMLHttpRequest;
|
|
3546
3817
|
oReq.open("GET", link, true);
|
|
3547
3818
|
oReq.responseType = "arraybuffer";
|
|
3548
3819
|
oReq.onload = function(_oEvent) {
|
|
3549
|
-
|
|
3820
|
+
const arrayBuffer = oReq.response;
|
|
3550
3821
|
resolve(arrayBuffer);
|
|
3551
3822
|
};
|
|
3552
3823
|
oReq.onerror = function(oEvent) {
|
|
@@ -3555,11 +3826,37 @@ function downloadFileFromInternet(link) {
|
|
|
3555
3826
|
oReq.send(null);
|
|
3556
3827
|
});
|
|
3557
3828
|
}
|
|
3558
|
-
function
|
|
3559
|
-
return new Promise((resolve) => {
|
|
3829
|
+
async function sleepUntilAsync(f, timeout, interval = 20) {
|
|
3830
|
+
return await new Promise((resolve) => {
|
|
3831
|
+
let lastTime = new Date().getTime();
|
|
3832
|
+
let stopped = false;
|
|
3833
|
+
const stopper = setTimeout(() => {
|
|
3834
|
+
stopped = true;
|
|
3835
|
+
resolve(false);
|
|
3836
|
+
}, timeout);
|
|
3837
|
+
const checker = (val) => {
|
|
3838
|
+
if (stopped)
|
|
3839
|
+
return;
|
|
3840
|
+
if (val) {
|
|
3841
|
+
clearTimeout(stopper);
|
|
3842
|
+
resolve(true);
|
|
3843
|
+
} else if (new Date().getTime() - lastTime > interval) {
|
|
3844
|
+
lastTime = new Date().getTime();
|
|
3845
|
+
f().then(checker);
|
|
3846
|
+
} else
|
|
3847
|
+
setTimeout(() => {
|
|
3848
|
+
lastTime = new Date().getTime();
|
|
3849
|
+
f().then(checker);
|
|
3850
|
+
}, new Date().getTime() - lastTime);
|
|
3851
|
+
};
|
|
3852
|
+
f().then(checker);
|
|
3853
|
+
});
|
|
3854
|
+
}
|
|
3855
|
+
async function sleepUntil(f, timeout, interval = 20) {
|
|
3856
|
+
return await new Promise((resolve) => {
|
|
3560
3857
|
const timeWas = new Date().getTime();
|
|
3561
|
-
const wait = setInterval(
|
|
3562
|
-
if (
|
|
3858
|
+
const wait = setInterval(function() {
|
|
3859
|
+
if (f()) {
|
|
3563
3860
|
clearInterval(wait);
|
|
3564
3861
|
resolve(true);
|
|
3565
3862
|
} else if (new Date().getTime() - timeWas > timeout) {
|
|
@@ -3569,28 +3866,15 @@ function sleepUntil(f, timeout, interval = 20) {
|
|
|
3569
3866
|
}, interval);
|
|
3570
3867
|
});
|
|
3571
3868
|
}
|
|
3572
|
-
function sleep(ms) {
|
|
3573
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3574
|
-
}
|
|
3575
|
-
function shallowEqual(object1, object2) {
|
|
3576
|
-
const keys1 = Object.keys(object1);
|
|
3577
|
-
const keys2 = Object.keys(object2);
|
|
3578
|
-
if (keys1.length !== keys2.length) {
|
|
3579
|
-
return false;
|
|
3580
|
-
}
|
|
3581
|
-
for (let key of keys1) {
|
|
3582
|
-
if (object1[key] !== object2[key]) {
|
|
3583
|
-
return false;
|
|
3584
|
-
}
|
|
3585
|
-
}
|
|
3586
|
-
return true;
|
|
3869
|
+
async function sleep(ms) {
|
|
3870
|
+
return await new Promise((resolve) => setTimeout(resolve, ms));
|
|
3587
3871
|
}
|
|
3588
3872
|
|
|
3589
3873
|
class VexSerialDevice extends VexEventTarget {
|
|
3590
3874
|
connection;
|
|
3591
3875
|
defaultSerial;
|
|
3592
3876
|
get isConnected() {
|
|
3593
|
-
return this.connection ? this.connection.isConnected : false;
|
|
3877
|
+
return this.connection != null ? this.connection.isConnected : false;
|
|
3594
3878
|
}
|
|
3595
3879
|
get deviceType() {
|
|
3596
3880
|
return this.isConnected ? this.connection?.port?.getInfo().usbProductId : undefined;
|
|
@@ -3601,40 +3885,6 @@ class VexSerialDevice extends VexEventTarget {
|
|
|
3601
3885
|
}
|
|
3602
3886
|
}
|
|
3603
3887
|
|
|
3604
|
-
class V5SerialDeviceProxyHandler {
|
|
3605
|
-
device;
|
|
3606
|
-
parent;
|
|
3607
|
-
rootkey;
|
|
3608
|
-
constructor(device, parent, rootkey) {
|
|
3609
|
-
this.device = device;
|
|
3610
|
-
this.parent = parent;
|
|
3611
|
-
this.rootkey = rootkey;
|
|
3612
|
-
}
|
|
3613
|
-
get(target, key) {
|
|
3614
|
-
if (typeof target[key] === "object" && target[key] !== null && (typeof key !== "string" ? true : !key.startsWith("_"))) {
|
|
3615
|
-
return new Proxy(target[key], new V5SerialDeviceProxyHandler(this.device, this, key));
|
|
3616
|
-
} else {
|
|
3617
|
-
return target[key];
|
|
3618
|
-
}
|
|
3619
|
-
}
|
|
3620
|
-
set(target, key, value) {
|
|
3621
|
-
let oldValue = target[key];
|
|
3622
|
-
if (oldValue === value) {
|
|
3623
|
-
return true;
|
|
3624
|
-
} else if (typeof oldValue === "object" && typeof value === "object" && oldValue !== null && value !== null) {
|
|
3625
|
-
if (shallowEqual(oldValue, value))
|
|
3626
|
-
return true;
|
|
3627
|
-
}
|
|
3628
|
-
target[key] = value;
|
|
3629
|
-
this.parent?.childSet(this.rootkey, key, value);
|
|
3630
|
-
return true;
|
|
3631
|
-
}
|
|
3632
|
-
childSet(rootkey, subkey, value) {
|
|
3633
|
-
if (this.parent)
|
|
3634
|
-
this.parent.childSet(this.rootkey, rootkey + "." + subkey, value);
|
|
3635
|
-
}
|
|
3636
|
-
}
|
|
3637
|
-
|
|
3638
3888
|
class V5SerialDeviceState {
|
|
3639
3889
|
_instance;
|
|
3640
3890
|
_isFileTransferring = false;
|
|
@@ -3703,11 +3953,11 @@ class V5Brain {
|
|
|
3703
3953
|
(async () => {
|
|
3704
3954
|
if (this.state.brain.activeProgram === value)
|
|
3705
3955
|
return;
|
|
3706
|
-
|
|
3707
|
-
if (
|
|
3956
|
+
const conn = this.state._instance.connection;
|
|
3957
|
+
if (conn == null)
|
|
3708
3958
|
return;
|
|
3709
|
-
|
|
3710
|
-
if (fn)
|
|
3959
|
+
const fn = value === 0 ? await conn.stopProgram() : await conn.loadProgram(value);
|
|
3960
|
+
if (fn != null)
|
|
3711
3961
|
this.state.brain.activeProgram = value;
|
|
3712
3962
|
})();
|
|
3713
3963
|
}
|
|
@@ -3736,26 +3986,26 @@ class V5Brain {
|
|
|
3736
3986
|
return this.state.brain.uniqueId;
|
|
3737
3987
|
}
|
|
3738
3988
|
async getValue(key) {
|
|
3739
|
-
|
|
3989
|
+
const result = await this.state._instance.connection?.writeDataAsync(new ReadKeyValueH2DPacket(key));
|
|
3740
3990
|
return result instanceof ReadKeyValueReplyD2HPacket ? result.value : undefined;
|
|
3741
3991
|
}
|
|
3742
3992
|
async setValue(key, value) {
|
|
3743
|
-
|
|
3744
|
-
return result instanceof WriteKeyValueReplyD2HPacket
|
|
3993
|
+
const result = await this.state._instance.connection?.writeDataAsync(new WriteKeyValueH2DPacket(key, value));
|
|
3994
|
+
return result instanceof WriteKeyValueReplyD2HPacket;
|
|
3745
3995
|
}
|
|
3746
3996
|
async listFiles(vendor = 1 /* USER */) {
|
|
3747
|
-
|
|
3748
|
-
if (!conn)
|
|
3997
|
+
const conn = this.state._instance.connection;
|
|
3998
|
+
if (conn == null || !conn.isConnected)
|
|
3749
3999
|
return;
|
|
3750
|
-
|
|
4000
|
+
const result = await conn.writeDataAsync(new GetDirectoryFileCountH2DPacket(vendor));
|
|
3751
4001
|
if (!(result instanceof GetDirectoryFileCountReplyD2HPacket))
|
|
3752
4002
|
return;
|
|
3753
|
-
|
|
4003
|
+
const files = [];
|
|
3754
4004
|
for (let i = 0;i < result.count; i++) {
|
|
3755
|
-
|
|
4005
|
+
const result2 = await conn.writeDataAsync(new GetDirectoryEntryH2DPacket(i));
|
|
3756
4006
|
if (!(result2 instanceof GetDirectoryEntryReplyD2HPacket))
|
|
3757
4007
|
return;
|
|
3758
|
-
if (result2.file) {
|
|
4008
|
+
if (result2.file != null) {
|
|
3759
4009
|
files.push({
|
|
3760
4010
|
filename: result2.file.filename,
|
|
3761
4011
|
vendor,
|
|
@@ -3771,25 +4021,25 @@ class V5Brain {
|
|
|
3771
4021
|
return files;
|
|
3772
4022
|
}
|
|
3773
4023
|
async listProgram() {
|
|
3774
|
-
|
|
3775
|
-
if (!conn
|
|
4024
|
+
const conn = this.state._instance.connection;
|
|
4025
|
+
if (conn == null || !conn.isConnected)
|
|
3776
4026
|
return;
|
|
3777
|
-
|
|
4027
|
+
const files = await this.listFiles(1 /* USER */);
|
|
3778
4028
|
if (files === undefined)
|
|
3779
4029
|
return;
|
|
3780
|
-
|
|
3781
|
-
|
|
4030
|
+
const programList = [];
|
|
4031
|
+
const iniFiles = files.filter((file) => file?.filename.search(/.ini$/) > 0);
|
|
3782
4032
|
for (let i = 0;i < iniFiles.length; i++) {
|
|
3783
|
-
|
|
3784
|
-
if (
|
|
4033
|
+
const ini = iniFiles[i];
|
|
4034
|
+
if (ini.size === 0)
|
|
3785
4035
|
continue;
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
if (
|
|
4036
|
+
const programName = /(.+?)(\.[^.]*$|$)/.exec(ini.filename)?.[1] ?? "";
|
|
4037
|
+
const bin = files.filter((e) => e != null && e.filename === programName + ".bin")[0];
|
|
4038
|
+
if (bin == null || bin.timestamp === 0 || bin.size === 0)
|
|
3789
4039
|
continue;
|
|
3790
|
-
|
|
4040
|
+
const n = new Date;
|
|
3791
4041
|
n.setTime(1000 * bin.timestamp);
|
|
3792
|
-
|
|
4042
|
+
const program = {
|
|
3793
4043
|
name: programName,
|
|
3794
4044
|
binfile: bin.filename,
|
|
3795
4045
|
size: ini.size + bin.size,
|
|
@@ -3797,7 +4047,7 @@ class V5Brain {
|
|
|
3797
4047
|
time: n,
|
|
3798
4048
|
requestedSlot: -1
|
|
3799
4049
|
};
|
|
3800
|
-
|
|
4050
|
+
const result2 = await conn?.writeDataAsync(new GetProgramSlotInfoH2DPacket(1 /* USER */, program.binfile));
|
|
3801
4051
|
if (result2 instanceof GetProgramSlotInfoReplyD2HPacket) {
|
|
3802
4052
|
program.slot = result2.slot;
|
|
3803
4053
|
program.requestedSlot = result2.requestedSlot;
|
|
@@ -3807,8 +4057,8 @@ class V5Brain {
|
|
|
3807
4057
|
return programList;
|
|
3808
4058
|
}
|
|
3809
4059
|
async readFile(request, downloadTarget = 1 /* FILE_TARGET_QSPI */, progressCallback) {
|
|
3810
|
-
|
|
3811
|
-
if (!conn
|
|
4060
|
+
const conn = this.state._instance.connection;
|
|
4061
|
+
if (conn == null || !conn.isConnected)
|
|
3812
4062
|
return;
|
|
3813
4063
|
this.state._isFileTransferring = true;
|
|
3814
4064
|
let handle;
|
|
@@ -3818,16 +4068,15 @@ class V5Brain {
|
|
|
3818
4068
|
handle = request;
|
|
3819
4069
|
}
|
|
3820
4070
|
try {
|
|
3821
|
-
return conn.downloadFileToHost(handle, downloadTarget, progressCallback);
|
|
4071
|
+
return await conn.downloadFileToHost(handle, downloadTarget, progressCallback);
|
|
3822
4072
|
} catch (e) {
|
|
3823
|
-
throw e;
|
|
3824
|
-
} finally {
|
|
3825
4073
|
this.state._isFileTransferring = false;
|
|
4074
|
+
throw e;
|
|
3826
4075
|
}
|
|
3827
4076
|
}
|
|
3828
4077
|
async removeFile(request) {
|
|
3829
|
-
|
|
3830
|
-
if (!conn
|
|
4078
|
+
const conn = this.state._instance.connection;
|
|
4079
|
+
if (conn == null || !conn.isConnected)
|
|
3831
4080
|
return;
|
|
3832
4081
|
let vendor, filename;
|
|
3833
4082
|
if (typeof request === "string") {
|
|
@@ -3837,8 +4086,8 @@ class V5Brain {
|
|
|
3837
4086
|
vendor = request.vendor;
|
|
3838
4087
|
filename = request.filename;
|
|
3839
4088
|
}
|
|
3840
|
-
|
|
3841
|
-
|
|
4089
|
+
const result = await conn.writeDataAsync(new EraseFileH2DPacket(vendor, filename));
|
|
4090
|
+
const result2 = await conn.writeDataAsync(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */));
|
|
3842
4091
|
if (!(result instanceof EraseFileReplyD2HPacket))
|
|
3843
4092
|
return false;
|
|
3844
4093
|
if (!(result2 instanceof ExitFileTransferReplyD2HPacket))
|
|
@@ -3846,16 +4095,16 @@ class V5Brain {
|
|
|
3846
4095
|
return true;
|
|
3847
4096
|
}
|
|
3848
4097
|
async removeAllFiles() {
|
|
3849
|
-
|
|
3850
|
-
if (!conn
|
|
4098
|
+
const conn = this.state._instance.connection;
|
|
4099
|
+
if (conn == null || !conn.isConnected)
|
|
3851
4100
|
return;
|
|
3852
|
-
|
|
3853
|
-
return result instanceof FileClearUpReplyD2HPacket
|
|
4101
|
+
const result = await conn.writeDataAsync(new FileClearUpH2DPacket(1 /* USER */), 30000);
|
|
4102
|
+
return result instanceof FileClearUpReplyD2HPacket;
|
|
3854
4103
|
}
|
|
3855
4104
|
async uploadFirmware(publicUrl = "https://content.vexrobotics.com/vexos/public/V5/", usingVersion, progressCallback) {
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
if (!conn
|
|
4105
|
+
const device = this.state._instance;
|
|
4106
|
+
const conn = device.connection;
|
|
4107
|
+
if (conn == null || !conn.isConnected)
|
|
3859
4108
|
return;
|
|
3860
4109
|
const pcb = progressCallback ?? (() => {});
|
|
3861
4110
|
let vexos, bootBin, assertBin;
|
|
@@ -3863,7 +4112,7 @@ class V5Brain {
|
|
|
3863
4112
|
if (usingVersion === undefined) {
|
|
3864
4113
|
pcb("FETCH CATALOG", 0, 1);
|
|
3865
4114
|
const catalog = await downloadFileFromInternet(publicUrl + "catalog.txt");
|
|
3866
|
-
|
|
4115
|
+
const latestVersion = new TextDecoder().decode(catalog);
|
|
3867
4116
|
usingVersion = latestVersion;
|
|
3868
4117
|
pcb("FETCH CATALOG", 1, 1);
|
|
3869
4118
|
console.log("fetched catalog.txt", latestVersion);
|
|
@@ -3872,7 +4121,7 @@ class V5Brain {
|
|
|
3872
4121
|
vexos = await downloadFileFromInternet(publicUrl + usingVersion + ".vexos");
|
|
3873
4122
|
pcb("FETCH VEXOS", 1, 1);
|
|
3874
4123
|
pcb("UNZIP VEXOS", 0, 1);
|
|
3875
|
-
|
|
4124
|
+
const { entries } = await unzip(vexos);
|
|
3876
4125
|
bootBin = await entries[usingVersion + "/BOOT.bin"].arrayBuffer();
|
|
3877
4126
|
assertBin = await entries[usingVersion + "/assets.bin"].arrayBuffer();
|
|
3878
4127
|
pcb("UNZIP VEXOS", 1, 1);
|
|
@@ -3882,10 +4131,10 @@ class V5Brain {
|
|
|
3882
4131
|
try {
|
|
3883
4132
|
this.state._isFileTransferring = true;
|
|
3884
4133
|
pcb("FACTORY ENB BOOT", 0, 0);
|
|
3885
|
-
|
|
4134
|
+
const result = await conn.writeDataAsync(new FactoryEnableH2DPacket);
|
|
3886
4135
|
if (!(result instanceof FactoryEnableReplyD2HPacket))
|
|
3887
4136
|
return false;
|
|
3888
|
-
|
|
4137
|
+
const bootWriteRequest = {
|
|
3889
4138
|
filename: "null.bin",
|
|
3890
4139
|
vendor: 1 /* USER */,
|
|
3891
4140
|
loadAddress: USER_FLASH_USR_CODE_START,
|
|
@@ -3895,11 +4144,13 @@ class V5Brain {
|
|
|
3895
4144
|
autoRun: true,
|
|
3896
4145
|
linkedFile: undefined
|
|
3897
4146
|
};
|
|
3898
|
-
|
|
4147
|
+
const result2 = await conn.uploadFileToDevice(bootWriteRequest, (c, t) => {
|
|
4148
|
+
pcb("UPLOAD BOOT", c, t);
|
|
4149
|
+
});
|
|
3899
4150
|
if (!result2)
|
|
3900
4151
|
return false;
|
|
3901
4152
|
while (true) {
|
|
3902
|
-
|
|
4153
|
+
const result3 = await conn.writeDataAsync(new FactoryStatusH2DPacket, 1e4);
|
|
3903
4154
|
if (result3 instanceof FactoryStatusReplyD2HPacket) {
|
|
3904
4155
|
switch (result3.status) {
|
|
3905
4156
|
case 2:
|
|
@@ -3923,10 +4174,10 @@ class V5Brain {
|
|
|
3923
4174
|
await sleep(500);
|
|
3924
4175
|
}
|
|
3925
4176
|
pcb("FACTORY ENB ASSERT", 0, 0);
|
|
3926
|
-
|
|
4177
|
+
const result5 = await conn.writeDataAsync(new FactoryEnableH2DPacket);
|
|
3927
4178
|
if (!(result5 instanceof FactoryEnableReplyD2HPacket))
|
|
3928
4179
|
return false;
|
|
3929
|
-
|
|
4180
|
+
const assertWriteRequest = {
|
|
3930
4181
|
filename: "null.bin",
|
|
3931
4182
|
vendor: 1 /* USER */,
|
|
3932
4183
|
loadAddress: USER_FLASH_USR_CODE_START,
|
|
@@ -3936,11 +4187,13 @@ class V5Brain {
|
|
|
3936
4187
|
autoRun: true,
|
|
3937
4188
|
linkedFile: undefined
|
|
3938
4189
|
};
|
|
3939
|
-
|
|
4190
|
+
const result6 = await conn.uploadFileToDevice(assertWriteRequest, (c, t) => {
|
|
4191
|
+
pcb("UPLOAD ASSERT", c, t);
|
|
4192
|
+
});
|
|
3940
4193
|
if (!result6)
|
|
3941
4194
|
return false;
|
|
3942
4195
|
while (true) {
|
|
3943
|
-
|
|
4196
|
+
const result7 = await conn.writeDataAsync(new FactoryStatusH2DPacket, 1e4);
|
|
3944
4197
|
if (result7 instanceof FactoryStatusReplyD2HPacket) {
|
|
3945
4198
|
switch (result7.status) {
|
|
3946
4199
|
case 2:
|
|
@@ -3964,64 +4217,90 @@ class V5Brain {
|
|
|
3964
4217
|
await sleep(500);
|
|
3965
4218
|
}
|
|
3966
4219
|
} catch (e) {
|
|
3967
|
-
throw e;
|
|
3968
|
-
} finally {
|
|
3969
4220
|
this.state._isFileTransferring = false;
|
|
4221
|
+
throw e;
|
|
3970
4222
|
}
|
|
3971
4223
|
return true;
|
|
3972
4224
|
}
|
|
3973
4225
|
async uploadProgram(iniConfig, binFileBuf, coldFileBuf, progressCallback) {
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
if (!conn
|
|
4226
|
+
const device = this.state._instance;
|
|
4227
|
+
const conn = device.connection;
|
|
4228
|
+
if (conn == null || !conn.isConnected)
|
|
3977
4229
|
return;
|
|
3978
4230
|
this.state._isFileTransferring = true;
|
|
3979
4231
|
try {
|
|
3980
4232
|
if (device.isV5Controller) {
|
|
3981
4233
|
await sleep(250);
|
|
3982
|
-
if (!device.refresh())
|
|
4234
|
+
if (!await device.refresh())
|
|
3983
4235
|
return;
|
|
3984
4236
|
console.log("Transferring to download channel");
|
|
3985
|
-
|
|
4237
|
+
const p1 = await device.radio.changeChannel(1 /* DOWNLOAD */);
|
|
3986
4238
|
if (!p1)
|
|
3987
4239
|
return false;
|
|
3988
4240
|
await sleep(250);
|
|
3989
|
-
await
|
|
4241
|
+
await sleepUntilAsync(async () => await conn?.getSystemStatus(150) != null, 1e4, 200);
|
|
3990
4242
|
console.log("Transferred to download channel");
|
|
3991
4243
|
}
|
|
3992
|
-
|
|
3993
|
-
if (!p2)
|
|
4244
|
+
const p2 = await conn.uploadProgramToDevice(iniConfig, binFileBuf, coldFileBuf, progressCallback);
|
|
4245
|
+
if (!(p2 ?? false))
|
|
3994
4246
|
return false;
|
|
3995
4247
|
if (device.isV5Controller) {
|
|
3996
4248
|
if (!device.brain.isAvailable)
|
|
3997
4249
|
return false;
|
|
3998
4250
|
console.log("Transferring back to pit channel");
|
|
3999
|
-
|
|
4251
|
+
const p3 = await device.radio.changeChannel(0 /* PIT */);
|
|
4000
4252
|
if (!p3)
|
|
4001
4253
|
return false;
|
|
4002
4254
|
await sleep(250);
|
|
4003
|
-
await
|
|
4255
|
+
await sleepUntilAsync(async () => await conn?.getSystemStatus(150) != null, 1e4, 200);
|
|
4004
4256
|
console.log("All done");
|
|
4005
4257
|
}
|
|
4006
4258
|
return true;
|
|
4007
4259
|
} catch (e) {
|
|
4008
|
-
throw e;
|
|
4009
|
-
} finally {
|
|
4010
4260
|
this.state._isFileTransferring = false;
|
|
4261
|
+
throw e;
|
|
4011
4262
|
}
|
|
4012
4263
|
}
|
|
4013
4264
|
async writeFile(request, progressCallback) {
|
|
4014
4265
|
this.state._isFileTransferring = true;
|
|
4015
|
-
|
|
4016
|
-
if (!conn
|
|
4266
|
+
const conn = this.state._instance.connection;
|
|
4267
|
+
if (conn == null || !conn.isConnected)
|
|
4017
4268
|
return;
|
|
4018
4269
|
try {
|
|
4019
|
-
return conn.uploadFileToDevice(request, progressCallback);
|
|
4270
|
+
return await conn.uploadFileToDevice(request, progressCallback);
|
|
4020
4271
|
} catch (e) {
|
|
4021
|
-
throw e;
|
|
4022
|
-
} finally {
|
|
4023
4272
|
this.state._isFileTransferring = false;
|
|
4273
|
+
throw e;
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
async captureScreen(progressCallback) {
|
|
4277
|
+
const conn = this.state._instance.connection;
|
|
4278
|
+
if (conn == null || !conn.isConnected)
|
|
4279
|
+
return;
|
|
4280
|
+
await new Promise((resolve) => {
|
|
4281
|
+
conn.writeData(new ScreenCaptureH2DPacket(0), resolve);
|
|
4282
|
+
});
|
|
4283
|
+
const height = 272;
|
|
4284
|
+
const width = 480;
|
|
4285
|
+
const channels = 3;
|
|
4286
|
+
const messageWidth = 512;
|
|
4287
|
+
const messageChannels = 4;
|
|
4288
|
+
let buf = await conn?.downloadFileToHost({
|
|
4289
|
+
filename: "screen",
|
|
4290
|
+
vendor: 15 /* SYS */,
|
|
4291
|
+
loadAddress: 0,
|
|
4292
|
+
size: messageWidth * height * messageChannels
|
|
4293
|
+
}, 2 /* FILE_TARGET_CBUF */, progressCallback);
|
|
4294
|
+
if (buf == null)
|
|
4295
|
+
return;
|
|
4296
|
+
buf = buf.filter((_byte, i) => i % (messageWidth * messageChannels) < width * messageChannels).filter((_byte, i) => (i + 1) % messageChannels !== 0);
|
|
4297
|
+
for (let i = 0;i < buf.length; i += channels) {
|
|
4298
|
+
const px = buf.slice(i, i + channels).reverse();
|
|
4299
|
+
for (let j = 0;j < px.length; j++) {
|
|
4300
|
+
buf[i + j] = px[j];
|
|
4301
|
+
}
|
|
4024
4302
|
}
|
|
4303
|
+
return buf;
|
|
4025
4304
|
}
|
|
4026
4305
|
}
|
|
4027
4306
|
|
|
@@ -4095,17 +4374,20 @@ class V5SmartDevice {
|
|
|
4095
4374
|
this.state = state;
|
|
4096
4375
|
this.deviceIndex = index;
|
|
4097
4376
|
}
|
|
4377
|
+
getDeviceInfo() {
|
|
4378
|
+
return this.state.devices[this.deviceIndex];
|
|
4379
|
+
}
|
|
4098
4380
|
get isAvailable() {
|
|
4099
|
-
return this.
|
|
4381
|
+
return this.getDeviceInfo() !== undefined;
|
|
4100
4382
|
}
|
|
4101
4383
|
get port() {
|
|
4102
4384
|
return this.deviceIndex;
|
|
4103
4385
|
}
|
|
4104
4386
|
get type() {
|
|
4105
|
-
return this.
|
|
4387
|
+
return this.getDeviceInfo()?.type ?? 0 /* EMPTY */;
|
|
4106
4388
|
}
|
|
4107
4389
|
get version() {
|
|
4108
|
-
return this.
|
|
4390
|
+
return this.getDeviceInfo()?.version ?? 0;
|
|
4109
4391
|
}
|
|
4110
4392
|
}
|
|
4111
4393
|
|
|
@@ -4133,8 +4415,8 @@ class V5Radio {
|
|
|
4133
4415
|
return this.state.radio.latency;
|
|
4134
4416
|
}
|
|
4135
4417
|
async changeChannel(channel) {
|
|
4136
|
-
|
|
4137
|
-
return result instanceof FileControlReplyD2HPacket
|
|
4418
|
+
const result = await this.state._instance.connection?.writeDataAsync(new FileControlH2DPacket(1, channel));
|
|
4419
|
+
return result instanceof FileControlReplyD2HPacket;
|
|
4138
4420
|
}
|
|
4139
4421
|
}
|
|
4140
4422
|
|
|
@@ -4142,36 +4424,23 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4142
4424
|
autoReconnect = true;
|
|
4143
4425
|
autoRefresh = true;
|
|
4144
4426
|
pauseRefreshOnFileTransfer = true;
|
|
4145
|
-
_isDisconnecting = false;
|
|
4146
4427
|
_isReconnecting = false;
|
|
4147
|
-
|
|
4148
|
-
proxy = new V5SerialDeviceProxyHandler(this);
|
|
4149
|
-
state = new Proxy(new V5SerialDeviceState(this), this.proxy);
|
|
4428
|
+
state = new V5SerialDeviceState(this);
|
|
4150
4429
|
constructor(defaultSerial) {
|
|
4151
4430
|
super(defaultSerial);
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
if (this._refreshInterval)
|
|
4156
|
-
return;
|
|
4157
|
-
this._refreshInterval = setInterval(() => {
|
|
4158
|
-
if (this.autoRefresh) {
|
|
4431
|
+
let isLastRefreshComplete = true;
|
|
4432
|
+
setInterval(() => {
|
|
4433
|
+
if (this.autoRefresh && isLastRefreshComplete) {
|
|
4159
4434
|
if (!this.isConnected) {
|
|
4160
4435
|
this.state.brain.isAvailable = false;
|
|
4161
4436
|
return;
|
|
4162
4437
|
}
|
|
4163
4438
|
if (this.pauseRefreshOnFileTransfer && !this.state._isFileTransferring) {
|
|
4164
|
-
|
|
4439
|
+
isLastRefreshComplete = false;
|
|
4440
|
+
this.refresh().finally(() => isLastRefreshComplete = true);
|
|
4165
4441
|
}
|
|
4166
4442
|
}
|
|
4167
4443
|
}, 200);
|
|
4168
|
-
this._refreshInterval.unref?.();
|
|
4169
|
-
}
|
|
4170
|
-
stopAutoRefresh() {
|
|
4171
|
-
if (!this._refreshInterval)
|
|
4172
|
-
return;
|
|
4173
|
-
clearInterval(this._refreshInterval);
|
|
4174
|
-
this._refreshInterval = undefined;
|
|
4175
4444
|
}
|
|
4176
4445
|
get isV5Controller() {
|
|
4177
4446
|
return this.deviceType === 1283 /* V5_CONTROLLER */;
|
|
@@ -4183,9 +4452,9 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4183
4452
|
return [new V5Controller(this.state, 0), new V5Controller(this.state, 1)];
|
|
4184
4453
|
}
|
|
4185
4454
|
get devices() {
|
|
4186
|
-
|
|
4455
|
+
const rtn = [];
|
|
4187
4456
|
for (let i = 1;i <= this.state.devices.length; i++) {
|
|
4188
|
-
if (this.state.devices[i])
|
|
4457
|
+
if (this.state.devices[i] != null)
|
|
4189
4458
|
rtn.push(new V5SmartDevice(this.state, i));
|
|
4190
4459
|
}
|
|
4191
4460
|
return rtn;
|
|
@@ -4198,7 +4467,7 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4198
4467
|
}
|
|
4199
4468
|
set matchMode(value) {
|
|
4200
4469
|
(async () => {
|
|
4201
|
-
if (await this.connection?.setMatchMode(value))
|
|
4470
|
+
if (await this.connection?.setMatchMode(value) != null)
|
|
4202
4471
|
this.state.matchMode = value;
|
|
4203
4472
|
})();
|
|
4204
4473
|
}
|
|
@@ -4206,24 +4475,23 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4206
4475
|
return new V5Radio(this.state);
|
|
4207
4476
|
}
|
|
4208
4477
|
async mockTouch(x, y, press) {
|
|
4209
|
-
return await this.connection?.mockTouch(x, y, press)
|
|
4478
|
+
return !(await this.connection?.mockTouch(x, y, press) == null);
|
|
4210
4479
|
}
|
|
4211
4480
|
async connect(conn) {
|
|
4212
4481
|
if (this.isConnected)
|
|
4213
4482
|
return true;
|
|
4214
|
-
|
|
4215
|
-
if (conn?.isConnected) {
|
|
4483
|
+
if (conn != null && !conn.isConnected) {
|
|
4216
4484
|
if (await conn.query1() === null)
|
|
4217
4485
|
return false;
|
|
4218
4486
|
this.connection = conn;
|
|
4219
4487
|
} else {
|
|
4220
4488
|
let tryIdx = 0;
|
|
4221
4489
|
while (true) {
|
|
4222
|
-
|
|
4223
|
-
|
|
4490
|
+
const c = new V5SerialConnection(this.defaultSerial);
|
|
4491
|
+
const result = await c.open(tryIdx++, true);
|
|
4224
4492
|
if (result === undefined)
|
|
4225
4493
|
return false;
|
|
4226
|
-
if (result
|
|
4494
|
+
if (!result) {
|
|
4227
4495
|
await c.close();
|
|
4228
4496
|
continue;
|
|
4229
4497
|
}
|
|
@@ -4241,44 +4509,38 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4241
4509
|
return true;
|
|
4242
4510
|
}
|
|
4243
4511
|
async disconnect() {
|
|
4244
|
-
this.
|
|
4245
|
-
this.
|
|
4246
|
-
try {
|
|
4247
|
-
await this.connection?.close();
|
|
4248
|
-
this.connection = undefined;
|
|
4249
|
-
} finally {
|
|
4250
|
-
this._isDisconnecting = false;
|
|
4251
|
-
}
|
|
4512
|
+
await this.connection?.close();
|
|
4513
|
+
this.connection = undefined;
|
|
4252
4514
|
}
|
|
4253
4515
|
async reconnect(timeout = 0) {
|
|
4254
4516
|
if (this.isConnected)
|
|
4255
4517
|
return true;
|
|
4256
4518
|
if (timeout < 0)
|
|
4257
4519
|
return false;
|
|
4258
|
-
|
|
4520
|
+
const endTime = new Date().getTime() + timeout;
|
|
4259
4521
|
if (this._isReconnecting) {
|
|
4260
|
-
let
|
|
4522
|
+
let successBeforeTimeout;
|
|
4261
4523
|
do {
|
|
4262
|
-
|
|
4263
|
-
} while (timeout === 0 && !
|
|
4524
|
+
successBeforeTimeout = await sleepUntil(() => !this._isReconnecting, timeout === 0 ? 1000 : timeout);
|
|
4525
|
+
} while (timeout === 0 && !successBeforeTimeout);
|
|
4264
4526
|
if (this.isConnected)
|
|
4265
4527
|
return true;
|
|
4266
|
-
if (!
|
|
4528
|
+
if (!successBeforeTimeout)
|
|
4267
4529
|
return false;
|
|
4268
4530
|
}
|
|
4269
4531
|
this._isReconnecting = true;
|
|
4270
|
-
while (timeout === 0 || new Date().getTime()
|
|
4532
|
+
while (timeout === 0 || new Date().getTime() < endTime) {
|
|
4271
4533
|
let tryIdx = 0;
|
|
4272
4534
|
while (true) {
|
|
4273
|
-
|
|
4274
|
-
|
|
4535
|
+
const c = new V5SerialConnection(this.defaultSerial);
|
|
4536
|
+
const result = await c.open(tryIdx++, false);
|
|
4275
4537
|
if (result === undefined)
|
|
4276
4538
|
break;
|
|
4277
|
-
if (result
|
|
4539
|
+
if (!result) {
|
|
4278
4540
|
await c.close();
|
|
4279
4541
|
continue;
|
|
4280
4542
|
}
|
|
4281
|
-
|
|
4543
|
+
const result2 = await c.getSystemStatus(200);
|
|
4282
4544
|
if (result2 === null) {
|
|
4283
4545
|
await c.close();
|
|
4284
4546
|
continue;
|
|
@@ -4292,9 +4554,9 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4292
4554
|
}
|
|
4293
4555
|
if (this.isConnected)
|
|
4294
4556
|
break;
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
await
|
|
4557
|
+
const getPortCount = async () => (await this.defaultSerial.getPorts()).length;
|
|
4558
|
+
const portsCount = await getPortCount();
|
|
4559
|
+
await sleepUntilAsync(async () => await getPortCount() !== portsCount, 1000);
|
|
4298
4560
|
}
|
|
4299
4561
|
this._isReconnecting = false;
|
|
4300
4562
|
if (!this.isConnected)
|
|
@@ -4303,36 +4565,37 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4303
4565
|
return true;
|
|
4304
4566
|
}
|
|
4305
4567
|
async doAfterConnect() {
|
|
4306
|
-
if (
|
|
4568
|
+
if (this.connection == null)
|
|
4307
4569
|
return;
|
|
4570
|
+
console.log("doAfterConnect");
|
|
4308
4571
|
this.connection.on("disconnected", (_data) => {
|
|
4309
|
-
if (this.autoReconnect
|
|
4572
|
+
if (this.autoReconnect)
|
|
4310
4573
|
this.reconnect();
|
|
4311
4574
|
});
|
|
4312
4575
|
await this.refresh();
|
|
4313
4576
|
}
|
|
4314
4577
|
async refresh() {
|
|
4315
|
-
|
|
4316
|
-
if (
|
|
4578
|
+
const ssPacket = await this.connection?.getSystemStatus();
|
|
4579
|
+
if (ssPacket == null) {
|
|
4317
4580
|
this.state.brain.isAvailable = false;
|
|
4318
4581
|
return false;
|
|
4319
4582
|
}
|
|
4320
4583
|
this.state.brain.cpu0Version = ssPacket.cpu0Version;
|
|
4321
4584
|
this.state.brain.cpu1Version = ssPacket.cpu1Version;
|
|
4322
4585
|
this.state.brain.systemVersion = ssPacket.systemVersion;
|
|
4323
|
-
|
|
4586
|
+
const flags2 = ssPacket.sysflags[2];
|
|
4324
4587
|
this.state.controllers[0].isCharging = (flags2 & 128) !== 0;
|
|
4325
|
-
this.state.matchMode = flags2 & 32 ? "disabled" : flags2 & 64 ? "autonomous" : "driver";
|
|
4588
|
+
this.state.matchMode = (flags2 & 32) !== 0 ? "disabled" : (flags2 & 64) !== 0 ? "autonomous" : "driver";
|
|
4326
4589
|
this.state.isFieldControllerConnected = (flags2 & 16) !== 0;
|
|
4327
|
-
|
|
4590
|
+
const flags4 = ssPacket.sysflags[4];
|
|
4328
4591
|
this.state.brain.settings.usingLanguage = (flags4 & 240) >> 4;
|
|
4329
4592
|
this.state.brain.settings.isWhiteTheme = (flags4 & 4) !== 0;
|
|
4330
4593
|
this.state.brain.settings.isScreenReversed = (flags4 & 1) === 0;
|
|
4331
4594
|
this.state.brain.uniqueId = ssPacket.uniqueId;
|
|
4332
|
-
|
|
4333
|
-
if (
|
|
4595
|
+
const sfPacket = await this.connection?.getSystemFlags();
|
|
4596
|
+
if (sfPacket == null)
|
|
4334
4597
|
return false;
|
|
4335
|
-
|
|
4598
|
+
const flags5 = sfPacket.flags;
|
|
4336
4599
|
this.state.radio.isRadioData = (flags5 & Math.pow(2, 32 - 12)) !== 0;
|
|
4337
4600
|
this.state.brain.button.isDoublePressed = (flags5 & Math.pow(2, 32 - 14)) !== 0;
|
|
4338
4601
|
this.state.brain.battery.isCharging = (flags5 & Math.pow(2, 32 - 15)) !== 0;
|
|
@@ -4341,29 +4604,31 @@ class V5SerialDevice extends VexSerialDevice {
|
|
|
4341
4604
|
this.state.controllers[1].isAvailable = (flags5 & Math.pow(2, 32 - 19)) !== 0;
|
|
4342
4605
|
this.state.radio.isConnected = (flags5 & Math.pow(2, 32 - 22)) !== 0;
|
|
4343
4606
|
this.state.radio.isAvailable = (flags5 & Math.pow(2, 32 - 23)) !== 0;
|
|
4344
|
-
this.state.brain.battery.batteryPercent = sfPacket.battery
|
|
4607
|
+
this.state.brain.battery.batteryPercent = sfPacket.battery ?? 0;
|
|
4345
4608
|
this.state.controllers[0].isAvailable = this.state.radio.isConnected || this.state.controllers[0].isCharging;
|
|
4346
|
-
this.state.controllers[0].battery = sfPacket.controllerBatteryPercent
|
|
4347
|
-
this.state.controllers[1].battery = sfPacket.partnerControllerBatteryPercent
|
|
4609
|
+
this.state.controllers[0].battery = sfPacket.controllerBatteryPercent ?? 0;
|
|
4610
|
+
this.state.controllers[1].battery = sfPacket.partnerControllerBatteryPercent ?? 0;
|
|
4348
4611
|
this.state.brain.activeProgram = sfPacket.currentProgram;
|
|
4349
4612
|
this.state.brain.isAvailable = !this.isV5Controller || this.state.radio.isConnected;
|
|
4350
|
-
|
|
4351
|
-
if (
|
|
4613
|
+
const rdPacket = await this.connection?.getRadioStatus();
|
|
4614
|
+
if (rdPacket == null)
|
|
4352
4615
|
return false;
|
|
4353
4616
|
this.state.radio.channel = rdPacket.channel;
|
|
4354
4617
|
this.state.radio.latency = rdPacket.timeslot;
|
|
4355
4618
|
this.state.radio.signalQuality = rdPacket.quality;
|
|
4356
4619
|
this.state.radio.signalStrength = rdPacket.strength;
|
|
4357
|
-
|
|
4358
|
-
if (
|
|
4620
|
+
const dsPacket = await this.connection?.getDeviceStatus();
|
|
4621
|
+
if (dsPacket == null)
|
|
4359
4622
|
return false;
|
|
4360
4623
|
let missingPorts = this.state.devices.map((d) => d?.port).filter((p) => p !== undefined);
|
|
4361
4624
|
for (let i = 0;i < dsPacket.devices.length; i++) {
|
|
4362
|
-
|
|
4625
|
+
const device = dsPacket.devices[i];
|
|
4363
4626
|
this.state.devices[device.port] = device;
|
|
4364
4627
|
missingPorts = missingPorts.filter((p) => p !== device.port);
|
|
4365
4628
|
}
|
|
4366
|
-
missingPorts.forEach((port) =>
|
|
4629
|
+
missingPorts.forEach((port) => {
|
|
4630
|
+
this.state.devices[port] = undefined;
|
|
4631
|
+
});
|
|
4367
4632
|
return true;
|
|
4368
4633
|
}
|
|
4369
4634
|
}
|