{"version":3,"file":"detect-C63LoF7X.mjs","names":[],"sources":["../src/detect.ts"],"sourcesContent":["export type FormatType = \"ipuz\" | \"puz\" | \"jpz\" | \"xd\" | \"unknown\";\n\nexport interface FormatHint {\n  format: FormatType;\n  confidence: \"high\" | \"medium\" | \"low\";\n}\n\nexport function detectFormatFromContent(\n  content: string | Buffer,\n  filename?: string,\n): FormatHint[] {\n  const hints: FormatHint[] = [];\n\n  // Check filename extension first\n  if (filename) {\n    const ext = filename.split(\".\").pop()?.toLowerCase();\n    if (ext === \"puz\") {\n      hints.push({ format: \"puz\", confidence: \"high\" });\n    } else if (ext === \"ipuz\") {\n      hints.push({ format: \"ipuz\", confidence: \"high\" });\n    } else if (ext === \"jpz\") {\n      hints.push({ format: \"jpz\", confidence: \"high\" });\n    } else if (ext === \"xd\") {\n      hints.push({ format: \"xd\", confidence: \"high\" });\n    }\n  }\n\n  // Content-based detection\n  if (typeof content === \"string\") {\n    const trimmed = content.trim();\n\n    // iPUZ detection\n    if (\n      trimmed.startsWith(\"ipuz({\") ||\n      (trimmed.startsWith(\"{\") && trimmed.includes('\"version\"'))\n    ) {\n      if (!hints.some((h) => h.format === \"ipuz\")) {\n        hints.push({ format: \"ipuz\", confidence: \"high\" });\n      }\n    }\n\n    // JPZ detection (XML)\n    if (\n      content.includes(\"<?xml\") ||\n      content.includes(\"<crossword\") ||\n      content.includes(\"<puzzle\")\n    ) {\n      if (!hints.some((h) => h.format === \"jpz\")) {\n        hints.push({ format: \"jpz\", confidence: \"high\" });\n      }\n    }\n\n    // XD detection\n    const lines = content.split(\"\\n\");\n    const hasXdHeaders = lines.some((line) =>\n      /^(Title|Author|Editor|Copyright|Date|Rebus|Notepad|Notes?):/i.test(line),\n    );\n    if (hasXdHeaders) {\n      if (!hints.some((h) => h.format === \"xd\")) {\n        hints.push({ format: \"xd\", confidence: \"high\" });\n      }\n    }\n  } else {\n    // Binary content - likely PUZ\n    if (!hints.some((h) => h.format === \"puz\")) {\n      hints.push({ format: \"puz\", confidence: \"medium\" });\n    }\n\n    // But could also be text encoded as Buffer\n    const textContent = content.toString(\"utf-8\");\n    const trimmed = textContent.trim();\n\n    if (\n      trimmed.startsWith(\"ipuz({\") ||\n      (trimmed.startsWith(\"{\") && trimmed.includes('\"version\"'))\n    ) {\n      if (!hints.some((h) => h.format === \"ipuz\")) {\n        hints.push({ format: \"ipuz\", confidence: \"medium\" });\n      }\n    }\n\n    if (\n      textContent.includes(\"<?xml\") ||\n      textContent.includes(\"<crossword\") ||\n      textContent.includes(\"<puzzle\")\n    ) {\n      if (!hints.some((h) => h.format === \"jpz\")) {\n        hints.push({ format: \"jpz\", confidence: \"medium\" });\n      }\n    }\n\n    const lines = textContent.split(\"\\n\");\n    const hasXdHeaders = lines.some((line) =>\n      /^(Title|Author|Editor|Copyright|Date|Rebus|Notepad|Notes?):/i.test(line),\n    );\n    if (hasXdHeaders) {\n      if (!hints.some((h) => h.format === \"xd\")) {\n        hints.push({ format: \"xd\", confidence: \"medium\" });\n      }\n    }\n  }\n\n  // Sort by confidence (high first)\n  hints.sort((a, b) => {\n    const confidenceOrder = { high: 0, medium: 1, low: 2 };\n    return confidenceOrder[a.confidence] - confidenceOrder[b.confidence];\n  });\n\n  return hints;\n}\n\nexport function getOrderedFormatsToTry(\n  content: string | Buffer,\n  filename?: string,\n): FormatType[] {\n  const hints = detectFormatFromContent(content, filename);\n  const formats: FormatType[] = [];\n\n  // Add hinted formats first\n  for (const hint of hints) {\n    if (!formats.includes(hint.format)) {\n      formats.push(hint.format);\n    }\n  }\n\n  // Add remaining formats\n  const allFormats: FormatType[] = [\"ipuz\", \"puz\", \"jpz\", \"xd\"];\n  for (const format of allFormats) {\n    if (!formats.includes(format)) {\n      formats.push(format);\n    }\n  }\n\n  return formats;\n}\n"],"mappings":";AAOA,SAAgB,wBACd,SACA,UACc;CACd,MAAM,QAAsB,EAAE;AAG9B,KAAI,UAAU;EACZ,MAAM,MAAM,SAAS,MAAM,IAAI,CAAC,KAAK,EAAE,aAAa;AACpD,MAAI,QAAQ,MACV,OAAM,KAAK;GAAE,QAAQ;GAAO,YAAY;GAAQ,CAAC;WACxC,QAAQ,OACjB,OAAM,KAAK;GAAE,QAAQ;GAAQ,YAAY;GAAQ,CAAC;WACzC,QAAQ,MACjB,OAAM,KAAK;GAAE,QAAQ;GAAO,YAAY;GAAQ,CAAC;WACxC,QAAQ,KACjB,OAAM,KAAK;GAAE,QAAQ;GAAM,YAAY;GAAQ,CAAC;;AAKpD,KAAI,OAAO,YAAY,UAAU;EAC/B,MAAM,UAAU,QAAQ,MAAM;AAG9B,MACE,QAAQ,WAAW,SAAS,IAC3B,QAAQ,WAAW,IAAI,IAAI,QAAQ,SAAS,cAAY,EAEzD;OAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,OAAO,CACzC,OAAM,KAAK;IAAE,QAAQ;IAAQ,YAAY;IAAQ,CAAC;;AAKtD,MACE,QAAQ,SAAS,QAAQ,IACzB,QAAQ,SAAS,aAAa,IAC9B,QAAQ,SAAS,UAAU,EAE3B;OAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,MAAM,CACxC,OAAM,KAAK;IAAE,QAAQ;IAAO,YAAY;IAAQ,CAAC;;AASrD,MAJc,QAAQ,MAAM,KAAK,CACN,MAAM,SAC/B,+DAA+D,KAAK,KAAK,CAC1E,EAEC;OAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,KAAK,CACvC,OAAM,KAAK;IAAE,QAAQ;IAAM,YAAY;IAAQ,CAAC;;QAG/C;AAEL,MAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,MAAM,CACxC,OAAM,KAAK;GAAE,QAAQ;GAAO,YAAY;GAAU,CAAC;EAIrD,MAAM,cAAc,QAAQ,SAAS,QAAQ;EAC7C,MAAM,UAAU,YAAY,MAAM;AAElC,MACE,QAAQ,WAAW,SAAS,IAC3B,QAAQ,WAAW,IAAI,IAAI,QAAQ,SAAS,cAAY,EAEzD;OAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,OAAO,CACzC,OAAM,KAAK;IAAE,QAAQ;IAAQ,YAAY;IAAU,CAAC;;AAIxD,MACE,YAAY,SAAS,QAAQ,IAC7B,YAAY,SAAS,aAAa,IAClC,YAAY,SAAS,UAAU,EAE/B;OAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,MAAM,CACxC,OAAM,KAAK;IAAE,QAAQ;IAAO,YAAY;IAAU,CAAC;;AAQvD,MAJc,YAAY,MAAM,KAAK,CACV,MAAM,SAC/B,+DAA+D,KAAK,KAAK,CAC1E,EAEC;OAAI,CAAC,MAAM,MAAM,MAAM,EAAE,WAAW,KAAK,CACvC,OAAM,KAAK;IAAE,QAAQ;IAAM,YAAY;IAAU,CAAC;;;AAMxD,OAAM,MAAM,GAAG,MAAM;EACnB,MAAM,kBAAkB;GAAE,MAAM;GAAG,QAAQ;GAAG,KAAK;GAAG;AACtD,SAAO,gBAAgB,EAAE,cAAc,gBAAgB,EAAE;GACzD;AAEF,QAAO;;AAGT,SAAgB,uBACd,SACA,UACc;CACd,MAAM,QAAQ,wBAAwB,SAAS,SAAS;CACxD,MAAM,UAAwB,EAAE;AAGhC,MAAK,MAAM,QAAQ,MACjB,KAAI,CAAC,QAAQ,SAAS,KAAK,OAAO,CAChC,SAAQ,KAAK,KAAK,OAAO;AAM7B,MAAK,MAAM,UADsB;EAAC;EAAQ;EAAO;EAAO;EAAK,CAE3D,KAAI,CAAC,QAAQ,SAAS,OAAO,CAC3B,SAAQ,KAAK,OAAO;AAIxB,QAAO"}