@fdm-monster/server 2.0.6 → 2.0.8
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/.yarn/install-state.gz +0 -0
- package/RELEASE_NOTES.MD +31 -0
- package/dist/consoles/bambu-mqtt-diagnostic.console.js +565 -0
- package/dist/consoles/bambu-mqtt-diagnostic.console.js.map +1 -0
- package/dist/consoles/mock-bambu.server.js +114 -88
- package/dist/consoles/mock-bambu.server.js.map +1 -1
- package/dist/controllers/file-storage.controller.js +34 -14
- package/dist/controllers/file-storage.controller.js.map +1 -1
- package/dist/controllers/print-job.controller.js +33 -236
- package/dist/controllers/print-job.controller.js.map +1 -1
- package/dist/controllers/print-queue.controller.js +82 -17
- package/dist/controllers/print-queue.controller.js.map +1 -1
- package/dist/controllers/printer-files.controller.js +8 -2
- package/dist/controllers/printer-files.controller.js.map +1 -1
- package/dist/controllers/printer.controller.js +3 -3
- package/dist/controllers/printer.controller.js.map +1 -1
- package/dist/entities/print-job.entity.js.map +1 -1
- package/dist/server.constants.js +1 -1
- package/dist/services/bambu/bambu-ftp.adapter.js +13 -21
- package/dist/services/bambu/bambu-ftp.adapter.js.map +1 -1
- package/dist/services/bambu/bambu-mqtt.adapter.js +86 -32
- package/dist/services/bambu/bambu-mqtt.adapter.js.map +1 -1
- package/dist/services/bambu/bambu.client.js.map +1 -1
- package/dist/services/bambu.api.js +12 -24
- package/dist/services/bambu.api.js.map +1 -1
- package/dist/services/file-storage.service.js +11 -2
- package/dist/services/file-storage.service.js.map +1 -1
- package/dist/services/moonraker/moonraker.client.js +5 -17
- package/dist/services/moonraker/moonraker.client.js.map +1 -1
- package/dist/services/moonraker.api.js +3 -2
- package/dist/services/moonraker.api.js.map +1 -1
- package/dist/services/octoprint/octoprint.client.js +5 -17
- package/dist/services/octoprint/octoprint.client.js.map +1 -1
- package/dist/services/octoprint.api.js +3 -2
- package/dist/services/octoprint.api.js.map +1 -1
- package/dist/services/orm/print-job.service.js +55 -47
- package/dist/services/orm/print-job.service.js.map +1 -1
- package/dist/services/print-queue.service.js +90 -30
- package/dist/services/print-queue.service.js.map +1 -1
- package/dist/services/printer-api.interface.js +13 -0
- package/dist/services/printer-api.interface.js.map +1 -1
- package/dist/services/prusa-link/prusa-link.api.js +12 -22
- package/dist/services/prusa-link/prusa-link.api.js.map +1 -1
- package/dist/tasks/print-job-analysis.task.js.map +1 -1
- package/dist/utils/bgcode/bgcode-thumbnail.parser.js +50 -0
- package/dist/utils/bgcode/bgcode-thumbnail.parser.js.map +1 -0
- package/dist/utils/bgcode/bgcode.constants.js +57 -0
- package/dist/utils/bgcode/bgcode.constants.js.map +1 -0
- package/dist/utils/bgcode/bgcode.types.js +132 -0
- package/dist/utils/bgcode/bgcode.types.js.map +1 -0
- package/dist/utils/bgcode/bgcode.utils.js +288 -0
- package/dist/utils/bgcode/bgcode.utils.js.map +1 -0
- package/dist/utils/bgcode/heatshrink-decoder.js +172 -0
- package/dist/utils/bgcode/heatshrink-decoder.js.map +1 -0
- package/dist/utils/bgcode/png-encoder.js +76 -0
- package/dist/utils/bgcode/png-encoder.js.map +1 -0
- package/dist/utils/bgcode/qoi-decoder.js +141 -0
- package/dist/utils/bgcode/qoi-decoder.js.map +1 -0
- package/dist/utils/image-dimensions.js +62 -0
- package/dist/utils/image-dimensions.js.map +1 -0
- package/dist/utils/job-stats.util.js +79 -0
- package/dist/utils/job-stats.util.js.map +1 -0
- package/dist/utils/parsers/3mf.parser.js +39 -9
- package/dist/utils/parsers/3mf.parser.js.map +1 -1
- package/dist/utils/parsers/bgcode.parser.js +125 -144
- package/dist/utils/parsers/bgcode.parser.js.map +1 -1
- package/dist/utils/parsers/gcode.parser.js +13 -2
- package/dist/utils/parsers/gcode.parser.js.map +1 -1
- package/dist/utils/parsers/parser.types.js +6 -0
- package/dist/utils/parsers/parser.types.js.map +1 -0
- package/dist/utils/thumbnail.util.js +24 -0
- package/dist/utils/thumbnail.util.js.map +1 -0
- package/package.json +13 -10
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/RELEASE_NOTES.MD
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Develop
|
|
2
2
|
|
|
3
|
+
# FDM Monster 2.0.8
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Enhanced BGCode parser with MMU (Multi-Material Unit) support
|
|
8
|
+
- Detects MMU configurations by analyzing metadata fields for multiple values
|
|
9
|
+
- Parses filament data as arrays for MMU prints (per-extruder values)
|
|
10
|
+
- Provides `totalFilamentUsedGrams` for sum of all extruders in MMU mode
|
|
11
|
+
- Extracts thumbnails from BGCode files with QOI and Heatshrink decompression
|
|
12
|
+
- Supports comprehensive metadata including print times, temperatures, and layer information
|
|
13
|
+
|
|
14
|
+
## Refactor
|
|
15
|
+
|
|
16
|
+
- Refactored printer file upload system to use native streams across all printer API implementations (OctoPrint, Moonraker, PrusaLink, Bambu)
|
|
17
|
+
- Introduced Zod schema validation for upload file parameters with `UploadFileInput` type
|
|
18
|
+
- Added `getFileSize()` method to FileStorageService for consistent file size retrieval
|
|
19
|
+
- Improved memory efficiency for large file uploads by eliminating buffer conversions where possible
|
|
20
|
+
- OctoPrint: Native multipart/form-data streaming with `knownLength` optimization
|
|
21
|
+
- Moonraker: Native multipart/form-data streaming with `knownLength` optimization
|
|
22
|
+
- PrusaLink: Native streaming via `application/octet-stream` PUT requests
|
|
23
|
+
- Bambu: Native FTP streaming using basic-ftp's `uploadFrom()` with stream support
|
|
24
|
+
- Simplified print queue service by removing redundant comments and extracting printer assignment logic
|
|
25
|
+
|
|
26
|
+
# FDM Monster 2.0.7
|
|
27
|
+
|
|
28
|
+
## Fixes
|
|
29
|
+
|
|
30
|
+
- Improves Bambu FTP file handling and print commands (file paths corrected for listings and print commands)
|
|
31
|
+
- Handles initial Bambu printer status correctly by adding `pushall` MQTT command
|
|
32
|
+
- Simplifies thumbnail handling for files and jobs with structured thumbnails array including dimensions, format, and size
|
|
33
|
+
|
|
3
34
|
# FDM Monster 2.0.6
|
|
4
35
|
|
|
5
36
|
## Hotfix
|
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _mqtt = /*#__PURE__*/ _interop_require_default(require("mqtt"));
|
|
6
|
+
const _nodereadline = /*#__PURE__*/ _interop_require_wildcard(require("node:readline"));
|
|
7
|
+
const _nodefs = /*#__PURE__*/ _interop_require_wildcard(require("node:fs"));
|
|
8
|
+
const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
|
|
9
|
+
require("dotenv/config");
|
|
10
|
+
function _interop_require_default(obj) {
|
|
11
|
+
return obj && obj.__esModule ? obj : {
|
|
12
|
+
default: obj
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
16
|
+
if (typeof WeakMap !== "function") return null;
|
|
17
|
+
var cacheBabelInterop = new WeakMap();
|
|
18
|
+
var cacheNodeInterop = new WeakMap();
|
|
19
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
20
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
21
|
+
})(nodeInterop);
|
|
22
|
+
}
|
|
23
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
24
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
25
|
+
return obj;
|
|
26
|
+
}
|
|
27
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
28
|
+
return {
|
|
29
|
+
default: obj
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
33
|
+
if (cache && cache.has(obj)) {
|
|
34
|
+
return cache.get(obj);
|
|
35
|
+
}
|
|
36
|
+
var newObj = {
|
|
37
|
+
__proto__: null
|
|
38
|
+
};
|
|
39
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
40
|
+
for(var key in obj){
|
|
41
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
42
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
43
|
+
if (desc && (desc.get || desc.set)) {
|
|
44
|
+
Object.defineProperty(newObj, key, desc);
|
|
45
|
+
} else {
|
|
46
|
+
newObj[key] = obj[key];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
newObj.default = obj;
|
|
51
|
+
if (cache) {
|
|
52
|
+
cache.set(obj, newObj);
|
|
53
|
+
}
|
|
54
|
+
return newObj;
|
|
55
|
+
}
|
|
56
|
+
const host = process.argv[2] || process.env.BAMBU_HOST;
|
|
57
|
+
const accessCode = process.argv[3] || process.env.BAMBU_ACCESS_CODE;
|
|
58
|
+
const serial = process.argv[4] || process.env.BAMBU_SERIAL;
|
|
59
|
+
if (!host || !accessCode || !serial) {
|
|
60
|
+
console.error("Missing required configuration.");
|
|
61
|
+
console.error("");
|
|
62
|
+
console.error("Please provide configuration via .env file:");
|
|
63
|
+
console.error(" BAMBU_HOST=<printer_ip>");
|
|
64
|
+
console.error(" BAMBU_ACCESS_CODE=<8_character_access_code>");
|
|
65
|
+
console.error(" BAMBU_SERIAL=<printer_serial_number>");
|
|
66
|
+
console.error("");
|
|
67
|
+
console.error("Or via command line arguments:");
|
|
68
|
+
console.error(" yarn console:bambu-mqtt-diagnostic <host> <accessCode> <serial>");
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
const MQTT_PORT = 8883;
|
|
72
|
+
const MQTT_USERNAME = "bblp";
|
|
73
|
+
const RECONNECT_PERIOD = 5000;
|
|
74
|
+
const COMMAND_TIMEOUT = 10000;
|
|
75
|
+
let client = null;
|
|
76
|
+
let lastState = null;
|
|
77
|
+
let messageCount = 0;
|
|
78
|
+
let lastMessageTime = null;
|
|
79
|
+
let connectionStartTime = null;
|
|
80
|
+
let sequenceIdCounter = 10;
|
|
81
|
+
let isVerbose = false;
|
|
82
|
+
let dumpEnabled = true;
|
|
83
|
+
let dumpStream = null;
|
|
84
|
+
let dumpFilePath = null;
|
|
85
|
+
let dumpMessageCount = 0;
|
|
86
|
+
function initDumpFile() {
|
|
87
|
+
const timestamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
|
|
88
|
+
const dumpDir = _nodepath.join(process.cwd(), "mqtt-dumps");
|
|
89
|
+
if (!_nodefs.existsSync(dumpDir)) {
|
|
90
|
+
_nodefs.mkdirSync(dumpDir, {
|
|
91
|
+
recursive: true
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
dumpFilePath = _nodepath.join(dumpDir, `bambu-mqtt-dump-${timestamp}.jsonl`);
|
|
95
|
+
dumpStream = _nodefs.createWriteStream(dumpFilePath, {
|
|
96
|
+
flags: "a"
|
|
97
|
+
});
|
|
98
|
+
const header = {
|
|
99
|
+
_type: "session_start",
|
|
100
|
+
_timestamp: new Date().toISOString(),
|
|
101
|
+
host,
|
|
102
|
+
serial,
|
|
103
|
+
port: MQTT_PORT
|
|
104
|
+
};
|
|
105
|
+
dumpStream.write(JSON.stringify(header) + "\n");
|
|
106
|
+
log(`MQTT dump file: ${dumpFilePath}`, "INFO");
|
|
107
|
+
}
|
|
108
|
+
function writeToDump(direction, topic, payload) {
|
|
109
|
+
if (!dumpEnabled || !dumpStream) return;
|
|
110
|
+
dumpMessageCount++;
|
|
111
|
+
const entry = {
|
|
112
|
+
_seq: dumpMessageCount,
|
|
113
|
+
_timestamp: new Date().toISOString(),
|
|
114
|
+
_direction: direction,
|
|
115
|
+
topic,
|
|
116
|
+
payload
|
|
117
|
+
};
|
|
118
|
+
dumpStream.write(JSON.stringify(entry) + "\n");
|
|
119
|
+
}
|
|
120
|
+
function closeDumpFile() {
|
|
121
|
+
if (dumpStream) {
|
|
122
|
+
const footer = {
|
|
123
|
+
_type: "session_end",
|
|
124
|
+
_timestamp: new Date().toISOString(),
|
|
125
|
+
totalMessages: dumpMessageCount
|
|
126
|
+
};
|
|
127
|
+
dumpStream.write(JSON.stringify(footer) + "\n");
|
|
128
|
+
dumpStream.end();
|
|
129
|
+
dumpStream = null;
|
|
130
|
+
log(`Dump file closed: ${dumpFilePath} (${dumpMessageCount} messages)`, "INFO");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function log(message, level = "INFO") {
|
|
134
|
+
const timestamp = new Date().toISOString();
|
|
135
|
+
const prefix = `[${timestamp}] [${level}]`;
|
|
136
|
+
if (level === "ERROR") {
|
|
137
|
+
console.error(`${prefix} ${message}`);
|
|
138
|
+
} else if (level === "DEBUG") {
|
|
139
|
+
if (isVerbose) {
|
|
140
|
+
console.log(`${prefix} ${message}`);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
console.log(`${prefix} ${message}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function clearScreen() {
|
|
147
|
+
process.stdout.write("\x1B[2J\x1B[0f");
|
|
148
|
+
}
|
|
149
|
+
function formatTemp(current, target) {
|
|
150
|
+
if (current === undefined || current === null) return "N/A";
|
|
151
|
+
const curr = current.toFixed(1).padStart(6);
|
|
152
|
+
if (target !== undefined && target !== null && target > 0) {
|
|
153
|
+
return `${curr}C -> ${target.toFixed(1)}C`;
|
|
154
|
+
}
|
|
155
|
+
return `${curr}C`;
|
|
156
|
+
}
|
|
157
|
+
function formatDuration(ms) {
|
|
158
|
+
const seconds = Math.floor(ms / 1000);
|
|
159
|
+
const minutes = Math.floor(seconds / 60);
|
|
160
|
+
const hours = Math.floor(minutes / 60);
|
|
161
|
+
if (hours > 0) {
|
|
162
|
+
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
163
|
+
}
|
|
164
|
+
if (minutes > 0) {
|
|
165
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
166
|
+
}
|
|
167
|
+
return `${seconds}s`;
|
|
168
|
+
}
|
|
169
|
+
function formatTimeRemaining(minutes) {
|
|
170
|
+
if (minutes === undefined || minutes === null || minutes <= 0) return "N/A";
|
|
171
|
+
const hours = Math.floor(minutes / 60);
|
|
172
|
+
const mins = minutes % 60;
|
|
173
|
+
if (hours > 0) {
|
|
174
|
+
return `${hours}h ${mins}m`;
|
|
175
|
+
}
|
|
176
|
+
return `${mins}m`;
|
|
177
|
+
}
|
|
178
|
+
function createProgressBar(percent, width) {
|
|
179
|
+
const filled = Math.round(percent / 100 * width);
|
|
180
|
+
const empty = width - filled;
|
|
181
|
+
return "[" + "=".repeat(filled) + "-".repeat(empty) + "]";
|
|
182
|
+
}
|
|
183
|
+
function printDiagnostics() {
|
|
184
|
+
console.log("\n==================================================================");
|
|
185
|
+
console.log(" BAMBU MQTT DIAGNOSTIC ");
|
|
186
|
+
console.log("==================================================================");
|
|
187
|
+
console.log(` Host: ${host}:${MQTT_PORT}`);
|
|
188
|
+
console.log(` Serial: ${serial}`);
|
|
189
|
+
console.log(` Access Code: ${"*".repeat(accessCode?.length || 0)}`);
|
|
190
|
+
console.log(` Topic: device/${serial}/report`);
|
|
191
|
+
console.log("------------------------------------------------------------------");
|
|
192
|
+
console.log(` Connection: ${client?.connected ? "CONNECTED" : "DISCONNECTED"}`);
|
|
193
|
+
if (connectionStartTime) {
|
|
194
|
+
console.log(` Uptime: ${formatDuration(Date.now() - connectionStartTime.getTime())}`);
|
|
195
|
+
}
|
|
196
|
+
console.log(` Messages: ${messageCount}`);
|
|
197
|
+
if (lastMessageTime) {
|
|
198
|
+
console.log(` Last Message: ${lastMessageTime.toISOString()}`);
|
|
199
|
+
console.log(` Time Since: ${formatDuration(Date.now() - lastMessageTime.getTime())} ago`);
|
|
200
|
+
}
|
|
201
|
+
console.log("------------------------------------------------------------------");
|
|
202
|
+
console.log(` Dump Enabled: ${dumpEnabled ? "YES" : "NO"}`);
|
|
203
|
+
if (dumpFilePath) {
|
|
204
|
+
console.log(` Dump File: ${_nodepath.basename(dumpFilePath)}`);
|
|
205
|
+
console.log(` Dumped Msgs: ${dumpMessageCount}`);
|
|
206
|
+
}
|
|
207
|
+
console.log("==================================================================");
|
|
208
|
+
}
|
|
209
|
+
function printState() {
|
|
210
|
+
if (!lastState) {
|
|
211
|
+
console.log("\n Waiting for printer state...\n");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
console.log("\n------------------------------------------------------------------");
|
|
215
|
+
console.log(" PRINTER STATE ");
|
|
216
|
+
console.log("------------------------------------------------------------------");
|
|
217
|
+
const gcodeState = lastState.gcode_state || "UNKNOWN";
|
|
218
|
+
const gcodeFile = lastState.gcode_file || lastState.subtask_name || "None";
|
|
219
|
+
const progress = lastState.mc_percent;
|
|
220
|
+
const remaining = lastState.mc_remaining_time;
|
|
221
|
+
const stage = lastState.mc_print_stage || "N/A";
|
|
222
|
+
console.log(` Status: ${gcodeState}`);
|
|
223
|
+
console.log(` Stage: ${stage}`);
|
|
224
|
+
console.log(` File: ${gcodeFile.substring(0, 50)}`);
|
|
225
|
+
if (progress !== undefined && progress !== null) {
|
|
226
|
+
const progressBar = createProgressBar(progress, 30);
|
|
227
|
+
console.log(` Progress: ${progressBar} ${progress.toFixed(1)}%`);
|
|
228
|
+
}
|
|
229
|
+
if (remaining !== undefined && remaining !== null && remaining > 0) {
|
|
230
|
+
console.log(` Remaining: ${formatTimeRemaining(remaining)}`);
|
|
231
|
+
}
|
|
232
|
+
if (lastState.layer_num !== undefined && lastState.total_layer_num !== undefined) {
|
|
233
|
+
console.log(` Layer: ${lastState.layer_num} / ${lastState.total_layer_num}`);
|
|
234
|
+
}
|
|
235
|
+
console.log("------------------------------------------------------------------");
|
|
236
|
+
console.log(" TEMPERATURES");
|
|
237
|
+
console.log(` Nozzle: ${formatTemp(lastState.nozzle_temper, lastState.nozzle_target_temper)}`);
|
|
238
|
+
console.log(` Bed: ${formatTemp(lastState.bed_temper, lastState.bed_target_temper)}`);
|
|
239
|
+
if (lastState.chamber_temper !== undefined) {
|
|
240
|
+
console.log(` Chamber: ${formatTemp(lastState.chamber_temper, undefined)}`);
|
|
241
|
+
}
|
|
242
|
+
console.log("------------------------------------------------------------------");
|
|
243
|
+
console.log(" FANS");
|
|
244
|
+
console.log(` Heatbreak: ${lastState.heatbreak_fan_speed ?? "N/A"}`);
|
|
245
|
+
console.log(` Cooling: ${lastState.cooling_fan_speed ?? "N/A"}`);
|
|
246
|
+
console.log(` Big Fan 1: ${lastState.big_fan1_speed ?? "N/A"}`);
|
|
247
|
+
console.log(` Big Fan 2: ${lastState.big_fan2_speed ?? "N/A"}`);
|
|
248
|
+
if (lastState.spd_lvl !== undefined) {
|
|
249
|
+
const speedNames = {
|
|
250
|
+
1: "Silent",
|
|
251
|
+
2: "Standard",
|
|
252
|
+
3: "Sport",
|
|
253
|
+
4: "Ludicrous"
|
|
254
|
+
};
|
|
255
|
+
console.log("------------------------------------------------------------------");
|
|
256
|
+
console.log(` Speed Level: ${speedNames[lastState.spd_lvl] || lastState.spd_lvl} (${lastState.spd_mag ?? 100}%)`);
|
|
257
|
+
}
|
|
258
|
+
if (lastState.wifi_signal) {
|
|
259
|
+
console.log("------------------------------------------------------------------");
|
|
260
|
+
console.log(` WiFi Signal: ${lastState.wifi_signal}`);
|
|
261
|
+
}
|
|
262
|
+
if (lastState.print_error !== undefined && lastState.print_error !== 0) {
|
|
263
|
+
console.log("------------------------------------------------------------------");
|
|
264
|
+
console.log(` ERROR CODE: ${lastState.print_error}`);
|
|
265
|
+
}
|
|
266
|
+
if (lastState.lifecycle) {
|
|
267
|
+
console.log(` Lifecycle: ${lastState.lifecycle}`);
|
|
268
|
+
}
|
|
269
|
+
console.log("==================================================================");
|
|
270
|
+
}
|
|
271
|
+
function printMenu() {
|
|
272
|
+
console.log("\n------------------------------------------------------------------");
|
|
273
|
+
console.log(" COMMANDS");
|
|
274
|
+
console.log("------------------------------------------------------------------");
|
|
275
|
+
console.log(" [r] Refresh (send pushall) [s] Show state");
|
|
276
|
+
console.log(" [d] Show diagnostics [v] Toggle verbose mode");
|
|
277
|
+
console.log(" [c] Clear screen [j] Show raw JSON");
|
|
278
|
+
console.log(" [p] Pause print [u] Resume print");
|
|
279
|
+
console.log(" [x] Stop print [g] Send GCode");
|
|
280
|
+
console.log(" [h] Home X (G28 X) [t] Start print (file path)");
|
|
281
|
+
console.log(` [l] Toggle dump (${dumpEnabled ? "ON" : "OFF"}) [f] Show dump file path`);
|
|
282
|
+
console.log(" [q] Quit");
|
|
283
|
+
console.log("------------------------------------------------------------------");
|
|
284
|
+
process.stdout.write("\n> ");
|
|
285
|
+
}
|
|
286
|
+
async function sendPushall() {
|
|
287
|
+
if (!client?.connected) {
|
|
288
|
+
log("Cannot send pushall: not connected", "ERROR");
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const payload = {
|
|
292
|
+
pushing: {
|
|
293
|
+
sequence_id: sequenceIdCounter++,
|
|
294
|
+
command: "pushall",
|
|
295
|
+
version: 1,
|
|
296
|
+
push_target: 1
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
const topic = `device/${serial}/report`;
|
|
300
|
+
const message = JSON.stringify(payload);
|
|
301
|
+
log(`Sending pushall command (seq: ${payload.pushing.sequence_id})`, "DEBUG");
|
|
302
|
+
writeToDump("OUT", topic, payload);
|
|
303
|
+
client.publish(topic, message, {
|
|
304
|
+
qos: 0
|
|
305
|
+
}, (err)=>{
|
|
306
|
+
if (err) {
|
|
307
|
+
log(`Failed to send pushall: ${err.message}`, "ERROR");
|
|
308
|
+
} else {
|
|
309
|
+
log("Pushall command sent", "INFO");
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async function sendPrintCommand(command, params) {
|
|
314
|
+
if (!client?.connected) {
|
|
315
|
+
log("Cannot send command: not connected", "ERROR");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const payload = {
|
|
319
|
+
print: {
|
|
320
|
+
command,
|
|
321
|
+
sequence_id: sequenceIdCounter++,
|
|
322
|
+
...params
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
const topic = `device/${serial}/report`;
|
|
326
|
+
const message = JSON.stringify(payload);
|
|
327
|
+
log(`Sending command: ${command} (seq: ${payload.print.sequence_id})`, "DEBUG");
|
|
328
|
+
writeToDump("OUT", topic, payload);
|
|
329
|
+
client.publish(topic, message, {
|
|
330
|
+
qos: 0
|
|
331
|
+
}, (err)=>{
|
|
332
|
+
if (err) {
|
|
333
|
+
log(`Failed to send command: ${err.message}`, "ERROR");
|
|
334
|
+
} else {
|
|
335
|
+
log(`Command '${command}' sent`, "INFO");
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
async function sendGcode(gcode) {
|
|
340
|
+
await sendPrintCommand("gcode_line", {
|
|
341
|
+
param: gcode
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
function handleMessage(topic, message) {
|
|
345
|
+
messageCount++;
|
|
346
|
+
lastMessageTime = new Date();
|
|
347
|
+
try {
|
|
348
|
+
const payload = JSON.parse(message.toString());
|
|
349
|
+
writeToDump("IN", topic, payload);
|
|
350
|
+
if (payload.print?.command === "push_status") {
|
|
351
|
+
lastState = payload.print;
|
|
352
|
+
log(`State update received (gcode_state: ${lastState.gcode_state || "N/A"})`, "DEBUG");
|
|
353
|
+
} else if (payload.print) {
|
|
354
|
+
lastState = payload.print;
|
|
355
|
+
log(`Print data received`, "DEBUG");
|
|
356
|
+
} else if (payload.pushing) {
|
|
357
|
+
log(`Pushing response received (seq: ${payload.pushing.sequence_id})`, "DEBUG");
|
|
358
|
+
} else {
|
|
359
|
+
log(`Unknown message type received`, "DEBUG");
|
|
360
|
+
}
|
|
361
|
+
if (isVerbose) {
|
|
362
|
+
log(`Raw message: ${JSON.stringify(payload).substring(0, 200)}...`, "DEBUG");
|
|
363
|
+
}
|
|
364
|
+
} catch (error) {
|
|
365
|
+
log(`Failed to parse message: ${error}`, "ERROR");
|
|
366
|
+
writeToDump("IN", topic, {
|
|
367
|
+
_raw: message.toString(),
|
|
368
|
+
_error: String(error)
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function connect() {
|
|
373
|
+
const mqttUrl = `mqtts://${host}:${MQTT_PORT}`;
|
|
374
|
+
const topic = `device/${serial}/report`;
|
|
375
|
+
if (dumpEnabled) {
|
|
376
|
+
initDumpFile();
|
|
377
|
+
}
|
|
378
|
+
log(`Connecting to ${mqttUrl}...`, "INFO");
|
|
379
|
+
log(`Username: ${MQTT_USERNAME}`, "DEBUG");
|
|
380
|
+
log(`Topic: ${topic}`, "DEBUG");
|
|
381
|
+
client = _mqtt.default.connect(mqttUrl, {
|
|
382
|
+
username: MQTT_USERNAME,
|
|
383
|
+
password: accessCode,
|
|
384
|
+
reconnectPeriod: RECONNECT_PERIOD,
|
|
385
|
+
rejectUnauthorized: false,
|
|
386
|
+
connectTimeout: 30000
|
|
387
|
+
});
|
|
388
|
+
client.on("connect", ()=>{
|
|
389
|
+
connectionStartTime = new Date();
|
|
390
|
+
log("MQTT connected successfully", "INFO");
|
|
391
|
+
client.subscribe(topic, {
|
|
392
|
+
qos: 0
|
|
393
|
+
}, (err)=>{
|
|
394
|
+
if (err) {
|
|
395
|
+
log(`Failed to subscribe: ${err.message}`, "ERROR");
|
|
396
|
+
} else {
|
|
397
|
+
log(`Subscribed to ${topic}`, "INFO");
|
|
398
|
+
setTimeout(()=>{
|
|
399
|
+
sendPushall();
|
|
400
|
+
}, 500);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
client.on("message", (topic, message)=>{
|
|
405
|
+
handleMessage(topic, message);
|
|
406
|
+
});
|
|
407
|
+
client.on("error", (error)=>{
|
|
408
|
+
log(`MQTT error: ${error.message}`, "ERROR");
|
|
409
|
+
});
|
|
410
|
+
client.on("disconnect", ()=>{
|
|
411
|
+
log("MQTT disconnected", "WARN");
|
|
412
|
+
});
|
|
413
|
+
client.on("reconnect", ()=>{
|
|
414
|
+
log("MQTT attempting to reconnect...", "INFO");
|
|
415
|
+
});
|
|
416
|
+
client.on("close", ()=>{
|
|
417
|
+
log("MQTT connection closed", "WARN");
|
|
418
|
+
});
|
|
419
|
+
client.on("offline", ()=>{
|
|
420
|
+
log("MQTT client offline", "WARN");
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
const rl = _nodereadline.createInterface({
|
|
424
|
+
input: process.stdin,
|
|
425
|
+
output: process.stdout
|
|
426
|
+
});
|
|
427
|
+
async function handleCommand(input) {
|
|
428
|
+
const cmd = input.trim().toLowerCase();
|
|
429
|
+
switch(cmd){
|
|
430
|
+
case "r":
|
|
431
|
+
await sendPushall();
|
|
432
|
+
break;
|
|
433
|
+
case "s":
|
|
434
|
+
clearScreen();
|
|
435
|
+
printDiagnostics();
|
|
436
|
+
printState();
|
|
437
|
+
break;
|
|
438
|
+
case "d":
|
|
439
|
+
clearScreen();
|
|
440
|
+
printDiagnostics();
|
|
441
|
+
break;
|
|
442
|
+
case "v":
|
|
443
|
+
isVerbose = !isVerbose;
|
|
444
|
+
log(`Verbose mode: ${isVerbose ? "ON" : "OFF"}`, "INFO");
|
|
445
|
+
break;
|
|
446
|
+
case "c":
|
|
447
|
+
clearScreen();
|
|
448
|
+
break;
|
|
449
|
+
case "j":
|
|
450
|
+
console.log("\n--- RAW STATE JSON ---");
|
|
451
|
+
console.log(JSON.stringify(lastState, null, 2));
|
|
452
|
+
console.log("--- END JSON ---");
|
|
453
|
+
break;
|
|
454
|
+
case "p":
|
|
455
|
+
log("Sending pause command...", "INFO");
|
|
456
|
+
await sendPrintCommand("pause");
|
|
457
|
+
break;
|
|
458
|
+
case "u":
|
|
459
|
+
log("Sending resume command...", "INFO");
|
|
460
|
+
await sendPrintCommand("resume");
|
|
461
|
+
break;
|
|
462
|
+
case "x":
|
|
463
|
+
log("Sending stop command...", "INFO");
|
|
464
|
+
await sendPrintCommand("stop");
|
|
465
|
+
break;
|
|
466
|
+
case "h":
|
|
467
|
+
log("Sending G28 X (home X axis)...", "INFO");
|
|
468
|
+
await sendGcode("G28 X");
|
|
469
|
+
break;
|
|
470
|
+
case "t":
|
|
471
|
+
rl.question("Enter file path (e.g. cache/file.gcode): ", async (filePath)=>{
|
|
472
|
+
if (filePath.trim()) {
|
|
473
|
+
log(`Starting print: ${filePath.trim()}`, "INFO");
|
|
474
|
+
await sendPrintCommand("project_file", {
|
|
475
|
+
param: `Metadata/plate_1.gcode`,
|
|
476
|
+
url: `file:///sdcard/${filePath.trim()}`,
|
|
477
|
+
subtask_name: _nodepath.basename(filePath.trim()),
|
|
478
|
+
bed_leveling: true,
|
|
479
|
+
flow_cali: true,
|
|
480
|
+
vibration_cali: true,
|
|
481
|
+
layer_inspect: false,
|
|
482
|
+
use_ams: true
|
|
483
|
+
});
|
|
484
|
+
} else {
|
|
485
|
+
log("No file path entered", "WARN");
|
|
486
|
+
}
|
|
487
|
+
printMenu();
|
|
488
|
+
});
|
|
489
|
+
return;
|
|
490
|
+
case "g":
|
|
491
|
+
rl.question("Enter GCode: ", async (gcode)=>{
|
|
492
|
+
if (gcode.trim()) {
|
|
493
|
+
await sendGcode(gcode.trim());
|
|
494
|
+
}
|
|
495
|
+
printMenu();
|
|
496
|
+
});
|
|
497
|
+
return;
|
|
498
|
+
case "l":
|
|
499
|
+
dumpEnabled = !dumpEnabled;
|
|
500
|
+
if (dumpEnabled && !dumpStream) {
|
|
501
|
+
initDumpFile();
|
|
502
|
+
} else if (!dumpEnabled && dumpStream) {
|
|
503
|
+
closeDumpFile();
|
|
504
|
+
}
|
|
505
|
+
log(`MQTT dump: ${dumpEnabled ? "ENABLED" : "DISABLED"}`, "INFO");
|
|
506
|
+
break;
|
|
507
|
+
case "f":
|
|
508
|
+
if (dumpFilePath) {
|
|
509
|
+
console.log(`\nDump file: ${dumpFilePath}`);
|
|
510
|
+
console.log(`Messages dumped: ${dumpMessageCount}`);
|
|
511
|
+
} else {
|
|
512
|
+
console.log("\nNo dump file active.");
|
|
513
|
+
}
|
|
514
|
+
break;
|
|
515
|
+
case "q":
|
|
516
|
+
log("Disconnecting...", "INFO");
|
|
517
|
+
closeDumpFile();
|
|
518
|
+
if (client) {
|
|
519
|
+
client.end(false, {}, ()=>{
|
|
520
|
+
log("Disconnected. Goodbye!", "INFO");
|
|
521
|
+
process.exit(0);
|
|
522
|
+
});
|
|
523
|
+
} else {
|
|
524
|
+
process.exit(0);
|
|
525
|
+
}
|
|
526
|
+
return;
|
|
527
|
+
default:
|
|
528
|
+
if (cmd) {
|
|
529
|
+
log(`Unknown command: ${cmd}`, "WARN");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
printMenu();
|
|
533
|
+
}
|
|
534
|
+
rl.on("line", (input)=>{
|
|
535
|
+
handleCommand(input);
|
|
536
|
+
});
|
|
537
|
+
process.on("SIGINT", ()=>{
|
|
538
|
+
log("\nReceived SIGINT. Shutting down...", "INFO");
|
|
539
|
+
closeDumpFile();
|
|
540
|
+
if (client) {
|
|
541
|
+
client.end(false, {}, ()=>{
|
|
542
|
+
process.exit(0);
|
|
543
|
+
});
|
|
544
|
+
} else {
|
|
545
|
+
process.exit(0);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
process.on("SIGTERM", ()=>{
|
|
549
|
+
log("\nReceived SIGTERM. Shutting down...", "INFO");
|
|
550
|
+
closeDumpFile();
|
|
551
|
+
if (client) {
|
|
552
|
+
client.end(false, {}, ()=>{
|
|
553
|
+
process.exit(0);
|
|
554
|
+
});
|
|
555
|
+
} else {
|
|
556
|
+
process.exit(0);
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
console.log("BAMBU MQTT DIAGNOSTIC CONSOLE");
|
|
560
|
+
console.log("=============================");
|
|
561
|
+
console.log("");
|
|
562
|
+
connect();
|
|
563
|
+
printMenu();
|
|
564
|
+
|
|
565
|
+
//# sourceMappingURL=bambu-mqtt-diagnostic.console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/consoles/bambu-mqtt-diagnostic.console.ts"],"names":["host","process","argv","env","BAMBU_HOST","accessCode","BAMBU_ACCESS_CODE","serial","BAMBU_SERIAL","console","error","exit","MQTT_PORT","MQTT_USERNAME","RECONNECT_PERIOD","COMMAND_TIMEOUT","client","lastState","messageCount","lastMessageTime","connectionStartTime","sequenceIdCounter","isVerbose","dumpEnabled","dumpStream","dumpFilePath","dumpMessageCount","initDumpFile","timestamp","Date","toISOString","replaceAll","dumpDir","path","join","cwd","fs","existsSync","mkdirSync","recursive","createWriteStream","flags","header","_type","_timestamp","port","write","JSON","stringify","log","writeToDump","direction","topic","payload","entry","_seq","_direction","closeDumpFile","footer","totalMessages","end","message","level","prefix","clearScreen","stdout","formatTemp","current","target","undefined","curr","toFixed","padStart","formatDuration","ms","seconds","Math","floor","minutes","hours","formatTimeRemaining","mins","createProgressBar","percent","width","filled","round","empty","repeat","printDiagnostics","length","connected","now","getTime","basename","printState","gcodeState","gcode_state","gcodeFile","gcode_file","subtask_name","progress","mc_percent","remaining","mc_remaining_time","stage","mc_print_stage","substring","progressBar","layer_num","total_layer_num","nozzle_temper","nozzle_target_temper","bed_temper","bed_target_temper","chamber_temper","heatbreak_fan_speed","cooling_fan_speed","big_fan1_speed","big_fan2_speed","spd_lvl","speedNames","spd_mag","wifi_signal","print_error","lifecycle","printMenu","sendPushall","pushing","sequence_id","command","version","push_target","publish","qos","err","sendPrintCommand","params","print","sendGcode","gcode","param","handleMessage","parse","toString","_raw","_error","String","connect","mqttUrl","mqtt","username","password","reconnectPeriod","rejectUnauthorized","connectTimeout","on","subscribe","setTimeout","rl","readline","createInterface","input","stdin","output","handleCommand","cmd","trim","toLowerCase","question","filePath","url","bed_leveling","flow_cali","vibration_cali","layer_inspect","use_ams"],"mappings":";;;;6DAsBiC;sEACP;gEACN;kEACE;QACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGP,MAAMA,OAAOC,QAAQC,IAAI,CAAC,EAAE,IAAID,QAAQE,GAAG,CAACC,UAAU;AACtD,MAAMC,aAAaJ,QAAQC,IAAI,CAAC,EAAE,IAAID,QAAQE,GAAG,CAACG,iBAAiB;AACnE,MAAMC,SAASN,QAAQC,IAAI,CAAC,EAAE,IAAID,QAAQE,GAAG,CAACK,YAAY;AAE1D,IAAI,CAACR,QAAQ,CAACK,cAAc,CAACE,QAAQ;IACnCE,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdD,QAAQC,KAAK,CAAC;IACdT,QAAQU,IAAI,CAAC;AACf;AAEA,MAAMC,YAAY;AAClB,MAAMC,gBAAgB;AACtB,MAAMC,mBAAmB;AACzB,MAAMC,kBAAkB;AAGxB,IAAIC,SAA4B;AAChC,IAAIC,YAAiB;AACrB,IAAIC,eAAe;AACnB,IAAIC,kBAA+B;AACnC,IAAIC,sBAAmC;AACvC,IAAIC,oBAAoB;AACxB,IAAIC,YAAY;AAGhB,IAAIC,cAAc;AAClB,IAAIC,aAAoC;AACxC,IAAIC,eAA8B;AAClC,IAAIC,mBAAmB;AAGvB,SAASC;IACP,MAAMC,YAAY,IAAIC,OAAOC,WAAW,GAAGC,UAAU,CAAC,SAAS;IAC/D,MAAMC,UAAUC,UAAKC,IAAI,CAACjC,QAAQkC,GAAG,IAAI;IAGzC,IAAI,CAACC,QAAGC,UAAU,CAACL,UAAU;QAC3BI,QAAGE,SAAS,CAACN,SAAS;YAAEO,WAAW;QAAK;IAC1C;IAEAd,eAAeQ,UAAKC,IAAI,CAACF,SAAS,CAAC,gBAAgB,EAAEJ,UAAU,MAAM,CAAC;IACtEJ,aAAaY,QAAGI,iBAAiB,CAACf,cAAc;QAAEgB,OAAO;IAAI;IAG7D,MAAMC,SAAS;QACbC,OAAO;QACPC,YAAY,IAAIf,OAAOC,WAAW;QAClC9B;QACAO;QACAsC,MAAMjC;IACR;IACAY,WAAWsB,KAAK,CAACC,KAAKC,SAAS,CAACN,UAAU;IAE1CO,IAAI,CAAC,gBAAgB,EAAExB,cAAc,EAAE;AACzC;AAGA,SAASyB,YAAYC,SAAuB,EAAEC,KAAa,EAAEC,OAAY;IACvE,IAAI,CAAC9B,eAAe,CAACC,YAAY;IAEjCE;IACA,MAAM4B,QAAQ;QACZC,MAAM7B;QACNkB,YAAY,IAAIf,OAAOC,WAAW;QAClC0B,YAAYL;QACZC;QACAC;IACF;IAEA7B,WAAWsB,KAAK,CAACC,KAAKC,SAAS,CAACM,SAAS;AAC3C;AAGA,SAASG;IACP,IAAIjC,YAAY;QACd,MAAMkC,SAAS;YACbf,OAAO;YACPC,YAAY,IAAIf,OAAOC,WAAW;YAClC6B,eAAejC;QACjB;QACAF,WAAWsB,KAAK,CAACC,KAAKC,SAAS,CAACU,UAAU;QAC1ClC,WAAWoC,GAAG;QACdpC,aAAa;QACbyB,IAAI,CAAC,kBAAkB,EAAExB,aAAa,EAAE,EAAEC,iBAAiB,UAAU,CAAC,EAAE;IAC1E;AACF;AAGA,SAASuB,IAAIY,OAAe,EAAEC,QAA6C,MAAM;IAC/E,MAAMlC,YAAY,IAAIC,OAAOC,WAAW;IACxC,MAAMiC,SAAS,CAAC,CAAC,EAAEnC,UAAU,GAAG,EAAEkC,MAAM,CAAC,CAAC;IAC1C,IAAIA,UAAU,SAAS;QACrBrD,QAAQC,KAAK,CAAC,GAAGqD,OAAO,CAAC,EAAEF,SAAS;IACtC,OAAO,IAAIC,UAAU,SAAS;QAC5B,IAAIxC,WAAW;YACbb,QAAQwC,GAAG,CAAC,GAAGc,OAAO,CAAC,EAAEF,SAAS;QACpC;IACF,OAAO;QACLpD,QAAQwC,GAAG,CAAC,GAAGc,OAAO,CAAC,EAAEF,SAAS;IACpC;AACF;AAGA,SAASG;IACP/D,QAAQgE,MAAM,CAACnB,KAAK,CAAC;AACvB;AAGA,SAASoB,WAAWC,OAA2B,EAAEC,MAA0B;IACzE,IAAID,YAAYE,aAAaF,YAAY,MAAM,OAAO;IACtD,MAAMG,OAAOH,QAAQI,OAAO,CAAC,GAAGC,QAAQ,CAAC;IACzC,IAAIJ,WAAWC,aAAaD,WAAW,QAAQA,SAAS,GAAG;QACzD,OAAO,GAAGE,KAAK,KAAK,EAAEF,OAAOG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C;IACA,OAAO,GAAGD,KAAK,CAAC,CAAC;AACnB;AAGA,SAASG,eAAeC,EAAU;IAChC,MAAMC,UAAUC,KAAKC,KAAK,CAACH,KAAK;IAChC,MAAMI,UAAUF,KAAKC,KAAK,CAACF,UAAU;IACrC,MAAMI,QAAQH,KAAKC,KAAK,CAACC,UAAU;IACnC,IAAIC,QAAQ,GAAG;QACb,OAAO,GAAGA,MAAM,EAAE,EAAED,UAAU,GAAG,EAAE,EAAEH,UAAU,GAAG,CAAC,CAAC;IACtD;IACA,IAAIG,UAAU,GAAG;QACf,OAAO,GAAGA,QAAQ,EAAE,EAAEH,UAAU,GAAG,CAAC,CAAC;IACvC;IACA,OAAO,GAAGA,QAAQ,CAAC,CAAC;AACtB;AAGA,SAASK,oBAAoBF,OAA2B;IACtD,IAAIA,YAAYT,aAAaS,YAAY,QAAQA,WAAW,GAAG,OAAO;IACtE,MAAMC,QAAQH,KAAKC,KAAK,CAACC,UAAU;IACnC,MAAMG,OAAOH,UAAU;IACvB,IAAIC,QAAQ,GAAG;QACb,OAAO,GAAGA,MAAM,EAAE,EAAEE,KAAK,CAAC,CAAC;IAC7B;IACA,OAAO,GAAGA,KAAK,CAAC,CAAC;AACnB;AAGA,SAASC,kBAAkBC,OAAe,EAAEC,KAAa;IACvD,MAAMC,SAAST,KAAKU,KAAK,CAAC,AAACH,UAAU,MAAOC;IAC5C,MAAMG,QAAQH,QAAQC;IACtB,OAAO,MAAM,IAAIG,MAAM,CAACH,UAAU,IAAIG,MAAM,CAACD,SAAS;AACxD;AAGA,SAASE;IACPhF,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEjD,KAAK,CAAC,EAAEY,WAAW;IACpDH,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE1C,QAAQ;IACzCE,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE,IAAIuC,MAAM,CAACnF,YAAYqF,UAAU,IAAI;IACtEjF,QAAQwC,GAAG,CAAC,CAAC,yBAAyB,EAAE1C,OAAO,OAAO,CAAC;IACvDE,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEjC,QAAQ2E,YAAY,cAAc,gBAAgB;IACnF,IAAIvE,qBAAqB;QACvBX,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEwB,eAAe5C,KAAK+D,GAAG,KAAKxE,oBAAoByE,OAAO,KAAK;IAC/F;IACApF,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE/B,cAAc;IAC/C,IAAIC,iBAAiB;QACnBV,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE9B,gBAAgBW,WAAW,IAAI;QAChErB,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEwB,eAAe5C,KAAK+D,GAAG,KAAKzE,gBAAgB0E,OAAO,IAAI,IAAI,CAAC;IAC/F;IACApF,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE1B,cAAc,QAAQ,MAAM;IAC7D,IAAIE,cAAc;QAChBhB,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhB,UAAK6D,QAAQ,CAACrE,eAAe;QAC9DhB,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEvB,kBAAkB;IACrD;IACAjB,QAAQwC,GAAG,CAAC;AACd;AAGA,SAAS8C;IACP,IAAI,CAAC9E,WAAW;QACdR,QAAQwC,GAAG,CAAC;QACZ;IACF;IAEAxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IAGZ,MAAM+C,aAAa/E,UAAUgF,WAAW,IAAI;IAC5C,MAAMC,YAAYjF,UAAUkF,UAAU,IAAIlF,UAAUmF,YAAY,IAAI;IACpE,MAAMC,WAAWpF,UAAUqF,UAAU;IACrC,MAAMC,YAAYtF,UAAUuF,iBAAiB;IAC7C,MAAMC,QAAQxF,UAAUyF,cAAc,IAAI;IAE1CjG,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE+C,YAAY;IAC7CvF,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEwD,OAAO;IACxChG,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEiD,UAAUS,SAAS,CAAC,GAAG,KAAK;IAE7D,IAAIN,aAAahC,aAAagC,aAAa,MAAM;QAC/C,MAAMO,cAAc1B,kBAAkBmB,UAAU;QAChD5F,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE2D,YAAY,CAAC,EAAEP,SAAS9B,OAAO,CAAC,GAAG,CAAC,CAAC;IACxE;IAEA,IAAIgC,cAAclC,aAAakC,cAAc,QAAQA,YAAY,GAAG;QAClE9F,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAE+B,oBAAoBuB,YAAY;IACnE;IAGA,IAAItF,UAAU4F,SAAS,KAAKxC,aAAapD,UAAU6F,eAAe,KAAKzC,WAAW;QAChF5D,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAU4F,SAAS,CAAC,GAAG,EAAE5F,UAAU6F,eAAe,EAAE;IACvF;IAGArG,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEiB,WAAWjD,UAAU8F,aAAa,EAAE9F,UAAU+F,oBAAoB,GAAG;IACtGvG,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEiB,WAAWjD,UAAUgG,UAAU,EAAEhG,UAAUiG,iBAAiB,GAAG;IAChG,IAAIjG,UAAUkG,cAAc,KAAK9C,WAAW;QAC1C5D,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEiB,WAAWjD,UAAUkG,cAAc,EAAE9C,YAAY;IACpF;IAGA5D,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAUmG,mBAAmB,IAAI,OAAO;IACzE3G,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAUoG,iBAAiB,IAAI,OAAO;IACvE5G,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAUqG,cAAc,IAAI,OAAO;IACpE7G,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAUsG,cAAc,IAAI,OAAO;IAGpE,IAAItG,UAAUuG,OAAO,KAAKnD,WAAW;QACnC,MAAMoD,aAAqC;YAAE,GAAG;YAAU,GAAG;YAAY,GAAG;YAAS,GAAG;QAAY;QACpGhH,QAAQwC,GAAG,CAAC;QACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEwE,UAAU,CAACxG,UAAUuG,OAAO,CAAC,IAAIvG,UAAUuG,OAAO,CAAC,EAAE,EAAEvG,UAAUyG,OAAO,IAAI,IAAI,EAAE,CAAC;IACtH;IAGA,IAAIzG,UAAU0G,WAAW,EAAE;QACzBlH,QAAQwC,GAAG,CAAC;QACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAU0G,WAAW,EAAE;IAC1D;IAGA,IAAI1G,UAAU2G,WAAW,KAAKvD,aAAapD,UAAU2G,WAAW,KAAK,GAAG;QACtEnH,QAAQwC,GAAG,CAAC;QACZxC,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAU2G,WAAW,EAAE;IAC1D;IAGA,IAAI3G,UAAU4G,SAAS,EAAE;QACvBpH,QAAQwC,GAAG,CAAC,CAAC,kBAAkB,EAAEhC,UAAU4G,SAAS,EAAE;IACxD;IAEApH,QAAQwC,GAAG,CAAC;AACd;AAGA,SAAS6E;IACPrH,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC,CAAC,mBAAmB,EAAE1B,cAAc,OAAO,MAAM,mCAAmC,CAAC;IACjGd,QAAQwC,GAAG,CAAC;IACZxC,QAAQwC,GAAG,CAAC;IACZhD,QAAQgE,MAAM,CAACnB,KAAK,CAAC;AACvB;AAGA,eAAeiF;IACb,IAAI,CAAC/G,QAAQ2E,WAAW;QACtB1C,IAAI,sCAAsC;QAC1C;IACF;IAEA,MAAMI,UAAU;QACd2E,SAAS;YACPC,aAAa5G;YACb6G,SAAS;YACTC,SAAS;YACTC,aAAa;QACf;IACF;IAEA,MAAMhF,QAAQ,CAAC,OAAO,EAAE7C,OAAO,OAAO,CAAC;IACvC,MAAMsD,UAAUd,KAAKC,SAAS,CAACK;IAE/BJ,IAAI,CAAC,8BAA8B,EAAEI,QAAQ2E,OAAO,CAACC,WAAW,CAAC,CAAC,CAAC,EAAE;IACrE/E,YAAY,OAAOE,OAAOC;IAE1BrC,OAAOqH,OAAO,CAACjF,OAAOS,SAAS;QAAEyE,KAAK;IAAE,GAAG,CAACC;QAC1C,IAAIA,KAAK;YACPtF,IAAI,CAAC,wBAAwB,EAAEsF,IAAI1E,OAAO,EAAE,EAAE;QAChD,OAAO;YACLZ,IAAI,wBAAwB;QAC9B;IACF;AACF;AAGA,eAAeuF,iBAAiBN,OAAe,EAAEO,MAA4B;IAC3E,IAAI,CAACzH,QAAQ2E,WAAW;QACtB1C,IAAI,sCAAsC;QAC1C;IACF;IAEA,MAAMI,UAA+B;QACnCqF,OAAO;YACLR;YACAD,aAAa5G;YACb,GAAGoH,MAAM;QACX;IACF;IAEA,MAAMrF,QAAQ,CAAC,OAAO,EAAE7C,OAAO,OAAO,CAAC;IACvC,MAAMsD,UAAUd,KAAKC,SAAS,CAACK;IAE/BJ,IAAI,CAAC,iBAAiB,EAAEiF,QAAQ,OAAO,EAAE7E,QAAQqF,KAAK,CAACT,WAAW,CAAC,CAAC,CAAC,EAAE;IACvE/E,YAAY,OAAOE,OAAOC;IAE1BrC,OAAOqH,OAAO,CAACjF,OAAOS,SAAS;QAAEyE,KAAK;IAAE,GAAG,CAACC;QAC1C,IAAIA,KAAK;YACPtF,IAAI,CAAC,wBAAwB,EAAEsF,IAAI1E,OAAO,EAAE,EAAE;QAChD,OAAO;YACLZ,IAAI,CAAC,SAAS,EAAEiF,QAAQ,MAAM,CAAC,EAAE;QACnC;IACF;AACF;AAGA,eAAeS,UAAUC,KAAa;IACpC,MAAMJ,iBAAiB,cAAc;QAAEK,OAAOD;IAAM;AACtD;AAGA,SAASE,cAAc1F,KAAa,EAAES,OAAe;IACnD3C;IACAC,kBAAkB,IAAIU;IAEtB,IAAI;QACF,MAAMwB,UAAUN,KAAKgG,KAAK,CAAClF,QAAQmF,QAAQ;QAG3C9F,YAAY,MAAME,OAAOC;QAGzB,IAAIA,QAAQqF,KAAK,EAAER,YAAY,eAAe;YAE5CjH,YAAYoC,QAAQqF,KAAK;YACzBzF,IAAI,CAAC,oCAAoC,EAAEhC,UAAUgF,WAAW,IAAI,MAAM,CAAC,CAAC,EAAE;QAChF,OAAO,IAAI5C,QAAQqF,KAAK,EAAE;YACxBzH,YAAYoC,QAAQqF,KAAK;YACzBzF,IAAI,CAAC,mBAAmB,CAAC,EAAE;QAC7B,OAAO,IAAII,QAAQ2E,OAAO,EAAE;YAC1B/E,IAAI,CAAC,gCAAgC,EAAEI,QAAQ2E,OAAO,CAACC,WAAW,CAAC,CAAC,CAAC,EAAE;QACzE,OAAO;YACLhF,IAAI,CAAC,6BAA6B,CAAC,EAAE;QACvC;QAEA,IAAI3B,WAAW;YACb2B,IAAI,CAAC,aAAa,EAAEF,KAAKC,SAAS,CAACK,SAASsD,SAAS,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE;QACtE;IACF,EAAE,OAAOjG,OAAO;QACduC,IAAI,CAAC,yBAAyB,EAAEvC,OAAO,EAAE;QAEzCwC,YAAY,MAAME,OAAO;YAAE6F,MAAMpF,QAAQmF,QAAQ;YAAIE,QAAQC,OAAOzI;QAAO;IAC7E;AACF;AAGA,SAAS0I;IACP,MAAMC,UAAU,CAAC,QAAQ,EAAErJ,KAAK,CAAC,EAAEY,WAAW;IAC9C,MAAMwC,QAAQ,CAAC,OAAO,EAAE7C,OAAO,OAAO,CAAC;IAGvC,IAAIgB,aAAa;QACfI;IACF;IAEAsB,IAAI,CAAC,cAAc,EAAEoG,QAAQ,GAAG,CAAC,EAAE;IACnCpG,IAAI,CAAC,UAAU,EAAEpC,eAAe,EAAE;IAClCoC,IAAI,CAAC,OAAO,EAAEG,OAAO,EAAE;IAEvBpC,SAASsI,aAAI,CAACF,OAAO,CAACC,SAAS;QAC7BE,UAAU1I;QACV2I,UAAUnJ;QACVoJ,iBAAiB3I;QACjB4I,oBAAoB;QACpBC,gBAAgB;IAClB;IAEA3I,OAAO4I,EAAE,CAAC,WAAW;QACnBxI,sBAAsB,IAAIS;QAC1BoB,IAAI,+BAA+B;QAEnCjC,OAAQ6I,SAAS,CAACzG,OAAO;YAAEkF,KAAK;QAAE,GAAG,CAACC;YACpC,IAAIA,KAAK;gBACPtF,IAAI,CAAC,qBAAqB,EAAEsF,IAAI1E,OAAO,EAAE,EAAE;YAC7C,OAAO;gBACLZ,IAAI,CAAC,cAAc,EAAEG,OAAO,EAAE;gBAG9B0G,WAAW;oBACT/B;gBACF,GAAG;YACL;QACF;IACF;IAEA/G,OAAO4I,EAAE,CAAC,WAAW,CAACxG,OAAOS;QAC3BiF,cAAc1F,OAAOS;IACvB;IAEA7C,OAAO4I,EAAE,CAAC,SAAS,CAAClJ;QAClBuC,IAAI,CAAC,YAAY,EAAEvC,MAAMmD,OAAO,EAAE,EAAE;IACtC;IAEA7C,OAAO4I,EAAE,CAAC,cAAc;QACtB3G,IAAI,qBAAqB;IAC3B;IAEAjC,OAAO4I,EAAE,CAAC,aAAa;QACrB3G,IAAI,mCAAmC;IACzC;IAEAjC,OAAO4I,EAAE,CAAC,SAAS;QACjB3G,IAAI,0BAA0B;IAChC;IAEAjC,OAAO4I,EAAE,CAAC,WAAW;QACnB3G,IAAI,uBAAuB;IAC7B;AACF;AAGA,MAAM8G,KAAKC,cAASC,eAAe,CAAC;IAClCC,OAAOjK,QAAQkK,KAAK;IACpBC,QAAQnK,QAAQgE,MAAM;AACxB;AAGA,eAAeoG,cAAcH,KAAa;IACxC,MAAMI,MAAMJ,MAAMK,IAAI,GAAGC,WAAW;IAEpC,OAAQF;QACN,KAAK;YACH,MAAMvC;YACN;QAEF,KAAK;YACH/D;YACAyB;YACAM;YACA;QAEF,KAAK;YACH/B;YACAyB;YACA;QAEF,KAAK;YACHnE,YAAY,CAACA;YACb2B,IAAI,CAAC,cAAc,EAAE3B,YAAY,OAAO,OAAO,EAAE;YACjD;QAEF,KAAK;YACH0C;YACA;QAEF,KAAK;YACHvD,QAAQwC,GAAG,CAAC;YACZxC,QAAQwC,GAAG,CAACF,KAAKC,SAAS,CAAC/B,WAAW,MAAM;YAC5CR,QAAQwC,GAAG,CAAC;YACZ;QAEF,KAAK;YACHA,IAAI,4BAA4B;YAChC,MAAMuF,iBAAiB;YACvB;QAEF,KAAK;YACHvF,IAAI,6BAA6B;YACjC,MAAMuF,iBAAiB;YACvB;QAEF,KAAK;YACHvF,IAAI,2BAA2B;YAC/B,MAAMuF,iBAAiB;YACvB;QAEF,KAAK;YACHvF,IAAI,kCAAkC;YACtC,MAAM0F,UAAU;YAChB;QAEF,KAAK;YACHoB,GAAGU,QAAQ,CAAC,6CAA6C,OAAOC;gBAC9D,IAAIA,SAASH,IAAI,IAAI;oBACnBtH,IAAI,CAAC,gBAAgB,EAAEyH,SAASH,IAAI,IAAI,EAAE;oBAC1C,MAAM/B,iBAAiB,gBAAgB;wBACrCK,OAAO,CAAC,sBAAsB,CAAC;wBAC/B8B,KAAK,CAAC,eAAe,EAAED,SAASH,IAAI,IAAI;wBACxCnE,cAAcnE,UAAK6D,QAAQ,CAAC4E,SAASH,IAAI;wBACzCK,cAAc;wBACdC,WAAW;wBACXC,gBAAgB;wBAChBC,eAAe;wBACfC,SAAS;oBACX;gBACF,OAAO;oBACL/H,IAAI,wBAAwB;gBAC9B;gBACA6E;YACF;YACA;QAEF,KAAK;YACHiC,GAAGU,QAAQ,CAAC,iBAAiB,OAAO7B;gBAClC,IAAIA,MAAM2B,IAAI,IAAI;oBAChB,MAAM5B,UAAUC,MAAM2B,IAAI;gBAC5B;gBACAzC;YACF;YACA;QAEF,KAAK;YACHvG,cAAc,CAACA;YACf,IAAIA,eAAe,CAACC,YAAY;gBAC9BG;YACF,OAAO,IAAI,CAACJ,eAAeC,YAAY;gBACrCiC;YACF;YACAR,IAAI,CAAC,WAAW,EAAE1B,cAAc,YAAY,YAAY,EAAE;YAC1D;QAEF,KAAK;YACH,IAAIE,cAAc;gBAChBhB,QAAQwC,GAAG,CAAC,CAAC,aAAa,EAAExB,cAAc;gBAC1ChB,QAAQwC,GAAG,CAAC,CAAC,iBAAiB,EAAEvB,kBAAkB;YACpD,OAAO;gBACLjB,QAAQwC,GAAG,CAAC;YACd;YACA;QAEF,KAAK;YACHA,IAAI,oBAAoB;YACxBQ;YACA,IAAIzC,QAAQ;gBACVA,OAAO4C,GAAG,CAAC,OAAO,CAAC,GAAG;oBACpBX,IAAI,0BAA0B;oBAC9BhD,QAAQU,IAAI,CAAC;gBACf;YACF,OAAO;gBACLV,QAAQU,IAAI,CAAC;YACf;YACA;QAEF;YACE,IAAI2J,KAAK;gBACPrH,IAAI,CAAC,iBAAiB,EAAEqH,KAAK,EAAE;YACjC;IACJ;IAEAxC;AACF;AAGAiC,GAAGH,EAAE,CAAC,QAAQ,CAACM;IACbG,cAAcH;AAChB;AAGAjK,QAAQ2J,EAAE,CAAC,UAAU;IACnB3G,IAAI,uCAAuC;IAC3CQ;IACA,IAAIzC,QAAQ;QACVA,OAAO4C,GAAG,CAAC,OAAO,CAAC,GAAG;YACpB3D,QAAQU,IAAI,CAAC;QACf;IACF,OAAO;QACLV,QAAQU,IAAI,CAAC;IACf;AACF;AAEAV,QAAQ2J,EAAE,CAAC,WAAW;IACpB3G,IAAI,wCAAwC;IAC5CQ;IACA,IAAIzC,QAAQ;QACVA,OAAO4C,GAAG,CAAC,OAAO,CAAC,GAAG;YACpB3D,QAAQU,IAAI,CAAC;QACf;IACF,OAAO;QACLV,QAAQU,IAAI,CAAC;IACf;AACF;AAGAF,QAAQwC,GAAG,CAAC;AACZxC,QAAQwC,GAAG,CAAC;AACZxC,QAAQwC,GAAG,CAAC;AACZmG;AACAtB"}
|