@thermal-label/brother-ql-node 0.0.1 → 0.3.0
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/__tests__/discovery.test.js +141 -68
- package/dist/__tests__/discovery.test.js.map +1 -1
- package/dist/__tests__/integration/print.test.d.ts +2 -0
- package/dist/__tests__/integration/print.test.d.ts.map +1 -0
- package/dist/__tests__/integration/print.test.js +71 -0
- package/dist/__tests__/integration/print.test.js.map +1 -0
- package/dist/__tests__/printer.test.js +214 -208
- package/dist/__tests__/printer.test.js.map +1 -1
- package/dist/discovery.d.ts +39 -4
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +87 -14
- package/dist/discovery.js.map +1 -1
- package/dist/index.d.ts +3 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -6
- package/dist/index.js.map +1 -1
- package/dist/printer.d.ts +38 -15
- package/dist/printer.d.ts.map +1 -1
- package/dist/printer.js +108 -149
- package/dist/printer.js.map +1 -1
- package/package.json +7 -5
- package/dist/__tests__/errors.test.d.ts +0 -2
- package/dist/__tests__/errors.test.d.ts.map +0 -1
- package/dist/__tests__/errors.test.js +0 -20
- package/dist/__tests__/errors.test.js.map +0 -1
- package/dist/__tests__/integration/print-image.test.d.ts +0 -2
- package/dist/__tests__/integration/print-image.test.d.ts.map +0 -1
- package/dist/__tests__/integration/print-image.test.js +0 -22
- package/dist/__tests__/integration/print-image.test.js.map +0 -1
- package/dist/__tests__/integration/print-text.test.d.ts +0 -2
- package/dist/__tests__/integration/print-text.test.d.ts.map +0 -1
- package/dist/__tests__/integration/print-text.test.js +0 -25
- package/dist/__tests__/integration/print-text.test.js.map +0 -1
- package/dist/__tests__/integration/print-two-color.test.d.ts +0 -2
- package/dist/__tests__/integration/print-two-color.test.d.ts.map +0 -1
- package/dist/__tests__/integration/print-two-color.test.js +0 -28
- package/dist/__tests__/integration/print-two-color.test.js.map +0 -1
- package/dist/__tests__/integration/tcp.test.d.ts +0 -2
- package/dist/__tests__/integration/tcp.test.d.ts.map +0 -1
- package/dist/__tests__/integration/tcp.test.js +0 -20
- package/dist/__tests__/integration/tcp.test.js.map +0 -1
- package/dist/__tests__/tcp-transport.test.d.ts +0 -2
- package/dist/__tests__/tcp-transport.test.d.ts.map +0 -1
- package/dist/__tests__/tcp-transport.test.js +0 -115
- package/dist/__tests__/tcp-transport.test.js.map +0 -1
- package/dist/__tests__/usb-transport.test.d.ts +0 -2
- package/dist/__tests__/usb-transport.test.d.ts.map +0 -1
- package/dist/__tests__/usb-transport.test.js +0 -99
- package/dist/__tests__/usb-transport.test.js.map +0 -1
- package/dist/errors.d.ts +0 -8
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -15
- package/dist/errors.js.map +0 -1
- package/dist/status.d.ts +0 -2
- package/dist/status.d.ts.map +0 -1
- package/dist/status.js +0 -2
- package/dist/status.js.map +0 -1
- package/dist/transport.d.ts +0 -32
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -120
- package/dist/transport.js.map +0 -1
- package/dist/types.d.ts +0 -13
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
package/dist/discovery.js
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import usb from 'usb';
|
|
2
1
|
import { DEVICES, findDevice, isMassStorageMode } from '@thermal-label/brother-ql-core';
|
|
3
|
-
import {} from '
|
|
2
|
+
import { SerialTransport, TcpTransport, UsbTransport } from '@thermal-label/transport/node';
|
|
3
|
+
import * as usb from 'usb';
|
|
4
|
+
import { BrotherQLPrinter } from './printer.js';
|
|
4
5
|
const BROTHER_VID = 0x04f9;
|
|
5
|
-
|
|
6
|
+
async function readSerialNumber(device, idx) {
|
|
7
|
+
return new Promise(resolve => {
|
|
8
|
+
device.getStringDescriptor(idx, (err, value) => {
|
|
9
|
+
resolve(err ? undefined : value);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async function enumerateUsbDevices() {
|
|
6
14
|
const results = [];
|
|
7
|
-
for (const
|
|
8
|
-
const desc =
|
|
15
|
+
for (const device of usb.getDeviceList()) {
|
|
16
|
+
const desc = device.deviceDescriptor;
|
|
9
17
|
if (desc.idVendor !== BROTHER_VID)
|
|
10
18
|
continue;
|
|
11
19
|
if (isMassStorageMode(desc.idProduct)) {
|
|
@@ -14,18 +22,83 @@ export function listPrinters() {
|
|
|
14
22
|
'Hold the Editor Lite button until the LED turns off to switch to printer mode.');
|
|
15
23
|
continue;
|
|
16
24
|
}
|
|
17
|
-
const
|
|
18
|
-
if (!
|
|
25
|
+
const descriptor = findDevice(desc.idVendor, desc.idProduct);
|
|
26
|
+
if (!descriptor)
|
|
19
27
|
continue;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
device
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
let serialNumber;
|
|
29
|
+
if (desc.iSerialNumber) {
|
|
30
|
+
device.open();
|
|
31
|
+
try {
|
|
32
|
+
serialNumber = await readSerialNumber(device, desc.iSerialNumber);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
device.close();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
results.push({ device, descriptor, serialNumber });
|
|
39
|
+
}
|
|
40
|
+
return results;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* `PrinterDiscovery` implementation for Brother QL printers.
|
|
44
|
+
*
|
|
45
|
+
* `listPrinters()` enumerates USB and skips printers in Editor Lite
|
|
46
|
+
* mass-storage mode (a warning is logged — the user has to switch
|
|
47
|
+
* them out of Editor Lite manually). Network printers open via
|
|
48
|
+
* `openPrinter({ host, port })`; there is no mDNS implementation so
|
|
49
|
+
* `listPrinters()` never surfaces them.
|
|
50
|
+
*/
|
|
51
|
+
export class BrotherQLDiscovery {
|
|
52
|
+
family = 'brother-ql';
|
|
53
|
+
async listPrinters() {
|
|
54
|
+
const found = await enumerateUsbDevices();
|
|
55
|
+
return found.map(({ device, descriptor, serialNumber }) => ({
|
|
56
|
+
device: descriptor,
|
|
57
|
+
...(serialNumber === undefined ? {} : { serialNumber }),
|
|
25
58
|
transport: 'usb',
|
|
59
|
+
connectionId: `${String(device.busNumber)}.${String(device.deviceAddress)}`,
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
async openPrinter(options = {}) {
|
|
63
|
+
if (options.path !== undefined) {
|
|
64
|
+
const transport = await SerialTransport.open(options.path, options.baudRate);
|
|
65
|
+
// Serial (typically RFCOMM) carries no identifying metadata —
|
|
66
|
+
// fall back to the most capable descriptor with a serial
|
|
67
|
+
// transport tag. `getStatus()` still returns accurate
|
|
68
|
+
// detectedMedia regardless of which descriptor we attach.
|
|
69
|
+
const descriptor = Object.values(DEVICES).find(d => d.transports.includes('serial'));
|
|
70
|
+
/* v8 ignore next -- DEVICES always has QL_820NWB with 'serial' in transports */
|
|
71
|
+
if (!descriptor)
|
|
72
|
+
throw new Error('No serial-capable Brother QL descriptor found.');
|
|
73
|
+
return new BrotherQLPrinter(descriptor, transport, 'serial');
|
|
74
|
+
}
|
|
75
|
+
if (options.host !== undefined) {
|
|
76
|
+
const transport = await TcpTransport.connect(options.host, options.port);
|
|
77
|
+
const descriptor = Object.values(DEVICES).find(d => d.network !== 'none');
|
|
78
|
+
/* v8 ignore next -- DEVICES always has network-capable entries */
|
|
79
|
+
if (!descriptor)
|
|
80
|
+
throw new Error('No network-capable Brother QL descriptor found.');
|
|
81
|
+
return new BrotherQLPrinter(descriptor, transport, 'tcp');
|
|
82
|
+
}
|
|
83
|
+
const found = await enumerateUsbDevices();
|
|
84
|
+
const match = found.find(entry => {
|
|
85
|
+
if (options.vid !== undefined && entry.descriptor.vid !== options.vid)
|
|
86
|
+
return false;
|
|
87
|
+
if (options.pid !== undefined && entry.descriptor.pid !== options.pid)
|
|
88
|
+
return false;
|
|
89
|
+
if (options.serialNumber !== undefined && entry.serialNumber !== options.serialNumber)
|
|
90
|
+
return false;
|
|
91
|
+
return true;
|
|
26
92
|
});
|
|
93
|
+
if (!match)
|
|
94
|
+
throw new Error('No compatible Brother QL printer found.');
|
|
95
|
+
const transport = await UsbTransport.open(match.descriptor.vid, match.descriptor.pid);
|
|
96
|
+
return new BrotherQLPrinter(match.descriptor, transport, 'usb');
|
|
27
97
|
}
|
|
28
|
-
return results;
|
|
29
98
|
}
|
|
30
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Named export discovered by the unified `thermal-label-cli` — the CLI
|
|
101
|
+
* walks installed drivers looking for `mod.discovery`.
|
|
102
|
+
*/
|
|
103
|
+
export const discovery = new BrotherQLDiscovery();
|
|
31
104
|
//# sourceMappingURL=discovery.js.map
|
package/dist/discovery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export { UnsupportedOperationError, PrinterError } from './errors.js';
|
|
5
|
-
export type { Transport } from './transport.js';
|
|
6
|
-
export type { OpenOptions, PrinterInfo } from './types.js';
|
|
7
|
-
export { DEVICES, MEDIA, findDevice, findMedia, findMediaByWidth, encodeJob, renderText, renderImage, } from '@thermal-label/brother-ql-core';
|
|
8
|
-
export type { DeviceDescriptor, MediaDescriptor, PageData, PageOptions, JobOptions, PrinterStatus, LabelBitmap, RawImageData, MediaType, TextPrintOptions, ImagePrintOptions, } from '@thermal-label/brother-ql-core';
|
|
1
|
+
export { BrotherQLDiscovery, discovery } from './discovery.js';
|
|
2
|
+
export type { BrotherQLOpenOptions } from './discovery.js';
|
|
3
|
+
export { BrotherQLPrinter } from './printer.js';
|
|
9
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { BrotherQLPrinter
|
|
3
|
-
export { listPrinters } from './discovery.js';
|
|
4
|
-
export { UnsupportedOperationError, PrinterError } from './errors.js';
|
|
5
|
-
// Re-export core API so consumers only need one import
|
|
6
|
-
export { DEVICES, MEDIA, findDevice, findMedia, findMediaByWidth, encodeJob, renderText, renderImage, } from '@thermal-label/brother-ql-core';
|
|
1
|
+
export { BrotherQLDiscovery, discovery } from './discovery.js';
|
|
2
|
+
export { BrotherQLPrinter } from './printer.js';
|
|
7
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/printer.d.ts
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import type { BrotherQLDevice, BrotherQLPrintOptions, BrotherQLStatus, MediaDescriptor, PreviewOptions, PreviewResult, PrinterAdapter, RawImageData, Transport, TransportType } from '@thermal-label/brother-ql-core';
|
|
2
|
+
/**
|
|
3
|
+
* Node.js driver for Brother QL label printers.
|
|
4
|
+
*
|
|
5
|
+
* Implements `PrinterAdapter`. Callers get a printer instance from
|
|
6
|
+
* `discovery.openPrinter()` (USB or TCP) and interact solely through
|
|
7
|
+
* the adapter surface: `print(rgba, media?, options?)`, `createPreview`,
|
|
8
|
+
* `getStatus`, `close`.
|
|
9
|
+
*
|
|
10
|
+
* Multi-ink media (DK-22251) is handled transparently — when the
|
|
11
|
+
* resolved media carries a `palette`, the driver runs the bitmap
|
|
12
|
+
* library's `renderMultiPlaneImage()` internally before encoding.
|
|
13
|
+
*
|
|
14
|
+
* Orientation is auto-decided via `pickRotation`: landscape input on
|
|
15
|
+
* media tagged `defaultOrientation: 'horizontal'` rotates 90° CW so
|
|
16
|
+
* the visual reads along the tape feed direction. Override per-call
|
|
17
|
+
* with `options.rotate`.
|
|
18
|
+
*/
|
|
19
|
+
export declare class BrotherQLPrinter implements PrinterAdapter {
|
|
20
|
+
readonly family: "brother-ql";
|
|
21
|
+
readonly device: BrotherQLDevice;
|
|
22
|
+
readonly transportType: TransportType;
|
|
23
|
+
private readonly transport;
|
|
24
|
+
private lastStatus;
|
|
25
|
+
constructor(device: BrotherQLDevice, transport: Transport, transportType: TransportType);
|
|
26
|
+
get model(): string;
|
|
27
|
+
get connected(): boolean;
|
|
28
|
+
print(image: RawImageData, media?: MediaDescriptor, options?: BrotherQLPrintOptions): Promise<void>;
|
|
29
|
+
private writeChunked;
|
|
30
|
+
createPreview(image: RawImageData, options?: PreviewOptions): Promise<PreviewResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Poll the status endpoint until 32 bytes are available.
|
|
33
|
+
*
|
|
34
|
+
* The USB `transferAsync()` call resolves immediately with 0 bytes if
|
|
35
|
+
* the printer hasn't queued a response yet, so retry with a short
|
|
36
|
+
* delay up to `STATUS_POLL_ATTEMPTS` times.
|
|
37
|
+
*/
|
|
38
|
+
getStatus(): Promise<BrotherQLStatus>;
|
|
14
39
|
close(): Promise<void>;
|
|
15
40
|
}
|
|
16
|
-
export declare function openPrinter(options?: OpenOptions): Promise<BrotherQLPrinter>;
|
|
17
|
-
export declare function openPrinterTcp(host: string, port?: number): Promise<BrotherQLPrinter>;
|
|
18
41
|
//# sourceMappingURL=printer.d.ts.map
|
package/dist/printer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printer.d.ts","sourceRoot":"","sources":["../src/printer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"printer.d.ts","sourceRoot":"","sources":["../src/printer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,eAAe,EAEf,qBAAqB,EACrB,eAAe,EAEf,eAAe,EAEf,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACd,MAAM,gCAAgC,CAAC;AAoBxC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IACrD,QAAQ,CAAC,MAAM,eAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,UAAU,CAA8B;gBAEpC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa;IAMvF,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAEK,KAAK,CACT,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC;YAgCF,YAAY;IAU1B,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAWpF;;;;;;OAMG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAcrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
package/dist/printer.js
CHANGED
|
@@ -1,167 +1,126 @@
|
|
|
1
|
-
import { encodeJob,
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { DEFAULT_MEDIA, ROTATE_DIRECTION, STATUS_REQUEST, createPreviewOffline, encodeJob, flipHorizontal, parseStatus, pickRotation, renderImage, renderMultiPlaneImage, } from '@thermal-label/brother-ql-core';
|
|
2
|
+
import { MediaNotSpecifiedError } from '@thermal-label/contracts';
|
|
3
|
+
const STATUS_BYTE_COUNT = 32;
|
|
4
|
+
const STATUS_POLL_INTERVAL_MS = 150;
|
|
5
|
+
const STATUS_POLL_ATTEMPTS = 10;
|
|
6
|
+
// Empirical: a single libusb bulk transfer of an entire raster job (~50 kB
|
|
7
|
+
// uncompressed two-colour at 280 rows) reliably hangs the QL-820NWBc
|
|
8
|
+
// firmware mid-print. Chunking the OUT pipe to ~1 kB with a 20 ms gap
|
|
9
|
+
// keeps the printer's input ring buffer drained at roughly its raster
|
|
10
|
+
// processing rate (~175 bytes/ms at 80 mm/s feed). Adds about 1 s to a
|
|
11
|
+
// 50 kB job, which is negligible compared to physical print time.
|
|
12
|
+
//
|
|
13
|
+
// Python `brother_ql` users hit this less often because the typical CLI
|
|
14
|
+
// path writes through `/dev/usb/lpN` where the kernel's usblp driver
|
|
15
|
+
// provides flow control; libusb bypasses that.
|
|
16
|
+
const USB_CHUNK_SIZE = 1024;
|
|
17
|
+
const USB_CHUNK_DELAY_MS = 20;
|
|
18
|
+
/**
|
|
19
|
+
* Node.js driver for Brother QL label printers.
|
|
20
|
+
*
|
|
21
|
+
* Implements `PrinterAdapter`. Callers get a printer instance from
|
|
22
|
+
* `discovery.openPrinter()` (USB or TCP) and interact solely through
|
|
23
|
+
* the adapter surface: `print(rgba, media?, options?)`, `createPreview`,
|
|
24
|
+
* `getStatus`, `close`.
|
|
25
|
+
*
|
|
26
|
+
* Multi-ink media (DK-22251) is handled transparently — when the
|
|
27
|
+
* resolved media carries a `palette`, the driver runs the bitmap
|
|
28
|
+
* library's `renderMultiPlaneImage()` internally before encoding.
|
|
29
|
+
*
|
|
30
|
+
* Orientation is auto-decided via `pickRotation`: landscape input on
|
|
31
|
+
* media tagged `defaultOrientation: 'horizontal'` rotates 90° CW so
|
|
32
|
+
* the visual reads along the tape feed direction. Override per-call
|
|
33
|
+
* with `options.rotate`.
|
|
34
|
+
*/
|
|
9
35
|
export class BrotherQLPrinter {
|
|
36
|
+
family = 'brother-ql';
|
|
10
37
|
device;
|
|
38
|
+
transportType;
|
|
11
39
|
transport;
|
|
12
|
-
|
|
13
|
-
constructor(
|
|
14
|
-
this._transport = transport;
|
|
40
|
+
lastStatus;
|
|
41
|
+
constructor(device, transport, transportType) {
|
|
15
42
|
this.device = device;
|
|
16
|
-
this.transport =
|
|
43
|
+
this.transport = transport;
|
|
44
|
+
this.transportType = transportType;
|
|
17
45
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// The USB IN endpoint (transferAsync) resolves immediately with 0 bytes if
|
|
21
|
-
// the printer hasn't queued its response yet. Retry until we have 32 bytes.
|
|
22
|
-
for (let attempt = 0; attempt < 10; attempt++) {
|
|
23
|
-
await new Promise(r => setTimeout(r, 150));
|
|
24
|
-
const bytes = await this._transport.read(32);
|
|
25
|
-
if (bytes.length >= 32)
|
|
26
|
-
return parseStatus(bytes);
|
|
27
|
-
}
|
|
28
|
-
throw new Error('Printer did not respond to status request within 1.5s');
|
|
46
|
+
get model() {
|
|
47
|
+
return this.device.name;
|
|
29
48
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
await this._transport.write(data);
|
|
33
|
-
}
|
|
34
|
-
async printText(text, media, options) {
|
|
35
|
-
const { invert, scaleX, scaleY, ...pageOptions } = options ?? {};
|
|
36
|
-
// Scale so the label is roughly square: largest integer scale where neither the tape
|
|
37
|
-
// width (base.heightPx axis) nor the label length (base.widthPx axis) exceeds printAreaDots.
|
|
38
|
-
const base = renderText(text, { scaleX: 1, scaleY: 1 });
|
|
39
|
-
const autoScale = Math.max(1, Math.floor(media.printAreaDots / Math.max(base.widthPx, base.heightPx)));
|
|
40
|
-
const effectiveScaleY = scaleY ?? autoScale;
|
|
41
|
-
const effectiveScaleX = scaleX ?? autoScale;
|
|
42
|
-
const rawBitmap = renderText(text, {
|
|
43
|
-
...(invert !== undefined ? { invert } : {}),
|
|
44
|
-
scaleX: effectiveScaleX,
|
|
45
|
-
scaleY: effectiveScaleY,
|
|
46
|
-
});
|
|
47
|
-
const bitmap = rotateBitmap(rawBitmap, 270);
|
|
48
|
-
const page = {
|
|
49
|
-
bitmap,
|
|
50
|
-
media,
|
|
51
|
-
...(Object.keys(pageOptions).length > 0 ? { options: pageOptions } : {}),
|
|
52
|
-
};
|
|
53
|
-
await this.print([page]);
|
|
49
|
+
get connected() {
|
|
50
|
+
return this.transport.connected;
|
|
54
51
|
}
|
|
55
|
-
async
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
async print(image, media, options) {
|
|
53
|
+
const resolvedMedia = (media ?? this.lastStatus?.detectedMedia);
|
|
54
|
+
if (!resolvedMedia) {
|
|
55
|
+
throw new MediaNotSpecifiedError();
|
|
56
|
+
}
|
|
57
|
+
const rotate = pickRotation(image, resolvedMedia, ROTATE_DIRECTION, options?.rotate);
|
|
58
|
+
// Brother QL print head: pin 0 (the first pin in each raster row) sits
|
|
59
|
+
// on the right side of the printed face when the leading edge is held
|
|
60
|
+
// up. Mirror the rendered bitmap so the input image's x-axis matches
|
|
61
|
+
// the printed x-axis. Verified on QL-820NWBc + DK-22251.
|
|
62
|
+
let page;
|
|
63
|
+
if (resolvedMedia.palette) {
|
|
64
|
+
const { black, red } = renderMultiPlaneImage(image, {
|
|
65
|
+
palette: resolvedMedia.palette,
|
|
66
|
+
rotate,
|
|
67
|
+
});
|
|
68
|
+
page = {
|
|
69
|
+
bitmap: flipHorizontal(black),
|
|
70
|
+
redBitmap: flipHorizontal(red),
|
|
71
|
+
media: resolvedMedia,
|
|
72
|
+
};
|
|
60
73
|
}
|
|
61
74
|
else {
|
|
62
|
-
|
|
75
|
+
const bitmap = flipHorizontal(renderImage(image, { dither: true, rotate }));
|
|
76
|
+
page = { bitmap, media: resolvedMedia };
|
|
63
77
|
}
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
...(dither !== undefined ? { dither } : {}),
|
|
67
|
-
...(invert !== undefined ? { invert } : {}),
|
|
68
|
-
...(rotate !== undefined ? { rotate } : {}),
|
|
69
|
-
});
|
|
70
|
-
const bitmap = rotateBitmap(rawBitmap, 270);
|
|
71
|
-
const page = {
|
|
72
|
-
bitmap,
|
|
73
|
-
media,
|
|
74
|
-
...(Object.keys(pageOptions).length > 0 ? { options: pageOptions } : {}),
|
|
75
|
-
};
|
|
76
|
-
await this.print([page]);
|
|
78
|
+
const bytes = encodeJob([page]);
|
|
79
|
+
await this.writeChunked(bytes);
|
|
77
80
|
}
|
|
78
|
-
async
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
async writeChunked(bytes) {
|
|
82
|
+
for (let off = 0; off < bytes.length; off += USB_CHUNK_SIZE) {
|
|
83
|
+
const end = Math.min(off + USB_CHUNK_SIZE, bytes.length);
|
|
84
|
+
await this.transport.write(bytes.subarray(off, end));
|
|
85
|
+
if (end < bytes.length) {
|
|
86
|
+
await new Promise(r => setTimeout(r, USB_CHUNK_DELAY_MS));
|
|
87
|
+
}
|
|
82
88
|
}
|
|
83
|
-
const page = {
|
|
84
|
-
bitmap: black,
|
|
85
|
-
redBitmap: red,
|
|
86
|
-
media,
|
|
87
|
-
...(options !== undefined ? { options } : {}),
|
|
88
|
-
};
|
|
89
|
-
await this.print([page]);
|
|
90
|
-
}
|
|
91
|
-
async close() {
|
|
92
|
-
await this._transport.close();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
export async function openPrinter(options) {
|
|
96
|
-
const { vid = BROTHER_VID, pid } = options ?? {};
|
|
97
|
-
if (pid) {
|
|
98
|
-
const device = findDevice(vid, pid);
|
|
99
|
-
if (!device)
|
|
100
|
-
throw new Error(`Unknown device: ${vid.toString(16)}:${pid.toString(16)}`);
|
|
101
|
-
const transport = await UsbTransport.open(vid, pid);
|
|
102
|
-
return new BrotherQLPrinter(transport, device, 'usb');
|
|
103
89
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// We can't know the device descriptor from TCP alone — request status and detect
|
|
116
|
-
// Fall back to a generic QL-820NWB descriptor (most capable, verified by maintainer)
|
|
117
|
-
const status = await (async () => {
|
|
118
|
-
await transport.write(new Uint8Array([0x1b, 0x69, 0x53]));
|
|
119
|
-
return transport.read(32);
|
|
120
|
-
})();
|
|
121
|
-
const mediaWidthMm = status[10] ?? 0;
|
|
122
|
-
// Try to find a matching device by network capability
|
|
123
|
-
const { DEVICES } = await import('@thermal-label/brother-ql-core');
|
|
124
|
-
const networkDevice = Object.values(DEVICES).find(d => d.network !== 'none');
|
|
125
|
-
const device = networkDevice ?? DEVICES.QL_820NWB;
|
|
126
|
-
void mediaWidthMm; // may be used for smarter detection in future
|
|
127
|
-
return new BrotherQLPrinter(transport, device, 'tcp');
|
|
128
|
-
}
|
|
129
|
-
async function loadImageFile(filePath) {
|
|
130
|
-
try {
|
|
131
|
-
const canvas = await import('@napi-rs/canvas');
|
|
132
|
-
const img = await canvas.loadImage(filePath);
|
|
133
|
-
const canvasEl = canvas.createCanvas(img.width, img.height);
|
|
134
|
-
const ctx = canvasEl.getContext('2d');
|
|
135
|
-
ctx.drawImage(img, 0, 0);
|
|
136
|
-
const imageData = ctx.getImageData(0, 0, img.width, img.height);
|
|
137
|
-
return {
|
|
138
|
-
width: img.width,
|
|
139
|
-
height: img.height,
|
|
140
|
-
data: new Uint8Array(imageData.data.buffer),
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
throw new Error('Cannot load image file: install @napi-rs/canvas for image file support, ' +
|
|
145
|
-
'or pass a pre-decoded RawImageData to print().');
|
|
90
|
+
createPreview(image, options) {
|
|
91
|
+
const override = options?.media;
|
|
92
|
+
const detected = this.lastStatus?.detectedMedia;
|
|
93
|
+
if (override)
|
|
94
|
+
return Promise.resolve(createPreviewOffline(image, override));
|
|
95
|
+
if (detected)
|
|
96
|
+
return Promise.resolve(createPreviewOffline(image, detected));
|
|
97
|
+
return Promise.resolve({
|
|
98
|
+
...createPreviewOffline(image, DEFAULT_MEDIA),
|
|
99
|
+
assumed: true,
|
|
100
|
+
});
|
|
146
101
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Poll the status endpoint until 32 bytes are available.
|
|
104
|
+
*
|
|
105
|
+
* The USB `transferAsync()` call resolves immediately with 0 bytes if
|
|
106
|
+
* the printer hasn't queued a response yet, so retry with a short
|
|
107
|
+
* delay up to `STATUS_POLL_ATTEMPTS` times.
|
|
108
|
+
*/
|
|
109
|
+
async getStatus() {
|
|
110
|
+
await this.transport.write(STATUS_REQUEST);
|
|
111
|
+
for (let attempt = 0; attempt < STATUS_POLL_ATTEMPTS; attempt++) {
|
|
112
|
+
await new Promise(r => setTimeout(r, STATUS_POLL_INTERVAL_MS));
|
|
113
|
+
const bytes = await this.transport.read(STATUS_BYTE_COUNT);
|
|
114
|
+
if (bytes.length >= STATUS_BYTE_COUNT) {
|
|
115
|
+
const status = parseStatus(bytes);
|
|
116
|
+
this.lastStatus = status;
|
|
117
|
+
return status;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw new Error('Printer did not respond to status request within 1.5s');
|
|
161
121
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
'or pass a pre-decoded RawImageData to print().');
|
|
122
|
+
async close() {
|
|
123
|
+
await this.transport.close();
|
|
165
124
|
}
|
|
166
125
|
}
|
|
167
126
|
//# sourceMappingURL=printer.js.map
|
package/dist/printer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printer.js","sourceRoot":"","sources":["../src/printer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"printer.js","sourceRoot":"","sources":["../src/printer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,WAAW,EACX,qBAAqB,GACtB,MAAM,gCAAgC,CAAC;AAgBxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,uBAAuB,GAAG,GAAG,CAAC;AACpC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,2EAA2E;AAC3E,qEAAqE;AACrE,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,kEAAkE;AAClE,EAAE;AACF,wEAAwE;AACxE,qEAAqE;AACrE,+CAA+C;AAC/C,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,gBAAgB;IAClB,MAAM,GAAG,YAAqB,CAAC;IAC/B,MAAM,CAAkB;IACxB,aAAa,CAAgB;IAErB,SAAS,CAAY;IAC9B,UAAU,CAA8B;IAEhD,YAAY,MAAuB,EAAE,SAAoB,EAAE,aAA4B;QACrF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,KAAK,CACT,KAAmB,EACnB,KAAuB,EACvB,OAA+B;QAE/B,MAAM,aAAa,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,aAAa,CAA+B,CAAC;QAC9F,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,sBAAsB,EAAE,CAAC;QACrC,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAErF,uEAAuE;QACvE,sEAAsE;QACtE,qEAAqE;QACrE,yDAAyD;QACzD,IAAI,IAAc,CAAC;QACnB,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC1B,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,qBAAqB,CAAC,KAAK,EAAE;gBAClD,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,MAAM;aACP,CAAyC,CAAC;YAC3C,IAAI,GAAG;gBACL,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC;gBAC7B,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC;gBAC9B,KAAK,EAAE,aAAa;aACrB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAC5E,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QAC1C,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,KAAiB;QAC1C,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACzD,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YACrD,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa,CAAC,KAAmB,EAAE,OAAwB;QACzD,MAAM,QAAQ,GAAG,OAAO,EAAE,KAAmC,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,aAA2C,CAAC;QAC9E,IAAI,QAAQ;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5E,IAAI,QAAQ;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5E,OAAO,OAAO,CAAC,OAAO,CAAC;YACrB,GAAG,oBAAoB,CAAC,KAAK,EAAE,aAAa,CAAC;YAC7C,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC3C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,oBAAoB,EAAE,OAAO,EAAE,EAAE,CAAC;YAChE,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,MAAM,IAAI,iBAAiB,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;gBACzB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thermal-label/brother-ql-node",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Node.js USB and TCP driver for Brother QL label printers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"brother",
|
|
@@ -45,17 +45,19 @@
|
|
|
45
45
|
},
|
|
46
46
|
"sideEffects": false,
|
|
47
47
|
"main": "./dist/index.js",
|
|
48
|
-
"types": "./
|
|
48
|
+
"types": "./dist/index.d.ts",
|
|
49
49
|
"exports": {
|
|
50
50
|
".": {
|
|
51
51
|
"import": "./dist/index.js",
|
|
52
|
-
"types": "./
|
|
52
|
+
"types": "./dist/index.d.ts"
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@mbtech-nl/bitmap": "^
|
|
56
|
+
"@mbtech-nl/bitmap": "^1.2.1",
|
|
57
|
+
"@thermal-label/contracts": "^0.2.0",
|
|
58
|
+
"@thermal-label/transport": "^0.2.1",
|
|
57
59
|
"usb": "^2.0.0",
|
|
58
|
-
"@thermal-label/brother-ql-core": "0.0
|
|
60
|
+
"@thermal-label/brother-ql-core": "0.3.0"
|
|
59
61
|
},
|
|
60
62
|
"optionalDependencies": {
|
|
61
63
|
"@napi-rs/canvas": "^0.1.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/errors.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { UnsupportedOperationError, PrinterError } from '../errors.js';
|
|
3
|
-
describe('UnsupportedOperationError', () => {
|
|
4
|
-
it('sets name and message', () => {
|
|
5
|
-
const err = new UnsupportedOperationError('not supported');
|
|
6
|
-
expect(err.name).toBe('UnsupportedOperationError');
|
|
7
|
-
expect(err.message).toBe('not supported');
|
|
8
|
-
expect(err).toBeInstanceOf(Error);
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
describe('PrinterError', () => {
|
|
12
|
-
it('sets name, message, and errors array', () => {
|
|
13
|
-
const err = new PrinterError('printer failed', ['Cover open', 'No media']);
|
|
14
|
-
expect(err.name).toBe('PrinterError');
|
|
15
|
-
expect(err.message).toBe('printer failed');
|
|
16
|
-
expect(err.errors).toEqual(['Cover open', 'No media']);
|
|
17
|
-
expect(err).toBeInstanceOf(Error);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
//# sourceMappingURL=errors.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../../src/__tests__/errors.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvE,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,GAAG,GAAG,IAAI,yBAAyB,CAAC,eAAe,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACnD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,gBAAgB,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|