@ecobridge.xyz/devicemanager 3.1.0 → 3.2.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.
Files changed (78) hide show
  1. package/.gitea/workflows/default_tags.yaml +0 -21
  2. package/.smartconfig.json +69 -0
  3. package/changelog.md +38 -1
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/device/device.classes.device.d.ts +2 -2
  6. package/dist_ts/device/device.classes.device.js +3 -3
  7. package/dist_ts/devicemanager.classes.devicemanager.d.ts +17 -4
  8. package/dist_ts/devicemanager.classes.devicemanager.js +99 -11
  9. package/dist_ts/discovery/discovery.classes.mdns.js +46 -11
  10. package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +5 -1
  11. package/dist_ts/discovery/discovery.classes.networkscanner.js +44 -3
  12. package/dist_ts/discovery/discovery.classes.ssdp.d.ts +52 -21
  13. package/dist_ts/discovery/discovery.classes.ssdp.js +407 -117
  14. package/dist_ts/events/events.observable.d.ts +15 -0
  15. package/dist_ts/events/events.observable.js +22 -0
  16. package/dist_ts/events/index.d.ts +1 -0
  17. package/dist_ts/events/index.js +2 -0
  18. package/dist_ts/factories/index.js +7 -5
  19. package/dist_ts/features/feature.abstract.d.ts +2 -2
  20. package/dist_ts/features/feature.abstract.js +3 -3
  21. package/dist_ts/features/feature.print.d.ts +3 -0
  22. package/dist_ts/features/feature.print.js +17 -2
  23. package/dist_ts/features/feature.scan.d.ts +5 -2
  24. package/dist_ts/features/feature.scan.js +98 -27
  25. package/dist_ts/index.d.ts +4 -2
  26. package/dist_ts/index.js +4 -2
  27. package/dist_ts/interfaces/feature.interfaces.d.ts +22 -2
  28. package/dist_ts/interfaces/index.d.ts +22 -4
  29. package/dist_ts/interfaces/index.js +1 -1
  30. package/dist_ts/plugins.d.ts +6 -15
  31. package/dist_ts/plugins.js +7 -19
  32. package/dist_ts/protocols/index.d.ts +2 -1
  33. package/dist_ts/protocols/index.js +4 -2
  34. package/dist_ts/protocols/protocol.brother.d.ts +67 -0
  35. package/dist_ts/protocols/protocol.brother.js +560 -0
  36. package/dist_ts/protocols/protocol.escl.d.ts +13 -4
  37. package/dist_ts/protocols/protocol.escl.js +345 -178
  38. package/dist_ts/protocols/protocol.ipp.d.ts +2 -0
  39. package/dist_ts/protocols/protocol.ipp.js +22 -2
  40. package/dist_ts/providers/index.d.ts +1 -0
  41. package/dist_ts/providers/index.js +2 -0
  42. package/dist_ts/providers/provider.smb.d.ts +60 -0
  43. package/dist_ts/providers/provider.smb.js +224 -0
  44. package/license.md +21 -0
  45. package/package.json +15 -20
  46. package/pnpm-workspace.yaml +6 -0
  47. package/readme.md +157 -78
  48. package/test/test.brother.node.ts +306 -0
  49. package/test/test.escl.node.ts +233 -0
  50. package/test/test.ipp.node.ts +75 -0
  51. package/test/{test.ts → test.node.ts} +37 -45
  52. package/test/test.smb.node.ts +123 -0
  53. package/test/test.ssdp.node.ts +978 -0
  54. package/ts/00_commitinfo_data.ts +1 -1
  55. package/ts/device/device.classes.device.ts +2 -2
  56. package/ts/devicemanager.classes.devicemanager.ts +125 -12
  57. package/ts/discovery/discovery.classes.mdns.ts +40 -11
  58. package/ts/discovery/discovery.classes.networkscanner.ts +51 -2
  59. package/ts/discovery/discovery.classes.ssdp.ts +493 -130
  60. package/ts/events/events.observable.ts +31 -0
  61. package/ts/events/index.ts +4 -0
  62. package/ts/factories/index.ts +7 -5
  63. package/ts/features/feature.abstract.ts +2 -2
  64. package/ts/features/feature.print.ts +16 -1
  65. package/ts/features/feature.scan.ts +93 -27
  66. package/ts/index.ts +21 -0
  67. package/ts/interfaces/feature.interfaces.ts +23 -2
  68. package/ts/interfaces/index.ts +23 -4
  69. package/ts/plugins.ts +6 -25
  70. package/ts/protocols/index.ts +11 -1
  71. package/ts/protocols/protocol.brother.ts +648 -0
  72. package/ts/protocols/protocol.escl.ts +348 -191
  73. package/ts/protocols/protocol.ipp.ts +24 -1
  74. package/ts/providers/index.ts +7 -0
  75. package/ts/providers/provider.smb.ts +326 -0
  76. package/dist_ts/protocols/protocol.ipp.old.d.ts +0 -45
  77. package/dist_ts/protocols/protocol.ipp.old.js +0 -284
  78. package/npmextra.json +0 -24
@@ -1,4 +1,5 @@
1
1
  import * as plugins from '../plugins.js'; // Used for smartdelay
2
+ import { XMLBuilder, XMLParser } from 'fast-xml-parser';
2
3
  /**
3
4
  * eSCL XML namespaces
4
5
  */
@@ -23,11 +24,120 @@ const FORMAT_MIME_MAP = {
23
24
  pdf: 'application/pdf',
24
25
  tiff: 'image/tiff',
25
26
  };
27
+ const STATUS_POLL_INTERVAL_MS = 500;
28
+ const MAX_STATUS_POLLS = 240;
29
+ const MAX_SCAN_DOCUMENTS = 500;
30
+ const CONTROL_REQUEST_TIMEOUT_MS = 30_000;
31
+ const DOCUMENT_REQUEST_TIMEOUT_MS = 10 * 60_000;
32
+ const xmlParser = new XMLParser({
33
+ ignoreAttributes: true,
34
+ removeNSPrefix: true,
35
+ trimValues: true,
36
+ parseTagValue: false,
37
+ processEntities: false,
38
+ });
39
+ const xmlBuilder = new XMLBuilder({
40
+ ignoreAttributes: false,
41
+ format: true,
42
+ suppressEmptyNode: false,
43
+ });
44
+ function asRecord(value) {
45
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
46
+ ? value
47
+ : {};
48
+ }
49
+ function asArray(value) {
50
+ if (value === undefined)
51
+ return [];
52
+ return Array.isArray(value) ? value : [value];
53
+ }
54
+ function asText(value) {
55
+ return typeof value === 'string' || typeof value === 'number' ? String(value).trim() : '';
56
+ }
57
+ function asInteger(value, fallback = 0) {
58
+ const parsed = Number.parseInt(asText(value), 10);
59
+ return Number.isFinite(parsed) ? parsed : fallback;
60
+ }
61
+ function unique(values) {
62
+ return [...new Set(values)];
63
+ }
64
+ function collectValues(value, key) {
65
+ if (Array.isArray(value)) {
66
+ return value.flatMap((item) => collectValues(item, key));
67
+ }
68
+ if (value === null || typeof value !== 'object')
69
+ return [];
70
+ const record = value;
71
+ return Object.entries(record).flatMap(([entryKey, entryValue]) => entryKey === key ? asArray(entryValue) : collectValues(entryValue, key));
72
+ }
73
+ function esclUnitsToMillimetres(value, fallback) {
74
+ const units = asInteger(value);
75
+ return units > 0 ? (units / 300) * 25.4 : fallback;
76
+ }
77
+ function formatFromMimeType(mimeType, fallback) {
78
+ const normalized = mimeType.split(';', 1)[0].trim().toLowerCase();
79
+ if (normalized === 'application/pdf')
80
+ return 'pdf';
81
+ if (normalized === 'image/jpeg')
82
+ return 'jpeg';
83
+ if (normalized === 'image/png')
84
+ return 'png';
85
+ if (normalized === 'image/tiff')
86
+ return 'tiff';
87
+ return fallback;
88
+ }
89
+ function readJpegMetadata(data) {
90
+ if (data.length < 4 || data[0] !== 0xff || data[1] !== 0xd8)
91
+ return {};
92
+ const metadata = {};
93
+ const startOfFrameMarkers = new Set([0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf]);
94
+ let offset = 2;
95
+ while (offset + 4 <= data.length) {
96
+ while (offset < data.length && data[offset] === 0xff)
97
+ offset++;
98
+ const marker = data[offset++];
99
+ if (marker === 0xd9 || marker === 0xda)
100
+ break;
101
+ if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7))
102
+ continue;
103
+ if (offset + 2 > data.length)
104
+ break;
105
+ const length = data.readUInt16BE(offset);
106
+ if (length < 2 || offset + length > data.length)
107
+ break;
108
+ const content = offset + 2;
109
+ if (marker === 0xe0 && length >= 16 && data.toString('ascii', content, content + 5) === 'JFIF\0') {
110
+ const units = data[content + 7];
111
+ const density = data.readUInt16BE(content + 8);
112
+ if (units === 1 && density > 0)
113
+ metadata.resolution = density;
114
+ if (units === 2 && density > 0)
115
+ metadata.resolution = Math.round(density * 2.54);
116
+ }
117
+ if (startOfFrameMarkers.has(marker) && length >= 7) {
118
+ metadata.height = data.readUInt16BE(content + 1);
119
+ metadata.width = data.readUInt16BE(content + 3);
120
+ }
121
+ offset += length;
122
+ }
123
+ return metadata;
124
+ }
125
+ export class EsclScanError extends Error {
126
+ partialResult;
127
+ constructor(message, partialResult) {
128
+ super(message);
129
+ this.partialResult = partialResult;
130
+ this.name = 'EsclScanError';
131
+ }
132
+ }
26
133
  /**
27
134
  * Helper to make HTTP requests using native fetch (available in Node.js 18+)
28
135
  */
29
136
  async function httpRequest(url, method, body) {
30
- const options = { method };
137
+ const options = {
138
+ method,
139
+ signal: AbortSignal.timeout(CONTROL_REQUEST_TIMEOUT_MS),
140
+ };
31
141
  if (body) {
32
142
  options.headers = { 'Content-Type': 'text/xml; charset=utf-8' };
33
143
  options.body = body;
@@ -50,6 +160,7 @@ async function httpRequest(url, method, body) {
50
160
  export class EsclProtocol {
51
161
  baseUrl;
52
162
  capabilities = null;
163
+ activeJobUri = null;
53
164
  constructor(address, port, secure = false) {
54
165
  const protocol = secure ? 'https' : 'http';
55
166
  this.baseUrl = `${protocol}://${address}:${port}/eSCL`;
@@ -81,13 +192,14 @@ export class EsclProtocol {
81
192
  */
82
193
  async submitScanJob(options) {
83
194
  const scanSettings = this.buildScanSettings(options);
84
- // Use fetch for POST with body since SmartRequest API may not support raw body
195
+ // Use fetch for the raw XML request body.
85
196
  const response = await fetch(`${this.baseUrl}/ScanJobs`, {
86
197
  method: 'POST',
87
198
  headers: {
88
- 'Content-Type': 'text/xml; charset=utf-8',
199
+ 'Content-Type': 'text/xml',
89
200
  },
90
201
  body: scanSettings,
202
+ signal: AbortSignal.timeout(CONTROL_REQUEST_TIMEOUT_MS),
91
203
  });
92
204
  if (response.status !== 201) {
93
205
  throw new Error(`Failed to submit scan job: HTTP ${response.status}`);
@@ -97,7 +209,7 @@ export class EsclProtocol {
97
209
  if (!location) {
98
210
  throw new Error('No job location returned from scanner');
99
211
  }
100
- return location;
212
+ return this.resolveJobUri(location);
101
213
  }
102
214
  /**
103
215
  * Wait for scan job to complete and download the result
@@ -106,77 +218,141 @@ export class EsclProtocol {
106
218
  * NextDocument is requested. The request triggers the scan and blocks
107
219
  * until complete. We try direct download first, then fall back to polling.
108
220
  */
109
- async waitForScanComplete(jobUri, options, pollInterval = 500) {
110
- // Try direct download first - this triggers the scan on many scanners
111
- // (including Brother) and blocks until the scan completes
112
- try {
113
- const result = await this.downloadScan(jobUri, options);
114
- if (result.data.length > 0) {
115
- return result;
221
+ async waitForScanComplete(jobUri, options, pollInterval = STATUS_POLL_INTERVAL_MS) {
222
+ const pages = [];
223
+ let emptyPolls = 0;
224
+ while (pages.length < MAX_SCAN_DOCUMENTS) {
225
+ let next;
226
+ const requestStartedAt = Date.now();
227
+ try {
228
+ next = await this.downloadNextDocument(jobUri, options);
229
+ }
230
+ catch (error) {
231
+ if (pages.length === 0)
232
+ throw error;
233
+ const message = error instanceof Error ? error.message : String(error);
234
+ throw new EsclScanError(message, this.combinePages(pages, false, message));
235
+ }
236
+ if (next) {
237
+ pages.push(next);
238
+ emptyPolls = 0;
239
+ const delay = this.nextDocumentDelay(options.source, Date.now() - requestStartedAt);
240
+ if (delay > 0)
241
+ await plugins.smartdelay.delayFor(delay);
242
+ continue;
116
243
  }
117
- }
118
- catch (err) {
119
- // Direct download failed, fall back to polling
120
- }
121
- // Fall back to polling for scanners that need it
122
- let attempts = 0;
123
- const maxAttempts = 120; // 60 seconds max
124
- while (attempts < maxAttempts) {
125
244
  const status = await this.getStatus();
126
- const job = status.jobs?.find((j) => jobUri.includes(j.jobUuid) || j.jobUri === jobUri);
127
- if (job) {
128
- if (job.jobState === 'Completed') {
129
- break;
130
- }
131
- else if (job.jobState === 'Canceled' || job.jobState === 'Aborted') {
132
- throw new Error(`Scan job ${job.jobState}: ${job.jobStateReason || 'Unknown reason'}`);
133
- }
245
+ const job = this.findJob(status, jobUri);
246
+ if (job?.jobState === 'Canceled' || job?.jobState === 'Aborted') {
247
+ const reason = job.jobStateReason || 'Unknown reason';
248
+ const message = `Scan job ${job.jobState}: ${reason}`;
249
+ throw new EsclScanError(message, pages.length > 0 ? this.combinePages(pages, false, reason) : undefined);
250
+ }
251
+ if (job?.jobState === 'Completed' || (!job && pages.length > 0)) {
252
+ break;
253
+ }
254
+ if (status.state === 'Stopped') {
255
+ const message = 'Scanner stopped before the scan completed';
256
+ throw new EsclScanError(message, pages.length > 0 ? this.combinePages(pages, false, message) : undefined);
257
+ }
258
+ if (++emptyPolls >= MAX_STATUS_POLLS) {
259
+ const message = `Scan job timed out after ${MAX_STATUS_POLLS * pollInterval} ms`;
260
+ throw new EsclScanError(message, pages.length > 0 ? this.combinePages(pages, false, message) : undefined);
134
261
  }
135
262
  await plugins.smartdelay.delayFor(pollInterval);
136
- attempts++;
137
263
  }
138
- if (attempts >= maxAttempts) {
139
- throw new Error('Scan job timed out');
264
+ if (pages.length === MAX_SCAN_DOCUMENTS) {
265
+ const message = `Scan exceeded the safety limit of ${MAX_SCAN_DOCUMENTS} documents`;
266
+ throw new EsclScanError(message, this.combinePages(pages, false, message));
267
+ }
268
+ if (pages.length === 0) {
269
+ throw new Error('Scan completed without returning a document');
140
270
  }
141
- // Download the scanned document
142
- return this.downloadScan(jobUri, options);
271
+ return this.combinePages(pages, true);
272
+ }
273
+ combinePages(pages, isComplete, jobStateReason) {
274
+ const first = pages[0];
275
+ return {
276
+ ...first,
277
+ pageCount: pages.length,
278
+ pages: pages.map((page) => ({
279
+ data: page.data,
280
+ width: page.width,
281
+ height: page.height,
282
+ mimeType: page.mimeType,
283
+ })),
284
+ isComplete,
285
+ jobStateReason,
286
+ settingsWarnings: unique(pages.flatMap((page) => page.settingsWarnings ?? [])),
287
+ };
143
288
  }
144
289
  /**
145
290
  * Download scanned document
146
291
  */
147
292
  async downloadScan(jobUri, options) {
148
- const downloadUrl = `${jobUri}/NextDocument`;
149
- const response = await fetch(downloadUrl, { method: 'GET' });
150
- if (response.status !== 200) {
293
+ const result = await this.downloadNextDocument(jobUri, options);
294
+ if (!result)
295
+ throw new Error('No scanned document is available');
296
+ return result;
297
+ }
298
+ async downloadNextDocument(jobUri, options) {
299
+ const downloadUrl = new URL('NextDocument', this.resolveJobUri(jobUri).replace(/\/?$/, '/'));
300
+ const response = await fetch(downloadUrl, {
301
+ method: 'GET',
302
+ signal: AbortSignal.timeout(DOCUMENT_REQUEST_TIMEOUT_MS),
303
+ });
304
+ if ([404, 409, 410, 503].includes(response.status))
305
+ return null;
306
+ if (response.status !== 200)
151
307
  throw new Error(`Failed to download scan: HTTP ${response.status}`);
152
- }
153
- const format = options.format ?? 'jpeg';
154
- const contentType = response.headers.get('content-type') ?? FORMAT_MIME_MAP[format];
155
- // Get image dimensions from headers if available
156
- const width = parseInt(response.headers.get('x-image-width') || '0') || 0;
157
- const height = parseInt(response.headers.get('x-image-height') || '0') || 0;
158
308
  const arrayBuffer = await response.arrayBuffer();
159
309
  const data = Buffer.from(arrayBuffer);
310
+ const requestedFormat = options.format ?? 'jpeg';
311
+ const contentType = response.headers.get('content-type') ?? FORMAT_MIME_MAP[requestedFormat];
312
+ const format = formatFromMimeType(contentType, requestedFormat);
313
+ const jpeg = format === 'jpeg' ? readJpegMetadata(data) : {};
314
+ const width = parseInt(response.headers.get('x-image-width') || '0') || jpeg.width || 0;
315
+ const height = parseInt(response.headers.get('x-image-height') || '0') || jpeg.height || 0;
316
+ const reportedResolution = parseInt(response.headers.get('x-image-resolution') || '0')
317
+ || jpeg.resolution;
318
+ const resolution = reportedResolution || options.resolution || 300;
319
+ const settingsWarnings = [];
320
+ if (format !== requestedFormat) {
321
+ settingsWarnings.push(`Requested ${requestedFormat} output but scanner returned ${format}`);
322
+ }
323
+ if (reportedResolution && options.resolution && reportedResolution !== options.resolution) {
324
+ settingsWarnings.push(`Requested ${options.resolution} dpi but scanner returned ${reportedResolution} dpi`);
325
+ }
160
326
  return {
161
327
  data: data,
162
328
  format: format,
163
329
  width: width,
164
330
  height: height,
165
- resolution: options.resolution ?? 300,
331
+ resolution,
166
332
  colorMode: options.colorMode ?? 'color',
167
333
  mimeType: contentType,
334
+ settingsWarnings,
335
+ pageCount: 1,
336
+ pages: [{ data, width, height, mimeType: contentType }],
168
337
  };
169
338
  }
170
339
  /**
171
340
  * Cancel a scan job
172
341
  */
173
342
  async cancelJob(jobUri) {
174
- const response = await fetch(jobUri, { method: 'DELETE' });
343
+ const response = await fetch(this.resolveJobUri(jobUri), {
344
+ method: 'DELETE',
345
+ signal: AbortSignal.timeout(CONTROL_REQUEST_TIMEOUT_MS),
346
+ });
175
347
  // 204 No Content or 200 OK are both acceptable
176
348
  if (response.status !== 200 && response.status !== 204) {
177
349
  throw new Error(`Failed to cancel job: HTTP ${response.status}`);
178
350
  }
179
351
  }
352
+ async cancelCurrentScan() {
353
+ if (this.activeJobUri)
354
+ await this.cancelJob(this.activeJobUri);
355
+ }
180
356
  /**
181
357
  * Build XML scan settings
182
358
  */
@@ -184,167 +360,155 @@ export class EsclProtocol {
184
360
  const resolution = options.resolution ?? 300;
185
361
  const colorMode = COLOR_MODE_MAP[options.colorMode ?? 'color'];
186
362
  const format = FORMAT_MIME_MAP[options.format ?? 'jpeg'];
187
- const source = this.mapSource(options.source ?? 'flatbed');
188
- const intent = options.intent ?? 'TextAndPhoto';
189
- let xml = `<?xml version="1.0" encoding="UTF-8"?>
190
- <scan:ScanSettings xmlns:scan="${NAMESPACES.scan}" xmlns:pwg="${NAMESPACES.pwg}">
191
- <pwg:Version>2.0</pwg:Version>
192
- <scan:Intent>${intent}</scan:Intent>
193
- <pwg:ScanRegions>
194
- <pwg:ScanRegion>`;
195
- if (options.area) {
196
- // Convert mm to 300ths of an inch (eSCL uses 300dpi as base unit)
197
- const toUnits = (mm) => Math.round((mm / 25.4) * 300);
198
- xml += `
199
- <pwg:XOffset>${toUnits(options.area.x)}</pwg:XOffset>
200
- <pwg:YOffset>${toUnits(options.area.y)}</pwg:YOffset>
201
- <pwg:Width>${toUnits(options.area.width)}</pwg:Width>
202
- <pwg:Height>${toUnits(options.area.height)}</pwg:Height>`;
203
- }
204
- else {
205
- // Full page (A4 default: 210x297mm)
206
- xml += `
207
- <pwg:XOffset>0</pwg:XOffset>
208
- <pwg:YOffset>0</pwg:YOffset>
209
- <pwg:Width>2480</pwg:Width>
210
- <pwg:Height>3508</pwg:Height>`;
211
- }
212
- xml += `
213
- <pwg:ContentRegionUnits>escl:ThreeHundredthsOfInches</pwg:ContentRegionUnits>
214
- </pwg:ScanRegion>
215
- </pwg:ScanRegions>
216
- <scan:DocumentFormatExt>${format}</scan:DocumentFormatExt>
217
- <scan:XResolution>${resolution}</scan:XResolution>
218
- <scan:YResolution>${resolution}</scan:YResolution>
219
- <scan:ColorMode>${colorMode}</scan:ColorMode>
220
- <scan:InputSource>${source}</scan:InputSource>`;
363
+ const scanSource = options.source ?? 'flatbed';
364
+ const source = scanSource === 'flatbed' ? 'Platen' : 'Feeder';
365
+ const intent = this.mapIntent(options.intent ?? 'document');
366
+ const toUnits = (mm) => Math.round((mm / 25.4) * 300);
367
+ const sourceCapabilities = scanSource === 'flatbed'
368
+ ? this.capabilities?.platen
369
+ : scanSource === 'adf-duplex'
370
+ ? this.capabilities?.adfDuplex
371
+ : this.capabilities?.adf;
372
+ const requestedArea = options.area ?? { x: 0, y: 0, width: 210, height: 297 };
373
+ const maxWidth = sourceCapabilities?.maxWidth ?? 215.9;
374
+ const maxHeight = sourceCapabilities?.maxHeight ?? (scanSource === 'flatbed' ? 296.926 : 355.6);
375
+ const area = {
376
+ x: Math.max(0, requestedArea.x),
377
+ y: Math.max(0, requestedArea.y),
378
+ width: Math.min(requestedArea.width, maxWidth - Math.max(0, requestedArea.x)),
379
+ height: Math.min(requestedArea.height, maxHeight - Math.max(0, requestedArea.y)),
380
+ };
381
+ const settings = {
382
+ '@_xmlns:scan': NAMESPACES.scan,
383
+ '@_xmlns:pwg': NAMESPACES.pwg,
384
+ 'pwg:Version': '2.0',
385
+ 'scan:Intent': intent,
386
+ 'pwg:ScanRegions': {
387
+ 'pwg:ScanRegion': {
388
+ 'pwg:ContentRegionUnits': 'escl:ThreeHundredthsOfInches',
389
+ 'pwg:XOffset': toUnits(area.x),
390
+ 'pwg:YOffset': toUnits(area.y),
391
+ 'pwg:Width': toUnits(area.width),
392
+ 'pwg:Height': toUnits(area.height),
393
+ },
394
+ },
395
+ 'pwg:InputSource': source,
396
+ 'scan:ColorMode': colorMode,
397
+ 'pwg:DocumentFormat': format,
398
+ 'scan:DocumentFormatExt': format,
399
+ 'scan:XResolution': resolution,
400
+ 'scan:YResolution': resolution,
401
+ };
402
+ if (scanSource !== 'flatbed')
403
+ settings['scan:Duplex'] = scanSource === 'adf-duplex';
221
404
  if (options.format === 'jpeg' && options.quality) {
222
- xml += `
223
- <scan:CompressionFactor>${100 - options.quality}</scan:CompressionFactor>`;
405
+ settings['scan:CompressionFactor'] = 100 - options.quality;
224
406
  }
225
- xml += `
226
- </scan:ScanSettings>`;
227
- return xml;
407
+ return `<?xml version="1.0" encoding="UTF-8"?>\n${xmlBuilder.build({ 'scan:ScanSettings': settings })}`;
228
408
  }
229
- /**
230
- * Map source to eSCL format
231
- */
232
- mapSource(source) {
233
- switch (source) {
234
- case 'flatbed':
235
- return 'Platen';
236
- case 'adf':
237
- return 'Feeder';
238
- case 'adf-duplex':
239
- return 'Duplex';
240
- default:
241
- return 'Platen';
242
- }
409
+ mapIntent(intent) {
410
+ if (intent === 'photo')
411
+ return 'Photo';
412
+ if (intent === 'preview')
413
+ return 'Preview';
414
+ return 'Document';
415
+ }
416
+ nextDocumentDelay(source, requestDuration) {
417
+ const isBrother = this.capabilities?.makeAndModel.toLowerCase().startsWith('brother ');
418
+ if (!isBrother || source === 'flatbed')
419
+ return 0;
420
+ return Math.min(Math.round(requestDuration * 0.5), 1000);
243
421
  }
244
422
  /**
245
423
  * Parse capabilities XML response
246
424
  */
247
425
  parseCapabilities(body) {
248
- const xml = body;
249
- // Simple XML parsing without full XML parser
250
- const getTagContent = (tag) => {
251
- const regex = new RegExp(`<[^:]*:?${tag}[^>]*>([^<]*)<`, 'i');
252
- const match = xml.match(regex);
253
- return match?.[1]?.trim() ?? '';
254
- };
255
- const getAllTagContents = (tag) => {
256
- const regex = new RegExp(`<[^:]*:?${tag}[^>]*>([^<]*)<`, 'gi');
257
- const matches = [];
258
- let match;
259
- while ((match = regex.exec(xml)) !== null) {
260
- if (match[1]?.trim()) {
261
- matches.push(match[1].trim());
262
- }
263
- }
264
- return matches;
265
- };
266
- const parseResolutions = () => {
267
- const resolutions = getAllTagContents('XResolution');
268
- return [...new Set(resolutions.map((r) => parseInt(r)).filter((r) => !isNaN(r)))];
269
- };
426
+ const document = asRecord(xmlParser.parse(body));
427
+ const root = asRecord(document.ScannerCapabilities);
428
+ const platen = asRecord(asRecord(root.Platen).PlatenInputCaps);
429
+ const adfRoot = asRecord(root.Adf);
430
+ const adf = asRecord(adfRoot.AdfSimplexInputCaps);
431
+ const adfDuplex = asRecord(adfRoot.AdfDuplexInputCaps);
270
432
  return {
271
- version: getTagContent('Version') || '2.0',
272
- makeAndModel: getTagContent('MakeAndModel') || getTagContent('Make') || 'Unknown',
273
- serialNumber: getTagContent('SerialNumber') || undefined,
274
- uuid: getTagContent('UUID') || undefined,
275
- adminUri: getTagContent('AdminURI') || undefined,
276
- iconUri: getTagContent('IconURI') || undefined,
277
- platen: xml.includes('Platen')
278
- ? {
279
- minWidth: parseInt(getTagContent('MinWidth')) || 0,
280
- maxWidth: parseInt(getTagContent('MaxWidth')) || 2550,
281
- minHeight: parseInt(getTagContent('MinHeight')) || 0,
282
- maxHeight: parseInt(getTagContent('MaxHeight')) || 3508,
283
- maxScanRegions: parseInt(getTagContent('MaxScanRegions')) || 1,
284
- supportedResolutions: parseResolutions(),
285
- colorModes: getAllTagContents('ColorMode'),
286
- documentFormats: getAllTagContents('DocumentFormatExt'),
287
- }
288
- : undefined,
289
- adf: xml.includes('Adf') || xml.includes('ADF') || xml.includes('Feeder')
290
- ? {
291
- minWidth: 0,
292
- maxWidth: 2550,
293
- minHeight: 0,
294
- maxHeight: 4200,
295
- maxScanRegions: 1,
296
- supportedResolutions: parseResolutions(),
297
- colorModes: getAllTagContents('ColorMode'),
298
- documentFormats: getAllTagContents('DocumentFormatExt'),
299
- }
433
+ version: asText(root.Version) || '2.0',
434
+ makeAndModel: asText(root.MakeAndModel) || asText(root.Make) || 'Unknown',
435
+ serialNumber: asText(root.SerialNumber) || undefined,
436
+ uuid: asText(root.UUID) || undefined,
437
+ adminUri: asText(root.AdminURI) || undefined,
438
+ iconUri: asText(root.IconURI) || undefined,
439
+ platen: Object.keys(platen).length > 0 ? this.parseInputSource(platen, 215.9, 297) : undefined,
440
+ adf: Object.keys(adf).length > 0 ? this.parseInputSource(adf, 215.9, 355.6) : undefined,
441
+ adfDuplex: Object.keys(adfDuplex).length > 0
442
+ ? this.parseInputSource(adfDuplex, 215.9, 355.6)
300
443
  : undefined,
301
444
  };
302
445
  }
446
+ parseInputSource(source, defaultWidth, defaultHeight) {
447
+ const resolutions = collectValues(source, 'XResolution')
448
+ .map((value) => asInteger(value))
449
+ .filter((value) => value > 0);
450
+ const colorModes = collectValues(source, 'ColorMode').map(asText).filter(Boolean);
451
+ const documentFormats = [
452
+ ...collectValues(source, 'DocumentFormat'),
453
+ ...collectValues(source, 'DocumentFormatExt'),
454
+ ].map(asText).filter(Boolean);
455
+ return {
456
+ minWidth: esclUnitsToMillimetres(source.MinWidth, 0),
457
+ maxWidth: esclUnitsToMillimetres(source.MaxWidth, defaultWidth),
458
+ minHeight: esclUnitsToMillimetres(source.MinHeight, 0),
459
+ maxHeight: esclUnitsToMillimetres(source.MaxHeight, defaultHeight),
460
+ maxScanRegions: asInteger(source.MaxScanRegions, 1),
461
+ supportedResolutions: unique(resolutions),
462
+ colorModes: unique(colorModes),
463
+ documentFormats: unique(documentFormats),
464
+ };
465
+ }
303
466
  /**
304
467
  * Parse status XML response
305
468
  */
306
469
  parseStatus(body) {
307
- const xml = body;
308
- const getTagContent = (tag) => {
309
- const regex = new RegExp(`<[^:]*:?${tag}[^>]*>([^<]*)<`, 'i');
310
- const match = xml.match(regex);
311
- return match?.[1]?.trim() ?? '';
312
- };
313
- const state = getTagContent('State') || getTagContent('ScannerState') || 'Idle';
314
- const adfState = getTagContent('AdfState') || undefined;
315
- // Parse jobs if present
316
- const jobs = [];
317
- const jobMatches = xml.match(/<[^:]*:?JobInfo[^>]*>[\s\S]*?<\/[^:]*:?JobInfo>/gi);
318
- if (jobMatches) {
319
- for (const jobXml of jobMatches) {
320
- const getJobTag = (tag) => {
321
- const regex = new RegExp(`<[^:]*:?${tag}[^>]*>([^<]*)<`, 'i');
322
- const match = jobXml.match(regex);
323
- return match?.[1]?.trim() ?? '';
324
- };
325
- jobs.push({
326
- jobUri: getJobTag('JobUri') || getJobTag('JobURI') || '',
327
- jobUuid: getJobTag('JobUuid') || getJobTag('JobUUID') || '',
328
- age: parseInt(getJobTag('Age')) || 0,
329
- imagesCompleted: parseInt(getJobTag('ImagesCompleted')) || 0,
330
- imagesToTransfer: parseInt(getJobTag('ImagesToTransfer')) || 0,
331
- jobState: getJobTag('JobState') || 'Pending',
332
- jobStateReason: getJobTag('JobStateReason') || undefined,
333
- });
334
- }
335
- }
470
+ const document = asRecord(xmlParser.parse(body));
471
+ const root = asRecord(document.ScannerStatus);
472
+ const state = asText(root.State) || asText(root.ScannerState) || 'Idle';
473
+ const rawAdfState = asText(root.AdfState).replace(/^ScannerAdf/, '');
474
+ const jobsRoot = asRecord(root.Jobs);
475
+ const jobs = asArray(jobsRoot.JobInfo).map((value) => {
476
+ const job = asRecord(value);
477
+ const reason = collectValues(job.JobStateReasons, 'JobStateReason').map(asText).find(Boolean);
478
+ return {
479
+ jobUri: asText(job.JobUri) || asText(job.JobURI),
480
+ jobUuid: asText(job.JobUuid) || asText(job.JobUUID),
481
+ age: asInteger(job.Age),
482
+ imagesCompleted: asInteger(job.ImagesCompleted),
483
+ imagesToTransfer: asInteger(job.ImagesToTransfer),
484
+ jobState: asText(job.JobState) || 'Pending',
485
+ jobStateReason: reason || undefined,
486
+ };
487
+ });
336
488
  return {
337
489
  state: state,
338
- adfState: adfState,
490
+ adfState: rawAdfState ? rawAdfState : undefined,
339
491
  jobs: jobs.length > 0 ? jobs : undefined,
340
492
  };
341
493
  }
494
+ resolveJobUri(jobUri) {
495
+ return new URL(jobUri, `${this.baseUrl}/`).toString();
496
+ }
497
+ findJob(status, jobUri) {
498
+ const resolved = new URL(this.resolveJobUri(jobUri));
499
+ const uuid = resolved.pathname.split('/').filter(Boolean).at(-1) || '';
500
+ return status.jobs?.find((job) => {
501
+ const candidate = new URL(job.jobUri, `${this.baseUrl}/`);
502
+ return candidate.pathname === resolved.pathname || job.jobUuid.endsWith(uuid);
503
+ });
504
+ }
342
505
  /**
343
506
  * Perform a complete scan operation
344
507
  */
345
508
  async scan(options) {
346
509
  // Submit the job
347
510
  const jobUri = await this.submitScanJob(options);
511
+ this.activeJobUri = jobUri;
348
512
  try {
349
513
  // Wait for completion and download
350
514
  return await this.waitForScanComplete(jobUri, options);
@@ -359,6 +523,9 @@ export class EsclProtocol {
359
523
  }
360
524
  throw error;
361
525
  }
526
+ finally {
527
+ this.activeJobUri = null;
528
+ }
362
529
  }
363
530
  }
364
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuZXNjbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3Byb3RvY29scy9wcm90b2NvbC5lc2NsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDLENBQUMsc0JBQXNCO0FBV2hFOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEdBQUc7SUFDakIsSUFBSSxFQUFFLCtDQUErQztJQUNyRCxHQUFHLEVBQUUsdUNBQXVDO0NBQzdDLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sY0FBYyxHQUErQjtJQUNqRCxLQUFLLEVBQUUsT0FBTztJQUNkLFNBQVMsRUFBRSxZQUFZO0lBQ3ZCLFVBQVUsRUFBRSxnQkFBZ0I7Q0FDN0IsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxlQUFlLEdBQWdDO0lBQ25ELElBQUksRUFBRSxZQUFZO0lBQ2xCLEdBQUcsRUFBRSxXQUFXO0lBQ2hCLEdBQUcsRUFBRSxpQkFBaUI7SUFDdEIsSUFBSSxFQUFFLFlBQVk7Q0FDbkIsQ0FBQztBQUVGOztHQUVHO0FBQ0gsS0FBSyxVQUFVLFdBQVcsQ0FDeEIsR0FBVyxFQUNYLE1BQWlDLEVBQ2pDLElBQWE7SUFFYixNQUFNLE9BQU8sR0FBZ0IsRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUV4QyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsT0FBTyxDQUFDLE9BQU8sR0FBRyxFQUFFLGNBQWMsRUFBRSx5QkFBeUIsRUFBRSxDQUFDO1FBQ2hFLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDM0MsTUFBTSxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFM0MsTUFBTSxPQUFPLEdBQTJCLEVBQUUsQ0FBQztJQUMzQyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUN0QyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTztRQUNMLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtRQUN2QixPQUFPO1FBQ1AsSUFBSSxFQUFFLFlBQVk7S0FDbkIsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBQ2YsT0FBTyxDQUFTO0lBQ2hCLFlBQVksR0FBNkIsSUFBSSxDQUFDO0lBRXRELFlBQVksT0FBZSxFQUFFLElBQVksRUFBRSxTQUFrQixLQUFLO1FBQ2hFLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDM0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLFFBQVEsTUFBTSxPQUFPLElBQUksSUFBSSxPQUFPLENBQUM7SUFDekQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGVBQWU7UUFDMUIsTUFBTSxRQUFRLEdBQUcsTUFBTSxXQUFXLENBQ2hDLEdBQUcsSUFBSSxDQUFDLE9BQU8sc0JBQXNCLEVBQ3JDLEtBQUssQ0FDTixDQUFDO1FBRUYsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxTQUFTO1FBQ3BCLE1BQU0sUUFBUSxHQUFHLE1BQU0sV0FBVyxDQUNoQyxHQUFHLElBQUksQ0FBQyxPQUFPLGdCQUFnQixFQUMvQixLQUFLLENBQ04sQ0FBQztRQUVGLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNuRSxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUFxQjtRQUM5QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFckQsK0VBQStFO1FBQy9FLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sV0FBVyxFQUFFO1lBQ3ZELE1BQU0sRUFBRSxNQUFNO1lBQ2QsT0FBTyxFQUFFO2dCQUNQLGNBQWMsRUFBRSx5QkFBeUI7YUFDMUM7WUFDRCxJQUFJLEVBQUUsWUFBWTtTQUNuQixDQUFDLENBQUM7UUFFSCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUVELG1DQUFtQztRQUNuQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMsbUJBQW1CLENBQzlCLE1BQWMsRUFDZCxPQUFxQixFQUNyQixlQUF1QixHQUFHO1FBRTFCLHNFQUFzRTtRQUN0RSwwREFBMEQ7UUFDMUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUN4RCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMzQixPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYiwrQ0FBK0M7UUFDakQsQ0FBQztRQUVELGlEQUFpRDtRQUNqRCxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFDakIsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLENBQUMsaUJBQWlCO1FBRTFDLE9BQU8sUUFBUSxHQUFHLFdBQVcsRUFBRSxDQUFDO1lBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDO1lBRXhGLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ1IsSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO29CQUNqQyxNQUFNO2dCQUNSLENBQUM7cUJBQU0sSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLFVBQVUsSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUNyRSxNQUFNLElBQUksS0FBSyxDQUFDLFlBQVksR0FBRyxDQUFDLFFBQVEsS0FBSyxHQUFHLENBQUMsY0FBYyxJQUFJLGdCQUFnQixFQUFFLENBQUMsQ0FBQztnQkFDekYsQ0FBQztZQUNILENBQUM7WUFFRCxNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2hELFFBQVEsRUFBRSxDQUFDO1FBQ2IsQ0FBQztRQUVELElBQUksUUFBUSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsZ0NBQWdDO1FBQ2hDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFjLEVBQUUsT0FBcUI7UUFDN0QsTUFBTSxXQUFXLEdBQUcsR0FBRyxNQUFNLGVBQWUsQ0FBQztRQUU3QyxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUU3RCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEUsQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDO1FBQ3hDLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwRixpREFBaUQ7UUFDakQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxRSxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUUsTUFBTSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUV0QyxPQUFPO1lBQ0wsSUFBSSxFQUFFLElBQUk7WUFDVixNQUFNLEVBQUUsTUFBTTtZQUNkLEtBQUssRUFBRSxLQUFLO1lBQ1osTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVUsSUFBSSxHQUFHO1lBQ3JDLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxJQUFJLE9BQU87WUFDdkMsUUFBUSxFQUFFLFdBQVc7U0FDdEIsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBYztRQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUUzRCwrQ0FBK0M7UUFDL0MsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ3ZELE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxPQUFxQjtRQUM3QyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQztRQUM3QyxNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLFNBQVMsSUFBSSxPQUFPLENBQUMsQ0FBQztRQUMvRCxNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsQ0FBQztRQUN6RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksU0FBUyxDQUFDLENBQUM7UUFDM0QsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxjQUFjLENBQUM7UUFFaEQsSUFBSSxHQUFHLEdBQUc7aUNBQ21CLFVBQVUsQ0FBQyxJQUFJLGdCQUFnQixVQUFVLENBQUMsR0FBRzs7aUJBRTdELE1BQU07O3FCQUVGLENBQUM7UUFFbEIsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDakIsa0VBQWtFO1lBQ2xFLE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBVSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQzlELEdBQUcsSUFBSTtxQkFDUSxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7cUJBQ3ZCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzttQkFDekIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUMxQixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDO1FBQzVELENBQUM7YUFBTSxDQUFDO1lBQ04sb0NBQW9DO1lBQ3BDLEdBQUcsSUFBSTs7OztvQ0FJdUIsQ0FBQztRQUNqQyxDQUFDO1FBRUQsR0FBRyxJQUFJOzs7OzRCQUlpQixNQUFNO3NCQUNaLFVBQVU7c0JBQ1YsVUFBVTtvQkFDWixTQUFTO3NCQUNQLE1BQU0scUJBQXFCLENBQUM7UUFFOUMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLE1BQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakQsR0FBRyxJQUFJOzRCQUNlLEdBQUcsR0FBRyxPQUFPLENBQUMsT0FBTywyQkFBMkIsQ0FBQztRQUN6RSxDQUFDO1FBRUQsR0FBRyxJQUFJO3FCQUNVLENBQUM7UUFFbEIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQ7O09BRUc7SUFDSyxTQUFTLENBQUMsTUFBYztRQUM5QixRQUFRLE1BQU0sRUFBRSxDQUFDO1lBQ2YsS0FBSyxTQUFTO2dCQUNaLE9BQU8sUUFBUSxDQUFDO1lBQ2xCLEtBQUssS0FBSztnQkFDUixPQUFPLFFBQVEsQ0FBQztZQUNsQixLQUFLLFlBQVk7Z0JBQ2YsT0FBTyxRQUFRLENBQUM7WUFDbEI7Z0JBQ0UsT0FBTyxRQUFRLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQixDQUFDLElBQVk7UUFDcEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDO1FBRWpCLDZDQUE2QztRQUM3QyxNQUFNLGFBQWEsR0FBRyxDQUFDLEdBQVcsRUFBVSxFQUFFO1lBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM5RCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9CLE9BQU8sS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO1FBQ2xDLENBQUMsQ0FBQztRQUVGLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxHQUFXLEVBQVksRUFBRTtZQUNsRCxNQUFNLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxXQUFXLEdBQUcsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDL0QsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO1lBQzdCLElBQUksS0FBSyxDQUFDO1lBQ1YsT0FBTyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQzFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7b0JBQ3JCLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ2hDLENBQUM7WUFDSCxDQUFDO1lBQ0QsT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQyxDQUFDO1FBRUYsTUFBTSxnQkFBZ0IsR0FBRyxHQUFhLEVBQUU7WUFDdEMsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDckQsT0FBTyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRixDQUFDLENBQUM7UUFFRixPQUFPO1lBQ0wsT0FBTyxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLO1lBQzFDLFlBQVksRUFBRSxhQUFhLENBQUMsY0FBYyxDQUFDLElBQUksYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFNBQVM7WUFDakYsWUFBWSxFQUFFLGFBQWEsQ0FBQyxjQUFjLENBQUMsSUFBSSxTQUFTO1lBQ3hELElBQUksRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksU0FBUztZQUN4QyxRQUFRLEVBQUUsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLFNBQVM7WUFDaEQsT0FBTyxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTO1lBQzlDLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDNUIsQ0FBQyxDQUFDO29CQUNFLFFBQVEsRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDbEQsUUFBUSxFQUFFLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxJQUFJO29CQUNyRCxTQUFTLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ3BELFNBQVMsRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksSUFBSTtvQkFDdkQsY0FBYyxFQUFFLFFBQVEsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQzlELG9CQUFvQixFQUFFLGdCQUFnQixFQUFFO29CQUN4QyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsV0FBVyxDQUFDO29CQUMxQyxlQUFlLEVBQUUsaUJBQWlCLENBQUMsbUJBQW1CLENBQUM7aUJBQ3hEO2dCQUNILENBQUMsQ0FBQyxTQUFTO1lBQ2IsR0FBRyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDdkUsQ0FBQyxDQUFDO29CQUNFLFFBQVEsRUFBRSxDQUFDO29CQUNYLFFBQVEsRUFBRSxJQUFJO29CQUNkLFNBQVMsRUFBRSxDQUFDO29CQUNaLFNBQVMsRUFBRSxJQUFJO29CQUNmLGNBQWMsRUFBRSxDQUFDO29CQUNqQixvQkFBb0IsRUFBRSxnQkFBZ0IsRUFBRTtvQkFDeEMsVUFBVSxFQUFFLGlCQUFpQixDQUFDLFdBQVcsQ0FBQztvQkFDMUMsZUFBZSxFQUFFLGlCQUFpQixDQUFDLG1CQUFtQixDQUFDO2lCQUN4RDtnQkFDSCxDQUFDLENBQUMsU0FBUztTQUNkLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxXQUFXLENBQUMsSUFBWTtRQUM5QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUM7UUFFakIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFXLEVBQVUsRUFBRTtZQUM1QyxNQUFNLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxXQUFXLEdBQUcsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDOUQsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixPQUFPLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUNsQyxDQUFDLENBQUM7UUFFRixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLElBQUksYUFBYSxDQUFDLGNBQWMsQ0FBQyxJQUFJLE1BQU0sQ0FBQztRQUNoRixNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksU0FBUyxDQUFDO1FBRXhELHdCQUF3QjtRQUN4QixNQUFNLElBQUksR0FBbUIsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztRQUNsRixJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsS0FBSyxNQUFNLE1BQU0sSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFXLEVBQVUsRUFBRTtvQkFDeEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsV0FBVyxHQUFHLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUM5RCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNsQyxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDO2dCQUVGLElBQUksQ0FBQyxJQUFJLENBQUM7b0JBQ1IsTUFBTSxFQUFFLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRTtvQkFDeEQsT0FBTyxFQUFFLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTtvQkFDM0QsR0FBRyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO29CQUNwQyxlQUFlLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDNUQsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDOUQsUUFBUSxFQUFHLFNBQVMsQ0FBQyxVQUFVLENBQThCLElBQUksU0FBUztvQkFDMUUsY0FBYyxFQUFFLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLFNBQVM7aUJBQ3pELENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTztZQUNMLEtBQUssRUFBRSxLQUFpQztZQUN4QyxRQUFRLEVBQUUsUUFBdUM7WUFDakQsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDekMsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBcUI7UUFDckMsaUJBQWlCO1FBQ2pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVqRCxJQUFJLENBQUM7WUFDSCxtQ0FBbUM7WUFDbkMsT0FBTyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixpQ0FBaUM7WUFDakMsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMvQixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLHVCQUF1QjtZQUN6QixDQUFDO1lBQ0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztDQUNGIn0=
531
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuZXNjbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3Byb3RvY29scy9wcm90b2NvbC5lc2NsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDLENBQUMsc0JBQXNCO0FBQ2hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFXeEQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsR0FBRztJQUNqQixJQUFJLEVBQUUsK0NBQStDO0lBQ3JELEdBQUcsRUFBRSx1Q0FBdUM7Q0FDN0MsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxjQUFjLEdBQStCO0lBQ2pELEtBQUssRUFBRSxPQUFPO0lBQ2QsU0FBUyxFQUFFLFlBQVk7SUFDdkIsVUFBVSxFQUFFLGdCQUFnQjtDQUM3QixDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLGVBQWUsR0FBZ0M7SUFDbkQsSUFBSSxFQUFFLFlBQVk7SUFDbEIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixJQUFJLEVBQUUsWUFBWTtDQUNuQixDQUFDO0FBRUYsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFDcEMsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7QUFDN0IsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFDL0IsTUFBTSwwQkFBMEIsR0FBRyxNQUFNLENBQUM7QUFDMUMsTUFBTSwyQkFBMkIsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDO0FBSWhELE1BQU0sU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDO0lBQzlCLGdCQUFnQixFQUFFLElBQUk7SUFDdEIsY0FBYyxFQUFFLElBQUk7SUFDcEIsVUFBVSxFQUFFLElBQUk7SUFDaEIsYUFBYSxFQUFFLEtBQUs7SUFDcEIsZUFBZSxFQUFFLEtBQUs7Q0FDdkIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxVQUFV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