{"version":3,"file":"index.cjs","sources":["../src/services/printer.ts","../src/services/imageProcessor.ts","../src/hooks/useThermalPrinter.ts"],"sourcesContent":["// MXW01 Thermal Printer Protocol (TypeScript version for React)\n\nexport const PRINTER_WIDTH = 384;\nexport const PRINTER_WIDTH_BYTES = PRINTER_WIDTH / 8; // 48 bytes\nexport const MIN_DATA_BYTES = 90 * PRINTER_WIDTH_BYTES; // 4320 bytes minimum\n\nconst CRC8_TABLE = [\n  0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24,\n  0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f,\n  0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2,\n  0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99,\n  0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xc7,\n  0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4,\n  0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81,\n  0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,\n  0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b,\n  0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e,\n  0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3,\n  0xa4, 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8,\n  0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51,\n  0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02,\n  0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40,\n  0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,\n  0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a,\n  0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91,\n  0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc,\n  0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3,\n];\n\nexport const Command = {\n  GetStatus: 0xa1,\n  SetIntensity: 0xa2,\n  PrintRequest: 0xa9,\n  FlushData: 0xad,\n  PrintComplete: 0xaa,\n} as const;\n\nexport interface PrinterState {\n  printing: boolean;\n  paper_jam: boolean;\n  out_of_paper: boolean;\n  cover_open: boolean;\n  battery_low: boolean;\n  overheat: boolean;\n}\n\n// Type for Bluetooth write functions\nexport type WriteFunction = (data: BufferSource) => Promise<void>;\n\nfunction crc8(data: Uint8Array): number {\n  let crc = 0;\n  for (const byte of data) {\n    crc = CRC8_TABLE[(crc ^ byte) & 0xff];\n  }\n  return crc & 0xff;\n}\n\nfunction delay(msecs: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(() => resolve(), msecs));\n}\n\nexport class MXW01Printer {\n  private controlWrite: WriteFunction;\n  private dataWrite: WriteFunction;\n  private printComplete: boolean;\n  private pendingResolvers: Map<number, (payload: Uint8Array) => void>;\n  state: PrinterState;\n\n  constructor(controlWrite: WriteFunction, dataWrite: WriteFunction) {\n    this.controlWrite = controlWrite;\n    this.dataWrite = dataWrite;\n    this.printComplete = false;\n    this.pendingResolvers = new Map();\n    this.state = {\n      printing: false,\n      paper_jam: false,\n      out_of_paper: false,\n      cover_open: false,\n      battery_low: false,\n      overheat: false,\n    };\n  }\n\n  notify(message: Uint8Array): void {\n    if (message[0] !== 0x22 || message[1] !== 0x21) {\n      console.warn(\"Ignoring unexpected notification format\");\n      return;\n    }\n\n    const cmdId = message[2];\n    const len = message[4] | (message[5] << 8);\n    const payload = message.slice(6, 6 + len);\n\n    // Check for print complete notification\n    if (cmdId === Command.PrintComplete) {\n      this.printComplete = true;\n    }\n\n    // Parse printer state from status response\n    if (cmdId === Command.GetStatus && payload.length >= 7) {\n      const statusByte = payload[6];\n      this.state = {\n        printing: (statusByte & 0x01) !== 0,\n        paper_jam: (statusByte & 0x02) !== 0,\n        out_of_paper: (statusByte & 0x04) !== 0,\n        cover_open: (statusByte & 0x08) !== 0,\n        battery_low: (statusByte & 0x10) !== 0,\n        overheat: (statusByte & 0x20) !== 0,\n      };\n    }\n\n    // Resolve any pending promise for this command\n    const resolver = this.pendingResolvers.get(cmdId);\n    if (resolver) {\n      resolver(payload);\n      this.pendingResolvers.delete(cmdId);\n    }\n  }\n\n  makeCommand(command: number, payload: Uint8Array): Uint8Array {\n    const len = payload.length;\n    const header = new Uint8Array([\n      0x22,\n      0x21,\n      command,\n      0x00,\n      len & 0xff,\n      (len >> 8) & 0xff,\n    ]);\n\n    // Concatenate header and payload\n    const cmdWithPayload = new Uint8Array(header.length + payload.length);\n    cmdWithPayload.set(header);\n    cmdWithPayload.set(payload, header.length);\n\n    // Calculate CRC on payload only\n    const crcValue = crc8(payload);\n\n    // Final command: header + payload + CRC + 0xFF\n    const result = new Uint8Array(cmdWithPayload.length + 2);\n    result.set(cmdWithPayload);\n    result[result.length - 2] = crcValue;\n    result[result.length - 1] = 0xff;\n\n    return result;\n  }\n\n  waitForNotification(cmdId: number, timeoutMs = 10000): Promise<Uint8Array> {\n    return new Promise((resolve, reject) => {\n      const timer = setTimeout(() => {\n        this.pendingResolvers.delete(cmdId);\n        reject(\n          new Error(`Timeout waiting for notification 0x${cmdId.toString(16)}`)\n        );\n      }, timeoutMs);\n\n      this.pendingResolvers.set(cmdId, (payload) => {\n        clearTimeout(timer);\n        resolve(payload);\n      });\n    });\n  }\n\n  async setIntensity(intensity = 0x5d): Promise<void> {\n    const command = this.makeCommand(\n      Command.SetIntensity,\n      Uint8Array.of(intensity)\n    );\n    await this.controlWrite(command as BufferSource);\n    await delay(50);\n  }\n\n  async requestStatus(): Promise<Uint8Array> {\n    const command = this.makeCommand(Command.GetStatus, Uint8Array.of(0x00));\n    await this.controlWrite(command as BufferSource);\n    return this.waitForNotification(Command.GetStatus, 5000);\n  }\n\n  async printRequest(lines: number, mode = 0): Promise<Uint8Array> {\n    // Send 4 bytes: lines_low, lines_high, 0x30, mode\n    const payload = new Uint8Array(4);\n    payload[0] = lines & 0xff;\n    payload[1] = (lines >> 8) & 0xff;\n    payload[2] = 0x30;\n    payload[3] = mode;\n\n    const command = this.makeCommand(Command.PrintRequest, payload);\n    await this.controlWrite(command as BufferSource);\n    return this.waitForNotification(Command.PrintRequest, 5000);\n  }\n\n  async flushData(): Promise<void> {\n    const command = this.makeCommand(Command.FlushData, Uint8Array.of(0x00));\n    await this.controlWrite(command as BufferSource);\n    await delay(50);\n  }\n\n  async sendDataChunks(\n    data: Uint8Array,\n    chunkSize = PRINTER_WIDTH_BYTES\n  ): Promise<void> {\n    // Send data in chunks (48 bytes per chunk = 1 line)\n    let pos = 0;\n    while (pos < data.length) {\n      const chunk = data.slice(pos, Math.min(pos + chunkSize, data.length));\n      await this.dataWrite(chunk);\n      pos += chunk.length;\n      // Small delay to prevent buffer overrun\n      await delay(15);\n    }\n  }\n\n  async waitForPrintComplete(timeoutMs = 20000): Promise<void> {\n    this.printComplete = false;\n    const startTime = Date.now();\n\n    while (!this.printComplete && Date.now() - startTime < timeoutMs) {\n      await delay(100);\n    }\n\n    if (!this.printComplete) {\n      throw new Error(\"Print timeout: Did not receive completion notification\");\n    }\n  }\n}\n\n// Helper function to encode a row of boolean pixels\nexport function encode1bppRow(rowBool: boolean[]): Uint8Array {\n  if (rowBool.length !== PRINTER_WIDTH) {\n    throw new Error(\n      `Row length must be ${PRINTER_WIDTH}, got ${rowBool.length}`\n    );\n  }\n\n  const rowBytes = new Uint8Array(PRINTER_WIDTH_BYTES);\n  for (let byteIndex = 0; byteIndex < PRINTER_WIDTH_BYTES; byteIndex++) {\n    let byteVal = 0;\n    for (let bit = 0; bit < 8; bit++) {\n      if (rowBool[byteIndex * 8 + bit]) {\n        byteVal |= 1 << bit;\n      }\n    }\n    rowBytes[byteIndex] = byteVal;\n  }\n\n  return rowBytes;\n}\n\n// Prepare image data buffer with padding\nexport function prepareImageDataBuffer(imageRowsBool: boolean[][]): Uint8Array {\n  const height = imageRowsBool.length;\n  let buffer = new Uint8Array(0);\n\n  for (let y = 0; y < height; y++) {\n    const rowBytes = encode1bppRow(imageRowsBool[y]);\n    const newBuf = new Uint8Array(buffer.length + rowBytes.length);\n    newBuf.set(buffer);\n    newBuf.set(rowBytes, buffer.length);\n    buffer = newBuf;\n  }\n\n  // Pad to minimum size if needed\n  if (buffer.length < MIN_DATA_BYTES) {\n    const pad = new Uint8Array(MIN_DATA_BYTES - buffer.length);\n    const newBuf = new Uint8Array(buffer.length + pad.length);\n    newBuf.set(buffer);\n    newBuf.set(pad, buffer.length);\n    buffer = newBuf;\n  }\n\n  return buffer;\n}\n","// Image processing service for MXW01 thermal printer\n\n/**\n * Convert RGBA image to grayscale\n */\nexport function rgbaToGray(\n  rgba: Uint32Array,\n  brightness: number = 128,\n  alphaAsWhite: boolean = true\n): Uint8ClampedArray {\n  const mono = new Uint8ClampedArray(rgba.length);\n  let r = 0.0,\n    g = 0.0,\n    b = 0.0,\n    a = 0.0,\n    m = 0.0,\n    n = 0;\n\n  for (let i = 0; i < mono.length; ++i) {\n    n = rgba[i];\n    r = n & 0xff;\n    g = (n >> 8) & 0xff;\n    b = (n >> 16) & 0xff;\n    a = ((n >> 24) & 0xff) / 0xff;\n\n    if (a < 1 && alphaAsWhite) {\n      a = 1 - a;\n      r += (0xff - r) * a;\n      g += (0xff - g) * a;\n      b += (0xff - b) * a;\n    } else {\n      r *= a;\n      g *= a;\n      b *= a;\n    }\n\n    // RGB to grayscale with weighting\n    m = r * 0.2125 + g * 0.7154 + b * 0.0721;\n\n    // Brightness adjustment\n    m += (brightness - 0x80) * (1 - m / 0xff) * (m / 0xff) * 2;\n    mono[i] = m;\n  }\n\n  return mono;\n}\n\n/**\n * Convert grayscale to RGBA\n */\nexport function grayToRgba(\n  mono: Uint8ClampedArray,\n  whiteAsTransparent: boolean = false\n): Uint32Array {\n  const rgba = new Uint32Array(mono.length);\n\n  for (let i = 0; i < mono.length; ++i) {\n    const base = mono[i] === 0xff && whiteAsTransparent ? 0 : 0xff000000;\n    rgba[i] = base | (mono[i] << 16) | (mono[i] << 8) | mono[i];\n  }\n\n  return rgba;\n}\n\n// Dithering methods\n\n/**\n * Simple threshold dithering\n */\nexport function ditherThreshold(mono: Uint8ClampedArray): Uint8ClampedArray {\n  for (let i = 0; i < mono.length; ++i) {\n    mono[i] = mono[i] > 0x80 ? 0xff : 0x00;\n  }\n  return mono;\n}\n\n/**\n * Floyd-Steinberg error diffusion dithering\n */\nexport function ditherSteinberg(\n  mono: Uint8ClampedArray,\n  w: number,\n  h: number\n): Uint8ClampedArray {\n  let p = 0,\n    m = 0,\n    n = 0,\n    o = 0;\n\n  for (let j = 0; j < h; ++j) {\n    for (let i = 0; i < w; ++i) {\n      m = mono[p];\n      n = mono[p] > 0x80 ? 0xff : 0x00;\n      o = m - n;\n      mono[p] = n;\n\n      if (i >= 0 && i < w - 1 && j >= 0 && j < h) mono[p + 1] += (o * 7) / 16;\n      if (i >= 1 && i < w && j >= 0 && j < h - 1)\n        mono[p + w - 1] += (o * 3) / 16;\n      if (i >= 0 && i < w && j >= 0 && j < h - 1) mono[p + w] += (o * 5) / 16;\n      if (i >= 0 && i < w - 1 && j >= 0 && j < h - 1) {\n        mono[p + w + 1] += (o * 1) / 16;\n      }\n      ++p;\n    }\n  }\n\n  return mono;\n}\n\n/**\n * Halftone pattern dithering\n */\nexport function ditherHalftone(\n  mono: Uint8ClampedArray,\n  w: number,\n  h: number\n): Uint8ClampedArray {\n  const spot = 4;\n  const spot_h = spot / 2 + 1;\n  const spot_s = spot * spot;\n  let i = 0,\n    j = 0,\n    x = 0,\n    y = 0,\n    o = 0.0;\n\n  for (j = 0; j < h - spot; j += spot) {\n    for (i = 0; i < w - spot; i += spot) {\n      o = 0;\n      for (x = 0; x < spot; ++x) {\n        for (y = 0; y < spot; ++y) {\n          o += mono[(j + y) * w + i + x];\n        }\n      }\n      o = (1 - o / spot_s / 0xff) * spot;\n\n      for (x = 0; x < spot; ++x) {\n        for (y = 0; y < spot; ++y) {\n          mono[(j + y) * w + i + x] =\n            Math.abs(x - spot_h) >= o || Math.abs(y - spot_h) >= o\n              ? 0xff\n              : 0x00;\n        }\n      }\n    }\n\n    for (; i < w; ++i) mono[j * w + i] = 0xff;\n  }\n\n  for (; j < h; ++j) {\n    for (i = 0; i < w; ++i) mono[j * w + i] = 0xff;\n  }\n\n  return mono;\n}\n\n/**\n * Bayer matrix dithering\n */\nexport function ditherBayer(\n  mono: Uint8ClampedArray,\n  w: number,\n  h: number\n): Uint8ClampedArray {\n  const bayer8 = [\n    0, 48, 12, 60, 3, 51, 15, 63, 32, 16, 44, 28, 35, 19, 47, 31, 8, 56, 4, 52,\n    11, 59, 7, 55, 40, 24, 36, 20, 43, 27, 39, 23, 2, 50, 14, 62, 1, 49, 13, 61,\n    34, 18, 46, 30, 33, 17, 45, 29, 10, 58, 6, 54, 9, 57, 5, 53, 42, 26, 38, 22,\n    41, 25, 37, 21,\n  ];\n\n  const ditherFactor = 0.6;\n  let p = 0;\n\n  for (let j = 0; j < h; ++j) {\n    for (let i = 0; i < w; ++i) {\n      const bayerValue = bayer8[(j % 8) * 8 + (i % 8)];\n      let pixelValue = mono[p];\n      pixelValue = pixelValue + (bayerValue - 32) * ditherFactor;\n      if (pixelValue < 0) pixelValue = 0;\n      if (pixelValue > 255) pixelValue = 255;\n      mono[p] = pixelValue > 128 ? 0xff : 0x00;\n      ++p;\n    }\n  }\n\n  return mono;\n}\n\n/**\n * Atkinson dithering algorithm\n */\nexport function ditherAtkinson(\n  mono: Uint8ClampedArray,\n  w: number,\n  h: number\n): Uint8ClampedArray {\n  let p = 0;\n  let oldPixel = 0,\n    newPixel = 0,\n    error = 0;\n\n  for (let j = 0; j < h; ++j) {\n    for (let i = 0; i < w; ++i) {\n      oldPixel = mono[p];\n      newPixel = oldPixel > 0x80 ? 0xff : 0x00;\n      error = (oldPixel - newPixel) >> 3; // Division by 8\n      mono[p] = newPixel;\n\n      if (i < w - 1) {\n        mono[p + 1] += error;\n      }\n      if (i < w - 2) {\n        mono[p + 2] += error;\n      }\n      if (j < h - 1) {\n        if (i > 0) {\n          mono[p + w - 1] += error;\n        }\n        mono[p + w] += error;\n        if (i < w - 1) {\n          mono[p + w + 1] += error;\n        }\n      }\n      if (j < h - 2) {\n        mono[p + 2 * w] += error;\n      }\n\n      ++p;\n    }\n  }\n\n  return mono;\n}\n\n/**\n * Rotate an image\n */\nexport function rotate(\n  before: Uint8ClampedArray,\n  w: number,\n  h: number,\n  turn: 0 | 90 | 180 | 270\n): Uint8ClampedArray {\n  const after = new Uint8ClampedArray(before.length);\n\n  switch (turn) {\n    case 0:\n      return before;\n    case 90:\n      for (let j = 0; j < h; j++) {\n        for (let i = 0; i < w; i++) {\n          after[j * w + i] = before[(w - i - 1) * h + j];\n        }\n      }\n      break;\n    case 180:\n      for (let j = 0; j < h; j++) {\n        for (let i = 0; i < w; i++) {\n          after[j * w + i] = before[(h - j - 1) * w + (w - i - 1)];\n        }\n      }\n      break;\n    case 270:\n      for (let j = 0; j < h; j++) {\n        for (let i = 0; i < w; i++) {\n          after[j * w + i] = before[i * h + (h - j - 1)];\n        }\n      }\n      break;\n  }\n\n  return after;\n}\n\n/**\n * Flip an image\n */\nexport function flip(\n  before: Uint8ClampedArray,\n  w: number,\n  h: number,\n  mode: \"none\" | \"h\" | \"v\" | \"both\"\n): Uint8ClampedArray {\n  const after = new Uint8ClampedArray(before.length);\n\n  switch (mode) {\n    case \"none\":\n      return before;\n    case \"h\":\n      for (let j = 0; j < h; j++) {\n        for (let i = 0; i < w; i++) {\n          after[j * w + i] = before[j * w + (w - i - 1)];\n        }\n      }\n      break;\n    case \"v\":\n      for (let j = 0; j < h; j++) {\n        for (let i = 0; i < w; i++) {\n          after[j * w + i] = before[(h - j - 1) * w + i];\n        }\n      }\n      break;\n    case \"both\":\n      for (let j = 0; j < h; j++) {\n        for (let i = 0; i < w; i++) {\n          after[j * w + i] = before[(h - j - 1) * w + (w - i - 1)];\n        }\n      }\n      break;\n  }\n\n  return after;\n}\n\nexport type DitherMethod =\n  | \"threshold\"\n  | \"steinberg\"\n  | \"bayer\"\n  | \"atkinson\"\n  | \"pattern\";\n\nexport interface ImageProcessorOptions {\n  dither: DitherMethod;\n  rotate: 0 | 90 | 180 | 270;\n  flip: \"none\" | \"h\" | \"v\" | \"both\";\n  brightness: number;\n}\n\n/**\n * Process an image for thermal printer\n */\nexport function processImageForPrinter(\n  imageData: ImageData,\n  options: ImageProcessorOptions\n): {\n  processedData: Uint32Array;\n  width: number;\n  height: number;\n  binaryRows: boolean[][];\n} {\n  // Convert to RGBA array\n  const rgbaData = new Uint32Array(\n    new Uint8ClampedArray(imageData.data).buffer\n  );\n\n  const w = imageData.width;\n  const h = imageData.height;\n\n  // Convert to grayscale\n  let mono = rgbaToGray(rgbaData, options.brightness, true);\n\n  // Apply dithering\n  switch (options.dither) {\n    case \"steinberg\":\n      mono = ditherSteinberg(mono, w, h);\n      break;\n    case \"bayer\":\n      mono = ditherBayer(mono, w, h);\n      break;\n    case \"atkinson\":\n      mono = ditherAtkinson(mono, w, h);\n      break;\n    case \"pattern\":\n      mono = ditherHalftone(mono, w, h);\n      break;\n    case \"threshold\":\n    default:\n      mono = ditherThreshold(mono);\n      break;\n  }\n\n  // Apply flip\n  mono = flip(mono, w, h, options.flip);\n\n  // Apply rotation\n  let finalWidth = w;\n  let finalHeight = h;\n\n  if (options.rotate === 0 || options.rotate === 180) {\n    mono = rotate(mono, w, h, options.rotate);\n  } else {\n    mono = rotate(mono, h, w, options.rotate);\n    finalWidth = h;\n    finalHeight = w;\n  }\n\n  // Convert to RGBA for display if needed\n  const processedData = grayToRgba(mono, true);\n\n  // Create binary rows array for printing\n  const binaryRows: boolean[][] = [];\n\n  for (let y = 0; y < finalHeight; y++) {\n    const row: boolean[] = [];\n    for (let x = 0; x < finalWidth; x++) {\n      // true = black (print), false = white\n      const idx = y * finalWidth + x;\n      const lum = mono[idx];\n      row.push(lum < 128);\n    }\n    binaryRows.push(row);\n  }\n\n  return {\n    processedData,\n    width: finalWidth,\n    height: finalHeight,\n    binaryRows,\n  };\n}\n","import { useState, useCallback, useRef } from \"react\";\nimport {\n  MXW01Printer,\n  PRINTER_WIDTH,\n  prepareImageDataBuffer,\n} from \"../services/printer\";\nimport type { PrinterState } from \"../services/printer\";\nimport { processImageForPrinter } from \"../services/imageProcessor\";\nimport type {\n  ImageProcessorOptions,\n  DitherMethod,\n} from \"../services/imageProcessor\";\n\n// Bluetooth service UUIDs\nconst PRINTER_SERVICE_UUID = \"0000ae30-0000-1000-8000-00805f9b34fb\";\nconst PRINTER_SERVICE_UUID_ALT = \"0000af30-0000-1000-8000-00805f9b34fb\"; // macOS alternate UUID\nconst CONTROL_CHAR_UUID = \"0000ae01-0000-1000-8000-00805f9b34fb\";\nconst NOTIFY_CHAR_UUID = \"0000ae02-0000-1000-8000-00805f9b34fb\";\nconst DATA_CHAR_UUID = \"0000ae03-0000-1000-8000-00805f9b34fb\";\n\nexport interface ThermalPrinterHook {\n  isConnected: boolean;\n  isPrinting: boolean;\n  printerState: PrinterState | null;\n  statusMessage: string;\n  ditherMethod: DitherMethod;\n  printIntensity: number;\n  connectPrinter: () => Promise<void>;\n  printCanvas: (\n    canvas: HTMLCanvasElement,\n    options?: Partial<ImageProcessorOptions>\n  ) => Promise<void>;\n  getPrinterStatus: () => Promise<PrinterState | null>;\n  disconnect: () => Promise<void>;\n  setDitherMethod: (method: DitherMethod) => void;\n  setPrintIntensity: (intensity: number) => void;\n}\n\nexport function useThermalPrinter(): ThermalPrinterHook {\n  const [isConnected, setIsConnected] = useState<boolean>(false);\n  const [isPrinting, setIsPrinting] = useState<boolean>(false);\n  const [printerState, setPrinterState] = useState<PrinterState | null>(null);\n  const [statusMessage, setStatusMessage] = useState<string>(\n    \"Ready to connect printer\"\n  );\n  const [ditherMethod, setDitherMethod] = useState<DitherMethod>(\"steinberg\");\n  const [printIntensity, setPrintIntensity] = useState<number>(0x5d);\n\n  // References for BLE connections\n  const printerRef = useRef<MXW01Printer | null>(null);\n  const deviceRef = useRef<BluetoothDevice | null>(null);\n  const notifyCharRef = useRef<BluetoothRemoteGATTCharacteristic | null>(null);\n\n  /**\n   * Connect to printer via Bluetooth\n   */\n  const connectPrinter = useCallback(async () => {\n    try {\n      setStatusMessage(\"Connecting to printer...\");\n\n      // Request Bluetooth device with support for both standard and macOS UUIDs\n      const device = await navigator.bluetooth.requestDevice({\n        filters: [\n          { services: [PRINTER_SERVICE_UUID] },\n          { services: [PRINTER_SERVICE_UUID_ALT] },\n        ],\n        optionalServices: [PRINTER_SERVICE_UUID, PRINTER_SERVICE_UUID_ALT],\n      });\n\n      deviceRef.current = device;\n\n      // Connect to GATT server\n      const server = await device.gatt?.connect();\n      if (!server) throw new Error(\"Failed to connect to GATT server\");\n\n      // Access printer service - try standard UUID first, then macOS alternate\n      let service;\n      try {\n        service = await server.getPrimaryService(PRINTER_SERVICE_UUID);\n      } catch (error) {\n        console.log(\"Trying alternate UUID for macOS compatibility...\");\n        service = await server.getPrimaryService(PRINTER_SERVICE_UUID_ALT);\n      }\n\n      // Get characteristics\n      const [controlChar, notifyChar, dataChar] = await Promise.all([\n        service.getCharacteristic(CONTROL_CHAR_UUID),\n        service.getCharacteristic(NOTIFY_CHAR_UUID),\n        service.getCharacteristic(DATA_CHAR_UUID),\n      ]);\n\n      notifyCharRef.current = notifyChar;\n\n      // Initialize printer\n      const printer = new MXW01Printer(\n        controlChar.writeValueWithoutResponse.bind(controlChar),\n        dataChar.writeValueWithoutResponse.bind(dataChar)\n      );\n\n      printerRef.current = printer;\n\n      // Setup notifications\n      const notifier = (event: Event) => {\n        const characteristic =\n          event.target as BluetoothRemoteGATTCharacteristic;\n        const value = characteristic.value;\n        if (value) {\n          printer.notify(new Uint8Array(value.buffer));\n          setPrinterState({ ...printer.state });\n        }\n      };\n\n      await notifyChar.startNotifications();\n      notifyChar.addEventListener(\"characteristicvaluechanged\", notifier);\n\n      setIsConnected(true);\n      setStatusMessage(\"Printer connected\");\n\n      // Initial status request\n      await getPrinterStatus();\n    } catch (error) {\n      console.error(\"Connection error:\", error);\n      setStatusMessage(`Error: ${(error as Error).message}`);\n      throw error;\n    }\n  }, []);\n\n  /**\n   * Get current printer status\n   */\n  const getPrinterStatus =\n    useCallback(async (): Promise<PrinterState | null> => {\n      if (!printerRef.current || !isConnected) {\n        setStatusMessage(\"Printer not connected\");\n        return null;\n      }\n\n      try {\n        await printerRef.current.requestStatus();\n        const newState = { ...printerRef.current.state };\n        setPrinterState(newState);\n        return newState;\n      } catch (error) {\n        console.error(\"Error requesting status:\", error);\n        setStatusMessage(`Error: ${(error as Error).message}`);\n        return null;\n      }\n    }, [isConnected]);\n\n  /**\n   * Print from HTML canvas\n   */\n  const printCanvas = useCallback(\n    async (\n      canvas: HTMLCanvasElement,\n      options: Partial<ImageProcessorOptions> = {}\n    ) => {\n      if (!printerRef.current || !isConnected) {\n        setStatusMessage(\"Printer not connected\");\n        return;\n      }\n\n      try {\n        setIsPrinting(true);\n        setStatusMessage(\"Preparing to print...\");\n\n        // Default image processing options\n        const defaultOptions: ImageProcessorOptions = {\n          dither: ditherMethod,\n          brightness: 128,\n          flip: \"none\",\n          rotate: 180, // Required rotation for MXW01 printer\n          ...options,\n        };\n\n        // Get canvas dimensions\n        const canvasWidth = canvas.width;\n        const canvasHeight = canvas.height;\n\n        // Calculate scaling to fit printer width\n        const scale = PRINTER_WIDTH / canvasWidth;\n        const scaledHeight = Math.floor(canvasHeight * scale);\n\n        // Create temporary canvas for resizing\n        const tempCanvas = document.createElement(\"canvas\");\n        const tempCtx = tempCanvas.getContext(\"2d\");\n        if (!tempCtx) {\n          throw new Error(\"Failed to create 2D context\");\n        }\n\n        // Resize to printer width\n        tempCanvas.width = PRINTER_WIDTH;\n        tempCanvas.height = scaledHeight;\n\n        // Draw with white background\n        tempCtx.fillStyle = \"white\";\n        tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);\n        tempCtx.drawImage(canvas, 0, 0, tempCanvas.width, tempCanvas.height);\n\n        // Get image data\n        const imageData = tempCtx.getImageData(\n          0,\n          0,\n          tempCanvas.width,\n          tempCanvas.height\n        );\n\n        // Process image for printing\n        setStatusMessage(\"Processing image...\");\n        const { binaryRows } = processImageForPrinter(\n          imageData,\n          defaultOptions\n        );\n\n        // Prepare print buffer\n        const imageBuffer = prepareImageDataBuffer(binaryRows);\n\n        // Configure print intensity\n        setStatusMessage(\"Configuring printer...\");\n        await printerRef.current.setIntensity(printIntensity);\n\n        // Check printer status\n        const status = await printerRef.current.requestStatus();\n        if (status.length >= 13 && status[12] !== 0) {\n          throw new Error(`Printer error: ${status[13]}`);\n        }\n\n        // Send print request\n        setStatusMessage(\"Sending data...\");\n        const ack = await printerRef.current.printRequest(binaryRows.length, 0);\n        if (!ack || ack[0] !== 0) {\n          throw new Error(\"Print request rejected\");\n        }\n\n        // Send image data\n        await printerRef.current.sendDataChunks(imageBuffer);\n        await printerRef.current.flushData();\n\n        // Wait for print completion\n        setStatusMessage(\"Printing...\");\n        await printerRef.current.waitForPrintComplete();\n\n        setStatusMessage(\"Print completed\");\n        await getPrinterStatus();\n      } catch (error) {\n        console.error(\"Print error:\", error);\n        setStatusMessage(`Error: ${(error as Error).message}`);\n      } finally {\n        setIsPrinting(false);\n      }\n    },\n    [isConnected, ditherMethod, printIntensity, getPrinterStatus]\n  );\n\n  /**\n   * Disconnect printer\n   */\n  const disconnect = useCallback(async () => {\n    if (notifyCharRef.current) {\n      try {\n        await notifyCharRef.current.stopNotifications();\n      } catch (e) {\n        console.warn(\"Error stopping notifications:\", e);\n      }\n    }\n\n    if (deviceRef.current?.gatt?.connected) {\n      deviceRef.current.gatt.disconnect();\n    }\n\n    printerRef.current = null;\n    notifyCharRef.current = null;\n    deviceRef.current = null;\n\n    setIsConnected(false);\n    setPrinterState(null);\n    setStatusMessage(\"Printer disconnected\");\n  }, []);\n\n  return {\n    isConnected,\n    isPrinting,\n    printerState,\n    statusMessage,\n    ditherMethod,\n    printIntensity,\n    connectPrinter,\n    printCanvas,\n    getPrinterStatus,\n    disconnect,\n    setDitherMethod,\n    setPrintIntensity,\n  };\n}\n\nexport default useThermalPrinter;\n"],"names":["PRINTER_WIDTH","PRINTER_WIDTH_BYTES","MIN_DATA_BYTES","CRC8_TABLE","Command","crc8","data","crc","byte","delay","msecs","resolve","MXW01Printer","controlWrite","dataWrite","message","cmdId","len","payload","statusByte","resolver","command","header","cmdWithPayload","crcValue","result","timeoutMs","reject","timer","intensity","lines","mode","chunkSize","pos","chunk","startTime","encode1bppRow","rowBool","rowBytes","byteIndex","byteVal","bit","prepareImageDataBuffer","imageRowsBool","height","buffer","y","newBuf","pad","rgbaToGray","rgba","brightness","alphaAsWhite","mono","r","g","b","a","m","n","i","grayToRgba","whiteAsTransparent","base","ditherThreshold","ditherSteinberg","w","h","p","o","j","ditherHalftone","x","ditherBayer","bayer8","ditherFactor","bayerValue","pixelValue","ditherAtkinson","oldPixel","newPixel","error","rotate","before","turn","after","flip","processImageForPrinter","imageData","options","rgbaData","finalWidth","finalHeight","processedData","binaryRows","row","idx","lum","PRINTER_SERVICE_UUID","PRINTER_SERVICE_UUID_ALT","CONTROL_CHAR_UUID","NOTIFY_CHAR_UUID","DATA_CHAR_UUID","useThermalPrinter","isConnected","setIsConnected","useState","isPrinting","setIsPrinting","printerState","setPrinterState","statusMessage","setStatusMessage","ditherMethod","setDitherMethod","printIntensity","setPrintIntensity","printerRef","useRef","deviceRef","notifyCharRef","connectPrinter","useCallback","device","server","service","controlChar","notifyChar","dataChar","printer","notifier","event","value","getPrinterStatus","newState","printCanvas","canvas","defaultOptions","canvasWidth","canvasHeight","scale","scaledHeight","tempCanvas","tempCtx","imageBuffer","status","ack","disconnect","e"],"mappings":"yGAEaA,EAAgB,IAChBC,EAAsBD,EAAgB,EACtCE,EAAiB,GAAKD,EAE7BE,EAAa,CACjB,EAAM,EAAM,GAAM,EAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GACxE,GAAM,GAAM,GAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,GAAM,IAAM,GAAM,GACxE,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GACxE,GAAM,GAAM,GAAM,GAAM,EAAM,EAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GACxE,GAAM,GAAM,GAAM,IAAM,IAAM,GAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,GAAM,IAAM,IAAM,IAAM,IAAM,GACxE,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,EAAM,EACxE,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GACxE,GAAM,GAAM,GAAM,GAAM,GAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,GACxE,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,EAAM,EAAM,EAAM,GAAM,GACxE,GAAM,GAAM,GAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IACxE,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,IAAM,GAClD,EAEaC,EAAU,CACrB,UAAW,IACX,aAAc,IACd,aAAc,IACd,UAAW,IACX,cAAe,GACjB,EAcA,SAASC,EAAKC,EAA0B,CACtC,IAAIC,EAAM,EACV,UAAWC,KAAQF,EACjBC,EAAMJ,GAAYI,EAAMC,GAAQ,GAAI,EAEtC,OAAOD,EAAM,GACf,CAEA,SAASE,EAAMC,EAA8B,CAC3C,OAAO,IAAI,QAASC,GAAY,WAAW,IAAMA,EAAA,EAAWD,CAAK,CAAC,CACpE,CAEO,MAAME,CAAa,CAChB,aACA,UACA,cACA,iBACR,MAEA,YAAYC,EAA6BC,EAA0B,CACjE,KAAK,aAAeD,EACpB,KAAK,UAAYC,EACjB,KAAK,cAAgB,GACrB,KAAK,qBAAuB,IAC5B,KAAK,MAAQ,CACX,SAAU,GACV,UAAW,GACX,aAAc,GACd,WAAY,GACZ,YAAa,GACb,SAAU,EAAA,CAEd,CAEA,OAAOC,EAA2B,CAChC,GAAIA,EAAQ,CAAC,IAAM,IAAQA,EAAQ,CAAC,IAAM,GAAM,CAC9C,QAAQ,KAAK,yCAAyC,EACtD,MACF,CAEA,MAAMC,EAAQD,EAAQ,CAAC,EACjBE,EAAMF,EAAQ,CAAC,EAAKA,EAAQ,CAAC,GAAK,EAClCG,EAAUH,EAAQ,MAAM,EAAG,EAAIE,CAAG,EAQxC,GALID,IAAUZ,EAAQ,gBACpB,KAAK,cAAgB,IAInBY,IAAUZ,EAAQ,WAAac,EAAQ,QAAU,EAAG,CACtD,MAAMC,EAAaD,EAAQ,CAAC,EAC5B,KAAK,MAAQ,CACX,UAAWC,EAAa,KAAU,EAClC,WAAYA,EAAa,KAAU,EACnC,cAAeA,EAAa,KAAU,EACtC,YAAaA,EAAa,KAAU,EACpC,aAAcA,EAAa,MAAU,EACrC,UAAWA,EAAa,MAAU,CAAA,CAEtC,CAGA,MAAMC,EAAW,KAAK,iBAAiB,IAAIJ,CAAK,EAC5CI,IACFA,EAASF,CAAO,EAChB,KAAK,iBAAiB,OAAOF,CAAK,EAEtC,CAEA,YAAYK,EAAiBH,EAAiC,CAC5D,MAAMD,EAAMC,EAAQ,OACdI,EAAS,IAAI,WAAW,CAC5B,GACA,GACAD,EACA,EACAJ,EAAM,IACLA,GAAO,EAAK,GAAA,CACd,EAGKM,EAAiB,IAAI,WAAWD,EAAO,OAASJ,EAAQ,MAAM,EACpEK,EAAe,IAAID,CAAM,EACzBC,EAAe,IAAIL,EAASI,EAAO,MAAM,EAGzC,MAAME,EAAWnB,EAAKa,CAAO,EAGvBO,EAAS,IAAI,WAAWF,EAAe,OAAS,CAAC,EACvD,OAAAE,EAAO,IAAIF,CAAc,EACzBE,EAAOA,EAAO,OAAS,CAAC,EAAID,EAC5BC,EAAOA,EAAO,OAAS,CAAC,EAAI,IAErBA,CACT,CAEA,oBAAoBT,EAAeU,EAAY,IAA4B,CACzE,OAAO,IAAI,QAAQ,CAACf,EAASgB,IAAW,CACtC,MAAMC,EAAQ,WAAW,IAAM,CAC7B,KAAK,iBAAiB,OAAOZ,CAAK,EAClCW,EACE,IAAI,MAAM,sCAAsCX,EAAM,SAAS,EAAE,CAAC,EAAE,CAAA,CAExE,EAAGU,CAAS,EAEZ,KAAK,iBAAiB,IAAIV,EAAQE,GAAY,CAC5C,aAAaU,CAAK,EAClBjB,EAAQO,CAAO,CACjB,CAAC,CACH,CAAC,CACH,CAEA,MAAM,aAAaW,EAAY,GAAqB,CAClD,MAAMR,EAAU,KAAK,YACnBjB,EAAQ,aACR,WAAW,GAAGyB,CAAS,CAAA,EAEzB,MAAM,KAAK,aAAaR,CAAuB,EAC/C,MAAMZ,EAAM,EAAE,CAChB,CAEA,MAAM,eAAqC,CACzC,MAAMY,EAAU,KAAK,YAAYjB,EAAQ,UAAW,WAAW,GAAG,CAAI,CAAC,EACvE,aAAM,KAAK,aAAaiB,CAAuB,EACxC,KAAK,oBAAoBjB,EAAQ,UAAW,GAAI,CACzD,CAEA,MAAM,aAAa0B,EAAeC,EAAO,EAAwB,CAE/D,MAAMb,EAAU,IAAI,WAAW,CAAC,EAChCA,EAAQ,CAAC,EAAIY,EAAQ,IACrBZ,EAAQ,CAAC,EAAKY,GAAS,EAAK,IAC5BZ,EAAQ,CAAC,EAAI,GACbA,EAAQ,CAAC,EAAIa,EAEb,MAAMV,EAAU,KAAK,YAAYjB,EAAQ,aAAcc,CAAO,EAC9D,aAAM,KAAK,aAAaG,CAAuB,EACxC,KAAK,oBAAoBjB,EAAQ,aAAc,GAAI,CAC5D,CAEA,MAAM,WAA2B,CAC/B,MAAMiB,EAAU,KAAK,YAAYjB,EAAQ,UAAW,WAAW,GAAG,CAAI,CAAC,EACvE,MAAM,KAAK,aAAaiB,CAAuB,EAC/C,MAAMZ,EAAM,EAAE,CAChB,CAEA,MAAM,eACJH,EACA0B,EAAY/B,EACG,CAEf,IAAIgC,EAAM,EACV,KAAOA,EAAM3B,EAAK,QAAQ,CACxB,MAAM4B,EAAQ5B,EAAK,MAAM2B,EAAK,KAAK,IAAIA,EAAMD,EAAW1B,EAAK,MAAM,CAAC,EACpE,MAAM,KAAK,UAAU4B,CAAK,EAC1BD,GAAOC,EAAM,OAEb,MAAMzB,EAAM,EAAE,CAChB,CACF,CAEA,MAAM,qBAAqBiB,EAAY,IAAsB,CAC3D,KAAK,cAAgB,GACrB,MAAMS,EAAY,KAAK,IAAA,EAEvB,KAAO,CAAC,KAAK,eAAiB,KAAK,IAAA,EAAQA,EAAYT,GACrD,MAAMjB,EAAM,GAAG,EAGjB,GAAI,CAAC,KAAK,cACR,MAAM,IAAI,MAAM,wDAAwD,CAE5E,CACF,CAGO,SAAS2B,EAAcC,EAAgC,CAC5D,GAAIA,EAAQ,SAAWrC,EACrB,MAAM,IAAI,MACR,sBAAsBA,CAAa,SAASqC,EAAQ,MAAM,EAAA,EAI9D,MAAMC,EAAW,IAAI,WAAWrC,CAAmB,EACnD,QAASsC,EAAY,EAAGA,EAAYtC,EAAqBsC,IAAa,CACpE,IAAIC,EAAU,EACd,QAASC,EAAM,EAAGA,EAAM,EAAGA,IACrBJ,EAAQE,EAAY,EAAIE,CAAG,IAC7BD,GAAW,GAAKC,GAGpBH,EAASC,CAAS,EAAIC,CACxB,CAEA,OAAOF,CACT,CAGO,SAASI,EAAuBC,EAAwC,CAC7E,MAAMC,EAASD,EAAc,OAC7B,IAAIE,EAAS,IAAI,WAAW,CAAC,EAE7B,QAASC,EAAI,EAAGA,EAAIF,EAAQE,IAAK,CAC/B,MAAMR,EAAWF,EAAcO,EAAcG,CAAC,CAAC,EACzCC,EAAS,IAAI,WAAWF,EAAO,OAASP,EAAS,MAAM,EAC7DS,EAAO,IAAIF,CAAM,EACjBE,EAAO,IAAIT,EAAUO,EAAO,MAAM,EAClCA,EAASE,CACX,CAGA,GAAIF,EAAO,OAAS3C,EAAgB,CAClC,MAAM8C,EAAM,IAAI,WAAW9C,EAAiB2C,EAAO,MAAM,EACnDE,EAAS,IAAI,WAAWF,EAAO,OAASG,EAAI,MAAM,EACxDD,EAAO,IAAIF,CAAM,EACjBE,EAAO,IAAIC,EAAKH,EAAO,MAAM,EAC7BA,EAASE,CACX,CAEA,OAAOF,CACT,CC1QO,SAASI,EACdC,EACAC,EAAqB,IACrBC,EAAwB,GACL,CACnB,MAAMC,EAAO,IAAI,kBAAkBH,EAAK,MAAM,EAC9C,IAAII,EAAI,EACNC,EAAI,EACJC,EAAI,EACJC,EAAI,EACJC,EAAI,EACJC,EAAI,EAEN,QAASC,EAAI,EAAGA,EAAIP,EAAK,OAAQ,EAAEO,EACjCD,EAAIT,EAAKU,CAAC,EACVN,EAAIK,EAAI,IACRJ,EAAKI,GAAK,EAAK,IACfH,EAAKG,GAAK,GAAM,IAChBF,GAAME,GAAK,GAAM,KAAQ,IAErBF,EAAI,GAAKL,GACXK,EAAI,EAAIA,EACRH,IAAM,IAAOA,GAAKG,EAClBF,IAAM,IAAOA,GAAKE,EAClBD,IAAM,IAAOA,GAAKC,IAElBH,GAAKG,EACLF,GAAKE,EACLD,GAAKC,GAIPC,EAAIJ,EAAI,MAASC,EAAI,MAASC,EAAI,MAGlCE,IAAMP,EAAa,MAAS,EAAIO,EAAI,MAASA,EAAI,KAAQ,EACzDL,EAAKO,CAAC,EAAIF,EAGZ,OAAOL,CACT,CAKO,SAASQ,EACdR,EACAS,EAA8B,GACjB,CACb,MAAMZ,EAAO,IAAI,YAAYG,EAAK,MAAM,EAExC,QAAS,EAAI,EAAG,EAAIA,EAAK,OAAQ,EAAE,EAAG,CACpC,MAAMU,EAAOV,EAAK,CAAC,IAAM,KAAQS,EAAqB,EAAI,WAC1DZ,EAAK,CAAC,EAAIa,EAAQV,EAAK,CAAC,GAAK,GAAOA,EAAK,CAAC,GAAK,EAAKA,EAAK,CAAC,CAC5D,CAEA,OAAOH,CACT,CAOO,SAASc,EAAgBX,EAA4C,CAC1E,QAASO,EAAI,EAAGA,EAAIP,EAAK,OAAQ,EAAEO,EACjCP,EAAKO,CAAC,EAAIP,EAAKO,CAAC,EAAI,IAAO,IAAO,EAEpC,OAAOP,CACT,CAKO,SAASY,EACdZ,EACAa,EACAC,EACmB,CACnB,IAAIC,EAAI,EACNV,EAAI,EACJC,EAAI,EACJU,EAAI,EAEN,QAASC,EAAI,EAAGA,EAAIH,EAAG,EAAEG,EACvB,QAASV,EAAI,EAAGA,EAAIM,EAAG,EAAEN,EACvBF,EAAIL,EAAKe,CAAC,EACVT,EAAIN,EAAKe,CAAC,EAAI,IAAO,IAAO,EAC5BC,EAAIX,EAAIC,EACRN,EAAKe,CAAC,EAAIT,EAENC,GAAK,GAAKA,EAAIM,EAAI,GAAKI,GAAK,GAAKA,EAAIH,IAAGd,EAAKe,EAAI,CAAC,GAAMC,EAAI,EAAK,IACjET,GAAK,GAAKA,EAAIM,GAAKI,GAAK,GAAKA,EAAIH,EAAI,IACvCd,EAAKe,EAAIF,EAAI,CAAC,GAAMG,EAAI,EAAK,IAC3BT,GAAK,GAAKA,EAAIM,GAAKI,GAAK,GAAKA,EAAIH,EAAI,IAAGd,EAAKe,EAAIF,CAAC,GAAMG,EAAI,EAAK,IACjET,GAAK,GAAKA,EAAIM,EAAI,GAAKI,GAAK,GAAKA,EAAIH,EAAI,IAC3Cd,EAAKe,EAAIF,EAAI,CAAC,GAAMG,EAAI,EAAK,IAE/B,EAAED,EAIN,OAAOf,CACT,CAKO,SAASkB,EACdlB,EACAa,EACAC,EACmB,CAInB,IAAIP,EAAI,EACNU,EAAI,EACJE,EAAI,EACJ1B,EAAI,EACJuB,EAAI,EAEN,IAAKC,EAAI,EAAGA,EAAIH,EAAI,EAAMG,GAAK,EAAM,CACnC,IAAKV,EAAI,EAAGA,EAAIM,EAAI,EAAMN,GAAK,EAAM,CAEnC,IADAS,EAAI,EACCG,EAAI,EAAGA,EAAI,EAAM,EAAEA,EACtB,IAAK1B,EAAI,EAAGA,EAAI,EAAM,EAAEA,EACtBuB,GAAKhB,GAAMiB,EAAIxB,GAAKoB,EAAIN,EAAIY,CAAC,EAKjC,IAFAH,GAAK,EAAIA,EAAI,GAAS,KAAQ,EAEzBG,EAAI,EAAGA,EAAI,EAAM,EAAEA,EACtB,IAAK1B,EAAI,EAAGA,EAAI,EAAM,EAAEA,EACtBO,GAAMiB,EAAIxB,GAAKoB,EAAIN,EAAIY,CAAC,EACtB,KAAK,IAAIA,EAAI,CAAM,GAAKH,GAAK,KAAK,IAAIvB,EAAI,CAAM,GAAKuB,EACjD,IACA,CAGZ,CAEA,KAAOT,EAAIM,EAAG,EAAEN,IAAQU,EAAIJ,EAAIN,CAAC,EAAI,GACvC,CAEA,KAAOU,EAAIH,EAAG,EAAEG,EACd,IAAKV,EAAI,EAAGA,EAAIM,EAAG,EAAEN,EAAGP,EAAKiB,EAAIJ,EAAIN,CAAC,EAAI,IAG5C,OAAOP,CACT,CAKO,SAASoB,EACdpB,EACAa,EACAC,EACmB,CACnB,MAAMO,EAAS,CACb,EAAG,GAAI,GAAI,GAAI,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,EAAG,GACxE,GAAI,GAAI,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,GAAI,GAAI,EAAG,GAAI,GAAI,GACzE,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,GAAI,GAAI,GAAI,GACzE,GAAI,GAAI,GAAI,EAAA,EAGRC,EAAe,GACrB,IAAIP,EAAI,EAER,QAASE,EAAI,EAAGA,EAAIH,EAAG,EAAEG,EACvB,QAASV,EAAI,EAAGA,EAAIM,EAAG,EAAEN,EAAG,CAC1B,MAAMgB,EAAaF,EAAQJ,EAAI,EAAK,EAAKV,EAAI,CAAE,EAC/C,IAAIiB,EAAaxB,EAAKe,CAAC,EACvBS,EAAaA,GAAcD,EAAa,IAAMD,EAC1CE,EAAa,IAAGA,EAAa,GAC7BA,EAAa,MAAKA,EAAa,KACnCxB,EAAKe,CAAC,EAAIS,EAAa,IAAM,IAAO,EACpC,EAAET,CACJ,CAGF,OAAOf,CACT,CAKO,SAASyB,GACdzB,EACAa,EACAC,EACmB,CACnB,IAAIC,EAAI,EACJW,EAAW,EACbC,EAAW,EACXC,EAAQ,EAEV,QAASX,EAAI,EAAGA,EAAIH,EAAG,EAAEG,EACvB,QAASV,EAAI,EAAGA,EAAIM,EAAG,EAAEN,EACvBmB,EAAW1B,EAAKe,CAAC,EACjBY,EAAWD,EAAW,IAAO,IAAO,EACpCE,EAASF,EAAWC,GAAa,EACjC3B,EAAKe,CAAC,EAAIY,EAENpB,EAAIM,EAAI,IACVb,EAAKe,EAAI,CAAC,GAAKa,GAEbrB,EAAIM,EAAI,IACVb,EAAKe,EAAI,CAAC,GAAKa,GAEbX,EAAIH,EAAI,IACNP,EAAI,IACNP,EAAKe,EAAIF,EAAI,CAAC,GAAKe,GAErB5B,EAAKe,EAAIF,CAAC,GAAKe,EACXrB,EAAIM,EAAI,IACVb,EAAKe,EAAIF,EAAI,CAAC,GAAKe,IAGnBX,EAAIH,EAAI,IACVd,EAAKe,EAAI,EAAIF,CAAC,GAAKe,GAGrB,EAAEb,EAIN,OAAOf,CACT,CAKO,SAAS6B,EACdC,EACAjB,EACAC,EACAiB,EACmB,CACnB,MAAMC,EAAQ,IAAI,kBAAkBF,EAAO,MAAM,EAEjD,OAAQC,EAAA,CACN,IAAK,GACH,OAAOD,EACT,IAAK,IACH,QAASb,EAAI,EAAGA,EAAIH,EAAGG,IACrB,QAASV,EAAI,EAAGA,EAAIM,EAAGN,IACrByB,EAAMf,EAAIJ,EAAIN,CAAC,EAAIuB,GAAQjB,EAAIN,EAAI,GAAKO,EAAIG,CAAC,EAGjD,MACF,IAAK,KACH,QAASA,EAAI,EAAGA,EAAIH,EAAGG,IACrB,QAASV,EAAI,EAAGA,EAAIM,EAAGN,IACrByB,EAAMf,EAAIJ,EAAIN,CAAC,EAAIuB,GAAQhB,EAAIG,EAAI,GAAKJ,GAAKA,EAAIN,EAAI,EAAE,EAG3D,MACF,IAAK,KACH,QAASU,EAAI,EAAGA,EAAIH,EAAGG,IACrB,QAASV,EAAI,EAAGA,EAAIM,EAAGN,IACrByB,EAAMf,EAAIJ,EAAIN,CAAC,EAAIuB,EAAOvB,EAAIO,GAAKA,EAAIG,EAAI,EAAE,EAGjD,KAAA,CAGJ,OAAOe,CACT,CAKO,SAASC,GACdH,EACAjB,EACAC,EACApC,EACmB,CACnB,MAAMsD,EAAQ,IAAI,kBAAkBF,EAAO,MAAM,EAEjD,OAAQpD,EAAA,CACN,IAAK,OACH,OAAOoD,EACT,IAAK,IACH,QAASb,EAAI,EAAGA,EAAIH,EAAGG,IACrB,QAASV,EAAI,EAAGA,EAAIM,EAAGN,IACrByB,EAAMf,EAAIJ,EAAIN,CAAC,EAAIuB,EAAOb,EAAIJ,GAAKA,EAAIN,EAAI,EAAE,EAGjD,MACF,IAAK,IACH,QAASU,EAAI,EAAGA,EAAIH,EAAGG,IACrB,QAASV,EAAI,EAAGA,EAAIM,EAAGN,IACrByB,EAAMf,EAAIJ,EAAIN,CAAC,EAAIuB,GAAQhB,EAAIG,EAAI,GAAKJ,EAAIN,CAAC,EAGjD,MACF,IAAK,OACH,QAASU,EAAI,EAAGA,EAAIH,EAAGG,IACrB,QAASV,EAAI,EAAGA,EAAIM,EAAGN,IACrByB,EAAMf,EAAIJ,EAAIN,CAAC,EAAIuB,GAAQhB,EAAIG,EAAI,GAAKJ,GAAKA,EAAIN,EAAI,EAAE,EAG3D,KAAA,CAGJ,OAAOyB,CACT,CAmBO,SAASE,EACdC,EACAC,EAMA,CAEA,MAAMC,EAAW,IAAI,YACnB,IAAI,kBAAkBF,EAAU,IAAI,EAAE,MAAA,EAGlCtB,EAAIsB,EAAU,MACdrB,EAAIqB,EAAU,OAGpB,IAAInC,EAAOJ,EAAWyC,EAAUD,EAAQ,WAAY,EAAI,EAGxD,OAAQA,EAAQ,OAAA,CACd,IAAK,YACHpC,EAAOY,EAAgBZ,EAAMa,EAAGC,CAAC,EACjC,MACF,IAAK,QACHd,EAAOoB,EAAYpB,EAAMa,EAAGC,CAAC,EAC7B,MACF,IAAK,WACHd,EAAOyB,GAAezB,EAAMa,EAAGC,CAAC,EAChC,MACF,IAAK,UACHd,EAAOkB,EAAelB,EAAMa,EAAGC,CAAC,EAChC,MACF,IAAK,YACL,QACEd,EAAOW,EAAgBX,CAAI,EAC3B,KAAA,CAIJA,EAAOiC,GAAKjC,EAAMa,EAAGC,EAAGsB,EAAQ,IAAI,EAGpC,IAAIE,EAAazB,EACb0B,EAAczB,EAEdsB,EAAQ,SAAW,GAAKA,EAAQ,SAAW,IAC7CpC,EAAO6B,EAAO7B,EAAMa,EAAGC,EAAGsB,EAAQ,MAAM,GAExCpC,EAAO6B,EAAO7B,EAAMc,EAAGD,EAAGuB,EAAQ,MAAM,EACxCE,EAAaxB,EACbyB,EAAc1B,GAIhB,MAAM2B,EAAgBhC,EAAWR,EAAM,EAAI,EAGrCyC,EAA0B,CAAA,EAEhC,QAAShD,EAAI,EAAGA,EAAI8C,EAAa9C,IAAK,CACpC,MAAMiD,EAAiB,CAAA,EACvB,QAASvB,EAAI,EAAGA,EAAImB,EAAYnB,IAAK,CAEnC,MAAMwB,EAAMlD,EAAI6C,EAAanB,EACvByB,EAAM5C,EAAK2C,CAAG,EACpBD,EAAI,KAAKE,EAAM,GAAG,CACpB,CACAH,EAAW,KAAKC,CAAG,CACrB,CAEA,MAAO,CACL,cAAAF,EACA,MAAOF,EACP,OAAQC,EACR,WAAAE,CAAA,CAEJ,CC7YA,MAAMI,EAAuB,uCACvBC,EAA2B,uCAC3BC,GAAoB,uCACpBC,GAAmB,uCACnBC,GAAiB,uCAoBhB,SAASC,IAAwC,CACtD,KAAM,CAACC,EAAaC,CAAc,EAAIC,EAAAA,SAAkB,EAAK,EACvD,CAACC,EAAYC,CAAa,EAAIF,EAAAA,SAAkB,EAAK,EACrD,CAACG,EAAcC,CAAe,EAAIJ,EAAAA,SAA8B,IAAI,EACpE,CAACK,EAAeC,CAAgB,EAAIN,EAAAA,SACxC,0BAAA,EAEI,CAACO,EAAcC,CAAe,EAAIR,EAAAA,SAAuB,WAAW,EACpE,CAACS,EAAgBC,CAAiB,EAAIV,EAAAA,SAAiB,EAAI,EAG3DW,EAAaC,EAAAA,OAA4B,IAAI,EAC7CC,EAAYD,EAAAA,OAA+B,IAAI,EAC/CE,EAAgBF,EAAAA,OAAiD,IAAI,EAKrEG,EAAiBC,EAAAA,YAAY,SAAY,CAC7C,GAAI,CACFV,EAAiB,0BAA0B,EAG3C,MAAMW,EAAS,MAAM,UAAU,UAAU,cAAc,CACrD,QAAS,CACP,CAAE,SAAU,CAACzB,CAAoB,CAAA,EACjC,CAAE,SAAU,CAACC,CAAwB,CAAA,CAAE,EAEzC,iBAAkB,CAACD,EAAsBC,CAAwB,CAAA,CAClE,EAEDoB,EAAU,QAAUI,EAGpB,MAAMC,EAAS,MAAMD,EAAO,MAAM,QAAA,EAClC,GAAI,CAACC,EAAQ,MAAM,IAAI,MAAM,kCAAkC,EAG/D,IAAIC,EACJ,GAAI,CACFA,EAAU,MAAMD,EAAO,kBAAkB1B,CAAoB,CAC/D,MAAgB,CACd,QAAQ,IAAI,kDAAkD,EAC9D2B,EAAU,MAAMD,EAAO,kBAAkBzB,CAAwB,CACnE,CAGA,KAAM,CAAC2B,EAAaC,EAAYC,CAAQ,EAAI,MAAM,QAAQ,IAAI,CAC5DH,EAAQ,kBAAkBzB,EAAiB,EAC3CyB,EAAQ,kBAAkBxB,EAAgB,EAC1CwB,EAAQ,kBAAkBvB,EAAc,CAAA,CACzC,EAEDkB,EAAc,QAAUO,EAGxB,MAAME,EAAU,IAAIrH,EAClBkH,EAAY,0BAA0B,KAAKA,CAAW,EACtDE,EAAS,0BAA0B,KAAKA,CAAQ,CAAA,EAGlDX,EAAW,QAAUY,EAGrB,MAAMC,EAAYC,GAAiB,CAGjC,MAAMC,EADJD,EAAM,OACqB,MACzBC,IACFH,EAAQ,OAAO,IAAI,WAAWG,EAAM,MAAM,CAAC,EAC3CtB,EAAgB,CAAE,GAAGmB,EAAQ,MAAO,EAExC,EAEA,MAAMF,EAAW,mBAAA,EACjBA,EAAW,iBAAiB,6BAA8BG,CAAQ,EAElEzB,EAAe,EAAI,EACnBO,EAAiB,mBAAmB,EAGpC,MAAMqB,EAAA,CACR,OAASpD,EAAO,CACd,cAAQ,MAAM,oBAAqBA,CAAK,EACxC+B,EAAiB,UAAW/B,EAAgB,OAAO,EAAE,EAC/CA,CACR,CACF,EAAG,CAAA,CAAE,EAKCoD,EACJX,EAAAA,YAAY,SAA0C,CACpD,GAAI,CAACL,EAAW,SAAW,CAACb,EAC1B,OAAAQ,EAAiB,uBAAuB,EACjC,KAGT,GAAI,CACF,MAAMK,EAAW,QAAQ,cAAA,EACzB,MAAMiB,EAAW,CAAE,GAAGjB,EAAW,QAAQ,KAAA,EACzC,OAAAP,EAAgBwB,CAAQ,EACjBA,CACT,OAASrD,EAAO,CACd,eAAQ,MAAM,2BAA4BA,CAAK,EAC/C+B,EAAiB,UAAW/B,EAAgB,OAAO,EAAE,EAC9C,IACT,CACF,EAAG,CAACuB,CAAW,CAAC,EAKZ+B,EAAcb,EAAAA,YAClB,MACEc,EACA/C,EAA0C,KACvC,CACH,GAAI,CAAC4B,EAAW,SAAW,CAACb,EAAa,CACvCQ,EAAiB,uBAAuB,EACxC,MACF,CAEA,GAAI,CACFJ,EAAc,EAAI,EAClBI,EAAiB,uBAAuB,EAGxC,MAAMyB,EAAwC,CAC5C,OAAQxB,EACR,WAAY,IACZ,KAAM,OACN,OAAQ,IACR,GAAGxB,CAAA,EAICiD,EAAcF,EAAO,MACrBG,EAAeH,EAAO,OAGtBI,EAAQ5I,EAAgB0I,EACxBG,EAAe,KAAK,MAAMF,EAAeC,CAAK,EAG9CE,EAAa,SAAS,cAAc,QAAQ,EAC5CC,EAAUD,EAAW,WAAW,IAAI,EAC1C,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,6BAA6B,EAI/CD,EAAW,MAAQ9I,EACnB8I,EAAW,OAASD,EAGpBE,EAAQ,UAAY,QACpBA,EAAQ,SAAS,EAAG,EAAGD,EAAW,MAAOA,EAAW,MAAM,EAC1DC,EAAQ,UAAUP,EAAQ,EAAG,EAAGM,EAAW,MAAOA,EAAW,MAAM,EAGnE,MAAMtD,EAAYuD,EAAQ,aACxB,EACA,EACAD,EAAW,MACXA,EAAW,MAAA,EAIb9B,EAAiB,qBAAqB,EACtC,KAAM,CAAE,WAAAlB,GAAeP,EACrBC,EACAiD,CAAA,EAIIO,EAActG,EAAuBoD,CAAU,EAGrDkB,EAAiB,wBAAwB,EACzC,MAAMK,EAAW,QAAQ,aAAaF,CAAc,EAGpD,MAAM8B,EAAS,MAAM5B,EAAW,QAAQ,cAAA,EACxC,GAAI4B,EAAO,QAAU,IAAMA,EAAO,EAAE,IAAM,EACxC,MAAM,IAAI,MAAM,kBAAkBA,EAAO,EAAE,CAAC,EAAE,EAIhDjC,EAAiB,iBAAiB,EAClC,MAAMkC,EAAM,MAAM7B,EAAW,QAAQ,aAAavB,EAAW,OAAQ,CAAC,EACtE,GAAI,CAACoD,GAAOA,EAAI,CAAC,IAAM,EACrB,MAAM,IAAI,MAAM,wBAAwB,EAI1C,MAAM7B,EAAW,QAAQ,eAAe2B,CAAW,EACnD,MAAM3B,EAAW,QAAQ,UAAA,EAGzBL,EAAiB,aAAa,EAC9B,MAAMK,EAAW,QAAQ,qBAAA,EAEzBL,EAAiB,iBAAiB,EAClC,MAAMqB,EAAA,CACR,OAASpD,EAAO,CACd,QAAQ,MAAM,eAAgBA,CAAK,EACnC+B,EAAiB,UAAW/B,EAAgB,OAAO,EAAE,CACvD,QAAA,CACE2B,EAAc,EAAK,CACrB,CACF,EACA,CAACJ,EAAaS,EAAcE,EAAgBkB,CAAgB,CAAA,EAMxDc,EAAazB,EAAAA,YAAY,SAAY,CACzC,GAAIF,EAAc,QAChB,GAAI,CACF,MAAMA,EAAc,QAAQ,kBAAA,CAC9B,OAAS4B,EAAG,CACV,QAAQ,KAAK,gCAAiCA,CAAC,CACjD,CAGE7B,EAAU,SAAS,MAAM,WAC3BA,EAAU,QAAQ,KAAK,WAAA,EAGzBF,EAAW,QAAU,KACrBG,EAAc,QAAU,KACxBD,EAAU,QAAU,KAEpBd,EAAe,EAAK,EACpBK,EAAgB,IAAI,EACpBE,EAAiB,sBAAsB,CACzC,EAAG,CAAA,CAAE,EAEL,MAAO,CACL,YAAAR,EACA,WAAAG,EACA,aAAAE,EACA,cAAAE,EACA,aAAAE,EACA,eAAAE,EACA,eAAAM,EACA,YAAAc,EACA,iBAAAF,EACA,WAAAc,EACA,gBAAAjC,EACA,kBAAAE,CAAA,CAEJ"}