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