@plevands/epson-thermal-printer 0.1.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.
@@ -0,0 +1,435 @@
1
+ import * as pdfjsLib from "pdfjs-dist";
2
+ var config = {
3
+ enabled: !1,
4
+ onLog: void 0
5
+ };
6
+ function configureLogger(e) {
7
+ e.enabled !== void 0 && (config.enabled = e.enabled), e.onLog !== void 0 && (config.onLog = e.onLog);
8
+ }
9
+ function getLoggerConfig() {
10
+ return { ...config };
11
+ }
12
+ function log(e, p, ...m) {
13
+ let h = {
14
+ level: e,
15
+ message: p,
16
+ args: m.length > 0 ? m : void 0
17
+ };
18
+ if (config.onLog && config.onLog(h), e === "error") {
19
+ console.error(`[epson-printer] ${p}`, ...m);
20
+ return;
21
+ }
22
+ config.enabled && (e === "warn" ? console.warn(`[epson-printer] ${p}`, ...m) : console.log(`[epson-printer] ${p}`, ...m));
23
+ }
24
+ function debug(e, ...f) {
25
+ log("debug", e, ...f);
26
+ }
27
+ function warn(e, ...f) {
28
+ log("warn", e, ...f);
29
+ }
30
+ function error(e, ...f) {
31
+ log("error", e, ...f);
32
+ }
33
+ var state = {
34
+ loading: !1,
35
+ loaded: !1,
36
+ error: null,
37
+ promise: null
38
+ };
39
+ function isEpsonSDKLoaded() {
40
+ return typeof window < "u" && window.epson !== void 0 && window.epson.ePOSPrint !== void 0;
41
+ }
42
+ function getSDKPath() {
43
+ try {
44
+ return new URL("../../dist/assets/epos-2.27.0.js", "" + import.meta.url).href;
45
+ } catch {
46
+ return "/epos-2.27.0.js";
47
+ }
48
+ }
49
+ function loadScript(e) {
50
+ return new Promise((f, p) => {
51
+ if (document.querySelector(`script[src="${e}"]`)) {
52
+ f();
53
+ return;
54
+ }
55
+ let m = document.createElement("script");
56
+ m.src = e, m.type = "text/javascript", m.async = !0, m.onload = () => {
57
+ debug("Epson SDK loaded successfully from:", e), f();
58
+ }, m.onerror = (f) => {
59
+ error("Failed to load Epson SDK from:", e, f), p(/* @__PURE__ */ Error(`Failed to load Epson SDK from ${e}`));
60
+ }, document.head.appendChild(m);
61
+ });
62
+ }
63
+ function waitForSDKAvailable(e = 1e4) {
64
+ return new Promise((f) => {
65
+ let p = Date.now(), m = () => {
66
+ if (isEpsonSDKLoaded()) {
67
+ f(!0);
68
+ return;
69
+ }
70
+ if (Date.now() - p > e) {
71
+ warn("Timeout waiting for Epson SDK to be available"), f(!1);
72
+ return;
73
+ }
74
+ setTimeout(m, 100);
75
+ };
76
+ m();
77
+ });
78
+ }
79
+ async function loadEpsonSDK(e) {
80
+ return state.loaded || isEpsonSDKLoaded() ? (state.loaded = !0, state.loading = !1, !0) : state.loading && state.promise ? state.promise : (state.loading = !0, state.error = null, state.promise = (async () => {
81
+ try {
82
+ let f = e?.sdkPath || getSDKPath(), p = e?.timeout || 1e4;
83
+ if (debug("Loading Epson SDK from:", f), await loadScript(f), !await waitForSDKAvailable(p)) throw Error("Epson SDK loaded but not available in window.epson");
84
+ return state.loaded = !0, state.loading = !1, debug("Epson SDK ready"), !0;
85
+ } catch (e) {
86
+ return state.error = e instanceof Error ? e : Error(String(e)), state.loading = !1, state.loaded = !1, error("Failed to load Epson SDK:", state.error), !1;
87
+ }
88
+ })(), state.promise);
89
+ }
90
+ function getLoaderState() {
91
+ return { ...state };
92
+ }
93
+ function resetLoaderState() {
94
+ state.loading = !1, state.loaded = !1, state.error = null, state.promise = null;
95
+ }
96
+ function getEpsonSDK() {
97
+ if (!isEpsonSDKLoaded()) throw Error("Epson SDK not loaded. Call loadEpsonSDK() first or wait for automatic loading.");
98
+ return window.epson;
99
+ }
100
+ async function initializeEpsonSDK(e) {
101
+ try {
102
+ return await loadEpsonSDK(e) ? { success: !0 } : {
103
+ success: !1,
104
+ error: getLoaderState().error?.message || "Failed to load Epson SDK"
105
+ };
106
+ } catch (e) {
107
+ return {
108
+ success: !1,
109
+ error: e instanceof Error ? e.message : "Unknown error"
110
+ };
111
+ }
112
+ }
113
+ function checkEpsonSDKStatus() {
114
+ let e = getLoaderState(), f = window.epson, p = [];
115
+ return f && (f.ePOSBuilder && p.push("ePOSBuilder"), f.ePOSPrint && p.push("ePOSPrint"), f.CanvasPrint && p.push("CanvasPrint"), f.ePOSDevice && p.push("ePOSDevice")), {
116
+ loaded: e.loaded || isEpsonSDKLoaded(),
117
+ loading: e.loading,
118
+ error: e.error,
119
+ classes: p
120
+ };
121
+ }
122
+ var EposPrintService = class {
123
+ constructor(e, f = {}) {
124
+ this.initPromise = null, this.config = {
125
+ printerIP: e.printerIP,
126
+ printerPort: e.printerPort ?? 80,
127
+ deviceId: e.deviceId ?? "local_printer",
128
+ timeout: e.timeout ?? 6e4
129
+ }, this.printOptions = {
130
+ halftone: f.halftone ?? 1,
131
+ brightness: f.brightness ?? 1,
132
+ mode: f.mode ?? "mono",
133
+ cut: f.cut ?? !0,
134
+ align: f.align ?? "center"
135
+ };
136
+ }
137
+ async ensureSDKLoaded() {
138
+ if (isEpsonSDKLoaded()) return !0;
139
+ if (this.initPromise) return this.initPromise;
140
+ debug("EposPrintService: Loading Epson SDK..."), this.initPromise = loadEpsonSDK();
141
+ let e = await this.initPromise;
142
+ return this.initPromise = null, e || error("EposPrintService: Failed to load SDK"), e;
143
+ }
144
+ getPrinterUrl() {
145
+ let { printerIP: e, printerPort: f, deviceId: p, timeout: m } = this.config;
146
+ return `http://${e}:${f}/cgi-bin/epos/service.cgi?devid=${p}&timeout=${m}`;
147
+ }
148
+ async printCanvas(e) {
149
+ return await this.ensureSDKLoaded() ? new Promise((f) => {
150
+ let p = !1, m = (e) => {
151
+ p || (p = !0, f(e));
152
+ }, h = setTimeout(() => {
153
+ error("printCanvas: timeout reached"), m({
154
+ success: !1,
155
+ code: "TIMEOUT",
156
+ message: `Sin respuesta de la impresora después de ${this.config.timeout}ms. Verifica la IP y puerto.`
157
+ });
158
+ }, this.config.timeout + 5e3);
159
+ try {
160
+ let f = getEpsonSDK(), p = this.getPrinterUrl(), _ = new f.ePOSBuilder();
161
+ _.halftone = this.printOptions.halftone ?? 1, _.brightness = this.printOptions.brightness ?? 1;
162
+ let y = e.getContext("2d");
163
+ if (!y) {
164
+ clearTimeout(h), m({
165
+ success: !1,
166
+ code: "CANVAS_ERROR",
167
+ message: "No se pudo obtener el contexto 2D del canvas"
168
+ });
169
+ return;
170
+ }
171
+ debug("printCanvas: Building commands for canvas:", e.width, "x", e.height);
172
+ let b = this.getAlignValue(this.printOptions.align);
173
+ _.addTextAlign(b), _.addImage(y, 0, 0, e.width, e.height), this.printOptions.cut && _.addCut(_.CUT_FEED);
174
+ let x = _.toString();
175
+ debug("printCanvas: XML length:", x.length);
176
+ let S = new f.ePOSPrint(p);
177
+ S.timeout = this.config.timeout, S.onreceive = (e) => {
178
+ debug("printCanvas onreceive:", e), clearTimeout(h), m({
179
+ success: e.success,
180
+ code: e.code,
181
+ status: e.status,
182
+ message: e.success ? "Impresión exitosa" : `Error: ${e.code}`,
183
+ printjobid: e.printjobid
184
+ });
185
+ }, S.onerror = (e) => {
186
+ error("printCanvas onerror:", e), clearTimeout(h), m({
187
+ success: !1,
188
+ code: "NETWORK_ERROR",
189
+ status: e?.status,
190
+ message: `Error de red: ${e?.responseText || "Sin conexión"}`
191
+ });
192
+ }, debug("printCanvas: Sending XML to printer..."), S.send(x);
193
+ } catch (e) {
194
+ error("printCanvas error:", e), clearTimeout(h), m({
195
+ success: !1,
196
+ code: "SDK_ERROR",
197
+ message: e instanceof Error ? e.message : "Error desconocido"
198
+ });
199
+ }
200
+ }) : {
201
+ success: !1,
202
+ code: "SDK_NOT_LOADED",
203
+ message: "Failed to load Epson ePOS SDK. Check console for details."
204
+ };
205
+ }
206
+ getAlignValue(e) {
207
+ switch (e) {
208
+ case "left": return "left";
209
+ case "right": return "right";
210
+ case "center":
211
+ default: return "center";
212
+ }
213
+ }
214
+ async printWithBuilder(e) {
215
+ return await this.ensureSDKLoaded() ? new Promise((f) => {
216
+ let p = !1, m = (e) => {
217
+ p || (p = !0, f(e));
218
+ }, h = setTimeout(() => {
219
+ error("printWithBuilder: timeout reached"), m({
220
+ success: !1,
221
+ code: "TIMEOUT",
222
+ message: `Sin respuesta de la impresora después de ${this.config.timeout}ms. Verifica la IP y puerto.`
223
+ });
224
+ }, this.config.timeout + 5e3);
225
+ try {
226
+ let f = getEpsonSDK(), p = this.getPrinterUrl();
227
+ debug("printWithBuilder: Creating ePOSPrint with URL:", p);
228
+ let _ = new f.ePOSBuilder();
229
+ _.halftone = this.printOptions.halftone ?? 1, _.brightness = this.printOptions.brightness ?? 1, debug("printWithBuilder: Building commands..."), e(_);
230
+ let y = _.toString();
231
+ debug("printWithBuilder: XML to send:", y);
232
+ let b = new f.ePOSPrint(p);
233
+ b.timeout = this.config.timeout, b.onreceive = (e) => {
234
+ debug("ePOSPrint onreceive:", e), clearTimeout(h), m({
235
+ success: e.success,
236
+ code: e.code,
237
+ status: e.status,
238
+ message: e.success ? "Impresión exitosa" : `Error: ${e.code}`,
239
+ printjobid: e.printjobid
240
+ });
241
+ }, b.onerror = (e) => {
242
+ error("ePOSPrint onerror:", e), clearTimeout(h), m({
243
+ success: !1,
244
+ code: "NETWORK_ERROR",
245
+ status: e?.status,
246
+ message: `Error de red: ${e?.responseText || "Sin conexión"}`
247
+ });
248
+ }, debug("printWithBuilder: Calling printer.send(xml)"), b.send(y);
249
+ } catch (e) {
250
+ error("printWithBuilder error:", e), f({
251
+ success: !1,
252
+ code: "SDK_ERROR",
253
+ message: e instanceof Error ? e.message : "Error desconocido"
254
+ });
255
+ }
256
+ }) : {
257
+ success: !1,
258
+ code: "SDK_NOT_LOADED",
259
+ message: "Failed to load Epson ePOS SDK"
260
+ };
261
+ }
262
+ async printPages(e, f) {
263
+ return await this.ensureSDKLoaded() ? new Promise((p) => {
264
+ let m = !1, h = (e) => {
265
+ m || (m = !0, p(e));
266
+ }, _ = setTimeout(() => {
267
+ error("printPages: timeout reached"), h({
268
+ success: !1,
269
+ code: "TIMEOUT",
270
+ message: `Sin respuesta de la impresora después de ${this.config.timeout}ms`
271
+ });
272
+ }, this.config.timeout + 1e4);
273
+ try {
274
+ let p = getEpsonSDK(), m = new p.ePOSBuilder();
275
+ m.halftone = this.printOptions.halftone ?? 1, m.brightness = this.printOptions.brightness ?? 1, f?.header && (m.addTextAlign("center"), m.addTextStyle(!1, !1, !0), m.addTextSize(2, 2), m.addText(f.header + "\n"), m.addTextSize(1, 1), m.addTextStyle(!1, !1, !1), m.addFeedLine(1)), e.forEach((p, h) => {
276
+ let g = p.getContext("2d");
277
+ g && (m.addTextAlign(this.printOptions.align ?? "center"), m.addImage(g, 0, 0, p.width, p.height, "color_1", this.printOptions.mode ?? "mono")), f?.pageSeparator && h < e.length - 1 && (m.addFeedLine(2), m.addTextAlign("center"), m.addText("- - - - - - - - - -\n"), m.addFeedLine(2));
278
+ }), f?.footer && (m.addFeedLine(1), m.addTextAlign("center"), m.addText(f.footer + "\n")), m.addFeedLine(3), this.printOptions.cut && m.addCut("feed");
279
+ let y = m.toString();
280
+ debug("printPages: XML to send (first 500 chars):", y.substring(0, 500));
281
+ let b = new p.ePOSPrint(this.getPrinterUrl());
282
+ b.timeout = this.config.timeout, b.onreceive = (e) => {
283
+ debug("printPages onreceive:", e), clearTimeout(_), h({
284
+ success: e.success,
285
+ code: e.code,
286
+ status: e.status,
287
+ message: e.success ? "Impresión exitosa" : `Error: ${e.code}`,
288
+ printjobid: e.printjobid
289
+ });
290
+ }, b.onerror = (e) => {
291
+ error("printPages onerror:", e), clearTimeout(_), h({
292
+ success: !1,
293
+ code: "NETWORK_ERROR",
294
+ status: e?.status,
295
+ message: `Error de red: ${e?.responseText || "Sin conexión"}`
296
+ });
297
+ }, debug("printPages: sending to printer, pages:", e.length), b.send(y);
298
+ } catch (e) {
299
+ error("printPages error:", e), clearTimeout(_), h({
300
+ success: !1,
301
+ code: "SDK_ERROR",
302
+ message: e instanceof Error ? e.message : "Error desconocido"
303
+ });
304
+ }
305
+ }) : {
306
+ success: !1,
307
+ code: "SDK_NOT_LOADED",
308
+ message: "Failed to load Epson ePOS SDK"
309
+ };
310
+ }
311
+ testConnection() {
312
+ return debug("testConnection: starting..."), this.printWithBuilder((e) => {
313
+ e.addTextAlign("center"), e.addText("Test de conexión\n"), e.addFeedLine(3), e.addCut("feed");
314
+ });
315
+ }
316
+ printTestPage() {
317
+ return debug("printTestPage: starting..."), this.printWithBuilder((e) => {
318
+ e.addTextAlign("center"), e.addTextStyle(!1, !1, !0), e.addTextSize(2, 2), e.addText("PÁGINA DE PRUEBA\n"), e.addTextSize(1, 1), e.addTextStyle(!1, !1, !1), e.addFeedLine(1), e.addText("================================\n"), e.addTextAlign("left"), e.addText("Impresora: " + this.config.printerIP + "\n"), e.addText("Puerto: " + this.config.printerPort + "\n"), e.addText("Device ID: " + this.config.deviceId + "\n"), e.addText("Halftone: " + this.printOptions.halftone + "\n"), e.addText("Brightness: " + this.printOptions.brightness + "\n"), e.addText("Mode: " + this.printOptions.mode + "\n"), e.addText("================================\n"), e.addFeedLine(1), e.addTextAlign("center"), e.addText("Fecha: " + (/* @__PURE__ */ new Date()).toLocaleString() + "\n"), e.addFeedLine(3), e.addCut("feed");
319
+ });
320
+ }
321
+ }, PDFJS_VERSION = "4.10.38";
322
+ pdfjsLib.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${PDFJS_VERSION}/build/pdf.worker.min.mjs`;
323
+ const DEFAULT_PDF_CONFIG = {
324
+ enabled: !0,
325
+ trimMargins: {
326
+ top: 8,
327
+ bottom: 8,
328
+ left: 8,
329
+ right: 8
330
+ },
331
+ targetWidth: 576,
332
+ scale: 3,
333
+ monochromeThreshold: 160
334
+ };
335
+ function trimCanvasMargins(e, f) {
336
+ let p = e.getContext("2d").getImageData(0, 0, e.width, e.height).data, m = e.width, h = e.height, g = 0, _ = h - 1, v = 0, y = m - 1;
337
+ topLoop: for (let e = 0; e < h; e++) for (let f = 0; f < m; f++) {
338
+ let h = (e * m + f) * 4;
339
+ if (p[h] < 250 || p[h + 1] < 250 || p[h + 2] < 250) {
340
+ g = e;
341
+ break topLoop;
342
+ }
343
+ }
344
+ bottomLoop: for (let e = h - 1; e >= 0; e--) for (let f = 0; f < m; f++) {
345
+ let h = (e * m + f) * 4;
346
+ if (p[h] < 250 || p[h + 1] < 250 || p[h + 2] < 250) {
347
+ _ = e;
348
+ break bottomLoop;
349
+ }
350
+ }
351
+ leftLoop: for (let e = 0; e < m; e++) for (let f = 0; f < h; f++) {
352
+ let h = (f * m + e) * 4;
353
+ if (p[h] < 250 || p[h + 1] < 250 || p[h + 2] < 250) {
354
+ v = e;
355
+ break leftLoop;
356
+ }
357
+ }
358
+ rightLoop: for (let e = m - 1; e >= 0; e--) for (let f = 0; f < h; f++) {
359
+ let h = (f * m + e) * 4;
360
+ if (p[h] < 250 || p[h + 1] < 250 || p[h + 2] < 250) {
361
+ y = e;
362
+ break rightLoop;
363
+ }
364
+ }
365
+ g = Math.max(0, g - f.top), _ = Math.min(h - 1, _ + f.bottom), v = Math.max(0, v - f.left), y = Math.min(m - 1, y + f.right);
366
+ let b = y - v + 1, x = _ - g + 1;
367
+ if (b >= m - 10 && x >= h - 10) return e;
368
+ let S = document.createElement("canvas");
369
+ S.width = b, S.height = x;
370
+ let C = S.getContext("2d");
371
+ return C.fillStyle = "white", C.fillRect(0, 0, b, x), C.drawImage(e, v, g, b, x, 0, 0, b, x), S;
372
+ }
373
+ function canvasToRasterData(e, f) {
374
+ let p = e.getContext("2d").getImageData(0, 0, e.width, e.height).data, m = Math.ceil(e.width / 8) * 8, h = e.height, g = m / 8, _ = new Uint8Array(g * h);
375
+ for (let v = 0; v < h; v++) for (let h = 0; h < m; h++) {
376
+ let m = Math.min(h, e.width - 1), y = (v * e.width + m) * 4, b = p[y], x = p[y + 1], S = p[y + 2], C = .299 * b + .587 * x + .114 * S < f ? 1 : 0, w = v * g + Math.floor(h / 8), T = 7 - h % 8;
377
+ C && (_[w] |= 1 << T);
378
+ }
379
+ let v = "";
380
+ for (let e = 0; e < _.length; e++) v += String.fromCharCode(_[e]);
381
+ return btoa(v);
382
+ }
383
+ async function processPdfPage(e, f = DEFAULT_PDF_CONFIG) {
384
+ let p = {
385
+ ...DEFAULT_PDF_CONFIG,
386
+ ...f,
387
+ trimMargins: {
388
+ ...DEFAULT_PDF_CONFIG.trimMargins,
389
+ ...f.trimMargins
390
+ }
391
+ }, m = p.scale, h = e.getViewport({ scale: m }), g = document.createElement("canvas");
392
+ g.width = h.width, g.height = h.height;
393
+ let _ = g.getContext("2d");
394
+ _.fillStyle = "white", _.fillRect(0, 0, g.width, g.height), await e.render({
395
+ canvasContext: _,
396
+ viewport: h,
397
+ canvas: g
398
+ }).promise;
399
+ let v = g;
400
+ if (p.enabled) {
401
+ let e = {
402
+ top: p.trimMargins.top ?? 8,
403
+ bottom: p.trimMargins.bottom ?? 8,
404
+ left: p.trimMargins.left ?? 8,
405
+ right: p.trimMargins.right ?? 8
406
+ };
407
+ v = trimCanvasMargins(v, e);
408
+ }
409
+ let y = v;
410
+ if (p.enabled && p.targetWidth) {
411
+ let e = p.targetWidth, f = v.height / v.width, m = Math.round(e * f), h = document.createElement("canvas");
412
+ h.width = e, h.height = m;
413
+ let g = h.getContext("2d");
414
+ g.fillStyle = "white", g.fillRect(0, 0, e, m), g.drawImage(v, 0, 0, e, m), y = h;
415
+ }
416
+ let b = y.toDataURL("image/png"), x = canvasToRasterData(y, p.monochromeThreshold);
417
+ return {
418
+ base64: b,
419
+ width: y.width,
420
+ height: y.height,
421
+ rasterBase64: x,
422
+ canvas: y
423
+ };
424
+ }
425
+ async function processPdfFile(f, p = DEFAULT_PDF_CONFIG) {
426
+ let m = await f.arrayBuffer(), h = await pdfjsLib.getDocument({ data: m }).promise, g = [];
427
+ for (let e = 1; e <= h.numPages; e++) {
428
+ let f = await processPdfPage(await h.getPage(e), p);
429
+ g.push(f);
430
+ }
431
+ return g;
432
+ }
433
+ export { checkEpsonSDKStatus as a, initializeEpsonSDK as c, resetLoaderState as d, configureLogger as f, getLoggerConfig as h, EposPrintService as i, isEpsonSDKLoaded as l, error as m, processPdfFile as n, getEpsonSDK as o, debug as p, processPdfPage as r, getLoaderState as s, DEFAULT_PDF_CONFIG as t, loadEpsonSDK as u };
434
+
435
+ //# sourceMappingURL=pdf-processor-B7cA9poK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-processor-B7cA9poK.js","names":["config: LoggerConfig","entry: LogEntry","state: LoaderState","classes: string[]","results: { canvas: HTMLCanvasElement; width: number; height: number }[]","DEFAULT_PDF_CONFIG: Required<PdfProcessingConfig>","pages: ProcessedPage[]"],"sources":["../src/lib/logger.ts","../src/lib/epson-sdk-loader.ts","../src/lib/epos-print.ts","../src/lib/pdf-processor.ts"],"sourcesContent":["/**\n * Configurable logger for @plevands/epson-thermal-printer\n * - Errors are always shown in console\n * - Debug/warn logs are controlled by `enabled` config\n * - All logs can be intercepted via `onLog` callback\n */\n\nimport type { LogLevel, LogEntry, LoggerConfig } from '../types';\n\nconst config: LoggerConfig = {\n enabled: false,\n onLog: undefined,\n};\n\n/**\n * Configure the logger\n * @param newConfig - Logger configuration options\n */\nexport function configureLogger(newConfig: Partial<LoggerConfig>): void {\n if (newConfig.enabled !== undefined) {\n config.enabled = newConfig.enabled;\n }\n if (newConfig.onLog !== undefined) {\n config.onLog = newConfig.onLog;\n }\n}\n\n/**\n * Get current logger configuration\n */\nexport function getLoggerConfig(): Readonly<LoggerConfig> {\n return { ...config };\n}\n\n/**\n * Internal function to handle logging\n */\nfunction log(level: LogLevel, message: string, ...args: unknown[]): void {\n const entry: LogEntry = {\n level,\n message,\n args: args.length > 0 ? args : undefined,\n };\n\n // Always call the callback if provided (for all levels including errors)\n if (config.onLog) {\n config.onLog(entry);\n }\n\n // Errors are always shown in console\n if (level === 'error') {\n console.error(`[epson-printer] ${message}`, ...args);\n return;\n }\n\n // Debug and warn only show if enabled\n if (config.enabled) {\n if (level === 'warn') {\n console.warn(`[epson-printer] ${message}`, ...args);\n } else {\n console.log(`[epson-printer] ${message}`, ...args);\n }\n }\n}\n\n/**\n * Log debug message (only when enabled)\n */\nexport function debug(message: string, ...args: unknown[]): void {\n log('debug', message, ...args);\n}\n\n/**\n * Log warning message (only when enabled)\n */\nexport function warn(message: string, ...args: unknown[]): void {\n log('warn', message, ...args);\n}\n\n/**\n * Log error message (always shown)\n */\nexport function error(message: string, ...args: unknown[]): void {\n log('error', message, ...args);\n}\n\nexport const logger = {\n debug,\n warn,\n error,\n configure: configureLogger,\n getConfig: getLoggerConfig,\n};\n","/**\n * Dynamic loader for Epson ePOS SDK\n * Implements singleton pattern to avoid multiple loads\n */\n\nimport { debug, warn, error } from './logger';\n\ninterface LoaderState {\n loading: boolean;\n loaded: boolean;\n error: Error | null;\n promise: Promise<boolean> | null;\n}\n\nconst state: LoaderState = {\n loading: false,\n loaded: false,\n error: null,\n promise: null,\n};\n\n/**\n * Check if SDK is already available in window\n */\nexport function isEpsonSDKLoaded(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.epson !== 'undefined' &&\n typeof window.epson.ePOSPrint !== 'undefined'\n );\n}\n\n/**\n * Get the SDK path - can be customized based on environment\n */\nfunction getSDKPath(): string {\n // In development mode, load from public folder\n if (import.meta.env.DEV) {\n return '/epos-2.27.0.js';\n }\n \n // In production/library mode, load from bundled assets\n // The SDK will be in dist/assets after build\n try {\n return new URL('../../dist/assets/epos-2.27.0.js', import.meta.url).href;\n } catch {\n // Fallback to relative path\n return '/epos-2.27.0.js';\n }\n}\n\n/**\n * Load SDK script dynamically\n */\nfunction loadScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // Check if script already exists in DOM\n const existing = document.querySelector(`script[src=\"${src}\"]`);\n if (existing) {\n resolve();\n return;\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.type = 'text/javascript';\n script.async = true;\n\n script.onload = () => {\n debug('Epson SDK loaded successfully from:', src);\n resolve();\n };\n\n script.onerror = (err) => {\n error('Failed to load Epson SDK from:', src, err);\n reject(new Error(`Failed to load Epson SDK from ${src}`));\n };\n\n document.head.appendChild(script);\n });\n}\n\n/**\n * Wait for SDK to be available in window with timeout\n */\nfunction waitForSDKAvailable(maxWait: number = 10000): Promise<boolean> {\n return new Promise((resolve) => {\n const start = Date.now();\n \n const check = () => {\n if (isEpsonSDKLoaded()) {\n resolve(true);\n return;\n }\n \n if (Date.now() - start > maxWait) {\n warn('Timeout waiting for Epson SDK to be available');\n resolve(false);\n return;\n }\n \n setTimeout(check, 100);\n };\n \n check();\n });\n}\n\n/**\n * Load Epson SDK dynamically (singleton pattern)\n * Returns true if loaded successfully, false otherwise\n */\nexport async function loadEpsonSDK(options?: {\n sdkPath?: string;\n timeout?: number;\n}): Promise<boolean> {\n // Already loaded\n if (state.loaded || isEpsonSDKLoaded()) {\n state.loaded = true;\n state.loading = false;\n return true;\n }\n\n // Currently loading - return existing promise\n if (state.loading && state.promise) {\n return state.promise;\n }\n\n // Start loading\n state.loading = true;\n state.error = null;\n\n state.promise = (async () => {\n try {\n const sdkPath = options?.sdkPath || getSDKPath();\n const timeout = options?.timeout || 10000;\n\n debug('Loading Epson SDK from:', sdkPath);\n\n // Load the script\n await loadScript(sdkPath);\n\n // Wait for SDK to be available\n const available = await waitForSDKAvailable(timeout);\n\n if (!available) {\n throw new Error('Epson SDK loaded but not available in window.epson');\n }\n\n state.loaded = true;\n state.loading = false;\n debug('Epson SDK ready');\n return true;\n\n } catch (err) {\n state.error = err instanceof Error ? err : new Error(String(err));\n state.loading = false;\n state.loaded = false;\n error('Failed to load Epson SDK:', state.error);\n return false;\n }\n })();\n\n return state.promise;\n}\n\n/**\n * Get current loader state\n */\nexport function getLoaderState(): Readonly<LoaderState> {\n return { ...state };\n}\n\n/**\n * Reset loader state (useful for testing)\n */\nexport function resetLoaderState(): void {\n state.loading = false;\n state.loaded = false;\n state.error = null;\n state.promise = null;\n}\n\n/**\n * Get Epson SDK (throws if not loaded)\n */\nexport function getEpsonSDK(): typeof window.epson {\n if (!isEpsonSDKLoaded()) {\n throw new Error(\n 'Epson SDK not loaded. Call loadEpsonSDK() first or wait for automatic loading.'\n );\n }\n return window.epson;\n}\n\n/**\n * Initialize SDK (optional - for eager loading)\n */\nexport async function initializeEpsonSDK(options?: {\n sdkPath?: string;\n timeout?: number;\n}): Promise<{ success: boolean; error?: string }> {\n try {\n const loaded = await loadEpsonSDK(options);\n \n if (!loaded) {\n const loaderState = getLoaderState();\n return {\n success: false,\n error: loaderState.error?.message || 'Failed to load Epson SDK',\n };\n }\n \n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n","/**\n * ePOS Print SDK Wrapper\n * Uses the official Epson ePOS SDK (epos-2.27.0.js) with dynamic loading\n */\n\nimport type { epson } from './epson-sdk';\nimport { \n loadEpsonSDK, \n isEpsonSDKLoaded, \n getEpsonSDK,\n getLoaderState,\n initializeEpsonSDK,\n} from './epson-sdk-loader';\nimport { debug, error } from './logger';\n\n// Re-export types from central types file\nexport type { EpsonPrinterConfig, PrintResult, PrintOptions } from '../types';\n\n// Import types for internal use\nimport type { EpsonPrinterConfig, PrintResult, PrintOptions } from '../types';\n\n// Re-export SDK loader functions\nexport { \n loadEpsonSDK, \n isEpsonSDKLoaded, \n initializeEpsonSDK,\n getLoaderState,\n};\n\n/**\n * Check SDK status - useful for debugging\n */\nexport function checkEpsonSDKStatus(): { \n loaded: boolean; \n loading: boolean;\n error: Error | null;\n classes: string[] \n} {\n const loaderState = getLoaderState();\n const epson = window.epson;\n const classes: string[] = [];\n \n if (epson) {\n if (epson.ePOSBuilder) classes.push('ePOSBuilder');\n if (epson.ePOSPrint) classes.push('ePOSPrint');\n if (epson.CanvasPrint) classes.push('CanvasPrint');\n if (epson.ePOSDevice) classes.push('ePOSDevice');\n }\n \n return {\n loaded: loaderState.loaded || isEpsonSDKLoaded(),\n loading: loaderState.loading,\n error: loaderState.error,\n classes,\n };\n}\n\n/**\n * ePOS Print Service using official SDK\n */\nexport class EposPrintService {\n private config: Required<EpsonPrinterConfig>;\n private printOptions: PrintOptions;\n private initPromise: Promise<boolean> | null = null;\n\n constructor(config: EpsonPrinterConfig, options: PrintOptions = {}) {\n this.config = {\n printerIP: config.printerIP,\n printerPort: config.printerPort ?? 80,\n deviceId: config.deviceId ?? 'local_printer',\n timeout: config.timeout ?? 60000,\n };\n this.printOptions = {\n halftone: options.halftone ?? 1,\n brightness: options.brightness ?? 1.0,\n mode: options.mode ?? 'mono',\n cut: options.cut ?? true,\n align: options.align ?? 'center',\n };\n }\n\n /**\n * Ensure SDK is loaded before any print operation (lazy loading)\n */\n private async ensureSDKLoaded(): Promise<boolean> {\n // Already loaded\n if (isEpsonSDKLoaded()) {\n return true;\n }\n\n // Loading in progress\n if (this.initPromise) {\n return this.initPromise;\n }\n\n // Start loading\n debug('EposPrintService: Loading Epson SDK...');\n this.initPromise = loadEpsonSDK();\n const result = await this.initPromise;\n this.initPromise = null;\n \n if (!result) {\n error('EposPrintService: Failed to load SDK');\n }\n \n return result;\n }\n\n /**\n * Get the printer URL for ePOS Print\n */\n private getPrinterUrl(): string {\n const { printerIP, printerPort, deviceId, timeout } = this.config;\n return `http://${printerIP}:${printerPort}/cgi-bin/epos/service.cgi?devid=${deviceId}&timeout=${timeout}`;\n }\n\n /**\n * Print a canvas element using ePOSBuilder\n * \n * IMPORTANT: We don't use CanvasPrint.print() directly due to an SDK bug.\n * The SDK's prototypal inheritance causes CanvasPrint.print() to call\n * this.send(printjobid) which internally creates a new empty ePOSBuilder,\n * ignoring all the commands built in 'this'.\n * \n * Instead, we use ePOSBuilder to construct the print commands manually,\n * get the XML, and send it via ePOSPrint.send(xml).\n */\n async printCanvas(canvas: HTMLCanvasElement): Promise<PrintResult> {\n // Ensure SDK is loaded first\n const sdkLoaded = await this.ensureSDKLoaded();\n if (!sdkLoaded) {\n return {\n success: false,\n code: 'SDK_NOT_LOADED',\n message: 'Failed to load Epson ePOS SDK. Check console for details.',\n };\n }\n\n return new Promise((resolve) => {\n let resolved = false;\n \n const doResolve = (result: PrintResult) => {\n if (!resolved) {\n resolved = true;\n resolve(result);\n }\n };\n\n // Timeout in case printer doesn't respond\n const timeoutId = setTimeout(() => {\n error('printCanvas: timeout reached');\n doResolve({\n success: false,\n code: 'TIMEOUT',\n message: `Sin respuesta de la impresora después de ${this.config.timeout}ms. Verifica la IP y puerto.`,\n });\n }, this.config.timeout + 5000);\n\n try {\n const epson = getEpsonSDK();\n const printerUrl = this.getPrinterUrl();\n \n // Use separate ePOSBuilder to construct the message\n // This avoids the SDK inheritance bug where send() creates a new empty builder\n const builder = new epson.ePOSBuilder();\n builder.halftone = this.printOptions.halftone ?? 1;\n builder.brightness = this.printOptions.brightness ?? 1.0;\n \n // Get canvas context\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n clearTimeout(timeoutId);\n doResolve({\n success: false,\n code: 'CANVAS_ERROR',\n message: 'No se pudo obtener el contexto 2D del canvas',\n });\n return;\n }\n \n // Build print commands using builder\n debug('printCanvas: Building commands for canvas:', canvas.width, 'x', canvas.height);\n // Access alignment constants from the builder instance (they are instance properties, not static)\n const alignValue = this.getAlignValue(this.printOptions.align);\n builder.addTextAlign(alignValue);\n builder.addImage(ctx, 0, 0, canvas.width, canvas.height);\n \n if (this.printOptions.cut) {\n builder.addCut(builder.CUT_FEED);\n }\n \n // Get the XML from builder\n const xml = builder.toString();\n debug('printCanvas: XML length:', xml.length);\n \n // Create printer for sending\n const printer = new epson.ePOSPrint(printerUrl);\n printer.timeout = this.config.timeout;\n\n // Set callbacks BEFORE sending\n printer.onreceive = (res) => {\n debug('printCanvas onreceive:', res);\n clearTimeout(timeoutId);\n doResolve({\n success: res.success,\n code: res.code,\n status: res.status,\n message: res.success ? 'Impresión exitosa' : `Error: ${res.code}`,\n printjobid: res.printjobid,\n });\n };\n\n printer.onerror = (err) => {\n error('printCanvas onerror:', err);\n clearTimeout(timeoutId);\n doResolve({\n success: false,\n code: 'NETWORK_ERROR',\n status: err?.status,\n message: `Error de red: ${err?.responseText || 'Sin conexión'}`,\n });\n };\n\n // Send the XML directly\n debug('printCanvas: Sending XML to printer...');\n printer.send(xml);\n } catch (err) {\n error('printCanvas error:', err);\n clearTimeout(timeoutId);\n doResolve({\n success: false,\n code: 'SDK_ERROR',\n message: err instanceof Error ? err.message : 'Error desconocido',\n });\n }\n });\n }\n \n /**\n * Get alignment value for SDK (instance property values are strings)\n */\n private getAlignValue(align?: string): 'left' | 'center' | 'right' {\n switch (align) {\n case 'left':\n return 'left';\n case 'right':\n return 'right';\n case 'center':\n default:\n return 'center';\n }\n }\n\n /**\n * Print using ePOSPrint with builder pattern\n */\n async printWithBuilder(buildFn: (builder: epson.ePOSBuilder) => void): Promise<PrintResult> {\n // Ensure SDK is loaded first\n const sdkLoaded = await this.ensureSDKLoaded();\n if (!sdkLoaded) {\n return {\n success: false,\n code: 'SDK_NOT_LOADED',\n message: 'Failed to load Epson ePOS SDK',\n };\n }\n\n return new Promise((resolve) => {\n let resolved = false;\n \n const doResolve = (result: PrintResult) => {\n if (!resolved) {\n resolved = true;\n resolve(result);\n }\n };\n\n // Timeout in case printer doesn't respond\n const timeoutId = setTimeout(() => {\n error('printWithBuilder: timeout reached');\n doResolve({\n success: false,\n code: 'TIMEOUT',\n message: `Sin respuesta de la impresora después de ${this.config.timeout}ms. Verifica la IP y puerto.`,\n });\n }, this.config.timeout + 5000);\n\n try {\n const epson = getEpsonSDK();\n const printerUrl = this.getPrinterUrl();\n debug('printWithBuilder: Creating ePOSPrint with URL:', printerUrl);\n \n // Use separate ePOSBuilder to construct the message\n const builder = new epson.ePOSBuilder();\n builder.halftone = this.printOptions.halftone ?? 1;\n builder.brightness = this.printOptions.brightness ?? 1.0;\n \n // Build commands using the builder\n debug('printWithBuilder: Building commands...');\n buildFn(builder);\n \n // Get the XML from builder\n const xml = builder.toString();\n debug('printWithBuilder: XML to send:', xml);\n \n // Create printer for sending\n const printer = new epson.ePOSPrint(printerUrl);\n printer.timeout = this.config.timeout;\n\n // Set callbacks BEFORE sending\n printer.onreceive = (res) => {\n debug('ePOSPrint onreceive:', res);\n clearTimeout(timeoutId);\n doResolve({\n success: res.success,\n code: res.code,\n status: res.status,\n message: res.success ? 'Impresión exitosa' : `Error: ${res.code}`,\n printjobid: res.printjobid,\n });\n };\n\n printer.onerror = (err) => {\n error('ePOSPrint onerror:', err);\n clearTimeout(timeoutId);\n doResolve({\n success: false,\n code: 'NETWORK_ERROR',\n status: err?.status,\n message: `Error de red: ${err?.responseText || 'Sin conexión'}`,\n });\n };\n\n // Send XML to printer\n debug('printWithBuilder: Calling printer.send(xml)');\n printer.send(xml);\n } catch (err) {\n error('printWithBuilder error:', err);\n resolve({\n success: false,\n code: 'SDK_ERROR',\n message: err instanceof Error ? err.message : 'Error desconocido',\n });\n }\n });\n }\n\n /**\n * Print multiple canvases (pages) with optional header/footer\n */\n async printPages(\n canvases: HTMLCanvasElement[],\n options?: {\n header?: string;\n footer?: string;\n pageSeparator?: boolean;\n }\n ): Promise<PrintResult> {\n // Ensure SDK is loaded first\n const sdkLoaded = await this.ensureSDKLoaded();\n if (!sdkLoaded) {\n return {\n success: false,\n code: 'SDK_NOT_LOADED',\n message: 'Failed to load Epson ePOS SDK',\n };\n }\n\n return new Promise((resolve) => {\n let resolved = false;\n \n const doResolve = (result: PrintResult) => {\n if (!resolved) {\n resolved = true;\n resolve(result);\n }\n };\n\n // Timeout in case printer doesn't respond\n const timeoutId = setTimeout(() => {\n error('printPages: timeout reached');\n doResolve({\n success: false,\n code: 'TIMEOUT',\n message: `Sin respuesta de la impresora después de ${this.config.timeout}ms`,\n });\n }, this.config.timeout + 10000); // Extra time for multiple pages\n\n try {\n const epson = getEpsonSDK();\n \n // Use separate ePOSBuilder to construct the message\n const builder = new epson.ePOSBuilder();\n builder.halftone = this.printOptions.halftone ?? 1;\n builder.brightness = this.printOptions.brightness ?? 1.0;\n\n // Add header if provided\n if (options?.header) {\n builder.addTextAlign('center');\n builder.addTextStyle(false, false, true); // Bold\n builder.addTextSize(2, 2);\n builder.addText(options.header + '\\n');\n builder.addTextSize(1, 1);\n builder.addTextStyle(false, false, false);\n builder.addFeedLine(1);\n }\n\n // Add each page\n canvases.forEach((canvas, index) => {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n builder.addTextAlign(this.printOptions.align ?? 'center');\n builder.addImage(\n ctx,\n 0, 0,\n canvas.width,\n canvas.height,\n 'color_1',\n this.printOptions.mode ?? 'mono'\n );\n }\n\n // Add separator between pages\n if (options?.pageSeparator && index < canvases.length - 1) {\n builder.addFeedLine(2);\n builder.addTextAlign('center');\n builder.addText('- - - - - - - - - -\\n');\n builder.addFeedLine(2);\n }\n });\n\n // Add footer if provided\n if (options?.footer) {\n builder.addFeedLine(1);\n builder.addTextAlign('center');\n builder.addText(options.footer + '\\n');\n }\n\n // Final feed and cut\n builder.addFeedLine(3);\n if (this.printOptions.cut) {\n builder.addCut('feed');\n }\n\n // Get the XML from builder\n const xml = builder.toString();\n debug('printPages: XML to send (first 500 chars):', xml.substring(0, 500));\n\n // Create printer for sending\n const printer = new epson.ePOSPrint(this.getPrinterUrl());\n printer.timeout = this.config.timeout;\n\n // Set callbacks\n printer.onreceive = (res) => {\n debug('printPages onreceive:', res);\n clearTimeout(timeoutId);\n doResolve({\n success: res.success,\n code: res.code,\n status: res.status,\n message: res.success ? 'Impresión exitosa' : `Error: ${res.code}`,\n printjobid: res.printjobid,\n });\n };\n\n printer.onerror = (err) => {\n error('printPages onerror:', err);\n clearTimeout(timeoutId);\n doResolve({\n success: false,\n code: 'NETWORK_ERROR',\n status: err?.status,\n message: `Error de red: ${err?.responseText || 'Sin conexión'}`,\n });\n };\n\n // Send XML to printer\n debug('printPages: sending to printer, pages:', canvases.length);\n printer.send(xml);\n } catch (err) {\n error('printPages error:', err);\n clearTimeout(timeoutId);\n doResolve({\n success: false,\n code: 'SDK_ERROR',\n message: err instanceof Error ? err.message : 'Error desconocido',\n });\n }\n });\n }\n\n /**\n * Test printer connection\n */\n testConnection(): Promise<PrintResult> {\n debug('testConnection: starting...');\n return this.printWithBuilder((builder) => {\n builder.addTextAlign('center');\n builder.addText('Test de conexión\\n');\n builder.addFeedLine(3);\n builder.addCut('feed');\n });\n }\n\n /**\n * Print a test page\n */\n printTestPage(): Promise<PrintResult> {\n debug('printTestPage: starting...');\n return this.printWithBuilder((builder) => {\n builder.addTextAlign('center');\n builder.addTextStyle(false, false, true); // Bold\n builder.addTextSize(2, 2);\n builder.addText('PÁGINA DE PRUEBA\\n');\n builder.addTextSize(1, 1);\n builder.addTextStyle(false, false, false);\n builder.addFeedLine(1);\n \n builder.addText('================================\\n');\n builder.addTextAlign('left');\n builder.addText('Impresora: ' + this.config.printerIP + '\\n');\n builder.addText('Puerto: ' + this.config.printerPort + '\\n');\n builder.addText('Device ID: ' + this.config.deviceId + '\\n');\n builder.addText('Halftone: ' + this.printOptions.halftone + '\\n');\n builder.addText('Brightness: ' + this.printOptions.brightness + '\\n');\n builder.addText('Mode: ' + this.printOptions.mode + '\\n');\n builder.addText('================================\\n');\n \n builder.addFeedLine(1);\n builder.addTextAlign('center');\n builder.addText('Fecha: ' + new Date().toLocaleString() + '\\n');\n \n builder.addFeedLine(3);\n builder.addCut('feed');\n });\n }\n}\n\n/**\n * PDF to Canvas conversion utilities\n */\nexport async function pdfToCanvases(\n pdfFile: File,\n options: {\n scale?: number;\n maxWidth?: number;\n } = {}\n): Promise<{ canvas: HTMLCanvasElement; width: number; height: number }[]> {\n const { scale = 2, maxWidth = 576 } = options;\n \n const pdfjsLib = await import('pdfjs-dist');\n pdfjsLib.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`;\n\n const arrayBuffer = await pdfFile.arrayBuffer();\n const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;\n \n const results: { canvas: HTMLCanvasElement; width: number; height: number }[] = [];\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const viewport = page.getViewport({ scale });\n\n let width = viewport.width;\n let height = viewport.height;\n \n if (width > maxWidth) {\n const ratio = maxWidth / width;\n width = maxWidth;\n height = Math.floor(height * ratio);\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n \n const context = canvas.getContext('2d')!;\n context.fillStyle = 'white';\n context.fillRect(0, 0, width, height);\n\n await page.render({\n canvasContext: context,\n viewport: page.getViewport({ scale: (width / viewport.width) * scale }),\n canvas,\n }).promise;\n \n results.push({\n canvas,\n width: Math.floor(width),\n height: Math.floor(height),\n });\n }\n\n return results;\n}\n\n/**\n * Convert image file to canvas\n */\nexport async function imageToCanvas(\n file: File,\n maxWidth: number = 576\n): Promise<{ canvas: HTMLCanvasElement; width: number; height: number }> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const img = new Image();\n img.onload = () => {\n let width = img.width;\n let height = img.height;\n \n if (width > maxWidth) {\n const ratio = maxWidth / width;\n width = maxWidth;\n height = Math.floor(height * ratio);\n }\n \n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n \n const ctx = canvas.getContext('2d')!;\n ctx.fillStyle = 'white';\n ctx.fillRect(0, 0, width, height);\n ctx.drawImage(img, 0, 0, width, height);\n \n resolve({ canvas, width, height });\n };\n img.onerror = reject;\n img.src = reader.result as string;\n };\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n}\n\n// Legacy exports for backward compatibility\nexport class EposPrintBuilder {\n private builder: epson.ePOSBuilder;\n\n constructor() {\n if (!isEpsonSDKLoaded()) {\n throw new Error('Epson ePOS SDK not loaded');\n }\n const epson = getEpsonSDK();\n this.builder = new epson.ePOSBuilder();\n }\n\n reset(): this {\n const epson = getEpsonSDK();\n this.builder = new epson.ePOSBuilder();\n return this;\n }\n\n addText(text: string): this {\n this.builder.addText(text);\n return this;\n }\n\n addTextLine(text: string): this {\n this.builder.addText(text + '\\n');\n return this;\n }\n\n addFeedLine(lines: number = 1): this {\n this.builder.addFeedLine(lines);\n return this;\n }\n\n addCut(type: 'no_feed' | 'feed' | 'reserve' = 'feed'): this {\n this.builder.addCut(type);\n return this;\n }\n\n addTextAlign(align: 'left' | 'center' | 'right'): this {\n this.builder.addTextAlign(align);\n return this;\n }\n\n addTextStyle(reverse = false, underline = false, bold = false, color: 'color_1' | 'color_2' | 'color_3' | 'color_4' = 'color_1'): this {\n this.builder.addTextStyle(reverse, underline, bold, color);\n return this;\n }\n\n addTextSize(width: number = 1, height: number = 1): this {\n this.builder.addTextSize(width, height);\n return this;\n }\n\n addImage(canvas: HTMLCanvasElement, mode: 'mono' | 'gray16' = 'mono'): this {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n this.builder.addImage(ctx, 0, 0, canvas.width, canvas.height, 'color_1', mode);\n }\n return this;\n }\n\n addBarcode(\n data: string,\n type: string = 'code128',\n hri: 'none' | 'above' | 'below' | 'both' = 'below',\n width: number = 2,\n height: number = 100\n ): this {\n this.builder.addBarcode(data, type, hri, 'font_a', width, height);\n return this;\n }\n\n addQRCode(\n data: string,\n type: 'model_1' | 'model_2' | 'micro' = 'model_2',\n level: 'level_l' | 'level_m' | 'level_q' | 'level_h' = 'level_m',\n width: number = 4\n ): this {\n this.builder.addSymbol(data, `qrcode_${type}`, level, width);\n return this;\n }\n\n build(): string {\n return this.builder.toString();\n }\n\n getBuilder(): epson.ePOSBuilder {\n return this.builder;\n }\n}\n\n// Legacy function exports\nexport async function pdfToImages(\n pdfFile: File,\n options: { scale?: number; maxWidth?: number } = {}\n): Promise<{ images: string[]; width: number; height: number }[]> {\n const canvases = await pdfToCanvases(pdfFile, options);\n return canvases.map(({ canvas, width, height }) => ({\n images: [canvas.toDataURL('image/png').split(',')[1]],\n width,\n height,\n }));\n}\n\nexport async function imageToBase64(file: File): Promise<{ base64: string; width: number; height: number }> {\n const { canvas, width, height } = await imageToCanvas(file);\n return {\n base64: canvas.toDataURL('image/png').split(',')[1],\n width,\n height,\n };\n}\n","/**\n * PDF Processing utilities for Epson thermal printers\n * Handles margin trimming, scaling, and monochrome conversion\n */\n\nimport * as pdfjsLib from 'pdfjs-dist';\nimport type { PDFPageProxy } from 'pdfjs-dist';\n\n// Configure PDF.js worker from CDN to avoid bundling\nconst PDFJS_VERSION = '4.10.38';\npdfjsLib.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${PDFJS_VERSION}/build/pdf.worker.min.mjs`;\n\nexport interface PdfProcessingConfig {\n /** Enable PDF processing (trimming, scaling) */\n enabled: boolean;\n /** Margin settings for trimming white space */\n trimMargins?: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n };\n /** Target width for printer paper (576 for 80mm, 384 for 58mm) */\n targetWidth?: number;\n /** Rendering scale for quality (higher = better quality) */\n scale?: number;\n /** Threshold for monochrome conversion (0-255, lower = darker) */\n monochromeThreshold?: number;\n}\n\nexport interface ProcessedPage {\n base64: string;\n width: number;\n height: number;\n rasterBase64: string;\n canvas: HTMLCanvasElement;\n}\n\n/**\n * Default configuration for PDF processing\n */\nexport const DEFAULT_PDF_CONFIG: Required<PdfProcessingConfig> = {\n enabled: true,\n trimMargins: {\n top: 8,\n bottom: 8,\n left: 8,\n right: 8,\n },\n targetWidth: 576, // 80mm paper\n scale: 3,\n monochromeThreshold: 160,\n};\n\n/**\n * Trim white margins from a canvas\n */\nfunction trimCanvasMargins(\n canvas: HTMLCanvasElement,\n margins: { top: number; bottom: number; left: number; right: number }\n): HTMLCanvasElement {\n const ctx = canvas.getContext('2d')!;\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n const pixels = imageData.data;\n const width = canvas.width;\n const height = canvas.height;\n \n // Threshold to consider a pixel \"white\"\n const whiteThreshold = 250;\n \n // Find content boundaries\n let top = 0;\n let bottom = height - 1;\n let left = 0;\n let right = width - 1;\n \n // Find top margin\n topLoop: for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n if (pixels[idx] < whiteThreshold || pixels[idx + 1] < whiteThreshold || pixels[idx + 2] < whiteThreshold) {\n top = y;\n break topLoop;\n }\n }\n }\n \n // Find bottom margin\n bottomLoop: for (let y = height - 1; y >= 0; y--) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n if (pixels[idx] < whiteThreshold || pixels[idx + 1] < whiteThreshold || pixels[idx + 2] < whiteThreshold) {\n bottom = y;\n break bottomLoop;\n }\n }\n }\n \n // Find left margin\n leftLoop: for (let x = 0; x < width; x++) {\n for (let y = 0; y < height; y++) {\n const idx = (y * width + x) * 4;\n if (pixels[idx] < whiteThreshold || pixels[idx + 1] < whiteThreshold || pixels[idx + 2] < whiteThreshold) {\n left = x;\n break leftLoop;\n }\n }\n }\n \n // Find right margin\n rightLoop: for (let x = width - 1; x >= 0; x--) {\n for (let y = 0; y < height; y++) {\n const idx = (y * width + x) * 4;\n if (pixels[idx] < whiteThreshold || pixels[idx + 1] < whiteThreshold || pixels[idx + 2] < whiteThreshold) {\n right = x;\n break rightLoop;\n }\n }\n }\n \n // Apply configured margins\n top = Math.max(0, top - margins.top);\n bottom = Math.min(height - 1, bottom + margins.bottom);\n left = Math.max(0, left - margins.left);\n right = Math.min(width - 1, right + margins.right);\n \n const newWidth = right - left + 1;\n const newHeight = bottom - top + 1;\n \n // If margins are minimal, return original\n if (newWidth >= width - 10 && newHeight >= height - 10) {\n return canvas;\n }\n \n // Create cropped canvas\n const croppedCanvas = document.createElement('canvas');\n croppedCanvas.width = newWidth;\n croppedCanvas.height = newHeight;\n \n const croppedCtx = croppedCanvas.getContext('2d')!;\n croppedCtx.fillStyle = 'white';\n croppedCtx.fillRect(0, 0, newWidth, newHeight);\n croppedCtx.drawImage(canvas, left, top, newWidth, newHeight, 0, 0, newWidth, newHeight);\n \n return croppedCanvas;\n}\n\n/**\n * Convert canvas to monochrome raster data for ePOS Print\n */\nfunction canvasToRasterData(canvas: HTMLCanvasElement, threshold: number): string {\n const ctx = canvas.getContext('2d')!;\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n const pixels = imageData.data;\n \n // Width must be multiple of 8 for mono printing\n const width = Math.ceil(canvas.width / 8) * 8;\n const height = canvas.height;\n \n // Create binary array (1 bit per pixel, 8 pixels per byte)\n const bytesPerLine = width / 8;\n const rasterData = new Uint8Array(bytesPerLine * height);\n \n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const srcX = Math.min(x, canvas.width - 1);\n const pixelIndex = (y * canvas.width + srcX) * 4;\n \n // Get grayscale value using luminance formula\n const r = pixels[pixelIndex];\n const g = pixels[pixelIndex + 1];\n const b = pixels[pixelIndex + 2];\n const gray = 0.299 * r + 0.587 * g + 0.114 * b;\n \n // Convert to 1-bit (1 = black/print, 0 = white/no print)\n const isBlack = gray < threshold ? 1 : 0;\n \n // Set bit in byte (MSB first)\n const byteIndex = y * bytesPerLine + Math.floor(x / 8);\n const bitIndex = 7 - (x % 8);\n \n if (isBlack) {\n rasterData[byteIndex] |= (1 << bitIndex);\n }\n }\n }\n \n // Convert to base64\n let binary = '';\n for (let i = 0; i < rasterData.length; i++) {\n binary += String.fromCharCode(rasterData[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Process a PDF page to canvas with optional trimming and scaling\n */\nexport async function processPdfPage(\n page: PDFPageProxy,\n config: PdfProcessingConfig = DEFAULT_PDF_CONFIG\n): Promise<ProcessedPage> {\n const mergedConfig = {\n ...DEFAULT_PDF_CONFIG,\n ...config,\n trimMargins: {\n ...DEFAULT_PDF_CONFIG.trimMargins,\n ...config.trimMargins,\n },\n };\n\n // Render at high resolution first\n const renderScale = mergedConfig.scale;\n const highResViewport = page.getViewport({ scale: renderScale });\n \n const highResCanvas = document.createElement('canvas');\n highResCanvas.width = highResViewport.width;\n highResCanvas.height = highResViewport.height;\n \n const highResContext = highResCanvas.getContext('2d')!;\n highResContext.fillStyle = 'white';\n highResContext.fillRect(0, 0, highResCanvas.width, highResCanvas.height);\n \n await page.render({\n canvasContext: highResContext,\n viewport: highResViewport,\n canvas: highResCanvas,\n }).promise;\n\n let processedCanvas = highResCanvas;\n\n // Apply trimming if enabled\n if (mergedConfig.enabled) {\n const margins = {\n top: mergedConfig.trimMargins.top ?? 8,\n bottom: mergedConfig.trimMargins.bottom ?? 8,\n left: mergedConfig.trimMargins.left ?? 8,\n right: mergedConfig.trimMargins.right ?? 8,\n };\n processedCanvas = trimCanvasMargins(processedCanvas, margins);\n }\n\n // Scale to target width if enabled\n let finalCanvas = processedCanvas;\n if (mergedConfig.enabled && mergedConfig.targetWidth) {\n const targetWidth = mergedConfig.targetWidth;\n const aspectRatio = processedCanvas.height / processedCanvas.width;\n const targetHeight = Math.round(targetWidth * aspectRatio);\n\n const scaledCanvas = document.createElement('canvas');\n scaledCanvas.width = targetWidth;\n scaledCanvas.height = targetHeight;\n\n const scaledContext = scaledCanvas.getContext('2d')!;\n scaledContext.fillStyle = 'white';\n scaledContext.fillRect(0, 0, targetWidth, targetHeight);\n scaledContext.drawImage(processedCanvas, 0, 0, targetWidth, targetHeight);\n\n finalCanvas = scaledCanvas;\n }\n\n // Generate base64 for preview\n const base64 = finalCanvas.toDataURL('image/png');\n \n // Generate raster data for printing\n const rasterBase64 = canvasToRasterData(finalCanvas, mergedConfig.monochromeThreshold);\n\n return {\n base64,\n width: finalCanvas.width,\n height: finalCanvas.height,\n rasterBase64,\n canvas: finalCanvas,\n };\n}\n\n/**\n * Process all pages of a PDF file\n */\nexport async function processPdfFile(\n file: File,\n config: PdfProcessingConfig = DEFAULT_PDF_CONFIG\n): Promise<ProcessedPage[]> {\n const arrayBuffer = await file.arrayBuffer();\n const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;\n\n const pages: ProcessedPage[] = [];\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const processedPage = await processPdfPage(page, config);\n pages.push(processedPage);\n }\n\n return pages;\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`pdfjs-dist`);c=s(c);var l={enabled:!1,onLog:void 0};function u(e){e.enabled!==void 0&&(l.enabled=e.enabled),e.onLog!==void 0&&(l.onLog=e.onLog)}function d(){return{...l}}function f(e,t,...n){let r={level:e,message:t,args:n.length>0?n:void 0};if(l.onLog&&l.onLog(r),e===`error`){console.error(`[epson-printer] ${t}`,...n);return}l.enabled&&(e===`warn`?console.warn(`[epson-printer] ${t}`,...n):console.log(`[epson-printer] ${t}`,...n))}function p(e,...t){f(`debug`,e,...t)}function m(e,...t){f(`warn`,e,...t)}function h(e,...t){f(`error`,e,...t)}var g={loading:!1,loaded:!1,error:null,promise:null};function _(){return typeof window<`u`&&window.epson!==void 0&&window.epson.ePOSPrint!==void 0}function v(){try{return new URL(`../../dist/assets/epos-2.27.0.js`,``+{}.url).href}catch{return`/epos-2.27.0.js`}}function y(e){return new Promise((t,n)=>{if(document.querySelector(`script[src="${e}"]`)){t();return}let r=document.createElement(`script`);r.src=e,r.type=`text/javascript`,r.async=!0,r.onload=()=>{p(`Epson SDK loaded successfully from:`,e),t()},r.onerror=t=>{h(`Failed to load Epson SDK from:`,e,t),n(Error(`Failed to load Epson SDK from ${e}`))},document.head.appendChild(r)})}function b(e=1e4){return new Promise(t=>{let n=Date.now(),r=()=>{if(_()){t(!0);return}if(Date.now()-n>e){m(`Timeout waiting for Epson SDK to be available`),t(!1);return}setTimeout(r,100)};r()})}async function x(e){return g.loaded||_()?(g.loaded=!0,g.loading=!1,!0):g.loading&&g.promise?g.promise:(g.loading=!0,g.error=null,g.promise=(async()=>{try{let t=e?.sdkPath||v(),n=e?.timeout||1e4;if(p(`Loading Epson SDK from:`,t),await y(t),!await b(n))throw Error(`Epson SDK loaded but not available in window.epson`);return g.loaded=!0,g.loading=!1,p(`Epson SDK ready`),!0}catch(e){return g.error=e instanceof Error?e:Error(String(e)),g.loading=!1,g.loaded=!1,h(`Failed to load Epson SDK:`,g.error),!1}})(),g.promise)}function S(){return{...g}}function C(){g.loading=!1,g.loaded=!1,g.error=null,g.promise=null}function w(){if(!_())throw Error(`Epson SDK not loaded. Call loadEpsonSDK() first or wait for automatic loading.`);return window.epson}async function T(e){try{return await x(e)?{success:!0}:{success:!1,error:S().error?.message||`Failed to load Epson SDK`}}catch(e){return{success:!1,error:e instanceof Error?e.message:`Unknown error`}}}function E(){let e=S(),t=window.epson,n=[];return t&&(t.ePOSBuilder&&n.push(`ePOSBuilder`),t.ePOSPrint&&n.push(`ePOSPrint`),t.CanvasPrint&&n.push(`CanvasPrint`),t.ePOSDevice&&n.push(`ePOSDevice`)),{loaded:e.loaded||_(),loading:e.loading,error:e.error,classes:n}}var D=class{constructor(e,t={}){this.initPromise=null,this.config={printerIP:e.printerIP,printerPort:e.printerPort??80,deviceId:e.deviceId??`local_printer`,timeout:e.timeout??6e4},this.printOptions={halftone:t.halftone??1,brightness:t.brightness??1,mode:t.mode??`mono`,cut:t.cut??!0,align:t.align??`center`}}async ensureSDKLoaded(){if(_())return!0;if(this.initPromise)return this.initPromise;p(`EposPrintService: Loading Epson SDK...`),this.initPromise=x();let e=await this.initPromise;return this.initPromise=null,e||h(`EposPrintService: Failed to load SDK`),e}getPrinterUrl(){let{printerIP:e,printerPort:t,deviceId:n,timeout:r}=this.config;return`http://${e}:${t}/cgi-bin/epos/service.cgi?devid=${n}&timeout=${r}`}async printCanvas(e){return await this.ensureSDKLoaded()?new Promise(t=>{let n=!1,r=e=>{n||(n=!0,t(e))},i=setTimeout(()=>{h(`printCanvas: timeout reached`),r({success:!1,code:`TIMEOUT`,message:`Sin respuesta de la impresora después de ${this.config.timeout}ms. Verifica la IP y puerto.`})},this.config.timeout+5e3);try{let t=w(),n=this.getPrinterUrl(),a=new t.ePOSBuilder;a.halftone=this.printOptions.halftone??1,a.brightness=this.printOptions.brightness??1;let o=e.getContext(`2d`);if(!o){clearTimeout(i),r({success:!1,code:`CANVAS_ERROR`,message:`No se pudo obtener el contexto 2D del canvas`});return}p(`printCanvas: Building commands for canvas:`,e.width,`x`,e.height);let s=this.getAlignValue(this.printOptions.align);a.addTextAlign(s),a.addImage(o,0,0,e.width,e.height),this.printOptions.cut&&a.addCut(a.CUT_FEED);let c=a.toString();p(`printCanvas: XML length:`,c.length);let l=new t.ePOSPrint(n);l.timeout=this.config.timeout,l.onreceive=e=>{p(`printCanvas onreceive:`,e),clearTimeout(i),r({success:e.success,code:e.code,status:e.status,message:e.success?`Impresión exitosa`:`Error: ${e.code}`,printjobid:e.printjobid})},l.onerror=e=>{h(`printCanvas onerror:`,e),clearTimeout(i),r({success:!1,code:`NETWORK_ERROR`,status:e?.status,message:`Error de red: ${e?.responseText||`Sin conexión`}`})},p(`printCanvas: Sending XML to printer...`),l.send(c)}catch(e){h(`printCanvas error:`,e),clearTimeout(i),r({success:!1,code:`SDK_ERROR`,message:e instanceof Error?e.message:`Error desconocido`})}}):{success:!1,code:`SDK_NOT_LOADED`,message:`Failed to load Epson ePOS SDK. Check console for details.`}}getAlignValue(e){switch(e){case`left`:return`left`;case`right`:return`right`;case`center`:default:return`center`}}async printWithBuilder(e){return await this.ensureSDKLoaded()?new Promise(t=>{let n=!1,r=e=>{n||(n=!0,t(e))},i=setTimeout(()=>{h(`printWithBuilder: timeout reached`),r({success:!1,code:`TIMEOUT`,message:`Sin respuesta de la impresora después de ${this.config.timeout}ms. Verifica la IP y puerto.`})},this.config.timeout+5e3);try{let t=w(),n=this.getPrinterUrl();p(`printWithBuilder: Creating ePOSPrint with URL:`,n);let a=new t.ePOSBuilder;a.halftone=this.printOptions.halftone??1,a.brightness=this.printOptions.brightness??1,p(`printWithBuilder: Building commands...`),e(a);let o=a.toString();p(`printWithBuilder: XML to send:`,o);let s=new t.ePOSPrint(n);s.timeout=this.config.timeout,s.onreceive=e=>{p(`ePOSPrint onreceive:`,e),clearTimeout(i),r({success:e.success,code:e.code,status:e.status,message:e.success?`Impresión exitosa`:`Error: ${e.code}`,printjobid:e.printjobid})},s.onerror=e=>{h(`ePOSPrint onerror:`,e),clearTimeout(i),r({success:!1,code:`NETWORK_ERROR`,status:e?.status,message:`Error de red: ${e?.responseText||`Sin conexión`}`})},p(`printWithBuilder: Calling printer.send(xml)`),s.send(o)}catch(e){h(`printWithBuilder error:`,e),t({success:!1,code:`SDK_ERROR`,message:e instanceof Error?e.message:`Error desconocido`})}}):{success:!1,code:`SDK_NOT_LOADED`,message:`Failed to load Epson ePOS SDK`}}async printPages(e,t){return await this.ensureSDKLoaded()?new Promise(n=>{let r=!1,i=e=>{r||(r=!0,n(e))},a=setTimeout(()=>{h(`printPages: timeout reached`),i({success:!1,code:`TIMEOUT`,message:`Sin respuesta de la impresora después de ${this.config.timeout}ms`})},this.config.timeout+1e4);try{let n=w(),r=new n.ePOSBuilder;r.halftone=this.printOptions.halftone??1,r.brightness=this.printOptions.brightness??1,t?.header&&(r.addTextAlign(`center`),r.addTextStyle(!1,!1,!0),r.addTextSize(2,2),r.addText(t.header+`
2
+ `),r.addTextSize(1,1),r.addTextStyle(!1,!1,!1),r.addFeedLine(1)),e.forEach((n,i)=>{let a=n.getContext(`2d`);a&&(r.addTextAlign(this.printOptions.align??`center`),r.addImage(a,0,0,n.width,n.height,`color_1`,this.printOptions.mode??`mono`)),t?.pageSeparator&&i<e.length-1&&(r.addFeedLine(2),r.addTextAlign(`center`),r.addText(`- - - - - - - - - -
3
+ `),r.addFeedLine(2))}),t?.footer&&(r.addFeedLine(1),r.addTextAlign(`center`),r.addText(t.footer+`
4
+ `)),r.addFeedLine(3),this.printOptions.cut&&r.addCut(`feed`);let o=r.toString();p(`printPages: XML to send (first 500 chars):`,o.substring(0,500));let s=new n.ePOSPrint(this.getPrinterUrl());s.timeout=this.config.timeout,s.onreceive=e=>{p(`printPages onreceive:`,e),clearTimeout(a),i({success:e.success,code:e.code,status:e.status,message:e.success?`Impresión exitosa`:`Error: ${e.code}`,printjobid:e.printjobid})},s.onerror=e=>{h(`printPages onerror:`,e),clearTimeout(a),i({success:!1,code:`NETWORK_ERROR`,status:e?.status,message:`Error de red: ${e?.responseText||`Sin conexión`}`})},p(`printPages: sending to printer, pages:`,e.length),s.send(o)}catch(e){h(`printPages error:`,e),clearTimeout(a),i({success:!1,code:`SDK_ERROR`,message:e instanceof Error?e.message:`Error desconocido`})}}):{success:!1,code:`SDK_NOT_LOADED`,message:`Failed to load Epson ePOS SDK`}}testConnection(){return p(`testConnection: starting...`),this.printWithBuilder(e=>{e.addTextAlign(`center`),e.addText(`Test de conexión
5
+ `),e.addFeedLine(3),e.addCut(`feed`)})}printTestPage(){return p(`printTestPage: starting...`),this.printWithBuilder(e=>{e.addTextAlign(`center`),e.addTextStyle(!1,!1,!0),e.addTextSize(2,2),e.addText(`PÁGINA DE PRUEBA
6
+ `),e.addTextSize(1,1),e.addTextStyle(!1,!1,!1),e.addFeedLine(1),e.addText(`================================
7
+ `),e.addTextAlign(`left`),e.addText(`Impresora: `+this.config.printerIP+`
8
+ `),e.addText(`Puerto: `+this.config.printerPort+`
9
+ `),e.addText(`Device ID: `+this.config.deviceId+`
10
+ `),e.addText(`Halftone: `+this.printOptions.halftone+`
11
+ `),e.addText(`Brightness: `+this.printOptions.brightness+`
12
+ `),e.addText(`Mode: `+this.printOptions.mode+`
13
+ `),e.addText(`================================
14
+ `),e.addFeedLine(1),e.addTextAlign(`center`),e.addText(`Fecha: `+new Date().toLocaleString()+`
15
+ `),e.addFeedLine(3),e.addCut(`feed`)})}},O=`4.10.38`;c.GlobalWorkerOptions.workerSrc=`https://unpkg.com/pdfjs-dist@${O}/build/pdf.worker.min.mjs`;const k={enabled:!0,trimMargins:{top:8,bottom:8,left:8,right:8},targetWidth:576,scale:3,monochromeThreshold:160};function A(e,t){let n=e.getContext(`2d`).getImageData(0,0,e.width,e.height).data,r=e.width,i=e.height,a=0,o=i-1,s=0,c=r-1;topLoop:for(let e=0;e<i;e++)for(let t=0;t<r;t++){let i=(e*r+t)*4;if(n[i]<250||n[i+1]<250||n[i+2]<250){a=e;break topLoop}}bottomLoop:for(let e=i-1;e>=0;e--)for(let t=0;t<r;t++){let i=(e*r+t)*4;if(n[i]<250||n[i+1]<250||n[i+2]<250){o=e;break bottomLoop}}leftLoop:for(let e=0;e<r;e++)for(let t=0;t<i;t++){let i=(t*r+e)*4;if(n[i]<250||n[i+1]<250||n[i+2]<250){s=e;break leftLoop}}rightLoop:for(let e=r-1;e>=0;e--)for(let t=0;t<i;t++){let i=(t*r+e)*4;if(n[i]<250||n[i+1]<250||n[i+2]<250){c=e;break rightLoop}}a=Math.max(0,a-t.top),o=Math.min(i-1,o+t.bottom),s=Math.max(0,s-t.left),c=Math.min(r-1,c+t.right);let l=c-s+1,u=o-a+1;if(l>=r-10&&u>=i-10)return e;let d=document.createElement(`canvas`);d.width=l,d.height=u;let f=d.getContext(`2d`);return f.fillStyle=`white`,f.fillRect(0,0,l,u),f.drawImage(e,s,a,l,u,0,0,l,u),d}function j(e,t){let n=e.getContext(`2d`).getImageData(0,0,e.width,e.height).data,r=Math.ceil(e.width/8)*8,i=e.height,a=r/8,o=new Uint8Array(a*i);for(let s=0;s<i;s++)for(let i=0;i<r;i++){let r=Math.min(i,e.width-1),c=(s*e.width+r)*4,l=n[c],u=n[c+1],d=n[c+2],f=.299*l+.587*u+.114*d<t?1:0,p=s*a+Math.floor(i/8),m=7-i%8;f&&(o[p]|=1<<m)}let s=``;for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}async function M(e,t=k){let n={...k,...t,trimMargins:{...k.trimMargins,...t.trimMargins}},r=n.scale,i=e.getViewport({scale:r}),a=document.createElement(`canvas`);a.width=i.width,a.height=i.height;let o=a.getContext(`2d`);o.fillStyle=`white`,o.fillRect(0,0,a.width,a.height),await e.render({canvasContext:o,viewport:i,canvas:a}).promise;let s=a;if(n.enabled){let e={top:n.trimMargins.top??8,bottom:n.trimMargins.bottom??8,left:n.trimMargins.left??8,right:n.trimMargins.right??8};s=A(s,e)}let c=s;if(n.enabled&&n.targetWidth){let e=n.targetWidth,t=s.height/s.width,r=Math.round(e*t),i=document.createElement(`canvas`);i.width=e,i.height=r;let a=i.getContext(`2d`);a.fillStyle=`white`,a.fillRect(0,0,e,r),a.drawImage(s,0,0,e,r),c=i}let l=c.toDataURL(`image/png`),u=j(c,n.monochromeThreshold);return{base64:l,width:c.width,height:c.height,rasterBase64:u,canvas:c}}async function N(e,t=k){let n=await e.arrayBuffer(),r=await c.getDocument({data:n}).promise,i=[];for(let e=1;e<=r.numPages;e++){let n=await M(await r.getPage(e),t);i.push(n)}return i}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return x}});
16
+ //# sourceMappingURL=pdf-processor-DwUY-8_K.cjs.map