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