{"version":3,"file":"phrase-parser.cjs","sources":["../../../src/utils/phrase-parser.ts"],"sourcesContent":["/**\n * Phrase parser for multi-word query support\n * Extracts quoted phrases and regular terms from search queries\n */\n\nexport interface ParsedQuery {\n  /** Quoted phrases to search as units */\n  phrases: string[];\n  /** Individual search terms */\n  terms: string[];\n  /** Original query string */\n  original: string;\n  /** Whether query contains any phrases */\n  hasPhrases: boolean;\n}\n\n/**\n * Parse a search query to extract phrases and terms\n * Supports both double quotes (\") and single quotes (')\n * \n * @example\n * parseQuery('\"new york\" city')\n * // → { phrases: ['new york'], terms: ['city'], hasPhrases: true }\n * \n * parseQuery('hello world')\n * // → { phrases: [], terms: ['hello', 'world'], hasPhrases: false }\n */\nexport function parseQuery(query: string): ParsedQuery {\n  if (!query || typeof query !== 'string') {\n    return {\n      phrases: [],\n      terms: [],\n      original: query || '',\n      hasPhrases: false,\n    };\n  }\n\n  const phrases: string[] = [];\n  let remaining = query;\n\n  // Extract phrases with double quotes\n  const doubleQuoteRegex = /\"([^\"]+)\"/g;\n  let match;\n  \n  while ((match = doubleQuoteRegex.exec(query)) !== null) {\n    const phrase = match[1].trim();\n    if (phrase) {\n      // Validate phrase length (max 10 words)\n      const wordCount = phrase.split(/\\s+/).length;\n      if (wordCount <= 10) {\n        phrases.push(phrase);\n      }\n    }\n  }\n\n  // Remove double-quoted phrases from remaining text (including empty ones)\n  remaining = remaining.replace(/\"[^\"]*\"/g, ' ');\n\n  // Extract phrases with single quotes\n  const singleQuoteRegex = /'([^']+)'/g;\n  \n  while ((match = singleQuoteRegex.exec(query)) !== null) {\n    const phrase = match[1].trim();\n    if (phrase) {\n      // Validate phrase length (max 10 words)\n      const wordCount = phrase.split(/\\s+/).length;\n      if (wordCount <= 10) {\n        phrases.push(phrase);\n      }\n    }\n  }\n\n  // Remove single-quoted phrases from remaining text (including empty ones)\n  remaining = remaining.replace(/'[^']*'/g, ' ');\n\n  // Extract remaining terms (non-phrase words)\n  const terms = remaining\n    .split(/\\s+/)\n    .map(t => t.trim())\n    .filter(t => t.length > 0);\n\n  return {\n    phrases,\n    terms,\n    original: query,\n    hasPhrases: phrases.length > 0,\n  };\n}\n\n/**\n * Check if a query contains phrase syntax (quotes)\n */\nexport function hasPhraseSyntax(query: string): boolean {\n  if (!query) return false;\n  return /\"[^\"]*\"/.test(query) || /'[^']*'/.test(query);\n}\n\n/**\n * Normalize a phrase for matching (lowercase, trim)\n */\nexport function normalizePhrase(phrase: string): string {\n  return phrase.toLowerCase().trim().replace(/\\s+/g, ' ');\n}\n\n/**\n * Split a phrase into words\n */\nexport function splitPhraseWords(phrase: string): string[] {\n  return phrase\n    .toLowerCase()\n    .trim()\n    .split(/\\s+/)\n    .filter(w => w.length > 0);\n}\n"],"names":[],"mappings":";;AA2BO,SAAS,WAAW,OAA4B;AACrD,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,MACL,SAAS,CAAA;AAAA,MACT,OAAO,CAAA;AAAA,MACP,UAAU,SAAS;AAAA,MACnB,YAAY;AAAA,IAAA;AAAA,EAEhB;AAEA,QAAM,UAAoB,CAAA;AAC1B,MAAI,YAAY;AAGhB,QAAM,mBAAmB;AACzB,MAAI;AAEJ,UAAQ,QAAQ,iBAAiB,KAAK,KAAK,OAAO,MAAM;AACtD,UAAM,SAAS,MAAM,CAAC,EAAE,KAAA;AACxB,QAAI,QAAQ;AAEV,YAAM,YAAY,OAAO,MAAM,KAAK,EAAE;AACtC,UAAI,aAAa,IAAI;AACnB,gBAAQ,KAAK,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAGA,cAAY,UAAU,QAAQ,YAAY,GAAG;AAG7C,QAAM,mBAAmB;AAEzB,UAAQ,QAAQ,iBAAiB,KAAK,KAAK,OAAO,MAAM;AACtD,UAAM,SAAS,MAAM,CAAC,EAAE,KAAA;AACxB,QAAI,QAAQ;AAEV,YAAM,YAAY,OAAO,MAAM,KAAK,EAAE;AACtC,UAAI,aAAa,IAAI;AACnB,gBAAQ,KAAK,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAGA,cAAY,UAAU,QAAQ,YAAY,GAAG;AAG7C,QAAM,QAAQ,UACX,MAAM,KAAK,EACX,IAAI,CAAA,MAAK,EAAE,KAAA,CAAM,EACjB,OAAO,CAAA,MAAK,EAAE,SAAS,CAAC;AAE3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,YAAY,QAAQ,SAAS;AAAA,EAAA;AAEjC;AAKO,SAAS,gBAAgB,OAAwB;AACtD,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,UAAU,KAAK,KAAK,KAAK,UAAU,KAAK,KAAK;AACtD;AAKO,SAAS,gBAAgB,QAAwB;AACtD,SAAO,OAAO,cAAc,OAAO,QAAQ,QAAQ,GAAG;AACxD;AAKO,SAAS,iBAAiB,QAA0B;AACzD,SAAO,OACJ,YAAA,EACA,KAAA,EACA,MAAM,KAAK,EACX,OAAO,CAAA,MAAK,EAAE,SAAS,CAAC;AAC7B;;;;;"}